public void AddWhereFragment( JoinFragment joinFragment, SqlString whereFragment, QueryNode query, FromElement fromElement, HqlSqlWalker hqlSqlWalker) { if (whereFragment == null) { return; } if (!fromElement.UseWhereFragment && !joinFragment.HasThetaJoins) { return; } whereFragment = whereFragment.Trim(); if (StringHelper.IsEmpty(whereFragment.ToString())) { return; } // Forcefully remove leading ands from where fragments; the grammar will // handle adding them if (whereFragment.StartsWithCaseInsensitive("and")) { whereFragment = whereFragment.Substring(4); } log.Debug("Using unprocessed WHERE-fragment [" + whereFragment + "]"); SqlFragment fragment = (SqlFragment)Create(HqlSqlWalker.SQL_TOKEN, whereFragment.ToString()); fragment.SetJoinFragment(joinFragment); fragment.FromElement = fromElement; if (fromElement.IndexCollectionSelectorParamSpec != null) { fragment.AddEmbeddedParameter(fromElement.IndexCollectionSelectorParamSpec); fromElement.IndexCollectionSelectorParamSpec = null; } if (hqlSqlWalker.IsFilter()) { //if (whereFragment.IndexOfCaseInsensitive("?") >= 0) if (whereFragment.ToString().IndexOf("?") >= 0) { IType collectionFilterKeyType = hqlSqlWalker.SessionFactoryHelper .RequireQueryableCollection(hqlSqlWalker.CollectionFilterRole) .KeyType; CollectionFilterKeyParameterSpecification paramSpec = new CollectionFilterKeyParameterSpecification( hqlSqlWalker.CollectionFilterRole, collectionFilterKeyType, 0 ); fragment.AddEmbeddedParameter(paramSpec); } } JoinProcessor.ProcessDynamicFilterParameters( whereFragment, fragment, hqlSqlWalker ); log.Debug("Using processed WHERE-fragment [" + fragment.Text + "]"); // Filter conditions need to be inserted before the HQL where condition and the // theta join node. This is because org.hibernate.loader.Loader binds the filter parameters first, // then it binds all the HQL query parameters, see org.hibernate.loader.Loader.processFilterParameters(). if (fragment.FromElement.IsFilter || fragment.HasFilterCondition) { if (_filters == null) { // Find or create the WHERE clause IASTNode where = (IASTNode)query.WhereClause; // Create a new FILTERS node as a parent of all filters _filters = Create(HqlSqlWalker.FILTERS, "{filter conditions}"); // Put the FILTERS node before the HQL condition and theta joins where.InsertChild(0, _filters); } // add the current fragment to the FILTERS node _filters.AddChild(fragment); } else { if (_thetaJoins == null) { // Find or create the WHERE clause IASTNode where = (IASTNode)query.WhereClause; // Create a new THETA_JOINS node as a parent of all filters _thetaJoins = Create(HqlSqlWalker.THETA_JOINS, "{theta joins}"); // Put the THETA_JOINS node before the HQL condition, after the filters. if (_filters == null) { where.InsertChild(0, _thetaJoins); } else { _filters.AddSibling(_thetaJoins); } } // add the current fragment to the THETA_JOINS node _thetaJoins.AddChild(fragment); } }
void ProcessQuery(IASTNode select, IASTNode query) { if ( log.IsDebugEnabled ) { log.Debug( "processQuery() : " + query.ToStringTree() ); } try { QueryNode qn = ( QueryNode ) query; // Was there an explicit select expression? bool explicitSelect = select != null && select.ChildCount > 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( this ); joinProcessor.ProcessJoins( qn ); // Attach any mapping-defined "ORDER BY" fragments foreach (FromElement fromElement in qn.FromClause.GetProjectionList()) { if ( fromElement.IsFetch && fromElement.QueryableCollection != 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.QueryableCollection.HasOrdering) { string orderByFragment = fromElement .QueryableCollection .GetSQLOrderByString( fromElement.TableAlias ); qn.GetOrderByClause().AddOrderFragment( orderByFragment ); } if ( fromElement.QueryableCollection.HasManyToManyOrdering ) { string orderByFragment = fromElement.QueryableCollection .GetManyToManyOrderByString( fromElement.TableAlias ); qn.GetOrderByClause().AddOrderFragment( orderByFragment ); } } } } finally { PopFromClause(); } }