Search in sources :

Example 56 with TableDescriptor

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

the class MatchingClauseNode method buildThenColumnsForInsert.

/**
 * <p>
 * Construct the row in the temporary table which drives an INSERT action.
 * Unlike a DELETE, whose temporary row is just a list of copied columns, the
 * temporary row for INSERT may contain complex expressions which must
 * be code-generated later on.
 * </p>
 */
private void buildThenColumnsForInsert(FromList fullFromList, FromTable targetTable, ResultColumnList fullRow, ResultColumnList insertColumns, ResultColumnList insertValues) throws StandardException {
    // 
    // Don't add USAGE privilege on user-defined types just because we're
    // building the THEN columns.
    // 
    boolean wasSkippingTypePrivileges = getCompilerContext().skipTypePrivileges(true);
    TableDescriptor td = targetTable.getTableDescriptor();
    _thenColumns = fullRow.copyListAndObjects();
    // 
    for (int i = 0; i < _thenColumns.size(); i++) {
        ResultColumn origRC = _thenColumns.elementAt(i);
        String columnName = origRC.getName();
        ColumnDescriptor cd = td.getColumnDescriptor(columnName);
        boolean changed = false;
        // 
        if (!origRC.isAutoincrement() && (origRC.getExpression() instanceof VirtualColumnNode)) {
            origRC.setExpression(new UntypedNullConstantNode(getContextManager()));
        }
        if (cd.hasGenerationClause()) {
            origRC.setExpression(new UntypedNullConstantNode(getContextManager()));
            continue;
        }
        for (int ic = 0; ic < insertColumns.size(); ic++) {
            ResultColumn icRC = insertColumns.elementAt(ic);
            if (columnName.equals(icRC.getName())) {
                ResultColumn newRC = null;
                // replace DEFAULT for a generated or identity column
                ResultColumn valueRC = insertValues.elementAt(ic);
                if (valueRC.wasDefaultColumn() || (valueRC.getExpression() instanceof UntypedNullConstantNode)) {
                    if (!cd.isAutoincrement()) {
                        // 
                        // Eliminate column references under identity columns. They
                        // will mess up the code generation.
                        // 
                        ValueNode expr = origRC.getExpression();
                        if (expr instanceof ColumnReference) {
                            origRC.setExpression(new UntypedNullConstantNode(getContextManager()));
                        }
                        continue;
                    }
                    newRC = makeAutoGenRC(targetTable, origRC, i + 1);
                } else {
                    newRC = valueRC.cloneMe();
                    newRC.setType(origRC.getTypeServices());
                }
                newRC.setVirtualColumnId(origRC.getVirtualColumnId());
                _thenColumns.setElementAt(newRC, i);
                changed = true;
                break;
            }
        }
        // plug in defaults if we haven't done so already
        if (!changed) {
            DefaultInfoImpl defaultInfo = (DefaultInfoImpl) cd.getDefaultInfo();
            if ((defaultInfo != null) && !defaultInfo.isGeneratedColumn() && !cd.isAutoincrement()) {
                _thenColumns.setDefault(origRC, cd, defaultInfo);
                changed = true;
            }
        }
        // set the result column name correctly for buildThenColumnSignature()
        ResultColumn finalRC = _thenColumns.elementAt(i);
        finalRC.setName(cd.getColumnName());
    }
    // end loop through _thenColumns
    getCompilerContext().skipTypePrivileges(wasSkippingTypePrivileges);
}
Also used : ResultColumnDescriptor(org.apache.derby.iapi.sql.ResultColumnDescriptor) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) TableDescriptor(org.apache.derby.iapi.sql.dictionary.TableDescriptor) DefaultInfoImpl(org.apache.derby.catalog.types.DefaultInfoImpl)

Example 57 with TableDescriptor

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

the class MatchingClauseNode method buildThenColumnsForUpdate.

/**
 * <p>
 * Construct the row in the temporary table which drives an UPDATE action.
 * Unlike a DELETE, whose temporary row is just a list of copied columns, the
 * temporary row for UPDATE may contain complex expressions which must
 * be code-generated later on.
 * </p>
 */
private void buildThenColumnsForUpdate(FromList fullFromList, FromTable targetTable, ResultColumnList fullRow, ResultColumnList beforeRow, ResultColumnList afterValues) throws StandardException {
    TableDescriptor td = targetTable.getTableDescriptor();
    HashSet<String> changedColumns = getChangedColumnNames();
    HashSet<String> changedGeneratedColumns = getChangedGeneratedColumnNames(td, changedColumns);
    _thenColumns = fullRow.copyListAndObjects();
    // 
    for (int i = 0; i < _thenColumns.size(); i++) {
        ResultColumn origRC = _thenColumns.elementAt(i);
        boolean isAfterColumn = (i >= beforeRow.size());
        // skip the final RowLocation column of an UPDATE
        boolean isRowLocation = isRowLocation(origRC);
        ValueNode origExpr = origRC.getExpression();
        if (isRowLocation) {
            continue;
        }
        String columnName = origRC.getName();
        ColumnDescriptor cd = td.getColumnDescriptor(columnName);
        boolean changed = false;
        // 
        if (cd.isAutoincrement() && (origRC.getExpression() instanceof NumericConstantNode)) {
            DataValueDescriptor numericValue = ((NumericConstantNode) origRC.getExpression()).getValue();
            if (numericValue == null) {
                ResultColumn newRC = makeAutoGenRC(targetTable, origRC, i + 1);
                newRC.setVirtualColumnId(origRC.getVirtualColumnId());
                _thenColumns.setElementAt(newRC, i);
                continue;
            }
        }
        // 
        if (!origRC.isAutoincrement() && (origRC.getExpression() instanceof VirtualColumnNode)) {
            origRC.setExpression(new UntypedNullConstantNode(getContextManager()));
        }
        // 
        if (cd.hasGenerationClause()) {
            if (isAfterColumn && changedGeneratedColumns.contains(columnName)) {
                // Set the expression to something that won't choke ResultColumnList.generateEvaluatedRow().
                // The value will be a Java null at execution time, which will cause the value
                // to be re-generated.
                origRC.setExpression(new UntypedNullConstantNode(getContextManager()));
            } else {
                ColumnReference cr = new ColumnReference(columnName, targetTable.getTableName(), getContextManager());
                origRC.setExpression(cr);
                // remove the column descriptor in order to turn off hasGenerationClause()
                origRC.setColumnDescriptor(null, null);
            }
            continue;
        }
        if (isAfterColumn) {
            for (int ic = 0; ic < beforeRow.size(); ic++) {
                ResultColumn icRC = beforeRow.elementAt(ic);
                if (columnName.equals(icRC.getName())) {
                    ResultColumn newRC = null;
                    // replace DEFAULT for a generated or identity column
                    ResultColumn valueRC = afterValues.elementAt(ic);
                    if (valueRC.wasDefaultColumn() || (valueRC.getExpression() instanceof UntypedNullConstantNode)) {
                        if (!cd.isAutoincrement()) {
                            // 
                            // Eliminate column references under identity columns. They
                            // will mess up the code generation.
                            // 
                            ValueNode expr = origRC.getExpression();
                            if (expr instanceof ColumnReference) {
                                origRC.setExpression(new UntypedNullConstantNode(getContextManager()));
                            }
                            continue;
                        }
                        newRC = makeAutoGenRC(targetTable, origRC, i + 1);
                    } else {
                        newRC = valueRC.cloneMe();
                        newRC.setType(origRC.getTypeServices());
                    }
                    newRC.setVirtualColumnId(origRC.getVirtualColumnId());
                    _thenColumns.setElementAt(newRC, i);
                    changed = true;
                    break;
                }
            }
        }
        // plug in defaults if we haven't done so already
        if (!changed) {
            DefaultInfoImpl defaultInfo = (DefaultInfoImpl) cd.getDefaultInfo();
            if ((defaultInfo != null) && !defaultInfo.isGeneratedColumn() && !cd.isAutoincrement()) {
                _thenColumns.setDefault(origRC, cd, defaultInfo);
                changed = true;
            }
        }
        // set the result column name correctly for buildThenColumnSignature()
        ResultColumn finalRC = _thenColumns.elementAt(i);
        finalRC.setName(cd.getColumnName());
        // 
        // Turn off the autogenerated bit for identity columns so that
        // ResultColumnList.generateEvaluatedRow() doesn't try to compile
        // code to generate values for the before images in UPDATE rows.
        // This logic will probably need to be revisited as part of fixing derby-6414.
        // 
        finalRC.resetAutoincrementGenerated();
    }
// end loop through _thenColumns
}
Also used : ResultColumnDescriptor(org.apache.derby.iapi.sql.ResultColumnDescriptor) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) TableDescriptor(org.apache.derby.iapi.sql.dictionary.TableDescriptor) DefaultInfoImpl(org.apache.derby.catalog.types.DefaultInfoImpl) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor)

Example 58 with TableDescriptor

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

the class MergeNode method targetIsBaseTable.

/**
 * Return true if the target table is a base table
 */
private boolean targetIsBaseTable(FromBaseTable targetTable) throws StandardException {
    FromBaseTable fbt = targetTable;
    TableDescriptor desc = fbt.getTableDescriptor();
    if (desc == null) {
        return false;
    }
    switch(desc.getTableType()) {
        case TableDescriptor.BASE_TABLE_TYPE:
        case TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE:
            return true;
        default:
            return false;
    }
}
Also used : TableDescriptor(org.apache.derby.iapi.sql.dictionary.TableDescriptor)

Example 59 with TableDescriptor

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

the class CurrentOfNode method bindNonVTITables.

// 
// FromTable interface
// 
/**
 * Binding this FromTable means finding the prepared statement
 * for the cursor and creating the result columns (the columns
 * updatable on that cursor).
 *
 * We expect someone else to verify that the target table
 * of the positioned update or delete is the table under this cursor.
 *
 * @param dataDictionary	The DataDictionary to use for binding
 * @param fromListParam		FromList to use/append to.
 *
 * @return	ResultSetNode		Returns this.
 *
 * @exception StandardException		Thrown on error
 */
@Override
ResultSetNode bindNonVTITables(DataDictionary dataDictionary, FromList fromListParam) throws StandardException {
    // verify that the cursor exists
    preStmt = getCursorStatement();
    if (preStmt == null) {
        throw StandardException.newException(SQLState.LANG_CURSOR_NOT_FOUND, cursorName);
    }
    preStmt.rePrepare(getLanguageConnectionContext());
    // for checking that the right columns are updatable)
    if (preStmt.getUpdateMode() != CursorNode.UPDATE) {
        String printableString = (cursorName == null) ? "" : cursorName;
        throw StandardException.newException(SQLState.LANG_CURSOR_NOT_UPDATABLE, printableString);
    }
    ExecCursorTableReference refTab = preStmt.getTargetTable();
    String schemaName = refTab.getSchemaName();
    exposedTableName = makeTableName(null, refTab.getExposedName());
    baseTableName = makeTableName(schemaName, refTab.getBaseName());
    SchemaDescriptor tableSchema = getSchemaDescriptor(refTab.getSchemaName());
    /*
		** This will only happen when we are binding against a publication
		** dictionary w/o the schema we are interested in.
		*/
    if (tableSchema == null) {
        throw StandardException.newException(SQLState.LANG_SCHEMA_DOES_NOT_EXIST, refTab.getSchemaName());
    }
    /* Create dependency on target table, in case table not named in 
		 * positioned update/delete.  Make sure we find the table descriptor,
		 * we may fail to find it if we are binding a publication.
		 */
    TableDescriptor td = getTableDescriptor(refTab.getBaseName(), tableSchema);
    if (td == null) {
        throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, refTab.getBaseName());
    }
    /*
		** Add all the result columns from the target table.
		** For now, all updatable cursors have all columns
		** from the target table.  In the future, we should
		** relax this so that the cursor may do a partial
		** read and then the current of should make sure that
		** it can go to the base table to get all of the 
		** columns needed by the referencing positioned
		** DML.  In the future, we'll probably need to get
		** the result columns from preparedStatement and
		** turn them into an RCL that we can run with.
		*/
    setResultColumns(new ResultColumnList(getContextManager()));
    ColumnDescriptorList cdl = td.getColumnDescriptorList();
    int cdlSize = cdl.size();
    for (int index = 0; index < cdlSize; index++) {
        /* Build a ResultColumn/BaseColumnNode pair for the column */
        ColumnDescriptor colDesc = cdl.elementAt(index);
        BaseColumnNode bcn = new BaseColumnNode(colDesc.getColumnName(), exposedTableName, colDesc.getType(), getContextManager());
        ResultColumn rc = new ResultColumn(colDesc, bcn, getContextManager());
        /* Build the ResultColumnList to return */
        getResultColumns().addResultColumn(rc);
    }
    /* Assign the tableNumber */
    if (// allow re-bind, in which case use old number
    tableNumber == -1)
        tableNumber = getCompilerContext().getNextTableNumber();
    return this;
}
Also used : SchemaDescriptor(org.apache.derby.iapi.sql.dictionary.SchemaDescriptor) ExecCursorTableReference(org.apache.derby.iapi.sql.execute.ExecCursorTableReference) ColumnDescriptorList(org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) TableDescriptor(org.apache.derby.iapi.sql.dictionary.TableDescriptor)

Example 60 with TableDescriptor

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

the class CursorNode method bindUpdateColumns.

/**
 *		Bind the update columns by their names to the target table
 *		of the cursor specification.
 *		Doesn't check for duplicates in the list, although it could...
 *		REVISIT: If the list is empty, should it expand it out? at present,
 *		it leaves it empty.
 *
 *		@param targetTable	The underlying target table
 *
 *		@exception StandardException		Thrown on error
 */
private void bindUpdateColumns(FromTable targetTable) throws StandardException {
    int size = updatableColumns.size();
    TableDescriptor tableDescriptor;
    String columnName;
    ResultColumnList rcl = resultSet.getResultColumns();
    for (int index = 0; index < size; index++) {
        columnName = updatableColumns.get(index);
        tableDescriptor = targetTable.getTableDescriptor();
        if (tableDescriptor.getColumnDescriptor(columnName) == null) {
            throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND, columnName);
        }
        for (ResultColumn rc : rcl) {
            // Look through each column in the resultset for cursor.
            if (rc.getSourceTableName() == null) {
                // a derived column in the select list.
                continue;
            }
            if (rc.getExpression() != null && rc.getExpression().getColumnName().equals(columnName) && !rc.getName().equals(columnName)) {
                throw StandardException.newException(SQLState.LANG_CORRELATION_NAME_FOR_UPDATABLE_COLUMN_DISALLOWED_IN_CURSOR, columnName);
            }
        }
    }
}
Also used : TableDescriptor(org.apache.derby.iapi.sql.dictionary.TableDescriptor)

Aggregations

TableDescriptor (org.apache.derby.iapi.sql.dictionary.TableDescriptor)80 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)27 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)23 UUID (org.apache.derby.catalog.UUID)22 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)20 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)20 TransactionController (org.apache.derby.iapi.store.access.TransactionController)20 ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)19 DependencyManager (org.apache.derby.iapi.sql.depend.DependencyManager)11 ColumnDescriptorList (org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList)11 ConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor)9 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)9 StandardException (org.apache.derby.shared.common.error.StandardException)9 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)7 DataDescriptorGenerator (org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator)7 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)7 ArrayList (java.util.ArrayList)6 AliasDescriptor (org.apache.derby.iapi.sql.dictionary.AliasDescriptor)6 ConstraintDescriptorList (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList)6 ViewDescriptor (org.apache.derby.iapi.sql.dictionary.ViewDescriptor)6