📄 hqlsqlwalker.java
字号:
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 rhs yet. dotNode.resolveFirstChild(); return dotNode; } } 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 ); // 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 ); } } } } finally { popFromClause(); } } protected void postProcessUpdate(AST update) throws SemanticException { QueryNode qn = ( QueryNode ) update; FromClause fromClause = qn.getFromClause(); fromClause.resolve(); // For now, validate that the FROM clause did not reference any // form of subclass... FromElement fromElement = ( FromElement ) fromClause.getFromElements().get( 0 ); Queryable persister = fromElement.getQueryable(); // Make #@%$^#^&# sure no alias is applied to the table name fromElement.setText( persister.getTableName() ); // TODO : need a better way to do these checks if ( persister instanceof SingleTableEntityPersister ) { SingleTableEntityPersister step = ( SingleTableEntityPersister ) persister; new SyntheticAndFactory( getASTFactory() ) .addDiscriminatorWhereFragment( qn, step, fromElement.getTableAlias() ); } else { if ( persister.getMappedSuperclass() != null ) { // TODO : add support for spawning potential multiple sql updates for these cases... // for now, just error as unsupported... throw new QueryException( "Update statements against joined or union subclasses not yet supported!" ); } } } protected void postProcessDelete(AST delete) throws SemanticException { QueryNode qn = ( QueryNode ) delete; FromClause fromClause = qn.getFromClause(); fromClause.resolve(); // For now, validate that the FROM clause did not reference any // form of subclass... FromElement fromElement = ( FromElement ) fromClause.getFromElements().get( 0 ); Queryable persister = fromElement.getQueryable(); // Make #@%$^#^&# sure no alias is applied to the table name fromElement.setText( persister.getTableName() ); // TODO : need a better way to do these checks if ( persister instanceof SingleTableEntityPersister ) { SingleTableEntityPersister step = ( SingleTableEntityPersister ) persister; new SyntheticAndFactory( getASTFactory() ) .addDiscriminatorWhereFragment( qn, step, fromElement.getTableAlias() ); } else { if ( persister.getMappedSuperclass() != null ) { // TODO : add support for spawning potential multiple sql deletes for these cases... // for now, just error as unsupported... throw new QueryException( "Delete statements against joined or union subclasses not yet supported!" ); } } } private void useSelectClause(AST select) throws SemanticException { selectClause = ( SelectClause ) select; selectClause.initializeExplicitSelectClause( currentFromClause ); } private void createSelectClauseFromFromClause(QueryNode qn) throws SemanticException { AST select = astFactory.create( SELECT_CLAUSE, "{derived select clause}" ); AST sibling = qn.getFromClause(); qn.setFirstChild( select ); select.setNextSibling( sibling ); selectClause = ( SelectClause ) select; selectClause.initializeDerivedSelectClause( currentFromClause ); if ( log.isDebugEnabled() ) { log.debug( "Derived SELECT clause created." ); } } protected void resolve(AST node) throws SemanticException { if ( node != null ) { // This is called when it's time to fully resolve a path expression. ResolvableNode r = ( ResolvableNode ) node; if ( isInFunctionCall() ) { r.resolveInFunctionCall( false, true ); } else { r.resolve( false, true ); // Generate implicit joins, only if necessary. } } } protected void resolveSelectExpression(AST node) throws SemanticException { // This is called when it's time to fully resolve a path expression. int type = node.getType(); switch ( type ) { case DOT: DotNode dot = ( DotNode ) node; dot.resolveSelectExpression( useThetaStyleImplicitJoins ); break; case ALIAS_REF: // Notify the FROM element that it is being referenced by the select. FromReferenceNode aliasRefNode = ( FromReferenceNode ) node; //aliasRefNode.resolve( false, false, aliasRefNode.getText() ); //TODO: is it kosher to do it here? aliasRefNode.resolve( false, false ); //TODO: is it kosher to do it here? FromElement fromElement = aliasRefNode.getFromElement(); if ( fromElement != null ) { fromElement.setIncludeSubclasses( true ); } default: break; } } protected void beforeSelectClause() throws SemanticException { // Turn off includeSubclasses on all FromElements. FromClause from = getCurrentFromClause(); List fromElements = from.getFromElements(); for ( Iterator iterator = fromElements.iterator(); iterator.hasNext(); ) { FromElement fromElement = ( FromElement ) iterator.next(); fromElement.setIncludeSubclasses( false ); } } protected void positionalParameter(AST parameter) throws SemanticException { if ( namedParameters.size() > 0 ) { throw new SemanticException( "" ); } } private void addNamedParameter(String name) { Integer loc = new Integer( parameterCount++ ); Object o = namedParameters.get( name ); if ( o == null ) { namedParameters.put( name, loc ); } else if ( o instanceof Integer ) { ArrayList list = new ArrayList( 4 ); list.add( o ); list.add( loc ); namedParameters.put( name, list ); } else { ( ( ArrayList ) o ).add( loc ); } } protected void processConstant(AST constant) throws SemanticException { literalProcessor.processConstant( constant ); // Use the delegate. } protected void processBoolean(AST constant) throws SemanticException { literalProcessor.processBoolean( constant ); // Use the delegate. } protected void processIndex(AST indexOp) throws SemanticException { IndexNode indexNode = ( IndexNode ) indexOp; indexNode.resolve( true, true ); } protected void processFunction(AST functionCall, boolean inSelect) throws SemanticException { MethodNode methodNode = ( MethodNode ) functionCall; methodNode.resolve( inSelect ); } protected void processConstructor(AST constructor) throws SemanticException { ConstructorNode constructorNode = ( ConstructorNode ) constructor; constructorNode.prepare(); } protected void namedParameter(AST namedParameter) throws SemanticException { addNamedParameter( namedParameter.getText() ); namedParameter.setText( "?" ); // Named HQL parameters translate into SQL '?' parameters. } /** * Returns the locations of all occurrences of the named parameter. */ int[] getNamedParameterLocs(String name) throws QueryException { Object o = namedParameters.get( name ); if ( o == null ) { QueryException qe = new QueryException( QueryTranslator.ERROR_NAMED_PARAMETER_DOES_NOT_APPEAR + name ); qe.setQueryString( queryTranslatorImpl.getQueryString() ); throw qe; } if ( o instanceof Integer ) { return new int[]{( ( Integer ) o ).intValue()}; } else { return ArrayHelper.toIntArray( ( ArrayList ) o ); } } void addQuerySpaces(Serializable[] spaces) { for ( int i = 0; i < spaces.length; i++ ) { querySpaces.add( spaces[i] ); } } public Type[] getReturnTypes() { return selectClause.getQueryReturnTypes(); } public String[] getReturnAliases() { return selectClause.getQueryReturnAliases(); } public boolean isSubQuery() { return currentFromClause != null ? currentFromClause.isSubQuery() : false; } public SelectClause getSelectClause() { return selectClause; } public boolean isShallowQuery() { return queryTranslatorImpl.isShallowQuery(); } public Map getEnabledFilters() { return queryTranslatorImpl.getEnabledFilters(); } LiteralProcessor getLiteralProcessor() { return literalProcessor; } ASTPrinter getASTPrinter() { return printer; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -