Search in sources :

Example 76 with ColumnDescriptor

use of org.apache.derby.iapi.sql.dictionary.ColumnDescriptor in project derby by apache.

the class DataDictionaryImpl method addSPSParams.

/**
 * Add a column in SYS.SYSCOLUMNS for each parameter in the
 * parameter list.
 */
private void addSPSParams(SPSDescriptor spsd, TransactionController tc) throws StandardException {
    UUID uuid = spsd.getUUID();
    DataTypeDescriptor[] params = spsd.getParams();
    Object[] parameterDefaults = spsd.getParameterDefaults();
    if (params == null)
        return;
    /* Create the columns */
    int pdlSize = params.length;
    for (int index = 0; index < pdlSize; index++) {
        int parameterId = index + 1;
        // RESOLVEAUTOINCREMENT
        ColumnDescriptor cd = new ColumnDescriptor("PARAM" + parameterId, // position
        parameterId, params[index], (// default
        (parameterDefaults == null) || (index >= parameterDefaults.length)) ? (DataValueDescriptor) null : (DataValueDescriptor) parameterDefaults[index], (DefaultInfo) null, uuid, (UUID) null, 0, 0, 0, false);
        addDescriptor(cd, null, SYSCOLUMNS_CATALOG_NUM, // no chance of duplicates here
        false, tc);
    }
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) UUID(org.apache.derby.catalog.UUID) SQLLongint(org.apache.derby.iapi.types.SQLLongint)

Example 77 with ColumnDescriptor

use of org.apache.derby.iapi.sql.dictionary.ColumnDescriptor in project derby by apache.

the class DataDictionaryImpl method getTriggerActionString.

public String getTriggerActionString(Visitable actionStmt, String oldReferencingName, String newReferencingName, String triggerDefinition, int[] referencedCols, int[] referencedColsInTriggerAction, int actionOffset, TableDescriptor triggerTableDescriptor, int triggerEventMask, boolean createTriggerTime, List<int[]> replacements, int[] cols) throws StandardException {
    boolean in10_9_orHigherVersion = checkVersion(DataDictionary.DD_VERSION_DERBY_10_9, null);
    StringBuilder newText = new StringBuilder();
    int start = 0;
    // Total Number of columns in the trigger table
    int numberOfColsInTriggerTable = triggerTableDescriptor.getNumberOfColumns();
    int[] triggerColsAndTriggerActionCols = new int[numberOfColsInTriggerTable];
    SortedSet<ColumnReference> refs = getTransitionVariables(actionStmt, oldReferencingName, newReferencingName);
    triggerColsAndTriggerActionCols = cols;
    // (SELECT c FROM new TriggerOldTransitionTable OLD)
    for (ColumnReference ref : refs) {
        TableName tableName = ref.getQualifiedTableName();
        int tableBeginOffset = tableName.getBeginOffset() - actionOffset;
        String colName = ref.getColumnName();
        // Add whatever we've seen after the previous replacement.
        newText.append(triggerDefinition, start, tableBeginOffset);
        int colPositionInRuntimeResultSet = -1;
        ColumnDescriptor triggerColDesc = triggerTableDescriptor.getColumnDescriptor(colName);
        // column in the trigger table.
        if (triggerColDesc == null) {
            throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND, tableName + "." + colName);
        }
        int colPositionInTriggerTable = triggerColDesc.getPosition();
        // is 2. That is what the following code is doing.
        if (in10_9_orHigherVersion && triggerColsAndTriggerActionCols != null) {
            for (int j = 0; j < triggerColsAndTriggerActionCols.length; j++) {
                if (triggerColsAndTriggerActionCols[j] == colPositionInTriggerTable)
                    colPositionInRuntimeResultSet = j + 1;
            }
        } else
            colPositionInRuntimeResultSet = colPositionInTriggerTable;
        // Add the replacement code that accesses a value in the
        // transition variable.
        final int replacementOffset = newText.length();
        newText.append(genColumnReferenceSQL(triggerTableDescriptor, colName, tableName.getTableName(), tableName.getTableName().equals(oldReferencingName), colPositionInRuntimeResultSet));
        start = ref.getEndOffset() + 1 - actionOffset;
        if (replacements != null) {
            // Record that we have made a change.
            replacements.add(new int[] { // offset to replaced text
            tableBeginOffset, // offset to token after replaced text
            start, // offset to replacement
            replacementOffset, // offset to token after replacement
            newText.length() });
        }
    }
    // By this point, we are finished transforming the trigger action if
    // it has any references to old/new transition variables.
    newText.append(triggerDefinition, start, triggerDefinition.length());
    return newText.toString();
}
Also used : TableName(org.apache.derby.impl.sql.compile.TableName) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) SQLLongint(org.apache.derby.iapi.types.SQLLongint) ColumnReference(org.apache.derby.impl.sql.compile.ColumnReference)

Example 78 with ColumnDescriptor

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

Example 79 with ColumnDescriptor

use of org.apache.derby.iapi.sql.dictionary.ColumnDescriptor in project derby by apache.

the class SYSCOLUMNSRowFactory method buildDescriptor.

// /////////////////////////////////////////////////////////////////////////
// 
// ABSTRACT METHODS TO BE IMPLEMENTED BY CHILDREN OF CatalogRowFactory
// 
// /////////////////////////////////////////////////////////////////////////
/**
 * Make a ColumnDescriptor out of a SYSCOLUMNS row
 *
 * @param row 					a SYSCOLUMNS row
 * @param parentTupleDescriptor	The UniqueTupleDescriptor for the object that is tied
 *								to this column
 * @param dd 					dataDictionary
 *
 * @return	a column descriptor equivalent to a SYSCOLUMNS row
 *
 * @exception   StandardException thrown on failure
 */
public TupleDescriptor buildDescriptor(ExecRow row, TupleDescriptor parentTupleDescriptor, DataDictionary dd) throws StandardException {
    if (SanityManager.DEBUG) {
        int expectedCols = dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_14, null) ? SYSCOLUMNS_COLUMN_COUNT : (SYSCOLUMNS_COLUMN_COUNT - 1);
        SanityManager.ASSERT(row.nColumns() == expectedCols, "Wrong number of columns for a SYSCOLUMNS row");
    }
    int columnNumber;
    String columnName;
    String defaultID;
    DefaultInfoImpl defaultInfo = null;
    ColumnDescriptor colDesc;
    DataValueDescriptor defaultValue = null;
    UUID defaultUUID = null;
    UUID uuid = null;
    UUIDFactory uuidFactory = getUUIDFactory();
    long autoincStart, autoincInc, autoincValue;
    boolean autoincCycle = false;
    DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
    /*
		** We're going to be getting the UUID for this sucka
		** so make sure it is a UniqueTupleDescriptor.
		*/
    if (parentTupleDescriptor != null) {
        if (SanityManager.DEBUG) {
            if (!(parentTupleDescriptor instanceof UniqueTupleDescriptor)) {
                SanityManager.THROWASSERT(parentTupleDescriptor.getClass().getName() + " not instanceof UniqueTupleDescriptor");
            }
        }
        uuid = ((UniqueTupleDescriptor) parentTupleDescriptor).getUUID();
    } else {
        /* 1st column is REFERENCEID (char(36)) */
        uuid = uuidFactory.recreateUUID(row.getColumn(SYSCOLUMNS_REFERENCEID).getString());
    }
    /* NOTE: We get columns 5 and 6 next in order to work around 
		 * a 1.3.0 HotSpot bug.  (#4361550)
		 */
    // 5th column is COLUMNDEFAULT (serialiazable)
    Object object = row.getColumn(SYSCOLUMNS_COLUMNDEFAULT).getObject();
    if (object instanceof DataValueDescriptor) {
        defaultValue = (DataValueDescriptor) object;
    } else if (object instanceof DefaultInfoImpl) {
        defaultInfo = (DefaultInfoImpl) object;
        defaultValue = defaultInfo.getDefaultValue();
    }
    /* 6th column is DEFAULTID (char(36)) */
    defaultID = row.getColumn(SYSCOLUMNS_COLUMNDEFAULTID).getString();
    if (defaultID != null) {
        defaultUUID = uuidFactory.recreateUUID(defaultID);
    }
    /* 2nd column is COLUMNNAME (varchar(128)) */
    columnName = row.getColumn(SYSCOLUMNS_COLUMNNAME).getString();
    /* 3rd column is COLUMNNUMBER (int) */
    columnNumber = row.getColumn(SYSCOLUMNS_COLUMNNUMBER).getInt();
    /* 4th column is COLUMNDATATYPE */
    /*
		** What is stored in the column is a TypeDescriptorImpl, which
		** points to a BaseTypeIdImpl.  These are simple types that are
		** intended to be movable to the client, so they don't have
		** the entire implementation.  We need to wrap them in DataTypeServices
		** and TypeId objects that contain the full implementations for
		** language processing.
		*/
    TypeDescriptor catalogType = (TypeDescriptor) row.getColumn(SYSCOLUMNS_COLUMNDATATYPE).getObject();
    DataTypeDescriptor dataTypeServices = DataTypeDescriptor.getType(catalogType);
    /* 7th column is AUTOINCREMENTVALUE (long) */
    autoincValue = row.getColumn(SYSCOLUMNS_AUTOINCREMENTVALUE).getLong();
    /* 8th column is AUTOINCREMENTSTART (long) */
    autoincStart = row.getColumn(SYSCOLUMNS_AUTOINCREMENTSTART).getLong();
    /* 9th column is AUTOINCREMENTINC (long) */
    autoincInc = row.getColumn(SYSCOLUMNS_AUTOINCREMENTINC).getLong();
    if (row.nColumns() >= 10) {
        DataValueDescriptor col = row.getColumn(SYSCOLUMNS_AUTOINCREMENTINCCYCLE);
        autoincCycle = col.getBoolean();
    }
    DataValueDescriptor col = row.getColumn(SYSCOLUMNS_AUTOINCREMENTSTART);
    autoincStart = col.getLong();
    col = row.getColumn(SYSCOLUMNS_AUTOINCREMENTINC);
    autoincInc = col.getLong();
    // Hard upgraded tables <=10.13 come with a false autoincCyle before they are first
    // explicitly set with cycle or no cycle command.
    colDesc = new ColumnDescriptor(columnName, columnNumber, dataTypeServices, defaultValue, defaultInfo, uuid, defaultUUID, autoincStart, autoincInc, autoincValue, autoincCycle);
    return colDesc;
}
Also used : UUIDFactory(org.apache.derby.iapi.services.uuid.UUIDFactory) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) DefaultInfoImpl(org.apache.derby.catalog.types.DefaultInfoImpl) DataDescriptorGenerator(org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator) TypeDescriptor(org.apache.derby.catalog.TypeDescriptor) UUID(org.apache.derby.catalog.UUID) UniqueTupleDescriptor(org.apache.derby.iapi.sql.dictionary.UniqueTupleDescriptor)

Aggregations

ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)79 ColumnDescriptorList (org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList)23 TableDescriptor (org.apache.derby.iapi.sql.dictionary.TableDescriptor)20 ResultColumnDescriptor (org.apache.derby.iapi.sql.ResultColumnDescriptor)19 UUID (org.apache.derby.catalog.UUID)15 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)14 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)10 ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)8 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)8 TransactionController (org.apache.derby.iapi.store.access.TransactionController)8 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)8 SQLLongint (org.apache.derby.iapi.types.SQLLongint)8 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)7 DependencyManager (org.apache.derby.iapi.sql.depend.DependencyManager)7 ConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor)7 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)7 RowLocation (org.apache.derby.iapi.types.RowLocation)7 DefaultInfoImpl (org.apache.derby.catalog.types.DefaultInfoImpl)6 ConstraintDescriptorList (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList)6 DefaultDescriptor (org.apache.derby.iapi.sql.dictionary.DefaultDescriptor)6