in flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/calls/StringCallGen.scala [47:251]
def generateCallExpression(
ctx: CodeGeneratorContext,
operator: SqlOperator,
operands: Seq[GeneratedExpression],
returnType: LogicalType): Option[GeneratedExpression] = {
def methodGen(method: Method): GeneratedExpression = {
new MethodCallGen(method).generate(ctx, operands, returnType)
}
def fallibleMethodGen(method: Method): GeneratedExpression = {
new MethodCallGen(method, wrapTryCatch = true).generate(ctx, operands, returnType)
}
val generator = operator match {
case LIKE =>
new LikeCallGen().generate(ctx, operands, returnType)
case NOT_LIKE =>
generateNot(ctx, new LikeCallGen().generate(ctx, operands, returnType), returnType)
case SUBSTR | SUBSTRING => generateSubString(ctx, operands, returnType)
case LEFT => generateLeft(ctx, operands.head, operands(1), returnType)
case RIGHT => generateRight(ctx, operands.head, operands(1), returnType)
case CHAR_LENGTH | CHARACTER_LENGTH => generateCharLength(ctx, operands, returnType)
case SIMILAR_TO => generateSimilarTo(ctx, operands, returnType)
case NOT_SIMILAR_TO =>
generateNot(ctx, generateSimilarTo(ctx, operands, returnType), returnType)
case REGEXP_EXTRACT => generateRegexpExtract(ctx, operands, returnType)
case REGEXP_REPLACE => generateRegexpReplace(ctx, operands, returnType)
case IS_DECIMAL => generateIsDecimal(ctx, operands, returnType)
case IS_DIGIT => generateIsDigit(ctx, operands, returnType)
case IS_ALPHA => generateIsAlpha(ctx, operands, returnType)
case UPPER => generateUpper(ctx, operands, returnType)
case LOWER => generateLower(ctx, operands, returnType)
case INITCAP => generateInitcap(ctx, operands, returnType)
case POSITION => generatePosition(ctx, operands, returnType)
case LOCATE => generateLocate(ctx, operands, returnType)
case OVERLAY => generateOverlay(ctx, operands, returnType)
case LPAD => generateLpad(ctx, operands, returnType)
case RPAD => generateRpad(ctx, operands, returnType)
case REPEAT => generateRepeat(ctx, operands, returnType)
case REVERSE => generateReverse(ctx, operands, returnType)
case REPLACE => generateReplace(ctx, operands, returnType)
case SPLIT_INDEX => generateSplitIndex(ctx, operands, returnType)
case HASH_CODE if isCharacterString(operands.head.resultType) =>
generateHashCode(ctx, operands, returnType)
case MD5 => generateMd5(ctx, operands, returnType)
case SHA1 => generateSha1(ctx, operands, returnType)
case SHA224 => generateSha224(ctx, operands, returnType)
case SHA256 => generateSha256(ctx, operands, returnType)
case SHA384 => generateSha384(ctx, operands, returnType)
case SHA512 => generateSha512(ctx, operands, returnType)
case SHA2 => generateSha2(ctx, operands, returnType)
case PARSE_URL => generateParserUrl(ctx, operands, returnType)
case FROM_BASE64 => generateFromBase64(ctx, operands, returnType)
case TO_BASE64 => generateToBase64(ctx, operands, returnType)
case CHR => generateChr(ctx, operands, returnType)
case REGEXP => generateRegExp(ctx, operands, returnType)
case BIN => generateBin(ctx, operands, returnType)
case CONCAT_FUNCTION =>
operands.foreach(requireCharacterString)
generateConcat(ctx, operands, returnType)
case CONCAT_WS =>
operands.foreach(requireCharacterString)
generateConcatWs(ctx, operands, returnType)
case STR_TO_MAP => generateStrToMap(ctx, operands, returnType)
case TRIM => generateTrim(ctx, operands, returnType)
case LTRIM => generateTrimLeft(ctx, operands, returnType)
case RTRIM => generateTrimRight(ctx, operands, returnType)
case CONCAT =>
val left = operands.head
val right = operands(1)
requireCharacterString(left)
generateArithmeticConcat(ctx, left, right, returnType)
case UUID => generateUuid(ctx, operands, returnType)
case ASCII => generateAscii(ctx, operands.head, returnType)
case ENCODE => generateEncode(ctx, operands.head, operands(1), returnType)
case DECODE => generateDecode(ctx, operands.head, operands(1), returnType)
case INSTR => generateInstr(ctx, operands, returnType)
case PRINT => new PrintCallGen().generate(ctx, operands, returnType)
case IF =>
requireBoolean(operands.head)
new IfCallGen().generate(ctx, operands, returnType)
// Date/Time & StringData Converting -- start
case TO_DATE if operands.size == 1 && isCharacterString(operands.head.resultType) =>
methodGen(BuiltInMethods.STRING_TO_DATE)
case TO_DATE
if operands.size == 2 &&
isCharacterString(operands.head.resultType) &&
isCharacterString(operands(1).resultType) =>
methodGen(BuiltInMethods.STRING_TO_DATE_WITH_FORMAT)
case TO_TIMESTAMP if operands.size == 1 && isCharacterString(operands.head.resultType) =>
fallibleMethodGen(BuiltInMethods.STRING_TO_TIMESTAMP)
case TO_TIMESTAMP
if operands.size == 2 &&
isCharacterString(operands.head.resultType) &&
isCharacterString(operands(1).resultType) =>
fallibleMethodGen(BuiltInMethods.STRING_TO_TIMESTAMP_WITH_FORMAT)
case UNIX_TIMESTAMP if operands.size == 1 && isCharacterString(operands.head.resultType) =>
methodGen(BuiltInMethods.UNIX_TIMESTAMP_STR)
case UNIX_TIMESTAMP
if operands.size == 2 &&
isCharacterString(operands.head.resultType) &&
isCharacterString(operands(1).resultType) =>
methodGen(BuiltInMethods.UNIX_TIMESTAMP_FORMAT)
case DATE_FORMAT
if operands.size == 2 &&
isTimestamp(operands.head.resultType) &&
isCharacterString(operands(1).resultType) =>
methodGen(BuiltInMethods.FORMAT_TIMESTAMP_DATA)
case DATE_FORMAT
if operands.size == 2 &&
isTimestampWithLocalZone(operands.head.resultType) &&
isCharacterString(operands(1).resultType) =>
methodGen(BuiltInMethods.FORMAT_TIMESTAMP_DATA_WITH_TIME_ZONE)
case DATE_FORMAT
if operands.size == 2 &&
isCharacterString(operands.head.resultType) &&
isCharacterString(operands(1).resultType) =>
methodGen(BuiltInMethods.FORMAT_TIMESTAMP_STRING_FORMAT_STRING_STRING)
case CONVERT_TZ
if operands.size == 3 &&
isCharacterString(operands.head.resultType) &&
isCharacterString(operands(1).resultType) &&
isCharacterString(operands(2).resultType) =>
methodGen(BuiltInMethods.CONVERT_TZ)
case CURRENT_DATABASE =>
val currentDatabase = ctx.addReusableQueryLevelCurrentDatabase()
generateNonNullField(returnType, currentDatabase)
case op => {
if (op.isInstanceOf[SqlDefaultArgOperator]) {
generateNullLiteral(returnType)
} else {
null
}
}
}
Option(generator)
}