Type type = collectionNode.getDataType();
if ( !type.isCollectionType() ) {
throw new SemanticException( "The [] operator cannot be applied to type " + type.toString() );
}
String collectionRole = ( (CollectionType) type ).getRole();
QueryableCollection queryableCollection = sessionFactoryHelper.requireQueryableCollection( collectionRole );
if ( !queryableCollection.hasIndex() ) {
throw new QueryException( "unindexed fromElement before []: " + collectionNode.getPath() );
}
// Generate the inner join -- The elements need to be joined to the collection they are in.
FromElement fromElement = collectionNode.getFromElement();
String elementTable = fromElement.getTableAlias();
FromClause fromClause = fromElement.getFromClause();
String path = collectionNode.getPath();
FromElement elem = fromClause.findCollectionJoin( path );
if ( elem == null ) {
FromElementFactory factory = new FromElementFactory( fromClause, fromElement, path );
elem = factory.createCollectionElementsJoin( queryableCollection, elementTable );
LOG.debugf( "No FROM element found for the elements of collection join path %s, created %s", path, elem );
}
else {
LOG.debugf( "FROM element found for collection join path %s", path );
}
// The 'from element' that represents the elements of the collection.
setFromElement( fromElement );
// Add the condition to the join sequence that qualifies the indexed element.
AST selector = collectionNode.getNextSibling();
if ( selector == null ) {
throw new QueryException( "No index value!" );
}
// Sometimes use the element table alias, sometimes use the... umm... collection table alias (many to many)
String collectionTableAlias = elementTable;
if ( elem.getCollectionTableAlias() != null ) {
collectionTableAlias = elem.getCollectionTableAlias();
}
// TODO: get SQL rendering out of here, create an AST for the join expressions.
// Use the SQL generator grammar to generate the SQL text for the index expression.
JoinSequence joinSequence = fromElement.getJoinSequence();
String[] indexCols = queryableCollection.getIndexColumnNames();
if ( indexCols.length != 1 ) {
throw new QueryException( "composite-index appears in []: " + collectionNode.getPath() );
}
SqlGenerator gen = new SqlGenerator( getSessionFactoryHelper().getFactory() );
try {
gen.simpleExpr( selector ); //TODO: used to be exprNoParens! was this needed?
}
catch (RecognitionException e) {
throw new QueryException( e.getMessage(), e );
}
String selectorExpression = gen.getSQL();
joinSequence.addCondition( collectionTableAlias + '.' + indexCols[0] + " = " + selectorExpression );
List<ParameterSpecification> paramSpecs = gen.getCollectedParameters();
if ( paramSpecs != null ) {
switch ( paramSpecs.size() ) {
case 0:
// nothing to do
break;
case 1:
ParameterSpecification paramSpec = paramSpecs.get( 0 );
paramSpec.setExpectedType( queryableCollection.getIndexType() );
fromElement.setIndexCollectionSelectorParamSpec( paramSpec );
break;
default:
fromElement.setIndexCollectionSelectorParamSpec(
new AggregatedIndexCollectionSelectorParameterSpecifications( paramSpecs )
);
break;
}
}
// Now, set the text for this node. It should be the element columns.
String[] elementColumns = queryableCollection.getElementColumnNames( elementTable );
setText( elementColumns[0] );
setResolved();
}