use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class ResultColumnList method hasConsistentTypeInfo.
/* Debugging methods */
/**
* Verify that all ResultColumns and their expressions have type information
* and that the type information between the respective RCs and
* expressions matches.
*
* @return boolean Whether or not the type information is consistent
*/
boolean hasConsistentTypeInfo() throws StandardException {
boolean isConsistent = true;
if (SanityManager.DEBUG) {
for (ResultColumn rc : this) {
ValueNode expr = rc.getExpression();
DataTypeDescriptor rcDTS = rc.getTypeServices();
DataTypeDescriptor exDTS = expr.getTypeServices();
if (rcDTS == null || exDTS == null) {
isConsistent = false;
break;
}
if (rcDTS.getClass().getName() != exDTS.getClass().getName()) {
isConsistent = false;
break;
}
}
}
return isConsistent;
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class ResultSetNode method generateProjectRestrictForInsert.
/**
* Generate a ProjectRestrictNode to put on top of this node if it's the
* source for an insert, and the RCL needs reordering and/or addition of
* columns in order to match the target RCL.
*
* @param target the target node for the insert
* @param colMap int array representation of correspondence between
* RCLs - colmap[i] = -1 -> missing in current RCL
* colmap[i] = j -> targetRCL(i) <-> thisRCL(j+1)
* @return a ProjectRestrictNode whos RCL matches the target RCL
*/
private ResultSetNode generateProjectRestrictForInsert(InsertNode target, int[] colMap) throws StandardException {
// our newResultCols are put into the bound form straight away.
ResultColumnList newResultCols = new ResultColumnList(getContextManager());
int numTargetColumns = target.resultColumnList.size();
/* Create a massaged version of the source RCL.
* (Much simpler to build new list and then assign to source,
* rather than massage the source list in place.)
*/
for (int index = 0; index < numTargetColumns; index++) {
ResultColumn newResultColumn;
ResultColumn oldResultColumn;
ColumnReference newColumnReference;
if (colMap[index] != -1) {
// getResultColumn uses 1-based positioning, so offset the
// colMap entry appropriately
oldResultColumn = resultColumns.getResultColumn(colMap[index] + 1);
newColumnReference = new ColumnReference(oldResultColumn.getName(), null, getContextManager());
DataTypeDescriptor dtd = oldResultColumn.getType();
if (dtd == null) {
ColumnDescriptor cd = target.targetTableDescriptor.getColumnDescriptor(index + 1);
dtd = cd.getType();
}
/* The ColumnReference points to the source of the value */
newColumnReference.setSource(oldResultColumn);
// colMap entry is 0-based, columnId is 1-based.
newColumnReference.setType(dtd);
// Source of an insert, so nesting levels must be 0
newColumnReference.setNestingLevel(0);
newColumnReference.setSourceLevel(0);
// because the insert already copied the target table's
// column descriptors into the result, we grab it from there.
// alternatively, we could do what the else clause does,
// and look it up in the DD again.
newResultColumn = new ResultColumn(dtd, newColumnReference, getContextManager());
} else {
newResultColumn = genNewRCForInsert(target.targetTableDescriptor, target.targetVTI, index + 1, target.getDataDictionary());
}
newResultCols.addResultColumn(newResultColumn);
}
/* The generated ProjectRestrictNode now has the ResultColumnList
* in the order that the InsertNode expects.
* NOTE: This code here is an exception to several "rules":
* o This is the only ProjectRestrictNode that is currently
* generated outside of preprocess().
* o The UnionNode is the only node which is not at the
* top of the query tree which has ColumnReferences under
* its ResultColumnList prior to expression push down.
*/
return new ProjectRestrictNode(this, newResultCols, null, null, null, null, null, getContextManager());
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class ResultSetNode method genNewRCForInsert.
/**
* Generate the RC/expression for an unspecified column in an insert.
* Use the default if one exists.
*
* @param targetTD Target TableDescriptor if the target is not a VTI, null if a VTI.
* @param targetVTI Target description if it is a VTI, null if not a VTI
* @param columnNumber The column number
* @param dataDictionary The DataDictionary
* @return The RC/expression for the unspecified column.
*
* @exception StandardException Thrown on error
*/
private ResultColumn genNewRCForInsert(TableDescriptor targetTD, FromVTI targetVTI, int columnNumber, DataDictionary dataDictionary) throws StandardException {
ResultColumn newResultColumn;
if (targetVTI != null) {
newResultColumn = targetVTI.getResultColumns().getResultColumn(columnNumber);
newResultColumn = newResultColumn.cloneMe();
newResultColumn.setExpressionToNullNode();
} else {
// column position is 1-based, index is 0-based.
ColumnDescriptor colDesc = targetTD.getColumnDescriptor(columnNumber);
DataTypeDescriptor colType = colDesc.getType();
// Check for defaults
DefaultInfoImpl defaultInfo = (DefaultInfoImpl) colDesc.getDefaultInfo();
// if it have defaultInfo and not be autoincrement.
if (defaultInfo != null && !colDesc.isAutoincrement()) {
// RESOLVEPARAMETER - skip the tree if we have the value
/*
if (defaultInfo.getDefaultValue() != null)
{
}
else
*/
{
if (colDesc.hasGenerationClause()) {
// later on we will revisit the generated columns and bind
// their generation clauses
newResultColumn = createGeneratedColumn(targetTD, colDesc);
} else {
// Generate the tree for the default
String defaultText = defaultInfo.getDefaultText();
ValueNode defaultTree = parseDefault(defaultText);
defaultTree = defaultTree.bindExpression(getFromList(), (SubqueryList) null, (List<AggregateNode>) null);
newResultColumn = new ResultColumn(defaultTree.getTypeServices(), defaultTree, getContextManager());
}
DefaultDescriptor defaultDescriptor = colDesc.getDefaultDescriptor(dataDictionary);
if (SanityManager.DEBUG) {
SanityManager.ASSERT(defaultDescriptor != null, "defaultDescriptor expected to be non-null");
}
getCompilerContext().createDependency(defaultDescriptor);
}
} else if (colDesc.isAutoincrement()) {
newResultColumn = new ResultColumn(colDesc, null, getContextManager());
newResultColumn.setAutoincrementGenerated();
} else {
newResultColumn = new ResultColumn(colType, getNullNode(colType), getContextManager());
}
}
// Mark the new RC as generated for an unmatched column in an insert
newResultColumn.markGeneratedForUnmatchedColumnInInsert();
return newResultColumn;
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class RowResultSetNode method setTableConstructorTypes.
/**
* Set the type of each parameter in the result column list for this table constructor.
*
* @param typeColumns The ResultColumnList containing the desired result
* types.
*
* @exception StandardException Thrown on error
*/
@Override
void setTableConstructorTypes(ResultColumnList typeColumns) throws StandardException {
if (SanityManager.DEBUG)
SanityManager.ASSERT(getResultColumns().visibleSize() <= typeColumns.size(), "More columns in ResultColumnList than in base table");
/* Look for ? parameters in the result column list */
int rclSize = getResultColumns().size();
for (int index = 0; index < rclSize; index++) {
ResultColumn rc = getResultColumns().elementAt(index);
ValueNode re = rc.getExpression();
if (re.requiresTypeFromContext()) {
ResultColumn typeCol = typeColumns.elementAt(index);
/*
** We found a ? - set its type to the type of the
** corresponding column of the target table.
*/
re.setType(typeCol.getTypeServices());
} else if (re instanceof CharConstantNode) {
// Character constants are of type CHAR (fixed length string).
// This causes a problem (beetle 5160) when multiple row values are provided
// as constants for insertion into a variable length string column.
//
// This issue is the query expression
// VALUES 'abc', 'defghi'
// has type of CHAR(6), ie. the length of largest row value for that column.
// This is from the UNION defined behaviour.
// This causes strings with less than the maximum length to be blank padded
// to that length (CHAR semantics). Thus if this VALUES clause is used to
// insert into a variable length string column, then these blank padded values
// are inserted, which is not what is required ...
//
// BECAUSE, when the VALUES is used as a table constructor SQL standard says the
// types of the table constructor's columns are set by the table's column types.
// Thus, in this case, each of those string constants should be of type VARCHAR
// (or the matching string type for the table).
//
//
// This is only an issue for fixed length character (CHAR, BIT) string or
// binary consraints being inserted into variable length types.
// This is because any other type's fundemental literal value is not affected
// by its data type. E.g. Numeric types such as INT, REAL, BIGINT, DECIMAL etc.
// do not have their value modifed by the union since even if the type is promoted
// to a higher type, its fundemental value remains unchanged.
// values (1.2, 34.4567, 234.47) will be promoted to
// values (1.2000, 34.4567, 234.4700)
// but their numeric value remains the same.
//
//
//
// The fix is to change the base type of the table constructor's value to
// match the column type. Its length can be left as-is, because there is
// still a normailzation step when the value is inserted into the table.
// That will set the correct length and perform truncation checks etc.
ResultColumn typeCol = typeColumns.elementAt(index);
TypeId colTypeId = typeCol.getTypeId();
if (colTypeId.isStringTypeId()) {
if (colTypeId.getJDBCTypeId() != java.sql.Types.CHAR) {
int maxWidth = re.getTypeServices().getMaximumWidth();
re.setType(new DataTypeDescriptor(colTypeId, true, maxWidth));
}
} else if (colTypeId.isBitTypeId()) {
if (colTypeId.getJDBCTypeId() == java.sql.Types.VARBINARY) {
// then we're trying to cast a char literal into a
// variable bit column. We can't change the base
// type of the table constructor's value from char
// to bit, so instead, we just change the base type
// of that value from char to varchar--that way,
// no padding will be added when we convert to
// bits later on (Beetle 5306).
TypeId tId = TypeId.getBuiltInTypeId(java.sql.Types.VARCHAR);
re.setType(new DataTypeDescriptor(tId, true));
typeColumns.setElementAt(typeCol, index);
} else if (colTypeId.getJDBCTypeId() == java.sql.Types.LONGVARBINARY) {
TypeId tId = TypeId.getBuiltInTypeId(java.sql.Types.LONGVARCHAR);
re.setType(new DataTypeDescriptor(tId, true));
typeColumns.setElementAt(typeCol, index);
}
}
} else if (re instanceof BitConstantNode) {
ResultColumn typeCol = typeColumns.elementAt(index);
TypeId colTypeId = typeCol.getTypeId();
if (colTypeId.isBitTypeId()) {
// columns (they have to be explicitly casted first); beetle 5266.
if ((colTypeId.getJDBCTypeId() != java.sql.Types.BINARY) && (colTypeId.getJDBCTypeId() != java.sql.Types.BLOB)) {
int maxWidth = re.getTypeServices().getMaximumWidth();
re.setType(new DataTypeDescriptor(colTypeId, true, maxWidth));
}
} else if (colTypeId.isStringTypeId()) {
if (colTypeId.getJDBCTypeId() == java.sql.Types.VARCHAR) {
// then we're trying to cast a bit literal into a
// variable char column. We can't change the base
// type of the table constructor's value from bit
// to char, so instead, we just change the base
// type of that value from bit to varbit--that way,
// no padding will be added when we convert to
// char later on.
TypeId tId = TypeId.getBuiltInTypeId(java.sql.Types.VARBINARY);
re.setType(new DataTypeDescriptor(tId, true));
typeColumns.setElementAt(typeCol, index);
} else if (colTypeId.getJDBCTypeId() == java.sql.Types.LONGVARCHAR) {
TypeId tId = TypeId.getBuiltInTypeId(java.sql.Types.LONGVARBINARY);
re.setType(new DataTypeDescriptor(tId, true));
typeColumns.setElementAt(typeCol, index);
}
}
}
}
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class MethodCallNode method setNullParameterInfo.
/**
* Set the appropriate type information for a null passed as a parameter.
* This method is called after method resolution, when a signature was
* successfully matched.
*
* @param parmTypeNames String[] with the java type names for the parameters
* as declared by the method
*
* @exception StandardException Thrown on error
*/
void setNullParameterInfo(String[] parmTypeNames) throws StandardException {
for (int i = 0; i < methodParms.length; i++) {
/* null parameters are represented by a java type name of "" */
if (methodParms[i].getJavaTypeName().equals("")) {
/* Set the type information in the null constant node */
DataTypeDescriptor dts = DataTypeDescriptor.getSQLDataTypeDescriptor(parmTypeNames[i]);
((SQLToJavaValueNode) methodParms[i]).value.setType(dts);
/* Set the correct java type name */
methodParms[i].setJavaTypeName(parmTypeNames[i]);
signature[i] = methodParms[i].getJSQLType();
}
}
}
Aggregations