You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by dl...@apache.org on 2019/06/05 15:45:28 UTC

[asterixdb] branch master updated: [NO ISSUE][SQLPP] Optional field name in object constructor

This is an automated email from the ASF dual-hosted git repository.

dlych pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new cdcb923  [NO ISSUE][SQLPP] Optional field name in object constructor
cdcb923 is described below

commit cdcb9235ae6d1e6d66d4c6d57de5098090e3996c
Author: Dmitry Lychagin <dm...@couchbase.com>
AuthorDate: Tue Jun 4 13:27:03 2019 -0700

    [NO ISSUE][SQLPP] Optional field name in object constructor
    
    - user model changes: yes
    - storage format changes: no
    - interface changes: no
    
    Details:
    - Allow field name to be optional in object constructors.
      If missing then it will be inferred from a field value
      expression in a manner similar to unnamed projections.
    - Add documentation and testcases
    
    Change-Id: I0dfba8f8137f88d934a5be8ffb5fbc1c1db0bb58
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/3424
    Sonar-Qube: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Ali Alsuliman <al...@gmail.com>
---
 .../queries_sqlpp/objects/ObjectsQueries.xml       | 11 +++++++++
 .../no_fieldname_constr.1.query.sqlpp              | 27 ++++++++++++++++++++++
 .../no_fieldname_constr.2.query.sqlpp              | 27 ++++++++++++++++++++++
 .../no_fieldname_constr_negative.1.query.sqlpp     | 26 +++++++++++++++++++++
 .../no_fieldname_constr/no_fieldname_constr.1.adm  |  4 ++++
 .../no_fieldname_constr/no_fieldname_constr.2.adm  |  2 ++
 .../asterix-doc/src/main/markdown/sqlpp/2_expr.md  | 24 ++++++++++++++++++-
 .../asterix-lang-sqlpp/src/main/javacc/SQLPP.jj    | 15 +++++++++---
 8 files changed, 132 insertions(+), 4 deletions(-)

diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml
index b91a5ef..e0114fc 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml
@@ -103,6 +103,17 @@
     </compilation-unit>
   </test-case>
   <test-case FilePath="objects">
+    <compilation-unit name="no_fieldname_constr">
+      <output-dir compare="Text">no_fieldname_constr</output-dir>
+    </compilation-unit>
+  </test-case>
+  <test-case FilePath="objects">
+    <compilation-unit name="no_fieldname_constr_negative">
+      <output-dir compare="Text">no_fieldname_constr</output-dir>
+      <expected-error>ASX1001: Syntax error: Cannot infer field name</expected-error>
+    </compilation-unit>
+  </test-case>
+  <test-case FilePath="objects">
     <compilation-unit name="object_concat">
       <output-dir compare="Text">object_concat</output-dir>
     </compilation-unit>
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/no_fieldname_constr/no_fieldname_constr.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/no_fieldname_constr/no_fieldname_constr.1.query.sqlpp
new file mode 100644
index 0000000..13d9fff
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/no_fieldname_constr/no_fieldname_constr.1.query.sqlpp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+/*
+ * Description  : Testing object constructor without field names
+ * Expected Res : Success
+ */
+
+ from range(1, 2) x, range(3, 4) y
+ select value { x, y }
+ order by x, y
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/no_fieldname_constr/no_fieldname_constr.2.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/no_fieldname_constr/no_fieldname_constr.2.query.sqlpp
new file mode 100644
index 0000000..7ffab82
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/no_fieldname_constr/no_fieldname_constr.2.query.sqlpp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+/*
+ * Description  : Testing object constructor without field names
+ * Expected Res : Success
+ */
+
+ from (from range(1, 2) x select x) y
+ select value { y.x }
+ order by y.x
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/no_fieldname_constr_negative/no_fieldname_constr_negative.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/no_fieldname_constr_negative/no_fieldname_constr_negative.1.query.sqlpp
new file mode 100644
index 0000000..edcefcf
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/no_fieldname_constr_negative/no_fieldname_constr_negative.1.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/*
+ * Description  : Testing object constructor without field names
+ * Expected Res : Failure: Cannot infer field name
+ */
+
+ from range(1, 2) x
+ select value { x + 1 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/no_fieldname_constr/no_fieldname_constr.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/no_fieldname_constr/no_fieldname_constr.1.adm
new file mode 100644
index 0000000..ffd1e6c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/no_fieldname_constr/no_fieldname_constr.1.adm
@@ -0,0 +1,4 @@
+{ "x": 1, "y": 3 }
+{ "x": 1, "y": 4 }
+{ "x": 2, "y": 3 }
+{ "x": 2, "y": 4 }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/no_fieldname_constr/no_fieldname_constr.2.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/no_fieldname_constr/no_fieldname_constr.2.adm
new file mode 100644
index 0000000..1379125
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/no_fieldname_constr/no_fieldname_constr.2.adm
@@ -0,0 +1,2 @@
+{ "x": 1 }
+{ "x": 2 }
\ No newline at end of file
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 ef19dca..efc2a86 100644
--- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md
+++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md
@@ -423,7 +423,7 @@ The following example illustrates the form of a case expression.
     ArrayConstructor         ::= "[" ( Expression ( "," Expression )* )? "]"
     MultisetConstructor      ::= "{{" ( Expression ( "," Expression )* )? "}}"
     ObjectConstructor        ::= "{" ( FieldBinding ( "," FieldBinding )* )? "}"
-    FieldBinding             ::= Expression ":" Expression
+    FieldBinding             ::= Expression ( ":" Expression )?
 
 A major feature of the query language is its ability to construct new data model instances. This is accomplished using
 its constructors for each of the model's complex object structures, namely arrays, multisets, and objects.
@@ -450,3 +450,25 @@ duplicate field errors will be raised if they are not distinct.
       'project members': [ 'vinayakb', 'dtabass', 'chenli', 'tsotras', 'tillw' ]
     }
 
+
+If only one expression is specified instead of the field-name/field-value pair in an object constructor then this
+expression is supposed to provide the field value. The field name is then automatically generated based on the 
+kind of the value expression:
+
+  * If it is a variable reference expression then generated field name is the name of that variable.
+  * If it is a field access expression then generated field name is the last identifier in that expression.
+  * For all other cases, a compilation error will be raised.
+ 
+##### Example
+
+    SELECT VALUE { user.alias, user.userSince }
+    FROM GleambookUsers user
+    WHERE user.id = 1;
+
+This query outputs:
+
+    [ {
+        "alias": "Margarita",
+        "userSince": "2012-08-20T10:10:00"
+    } ]
+
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 6f63441..73612ab 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -2690,12 +2690,21 @@ RecordConstructor RecordConstructor() throws ParseException:
 
 FieldBinding FieldBinding() throws ParseException:
 {
-  Expression left, right;
+  Expression left, right = null;
 }
 {
-  left = Expression() <COLON> right = Expression()
+  left = Expression() ( <COLON> right = Expression() )?
   {
-    return new FieldBinding(left, right);
+    if (right == null) {
+        String generatedIdentifier = ExpressionToVariableUtil.getGeneratedIdentifier(left, false);
+        if (generatedIdentifier == null) {
+          throw new SqlppParseException(getSourceLocation(token), "Cannot infer field name");
+        }
+        String generatedName = SqlppVariableUtil.toUserDefinedName(generatedIdentifier);
+        return new FieldBinding(new LiteralExpr(new StringLiteral(generatedName)), left);
+    } else {
+      return new FieldBinding(left, right);
+    }
   }
 }