Search in sources :

Example 16 with DataTypeDescriptor

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;
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Example 17 with DataTypeDescriptor

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());
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) ResultColumnDescriptor(org.apache.derby.iapi.sql.ResultColumnDescriptor) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)

Example 18 with DataTypeDescriptor

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;
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) ResultColumnDescriptor(org.apache.derby.iapi.sql.ResultColumnDescriptor) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) DefaultDescriptor(org.apache.derby.iapi.sql.dictionary.DefaultDescriptor) DefaultInfoImpl(org.apache.derby.catalog.types.DefaultInfoImpl)

Example 19 with DataTypeDescriptor

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);
                }
            }
        }
    }
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Example 20 with DataTypeDescriptor

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();
        }
    }
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor)

Aggregations

DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)99 TypeId (org.apache.derby.iapi.types.TypeId)32 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)14 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)14 CompilerContext (org.apache.derby.iapi.sql.compile.CompilerContext)9 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)8 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)8 TypeDescriptor (org.apache.derby.catalog.TypeDescriptor)7 UUID (org.apache.derby.catalog.UUID)5 ClassFactory (org.apache.derby.iapi.services.loader.ClassFactory)5 ResultColumnDescriptor (org.apache.derby.iapi.sql.ResultColumnDescriptor)5 TypeCompiler (org.apache.derby.iapi.sql.compile.TypeCompiler)5 StandardException (org.apache.derby.shared.common.error.StandardException)5 Properties (java.util.Properties)4 UserDefinedTypeIdImpl (org.apache.derby.catalog.types.UserDefinedTypeIdImpl)4 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)4 AliasDescriptor (org.apache.derby.iapi.sql.dictionary.AliasDescriptor)3 ColumnDescriptorList (org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList)3 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)3 ExecIndexRow (org.apache.derby.iapi.sql.execute.ExecIndexRow)3