diff --git a/docs/sql-ref-literals.md b/docs/sql-ref-literals.md index b83f7f0a97c24..3dbed846d40b8 100644 --- a/docs/sql-ref-literals.md +++ b/docs/sql-ref-literals.md @@ -219,6 +219,11 @@ double literals: decimal_digits { D | exponent [ D ] } | digit [ ... ] { exponent [ D ] | [ exponent ] D } ``` +float literals: +```sql +decimal_digits { F | exponent [ F ] } | digit [ ... ] { exponent [ F ] | [ exponent ] F } +``` + While decimal_digits is defined as ```sql [ + | - ] { digit [ ... ] . [ digit [ ... ] ] | . digit [ ... ] } @@ -239,6 +244,10 @@ E [ + | - ] digit [ ... ] Case insensitive, indicates `DOUBLE`, which is an 8-byte double-precision floating point number. +* **F** + + Case insensitive, indicates `FLOAT`, which is a 4-byte single-precision floating point number. + * **BD** Case insensitive, indicates `DECIMAL`, with the total number of digits as precision and the number of digits to right of decimal point as scale. diff --git a/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4 b/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4 index 691fde8d48f94..0e278edf97616 100644 --- a/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4 +++ b/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4 @@ -988,6 +988,7 @@ number | MINUS? SMALLINT_LITERAL #smallIntLiteral | MINUS? TINYINT_LITERAL #tinyIntLiteral | MINUS? DOUBLE_LITERAL #doubleLiteral + | MINUS? FLOAT_LITERAL #floatLiteral | MINUS? BIGDECIMAL_LITERAL #bigDecimalLiteral ; @@ -1776,6 +1777,11 @@ DECIMAL_VALUE : DECIMAL_DIGITS {isValidDecimal()}? ; +FLOAT_LITERAL + : DIGIT+ EXPONENT? 'F' + | DECIMAL_DIGITS EXPONENT? 'F' {isValidDecimal()}? + ; + DOUBLE_LITERAL : DIGIT+ EXPONENT? 'D' | DECIMAL_DIGITS EXPONENT? 'D' {isValidDecimal()}? diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala index d08bcb1420176..acb16e98a3fb8 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala @@ -2030,6 +2030,15 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging Long.MinValue, Long.MaxValue, LongType.simpleString)(_.toLong) } + /** + * Create a Float Literal expression. + */ + override def visitFloatLiteral(ctx: FloatLiteralContext): Literal = { + val rawStrippedQualifier = ctx.getText.substring(0, ctx.getText.length - 1) + numericLiteral(ctx, rawStrippedQualifier, + Float.MinValue, Float.MaxValue, FloatType.simpleString)(_.toFloat) + } + /** * Create a Double Literal expression. */ diff --git a/sql/core/src/test/resources/sql-tests/inputs/literals.sql b/sql/core/src/test/resources/sql-tests/inputs/literals.sql index 108cfd766af2c..9f0eefc16a8cd 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/literals.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/literals.sql @@ -45,6 +45,11 @@ select 9223372036854775808, -9223372036854775809; select 1234567890123456789012345678901234567890; select 1234567890123456789012345678901234567890.0; +-- float +select 1F, 1.2F, .10f, 0.10f; +select -1F, -1.2F, -.10F, -0.10F; +select -3.4028235E39f; + -- double select 1D, 1.2D, 1e10, 1.5e5, .10D, 0.10D, .1e5, .9e+2, 0.9e+2, 900e-1, 9.e+1; select -1D, -1.2D, -1e10, -1.5e5, -.10D, -0.10D, -.1e5; @@ -55,6 +60,7 @@ select 1E309, -1E309; -- decimal parsing select 0.3, -0.8, .5, -.18, 0.1111, .1111; +select 0.3 F, 0.4 D, 0.5 BD; -- super large scientific notation double literals should still be valid doubles select 123456789012345678901234567890123456789e10d, 123456789012345678901234567890123456789.1e10d; diff --git a/sql/core/src/test/resources/sql-tests/results/ansi/literals.sql.out b/sql/core/src/test/resources/sql-tests/results/ansi/literals.sql.out index f6720f6c5faa4..ea74bb7175e96 100644 --- a/sql/core/src/test/resources/sql-tests/results/ansi/literals.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/ansi/literals.sql.out @@ -1,5 +1,5 @@ -- Automatically generated by SQLQueryTestSuite --- Number of queries: 50 +-- Number of queries: 54 -- !query @@ -164,6 +164,36 @@ decimal can only support precision up to 38 select 1234567890123456789012345678901234567890.0 +-- !query +select 1F, 1.2F, .10f, 0.10f +-- !query schema +struct<1.0:float,1.2:float,0.1:float,0.1:float> +-- !query output +1.0 1.2 0.1 0.1 + + +-- !query +select -1F, -1.2F, -.10F, -0.10F +-- !query schema +struct<-1.0:float,-1.2:float,-0.1:float,-0.1:float> +-- !query output +-1.0 -1.2 -0.1 -0.1 + + +-- !query +select -3.4028235E39f +-- !query schema +struct<> +-- !query output +org.apache.spark.sql.catalyst.parser.ParseException + +Numeric literal -3.4028235E39 does not fit in range [-3.4028234663852886E+38, 3.4028234663852886E+38] for type float(line 1, pos 7) + +== SQL == +select -3.4028235E39f +-------^^^ + + -- !query select 1D, 1.2D, 1e10, 1.5e5, .10D, 0.10D, .1e5, .9e+2, 0.9e+2, 900e-1, 9.e+1 -- !query schema @@ -216,6 +246,14 @@ struct<0.3:decimal(1,1),-0.8:decimal(1,1),0.5:decimal(1,1),-0.18:decimal(2,2),0. 0.3 -0.8 0.5 -0.18 0.1111 0.1111 +-- !query +select 0.3 F, 0.4 D, 0.5 BD +-- !query schema +struct +-- !query output +0.3 0.4 0.5 + + -- !query select 123456789012345678901234567890123456789e10d, 123456789012345678901234567890123456789.1e10d -- !query schema diff --git a/sql/core/src/test/resources/sql-tests/results/literals.sql.out b/sql/core/src/test/resources/sql-tests/results/literals.sql.out index f6720f6c5faa4..ea74bb7175e96 100644 --- a/sql/core/src/test/resources/sql-tests/results/literals.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/literals.sql.out @@ -1,5 +1,5 @@ -- Automatically generated by SQLQueryTestSuite --- Number of queries: 50 +-- Number of queries: 54 -- !query @@ -164,6 +164,36 @@ decimal can only support precision up to 38 select 1234567890123456789012345678901234567890.0 +-- !query +select 1F, 1.2F, .10f, 0.10f +-- !query schema +struct<1.0:float,1.2:float,0.1:float,0.1:float> +-- !query output +1.0 1.2 0.1 0.1 + + +-- !query +select -1F, -1.2F, -.10F, -0.10F +-- !query schema +struct<-1.0:float,-1.2:float,-0.1:float,-0.1:float> +-- !query output +-1.0 -1.2 -0.1 -0.1 + + +-- !query +select -3.4028235E39f +-- !query schema +struct<> +-- !query output +org.apache.spark.sql.catalyst.parser.ParseException + +Numeric literal -3.4028235E39 does not fit in range [-3.4028234663852886E+38, 3.4028234663852886E+38] for type float(line 1, pos 7) + +== SQL == +select -3.4028235E39f +-------^^^ + + -- !query select 1D, 1.2D, 1e10, 1.5e5, .10D, 0.10D, .1e5, .9e+2, 0.9e+2, 900e-1, 9.e+1 -- !query schema @@ -216,6 +246,14 @@ struct<0.3:decimal(1,1),-0.8:decimal(1,1),0.5:decimal(1,1),-0.18:decimal(2,2),0. 0.3 -0.8 0.5 -0.18 0.1111 0.1111 +-- !query +select 0.3 F, 0.4 D, 0.5 BD +-- !query schema +struct +-- !query output +0.3 0.4 0.5 + + -- !query select 123456789012345678901234567890123456789e10d, 123456789012345678901234567890123456789.1e10d -- !query schema