⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hqlsqlwalker.java

📁 一个Java持久层类库
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
			fromElement.setWithClauseFragment( visitor.getJoinAlias(), "(" + sql.getSQL() + ")" );		}		catch( SemanticException e ) {			throw e;		}		catch( InvalidWithClauseException e ) {			throw e;		}		catch ( Exception e) {			throw new SemanticException( e.getMessage() );		}	}	private static class WithClauseVisitor implements NodeTraverser.VisitationStrategy {		private FromElement referencedFromElement;		private String joinAlias;		public void visit(AST node) {			// todo : currently expects that the individual with expressions apply to the same sql table join.			//      This may not be the case for joined-subclass where the property values			//      might be coming from different tables in the joined hierarchy.  At some			//      point we should expand this to support that capability.  However, that has			//      some difficulties:			//          1) the biggest is how to handle ORs when the individual comparisons are			//              linked to different sql joins.			//          2) here we would need to track each comparison individually, along with			//              the join alias to which it applies and then pass that information			//              back to the FromElement so it can pass it along to the JoinSequence			if ( node instanceof DotNode ) {				DotNode dotNode = ( DotNode ) node;				FromElement fromElement = dotNode.getFromElement();				if ( referencedFromElement != null ) {					if ( fromElement != referencedFromElement ) {						throw new HibernateException( "with-clause referenced two different from-clause elements" );					}				}				else {					referencedFromElement = fromElement;					joinAlias = extractAppliedAlias( dotNode );					// todo : temporary					//      needed because currently persister is the one that					//      creates and renders the join fragments for inheritence					//      hierarchies...					if ( !joinAlias.equals( referencedFromElement.getTableAlias() ) ) {						throw new InvalidWithClauseException( "with clause can only reference columns in the driving table" );					}				}			}		}		private String extractAppliedAlias(DotNode dotNode) {			return dotNode.getText().substring( 0, dotNode.getText().indexOf( '.' ) );		}		public FromElement getReferencedFromElement() {			return referencedFromElement;		}		public String getJoinAlias() {			return joinAlias;		}	}	/**	 * Sets the current 'FROM' context.	 *	 * @param fromNode      The new 'FROM' context.	 * @param inputFromNode The from node from the input AST.	 */	protected void pushFromClause(AST fromNode, AST inputFromNode) {		FromClause newFromClause = ( FromClause ) fromNode;		newFromClause.setParentFromClause( currentFromClause );		currentFromClause = newFromClause;	}	/**	 * Returns to the previous 'FROM' context.	 */	private void popFromClause() {		currentFromClause = currentFromClause.getParentFromClause();	}	protected void lookupAlias(AST aliasRef)			throws SemanticException {		FromElement alias = currentFromClause.getFromElement( aliasRef.getText() );		FromReferenceNode aliasRefNode = ( FromReferenceNode ) aliasRef;		aliasRefNode.setFromElement( alias );	}	protected void setImpliedJoinType(int joinType) {		impliedJoinType = JoinProcessor.toHibernateJoinType( joinType );	}	public int getImpliedJoinType() {		return impliedJoinType;	}	protected AST lookupProperty(AST dot, boolean root, boolean inSelect) throws SemanticException {		DotNode dotNode = ( DotNode ) dot;		FromReferenceNode lhs = dotNode.getLhs();		AST rhs = lhs.getNextSibling();		switch ( rhs.getType() ) {			case SqlTokenTypes.ELEMENTS:			case SqlTokenTypes.INDICES:				if ( log.isDebugEnabled() ) {					log.debug( "lookupProperty() " + dotNode.getPath() + " => " + rhs.getText() + "(" + lhs.getPath() + ")" );				}				CollectionFunction f = ( CollectionFunction ) rhs;				// Re-arrange the tree so that the collection function is the root and the lhs is the path.				f.setFirstChild( lhs );				lhs.setNextSibling( null );				dotNode.setFirstChild( f );				resolve( lhs );			// Don't forget to resolve the argument!				f.resolve( inSelect );	// Resolve the collection function now.				return f;			default:				// Resolve everything up to this dot, but don't resolve the placeholders yet.				dotNode.resolveFirstChild();				return dotNode;		}	}	protected boolean isNonQualifiedPropertyRef(AST ident) {		final String identText = ident.getText();		if ( currentFromClause.isFromElementAlias( identText ) ) {			return false;		}		List fromElements = currentFromClause.getExplicitFromElements();		if ( fromElements.size() == 1 ) {			final FromElement fromElement = ( FromElement ) fromElements.get( 0 );			try {				log.trace( "attempting to resolve property [" + identText + "] as a non-qualified ref" );				return fromElement.getPropertyMapping( identText ).toType( identText ) != null;			}			catch( QueryException e ) {				// Should mean that no such property was found			}		}		return false;	}	protected AST lookupNonQualifiedProperty(AST property) throws SemanticException {		final FromElement fromElement = ( FromElement ) currentFromClause.getExplicitFromElements().get( 0 );		AST syntheticDotNode = generateSyntheticDotNodeForNonQualifiedPropertyRef( property, fromElement );		return lookupProperty( syntheticDotNode, false, getCurrentClauseType() == HqlSqlTokenTypes.SELECT );	}	private AST generateSyntheticDotNodeForNonQualifiedPropertyRef(AST property, FromElement fromElement) {		AST dot = getASTFactory().create( DOT, "{non-qualified-property-ref}" );		// TODO : better way?!?		( ( DotNode ) dot ).setPropertyPath( ( ( FromReferenceNode ) property ).getPath() );		IdentNode syntheticAlias = ( IdentNode ) getASTFactory().create( IDENT, "{synthetic-alias}" );		syntheticAlias.setFromElement( fromElement );		syntheticAlias.setResolved();		dot.setFirstChild( syntheticAlias );		dot.addChild( property );		return dot;	}	protected void processQuery(AST select, AST query) throws SemanticException {		if ( log.isDebugEnabled() ) {			log.debug( "processQuery() : " + query.toStringTree() );		}		try {			QueryNode qn = ( QueryNode ) query;			// Was there an explicit select expression?			boolean explicitSelect = select != null && select.getNumberOfChildren() > 0;			if ( !explicitSelect ) {				// No explicit select expression; render the id and properties				// projection lists for every persister in the from clause into				// a single 'token node'.				//TODO: the only reason we need this stuff now is collection filters,				//      we should get rid of derived select clause completely!				createSelectClauseFromFromClause( qn );			}			else {				// Use the explicitly declared select expression; determine the				// return types indicated by each select token				useSelectClause( select );			}			// After that, process the JOINs.			// Invoke a delegate to do the work, as this is farily complex.			JoinProcessor joinProcessor = new JoinProcessor( astFactory, queryTranslatorImpl );			joinProcessor.processJoins( qn, isSubQuery() );			// Attach any mapping-defined "ORDER BY" fragments			Iterator itr = qn.getFromClause().getProjectionList().iterator();			while ( itr.hasNext() ) {				final FromElement fromElement = ( FromElement ) itr.next();//			if ( fromElement.isFetch() && fromElement.isCollectionJoin() ) {				if ( fromElement.isFetch() && fromElement.getQueryableCollection() != null ) {					// Does the collection referenced by this FromElement					// specify an order-by attribute?  If so, attach it to					// the query's order-by					if ( fromElement.getQueryableCollection().hasOrdering() ) {						String orderByFragment = fromElement								.getQueryableCollection()								.getSQLOrderByString( fromElement.getCollectionTableAlias() );						qn.getOrderByClause().addOrderFragment( orderByFragment );					}					if ( fromElement.getQueryableCollection().hasManyToManyOrdering() ) {						String orderByFragment = fromElement.getQueryableCollection()								.getManyToManyOrderByString( fromElement.getTableAlias() );						qn.getOrderByClause().addOrderFragment( orderByFragment );					}				}			}		}		finally {			popFromClause();		}	}	protected void postProcessDML(RestrictableStatement statement) throws SemanticException {		statement.getFromClause().resolve();		FromElement fromElement = ( FromElement ) statement.getFromClause().getFromElements().get( 0 );		Queryable persister = fromElement.getQueryable();		// Make #@%$^#^&# sure no alias is applied to the table name		fromElement.setText( persister.getTableName() );		// append any filter fragments; the EMPTY_MAP is used under the assumption that		// currently enabled filters should not affect this process		if ( persister.getDiscriminatorType() != null ) {			new SyntheticAndFactory( getASTFactory() ).addDiscriminatorWhereFragment(			        statement,			        persister,			        java.util.Collections.EMPTY_MAP,			        fromElement.getTableAlias()			);		}	}	protected void postProcessUpdate(AST update) throws SemanticException {		UpdateStatement updateStatement = ( UpdateStatement ) update;		postProcessDML( updateStatement );	}	protected void postProcessDelete(AST delete) throws SemanticException {		postProcessDML( ( DeleteStatement ) delete );	}	public static boolean supportsIdGenWithBulkInsertion(IdentifierGenerator generator) {		return SequenceGenerator.class.isAssignableFrom( generator.getClass() )		        || PostInsertIdentifierGenerator.class.isAssignableFrom( generator.getClass() );	}	protected void postProcessInsert(AST insert) throws SemanticException, QueryException {		InsertStatement insertStatement = ( InsertStatement ) insert;		insertStatement.validate();		SelectClause selectClause = insertStatement.getSelectClause();		Queryable persister = insertStatement.getIntoClause().getQueryable();		if ( !insertStatement.getIntoClause().isExplicitIdInsertion() ) {			// We need to generate ids as part of this bulk insert.			//			// Note that this is only supported for sequence-style generators and			// post-insert-style generators; basically, only in-db generators			IdentifierGenerator generator = persister.getIdentifierGenerator();			if ( !supportsIdGenWithBulkInsertion( generator ) ) {				throw new QueryException( "can only generate ids as part of bulk insert with either sequence or post-insert style generators" );			}			AST idSelectExprNode = null;			if ( SequenceGenerator.class.isAssignableFrom( generator.getClass() ) ) {				String seqName = ( String ) ( ( SequenceGenerator ) generator ).generatorKey();				String nextval = sessionFactoryHelper.getFactory().getDialect().getSelectSequenceNextValString( seqName );				idSelectExprNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, nextval );			}			else {				//Don't need this, because we should never ever be selecting no columns in an insert ... select...				//and because it causes a bug on DB2				/*String idInsertString = sessionFactoryHelper.getFactory().getDialect().getIdentityInsertString();				if ( idInsertString != null ) {					idSelectExprNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, idInsertString );				}*/			}			if ( idSelectExprNode != null ) {				AST currentFirstSelectExprNode = selectClause.getFirstChild();				selectClause.setFirstChild( idSelectExprNode );				idSelectExprNode.setNextSibling( currentFirstSelectExprNode );				insertStatement.getIntoClause().prependIdColumnSpec();			}		}		final boolean includeVersionProperty = persister.isVersioned() &&				!insertStatement.getIntoClause().isExplicitVersionInsertion() &&				persister.isVersionPropertyInsertable();		if ( includeVersionProperty ) {			// We need to seed the version value as part of this bulk insert			VersionType versionType = persister.getVersionType();			AST versionValueNode = null;			if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {				versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );				ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );				( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );				parameters.add( 0, paramSpec );			}			else {				if ( isIntegral( versionType ) ) {					try {						Object seedValue = versionType.seed( null );						versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString() );					}					catch( Throwable t ) {						throw new QueryException( "could not determine seed value for version on bulk insert [" + versionType + "]" );					}				}				else if ( isDatabaseGeneratedTimestamp( versionType ) ) {					String functionName = sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();					versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, functionName );				}				else {					throw new QueryException( "cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements" );				}			}			AST currentFirstSelectExprNode = selectClause.getFirstChild();			selectClause.setFirstChild( versionValueNode );			versionValueNode.setNextSibling( currentFirstSelectExprNode );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -