private void copySourceLocation(ILogicalExpression src, AbstractLogicalExpression dest) { dest.setSourceLocation(src.getSourceLocation()); }
/** * Finds a variable assigned to a given expression and returns a new {@link VariableReferenceExpression} * referring to this variable. * @param assignVarList list of variables * @param assignExprList list of expressions assigned to those variables * @param searchExpr expression to search for * @return said value, {@code null} if a variable is not found */ public static VariableReferenceExpression findAssignedVariable(List<LogicalVariable> assignVarList, List<Mutable<ILogicalExpression>> assignExprList, ILogicalExpression searchExpr) { for (int i = 0, n = assignExprList.size(); i < n; i++) { ILogicalExpression expr = assignExprList.get(i).getValue(); if (expr.equals(searchExpr)) { VariableReferenceExpression result = new VariableReferenceExpression(assignVarList.get(i)); result.setSourceLocation(expr.getSourceLocation()); return result; } } return null; } }
private ILogicalExpression getScalarExpr(FunctionIdentifier func, ILogicalExpression interval) { List<Mutable<ILogicalExpression>> intervalArg = new ArrayList<>(); intervalArg.add(new MutableObject<ILogicalExpression>(interval)); ScalarFunctionCallExpression fnExpr = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(func), intervalArg); fnExpr.setSourceLocation(interval.getSourceLocation()); return fnExpr; }
private ILogicalExpression createNotNullFunction(ILogicalExpression mergedRec) { List<Mutable<ILogicalExpression>> args = new ArrayList<>(); args.add(new MutableObject<ILogicalExpression>(mergedRec)); AbstractFunctionCallExpression notNullFn = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.CHECK_UNKNOWN), args); notNullFn.setSourceLocation(mergedRec.getSourceLocation()); return notNullFn; }
private ILogicalExpression getScalarExpr(FunctionIdentifier func, ILogicalExpression interval1, ILogicalExpression interval2) { List<Mutable<ILogicalExpression>> intervalArg = new ArrayList<>(); intervalArg.add(new MutableObject<ILogicalExpression>(interval1)); intervalArg.add(new MutableObject<ILogicalExpression>(interval2)); ScalarFunctionCallExpression fnExpr = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(func), intervalArg); fnExpr.setSourceLocation(interval1.getSourceLocation()); return fnExpr; }
private ILogicalExpression createSelectCondition(List<Mutable<ILogicalExpression>> predList) { if (predList.size() > 1) { IFunctionInfo finfo = FunctionUtil.getFunctionInfo(AlgebricksBuiltinFunctions.AND); ScalarFunctionCallExpression andExpr = new ScalarFunctionCallExpression(finfo, predList); andExpr.setSourceLocation(predList.get(0).getValue().getSourceLocation()); return andExpr; } return predList.get(0).getValue(); }
private boolean testAndModifyRedundantOp(AssignOperator access, AbstractLogicalOperator op2) { if (op2.getOperatorTag() != LogicalOperatorTag.ASSIGN) { return false; } AssignOperator a2 = (AssignOperator) op2; ILogicalExpression accessExpr0 = getFirstExpr(access); if (accessExpr0.equals(getFirstExpr(a2))) { VariableReferenceExpression varRef = new VariableReferenceExpression(a2.getVariables().get(0)); varRef.setSourceLocation(accessExpr0.getSourceLocation()); access.getExpressions().get(0).setValue(varRef); return true; } else { return false; } }
@Override public Object getType(ILogicalExpression expr, IMetadataProvider<?, ?> metadataProvider, IVariableTypeEnvironment env) throws AlgebricksException { switch (expr.getExpressionTag()) { case CONSTANT: return getTypeForConstant((ConstantExpression) expr, env); case FUNCTION_CALL: return getTypeForFunction((AbstractFunctionCallExpression) expr, env, metadataProvider); case VARIABLE: try { return env.getVarType(((VariableReferenceExpression) expr).getVariableReference()); } catch (Exception e) { throw new CompilationException(ErrorCode.COMPILATION_ERROR, expr.getSourceLocation(), "Could not resolve type for " + expr.toString() + "," + "please check whether the used variable has been defined!", e); } default: throw new IllegalStateException(); } }
private boolean extractFirstArg(AbstractFunctionCallExpression fce, ILogicalOperator op, IOptimizationContext context) throws AlgebricksException { ILogicalExpression firstArg = fce.getArguments().get(0).getValue(); if (firstArg.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) { return false; } SourceLocation sourceLoc = firstArg.getSourceLocation(); LogicalVariable var1 = context.newVar(); AssignOperator assignOp = new AssignOperator(new ArrayList<>(Collections.singletonList(var1)), new ArrayList<>(Collections.singletonList(new MutableObject<>(firstArg)))); assignOp.setSourceLocation(sourceLoc); VariableReferenceExpression var1Ref = new VariableReferenceExpression(var1); var1Ref.setSourceLocation(sourceLoc); fce.getArguments().get(0).setValue(var1Ref); assignOp.getInputs().add(new MutableObject<>(op.getInputs().get(0).getValue())); op.getInputs().get(0).setValue(assignOp); context.computeAndSetTypeEnvironmentForOperator(assignOp); return true; }
protected Mutable<ILogicalExpression> generateAndNotIsUnknownWrap(ILogicalExpression logicalExpr) { SourceLocation sourceLoc = logicalExpr.getSourceLocation(); List<Mutable<ILogicalExpression>> arguments = new ArrayList<>(); arguments.add(new MutableObject<>(logicalExpr)); ScalarFunctionCallExpression isUnknownExpr = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.IS_UNKNOWN), new ArrayList<>(Collections.singletonList(new MutableObject<>(logicalExpr)))); isUnknownExpr.setSourceLocation(sourceLoc); ScalarFunctionCallExpression notExpr = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.NOT), new ArrayList<>(Collections.singletonList(new MutableObject<>(isUnknownExpr)))); notExpr.setSourceLocation(sourceLoc); arguments.add(new MutableObject<>(notExpr)); ScalarFunctionCallExpression andExpr = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.AND), arguments); andExpr.setSourceLocation(sourceLoc); return new MutableObject<>(andExpr); }
@Override public boolean transform(Mutable<ILogicalExpression> exprRef) { ILogicalExpression expr = exprRef.getValue(); if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) { return false; } AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr; if (!funcExpr.getFunctionIdentifier().equals(BuiltinFunctions.META_KEY)) { return false; } // function is meta key access for (int i = 0; i < metaKeyAccessExpressions.size(); i++) { if (metaKeyAccessExpressions.get(i).equals(funcExpr)) { VariableReferenceExpression varRef = new VariableReferenceExpression(keyVars.get(i)); varRef.setSourceLocation(expr.getSourceLocation()); exprRef.setValue(varRef); return true; } } return false; } }
protected static <T> boolean extractComplexExpressions(ILogicalOperator op, List<T> exprList, Function<T, Mutable<ILogicalExpression>> exprGetter, Predicate<ILogicalExpression> retainPredicate, IOptimizationContext context) throws AlgebricksException { if (!hasComplexExpressions(exprList, exprGetter)) { return false; } boolean rewritten = false; Mutable<ILogicalOperator> inputOpRef = op.getInputs().get(0); for (T item : exprList) { Mutable<ILogicalExpression> exprMutable = exprGetter.apply(item); ILogicalExpression expr = exprMutable.getValue(); if (expr.getExpressionTag() != LogicalExpressionTag.VARIABLE && !retainPredicate.test(expr)) { LogicalVariable v = extractExprIntoAssignOpRef(expr, inputOpRef, context); VariableReferenceExpression vRef = new VariableReferenceExpression(v); vRef.setSourceLocation(expr.getSourceLocation()); exprMutable.setValue(vRef); rewritten = true; } } context.computeAndSetTypeEnvironmentForOperator(op); return rewritten; }
private boolean rewriteFunctionArgument(Mutable<ILogicalExpression> argRef, IAType funcOutputType, IVariableTypeEnvironment env) throws AlgebricksException { ILogicalExpression argExpr = argRef.getValue(); IAType type = (IAType) env.getType(argExpr); if (TypeResolverUtil.needsCast(funcOutputType, type)) { // Injects a cast call to cast the data type to the produced type of the function call. ScalarFunctionCallExpression castFunc = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.CAST_TYPE), new ArrayList<>(Collections.singletonList(new MutableObject<>(argExpr)))); castFunc.setSourceLocation(argExpr.getSourceLocation()); TypeCastUtils.setRequiredAndInputTypes(castFunc, funcOutputType, type); argRef.setValue(castFunc); return true; } return false; } }
@Override protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException { IAType inputType = strippedInputTypes[0]; if (ATypeHierarchy.isCompatible(inputType.getTypeTag(), type.getTypeTag())) { return type; } else { throw new TypeMismatchException(expr.getSourceLocation(), inputType.getTypeTag(), type.getTypeTag()); } } }
protected static LogicalVariable extractExprIntoAssignOpRef(ILogicalExpression gExpr, Mutable<ILogicalOperator> opRef2, IOptimizationContext context) throws AlgebricksException { LogicalVariable v = context.newVar(); AssignOperator a = new AssignOperator(v, new MutableObject<>(gExpr)); a.setSourceLocation(gExpr.getSourceLocation()); a.getInputs().add(new MutableObject<>(opRef2.getValue())); opRef2.setValue(a); if (gExpr.getExpressionTag() == LogicalExpressionTag.CONSTANT) { context.addNotToBeInlinedVar(v); } context.computeAndSetTypeEnvironmentForOperator(a); return v; }
@Override public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException { AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue(); if (op.getOperatorTag() != LogicalOperatorTag.SELECT) { return false; } SelectOperator select = (SelectOperator) op; ILogicalExpression condition = select.getCondition().getValue(); IVariableTypeEnvironment env = select.computeOutputTypeEnvironment(context); IAType condType = (IAType) env.getType(condition); if (condType.getTypeTag() != ATypeTag.BOOLEAN && condType.getTypeTag() != ATypeTag.ANY && !isPossibleBoolean(condType)) { throw new CompilationException(ErrorCode.COMPILATION_ERROR, condition.getSourceLocation(), "The select condition " + LogRedactionUtil.userData(condition.toString()) + " should be of the " + "boolean type."); } return false; }
@Override protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException { if (strippedInputTypes.length < 2) { String functionName = ((AbstractFunctionCallExpression) expr).getFunctionIdentifier().getName(); throw new CompilationException(ErrorCode.COMPILATION_INVALID_NUM_OF_ARGS, expr.getSourceLocation(), functionName); } IAType listType = strippedInputTypes[0]; if (listType.getTypeTag().isListType()) { listType = DefaultOpenFieldType.getDefaultOpenFieldType(listType.getTypeTag()); return AUnionType.createUnknownableType(listType); } else { return BuiltinType.ANY; } } }
protected ILogicalPlan createNestedPlanWithAggregate(LogicalVariable aggOutputVar, FunctionIdentifier aggFunc, ILogicalExpression aggFnInput, Mutable<ILogicalOperator> aggOpInput) { SourceLocation sourceLoc = aggFnInput.getSourceLocation(); AggregateFunctionCallExpression aggFnCall = BuiltinFunctions.makeAggregateFunctionExpression(aggFunc, mkSingletonArrayList(new MutableObject<>(aggFnInput))); aggFnCall.setSourceLocation(sourceLoc); AggregateOperator aggOp = new AggregateOperator(mkSingletonArrayList(aggOutputVar), mkSingletonArrayList(new MutableObject<>(aggFnCall))); aggOp.getInputs().add(aggOpInput); aggOp.setSourceLocation(sourceLoc); return new ALogicalPlanImpl(new MutableObject<>(aggOp)); }
@Override protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException { if (strippedInputTypes.length != 2 && strippedInputTypes.length != 3) { String functionName = ((AbstractFunctionCallExpression) expr).getFunctionIdentifier().getName(); throw new CompilationException(ErrorCode.COMPILATION_INVALID_NUM_OF_ARGS, expr.getSourceLocation(), functionName); } IAType startNum = strippedInputTypes[0]; IAType endNum = strippedInputTypes[1]; IAType step = strippedInputTypes.length == 3 ? strippedInputTypes[2] : null; if (ATypeHierarchy.canPromote(startNum.getTypeTag(), ATypeTag.BIGINT) && ATypeHierarchy.canPromote(endNum.getTypeTag(), ATypeTag.BIGINT) && (step == null || ATypeHierarchy.canPromote(step.getTypeTag(), ATypeTag.BIGINT))) { return LONG_LIST; } else if (ATypeHierarchy.canPromote(startNum.getTypeTag(), ATypeTag.DOUBLE) && ATypeHierarchy.canPromote(endNum.getTypeTag(), ATypeTag.DOUBLE) && (step == null || ATypeHierarchy.canPromote(step.getTypeTag(), ATypeTag.DOUBLE))) { return DOUBLE_LIST; } else { return BuiltinType.ANY; } } }
public static void checkFTSearchConstantExpression(ILogicalExpression constExpression) throws AlgebricksException { IAObject objectFromExpr = ConstantExpressionUtil.getConstantIaObject(constExpression, null); String arg2Value; IACursor oListCursor; switch (objectFromExpr.getType().getTypeTag()) { case STRING: arg2Value = ConstantExpressionUtil.getStringConstant(objectFromExpr); checkAndGenerateFTSearchExceptionForStringPhrase(arg2Value); break; case ARRAY: oListCursor = ConstantExpressionUtil.getOrderedListConstant(objectFromExpr).getCursor(); checkEachElementInFTSearchListPredicate(oListCursor); break; case MULTISET: oListCursor = ConstantExpressionUtil.getUnorderedListConstant(objectFromExpr).getCursor(); checkEachElementInFTSearchListPredicate(oListCursor); break; default: throw new CompilationException(ErrorCode.COMPILATION_TYPE_UNSUPPORTED, constExpression.getSourceLocation(), BuiltinFunctions.FULLTEXT_CONTAINS.getName(), objectFromExpr.getType().getTypeTag()); } }