protected AST createFromFilterElement(AST filterEntity, AST alias) throws SemanticException {
   FromElement fromElement = currentFromClause.addFromElement(filterEntity.getText(), alias);
   FromClause fromClause = fromElement.getFromClause();
   QueryableCollection persister =
       sessionFactoryHelper.getCollectionPersister(filterCollectionRole);
   // Get the names of the columns used to link between the collection
   // owner and the collection elements.
   String[] keyColumnNames = persister.getKeyColumnNames();
   String fkTableAlias =
       persister.isOneToMany()
           ? fromElement.getTableAlias()
           : fromClause.getAliasGenerator().createName(filterCollectionRole);
   JoinSequence join = sessionFactoryHelper.createJoinSequence();
   join.setRoot(persister, fkTableAlias);
   if (!persister.isOneToMany()) {
     join.addJoin(
         (AssociationType) persister.getElementType(),
         fromElement.getTableAlias(),
         JoinFragment.INNER_JOIN,
         persister.getElementColumnNames(fkTableAlias));
   }
   join.addCondition(fkTableAlias, keyColumnNames, " = ?");
   fromElement.setJoinSequence(join);
   fromElement.setFilter(true);
   if (log.isDebugEnabled()) {
     log.debug("createFromFilterElement() : processed filter FROM element.");
   }
   return fromElement;
 }
    public void visit(AST node) {
      // todo : currently expects that the individual with expressions apply to the same sql table
      // join.
      //      This may not be the case for joined-subclass where the property values
      //      might be coming from different tables in the joined hierarchy.  At some
      //      point we should expand this to support that capability.  However, that has
      //      some difficulties:
      //          1) the biggest is how to handle ORs when the individual comparisons are
      //              linked to different sql joins.
      //          2) here we would need to track each comparison individually, along with
      //              the join alias to which it applies and then pass that information
      //              back to the FromElement so it can pass it along to the JoinSequence

      if (node instanceof DotNode) {
        DotNode dotNode = (DotNode) node;
        FromElement fromElement = dotNode.getFromElement();
        if (referencedFromElement != null) {
          if (fromElement != referencedFromElement) {
            throw new HibernateException(
                "with-clause referenced two different from-clause elements");
          }
        } else {
          referencedFromElement = fromElement;
          joinAlias = extractAppliedAlias(dotNode);
          // todo : temporary
          //      needed because currently persister is the one that
          //      creates and renders the join fragments for inheritence
          //      hierarchies...
          if (!joinAlias.equals(referencedFromElement.getTableAlias())) {
            throw new HibernateException(
                "with clause can only reference columns in the driving table");
          }
        }
      }
    }
  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, isSubQuery());

      // 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);
          }
          if (fromElement.getQueryableCollection().hasManyToManyOrdering()) {
            String orderByFragment =
                fromElement
                    .getQueryableCollection()
                    .getManyToManyOrderByString(fromElement.getTableAlias());
            qn.getOrderByClause().addOrderFragment(orderByFragment);
          }
        }
      }
    } finally {
      popFromClause();
    }
  }
  protected void postProcessDML(RestrictableStatement statement) throws SemanticException {
    statement.getFromClause().resolve();

    FromElement fromElement = (FromElement) statement.getFromClause().getFromElements().get(0);
    Queryable persister = fromElement.getQueryable();
    // Make #@%$^#^&# sure no alias is applied to the table name
    fromElement.setText(persister.getTableName());

    // append any filter fragments; the EMPTY_MAP is used under the assumption that
    // currently enabled filters should not affect this process
    if (persister.getDiscriminatorType() != null) {
      new SyntheticAndFactory(getASTFactory())
          .addDiscriminatorWhereFragment(
              statement, persister, java.util.Collections.EMPTY_MAP, fromElement.getTableAlias());
    }
  }