package org.hibernate.hql.internal.ast.util;
import java.util.Map;
import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes;
import org.hibernate.hql.internal.ast.HqlSqlWalker;
import org.hibernate.hql.internal.ast.tree.FromElement;
import org.hibernate.hql.internal.ast.tree.Node;
import org.hibernate.hql.internal.ast.tree.QueryNode;
import org.hibernate.hql.internal.ast.tree.RestrictableStatement;
import org.hibernate.hql.internal.ast.tree.SqlFragment;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.param.CollectionFilterKeyParameterSpecification;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.sql.JoinFragment;
import org.hibernate.type.Type;
import antlr.collections.AST;
public class SyntheticAndFactory implements HqlSqlTokenTypes {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( SyntheticAndFactory.class );
private HqlSqlWalker hqlSqlWalker;
private AST thetaJoins;
private AST filters;
public SyntheticAndFactory(HqlSqlWalker hqlSqlWalker) {
this.hqlSqlWalker = hqlSqlWalker;
}
private Node create(int tokenType, String text) {
return (Node) hqlSqlWalker.getASTFactory().create( tokenType, text );
}
public void addWhereFragment(
JoinFragment joinFragment,
String whereFragment,
QueryNode query,
FromElement fromElement,
HqlSqlWalker hqlSqlWalker) {
if ( whereFragment == null ) {
return;
}
if ( !fromElement.useWhereFragment() && !joinFragment.hasThetaJoins() ) {
return;
}
whereFragment = whereFragment.trim();
if ( StringHelper.isEmpty( whereFragment ) ) {
return;
}
if ( whereFragment.startsWith( "and" ) ) {
whereFragment = whereFragment.substring( 4 );
}
LOG.debugf( "Using unprocessed WHERE-fragment [%s]", whereFragment );
SqlFragment fragment = (SqlFragment) create( SQL_TOKEN, whereFragment );
fragment.setJoinFragment( joinFragment );
fragment.setFromElement( fromElement );
if ( fromElement.getIndexCollectionSelectorParamSpec() != null ) {
fragment.addEmbeddedParameter( fromElement.getIndexCollectionSelectorParamSpec() );
fromElement.setIndexCollectionSelectorParamSpec( null );
}
if ( hqlSqlWalker.isFilter() ) {
if ( whereFragment.indexOf( '?' ) >= 0 ) {
Type collectionFilterKeyType = hqlSqlWalker.getSessionFactoryHelper()
.requireQueryableCollection( hqlSqlWalker.getCollectionFilterRole() )
.getKeyType();
CollectionFilterKeyParameterSpecification paramSpec = new CollectionFilterKeyParameterSpecification(
hqlSqlWalker.getCollectionFilterRole(),
collectionFilterKeyType
);
fragment.addEmbeddedParameter( paramSpec );
}
}
JoinProcessor.processDynamicFilterParameters(
whereFragment,
fragment,
hqlSqlWalker
);
if ( LOG.isDebugEnabled() ) {
LOG.debugf( "Using processed WHERE-fragment [%s]", fragment.getText() );
}
if ( fragment.getFromElement().isFilter() || fragment.hasFilterCondition() ) {
if ( filters == null ) {
AST where = query.getWhereClause();
filters = create( FILTERS, "{filter conditions}" );
ASTUtil.insertChild( where, filters );
}
filters.addChild( fragment );
}
else {
if ( thetaJoins == null ) {
AST where = query.getWhereClause();
thetaJoins = create( THETA_JOINS, "{theta joins}" );
if ( filters == null ) {
ASTUtil.insertChild( where, thetaJoins );
}
else {
ASTUtil.insertSibling( thetaJoins, filters );
}
}
thetaJoins.addChild( fragment );
}
}
public void addDiscriminatorWhereFragment(
RestrictableStatement statement,
Queryable persister,
Map enabledFilters,
String alias) {
String whereFragment = persister.filterFragment( alias, enabledFilters ).trim();
if ( "".equals( whereFragment ) ) {
return;
}
if ( whereFragment.startsWith( "and" ) ) {
whereFragment = whereFragment.substring( 4 );
}
whereFragment = StringHelper.replace(
whereFragment,
persister.generateFilterConditionAlias( alias ) + ".",
""
);
SqlFragment discrimNode = (SqlFragment) create( SQL_TOKEN, whereFragment );
JoinProcessor.processDynamicFilterParameters(
whereFragment,
discrimNode,
hqlSqlWalker
);
if ( statement.getWhereClause().getNumberOfChildren() == 0 ) {
statement.getWhereClause().setFirstChild( discrimNode );
}
else {
AST and = create( AND, "{and}" );
AST currentFirstChild = statement.getWhereClause().getFirstChild();
and.setFirstChild( discrimNode );
and.addChild( currentFirstChild );
statement.getWhereClause().setFirstChild( and );
}
}
}