Skip to content

Commit

Permalink
[feature] support sql_mode MODE_DOUBLE_LITERAL (StarRocks#7240)
Browse files Browse the repository at this point in the history
For accuracy, in the past our literal would give preference to the decimal type,
but in some cases we don't care about a precise value, so we provide a new SQL_MODE that gives preference to the float/double type for literals
  • Loading branch information
stdpain authored Jun 16, 2022
1 parent a6b3b20 commit 2552309
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
4 changes: 3 additions & 1 deletion fe/fe-core/src/main/java/com/starrocks/qe/SqlModeHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public class SqlModeHelper {
public static final long MODE_ONLY_FULL_GROUP_BY = 1L << 5;
public static final long MODE_NO_UNSIGNED_SUBTRACTION = 1L << 6;
public static final long MODE_NO_DIR_IN_CREATE = 1L << 7;
public static final long MODE_DOUBLE_LITERAL = 1L << 17;
public static final long MODE_ANSI = 1L << 18;
public static final long MODE_NO_AUTO_VALUE_ON_ZERO = 1L << 19;
public static final long MODE_NO_BACKSLASH_ESCAPES = 1L << 20;
Expand All @@ -78,7 +79,7 @@ public class SqlModeHelper {
public static final long MODE_ALLOWED_MASK =
(MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
MODE_IGNORE_SPACE | MODE_NOT_USED | MODE_ONLY_FULL_GROUP_BY |
MODE_NO_UNSIGNED_SUBTRACTION | MODE_NO_DIR_IN_CREATE |
MODE_NO_UNSIGNED_SUBTRACTION | MODE_NO_DIR_IN_CREATE | MODE_DOUBLE_LITERAL |
MODE_NO_AUTO_VALUE_ON_ZERO | MODE_NO_BACKSLASH_ESCAPES |
MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES | MODE_NO_ZERO_IN_DATE |
MODE_NO_ZERO_DATE | MODE_INVALID_DATES | MODE_ERROR_FOR_DIVISION_BY_ZERO |
Expand All @@ -99,6 +100,7 @@ public class SqlModeHelper {
sqlModeSet.put("ONLY_FULL_GROUP_BY", MODE_ONLY_FULL_GROUP_BY);
sqlModeSet.put("NO_UNSIGNED_SUBTRACTION", MODE_NO_UNSIGNED_SUBTRACTION);
sqlModeSet.put("NO_DIR_IN_CREATE", MODE_NO_DIR_IN_CREATE);
sqlModeSet.put("MODE_DOUBLE_LITERAL", MODE_DOUBLE_LITERAL);
sqlModeSet.put("ANSI", MODE_ANSI);
sqlModeSet.put("NO_AUTO_VALUE_ON_ZERO", MODE_NO_AUTO_VALUE_ON_ZERO);
sqlModeSet.put("NO_BACKSLASH_ESCAPES", MODE_NO_BACKSLASH_ESCAPES);
Expand Down
23 changes: 16 additions & 7 deletions fe/fe-core/src/main/java/com/starrocks/sql/parser/AstBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2203,14 +2203,19 @@ public ParseNode visitIntegerValue(StarRocksParser.IntegerValueContext context)
@Override
public ParseNode visitDoubleValue(StarRocksParser.DoubleValueContext context) {
try {
BigDecimal decimal = new BigDecimal(context.getText());
int precision = DecimalLiteral.getRealPrecision(decimal);
int scale = DecimalLiteral.getRealScale(decimal);
int integerPartWidth = precision - scale;
if (integerPartWidth > 38) {
if (SqlModeHelper.check(sqlMode, SqlModeHelper.MODE_DOUBLE_LITERAL)) {
return new FloatLiteral(context.getText());
} else {
BigDecimal decimal = new BigDecimal(context.getText());
int precision = DecimalLiteral.getRealPrecision(decimal);
int scale = DecimalLiteral.getRealScale(decimal);
int integerPartWidth = precision - scale;
if (integerPartWidth > 38) {
return new FloatLiteral(context.getText());
}
return new DecimalLiteral(decimal);
}
return new DecimalLiteral(decimal);

} catch (AnalysisException | NumberFormatException e) {
throw new ParsingException(e.getMessage());
}
Expand All @@ -2219,7 +2224,11 @@ public ParseNode visitDoubleValue(StarRocksParser.DoubleValueContext context) {
@Override
public ParseNode visitDecimalValue(StarRocksParser.DecimalValueContext context) {
try {
return new DecimalLiteral(context.getText());
if (SqlModeHelper.check(sqlMode, SqlModeHelper.MODE_DOUBLE_LITERAL)) {
return new FloatLiteral(context.getText());
} else {
return new DecimalLiteral(context.getText());
}
} catch (AnalysisException e) {
throw new ParsingException(e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import com.starrocks.common.Config;
import com.starrocks.qe.ConnectContext;
import com.starrocks.qe.SqlModeHelper;
import com.starrocks.utframe.StarRocksAssert;
import com.starrocks.utframe.UtFrameUtils;
import org.junit.Assert;
Expand Down Expand Up @@ -467,5 +468,21 @@ public void testDecimalNullableProperties() throws Exception {
System.out.println("plan = " + plan);
Assert.assertTrue(plan.contains("round[(cast([2: dec_18_0, DECIMAL64(18,0), false] as DECIMAL128(18,0))); args: DECIMAL128; result: DECIMAL128(38,0); args nullable: true; result nullable: true]"));
}

@Test
public void testDoubleLiteralMul() throws Exception {
String sql;
String plan;
sql = "select 123456789000000000000000000000000000.00 * 123456789.123456789 * 123456789.123456789;";
final long sqlMode = ctx.getSessionVariable().getSqlMode();
final long code = SqlModeHelper.encode("MODE_DOUBLE_LITERAL");
ctx.getSessionVariable().setSqlMode(code|sqlMode);
plan = UtFrameUtils.getVerboseFragmentPlan(ctx, sql);
Assert.assertTrue(plan.contains(" | 2 <-> 1.8816763755525075E51"));
ctx.getSessionVariable().setSqlMode(sqlMode);
plan = UtFrameUtils.getVerboseFragmentPlan(ctx, sql);
Assert.assertTrue(plan.contains(" | 2 <-> 123456789000000000000000000000000000 * 123456789.123456789 * 123456789.123456789"));
}

}

0 comments on commit 2552309

Please sign in to comment.