SQL++ support in AsterixDB:
1. implemented SQL++ expression to logical plan translator;
2. refactored REST API to be agnostic of query languages;
3. disabled fuzzy join queries for SQL++ runtime tests;
4. fixed several rewriting rules.
Change-Id: I82919c4527b304325059519d819a2c30cf2902a9
Reviewed-on: https://asterix-gerrit.ics.uci.edu/479
Reviewed-by: Till Westmann <tillw@apache.org>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/clause/DistinctClause.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/clause/DistinctClause.java
index 789c5bd..9ee86e2 100644
--- a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/clause/DistinctClause.java
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/clause/DistinctClause.java
@@ -38,6 +38,10 @@
return distinctByExprs;
}
+ public void setDistinctByExpr(List<Expression> exprList) {
+ this.distinctByExprs = exprList;
+ }
+
@Override
public ClauseType getClauseType() {
return ClauseType.DISTINCT_BY_CLAUSE;
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/parser/AQLParserFactory.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/parser/AQLParserFactory.java
new file mode 100644
index 0000000..41ca142
--- /dev/null
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/parser/AQLParserFactory.java
@@ -0,0 +1,38 @@
+/*
+ * 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.aql.parser;
+
+import java.io.Reader;
+
+import org.apache.asterix.lang.common.base.IParser;
+import org.apache.asterix.lang.common.base.IParserFactory;
+
+public class AQLParserFactory implements IParserFactory {
+
+ @Override
+ public IParser createParser(String query) {
+ return new AQLParser(query);
+ }
+
+ @Override
+ public IParser createParser(Reader reader) {
+ return new AQLParser(reader);
+ }
+
+}
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/util/FunctionUtils.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/parser/FunctionParser.java
similarity index 69%
rename from asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/util/FunctionUtils.java
rename to asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/parser/FunctionParser.java
index 2f326ae..96086a1 100644
--- a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/util/FunctionUtils.java
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/parser/FunctionParser.java
@@ -17,28 +17,29 @@
* under the License.
*/
-package org.apache.asterix.lang.aql.util;
+package org.apache.asterix.lang.aql.parser;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.asterix.common.exceptions.AsterixException;
-import org.apache.asterix.common.functions.FunctionSignature;
-import org.apache.asterix.lang.aql.parser.AQLParser;
+import org.apache.asterix.lang.common.base.IParser;
+import org.apache.asterix.lang.common.base.IParserFactory;
import org.apache.asterix.lang.common.base.Statement;
import org.apache.asterix.lang.common.statement.FunctionDecl;
import org.apache.asterix.lang.common.struct.VarIdentifier;
import org.apache.asterix.metadata.entities.Function;
-import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
-public class FunctionUtils {
+public class FunctionParser {
- public static final String IMPORT_PRIVATE_FUNCTIONS = "import-private-functions";
+ private final IParserFactory parserFactory;
- public static FunctionDecl getFunctionDecl(Function function) throws AsterixException {
+ public FunctionParser(IParserFactory parserFactory) {
+ this.parserFactory = parserFactory;
+ }
+
+ public FunctionDecl getFunctionDecl(Function function) throws AsterixException {
String functionBody = function.getFunctionBody();
List<String> params = function.getParams();
List<VarIdentifier> varIdentifiers = new ArrayList<VarIdentifier>();
@@ -63,19 +64,10 @@
builder.append("\n");
builder.append("}");
- AQLParser parser = new AQLParser(new StringReader(new String(builder)));
-
+ IParser parser = parserFactory.createParser(new StringReader(new String(builder)));
List<Statement> statements = parser.parse();
FunctionDecl decl = (FunctionDecl) statements.get(1);
return decl;
}
- public static IFunctionInfo getFunctionInfo(FunctionIdentifier fi) {
- return AsterixBuiltinFunctions.getAsterixFunctionInfo(fi);
- }
-
- public static IFunctionInfo getFunctionInfo(FunctionSignature fs) {
- return getFunctionInfo(new FunctionIdentifier(fs.getNamespace(), fs.getName(), fs.getArity()));
- }
-
}
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AQLRewriterFactory.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AQLRewriterFactory.java
new file mode 100644
index 0000000..87885b8
--- /dev/null
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AQLRewriterFactory.java
@@ -0,0 +1,37 @@
+/*
+ * 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.aql.rewrites;
+
+import org.apache.asterix.lang.common.base.IQueryRewriter;
+import org.apache.asterix.lang.common.base.IRewriterFactory;
+import org.apache.asterix.lang.common.base.IStatementRewriter;
+
+public class AQLRewriterFactory implements IRewriterFactory {
+
+ @Override
+ public IQueryRewriter createQueryRewriter() {
+ return new AqlQueryRewriter();
+ }
+
+ @Override
+ public IStatementRewriter createStatementRewriter() {
+ return new AqlStatementRewriter();
+ }
+
+}
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlRewriter.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlQueryRewriter.java
similarity index 86%
rename from asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlRewriter.java
rename to asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlQueryRewriter.java
index dc99549..263cf9c 100644
--- a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlRewriter.java
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlQueryRewriter.java
@@ -28,12 +28,14 @@
import org.apache.asterix.lang.aql.clause.ForClause;
import org.apache.asterix.lang.aql.expression.FLWOGRExpression;
import org.apache.asterix.lang.aql.expression.UnionExpr;
-import org.apache.asterix.lang.aql.util.FunctionUtils;
+import org.apache.asterix.lang.aql.parser.AQLParserFactory;
+import org.apache.asterix.lang.aql.parser.FunctionParser;
import org.apache.asterix.lang.aql.visitor.AQLInlineUdfsVisitor;
import org.apache.asterix.lang.aql.visitor.base.IAQLVisitor;
import org.apache.asterix.lang.common.base.Clause;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.base.Expression.Kind;
+import org.apache.asterix.lang.common.base.IQueryRewriter;
import org.apache.asterix.lang.common.clause.GroupbyClause;
import org.apache.asterix.lang.common.clause.LetClause;
import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
@@ -42,6 +44,7 @@
import org.apache.asterix.lang.common.statement.FunctionDecl;
import org.apache.asterix.lang.common.statement.Query;
import org.apache.asterix.lang.common.struct.VarIdentifier;
+import org.apache.asterix.lang.common.util.FunctionUtil;
import org.apache.asterix.lang.common.visitor.GatherFunctionCallsVisitor;
import org.apache.asterix.metadata.MetadataManager;
import org.apache.asterix.metadata.MetadataTransactionContext;
@@ -49,33 +52,33 @@
import org.apache.asterix.metadata.entities.Function;
import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
-public final class AqlRewriter {
+class AqlQueryRewriter implements IQueryRewriter {
- private final Query topExpr;
- private final List<FunctionDecl> declaredFunctions;
- private final LangRewritingContext context;
- private final MetadataTransactionContext mdTxnCtx;
- private final AqlMetadataProvider metadataProvider;
+ private final FunctionParser functionParser = new FunctionParser(new AQLParserFactory());
+ private Query topExpr;
+ private List<FunctionDecl> declaredFunctions;
+ private LangRewritingContext context;
+ private MetadataTransactionContext mdTxnCtx;
+ private AqlMetadataProvider metadataProvider;
- public AqlRewriter(List<FunctionDecl> declaredFunctions, Query topExpr, AqlMetadataProvider metadataProvider) {
+ private void setup(List<FunctionDecl> declaredFunctions, Query topExpr, AqlMetadataProvider metadataProvider,
+ LangRewritingContext context) {
this.topExpr = topExpr;
- context = new LangRewritingContext(topExpr.getVarCounter());
+ this.context = context;
this.declaredFunctions = declaredFunctions;
this.mdTxnCtx = metadataProvider.getMetadataTxnContext();
this.metadataProvider = metadataProvider;
}
- public Query getExpr() {
- return topExpr;
- }
-
- public int getVarCounter() {
- return context.getVarCounter();
- }
-
- public void rewrite() throws AsterixException {
- wrapInLets();
+ @Override
+ public void rewrite(List<FunctionDecl> declaredFunctions, Query topExpr, AqlMetadataProvider metadataProvider,
+ LangRewritingContext context) throws AsterixException {
+ setup(declaredFunctions, topExpr, metadataProvider, context);
+ if (topExpr.isTopLevel()) {
+ wrapInLets();
+ }
inlineDeclaredUdfs();
+ topExpr.setVarCounter(context.getVarCounter());
}
private void wrapInLets() {
@@ -109,7 +112,8 @@
buildOtherUdfs(topExpr.getBody(), otherFDecls, funIds);
declaredFunctions.addAll(otherFDecls);
if (!declaredFunctions.isEmpty()) {
- AQLInlineUdfsVisitor visitor = new AQLInlineUdfsVisitor(context);
+ AQLInlineUdfsVisitor visitor = new AQLInlineUdfsVisitor(context, new AQLRewriterFactory(),
+ declaredFunctions, metadataProvider);
while (topExpr.accept(visitor, declaredFunctions)) {
// loop until no more changes
}
@@ -122,7 +126,7 @@
if (expression == null) {
return;
}
- String value = metadataProvider.getConfig().get(FunctionUtils.IMPORT_PRIVATE_FUNCTIONS);
+ String value = metadataProvider.getConfig().get(FunctionUtil.IMPORT_PRIVATE_FUNCTIONS);
boolean includePrivateFunctions = (value != null) ? Boolean.valueOf(value.toLowerCase()) : false;
Set<FunctionSignature> functionCalls = getFunctionCalls(expression);
for (FunctionSignature signature : functionCalls) {
@@ -147,7 +151,7 @@
}
if (function.getLanguage().equalsIgnoreCase(Function.LANGUAGE_AQL)) {
- FunctionDecl functionDecl = FunctionUtils.getFunctionDecl(function);
+ FunctionDecl functionDecl = functionParser.getFunctionDecl(function);
if (functionDecl != null) {
if (functionDecls.contains(functionDecl)) {
throw new AsterixException("ERROR:Recursive invocation "
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlStatementRewriter.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlStatementRewriter.java
new file mode 100644
index 0000000..b9566f4
--- /dev/null
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlStatementRewriter.java
@@ -0,0 +1,39 @@
+/*
+ * 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.aql.rewrites;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.lang.aql.visitor.AqlDeleteRewriteVisitor;
+import org.apache.asterix.lang.common.base.IStatementRewriter;
+import org.apache.asterix.lang.common.base.Statement;
+
+class AqlStatementRewriter implements IStatementRewriter {
+
+ @Override
+ public void rewrite(Statement stmt) throws AsterixException {
+ rewriteDeleteStatement(stmt);
+ }
+
+ private void rewriteDeleteStatement(Statement stmt) throws AsterixException {
+ if (stmt != null) {
+ AqlDeleteRewriteVisitor visitor = new AqlDeleteRewriteVisitor();
+ stmt.accept(visitor, null);
+ }
+ }
+}
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/statement/SubscribeFeedStatement.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/statement/SubscribeFeedStatement.java
index a86c409..e6f1999 100644
--- a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/statement/SubscribeFeedStatement.java
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/statement/SubscribeFeedStatement.java
@@ -29,12 +29,13 @@
import org.apache.asterix.common.feeds.FeedId;
import org.apache.asterix.common.feeds.FeedPolicyAccessor;
import org.apache.asterix.common.functions.FunctionSignature;
-import org.apache.asterix.lang.aql.parser.AQLParser;
-import org.apache.asterix.lang.aql.parser.ParseException;
-import org.apache.asterix.lang.aql.util.FunctionUtils;
+import org.apache.asterix.lang.aql.parser.AQLParserFactory;
+import org.apache.asterix.lang.common.base.IParser;
+import org.apache.asterix.lang.common.base.IParserFactory;
import org.apache.asterix.lang.common.base.Statement;
import org.apache.asterix.lang.common.statement.InsertStatement;
import org.apache.asterix.lang.common.statement.Query;
+import org.apache.asterix.lang.common.util.FunctionUtil;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
import org.apache.asterix.metadata.MetadataException;
import org.apache.asterix.metadata.MetadataManager;
@@ -63,6 +64,7 @@
private final String[] locations;
public static final String WAIT_FOR_COMPLETION = "wait-for-completion-feed";
+ private final IParserFactory parserFactory = new AQLParserFactory();
public SubscribeFeedStatement(String[] locations, FeedConnectionRequest subscriptionRequest) {
this.connectionRequest = subscriptionRequest;
@@ -95,7 +97,7 @@
StringBuilder builder = new StringBuilder();
builder.append("use dataverse " + sourceFeedId.getDataverse() + ";\n");
- builder.append("set" + " " + FunctionUtils.IMPORT_PRIVATE_FUNCTIONS + " " + "'" + Boolean.TRUE + "'" + ";\n");
+ builder.append("set" + " " + FunctionUtil.IMPORT_PRIVATE_FUNCTIONS + " " + "'" + Boolean.TRUE + "'" + ";\n");
builder.append("set" + " " + FeedActivity.FeedActivityDetails.FEED_POLICY_NAME + " " + "'"
+ connectionRequest.getPolicy() + "'" + ";\n");
@@ -136,13 +138,13 @@
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.info("Connect feed statement translated to\n" + builder.toString());
}
- AQLParser parser = new AQLParser(new StringReader(builder.toString()));
+ IParser parser = parserFactory.createParser(new StringReader(builder.toString()));
List<Statement> statements;
try {
- statements = parser.Statement();
+ statements = parser.parse();
query = ((InsertStatement) statements.get(3)).getQuery();
- } catch (ParseException pe) {
+ } catch (AsterixException pe) {
throw new MetadataException(pe);
}
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/util/AQLVariableSubstitutionUtil.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/util/AQLVariableSubstitutionUtil.java
index 06e6fa7..717eb5c 100644
--- a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/util/AQLVariableSubstitutionUtil.java
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/util/AQLVariableSubstitutionUtil.java
@@ -18,8 +18,6 @@
*/
package org.apache.asterix.lang.aql.util;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Map;
import org.apache.asterix.common.exceptions.AsterixException;
@@ -32,18 +30,6 @@
public class AQLVariableSubstitutionUtil {
- public static List<ILangExpression> substituteVariable(List<ILangExpression> expressions,
- Map<VariableExpr, Expression> varExprMap) throws AsterixException {
- AQLCloneAndSubstituteVariablesVisitor visitor = new AQLCloneAndSubstituteVariablesVisitor(
- new LangRewritingContext(0));
- VariableSubstitutionEnvironment env = new VariableSubstitutionEnvironment(varExprMap);
- List<ILangExpression> newExprs = new ArrayList<ILangExpression>();
- for (ILangExpression expression : expressions) {
- newExprs.add(expression.accept(visitor, env).first);
- }
- return newExprs;
- }
-
public static ILangExpression substituteVariable(ILangExpression expression,
Map<VariableExpr, Expression> varExprMap) throws AsterixException {
AQLCloneAndSubstituteVariablesVisitor visitor = new AQLCloneAndSubstituteVariablesVisitor(
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/util/RangeMapBuilder.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/util/RangeMapBuilder.java
index a15fb45..2fc4b14 100644
--- a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/util/RangeMapBuilder.java
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/util/RangeMapBuilder.java
@@ -24,9 +24,11 @@
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
-import org.apache.asterix.lang.aql.parser.AQLParser;
+import org.apache.asterix.lang.aql.parser.AQLParserFactory;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.base.Expression.Kind;
+import org.apache.asterix.lang.common.base.IParser;
+import org.apache.asterix.lang.common.base.IParserFactory;
import org.apache.asterix.lang.common.base.Literal;
import org.apache.asterix.lang.common.base.Statement;
import org.apache.asterix.lang.common.expression.ListConstructor;
@@ -54,13 +56,14 @@
import org.apache.hyracks.dataflow.common.data.partition.range.RangeMap;
public abstract class RangeMapBuilder {
+ private static final IParserFactory parserFactory = new AQLParserFactory();
public static IRangeMap parseHint(Object hint) throws AsterixException {
ArrayBackedValueStorage abvs = new ArrayBackedValueStorage();
DataOutput out = abvs.getDataOutput();;
abvs.reset();
- AQLParser parser = new AQLParser((String) hint);
+ IParser parser = parserFactory.createParser((String) hint);
List<Statement> hintStatements = parser.parse();
if (hintStatements.size() != 1) {
throw new AsterixException("Only one range statement is allowed for the range hint.");
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLPrintVisitor.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLAstPrintVisitor.java
similarity index 94%
rename from asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLPrintVisitor.java
rename to asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLAstPrintVisitor.java
index 2798ef8..0636114 100644
--- a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLPrintVisitor.java
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLAstPrintVisitor.java
@@ -30,16 +30,16 @@
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.visitor.QueryPrintVisitor;
-public class AQLPrintVisitor extends QueryPrintVisitor implements IAQLVisitor<Void, Integer> {
+class AQLAstPrintVisitor extends QueryPrintVisitor implements IAQLVisitor<Void, Integer> {
private final PrintWriter out;
- public AQLPrintVisitor() {
+ public AQLAstPrintVisitor() {
super();
out = new PrintWriter(System.out);
}
- public AQLPrintVisitor(PrintWriter out) {
+ public AQLAstPrintVisitor(PrintWriter out) {
super(out);
this.out = out;
}
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLAstPrintVisitorFactory.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLAstPrintVisitorFactory.java
new file mode 100644
index 0000000..ff76fee
--- /dev/null
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLAstPrintVisitorFactory.java
@@ -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.
+ */
+package org.apache.asterix.lang.aql.visitor;
+
+import java.io.PrintWriter;
+
+import org.apache.asterix.lang.common.base.IAstPrintVisitorFactory;
+import org.apache.asterix.lang.common.visitor.QueryPrintVisitor;
+
+public class AQLAstPrintVisitorFactory implements IAstPrintVisitorFactory {
+
+ @Override
+ public QueryPrintVisitor createLangVisitor(PrintWriter writer) {
+ return new AQLAstPrintVisitor(writer);
+ }
+
+}
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLCloneAndSubstituteVariablesVisitor.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLCloneAndSubstituteVariablesVisitor.java
index 511354e..dfbf757 100644
--- a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLCloneAndSubstituteVariablesVisitor.java
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLCloneAndSubstituteVariablesVisitor.java
@@ -33,7 +33,7 @@
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
import org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment;
-import org.apache.asterix.lang.common.utils.VariableCloneAndSubstitutionUtil;
+import org.apache.asterix.lang.common.util.VariableCloneAndSubstitutionUtil;
import org.apache.asterix.lang.common.visitor.CloneAndSubstituteVariablesVisitor;
import org.apache.hyracks.algebricks.common.utils.Pair;
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLInlineUdfsVisitor.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLInlineUdfsVisitor.java
index b53d888..dd1a1fb 100644
--- a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLInlineUdfsVisitor.java
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLInlineUdfsVisitor.java
@@ -29,17 +29,21 @@
import org.apache.asterix.lang.aql.visitor.base.IAQLVisitor;
import org.apache.asterix.lang.common.base.Clause;
import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.base.IRewriterFactory;
import org.apache.asterix.lang.common.clause.LetClause;
import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
import org.apache.asterix.lang.common.statement.FunctionDecl;
import org.apache.asterix.lang.common.visitor.AbstractInlineUdfsVisitor;
+import org.apache.asterix.metadata.declared.AqlMetadataProvider;
import org.apache.hyracks.algebricks.common.utils.Pair;
public class AQLInlineUdfsVisitor extends AbstractInlineUdfsVisitor
implements IAQLVisitor<Boolean, List<FunctionDecl>> {
- public AQLInlineUdfsVisitor(LangRewritingContext context) {
- super(context, new AQLCloneAndSubstituteVariablesVisitor(context));
+ public AQLInlineUdfsVisitor(LangRewritingContext context, IRewriterFactory rewriterFactory,
+ List<FunctionDecl> declaredFunctions, AqlMetadataProvider metadataProvider) {
+ super(context, rewriterFactory, declaredFunctions, metadataProvider,
+ new AQLCloneAndSubstituteVariablesVisitor(context));
}
@Override
@@ -71,11 +75,9 @@
@Override
public Boolean visit(DistinctClause dc, List<FunctionDecl> arg) throws AsterixException {
- boolean changed = false;
- for (Expression expr : dc.getDistinctByExpr()) {
- changed = expr.accept(this, arg);
- }
- return changed;
+ Pair<Boolean, ArrayList<Expression>> p = inlineUdfsInExprList(dc.getDistinctByExpr(), arg);
+ dc.setDistinctByExpr(p.second);
+ return p.first;
}
@Override
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AqlDeleteRewriteVisitor.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AqlDeleteRewriteVisitor.java
new file mode 100644
index 0000000..cedeb77
--- /dev/null
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AqlDeleteRewriteVisitor.java
@@ -0,0 +1,73 @@
+/*
+ * 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.aql.visitor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.asterix.common.functions.FunctionConstants;
+import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.aql.clause.ForClause;
+import org.apache.asterix.lang.aql.expression.FLWOGRExpression;
+import org.apache.asterix.lang.aql.visitor.base.AbstractAqlAstVisitor;
+import org.apache.asterix.lang.common.base.Clause;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.clause.WhereClause;
+import org.apache.asterix.lang.common.expression.CallExpr;
+import org.apache.asterix.lang.common.expression.LiteralExpr;
+import org.apache.asterix.lang.common.expression.VariableExpr;
+import org.apache.asterix.lang.common.literal.StringLiteral;
+import org.apache.asterix.lang.common.statement.DeleteStatement;
+import org.apache.asterix.lang.common.statement.Query;
+import org.apache.asterix.lang.common.struct.Identifier;
+
+public class AqlDeleteRewriteVisitor extends AbstractAqlAstVisitor<Void, Void> {
+
+ @Override
+ public Void visit(DeleteStatement deleteStmt, Void visitArg) {
+ List<Expression> arguments = new ArrayList<Expression>();
+ Identifier dataverseName = deleteStmt.getDataverseName();
+ Identifier datasetName = deleteStmt.getDatasetName();
+ String arg = dataverseName == null ? datasetName.getValue()
+ : dataverseName.getValue() + "." + datasetName.getValue();
+ LiteralExpr argumentLiteral = new LiteralExpr(new StringLiteral(arg));
+ arguments.add(argumentLiteral);
+ CallExpr callExpression = new CallExpr(new FunctionSignature(FunctionConstants.ASTERIX_NS, "dataset", 1),
+ arguments);
+
+ List<Clause> clauseList = new ArrayList<Clause>();
+ VariableExpr var = deleteStmt.getVariableExpr();
+ Clause forClause = new ForClause(var, callExpression);
+ clauseList.add(forClause);
+ Clause whereClause = null;
+ Expression condition = deleteStmt.getCondition();
+ if (condition != null) {
+ whereClause = new WhereClause(condition);
+ clauseList.add(whereClause);
+ }
+ VariableExpr returnExpr = new VariableExpr(var.getVar());
+ returnExpr.setIsNewVar(false);
+ FLWOGRExpression flowgr = new FLWOGRExpression(clauseList, returnExpr);
+ Query query = new Query();
+ query.setBody(flowgr);
+ deleteStmt.setQuery(query);
+ return null;
+ }
+
+}
diff --git a/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/base/AbstractAqlAstVisitor.java b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/base/AbstractAqlAstVisitor.java
new file mode 100644
index 0000000..05c1b81
--- /dev/null
+++ b/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/base/AbstractAqlAstVisitor.java
@@ -0,0 +1,50 @@
+/*
+ * 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.aql.visitor.base;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.lang.aql.clause.DistinctClause;
+import org.apache.asterix.lang.aql.clause.ForClause;
+import org.apache.asterix.lang.aql.expression.FLWOGRExpression;
+import org.apache.asterix.lang.aql.expression.UnionExpr;
+import org.apache.asterix.lang.common.visitor.base.AbstractAstVisitor;
+
+public abstract class AbstractAqlAstVisitor<R, T> extends AbstractAstVisitor<R, T> implements IAQLVisitor<R, T> {
+
+ @Override
+ public R visit(FLWOGRExpression flwogreExpr, T arg) throws AsterixException {
+ return null;
+ }
+
+ @Override
+ public R visit(UnionExpr u, T arg) throws AsterixException {
+ return null;
+ }
+
+ @Override
+ public R visit(ForClause forClause, T arg) throws AsterixException {
+ return null;
+ }
+
+ @Override
+ public R visit(DistinctClause distinctClause, T arg) throws AsterixException {
+ return null;
+ }
+
+}
diff --git a/asterix-lang-aql/src/main/javacc/AQL.jj b/asterix-lang-aql/src/main/javacc/AQL.jj
index bb574d0..78c9abd 100644
--- a/asterix-lang-aql/src/main/javacc/AQL.jj
+++ b/asterix-lang-aql/src/main/javacc/AQL.jj
@@ -135,7 +135,7 @@
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-public class AQLParser extends ScopeChecker implements IParser {
+class AQLParser extends ScopeChecker implements IParser {
// optimizer hints
private static final String AUTO_HINT = "auto";
@@ -886,7 +886,7 @@
{
"insert" "into" <DATASET> nameComponents = QualifiedName() query = Query()
{
- query.setTopLevel(false);
+ query.setTopLevel(true);
return new InsertStatement(nameComponents.first, nameComponents.second, query, getVarCounter());
}
}