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 2020/02/03 22:36:56 UTC
[asterixdb] branch master updated: [NO ISSUE][COMP] Improve
function parsing
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 45de234 [NO ISSUE][COMP] Improve function parsing
45de234 is described below
commit 45de2345f100e89579dc2d0e3169c837e6a30e50
Author: Dmitry Lychagin <dm...@couchbase.com>
AuthorDate: Mon Feb 3 12:01:28 2020 -0800
[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 <je...@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
Reviewed-by: Dmitry Lychagin <dm...@couchbase.com>
Reviewed-by: Ian Maxon <im...@uci.edu>
---
.../compiler/provider/AqlCompilationProvider.java | 2 +-
.../provider/SqlppCompilationProvider.java | 2 +-
.../asterix/test/sqlpp/ParserTestExecutor.java | 2 +-
asterixdb/asterix-lang-aql/pom.xml | 4 -
.../lang/aql/rewrites/AQLRewriterFactory.java | 9 +-
.../lang/aql/rewrites/AqlQueryRewriter.java | 17 ++--
asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj | 33 +++++++-
.../apache/asterix/lang/common/base/IParser.java | 5 ++
.../lang/common}/parser/FunctionParser.java | 50 +++++-------
.../asterix/lang/sqlpp/parser/FunctionParser.java | 95 ----------------------
.../sqlpp/rewrites/SqlppFunctionBodyRewriter.java | 5 ++
.../rewrites/SqlppFunctionBodyRewriterFactory.java | 9 +-
.../lang/sqlpp/rewrites/SqlppQueryRewriter.java | 16 +++-
.../lang/sqlpp/rewrites/SqlppRewriterFactory.java | 9 +-
.../asterix-lang-sqlpp/src/main/javacc/SQLPP.jj | 36 +++++++-
15 files changed, 147 insertions(+), 147 deletions(-)
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 @@ public class AqlCompilationProvider implements ILangCompilationProvider {
@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 @@ public class SqlppCompilationProvider implements ILangCompilationProvider {
@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 @@ import junit.extensions.PA;
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/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.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.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.clause.LetClause;
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.CommonFunctionMapUtil;
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 @@ class AqlQueryRewriter implements IQueryRewriter {
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 @@ class AQLParser extends ScopeChecker implements IParser {
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 @@ CreateFunctionStatement FunctionSpecification() throws ParseException:
{
beginPos = token;
}
- functionBodyExpr = Expression() <RIGHTBRACE>
+ functionBodyExpr = FunctionBody() <RIGHTBRACE>
{
endPos = token;
functionBody = extractFragment(beginPos.beginLine, beginPos.beginColumn, endPos.beginLine, endPos.beginColumn);
@@ -746,6 +766,17 @@ CreateFunctionStatement FunctionSpecification() throws ParseException:
}
}
+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.Collection;
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-aql/src/main/java/org/apache/asterix/lang/aql/parser/FunctionParser.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/FunctionParser.java
similarity index 55%
rename from asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/parser/FunctionParser.java
rename to asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/FunctionParser.java
index adaeaaf..0bd1f84 100644
--- a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/parser/FunctionParser.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/FunctionParser.java
@@ -17,59 +17,51 @@
* under the License.
*/
-package org.apache.asterix.lang.aql.parser;
+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.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 String language;
+
private final IParserFactory parserFactory;
- public FunctionParser(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(Function.LANGUAGE_AQL)) {
- throw new CompilationException(ErrorCode.COMPILATION_INCOMPATIBLE_FUNCTION_LANGUAGE, Function.LANGUAGE_AQL,
+ if (!function.getLanguage().equals(language)) {
+ throw new CompilationException(ErrorCode.COMPILATION_INCOMPATIBLE_FUNCTION_LANGUAGE, language,
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);
+ 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));
}
- 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;
- }
+ 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.Collection;
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 @@ import org.apache.asterix.metadata.declared.MetadataProvider;
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.exceptions.CompilationException;
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.clause.UnnestClause;
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.SqlppAstPrintUtil;
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 class SqlppQueryRewriter implements IQueryRewriter {
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 @@ public class SqlppQueryRewriter implements IQueryRewriter {
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 @@ public class SqlppQueryRewriter implements IQueryRewriter {
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 @@ class SQLPPParser extends ScopeChecker implements IParser {
//st.accept(new SQLPPPrintVisitor(), 0);
}
+ @Override
public List<Statement> parse() throws CompilationException {
return parseImpl(new ParseFunction<List<Statement>>() {
@Override
@@ -347,6 +348,23 @@ class SQLPPParser extends ScopeChecker implements IParser {
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 @@ CreateFunctionStatement FunctionSpecification(Token startStmtToken) throws Parse
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 @@ CreateFunctionStatement FunctionSpecification(Token startStmtToken) throws Parse
(
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 @@ CreateFunctionStatement FunctionSpecification(Token startStmtToken) throws Parse
)
}
+Expression FunctionBody() throws ParseException:
+{
+ Expression functionBodyExpr = null;
+}
+{
+ ( functionBodyExpr = SelectExpression(true) | functionBodyExpr = Expression() )
+ {
+ return functionBodyExpr;
+ }
+}
+
CreateFeedStatement CreateFeedStatement(Token startStmtToken) throws ParseException:
{
CreateFeedStatement stmt = null;