You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@asterixdb.apache.org by AsterixDB Code Review <do...@asterix-gerrit.ics.uci.edu> on 2024/07/26 00:32:25 UTC
Change in asterixdb[master]: heterogeneous index
From Shahrzad Haji Amin Shirazi <sh...@ucr.edu>:
Shahrzad Haji Amin Shirazi has uploaded this change for review. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18522 )
Change subject: heterogeneous index
......................................................................
heterogeneous index
The following commits from your working branch will be included:
commit c863b9e55a99e8d574e94874968cef79a1064bbe
Author: Shahrzad shirazi <sh...@ucr.edu>
Date: Thu Jul 25 17:30:59 2024 -0700
heterogeneous index
Change-Id: I03b5edfbc304cdb9f36e2b382050781811a14759
---
M asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslator.java
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
M asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
M asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/KeyFieldTypeUtil.java
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
7 files changed, 225 insertions(+), 25 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb refs/changes/22/18522/1
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
index dd8f630..b6b2f17 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
@@ -860,7 +860,7 @@
AbstractFunctionCallExpression theFieldAccessFunc;
LogicalVariable fieldVar = context.newVar();
- if (fieldType == null) {
+ if (fieldType == null && skType != BuiltinType.ANY) {
// Open field. must prevent inlining to maintain the cast before the primaryOp and
// make handling of records with incorrect value type for this field easier and cleaner
context.addNotToBeInlinedVar(fieldVar);
@@ -906,6 +906,9 @@
FunctionIdentifier skFun = null;
IAObject fmtArg = null;
Pair<FunctionIdentifier, IAObject> castExpr;
+ if(skType==BuiltinType.ANY) {
+ return new IndexFieldId(skSrc, skName, skType.getTypeTag(), skFun, fmtArg);
+ }
if (fieldType == null) {
// open field
castExpr = getCastExpression(index, skType, srcLoc);
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
index b5041f0..248ab7e 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
@@ -626,6 +626,9 @@
Index.getNonNullableType(type2).first.getTypeTag(), useListDomain)) {
return true;
}
+ if (type2 == BuiltinType.ANY) {
+ return true;
+ }
return ATypeHierarchy.canPromote(Index.getNonNullableType(type1).first.getTypeTag(),
Index.getNonNullableType(type2).first.getTypeTag());
}
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
index 1ff90c6..840a835 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
@@ -1132,21 +1132,202 @@
return secondaryIndexUnnestOp;
}
}
+ private static void splitIntoConjuncts(ILogicalExpression condition, List<Mutable<ILogicalExpression>> conjuncts) {
+ if (condition.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
+ return;
+ }
+ AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) condition;
+ if (funcExpr.getFunctionIdentifier() == BuiltinFunctions.AND) {
+ for (Mutable<ILogicalExpression> arg : funcExpr.getArguments()) {
+ splitIntoConjuncts(arg.getValue(), conjuncts);
+ }
+ } else {
+ conjuncts.add(new MutableObject<>(condition));
+ }
+ }
- private static AbstractUnnestMapOperator createFinalNonIndexOnlySearchPlan(Dataset dataset,
+ protected static ILogicalExpression filterCondition(ILogicalExpression condition, List<LogicalVariable> pkVarsFromSIdxUnnestMapOp) {
+ List<Mutable<ILogicalExpression>> conjuncts = new ArrayList<>();
+ List<Mutable<ILogicalExpression>> filteredConjuncts = new ArrayList<>();
+
+ if (containsOnlyAllowedVariables(condition, pkVarsFromSIdxUnnestMapOp)) {
+ return condition;
+ }
+ splitIntoConjuncts(condition, conjuncts);
+
+ for (Mutable<ILogicalExpression> conjunct : conjuncts) {
+ if (containsOnlyAllowedVariables(conjunct.getValue(), pkVarsFromSIdxUnnestMapOp)) {
+ filteredConjuncts.add(conjunct);
+ }
+ }
+
+ if (filteredConjuncts.size() == 1) {
+ return filteredConjuncts.get(0).getValue();
+ } else if (!filteredConjuncts.isEmpty()) {
+ //seems like only conditions with and will use the index search(?) if not we can get this from the original condition
+ ScalarFunctionCallExpression combinedCondition = new ScalarFunctionCallExpression(BuiltinFunctions
+ .getBuiltinFunctionInfo(BuiltinFunctions.AND));
+ combinedCondition.getArguments().addAll(filteredConjuncts);
+ combinedCondition.setSourceLocation(condition.getSourceLocation());
+ return combinedCondition;
+ } else {
+ return null;
+ }
+ }
+
+ private static boolean containsOnlyAllowedVariables(ILogicalExpression expression, List<LogicalVariable> allowedVars) {
+ Set<LogicalVariable> usedVars = new HashSet<>();
+ expression.getUsedVariables(usedVars);
+ for (LogicalVariable var : usedVars) {
+ if (!allowedVars.contains(var)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ private static AbstractUnnestMapOperator createFinalNonIndexOnlySearchPlan( Dataset dataset,
ILogicalOperator inputOp, IOptimizationContext context, boolean sortPrimaryKeys, boolean retainInput,
boolean retainMissing, boolean requiresBroadcast, boolean requiresDistinct,
List<LogicalVariable> primaryKeyVars, List<LogicalVariable> primaryIndexUnnestVars,
List<LogicalVariable> auxDistinctVars, List<Object> primaryIndexOutputTypes,
- IAlgebricksConstantValue leftOuterMissingValue) throws AlgebricksException {
- SourceLocation sourceLoc = inputOp.getSourceLocation();
+ IAlgebricksConstantValue leftOuterMissingValue,
+ ARecordType recordType, ARecordType metaRecordType, OptimizableOperatorSubTree subTree,
+ Index secondaryIndex, Mutable<ILogicalOperator> topOpRef, List<Mutable<ILogicalOperator>> assignsBeforeTopOpRef,
+ Mutable<ILogicalExpression> conditionRef) throws AlgebricksException {
+ SourceLocation sourceLoc = inputOp.getSourceLocation();
// Sanity check: requiresDistinct and sortPrimaryKeys are mutually exclusive.
if (requiresDistinct && sortPrimaryKeys) {
throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, sourceLoc,
"Non-index search plan " + "cannot include a DISTINCT and an ORDER.");
}
+ ILogicalOperator op=null;
+ Index.ValueIndexDetails secondaryIndexDetails = (Index.ValueIndexDetails) secondaryIndex.getIndexDetails();
+ List<List<String>> chosenIndexFieldNames = secondaryIndexDetails.getKeyFieldNames();
+ List<IAType> secodaryKeysType = secondaryIndexDetails.getKeyFieldTypes();
+ IndexType idxType = secondaryIndex.getIndexType();
+ if(secodaryKeysType.contains(BuiltinType.ANY) && idxType != IndexType.RTREE) {
+ List<LogicalVariable> skVarsFromSIdxUnnestMap = AccessMethodUtils.getKeyVarsFromSecondaryUnnestMap(dataset,
+ recordType, metaRecordType, inputOp, secondaryIndex, SecondaryUnnestMapOutputVarType.SECONDARY_KEY);
+ List<LogicalVariable> usedVarsInTopOp = new ArrayList<>();
+ List<LogicalVariable> uniqueUsedVarsInTopOp = new ArrayList<>();
+ List<LogicalVariable> producedVarsInAssignsBeforeTopOp = new ArrayList<>();
+ List<LogicalVariable> liveVarsInSubTreeRootOp = new ArrayList<>();
+ List<LogicalVariable> usedVarsAfterTopOp = new ArrayList<>();
+ List<LogicalVariable> varsTmpList = new ArrayList<>();
+ LinkedHashMap<LogicalVariable, LogicalVariable> origVarToSIdxUnnestMapOpVarMap = new LinkedHashMap<>();
+
+ VariableUtilities.getUsedVariables(topOpRef.getValue(), usedVarsInTopOp);
+ VariableUtilities.getLiveVariables(subTree.getRootRef().getValue(), liveVarsInSubTreeRootOp);
+ for (Iterator<LogicalVariable> iterator = usedVarsInTopOp.iterator(); iterator.hasNext(); ) {
+ LogicalVariable v = iterator.next();
+ if (!liveVarsInSubTreeRootOp.contains(v)) {
+ iterator.remove();
+ }
+ }
+ copyVarsToAnotherList(usedVarsInTopOp, uniqueUsedVarsInTopOp);
+
+ if (assignsBeforeTopOpRef != null && !assignsBeforeTopOpRef.isEmpty()) {
+ for (int i = 0; i < assignsBeforeTopOpRef.size(); i++) {
+ ILogicalOperator assignBeforeTopOp = assignsBeforeTopOpRef.get(i).getValue();
+ varsTmpList.clear();
+ VariableUtilities.getProducedVariables(assignBeforeTopOp, varsTmpList);
+ copyVarsToAnotherList(varsTmpList, producedVarsInAssignsBeforeTopOp);
+ }
+ }
+
+ AssignOperator constAssignOp;
+ List<LogicalVariable> constAssignVars = new ArrayList<>();
+ List<Mutable<ILogicalExpression>> constAssignExprs = new ArrayList<>();
+
+ boolean constantAssignVarUsedInTopOp = false;
+ if (assignsBeforeTopOpRef != null && !assignsBeforeTopOpRef.isEmpty()) {
+ for (int i = assignsBeforeTopOpRef.size() - 1; i >= 0; i--) {
+ AssignOperator tmpOp = (AssignOperator) assignsBeforeTopOpRef.get(i).getValue();
+ List<LogicalVariable> tmpAssignVars = tmpOp.getVariables();
+ List<Mutable<ILogicalExpression>> tmpAsssignExprs = tmpOp.getExpressions();
+ Iterator<LogicalVariable> varIt = tmpAssignVars.iterator();
+ Iterator<Mutable<ILogicalExpression>> exprIt = tmpAsssignExprs.iterator();
+ while (exprIt.hasNext()) {
+ Mutable<ILogicalExpression> tmpExpr = exprIt.next();
+ LogicalVariable tmpVar = varIt.next();
+ if (tmpExpr.getValue().getExpressionTag() == LogicalExpressionTag.CONSTANT) {
+ constAssignVars.add(tmpVar);
+ constAssignExprs.add(tmpExpr);
+ varIt.remove();
+ exprIt.remove();
+ }
+ }
+ }
+
+ if (!constAssignVars.isEmpty()) {
+ for (LogicalVariable v : constAssignVars) {
+ if (usedVarsInTopOp.contains(v)) {
+ constantAssignVarUsedInTopOp = true;
+ break;
+ }
+ }
+ constAssignOp = new AssignOperator(constAssignVars, constAssignExprs);
+ constAssignOp.setSourceLocation(sourceLoc);
+ if (constantAssignVarUsedInTopOp) {
+ constAssignOp.getInputs().add(new MutableObject(inputOp));
+ constAssignOp.setExecutionMode(ExecutionMode.PARTITIONED);
+ }
+ }
+ }
+
+ for (LogicalVariable tVar : usedVarsAfterTopOp) {
+
+ // Should be either used in the condition or a composite index field that is not used in the condition.
+ if (!usedVarsInTopOp.contains(tVar) && !producedVarsInAssignsBeforeTopOp.contains(tVar)) {
+ continue;
+ }
+ int sIndexIdx = chosenIndexFieldNames.indexOf(subTree.getVarsToFieldNameMap().get(tVar));
+ if (sIndexIdx == -1) {
+ continue;
+ }
+ origVarToSIdxUnnestMapOpVarMap.put(tVar, skVarsFromSIdxUnnestMap.get(sIndexIdx));
+ }
+
+ List<LogicalVariable> varsUsedInTopOpButNotAfterwards = new ArrayList<>();
+ copyVarsToAnotherList(uniqueUsedVarsInTopOp, varsUsedInTopOpButNotAfterwards);
+ varsUsedInTopOpButNotAfterwards.removeAll(usedVarsAfterTopOp);
+ if (idxType == IndexType.BTREE) {
+ for (LogicalVariable v : varsUsedInTopOpButNotAfterwards) {
+ int sIndexIdx = chosenIndexFieldNames.indexOf(subTree.getVarsToFieldNameMap().get(v));
+ if (sIndexIdx == -1) {
+ continue;
+ }
+ origVarToSIdxUnnestMapOpVarMap.put(v, skVarsFromSIdxUnnestMap.get(sIndexIdx));
+ }
+ }
+
+ SelectOperator newSelectOpInRightPath;
+ if (uniqueUsedVarsInTopOp.size() > 1 || IndexUtil.includesUnknowns(secondaryIndex)) {
+ List<LogicalVariable> list = new ArrayList<LogicalVariable>(origVarToSIdxUnnestMapOpVarMap.keySet());
+
+ ILogicalExpression conditionRefExpr2 = filterCondition(conditionRef.getValue().cloneExpression(), list);
+ if(conditionRefExpr2 != null) {
+ newSelectOpInRightPath =
+ retainMissing
+ ? new SelectOperator(new MutableObject<>(conditionRefExpr2), leftOuterMissingValue,
+ null)
+ : new SelectOperator(new MutableObject<>(conditionRefExpr2));
+ newSelectOpInRightPath.setSourceLocation(conditionRefExpr2.getSourceLocation());
+ newSelectOpInRightPath.getInputs().add(new MutableObject(inputOp));
+ VariableUtilities.substituteVariables(newSelectOpInRightPath, origVarToSIdxUnnestMapOpVarMap, context);
+ newSelectOpInRightPath.setExecutionMode(ExecutionMode.PARTITIONED);
+ context.computeAndSetTypeEnvironmentForOperator(newSelectOpInRightPath);
+ op = newSelectOpInRightPath;
+
+
+ }
+ }
+ }
+ if(op == null){
+ op = inputOp;
+ }
// If we have an array index, then we must only give unique keys to our primary-index scan.
DistinctOperator distinct = null;
if (requiresDistinct) {
@@ -1165,7 +1346,7 @@
}
distinct = new DistinctOperator(distinctExprs);
distinct.setSourceLocation(sourceLoc);
- distinct.getInputs().add(new MutableObject<>(inputOp));
+ distinct.getInputs().add(new MutableObject<>(op));
distinct.setExecutionMode(ExecutionMode.LOCAL);
context.computeAndSetTypeEnvironmentForOperator(distinct);
}
@@ -1182,7 +1363,7 @@
order.getOrderExpressions().add(new Pair<>(OrderOperator.ASC_ORDER, vRef));
}
// The secondary-index search feeds into the sort.
- order.getInputs().add(new MutableObject<>(inputOp));
+ order.getInputs().add(new MutableObject<>(op));
order.setExecutionMode(ExecutionMode.LOCAL);
context.computeAndSetTypeEnvironmentForOperator(order);
}
@@ -1196,13 +1377,15 @@
} else if (sortPrimaryKeys) {
primaryIndexUnnestMapOp.getInputs().add(new MutableObject<>(order));
} else {
- primaryIndexUnnestMapOp.getInputs().add(new MutableObject<>(inputOp));
+ primaryIndexUnnestMapOp.getInputs().add(new MutableObject<>(op));
}
context.computeAndSetTypeEnvironmentForOperator(primaryIndexUnnestMapOp);
primaryIndexUnnestMapOp.setExecutionMode(ExecutionMode.PARTITIONED);
return primaryIndexUnnestMapOp;
}
+
+
private static ILogicalOperator createFinalIndexOnlySearchPlan(List<Mutable<ILogicalOperator>> afterTopOpRefs,
Mutable<ILogicalOperator> topOpRef, Mutable<ILogicalExpression> conditionRef,
List<Mutable<ILogicalOperator>> assignsBeforeTopOpRef, Dataset dataset, ARecordType recordType,
@@ -1833,7 +2016,7 @@
return createFinalNonIndexOnlySearchPlan(dataset, inputOp, context, !isArrayIndex && sortPrimaryKeys,
retainInput, retainMissing, requiresBroadcast, isArrayIndex, pkVarsFromSIdxUnnestMapOp,
- primaryIndexUnnestVars, joinPKVars, primaryIndexOutputTypes, leftOuterMissingValue);
+ primaryIndexUnnestVars, joinPKVars, primaryIndexOutputTypes, leftOuterMissingValue,recordType, metaRecordType,indexSubTree,secondaryIndex,topOpRef,assignsBeforeTopOpRef,conditionRef);
} else if (!isArrayIndex) {
// Index-only plan case: creates a UNIONALL operator that has two paths after the secondary unnest-map op,
// and returns it.
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java
index 34976b6..fa6d65c 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/ValidateUtil.java
@@ -276,6 +276,8 @@
case UUID:
case YEARMONTHDURATION:
case DAYTIMEDURATION:
+ case ANY:
+
break;
default:
throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLoc,
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
index 0c736a2..977b41c 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
@@ -1510,12 +1510,6 @@
}
if (fieldTypePrime == null) {
- if (projectPath != null) {
- String fieldName = LogRedactionUtil.userData(RecordUtil.toFullyQualifiedName(projectPath));
- throw new CompilationException(ErrorCode.COMPILATION_ERROR,
- indexedElement.getSourceLocation(),
- "cannot find type of field '" + fieldName + "'");
- }
// projectPath == null should only be the case with array index having UNNESTs only
if (indexedElement.hasUnnest()) {
List<List<String>> unnestList = indexedElement.getUnnestList();
@@ -1525,8 +1519,7 @@
indexedElement.getSourceLocation(),
"cannot find type of elements of field '" + fieldName + "'");
}
- throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE,
- indexedElement.getSourceLocation(), "cannot find type of field");
+ fieldTypePrime = BuiltinType.ANY;
}
validateIndexFieldType(indexType, fieldTypePrime, projectPath, indexedElement.getSourceLocation());
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslator.java
index 453ccc1..149fa83 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslator.java
@@ -370,8 +370,8 @@
projectTypeNullable = inputTypeNullable;
projectTypeMissable = inputTypeMissable;
} else if (inputTypePrime == null ||
- // handle special case of the empty field name in
- // ExternalIndexingOperations.FILE_INDEX_FIELD_NAMES
+ // handle special case of the empty field name in
+ // ExternalIndexingOperations.FILE_INDEX_FIELD_NAMES
(projectPath.size() == 1 && projectPath.get(0).isEmpty())) {
projectTypePrime = null; // ANY
projectTypeNullable = projectTypeMissable = true;
@@ -381,16 +381,13 @@
}
Triple<IAType, Boolean, Boolean> projectTypeResult =
KeyFieldTypeUtil.getKeyProjectType((ARecordType) inputTypePrime, projectPath, null);
- if (projectTypeResult == null) {
- throw new AsterixException(ErrorCode.METADATA_ERROR, projectPath.toString());
- }
projectTypePrime = projectTypeResult.first;
projectTypeNullable = inputTypeNullable || projectTypeResult.second;
projectTypeMissable = inputTypeMissable || projectTypeResult.third;
}
IAType projectType = projectTypePrime == null ? null
: KeyFieldTypeUtil.makeUnknownableType(projectTypePrime, projectTypeNullable,
- projectTypeMissable);
+ projectTypeMissable);
projectTypeList.add(projectType);
}
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/KeyFieldTypeUtil.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/KeyFieldTypeUtil.java
index fd20b3c..de75d1a 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/KeyFieldTypeUtil.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/KeyFieldTypeUtil.java
@@ -33,6 +33,7 @@
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.AUnionType;
import org.apache.asterix.om.types.AbstractCollectionType;
+import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.types.IAType;
import org.apache.asterix.om.utils.NonTaggedFormatUtil;
import org.apache.asterix.om.utils.RecordUtil;
@@ -269,7 +270,7 @@
}
ARecordType itemRecordType = (ARecordType) itemType;
Triple<IAType, Boolean, Boolean> fieldTypeResult = getKeyProjectType(itemRecordType, unnestPath, sourceLoc);
- if (fieldTypeResult == null) {
+ if (fieldTypeResult.first == BuiltinType.ANY) {
return null;
}
IAType fieldType = fieldTypeResult.first;
@@ -279,7 +280,7 @@
if (!fieldType.getTypeTag().isListType()) {
throw new CompilationException(ErrorCode.TYPE_MISMATCH_GENERIC,
sourceLoc, ExceptionUtil.toExpectedTypeString(new byte[] {
- ATypeTag.SERIALIZED_ORDEREDLIST_TYPE_TAG, ATypeTag.SERIALIZED_UNORDEREDLIST_TYPE_TAG }),
+ ATypeTag.SERIALIZED_ORDEREDLIST_TYPE_TAG, ATypeTag.SERIALIZED_UNORDEREDLIST_TYPE_TAG }),
fieldType);
}
AbstractCollectionType fieldListType = (AbstractCollectionType) fieldType;
@@ -320,7 +321,8 @@
if (fieldType == null) {
if (itemRecordType.isOpen()) {
// open record type and we couldn't find the field -> ok.
- return null;
+ itemType= BuiltinType.ANY;
+ return new Triple<>(itemType, itemTypeNullable, itemTypeMissable);
} else {
// closed record type and we couldn't find the field -> error.
throw new CompilationException(ErrorCode.COMPILATION_FIELD_NOT_FOUND, sourceLoc,
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18522
To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Change-Id: I03b5edfbc304cdb9f36e2b382050781811a14759
Gerrit-Change-Number: 18522
Gerrit-PatchSet: 1
Gerrit-Owner: Shahrzad Haji Amin Shirazi <sh...@ucr.edu>
Gerrit-MessageType: newchange