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); } }
public String getDisplayText() { return "{" + "method=" + getMethodName() + ",selectColumns=" + (selectColumns == null ? null : Arrays.asList(selectColumns)) + ",fromElement=" + fromElement.getTableAlias() + "}"; }
FromElement createElementJoin(QueryableCollection queryableCollection) throws SemanticException { FromElement elem; implied = true; // TODO: always true for now, but not if we later decide to support elements() in the // from clause inElementsFunction = true; Type elementType = queryableCollection.getElementType(); if (!elementType.isEntityType()) { throw new IllegalArgumentException( "Cannot create element join for a collection of non-entities!"); } this.queryableCollection = queryableCollection; SessionFactoryHelper sfh = fromClause.getSessionFactoryHelper(); FromElement destination = null; String tableAlias = null; EntityPersister entityPersister = queryableCollection.getElementPersister(); tableAlias = fromClause.getAliasGenerator().createName(entityPersister.getEntityName()); String associatedEntityName = entityPersister.getEntityName(); EntityPersister targetEntityPersister = sfh.requireClassPersister(associatedEntityName); // Create the FROM element for the target (the elements of the collection). destination = createAndAddFromElement( associatedEntityName, classAlias, targetEntityPersister, (EntityType) queryableCollection.getElementType(), tableAlias); // If the join is implied, then don't include sub-classes on the element. if (implied) { destination.setIncludeSubclasses(false); } fromClause.addCollectionJoinFromElementByPath(path, destination); // origin.addDestination(destination); // Add the query spaces. fromClause.getWalker().addQuerySpaces(entityPersister.getQuerySpaces()); CollectionType type = queryableCollection.getCollectionType(); String role = type.getRole(); String roleAlias = origin.getTableAlias(); String[] targetColumns = sfh.getCollectionElementColumns(role, roleAlias); AssociationType elementAssociationType = sfh.getElementAssociationType(type); // Create the join element under the from element. int joinType = JoinFragment.INNER_JOIN; JoinSequence joinSequence = sfh.createJoinSequence( implied, elementAssociationType, tableAlias, joinType, targetColumns); elem = initializeJoin(path, destination, joinSequence, targetColumns, origin, false); elem.setUseFromFragment( true); // The associated entity is implied, but it must be included in the FROM. elem.setCollectionTableAlias(roleAlias); // The collection alias is the role. return elem; }
private void prepareAnyImplicitJoins(DotNode dotNode) throws SemanticException { if (dotNode.getLhs() instanceof DotNode) { DotNode lhs = (DotNode) dotNode.getLhs(); FromElement lhsOrigin = lhs.getFromElement(); if (lhsOrigin != null && "".equals(lhsOrigin.getText())) { String lhsOriginText = lhsOrigin.getQueryable().getTableName() + " " + lhsOrigin.getTableAlias(); lhsOrigin.setText(lhsOriginText); } prepareAnyImplicitJoins(lhs); } }
void registerFromElement(FromElement element) { fromElements.add(element); String classAlias = element.getClassAlias(); if (classAlias != null) { // The HQL class alias refers to the class name. fromElementByClassAlias.put(classAlias, element); } // Associate the table alias with the element. String tableAlias = element.getTableAlias(); if (tableAlias != null) { fromElementByTableAlias.put(tableAlias, element); } }
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 FromElement createFromElementInSubselect( String path, String pathAlias, FromElement parentFromElement, String classAlias) throws SemanticException { if (log.isDebugEnabled()) { log.debug("createFromElementInSubselect() : path = " + path); } // Create an DotNode AST for the path and resolve it. FromElement fromElement = evaluateFromElementPath(path, classAlias); EntityPersister entityPersister = fromElement.getEntityPersister(); // If the first identifier in the path referrs to the class alias (not the class name), then // this // is a correlated subselect. If it's a correlated sub-select, use the existing table alias. // Otherwise // generate a new one. String tableAlias = null; boolean correlatedSubselect = pathAlias.equals(parentFromElement.getClassAlias()); if (correlatedSubselect) { tableAlias = fromElement.getTableAlias(); } else { tableAlias = null; } // If the from element isn't in the same clause, create a new from element. if (fromElement.getFromClause() != fromClause) { if (log.isDebugEnabled()) { log.debug("createFromElementInSubselect() : creating a new FROM element..."); } fromElement = createFromElement(entityPersister); initializeAndAddFromElement( fromElement, path, classAlias, entityPersister, (EntityType) ((Queryable) entityPersister).getType(), tableAlias); } if (log.isDebugEnabled()) { log.debug("createFromElementInSubselect() : " + path + " -> " + fromElement); } return fromElement; }