protected PlanNode attachCriteria ( final QueryContext context , PlanNode plan , Constraint constraint , List < ? extends Column > columns , Map < String , Subquery > subqueriesByVariableName ) { if ( constraint == null ) return plan ; context . getHints ( ) . hasCriteria = true ; // Extract the list of Constraint objects that all must be satisfied ... LinkedList < Constraint > andableConstraints = new LinkedList < Constraint > ( ) ; separateAndConstraints ( constraint , andableConstraints ) ; assert ! andableConstraints . isEmpty ( ) ; // Build up the map of aliases for the properties used in the criteria ... Map < String , String > propertyNameByAlias = new HashMap < String , String > ( ) ; for ( Column column : columns ) { if ( column . getColumnName ( ) != null && ! column . getColumnName ( ) . equals ( column . getPropertyName ( ) ) ) { propertyNameByAlias . put ( column . getColumnName ( ) , column . getPropertyName ( ) ) ; } } // For each of these constraints, create a criteria (SELECT) node above the supplied (JOIN or SOURCE) node. // Do this in reverse order so that the top-most SELECT node corresponds to the first constraint. while ( ! andableConstraints . isEmpty ( ) ) { Constraint criteria = andableConstraints . removeLast ( ) ; // Replace any subqueries with bind variables ... criteria = PlanUtil . replaceSubqueriesWithBindVariables ( context , criteria , subqueriesByVariableName ) ; // Replace any use of aliases with the actual properties ... criteria = PlanUtil . replaceAliasesWithProperties ( context , criteria , propertyNameByAlias ) ; // Create the select node ... PlanNode criteriaNode = new PlanNode ( Type . SELECT ) ; criteriaNode . setProperty ( Property . SELECT_CRITERIA , criteria ) ; // Add selectors to the criteria node ... criteriaNode . addSelectors ( Visitors . getSelectorsReferencedBy ( criteria ) ) ; // Is there at least one full-text search or subquery ... Visitors . visitAll ( criteria , new Visitors . AbstractVisitor ( ) { @ Override public void visit ( FullTextSearch obj ) { context . getHints ( ) . hasFullTextSearch = true ; } } ) ; criteriaNode . addFirstChild ( plan ) ; plan = criteriaNode ; } if ( ! subqueriesByVariableName . isEmpty ( ) ) { context . getHints ( ) . hasSubqueries = true ; } return plan ; }
Attach all criteria above the join nodes . The optimizer will push these criteria down to the appropriate source .