Supprt querying meta record with meta().
Change-Id: Ie65417b6baf209ca0ab413cfa4a5f7fc5156ca63
Reviewed-on: https://asterix-gerrit.ics.uci.edu/685
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <tillw@apache.org>
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/ExternalDataLookupPOperator.java b/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/ExternalDataLookupPOperator.java
index 4c0818b..1f5b47e 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/ExternalDataLookupPOperator.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/ExternalDataLookupPOperator.java
@@ -114,7 +114,8 @@
public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context)
throws AlgebricksException {
AqlDataSource ds = new DatasetDataSource(datasetId, datasetId.getDataverseName(), datasetId.getDatasourceName(),
- recordType, null /*external dataset doesn't have meta records.*/, AqlDataSourceType.EXTERNAL_DATASET);
+ recordType, null /*external dataset doesn't have meta records.*/, AqlDataSourceType.EXTERNAL_DATASET,
+ dataset.getDatasetDetails());
IDataSourcePropertiesProvider dspp = ds.getPropertiesProvider();
AbstractScanOperator as = (AbstractScanOperator) op;
deliveredProperties = dspp.computePropertiesVector(as.getVariables());
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
index ad5283a..8627b97 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
@@ -50,6 +50,7 @@
import org.apache.asterix.optimizer.rules.IntroduceStaticTypeCastForInsertRule;
import org.apache.asterix.optimizer.rules.IntroduceUnnestForCollectionToSequenceRule;
import org.apache.asterix.optimizer.rules.LoadRecordFieldsRule;
+import org.apache.asterix.optimizer.rules.MetaFunctionToMetaVariableRule;
import org.apache.asterix.optimizer.rules.NestGroupByRule;
import org.apache.asterix.optimizer.rules.PushAggFuncIntoStandaloneAggregateRule;
import org.apache.asterix.optimizer.rules.PushAggregateIntoGroupbyRule;
@@ -167,6 +168,7 @@
normalization.add(new ConstantFoldingRule());
normalization.add(new RemoveRedundantSelectRule());
normalization.add(new UnnestToDataScanRule());
+ normalization.add(new MetaFunctionToMetaVariableRule());
normalization.add(new IfElseToSwitchCaseFunctionRule());
normalization.add(new FuzzyEqRule());
normalization.add(new SimilarityCheckRule());
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java
index ebe01a7..c534454 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java
@@ -90,7 +90,7 @@
AsterixBuiltinFunctions.GET_RECORD_FIELD_VALUE, AsterixBuiltinFunctions.FIELD_ACCESS_NESTED,
AsterixBuiltinFunctions.GET_ITEM, AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR,
AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX, AsterixBuiltinFunctions.CAST_RECORD,
- AsterixBuiltinFunctions.CAST_LIST);
+ AsterixBuiltinFunctions.CAST_LIST, AsterixBuiltinFunctions.META);
/** Throws exceptions in substituiteProducedVariable, setVarType, and one getVarType method. */
private static final IVariableTypeEnvironment _emptyTypeEnv = new IVariableTypeEnvironment() {
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
index 956e6c5..ab09188 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
@@ -18,7 +18,6 @@
*/
package org.apache.asterix.optimizer.rules;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -558,67 +557,62 @@
throws AsterixException, AlgebricksException {
ARecordType enforcedType = initialType;
for (int i = 0; i < index.getKeyFieldNames().size(); i++) {
- try {
- Stack<Pair<ARecordType, String>> nestedTypeStack = new Stack<Pair<ARecordType, String>>();
- List<String> splits = index.getKeyFieldNames().get(i);
- ARecordType nestedFieldType = enforcedType;
- boolean openRecords = false;
- String bridgeName = nestedFieldType.getTypeName();
- int j;
- // Build the stack for the enforced type
- for (j = 1; j < splits.size(); j++) {
- nestedTypeStack.push(new Pair<ARecordType, String>(nestedFieldType, splits.get(j - 1)));
- bridgeName = nestedFieldType.getTypeName();
- nestedFieldType = (ARecordType) enforcedType.getSubFieldType(splits.subList(0, j));
- if (nestedFieldType == null) {
- openRecords = true;
- break;
- }
+
+ Stack<Pair<ARecordType, String>> nestedTypeStack = new Stack<Pair<ARecordType, String>>();
+ List<String> splits = index.getKeyFieldNames().get(i);
+ ARecordType nestedFieldType = enforcedType;
+ boolean openRecords = false;
+ String bridgeName = nestedFieldType.getTypeName();
+ int j;
+ // Build the stack for the enforced type
+ for (j = 1; j < splits.size(); j++) {
+ nestedTypeStack.push(new Pair<ARecordType, String>(nestedFieldType, splits.get(j - 1)));
+ bridgeName = nestedFieldType.getTypeName();
+ nestedFieldType = (ARecordType) enforcedType.getSubFieldType(splits.subList(0, j));
+ if (nestedFieldType == null) {
+ openRecords = true;
+ break;
}
- if (openRecords == true) {
- // create the smallest record
- enforcedType = new ARecordType(splits.get(splits.size() - 2),
- new String[] { splits.get(splits.size() - 1) },
- new IAType[] { AUnionType.createNullableType(index.getKeyFieldTypes().get(i)) }, true);
- // create the open part of the nested field
- for (int k = splits.size() - 3; k > (j - 2); k--) {
- enforcedType = new ARecordType(splits.get(k), new String[] { splits.get(k + 1) },
- new IAType[] { AUnionType.createNullableType(enforcedType) }, true);
- }
- // Bridge the gap
- Pair<ARecordType, String> gapPair = nestedTypeStack.pop();
- ARecordType parent = gapPair.first;
-
- IAType[] parentFieldTypes = ArrayUtils.addAll(parent.getFieldTypes().clone(),
- new IAType[] { AUnionType.createNullableType(enforcedType) });
- enforcedType = new ARecordType(bridgeName,
- ArrayUtils.addAll(parent.getFieldNames(), enforcedType.getTypeName()), parentFieldTypes,
- true);
-
- } else {
- // Schema is closed all the way to the field
- // enforced fields are either null or strongly typed
- enforcedType = new ARecordType(nestedFieldType.getTypeName(),
- ArrayUtils.addAll(nestedFieldType.getFieldNames(), splits.get(splits.size() - 1)),
- ArrayUtils.addAll(nestedFieldType.getFieldTypes(),
- AUnionType.createNullableType(index.getKeyFieldTypes().get(i))),
- nestedFieldType.isOpen());
+ }
+ if (openRecords == true) {
+ // create the smallest record
+ enforcedType = new ARecordType(splits.get(splits.size() - 2),
+ new String[] { splits.get(splits.size() - 1) },
+ new IAType[] { AUnionType.createNullableType(index.getKeyFieldTypes().get(i)) }, true);
+ // create the open part of the nested field
+ for (int k = splits.size() - 3; k > (j - 2); k--) {
+ enforcedType = new ARecordType(splits.get(k), new String[] { splits.get(k + 1) },
+ new IAType[] { AUnionType.createNullableType(enforcedType) }, true);
}
+ // Bridge the gap
+ Pair<ARecordType, String> gapPair = nestedTypeStack.pop();
+ ARecordType parent = gapPair.first;
- // Create the enforcedtype for the nested fields in the schema, from the ground up
- if (nestedTypeStack.size() > 0) {
- while (!nestedTypeStack.isEmpty()) {
- Pair<ARecordType, String> nestedTypePair = nestedTypeStack.pop();
- ARecordType nestedRecType = nestedTypePair.first;
- IAType[] nestedRecTypeFieldTypes = nestedRecType.getFieldTypes().clone();
- nestedRecTypeFieldTypes[nestedRecType.getFieldIndex(nestedTypePair.second)] = enforcedType;
- enforcedType = new ARecordType(nestedRecType.getTypeName(), nestedRecType.getFieldNames(),
- nestedRecTypeFieldTypes, nestedRecType.isOpen());
- }
+ IAType[] parentFieldTypes = ArrayUtils.addAll(parent.getFieldTypes().clone(),
+ new IAType[] { AUnionType.createNullableType(enforcedType) });
+ enforcedType = new ARecordType(bridgeName,
+ ArrayUtils.addAll(parent.getFieldNames(), enforcedType.getTypeName()), parentFieldTypes, true);
+
+ } else {
+ // Schema is closed all the way to the field
+ // enforced fields are either null or strongly typed
+ enforcedType = new ARecordType(nestedFieldType.getTypeName(),
+ ArrayUtils.addAll(nestedFieldType.getFieldNames(), splits.get(splits.size() - 1)),
+ ArrayUtils.addAll(nestedFieldType.getFieldTypes(),
+ AUnionType.createNullableType(index.getKeyFieldTypes().get(i))),
+ nestedFieldType.isOpen());
+ }
+
+ // Create the enforcedtype for the nested fields in the schema, from the ground up
+ if (nestedTypeStack.size() > 0) {
+ while (!nestedTypeStack.isEmpty()) {
+ Pair<ARecordType, String> nestedTypePair = nestedTypeStack.pop();
+ ARecordType nestedRecType = nestedTypePair.first;
+ IAType[] nestedRecTypeFieldTypes = nestedRecType.getFieldTypes().clone();
+ nestedRecTypeFieldTypes[nestedRecType.getFieldIndex(nestedTypePair.second)] = enforcedType;
+ enforcedType = new ARecordType(nestedRecType.getTypeName(), nestedRecType.getFieldNames(),
+ nestedRecTypeFieldTypes, nestedRecType.isOpen());
}
-
- } catch (IOException e) {
- throw new AsterixException(e);
}
}
return enforcedType;
@@ -628,6 +622,7 @@
* This method takes a list of {fields}: a subset of {recordFields}, the original record variable
* and populate expressions with expressions which evaluate to those fields (using field access functions) and
* variables to represent them
+ *
* @param fields
* desired fields
* @param recordFields
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/MetaFunctionToMetaVariableRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/MetaFunctionToMetaVariableRule.java
new file mode 100644
index 0000000..cd06303
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/MetaFunctionToMetaVariableRule.java
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.optimizer.rules;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.asterix.metadata.declared.AqlDataSource;
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+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.IOptimizationContext;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
+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.expressions.AbstractFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
+import org.apache.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionReferenceTransform;
+import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+
+/**
+ * This rule rewrites all meta() function calls in a query plan
+ * to proper variable references.
+ */
+public class MetaFunctionToMetaVariableRule implements IAlgebraicRewriteRule {
+ // The rule can only apply once.
+ private boolean hasApplied = false;
+ private boolean rewritten = false;
+
+ @Override
+ public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+ throws AlgebricksException {
+ if (hasApplied) {
+ return false;
+ }
+ hasApplied = true;
+ visit(opRef);
+ return rewritten;
+ }
+
+ private ILogicalExpressionReferenceTransformWithCondition visit(Mutable<ILogicalOperator> opRef)
+ throws AlgebricksException {
+ ILogicalOperator op = opRef.getValue();
+
+ // Reaches NTS or ETS.
+ if (op.getInputs().size() == 0) {
+ return NoOpExpressionReferenceTransform.INSTANCE;
+ }
+
+ // Datascan returns an useful transform if the meta part presents in the dataset.
+ if (op.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
+ DataSourceScanOperator scanOp = (DataSourceScanOperator) op;
+ ILogicalExpressionReferenceTransformWithCondition inputTransfomer = visit(op.getInputs().get(0));
+ AqlDataSource dataSource = (AqlDataSource) scanOp.getDataSource();
+ if (!dataSource.hasMeta()) {
+ return inputTransfomer;
+ };
+ List<LogicalVariable> allVars = scanOp.getVariables();
+ LogicalVariable dataVar = dataSource.getDataRecordVariable(allVars);
+ LogicalVariable metaVar = dataSource.getMetaVariable(allVars);
+ LogicalExpressionReferenceTransform currentTransformer = new LogicalExpressionReferenceTransform(dataVar,
+ metaVar);
+ if (inputTransfomer.equals(NoOpExpressionReferenceTransform.INSTANCE)) {
+ return currentTransformer;
+ } else {
+ // Requires an argument variable to resolve ambiguity.
+ List<ILogicalExpressionReferenceTransformWithCondition> transformers = new ArrayList<>();
+ inputTransfomer.setVariableRequired();
+ currentTransformer.setVariableRequired();
+ transformers.add(inputTransfomer);
+ transformers.add(currentTransformer);
+ return new CompositeExpressionReferenceTransform(transformers);
+ }
+ }
+
+ // Visits children in the depth-first order.
+ List<ILogicalExpressionReferenceTransformWithCondition> transformers = new ArrayList<>();
+ for (Mutable<ILogicalOperator> childRef : op.getInputs()) {
+ ILogicalExpressionReferenceTransformWithCondition transformer = visit(childRef);
+ if (!transformer.equals(NoOpExpressionReferenceTransform.INSTANCE)) {
+ transformers.add(transformer);
+ }
+ }
+ ILogicalExpressionReferenceTransformWithCondition currentTransformer = null;
+ if (transformers.size() == 0) {
+ currentTransformer = NoOpExpressionReferenceTransform.INSTANCE;
+ } else if (transformers.size() == 1) {
+ currentTransformer = transformers.get(0);
+ } else {
+ // Transformers in a CompositeTransformer should require argument variable check.
+ for (ILogicalExpressionReferenceTransformWithCondition transformer : transformers) {
+ transformer.setVariableRequired();
+ }
+ currentTransformer = new CompositeExpressionReferenceTransform(transformers);
+ }
+ rewritten |= op.acceptExpressionTransform(currentTransformer);
+ return currentTransformer;
+ }
+}
+
+interface ILogicalExpressionReferenceTransformWithCondition extends ILogicalExpressionReferenceTransform {
+ default void setVariableRequired() {
+
+ }
+}
+
+class NoOpExpressionReferenceTransform implements ILogicalExpressionReferenceTransformWithCondition {
+ static NoOpExpressionReferenceTransform INSTANCE = new NoOpExpressionReferenceTransform();
+
+ private NoOpExpressionReferenceTransform() {
+
+ }
+
+ @Override
+ public boolean transform(Mutable<ILogicalExpression> expression) throws AlgebricksException {
+ return false;
+ }
+
+}
+
+class LogicalExpressionReferenceTransform implements ILogicalExpressionReferenceTransformWithCondition {
+ private final LogicalVariable dataVar;
+ private final LogicalVariable metaVar;
+ private boolean variableRequired = false;
+
+ LogicalExpressionReferenceTransform(LogicalVariable dataVar, LogicalVariable metaVar) {
+ this.dataVar = dataVar;
+ this.metaVar = metaVar;
+ }
+
+ @Override
+ public void setVariableRequired() {
+ this.variableRequired = true;
+ }
+
+ @Override
+ public boolean transform(Mutable<ILogicalExpression> exprRef) throws AlgebricksException {
+ ILogicalExpression expr = exprRef.getValue();
+ if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
+ return false;
+ }
+ AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
+ List<Mutable<ILogicalExpression>> argRefs = funcExpr.getArguments();
+
+ // Recursively transform argument expressions.
+ for (Mutable<ILogicalExpression> argRef : argRefs) {
+ transform(argRef);
+ }
+
+ if (!funcExpr.getFunctionIdentifier().equals(AsterixBuiltinFunctions.META)) {
+ return false;
+ }
+ // The user query provides more than one parameter for the meta function.
+ if (argRefs.size() > 1) {
+ throw new AlgebricksException("The meta function can at most have one argument!");
+ }
+
+ // The user query provides exact one parameter for the meta function.
+ if (argRefs.size() == 1) {
+ ILogicalExpression argExpr = argRefs.get(0).getValue();
+ if (argExpr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
+ return false;
+ }
+ VariableReferenceExpression argVarExpr = (VariableReferenceExpression) argExpr;
+ LogicalVariable argVar = argVarExpr.getVariableReference();
+ if (!dataVar.equals(argVar)) {
+ return false;
+ }
+ exprRef.setValue(new VariableReferenceExpression(metaVar));
+ return true;
+ }
+
+ // The user query provides zero parameter for the meta function.
+ if (variableRequired) {
+ throw new AlgebricksException("Cannot resolve to ambiguity on the meta function call --"
+ + " there are more than once dataset choices!");
+ }
+ exprRef.setValue(new VariableReferenceExpression(metaVar));
+ return true;
+ }
+}
+
+class CompositeExpressionReferenceTransform implements ILogicalExpressionReferenceTransformWithCondition {
+ private final List<ILogicalExpressionReferenceTransformWithCondition> transformers;
+
+ public CompositeExpressionReferenceTransform(List<ILogicalExpressionReferenceTransformWithCondition> transforms) {
+ this.transformers = transforms;
+ }
+
+ @Override
+ public boolean transform(Mutable<ILogicalExpression> expression) throws AlgebricksException {
+ // Tries transfomations one by one.
+ for (ILogicalExpressionReferenceTransform transformer : transformers) {
+ if (transformer.transform(expression)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
index cbf0dec..0152c12 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
@@ -18,7 +18,6 @@
*/
package org.apache.asterix.optimizer.rules.am;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
@@ -229,9 +228,11 @@
//Prune indexes based on field types
List<IAType> indexedTypes = new ArrayList<IAType>();
//retrieve types of expressions joined/selected with an indexed field
- for (int j = 0; j < optFuncExpr.getNumLogicalVars(); j++)
- if (j != exprAndVarIdx.second)
+ for (int j = 0; j < optFuncExpr.getNumLogicalVars(); j++) {
+ if (j != exprAndVarIdx.second) {
indexedTypes.add(optFuncExpr.getFieldType(j));
+ }
+ }
//add constants in case of select
if (indexedTypes.size() < 2 && optFuncExpr.getNumLogicalVars() == 1
@@ -247,8 +248,9 @@
@Override
public Object getVarType(LogicalVariable var) throws AlgebricksException {
- if (var.equals(optFuncExpr.getSourceVar(exprAndVarIdx.second)))
+ if (var.equals(optFuncExpr.getSourceVar(exprAndVarIdx.second))) {
return keyType;
+ }
throw new IllegalArgumentException();
}
@@ -256,8 +258,9 @@
public Object getVarType(LogicalVariable var, List<LogicalVariable> nonNullVariables,
List<List<LogicalVariable>> correlatedNullableVariableLists)
throws AlgebricksException {
- if (var.equals(optFuncExpr.getSourceVar(exprAndVarIdx.second)))
+ if (var.equals(optFuncExpr.getSourceVar(exprAndVarIdx.second))) {
return keyType;
+ }
throw new IllegalArgumentException();
}
@@ -282,9 +285,11 @@
boolean jaccardSimilarity = optFuncExpr.getFuncExpr().getFunctionIdentifier().getName()
.startsWith("similarity-jaccard-check");
- for (int j = 0; j < indexedTypes.size(); j++)
- for (int k = j + 1; k < indexedTypes.size(); k++)
+ for (int j = 0; j < indexedTypes.size(); j++) {
+ for (int k = j + 1; k < indexedTypes.size(); k++) {
typeMatch &= isMatched(indexedTypes.get(j), indexedTypes.get(k), jaccardSimilarity);
+ }
+ }
// Check if any field name in the optFuncExpr matches.
if (optFuncExpr.findFieldName(keyField) != -1) {
@@ -333,8 +338,9 @@
private boolean isMatched(IAType type1, IAType type2, boolean useListDomain) throws AlgebricksException {
if (ATypeHierarchy.isSameTypeDomain(Index.getNonNullableType(type1).first.getTypeTag(),
- Index.getNonNullableType(type2).first.getTypeTag(), useListDomain))
+ Index.getNonNullableType(type2).first.getTypeTag(), useListDomain)) {
return true;
+ }
return ATypeHierarchy.canPromote(Index.getNonNullableType(type1).first.getTypeTag(),
Index.getNonNullableType(type2).first.getTypeTag());
}
@@ -438,9 +444,10 @@
if (index.getKeyFieldNames().contains(fieldName) && index.getPendingOp() == IMetadataEntity.PENDING_NO_OP) {
indexCandidates.add(index);
if (optFuncExpr.getFieldType(varIdx) == BuiltinType.ANULL
- || optFuncExpr.getFieldType(varIdx) == BuiltinType.ANY)
+ || optFuncExpr.getFieldType(varIdx) == BuiltinType.ANY) {
optFuncExpr.setFieldType(varIdx,
index.getKeyFieldTypes().get(index.getKeyFieldNames().indexOf(fieldName)));
+ }
analysisCtx.addIndexExpr(matchedSubTree.dataset, index, matchedFuncExprIndex, varIdx);
}
}
@@ -455,9 +462,10 @@
IOptimizationContext context) throws AlgebricksException {
int optFuncExprIndex = 0;
List<Index> datasetIndexes = new ArrayList<Index>();
- if (subTree.dataSourceType != DataSourceType.COLLECTION_SCAN)
+ if (subTree.dataSourceType != DataSourceType.COLLECTION_SCAN) {
datasetIndexes = metadataProvider.getDatasetIndexes(subTree.dataset.getDataverseName(),
subTree.dataset.getDatasetName());
+ }
for (IOptimizableFuncExpr optFuncExpr : analysisCtx.matchedFuncExprs) {
// Try to match variables from optFuncExpr to assigns or unnests.
for (int assignOrUnnestIndex = 0; assignOrUnnestIndex < subTree.assignsAndUnnests
@@ -744,12 +752,8 @@
}
if (!isByName) {
- try {
- fieldName = ((ARecordType) recordType.getSubFieldType(parentFieldNames))
- .getFieldNames()[fieldIndex];
- } catch (IOException e) {
- throw new AlgebricksException(e);
- }
+ fieldName = ((ARecordType) recordType.getSubFieldType(parentFieldNames))
+ .getFieldNames()[fieldIndex];
}
optFuncExpr.setSourceVar(funcVarIndex, ((AssignOperator) op).getVariables().get(assignVarIndex));
//add fieldName to the nested fieldName, return
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
index f39d190..294a098 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
@@ -19,7 +19,6 @@
package org.apache.asterix.optimizer.rules.am;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -36,6 +35,7 @@
import org.apache.asterix.metadata.entities.ExternalDatasetDetails;
import org.apache.asterix.metadata.entities.Index;
import org.apache.asterix.metadata.utils.DatasetUtils;
+import org.apache.asterix.metadata.utils.KeyFieldTypeUtils;
import org.apache.asterix.om.base.ABoolean;
import org.apache.asterix.om.base.AInt32;
import org.apache.asterix.om.base.AInt64;
@@ -47,7 +47,6 @@
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.IAType;
import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
-import org.apache.asterix.om.util.NonTaggedFormatUtil;
import org.apache.commons.lang3.mutable.Mutable;
import org.apache.commons.lang3.mutable.MutableObject;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -82,14 +81,17 @@
*/
public class AccessMethodUtils {
- public static void appendPrimaryIndexTypes(Dataset dataset, IAType itemType, List<Object> target)
- throws IOException, AlgebricksException {
+ public static void appendPrimaryIndexTypes(Dataset dataset, IAType itemType, IAType metaItemType,
+ List<Object> target) throws AlgebricksException {
ARecordType recordType = (ARecordType) itemType;
- List<List<String>> partitioningKeys = DatasetUtils.getPartitioningKeys(dataset);
- for (List<String> partitioningKey : partitioningKeys) {
- target.add(recordType.getSubFieldType(partitioningKey));
- }
+ ARecordType metaRecordType = (ARecordType) metaItemType;
+ target.addAll(KeyFieldTypeUtils.getPartitoningKeyTypes(dataset, recordType, metaRecordType));
+ // Adds data record type.
target.add(itemType);
+ // Adds meta record type if any.
+ if (dataset.hasMetaPart()) {
+ target.add(metaItemType);
+ }
}
public static ConstantExpression createStringConstant(String str) {
@@ -172,8 +174,9 @@
constantExpressionType);
for (IOptimizableFuncExpr optFuncExpr : analysisCtx.matchedFuncExprs) {
//avoid additional optFuncExpressions in case of a join
- if (optFuncExpr.getFuncExpr().equals(funcExpr))
+ if (optFuncExpr.getFuncExpr().equals(funcExpr)) {
return true;
+ }
}
analysisCtx.matchedFuncExprs.add(newOptFuncExpr);
return true;
@@ -196,61 +199,29 @@
new LogicalVariable[] { fieldVar1, fieldVar2 }, new ILogicalExpression[0], new IAType[0]);
for (IOptimizableFuncExpr optFuncExpr : analysisCtx.matchedFuncExprs) {
//avoid additional optFuncExpressions in case of a join
- if (optFuncExpr.getFuncExpr().equals(funcExpr))
+ if (optFuncExpr.getFuncExpr().equals(funcExpr)) {
return true;
+ }
}
analysisCtx.matchedFuncExprs.add(newOptFuncExpr);
return true;
}
- public static int getNumSecondaryKeys(Index index, ARecordType recordType) throws AlgebricksException {
- switch (index.getIndexType()) {
- case BTREE:
- case SINGLE_PARTITION_WORD_INVIX:
- case SINGLE_PARTITION_NGRAM_INVIX:
- case LENGTH_PARTITIONED_WORD_INVIX:
- case LENGTH_PARTITIONED_NGRAM_INVIX: {
- return index.getKeyFieldNames().size();
- }
- case RTREE: {
- Pair<IAType, Boolean> keyPairType = Index.getNonNullableOpenFieldType(index.getKeyFieldTypes().get(0),
- index.getKeyFieldNames().get(0), recordType);
- IAType keyType = keyPairType.first;
- int numDimensions = NonTaggedFormatUtil.getNumDimensions(keyType.getTypeTag());
- return numDimensions * 2;
- }
- default: {
- throw new AlgebricksException("Unknown index kind: " + index.getIndexType());
- }
- }
- }
-
/**
* Appends the types of the fields produced by the given secondary index to dest.
*/
- public static void appendSecondaryIndexTypes(Dataset dataset, ARecordType recordType, Index index,
- boolean primaryKeysOnly, List<Object> dest) throws AlgebricksException {
+ public static void appendSecondaryIndexTypes(Dataset dataset, ARecordType recordType, ARecordType metaRecordType,
+ Index index, boolean primaryKeysOnly, List<Object> dest) throws AlgebricksException {
if (!primaryKeysOnly) {
switch (index.getIndexType()) {
case BTREE:
case SINGLE_PARTITION_WORD_INVIX:
case SINGLE_PARTITION_NGRAM_INVIX: {
- for (int i = 0; i < index.getKeyFieldNames().size(); i++) {
- Pair<IAType, Boolean> keyPairType = Index.getNonNullableOpenFieldType(
- index.getKeyFieldTypes().get(i), index.getKeyFieldNames().get(i), recordType);
- dest.add(keyPairType.first);
- }
+ dest.addAll(KeyFieldTypeUtils.getBTreeIndexKeyTypes(index, recordType, metaRecordType));
break;
}
case RTREE: {
- Pair<IAType, Boolean> keyPairType = Index.getNonNullableOpenFieldType(
- index.getKeyFieldTypes().get(0), index.getKeyFieldNames().get(0), recordType);
- IAType keyType = keyPairType.first;
- IAType nestedKeyType = NonTaggedFormatUtil.getNestedSpatialType(keyType.getTypeTag());
- int numKeys = getNumSecondaryKeys(index, recordType);
- for (int i = 0; i < numKeys; i++) {
- dest.add(nestedKeyType);
- }
+ dest.addAll(KeyFieldTypeUtils.getRTreeIndexKeyTypes(index, recordType, metaRecordType));
break;
}
case LENGTH_PARTITIONED_NGRAM_INVIX:
@@ -268,20 +239,13 @@
throw new AlgebricksException(e);
}
} else {
- List<List<String>> partitioningKeys = DatasetUtils.getPartitioningKeys(dataset);
- for (List<String> partitioningKey : partitioningKeys) {
- try {
- dest.add(recordType.getSubFieldType(partitioningKey));
- } catch (IOException e) {
- throw new AlgebricksException(e);
- }
- }
+ dest.addAll(KeyFieldTypeUtils.getPartitoningKeyTypes(dataset, recordType, metaRecordType));
}
}
- public static void appendSecondaryIndexOutputVars(Dataset dataset, ARecordType recordType, Index index,
- boolean primaryKeysOnly, IOptimizationContext context, List<LogicalVariable> dest)
- throws AlgebricksException {
+ public static void appendSecondaryIndexOutputVars(Dataset dataset, ARecordType recordType,
+ ARecordType metaRecordType, Index index, boolean primaryKeysOnly, IOptimizationContext context,
+ List<LogicalVariable> dest) throws AlgebricksException {
int numPrimaryKeys = 0;
if (dataset.getDatasetType() == DatasetType.EXTERNAL) {
numPrimaryKeys = IndexingConstants
@@ -289,7 +253,7 @@
} else {
numPrimaryKeys = DatasetUtils.getPartitioningKeys(dataset).size();
}
- int numSecondaryKeys = getNumSecondaryKeys(index, recordType);
+ int numSecondaryKeys = KeyFieldTypeUtils.getNumSecondaryKeys(index, recordType, metaRecordType);
int numVars = (primaryKeysOnly) ? numPrimaryKeys : numPrimaryKeys + numSecondaryKeys;
for (int i = 0; i < numVars; i++) {
dest.add(context.newVar());
@@ -422,9 +386,10 @@
return indexExprs.get(0).second;
}
- public static UnnestMapOperator createSecondaryIndexUnnestMap(Dataset dataset, ARecordType recordType, Index index,
- ILogicalOperator inputOp, AccessMethodJobGenParams jobGenParams, IOptimizationContext context,
- boolean outputPrimaryKeysOnly, boolean retainInput) throws AlgebricksException {
+ public static UnnestMapOperator createSecondaryIndexUnnestMap(Dataset dataset, ARecordType recordType,
+ ARecordType metaRecordType, Index index, ILogicalOperator inputOp, AccessMethodJobGenParams jobGenParams,
+ IOptimizationContext context, boolean outputPrimaryKeysOnly, boolean retainInput)
+ throws AlgebricksException {
// The job gen parameters are transferred to the actual job gen via the UnnestMapOperator's function arguments.
ArrayList<Mutable<ILogicalExpression>> secondaryIndexFuncArgs = new ArrayList<Mutable<ILogicalExpression>>();
jobGenParams.writeToFuncArgs(secondaryIndexFuncArgs);
@@ -432,9 +397,10 @@
List<LogicalVariable> secondaryIndexUnnestVars = new ArrayList<LogicalVariable>();
List<Object> secondaryIndexOutputTypes = new ArrayList<Object>();
// Append output variables/types generated by the secondary-index search (not forwarded from input).
- appendSecondaryIndexOutputVars(dataset, recordType, index, outputPrimaryKeysOnly, context,
+ appendSecondaryIndexOutputVars(dataset, recordType, metaRecordType, index, outputPrimaryKeysOnly, context,
secondaryIndexUnnestVars);
- appendSecondaryIndexTypes(dataset, recordType, index, outputPrimaryKeysOnly, secondaryIndexOutputTypes);
+ appendSecondaryIndexTypes(dataset, recordType, metaRecordType, index, outputPrimaryKeysOnly,
+ secondaryIndexOutputTypes);
// An index search is expressed as an unnest over an index-search function.
IFunctionInfo secondaryIndexSearch = FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.INDEX_SEARCH);
UnnestingFunctionCallExpression secondaryIndexSearchFunc = new UnnestingFunctionCallExpression(
@@ -452,9 +418,9 @@
}
public static UnnestMapOperator createPrimaryIndexUnnestMap(AbstractDataSourceOperator dataSourceOp,
- Dataset dataset, ARecordType recordType, ILogicalOperator inputOp, IOptimizationContext context,
- boolean sortPrimaryKeys, boolean retainInput, boolean retainNull, boolean requiresBroadcast)
- throws AlgebricksException {
+ Dataset dataset, ARecordType recordType, ARecordType metaRecordType, ILogicalOperator inputOp,
+ IOptimizationContext context, boolean sortPrimaryKeys, boolean retainInput, boolean retainNull,
+ boolean requiresBroadcast) throws AlgebricksException {
List<LogicalVariable> primaryKeyVars = AccessMethodUtils.getPrimaryKeyVarsFromSecondaryUnnestMap(dataset,
inputOp);
// Optionally add a sort on the primary-index keys before searching the primary index.
@@ -488,11 +454,7 @@
List<Object> primaryIndexOutputTypes = new ArrayList<Object>();
// Append output variables/types generated by the primary-index search (not forwarded from input).
primaryIndexUnnestVars.addAll(dataSourceOp.getVariables());
- try {
- appendPrimaryIndexTypes(dataset, recordType, primaryIndexOutputTypes);
- } catch (IOException e) {
- throw new AlgebricksException(e);
- }
+ appendPrimaryIndexTypes(dataset, recordType, metaRecordType, primaryIndexOutputTypes);
// An index search is expressed as an unnest over an index-search function.
IFunctionInfo primaryIndexSearch = FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.INDEX_SEARCH);
AbstractFunctionCallExpression primaryIndexSearchFunc = new ScalarFunctionCallExpression(primaryIndexSearch,
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
index 1bbb13b..15dbe95 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
@@ -19,7 +19,6 @@
package org.apache.asterix.optimizer.rules.am;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
@@ -481,7 +480,7 @@
}
UnnestMapOperator secondaryIndexUnnestOp = AccessMethodUtils.createSecondaryIndexUnnestMap(dataset, recordType,
- chosenIndex, inputOp, jobGenParams, context, false, retainInput);
+ metaRecordType, chosenIndex, inputOp, jobGenParams, context, false, retainInput);
// Generate the rest of the upstream plan which feeds the search results into the primary index.
UnnestMapOperator primaryIndexUnnestOp = null;
@@ -494,7 +493,7 @@
return externalDataAccessOp;
} else if (!isPrimaryIndex) {
primaryIndexUnnestOp = AccessMethodUtils.createPrimaryIndexUnnestMap(dataSourceOp, dataset, recordType,
- secondaryIndexUnnestOp, context, true, retainInput, retainNull, false);
+ metaRecordType, secondaryIndexUnnestOp, context, true, retainInput, retainNull, false);
// Adds equivalence classes --- one equivalent class between a primary key
// variable and a record field-access expression.
@@ -502,11 +501,7 @@
dataSourceOp.getVariables(), recordType, metaRecordType, dataset, context);
} else {
List<Object> primaryIndexOutputTypes = new ArrayList<Object>();
- try {
- AccessMethodUtils.appendPrimaryIndexTypes(dataset, recordType, primaryIndexOutputTypes);
- } catch (IOException e) {
- throw new AlgebricksException(e);
- }
+ AccessMethodUtils.appendPrimaryIndexTypes(dataset, recordType, metaRecordType, primaryIndexOutputTypes);
List<LogicalVariable> scanVariables = dataSourceOp.getVariables();
primaryIndexUnnestOp = new UnnestMapOperator(scanVariables, secondaryIndexUnnestOp.getExpressionRef(),
primaryIndexOutputTypes, retainInput);
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceLSMComponentFilterRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceLSMComponentFilterRule.java
index 08a4e74..a2bf6d9 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceLSMComponentFilterRule.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceLSMComponentFilterRule.java
@@ -29,6 +29,7 @@
import org.apache.asterix.metadata.entities.Dataset;
import org.apache.asterix.metadata.entities.Index;
import org.apache.asterix.metadata.utils.DatasetUtils;
+import org.apache.asterix.metadata.utils.KeyFieldTypeUtils;
import org.apache.asterix.om.base.AInt32;
import org.apache.asterix.om.base.AString;
import org.apache.asterix.om.constants.AsterixConstantValue;
@@ -109,7 +110,7 @@
for (int i = 0; i < analysisCtx.matchedFuncExprs.size(); i++) {
IOptimizableFuncExpr optFuncExpr = analysisCtx.matchedFuncExprs.get(i);
- boolean found = findMacthedExprFieldName(optFuncExpr, op, dataset, recType, datasetIndexes);
+ boolean found = findMacthedExprFieldName(optFuncExpr, op, dataset, recType, datasetIndexes, context);
if (found && optFuncExpr.getFieldName(0).equals(filterFieldName)) {
optFuncExprs.add(optFuncExpr);
}
@@ -301,7 +302,8 @@
}
private boolean findMacthedExprFieldName(IOptimizableFuncExpr optFuncExpr, AbstractLogicalOperator op,
- Dataset dataset, ARecordType recType, List<Index> datasetIndexes) throws AlgebricksException {
+ Dataset dataset, ARecordType recType, List<Index> datasetIndexes, IOptimizationContext context)
+ throws AlgebricksException {
AbstractLogicalOperator descendantOp = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
while (descendantOp != null) {
if (descendantOp.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
@@ -368,7 +370,10 @@
}
}
- int numSecondaryKeys = AccessMethodUtils.getNumSecondaryKeys(index, recType);
+ IAType metaItemType = ((AqlMetadataProvider) context.getMetadataProvider())
+ .findType(dataset.getMetaItemTypeDataverseName(), dataset.getMetaItemTypeName());
+ ARecordType metaRecType = (ARecordType) metaItemType;
+ int numSecondaryKeys = KeyFieldTypeUtils.getNumSecondaryKeys(index, recType, metaRecType);
List<String> fieldName;
if (varIndex >= numSecondaryKeys) {
fieldName = DatasetUtils.getPartitioningKeys(dataset).get(varIndex - numSecondaryKeys);
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
index 824fe7a..70d7088 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
@@ -66,7 +66,6 @@
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
@@ -364,13 +363,13 @@
@Override
public ILogicalOperator createSecondaryToPrimaryPlan(Mutable<ILogicalExpression> conditionRef,
OptimizableOperatorSubTree indexSubTree, OptimizableOperatorSubTree probeSubTree, Index chosenIndex,
- AccessMethodAnalysisContext analysisCtx,
- boolean retainInput, boolean retainNull, boolean requiresBroadcast, IOptimizationContext context)
- throws AlgebricksException {
+ AccessMethodAnalysisContext analysisCtx, boolean retainInput, boolean retainNull, boolean requiresBroadcast,
+ IOptimizationContext context) throws AlgebricksException {
IOptimizableFuncExpr optFuncExpr = AccessMethodUtils.chooseFirstOptFuncExpr(chosenIndex, analysisCtx);
Dataset dataset = indexSubTree.dataset;
ARecordType recordType = indexSubTree.recordType;
+ ARecordType metaRecordType = indexSubTree.metaRecordType;
// we made sure indexSubTree has datasource scan
DataSourceScanOperator dataSourceScan = (DataSourceScanOperator) indexSubTree.dataSourceRef.getValue();
@@ -407,11 +406,11 @@
}
jobGenParams.setKeyVarList(keyVarList);
UnnestMapOperator secondaryIndexUnnestOp = AccessMethodUtils.createSecondaryIndexUnnestMap(dataset, recordType,
- chosenIndex, inputOp, jobGenParams, context, true, retainInput);
+ metaRecordType, chosenIndex, inputOp, jobGenParams, context, true, retainInput);
// Generate the rest of the upstream plan which feeds the search results into the primary index.
UnnestMapOperator primaryIndexUnnestOp = AccessMethodUtils.createPrimaryIndexUnnestMap(dataSourceScan, dataset,
- recordType, secondaryIndexUnnestOp, context, true, retainInput, retainNull, false);
+ recordType, metaRecordType, secondaryIndexUnnestOp, context, true, retainInput, retainNull, false);
return primaryIndexUnnestOp;
}
@@ -436,8 +435,8 @@
public boolean applySelectPlanTransformation(Mutable<ILogicalOperator> selectRef,
OptimizableOperatorSubTree subTree, Index chosenIndex, AccessMethodAnalysisContext analysisCtx,
IOptimizationContext context) throws AlgebricksException {
- ILogicalOperator indexPlanRootOp = createSecondaryToPrimaryPlan(null, subTree, null, chosenIndex, analysisCtx, false,
- false, false, context);
+ ILogicalOperator indexPlanRootOp = createSecondaryToPrimaryPlan(null, subTree, null, chosenIndex, analysisCtx,
+ false, false, false, context);
// Replace the datasource scan with the new plan rooted at primaryIndexUnnestMap.
subTree.dataSourceRef.setValue(indexPlanRootOp);
return true;
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/RTreeAccessMethod.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/RTreeAccessMethod.java
index 3c925e2..111fcf4 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/RTreeAccessMethod.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/RTreeAccessMethod.java
@@ -179,6 +179,7 @@
IOptimizableFuncExpr optFuncExpr = AccessMethodUtils.chooseFirstOptFuncExpr(chosenIndex, analysisCtx);
Dataset dataset = indexSubTree.dataset;
ARecordType recordType = indexSubTree.recordType;
+ ARecordType metaRecordType = indexSubTree.metaRecordType;
int optFieldIdx = AccessMethodUtils.chooseFirstOptFuncVar(chosenIndex, analysisCtx);
Pair<IAType, Boolean> keyPairType = Index.getNonNullableOpenFieldType(optFuncExpr.getFieldType(optFieldIdx),
@@ -239,7 +240,7 @@
}
UnnestMapOperator secondaryIndexUnnestOp = AccessMethodUtils.createSecondaryIndexUnnestMap(dataset, recordType,
- chosenIndex, assignSearchKeys, jobGenParams, context, false, retainInput);
+ metaRecordType, chosenIndex, assignSearchKeys, jobGenParams, context, false, retainInput);
// Generate the rest of the upstream plan which feeds the search results into the primary index.
if (dataset.getDatasetType() == DatasetType.EXTERNAL) {
@@ -248,8 +249,8 @@
return externalDataAccessOp;
} else {
UnnestMapOperator primaryIndexUnnestOp = AccessMethodUtils.createPrimaryIndexUnnestMap(dataSourceOp,
- dataset, recordType, secondaryIndexUnnestOp, context, true, retainInput, false, false);
-
+ dataset, recordType, metaRecordType, secondaryIndexUnnestOp, context, true, retainInput, false,
+ false);
return primaryIndexUnnestOp;
}
}
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/EquivalenceClassUtils.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/EquivalenceClassUtils.java
index e85fecf..242e15b 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/EquivalenceClassUtils.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/EquivalenceClassUtils.java
@@ -103,7 +103,7 @@
for (int pkIndex = 0; pkIndex < primaryKey.size(); ++pkIndex) {
LogicalVariable referredRecordVar = recordVar;
String pkFieldName = primaryKey.get(pkIndex).get(0);
- int source = keySourceIndicators == null ? 0 : keySourceIndicators.get(pkIndex);
+ int source = keySourceIndicators.get(pkIndex);
Integer fieldIndexInRecord;
if (source == 0) {
// The field is from the main record.
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java b/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
index c635125..28de56b 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
@@ -457,8 +457,8 @@
IAType metaItemType = metadataProvider.findType(dataset.getMetaItemTypeDataverseName(),
dataset.getMetaItemTypeName());
DatasetDataSource dataSource = new DatasetDataSource(sourceId, dataset.getDataverseName(),
- dataset.getDatasetName(), itemType, metaItemType, AqlDataSourceType.INTERNAL_DATASET);
-
+ dataset.getDatasetName(), itemType, metaItemType, AqlDataSourceType.INTERNAL_DATASET,
+ dataset.getDatasetDetails());
return dataSource;
}
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java b/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java
index 95a8802..03e3fe8 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java
@@ -18,12 +18,12 @@
*/
package org.apache.asterix.translator.util;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.asterix.common.config.DatasetConfig.IndexType;
import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.metadata.utils.KeyFieldTypeUtils;
import org.apache.asterix.om.types.ARecordType;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.BuiltinType;
@@ -47,8 +47,7 @@
* @throws AsterixException
* (if the validation failed), IOException
*/
- public static void validateFilterField(ARecordType recType, List<String> filterField)
- throws AsterixException, IOException {
+ public static void validateFilterField(ARecordType recType, List<String> filterField) throws AsterixException {
IAType fieldType = recType.getSubFieldType(filterField);
if (fieldType == null) {
throw new AsterixException("A field with this name \"" + filterField + "\" could not be found.");
@@ -88,7 +87,7 @@
*/
public static List<IAType> validatePartitioningExpressions(ARecordType recType, ARecordType metaRecType,
List<List<String>> partitioningExprs, List<Integer> keySourceIndicators, boolean autogenerated)
- throws AsterixException, IOException {
+ throws AsterixException {
List<IAType> partitioningExprTypes = new ArrayList<IAType>(partitioningExprs.size());
if (autogenerated) {
if (partitioningExprs.size() > 1) {
@@ -104,11 +103,10 @@
+ ". Autogenerated primary keys must be of type " + ATypeTag.UUID + ".");
}
} else {
- for (int i = 0; i < partitioningExprs.size(); i++) {
- List<String> fieldName = partitioningExprs.get(i);
- boolean useMeta = keySourceIndicators.get(i) > 0;
- IAType fieldType = useMeta ? metaRecType.getSubFieldType(fieldName)
- : recType.getSubFieldType(fieldName);
+ partitioningExprTypes = KeyFieldTypeUtils.getKeyTypes(recType, metaRecType, partitioningExprs,
+ keySourceIndicators);
+ for (int fidx = 0; fidx < partitioningExprTypes.size(); ++fidx) {
+ IAType fieldType = partitioningExprTypes.get(fidx);
switch (fieldType.getTypeTag()) {
case INT8:
case INT16:
@@ -124,13 +122,13 @@
case DATETIME:
case YEARMONTHDURATION:
case DAYTIMEDURATION:
- partitioningExprTypes.add(fieldType);
break;
case UNION:
- throw new AsterixException("The partitioning key \"" + fieldName + "\" cannot be nullable");
+ throw new AsterixException(
+ "The partitioning key \"" + partitioningExprs.get(fidx) + "\" cannot be nullable");
default:
- throw new AsterixException("The partitioning key \"" + fieldName + "\" cannot be of type "
- + fieldType.getTypeTag() + ".");
+ throw new AsterixException("The partitioning key \"" + partitioningExprs.get(fidx)
+ + "\" cannot be of type " + fieldType.getTypeTag() + ".");
}
}
}
@@ -151,12 +149,15 @@
* @throws AsterixException
* (if the validation failed), IOException
*/
- public static void validateKeyFields(ARecordType recType, List<List<String>> keyFieldNames,
- List<IAType> keyFieldTypes, IndexType indexType) throws AsterixException, IOException {
+ public static void validateKeyFields(ARecordType recType, ARecordType metaRecType, List<List<String>> keyFieldNames,
+ List<Integer> keySourceIndicators, List<IAType> keyFieldTypes, IndexType indexType)
+ throws AsterixException {
+ List<IAType> fieldTypes = KeyFieldTypeUtils.getKeyTypes(recType, metaRecType, keyFieldNames,
+ keySourceIndicators);
int pos = 0;
boolean openFieldCompositeIdx = false;
- for (List<String> fieldName : keyFieldNames) {
- IAType fieldType = recType.getSubFieldType(fieldName);
+ for (IAType fieldType : fieldTypes) {
+ List<String> fieldName = keyFieldNames.get(pos);
if (fieldType == null) {
fieldType = keyFieldTypes.get(pos);
if (keyFieldTypes.get(pos) == BuiltinType.ANULL) {
diff --git a/asterix-app/src/main/java/org/apache/asterix/aql/translator/QueryTranslator.java b/asterix-app/src/main/java/org/apache/asterix/aql/translator/QueryTranslator.java
index 75f325b..00bc254 100644
--- a/asterix-app/src/main/java/org/apache/asterix/aql/translator/QueryTranslator.java
+++ b/asterix-app/src/main/java/org/apache/asterix/aql/translator/QueryTranslator.java
@@ -141,6 +141,7 @@
import org.apache.asterix.metadata.feeds.FeedMetadataUtil;
import org.apache.asterix.metadata.utils.DatasetUtils;
import org.apache.asterix.metadata.utils.ExternalDatasetsRegistry;
+import org.apache.asterix.metadata.utils.KeyFieldTypeUtils;
import org.apache.asterix.metadata.utils.MetadataLockManager;
import org.apache.asterix.om.types.ARecordType;
import org.apache.asterix.om.types.ATypeTag;
@@ -811,6 +812,7 @@
CreateIndexStatement stmtCreateIndex = (CreateIndexStatement) stmt;
String dataverseName = getActiveDataverse(stmtCreateIndex.getDataverseName());
String datasetName = stmtCreateIndex.getDatasetName().getValue();
+ List<Integer> keySourceIndicators = stmtCreateIndex.getFieldSourceIndicators();
MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
boolean bActiveTxn = true;
@@ -838,19 +840,24 @@
indexName = stmtCreateIndex.getIndexName().getValue();
Index idx = MetadataManager.INSTANCE.getIndex(metadataProvider.getMetadataTxnContext(), dataverseName,
datasetName, indexName);
-
- String itemTypeName = ds.getItemTypeName();
Datatype dt = MetadataManager.INSTANCE.getDatatype(metadataProvider.getMetadataTxnContext(),
- ds.getItemTypeDataverseName(), itemTypeName);
- IAType itemType = dt.getDatatype();
- ARecordType aRecordType = (ARecordType) itemType;
+ ds.getItemTypeDataverseName(), ds.getItemTypeName());
+ ARecordType aRecordType = (ARecordType) dt.getDatatype();
+ ARecordType metaRecordType = null;
+ if (ds.hasMetaPart()) {
+ Datatype metaDt = MetadataManager.INSTANCE.getDatatype(metadataProvider.getMetadataTxnContext(),
+ ds.getMetaItemTypeDataverseName(), ds.getMetaItemTypeName());
+ metaRecordType = (ARecordType) metaDt.getDatatype();
+ }
List<List<String>> indexFields = new ArrayList<List<String>>();
List<IAType> indexFieldTypes = new ArrayList<IAType>();
+ int keyIndex = 0;
for (Pair<List<String>, TypeExpression> fieldExpr : stmtCreateIndex.getFieldExprs()) {
IAType fieldType = null;
- boolean isOpen = aRecordType.isOpen();
- ARecordType subType = aRecordType;
+ ARecordType subType = KeyFieldTypeUtils.chooseSource(keySourceIndicators, keyIndex, aRecordType,
+ metaRecordType);
+ boolean isOpen = subType.isOpen();
int i = 0;
if (fieldExpr.first.size() > 1 && !isOpen) {
for (; i < fieldExpr.first.size() - 1;) {
@@ -885,9 +892,11 @@
indexFields.add(fieldExpr.first);
indexFieldTypes.add(fieldType);
+ ++keyIndex;
}
- ValidateUtil.validateKeyFields(aRecordType, indexFields, indexFieldTypes, stmtCreateIndex.getIndexType());
+ ValidateUtil.validateKeyFields(aRecordType, metaRecordType, indexFields, keySourceIndicators,
+ indexFieldTypes, stmtCreateIndex.getIndexType());
if (idx != null) {
if (stmtCreateIndex.getIfNotExists()) {
@@ -995,8 +1004,8 @@
//#. add a new index with PendingAddOp
Index index = new Index(dataverseName, datasetName, indexName, stmtCreateIndex.getIndexType(), indexFields,
- stmtCreateIndex.getFieldSourceIndicators(), indexFieldTypes, stmtCreateIndex.getGramLength(),
- stmtCreateIndex.isEnforced(), false, IMetadataEntity.PENDING_ADD_OP);
+ keySourceIndicators, indexFieldTypes, stmtCreateIndex.getGramLength(), stmtCreateIndex.isEnforced(),
+ false, IMetadataEntity.PENDING_ADD_OP);
MetadataManager.INSTANCE.addIndex(metadataProvider.getMetadataTxnContext(), index);
ARecordType enforcedType = null;
diff --git a/asterix-app/src/main/java/org/apache/asterix/file/SecondaryIndexOperationsHelper.java b/asterix-app/src/main/java/org/apache/asterix/file/SecondaryIndexOperationsHelper.java
index 24df771..bd49293 100644
--- a/asterix-app/src/main/java/org/apache/asterix/file/SecondaryIndexOperationsHelper.java
+++ b/asterix-app/src/main/java/org/apache/asterix/file/SecondaryIndexOperationsHelper.java
@@ -20,7 +20,6 @@
package org.apache.asterix.file;
import java.io.DataOutput;
-import java.io.IOException;
import java.util.List;
import java.util.Map;
@@ -255,12 +254,7 @@
secondaryBTreeFields[i] = i;
}
- IAType type;
- try {
- type = itemType.getSubFieldType(filterFieldName);
- } catch (IOException e) {
- throw new AlgebricksException(e);
- }
+ IAType type = itemType.getSubFieldType(filterFieldName);
filterCmpFactories[0] = AqlBinaryComparatorFactoryProvider.INSTANCE.getBinaryComparatorFactory(type, true);
filterTypeTraits[0] = AqlTypeTraitProvider.INSTANCE.getTypeTrait(type);
secondaryFilterFields[0] = getNumSecondaryKeys() + numPrimaryKeys;
@@ -278,12 +272,7 @@
primaryBloomFilterKeyFields = new int[numPrimaryKeys];
ISerializerDeserializerProvider serdeProvider = metadataProvider.getFormat().getSerdeProvider();
for (int i = 0; i < numPrimaryKeys; i++) {
- IAType keyType;
- try {
- keyType = itemType.getSubFieldType(partitioningKeys.get(i));
- } catch (IOException e) {
- throw new AlgebricksException(e);
- }
+ IAType keyType = itemType.getSubFieldType(partitioningKeys.get(i));
primaryRecFields[i] = serdeProvider.getSerializerDeserializer(keyType);
primaryComparatorFactories[i] = AqlBinaryComparatorFactoryProvider.INSTANCE
.getBinaryComparatorFactory(keyType, true);
diff --git a/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-1/dataset_with_meta-1.1.ddl.aql b/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-1/dataset_with_meta-1.1.ddl.aql
index 6539dbc..f2682fa 100644
--- a/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-1/dataset_with_meta-1.1.ddl.aql
+++ b/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-1/dataset_with_meta-1.1.ddl.aql
@@ -21,7 +21,7 @@
create dataverse test;
use dataverse test;
-create type EmptyType as open {
+create type AuxiliaryType as open {
id: string
}
@@ -30,6 +30,6 @@
text: string
}
-create dataset Book(LineType) with meta(EmptyType)
+create dataset Book(LineType) with meta(AuxiliaryType)
primary key id;
diff --git a/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-2/dataset_with_meta-2.1.ddl.aql b/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-2/dataset_with_meta-2.1.ddl.aql
index cec01d2..2f4f181 100644
--- a/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-2/dataset_with_meta-2.1.ddl.aql
+++ b/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-2/dataset_with_meta-2.1.ddl.aql
@@ -20,7 +20,7 @@
drop dataverse meta if exists;
create dataverse meta;
use dataverse meta;
-create type EmptyType as open {
+create type AuxiliaryType as open {
id: string
}
@@ -34,6 +34,6 @@
text: string
}
-create dataset Book(LineType) with meta(meta.EmptyType)
+create dataset Book(LineType) with meta(meta.AuxiliaryType)
primary key id;
diff --git a/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-3/dataset_with_meta-3.1.ddl.aql b/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-3/dataset_with_meta-3.1.ddl.aql
index 78bd7ab..138a211 100644
--- a/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-3/dataset_with_meta-3.1.ddl.aql
+++ b/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-3/dataset_with_meta-3.1.ddl.aql
@@ -21,7 +21,7 @@
create dataverse test;
use dataverse test;
-create type EmptyType as open {
+create type AuxiliaryType as open {
id: string
}
diff --git a/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-5/dataset_with_meta-5.1.ddl.aql b/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-5/dataset_with_meta-5.1.ddl.aql
index ddb42c8..07df579 100644
--- a/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-5/dataset_with_meta-5.1.ddl.aql
+++ b/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-5/dataset_with_meta-5.1.ddl.aql
@@ -21,7 +21,7 @@
create dataverse test;
use dataverse test;
-create type EmptyType as open {
+create type AuxiliaryType as open {
"key":int32
}
@@ -31,6 +31,6 @@
text: string
}
-create dataset Book(LineType) with meta(EmptyType)
+create dataset Book(LineType) with meta(AuxiliaryType)
primary key meta()."key";
diff --git a/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-6/dataset_with_meta-6.1.ddl.aql b/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-6/dataset_with_meta-6.1.ddl.aql
index 510137f..c987a4c 100644
--- a/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-6/dataset_with_meta-6.1.ddl.aql
+++ b/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-6/dataset_with_meta-6.1.ddl.aql
@@ -21,7 +21,7 @@
create dataverse test;
use dataverse test;
-create type EmptyType as open {
+create type AuxiliaryType as open {
id: string
}
@@ -30,7 +30,7 @@
text: string
}
-create dataset Book(LineType) with meta(EmptyType)
+create dataset Book(LineType) with meta(AuxiliaryType)
primary key id;
create index MetaIndex on Book(meta().id) type btree;
diff --git a/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-7/dataset_with_meta-6.1.ddl.aql b/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-7/dataset_with_meta-6.1.ddl.aql
index 41b50d0..94f253f 100644
--- a/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-7/dataset_with_meta-6.1.ddl.aql
+++ b/asterix-app/src/test/resources/metadata/queries/basic/dataset_with_meta-7/dataset_with_meta-6.1.ddl.aql
@@ -21,7 +21,7 @@
create dataverse test;
use dataverse test;
-create type EmptyType as open {
+create type AuxiliaryType as open {
id: string
}
@@ -30,7 +30,7 @@
text: string
}
-create dataset Book(LineType) with meta(EmptyType)
+create dataset Book(LineType) with meta(AuxiliaryType)
primary key id;
create index MetaIndex on Book(meta().id, id) type btree;
diff --git a/asterix-app/src/test/resources/metadata/results/basic/dataset_with_meta-1/dataset_with_meta-1.1.adm b/asterix-app/src/test/resources/metadata/results/basic/dataset_with_meta-1/dataset_with_meta-1.1.adm
index 776e07f..e41fe03 100644
--- a/asterix-app/src/test/resources/metadata/results/basic/dataset_with_meta-1/dataset_with_meta-1.1.adm
+++ b/asterix-app/src/test/resources/metadata/results/basic/dataset_with_meta-1/dataset_with_meta-1.1.adm
@@ -1 +1 @@
-{ "DataverseName": "test", "DatasetName": "Book", "DatatypeDataverseName": "test", "DatatypeName": "LineType", "DatasetType": "INTERNAL", "GroupName": "DEFAULT_NG_ALL_NODES", "CompactionPolicy": "prefix", "CompactionPolicyProperties": [ { "Name": "max-mergable-component-size", "Value": "1073741824" }, { "Name": "max-tolerance-component-count", "Value": "5" } ], "InternalDetails": { "FileStructure": "BTREE", "PartitioningStrategy": "HASH", "PartitioningKey": [ [ "id" ] ], "PrimaryKey": [ [ "id" ] ], "Autogenerated": false }, "ExternalDetails": null, "Hints": {{ }}, "Timestamp": "Wed Feb 24 17:32:57 PST 2016", "DatasetId": 101i32, "PendingOp": 0i32, "MetatypeDataverseName": "test", "MetatypeName": "EmptyType" }
+{ "DataverseName": "test", "DatasetName": "Book", "DatatypeDataverseName": "test", "DatatypeName": "LineType", "DatasetType": "INTERNAL", "GroupName": "DEFAULT_NG_ALL_NODES", "CompactionPolicy": "prefix", "CompactionPolicyProperties": [ { "Name": "max-mergable-component-size", "Value": "1073741824" }, { "Name": "max-tolerance-component-count", "Value": "5" } ], "InternalDetails": { "FileStructure": "BTREE", "PartitioningStrategy": "HASH", "PartitioningKey": [ [ "id" ] ], "PrimaryKey": [ [ "id" ] ], "Autogenerated": false }, "ExternalDetails": null, "Hints": {{ }}, "Timestamp": "Wed Feb 24 17:32:57 PST 2016", "DatasetId": 101i32, "PendingOp": 0i32, "MetatypeDataverseName": "test", "MetatypeName": "AuxiliaryType" }
diff --git a/asterix-app/src/test/resources/metadata/results/basic/dataset_with_meta-2/dataset_with_meta-2.1.adm b/asterix-app/src/test/resources/metadata/results/basic/dataset_with_meta-2/dataset_with_meta-2.1.adm
index f3f00e9..2663a16 100644
--- a/asterix-app/src/test/resources/metadata/results/basic/dataset_with_meta-2/dataset_with_meta-2.1.adm
+++ b/asterix-app/src/test/resources/metadata/results/basic/dataset_with_meta-2/dataset_with_meta-2.1.adm
@@ -1 +1 @@
-{ "DataverseName": "test", "DatasetName": "Book", "DatatypeDataverseName": "test", "DatatypeName": "LineType", "DatasetType": "INTERNAL", "GroupName": "DEFAULT_NG_ALL_NODES", "CompactionPolicy": "prefix", "CompactionPolicyProperties": [ { "Name": "max-mergable-component-size", "Value": "1073741824" }, { "Name": "max-tolerance-component-count", "Value": "5" } ], "InternalDetails": { "FileStructure": "BTREE", "PartitioningStrategy": "HASH", "PartitioningKey": [ [ "id" ] ], "PrimaryKey": [ [ "id" ] ], "Autogenerated": false }, "ExternalDetails": null, "Hints": {{ }}, "Timestamp": "Wed Feb 24 17:32:57 PST 2016", "DatasetId": 101i32, "PendingOp": 0i32, "MetatypeDataverseName": "meta", "MetatypeName": "EmptyType" }
+{ "DataverseName": "test", "DatasetName": "Book", "DatatypeDataverseName": "test", "DatatypeName": "LineType", "DatasetType": "INTERNAL", "GroupName": "DEFAULT_NG_ALL_NODES", "CompactionPolicy": "prefix", "CompactionPolicyProperties": [ { "Name": "max-mergable-component-size", "Value": "1073741824" }, { "Name": "max-tolerance-component-count", "Value": "5" } ], "InternalDetails": { "FileStructure": "BTREE", "PartitioningStrategy": "HASH", "PartitioningKey": [ [ "id" ] ], "PrimaryKey": [ [ "id" ] ], "Autogenerated": false }, "ExternalDetails": null, "Hints": {{ }}, "Timestamp": "Wed Feb 24 17:32:57 PST 2016", "DatasetId": 101i32, "PendingOp": 0i32, "MetatypeDataverseName": "meta", "MetatypeName": "AuxiliaryType" }
diff --git a/asterix-app/src/test/resources/metadata/results/basic/dataset_with_meta-5/dataset_with_meta-5.3.adm b/asterix-app/src/test/resources/metadata/results/basic/dataset_with_meta-5/dataset_with_meta-5.3.adm
index 485ca4e..74ac8f9 100644
--- a/asterix-app/src/test/resources/metadata/results/basic/dataset_with_meta-5/dataset_with_meta-5.3.adm
+++ b/asterix-app/src/test/resources/metadata/results/basic/dataset_with_meta-5/dataset_with_meta-5.3.adm
@@ -1 +1 @@
-{ "DataverseName": "test", "DatasetName": "Book", "DatatypeDataverseName": "test", "DatatypeName": "LineType", "DatasetType": "INTERNAL", "GroupName": "DEFAULT_NG_ALL_NODES", "CompactionPolicy": "prefix", "CompactionPolicyProperties": [ { "Name": "max-mergable-component-size", "Value": "1073741824" }, { "Name": "max-tolerance-component-count", "Value": "5" } ], "InternalDetails": { "FileStructure": "BTREE", "PartitioningStrategy": "HASH", "PartitioningKey": [ [ "key" ] ], "PrimaryKey": [ [ "key" ] ], "Autogenerated": false, "KeySourceIndicator": [ 1i8 ] }, "ExternalDetails": null, "Hints": {{ }}, "Timestamp": "Mon Feb 29 15:58:41 PST 2016", "DatasetId": 105i32, "PendingOp": 0i32, "MetatypeDataverseName": "test", "MetatypeName": "EmptyType" }
+{ "DataverseName": "test", "DatasetName": "Book", "DatatypeDataverseName": "test", "DatatypeName": "LineType", "DatasetType": "INTERNAL", "GroupName": "DEFAULT_NG_ALL_NODES", "CompactionPolicy": "prefix", "CompactionPolicyProperties": [ { "Name": "max-mergable-component-size", "Value": "1073741824" }, { "Name": "max-tolerance-component-count", "Value": "5" } ], "InternalDetails": { "FileStructure": "BTREE", "PartitioningStrategy": "HASH", "PartitioningKey": [ [ "key" ] ], "PrimaryKey": [ [ "key" ] ], "Autogenerated": false, "KeySourceIndicator": [ 1i8 ] }, "ExternalDetails": null, "Hints": {{ }}, "Timestamp": "Mon Feb 29 15:58:41 PST 2016", "DatasetId": 105i32, "PendingOp": 0i32, "MetatypeDataverseName": "test", "MetatypeName": "AuxiliaryType" }
diff --git a/asterix-app/src/test/resources/optimizerts/queries/meta/primary_index_with_meta-1.aql b/asterix-app/src/test/resources/optimizerts/queries/meta/primary_index_with_meta-1.aql
new file mode 100644
index 0000000..c07dcb1
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/queries/meta/primary_index_with_meta-1.aql
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type AuxiliaryType as open {
+ id:int32
+}
+
+create type LineType as open {
+ id:int32,
+ text: string
+}
+
+create dataset Book(LineType) with meta(AuxiliaryType)
+primary key meta().id;
+
+
+for $x in dataset Book
+where meta($x).id >10
+return $x;
diff --git a/asterix-app/src/test/resources/optimizerts/queries/meta/primary_index_with_meta-2.aql b/asterix-app/src/test/resources/optimizerts/queries/meta/primary_index_with_meta-2.aql
new file mode 100644
index 0000000..f236645
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/queries/meta/primary_index_with_meta-2.aql
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type AuxiliaryType as open {
+ id:int32
+}
+
+create type LineType as open {
+ id:int32,
+ text: string
+}
+
+create dataset Book(LineType) with meta(AuxiliaryType)
+primary key meta().id;
+
+
+for $x in dataset Book
+where meta().id >10
+return $x;
diff --git a/asterix-app/src/test/resources/optimizerts/queries/meta/primary_index_with_meta_index_join.aql b/asterix-app/src/test/resources/optimizerts/queries/meta/primary_index_with_meta_index_join.aql
new file mode 100644
index 0000000..d1ec9bc
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/queries/meta/primary_index_with_meta_index_join.aql
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type AuxiliaryType as open {
+ id:int32
+}
+
+create type BookType as open {
+ id:int32,
+ text: string
+}
+
+create type ChapterType as open {
+ id: int32,
+ book_id: int32,
+ abstract: string
+}
+
+create dataset Book(BookType) with meta(AuxiliaryType)
+primary key meta().id;
+
+create dataset Chapter(ChapterType)
+primary key id;
+
+
+for $c in dataset Chapter
+for $b in dataset Book
+where $c.book_id /*+ indexnl */= meta().id
+return {
+ "id": meta().id,
+ "abstract": $c.abstract
+};
diff --git a/asterix-app/src/test/resources/optimizerts/queries/meta/primary_index_with_meta_self_index_join.aql b/asterix-app/src/test/resources/optimizerts/queries/meta/primary_index_with_meta_self_index_join.aql
new file mode 100644
index 0000000..953802e
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/queries/meta/primary_index_with_meta_self_index_join.aql
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type AuxiliaryType as open {
+ id:int32
+}
+
+create type LineType as open {
+ id:int32,
+ text: string
+}
+
+create dataset Book(LineType) with meta(AuxiliaryType)
+primary key meta().id;
+
+
+for $x in dataset Book
+for $y in dataset Book
+where $x.id /*+ indexnl */= meta($y).id
+return {
+ "id": meta($y).id,
+ "text": $x.text
+};
diff --git a/asterix-app/src/test/resources/optimizerts/results/meta/primary_index_with_meta-1.plan b/asterix-app/src/test/resources/optimizerts/results/meta/primary_index_with_meta-1.plan
new file mode 100644
index 0000000..6f13ebb
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/results/meta/primary_index_with_meta-1.plan
@@ -0,0 +1,8 @@
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- BTREE_SEARCH |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/meta/primary_index_with_meta-2.plan b/asterix-app/src/test/resources/optimizerts/results/meta/primary_index_with_meta-2.plan
new file mode 100644
index 0000000..6f13ebb
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/results/meta/primary_index_with_meta-2.plan
@@ -0,0 +1,8 @@
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- BTREE_SEARCH |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/meta/primary_index_with_meta_index_join.plan b/asterix-app/src/test/resources/optimizerts/results/meta/primary_index_with_meta_index_join.plan
new file mode 100644
index 0000000..1c763ec
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/results/meta/primary_index_with_meta_index_join.plan
@@ -0,0 +1,17 @@
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- BTREE_SEARCH |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STABLE_SORT [$$16(ASC)] |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$16] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/meta/primary_index_with_meta_self_index_join.plan b/asterix-app/src/test/resources/optimizerts/results/meta/primary_index_with_meta_self_index_join.plan
new file mode 100644
index 0000000..b39eb44
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/results/meta/primary_index_with_meta_self_index_join.plan
@@ -0,0 +1,17 @@
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- BTREE_SEARCH |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STABLE_SORT [$$17(ASC)] |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$17] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta-1/query_dataset_with_meta-1.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta-1/query_dataset_with_meta-1.1.ddl.aql
index ca5a534..f146ef6 100644
--- a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta-1/query_dataset_with_meta-1.1.ddl.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta-1/query_dataset_with_meta-1.1.ddl.aql
@@ -21,7 +21,7 @@
create dataverse test;
use dataverse test;
-create type EmptyType as open {
+create type AuxiliaryType as open {
"key":int32
}
@@ -30,5 +30,5 @@
text: string
}
-create dataset Book(LineType) with meta(EmptyType)
+create dataset Book(LineType) with meta(AuxiliaryType)
primary key id;
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta-2/query_dataset_with_meta-2.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta-2/query_dataset_with_meta-2.1.ddl.aql
index a341b29..704ece0 100644
--- a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta-2/query_dataset_with_meta-2.1.ddl.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta-2/query_dataset_with_meta-2.1.ddl.aql
@@ -21,7 +21,7 @@
create dataverse test;
use dataverse test;
-create type EmptyType as open {
+create type AuxiliaryType as open {
"key":int32
}
@@ -30,5 +30,5 @@
text: string
}
-create dataset Book(LineType) with meta(EmptyType)
+create dataset Book(LineType) with meta(AuxiliaryType)
primary key meta()."key";
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.1.ddl.aql
new file mode 100644
index 0000000..704ece0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.1.ddl.aql
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type AuxiliaryType as open {
+ "key":int32
+}
+
+create type LineType as open {
+ id:int32,
+ text: string
+}
+
+create dataset Book(LineType) with meta(AuxiliaryType)
+primary key meta()."key";
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.2.update.aql
new file mode 100644
index 0000000..bd244d0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.2.update.aql
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.3.query.aql
new file mode 100644
index 0000000..0ca33ab
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.3.query.aql
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+use dataverse test;
+
+for $x in dataset Book
+for $y in dataset Book
+where meta()."key" = $y.id
+return $x;
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.4.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.4.ddl.aql
new file mode 100644
index 0000000..dc10acd
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.4.ddl.aql
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.1.ddl.aql
new file mode 100644
index 0000000..704ece0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.1.ddl.aql
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type AuxiliaryType as open {
+ "key":int32
+}
+
+create type LineType as open {
+ id:int32,
+ text: string
+}
+
+create dataset Book(LineType) with meta(AuxiliaryType)
+primary key meta()."key";
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.2.update.aql
new file mode 100644
index 0000000..bd244d0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.2.update.aql
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.3.query.aql
new file mode 100644
index 0000000..246046d
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.3.query.aql
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+use dataverse test;
+
+for $x in dataset Book
+where meta($x)."key" >10
+return $x;
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.4.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.4.ddl.aql
new file mode 100644
index 0000000..dc10acd
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.4.ddl.aql
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.1.ddl.aql
new file mode 100644
index 0000000..704ece0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.1.ddl.aql
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type AuxiliaryType as open {
+ "key":int32
+}
+
+create type LineType as open {
+ id:int32,
+ text: string
+}
+
+create dataset Book(LineType) with meta(AuxiliaryType)
+primary key meta()."key";
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.2.update.aql
new file mode 100644
index 0000000..bd244d0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.2.update.aql
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.3.query.aql
new file mode 100644
index 0000000..6b8e4a9
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.3.query.aql
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+use dataverse test;
+
+for $x in dataset Book
+where meta()."key" >10
+return $x;
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.4.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.4.ddl.aql
new file mode 100644
index 0000000..dc10acd
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.4.ddl.aql
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
diff --git a/asterix-app/src/test/resources/runtimets/results/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.1.adm b/asterix-app/src/test/resources/runtimets/results/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.1.adm
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.1.adm
diff --git a/asterix-app/src/test/resources/runtimets/results/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.1.adm b/asterix-app/src/test/resources/runtimets/results/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.1.adm
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/meta/query_dataset_with_meta_primary_index-1/query_dataset_with_meta_primary_index-1.1.adm
diff --git a/asterix-app/src/test/resources/runtimets/results/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.1.adm b/asterix-app/src/test/resources/runtimets/results/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.1.adm
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/meta/query_dataset_with_meta_primary_index-2/query_dataset_with_meta_primary_index-2.1.adm
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 05f131e..adcb8cd 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -2916,6 +2916,22 @@
<output-dir compare="Text">query_dataset_with_meta-2</output-dir>
</compilation-unit>
</test-case>
+ <test-case FilePath="meta">
+ <compilation-unit name="query_dataset_with_meta_primary_index-1">
+ <output-dir compare="Text">query_dataset_with_meta_primary_index-1</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="meta">
+ <compilation-unit name="query_dataset_with_meta_primary_index-2">
+ <output-dir compare="Text">query_dataset_with_meta_primary_index-2</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="meta">
+ <compilation-unit name="query_dataset_with_meta_failure">
+ <output-dir compare="Text">query_dataset_with_meta_failure</output-dir>
+ <expected-error>org.apache.hyracks.algebricks.common.exceptions.AlgebricksException: Cannot resolve to ambiguity on the meta function call -- there are more than once dataset choices!</expected-error>
+ </compilation-unit>
+ </test-case>
</test-group>
<test-group name="misc">
<test-case FilePath="misc">
diff --git a/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java b/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java
index 75175f0..afccede 100644
--- a/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java
+++ b/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java
@@ -18,7 +18,9 @@
*/
package org.apache.asterix.common.exceptions;
-public class AsterixException extends Exception {
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+
+public class AsterixException extends AlgebricksException {
private static final long serialVersionUID = 1L;
public AsterixException() {
diff --git a/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/AqlDataSource.java b/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/AqlDataSource.java
index a10e191..dcd10b7 100644
--- a/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/AqlDataSource.java
+++ b/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/AqlDataSource.java
@@ -209,4 +209,20 @@
this.properties = properties;
}
+ public LogicalVariable getMetaVariable(List<LogicalVariable> dataScanVariables) {
+ if (hasMeta()) {
+ return dataScanVariables.get(dataScanVariables.size() - 1);
+ } else {
+ return null;
+ }
+ }
+
+ public LogicalVariable getDataRecordVariable(List<LogicalVariable> dataScanVariables) {
+ if (hasMeta()) {
+ return dataScanVariables.get(dataScanVariables.size() - 2);
+ } else {
+ return dataScanVariables.get(dataScanVariables.size() - 1);
+ }
+ }
+
}
diff --git a/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/AqlMetadataProvider.java b/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/AqlMetadataProvider.java
index 7ce7ba3..e0084f8 100644
--- a/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/AqlMetadataProvider.java
+++ b/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/AqlMetadataProvider.java
@@ -783,12 +783,7 @@
}
for (int j = 0; j < pidxKeyFieldCount; ++j, ++i) {
- IAType keyType = null;
- try {
- keyType = recType.getSubFieldType(pidxKeyFieldNames.get(j));
- } catch (IOException e) {
- throw new AlgebricksException(e);
- }
+ IAType keyType = recType.getSubFieldType(pidxKeyFieldNames.get(j));
comparatorFactories[i] = AqlBinaryComparatorFactoryProvider.INSTANCE.getBinaryComparatorFactory(keyType,
true);
typeTraits[i] = AqlTypeTraitProvider.INSTANCE.getTypeTrait(keyType);
@@ -989,7 +984,7 @@
AqlDataSourceType datasourceType = dataset.getDatasetType().equals(DatasetType.EXTERNAL)
? AqlDataSourceType.EXTERNAL_DATASET : AqlDataSourceType.INTERNAL_DATASET;
return new DatasetDataSource(aqlId, aqlId.getDataverseName(), aqlId.getDatasourceName(), itemType, metaItemType,
- datasourceType);
+ datasourceType, dataset.getDatasetDetails());
}
@Override
@@ -1510,8 +1505,6 @@
} catch (MetadataException e) {
throw new AlgebricksException(e);
- } catch (IOException e) {
- throw new AlgebricksException(e);
}
}
@@ -1680,8 +1673,6 @@
return new Pair<IOperatorDescriptor, AlgebricksPartitionConstraint>(op, splitsAndConstraint.second);
} catch (MetadataException e) {
throw new AlgebricksException(e);
- } catch (IOException e) {
- throw new AlgebricksException(e);
}
}
@@ -1892,8 +1883,6 @@
return new Pair<IOperatorDescriptor, AlgebricksPartitionConstraint>(op, splitsAndConstraint.second);
} catch (MetadataException e) {
throw new AlgebricksException(e);
- } catch (IOException e) {
- throw new AlgebricksException(e);
}
}
@@ -2038,7 +2027,7 @@
NoOpOperationCallbackFactory.INSTANCE);
}
return new Pair<IOperatorDescriptor, AlgebricksPartitionConstraint>(op, splitsAndConstraint.second);
- } catch (MetadataException | IOException e) {
+ } catch (MetadataException e) {
throw new AlgebricksException(e);
}
}
@@ -2654,8 +2643,6 @@
return new Pair<IOperatorDescriptor, AlgebricksPartitionConstraint>(op, splitsAndConstraint.second);
} catch (MetadataException e) {
throw new AlgebricksException(e);
- } catch (IOException e) {
- throw new AlgebricksException(e);
}
}
@@ -2808,7 +2795,7 @@
filterFactory, false, indexName, null, modificationCallbackFactory,
NoOpOperationCallbackFactory.INSTANCE, prevFieldPermutation);
return new Pair<IOperatorDescriptor, AlgebricksPartitionConstraint>(op, splitsAndConstraint.second);
- } catch (MetadataException | IOException e) {
+ } catch (MetadataException e) {
throw new AlgebricksException(e);
}
}
@@ -2959,8 +2946,6 @@
return new Pair<IOperatorDescriptor, AlgebricksPartitionConstraint>(op, splitsAndConstraint.second);
} catch (MetadataException e) {
throw new AlgebricksException(e);
- } catch (IOException e) {
- throw new AlgebricksException(e);
}
}
}
diff --git a/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/DatasetDataSource.java b/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/DatasetDataSource.java
index 8b5956f..5483d49 100644
--- a/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/DatasetDataSource.java
+++ b/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/DatasetDataSource.java
@@ -21,10 +21,12 @@
import java.io.IOException;
import java.util.List;
+import org.apache.asterix.metadata.IDatasetDetails;
import org.apache.asterix.metadata.MetadataManager;
import org.apache.asterix.metadata.MetadataTransactionContext;
import org.apache.asterix.metadata.entities.Dataset;
-import org.apache.asterix.metadata.utils.DatasetUtils;
+import org.apache.asterix.metadata.entities.InternalDatasetDetails;
+import org.apache.asterix.metadata.utils.KeyFieldTypeUtils;
import org.apache.asterix.om.types.ARecordType;
import org.apache.asterix.om.types.IAType;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -36,7 +38,8 @@
private Dataset dataset;
public DatasetDataSource(AqlSourceId id, String datasourceDataverse, String datasourceName, IAType itemType,
- IAType metaItemType, AqlDataSourceType datasourceType) throws AlgebricksException {
+ IAType metaItemType, AqlDataSourceType datasourceType, IDatasetDetails datasetDetails)
+ throws AlgebricksException {
super(id, itemType, metaItemType, datasourceType);
MetadataTransactionContext ctx = null;
try {
@@ -49,7 +52,7 @@
MetadataManager.INSTANCE.commitTransaction(ctx);
switch (dataset.getDatasetType()) {
case INTERNAL:
- initInternalDataset(itemType, metaItemType);
+ initInternalDataset(itemType, metaItemType, datasetDetails);
break;
case EXTERNAL:
initExternalDataset(itemType);
@@ -74,13 +77,17 @@
return dataset;
}
- private void initInternalDataset(IAType itemType, IAType metaItemType) throws IOException, AlgebricksException {
- List<List<String>> partitioningKeys = DatasetUtils.getPartitioningKeys(dataset);
+ private void initInternalDataset(IAType itemType, IAType metaItemType, IDatasetDetails datasetDetails)
+ throws IOException, AlgebricksException {
+ InternalDatasetDetails internalDatasetDetails = (InternalDatasetDetails) datasetDetails;
ARecordType recordType = (ARecordType) itemType;
- int n = partitioningKeys.size();
+ ARecordType metaRecordType = (ARecordType) metaItemType;
+ List<IAType> partitioningKeyTypes = KeyFieldTypeUtils.getPartitioningKeyTypes(internalDatasetDetails,
+ recordType, metaRecordType);
+ int n = partitioningKeyTypes.size();
schemaTypes = metaItemType == null ? new IAType[n + 1] : new IAType[n + 2];
- for (int i = 0; i < n; i++) {
- schemaTypes[i] = recordType.getSubFieldType(partitioningKeys.get(i));
+ for (int keyIndex = 0; keyIndex < n; ++keyIndex) {
+ schemaTypes[keyIndex] = partitioningKeyTypes.get(keyIndex);
}
schemaTypes[n] = itemType;
if (metaItemType != null) {
diff --git a/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java b/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java
index db3ccc1..3ff9a57 100644
--- a/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java
+++ b/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java
@@ -19,17 +19,16 @@
package org.apache.asterix.metadata.entities;
-import java.io.IOException;
import java.util.List;
import org.apache.asterix.common.config.DatasetConfig.IndexType;
+import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.metadata.MetadataCache;
import org.apache.asterix.metadata.api.IMetadataEntity;
import org.apache.asterix.om.types.ARecordType;
import org.apache.asterix.om.types.AUnionType;
import org.apache.asterix.om.types.IAType;
import org.apache.asterix.om.util.NonTaggedFormatUtil;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.common.utils.Pair;
/**
@@ -130,7 +129,7 @@
return !isPrimaryIndex();
}
- public static Pair<IAType, Boolean> getNonNullableType(IAType keyType) throws AlgebricksException {
+ public static Pair<IAType, Boolean> getNonNullableType(IAType keyType) throws AsterixException {
boolean nullable = false;
if (NonTaggedFormatUtil.isOptional(keyType)) {
keyType = ((AUnionType) keyType).getNullableType();
@@ -140,7 +139,7 @@
}
public static Pair<IAType, Boolean> getNonNullableOpenFieldType(IAType fieldType, List<String> fieldName,
- ARecordType recType) throws AlgebricksException {
+ ARecordType recType) throws AsterixException {
Pair<IAType, Boolean> keyPairType = null;
IAType subType = recType;
for (int i = 0; i < fieldName.size(); i++) {
@@ -157,18 +156,14 @@
}
public static Pair<IAType, Boolean> getNonNullableKeyFieldType(List<String> expr, ARecordType recType)
- throws AlgebricksException {
+ throws AsterixException {
IAType keyType = Index.keyFieldType(expr, recType);
return getNonNullableType(keyType);
}
- private static IAType keyFieldType(List<String> expr, ARecordType recType) throws AlgebricksException {
+ private static IAType keyFieldType(List<String> expr, ARecordType recType) throws AsterixException {
IAType fieldType = recType;
- try {
- fieldType = recType.getSubFieldType(expr);
- } catch (IOException e) {
- throw new AlgebricksException("Could not find field " + expr + " in the schema.", e);
- }
+ fieldType = recType.getSubFieldType(expr);
return fieldType;
}
diff --git a/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/InternalDatasetDetails.java b/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/InternalDatasetDetails.java
index 6971037..b0c6c51 100644
--- a/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/InternalDatasetDetails.java
+++ b/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/InternalDatasetDetails.java
@@ -20,6 +20,7 @@
package org.apache.asterix.metadata.entities;
import java.io.DataOutput;
+import java.util.ArrayList;
import java.util.List;
import org.apache.asterix.builders.IARecordBuilder;
@@ -75,6 +76,13 @@
this.partitioningStrategy = partitioningStrategy;
this.partitioningKeys = partitioningKey;
this.primaryKeys = primaryKey;
+ if (keyFieldIndicators == null) {
+ // Create a dummy list.
+ keyFieldIndicators = new ArrayList<>();
+ for (int index = 0; index < partitioningKey.size(); ++index) {
+ keyFieldIndicators.add(0);
+ }
+ }
this.keySourceIndicators = keyFieldIndicators;
this.primaryKeyTypes = primaryKeyType;
this.autogenerated = autogenerated;
diff --git a/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslator.java b/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslator.java
index f310a03..cedf0b4 100644
--- a/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslator.java
+++ b/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslator.java
@@ -29,6 +29,7 @@
import org.apache.asterix.builders.OrderedListBuilder;
import org.apache.asterix.common.config.DatasetConfig.IndexType;
+import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.common.transactions.JobId;
import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
import org.apache.asterix.metadata.MetadataException;
@@ -38,6 +39,7 @@
import org.apache.asterix.metadata.entities.AsterixBuiltinTypeMap;
import org.apache.asterix.metadata.entities.Dataset;
import org.apache.asterix.metadata.entities.Index;
+import org.apache.asterix.metadata.utils.KeyFieldTypeUtils;
import org.apache.asterix.om.base.ABoolean;
import org.apache.asterix.om.base.ACollectionCursor;
import org.apache.asterix.om.base.AInt32;
@@ -142,18 +144,7 @@
IAType fieldType = AsterixBuiltinTypeMap.getTypeFromTypeName(metadataNode, jobId, dvName, typeName, false);
searchKeyType.add(fieldType);
}
- // index key type information is not persisted, thus we extract type information from the record metadata
- if (searchKeyType.isEmpty()) {
- Dataset dSet = metadataNode.getDataset(jobId, dvName, dsName);
- String datatypeName = dSet.getItemTypeName();
- String datatypeDataverseName = dSet.getItemTypeDataverseName();
- ARecordType recordDt = (ARecordType) metadataNode.getDatatype(jobId, datatypeDataverseName, datatypeName)
- .getDatatype();
- for (int i = 0; i < searchKey.size(); i++) {
- IAType fieldType = recordDt.getSubFieldType(searchKey.get(i));
- searchKeyType.add(fieldType);
- }
- }
+
int isEnforcedFieldPos = rec.getType().getFieldIndex(INDEX_ISENFORCED_FIELD_NAME);
Boolean isEnforcingKeys = false;
if (isEnforcedFieldPos > 0) {
@@ -183,6 +174,27 @@
keyFieldSourceIndicator.add(0);
}
}
+
+ // index key type information is not persisted, thus we extract type information from the record metadata
+ if (searchKeyType.isEmpty()) {
+ Dataset dSet = metadataNode.getDataset(jobId, dvName, dsName);
+ String datatypeName = dSet.getItemTypeName();
+ String datatypeDataverseName = dSet.getItemTypeDataverseName();
+ ARecordType recordDt = (ARecordType) metadataNode.getDatatype(jobId, datatypeDataverseName, datatypeName)
+ .getDatatype();
+ String metatypeName = dSet.getMetaItemTypeName();
+ String metatypeDataverseName = dSet.getMetaItemTypeDataverseName();
+ ARecordType metaDt = null;
+ if (metatypeName != null && metatypeDataverseName != null) {
+ metaDt = (ARecordType) metadataNode.getDatatype(jobId, metatypeDataverseName, metatypeName)
+ .getDatatype();
+ }
+ try {
+ searchKeyType = KeyFieldTypeUtils.getKeyTypes(recordDt, metaDt, searchKey, keyFieldSourceIndicator);
+ } catch (AsterixException e) {
+ throw new MetadataException(e);
+ }
+ }
return new Index(dvName, dsName, indexName, indexStructure, searchKey, keyFieldSourceIndicator, searchKeyType,
gramLength, isEnforcingKeys, isPrimaryIndex, pendingOp);
}
diff --git a/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DatasetUtils.java b/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DatasetUtils.java
index 19471de..4e8c34c 100644
--- a/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DatasetUtils.java
+++ b/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DatasetUtils.java
@@ -20,7 +20,6 @@
package org.apache.asterix.metadata.utils;
import java.io.DataOutput;
-import java.io.IOException;
import java.util.List;
import java.util.Map;
@@ -73,12 +72,7 @@
}
} else {
for (int i = 0; i < partitioningKeys.size(); i++) {
- IAType keyType;
- try {
- keyType = itemType.getSubFieldType(partitioningKeys.get(i));
- } catch (IOException e) {
- throw new AlgebricksException(e);
- }
+ IAType keyType = itemType.getSubFieldType(partitioningKeys.get(i));
bcfs[i] = comparatorFactoryProvider.getBinaryComparatorFactory(keyType, true);
}
}
@@ -105,12 +99,7 @@
List<List<String>> partitioningKeys = getPartitioningKeys(dataset);
IBinaryHashFunctionFactory[] bhffs = new IBinaryHashFunctionFactory[partitioningKeys.size()];
for (int i = 0; i < partitioningKeys.size(); i++) {
- IAType keyType;
- try {
- keyType = itemType.getSubFieldType(partitioningKeys.get(i));
- } catch (IOException e) {
- throw new AlgebricksException(e);
- }
+ IAType keyType = itemType.getSubFieldType(partitioningKeys.get(i));
bhffs[i] = hashFunProvider.getBinaryHashFunctionFactory(keyType);
}
return bhffs;
@@ -125,12 +114,7 @@
int numKeys = partitioningKeys.size();
ITypeTraits[] typeTraits = new ITypeTraits[numKeys + 1];
for (int i = 0; i < numKeys; i++) {
- IAType keyType;
- try {
- keyType = itemType.getSubFieldType(partitioningKeys.get(i));
- } catch (IOException e) {
- throw new AlgebricksException(e);
- }
+ IAType keyType = itemType.getSubFieldType(partitioningKeys.get(i));
typeTraits[i] = AqlTypeTraitProvider.INSTANCE.getTypeTrait(keyType);
}
typeTraits[numKeys] = AqlTypeTraitProvider.INSTANCE.getTypeTrait(itemType);
@@ -159,12 +143,7 @@
return null;
}
IBinaryComparatorFactory[] bcfs = new IBinaryComparatorFactory[1];
- IAType type;
- try {
- type = itemType.getSubFieldType(filterField);
- } catch (IOException e) {
- throw new AlgebricksException(e);
- }
+ IAType type = itemType.getSubFieldType(filterField);
bcfs[0] = comparatorFactoryProvider.getBinaryComparatorFactory(type, true);
return bcfs;
}
@@ -179,13 +158,7 @@
return null;
}
ITypeTraits[] typeTraits = new ITypeTraits[1];
-
- IAType type;
- try {
- type = itemType.getSubFieldType(filterField);
- } catch (IOException e) {
- throw new AlgebricksException(e);
- }
+ IAType type = itemType.getSubFieldType(filterField);
typeTraits[0] = AqlTypeTraitProvider.INSTANCE.getTypeTrait(type);
return typeTraits;
}
diff --git a/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/KeyFieldTypeUtils.java b/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/KeyFieldTypeUtils.java
new file mode 100644
index 0000000..60ca42f
--- /dev/null
+++ b/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/KeyFieldTypeUtils.java
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.metadata.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.asterix.common.config.DatasetConfig.DatasetType;
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.metadata.entities.Dataset;
+import org.apache.asterix.metadata.entities.Index;
+import org.apache.asterix.metadata.entities.InternalDatasetDetails;
+import org.apache.asterix.om.types.ARecordType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.om.util.NonTaggedFormatUtil;
+import org.apache.hyracks.algebricks.common.utils.Pair;
+
+public class KeyFieldTypeUtils {
+
+ /**
+ * Get the types of primary key (partitioning key) fields
+ *
+ * @param dataset,
+ * the dataset to consider.
+ * @param recordType,
+ * the main record type.
+ * @param metaRecordType
+ * the auxiliary meta record type.
+ * @return a list of IATypes, one for each corresponding primary key field.
+ * @throws AsterixException
+ */
+ public static List<IAType> getPartitoningKeyTypes(Dataset dataset, ARecordType recordType,
+ ARecordType metaRecordType) throws AsterixException {
+ if (dataset.getDatasetType() != DatasetType.INTERNAL) {
+ return null;
+ }
+ InternalDatasetDetails datasetDetails = (InternalDatasetDetails) dataset.getDatasetDetails();
+ return getPartitioningKeyTypes(datasetDetails, recordType, metaRecordType);
+ }
+
+ /**
+ * Get the types of primary key (partitioning key) fields
+ *
+ * @param datasetDetails,
+ * contains specific data structures for an internal dataset.
+ * @param recordType,
+ * the main record type.
+ * @param metaRecordType
+ * the auxiliary meta record type.
+ * @return a list of IATypes, one for each corresponding primary key field.
+ * @throws AsterixException
+ */
+ public static List<IAType> getPartitioningKeyTypes(InternalDatasetDetails datasetDetails, ARecordType recordType,
+ ARecordType metaRecordType) throws AsterixException {
+ List<Integer> keySourceIndicators = datasetDetails.getKeySourceIndicator();
+ List<List<String>> partitioningKeys = datasetDetails.getPartitioningKey();
+ return getKeyTypes(recordType, metaRecordType, partitioningKeys, keySourceIndicators);
+ }
+
+ /**
+ * Get the types of key fields for an index, either primary or secondary.
+ *
+ * @param recordType,
+ * the main record type.
+ * @param metaRecordType,
+ * the auxiliary meta record type.
+ * @param keys,
+ * the list of key fields.
+ * @param keySourceIndicators,
+ * a list of integers to indicate that each key field is from the main record or the auxiliary meta record.
+ * @return a list of IATypes, one for each corresponding index key field.
+ * @throws AsterixException
+ */
+ public static List<IAType> getKeyTypes(ARecordType recordType, ARecordType metaRecordType, List<List<String>> keys,
+ List<Integer> keySourceIndicators) throws AsterixException {
+ List<IAType> keyTypes = new ArrayList<>();
+ int index = 0;
+ for (List<String> partitioningKey : keys) {
+ keyTypes.add(chooseSource(keySourceIndicators, index, recordType, metaRecordType)
+ .getSubFieldType(partitioningKey));
+ ++index;
+ }
+ return keyTypes;
+ }
+
+ /**
+ * Get the types of BTree index key fields
+ *
+ * @param index,
+ * the index to consider.
+ * @param recordType,
+ * the main record type.
+ * @param metaRecordType
+ * the auxiliary meta record type.
+ * @return a list of IATypes, one for each corresponding index key field.
+ * @throws AsterixException
+ */
+ public static List<IAType> getBTreeIndexKeyTypes(Index index, ARecordType recordType, ARecordType metaRecordType)
+ throws AsterixException {
+ List<Integer> keySourceIndicators = index.getKeyFieldSourceIndicators();
+ List<IAType> indexKeyTypes = new ArrayList<>();
+ for (int i = 0; i < index.getKeyFieldNames().size(); i++) {
+ Pair<IAType, Boolean> keyPairType = Index.getNonNullableOpenFieldType(index.getKeyFieldTypes().get(i),
+ index.getKeyFieldNames().get(i), chooseSource(keySourceIndicators, i, recordType, metaRecordType));
+ indexKeyTypes.add(keyPairType.first);
+ }
+ return indexKeyTypes;
+ }
+
+ /**
+ * Get the types of RTree index key fields
+ *
+ * @param index,
+ * the index to consider.
+ * @param recordType,
+ * the main record type.
+ * @param metaRecordType
+ * the auxiliary meta record type.
+ * @return a list of IATypes, one for each corresponding index key field.
+ * @throws AsterixException
+ */
+ public static List<IAType> getRTreeIndexKeyTypes(Index index, ARecordType recordType, ARecordType metaRecordType)
+ throws AsterixException {
+ List<Integer> keySourceIndicators = index.getKeyFieldSourceIndicators();
+ List<IAType> indexKeyTypes = new ArrayList<>();
+ ARecordType targetRecType = chooseSource(keySourceIndicators, 0, recordType, metaRecordType);
+ Pair<IAType, Boolean> keyPairType = Index.getNonNullableOpenFieldType(index.getKeyFieldTypes().get(0),
+ index.getKeyFieldNames().get(0), targetRecType);
+ IAType keyType = keyPairType.first;
+ IAType nestedKeyType = NonTaggedFormatUtil.getNestedSpatialType(keyType.getTypeTag());
+ int numKeys = KeyFieldTypeUtils.getNumSecondaryKeys(index, targetRecType, metaRecordType);
+ for (int i = 0; i < numKeys; i++) {
+ indexKeyTypes.add(nestedKeyType);
+ }
+ return indexKeyTypes;
+ }
+
+ /**
+ * Get the number of secondary index keys.
+ *
+ * @param index,
+ * the index to consider.
+ * @param recordType,
+ * the main record type.
+ * @param metaRecordType
+ * the auxiliary meta record type.
+ * @return the number of secondary index keys.
+ * @throws AsterixException
+ */
+ public static int getNumSecondaryKeys(Index index, ARecordType recordType, ARecordType metaRecordType)
+ throws AsterixException {
+ List<Integer> keySourceIndicators = index.getKeyFieldSourceIndicators();
+ switch (index.getIndexType()) {
+ case BTREE:
+ case SINGLE_PARTITION_WORD_INVIX:
+ case SINGLE_PARTITION_NGRAM_INVIX:
+ case LENGTH_PARTITIONED_WORD_INVIX:
+ case LENGTH_PARTITIONED_NGRAM_INVIX: {
+ return index.getKeyFieldNames().size();
+ }
+ case RTREE: {
+ Pair<IAType, Boolean> keyPairType = Index.getNonNullableOpenFieldType(index.getKeyFieldTypes().get(0),
+ index.getKeyFieldNames().get(0),
+ chooseSource(keySourceIndicators, 0, recordType, metaRecordType));
+ IAType keyType = keyPairType.first;
+ int numDimensions = NonTaggedFormatUtil.getNumDimensions(keyType.getTypeTag());
+ return numDimensions * 2;
+ }
+ default: {
+ throw new AsterixException("Unknown index kind: " + index.getIndexType());
+ }
+ }
+ }
+
+ /**
+ * Choose between the main record type and the auxiliary record type according to <code>keySourceIndicators</code>.
+ *
+ * @param keySourceIndicators,
+ * a list of integers, 0 means to choose <code>recordType</code> and 1
+ * means to choose <code>metaRecordType</code>.
+ * @param index,
+ * the offset to consider.
+ * @param recordType,
+ * the main record type.
+ * @param metaRecordType
+ * the auxiliary meta record type.
+ * @return the chosen record type.
+ */
+ public static ARecordType chooseSource(List<Integer> keySourceIndicators, int index, ARecordType recordType,
+ ARecordType metaRecordType) {
+ return keySourceIndicators.get(0) == 0 ? recordType : metaRecordType;
+ }
+}
diff --git a/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java b/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
index 997dccd..9f8d5d7 100644
--- a/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
+++ b/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
@@ -90,6 +90,7 @@
import org.apache.asterix.om.typecomputer.impl.OptionalATemporalInstanceTypeComputer;
import org.apache.asterix.om.typecomputer.impl.OptionalATimeTypeComputer;
import org.apache.asterix.om.typecomputer.impl.OptionalAYearMonthDurationTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.OptionalOpenARecordTypeComputer;
import org.apache.asterix.om.typecomputer.impl.OrderedListConstructorResultType;
import org.apache.asterix.om.typecomputer.impl.OrderedListOfAInt32TypeComputer;
import org.apache.asterix.om.typecomputer.impl.OrderedListOfAInt64TypeComputer;
@@ -723,6 +724,9 @@
public static final FunctionIdentifier EXTERNAL_LOOKUP = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"external-lookup", FunctionIdentifier.VARARGS);
+ public static final FunctionIdentifier META = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "meta",
+ FunctionIdentifier.VARARGS);
+
public static IFunctionInfo getAsterixFunctionInfo(FunctionIdentifier fid) {
return registeredFunctions.get(fid);
}
@@ -1028,6 +1032,9 @@
addFunction(INTERVAL_CONSTRUCTOR_START_FROM_DATETIME, OptionalAIntervalTypeComputer.INSTANCE, true);
addFunction(INTERVAL_CONSTRUCTOR_START_FROM_TIME, OptionalAIntervalTypeComputer.INSTANCE, true);
+ // meta() function
+ addFunction(META, OptionalOpenARecordTypeComputer.INSTANCE, true);
+
addPrivateFunction(COLLECTION_TO_SEQUENCE, CollectionToSequenceTypeComputer.INSTANCE, true);
// external lookup
diff --git a/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessNestedResultType.java b/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessNestedResultType.java
index f97e0ac..d8164b7 100644
--- a/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessNestedResultType.java
+++ b/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FieldAccessNestedResultType.java
@@ -18,7 +18,6 @@
*/
package org.apache.asterix.om.typecomputer.impl;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -78,16 +77,12 @@
} else {
throw new AlgebricksException("Typing error: expecting a String, found " + ce + " instead.");
}
- try {
- IAType subType = t0.getSubFieldType(fieldPath);
- if (subType != null) {
- return subType;
- } else {
- // Open field. Type can only be determined at runtime.
- return BuiltinType.ANY;
- }
- } catch (IOException e) {
- throw new AlgebricksException("FieldPath was invalid.");
+ IAType subType = t0.getSubFieldType(fieldPath);
+ if (subType != null) {
+ return subType;
+ } else {
+ // Open field. Type can only be determined at runtime.
+ return BuiltinType.ANY;
}
}
diff --git a/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/OptionalOpenARecordTypeComputer.java b/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/OptionalOpenARecordTypeComputer.java
new file mode 100644
index 0000000..b630f44
--- /dev/null
+++ b/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/OptionalOpenARecordTypeComputer.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.om.typecomputer.impl;
+
+import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
+import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
+import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+
+public class OptionalOpenARecordTypeComputer implements IResultTypeComputer {
+
+ public static final OptionalOpenARecordTypeComputer INSTANCE = new OptionalOpenARecordTypeComputer();
+
+ private OptionalOpenARecordTypeComputer() {
+ }
+
+ @Override
+ public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+ IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+ return AUnionType.createNullableType(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE, "OptionalOpenRecord");
+ }
+
+}
diff --git a/asterix-om/src/main/java/org/apache/asterix/om/types/ARecordType.java b/asterix-om/src/main/java/org/apache/asterix/om/types/ARecordType.java
index c2eae36..91a67ba 100644
--- a/asterix-om/src/main/java/org/apache/asterix/om/types/ARecordType.java
+++ b/asterix-om/src/main/java/org/apache/asterix/om/types/ARecordType.java
@@ -19,7 +19,6 @@
package org.apache.asterix.om.types;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -155,9 +154,9 @@
* @param subFieldName
* The full pathname of the child
* @return the type of the child
- * @throws IOException
+ * @throws AsterixException
*/
- public IAType getSubFieldType(List<String> subFieldName) throws IOException {
+ public IAType getSubFieldType(List<String> subFieldName) throws AsterixException {
IAType subRecordType = getFieldType(subFieldName.get(0));
for (int i = 1; i < subFieldName.size(); i++) {
if (subRecordType == null) {
@@ -166,8 +165,8 @@
if (subRecordType.getTypeTag().equals(ATypeTag.UNION)) {
//enforced SubType
subRecordType = ((AUnionType) subRecordType).getNullableType();
- if (subRecordType.getTypeTag().serialize() != ATypeTag.RECORD.serialize()) {
- throw new IOException(
+ if (subRecordType.getTypeTag() != ATypeTag.RECORD) {
+ throw new AsterixException(
"Field accessor is not defined for values of type " + subRecordType.getTypeTag());
}
diff --git a/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java b/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java
index 75350f0..054f3e4 100644
--- a/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java
+++ b/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java
@@ -19,7 +19,6 @@
package org.apache.asterix.runtime.formats;
import java.io.DataOutput;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -880,12 +879,8 @@
ScalarFunctionCallExpression partitionFun = new ScalarFunctionCallExpression(finfoAccess,
new MutableObject<ILogicalExpression>(new VariableReferenceExpression(METADATA_DUMMY_VAR)),
new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(as))));
- try {
- return new Triple<IScalarEvaluatorFactory, ScalarFunctionCallExpression, IAType>(evalFactory,
- partitionFun, recType.getSubFieldType(fldName));
- } catch (IOException e) {
- throw new AlgebricksException(e);
- }
+ return new Triple<IScalarEvaluatorFactory, ScalarFunctionCallExpression, IAType>(evalFactory, partitionFun,
+ recType.getSubFieldType(fldName));
}
throw new AlgebricksException("Could not find field " + fldName + " in the schema.");
}