[ASTERIXDB-2356][SQL] Syntax error when parsing CASE expression
- user model changes: no
- storage format changes: no
- interface changes: no
Details:
- Move CASE expression from Expression production to PrimaryExpr
Change-Id: Ia9ded0d7a20aaa9cd81240821f5b903f262b0b6a
Reviewed-on: https://asterix-gerrit.ics.uci.edu/2571
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Taewoo Kim <wangsaeu@gmail.com>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_08/case_08.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_08/case_08.1.query.sqlpp
new file mode 100644
index 0000000..60229d5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_08/case_08.1.query.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+SELECT
+ CASE WHEN get_year(current_date()) > 0 THEN "abc" ELSE "def" END LIKE "a%" as v1,
+ ( CASE WHEN get_year(current_date()) > 0 THEN "abc" ELSE "def" END ) LIKE "a%" as v2,
+ [ CASE WHEN get_year(current_date()) > 0 THEN "abc" ELSE "def" END LIKE "a%" ] as v3
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_08/case_08.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_08/case_08.1.adm
new file mode 100644
index 0000000..8b095a8
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_08/case_08.1.adm
@@ -0,0 +1 @@
+{ "v1": true, "v2": true, "v3": [ true ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index 7ba86c6..eb90276 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -3599,6 +3599,11 @@
</compilation-unit>
</test-case>
<test-case FilePath="misc">
+ <compilation-unit name="case_08">
+ <output-dir compare="Text">case_08</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="misc">
<compilation-unit name="dataset_nodegroup">
<output-dir compare="Text">dataset_nodegroup</output-dir>
</compilation-unit>
diff --git a/asterixdb/asterix-doc/src/main/markdown/sqlpp/0_toc.md b/asterixdb/asterix-doc/src/main/markdown/sqlpp/0_toc.md
index 84986ae..ebf8908 100644
--- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/0_toc.md
+++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/0_toc.md
@@ -26,7 +26,6 @@
* [Collection Operators](#Collection_operators)
* [Comparison Operators](#Comparison_operators)
* [Logical Operators](#Logical_operators)
- * [Case Expressions](#Case_expressions)
* [Quantified Expressions](#Quantified_expressions)
* [Path Expressions](#Path_expressions)
* [Primary Expressions](#Primary_expressions)
@@ -34,6 +33,7 @@
* [Variable References](#Variable_references)
* [Parenthesized Expressions](#Parenthesized_expressions)
* [Function call Expressions](#Function_call_expressions)
+ * [Case Expressions](#Case_expressions)
* [Constructors](#Constructors)
* [3. Queries](#Queries)
* [Declarations](#Declarations)
diff --git a/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md b/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md
index 5c19566..6ac6db1 100644
--- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md
+++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md
@@ -19,11 +19,10 @@
SQL++ is a highly composable expression language. Each SQL++ expression returns zero or more data model instances.
There are three major kinds of expressions in SQL++. At the topmost level, a SQL++ expression can be an
-OperatorExpression (similar to a mathematical expression), an ConditionalExpression (to choose between
-alternative values), or a QuantifiedExpression (which yields a boolean value). Each will be detailed as we
-explore the full SQL++ grammar.
+OperatorExpression (similar to a mathematical expression), or a QuantifiedExpression (which yields a boolean value).
+Each will be detailed as we explore the full SQL++ grammar.
- Expression ::= OperatorExpression | CaseExpression | QuantifiedExpression
+ Expression ::= OperatorExpression | QuantifiedExpression
Note that in the following text, words enclosed in angle brackets denote keywords that are not case-sensitive.
@@ -170,20 +169,6 @@
| NULL | NULL |
| MISSING | MISSING |
-## <a id="Case_expressions">Case Expressions</a>
-
- CaseExpression ::= SimpleCaseExpression | SearchedCaseExpression
- SimpleCaseExpression ::= <CASE> Expression ( <WHEN> Expression <THEN> Expression )+ ( <ELSE> Expression )? <END>
- SearchedCaseExpression ::= <CASE> ( <WHEN> Expression <THEN> Expression )+ ( <ELSE> Expression )? <END>
-
-In a simple `CASE` expression, the query evaluator searches for the first `WHEN` ... `THEN` pair in which the `WHEN` expression is equal to the expression following `CASE` and returns the expression following `THEN`. If none of the `WHEN` ... `THEN` pairs meet this condition, and an `ELSE` branch exists, it returns the `ELSE` expression. Otherwise, `NULL` is returned.
-
-In a searched CASE expression, the query evaluator searches from left to right until it finds a `WHEN` expression that is evaluated to `TRUE`, and then returns its corresponding `THEN` expression. If no condition is found to be `TRUE`, and an `ELSE` branch exists, it returns the `ELSE` expression. Otherwise, it returns `NULL`.
-
-The following example illustrates the form of a case expression.
-##### Example
-
- CASE (2 < 3) WHEN true THEN "yes" ELSE "no" END
## <a id="Quantified_expressions">Quantified Expressions</a>
@@ -241,11 +226,13 @@
| VariableReference
| ParenthesizedExpression
| FunctionCallExpression
+ | CaseExpression
| Constructor
The most basic building block for any SQL++ expression is PrimaryExpression. This can be a simple literal (constant)
-value, a reference to a query variable that is in scope, a parenthesized expression, a function call, or a newly
-constructed instance of the data model (such as a newly constructed object, array, or multiset of data model instances).
+value, a reference to a query variable that is in scope, a parenthesized expression, a function call, a conditional
+(case) expression, or a newly constructed instance of the data model (such as a newly constructed object, array,
+or multiset of data model instances).
## <a id="Literals">Literals</a>
@@ -361,6 +348,22 @@
length('a string')
+## <a id="Case_expressions">Case Expressions</a>
+
+ CaseExpression ::= SimpleCaseExpression | SearchedCaseExpression
+ SimpleCaseExpression ::= <CASE> Expression ( <WHEN> Expression <THEN> Expression )+ ( <ELSE> Expression )? <END>
+ SearchedCaseExpression ::= <CASE> ( <WHEN> Expression <THEN> Expression )+ ( <ELSE> Expression )? <END>
+
+In a simple `CASE` expression, the query evaluator searches for the first `WHEN` ... `THEN` pair in which the `WHEN` expression is equal to the expression following `CASE` and returns the expression following `THEN`. If none of the `WHEN` ... `THEN` pairs meet this condition, and an `ELSE` branch exists, it returns the `ELSE` expression. Otherwise, `NULL` is returned.
+
+In a searched CASE expression, the query evaluator searches from left to right until it finds a `WHEN` expression that is evaluated to `TRUE`, and then returns its corresponding `THEN` expression. If no condition is found to be `TRUE`, and an `ELSE` branch exists, it returns the `ELSE` expression. Otherwise, it returns `NULL`.
+
+The following example illustrates the form of a case expression.
+
+##### Example
+
+ CASE (2 < 3) WHEN true THEN "yes" ELSE "no" END
+
### <a id="Constructors">Constructors</a>
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 7f9149d..5ca88a8 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -1789,7 +1789,6 @@
(
LOOKAHEAD(2)
expr = OperatorExpr()
- | expr = CaseExpr()
| expr = QuantifiedExpression()
)
{
@@ -2305,6 +2304,7 @@
{
( LOOKAHEAD(4)
expr = FunctionCallExpr()
+ | expr = CaseExpr()
| expr = Literal()
| expr = VariableRef()
| expr = ListConstructor()