📄 querytranslatorimpl.java
字号:
parser.getParseErrorHandler().throwQueryException();
return parser;
}
void showHqlAst(AST hqlAst) {
if ( AST_LOG.isDebugEnabled() ) {
ASTPrinter printer = new ASTPrinter( HqlTokenTypes.class );
printer.setShowClassNames( false ); // The class names aren't interesting in the first tree.
AST_LOG.debug( printer.showAsString( hqlAst, "--- HQL AST ---" ) );
}
}
private void errorIfDML() throws HibernateException {
if ( sqlAst.needsExecutor() ) {
throw new HibernateException( "Not supported for DML operations" );
}
}
private void errorIfSelect() throws HibernateException {
if ( !sqlAst.needsExecutor() ) {
throw new HibernateException( "Not supported for select queries" );
}
}
public String getQueryIdentifier() {
return queryIdentifier;
}
public Statement getSqlAST() {
return sqlAst;
}
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();
return queryLoader.list( session, queryParameters );
}
/**
* 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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -