use of org.apache.derby.iapi.sql.dictionary.ColumnDescriptor in project derby by apache.
the class FromBaseTable method genResultColList.
/**
* Build a ResultColumnList based on all of the columns in this FromBaseTable.
* NOTE - Since the ResultColumnList generated is for the FromBaseTable,
* ResultColumn.expression will be a BaseColumnNode.
*
* @return ResultColumnList representing all referenced columns
*
* @exception StandardException Thrown on error
*/
ResultColumnList genResultColList() throws StandardException {
ResultColumn resultColumn;
ValueNode valueNode;
/* Cache exposed name for this table.
* The exposed name becomes the qualifier for each column
* in the expanded list.
*/
TableName exposedName = getExposedTableName();
/* Add all of the columns in the table */
ResultColumnList rcList = new ResultColumnList((getContextManager()));
ColumnDescriptorList cdl = tableDescriptor.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);
// A ColumnDescriptor instantiated through SYSCOLUMNSRowFactory only has
// the uuid set on it and no table descriptor set on it. Since we know here
// that this columnDescriptor is tied to tableDescriptor, set it so using
// setTableDescriptor method. ColumnDescriptor's table descriptor is used
// to get ResultSetMetaData.getTableName & ResultSetMetaData.getSchemaName
colDesc.setTableDescriptor(tableDescriptor);
valueNode = new BaseColumnNode(colDesc.getColumnName(), exposedName, colDesc.getType(), getContextManager());
resultColumn = new ResultColumn(colDesc, valueNode, getContextManager());
/* Build the ResultColumnList to return */
rcList.addResultColumn(resultColumn);
}
// add a row location column as necessary
if (rowLocationColumnName != null) {
CurrentRowLocationNode rowLocationNode = new CurrentRowLocationNode(getContextManager());
ResultColumn rowLocationColumn = new ResultColumn(rowLocationColumnName, rowLocationNode, getContextManager());
rowLocationColumn.markGenerated();
rowLocationNode.bindExpression(null, null, null);
rowLocationColumn.bindResultColumnToExpression();
rcList.addResultColumn(rowLocationColumn);
}
return rcList;
}
use of org.apache.derby.iapi.sql.dictionary.ColumnDescriptor in project derby by apache.
the class FromVTI method genResultColList.
private ResultColumnList genResultColList(TableDescriptor td) throws StandardException {
/* Add all of the columns in the table */
ResultColumnList rcList = 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);
ValueNode valueNode = new BaseColumnNode(colDesc.getColumnName(), exposedName, colDesc.getType(), getContextManager());
ResultColumn resultColumn = new ResultColumn(colDesc, valueNode, getContextManager());
/* Build the ResultColumnList to return */
rcList.addResultColumn(resultColumn);
}
return rcList;
}
use of org.apache.derby.iapi.sql.dictionary.ColumnDescriptor in project derby by apache.
the class CreateTriggerNode method bindStatement.
// accessors
// We inherit the generate() method from DDLStatementNode.
/**
* Bind this CreateTriggerNode. This means doing any static error
* checking that can be done before actually creating the table.
*
* @exception StandardException Thrown on error
*/
@Override
public void bindStatement() throws StandardException {
CompilerContext compilerContext = getCompilerContext();
DataDictionary dd = getDataDictionary();
/*
** Grab the current schema. We will use that for
** sps compilation
*/
LanguageConnectionContext lcc = getLanguageConnectionContext();
compSchemaDescriptor = lcc.getDefaultSchema();
/*
** Get and check the schema descriptor for this
** trigger. This check will throw the proper exception
** if someone tries to create a trigger in the SYS
** schema.
*/
triggerSchemaDescriptor = getSchemaDescriptor();
/*
** Get the trigger table.
*/
triggerTableDescriptor = getTableDescriptor(tableName);
// throw an exception if user is attempting to create a trigger on a temporary table
if (isSessionSchema(triggerTableDescriptor.getSchemaDescriptor())) {
throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);
}
if (isPrivilegeCollectionRequired()) {
compilerContext.pushCurrentPrivType(Authorizer.TRIGGER_PRIV);
compilerContext.addRequiredTablePriv(triggerTableDescriptor);
compilerContext.popCurrentPrivType();
}
/*
** Regenerates the actionText and actionNode if necessary.
*/
boolean needInternalSQL = bindReferencesClause(dd);
// Get all the names of SQL objects referenced by the triggered
// SQL statement and the WHEN clause. Since some of the TableName
// nodes may be eliminated from the node tree during the bind phase,
// we collect the nodes before the nodes have been bound. The
// names will be used later when we normalize the trigger text
// that will be stored in the system tables.
SortedSet<TableName> actionNames = actionNode.getOffsetOrderedNodes(TableName.class);
SortedSet<TableName> whenNames = (whenClause != null) ? whenClause.getOffsetOrderedNodes(TableName.class) : null;
ProviderList prevAPL = compilerContext.getCurrentAuxiliaryProviderList();
ProviderList apl = new ProviderList();
lcc.pushTriggerTable(triggerTableDescriptor);
try {
compilerContext.setCurrentAuxiliaryProviderList(apl);
/*
** Bind the trigger action and the trigger
** when clause to make sure that they are
** ok. Note that we have already substituted
** in various replacements for OLD/NEW transition
** tables/variables and reparsed if necessary.
*/
if (needInternalSQL)
compilerContext.setReliability(CompilerContext.INTERNAL_SQL_LEGAL);
// bind of the call statement node.
if (isBefore)
compilerContext.setReliability(CompilerContext.MODIFIES_SQL_DATA_PROCEDURE_ILLEGAL);
actionNode.bindStatement();
if (whenClause != null) {
ContextManager cm = getContextManager();
whenClause = whenClause.bindExpression(new FromList(cm), new SubqueryList(cm), new ArrayList<AggregateNode>(0));
// The WHEN clause must be a BOOLEAN expression.
whenClause.checkIsBoolean();
}
} finally {
lcc.popTriggerTable(triggerTableDescriptor);
compilerContext.setCurrentAuxiliaryProviderList(prevAPL);
}
// Qualify identifiers before storing them (DERBY-5901/DERBY-6370).
qualifyNames(actionNames, whenNames);
/*
** Statement is dependent on the TableDescriptor
*/
compilerContext.createDependency(triggerTableDescriptor);
/*
** If there is a list of columns, then no duplicate columns,
** and all columns must be found.
*/
if (triggerCols != null && triggerCols.size() != 0) {
HashSet<String> columnNames = new HashSet<String>();
for (ResultColumn rc : triggerCols) {
if (!columnNames.add(rc.getName())) {
throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_IN_TRIGGER_UPDATE, rc.getName(), triggerName);
}
ColumnDescriptor cd = triggerTableDescriptor.getColumnDescriptor(rc.getName());
if (cd == null) {
throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, rc.getName(), tableName);
}
}
}
// statement references a table in the SESSION schema.
if (referencesSessionSchema()) {
throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);
}
DependencyManager dm = dd.getDependencyManager();
providerInfo = dm.getPersistentProviderInfos(apl);
dm.clearColumnInfoInProviders(apl);
}
use of org.apache.derby.iapi.sql.dictionary.ColumnDescriptor in project derby by apache.
the class CreateTriggerNode method bindReferencesClause.
/*
** BIND OLD/NEW TRANSITION TABLES/VARIABLES AND collect TRIGGER ACTION
** COLUMNS referenced through REFERECING CLAUSE in CREATE TRIGGER statement
**
** 1) validate the referencing clause (if any)
**
** 2) convert trigger action text and WHEN clause text. e.g.
** DELETE FROM t WHERE c = old.c
** turns into
** DELETE FROM t WHERE c = org.apache.derby.iapi.db.Factory::
** getTriggerExecutionContext().getOldRow().
** getInt(columnNumberFor'C'inRuntimeResultset);
** or
** DELETE FROM t WHERE c in (SELECT c FROM OLD)
** turns into
** DELETE FROM t WHERE c in (
** SELECT c FROM new TriggerOldTransitionTable OLD)
**
** 3) check all column references against new/old transition
** variables (since they are no longer 'normal' column references
** that will be checked during bind)
**
** 4) collect all column references in trigger action through new/old
** transition variables. Information about them will be saved in
** SYSTRIGGERS table DERBY-1482(if we are dealing with pre-10.7 db, then we
** will not put any information about trigger action columns in the system
** table to ensure backward compatibility). This information along with the
** trigger columns will decide what columns from the trigger table will be
** fetched into memory during trigger execution.
**
** 5) reparse the new action text
**
** You might be wondering why we regenerate the text and reparse
** instead of just reworking the tree to have the nodes we want.
** Well, the primary reason is that if we screwed with the tree,
** then we would have a major headache if this trigger action
** was ever recompiled -- spses don't really know that they are
** triggers so it would be quite arduous to figure out that an
** sps is a trigger and munge up its query tree after figuring
** out what its OLD/NEW tables are, etc. Also, it is just plain
** easier to just generate the sql and rebind.
**
*/
private boolean bindReferencesClause(DataDictionary dd) throws StandardException {
validateReferencesClause(dd);
// the actions of before triggers may not reference generated columns
if (isBefore) {
forbidActionsOnGenCols();
}
String transformedActionText;
String transformedWhenText = null;
if (triggerCols != null && triggerCols.size() != 0) {
// If the trigger is defined on speific columns, then collect
// their column positions and ensure that those columns do
// indeed exist in the trigger table.
referencedColInts = new int[triggerCols.size()];
for (int i = 0; i < triggerCols.size(); i++) {
ResultColumn rc = triggerCols.elementAt(i);
ColumnDescriptor cd = triggerTableDescriptor.getColumnDescriptor(rc.getName());
// FOR EACH ROW UPDATE table2 SET c24=oldt.c14;
if (cd == null) {
throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, rc.getName(), tableName);
}
referencedColInts[i] = cd.getPosition();
}
// sort the list
java.util.Arrays.sort(referencedColInts);
}
if (isRow) {
// Create an array for column positions of columns referenced in
// trigger action. Initialize it to -1. The call to
// DataDictoinary.getTriggerActionSPS will find out the actual
// columns, if any, referenced in the trigger action and put their
// column positions in the array.
referencedColsInTriggerAction = new int[triggerTableDescriptor.getNumberOfColumns()];
java.util.Arrays.fill(referencedColsInTriggerAction, -1);
int[] cols;
cols = getDataDictionary().examineTriggerNodeAndCols(actionNode, oldTableName, newTableName, originalActionText, referencedColInts, referencedColsInTriggerAction, actionNode.getBeginOffset(), triggerTableDescriptor, triggerEventMask, true, actionTransformations);
if (whenClause != null) {
cols = getDataDictionary().examineTriggerNodeAndCols(whenClause, oldTableName, newTableName, originalActionText, referencedColInts, referencedColsInTriggerAction, actionNode.getBeginOffset(), triggerTableDescriptor, triggerEventMask, true, actionTransformations);
}
// Now that we have verified that are no invalid column references
// for trigger columns, let's go ahead and transform the OLD/NEW
// transient table references in the trigger action sql.
transformedActionText = getDataDictionary().getTriggerActionString(actionNode, oldTableName, newTableName, originalActionText, referencedColInts, referencedColsInTriggerAction, actionNode.getBeginOffset(), triggerTableDescriptor, triggerEventMask, true, actionTransformations, cols);
// If there is a WHEN clause, we need to transform its text too.
if (whenClause != null) {
transformedWhenText = getDataDictionary().getTriggerActionString(whenClause, oldTableName, newTableName, originalWhenText, referencedColInts, referencedColsInTriggerAction, whenClause.getBeginOffset(), triggerTableDescriptor, triggerEventMask, true, whenClauseTransformations, cols);
}
// Now that we know what columns we need for REFERENCEd columns in
// trigger action, we can get rid of -1 entries for the remaining
// columns from trigger table. This information will be saved in
// SYSTRIGGERS and will be used at trigger execution time to decide
// which columns need to be read into memory for trigger action
referencedColsInTriggerAction = justTheRequiredColumns(referencedColsInTriggerAction);
} else {
// This is a table level trigger
transformedActionText = transformStatementTriggerText(actionNode, originalActionText, actionTransformations);
if (whenClause != null) {
transformedWhenText = transformStatementTriggerText(whenClause, originalWhenText, whenClauseTransformations);
}
}
if (referencedColsInTriggerAction != null)
java.util.Arrays.sort(referencedColsInTriggerAction);
/*
** Parse the new action text with the substitutions.
** Also, we reset the actionText to this new value. This
** is what we are going to stick in the system tables.
*/
boolean regenNode = false;
if (!transformedActionText.equals(actionText)) {
regenNode = true;
actionText = transformedActionText;
actionNode = parseStatement(actionText, true);
}
if (whenClause != null && !transformedWhenText.equals(whenText)) {
regenNode = true;
whenText = transformedWhenText;
whenClause = parseSearchCondition(whenText, true);
}
return regenNode;
}
use of org.apache.derby.iapi.sql.dictionary.ColumnDescriptor in project derby by apache.
the class DeleteNode method getSetClause.
private ResultColumnList getSetClause(ColumnDescriptorList cdl) throws StandardException {
ResultColumn resultColumn;
ValueNode valueNode;
ResultColumnList columnList = new ResultColumnList(getContextManager());
valueNode = new UntypedNullConstantNode(getContextManager());
for (int index = 0; index < cdl.size(); index++) {
ColumnDescriptor cd = cdl.elementAt(index);
// DELETE SET NULL
if ((cd.getType()).isNullable()) {
resultColumn = new ResultColumn(cd, valueNode, getContextManager());
columnList.addResultColumn(resultColumn);
}
}
return columnList;
}
Aggregations