use of org.apache.derby.iapi.types.TypeId in project derby by apache.
the class MethodCallNode method getPrimitiveSignature.
String[] getPrimitiveSignature(boolean castToPrimitiveAsNecessary) throws StandardException {
int count = signature.length;
String[] primParmTypeNames = new String[count];
JSQLType jsqlTyp;
for (int i = 0; i < count; i++) {
jsqlTyp = signature[i];
if (jsqlTyp == null) {
primParmTypeNames[i] = "";
} else {
switch(jsqlTyp.getCategory()) {
case JSQLType.SQLTYPE:
if ((procedurePrimitiveArrayType != null) && (i < procedurePrimitiveArrayType.length) && (procedurePrimitiveArrayType[i] != null)) {
primParmTypeNames[i] = procedurePrimitiveArrayType[i];
} else {
TypeId ctid = mapToTypeID(jsqlTyp);
if ((ctid.isNumericTypeId() && !ctid.isDecimalTypeId()) || ctid.isBooleanTypeId()) {
TypeCompiler tc = getTypeCompiler(ctid);
primParmTypeNames[i] = tc.getCorrespondingPrimitiveTypeName();
if (castToPrimitiveAsNecessary) {
methodParms[i].castToPrimitive(true);
}
} else {
primParmTypeNames[i] = ctid.getCorrespondingJavaTypeName();
}
}
break;
case JSQLType.JAVA_CLASS:
primParmTypeNames[i] = jsqlTyp.getJavaClassName();
break;
case JSQLType.JAVA_PRIMITIVE:
primParmTypeNames[i] = JSQLType.getPrimitiveName(jsqlTyp.getPrimitiveKind());
if (castToPrimitiveAsNecessary) {
methodParms[i].castToPrimitive(true);
}
break;
default:
if (SanityManager.DEBUG) {
SanityManager.THROWASSERT("Unknown JSQLType: " + jsqlTyp);
}
}
// end switch
}
// end if
}
return primParmTypeNames;
}
use of org.apache.derby.iapi.types.TypeId in project derby by apache.
the class JavaToSQLValueNode method generateExpression.
/**
* Do code generation for this conversion of a value from the Java to
* the SQL domain.
*
* @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 {
TypeId resultType;
String resultTypeName;
/*
** Tell the Java node that it's value is being returned to the
** SQL domain. This way, it knows whether the checking for a null
** receiver is to be done at the Java level or the SQL level.
*/
javaNode.returnValueToSQLDomain();
/* Generate the receiver, if any. */
boolean hasReceiver = javaNode.generateReceiver(acb, mb);
/*
** If the java expression has a receiver, we want to check whether
** it's null before evaluating the whole expression (to avoid
** a NullPointerException.
*/
if (hasReceiver) {
/*
** There is a receiver. Generate a null SQL value to return
** in case the receiver is null. First, create a field to hold
** the null SQL value.
*/
String nullValueClass = getTypeCompiler().interfaceName();
LocalField nullValueField = acb.newFieldDeclaration(Modifier.PRIVATE, nullValueClass);
/*
** There is a receiver. Generate the following to test
** for null:
**
** (receiverExpression == null) ?
*/
mb.conditionalIfNull();
mb.getField(nullValueField);
acb.generateNullWithExpress(mb, getTypeCompiler(), getTypeServices().getCollationType());
/*
** We have now generated the expression to test, and the
** "true" side of the ?: operator. Finish the "true" side
** so we can generate the "false" side.
*/
mb.startElseCode();
}
resultType = getTypeId();
TypeCompiler tc = getTypeCompiler();
resultTypeName = tc.interfaceName();
/* Allocate an object for re-use to hold the result of the conversion */
LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, resultTypeName);
/* Generate the expression for the Java value under us */
javaNode.generateExpression(acb, mb);
/* Generate the SQL value, which is always nullable */
acb.generateDataValue(mb, tc, getTypeServices().getCollationType(), field);
/*
** If there was a receiver, the return value will be the result
** of the ?: operator.
*/
if (hasReceiver) {
mb.completeConditional();
}
}
use of org.apache.derby.iapi.types.TypeId in project derby by apache.
the class DataDictionaryImpl method genColumnReferenceSQL.
/*
** Make sure the given column name is found in the trigger
** target table. Generate the appropriate SQL to get it.
**
** @return a string that is used to get the column using
** getObject() on the desired result set and CAST it back
** to the proper type in the SQL domain.
**
** @exception StandardException on invalid column name
*/
private String genColumnReferenceSQL(TableDescriptor td, String colName, String tabName, boolean isOldTable, int colPositionInRuntimeResultSet) throws StandardException {
ColumnDescriptor colDesc = null;
if ((colDesc = td.getColumnDescriptor(colName)) == null) {
throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND, tabName + "." + colName);
}
/*
** Generate something like this:
**
** CAST (org.apache.derby.iapi.db.Factory::
** getTriggerExecutionContext().getNewRow().
** getObject(<colPosition>) AS DECIMAL(6,2))
**
** Column position is used to avoid the wrong column being
** selected problem (DERBY-1258) caused by the case insensitive
** JDBC rules for fetching a column by name.
**
** The cast back to the SQL Domain may seem redundant
** but we need it to make the column reference appear
** EXACTLY like a regular column reference, so we need
** the object in the SQL Domain and we need to have the
** type information. Thus a user should be able to do
** something like
**
** CREATE TRIGGER ... INSERT INTO T length(Column), ...
**
*/
DataTypeDescriptor dts = colDesc.getType();
TypeId typeId = dts.getTypeId();
if (!typeId.isXMLTypeId()) {
StringBuffer methodCall = new StringBuffer();
methodCall.append("CAST (org.apache.derby.iapi.db.Factory::getTriggerExecutionContext().");
methodCall.append(isOldTable ? "getOldRow()" : "getNewRow()");
methodCall.append(".getObject(");
methodCall.append(colPositionInRuntimeResultSet);
methodCall.append(") AS ");
/*
** getSQLString() returns <typeName>
** for user types, so call getSQLTypeName in that
** case.
*/
methodCall.append((typeId.userType() ? typeId.getSQLTypeName() : dts.getSQLstring()));
methodCall.append(") ");
return methodCall.toString();
} else {
/* DERBY-2350
**
** Triggers currently use jdbc 1.2 to access columns. The default
** uses getObject() which is not supported for an XML type until
** jdbc 4. In the meantime use getString() and then call
** XMLPARSE() on the string to get the type. See Derby issue and
** http://wiki.apache.org/db-derby/TriggerImplementation , for
** better long term solutions. Long term I think changing the
** trigger architecture to not rely on jdbc, but instead on an
** internal direct access interface to execution nodes would be
** best future direction, but believe such a change appropriate
** for a major release, not a bug fix.
**
** Rather than the above described code generation, use the
** following for XML types to generate an XML column from the
** old or new row.
**
** XMLPARSE(DOCUMENT
** CAST (org.apache.derby.iapi.db.Factory::
** getTriggerExecutionContext().getNewRow().
** getString(<colPosition>) AS CLOB)
** PRESERVE WHITESPACE)
*/
StringBuffer methodCall = new StringBuffer();
methodCall.append("XMLPARSE(DOCUMENT CAST( ");
methodCall.append("org.apache.derby.iapi.db.Factory::getTriggerExecutionContext().");
methodCall.append(isOldTable ? "getOldRow()" : "getNewRow()");
methodCall.append(".getString(");
methodCall.append(colPositionInRuntimeResultSet);
methodCall.append(") AS CLOB) PRESERVE WHITESPACE ) ");
return methodCall.toString();
}
}
Aggregations