Search in sources :

Example 6 with LocalField

use of org.apache.derby.iapi.services.compiler.LocalField in project derby by apache.

the class NotNode method generateExpression.

/**
 * Do code generation for the NOT operator.
 *
 * @param acb	The ExpressionClassBuilder for the class we're generating
 * @param mb	The method the expression will go into
 *
 * @exception StandardException		Thrown on error
 */
@Override
void generateExpression(ExpressionClassBuilder acb, MethodBuilder mb) throws StandardException {
    /*
		** This generates the following code:
		**
		** <boolean field> = <operand>.equals(<operand>,
		**					 					<false truth value>);
		*/
    /*
		** Generate the code for a Boolean false constant value.
		*/
    String interfaceName = getTypeCompiler().interfaceName();
    LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, interfaceName);
    /*
		** Generate the call to the equals method.
		** equals is only on Orderable, not any subinterfaces.
		*/
    /* Generate the code for operand */
    operand.generateExpression(acb, mb);
    mb.upCast(ClassName.DataValueDescriptor);
    // arg 1 is instance
    mb.dup();
    // arg 2
    mb.push(false);
    acb.generateDataValue(mb, getTypeCompiler(), getTypeServices().getCollationType(), field);
    mb.upCast(ClassName.DataValueDescriptor);
    mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "equals", interfaceName, 2);
}
Also used : LocalField(org.apache.derby.iapi.services.compiler.LocalField)

Example 7 with LocalField

use of org.apache.derby.iapi.services.compiler.LocalField in project derby by apache.

the class ResultColumnList method generateEvaluatedRow.

/**
 * <p>
 * Generate the code for a method (userExprFun) which creates a row
 * and, column by column, stuffs it with the evaluated
 * expressions of our ResultColumns. The method returns the
 * stuffed row.
 * </p>
 *
 * This is the method that does the work.
 */
void generateEvaluatedRow(ExpressionClassBuilder acb, MethodBuilder userExprFun, boolean genNulls, boolean forMatchingClause) throws StandardException {
    // generate the function and initializer:
    // private ExecRow fieldX;
    // In the constructor:
    // fieldX = getExecutionFactory().getValueRow(# cols);
    // private ExecRow exprN()
    // {
    // fieldX.setColumn(1, col(1).generateColumn(ps)));
    // ... and so on for each column ...
    // return fieldX;
    // }
    // static Method exprN = method pointer to exprN;
    /* Declare the field */
    LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, ClassName.ExecRow);
    // Generate the code to create the row in the constructor
    genCreateRow(acb, field, "getValueRow", ClassName.ExecRow, size());
    ResultColumn rc;
    int size = size();
    MethodBuilder cb = acb.getConstructor();
    for (int index = 0; index < size; index++) {
        // generate statements of the form
        // fieldX.setColumn(columnNumber, (DataValueDescriptor) columnExpr);
        // and add them to exprFun.
        rc = elementAt(index);
        /* If we are not generating nulls, then we can skip this RC if
			 * it is simply propagating a column from the source result set.
			 */
        if (!genNulls) {
            ValueNode sourceExpr = rc.getExpression();
            if (sourceExpr instanceof VirtualColumnNode && !(((VirtualColumnNode) sourceExpr).getCorrelated())) {
                continue;
            }
            // then pick up that value
            if (rc.getJoinResultSet() != null) {
                // We are dealing with a join column for
                // RIGHT OUTER JOIN with USING/NATURAL eg
                // select c from t1 right join t2 using (c)
                // We are talking about column c as in "select c"
                ResultColumnList jnRCL = rc.getJoinResultSet().getResultColumns();
                int joinResultSetNumber = rc.getJoinResultSet().getResultSetNumber();
                // We need to know the column positions of left
                // table's join column and right table's join
                // column to generate the code explained above
                int virtualColumnIdRightTable = -1;
                int virtualColumnIdLeftTable = -1;
                for (ResultColumn joinColumn : jnRCL) {
                    if (joinColumn.getName().equals(rc.getUnderlyingOrAliasName())) {
                        if (joinColumn.isRightOuterJoinUsingClause())
                            virtualColumnIdRightTable = joinColumn.getVirtualColumnId();
                        else
                            virtualColumnIdLeftTable = joinColumn.getVirtualColumnId();
                    }
                }
                // instance
                userExprFun.getField(field);
                // arg1
                userExprFun.push(index + 1);
                String resultTypeName = getTypeCompiler(DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.BOOLEAN).getTypeId()).interfaceName();
                String receiverType = ClassName.DataValueDescriptor;
                // Our plan is to generate DERBY-4631
                // if(lefTablJoinColumnValue is null)
                // then
                // use rightTablJoinColumnValue
                // else
                // use lefTablJoinColumnValue
                // Following will generate
                // if(lefTablJoinColumnValue is null)
                acb.pushColumnReference(userExprFun, joinResultSetNumber, virtualColumnIdLeftTable);
                userExprFun.cast(rc.getTypeCompiler().interfaceName());
                userExprFun.cast(receiverType);
                userExprFun.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "isNullOp", resultTypeName, 0);
                // Then call generateExpression on left Table's column
                userExprFun.cast(ClassName.BooleanDataValue);
                userExprFun.push(true);
                userExprFun.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "equals", "boolean", 1);
                // Following will generate
                // then
                // use rightTablJoinColumnValue
                userExprFun.conditionalIf();
                acb.pushColumnReference(userExprFun, joinResultSetNumber, virtualColumnIdRightTable);
                userExprFun.cast(rc.getTypeCompiler().interfaceName());
                // Following will generate
                // else
                // use lefTablJoinColumnValue
                userExprFun.startElseCode();
                acb.pushColumnReference(userExprFun, joinResultSetNumber, virtualColumnIdLeftTable);
                userExprFun.cast(rc.getTypeCompiler().interfaceName());
                userExprFun.completeConditional();
                userExprFun.cast(ClassName.DataValueDescriptor);
                userExprFun.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Row, "setColumn", "void", 2);
                continue;
            }
            if (!forMatchingClause) {
                if (sourceExpr instanceof ColumnReference && !(((ColumnReference) sourceExpr).getCorrelated())) {
                    continue;
                }
            }
        }
        // row add is 1-based, and iterator index is 0-based
        if (SanityManager.DEBUG) {
            if (index + 1 != rc.getVirtualColumnId()) {
                SanityManager.THROWASSERT("VirtualColumnId (" + rc.getVirtualColumnId() + ") does not agree with position within Vector (" + (index + 1) + ")");
            }
        }
        // 
        if (rc.hasGenerationClause()) {
            ValueNode expr = rc.getExpression();
            if ((expr != null) && !(expr instanceof VirtualColumnNode)) {
                continue;
            }
        }
        /* SPECIAL CASE:  Expression is a non-null constant.
			 *	Generate the setColumn() call in the constructor
			 *  so that it will only be executed once per instantiation.
			 *
		 	 * Increase the statement counter in constructor.  Code size in
		 	 * constructor can become too big (more than 64K) for Java compiler
		 	 * to handle (beetle 4293).  We set constant columns in other
		 	 * methods if constructor has too many statements already.
		 	 */
        if ((!genNulls) && (rc.getExpression() instanceof ConstantNode) && !((ConstantNode) rc.getExpression()).isNull() && !cb.statementNumHitLimit(1)) {
            // instance
            cb.getField(field);
            // first arg;
            cb.push(index + 1);
            rc.generateExpression(acb, cb);
            // second arg
            cb.cast(ClassName.DataValueDescriptor);
            cb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Row, "setColumn", "void", 2);
            continue;
        }
        // instance
        userExprFun.getField(field);
        // arg1
        userExprFun.push(index + 1);
        /* We want to reuse the null values instead of doing a new each time
			 * if the caller said to generate nulls or the underlying expression
			 * is a typed null value.
			 */
        boolean needDVDCast = true;
        if (rc.isAutoincrementGenerated()) {
            // (com.ibm.db2j.impl... DataValueDescriptor)
            // this.getSetAutoincValue(column_number)
            userExprFun.pushThis();
            userExprFun.push(rc.getColumnPosition());
            userExprFun.push(rc.getTableColumnDescriptor().getAutoincInc());
            userExprFun.callMethod(VMOpcode.INVOKEVIRTUAL, ClassName.BaseActivation, "getSetAutoincrementValue", ClassName.DataValueDescriptor, 2);
            needDVDCast = false;
        } else if (genNulls || ((rc.getExpression() instanceof ConstantNode) && ((ConstantNode) rc.getExpression()).isNull())) {
            userExprFun.getField(field);
            userExprFun.push(index + 1);
            userExprFun.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Row, "getColumn", ClassName.DataValueDescriptor, // the express
            1);
            acb.generateNullWithExpress(userExprFun, rc.getTypeCompiler(), rc.getTypeServices().getCollationType());
        } else {
            rc.generateExpression(acb, userExprFun);
        }
        if (needDVDCast)
            userExprFun.cast(ClassName.DataValueDescriptor);
        userExprFun.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Row, "setColumn", "void", 2);
    }
    userExprFun.getField(field);
    userExprFun.methodReturn();
    // we are now done modifying userExprFun
    userExprFun.complete();
}
Also used : LocalField(org.apache.derby.iapi.services.compiler.LocalField) MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder)

Example 8 with LocalField

use of org.apache.derby.iapi.services.compiler.LocalField in project derby by apache.

the class MethodCallNode method generateVarargs.

/**
 * <p>
 * Generate the trailing routine arguments into a varargs array and
 * push that array onto the stack.
 * </p>
 */
private void generateVarargs(ExpressionClassBuilder acb, MethodBuilder mb) throws StandardException {
    // the vararg is the last declared arg of the Java method. it is always
    // an array type. right now we only support vararg static methods.
    // if we have to support vararg constructors in the future, then this code
    // will need adjustment.
    int firstVarargIdx = getFirstVarargIdx();
    String arrayType = methodParameterTypes[firstVarargIdx];
    String cellType = stripOneArrayLevel(arrayType);
    String varargType = cellType;
    // must strip another array level off of out and in/out parameters
    if (routineInfo != null) {
        if (routineInfo.getParameterModes()[firstVarargIdx] != (ParameterMetaData.parameterModeIn)) {
            varargType = stripOneArrayLevel(varargType);
        }
    }
    int varargCount = methodParms.length - firstVarargIdx;
    if (varargCount < 0) {
        varargCount = 0;
    }
    // allocate an array to hold the varargs
    LocalField arrayField = acb.newFieldDeclaration(Modifier.PRIVATE, arrayType);
    MethodBuilder cb = acb.getConstructor();
    cb.pushNewArray(cellType, varargCount);
    cb.setField(arrayField);
    // now put the arguments into the array
    for (int i = 0; i < varargCount; i++) {
        // push the array onto the stack
        mb.getField(arrayField);
        // evaluate the parameter and push it onto the stack
        generateAndCastOneParameter(acb, mb, i + firstVarargIdx, cellType);
        // move the parameter into the array, pop the stack
        mb.setArrayElement(i);
    }
    // push the array onto the stack. it is the last parameter to the varargs routine.
    mb.getField(arrayField);
}
Also used : LocalField(org.apache.derby.iapi.services.compiler.LocalField) MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder)

Example 9 with LocalField

use of org.apache.derby.iapi.services.compiler.LocalField in project derby by apache.

the class FromVTI method generateConstructor.

private void generateConstructor(ActivationClassBuilder acb, MethodBuilder mb, boolean reuseablePs) throws StandardException {
    String vtiType = version2 ? "java.sql.PreparedStatement" : "java.sql.ResultSet";
    // this sets up the method and the static field.
    // generates:
    // java.sql.ResultSet userExprFun { }
    MethodBuilder userExprFun = acb.newGeneratedFun(vtiType, Modifier.PUBLIC);
    userExprFun.addThrownException("java.lang.Exception");
    // If it's a re-useable PreparedStatement then hold onto it.
    LocalField psHolder = reuseablePs ? acb.newFieldDeclaration(Modifier.PRIVATE, "java.sql.PreparedStatement") : null;
    if (reuseablePs) {
        userExprFun.getField(psHolder);
        userExprFun.conditionalIfNull();
    }
    methodCall.generateExpression(acb, userExprFun);
    userExprFun.upCast(vtiType);
    if (reuseablePs) {
        userExprFun.putField(psHolder);
        userExprFun.startElseCode();
        userExprFun.getField(psHolder);
        userExprFun.completeConditional();
    }
    userExprFun.methodReturn();
    // methodCall knows it is returning its value;
    /* generates:
		 *    return <newInvocation.generate(acb)>;
		 */
    // we are done modifying userExprFun, complete it.
    userExprFun.complete();
    // constructor is used in the final result set as an access of the new static
    // field holding a reference to this new method.
    // generates:
    // ActivationClass.userExprFun
    // which is the static field that "points" to the userExprFun
    // that evaluates the where clause.
    acb.pushMethodReference(mb, userExprFun);
    // the activation is closed.
    if (reuseablePs) {
        MethodBuilder closeActivationMethod = acb.getCloseActivationMethod();
        closeActivationMethod.getField(psHolder);
        closeActivationMethod.conditionalIfNull();
        // do nothing
        // work around for no support for real if statements
        closeActivationMethod.push(0);
        closeActivationMethod.startElseCode();
        closeActivationMethod.getField(psHolder);
        closeActivationMethod.callMethod(VMOpcode.INVOKEINTERFACE, "java.sql.Statement", "close", "void", 0);
        closeActivationMethod.push(0);
        closeActivationMethod.completeConditional();
        closeActivationMethod.endStatement();
    }
}
Also used : MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder) LocalField(org.apache.derby.iapi.services.compiler.LocalField)

Example 10 with LocalField

use of org.apache.derby.iapi.services.compiler.LocalField in project derby by apache.

the class DB2LengthOperatorNode method generateExpression.

/**
 * Do code generation for this unary operator.
 *
 * @param acb	The ExpressionClassBuilder for the class we're generating
 * @param mb	The method the expression will go into
 *
 * @exception StandardException		Thrown on error
 */
@Override
void generateExpression(ExpressionClassBuilder acb, MethodBuilder mb) throws StandardException {
    if (operand == null)
        return;
    int constantLength = getConstantLength();
    // -1 if the length of a non-null operand depends on the data
    String resultTypeName = getTypeCompiler().interfaceName();
    mb.pushThis();
    operand.generateExpression(acb, mb);
    mb.upCast(ClassName.DataValueDescriptor);
    mb.push(constantLength);
    /* Allocate an object for re-use to hold the result of the operator */
    LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, resultTypeName);
    mb.getField(field);
    mb.callMethod(VMOpcode.INVOKEVIRTUAL, ClassName.BaseActivation, methodName, resultTypeName, 3);
    /*
        ** Store the result of the method call in the field, so we can re-use
        ** the object.
        */
    mb.putField(field);
}
Also used : LocalField(org.apache.derby.iapi.services.compiler.LocalField)

Aggregations

LocalField (org.apache.derby.iapi.services.compiler.LocalField)32 MethodBuilder (org.apache.derby.iapi.services.compiler.MethodBuilder)18 OptimizablePredicate (org.apache.derby.iapi.sql.compile.OptimizablePredicate)3 TypeCompiler (org.apache.derby.iapi.sql.compile.TypeCompiler)2 Method (java.lang.reflect.Method)1 ArrayList (java.util.ArrayList)1 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)1 CostEstimate (org.apache.derby.iapi.sql.compile.CostEstimate)1 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)1 SqlXmlUtil (org.apache.derby.iapi.types.SqlXmlUtil)1 TypeId (org.apache.derby.iapi.types.TypeId)1