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 2021/10/12 17:50:54 UTC

[asterixdb] branch master updated: [NO ISSUE][COMP] Rewrite SELECT * in sql-compat mode

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 501b2ff  [NO ISSUE][COMP] Rewrite SELECT * in sql-compat mode
501b2ff is described below

commit 501b2ff594e574deebe2dd26a59c90d04c66855e
Author: Dmitry Lychagin <dm...@couchbase.com>
AuthorDate: Mon Oct 11 17:37:09 2021 -0700

    [NO ISSUE][COMP] Rewrite SELECT * in sql-compat mode
    
    - user model changes: no
    - storage format changes: no
    - interface changes: no
    
    Details:
    - In sql-compat mode rewrite SELECT * into SELECT v.*
      if there's a single variable defined in FROM clause
    - Fail if FROM clause has two or more variables
    
    Change-Id: I871398d60a328271e89842abcd95631a61dcc001
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/13647
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Dmitry Lychagin <dm...@couchbase.com>
    Reviewed-by: Ali Alsuliman <al...@gmail.com>
---
 .../SqlppExpressionToPlanTranslator.java           | 116 ++++++++++++++-------
 .../select_star_01/select_star_01.1.query.sqlpp    |  34 ++++++
 .../select_star_02_negative.1.query.sqlpp          |  33 ++++++
 .../sql-compat/select_star_01/select_star_01.1.adm |   2 +
 .../test/resources/runtimets/testsuite_sqlpp.xml   |  13 +++
 .../asterix/common/exceptions/ErrorCode.java       |   1 +
 .../src/main/resources/asx_errormsg/en.properties  |   1 +
 .../asterix/lang/sqlpp/clause/Projection.java      |   6 +-
 .../lang/sqlpp/rewrites/SqlppQueryRewriter.java    |  13 +++
 .../rewrites/visitor/SqlCompatRewriteVisitor.java  |  43 ++++++++
 .../rewrites/visitor/SqlppGroupingSetsVisitor.java |   3 +-
 .../lang/sqlpp/visitor/SqlppAstPrintVisitor.java   |   3 +
 .../sqlpp/visitor/SqlppFormatPrintVisitor.java     |   3 +
 13 files changed, 233 insertions(+), 38 deletions(-)

diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
index 48a8f4b..2dd4f96 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
@@ -778,45 +778,78 @@ public class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTransla
         Set<String> fieldNames = new HashSet<>();
 
         for (Projection projection : selectRegular.getProjections()) {
-            if (projection.varStar()) {
-                if (!fieldBindings.isEmpty()) {
-                    RecordConstructor recordConstr = new RecordConstructor(new ArrayList<>(fieldBindings));
-                    recordConstr.setSourceLocation(selectRegular.getSourceLocation());
-                    recordExprs.add(recordConstr);
-                    fieldBindings.clear();
-                }
-                Expression projectionExpr = projection.getExpression();
-                SourceLocation sourceLoc = projection.getSourceLocation();
-                CallExpr toObjectExpr = new CallExpr(new FunctionSignature(BuiltinFunctions.TO_OBJECT),
-                        Collections.singletonList(projectionExpr));
-                toObjectExpr.setSourceLocation(sourceLoc);
-                CallExpr ifMissingOrNullExpr = new CallExpr(new FunctionSignature(BuiltinFunctions.IF_MISSING_OR_NULL),
-                        Arrays.asList(toObjectExpr, new RecordConstructor(Collections.emptyList())));
-                ifMissingOrNullExpr.setSourceLocation(sourceLoc);
-                recordExprs.add(ifMissingOrNullExpr);
-            } else if (projection.star()) {
-                if (selectBlock.hasGroupbyClause()) {
-                    getGroupBindings(selectBlock.getGroupbyClause(), fieldBindings, fieldNames,
-                            SqlppExpressionToPlanTranslator::includeInSelectStar);
-                    if (selectBlock.hasLetHavingClausesAfterGroupby()) {
-                        getLetBindings(selectBlock.getLetHavingListAfterGroupby(), fieldBindings, fieldNames,
-                                SqlppExpressionToPlanTranslator::includeInSelectStar);
+            boolean everyVarStar = false;
+            switch (projection.getKind()) {
+                case VAR_STAR:
+                    if (!fieldBindings.isEmpty()) {
+                        RecordConstructor recordConstr = new RecordConstructor(new ArrayList<>(fieldBindings));
+                        recordConstr.setSourceLocation(selectRegular.getSourceLocation());
+                        recordExprs.add(recordConstr);
+                        fieldBindings.clear();
+                    }
+                    Expression expr =
+                            translateProjectVarStar(projection.getExpression(), projection.getSourceLocation());
+                    recordExprs.add(expr);
+                    break;
+                case EVERY_VAR_STAR:
+                    everyVarStar = true;
+                    // fall thru to STAR
+                case STAR:
+                    List<FieldBinding> fieldBindingsForStar;
+                    Set<String> fieldNamesForStar;
+                    if (everyVarStar) {
+                        fieldBindingsForStar = new ArrayList<>();
+                        fieldNamesForStar = new HashSet<>();
+                    } else {
+                        fieldBindingsForStar = fieldBindings;
+                        fieldNamesForStar = fieldNames;
                     }
-                } else if (selectBlock.hasFromClause()) {
-                    getFromBindings(selectBlock.getFromClause(), fieldBindings, fieldNames,
-                            SqlppExpressionToPlanTranslator::includeInSelectStar);
-                    if (selectBlock.hasLetWhereClauses()) {
-                        getLetBindings(selectBlock.getLetWhereList(), fieldBindings, fieldNames,
+                    if (selectBlock.hasGroupbyClause()) {
+                        getGroupBindings(selectBlock.getGroupbyClause(), fieldBindingsForStar, fieldNamesForStar,
+                                SqlppExpressionToPlanTranslator::includeInSelectStar);
+                        if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                            getLetBindings(selectBlock.getLetHavingListAfterGroupby(), fieldBindingsForStar,
+                                    fieldNamesForStar, SqlppExpressionToPlanTranslator::includeInSelectStar);
+                        }
+                    } else if (selectBlock.hasFromClause()) {
+                        getFromBindings(selectBlock.getFromClause(), fieldBindingsForStar, fieldNamesForStar,
+                                SqlppExpressionToPlanTranslator::includeInSelectStar);
+                        if (selectBlock.hasLetWhereClauses()) {
+                            getLetBindings(selectBlock.getLetWhereList(), fieldBindingsForStar, fieldNamesForStar,
+                                    SqlppExpressionToPlanTranslator::includeInSelectStar);
+                        }
+                    } else if (selectBlock.hasLetWhereClauses()) {
+                        getLetBindings(selectBlock.getLetWhereList(), fieldBindingsForStar, fieldNamesForStar,
                                 SqlppExpressionToPlanTranslator::includeInSelectStar);
                     }
-                } else if (selectBlock.hasLetWhereClauses()) {
-                    getLetBindings(selectBlock.getLetWhereList(), fieldBindings, fieldNames,
-                            SqlppExpressionToPlanTranslator::includeInSelectStar);
-                }
-            } else if (projection.hasName()) {
-                fieldBindings.add(getFieldBinding(projection, fieldNames));
-            } else {
-                throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, projection.getSourceLocation(), "");
+                    if (everyVarStar) {
+                        if (!fieldBindings.isEmpty()) {
+                            RecordConstructor recordConstr = new RecordConstructor(new ArrayList<>(fieldBindings));
+                            recordConstr.setSourceLocation(selectRegular.getSourceLocation());
+                            recordExprs.add(recordConstr);
+                            fieldBindings.clear();
+                        }
+                        // We currently only support EVERY_VAR_STAR over a single variable
+                        if (fieldBindingsForStar.size() > 1) {
+                            throw new CompilationException(ErrorCode.AMBIGUOUS_PROJECTION,
+                                    projection.getSourceLocation());
+                        }
+                        for (FieldBinding fieldBinding : fieldBindingsForStar) {
+                            expr = translateProjectVarStar(fieldBinding.getRightExpr(), projection.getSourceLocation());
+                            recordExprs.add(expr);
+                        }
+                    }
+                    break;
+                case NAMED_EXPR:
+                    if (!projection.hasName()) {
+                        throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE,
+                                projection.getSourceLocation(), "");
+                    }
+                    fieldBindings.add(getFieldBinding(projection, fieldNames));
+                    break;
+                default:
+                    throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, projection.getSourceLocation(),
+                            "");
             }
         }
         if (!fieldBindings.isEmpty()) {
@@ -835,6 +868,17 @@ public class SqlppExpressionToPlanTranslator extends LangExpressionToPlanTransla
         }
     }
 
+    private Expression translateProjectVarStar(Expression projectionExpr, SourceLocation sourceLoc) {
+        // var.* -> if_missing_or_null(to_object(var), {})
+        CallExpr toObjectExpr = new CallExpr(new FunctionSignature(BuiltinFunctions.TO_OBJECT),
+                Collections.singletonList(projectionExpr));
+        toObjectExpr.setSourceLocation(sourceLoc);
+        CallExpr ifMissingOrNullExpr = new CallExpr(new FunctionSignature(BuiltinFunctions.IF_MISSING_OR_NULL),
+                Arrays.asList(toObjectExpr, new RecordConstructor(Collections.emptyList())));
+        ifMissingOrNullExpr.setSourceLocation(sourceLoc);
+        return ifMissingOrNullExpr;
+    }
+
     private static boolean includeInSelectStar(VariableExpr varExpr) {
         boolean excludeFromSelectStar =
                 varExpr.hasHints() && varExpr.getHints().contains(ExcludeFromSelectStarAnnotation.INSTANCE);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/sql-compat/select_star_01/select_star_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/sql-compat/select_star_01/select_star_01.1.query.sqlpp
new file mode 100644
index 0000000..87d2207
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/sql-compat/select_star_01/select_star_01.1.query.sqlpp
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+/*
+ * Test SELECT * in sql-compat mode
+ */
+
+// requesttype=application/json
+// param sql-compat:json=true
+
+with T as (
+  select r x, -r y
+  from range(1, 2) r
+)
+
+select *
+from T t
+order by x;
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/sql-compat/select_star_02_negative/select_star_02_negative.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/sql-compat/select_star_02_negative/select_star_02_negative.1.query.sqlpp
new file mode 100644
index 0000000..c1b4824
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/sql-compat/select_star_02_negative/select_star_02_negative.1.query.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+/*
+ * Test that SELECT * fails in sql-compat mode if
+ * FROM clause has more than one variable
+ */
+
+// requesttype=application/json
+// param sql-compat:json=true
+
+with T as (
+  select r x, -r y
+  from range(1, 2) r
+)
+
+select *
+from T t1, T t2;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/sql-compat/select_star_01/select_star_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/sql-compat/select_star_01/select_star_01.1.adm
new file mode 100644
index 0000000..7c1ec37
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/sql-compat/select_star_01/select_star_01.1.adm
@@ -0,0 +1,2 @@
+{ "x": 1, "y": -1 }
+{ "x": 2, "y": -2 }
\ 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 6450a1c..facf00f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -10130,6 +10130,19 @@
       </compilation-unit>
     </test-case>
   </test-group>
+  <test-group name="sql-compat">
+    <test-case FilePath="sql-compat">
+      <compilation-unit name="select_star_01">
+        <output-dir compare="Text">select_star_01</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="sql-compat">
+      <compilation-unit name="select_star_02_negative">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1168: Ambiguous projection in SELECT clause (in line 32, at column 8)</expected-error>
+      </compilation-unit>
+    </test-case>
+  </test-group>
   <test-group name="statement-params">
     <test-case FilePath="statement-params">
       <compilation-unit name="index_01">
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
index 1f96cc8..d49dffc 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
@@ -252,6 +252,7 @@ public enum ErrorCode implements IError {
     INVALID_FOREIGN_KEY_DEFINITION_REF_PK_NOT_FOUND(1165),
     INVALID_FOREIGN_KEY_DEFINITION_REF_PK_MISMATCH(1166),
     CANNOT_CHANGE_PRIMARY_KEY(1167),
+    AMBIGUOUS_PROJECTION(1168),
 
     // Feed errors
     DATAFLOW_ILLEGAL_STATE(3001),
diff --git a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
index f40fdcf..136e169 100644
--- a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
+++ b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
@@ -254,6 +254,7 @@
 1165 = Invalid foreign key definition: %1$s %2$s does not have a primary key
 1166 = Invalid foreign key definition: foreign key does not match primary key of %1$s %2$s
 1167 = Cannot change primary key of %1$s %2$s
+1168 = Ambiguous projection in SELECT clause
 
 # Feed Errors
 3001 = Illegal state.
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/Projection.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/Projection.java
index 7aa3cec..fbfc5a2 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/Projection.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/Projection.java
@@ -32,7 +32,8 @@ public class Projection extends AbstractClause {
     public enum Kind {
         NAMED_EXPR, // expr AS name
         STAR, // *
-        VAR_STAR // variable.*
+        VAR_STAR, // variable.*
+        EVERY_VAR_STAR // *.* (currently only used in SQL-compatible mode)
     }
 
     private Kind kind;
@@ -54,6 +55,7 @@ public class Projection extends AbstractClause {
                 }
                 break;
             case STAR:
+            case EVERY_VAR_STAR:
                 if (expr != null || name != null) {
                     throw new IllegalArgumentException();
                 }
@@ -142,6 +144,8 @@ public class Projection extends AbstractClause {
                 return "*";
             case VAR_STAR:
                 return expr + ".*";
+            case EVERY_VAR_STAR:
+                return "*.*";
             default:
                 throw new IllegalStateException();
         }
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
index b6fd9da..b28f4b9 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
@@ -59,6 +59,7 @@ import org.apache.asterix.lang.sqlpp.rewrites.visitor.InlineColumnAliasVisitor;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.InlineWithExpressionVisitor;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.OperatorExpressionVisitor;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.SetOperationVisitor;
+import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlCompatRewriteVisitor;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppCaseAggregateExtractionVisitor;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppCaseExpressionVisitor;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppFunctionCallResolverVisitor;
@@ -138,6 +139,9 @@ public class SqlppQueryRewriter implements IQueryRewriter {
         // Sets up parameters.
         setup(context, topStatement, externalVars, allowNonStoredUdfCalls, inlineUdfsAndViews);
 
+        // Initial SQL-compat mode rewrites
+        rewriteSqlCompat();
+
         // Resolves function calls
         resolveFunctionCalls();
 
@@ -218,6 +222,15 @@ public class SqlppQueryRewriter implements IQueryRewriter {
         rewriteTopExpr(listInputFunctionVisitor, null);
     }
 
+    protected void rewriteSqlCompat() throws CompilationException {
+        boolean sqlCompatMode = metadataProvider.getBooleanProperty(SQL_COMPAT_OPTION, SQL_COMPAT_OPTION_DEFAULT);
+        if (!sqlCompatMode) {
+            return;
+        }
+        SqlCompatRewriteVisitor visitor = new SqlCompatRewriteVisitor();
+        rewriteTopExpr(visitor, null);
+    }
+
     protected void resolveFunctionCalls() throws CompilationException {
         SqlppFunctionCallResolverVisitor visitor =
                 new SqlppFunctionCallResolverVisitor(context, allowNonStoredUdfCalls);
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlCompatRewriteVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlCompatRewriteVisitor.java
new file mode 100644
index 0000000..69eb156
--- /dev/null
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlCompatRewriteVisitor.java
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+package org.apache.asterix.lang.sqlpp.rewrites.visitor;
+
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.base.ILangExpression;
+import org.apache.asterix.lang.sqlpp.clause.Projection;
+import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppSimpleExpressionVisitor;
+
+/**
+ * Applies initial rewritings for "SQL-compatible" evaluation mode
+ * <ol>
+ * <li>Rewrites "SELECT *" into "SELECT *.*".
+ * </ol>
+ */
+public final class SqlCompatRewriteVisitor extends AbstractSqlppSimpleExpressionVisitor {
+
+    @Override
+    public Expression visit(Projection projection, ILangExpression arg) throws CompilationException {
+        if (projection.getKind() == Projection.Kind.STAR) {
+            projection.setKind(Projection.Kind.EVERY_VAR_STAR);
+        }
+        return super.visit(projection, arg);
+    }
+}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupingSetsVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupingSetsVisitor.java
index 9aca37a..1259b64 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupingSetsVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupingSetsVisitor.java
@@ -165,7 +165,7 @@ public final class SqlppGroupingSetsVisitor extends AbstractSqlppExpressionScopi
         // For regular SELECT we need to add ORDERBY/LIMIT free variables to the projection list of the SELECT clause,
         // so they can be accessed using field-access-by-name after SELECT.
         // Some of these variables might be already projected by SELECT, so we need to account for that.
-        // We currently do not support (fail) SELECT v.* because in this case we cannot statically compute
+        // We currently do not support (fail) SELECT v.* and *.* because in this case we cannot statically compute
         // the schema of the record produced by the SELECT and therefore cannot guarantee that the field
         // names we generate will not conflict with the existing fields in the SELECT output.
         // The added projections will be later removed by the outer query.
@@ -181,6 +181,7 @@ public final class SqlppGroupingSetsVisitor extends AbstractSqlppExpressionScopi
                 Projection projection = projectionList.get(i);
                 switch (projection.getKind()) {
                     case VAR_STAR:
+                    case EVERY_VAR_STAR:
                         throw new CompilationException(ErrorCode.UNSUPPORTED_GBY_OBY_SELECT_COMBO,
                                 selectBlock.getSourceLocation());
                     case STAR:
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
index 27c3952..db663cd 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
@@ -135,6 +135,9 @@ public class SqlppAstPrintVisitor extends QueryPrintVisitor implements ISqlppVis
             case STAR:
                 out.println(skip(step) + "*");
                 break;
+            case EVERY_VAR_STAR:
+                out.println(skip(step) + "*.*");
+                break;
             case VAR_STAR:
                 projection.getExpression().accept(this, step);
                 out.println(skip(step) + ".*");
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
index 34ca727..975379d 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
@@ -127,6 +127,9 @@ public class SqlppFormatPrintVisitor extends FormatPrintVisitor implements ISqlp
             case STAR:
                 out.print(" * ");
                 break;
+            case EVERY_VAR_STAR:
+                out.print(" *.* ");
+                break;
             case VAR_STAR:
                 projection.getExpression().accept(this, step);
                 out.print(".* ");