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 <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Yingyi Bu <buyingyi@gmail.com>
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();