generationClauseNode = cdn.getGenerationClauseNode();
// bind the generation clause
final int previousReliability = cc.getReliability();
ProviderList prevAPL = cc.getCurrentAuxiliaryProviderList();
try
{
/* Each generation clause can have its own set of dependencies.
* These dependencies need to be shared with the prepared
* statement as well. We create a new auxiliary provider list
* for the generation clause, "push" it on the compiler context
* by swapping it with the current auxiliary provider list
* and the "pop" it when we're done by restoring the old
* auxiliary provider list.
*/
ProviderList apl = new ProviderList();
cc.setCurrentAuxiliaryProviderList(apl);
// Tell the compiler context to forbid subqueries and
// non-deterministic functions.
cc.setReliability( CompilerContext.GENERATION_CLAUSE_RESTRICTION );
generationTree = generationClauseNode.bindExpression(fromList, (SubqueryList) null,
aggregateVector);
//
// If the user did not declare a type for this column, then the column type defaults
// to the type of the generation clause.
// However, if the user did declare a type for this column, then the
// type of the generation clause must be assignable to the declared
// type.
//
DataTypeDescriptor generationClauseType = generationTree.getTypeServices();
DataTypeDescriptor declaredType = cdn.getType();
if ( declaredType == null )
{
cdn.setType( generationClauseType );
//
// Poke the type into the FromTable so that constraints will
// compile.
//
tableColumns.getResultColumn( cdn.getColumnName(), false ).setType( generationClauseType );
//
// We skipped these steps earlier on because we didn't have
// a datatype. Now that we have a datatype, revisit these
// steps.
//
setCollationTypeOnCharacterStringColumn( sd, cdn );
cdn.checkUserType( table.getTableDescriptor() );
}
else
{
TypeId declaredTypeId = declaredType.getTypeId();
TypeId resolvedTypeId = generationClauseType.getTypeId();
if ( !getTypeCompiler( resolvedTypeId ).convertible( declaredTypeId, false ) )
{
throw StandardException.newException
( SQLState.LANG_UNASSIGNABLE_GENERATION_CLAUSE, cdn.getName(), resolvedTypeId.getSQLTypeName() );
}
}
// no aggregates, please
if (aggregateVector.size() != 0)
{
throw StandardException.newException( SQLState.LANG_AGGREGATE_IN_GENERATION_CLAUSE, cdn.getName());
}
/* Save the APL off in the constraint node */
if (apl.size() > 0)
{
generationClauseNode.setAuxiliaryProviderList(apl);
}
}