[NO ISSUE][COMP] Improve function parsing
- user model changes: no
- storage format changes: no
- interface changes: no
Details:
- Added IParser.parseFunctionBody() method that
parses body of a user-defined function
- Modified FunctionParser to parse function body
directly by calling the above method instead
of creating "declare function" statement
- Consolidated SQLPP and AQL FunctionParsers
into a single common class
Change-Id: I498550c90f2ba492549d15b61d7607e986b08c04
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/4846
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Dmitry Lychagin <dmitry.lychagin@couchbase.com>
Reviewed-by: Ian Maxon <imaxon@uci.edu>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/compiler/provider/AqlCompilationProvider.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/compiler/provider/AqlCompilationProvider.java
index 548917a..662010f 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/compiler/provider/AqlCompilationProvider.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/compiler/provider/AqlCompilationProvider.java
@@ -42,7 +42,7 @@
@Override
public IRewriterFactory getRewriterFactory() {
- return new AQLRewriterFactory();
+ return new AQLRewriterFactory(getParserFactory());
}
@Override
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/compiler/provider/SqlppCompilationProvider.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/compiler/provider/SqlppCompilationProvider.java
index 6451b6f..2c18d41 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/compiler/provider/SqlppCompilationProvider.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/compiler/provider/SqlppCompilationProvider.java
@@ -42,7 +42,7 @@
@Override
public IRewriterFactory getRewriterFactory() {
- return new SqlppRewriterFactory();
+ return new SqlppRewriterFactory(getParserFactory());
}
@Override
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java
index 0ab41b7..c454993 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java
@@ -69,7 +69,7 @@
public class ParserTestExecutor extends TestExecutor {
private IParserFactory sqlppParserFactory = new SqlppParserFactory();
- private IRewriterFactory sqlppRewriterFactory = new SqlppRewriterFactory();
+ private IRewriterFactory sqlppRewriterFactory = new SqlppRewriterFactory(sqlppParserFactory);
@Override
public void executeTest(String actualPath, TestCaseContext testCaseCtx, ProcessBuilder pb,
diff --git a/asterixdb/asterix-lang-aql/pom.xml b/asterixdb/asterix-lang-aql/pom.xml
index f202192..de36d67 100644
--- a/asterixdb/asterix-lang-aql/pom.xml
+++ b/asterixdb/asterix-lang-aql/pom.xml
@@ -154,10 +154,6 @@
<artifactId>algebricks-common</artifactId>
</dependency>
<dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- </dependency>
- <dependency>
<groupId>org.apache.asterix</groupId>
<artifactId>asterix-om</artifactId>
<version>${project.version}</version>
diff --git a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/parser/FunctionParser.java b/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/parser/FunctionParser.java
deleted file mode 100644
index adaeaaf..0000000
--- a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/parser/FunctionParser.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.util.ArrayList;
-import java.util.List;
-
-import org.apache.asterix.common.exceptions.CompilationException;
-import org.apache.asterix.common.exceptions.ErrorCode;
-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.commons.io.input.CharSequenceReader;
-
-public class FunctionParser {
-
- private final IParserFactory parserFactory;
-
- public FunctionParser(IParserFactory parserFactory) {
- this.parserFactory = parserFactory;
- }
-
- public FunctionDecl getFunctionDecl(Function function) throws CompilationException {
- if (!function.getLanguage().equals(Function.LANGUAGE_AQL)) {
- throw new CompilationException(ErrorCode.COMPILATION_INCOMPATIBLE_FUNCTION_LANGUAGE, Function.LANGUAGE_AQL,
- function.getLanguage());
- }
- String functionBody = function.getFunctionBody();
- List<String> arguments = function.getArgNames();
- List<VarIdentifier> varIdentifiers = new ArrayList<VarIdentifier>();
-
- StringBuilder builder = new StringBuilder();
- builder.append(" use dataverse " + function.getDataverseName() + ";");
- builder.append(" declare function " + function.getName().split("@")[0]);
- builder.append("(");
- boolean first = true;
- for (String argument : arguments) {
- VarIdentifier varId = new VarIdentifier(argument);
- varIdentifiers.add(varId);
- if (first) {
- first = false;
- } else {
- builder.append(",");
- }
- builder.append(argument);
- }
- builder.append("){\n").append(functionBody).append("\n}");
-
- IParser parser = parserFactory.createParser(new CharSequenceReader(builder));
- List<Statement> statements = parser.parse();
- FunctionDecl decl = (FunctionDecl) statements.get(1);
- return decl;
- }
-
-}
diff --git a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AQLRewriterFactory.java b/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AQLRewriterFactory.java
index 87885b8..0987d89 100644
--- a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AQLRewriterFactory.java
+++ b/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AQLRewriterFactory.java
@@ -18,15 +18,22 @@
*/
package org.apache.asterix.lang.aql.rewrites;
+import org.apache.asterix.lang.common.base.IParserFactory;
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 {
+ private final IParserFactory parserFactory;
+
+ public AQLRewriterFactory(IParserFactory parserFactory) {
+ this.parserFactory = parserFactory;
+ }
+
@Override
public IQueryRewriter createQueryRewriter() {
- return new AqlQueryRewriter();
+ return new AqlQueryRewriter(parserFactory);
}
@Override
diff --git a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlQueryRewriter.java b/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlQueryRewriter.java
index 9aaf5b7..b3097dc 100644
--- a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlQueryRewriter.java
+++ b/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlQueryRewriter.java
@@ -30,14 +30,13 @@
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.parser.AQLParserFactory;
-import org.apache.asterix.lang.aql.parser.FunctionParser;
import org.apache.asterix.lang.aql.rewrites.visitor.AqlBuiltinFunctionRewriteVisitor;
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.IParserFactory;
import org.apache.asterix.lang.common.base.IQueryRewriter;
import org.apache.asterix.lang.common.base.IReturningStatement;
import org.apache.asterix.lang.common.clause.GroupbyClause;
@@ -45,6 +44,7 @@
import org.apache.asterix.lang.common.expression.CallExpr;
import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
import org.apache.asterix.lang.common.expression.VariableExpr;
+import org.apache.asterix.lang.common.parser.FunctionParser;
import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
import org.apache.asterix.lang.common.statement.FunctionDecl;
import org.apache.asterix.lang.common.struct.Identifier;
@@ -53,16 +53,23 @@
import org.apache.asterix.lang.common.util.FunctionUtil;
import org.apache.asterix.lang.common.visitor.GatherFunctionCallsVisitor;
import org.apache.asterix.metadata.declared.MetadataProvider;
+import org.apache.asterix.metadata.entities.Function;
import org.apache.hyracks.algebricks.common.utils.Pair;
class AqlQueryRewriter implements IQueryRewriter {
- private final FunctionParser functionParser = new FunctionParser(new AQLParserFactory());
+ private final IParserFactory parserFactory;
+ private final FunctionParser functionParser;
private IReturningStatement topStatement;
private List<FunctionDecl> declaredFunctions;
private LangRewritingContext context;
private MetadataProvider metadataProvider;
+ AqlQueryRewriter(IParserFactory parserFactory) {
+ this.parserFactory = parserFactory;
+ functionParser = new FunctionParser(Function.LANGUAGE_AQL, this.parserFactory);
+ }
+
private void setup(List<FunctionDecl> declaredFunctions, IReturningStatement topStatement,
MetadataProvider metadataProvider, LangRewritingContext context) {
this.topStatement = topStatement;
@@ -127,8 +134,8 @@
declaredFunctions.addAll(storedFunctionDecls);
}
if (!declaredFunctions.isEmpty()) {
- AQLInlineUdfsVisitor visitor =
- new AQLInlineUdfsVisitor(context, new AQLRewriterFactory(), declaredFunctions, metadataProvider);
+ AQLInlineUdfsVisitor visitor = new AQLInlineUdfsVisitor(context, new AQLRewriterFactory(parserFactory),
+ declaredFunctions, metadataProvider);
while (topStatement.accept(visitor, declaredFunctions)) {
// loop until no more changes
}
diff --git a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj b/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj
index 8094bdf..c73a1e8 100644
--- a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj
+++ b/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj
@@ -310,6 +310,26 @@
return new AQLParser(text).parseExpression();
}
+ @Override
+ public Expression parseFunctionBody(FunctionSignature signature, List<VarIdentifier> paramList)
+ throws CompilationException {
+ return parseImpl(new ParseFunction<Expression>() {
+ @Override
+ public Expression parse() throws ParseException {
+ DataverseName dataverse = defaultDataverse;
+ defaultDataverse = signature.getDataverseName();
+ createNewScope();
+ for (VarIdentifier var : paramList) {
+ getCurrentScope().addNewVarSymbolToScope(var);
+ }
+ Expression functionBodyExpr = AQLParser.this.FunctionBody();
+ removeCurrentScope();
+ defaultDataverse = dataverse;
+ return functionBodyExpr;
+ }
+ });
+ }
+
private <T> T parseImpl(ParseFunction<T> parseFunction) throws CompilationException {
try {
return parseFunction.parse();
@@ -731,7 +751,7 @@
{
beginPos = token;
}
- functionBodyExpr = Expression() <RIGHTBRACE>
+ functionBodyExpr = FunctionBody() <RIGHTBRACE>
{
endPos = token;
functionBody = extractFragment(beginPos.beginLine, beginPos.beginColumn, endPos.beginLine, endPos.beginColumn);
@@ -746,6 +766,17 @@
}
}
+Expression FunctionBody() throws ParseException:
+{
+ Expression functionBodyExpr = null;
+}
+{
+ functionBodyExpr = Expression()
+ {
+ return functionBodyExpr;
+ }
+}
+
CreateFeedStatement FeedSpecification() throws ParseException:
{
Pair<DataverseName,Identifier> nameComponents = null;
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IParser.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IParser.java
index 662a3f9..578d954 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IParser.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IParser.java
@@ -22,12 +22,17 @@
import java.util.List;
import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.common.struct.VarIdentifier;
import org.apache.hyracks.api.exceptions.Warning;
public interface IParser {
List<Statement> parse() throws CompilationException;
+ Expression parseFunctionBody(FunctionSignature signature, List<VarIdentifier> paramList)
+ throws CompilationException;
+
/**
* Gets the warnings generated during parsing up to the max number argument.
*/
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/FunctionParser.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/FunctionParser.java
new file mode 100644
index 0000000..0bd1f84
--- /dev/null
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/FunctionParser.java
@@ -0,0 +1,67 @@
+/*
+ * 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.common.parser;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.base.IParser;
+import org.apache.asterix.lang.common.base.IParserFactory;
+import org.apache.asterix.lang.common.statement.FunctionDecl;
+import org.apache.asterix.lang.common.struct.VarIdentifier;
+import org.apache.asterix.metadata.entities.Function;
+
+public class FunctionParser {
+
+ private final String language;
+
+ private final IParserFactory parserFactory;
+
+ public FunctionParser(String language, IParserFactory parserFactory) {
+ this.language = language;
+ this.parserFactory = parserFactory;
+ }
+
+ public FunctionDecl getFunctionDecl(Function function) throws CompilationException {
+ if (!function.getLanguage().equals(language)) {
+ throw new CompilationException(ErrorCode.COMPILATION_INCOMPATIBLE_FUNCTION_LANGUAGE, language,
+ function.getLanguage());
+ }
+
+ FunctionSignature signature = function.getSignature();
+
+ List<String> argNames = function.getArgNames();
+ List<VarIdentifier> paramList = new ArrayList<>(argNames.size());
+ for (String argName : argNames) {
+ paramList.add(new VarIdentifier(argName));
+ }
+
+ String functionBody = function.getFunctionBody();
+ IParser parser = parserFactory.createParser(new StringReader(functionBody));
+ Expression functionBodyExpr = parser.parseFunctionBody(signature, paramList);
+
+ return new FunctionDecl(signature, paramList, functionBodyExpr);
+ }
+}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/FunctionParser.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/FunctionParser.java
deleted file mode 100644
index 9942e25..0000000
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/parser/FunctionParser.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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.parser;
-
-import java.io.StringReader;
-import java.util.List;
-
-import org.apache.asterix.common.exceptions.CompilationException;
-import org.apache.asterix.common.exceptions.ErrorCode;
-import org.apache.asterix.common.metadata.DataverseName;
-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.lang.common.util.DataverseNameUtils;
-import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
-import org.apache.asterix.metadata.entities.Function;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.utils.Pair;
-
-public class FunctionParser {
-
- private final IParserFactory parserFactory;
-
- public FunctionParser(IParserFactory parserFactory) {
- this.parserFactory = parserFactory;
- }
-
- public FunctionDecl getFunctionDecl(Function function) throws CompilationException {
- if (!function.getLanguage().equals(Function.LANGUAGE_SQLPP)) {
- throw new CompilationException(ErrorCode.COMPILATION_INCOMPATIBLE_FUNCTION_LANGUAGE,
- Function.LANGUAGE_SQLPP, function.getLanguage());
- }
-
- String functionBody = function.getFunctionBody();
- List<String> argNames = function.getArgNames();
- List<Pair<DataverseName, IAType>> args = function.getArguments();
-
- StringBuilder builder = new StringBuilder();
- builder.append(" use " + DataverseNameUtils.generateDataverseName(function.getDataverseName()) + ";");
- builder.append(" declare function " + function.getName().split("@")[0]);
- builder.append("(");
- for (int i = 0; i < argNames.size(); i++) {
- String param = argNames.get(i);
- String type = null;
- if (args.get(i) != null) {
- Pair<DataverseName, IAType> t = args.get(i);
- String argToStringType = t.getFirst().getCanonicalForm() + "." + t.getSecond().getTypeName();
- if (!"asterix.any".equalsIgnoreCase(argToStringType)) {
- type = argToStringType;
- }
- }
- VarIdentifier varId = SqlppVariableUtil.toUserDefinedVariableName(param);
- builder.append(varId);
- if (type != null) {
- builder.append(":");
- builder.append(type);
- }
- builder.append(",");
- }
- if (argNames.size() > 0) {
- builder.delete(builder.length() - 1, builder.length());
- }
- builder.append(")");
- builder.append("{");
- builder.append("\n");
- builder.append(functionBody);
- builder.append("\n");
- builder.append("};");
-
- IParser parser = parserFactory.createParser(new StringReader(new String(builder)));
- List<Statement> statements = parser.parse();
- FunctionDecl decl = (FunctionDecl) statements.get(1);
- return decl;
- }
-
-}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
index bde40de..1e16b70 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
@@ -22,6 +22,7 @@
import java.util.List;
import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.IParserFactory;
import org.apache.asterix.lang.common.base.IReturningStatement;
import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
import org.apache.asterix.lang.common.statement.FunctionDecl;
@@ -30,6 +31,10 @@
class SqlppFunctionBodyRewriter extends SqlppQueryRewriter {
+ public SqlppFunctionBodyRewriter(IParserFactory parserFactory) {
+ super(parserFactory);
+ }
+
@Override
public void rewrite(List<FunctionDecl> declaredFunctions, IReturningStatement topStatement,
MetadataProvider metadataProvider, LangRewritingContext context, boolean inlineUdfs,
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriterFactory.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriterFactory.java
index 900cd73..bf27464 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriterFactory.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriterFactory.java
@@ -18,15 +18,22 @@
*/
package org.apache.asterix.lang.sqlpp.rewrites;
+import org.apache.asterix.lang.common.base.IParserFactory;
import org.apache.asterix.lang.common.base.IQueryRewriter;
import org.apache.asterix.lang.common.base.IRewriterFactory;
import org.apache.asterix.lang.common.base.IStatementRewriter;
class SqlppFunctionBodyRewriterFactory implements IRewriterFactory {
+ private final IParserFactory parserFactory;
+
+ public SqlppFunctionBodyRewriterFactory(IParserFactory parserFactory) {
+ this.parserFactory = parserFactory;
+ }
+
@Override
public IQueryRewriter createQueryRewriter() {
- return new SqlppFunctionBodyRewriter();
+ return new SqlppFunctionBodyRewriter(parserFactory);
}
@Override
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 8bc319f..ccc4b26 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
@@ -28,11 +28,13 @@
import org.apache.asterix.common.functions.FunctionSignature;
import org.apache.asterix.lang.common.base.AbstractClause;
import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.base.IParserFactory;
import org.apache.asterix.lang.common.base.IQueryRewriter;
import org.apache.asterix.lang.common.base.IReturningStatement;
import org.apache.asterix.lang.common.expression.CallExpr;
import org.apache.asterix.lang.common.expression.ListSliceExpression;
import org.apache.asterix.lang.common.expression.VariableExpr;
+import org.apache.asterix.lang.common.parser.FunctionParser;
import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
import org.apache.asterix.lang.common.statement.FunctionDecl;
import org.apache.asterix.lang.common.struct.Identifier;
@@ -56,8 +58,6 @@
import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.expression.WindowExpression;
-import org.apache.asterix.lang.sqlpp.parser.FunctionParser;
-import org.apache.asterix.lang.sqlpp.parser.SqlppParserFactory;
import org.apache.asterix.lang.sqlpp.rewrites.visitor.GenerateColumnNameVisitor;
import org.apache.asterix.lang.sqlpp.rewrites.visitor.InlineColumnAliasVisitor;
import org.apache.asterix.lang.sqlpp.rewrites.visitor.InlineWithExpressionVisitor;
@@ -78,6 +78,7 @@
import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
import org.apache.asterix.metadata.declared.MetadataProvider;
+import org.apache.asterix.metadata.entities.Function;
import org.apache.hyracks.algebricks.common.utils.Pair;
import org.apache.hyracks.util.LogRedactionUtil;
import org.apache.logging.log4j.LogManager;
@@ -89,7 +90,8 @@
public static final String INLINE_WITH_OPTION = "inline_with";
private static final boolean INLINE_WITH_OPTION_DEFAULT = true;
- private final FunctionParser functionRepository = new FunctionParser(new SqlppParserFactory());
+ private final IParserFactory parserFactory;
+ private final FunctionParser functionRepository;
private IReturningStatement topExpr;
private List<FunctionDecl> declaredFunctions;
private LangRewritingContext context;
@@ -97,6 +99,11 @@
private Collection<VarIdentifier> externalVars;
private boolean isLogEnabled;
+ public SqlppQueryRewriter(IParserFactory parserFactory) {
+ this.parserFactory = parserFactory;
+ functionRepository = new FunctionParser(Function.LANGUAGE_SQLPP, parserFactory);
+ }
+
protected void setup(List<FunctionDecl> declaredFunctions, IReturningStatement topExpr,
MetadataProvider metadataProvider, LangRewritingContext context, Collection<VarIdentifier> externalVars)
throws CompilationException {
@@ -262,7 +269,8 @@
declaredFunctions.addAll(usedStoredFunctionDecls);
if (inlineUdfs && !declaredFunctions.isEmpty()) {
SqlppInlineUdfsVisitor visitor = new SqlppInlineUdfsVisitor(context,
- new SqlppFunctionBodyRewriterFactory() /* the rewriter for function bodies expressions*/,
+ new SqlppFunctionBodyRewriterFactory(
+ parserFactory) /* the rewriter for function bodies expressions*/,
declaredFunctions, metadataProvider);
while (rewriteTopExpr(visitor, declaredFunctions)) {
// loop until no more changes
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppRewriterFactory.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppRewriterFactory.java
index 64fa576..67a0243 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppRewriterFactory.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppRewriterFactory.java
@@ -18,15 +18,22 @@
*/
package org.apache.asterix.lang.sqlpp.rewrites;
+import org.apache.asterix.lang.common.base.IParserFactory;
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 SqlppRewriterFactory implements IRewriterFactory {
+ private final IParserFactory parserFactory;
+
+ public SqlppRewriterFactory(IParserFactory parserFactory) {
+ this.parserFactory = parserFactory;
+ }
+
@Override
public IQueryRewriter createQueryRewriter() {
- return new SqlppQueryRewriter();
+ return new SqlppQueryRewriter(parserFactory);
}
@Override
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index fcd06eb..feff5c5 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -325,6 +325,7 @@
//st.accept(new SQLPPPrintVisitor(), 0);
}
+ @Override
public List<Statement> parse() throws CompilationException {
return parseImpl(new ParseFunction<List<Statement>>() {
@Override
@@ -347,6 +348,23 @@
return new SQLPPParser(text).parseExpression();
}
+ @Override
+ public Expression parseFunctionBody(FunctionSignature signature, List<VarIdentifier> paramList)
+ throws CompilationException {
+ return parseImpl(new ParseFunction<Expression>() {
+ @Override
+ public Expression parse() throws ParseException {
+ DataverseName dataverse = defaultDataverse;
+ defaultDataverse = signature.getDataverseName();
+ createNewScope();
+ Expression functionBodyExpr = SQLPPParser.this.FunctionBody();
+ removeCurrentScope();
+ defaultDataverse = dataverse;
+ return functionBodyExpr;
+ }
+ });
+ }
+
private <T> T parseImpl(ParseFunction<T> parseFunction) throws CompilationException {
warningCollector.clear();
hintCollector.clear();
@@ -1079,7 +1097,7 @@
createNewScope();
beginPos = token;
}
- (functionBodyExpr = SelectExpression(true) | functionBodyExpr = Expression())
+ functionBodyExpr = FunctionBody()
<RIGHTBRACE>{
endPos = token;
functionBody = extractFragment(beginPos.beginLine, beginPos.beginColumn, endPos.beginLine, endPos.beginColumn);
@@ -1096,11 +1114,12 @@
(
LOOKAHEAD({laIdentifier(INLINE)})
(
- <IDENTIFIER> <AS> {
+ <IDENTIFIER> <AS>
+ {
createNewScope();
beginPos = token;
}
- (functionBodyExpr = SelectExpression(true) | functionBodyExpr = Expression())
+ functionBodyExpr = FunctionBody()
{
endPos = token;
functionBody = extractFragment(beginPos.endLine, beginPos.beginColumn+1, endPos.endLine, endPos.endColumn+1);
@@ -1137,6 +1156,17 @@
)
}
+Expression FunctionBody() throws ParseException:
+{
+ Expression functionBodyExpr = null;
+}
+{
+ ( functionBodyExpr = SelectExpression(true) | functionBodyExpr = Expression() )
+ {
+ return functionBodyExpr;
+ }
+}
+
CreateFeedStatement CreateFeedStatement(Token startStmtToken) throws ParseException:
{
CreateFeedStatement stmt = null;