Search in sources :

Example 36 with MethodBuilder

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

the class CoalesceFunctionNode method generateExpression.

/**
 * Do code generation for coalesce/value
 *
 * @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 {
    int argumentsListSize = argumentsList.size();
    String receiverType = ClassName.DataValueDescriptor;
    String argumentsListInterfaceType = ClassName.DataValueDescriptor + "[]";
    // Generate the code to build the array
    LocalField arrayField = acb.newFieldDeclaration(Modifier.PRIVATE, argumentsListInterfaceType);
    /* The array gets created in the constructor.
		 * All constant elements in the array are initialized
		 * in the constructor.  
		 */
    /* Assign the initializer to the DataValueDescriptor[] field */
    MethodBuilder cb = acb.getConstructor();
    cb.pushNewArray(ClassName.DataValueDescriptor, argumentsListSize);
    cb.setField(arrayField);
    /* Set the array elements that are constant */
    int numConstants = 0;
    MethodBuilder nonConstantMethod = null;
    MethodBuilder currentConstMethod = cb;
    for (int index = 0; index < argumentsListSize; index++) {
        MethodBuilder setArrayMethod;
        if (argumentsList.elementAt(index) instanceof ConstantNode) {
            numConstants++;
            /*if too many statements are added  to a  method, 
				*size of method can hit  65k limit, which will
				*lead to the class format errors at load time.
				*To avoid this problem, when number of statements added 
				*to a method is > 2048, remaing statements are added to  a new function
				*and called from the function which created the function.
				*See Beetle 5135 or 4293 for further details on this type of problem.
				*/
            if (currentConstMethod.statementNumHitLimit(1)) {
                MethodBuilder genConstantMethod = acb.newGeneratedFun("void", Modifier.PRIVATE);
                currentConstMethod.pushThis();
                currentConstMethod.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, genConstantMethod.getName(), "void", 0);
                // if it is a generate function, close the metod.
                if (currentConstMethod != cb) {
                    currentConstMethod.methodReturn();
                    currentConstMethod.complete();
                }
                currentConstMethod = genConstantMethod;
            }
            setArrayMethod = currentConstMethod;
        } else {
            if (nonConstantMethod == null)
                nonConstantMethod = acb.newGeneratedFun("void", Modifier.PROTECTED);
            setArrayMethod = nonConstantMethod;
        }
        setArrayMethod.getField(arrayField);
        argumentsList.elementAt(index).generateExpression(acb, setArrayMethod);
        setArrayMethod.upCast(receiverType);
        setArrayMethod.setArrayElement(index);
    }
    // if a generated function was created to reduce the size of the methods close the functions.
    if (currentConstMethod != cb) {
        currentConstMethod.methodReturn();
        currentConstMethod.complete();
    }
    if (nonConstantMethod != null) {
        nonConstantMethod.methodReturn();
        nonConstantMethod.complete();
        mb.pushThis();
        mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, nonConstantMethod.getName(), "void", 0);
    }
    /*
		**  Call the method for coalesce/value function.
		**	First generate following
		**	<first non-param argument in the list>.method(<all the arguments>, <resultType>)
		**	Next, if we are dealing with result type that is variable length, then generate a call to setWidth.
		*/
    // coalesce will be called on this non-parameter argument
    argumentsList.elementAt(firstNonParameterNodeIdx).generateExpression(acb, mb);
    mb.upCast(ClassName.DataValueDescriptor);
    // first arg to the coalesce function
    mb.getField(arrayField);
    // Following is for the second arg. This arg will be used to pass the return value.
    // COALESCE method expects this to be initialized to NULL SQLxxx type object.
    LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, receiverType);
    acb.generateNull(mb, getTypeCompiler(), getTypeServices().getCollationType());
    mb.upCast(ClassName.DataValueDescriptor);
    mb.putField(field);
    mb.callMethod(VMOpcode.INVOKEINTERFACE, receiverType, "coalesce", receiverType, 2);
    if (// since result type is variable length, generate setWidth code.
    getTypeId().variableLength()) {
        boolean isNumber = getTypeId().isNumericTypeId();
        // to leave the DataValueDescriptor value on the stack, since setWidth is void
        mb.dup();
        mb.push(isNumber ? getTypeServices().getPrecision() : getTypeServices().getMaximumWidth());
        mb.push(getTypeServices().getScale());
        mb.push(true);
        mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.VariableSizeDataValue, "setWidth", "void", 3);
    }
}
Also used : LocalField(org.apache.derby.iapi.services.compiler.LocalField) MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder)

Example 37 with MethodBuilder

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

the class BinaryRelationalOperatorNode method generateQualMethod.

/**
 * @exception StandardException		Thrown on error
 */
public void generateQualMethod(ExpressionClassBuilderInterface acbi, MethodBuilder mb, Optimizable optTable) throws StandardException {
    ExpressionClassBuilder acb = (ExpressionClassBuilder) acbi;
    /* Generate a method that returns the expression */
    MethodBuilder qualMethod = acb.newUserExprFun();
    /*
		** Generate the expression that's on the opposite side
		** of the key column
		*/
    if (keyColumnOnLeft(optTable)) {
        rightOperand.generateExpression(acb, qualMethod);
    } else {
        leftOperand.generateExpression(acb, qualMethod);
    }
    qualMethod.methodReturn();
    qualMethod.complete();
    /* push an expression that evaluates to the GeneratedMethod */
    acb.pushMethodReference(mb, qualMethod);
}
Also used : MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder)

Example 38 with MethodBuilder

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

the class DMLModStatementNode method generateCheckConstraints.

/**
 *	Generate the code to evaluate a tree of CHECK CONSTRAINTS.
 *
 *	@param	checkConstraints	Bound query tree of ANDed check constraints.
 *	@param	ecb					Expression Class Builder
 *
 * @exception StandardException		Thrown on error
 */
public void generateCheckConstraints(ValueNode checkConstraints, ExpressionClassBuilder ecb, MethodBuilder mb) throws StandardException {
    // if there is no check constraint, we just want to pass null.
    if (checkConstraints == null) {
        mb.pushNull(ClassName.GeneratedMethod);
    } else {
        MethodBuilder userExprFun = generateCheckConstraints(checkConstraints, ecb);
        // check constraint is used in the final result set
        // as an access of the new static
        // field holding a reference to this new method.
        ecb.pushMethodReference(mb, userExprFun);
    }
}
Also used : MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder)

Example 39 with MethodBuilder

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

the class DMLModStatementNode method generateCheckConstraints.

/**
 *	Generate a method to evaluate a tree of CHECK CONSTRAINTS.
 *
 *	@param	checkConstraints	Bound query tree of ANDed check constraints.
 *	@param	ecb					Expression Class Builder
 *
 * @exception StandardException		Thrown on error
 */
public MethodBuilder generateCheckConstraints(ValueNode checkConstraints, ExpressionClassBuilder ecb) throws StandardException {
    // this sets up the method and the static field.
    // generates:
    // java.lang.Object userExprFun { }
    MethodBuilder userExprFun = ecb.newUserExprFun();
    // check constraint knows it is returning its value;
    /* generates:
		 *    return <checkExpress.generate(ecb)>;
		 * and adds it to userExprFun
		 */
    checkConstraints.generateExpression(ecb, userExprFun);
    userExprFun.methodReturn();
    // we are done modifying userExprFun, complete it.
    userExprFun.complete();
    return userExprFun;
}
Also used : MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder)

Example 40 with MethodBuilder

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

the class DMLModStatementNode method generateGenerationClauses.

/**
 *	Generate a method to compute all of the generation clauses in a row.
 *
 * @param rcl  describes the row of expressions to be put into the bas table
 * @param rsNumber  index of base table into array of ResultSets
 * @param isUpdate true if this is for an UPDATE statement
 * @param ecb code generation state variable
 */
private MethodBuilder generateGenerationClauses(ResultColumnList rcl, int rsNumber, boolean isUpdate, ExpressionClassBuilder ecb) throws StandardException {
    // this sets up the method and the static field.
    // generates:
    // java.lang.Object userExprFun( ) { }
    MethodBuilder userExprFun = ecb.newUserExprFun();
    /* Push the the current row onto the stack. */
    userExprFun.pushThis();
    userExprFun.push(rsNumber);
    userExprFun.callMethod(VMOpcode.INVOKEVIRTUAL, ClassName.BaseActivation, "getCurrentRow", ClassName.Row, 1);
    // Loop through the result columns, computing generated columns
    // as we go.
    int size = rcl.size();
    int startColumn = 0;
    // the before-images of the columns.
    if (isUpdate) {
        // throw away the last cell in the row, which is the row id
        startColumn = size - 1;
        startColumn = startColumn / 2;
    }
    for (int i = startColumn; i < size; i++) {
        ResultColumn rc = rcl.elementAt(i);
        if (!rc.hasGenerationClause()) {
            continue;
        }
        // instance (current row)
        userExprFun.dup();
        // arg1
        userExprFun.push(i + 1);
        // actually optimized so column references still need result set numbers
        if (inMatchingClause()) {
            CollectNodesVisitor<ColumnReference> getCRs = new CollectNodesVisitor<ColumnReference>(ColumnReference.class);
            rc.accept(getCRs);
            for (ColumnReference cr : getCRs.getList()) {
                cr.getSource().setResultSetNumber(rsNumber);
            }
        }
        rc.generateExpression(ecb, userExprFun);
        userExprFun.cast(ClassName.DataValueDescriptor);
        userExprFun.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Row, "setColumn", "void", 2);
    }
    /* generates:
		 *    return;
		 * And adds it to userExprFun
		 */
    userExprFun.methodReturn();
    // we are done modifying userExprFun, complete it.
    userExprFun.complete();
    return userExprFun;
}
Also used : MethodBuilder(org.apache.derby.iapi.services.compiler.MethodBuilder)

Aggregations

MethodBuilder (org.apache.derby.iapi.services.compiler.MethodBuilder)48 LocalField (org.apache.derby.iapi.services.compiler.LocalField)18 ReferencedColumnsDescriptorImpl (org.apache.derby.catalog.types.ReferencedColumnsDescriptorImpl)3 OptimizablePredicate (org.apache.derby.iapi.sql.compile.OptimizablePredicate)3 Method (java.lang.reflect.Method)1 ArrayList (java.util.ArrayList)1 FormatableArrayHolder (org.apache.derby.iapi.services.io.FormatableArrayHolder)1 FormatableIntHolder (org.apache.derby.iapi.services.io.FormatableIntHolder)1 GeneratedClass (org.apache.derby.iapi.services.loader.GeneratedClass)1 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)1 CostEstimate (org.apache.derby.iapi.sql.compile.CostEstimate)1 StaticCompiledOpenConglomInfo (org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo)1 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)1 SqlXmlUtil (org.apache.derby.iapi.types.SqlXmlUtil)1 StandardException (org.apache.derby.shared.common.error.StandardException)1