📄 querytranslatorimpl.java
字号:
private HqlSqlWalker getWalker() { return sqlAst.getWalker(); } /** * Types of the return values of an <tt>iterate()</tt> style query. * * @return an array of <tt>Type</tt>s. */ public Type[] getReturnTypes() { errorIfDML(); return getWalker().getReturnTypes(); } public String[] getReturnAliases() { errorIfDML(); return getWalker().getReturnAliases(); } public String[][] getColumnNames() { errorIfDML(); return getWalker().getSelectClause().getColumnNames(); } public Set getQuerySpaces() { return getWalker().getQuerySpaces(); } public List list(SessionImplementor session, QueryParameters queryParameters) throws HibernateException { // Delegate to the QueryLoader... errorIfDML(); QueryNode query = ( QueryNode ) sqlAst; boolean hasLimit = queryParameters.getRowSelection() != null && queryParameters.getRowSelection().definesLimits(); boolean needsDistincting = ( query.getSelectClause().isDistinct() || hasLimit ) && containsCollectionFetches(); QueryParameters queryParametersToUse; if ( hasLimit && containsCollectionFetches() ) { log.warn( "firstResult/maxResults specified with collection fetch; applying in memory!" ); RowSelection selection = new RowSelection(); selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() ); selection.setTimeout( queryParameters.getRowSelection().getTimeout() ); queryParametersToUse = queryParameters.createCopyUsing( selection ); } else { queryParametersToUse = queryParameters; } List results = queryLoader.list( session, queryParametersToUse ); if ( needsDistincting ) { int includedCount = -1; // NOTE : firstRow is zero-based int first = !hasLimit || queryParameters.getRowSelection().getFirstRow() == null ? 0 : queryParameters.getRowSelection().getFirstRow().intValue(); int max = !hasLimit || queryParameters.getRowSelection().getMaxRows() == null ? -1 : queryParameters.getRowSelection().getMaxRows().intValue(); int size = results.size(); List tmp = new ArrayList(); IdentitySet distinction = new IdentitySet(); for ( int i = 0; i < size; i++ ) { final Object result = results.get( i ); if ( !distinction.add( result ) ) { continue; } includedCount++; if ( includedCount < first ) { continue; } tmp.add( result ); // NOTE : ( max - 1 ) because first is zero-based while max is not... if ( max >= 0 && ( includedCount - first ) >= ( max - 1 ) ) { break; } } results = tmp; } return results; } /** * Return the query results as an iterator */ public Iterator iterate(QueryParameters queryParameters, EventSource session) throws HibernateException { // Delegate to the QueryLoader... errorIfDML(); return queryLoader.iterate( queryParameters, session ); } /** * Return the query results, as an instance of <tt>ScrollableResults</tt> */ public ScrollableResults scroll(QueryParameters queryParameters, SessionImplementor session) throws HibernateException { // Delegate to the QueryLoader... errorIfDML(); return queryLoader.scroll( queryParameters, session ); } public int executeUpdate(QueryParameters queryParameters, SessionImplementor session) throws HibernateException { errorIfSelect(); return statementExecutor.execute( queryParameters, session ); } /** * The SQL query string to be called; implemented by all subclasses */ public String getSQLString() { return sql; } public List collectSqlStrings() { ArrayList list = new ArrayList(); if ( isManipulationStatement() ) { String[] sqlStatements = statementExecutor.getSqlStatements(); for ( int i = 0; i < sqlStatements.length; i++ ) { list.add( sqlStatements[i] ); } } else { list.add( sql ); } return list; } // -- Package local methods for the QueryLoader delegate -- public boolean isShallowQuery() { return shallowQuery; } public String getQueryString() { return hql; } public Map getEnabledFilters() { return enabledFilters; } public int[] getNamedParameterLocs(String name) { return getWalker().getNamedParameterLocations( name ); } public boolean containsCollectionFetches() { errorIfDML(); List collectionFetches = ( ( QueryNode ) sqlAst ).getFromClause().getCollectionFetches(); return collectionFetches != null && collectionFetches.size() > 0; } public boolean isManipulationStatement() { return sqlAst.needsExecutor(); } public void validateScrollability() throws HibernateException { // Impl Note: allows multiple collection fetches as long as the // entire fecthed graph still "points back" to a single // root entity for return errorIfDML(); QueryNode query = ( QueryNode ) sqlAst; // If there are no collection fetches, then no further checks are needed List collectionFetches = query.getFromClause().getCollectionFetches(); if ( collectionFetches.isEmpty() ) { return; } // A shallow query is ok (although technically there should be no fetching here...) if ( isShallowQuery() ) { return; } // Otherwise, we have a non-scalar select with defined collection fetch(es). // Make sure that there is only a single root entity in the return (no tuples) if ( getReturnTypes().length > 1 ) { throw new HibernateException( "cannot scroll with collection fetches and returned tuples" ); } FromElement owner = null; Iterator itr = query.getSelectClause().getFromElementsForLoad().iterator(); while ( itr.hasNext() ) { // should be the first, but just to be safe... final FromElement fromElement = ( FromElement ) itr.next(); if ( fromElement.getOrigin() == null ) { owner = fromElement; break; } } if ( owner == null ) { throw new HibernateException( "unable to locate collection fetch(es) owner for scrollability checks" ); } // This is not strictly true. We actually just need to make sure that // it is ordered by root-entity PK and that that order-by comes before // any non-root-entity ordering... AST primaryOrdering = query.getOrderByClause().getFirstChild(); if ( primaryOrdering != null ) { // TODO : this is a bit dodgy, come up with a better way to check this (plus see above comment) String [] idColNames = owner.getQueryable().getIdentifierColumnNames(); String expectedPrimaryOrderSeq = StringHelper.join( ", ", StringHelper.qualify( owner.getTableAlias(), idColNames ) ); if ( !primaryOrdering.getText().startsWith( expectedPrimaryOrderSeq ) ) { throw new HibernateException( "cannot scroll results with collection fetches which are not ordered primarily by the root entity's PK" ); } } } private StatementExecutor buildAppropriateStatementExecutor(HqlSqlWalker walker) { Statement statement = ( Statement ) walker.getAST(); if ( walker.getStatementType() == HqlSqlTokenTypes.DELETE ) { FromElement fromElement = walker.getFinalFromClause().getFromElement(); Queryable persister = fromElement.getQueryable(); if ( persister.isMultiTable() ) { return new MultiTableDeleteExecutor( walker ); } else { return new BasicExecutor( walker, persister ); } } else if ( walker.getStatementType() == HqlSqlTokenTypes.UPDATE ) { FromElement fromElement = walker.getFinalFromClause().getFromElement(); Queryable persister = fromElement.getQueryable(); if ( persister.isMultiTable() ) { // even here, if only properties mapped to the "base table" are referenced // in the set and where clauses, this could be handled by the BasicDelegate. // TODO : decide if it is better performance-wise to perform that check, or to simply use the MultiTableUpdateDelegate return new MultiTableUpdateExecutor( walker ); } else { return new BasicExecutor( walker, persister ); } } else if ( walker.getStatementType() == HqlSqlTokenTypes.INSERT ) { return new BasicExecutor( walker, ( ( InsertStatement ) statement ).getIntoClause().getQueryable() ); } else { throw new QueryException( "Unexpected statement type" ); } } public ParameterTranslations getParameterTranslations() { if ( paramTranslations == null ) { paramTranslations = new ParameterTranslationsImpl( getWalker().getParameters() ); } return paramTranslations; } public static class JavaConstantConverter implements NodeTraverser.VisitationStrategy { private AST dotRoot; public void visit(AST node) { if ( dotRoot != null ) { // we are already processing a dot-structure if ( ASTUtil.isSubtreeChild( dotRoot, node ) ) { // igndore it... return; } else { // we are now at a new tree level dotRoot = null; } } if ( dotRoot == null && node.getType() == HqlTokenTypes.DOT ) { dotRoot = node; handleDotStructure( dotRoot ); } } private void handleDotStructure(AST dotStructureRoot) { String expression = ASTUtil.getPathText( dotStructureRoot ); Object constant = ReflectHelper.getConstantValue( expression ); if ( constant != null ) { dotStructureRoot.setFirstChild( null ); dotStructureRoot.setType( HqlTokenTypes.JAVA_CONSTANT ); dotStructureRoot.setText( expression ); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -