Skip to content

Commit fda100f

Browse files
committed
Add BigDecimal literal to parser.
1 parent 3e4c7db commit fda100f

7 files changed

Lines changed: 139 additions & 83 deletions

File tree

sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,7 @@ number
633633
| MINUS? SMALLINT_LITERAL #smallIntLiteral
634634
| MINUS? TINYINT_LITERAL #tinyIntLiteral
635635
| MINUS? DOUBLE_LITERAL #doubleLiteral
636+
| MINUS? BIGDECIMAL_LITERAL #bigDecimalLiteral
636637
;
637638

638639
nonReserved
@@ -928,6 +929,11 @@ DOUBLE_LITERAL
928929
(INTEGER_VALUE | DECIMAL_VALUE | SCIENTIFIC_DECIMAL_VALUE) 'D'
929930
;
930931

932+
BIGDECIMAL_LITERAL
933+
:
934+
(INTEGER_VALUE | DECIMAL_VALUE | SCIENTIFIC_DECIMAL_VALUE) 'BD'
935+
;
936+
931937
IDENTIFIER
932938
: (LETTER | DIGIT | '_')+
933939
;

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/literals.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ case class Literal (value: Any, dataType: DataType) extends LeafExpression with
266266
case Double.NegativeInfinity => s"CAST('-Infinity' AS ${DoubleType.sql})"
267267
case _ => v + "D"
268268
}
269-
case (v: Decimal, t: DecimalType) => s"CAST($v AS ${t.sql})"
269+
case (v: Decimal, t: DecimalType) => v + "BD"
270270
case (v: Int, DateType) => s"DATE '${DateTimeUtils.toJavaDate(v)}'"
271271
case (v: Long, TimestampType) => s"TIMESTAMP('${DateTimeUtils.toJavaTimestamp(v)}')"
272272
case _ => value.toString

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ import org.antlr.v4.runtime.{ParserRuleContext, Token}
2626
import org.antlr.v4.runtime.tree.{ParseTree, RuleNode, TerminalNode}
2727

2828
import org.apache.spark.internal.Logging
29-
import org.apache.spark.sql.catalyst.{FunctionIdentifier, InternalRow, TableIdentifier}
29+
import org.apache.spark.sql.AnalysisException
30+
import org.apache.spark.sql.catalyst.{FunctionIdentifier, TableIdentifier}
3031
import org.apache.spark.sql.catalyst.analysis._
3132
import org.apache.spark.sql.catalyst.expressions._
3233
import org.apache.spark.sql.catalyst.parser.SqlBaseParser._
@@ -1323,6 +1324,19 @@ class AstBuilder extends SqlBaseBaseVisitor[AnyRef] with Logging {
13231324
numericLiteral(ctx, Double.MinValue, Double.MaxValue, DoubleType.simpleString)(_.toDouble)
13241325
}
13251326

1327+
/**
1328+
* Create a BigDecimal Literal expression.
1329+
*/
1330+
override def visitBigDecimalLiteral(ctx: BigDecimalLiteralContext): Literal = {
1331+
val raw = ctx.getText.substring(0, ctx.getText.length - 2)
1332+
try {
1333+
Literal(BigDecimal(raw).underlying())
1334+
} catch {
1335+
case e: AnalysisException =>
1336+
throw new ParseException(e.message, ctx)
1337+
}
1338+
}
1339+
13261340
/**
13271341
* Create a String literal expression.
13281342
*/

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/ExpressionParserSuite.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,13 @@ class ExpressionParserSuite extends PlanTest {
392392
intercept("1.8E308D", s"does not fit in range")
393393
// TODO we need to figure out if we should throw an exception here!
394394
assertEqual("1E309", Literal(Double.PositiveInfinity))
395+
396+
// BigDecimal Literal
397+
assertEqual("90912830918230182310293801923652346786BD",
398+
Literal(BigDecimal("90912830918230182310293801923652346786").underlying()))
399+
assertEqual("123.0E-28BD", Literal(BigDecimal("123.0E-28").underlying()))
400+
assertEqual("123.08BD", Literal(BigDecimal("123.08").underlying()))
401+
intercept("1.20E-38BD", "DecimalType can only support precision up to 38")
395402
}
396403

397404
test("strings") {

sql/core/src/test/resources/sql-tests/inputs/literals.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ select 9223372036854775807L, -9223372036854775808L;
2727
-- out of range long
2828
select 9223372036854775808L;
2929

30+
-- big decimal parsing
31+
select 90912830918230182310293801923652346786BD, 123.0E-28BD, 123.08BD;
32+
33+
-- out of range big decimal
34+
select 1.20E-38BD;
35+
3036
-- integral parsing
3137

3238
-- parse int

0 commit comments

Comments
 (0)