Search in sources :

Example 31 with AssignOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator in project asterixdb by apache.

the class ExtractGroupByDecorVariablesRule method rewritePost.

@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    ILogicalOperator op = opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.GROUP) {
        return false;
    }
    GroupByOperator groupByOperator = (GroupByOperator) op;
    List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorList = groupByOperator.getDecorList();
    // Returns immediately if there is no decoration entry.
    if (groupByOperator.getDecorList() == null || groupByOperator.getDecorList().isEmpty()) {
        return false;
    }
    // Goes over the decoration list and performs the rewrite.
    boolean changed = false;
    List<LogicalVariable> vars = new ArrayList<>();
    List<Mutable<ILogicalExpression>> exprs = new ArrayList<>();
    for (Pair<LogicalVariable, Mutable<ILogicalExpression>> decorVarExpr : decorList) {
        Mutable<ILogicalExpression> exprRef = decorVarExpr.second;
        ILogicalExpression expr = exprRef.getValue();
        if (expr == null || expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
            continue;
        }
        // Rewrites the decoration entry if the decoration expression is not a variable reference expression.
        changed = true;
        LogicalVariable newVar = context.newVar();
        vars.add(newVar);
        exprs.add(exprRef);
        // Normalizes the decor entry -- expression be a variable reference
        decorVarExpr.second = new MutableObject<>(new VariableReferenceExpression(newVar));
    }
    if (!changed) {
        return false;
    }
    // Injects an assign operator to evaluate the decoration expression.
    AssignOperator assignOperator = new AssignOperator(vars, exprs);
    assignOperator.getInputs().addAll(op.getInputs());
    op.getInputs().set(0, new MutableObject<>(assignOperator));
    return changed;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) GroupByOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ArrayList(java.util.ArrayList) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) VariableReferenceExpression(org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression) Pair(org.apache.hyracks.algebricks.common.utils.Pair)

Example 32 with AssignOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator in project asterixdb by apache.

the class RTreeAccessMethod method createSecondaryToPrimaryPlan.

private ILogicalOperator createSecondaryToPrimaryPlan(OptimizableOperatorSubTree indexSubTree, OptimizableOperatorSubTree probeSubTree, Index chosenIndex, AccessMethodAnalysisContext analysisCtx, boolean retainInput, boolean retainNull, boolean requiresBroadcast, IOptimizationContext context) throws AlgebricksException {
    IOptimizableFuncExpr optFuncExpr = AccessMethodUtils.chooseFirstOptFuncExpr(chosenIndex, analysisCtx);
    Dataset dataset = indexSubTree.getDataset();
    ARecordType recordType = indexSubTree.getRecordType();
    ARecordType metaRecordType = indexSubTree.getMetaRecordType();
    int optFieldIdx = AccessMethodUtils.chooseFirstOptFuncVar(chosenIndex, analysisCtx);
    Pair<IAType, Boolean> keyPairType = Index.getNonNullableOpenFieldType(optFuncExpr.getFieldType(optFieldIdx), optFuncExpr.getFieldName(optFieldIdx), recordType);
    if (keyPairType == null) {
        return null;
    }
    // Get the number of dimensions corresponding to the field indexed by chosenIndex.
    IAType spatialType = keyPairType.first;
    int numDimensions = NonTaggedFormatUtil.getNumDimensions(spatialType.getTypeTag());
    int numSecondaryKeys = numDimensions * 2;
    // we made sure indexSubTree has datasource scan
    AbstractDataSourceOperator dataSourceOp = (AbstractDataSourceOperator) indexSubTree.getDataSourceRef().getValue();
    RTreeJobGenParams jobGenParams = new RTreeJobGenParams(chosenIndex.getIndexName(), IndexType.RTREE, dataset.getDataverseName(), dataset.getDatasetName(), retainInput, requiresBroadcast);
    // A spatial object is serialized in the constant of the func expr we are optimizing.
    // The R-Tree expects as input an MBR represented with 1 field per dimension.
    // Here we generate vars and funcs for extracting MBR fields from the constant into fields of a tuple (as the
    // R-Tree expects them).
    // List of variables for the assign.
    ArrayList<LogicalVariable> keyVarList = new ArrayList<>();
    // List of expressions for the assign.
    ArrayList<Mutable<ILogicalExpression>> keyExprList = new ArrayList<>();
    Pair<ILogicalExpression, Boolean> returnedSearchKeyExpr = AccessMethodUtils.createSearchKeyExpr(optFuncExpr, indexSubTree, probeSubTree);
    ILogicalExpression searchKeyExpr = returnedSearchKeyExpr.first;
    for (int i = 0; i < numSecondaryKeys; i++) {
        // The create MBR function "extracts" one field of an MBR around the given spatial object.
        AbstractFunctionCallExpression createMBR = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.CREATE_MBR));
        // Spatial object is the constant from the func expr we are optimizing.
        createMBR.getArguments().add(new MutableObject<>(searchKeyExpr));
        // The number of dimensions.
        createMBR.getArguments().add(new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(new AInt32(numDimensions)))));
        // Which part of the MBR to extract.
        createMBR.getArguments().add(new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(new AInt32(i)))));
        // Add a variable and its expr to the lists which will be passed into an assign op.
        LogicalVariable keyVar = context.newVar();
        keyVarList.add(keyVar);
        keyExprList.add(new MutableObject<ILogicalExpression>(createMBR));
    }
    jobGenParams.setKeyVarList(keyVarList);
    // Assign operator that "extracts" the MBR fields from the func-expr constant into a tuple.
    AssignOperator assignSearchKeys = new AssignOperator(keyVarList, keyExprList);
    if (probeSubTree == null) {
        // We are optimizing a selection query.
        // Input to this assign is the EmptyTupleSource (which the dataSourceScan also must have had as input).
        assignSearchKeys.getInputs().add(new MutableObject<>(OperatorManipulationUtil.deepCopy(dataSourceOp.getInputs().get(0).getValue())));
        assignSearchKeys.setExecutionMode(dataSourceOp.getExecutionMode());
    } else {
        // We are optimizing a join, place the assign op top of the probe subtree.
        assignSearchKeys.getInputs().add(probeSubTree.getRootRef());
    }
    ILogicalOperator secondaryIndexUnnestOp = AccessMethodUtils.createSecondaryIndexUnnestMap(dataset, recordType, metaRecordType, chosenIndex, assignSearchKeys, jobGenParams, context, false, retainInput, retainNull);
    // Generate the rest of the upstream plan which feeds the search results into the primary index.
    return dataset.getDatasetType() == DatasetType.EXTERNAL ? AccessMethodUtils.createExternalDataLookupUnnestMap(dataSourceOp, dataset, recordType, secondaryIndexUnnestOp, context, retainInput, retainNull) : AccessMethodUtils.createPrimaryIndexUnnestMap(dataSourceOp, dataset, recordType, metaRecordType, secondaryIndexUnnestOp, context, true, retainInput, false, false);
}
Also used : ConstantExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression) ArrayList(java.util.ArrayList) AsterixConstantValue(org.apache.asterix.om.constants.AsterixConstantValue) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression) LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractDataSourceOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractDataSourceOperator) Dataset(org.apache.asterix.metadata.entities.Dataset) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) AInt32(org.apache.asterix.om.base.AInt32) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) ARecordType(org.apache.asterix.om.types.ARecordType) IAType(org.apache.asterix.om.types.IAType)

Example 33 with AssignOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator in project asterixdb by apache.

the class IntroduceLSMComponentFilterRule method getFieldNameFromSubAssignTree.

private Pair<ARecordType, List<String>> getFieldNameFromSubAssignTree(IOptimizableFuncExpr optFuncExpr, AbstractLogicalOperator op, int varIndex, ARecordType recType) {
    AbstractLogicalExpression expr = null;
    if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
        AssignOperator assignOp = (AssignOperator) op;
        expr = (AbstractLogicalExpression) assignOp.getExpressions().get(varIndex).getValue();
    }
    if (expr == null || expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
        return null;
    }
    AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
    FunctionIdentifier funcIdent = funcExpr.getFunctionIdentifier();
    if (funcIdent == BuiltinFunctions.FIELD_ACCESS_BY_NAME || funcIdent == BuiltinFunctions.FIELD_ACCESS_BY_INDEX) {
        //get the variable from here. Figure out which input it came from. Go to that input!!!
        ArrayList<LogicalVariable> usedVars = new ArrayList<>();
        expr.getUsedVariables(usedVars);
        LogicalVariable usedVar = usedVars.get(0);
        List<String> returnList = new ArrayList<>();
        //Find the input that it came from
        for (int varCheck = 0; varCheck < op.getInputs().size(); varCheck++) {
            AbstractLogicalOperator nestedOp = (AbstractLogicalOperator) op.getInputs().get(varCheck).getValue();
            if (nestedOp.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
                if (varCheck == op.getInputs().size() - 1) {
                }
            } else {
                int nestedAssignVar = ((AssignOperator) nestedOp).getVariables().indexOf(usedVar);
                if (nestedAssignVar == -1) {
                    continue;
                }
                //get the nested info from the lower input
                Pair<ARecordType, List<String>> lowerInfo = getFieldNameFromSubAssignTree(optFuncExpr, (AbstractLogicalOperator) op.getInputs().get(varCheck).getValue(), nestedAssignVar, recType);
                if (lowerInfo != null) {
                    recType = lowerInfo.first;
                    returnList = lowerInfo.second;
                }
            }
        }
        if (funcIdent == BuiltinFunctions.FIELD_ACCESS_BY_NAME) {
            String fieldName = ConstantExpressionUtil.getStringArgument(funcExpr, 1);
            if (fieldName == null) {
                return null;
            }
            returnList.add(fieldName);
            return new Pair<>(recType, returnList);
        } else if (funcIdent == BuiltinFunctions.FIELD_ACCESS_BY_INDEX) {
            Integer fieldIndex = ConstantExpressionUtil.getIntArgument(funcExpr, 1);
            if (fieldIndex == null) {
                return null;
            }
            returnList.add(recType.getFieldNames()[fieldIndex]);
            IAType subType = recType.getFieldTypes()[fieldIndex];
            if (subType.getTypeTag() == ATypeTag.OBJECT) {
                recType = (ARecordType) subType;
            }
            return new Pair<>(recType, returnList);
        }
    }
    ILogicalExpression argExpr = funcExpr.getArguments().get(0).getValue();
    if (argExpr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
        return null;
    }
    return null;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractLogicalExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) ArrayList(java.util.ArrayList) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) FunctionIdentifier(org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) ARecordType(org.apache.asterix.om.types.ARecordType) Pair(org.apache.hyracks.algebricks.common.utils.Pair) IAType(org.apache.asterix.om.types.IAType)

Example 34 with AssignOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator in project asterixdb by apache.

the class IntroduceLSMComponentFilterRule method createAssignOperator.

private AssignOperator createAssignOperator(List<IOptimizableFuncExpr> optFuncExprs, List<LogicalVariable> minFilterVars, List<LogicalVariable> maxFilterVars, IOptimizationContext context) {
    List<LogicalVariable> assignKeyVarList = new ArrayList<>();
    List<Mutable<ILogicalExpression>> assignKeyExprList = new ArrayList<>();
    for (IOptimizableFuncExpr optFuncExpr : optFuncExprs) {
        ComparisonKind ck = AlgebricksBuiltinFunctions.getComparisonType(optFuncExpr.getFuncExpr().getFunctionIdentifier());
        ILogicalExpression searchKeyExpr = optFuncExpr.getConstantExpr(0);
        LogicalVariable var = context.newVar();
        assignKeyExprList.add(new MutableObject<>(searchKeyExpr));
        assignKeyVarList.add(var);
        if (ck == ComparisonKind.GE || ck == ComparisonKind.GT) {
            minFilterVars.add(var);
        } else if (ck == ComparisonKind.LE || ck == ComparisonKind.LT) {
            maxFilterVars.add(var);
        } else if (ck == ComparisonKind.EQ) {
            minFilterVars.add(var);
            maxFilterVars.add(var);
        }
    }
    return new AssignOperator(assignKeyVarList, assignKeyExprList);
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) ComparisonKind(org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions.ComparisonKind) ArrayList(java.util.ArrayList) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator)

Example 35 with AssignOperator

use of org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator in project asterixdb by apache.

the class IntroduceLSMComponentFilterRule method findMacthedExprFieldName.

private boolean findMacthedExprFieldName(IOptimizableFuncExpr optFuncExpr, AbstractLogicalOperator op, 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) {
            AssignOperator assignOp = (AssignOperator) descendantOp;
            List<LogicalVariable> varList = assignOp.getVariables();
            for (int varIndex = 0; varIndex < varList.size(); varIndex++) {
                LogicalVariable var = varList.get(varIndex);
                int funcVarIndex = optFuncExpr.findLogicalVar(var);
                if (funcVarIndex == -1) {
                    continue;
                }
                List<String> fieldName = getFieldNameFromSubAssignTree(optFuncExpr, descendantOp, varIndex, recType).second;
                if (fieldName == null) {
                    return false;
                }
                optFuncExpr.setFieldName(funcVarIndex, fieldName);
                return true;
            }
        } else if (descendantOp.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
            DataSourceScanOperator scanOp = (DataSourceScanOperator) descendantOp;
            List<LogicalVariable> varList = scanOp.getVariables();
            for (int varIndex = 0; varIndex < varList.size(); varIndex++) {
                LogicalVariable var = varList.get(varIndex);
                int funcVarIndex = optFuncExpr.findLogicalVar(var);
                if (funcVarIndex == -1) {
                    continue;
                }
                // The variable value is one of the partitioning fields.
                List<String> fieldName = dataset.getPrimaryKeys().get(varIndex);
                if (fieldName == null) {
                    return false;
                }
                optFuncExpr.setFieldName(funcVarIndex, fieldName);
                return true;
            }
        } else if (descendantOp.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
            UnnestMapOperator unnestMapOp = (UnnestMapOperator) descendantOp;
            List<LogicalVariable> varList = unnestMapOp.getVariables();
            for (int varIndex = 0; varIndex < varList.size(); varIndex++) {
                LogicalVariable var = varList.get(varIndex);
                int funcVarIndex = optFuncExpr.findLogicalVar(var);
                if (funcVarIndex == -1) {
                    continue;
                }
                String indexName;
                Index index = null;
                ILogicalExpression unnestExpr = unnestMapOp.getExpressionRef().getValue();
                if (unnestExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
                    AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) unnestExpr;
                    FunctionIdentifier fid = f.getFunctionIdentifier();
                    if (!fid.equals(BuiltinFunctions.INDEX_SEARCH)) {
                        throw new IllegalStateException();
                    }
                    AccessMethodJobGenParams jobGenParams = new AccessMethodJobGenParams();
                    jobGenParams.readFromFuncArgs(f.getArguments());
                    indexName = jobGenParams.indexName;
                    for (Index idx : datasetIndexes) {
                        if (idx.getIndexName().compareTo(indexName) == 0) {
                            index = idx;
                            break;
                        }
                    }
                }
                IAType metaItemType = ((MetadataProvider) context.getMetadataProvider()).findType(dataset.getMetaItemTypeDataverseName(), dataset.getMetaItemTypeName());
                ARecordType metaRecType = (ARecordType) metaItemType;
                int numSecondaryKeys = KeyFieldTypeUtil.getNumSecondaryKeys(index, recType, metaRecType);
                List<String> fieldName;
                if (varIndex >= numSecondaryKeys) {
                    fieldName = dataset.getPrimaryKeys().get(varIndex - numSecondaryKeys);
                } else {
                    fieldName = index.getKeyFieldNames().get(varIndex);
                }
                if (fieldName == null) {
                    return false;
                }
                optFuncExpr.setFieldName(funcVarIndex, fieldName);
                return true;
            }
        }
        if (descendantOp.getInputs().isEmpty()) {
            break;
        }
        descendantOp = (AbstractLogicalOperator) descendantOp.getInputs().get(0).getValue();
    }
    return false;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) UnnestMapOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator) AbstractFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression) Index(org.apache.asterix.metadata.entities.Index) AssignOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator) FunctionIdentifier(org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) DataSourceScanOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator) MetadataProvider(org.apache.asterix.metadata.declared.MetadataProvider) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) ARecordType(org.apache.asterix.om.types.ARecordType) IAType(org.apache.asterix.om.types.IAType)

Aggregations

AssignOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator)95 LogicalVariable (org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable)79 ILogicalExpression (org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression)75 ILogicalOperator (org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator)58 Mutable (org.apache.commons.lang3.mutable.Mutable)56 VariableReferenceExpression (org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression)52 AbstractLogicalOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator)42 ArrayList (java.util.ArrayList)41 AbstractFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)41 ScalarFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)32 Pair (org.apache.hyracks.algebricks.common.utils.Pair)30 MutableObject (org.apache.commons.lang3.mutable.MutableObject)24 ConstantExpression (org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression)24 GbyVariableExpressionPair (org.apache.asterix.lang.common.expression.GbyVariableExpressionPair)19 QuantifiedPair (org.apache.asterix.lang.common.struct.QuantifiedPair)14 AsterixConstantValue (org.apache.asterix.om.constants.AsterixConstantValue)14 UnnestingFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression)14 List (java.util.List)12 AString (org.apache.asterix.om.base.AString)12 AggregateFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression)12