Taewoo Kim has submitted this change and it was merged. Change subject: AQLPlus Refactoring 2: AQL+ grammar generation and AQLPlusExpressionToPlanTranslator ......................................................................
AQLPlus Refactoring 2: AQL+ grammar generation and AQLPlusExpressionToPlanTranslator - Apply a systematic way of generating AQL+ grammar from AQL grammar instead of having a separate grammar file and updating it by hand. - Refactor AQLPlusExpressionToPlanTranslator so that it extends AQLExpressionToPlanTranslator. This makes this class now follows the current translation logic and it doesn't have to manually updated for AQL expressions. Change-Id: I444dbf4f615c23ccd69a5e4bb1ead300d0a81451 Reviewed-on: https://asterix-gerrit.ics.uci.edu/1434 Sonar-Qube: Jenkins <[email protected]> Tested-by: Jenkins <[email protected]> Integration-Tests: Jenkins <[email protected]> Reviewed-by: Yingyi Bu <[email protected]> --- M asterixdb/asterix-algebra/pom.xml M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/FuzzyJoinRule.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlExpressionToPlanTranslator.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlPlusExpressionToPlanTranslator.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java D asterixdb/asterix-algebra/src/main/javacc/AQLPlus.jj A asterixdb/asterix-algebra/src/main/javacc/AQLPlusExtension.jj M asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java M asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties M asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj 10 files changed, 307 insertions(+), 3,059 deletions(-) Approvals: Yingyi Bu: Looks good to me, approved Jenkins: Verified; No violations found; Verified Objections: Jenkins: Violations found diff --git a/asterixdb/asterix-algebra/pom.xml b/asterixdb/asterix-algebra/pom.xml index 5a723b3..aa0ea27 100644 --- a/asterixdb/asterix-algebra/pom.xml +++ b/asterixdb/asterix-algebra/pom.xml @@ -40,6 +40,28 @@ <build> <plugins> <plugin> + <groupId>org.apache.asterix</groupId> + <artifactId>asterix-grammar-extension-maven-plugin</artifactId> + <version>${project.version}</version> + <configuration> + <base>${project.basedir}</base> + <gbase>../asterix-lang-aql/src/main/javacc/AQL.jj</gbase> + <gextension>src/main/javacc/AQLPlusExtension.jj</gextension> + <output>target/generated-resources/javacc/AQLPlus.jj</output> + <parserClassModifier>public</parserClassModifier> + <parserClassName>AQLPlusParser</parserClassName> + <packageName>org.apache.asterix.aqlplus.parser</packageName> + </configuration> + <executions> + <execution> + <phase>generate-sources</phase> + <goals> + <goal>grammarix</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>javacc-maven-plugin</artifactId> <version>2.6</version> @@ -51,6 +73,26 @@ </goals> <configuration> <isStatic>false</isStatic> + <sourceDirectory>target/generated-resources/javacc</sourceDirectory> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <version>1.9</version> + <executions> + <execution> + <id>add-source</id> + <phase>generate-sources</phase> + <goals> + <goal>add-source</goal> + </goals> + <configuration> + <sources> + <source>target/generated-sources/javacc/</source> + </sources> </configuration> </execution> </executions> diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/FuzzyJoinRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/FuzzyJoinRule.java index 67c33d4..f3f5581 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/FuzzyJoinRule.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/FuzzyJoinRule.java @@ -261,8 +261,7 @@ } // The translator will compile metadata internally. Run this compilation // under the same transaction id as the "outer" compilation. - AqlPlusExpressionToPlanTranslator translator = new AqlPlusExpressionToPlanTranslator( - metadataProvider.getJobId(), metadataProvider, counter, null, null); + AqlPlusExpressionToPlanTranslator translator = new AqlPlusExpressionToPlanTranslator(metadataProvider, counter); context.setVarCounter(counter.get()); LogicalOperatorDeepCopyWithNewVariablesVisitor deepCopyVisitor = new LogicalOperatorDeepCopyWithNewVariablesVisitor( diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlExpressionToPlanTranslator.java index 110c2b7..62b71df 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlExpressionToPlanTranslator.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlExpressionToPlanTranslator.java @@ -40,6 +40,7 @@ import org.apache.commons.lang3.mutable.MutableObject; import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; import org.apache.hyracks.algebricks.common.utils.Pair; +import org.apache.hyracks.algebricks.core.algebra.base.Counter; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator; import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag; @@ -64,7 +65,13 @@ class AqlExpressionToPlanTranslator extends LangExpressionToPlanTranslator implements ILangExpressionToPlanTranslator, IAQLVisitor<Pair<ILogicalOperator, LogicalVariable>, Mutable<ILogicalOperator>> { - public AqlExpressionToPlanTranslator(MetadataProvider metadataProvider, int currentVarCounter) + public AqlExpressionToPlanTranslator(MetadataProvider metadataProvider, int currentVarCounterValue) + throws AlgebricksException { + super(metadataProvider, currentVarCounterValue); + } + + // Keeps the given Counter if one is provided instead of a value. + public AqlExpressionToPlanTranslator(MetadataProvider metadataProvider, Counter currentVarCounter) throws AlgebricksException { super(metadataProvider, currentVarCounter); } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlPlusExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlPlusExpressionToPlanTranslator.java index 5eb5a5f..18304b3 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlPlusExpressionToPlanTranslator.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AqlPlusExpressionToPlanTranslator.java @@ -20,282 +20,58 @@ import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.List; -import java.util.Map.Entry; -import java.util.logging.Logger; -import org.apache.asterix.common.config.DatasetConfig.DatasetType; import org.apache.asterix.common.exceptions.CompilationException; -import org.apache.asterix.common.functions.FunctionConstants; -import org.apache.asterix.common.functions.FunctionSignature; -import org.apache.asterix.common.transactions.JobId; -import org.apache.asterix.formats.base.IDataFormat; -import org.apache.asterix.lang.aql.clause.DistinctClause; -import org.apache.asterix.lang.aql.clause.ForClause; +import org.apache.asterix.common.exceptions.ErrorCode; import org.apache.asterix.lang.aql.clause.JoinClause; import org.apache.asterix.lang.aql.clause.MetaVariableClause; -import org.apache.asterix.lang.aql.expression.FLWOGRExpression; import org.apache.asterix.lang.aql.expression.MetaVariableExpr; -import org.apache.asterix.lang.aql.expression.UnionExpr; import org.apache.asterix.lang.aql.visitor.base.IAQLPlusVisitor; 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.clause.GroupbyClause; -import org.apache.asterix.lang.common.clause.LetClause; -import org.apache.asterix.lang.common.clause.LimitClause; -import org.apache.asterix.lang.common.clause.OrderbyClause; -import org.apache.asterix.lang.common.clause.OrderbyClause.OrderModifier; -import org.apache.asterix.lang.common.clause.UpdateClause; -import org.apache.asterix.lang.common.clause.WhereClause; -import org.apache.asterix.lang.common.expression.CallExpr; -import org.apache.asterix.lang.common.expression.FieldAccessor; -import org.apache.asterix.lang.common.expression.FieldBinding; -import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair; -import org.apache.asterix.lang.common.expression.IfExpr; -import org.apache.asterix.lang.common.expression.IndexAccessor; -import org.apache.asterix.lang.common.expression.ListConstructor; -import org.apache.asterix.lang.common.expression.ListConstructor.Type; -import org.apache.asterix.lang.common.expression.LiteralExpr; -import org.apache.asterix.lang.common.expression.OperatorExpr; -import org.apache.asterix.lang.common.expression.OrderedListTypeDefinition; -import org.apache.asterix.lang.common.expression.QuantifiedExpression; -import org.apache.asterix.lang.common.expression.QuantifiedExpression.Quantifier; -import org.apache.asterix.lang.common.expression.RecordConstructor; -import org.apache.asterix.lang.common.expression.RecordTypeDefinition; -import org.apache.asterix.lang.common.expression.TypeReferenceExpression; -import org.apache.asterix.lang.common.expression.UnaryExpr; -import org.apache.asterix.lang.common.expression.UnorderedListTypeDefinition; import org.apache.asterix.lang.common.expression.VariableExpr; -import org.apache.asterix.lang.common.statement.CompactStatement; -import org.apache.asterix.lang.common.statement.ConnectFeedStatement; -import org.apache.asterix.lang.common.statement.CreateDataverseStatement; -import org.apache.asterix.lang.common.statement.CreateFeedPolicyStatement; -import org.apache.asterix.lang.common.statement.CreateFunctionStatement; -import org.apache.asterix.lang.common.statement.CreateIndexStatement; -import org.apache.asterix.lang.common.statement.CreatePrimaryFeedStatement; -import org.apache.asterix.lang.common.statement.CreateSecondaryFeedStatement; -import org.apache.asterix.lang.common.statement.DatasetDecl; -import org.apache.asterix.lang.common.statement.DataverseDecl; -import org.apache.asterix.lang.common.statement.DataverseDropStatement; -import org.apache.asterix.lang.common.statement.DeleteStatement; -import org.apache.asterix.lang.common.statement.DisconnectFeedStatement; -import org.apache.asterix.lang.common.statement.DropDatasetStatement; -import org.apache.asterix.lang.common.statement.FeedDropStatement; -import org.apache.asterix.lang.common.statement.FeedPolicyDropStatement; -import org.apache.asterix.lang.common.statement.FunctionDecl; -import org.apache.asterix.lang.common.statement.FunctionDropStatement; -import org.apache.asterix.lang.common.statement.IndexDropStatement; -import org.apache.asterix.lang.common.statement.InsertStatement; -import org.apache.asterix.lang.common.statement.LoadStatement; -import org.apache.asterix.lang.common.statement.NodeGroupDropStatement; -import org.apache.asterix.lang.common.statement.NodegroupDecl; -import org.apache.asterix.lang.common.statement.Query; -import org.apache.asterix.lang.common.statement.SetStatement; -import org.apache.asterix.lang.common.statement.TypeDecl; -import org.apache.asterix.lang.common.statement.TypeDropStatement; -import org.apache.asterix.lang.common.statement.UpdateStatement; -import org.apache.asterix.lang.common.statement.WriteStatement; import org.apache.asterix.lang.common.struct.Identifier; -import org.apache.asterix.lang.common.struct.OperatorType; -import org.apache.asterix.lang.common.struct.QuantifiedPair; -import org.apache.asterix.lang.common.struct.UnaryExprType; -import org.apache.asterix.lang.common.util.FunctionUtil; -import org.apache.asterix.metadata.declared.FileSplitDataSink; -import org.apache.asterix.metadata.declared.FileSplitSinkId; import org.apache.asterix.metadata.declared.MetadataProvider; -import org.apache.asterix.metadata.entities.Dataset; -import org.apache.asterix.metadata.utils.DatasetUtil; -import org.apache.asterix.om.base.AString; -import org.apache.asterix.om.constants.AsterixConstantValue; -import org.apache.asterix.om.functions.BuiltinFunctions; -import org.apache.asterix.om.functions.FunctionInfo; -import org.apache.asterix.om.types.ARecordType; -import org.apache.asterix.om.types.BuiltinType; -import org.apache.asterix.om.types.IAType; -import org.apache.asterix.translator.CompiledStatements.ICompiledDmlStatement; -import org.apache.asterix.translator.util.FunctionCollection; import org.apache.commons.lang3.mutable.Mutable; import org.apache.commons.lang3.mutable.MutableObject; import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; -import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException; import org.apache.hyracks.algebricks.common.utils.Pair; -import org.apache.hyracks.algebricks.common.utils.Triple; import org.apache.hyracks.algebricks.core.algebra.base.Counter; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan; -import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag; import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable; -import org.apache.hyracks.algebricks.core.algebra.base.OperatorAnnotations; -import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression; -import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind; -import org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression; -import org.apache.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation; -import org.apache.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation.BroadcastSide; -import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression; -import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression; -import org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression; import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression; -import org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions; -import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; -import org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo; import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.DistinctOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator; -import org.apache.hyracks.algebricks.core.algebra.operators.logical.WriteOperator; import org.apache.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl; -import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory; /** - * Each visit returns a pair of an operator and a variable. The variable - * corresponds to the new column, if any, added to the tuple flow. E.g., for - * Unnest, the column is the variable bound to the elements in the list, for - * Subplan it is null. The first argument of a visit method is the expression - * which is translated. The second argument of a visit method is the tuple - * source for the current subtree. + * This class is an extension of AQLExpressionToPlanTranslator. Specifically, it contains the visitor for + * three extensions (MetaVariable, MetaClause, and JoinClause) to AQL in AQL+. + * Meta-Variable ($$) refers the primary key or variable(s) in the logical plan. + * Meta-Clause (##) refers the operator in the logical plan. + * Join-Clause (join, loj) is required to build an explicit join in AQL level. + * For more details of AQL+, refer to this thesis: www.ics.uci.edu/~rares/pub/phd-thesis-vernica.pdf */ -public class AqlPlusExpressionToPlanTranslator extends AbstractLangTranslator +public class AqlPlusExpressionToPlanTranslator extends AqlExpressionToPlanTranslator implements IAQLPlusVisitor<Pair<ILogicalOperator, LogicalVariable>, Mutable<ILogicalOperator>> { - - private static final Logger LOGGER = Logger.getLogger(AqlPlusExpressionToPlanTranslator.class.getName()); - - private class MetaScopeLogicalVariable { - private HashMap<Identifier, LogicalVariable> map = new HashMap<Identifier, LogicalVariable>(); - - public VariableReferenceExpression getVariableReferenceExpression(Identifier id) throws CompilationException { - LogicalVariable var = map.get(id); - LOGGER.fine("get:" + id + ":" + var); - if (var == null) { - throw new CompilationException("Identifier " + id + " not found in AQL+ meta-scope."); - } - return new VariableReferenceExpression(var); - } - - public void put(Identifier id, LogicalVariable var) { - LOGGER.fine("put:" + id + ":" + var); - map.put(id, var); - } - } - - private class MetaScopeILogicalOperator { - private HashMap<Identifier, ILogicalOperator> map = new HashMap<Identifier, ILogicalOperator>(); - - public ILogicalOperator get(Identifier id) throws CompilationException { - ILogicalOperator op = map.get(id); - if (op == null) { - throw new CompilationException("Identifier " + id + " not found in AQL+ meta-scope."); - } - return op; - } - - public void put(Identifier id, ILogicalOperator op) { - LOGGER.fine("put:" + id + ":" + op); - map.put(id, op); - } - } - - private final JobId jobId; - private TranslationContext context; - private String outputDatasetName; - private ICompiledDmlStatement stmt; private MetaScopeLogicalVariable metaScopeExp = new MetaScopeLogicalVariable(); private MetaScopeILogicalOperator metaScopeOp = new MetaScopeILogicalOperator(); - private static LogicalVariable METADATA_DUMMY_VAR = new LogicalVariable(-1); - public AqlPlusExpressionToPlanTranslator(JobId jobId, MetadataProvider metadataProvider, - Counter currentVarCounter, String outputDatasetName, ICompiledDmlStatement stmt) { - this.jobId = jobId; - this.context = new TranslationContext(currentVarCounter); - this.outputDatasetName = outputDatasetName; - this.stmt = stmt; + public AqlPlusExpressionToPlanTranslator(MetadataProvider metadataProvider, Counter currentVarCounter) + throws AlgebricksException { + super(metadataProvider, currentVarCounter); this.context.setTopFlwor(false); } - public int getVarCounter() { - return context.getVarCounter(); - } - - public ILogicalPlan translate(Query expr) throws AlgebricksException, CompilationException { - return translate(expr, null); - } - - public ILogicalPlan translate(Query expr, MetadataProvider metadata) - throws AlgebricksException, CompilationException { - IDataFormat format = metadata.getFormat(); - if (format == null) { - throw new AlgebricksException("Data format has not been set."); - } - format.registerRuntimeFunctions(FunctionCollection.getFunctionDescriptorFactories()); - Pair<ILogicalOperator, LogicalVariable> p = - expr.accept(this, new MutableObject<ILogicalOperator>(new EmptyTupleSourceOperator())); - - ArrayList<Mutable<ILogicalOperator>> globalPlanRoots = new ArrayList<Mutable<ILogicalOperator>>(); - - boolean isTransactionalWrite = false; - ILogicalOperator topOp = p.first; - ProjectOperator project = (ProjectOperator) topOp; - LogicalVariable resVar = project.getVariables().get(0); - if (outputDatasetName == null) { - List<Mutable<ILogicalExpression>> writeExprList = new ArrayList<Mutable<ILogicalExpression>>(1); - writeExprList.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(resVar))); - FileSplitSinkId fssi = new FileSplitSinkId(metadata.getOutputFile()); - FileSplitDataSink sink = new FileSplitDataSink(fssi, null); - topOp = new WriteOperator(writeExprList, sink); - topOp.getInputs().add(new MutableObject<ILogicalOperator>(project)); - } else { - Dataset dataset = metadata.findDataset(stmt.getDataverseName(), outputDatasetName); - if (dataset == null) { - throw new AlgebricksException("Cannot find dataset " + outputDatasetName); - } - if (dataset.getDatasetType() == DatasetType.EXTERNAL) { - throw new AlgebricksException("Cannot write output to an external dataset."); - } - ARecordType itemType = - (ARecordType) metadata.findType(dataset.getItemTypeDataverseName(), dataset.getItemTypeName()); - List<List<String>> partitioningKeys = DatasetUtil.getPartitioningKeys(dataset); - ArrayList<LogicalVariable> vars = new ArrayList<LogicalVariable>(); - ArrayList<Mutable<ILogicalExpression>> exprs = new ArrayList<Mutable<ILogicalExpression>>(); - List<Mutable<ILogicalExpression>> varRefsForLoading = new ArrayList<Mutable<ILogicalExpression>>(); - for (List<String> partitioningKey : partitioningKeys) { - Triple<IScalarEvaluatorFactory, ScalarFunctionCallExpression, IAType> partitioner = - format.partitioningEvaluatorFactory(itemType, partitioningKey); - AbstractFunctionCallExpression f = partitioner.second.cloneExpression(); - f.substituteVar(METADATA_DUMMY_VAR, resVar); - exprs.add(new MutableObject<ILogicalExpression>(f)); - LogicalVariable v = context.newVar(); - vars.add(v); - varRefsForLoading.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(v))); - } - AssignOperator assign = new AssignOperator(vars, exprs); - assign.getInputs().add(new MutableObject<ILogicalOperator>(project)); - } - - globalPlanRoots.add(new MutableObject<ILogicalOperator>(topOp)); - ILogicalPlan plan = new ALogicalPlanImpl(globalPlanRoots); - return plan; - } - public ILogicalPlan translate(List<Clause> clauses) throws AlgebricksException, CompilationException { - if (clauses == null) { return null; } @@ -317,933 +93,6 @@ } @Override - public Pair<ILogicalOperator, LogicalVariable> visit(ForClause fc, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - LogicalVariable v = context.newVar(fc.getVarExpr()); - - Expression inExpr = fc.getInExpr(); - Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = aqlExprToAlgExpression(inExpr, tupSource); - ILogicalOperator returnedOp; - - if (fc.getPosVarExpr() == null) { - returnedOp = new UnnestOperator(v, new MutableObject<ILogicalExpression>(makeUnnestExpression(eo.first))); - } else { - LogicalVariable pVar = context.newVar(fc.getPosVarExpr()); - returnedOp = new UnnestOperator(v, new MutableObject<ILogicalExpression>(makeUnnestExpression(eo.first)), - pVar, BuiltinType.AINT32, new PositionWriter()); - } - returnedOp.getInputs().add(eo.second); - - return new Pair<ILogicalOperator, LogicalVariable>(returnedOp, v); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(LetClause lc, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - LogicalVariable v; - ILogicalOperator returnedOp; - - switch (lc.getBindingExpr().getKind()) { - case VARIABLE_EXPRESSION: { - v = context.newVar(lc.getVarExpr()); - LogicalVariable prev = context.getVar(((VariableExpr) lc.getBindingExpr()).getVar().getId()); - returnedOp = new AssignOperator(v, - new MutableObject<ILogicalExpression>(new VariableReferenceExpression(prev))); - returnedOp.getInputs().add(tupSource); - break; - } - default: { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = - aqlExprToAlgExpression(lc.getBindingExpr(), tupSource); - v = context.newVar(lc.getVarExpr()); - returnedOp = new AssignOperator(v, new MutableObject<ILogicalExpression>(eo.first)); - returnedOp.getInputs().add(eo.second); - break; - } - } - return new Pair<ILogicalOperator, LogicalVariable>(returnedOp, v); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(FLWOGRExpression flwor, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - Mutable<ILogicalOperator> flworPlan = tupSource; - boolean isTop = context.isTopFlwor(); - if (isTop) { - context.setTopFlwor(false); - } - for (Clause c : flwor.getClauseList()) { - Pair<ILogicalOperator, LogicalVariable> pC = c.accept(this, flworPlan); - flworPlan = new MutableObject<ILogicalOperator>(pC.first); - } - - Expression r = flwor.getReturnExpr(); - boolean noFlworClause = flwor.noForClause(); - - if (r.getKind() == Kind.VARIABLE_EXPRESSION) { - VariableExpr v = (VariableExpr) r; - LogicalVariable var = context.getVar(v.getVar().getId()); - - return produceFlwrResult(noFlworClause, isTop, flworPlan, var); - - } else { - Mutable<ILogicalOperator> baseOp = new MutableObject<ILogicalOperator>(flworPlan.getValue()); - Pair<ILogicalOperator, LogicalVariable> rRes = r.accept(this, baseOp); - ILogicalOperator rOp = rRes.first; - ILogicalOperator resOp; - if (expressionNeedsNoNesting(r)) { - baseOp.setValue(flworPlan.getValue()); - resOp = rOp; - } else { - SubplanOperator s = new SubplanOperator(rOp); - s.getInputs().add(flworPlan); - resOp = s; - baseOp.setValue(new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(s))); - } - Mutable<ILogicalOperator> resOpRef = new MutableObject<ILogicalOperator>(resOp); - return produceFlwrResult(noFlworClause, isTop, resOpRef, rRes.second); - } - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(FieldAccessor fa, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> p = aqlExprToAlgExpression(fa.getExpr(), tupSource); - LogicalVariable v = context.newVar(); - AbstractFunctionCallExpression fldAccess = new ScalarFunctionCallExpression( - FunctionUtil.getFunctionInfo(BuiltinFunctions.FIELD_ACCESS_BY_NAME)); - fldAccess.getArguments().add(new MutableObject<ILogicalExpression>(p.first)); - ILogicalExpression faExpr = - new ConstantExpression(new AsterixConstantValue(new AString(fa.getIdent().getValue()))); - fldAccess.getArguments().add(new MutableObject<ILogicalExpression>(faExpr)); - AssignOperator a = new AssignOperator(v, new MutableObject<ILogicalExpression>(fldAccess)); - a.getInputs().add(p.second); - return new Pair<ILogicalOperator, LogicalVariable>(a, v); - - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(IndexAccessor ia, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> p = aqlExprToAlgExpression(ia.getExpr(), tupSource); - LogicalVariable v = context.newVar(); - AbstractFunctionCallExpression f; - if (ia.isAny()) { - f = new ScalarFunctionCallExpression( - FunctionUtil.getFunctionInfo(BuiltinFunctions.ANY_COLLECTION_MEMBER)); - f.getArguments().add(new MutableObject<ILogicalExpression>(p.first)); - } else { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> indexPair = - aqlExprToAlgExpression(ia.getIndexExpr(), tupSource); - f = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.GET_ITEM)); - f.getArguments().add(new MutableObject<ILogicalExpression>(p.first)); - f.getArguments().add(new MutableObject<ILogicalExpression>(indexPair.first)); - } - AssignOperator a = new AssignOperator(v, new MutableObject<ILogicalExpression>(f)); - a.getInputs().add(p.second); - return new Pair<ILogicalOperator, LogicalVariable>(a, v); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(CallExpr fcall, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - LogicalVariable v = context.newVar(); - FunctionSignature signature = fcall.getFunctionSignature(); - List<Mutable<ILogicalExpression>> args = new ArrayList<Mutable<ILogicalExpression>>(); - Mutable<ILogicalOperator> topOp = tupSource; - - for (Expression expr : fcall.getExprList()) { - switch (expr.getKind()) { - case VARIABLE_EXPRESSION: { - LogicalVariable var = context.getVar(((VariableExpr) expr).getVar().getId()); - args.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(var))); - break; - } - case LITERAL_EXPRESSION: { - LiteralExpr val = (LiteralExpr) expr; - args.add(new MutableObject<ILogicalExpression>(new ConstantExpression( - new AsterixConstantValue(ConstantHelper.objectFromLiteral(val.getValue()))))); - break; - } - default: { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = aqlExprToAlgExpression(expr, topOp); - AbstractLogicalOperator o1 = (AbstractLogicalOperator) eo.second.getValue(); - args.add(new MutableObject<ILogicalExpression>(eo.first)); - if (o1 != null && !(o1.getOperatorTag() == LogicalOperatorTag.ASSIGN && hasOnlyChild(o1, topOp))) { - topOp = eo.second; - } - break; - } - } - } - - FunctionIdentifier fi = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS, signature.getName()); - FunctionInfo afi = BuiltinFunctions.lookupFunction(fi); - FunctionIdentifier builtinAquafi = afi == null ? null : afi.getFunctionIdentifier(); - - if (builtinAquafi != null) { - fi = builtinAquafi; - } else { - fi = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, signature.getName()); - FunctionIdentifier builtinAsterixFi = BuiltinFunctions.getBuiltinFunctionIdentifier(fi); - if (builtinAsterixFi != null) { - fi = builtinAsterixFi; - } - } - AbstractFunctionCallExpression f; - if (BuiltinFunctions.isBuiltinAggregateFunction(fi)) { - f = BuiltinFunctions.makeAggregateFunctionExpression(fi, args); - } else if (BuiltinFunctions.isBuiltinUnnestingFunction(fi)) { - UnnestingFunctionCallExpression ufce = - new UnnestingFunctionCallExpression(FunctionUtil.getFunctionInfo(fi), args); - ufce.setReturnsUniqueValues(BuiltinFunctions.returnsUniqueValues(fi)); - f = ufce; - } else { - f = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(fi), args); - } - AssignOperator op = new AssignOperator(v, new MutableObject<ILogicalExpression>(f)); - if (topOp != null) { - op.getInputs().add(topOp); - } - - return new Pair<ILogicalOperator, LogicalVariable>(op, v); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(FunctionDecl fd, Mutable<ILogicalOperator> tupSource) { - // TODO Auto-generated method stub - throw new NotImplementedException(); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(GroupbyClause gc, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - GroupByOperator gOp = new GroupByOperator(); - Mutable<ILogicalOperator> topOp = tupSource; - for (GbyVariableExpressionPair ve : gc.getGbyPairList()) { - LogicalVariable v; - VariableExpr vexpr = ve.getVar(); - if (vexpr != null) { - v = context.newVar(vexpr); - } else { - v = context.newVar(); - } - Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = aqlExprToAlgExpression(ve.getExpr(), topOp); - gOp.addGbyExpression(v, eo.first); - topOp = eo.second; - } - for (GbyVariableExpressionPair ve : gc.getDecorPairList()) { - LogicalVariable v; - VariableExpr vexpr = ve.getVar(); - if (vexpr != null) { - v = context.newVar(vexpr); - } else { - v = context.newVar(); - } - Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = aqlExprToAlgExpression(ve.getExpr(), topOp); - gOp.addDecorExpression(v, eo.first); - topOp = eo.second; - } - gOp.getInputs().add(topOp); - - for (Entry<Expression, VariableExpr> entry : gc.getWithVarMap().entrySet()) { - LogicalVariable aggVar = context.newVar(); - Pair<ILogicalExpression, Mutable<ILogicalOperator>> listifyInput = aqlExprToAlgExpression(entry.getKey(), - new MutableObject<>(new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(gOp)))); - List<Mutable<ILogicalExpression>> flArgs = new ArrayList<>(1); - flArgs.add(new MutableObject<>(listifyInput.first)); - AggregateFunctionCallExpression fListify = - BuiltinFunctions.makeAggregateFunctionExpression(BuiltinFunctions.LISTIFY, flArgs); - AggregateOperator agg = new AggregateOperator(mkSingletonArrayList(aggVar), - mkSingletonArrayList(new MutableObject<>(fListify))); - agg.getInputs().add(listifyInput.second); - ILogicalPlan plan = new ALogicalPlanImpl(new MutableObject<>(agg)); - gOp.getNestedPlans().add(plan); - // Hide the variable that was part of the "with", replacing it with - // the one bound by the aggregation op. - context.setVar(entry.getValue(), aggVar); - } - gOp.setGroupAll(gc.isGroupAll()); - gOp.getAnnotations().put(OperatorAnnotations.USE_HASH_GROUP_BY, gc.hasHashGroupByHint()); - return new Pair<ILogicalOperator, LogicalVariable>(gOp, null); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(IfExpr ifexpr, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - // In the most general case, IfThenElse is translated in the following - // way. - // - // We assign the result of the condition to one variable varCond. - // We create one subplan which contains the plan for the "then" branch, - // on top of which there is a selection whose condition is varCond. - // Similarly, we create one subplan for the "else" branch, in which the - // selection is not(varCond). - // Finally, we concatenate the results. (??) - - Pair<ILogicalOperator, LogicalVariable> pCond = ifexpr.getCondExpr().accept(this, tupSource); - ILogicalOperator opCond = pCond.first; - LogicalVariable varCond = pCond.second; - - SubplanOperator sp = new SubplanOperator(); - Mutable<ILogicalOperator> nestedSource = new MutableObject<ILogicalOperator>( - new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(sp))); - - Pair<ILogicalOperator, LogicalVariable> pThen = ifexpr.getThenExpr().accept(this, nestedSource); - SelectOperator sel1 = new SelectOperator( - new MutableObject<ILogicalExpression>(new VariableReferenceExpression(varCond)), false, null); - sel1.getInputs().add(new MutableObject<ILogicalOperator>(pThen.first)); - - Pair<ILogicalOperator, LogicalVariable> pElse = ifexpr.getElseExpr().accept(this, nestedSource); - AbstractFunctionCallExpression notVarCond = - new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(AlgebricksBuiltinFunctions.NOT), - new MutableObject<ILogicalExpression>(new VariableReferenceExpression(varCond))); - SelectOperator sel2 = new SelectOperator(new MutableObject<ILogicalExpression>(notVarCond), false, null); - sel2.getInputs().add(new MutableObject<ILogicalOperator>(pElse.first)); - - ILogicalPlan p1 = new ALogicalPlanImpl(new MutableObject<ILogicalOperator>(sel1)); - sp.getNestedPlans().add(p1); - ILogicalPlan p2 = new ALogicalPlanImpl(new MutableObject<ILogicalOperator>(sel2)); - sp.getNestedPlans().add(p2); - - Mutable<ILogicalOperator> opCondRef = new MutableObject<ILogicalOperator>(opCond); - sp.getInputs().add(opCondRef); - - LogicalVariable resV = context.newVar(); - AbstractFunctionCallExpression concatNonNull = - new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.CONCAT_NON_NULL), - new MutableObject<ILogicalExpression>(new VariableReferenceExpression(pThen.second)), - new MutableObject<ILogicalExpression>(new VariableReferenceExpression(pElse.second))); - AssignOperator a = new AssignOperator(resV, new MutableObject<ILogicalExpression>(concatNonNull)); - a.getInputs().add(new MutableObject<ILogicalOperator>(sp)); - - return new Pair<ILogicalOperator, LogicalVariable>(a, resV); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(LiteralExpr l, Mutable<ILogicalOperator> tupSource) { - LogicalVariable var = context.newVar(); - AssignOperator a = new AssignOperator(var, new MutableObject<ILogicalExpression>( - new ConstantExpression(new AsterixConstantValue(ConstantHelper.objectFromLiteral(l.getValue()))))); - if (tupSource != null) { - a.getInputs().add(tupSource); - } - return new Pair<ILogicalOperator, LogicalVariable>(a, var); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(OperatorExpr op, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - List<OperatorType> ops = op.getOpList(); - int nOps = ops.size(); - - if (nOps > 0 && (ops.get(0) == OperatorType.AND || ops.get(0) == OperatorType.OR)) { - return visitAndOrOperator(op, tupSource); - } - - List<Expression> exprs = op.getExprList(); - - Mutable<ILogicalOperator> topOp = tupSource; - - ILogicalExpression currExpr = null; - for (int i = 0; i <= nOps; i++) { - - Pair<ILogicalExpression, Mutable<ILogicalOperator>> p = aqlExprToAlgExpression(exprs.get(i), topOp); - topOp = p.second; - ILogicalExpression e = p.first; - // now look at the operator - if (i < nOps) { - if (OperatorExpr.opIsComparison(ops.get(i))) { - AbstractFunctionCallExpression c = createComparisonExpression(ops.get(i)); - - // chain the operators - if (i == 0) { - c.getArguments().add(new MutableObject<ILogicalExpression>(e)); - currExpr = c; - if (op.isBroadcastOperand(i)) { - BroadcastExpressionAnnotation bcast = new BroadcastExpressionAnnotation(); - bcast.setObject(BroadcastSide.LEFT); - c.getAnnotations().put(BroadcastExpressionAnnotation.BROADCAST_ANNOTATION_KEY, bcast); - } - } else { - ((AbstractFunctionCallExpression) currExpr).getArguments() - .add(new MutableObject<ILogicalExpression>(e)); - c.getArguments().add(new MutableObject<ILogicalExpression>(currExpr)); - currExpr = c; - if (i == 1 && op.isBroadcastOperand(i)) { - BroadcastExpressionAnnotation bcast = new BroadcastExpressionAnnotation(); - bcast.setObject(BroadcastSide.RIGHT); - c.getAnnotations().put(BroadcastExpressionAnnotation.BROADCAST_ANNOTATION_KEY, bcast); - } - } - } else { - AbstractFunctionCallExpression f = createFunctionCallExpressionForBuiltinOperator(ops.get(i)); - - if (i == 0) { - f.getArguments().add(new MutableObject<ILogicalExpression>(e)); - currExpr = f; - } else { - ((AbstractFunctionCallExpression) currExpr).getArguments() - .add(new MutableObject<ILogicalExpression>(e)); - f.getArguments().add(new MutableObject<ILogicalExpression>(currExpr)); - currExpr = f; - } - } - } else { // don't forget the last expression... - ((AbstractFunctionCallExpression) currExpr).getArguments() - .add(new MutableObject<ILogicalExpression>(e)); - if (i == 1 && op.isBroadcastOperand(i)) { - BroadcastExpressionAnnotation bcast = new BroadcastExpressionAnnotation(); - bcast.setObject(BroadcastSide.RIGHT); - ((AbstractFunctionCallExpression) currExpr).getAnnotations() - .put(BroadcastExpressionAnnotation.BROADCAST_ANNOTATION_KEY, bcast); - } - } - } - - LogicalVariable assignedVar = context.newVar(); - AssignOperator a = new AssignOperator(assignedVar, new MutableObject<ILogicalExpression>(currExpr)); - - a.getInputs().add(topOp); - - return new Pair<ILogicalOperator, LogicalVariable>(a, assignedVar); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(OrderbyClause oc, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - - OrderOperator ord = new OrderOperator(); - Iterator<OrderModifier> modifIter = oc.getModifierList().iterator(); - Mutable<ILogicalOperator> topOp = tupSource; - for (Expression e : oc.getOrderbyList()) { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> p = aqlExprToAlgExpression(e, topOp); - OrderModifier m = modifIter.next(); - OrderOperator.IOrder comp = (m == OrderModifier.ASC) ? OrderOperator.ASC_ORDER : OrderOperator.DESC_ORDER; - ord.getOrderExpressions().add(new Pair<IOrder, Mutable<ILogicalExpression>>(comp, - new MutableObject<ILogicalExpression>(p.first))); - topOp = p.second; - } - ord.getInputs().add(topOp); - if (oc.getNumTuples() > 0) { - ord.getAnnotations().put(OperatorAnnotations.CARDINALITY, oc.getNumTuples()); - } - if (oc.getNumFrames() > 0) { - ord.getAnnotations().put(OperatorAnnotations.MAX_NUMBER_FRAMES, oc.getNumFrames()); - } - return new Pair<ILogicalOperator, LogicalVariable>(ord, null); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(QuantifiedExpression qe, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - Mutable<ILogicalOperator> topOp = tupSource; - - ILogicalOperator firstOp = null; - Mutable<ILogicalOperator> lastOp = null; - - for (QuantifiedPair qt : qe.getQuantifiedList()) { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo1 = aqlExprToAlgExpression(qt.getExpr(), topOp); - topOp = eo1.second; - LogicalVariable uVar = context.newVar(qt.getVarExpr()); - ILogicalOperator u = - new UnnestOperator(uVar, new MutableObject<ILogicalExpression>(makeUnnestExpression(eo1.first))); - - if (firstOp == null) { - firstOp = u; - } - if (lastOp != null) { - u.getInputs().add(lastOp); - } - lastOp = new MutableObject<ILogicalOperator>(u); - } - - // We make all the unnest correspond. to quantif. vars. sit on top - // in the hope of enabling joins & other optimiz. - firstOp.getInputs().add(topOp); - topOp = lastOp; - - Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo2 = aqlExprToAlgExpression(qe.getSatisfiesExpr(), topOp); - - AggregateFunctionCallExpression fAgg; - SelectOperator s; - if (qe.getQuantifier() == Quantifier.SOME) { - s = new SelectOperator(new MutableObject<ILogicalExpression>(eo2.first), false, null); - s.getInputs().add(eo2.second); - fAgg = BuiltinFunctions.makeAggregateFunctionExpression(BuiltinFunctions.NON_EMPTY_STREAM, - new ArrayList<Mutable<ILogicalExpression>>()); - } else { // EVERY - List<Mutable<ILogicalExpression>> satExprList = new ArrayList<Mutable<ILogicalExpression>>(1); - satExprList.add(new MutableObject<ILogicalExpression>(eo2.first)); - s = new SelectOperator(new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression( - FunctionUtil.getFunctionInfo(AlgebricksBuiltinFunctions.NOT), satExprList)), false, null); - s.getInputs().add(eo2.second); - fAgg = BuiltinFunctions.makeAggregateFunctionExpression(BuiltinFunctions.EMPTY_STREAM, - new ArrayList<Mutable<ILogicalExpression>>()); - } - LogicalVariable qeVar = context.newVar(); - AggregateOperator a = new AggregateOperator(mkSingletonArrayList(qeVar), - (List) mkSingletonArrayList(new MutableObject<ILogicalExpression>(fAgg))); - a.getInputs().add(new MutableObject<ILogicalOperator>(s)); - return new Pair<ILogicalOperator, LogicalVariable>(a, qeVar); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(Query q, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - return q.getBody().accept(this, tupSource); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(RecordConstructor rc, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - AbstractFunctionCallExpression f = new ScalarFunctionCallExpression( - FunctionUtil.getFunctionInfo(BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR)); - LogicalVariable v1 = context.newVar(); - AssignOperator a = new AssignOperator(v1, new MutableObject<ILogicalExpression>(f)); - Mutable<ILogicalOperator> topOp = tupSource; - for (FieldBinding fb : rc.getFbList()) { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo1 = aqlExprToAlgExpression(fb.getLeftExpr(), topOp); - f.getArguments().add(new MutableObject<ILogicalExpression>(eo1.first)); - topOp = eo1.second; - Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo2 = aqlExprToAlgExpression(fb.getRightExpr(), topOp); - f.getArguments().add(new MutableObject<ILogicalExpression>(eo2.first)); - topOp = eo2.second; - } - a.getInputs().add(topOp); - return new Pair<ILogicalOperator, LogicalVariable>(a, v1); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(ListConstructor lc, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - FunctionIdentifier fid = (lc.getType() == Type.ORDERED_LIST_CONSTRUCTOR) - ? BuiltinFunctions.ORDERED_LIST_CONSTRUCTOR : BuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR; - AbstractFunctionCallExpression f = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(fid)); - LogicalVariable v1 = context.newVar(); - AssignOperator a = new AssignOperator(v1, new MutableObject<ILogicalExpression>(f)); - Mutable<ILogicalOperator> topOp = tupSource; - for (Expression expr : lc.getExprList()) { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = aqlExprToAlgExpression(expr, topOp); - f.getArguments().add(new MutableObject<ILogicalExpression>(eo.first)); - topOp = eo.second; - } - a.getInputs().add(topOp); - return new Pair<ILogicalOperator, LogicalVariable>(a, v1); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(UnaryExpr u, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - Expression expr = u.getExpr(); - Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = aqlExprToAlgExpression(expr, tupSource); - LogicalVariable v1 = context.newVar(); - AssignOperator a; - if (u.getExprType() == UnaryExprType.POSITIVE) { - a = new AssignOperator(v1, new MutableObject<ILogicalExpression>(eo.first)); - } else { - AbstractFunctionCallExpression m = new ScalarFunctionCallExpression( - FunctionUtil.getFunctionInfo(BuiltinFunctions.NUMERIC_UNARY_MINUS)); - m.getArguments().add(new MutableObject<ILogicalExpression>(eo.first)); - a = new AssignOperator(v1, new MutableObject<ILogicalExpression>(m)); - } - a.getInputs().add(eo.second); - return new Pair<ILogicalOperator, LogicalVariable>(a, v1); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(VariableExpr v, Mutable<ILogicalOperator> tupSource) { - // Should we ever get to this method? - LogicalVariable var = context.newVar(); - LogicalVariable oldV = context.getVar(v.getVar().getId()); - AssignOperator a = - new AssignOperator(var, new MutableObject<ILogicalExpression>(new VariableReferenceExpression(oldV))); - a.getInputs().add(tupSource); - return new Pair<ILogicalOperator, LogicalVariable>(a, var); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(WhereClause w, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> p = aqlExprToAlgExpression(w.getWhereExpr(), tupSource); - SelectOperator s = new SelectOperator(new MutableObject<ILogicalExpression>(p.first), false, null); - s.getInputs().add(p.second); - - return new Pair<ILogicalOperator, LogicalVariable>(s, null); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(LimitClause lc, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> p1 = aqlExprToAlgExpression(lc.getLimitExpr(), tupSource); - LimitOperator opLim; - Expression offset = lc.getOffset(); - if (offset != null) { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> p2 = aqlExprToAlgExpression(offset, p1.second); - opLim = new LimitOperator(p1.first, p2.first); - opLim.getInputs().add(p2.second); - } else { - opLim = new LimitOperator(p1.first); - opLim.getInputs().add(p1.second); - } - return new Pair<ILogicalOperator, LogicalVariable>(opLim, null); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(DistinctClause dc, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - List<Mutable<ILogicalExpression>> exprList = new ArrayList<Mutable<ILogicalExpression>>(); - Mutable<ILogicalOperator> input = null; - for (Expression expr : dc.getDistinctByExpr()) { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> p = aqlExprToAlgExpression(expr, tupSource); - exprList.add(new MutableObject<ILogicalExpression>(p.first)); - input = p.second; - } - DistinctOperator opDistinct = new DistinctOperator(exprList); - opDistinct.getInputs().add(input); - return new Pair<ILogicalOperator, LogicalVariable>(opDistinct, null); - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(UnionExpr unionExpr, Mutable<ILogicalOperator> tupSource) - throws CompilationException { - Mutable<ILogicalOperator> ts = tupSource; - ILogicalOperator lastOp = null; - LogicalVariable lastVar = null; - boolean first = true; - for (Expression e : unionExpr.getExprs()) { - if (first) { - first = false; - } else { - ts = new MutableObject<ILogicalOperator>(new EmptyTupleSourceOperator()); - } - Pair<ILogicalOperator, LogicalVariable> p1 = e.accept(this, ts); - if (lastOp == null) { - lastOp = p1.first; - lastVar = p1.second; - } else { - LogicalVariable unnestVar1 = context.newVar(); - UnnestOperator unnest1 = new UnnestOperator(unnestVar1, new MutableObject<ILogicalExpression>( - makeUnnestExpression(new VariableReferenceExpression(lastVar)))); - unnest1.getInputs().add(new MutableObject<ILogicalOperator>(lastOp)); - LogicalVariable unnestVar2 = context.newVar(); - UnnestOperator unnest2 = new UnnestOperator(unnestVar2, new MutableObject<ILogicalExpression>( - makeUnnestExpression(new VariableReferenceExpression(p1.second)))); - unnest2.getInputs().add(new MutableObject<ILogicalOperator>(p1.first)); - List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> varMap = new ArrayList<>(1); - LogicalVariable resultVar = context.newVar(); - Triple<LogicalVariable, LogicalVariable, LogicalVariable> triple = - new Triple<>(unnestVar1, unnestVar2, resultVar); - varMap.add(triple); - UnionAllOperator unionOp = new UnionAllOperator(varMap); - unionOp.getInputs().add(new MutableObject<ILogicalOperator>(unnest1)); - unionOp.getInputs().add(new MutableObject<ILogicalOperator>(unnest2)); - lastVar = resultVar; - lastOp = unionOp; - } - } - LogicalVariable aggVar = context.newVar(); - ArrayList<LogicalVariable> aggregVars = new ArrayList<LogicalVariable>(1); - aggregVars.add(aggVar); - List<Mutable<ILogicalExpression>> afcExprs = new ArrayList<Mutable<ILogicalExpression>>(1); - afcExprs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(lastVar))); - AggregateFunctionCallExpression afc = - BuiltinFunctions.makeAggregateFunctionExpression(BuiltinFunctions.LISTIFY, afcExprs); - ArrayList<Mutable<ILogicalExpression>> aggregExprs = new ArrayList<Mutable<ILogicalExpression>>(1); - aggregExprs.add(new MutableObject<ILogicalExpression>(afc)); - AggregateOperator agg = new AggregateOperator(aggregVars, aggregExprs); - agg.getInputs().add(new MutableObject<ILogicalOperator>(lastOp)); - return new Pair<ILogicalOperator, LogicalVariable>(agg, aggVar); - } - - private AbstractFunctionCallExpression createComparisonExpression(OperatorType t) { - FunctionIdentifier fi = operatorTypeToFunctionIdentifier(t); - IFunctionInfo finfo = FunctionUtil.getFunctionInfo(fi); - return new ScalarFunctionCallExpression(finfo); - } - - private FunctionIdentifier operatorTypeToFunctionIdentifier(OperatorType t) { - switch (t) { - case EQ: { - return AlgebricksBuiltinFunctions.EQ; - } - case NEQ: { - return AlgebricksBuiltinFunctions.NEQ; - } - case GT: { - return AlgebricksBuiltinFunctions.GT; - } - case GE: { - return AlgebricksBuiltinFunctions.GE; - } - case LT: { - return AlgebricksBuiltinFunctions.LT; - } - case LE: { - return AlgebricksBuiltinFunctions.LE; - } - default: { - throw new IllegalStateException(); - } - } - } - - private AbstractFunctionCallExpression createFunctionCallExpressionForBuiltinOperator(OperatorType t) - throws CompilationException { - - FunctionIdentifier fid = null; - switch (t) { - case PLUS: { - fid = AlgebricksBuiltinFunctions.NUMERIC_ADD; - break; - } - case MINUS: { - fid = BuiltinFunctions.NUMERIC_SUBTRACT; - break; - } - case MUL: { - fid = BuiltinFunctions.NUMERIC_MULTIPLY; - break; - } - case DIV: { - fid = BuiltinFunctions.NUMERIC_DIVIDE; - break; - } - case MOD: { - fid = BuiltinFunctions.NUMERIC_MOD; - break; - } - case IDIV: { - fid = BuiltinFunctions.NUMERIC_IDIV; - break; - } - case CARET: { - fid = BuiltinFunctions.CARET; - break; - } - case AND: { - fid = AlgebricksBuiltinFunctions.AND; - break; - } - case OR: { - fid = AlgebricksBuiltinFunctions.OR; - break; - } - case FUZZY_EQ: { - fid = BuiltinFunctions.FUZZY_EQ; - break; - } - - default: { - throw new NotImplementedException("Operator " + t + " is not yet implemented"); - } - } - return new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(fid)); - } - - private static boolean hasOnlyChild(ILogicalOperator parent, Mutable<ILogicalOperator> childCandidate) { - List<Mutable<ILogicalOperator>> inp = parent.getInputs(); - if (inp == null || inp.size() != 1) { - return false; - } - return inp.get(0) == childCandidate; - } - - private Pair<ILogicalExpression, Mutable<ILogicalOperator>> aqlExprToAlgExpression(Expression expr, - Mutable<ILogicalOperator> topOp) throws CompilationException { - switch (expr.getKind()) { - case VARIABLE_EXPRESSION: { - VariableReferenceExpression ve = - new VariableReferenceExpression(context.getVar(((VariableExpr) expr).getVar().getId())); - return new Pair<ILogicalExpression, Mutable<ILogicalOperator>>(ve, topOp); - } - case METAVARIABLE_EXPRESSION: { - ILogicalExpression le = metaScopeExp.getVariableReferenceExpression(((VariableExpr) expr).getVar()); - return new Pair<ILogicalExpression, Mutable<ILogicalOperator>>(le, topOp); - } - case LITERAL_EXPRESSION: { - LiteralExpr val = (LiteralExpr) expr; - return new Pair<ILogicalExpression, Mutable<ILogicalOperator>>(new ConstantExpression( - new AsterixConstantValue(ConstantHelper.objectFromLiteral(val.getValue()))), topOp); - } - default: { - // Mutable<ILogicalExpression> src = new - // Mutable<ILogicalExpression>(); - // Mutable<ILogicalExpression> src = topOp; - if (expressionNeedsNoNesting(expr)) { - Pair<ILogicalOperator, LogicalVariable> p = expr.accept(this, topOp); - ILogicalExpression exp = ((AssignOperator) p.first).getExpressions().get(0).getValue(); - return new Pair<ILogicalExpression, Mutable<ILogicalOperator>>(exp, p.first.getInputs().get(0)); - } else { - Mutable<ILogicalOperator> src = new MutableObject<ILogicalOperator>(); - - Pair<ILogicalOperator, LogicalVariable> p = expr.accept(this, src); - - if (((AbstractLogicalOperator) p.first).getOperatorTag() == LogicalOperatorTag.SUBPLAN) { - // src.setOperator(topOp.getOperator()); - Mutable<ILogicalOperator> top2 = new MutableObject<ILogicalOperator>(p.first); - return new Pair<ILogicalExpression, Mutable<ILogicalOperator>>( - new VariableReferenceExpression(p.second), top2); - } else { - SubplanOperator s = new SubplanOperator(); - s.getInputs().add(topOp); - src.setValue(new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(s))); - Mutable<ILogicalOperator> planRoot = new MutableObject<ILogicalOperator>(p.first); - s.setRootOp(planRoot); - return new Pair<ILogicalExpression, Mutable<ILogicalOperator>>( - new VariableReferenceExpression(p.second), new MutableObject<ILogicalOperator>(s)); - } - } - } - } - - } - - private Pair<ILogicalOperator, LogicalVariable> produceFlwrResult(boolean noForClause, boolean isTop, - Mutable<ILogicalOperator> resOpRef, LogicalVariable resVar) { - if (isTop) { - ProjectOperator pr = new ProjectOperator(resVar); - pr.getInputs().add(resOpRef); - return new Pair<ILogicalOperator, LogicalVariable>(pr, resVar); - - } else if (noForClause) { - return new Pair<ILogicalOperator, LogicalVariable>(resOpRef.getValue(), resVar); - } else { - return aggListify(resVar, resOpRef, false); - } - } - - private Pair<ILogicalOperator, LogicalVariable> aggListify(LogicalVariable var, Mutable<ILogicalOperator> opRef, - boolean bProject) { - AggregateFunctionCallExpression funAgg = BuiltinFunctions.makeAggregateFunctionExpression( - BuiltinFunctions.LISTIFY, new ArrayList<Mutable<ILogicalExpression>>()); - funAgg.getArguments().add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(var))); - LogicalVariable varListified = context.newVar(); - AggregateOperator agg = new AggregateOperator(mkSingletonArrayList(varListified), - (List) mkSingletonArrayList(new MutableObject<ILogicalExpression>(funAgg))); - agg.getInputs().add(opRef); - ILogicalOperator res; - if (bProject) { - ProjectOperator pr = new ProjectOperator(varListified); - pr.getInputs().add(new MutableObject<ILogicalOperator>(agg)); - res = pr; - } else { - res = agg; - } - return new Pair<ILogicalOperator, LogicalVariable>(res, varListified); - } - - private Pair<ILogicalOperator, LogicalVariable> visitAndOrOperator(OperatorExpr op, - Mutable<ILogicalOperator> tupSource) throws CompilationException { - List<OperatorType> ops = op.getOpList(); - int nOps = ops.size(); - - List<Expression> exprs = op.getExprList(); - - Mutable<ILogicalOperator> topOp = tupSource; - - OperatorType opLogical = ops.get(0); - AbstractFunctionCallExpression f = createFunctionCallExpressionForBuiltinOperator(opLogical); - - for (int i = 0; i <= nOps; i++) { - Pair<ILogicalExpression, Mutable<ILogicalOperator>> p = aqlExprToAlgExpression(exprs.get(i), topOp); - topOp = p.second; - // now look at the operator - if (i < nOps) { - if (ops.get(i) != opLogical) { - throw new TranslationException( - "Unexpected operator " + ops.get(i) + " in an OperatorExpr starting with " + opLogical); - } - } - f.getArguments().add(new MutableObject<ILogicalExpression>(p.first)); - } - - LogicalVariable assignedVar = context.newVar(); - AssignOperator a = new AssignOperator(assignedVar, new MutableObject<ILogicalExpression>(f)); - a.getInputs().add(topOp); - - return new Pair<ILogicalOperator, LogicalVariable>(a, assignedVar); - - } - - private static boolean expressionNeedsNoNesting(Expression expr) { - Kind k = expr.getKind(); - return k == Kind.LITERAL_EXPRESSION || k == Kind.LIST_CONSTRUCTOR_EXPRESSION - || k == Kind.RECORD_CONSTRUCTOR_EXPRESSION || k == Kind.VARIABLE_EXPRESSION || k == Kind.CALL_EXPRESSION - || k == Kind.OP_EXPRESSION || k == Kind.FIELD_ACCESSOR_EXPRESSION || k == Kind.INDEX_ACCESSOR_EXPRESSION - || k == Kind.UNARY_EXPRESSION; - } - - private <T> ArrayList<T> mkSingletonArrayList(T item) { - ArrayList<T> array = new ArrayList<T>(1); - array.add(item); - return array; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(TypeDecl td, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(RecordTypeDefinition tre, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(TypeReferenceExpression tre, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(NodegroupDecl ngd, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(LoadStatement stmtLoad, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(DropDatasetStatement del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(CreateIndexStatement cis, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(OrderedListTypeDefinition olte, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(UnorderedListTypeDefinition ulte, - Mutable<ILogicalOperator> arg) throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override public Pair<ILogicalOperator, LogicalVariable> visitMetaVariableClause(MetaVariableClause mc, Mutable<ILogicalOperator> tupSource) throws CompilationException { return new Pair<ILogicalOperator, LogicalVariable>(metaScopeOp.get(mc.getVar()), null); @@ -1252,8 +101,6 @@ @Override public Pair<ILogicalOperator, LogicalVariable> visitJoinClause(JoinClause jc, Mutable<ILogicalOperator> tupSource) throws CompilationException { - // Pair<ILogicalOperator, LogicalVariable> leftSide = - // jc.getLeftExpr().accept(this, tupSource); Mutable<ILogicalOperator> opRef = tupSource; Pair<ILogicalOperator, LogicalVariable> leftSide = null; for (Clause c : jc.getLeftClauses()) { @@ -1261,8 +108,6 @@ opRef = new MutableObject<ILogicalOperator>(leftSide.first); } - // Pair<ILogicalOperator, LogicalVariable> rightSide = - // jc.getRightExpr().accept(this, tupSource); opRef = tupSource; Pair<ILogicalOperator, LogicalVariable> rightSide = null; for (Clause c : jc.getRightClauses()) { @@ -1271,21 +116,18 @@ } Pair<ILogicalExpression, Mutable<ILogicalOperator>> whereCond = - aqlExprToAlgExpression(jc.getWhereExpr(), tupSource); + langExprToAlgExpression(jc.getWhereExpr(), tupSource); AbstractBinaryJoinOperator join; switch (jc.getKind()) { - case INNER: { + case INNER: join = new InnerJoinOperator(new MutableObject<ILogicalExpression>(whereCond.first)); break; - } - case LEFT_OUTER: { + case LEFT_OUTER: join = new LeftOuterJoinOperator(new MutableObject<ILogicalExpression>(whereCond.first)); break; - } - default: { - throw new IllegalStateException(); - } + default: + throw new CompilationException(ErrorCode.COMPILATION_AQLPLUS_NO_SUCH_JOIN_TYPE); } join.getInputs().add(new MutableObject<ILogicalOperator>(leftSide.first)); join.getInputs().add(new MutableObject<ILogicalOperator>(rightSide.first)); @@ -1302,195 +144,64 @@ return new Pair<ILogicalOperator, LogicalVariable>(a, var); } - public void addOperatorToMetaScope(Identifier id, ILogicalOperator op) { - metaScopeOp.put(id, op); - } public void addVariableToMetaScope(Identifier id, LogicalVariable var) { metaScopeExp.put(id, var); } - private ILogicalExpression makeUnnestExpression(ILogicalExpression expr) { - switch (expr.getExpressionTag()) { - case VARIABLE: { - return new UnnestingFunctionCallExpression( - FunctionUtil.getFunctionInfo(BuiltinFunctions.SCAN_COLLECTION), - new MutableObject<ILogicalExpression>(expr)); - } - case FUNCTION_CALL: { - AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expr; - if (fce.getKind() == FunctionKind.UNNEST) { - return expr; - } else { - return new UnnestingFunctionCallExpression( - FunctionUtil.getFunctionInfo(BuiltinFunctions.SCAN_COLLECTION), - new MutableObject<ILogicalExpression>(expr)); - } - } - default: { - return expr; - } + public void addOperatorToMetaScope(Identifier id, ILogicalOperator op) { + metaScopeOp.put(id, op); + } + + // This method was overridden because of METAVARIABLE_EXPRESSION case. + @Override + protected Pair<ILogicalExpression, Mutable<ILogicalOperator>> langExprToAlgExpression(Expression expr, + Mutable<ILogicalOperator> topOpRef) throws CompilationException { + switch (expr.getKind()) { + case METAVARIABLE_EXPRESSION: + ILogicalExpression le = metaScopeExp.getVariableReferenceExpression(((VariableExpr) expr).getVar()); + return new Pair<ILogicalExpression, Mutable<ILogicalOperator>>(le, topOpRef); + default: + return super.langExprToAlgExpression(expr, topOpRef); } } - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(InsertStatement insert, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; + /** + * This class refers to the primary-key or other variables in the given plan in AQL+ statements level. + */ + private class MetaScopeLogicalVariable { + private HashMap<Identifier, LogicalVariable> map = new HashMap<Identifier, LogicalVariable>(); + + public VariableReferenceExpression getVariableReferenceExpression(Identifier id) throws CompilationException { + LogicalVariable var = map.get(id); + if (var == null) { + throw new CompilationException(ErrorCode.COMPILATION_AQLPLUS_IDENTIFIER_NOT_FOUND, id.toString()); + } + return new VariableReferenceExpression(var); + } + + public void put(Identifier id, LogicalVariable var) { + map.put(id, var); + } } - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(DeleteStatement del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; + /** + * This class refers to the operators in the given plan in AQL+ statements level. + */ + private class MetaScopeILogicalOperator { + private HashMap<Identifier, ILogicalOperator> map = new HashMap<Identifier, ILogicalOperator>(); + + public ILogicalOperator get(Identifier id) throws CompilationException { + ILogicalOperator op = map.get(id); + if (op == null) { + throw new CompilationException(ErrorCode.COMPILATION_AQLPLUS_IDENTIFIER_NOT_FOUND, id.toString()); + } + return op; + } + + public void put(Identifier id, ILogicalOperator op) { + map.put(id, op); + } } - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(UpdateStatement update, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(UpdateClause del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(DataverseDecl dv, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(DatasetDecl dd, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(SetStatement ss, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(WriteStatement ws, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(CreateDataverseStatement del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(IndexDropStatement del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(NodeGroupDropStatement del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(DataverseDropStatement del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(TypeDropStatement del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(DisconnectFeedStatement del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(CreateFunctionStatement cfs, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(FunctionDropStatement del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(ConnectFeedStatement del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(FeedDropStatement del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(CompactStatement del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(CreatePrimaryFeedStatement del, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(CreateSecondaryFeedStatement del, - Mutable<ILogicalOperator> arg) throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(CreateFeedPolicyStatement cfps, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Pair<ILogicalOperator, LogicalVariable> visit(FeedPolicyDropStatement dfs, Mutable<ILogicalOperator> arg) - throws CompilationException { - // TODO Auto-generated method stub - return null; - } } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java index 741ce56..c4cc486 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java @@ -177,9 +177,17 @@ private static final AtomicLong outputFileID = new AtomicLong(0); private static final String OUTPUT_FILE_PREFIX = "OUTPUT_"; - public LangExpressionToPlanTranslator(MetadataProvider metadataProvider, int currentVarCounter) + public LangExpressionToPlanTranslator(MetadataProvider metadataProvider, int currentVarCounterValue) throws AlgebricksException { - this.context = new TranslationContext(new Counter(currentVarCounter)); + this.context = new TranslationContext(new Counter(currentVarCounterValue)); + this.metadataProvider = metadataProvider; + FormatUtils.getDefaultFormat().registerRuntimeFunctions(FunctionCollection.getFunctionDescriptorFactories()); + } + + // Keeps the given Counter if one is provided instead of a value. + public LangExpressionToPlanTranslator(MetadataProvider metadataProvider, Counter currentVarCounter) + throws AlgebricksException { + this.context = new TranslationContext(currentVarCounter); this.metadataProvider = metadataProvider; FormatUtils.getDefaultFormat().registerRuntimeFunctions(FunctionCollection.getFunctionDescriptorFactories()); } diff --git a/asterixdb/asterix-algebra/src/main/javacc/AQLPlus.jj b/asterixdb/asterix-algebra/src/main/javacc/AQLPlus.jj deleted file mode 100644 index b44e1bc..0000000 --- a/asterixdb/asterix-algebra/src/main/javacc/AQLPlus.jj +++ /dev/null @@ -1,1701 +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. - */ - -options { - - - STATIC = false; - -} - - -PARSER_BEGIN(AQLPlusParser) - -package org.apache.asterix.aqlplus.parser; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.asterix.common.exceptions.CompilationException; -import org.apache.asterix.common.functions.FunctionSignature; -import org.apache.asterix.lang.aql.clause.DistinctClause; -import org.apache.asterix.lang.aql.clause.ForClause; -import org.apache.asterix.lang.aql.clause.JoinClause; -import org.apache.asterix.lang.aql.clause.MetaVariableClause; -import org.apache.asterix.lang.aql.expression.FLWOGRExpression; -import org.apache.asterix.lang.aql.expression.MetaVariableExpr; -import org.apache.asterix.lang.aql.expression.UnionExpr; -import org.apache.asterix.lang.common.base.Clause; -import org.apache.asterix.lang.common.base.Expression; -import org.apache.asterix.lang.common.base.Literal; -import org.apache.asterix.lang.common.base.Statement; -import org.apache.asterix.lang.common.clause.GroupbyClause; -import org.apache.asterix.lang.common.clause.LetClause; -import org.apache.asterix.lang.common.clause.LimitClause; -import org.apache.asterix.lang.common.clause.OrderbyClause; -import org.apache.asterix.lang.common.clause.WhereClause; -import org.apache.asterix.lang.common.context.RootScopeFactory; -import org.apache.asterix.lang.common.context.Scope; -import org.apache.asterix.lang.common.expression.AbstractAccessor; -import org.apache.asterix.lang.common.expression.CallExpr; -import org.apache.asterix.lang.common.expression.FieldAccessor; -import org.apache.asterix.lang.common.expression.FieldBinding; -import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair; -import org.apache.asterix.lang.common.expression.IfExpr; -import org.apache.asterix.lang.common.expression.IndexAccessor; -import org.apache.asterix.lang.common.expression.ListConstructor; -import org.apache.asterix.lang.common.expression.LiteralExpr; -import org.apache.asterix.lang.common.expression.OperatorExpr; -import org.apache.asterix.lang.common.expression.OrderedListTypeDefinition; -import org.apache.asterix.lang.common.expression.QuantifiedExpression; -import org.apache.asterix.lang.common.expression.RecordConstructor; -import org.apache.asterix.lang.common.expression.RecordTypeDefinition; -import org.apache.asterix.lang.common.expression.TypeExpression; -import org.apache.asterix.lang.common.expression.TypeReferenceExpression; -import org.apache.asterix.lang.common.expression.UnaryExpr; -import org.apache.asterix.lang.common.expression.UnorderedListTypeDefinition; -import org.apache.asterix.lang.common.expression.VariableExpr; -import org.apache.asterix.lang.common.literal.DoubleLiteral; -import org.apache.asterix.lang.common.literal.FalseLiteral; -import org.apache.asterix.lang.common.literal.FloatLiteral; -import org.apache.asterix.lang.common.literal.IntegerLiteral; -import org.apache.asterix.lang.common.literal.LongIntegerLiteral; -import org.apache.asterix.lang.common.literal.NullLiteral; -import org.apache.asterix.lang.common.literal.StringLiteral; -import org.apache.asterix.lang.common.literal.TrueLiteral; -import org.apache.asterix.lang.common.parser.ScopeChecker; -import org.apache.asterix.lang.common.statement.DataverseDecl; -import org.apache.asterix.lang.common.statement.FunctionDecl; -import org.apache.asterix.lang.common.statement.LoadStatement; -import org.apache.asterix.lang.common.statement.Query; -import org.apache.asterix.lang.common.statement.SetStatement; -import org.apache.asterix.lang.common.statement.TypeDecl; -import org.apache.asterix.lang.common.statement.WriteStatement; -import org.apache.asterix.lang.common.struct.Identifier; -import org.apache.asterix.lang.common.struct.QuantifiedPair; -import org.apache.asterix.lang.common.struct.VarIdentifier; -import org.apache.asterix.metadata.utils.MetadataConstants; -import org.apache.hyracks.algebricks.common.utils.Pair; -import org.apache.hyracks.algebricks.core.algebra.expressions.IndexedNLJoinExpressionAnnotation; - - -public class AQLPlusParser extends ScopeChecker { - -/* - private void printHints(Token t) { - //System.err.println("token="+t.image+"\t special="+t.specialToken); - if (t.specialToken == null) return; - Token tmp_t = t.specialToken; - while (tmp_t.specialToken != null) tmp_t = tmp_t.specialToken; - while (tmp_t != null) { - System.out.println(tmp_t.image); - tmp_t = tmp_t.next; - } - } -*/ - - private static final String HASH_GROUP_BY_HINT = "hash"; - private static final String BROADCAST_JOIN_HINT = "bcast"; - private static final String INMEMORY_HINT = "inmem"; - private static final String INDEXED_NESTED_LOOP_JOIN_HINT = "indexnl"; - - - - private static String getHint(Token t) { - if (t.specialToken == null) { - return null; - } - String s = t.specialToken.image; - int n = s.length(); - if (n < 2) { - return null; - } - return s.substring(1).trim(); - } - - public static void main(String args[]) throws ParseException, TokenMgrError, IOException, FileNotFoundException, CompilationException { - File file = new File(args[0]); - Reader fis = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); - AQLPlusParser parser = new AQLPlusParser(fis); - List<Statement> st = parser.Statement(); - } - - public void initScope() { - scopeStack.push(RootScopeFactory.createRootScope(this)); - } -} - -PARSER_END(AQLPlusParser) - - -List<Statement> Statement() throws ParseException: -{ - Query query = null; - // scopeStack.push(RootScopeFactory.createRootScope(this)); - initScope(); - List<Statement> decls = new ArrayList<Statement>(); -} -{ - ( - ( - ( - "use" - { - decls.add(DataverseDeclaration()); - } - | "declare" - ( "function" { - decls.add(FunctionDeclaration()); - } - | "type" { - decls.add(TypeDeclaration()); - } - ) - | "load" { - decls.add(LoadStatement()); - } - - | "write" { - decls.add(WriteStatement()); - } - | "set" { - decls.add(SetStatement()); - } - | - { - decls.add(Query()) ; - } ";" - - - )* - ) - - <EOF> - ) - { - - return decls; - } -} - -Statement SetStatement() throws ParseException: -{ - String pn = null; - Statement stmt = null; -} -{ - <IDENTIFIER> { pn = token.image; } - <STRING_LITERAL> - { String pv = removeQuotesAndEscapes(token.image); } - ";" - { - return new SetStatement(pn, pv); - } -} - -Statement WriteStatement() throws ParseException: -{ - Identifier nodeName = null; - String fileName = null; - Identifier datasetName = null; - Statement stmt = null; - Query query; -} -{ - ( "output" "to" - <IDENTIFIER> { nodeName = new Identifier(token.image); } - ":" <STRING_LITERAL> { - fileName = removeQuotesAndEscapes(token.image); - stmt = new WriteStatement(nodeName, fileName, null); - } - ) ";" - { - return stmt; - } -} - -DataverseDecl DataverseDeclaration() throws ParseException: -{ - Identifier dvName = null; -} -{ - "dataverse" <IDENTIFIER> { defaultDataverse = token.image;} - ";" - { - return new DataverseDecl(new Identifier(defaultDataverse)); - } -} - -LoadStatement LoadStatement() throws ParseException: -{ - Identifier datasetName = null; - boolean alreadySorted = false; - String adapter; - Map<String,String> properties = new HashMap<String,String>(); - String name; - String value; -} -{ - <DATASET> <IDENTIFIER> { datasetName = new Identifier(token.image); } - - "using" - ( - <STRING_LITERAL> - { - adapter = removeQuotesAndEscapes(token.image); - } - <LEFTPAREN> - ( - ( - <LEFTPAREN> - ( - <STRING_LITERAL> - { - name = removeQuotesAndEscapes(token.image); - } - "=" <STRING_LITERAL> - { - value = removeQuotesAndEscapes(token.image); - } - ) - <RIGHTPAREN> - { - properties.put(name, value); - } - ) - ( - "," <LEFTPAREN> - ( - <STRING_LITERAL> - { - name = removeQuotesAndEscapes(token.image); - } - "=" <STRING_LITERAL> - { - value = removeQuotesAndEscapes(token.image); - } - ) - <RIGHTPAREN> - { - properties.put(name, value); - } - )* - )? - <RIGHTPAREN> - ) - - ("pre-sorted" - { alreadySorted = true; } - )? - - ";" - { - return new LoadStatement(null, datasetName, adapter, properties, alreadySorted); - } -} - -TypeDecl TypeDeclaration() throws ParseException: -{ - Identifier ident; - TypeExpression typeExpr; -} -{ - <IDENTIFIER> - { - ident = new Identifier(token.image.toString()); - } - "as" - ( typeExpr = TypeExpr() ) - { - return new TypeDecl(null, ident, typeExpr); - } -} - -TypeExpression TypeExpr() throws ParseException: -{ - TypeExpression typeExpr = null; -} -{ - ( - typeExpr = RecordTypeDef() - | typeExpr = TypeReference() - | typeExpr = OrderedListTypeDef() - | typeExpr = UnorderedListTypeDef() - ) - { - return typeExpr; - } -} - -RecordTypeDefinition RecordTypeDef() throws ParseException: -{ - RecordTypeDefinition recType = new RecordTypeDefinition(); - RecordTypeDefinition.RecordKind recordKind = null; -} -{ - ( "closed" { recordKind = RecordTypeDefinition.RecordKind.CLOSED; } - | "open" { recordKind = RecordTypeDefinition.RecordKind.OPEN; } )? - "{" - ( - RecordField(recType) - ( "," RecordField(recType) )* - )? - "}" - { - if (recordKind == null) { - recordKind = RecordTypeDefinition.RecordKind.OPEN; - } - recType.setRecordKind(recordKind); - return recType; - } -} - -void RecordField(RecordTypeDefinition recType) throws ParseException: -{ - String fieldName; - TypeExpression type = null; - boolean nullable = false; -} -{ - <IDENTIFIER> - { - Token t = getToken(0); - fieldName = t.toString(); - } - ":" - ( type = TypeExpr() ) - ("?" { nullable = true; } )? - { - - recType.addField(fieldName, type, nullable); - } -} - -TypeReferenceExpression TypeReference() throws ParseException: -{} -{ - <IDENTIFIER> - { - Token t = getToken(0); - Identifier id; - if (t.toString().equalsIgnoreCase("int")) { - id = new Identifier("int64"); - } else { - id = new Identifier(t.toString()); - } - return new TypeReferenceExpression(new Pair<Identifier,Identifier>(null,id)); - } -} - -OrderedListTypeDefinition OrderedListTypeDef() throws ParseException: -{ - TypeExpression type = null; -} -{ - "[" - ( type = TypeExpr() ) - "]" - { - return new OrderedListTypeDefinition(type); - } -} - - -UnorderedListTypeDefinition UnorderedListTypeDef() throws ParseException: -{ - TypeExpression type = null; -} -{ - "<" - ( type = TypeExpr() ) - ">" - { - return new UnorderedListTypeDefinition(type); - } -} - - -FunctionDecl FunctionDeclaration() throws ParseException: -{ - FunctionDecl funcDecl; - FunctionSignature signature; - String functionName; - int arity = 0; - List<VarIdentifier> paramList = new ArrayList<VarIdentifier>(); - Expression funcBody; - VarIdentifier var = null; - createNewScope(); -} -{ - - <IDENTIFIER> - { - Token t = getToken(0); - functionName = t.toString(); - if (functionName.equalsIgnoreCase("int")) { - functionName = "int64"; - } - } - <LEFTPAREN> (<VARIABLE> - { - var = new VarIdentifier(); - var.setValue(getToken(0).toString()); - paramList.add(var); - getCurrentScope().addNewVarSymbolToScope(var); - arity++; - } - ("," <VARIABLE> - { - var = new VarIdentifier(); - var.setValue(getToken(0).toString()); - paramList.add(var); - getCurrentScope().addNewVarSymbolToScope(var); - arity++; - })*)? <RIGHTPAREN> "{" funcBody = Expression() "}" - - { - signature = new FunctionSignature(defaultDataverse, functionName, arity); - getCurrentScope().addFunctionDescriptor(signature, false); - funcDecl = new FunctionDecl(signature, paramList, funcBody); - return funcDecl; - } -} - -Query Query()throws ParseException: -{ - Query query = new Query(false); - Expression expr; -} -{ - expr = Expression() - - { - query.setBody(expr); - return query; - } -} - - - -Expression Expression(): -{ - Expression expr = null; - Expression exprP = null; -} -{ -( - -//OperatorExpr | IfThenElse | FLWOGRExpression | QuantifiedExpression - expr = OperatorExpr() - | expr = IfThenElse() - | expr = FLWOGR() - | expr = QuantifiedExpression() - - -) - { - return (exprP==null) ? expr : exprP; - } -} - - - -Expression OperatorExpr()throws ParseException: -{ - OperatorExpr op = null; - Expression operand = null; -} -{ - operand = AndExpr() - ( - - "or" - { - if (op == null) { - op = new OperatorExpr(); - op.addOperand(operand); - op.setCurrentop(true); - } - Token t = getToken(0); - try{ - op.addOperator(t.toString()); - } catch (Exception e){ - throw new ParseException(e.getMessage()); - } - } - - operand = AndExpr() - { - op.addOperand(operand); - } - - )* - - { - return op==null? operand: op; - } -} - -Expression AndExpr()throws ParseException: -{ - OperatorExpr op = null; - Expression operand = null; -} -{ - operand = RelExpr() - ( - - "and" - { - if (op == null) { - op = new OperatorExpr(); - op.addOperand(operand); - op.setCurrentop(true); - } - Token t = getToken(0); - try{ - op.addOperator(t.toString()); - } catch (Exception e){ - throw new ParseException(e.getMessage()); - } - } - - operand = RelExpr() - { - op.addOperand(operand); - } - - )* - - { - return op==null? operand: op; - } -} - - - -Expression RelExpr()throws ParseException: -{ - OperatorExpr op = null; - Expression operand = null; - boolean broadcast = false; -} -{ - operand = AddExpr() - { - if (operand instanceof VariableExpr) { - String hint = getHint(token); - if (hint != null && hint.equals(BROADCAST_JOIN_HINT)) { - broadcast = true; - } - } - } - - ( - LOOKAHEAD(2)( "<" | ">" | "<=" | ">=" | "=" | "!=" |"~=") - { - if (op == null) { - op = new OperatorExpr(); - op.addOperand(operand, broadcast); - op.setCurrentop(true); - broadcast = false; - } - Token t = getToken(0); - try{ - op.addOperator(t.toString()); - } catch (Exception e){ - throw new ParseException(e.getMessage()); - } - } - - operand = AddExpr() - { - broadcast = false; - if (operand instanceof VariableExpr) { - String hint = getHint(token); - if (hint != null && hint.equals(BROADCAST_JOIN_HINT)) { - broadcast = true; - } - } - op.addOperand(operand, broadcast); - } - )? - - { - return op==null? operand: op; - } -} - -Expression AddExpr()throws ParseException: -{ - OperatorExpr op = null; - Expression operand = null; -} -{ - operand = MultExpr() - - ( ("+" | "-") - { - if (op == null) { - op = new OperatorExpr(); - op.addOperand(operand); - op.setCurrentop(true); - } - Token t = getToken(0); - try{ - ((OperatorExpr)op).addOperator(t.toString()); - } catch (Exception e){ - throw new ParseException(e.getMessage()); - } - } - - operand = MultExpr() - { - op.addOperand(operand); - } - )* - - { - return op==null? operand: op; - } -} - -Expression MultExpr()throws ParseException: -{ - OperatorExpr op = null; - Expression operand = null; -} -{ - operand = UnionExpr() - - (( "*" | "/" | "%" | <CARET> | "idiv") - { - if (op == null) { - op = new OperatorExpr(); - op.addOperand(operand); - op.setCurrentop(true); - } - Token t = getToken(0); - try{ - op.addOperator(t.toString()); - } catch (CompilationException e){ - throw new ParseException(e.getMessage()); - } - } - operand = UnionExpr() - { - op.addOperand(operand); - } - )* - - { - return op==null?operand:op; - } -} - -Expression UnionExpr() throws ParseException: -{ - UnionExpr union = null; - Expression operand1 = null; - Expression operand2 = null; -} -{ - operand1 = UnaryExpr() - ("union" - (operand2 = UnaryExpr()) { - if (union == null) { - union = new UnionExpr(); - union.addExpr(operand1); - } - union.addExpr(operand2); - } )* - { - return (union == null)? operand1: union; - } -} - -Expression UnaryExpr() throws ParseException: -{ - UnaryExpr uexpr = null; - Expression expr = null; -} -{ - ( ("+"|"-") - { - uexpr = new UnaryExpr(); - try{ - uexpr.setExprType(token.image); - } catch (CompilationException e){ - throw new ParseException(e.getMessage()); - } - } - )? - - expr = ValueExpr() - { - if(uexpr!=null){ - ((UnaryExpr)uexpr).setExpr(expr); - return uexpr; - } - else{ - return expr; - } - } -} - -Expression ValueExpr() throws ParseException: -{ - Expression expr; -} -{ - expr = FieldOrIndexAccessor() - { - return expr; - } -} - - -Expression FieldOrIndexAccessor()throws ParseException: -{ - Expression expr = null; - Identifier ident = null; - AbstractAccessor fa = null; - Expression indexExpr = null; - -} -{ - ( expr = PrimaryExpr() - - ) - - - ( - ( - ident = Field() - { - if(fa == null) - fa = new FieldAccessor(expr, ident); - else - fa = new FieldAccessor(fa, ident); - } - ) - | ( - indexExpr = Index() - { - if(fa == null) - fa = new IndexAccessor(expr, indexExpr); - else - fa = new IndexAccessor(fa, indexExpr); - } - ) - )* - - - { - return fa==null?expr:fa; - } -} - -Identifier Field() throws ParseException: -{ - Identifier ident = null; - -} -{ - "." < IDENTIFIER > - { - - ident = new Identifier(); - ident.setValue(getToken(0).toString()); - - return ident; - } -} - -Expression Index() throws ParseException: -{ - Expression expr = null; -} -{ - "[" ( expr = Expression() - { - if(expr.getKind() == Expression.Kind.LITERAL_EXPRESSION) - { - Literal lit = ((LiteralExpr)expr).getValue(); - if(lit.getLiteralType() != Literal.Type.INTEGER && - lit.getLiteralType() != Literal.Type.LONG) { - throw new ParseException("Index should be an INTEGER"); - } - } - } - - | "?" // ANY - - ) - - "]" - { - return expr; - } -} - - -Expression PrimaryExpr()throws ParseException: -{ - Expression expr = null; -} -{ - //Literal | VariableRef | ListConstructor | RecordConstructor | FunctionCallExpr | ParenthesizedExpression - ( - expr =Literal() - | expr = FunctionCallExpr() - | expr =VariableRef() - - { - if(((VariableExpr)expr).getIsNewVar() == true) - throw new ParseException("can't find variable " + ((VariableExpr)expr).getVar()); - } - | expr = ListConstructor() - | expr = RecordConstructor() - | expr = ParenthesizedExpression() - | expr = MetaVariableRef() - ) - { - return expr; - } -} - -Expression Literal() throws ParseException: -{ - - LiteralExpr lit = new LiteralExpr(); - Token t; -} -{ -( - <STRING_LITERAL> - { - t= getToken(0); - lit.setValue( new StringLiteral(removeQuotesAndEscapes(t.image))); - } - - | <INTEGER_LITERAL> - { - t= getToken(0); - try { - lit.setValue(new IntegerLiteral(new Integer(t.image))); - } catch(NumberFormatException ex) { - lit.setValue(new LongIntegerLiteral(new Long(t.image))); - } - } - | < FLOAT_LITERAL > - { - t= getToken(0); - lit.setValue(new FloatLiteral(new Float(t.image))); - } - | < DOUBLE_LITERAL > - { - t= getToken(0); - lit.setValue(new DoubleLiteral(new Double(t.image))); - } - | <NULL> - { - t= getToken(0); - lit.setValue(NullLiteral.INSTANCE); - } - | <TRUE> - { - t= getToken(0); - lit.setValue(TrueLiteral.INSTANCE); - } - | <FALSE> - { - t= getToken(0); - lit.setValue(FalseLiteral.INSTANCE); - } -) - { - return lit; - } -} - - -VariableExpr VariableRef() throws ParseException: -{ - VariableExpr varExp = new VariableExpr(); - VarIdentifier var = new VarIdentifier(); - Token t; -} -{ - <VARIABLE> - { - t = getToken(0);//get current token - String varName = t.toString(); - Identifier ident = lookupSymbol(varName); - if (isInForbiddenScopes(varName)) { - throw new ParseException("Inside limit clauses, it is disallowed to reference a variable having the same name as any variable bound in the same scope as the limit clause."); - } - if(ident != null) { // exist such ident - varExp.setIsNewVar(false); - varExp.setVar((VarIdentifier)ident); - } else { - varExp.setVar(var); - } - var.setValue(t.toString()); - return varExp; - } -} - - -VariableExpr Variable() throws ParseException: -{ - VariableExpr varExp = new VariableExpr(); - VarIdentifier var = new VarIdentifier(); - Token t; -} -{ - <VARIABLE> - { - t = getToken(0);//get current token - Identifier ident = lookupSymbol(t.toString()); - if(ident != null) { // exist such ident - varExp.setIsNewVar(false); - } - varExp.setVar(var); - var.setValue(t.toString()); - return varExp; - } -} - -MetaVariableExpr MetaVariableRef() throws ParseException: -{ - MetaVariableExpr metaVarExp = new MetaVariableExpr(); - VarIdentifier var = new VarIdentifier(); - Token t; -} -{ - <METAVARIABLE> - { - t = getToken(0);//get current token - metaVarExp.setVar(var); - var.setValue(t.toString()); - return metaVarExp; - } -} - -Expression ListConstructor() throws ParseException: -{ - Expression expr = null; -} -{ - ( - expr = OrderedListConstructor() | expr = UnorderedListConstructor() - ) - - { - return expr; - } -} - - -ListConstructor OrderedListConstructor() throws ParseException: -{ - ListConstructor expr = new ListConstructor(); - Expression tmp = null; - List<Expression> exprList = new ArrayList<Expression>(); - expr.setType(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR); -} -{ - - "[" - ( tmp = Expression() - { - exprList.add(tmp); - } - - ("," tmp = Expression() { exprList.add(tmp); })* - )? - - "]" - - { - expr.setExprList(exprList); - return expr; - } -} - -ListConstructor UnorderedListConstructor() throws ParseException: -{ - ListConstructor expr = new ListConstructor(); - Expression tmp = null; - List<Expression> exprList = new ArrayList<Expression>(); - expr.setType(ListConstructor.Type.UNORDERED_LIST_CONSTRUCTOR); -} -{ - - "{{" ( tmp = Expression() - { - exprList.add(tmp); - } - ("," tmp = Expression() { exprList.add(tmp); })*)? "}}" - { - expr.setExprList(exprList); - return expr; - } -} - -RecordConstructor RecordConstructor() throws ParseException: -{ - RecordConstructor expr = new RecordConstructor(); - FieldBinding tmp = null; - List<FieldBinding> fbList = new ArrayList<FieldBinding>(); -} -{ - "{" (tmp = FieldBinding() - { - fbList.add(tmp); - } - ("," tmp = FieldBinding() { fbList.add(tmp); })*)? "}" - { - expr.setFbList(fbList); - return expr; - } -} - -FieldBinding FieldBinding() throws ParseException: -{ - FieldBinding fb = new FieldBinding(); - Expression left, right; -} -{ - left = Expression() ":" right = Expression() - { - fb.setLeftExpr(left); - fb.setRightExpr(right); - return fb; - } -} - -Expression FunctionCallExpr() throws ParseException: -{ - CallExpr callExpr; - List<Expression> argList = new ArrayList<Expression>(); - Expression tmp; - int arity = 0; - String funcName; - String dataverse; - String hint=null; - String id1=null; - String id2=null; -} -{ - ( <IDENTIFIER> { dataverse = defaultDataverse; funcName = token.image;} - ("." <IDENTIFIER> { dataverse = funcName; funcName = token.image;})? - | - <DATASET> {dataverse = MetadataConstants.METADATA_DATAVERSE_NAME; funcName = getToken(0).toString();} - ) - { - hint=getHint(token); - } - <LEFTPAREN> (tmp = Expression() - { - argList.add(tmp); - arity ++; - } ("," tmp = Expression() { argList.add(tmp); arity++; })*)? <RIGHTPAREN> - - { - FunctionSignature signature = lookupFunctionSignature(dataverse, funcName.toString(), arity); - if(signature == null) - { - signature = new FunctionSignature(dataverse, funcName.toString(), arity); - } - callExpr = new CallExpr(signature,argList); - if (hint != null && hint.startsWith(INDEXED_NESTED_LOOP_JOIN_HINT)) { - callExpr.addHint(IndexedNLJoinExpressionAnnotation.INSTANCE); - } - return callExpr; - } -} - - -Expression ParenthesizedExpression() throws ParseException: -{ - Expression expr; -} -{ - <LEFTPAREN> expr = Expression() <RIGHTPAREN> - { - return expr; - } -} - -Expression IfThenElse() throws ParseException: -{ - Expression condExpr; - Expression thenExpr; - Expression elseExpr; - IfExpr ifExpr = new IfExpr(); -} -{ - "if" <LEFTPAREN> condExpr = Expression() <RIGHTPAREN> "then" thenExpr = Expression() "else" elseExpr = Expression() - - { - ifExpr.setCondExpr(condExpr); - ifExpr.setThenExpr(thenExpr); - ifExpr.setElseExpr(elseExpr); - return ifExpr; - } -} - -Expression FLWOGR() throws ParseException: -{ - FLWOGRExpression flworg = new FLWOGRExpression(); - List<Clause> clauseList = new ArrayList<Clause>(); - Expression returnExpr; - Clause tmp; - createNewScope(); -} -{ - (tmp = ForClause() {clauseList.add(tmp);} | tmp = LetClause() {clauseList.add(tmp);} | tmp = MetaVariableClause() {clauseList.add(tmp);}) - (tmp = Clause() {clauseList.add(tmp);})* "return" returnExpr = Expression() - - { - flworg.setClauseList(clauseList); - flworg.setReturnExpr(returnExpr); - removeCurrentScope(); - return flworg; - } -} - -List<Clause> Clauses() throws ParseException: -{ - List<Clause> clauses = new ArrayList<Clause>(); - Clause c = null; -} -{ - ( - ( - c = Clause() { - clauses.add(c); - } - )* - ) - { - return clauses; - } -} - -Clause Clause() throws ParseException : -{ - Clause clause; -} -{ - ( - clause = ForClause() - | clause = LetClause() - | clause = WhereClause() - | clause = OrderbyClause() - | clause = GroupClause() - | clause = LimitClause() - | clause = DistinctClause() - | clause = MetaVariableClause() - | clause = JoinClause() - ) - { - return clause; - } -} - -Clause MetaVariableClause() throws ParseException : -{ - MetaVariableClause mc = new MetaVariableClause(); - VarIdentifier var = new VarIdentifier(); - Token t; -} -{ - <METAVARIABLECLAUSE> - { - t = getToken(0); - mc.setVar(var); - var.setValue(t.toString()); - return mc; - } -} - -Clause JoinClause() throws ParseException : -{ - Expression whereExpr; - List<Clause> leftClauses, rightClauses; - JoinClause.JoinKind kind = JoinClause.JoinKind.INNER; -} -{ - ("join" | "loj" { kind = JoinClause.JoinKind.LEFT_OUTER; } ) - <LEFTPAREN> <LEFTPAREN> leftClauses = Clauses() <RIGHTPAREN> "," - <LEFTPAREN> rightClauses = Clauses() <RIGHTPAREN> "," - whereExpr = Expression() <RIGHTPAREN> - { - JoinClause jc = new JoinClause(kind); - jc.setLeftClauses(leftClauses); - jc.setRightClauses(rightClauses); - jc.setWhereExpr(whereExpr); - return jc; - } -} - -Clause ForClause()throws ParseException : -{ - ForClause fc = new ForClause(); - VariableExpr varExp; - VariableExpr varPos = null; - Expression inExp; - extendCurrentScope(); -} -{ - "for" varExp = Variable() - { - getCurrentScope().addNewVarSymbolToScope(varExp.getVar()); - } - ("at" varPos = Variable() - { - getCurrentScope().addNewVarSymbolToScope(varPos.getVar()); - } - )? - "in" ( inExp = Expression() ) - { - fc.setVarExpr(varExp); - fc.setInExpr(inExp); - if (varPos != null) { - fc.setPosExpr(varPos); - } - return fc; - } -} - -Clause LetClause() throws ParseException: -{ - LetClause lc = new LetClause(); - VariableExpr varExp; - Expression beExp; - extendCurrentScope(); -} -{ - "let" varExp = Variable() ":=" beExp = Expression() - { - getCurrentScope().addNewVarSymbolToScope(varExp.getVar()); - lc.setVarExpr(varExp); - lc.setBindingExpr(beExp); - return lc; - } -} - -Clause WhereClause()throws ParseException : -{ - WhereClause wc = new WhereClause(); - Expression whereExpr; -} -{ - "where" whereExpr = Expression() - { - wc.setWhereExpr(whereExpr); - return wc; - } -} - -Clause OrderbyClause()throws ParseException : -{ - OrderbyClause oc = new OrderbyClause(); - Expression orderbyExpr; - List<Expression> orderbyList = new ArrayList<Expression>(); - List<OrderbyClause.OrderModifier> modifierList = new ArrayList<OrderbyClause.OrderModifier >(); - int numOfOrderby = 0; -} -{ - ( - "order" - { - String hint = getHint(token); - if (hint != null && hint.startsWith(INMEMORY_HINT)) { - String splits[] = hint.split(" +"); - int numFrames = Integer.parseInt(splits[1]); - int numTuples = Integer.parseInt(splits[2]); - oc.setNumFrames(numFrames); - oc.setNumTuples(numTuples); - } - } - "by" orderbyExpr = Expression() - { - orderbyList.add(orderbyExpr); - OrderbyClause.OrderModifier modif = OrderbyClause.OrderModifier.ASC; - } - ( ("asc" { modif = OrderbyClause.OrderModifier.ASC; }) - | ("desc" { modif = OrderbyClause.OrderModifier.DESC; }))? - { - modifierList.add(modif); - } - - ("," orderbyExpr = Expression() - { - orderbyList.add(orderbyExpr); - modif = OrderbyClause.OrderModifier.ASC; - } - ( ("asc" { modif = OrderbyClause.OrderModifier.ASC; }) - | ("desc" { modif = OrderbyClause.OrderModifier.DESC; }))? - { - modifierList.add(modif); - } - )* -) - { - oc.setModifierList(modifierList); - oc.setOrderbyList(orderbyList); - return oc; - } -} -Clause GroupClause()throws ParseException : -{ - GroupbyClause gbc = new GroupbyClause(); - // GbyVariableExpressionPair pair = new GbyVariableExpressionPair(); - List<GbyVariableExpressionPair> vePairList = new ArrayList<GbyVariableExpressionPair>(); - List<GbyVariableExpressionPair> decorPairList = new ArrayList<GbyVariableExpressionPair>(); - Map<Expression, VariableExpr> withVarMap= new HashMap<Expression, VariableExpr>(); - VariableExpr var = null; - VariableExpr withVar = null; - Expression expr = null; - VariableExpr decorVar = null; - Expression decorExpr = null; -} -{ - { - Scope newScope = extendCurrentScopeNoPush(true); - // extendCurrentScope(true); - } - "group" - { - String hint = getHint(token); - if (hint != null && hint.equals(HASH_GROUP_BY_HINT)) { - gbc.setHashGroupByHint(true); - } - } - "by" (LOOKAHEAD(2) var = Variable() - { - newScope.addNewVarSymbolToScope(var.getVar()); - } ":=")? - expr = Expression() - { - GbyVariableExpressionPair pair1 = new GbyVariableExpressionPair(var, expr); - vePairList.add(pair1); - } - ("," ( LOOKAHEAD(2) var = Variable() - { - newScope.addNewVarSymbolToScope(var.getVar()); - } ":=")? - expr = Expression() - { - GbyVariableExpressionPair pair2 = new GbyVariableExpressionPair(var, expr); - vePairList.add(pair2); - } - )* - ("decor" decorVar = Variable() ":=" decorExpr = Expression() - { - newScope.addNewVarSymbolToScope(decorVar.getVar()); - GbyVariableExpressionPair pair3 = new GbyVariableExpressionPair(decorVar, decorExpr); - decorPairList.add(pair3); - } - ("," "decor" decorVar = Variable() ":=" decorExpr = Expression() - { - newScope.addNewVarSymbolToScope(decorVar.getVar()); - GbyVariableExpressionPair pair4 = new GbyVariableExpressionPair(decorVar, decorExpr); - decorPairList.add(pair4); - } - )* - )? - "with" withVar = VariableRef() - { - if(withVar.getIsNewVar()==true) - throw new ParseException("can't find variable " + withVar.getVar()); - withVarMap.put(withVar, withVar); - newScope.addNewVarSymbolToScope(withVar.getVar()); - } - ("," withVar = VariableRef() - { - if(withVar.getIsNewVar()==true) - throw new ParseException("can't find variable " + withVar.getVar()); - withVarMap.put(withVar, withVar); - newScope.addNewVarSymbolToScope(withVar.getVar()); - })* - { - gbc.setGbyPairList(vePairList); - gbc.setDecorPairList(decorPairList); - gbc.setWithVarMap(withVarMap); - replaceCurrentScope(newScope); - return gbc; - } -} - - -LimitClause LimitClause() throws ParseException: -{ - LimitClause lc = new LimitClause(); - Expression expr; - pushForbiddenScope(getCurrentScope()); -} -{ - "limit" expr = Expression() { lc.setLimitExpr(expr); } - ("offset" expr = Expression() { lc.setOffset(expr); })? - - { - popForbiddenScope(); - return lc; - } -} - -DistinctClause DistinctClause() throws ParseException: -{ - List<Expression> exprs = new ArrayList<Expression>(); - Expression expr; -} -{ - "distinct" "by" expr = Expression() - { - exprs.add(expr); - } - ("," expr = Expression() - { - exprs.add(expr); - } - )* - { - return new DistinctClause(exprs); - } -} - - -QuantifiedExpression QuantifiedExpression()throws ParseException: -{ - QuantifiedExpression qc = new QuantifiedExpression(); - List<QuantifiedPair> quantifiedList = new ArrayList<QuantifiedPair>(); - Expression satisfiesExpr; - VariableExpr var; - Expression inExpr; - QuantifiedPair pair; -} -{ - { - createNewScope(); - } - - ( ("some" { qc.setQuantifier(QuantifiedExpression.Quantifier.SOME); }) - | ("every" { qc.setQuantifier(QuantifiedExpression.Quantifier.EVERY); })) - var = Variable() "in" inExpr = Expression() - { - pair = new QuantifiedPair(var, inExpr); - getCurrentScope().addNewVarSymbolToScope(var.getVar()); - quantifiedList.add(pair); - } - ( - "," var = Variable() "in" inExpr = Expression() - { - pair = new QuantifiedPair(var, inExpr); - getCurrentScope().addNewVarSymbolToScope(var.getVar()); - quantifiedList.add(pair); - } - )* - "satisfies" satisfiesExpr = Expression() - { - qc.setSatisfiesExpr(satisfiesExpr); - qc.setQuantifiedList(quantifiedList); - removeCurrentScope(); - return qc; - } -} - -TOKEN_MGR_DECLS: -{ - public int commentDepth = 0; -} - -<DEFAULT> -TOKEN : -{ - <CARET : "^" > -} - -<DEFAULT> -TOKEN : -{ - <DATASET : "dataset" > -} - -<DEFAULT> -TOKEN : -{ - <LEFTPAREN : "(" > -} - -<DEFAULT> -TOKEN : -{ - <RIGHTPAREN : ")" > -} - - -<DEFAULT> -TOKEN : -{ - <INTEGER_LITERAL : (<DIGIT>)+ > -} - - -<DEFAULT> -TOKEN : -{ - <NULL : "null"> -} - -<DEFAULT> -TOKEN : -{ - <TRUE : "true"> -} - -<DEFAULT> -TOKEN : -{ - <FALSE : "false"> -} - -<DEFAULT> -TOKEN : -{ - <#DIGIT : ["0" - "9"]> -} - - -TOKEN: -{ - < DOUBLE_LITERAL: <INTEGER> - | <INTEGER> ( "." <INTEGER> )? - | "." <INTEGER> - > - | - < FLOAT_LITERAL: <INTEGER> ( "f" | "F" ) - | <INTEGER> ( "." <INTEGER> ( "f" | "F" ) )? - | "." <INTEGER> ( "f" | "F" ) - > - | - <INTEGER : (<DIGIT>)+ > -} - -<DEFAULT> -TOKEN : -{ - <#LETTER : ["A" - "Z", "a" - "z"]> -} - -<DEFAULT> -TOKEN : -{ - <SPECIALCHARS : ["$", "_", "-"] > -} - -<DEFAULT> -TOKEN : -{ - <STRING_LITERAL : ("\"" (<EscapeQuot> | ~["\""])* "\"") | ("\'"(<EscapeApos> | ~["\'"])* "\'")> - | - < #EscapeQuot: "\\\"" > - | - < #EscapeApos: "\\\'" > -} - -<DEFAULT> -TOKEN : -{ - <IDENTIFIER : (<LETTER>)+ (<LETTER> | <DIGIT> | <SPECIALCHARS>)*> -} - -<DEFAULT> -TOKEN : -{ - <VARIABLE : "$" <IDENTIFIER> > -} - -<DEFAULT> -TOKEN : -{ - <METAVARIABLECLAUSE : "#" <IDENTIFIER> > -} - -<DEFAULT> -TOKEN : -{ - <METAVARIABLE : "$$" <IDENTIFIER> > -} - -SKIP: -{ - " " -| "\t" -| "\r" -| "\n" -} - -SKIP: -{ - <"//" (~["\n"])* "\n"> -} - -SKIP: -{ - <"//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?> -} - - -SKIP: -{ - <"/*"> {commentDepth=1;}: INSIDE_COMMENT -} - -<INSIDE_COMMENT> -SPECIAL_TOKEN: -{ - <"+"(" ")*(~["/","*"])*> -} - -<INSIDE_COMMENT> -SKIP: -{ - <"/*"> {commentDepth++;} -} - -<INSIDE_COMMENT> -SKIP: -{ - <"*/"> {commentDepth--; if (commentDepth == 0) SwitchTo(DEFAULT);} -| <~[]> -} diff --git a/asterixdb/asterix-algebra/src/main/javacc/AQLPlusExtension.jj b/asterixdb/asterix-algebra/src/main/javacc/AQLPlusExtension.jj new file mode 100644 index 0000000..4024342 --- /dev/null +++ b/asterixdb/asterix-algebra/src/main/javacc/AQLPlusExtension.jj @@ -0,0 +1,175 @@ +// This is not a complete javacc file. +// This file is used by asterix-grammar-extension-maven-plugin to extend the AQL grammar to AQL+ grammar. +// For more details about how to use this plugin, refer to asterix-grammar-extension-maven-plugin. + +// If you want to put an additional import, just add import statements like the following. +// import package name +import org.apache.asterix.lang.aql.clause.JoinClause; +import org.apache.asterix.lang.aql.clause.MetaVariableClause; +import org.apache.asterix.lang.aql.expression.MetaVariableExpr; + +// To remove an import, use the keyword unimport +// unimport package name + +// If you want to add a method in the class definition (before PARSER_END), use the following phrase and attach +// new method right after the phrase. +// @new_at_the_end +@new_at_the_class_def + public void initScope() { + scopeStack.push(RootScopeFactory.createRootScope(this)); + } + +// Merging of non-terminals can only be done on non-terminals which conform to the following structure. +// Content will simply be prepended or appended to the base blocks. +// Note: refrain from using the strings "before:" and "after:" in the merge areas as that will break the merge. +// As a workaround, you can always override +// one additional possible change is direct replacement and it can be done through the followin syntax: +// @merge replace "base phrase" with "extension phrase" true/false +// Here, true/false tells whether the tool needs to process the three blocks. +// If true, like normal @merge case, before and after clause in each block will be processed +// after "base phrase" in the blocks have been replaced with "new phrase". +// If false, then it just expects the blank form that consists of three blocks and not process them. +// Only, "base phrase" in the blocks will be replaced with "new phrase". +@merge +Clause Clause() throws ParseException : +{ + // merge area 1 + before: + after: +} +{ + ( + // merge area 2 + before: + after: | clause = MetaVariableClause() + | clause = JoinClause()) + { + // merge area 3 + } +} + +@merge +Expression PrimaryExpr()throws ParseException: +{ + // merge area 1 + before: + after: +} +{ + ( + // merge area 2 + before: + after: | expr = MetaVariableRef()) + { + // merge area 3 + } +} + +// In the following case, all instances of "tmp = LetClause() {clauseList.add(tmp);}" will be replaced +// with "tmp = LetClause() {clauseList.add(tmp);} | tmp = MetaVariableClause() {clauseList.add(tmp);}". +// Also, we don't check "before:" and "after:" section of each area. That check will be ignored since +// the last parameter is set to false. +@merge replace "tmp = LetClause() {clauseList.add(tmp);}" with "tmp = LetClause() {clauseList.add(tmp);} | tmp = MetaVariableClause() {clauseList.add(tmp);}" false +Expression FLWOGR() throws ParseException: +{ + // merge area 1 +} +{ + ( + // merge area 2 + ) + { + // merge area 3 + } +} + +// The default option when you don't specify any @optiontype. +// Adding a new node. if a node exists, it will throw an exception. +@new +Clause MetaVariableClause() throws ParseException : +{ + MetaVariableClause mc = new MetaVariableClause(); + VarIdentifier var = new VarIdentifier(); +} +{ + <METAVARIABLECLAUSE> + { + mc.setVar(var); + var.setValue(token.image); + return mc; + } +} + +@new +MetaVariableExpr MetaVariableRef() throws ParseException: +{ + MetaVariableExpr metaVarExp = new MetaVariableExpr(); + VarIdentifier var = new VarIdentifier(); +} +{ + <METAVARIABLE> + { + metaVarExp.setVar(var); + var.setValue(token.image); + return metaVarExp; + } +} + +@new +Clause JoinClause() throws ParseException : +{ + Expression whereExpr; + List<Clause> leftClauses, rightClauses; + JoinClause.JoinKind kind = JoinClause.JoinKind.INNER; +} +{ + ("join" | "loj" { kind = JoinClause.JoinKind.LEFT_OUTER; } ) + <LEFTPAREN> <LEFTPAREN> leftClauses = Clauses() <RIGHTPAREN> <COMMA> + <LEFTPAREN> rightClauses = Clauses() <RIGHTPAREN> <COMMA> + whereExpr = Expression() <RIGHTPAREN> + { + JoinClause jc = new JoinClause(kind); + jc.setLeftClauses(leftClauses); + jc.setRightClauses(rightClauses); + jc.setWhereExpr(whereExpr); + return jc; + } +} + +@new +List<Clause> Clauses() throws ParseException: +{ + List<Clause> clauses = new ArrayList<Clause>(); + Clause c = null; +} +{ + ( + ( + c = Clause() { + clauses.add(c); + } + )* + ) + { + return clauses; + } +} + +// Overriding a non-terminal. if exists in base, it will be overriden, otherwise, it will be added. +// @override + + +// If something needs to be added at the end of file, you can use @new_at_the_end like the following. +@new_at_the_end +<DEFAULT,IN_DBL_BRACE> +TOKEN : +{ + <METAVARIABLE : "$$" <IDENTIFIER> > +} + +@new_at_the_end +<DEFAULT,IN_DBL_BRACE> +TOKEN : +{ + <METAVARIABLECLAUSE : "##" <IDENTIFIER> > +} diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java index 5ae313d..dd7c8e4 100644 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java @@ -77,6 +77,8 @@ public static final int COMPILATION_PRIMARY_KEY_CANNOT_BE_NULLABLE = 1021; public static final int COMPILATION_ILLEGAL_PRIMARY_KEY_TYPE = 1022; public static final int COMPILATION_CANT_DROP_ACTIVE_DATASET = 1023; + public static final int COMPILATION_AQLPLUS_IDENTIFIER_NOT_FOUND = 1024; + public static final int COMPILATION_AQLPLUS_NO_SUCH_JOIN_TYPE = 1025; // Feed errors public static final int DATAFLOW_ILLEGAL_STATE = 3001; diff --git a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties index 440e2d3..3e96972 100644 --- a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties +++ b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties @@ -62,6 +62,8 @@ 1021 = The primary key field \"%1$s\" cannot be nullable 1022 = Field of type %1$s cannot be used as a primary key field 1023 = Can't drop dataset %1$s since it is connected to active entity: %2$s +1024 = Identifier %1$s is not found in AQL+ meta-scope +1025 = There is no such join type in AQL+ # Feed Errors 3001 = Illegal state. diff --git a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj b/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj index 4b2091c..e5af86f 100644 --- a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj +++ b/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj @@ -2302,6 +2302,9 @@ } } +// Note: if you modify this part: "tmp = LetClause() {clauseList.add(tmp);}", please also apply the necessary +// change to the AQLPlusExtension.jj file since it refers to this string part and may behave incorrectly if this +// part is modified. For more details, please refer to AQLPlusExtension.jj file. Expression FLWOGR() throws ParseException: { FLWOGRExpression flworg = new FLWOGRExpression(); -- To view, visit https://asterix-gerrit.ics.uci.edu/1434 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: merged Gerrit-Change-Id: I444dbf4f615c23ccd69a5e4bb1ead300d0a81451 Gerrit-PatchSet: 18 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Taewoo Kim <[email protected]> Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Michael Carey <[email protected]> Gerrit-Reviewer: Taewoo Kim <[email protected]> Gerrit-Reviewer: Till Westmann <[email protected]> Gerrit-Reviewer: Yingyi Bu <[email protected]>
