use of org.apache.hyracks.algebricks.common.exceptions.AlgebricksException in project asterixdb by apache.
the class AccessMethodUtils method createSecondaryIndexUnnestMap.
public static ILogicalOperator createSecondaryIndexUnnestMap(Dataset dataset, ARecordType recordType, ARecordType metaRecordType, Index index, ILogicalOperator inputOp, AccessMethodJobGenParams jobGenParams, IOptimizationContext context, boolean outputPrimaryKeysOnly, boolean retainInput, boolean retainNull) 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<>();
jobGenParams.writeToFuncArgs(secondaryIndexFuncArgs);
// Variables and types coming out of the secondary-index search.
List<LogicalVariable> secondaryIndexUnnestVars = new ArrayList<>();
List<Object> secondaryIndexOutputTypes = new ArrayList<>();
// Append output variables/types generated by the secondary-index search (not forwarded from input).
appendSecondaryIndexOutputVars(dataset, recordType, metaRecordType, index, outputPrimaryKeysOnly, context, secondaryIndexUnnestVars);
appendSecondaryIndexTypes(dataset, recordType, metaRecordType, index, outputPrimaryKeysOnly, secondaryIndexOutputTypes);
// An index search is expressed as an unnest over an index-search function.
IFunctionInfo secondaryIndexSearch = FunctionUtil.getFunctionInfo(BuiltinFunctions.INDEX_SEARCH);
UnnestingFunctionCallExpression secondaryIndexSearchFunc = new UnnestingFunctionCallExpression(secondaryIndexSearch, secondaryIndexFuncArgs);
secondaryIndexSearchFunc.setReturnsUniqueValues(true);
// Then, we use the LEFT-OUTER-UNNEST-MAP operator instead of unnest-map operator.
if (retainNull) {
if (retainInput) {
LeftOuterUnnestMapOperator secondaryIndexLeftOuterUnnestOp = new LeftOuterUnnestMapOperator(secondaryIndexUnnestVars, new MutableObject<ILogicalExpression>(secondaryIndexSearchFunc), secondaryIndexOutputTypes, true);
secondaryIndexLeftOuterUnnestOp.getInputs().add(new MutableObject<>(inputOp));
context.computeAndSetTypeEnvironmentForOperator(secondaryIndexLeftOuterUnnestOp);
secondaryIndexLeftOuterUnnestOp.setExecutionMode(ExecutionMode.PARTITIONED);
return secondaryIndexLeftOuterUnnestOp;
} else {
// Left-outer-join without retainInput doesn't make sense.
throw new AlgebricksException("Left-outer-join should propagate all inputs from the outer branch.");
}
} else {
// If this is not a left-outer-join case, then we use UNNEST-MAP operator.
UnnestMapOperator secondaryIndexUnnestOp = new UnnestMapOperator(secondaryIndexUnnestVars, new MutableObject<ILogicalExpression>(secondaryIndexSearchFunc), secondaryIndexOutputTypes, retainInput);
secondaryIndexUnnestOp.getInputs().add(new MutableObject<>(inputOp));
context.computeAndSetTypeEnvironmentForOperator(secondaryIndexUnnestOp);
secondaryIndexUnnestOp.setExecutionMode(ExecutionMode.PARTITIONED);
return secondaryIndexUnnestOp;
}
}
use of org.apache.hyracks.algebricks.common.exceptions.AlgebricksException in project asterixdb by apache.
the class UnnestToDataScanRule method parseDatasetReference.
private Pair<String, String> parseDatasetReference(MetadataProvider metadataProvider, String datasetArg) throws AlgebricksException {
String[] datasetNameComponents = datasetArg.split("\\.");
String dataverseName;
String datasetName;
if (datasetNameComponents.length == 1) {
Dataverse defaultDataverse = metadataProvider.getDefaultDataverse();
if (defaultDataverse == null) {
throw new AlgebricksException("Unresolved dataset " + datasetArg + " Dataverse not specified.");
}
dataverseName = defaultDataverse.getDataverseName();
datasetName = datasetNameComponents[0];
} else {
dataverseName = datasetNameComponents[0];
datasetName = datasetNameComponents[1];
}
return new Pair<>(dataverseName, datasetName);
}
use of org.apache.hyracks.algebricks.common.exceptions.AlgebricksException in project asterixdb by apache.
the class ResolveVariableRule method resolveInternal.
// Resolves an undefined name to a dataset or a fully qualified variable/field-access path
// based on the given information of dataset matches and candidate paths.
private boolean resolveInternal(Mutable<ILogicalExpression> funcRef, boolean hasMatchedDataset, Collection<Pair<ILogicalExpression, List<String>>> varAccessCandidates, String unresolvedVarName, Triple<Boolean, String, String> fullyQualifiedDatasetPathCandidateFromParent, Mutable<ILogicalExpression> parentFuncRef, IOptimizationContext context) throws AlgebricksException {
AbstractFunctionCallExpression func = (AbstractFunctionCallExpression) funcRef.getValue();
int numVarCandidates = varAccessCandidates.size();
// The resolution order: 1. field-access 2. datasets (standalone-name or fully-qualified)
if (numVarCandidates > 0) {
if (numVarCandidates == 1) {
resolveAsFieldAccess(funcRef, varAccessCandidates.iterator().next());
} else {
// More than one possibilities.
throw new AlgebricksException("Cannot resolve ambiguous alias reference for undefined identifier " + unresolvedVarName);
}
} else if (hasMatchedDataset) {
// Rewrites the "resolve" function to a "dataset" function and only keep the dataset name argument.
func.setFunctionInfo(FunctionUtil.getFunctionInfo(BuiltinFunctions.DATASET));
Mutable<ILogicalExpression> datasetNameExpression = func.getArguments().get(0);
func.getArguments().clear();
func.getArguments().add(datasetNameExpression);
} else if (fullyQualifiedDatasetPathCandidateFromParent.first) {
// Rewrites the parent "field-access" function to a "dataset" function.
AbstractFunctionCallExpression parentFunc = (AbstractFunctionCallExpression) parentFuncRef.getValue();
parentFunc.setFunctionInfo(FunctionUtil.getFunctionInfo(BuiltinFunctions.DATASET));
parentFunc.getArguments().clear();
parentFunc.getArguments().add(new MutableObject<>(new ConstantExpression(new AsterixConstantValue(new AString(fullyQualifiedDatasetPathCandidateFromParent.second + "." + fullyQualifiedDatasetPathCandidateFromParent.third)))));
} else {
MetadataProvider metadataProvider = (MetadataProvider) context.getMetadataProvider();
// Cannot find any resolution.
throw new AlgebricksException("Cannot find dataset " + unresolvedVarName + " in dataverse " + metadataProvider.getDefaultDataverseName() + " nor an alias with name " + unresolvedVarName);
}
return true;
}
use of org.apache.hyracks.algebricks.common.exceptions.AlgebricksException in project asterixdb by apache.
the class IntroduceSelectAccessMethodRule method connectAll2ndarySearchPlanWithIntersect.
/**
* Connect each secondary index utilization plan to a common INTERSECT operator.
*/
private ILogicalOperator connectAll2ndarySearchPlanWithIntersect(List<ILogicalOperator> subRoots, IOptimizationContext context) throws AlgebricksException {
ILogicalOperator lop = subRoots.get(0);
List<List<LogicalVariable>> inputVars = new ArrayList<>(subRoots.size());
for (int i = 0; i < subRoots.size(); i++) {
if (lop.getOperatorTag() != subRoots.get(i).getOperatorTag()) {
throw new AlgebricksException("The data source root should have the same operator type.");
}
if (lop.getInputs().size() != 1) {
throw new AlgebricksException("The primary search has multiple inputs.");
}
ILogicalOperator curRoot = subRoots.get(i);
OrderOperator order = (OrderOperator) curRoot.getInputs().get(0).getValue();
List<LogicalVariable> orderedColumn = new ArrayList<>(order.getOrderExpressions().size());
for (Pair<OrderOperator.IOrder, Mutable<ILogicalExpression>> orderExpression : order.getOrderExpressions()) {
if (orderExpression.second.getValue().getExpressionTag() != LogicalExpressionTag.VARIABLE) {
throw new AlgebricksException("The order by expression should be variables, but they aren't variables.");
}
VariableReferenceExpression orderedVar = (VariableReferenceExpression) orderExpression.second.getValue();
orderedColumn.add(orderedVar.getVariableReference());
}
inputVars.add(orderedColumn);
}
List<LogicalVariable> outputVar = inputVars.get(0);
IntersectOperator intersect = new IntersectOperator(outputVar, inputVars);
for (ILogicalOperator secondarySearch : subRoots) {
intersect.getInputs().add(secondarySearch.getInputs().get(0));
}
context.computeAndSetTypeEnvironmentForOperator(intersect);
lop.getInputs().set(0, new MutableObject<>(intersect));
return lop;
}
use of org.apache.hyracks.algebricks.common.exceptions.AlgebricksException in project asterixdb by apache.
the class LangExpressionToPlanTranslator method eliminateSharedOperatorReference.
/**
* Eliminate shared operator references in a query plan rooted at <code>currentOpRef.getValue()</code>.
* Deep copy a new query plan subtree whenever there is a shared operator reference.
*
* @param currentOpRef,
* the operator reference to consider
* @param opRefSet,
* the set storing seen operator references so far.
* @return a mapping that maps old variables to new variables, for the ancestors of
* <code>currentOpRef</code> to replace variables properly.
* @throws CompilationException
*/
private LinkedHashMap<LogicalVariable, LogicalVariable> eliminateSharedOperatorReference(Mutable<ILogicalOperator> currentOpRef, Set<Mutable<ILogicalOperator>> opRefSet) throws CompilationException {
try {
opRefSet.add(currentOpRef);
AbstractLogicalOperator currentOperator = (AbstractLogicalOperator) currentOpRef.getValue();
// Recursively eliminates shared references in nested plans.
if (currentOperator.hasNestedPlans()) {
// Since a nested plan tree itself can never be shared with another nested plan tree in
// another operator, the operation called in the if block does not need to replace
// any variables further for <code>currentOpRef.getValue()</code> nor its ancestor.
AbstractOperatorWithNestedPlans opWithNestedPlan = (AbstractOperatorWithNestedPlans) currentOperator;
for (ILogicalPlan plan : opWithNestedPlan.getNestedPlans()) {
for (Mutable<ILogicalOperator> rootRef : plan.getRoots()) {
Set<Mutable<ILogicalOperator>> nestedOpRefSet = new HashSet<>();
eliminateSharedOperatorReference(rootRef, nestedOpRefSet);
}
}
}
int childIndex = 0;
LinkedHashMap<LogicalVariable, LogicalVariable> varMap = new LinkedHashMap<>();
for (Mutable<ILogicalOperator> childRef : currentOperator.getInputs()) {
if (opRefSet.contains(childRef)) {
// There is a shared operator reference in the query plan.
// Deep copies the child plan.
LogicalOperatorDeepCopyWithNewVariablesVisitor visitor = new LogicalOperatorDeepCopyWithNewVariablesVisitor(context, null);
ILogicalOperator newChild = childRef.getValue().accept(visitor, null);
LinkedHashMap<LogicalVariable, LogicalVariable> cloneVarMap = visitor.getInputToOutputVariableMapping();
// Substitute variables according to the deep copy which generates new variables.
VariableUtilities.substituteVariables(currentOperator, cloneVarMap, null);
varMap.putAll(cloneVarMap);
// Sets the new child.
childRef = new MutableObject<>(newChild);
currentOperator.getInputs().set(childIndex, childRef);
}
// Recursively eliminate shared operator reference for the operator subtree,
// even if it is a deep copy of some other one.
LinkedHashMap<LogicalVariable, LogicalVariable> childVarMap = eliminateSharedOperatorReference(childRef, opRefSet);
// Substitute variables according to the new subtree.
VariableUtilities.substituteVariables(currentOperator, childVarMap, null);
// in childVarMap.
for (Map.Entry<LogicalVariable, LogicalVariable> entry : varMap.entrySet()) {
LogicalVariable newVar = childVarMap.get(entry.getValue());
if (newVar != null) {
entry.setValue(newVar);
}
}
varMap.putAll(childVarMap);
++childIndex;
}
// Only retain live variables for parent operators to substitute variables.
Set<LogicalVariable> liveVars = new HashSet<>();
VariableUtilities.getLiveVariables(currentOperator, liveVars);
varMap.values().retainAll(liveVars);
return varMap;
} catch (AlgebricksException e) {
throw new CompilationException(e);
}
}
Aggregations