private void prepareForIndex(QueryTranslatorImpl q) throws QueryException { QueryableCollection collPersister = q.getCollectionPersister( collectionRole ); if ( !collPersister.hasIndex() ) { throw new QueryException( "unindexed collection before []: " + path ); } String[] indexCols = collPersister.getIndexColumnNames(); if ( indexCols.length != 1 ) { throw new QueryException( "composite-index appears in []: " + path ); } //String[] keyCols = collPersister.getKeyColumnNames(); JoinSequence fromJoins = new JoinSequence( q.getFactory() ) .setUseThetaStyle( useThetaStyleJoin ) .setRoot( collPersister, collectionName ) .setNext( joinSequence.copy() ); if ( !continuation ) { addJoin( collectionName, collPersister.getCollectionType() ); } joinSequence.addCondition( collectionName + '.' + indexCols[0] + " = " ); //TODO: get SQL rendering out of here CollectionElement elem = new CollectionElement(); elem.elementColumns = collPersister.getElementColumnNames(collectionName); elem.elementType = collPersister.getElementType(); elem.isOneToMany = collPersister.isOneToMany(); elem.alias = collectionName; elem.joinSequence = joinSequence; collectionElements.addLast( elem ); setExpectingCollectionIndex(); q.addCollection( collectionName, collectionRole ); q.addFromJoinOnly( collectionName, fromJoins ); }
JoinSequence join = new JoinSequence( getFactory() ); collectionName = persister.isOneToMany() ? elementName : createNameForCollection( collectionRole ); join.setRoot( persister, collectionName ); if ( !persister.isOneToMany() ) { join.addJoin( (AssociationType) persister.getElementType(), elementName, join.addCondition( collectionName, keyColumnNames, " = ?" );
@Override public String[] toColumns(String alias, String propertyName) throws QueryException { validate( propertyName ); final String joinTableAlias = joinSequence.getFirstJoin().getAlias(); if ( CollectionPropertyNames.COLLECTION_INDEX.equals( propertyName ) ) { return queryableCollection.toColumns( joinTableAlias, propertyName ); } final String[] cols = queryableCollection.getIndexColumnNames( joinTableAlias ); if ( CollectionPropertyNames.COLLECTION_MIN_INDEX.equals( propertyName ) ) { if ( cols.length != 1 ) { throw new QueryException( "composite collection index in minIndex()" ); } return new String[] {"min(" + cols[0] + ')'}; } else { if ( cols.length != 1 ) { throw new QueryException( "composite collection index in maxIndex()" ); } return new String[] {"max(" + cols[0] + ')'}; } }
/** * Retrieve a JoinSequence that represents just the FROM clause parts * * @return The JoinSequence that represents just the FROM clause parts */ public JoinSequence getFromPart() { final JoinSequence fromPart = new JoinSequence( factory ); fromPart.joins.addAll( this.joins ); fromPart.useThetaStyle = this.useThetaStyle; fromPart.rootAlias = this.rootAlias; fromPart.rootJoinable = this.rootJoinable; fromPart.selector = this.selector; fromPart.next = this.next == null ? null : this.next.getFromPart(); fromPart.isFromPart = true; return fromPart; }
/** * Create a full, although shallow, copy. * * @return The copy */ public JoinSequence copy() { final JoinSequence copy = new JoinSequence( factory ); copy.joins.addAll( this.joins ); copy.useThetaStyle = this.useThetaStyle; copy.rootAlias = this.rootAlias; copy.rootJoinable = this.rootJoinable; copy.selector = this.selector; copy.next = this.next == null ? null : this.next.copy(); copy.isFromPart = this.isFromPart; copy.conditions.append( this.conditions.toString() ); return copy; }
/** * Generate a join sequence representing the given association type. * * @param implicit Should implicit joins (theta-style) or explicit joins (ANSI-style) be rendered * @param associationType The type representing the thing to be joined into. * @param tableAlias The table alias to use in qualifying the join conditions * @param joinType The type of join to render (inner, outer, etc); see {@link org.hibernate.sql.JoinFragment} * @param columns The columns making up the condition of the join. * * @return The generated join sequence. */ public JoinSequence createJoinSequence(boolean implicit, AssociationType associationType, String tableAlias, JoinType joinType, String[][] columns) { JoinSequence joinSequence = createJoinSequence(); joinSequence.setUseThetaStyle( implicit ); // Implicit joins use theta style (WHERE pk = fk), explicit joins use JOIN (afterQuery from) joinSequence.addJoin( associationType, tableAlias, joinType, columns ); return joinSequence; }
@Override protected AST createFromFilterElement(AST filterEntity, AST alias) throws SemanticException { FromElement fromElement = currentFromClause.addFromElement( filterEntity.getText(), alias ); FromClause fromClause = fromElement.getFromClause(); QueryableCollection persister = sessionFactoryHelper.getCollectionPersister( collectionFilterRole ); // 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( collectionFilterRole ); JoinSequence join = sessionFactoryHelper.createJoinSequence(); join.setRoot( persister, fkTableAlias ); if ( !persister.isOneToMany() ) { join.addJoin( (AssociationType) persister.getElementType(), fromElement.getTableAlias(), JoinType.INNER_JOIN, persister.getElementColumnNames( fkTableAlias ) ); } join.addCondition( fkTableAlias, keyColumnNames, " = ?" ); fromElement.setJoinSequence( join ); fromElement.setFilter( true ); LOG.debug( "createFromFilterElement() : processed filter FROM element." ); return fromElement; }
private void addJoinNodes(QueryNode query, JoinSequence join, FromElement fromElement) { JoinFragment joinFragment = join.toJoinFragment( walker.getEnabledFilters(), fromElement.useFromFragment() || fromElement.isDereferencedBySuperclassOrSubclassProperty(), ( join.isThetaStyle() || StringHelper.isNotEmpty( whereFrag ) ) ) { fromElement.setType( FROM_FRAGMENT ); fromElement.getJoinSequence().setUseThetaStyle( true ); // this is used during SqlGenerator processing
addExtraJoins( joinFragment, rootAlias, rootJoinable, true ); String condition = null; if ( last != null && isManyToManyRoot( last ) && ( ( QueryableCollection ) last ).getElementType() == join.getAssociationType() ) { ); if (includeExtraJoins) { //TODO: not quite sure about the full implications of this! addExtraJoins( joinFragment, join.getAlias(), join.getJoinable(), join.joinType == JoinType.INNER_JOIN ); joinFragment.addFragment( next.toJoinFragment( enabledFilters, includeExtraJoins ) );
public void start(QueryTranslatorImpl q) { if ( !continuation ) { reset( q ); path.setLength( 0 ); joinSequence = new JoinSequence( q.getFactory() ).setUseThetaStyle( useThetaStyleJoin ); } }
void addFromClass(String name, Queryable classPersister) throws QueryException { JoinSequence joinSequence = new JoinSequence( getFactory() ) .setRoot( classPersister, name ); //crossJoins.add(name); addFrom( name, classPersister.getEntityName(), joinSequence ); }
JoinSequence ojf = q.getPathJoin( path.toString() ); try { joinSequence.addCondition( ojf.toJoinFragment( q.getEnabledFilters(), true ).toWhereFragmentString() ); //after reset!
private void addJoin(String name, AssociationType joinableType, String[] foreignKeyColumns) throws QueryException { try { joinSequence.addJoin( joinableType, name, joinType, foreignKeyColumns ); } catch ( MappingException me ) { throw new QueryException( me ); } }
addSubclassJoins( joinFragment, rootAlias, rootJoinable, true, includeAllSubclassJoins, treatAsDeclarations ); else if ( needsTableGroupJoin( joins, withClauseFragment ) ) { iter = joins.iterator(); first = iter.next(); ); addSubclassJoins( joinFragment, join.getAlias(), String condition; if ( last != null && isManyToManyRoot( last ) && ((QueryableCollection) last).getElementType() == join.getAssociationType() ) { if ( withClauseFragment != null && !isManyToManyRoot( join.joinable )) { condition += " and " + withClauseFragment; addSubclassJoins( joinFragment, join.getAlias(), joinFragment.addFragment( next.toJoinFragment( enabledFilters, includeAllSubclassJoins ) );
Map enabledFilters = fromElement.getWalker().getEnabledFilters(); String subquery = CollectionSubqueryFactory.createCollectionSubquery( joinSequence.copy().setUseThetaStyle( true ), enabledFilters, propertyMapping.toColumns( tableAlias, path )
public JoinSequence copyForCollectionProperty() { JoinSequence copy = this.copy(); copy.joins.clear(); Iterator<Join> joinIterator = this.joins.iterator(); while ( joinIterator.hasNext() ) { Join join = joinIterator.next(); copy.addJoin( join.getAssociationType(), join.getAlias(), JoinType.INNER_JOIN, join.getLHSColumns() ); } return copy; }
@Override protected void nestedFromFragment(AST d, AST parent) { // check a set of parent/child nodes in the from-clause tree // to determine if a comma is required between them if ( d != null && hasText( d ) ) { if ( parent != null && hasText( parent ) ) { // again, both should be FromElements FromElement left = (FromElement) parent; FromElement right = (FromElement) d; if ( right.getRealOrigin() == left ) { // right represents a joins originating from left... if ( right.getJoinSequence() != null && right.getJoinSequence().isThetaStyle() ) { writeCrossJoinSeparator(); } else { out( " " ); } } else { // not so sure this is even valid subtree. but if it was, it'd // represent two unrelated table references... writeCrossJoinSeparator(); } } out( d ); } }
&& fromElement.getOrigin().getWithClauseFragment() != null && fromElement.getOrigin().getWithClauseFragment().contains( fromElement.getTableAlias() ) ) { fromElement.getOrigin().getJoinSequence().addJoin( (ImpliedFromElement) fromElement ); final FromElement fromElement = (FromElement) iter.next(); JoinSequence join = fromElement.getJoinSequence(); join.setSelector( new JoinSequence.Selector() { public boolean includeSubclasses(String alias) {
final boolean useThetaJoin = collectionFromElement.getJoinSequence().isThetaStyle(); collectionFromElement.getJoinSequence().getFirstJoin().getJoinType(), joinColumns );
/** * Generate an empty join sequence instance. * * @return The generate join sequence. */ public JoinSequence createJoinSequence() { return new JoinSequence( sfi ); }