use of org.apache.commons.lang3.mutable.MutableObject in project asterixdb by apache.
the class SqlppExpressionToPlanTranslator method generateUnnestForBinaryCorrelateRightBranch.
private Pair<ILogicalOperator, LogicalVariable> generateUnnestForBinaryCorrelateRightBranch(AbstractBinaryCorrelateClause binaryCorrelate, Mutable<ILogicalOperator> inputOpRef, boolean innerUnnest) throws CompilationException {
LogicalVariable rightVar = context.newVarFromExpression(binaryCorrelate.getRightVariable());
Expression rightExpr = binaryCorrelate.getRightExpression();
Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(rightExpr, inputOpRef);
ILogicalOperator unnestOp;
if (binaryCorrelate.hasPositionalVariable()) {
LogicalVariable pVar = context.newVarFromExpression(binaryCorrelate.getPositionalVariable());
// We set the positional variable type as BIGINT type.
unnestOp = innerUnnest ? new UnnestOperator(rightVar, new MutableObject<>(makeUnnestExpression(eo.first)), pVar, BuiltinType.AINT64, new PositionWriter()) : new LeftOuterUnnestOperator(rightVar, new MutableObject<>(makeUnnestExpression(eo.first)), pVar, BuiltinType.AINT64, new PositionWriter());
} else {
unnestOp = innerUnnest ? new UnnestOperator(rightVar, new MutableObject<>(makeUnnestExpression(eo.first))) : new LeftOuterUnnestOperator(rightVar, new MutableObject<>(makeUnnestExpression(eo.first)));
}
unnestOp.getInputs().add(eo.second);
return new Pair<>(unnestOp, rightVar);
}
use of org.apache.commons.lang3.mutable.MutableObject in project asterixdb by apache.
the class SqlppExpressionToPlanTranslator method processSelectClause.
// Generates the return expression for a select clause.
private Pair<ILogicalOperator, LogicalVariable> processSelectClause(SelectBlock selectBlock, Mutable<ILogicalOperator> tupSrc) throws CompilationException {
SelectClause selectClause = selectBlock.getSelectClause();
Expression returnExpr;
if (selectClause.selectElement()) {
returnExpr = selectClause.getSelectElement().getExpression();
} else {
returnExpr = generateReturnExpr(selectClause, selectBlock);
}
Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(returnExpr, tupSrc);
LogicalVariable returnVar;
ILogicalOperator returnOperator;
if (returnExpr.getKind() == Kind.VARIABLE_EXPRESSION) {
VariableExpr varExpr = (VariableExpr) returnExpr;
returnOperator = eo.second.getValue();
returnVar = context.getVar(varExpr.getVar().getId());
} else {
returnVar = context.newVar();
returnOperator = new AssignOperator(returnVar, new MutableObject<ILogicalExpression>(eo.first));
returnOperator.getInputs().add(eo.second);
}
if (selectClause.distinct()) {
DistinctOperator distinctOperator = new DistinctOperator(mkSingletonArrayList(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(returnVar))));
distinctOperator.getInputs().add(new MutableObject<ILogicalOperator>(returnOperator));
return new Pair<>(distinctOperator, returnVar);
} else {
return new Pair<>(returnOperator, returnVar);
}
}
use of org.apache.commons.lang3.mutable.MutableObject in project asterixdb by apache.
the class StaticTypeCastUtil method staticRecordTypeCast.
/**
* This method statically cast the type of records from their current type to the required type.
*
* @param func
* The record constructor expression.
* @param reqType
* The required type.
* @param inputType
* The current type.
* @param env
* The type environment.
* @throws AlgebricksException
*/
private static boolean staticRecordTypeCast(AbstractFunctionCallExpression func, ARecordType reqType, ARecordType inputType, IVariableTypeEnvironment env) throws AlgebricksException {
if (!(func.getFunctionIdentifier() == BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR || func.getFunctionIdentifier() == BuiltinFunctions.CLOSED_RECORD_CONSTRUCTOR)) {
return false;
}
IAType[] reqFieldTypes = reqType.getFieldTypes();
String[] reqFieldNames = reqType.getFieldNames();
IAType[] inputFieldTypes = inputType.getFieldTypes();
String[] inputFieldNames = inputType.getFieldNames();
int[] fieldPermutation = new int[reqFieldTypes.length];
boolean[] nullFields = new boolean[reqFieldTypes.length];
boolean[] openFields = new boolean[inputFieldTypes.length];
Arrays.fill(nullFields, false);
Arrays.fill(openFields, true);
Arrays.fill(fieldPermutation, -1);
// forward match: match from actual to required
boolean matched = false;
for (int i = 0; i < inputFieldNames.length; i++) {
String fieldName = inputFieldNames[i];
IAType fieldType = inputFieldTypes[i];
if (2 * i + 1 > func.getArguments().size()) {
// it is not a record constructor function
return false;
}
// 2*i+1 is the index of field value expression
ILogicalExpression arg = func.getArguments().get(2 * i + 1).getValue();
matched = false;
for (int j = 0; j < reqFieldNames.length; j++) {
String reqFieldName = reqFieldNames[j];
IAType reqFieldType = reqFieldTypes[j];
if (fieldName.equals(reqFieldName)) {
//type matched
if (fieldType.equals(reqFieldType)) {
fieldPermutation[j] = i;
openFields[i] = false;
matched = true;
if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
ScalarFunctionCallExpression scalarFunc = (ScalarFunctionCallExpression) arg;
rewriteFuncExpr(scalarFunc, reqFieldType, fieldType, env);
}
break;
}
// match the optional field
if (NonTaggedFormatUtil.isOptional(reqFieldType)) {
IAType itemType = ((AUnionType) reqFieldType).getActualType();
reqFieldType = itemType;
if (fieldType.equals(BuiltinType.AMISSING) || fieldType.equals(itemType)) {
fieldPermutation[j] = i;
openFields[i] = false;
matched = true;
// rewrite record expr
if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
ScalarFunctionCallExpression scalarFunc = (ScalarFunctionCallExpression) arg;
rewriteFuncExpr(scalarFunc, reqFieldType, fieldType, env);
}
break;
}
}
// delay that to runtime by calling the not-null function
if (NonTaggedFormatUtil.isOptional(fieldType)) {
IAType itemType = ((AUnionType) fieldType).getActualType();
if (reqFieldType.equals(itemType)) {
fieldPermutation[j] = i;
openFields[i] = false;
matched = true;
ScalarFunctionCallExpression notNullFunc = new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(BuiltinFunctions.CHECK_UNKNOWN));
notNullFunc.getArguments().add(new MutableObject<ILogicalExpression>(arg));
//wrap the not null function to the original function
func.getArguments().get(2 * i + 1).setValue(notNullFunc);
break;
}
}
// match the record field: need cast
if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
ScalarFunctionCallExpression scalarFunc = (ScalarFunctionCallExpression) arg;
rewriteFuncExpr(scalarFunc, reqFieldType, fieldType, env);
fieldPermutation[j] = i;
openFields[i] = false;
matched = true;
break;
}
}
}
// the input has extra fields
if (!matched && !reqType.isOpen()) {
throw new AlgebricksException("static type mismatch: the input record includes an extra closed field " + fieldName + ":" + fieldType + "! Please check the field name and type.");
}
}
// backward match: match from required to actual
for (int i = 0; i < reqFieldNames.length; i++) {
String reqFieldName = reqFieldNames[i];
IAType reqFieldType = reqFieldTypes[i];
matched = false;
for (int j = 0; j < inputFieldNames.length; j++) {
String fieldName = inputFieldNames[j];
IAType fieldType = inputFieldTypes[j];
if (!fieldName.equals(reqFieldName)) {
continue;
}
// the entry index of fieldPermuatons is req field index
if (!openFields[j]) {
matched = true;
break;
}
// match the optional field
if (!NonTaggedFormatUtil.isOptional(reqFieldType)) {
continue;
}
IAType itemType = ((AUnionType) reqFieldType).getActualType();
if (fieldType.equals(BuiltinType.AMISSING) || fieldType.equals(itemType)) {
matched = true;
break;
}
}
if (matched) {
continue;
}
if (NonTaggedFormatUtil.isOptional(reqFieldType)) {
// add a null field
nullFields[i] = true;
} else {
// no matched field in the input for a required closed field
if (inputType.isOpen()) {
//if the input type is open, return false, give that to dynamic type cast to defer the error to the runtime
return false;
} else {
throw new AlgebricksException("static type mismatch: the input record misses a required closed field " + reqFieldName + ":" + reqFieldType + "! Please check the field name and type.");
}
}
}
List<Mutable<ILogicalExpression>> arguments = func.getArguments();
List<Mutable<ILogicalExpression>> originalArguments = new ArrayList<Mutable<ILogicalExpression>>();
originalArguments.addAll(arguments);
arguments.clear();
// re-order the closed part and fill in null fields
for (int i = 0; i < fieldPermutation.length; i++) {
int pos = fieldPermutation[i];
if (pos >= 0) {
arguments.add(originalArguments.get(2 * pos));
arguments.add(originalArguments.get(2 * pos + 1));
}
if (nullFields[i]) {
// add a null field
arguments.add(new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(new AString(reqFieldNames[i])))));
arguments.add(new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(ANull.NULL))));
}
}
// add the open part
for (int i = 0; i < openFields.length; i++) {
if (openFields[i]) {
arguments.add(originalArguments.get(2 * i));
Mutable<ILogicalExpression> expRef = originalArguments.get(2 * i + 1);
injectCastToRelaxType(expRef, inputFieldTypes[i], env);
arguments.add(expRef);
}
}
return true;
}
use of org.apache.commons.lang3.mutable.MutableObject in project asterixdb by apache.
the class SqlppExpressionToPlanTranslator method visit.
@Override
public Pair<ILogicalOperator, LogicalVariable> visit(Query q, Mutable<ILogicalOperator> tupSource) throws CompilationException {
Expression queryBody = q.getBody();
if (queryBody.getKind() == Kind.SELECT_EXPRESSION) {
SelectExpression selectExpr = (SelectExpression) queryBody;
if (q.isTopLevel()) {
selectExpr.setSubquery(false);
}
return queryBody.accept(this, tupSource);
} else {
LogicalVariable var = context.newVar();
Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(queryBody, tupSource);
AssignOperator assignOp = new AssignOperator(var, new MutableObject<ILogicalExpression>(eo.first));
assignOp.getInputs().add(eo.second);
ProjectOperator projectOp = new ProjectOperator(var);
projectOp.getInputs().add(new MutableObject<ILogicalOperator>(assignOp));
return new Pair<>(projectOp, var);
}
}
use of org.apache.commons.lang3.mutable.MutableObject in project asterixdb by apache.
the class SqlppExpressionToPlanTranslator method visit.
@Override
public Pair<ILogicalOperator, LogicalVariable> visit(FromTerm fromTerm, Mutable<ILogicalOperator> tupSource) throws CompilationException {
LogicalVariable fromVar = context.newVarFromExpression(fromTerm.getLeftVariable());
Expression fromExpr = fromTerm.getLeftExpression();
Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(fromExpr, tupSource);
ILogicalOperator unnestOp;
if (fromTerm.hasPositionalVariable()) {
LogicalVariable pVar = context.newVarFromExpression(fromTerm.getPositionalVariable());
// We set the positional variable type as BIGINT type.
unnestOp = new UnnestOperator(fromVar, new MutableObject<ILogicalExpression>(makeUnnestExpression(eo.first)), pVar, BuiltinType.AINT64, new PositionWriter());
} else {
unnestOp = new UnnestOperator(fromVar, new MutableObject<ILogicalExpression>(makeUnnestExpression(eo.first)));
}
unnestOp.getInputs().add(eo.second);
// Processes joins, unnests, and nests.
Mutable<ILogicalOperator> topOpRef = new MutableObject<>(unnestOp);
if (fromTerm.hasCorrelateClauses()) {
for (AbstractBinaryCorrelateClause correlateClause : fromTerm.getCorrelateClauses()) {
if (correlateClause.getClauseType() == ClauseType.UNNEST_CLAUSE) {
// Correlation is allowed.
topOpRef = new MutableObject<>(correlateClause.accept(this, topOpRef).first);
} else {
// Correlation is dis-allowed.
uncorrelatedLeftBranchStack.push(topOpRef);
topOpRef = new MutableObject<>(correlateClause.accept(this, tupSource).first);
}
}
}
return new Pair<>(topOpRef.getValue(), fromVar);
}
Aggregations