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;
 }
 private FromElement createManyToMany(
     String role,
     String associatedEntityName,
     String roleAlias,
     Queryable entityPersister,
     EntityType type,
     int joinType)
     throws SemanticException {
   FromElement elem;
   SessionFactoryHelper sfh = fromClause.getSessionFactoryHelper();
   if (inElementsFunction /*implied*/) {
     // For implied many-to-many, just add the end join.
     JoinSequence joinSequence = createJoinSequence(roleAlias, joinType);
     elem = createJoin(associatedEntityName, roleAlias, joinSequence, type, true);
   } else {
     // For an explicit many-to-many relationship, add a second join from the intermediate
     // (many-to-many) table to the destination table.  Also, make sure that the from element's
     // idea of the destination is the destination table.
     String tableAlias =
         fromClause.getAliasGenerator().createName(entityPersister.getEntityName());
     String[] secondJoinColumns = sfh.getCollectionElementColumns(role, roleAlias);
     // Add the second join, the one that ends in the destination table.
     JoinSequence joinSequence = createJoinSequence(roleAlias, joinType);
     joinSequence.addJoin(
         sfh.getElementAssociationType(collectionType), tableAlias, joinType, secondJoinColumns);
     elem = createJoin(associatedEntityName, tableAlias, joinSequence, type, false);
     elem.setUseFromFragment(true);
   }
   return elem;
 }
  FromElement createEntityJoin(
      String entityClass,
      String tableAlias,
      JoinSequence joinSequence,
      boolean fetchFlag,
      boolean inFrom,
      EntityType type)
      throws SemanticException {
    FromElement elem = createJoin(entityClass, tableAlias, joinSequence, type, false);
    elem.setFetch(fetchFlag);
    EntityPersister entityPersister = elem.getEntityPersister();
    int numberOfTables = entityPersister.getQuerySpaces().length;
    if (numberOfTables > 1 && implied && !elem.useFromFragment()) {
      if (log.isDebugEnabled()) {
        log.debug("createEntityJoin() : Implied multi-table entity join");
      }
      elem.setUseFromFragment(true);
    }

    // If this is an implied join in a FROM clause, then use ANSI-style joining, and set the
    // flag on the FromElement that indicates that it was implied in the FROM clause itself.
    if (implied && inFrom) {
      joinSequence.setUseThetaStyle(false);
      elem.setUseFromFragment(true);
      elem.setImpliedInFromClause(true);
    }
    if (elem.getWalker().isSubQuery()) {
      // two conditions where we need to transform this to a theta-join syntax:
      //      1) 'elem' is the "root from-element" in correlated subqueries
      //      2) The DotNode.useThetaStyleImplicitJoins has been set to true
      //          and 'elem' represents an implicit join
      if (elem.getFromClause() != elem.getOrigin().getFromClause()
          ||
          //			        ( implied && DotNode.useThetaStyleImplicitJoins ) ) {
          DotNode.useThetaStyleImplicitJoins) {
        // the "root from-element" in correlated subqueries do need this piece
        elem.setType(FROM_FRAGMENT);
        joinSequence.setUseThetaStyle(true);
        elem.setUseFromFragment(false);
      }
    }

    return elem;
  }
  /** Used for collection filters */
  private void addFromAssociation(final String elementName, final String collectionRole)
      throws QueryException {
    // q.addCollection(collectionName, collectionRole);
    QueryableCollection persister = getCollectionPersister(collectionRole);
    Type collectionElementType = persister.getElementType();
    if (!collectionElementType.isEntityType()) {
      throw new QueryException("collection of values in filter: " + elementName);
    }

    String[] keyColumnNames = persister.getKeyColumnNames();
    // if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: "
    // + collectionRole);

    String collectionName;
    JoinSequence join = new JoinSequence(getFactory());
    collectionName =
        persister.isOneToMany() ? elementName : createNameForCollection(collectionRole);
    join.setRoot(persister, collectionName);
    if (!persister.isOneToMany()) {
      // many-to-many
      addCollection(collectionName, collectionRole);
      try {
        join.addJoin(
            (AssociationType) persister.getElementType(),
            elementName,
            JoinFragment.INNER_JOIN,
            persister.getElementColumnNames(collectionName));
      } catch (MappingException me) {
        throw new QueryException(me);
      }
    }
    join.addCondition(collectionName, keyColumnNames, " = ?");
    // if ( persister.hasWhere() ) join.addCondition( persister.getSQLWhereString(collectionName) );
    EntityType elemType = (EntityType) collectionElementType;
    addFrom(elementName, elemType.getAssociatedEntityName(), join);
  }
  private void mergeJoins(JoinFragment ojf) throws MappingException, QueryException {

    Iterator iter = joins.entrySet().iterator();
    while (iter.hasNext()) {
      Map.Entry me = (Map.Entry) iter.next();
      String name = (String) me.getKey();
      JoinSequence join = (JoinSequence) me.getValue();
      join.setSelector(
          new JoinSequence.Selector() {
            public boolean includeSubclasses(String alias) {
              boolean include = returnedTypes.contains(alias) && !isShallowQuery();
              return include;
            }
          });

      if (typeMap.containsKey(name)) {
        ojf.addFragment(join.toJoinFragment(enabledFilters, true));
      } else if (collections.containsKey(name)) {
        ojf.addFragment(join.toJoinFragment(enabledFilters, true));
      } else {
        // name from a super query (a bit inelegant that it shows up here)
      }
    }
  }
 void addFromJoinOnly(String name, JoinSequence joinSequence) throws QueryException {
   addJoin(name, joinSequence.getFromPart());
 }