def generateLiteral()

in flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/planner/codegen/GenerateUtils.scala [295:460]


  def generateLiteral(
      ctx: CodeGeneratorContext,
      literalType: LogicalType,
      literalValue: Any): GeneratedExpression = {
    if (literalValue == null) {
      return generateNullLiteral(literalType, ctx.nullCheck)
    }
    // non-null values
    literalType.getTypeRoot match {
      // ordered by type root definition
      case CHAR | VARCHAR =>
        val escapedValue = StringEscapeUtils.ESCAPE_JAVA.translate(literalValue.toString)
        val field = ctx.addReusableStringConstants(escapedValue)
        generateNonNullLiteral(literalType, field, StringData.fromString(escapedValue))

      case BOOLEAN =>
        generateNonNullLiteral(literalType, literalValue.toString, literalValue)

      case BINARY | VARBINARY =>
        val bytesVal = literalValue.asInstanceOf[ByteString].getBytes
        val fieldTerm = ctx.addReusableObject(
          bytesVal, "binary", bytesVal.getClass.getCanonicalName)
        generateNonNullLiteral(literalType, fieldTerm, bytesVal)

      case DECIMAL =>
        val dt = literalType.asInstanceOf[DecimalType]
        val precision = dt.getPrecision
        val scale = dt.getScale
        val fieldTerm = newName("decimal")
        val decimalClass = className[DecimalData]
        val fieldDecimal =
          s"""
             |$decimalClass $fieldTerm =
             |    $DECIMAL_UTIL.castFrom("${literalValue.toString}", $precision, $scale);
             |""".stripMargin
        ctx.addReusableMember(fieldDecimal)
        val value = DecimalData.fromBigDecimal(
          literalValue.asInstanceOf[JBigDecimal], precision, scale)
        if (value == null) {
          generateNullLiteral(literalType, ctx.nullCheck)
        } else {
          generateNonNullLiteral(literalType, fieldTerm, value)
        }

      case TINYINT =>
        val decimal = BigDecimal(literalValue.asInstanceOf[JBigDecimal])
        generateNonNullLiteral(literalType, decimal.byteValue().toString, decimal.byteValue())

      case SMALLINT =>
        val decimal = BigDecimal(literalValue.asInstanceOf[JBigDecimal])
        generateNonNullLiteral(literalType, decimal.shortValue().toString, decimal.shortValue())

      case INTEGER =>
        val decimal = BigDecimal(literalValue.asInstanceOf[JBigDecimal])
        generateNonNullLiteral(literalType, decimal.intValue().toString, decimal.intValue())

      case BIGINT =>
        val decimal = BigDecimal(literalValue.asInstanceOf[JBigDecimal])
        generateNonNullLiteral(
          literalType, decimal.longValue().toString + "L", decimal.longValue())

      case FLOAT =>
        val floatValue = literalValue.asInstanceOf[JBigDecimal].floatValue()
        floatValue match {
          case Float.NegativeInfinity =>
            generateNonNullLiteral(
              literalType,
              "java.lang.Float.NEGATIVE_INFINITY",
              Float.NegativeInfinity)
          case Float.PositiveInfinity => generateNonNullLiteral(
            literalType,
            "java.lang.Float.POSITIVE_INFINITY",
            Float.PositiveInfinity)
          case _ => generateNonNullLiteral(
            literalType, floatValue.toString + "f", floatValue)
        }

      case DOUBLE =>
        val doubleValue = literalValue.asInstanceOf[JBigDecimal].doubleValue()
        doubleValue match {
          case Double.NegativeInfinity =>
            generateNonNullLiteral(
              literalType,
              "java.lang.Double.NEGATIVE_INFINITY",
              Double.NegativeInfinity)
          case Double.PositiveInfinity =>
            generateNonNullLiteral(
              literalType,
              "java.lang.Double.POSITIVE_INFINITY",
              Double.PositiveInfinity)
          case _ => generateNonNullLiteral(
            literalType, doubleValue.toString + "d", doubleValue)
        }

      case DATE =>
        generateNonNullLiteral(literalType, literalValue.toString, literalValue)

      case TIME_WITHOUT_TIME_ZONE =>
        generateNonNullLiteral(literalType, literalValue.toString, literalValue)

      case TIMESTAMP_WITHOUT_TIME_ZONE =>
        val fieldTerm = newName("timestamp")
        val ldt = toLocalDateTime(literalValue.asInstanceOf[TimestampString])
        val ts = TimestampData.fromLocalDateTime(ldt)
        val fieldTimestamp =
          s"""
             |$TIMESTAMP_DATA $fieldTerm =
             |  $TIMESTAMP_DATA.fromEpochMillis(${ts.getMillisecond}L, ${ts.getNanoOfMillisecond});
           """.stripMargin
        ctx.addReusableMember(fieldTimestamp)
        generateNonNullLiteral(literalType, fieldTerm, ts)

      case TIMESTAMP_WITH_TIME_ZONE =>
        throw new UnsupportedOperationException("Unsupported type: " + literalType)

      case TIMESTAMP_WITH_LOCAL_TIME_ZONE =>
        val fieldTerm = newName("timestampWithLocalZone")
        val ins =
          toLocalDateTime(literalValue.asInstanceOf[TimestampString])
            .atOffset(ZoneOffset.UTC)
            .toInstant
        val ts = TimestampData.fromInstant(ins)
        val fieldTimestampWithLocalZone =
          s"""
             |$TIMESTAMP_DATA $fieldTerm =
             |  $TIMESTAMP_DATA.fromEpochMillis(${ts.getMillisecond}L, ${ts.getNanoOfMillisecond});
           """.stripMargin
        ctx.addReusableMember(fieldTimestampWithLocalZone)
        generateNonNullLiteral(literalType, fieldTerm, literalValue)

      case INTERVAL_YEAR_MONTH =>
        val decimal = BigDecimal(literalValue.asInstanceOf[JBigDecimal])
        if (decimal.isValidInt) {
          generateNonNullLiteral(literalType, decimal.intValue().toString, decimal.intValue())
        } else {
          throw new CodeGenException(
            s"Decimal '$decimal' can not be converted to interval of months.")
        }

      case INTERVAL_DAY_TIME =>
        val decimal = BigDecimal(literalValue.asInstanceOf[JBigDecimal])
        if (decimal.isValidLong) {
          generateNonNullLiteral(
            literalType,
            decimal.longValue().toString + "L",
            decimal.longValue())
        } else {
          throw new CodeGenException(
            s"Decimal '$decimal' can not be converted to interval of milliseconds.")
        }

      case DISTINCT_TYPE =>
        generateLiteral(ctx, literalType.asInstanceOf[DistinctType].getSourceType, literalValue)

      // Symbol type for special flags e.g. TRIM's BOTH, LEADING, TRAILING
      case RAW if literalType.asInstanceOf[TypeInformationRawType[_]]
          .getTypeInformation.getTypeClass.isAssignableFrom(classOf[Enum[_]]) =>
        generateSymbol(literalValue.asInstanceOf[Enum[_]])

      case SYMBOL =>
        throw new UnsupportedOperationException() // TODO support symbol?

      case ARRAY | MULTISET | MAP | ROW | STRUCTURED_TYPE | NULL | UNRESOLVED =>
        throw new CodeGenException(s"Type not supported: $literalType")
    }
  }