def generateCallExpression()

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)
  }