public void resolveCollectionProperty(AST expr) throws SemanticException {
   String propertyName = CollectionProperties.getNormalizedPropertyName(getMethodName());
   if (expr instanceof FromReferenceNode) {
     FromReferenceNode collectionNode = (FromReferenceNode) expr;
     // If this is 'elements' then create a new FROM element.
     if (CollectionPropertyNames.COLLECTION_ELEMENTS.equals(propertyName)) {
       handleElements(collectionNode, propertyName);
     } else {
       // Not elements(x)
       fromElement = collectionNode.getFromElement();
       setDataType(fromElement.getPropertyType(propertyName, propertyName));
       selectColumns = fromElement.toColumns(fromElement.getTableAlias(), propertyName, inSelect);
     }
     if (collectionNode instanceof DotNode) {
       prepareAnyImplicitJoins((DotNode) collectionNode);
     }
     if (!inSelect) {
       fromElement.setText("");
       fromElement.setUseWhereFragment(false);
     }
     prepareSelectColumns(selectColumns);
     setText(selectColumns[0]);
     setType(SqlTokenTypes.SQL_TOKEN);
   } else {
     throw new SemanticException(
         "Unexpected expression " + expr + " found for collection function " + propertyName);
   }
 }
  private void typeDiscriminator(AST path) throws SemanticException {
    if (path == null) {
      throw new SemanticException("type() discriminator reference has no path!");
    }

    FromReferenceNode pathAsFromReferenceNode = (FromReferenceNode) path;
    FromElement fromElement = pathAsFromReferenceNode.getFromElement();
    TypeDiscriminatorMetadata typeDiscriminatorMetadata =
        fromElement.getTypeDiscriminatorMetadata();

    setDataType(typeDiscriminatorMetadata.getResolutionType());
    setText(typeDiscriminatorMetadata.getSqlFragment());
    setType(SqlTokenTypes.SQL_TOKEN);
  }
 private FromElement evaluateFromElementPath(String path, String classAlias)
     throws SemanticException {
   ASTFactory factory = fromClause.getASTFactory();
   FromReferenceNode pathNode = (FromReferenceNode) PathHelper.parsePath(path, factory);
   pathNode.recursiveResolve(
       FromReferenceNode.ROOT_LEVEL, // This is the root level node.
       false, // Generate an explicit from clause at the root.
       classAlias,
       null);
   if (pathNode.getImpliedJoin() != null) {
     return pathNode.getImpliedJoin();
   } else {
     return pathNode.getFromElement();
   }
 }
  private void handleElements(FromReferenceNode collectionNode, String propertyName) {
    FromElement collectionFromElement = collectionNode.getFromElement();
    QueryableCollection queryableCollection = collectionFromElement.getQueryableCollection();

    String path = collectionNode.getPath() + "[]." + propertyName;
    log.debug("Creating elements for " + path);

    fromElement = collectionFromElement;
    if (!collectionFromElement.isCollectionOfValuesOrComponents()) {
      getWalker().addQuerySpaces(queryableCollection.getElementPersister().getQuerySpaces());
    }

    setDataType(queryableCollection.getElementType());
    selectColumns =
        collectionFromElement.toColumns(fromElement.getTableAlias(), propertyName, inSelect);
  }
  private void validateLhs(FromReferenceNode lhs) {
    // make sure the lhs is "assignable"...
    if (!lhs.isResolved()) {
      throw new UnsupportedOperationException("cannot validate assignablity of unresolved node");
    }

    if (lhs.getDataType().isCollectionType()) {
      throw new QueryException("collections not assignable in update statements");
    } else if (lhs.getDataType().isComponentType()) {
      throw new QueryException("Components currently not assignable in update statements");
    } else if (lhs.getDataType().isEntityType()) {
      // currently allowed...
    }

    // TODO : why aren't these the same?
    if (lhs.getImpliedJoin() != null || lhs.getFromElement().isImplied()) {
      throw new QueryException("Implied join paths are not assignable in update statements");
    }
  }