FileDocCategorySizeDatePackage
AssignmentSpecification.javaAPI DocHibernate 3.2.54751Fri Sep 30 12:54:42 BST 2005org.hibernate.hql.ast.tree

AssignmentSpecification

public class AssignmentSpecification extends Object
Encapsulates the information relating to an individual assignment within the set clause of an HQL update statement. This information is used during execution of the update statements when the updates occur against "multi-table" stuff.
author
Steve Ebersole

Fields Summary
private final Set
tableNames
private final org.hibernate.param.ParameterSpecification[]
hqlParameters
private final antlr.collections.AST
eq
private final org.hibernate.engine.SessionFactoryImplementor
factory
private String
sqlAssignmentString
Constructors Summary
public AssignmentSpecification(antlr.collections.AST eq, org.hibernate.persister.entity.Queryable persister)

		if ( eq.getType() != HqlSqlTokenTypes.EQ ) {
			throw new QueryException( "assignment in set-clause not associated with equals" );
		}

		this.eq = eq;
		this.factory = persister.getFactory();

		// Needed to bump this up to DotNode, because that is the only thing which currently
		// knows about the property-ref path in the correct format; it is either this, or
		// recurse over the DotNodes constructing the property path just like DotNode does
		// internally
		DotNode lhs = ( DotNode ) eq.getFirstChild();
		SqlNode rhs = ( SqlNode ) lhs.getNextSibling();

		validateLhs( lhs );

		final String propertyPath = lhs.getPropertyPath();
		Set temp = new HashSet();
		// yuck!
		if ( persister instanceof UnionSubclassEntityPersister ) {
			UnionSubclassEntityPersister usep = ( UnionSubclassEntityPersister ) persister;
			String[] tables = persister.getConstraintOrderedTableNameClosure();
			int size = tables.length;
			for ( int i = 0; i < size; i ++ ) {
				temp.add( tables[i] );
			}
		}
		else {
			temp.add(
					persister.getSubclassTableName( persister.getSubclassPropertyTableNumber( propertyPath ) )
			);
		}
		this.tableNames = Collections.unmodifiableSet( temp );

		if (rhs==null) {
			hqlParameters = new ParameterSpecification[0];
		}
		else if ( isParam( rhs ) ) {
			hqlParameters = new ParameterSpecification[] { ( ( ParameterNode ) rhs ).getHqlParameterSpecification() };
		}
		else {
			List parameterList = ASTUtil.collectChildren(
			        rhs,
			        new ASTUtil.IncludePredicate() {
				        public boolean include(AST node) {
					        return isParam( node );
			            }
			        }
			);
			hqlParameters = new ParameterSpecification[ parameterList.size() ];
			Iterator itr = parameterList.iterator();
			int i = 0;
			while( itr.hasNext() ) {
				hqlParameters[i++] = ( ( ParameterNode ) itr.next() ).getHqlParameterSpecification();
			}
		}
	
Methods Summary
public booleanaffectsTable(java.lang.String tableName)

		return this.tableNames.contains( tableName );
	
public org.hibernate.param.ParameterSpecification[]getParameters()

		return hqlParameters;
	
public java.lang.StringgetSqlAssignmentFragment()

		if ( sqlAssignmentString == null ) {
			try {
				SqlGenerator sqlGenerator = new SqlGenerator( factory );
				sqlGenerator.comparisonExpr( eq, false );  // false indicates to not generate parens around the assignment
				sqlAssignmentString = sqlGenerator.getSQL();
			}
			catch( Throwable t ) {
				throw new QueryException( "cannot interpret set-clause assignment" );
			}
		}
		return sqlAssignmentString;
	
private static booleanisParam(antlr.collections.AST node)

		return node.getType() == HqlSqlTokenTypes.PARAM || node.getType() == HqlSqlTokenTypes.NAMED_PARAM;
	
private voidvalidateLhs(FromReferenceNode lhs)

		// make sure the lhs is "assignable"...
		if ( !lhs.isResolved() ) {
			throw new UnsupportedOperationException( "cannot validate assignablity of unresolved node" );
		}

		if ( lhs.getDataType().isCollectionType() ) {
			throw new QueryException( "collections not assignable in update statements" );
		}
		else if ( lhs.getDataType().isComponentType() ) {
			throw new QueryException( "Components currently not assignable in update statements" );
		}
		else if ( lhs.getDataType().isEntityType() ) {
			// currently allowed...
		}

		// TODO : why aren't these the same?
		if ( lhs.getImpliedJoin() != null || lhs.getFromElement().isImplied() ) {
			throw new QueryException( "Implied join paths are not assignable in update statements" );
		}