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);
}
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();
}
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);
}
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();
}
}
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);
}
Aggregations