use of org.apache.derby.iapi.services.context.ContextManager 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.services.context.ContextManager in project derby by apache.
the class BetweenOperatorNode method eliminateNots.
/**
* Eliminate NotNodes in the current query block. We traverse the tree,
* inverting ANDs and ORs and eliminating NOTs as we go. We stop at
* ComparisonOperators and boolean expressions. We invert
* ComparisonOperators and replace boolean expressions with
* boolean expression = false.
* NOTE: Since we do not recurse under ComparisonOperators, there
* still could be NotNodes left in the tree.
*
* @param underNotNode Whether or not we are under a NotNode.
*
* @return The modified expression
*
* @exception StandardException Thrown on error
*/
@Override
ValueNode eliminateNots(boolean underNotNode) throws StandardException {
BinaryComparisonOperatorNode leftBCO;
BinaryComparisonOperatorNode rightBCO;
OrNode newOr;
if (SanityManager.DEBUG)
SanityManager.ASSERT(rightOperandList.size() == 2, "rightOperandList.size() (" + rightOperandList.size() + ") is expected to be 2");
if (!underNotNode) {
return this;
}
/* we want to convert the BETWEEN * into < OR >
as described below.
*/
/* Convert:
* leftO between rightOList.elementAt(0) and rightOList.elementAt(1)
* to:
* leftO < rightOList.elementAt(0) or leftO > rightOList.elementAt(1)
* NOTE - We do the conversion here since ORs will eventually be
* optimizable and there's no benefit for the optimizer to see NOT BETWEEN
*/
ContextManager cm = getContextManager();
/* leftO < rightOList.elementAt(0) */
leftBCO = new BinaryRelationalOperatorNode(BinaryRelationalOperatorNode.K_LESS_THAN, leftOperand, rightOperandList.elementAt(0), false, cm);
/* Set type info for the operator node */
leftBCO.bindComparisonOperator();
// DERBY-4388: If leftOperand is a ColumnReference, it may be remapped
// during optimization, and that requires the less-than node and the
// greater-than node to have separate objects.
ValueNode leftClone = (leftOperand instanceof ColumnReference) ? leftOperand.getClone() : leftOperand;
/* leftO > rightOList.elementAt(1) */
rightBCO = new BinaryRelationalOperatorNode(BinaryRelationalOperatorNode.K_GREATER_THAN, leftClone, rightOperandList.elementAt(1), false, cm);
/* Set type info for the operator node */
rightBCO.bindComparisonOperator();
/* Create and return the OR */
newOr = new OrNode(leftBCO, rightBCO, cm);
newOr.postBindFixup();
/* Tell optimizer to use the between selectivity instead of >= * <= selectivities */
leftBCO.setBetweenSelectivity();
rightBCO.setBetweenSelectivity();
return newOr;
}
use of org.apache.derby.iapi.services.context.ContextManager in project derby by apache.
the class BetweenOperatorNode method generateExpression.
/**
* Do code generation for this BETWEEN operator.
*
* @param acb The ExpressionClassBuilder for the class we're generating
* @param mb The method the code to place the code
*
* @exception StandardException Thrown on error
*/
@Override
void generateExpression(ExpressionClassBuilder acb, MethodBuilder mb) throws StandardException {
AndNode newAnd;
BinaryComparisonOperatorNode leftBCO;
BinaryComparisonOperatorNode rightBCO;
if (SanityManager.DEBUG)
SanityManager.ASSERT(rightOperandList.size() == 2, "rightOperandList.size() (" + rightOperandList.size() + ") is expected to be 2");
/* Convert:
* leftO between rightOList.elementAt(0) and rightOList.elementAt(1)
* to:
* leftO >= rightOList.elementAt(0) and leftO <= rightOList.elementAt(1)
*/
ContextManager cm = getContextManager();
/* leftO >= rightOList.elementAt(0) */
leftBCO = new BinaryRelationalOperatorNode(BinaryRelationalOperatorNode.K_GREATER_EQUALS, leftOperand, rightOperandList.elementAt(0), false, cm);
/* Set type info for the operator node */
leftBCO.bindComparisonOperator();
/* leftO <= rightOList.elementAt(1) */
rightBCO = new BinaryRelationalOperatorNode(BinaryRelationalOperatorNode.K_LESS_EQUALS, leftOperand, rightOperandList.elementAt(1), false, cm);
/* Set type info for the operator node */
rightBCO.bindComparisonOperator();
/* Create and return the AND */
newAnd = new AndNode(leftBCO, rightBCO, cm);
newAnd.postBindFixup();
newAnd.generateExpression(acb, mb);
}
use of org.apache.derby.iapi.services.context.ContextManager in project derby by apache.
the class BetweenOperatorNode method preprocess.
/**
* Preprocess an expression tree. We do a number of transformations
* here (including subqueries, IN lists, LIKE and BETWEEN) plus
* subquery flattening.
* NOTE: This is done before the outer ResultSetNode is preprocessed.
*
* @param numTables Number of tables in the DML Statement
* @param outerFromList FromList from outer query block
* @param outerSubqueryList SubqueryList from outer query block
* @param outerPredicateList PredicateList from outer query block
*
* @return The modified expression
*
* @exception StandardException Thrown on error
*/
@Override
ValueNode preprocess(int numTables, FromList outerFromList, SubqueryList outerSubqueryList, PredicateList outerPredicateList) throws StandardException {
ValueNode leftClone1;
ValueNode rightOperand;
/* We must 1st preprocess the component parts */
super.preprocess(numTables, outerFromList, outerSubqueryList, outerPredicateList);
/* This is where we do the transformation for BETWEEN to make it optimizable.
* c1 BETWEEN value1 AND value2 -> c1 >= value1 AND c1 <= value2
* This transformation is only done if the leftOperand is a ColumnReference.
*/
if (!(leftOperand instanceof ColumnReference)) {
return this;
}
/* For some unknown reason we need to clone the leftOperand if it is
* a ColumnReference because reusing them in Qualifiers for a scan
* does not work.
*/
leftClone1 = leftOperand.getClone();
/* The transformed tree has to be normalized:
* AND
* / \
* >= AND
* / \
* <= TRUE
*/
ContextManager cm = getContextManager();
BooleanConstantNode trueNode = new BooleanConstantNode(true, cm);
/* Create the AND <= */
BinaryComparisonOperatorNode lessEqual = new BinaryRelationalOperatorNode(BinaryRelationalOperatorNode.K_LESS_EQUALS, leftClone1, rightOperandList.elementAt(1), false, cm);
/* Set type info for the operator node */
lessEqual.bindComparisonOperator();
/* Create the AND */
AndNode newAnd = new AndNode(lessEqual, trueNode, cm);
newAnd.postBindFixup();
/* Create the AND >= */
BinaryComparisonOperatorNode greaterEqual = new BinaryRelationalOperatorNode(BinaryRelationalOperatorNode.K_GREATER_EQUALS, leftOperand, rightOperandList.elementAt(0), false, cm);
/* Set type info for the operator node */
greaterEqual.bindComparisonOperator();
/* Create the AND */
newAnd = new AndNode(greaterEqual, newAnd, cm);
newAnd.postBindFixup();
/* Tell optimizer to use the between selectivity instead of >= * <= selectivities */
lessEqual.setBetweenSelectivity();
greaterEqual.setBetweenSelectivity();
return newAnd;
}
use of org.apache.derby.iapi.services.context.ContextManager in project derby by apache.
the class GenericLanguageConnectionContext method resetSavepoints.
/**
* Reset all statement savepoints. Traverses the StatementContext
* stack from bottom to top, calling resetSavePoint()
* on each element.
*
* @exception StandardException thrown if something goes wrong
*/
private void resetSavepoints() throws StandardException {
final ContextManager cm = getContextManager();
final List<Context> stmts = cm.getContextStack(ContextId.LANG_STATEMENT);
for (Context c : stmts) {
((StatementContext) c).resetSavePoint();
}
}
Aggregations