lowka commented on code in PR #3222:
URL: https://github.com/apache/ignite-3/pull/3222#discussion_r1492370137


##########
modules/sql-engine/src/main/java/org/apache/ignite/internal/sql/engine/prepare/ddl/DdlSqlToCommandConverter.java:
##########
@@ -824,60 +842,142 @@ private Type convertIndexType(IgniteSqlIndexType type) {
     /**
      * Creates a value of required type from the literal.
      */
-    private static @Nullable Object fromLiteral(ColumnType columnType, 
SqlLiteral literal) {
+    private static @Nullable Object fromLiteral(ColumnType columnType, 
SqlLiteral literal, int precision) {
         if (literal.getValue() == null) {
             return null;
         }
 
         try {
             switch (columnType) {
-                case STRING:
-                    return literal.getValueAs(String.class);
+                case PERIOD: {
+                    if (!(literal instanceof SqlCharStringLiteral) && 
!(literal instanceof SqlIntervalLiteral)) {
+                        throw new SqlException(STMT_VALIDATION_ERR,
+                                "Default expression is of numeric type and 
can`t be applied to interval type");
+                    }
+                    String strValue = 
Objects.requireNonNull(literal.toValue());
+                    // reject possible exponent
+                    if (strValue.toLowerCase(Locale.ROOT).contains("e")) {
+                        throw new SqlException(STMT_VALIDATION_ERR,
+                                "Invalid input syntax for interval type: " + 
literal.toValue());
+                    }
+                    literal = SqlLiteral.createExactNumeric(strValue, 
literal.getParserPosition());
+                    int val = convertToIntExact(literal.longValue(false));
+                    return fromInternal(val, Period.class);
+                }
+                case DURATION: {
+                    if (!(literal instanceof SqlCharStringLiteral) && 
!(literal instanceof SqlIntervalLiteral)) {
+                        throw new SqlException(STMT_VALIDATION_ERR,
+                                "Default expression is of numeric type and 
can`t be applied to interval type");
+                    }
+                    String strValue = 
Objects.requireNonNull(literal.toValue());
+                    // reject possible exponent
+                    if (strValue.toLowerCase(Locale.ROOT).contains("e")) {
+                        throw new SqlException(STMT_VALIDATION_ERR,
+                                "Invalid input syntax for interval type: " + 
literal.toValue());
+                    }
+                    literal = SqlLiteral.createExactNumeric(strValue, 
literal.getParserPosition());
+                    long val = 
convertToLongExact(Objects.requireNonNull(literal.bigDecimalValue()));
+                    return fromInternal(val, Duration.class);
+                }
+                case STRING: {
+                    String val = literal.toValue();
+                    // varchar without limitation
+                    if (precision != PRECISION_NOT_SPECIFIED && 
Objects.requireNonNull(val).length() > precision) {
+                        throw new SqlException(STMT_VALIDATION_ERR,
+                                format("Value too long for type 
character({})", precision));
+                    }
+                    return val;
+                }
+                case UUID:
+                    return 
UUID.fromString(Objects.requireNonNull(literal.toValue()));
                 case DATE: {
-                    SqlLiteral literal0 = ((SqlUnknownLiteral) 
literal).resolve(SqlTypeName.DATE);
-                    return 
LocalDate.ofEpochDay(literal0.getValueAs(DateString.class).getDaysSinceEpoch());
+                    try {
+                        literal = 
SqlParserUtil.parseDateLiteral(literal.getValueAs(String.class), 
literal.getParserPosition());
+                        int val = 
literal.getValueAs(DateString.class).getDaysSinceEpoch();
+                        return fromInternal(val, LocalDate.class);
+                    } catch (CalciteContextException e) {
+                        literal = 
SqlParserUtil.parseTimestampLiteral(literal.getValueAs(String.class), 
literal.getParserPosition());
+                        TimestampString tsString = 
literal.getValueAs(TimestampString.class);
+                        int val = 
convertToIntExact(TimeUnit.MILLISECONDS.toDays(tsString.getMillisSinceEpoch()));
+                        return fromInternal(val, LocalDate.class);
+                    }
                 }
                 case TIME: {
-                    SqlLiteral literal0 = ((SqlUnknownLiteral) 
literal).resolve(SqlTypeName.TIME);
-                    return 
LocalTime.ofNanoOfDay(TimeUnit.MILLISECONDS.toNanos(literal0.getValueAs(TimeString.class).getMillisOfDay()));
+                    literal = 
SqlParserUtil.parseTimeLiteral(literal.getValueAs(String.class), 
literal.getParserPosition());
+                    int val = 
literal.getValueAs(TimeString.class).getMillisOfDay();
+                    return fromInternal(val, LocalTime.class);
                 }
                 case DATETIME: {
-                    SqlLiteral literal0 = ((SqlUnknownLiteral) 
literal).resolve(SqlTypeName.TIMESTAMP);
-                    var tsString = literal0.getValueAs(TimestampString.class);
-
-                    return LocalDateTime.ofEpochSecond(
-                            
TimeUnit.MILLISECONDS.toSeconds(tsString.getMillisSinceEpoch()),
-                            (int) 
(TimeUnit.MILLISECONDS.toNanos(tsString.getMillisSinceEpoch() % 1000)),
-                            ZoneOffset.UTC
-                    );
+                    literal = 
SqlParserUtil.parseTimestampLiteral(literal.getValueAs(String.class), 
literal.getParserPosition());
+                    var tsString = literal.getValueAs(TimestampString.class);
+
+                    return fromInternal(tsString.getMillisSinceEpoch(), 
LocalDateTime.class);
                 }
                 case TIMESTAMP:
                     // TODO: IGNITE-17376
                     throw new UnsupportedOperationException("Type is not 
supported: " + columnType);
-                case INT32:
-                    return literal.getValueAs(Integer.class);
-                case INT64:
-                    return literal.getValueAs(Long.class);
-                case INT16:
-                    return literal.getValueAs(Short.class);
-                case INT8:
-                    return literal.getValueAs(Byte.class);
+                case INT32: {
+                    acceptStringOrNumericLiteral(literal, columnType);
+                    long val = literal.longValue(false);
+                    return convertToIntExact(val);
+                }
+                case INT64: {
+                    acceptStringOrNumericLiteral(literal, columnType);
+                    BigDecimal val = literal.bigDecimalValue();
+                    return convertToLongExact(Objects.requireNonNull(val));
+                }
+                case INT16: {
+                    acceptStringOrNumericLiteral(literal, columnType);
+                    long val = literal.longValue(false);
+                    return convertToShortExact(val);
+                }
+                case INT8: {
+                    acceptStringOrNumericLiteral(literal, columnType);
+                    long val = literal.longValue(false);
+                    return convertToByteExact(val);
+                }
                 case DECIMAL:
+                    acceptStringOrNumericLiteral(literal, columnType);
                     return literal.getValueAs(BigDecimal.class);
                 case DOUBLE:
+                    acceptStringOrNumericLiteral(literal, columnType);
                     return literal.getValueAs(Double.class);
                 case FLOAT:
+                    acceptStringOrNumericLiteral(literal, columnType);
                     return literal.getValueAs(Float.class);
                 case BYTE_ARRAY:
-                    return literal.getValueAs(byte[].class);
+                    byte[] arr = literal.getValueAs(byte[].class);
+                    // varbinary without limitation
+                    if (precision != PRECISION_NOT_SPECIFIED && 
Objects.requireNonNull(arr).length > precision) {
+                        throw new SqlException(STMT_VALIDATION_ERR,
+                                format("Value too long for type binary({})", 
precision));
+                    }
+                    return arr;
                 case BOOLEAN:
-                    return literal.getValueAs(Boolean.class);
+                    String val = Objects.requireNonNull(literal.toValue());
+                    val = val.trim().toLowerCase();
+
+                    if ("true".equals(val) || "yes".equals(val) || 
"1".equals(val)) {
+                        return true;
+                    }
+
+                    if ("false".equals(val) || "no".equals(val) || 
"0".equals(val)) {

Review Comment:
   `no` `yes` are also not considered legal.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to