Introduce SqmVisitableNode#appendHqlString to support indexed collection access paths
This commit is contained in:
parent
97127fa1c5
commit
8e0864af10
|
@ -1566,7 +1566,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
|
|||
"where current_date() > key( p.callHistory )", Phone.class )
|
||||
.getResultList();
|
||||
//end::hql-collection-expressions-example[]
|
||||
assertEquals(2, phones.size());
|
||||
assertEquals( 1, phones.size() );
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -144,6 +144,13 @@ public class FullyQualifiedReflectivePathTerminal
|
|||
public void applyInferableType(SqmExpressable type) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( getParent().getFullPath() );
|
||||
sb.append( '.' );
|
||||
sb.append( getLocalName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmExpression<Long> asLong() {
|
||||
return null;
|
||||
|
|
|
@ -13,7 +13,9 @@ import org.hibernate.query.sqm.NodeBuilder;
|
|||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmDistinct;
|
||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
||||
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||
|
||||
/**
|
||||
|
@ -51,4 +53,29 @@ public class SelfRenderingSqmAggregateFunction<T> extends SelfRenderingSqmFuncti
|
|||
getMappingModelExpressable( walker, resultType )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
final List<SqmTypedNode<?>> arguments = getArguments();
|
||||
sb.append( getFunctionName() );
|
||||
sb.append( '(' );
|
||||
int i = 1;
|
||||
if ( arguments.get( 0 ) instanceof SqmDistinct<?> ) {
|
||||
( (SqmSelectableNode<?>) arguments.get( 0 ) ).appendHqlString( sb );
|
||||
sb.append( ' ' );
|
||||
( (SqmSelectableNode<?>) arguments.get( 1 ) ).appendHqlString( sb );
|
||||
i = 2;
|
||||
}
|
||||
for ( ; i < arguments.size(); i++ ) {
|
||||
sb.append(", ");
|
||||
( (SqmSelectableNode<?>) arguments.get( i ) ).appendHqlString( sb );
|
||||
}
|
||||
|
||||
sb.append( ')' );
|
||||
if ( filter != null ) {
|
||||
sb.append( " filter (where " );
|
||||
filter.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,4 +19,12 @@ public interface SqmVisitableNode extends SqmNode {
|
|||
* Accept the walker per visitation
|
||||
*/
|
||||
<X> X accept(SemanticQueryWalker<X> walker);
|
||||
|
||||
void appendHqlString(StringBuilder sb);
|
||||
|
||||
default String toHqlString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendHqlString( sb );
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,10 @@ package org.hibernate.query.sqm.tree.cte;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.NullPrecedence;
|
||||
import org.hibernate.query.SortOrder;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
||||
import org.hibernate.sql.ast.tree.cte.CteColumn;
|
||||
import org.hibernate.sql.ast.tree.cte.CteMaterialization;
|
||||
import org.hibernate.sql.ast.tree.cte.CteSearchClauseKind;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
|
@ -15,6 +19,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker;
|
|||
import org.hibernate.query.sqm.tree.AbstractSqmNode;
|
||||
import org.hibernate.query.sqm.tree.SqmStatement;
|
||||
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
||||
import org.hibernate.sql.ast.tree.cte.SearchClauseSpecification;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -112,4 +117,74 @@ public class SqmCteStatement<T> extends AbstractSqmNode implements SqmVisitableN
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitCteStatement( this );
|
||||
}
|
||||
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( cteTable.getCteName() );
|
||||
sb.append( " (" );
|
||||
final List<SqmCteTableColumn> columns = cteTable.getColumns();
|
||||
sb.append( columns.get( 0 ).getColumnName() );
|
||||
for ( int i = 1; i < columns.size(); i++ ) {
|
||||
sb.append( ", " );
|
||||
sb.append( columns.get( i ).getColumnName() );
|
||||
}
|
||||
|
||||
sb.append( ") as " );
|
||||
|
||||
if ( getMaterialization() != CteMaterialization.UNDEFINED ) {
|
||||
sb.append( getMaterialization() ).append( ' ' );
|
||||
}
|
||||
sb.append( '(' );
|
||||
getCteDefinition().appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
|
||||
String separator;
|
||||
if ( getSearchClauseKind() != null ) {
|
||||
sb.append( " search " );
|
||||
if ( getSearchClauseKind() == CteSearchClauseKind.DEPTH_FIRST ) {
|
||||
sb.append( " depth " );
|
||||
}
|
||||
else {
|
||||
sb.append( " breadth " );
|
||||
}
|
||||
sb.append( " first by " );
|
||||
separator = "";
|
||||
for ( SqmSearchClauseSpecification searchBySpecification : getSearchBySpecifications() ) {
|
||||
sb.append( separator );
|
||||
sb.append( searchBySpecification.getCteColumn().getColumnName() );
|
||||
if ( searchBySpecification.getSortOrder() != null ) {
|
||||
if ( searchBySpecification.getSortOrder() == SortOrder.ASCENDING ) {
|
||||
sb.append( " asc" );
|
||||
}
|
||||
else {
|
||||
sb.append( " desc" );
|
||||
}
|
||||
if ( searchBySpecification.getNullPrecedence() != null ) {
|
||||
if ( searchBySpecification.getNullPrecedence() == NullPrecedence.FIRST ) {
|
||||
sb.append( " nulls first" );
|
||||
}
|
||||
else {
|
||||
sb.append( " nulls last" );
|
||||
}
|
||||
}
|
||||
}
|
||||
separator = ", ";
|
||||
}
|
||||
}
|
||||
if ( getCycleMarkColumn() != null ) {
|
||||
sb.append( " cycle " );
|
||||
separator = "";
|
||||
for ( SqmCteTableColumn cycleColumn : getCycleColumns() ) {
|
||||
sb.append( separator );
|
||||
sb.append( cycleColumn.getColumnName() );
|
||||
separator = ", ";
|
||||
}
|
||||
sb.append( " set " );
|
||||
sb.append( getCycleMarkColumn().getColumnName() );
|
||||
sb.append( " to '" );
|
||||
sb.append( getCycleValue() );
|
||||
sb.append( "' default '" );
|
||||
sb.append( getNoCycleValue() );
|
||||
sb.append( "'" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ public class SqmDeleteStatement<T>
|
|||
public SqmDeleteStatement(SqmRoot<T> target, SqmQuerySource querySource, NodeBuilder nodeBuilder) {
|
||||
super( target, querySource, nodeBuilder );
|
||||
this.querySource = SqmQuerySource.HQL;
|
||||
|
||||
}
|
||||
|
||||
public SqmDeleteStatement(Class<T> targetEntity, SqmQuerySource querySource, NodeBuilder nodeBuilder) {
|
||||
|
@ -122,4 +121,17 @@ public class SqmDeleteStatement<T>
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitDeleteStatement( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "delete from " );
|
||||
sb.append( getTarget().getEntityName() );
|
||||
if ( getTarget().getExplicitAlias() != null ) {
|
||||
sb.append( ' ' ).append( getTarget().getExplicitAlias() );
|
||||
}
|
||||
if ( whereClause != null && whereClause.getPredicate() != null ) {
|
||||
sb.append( " where " );
|
||||
whereClause.getPredicate().appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -597,4 +597,15 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
|
|||
nodeBuilder()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
if ( alias == null ) {
|
||||
// If we don't have an alias, this is the best we can do to at least ensure uniqueness
|
||||
sb.append( "alias_" ).append( System.identityHashCode( this ) );
|
||||
}
|
||||
else {
|
||||
sb.append( alias );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,4 +42,13 @@ public abstract class AbstractSqmSimplePath<T> extends AbstractSqmPath<T> implem
|
|||
public NavigablePath getNavigablePath() {
|
||||
return navigablePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
if ( getLhs() != null ) {
|
||||
getLhs().appendHqlString( sb );
|
||||
sb.append( '.' );
|
||||
}
|
||||
sb.append( getReferencedPathSource().getPathName() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,4 +47,11 @@ public class SqmBasicValuedEntityTypePath<T> extends SqmBasicValuedSimplePath<T>
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitEntityTypeLiteralExpression( literal );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "type(" );
|
||||
super.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ public class SqmIndexedCollectionAccessPath<T> extends AbstractSqmPath<T> implem
|
|||
SqmExpression<?> selectorExpression) {
|
||||
//noinspection unchecked
|
||||
super(
|
||||
pluralDomainPath.getNavigablePath().getParent().append( pluralDomainPath.getNavigablePath().getLocalName(), "[]" ),
|
||||
pluralDomainPath.getNavigablePath().getParent().append( pluralDomainPath.getNavigablePath().getLocalName(), selectorExpression.toHqlString() ),
|
||||
(PluralPersistentAttribute) pluralDomainPath.getReferencedPathSource(),
|
||||
pluralDomainPath,
|
||||
pluralDomainPath.nodeBuilder()
|
||||
|
@ -83,4 +83,12 @@ public class SqmIndexedCollectionAccessPath<T> extends AbstractSqmPath<T> implem
|
|||
|
||||
throw new UnsupportedOperationException( );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
getLhs().appendHqlString( sb );
|
||||
sb.append( '[' );
|
||||
selectorExpression.appendHqlString( sb );
|
||||
sb.append( ']' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,6 +107,12 @@ public class SqmMapEntryReference<K,V>
|
|||
return nodeBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "entry(" );
|
||||
mapPath.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// JPA (ugh)
|
||||
|
|
|
@ -52,4 +52,11 @@ public class SqmMaxElementPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitMaxElementPath( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "maxelement(" );
|
||||
getLhs().appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,4 +60,11 @@ public class SqmMaxIndexPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitMaxIndexPath( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "maxindex(" );
|
||||
getLhs().appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,4 +52,11 @@ public class SqmMinElementPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitMinElementPath( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "minelement(" );
|
||||
getLhs().appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,4 +61,11 @@ public class SqmMinIndexPath<T> extends AbstractSqmSpecificPluralPartPath<T> {
|
|||
return walker.visitMinIndexPath( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "minindex(" );
|
||||
getLhs().appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,4 +51,13 @@ public class SqmTreatedBagJoin<O,T, S extends T> extends SqmBagJoin<O,S> impleme
|
|||
//noinspection unchecked
|
||||
return new SqmTreatedBagJoin( wrappedPath, treatTarget, getAlias() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "treat(" );
|
||||
wrappedPath.appendHqlString( sb );
|
||||
sb.append( " as " );
|
||||
sb.append( treatTarget.getName() );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,4 +50,13 @@ public class SqmTreatedCrossJoin<T, S extends T> extends SqmCrossJoin<S> impleme
|
|||
//noinspection unchecked
|
||||
return (EntityDomainType) wrappedPath.getReferencedPathSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "treat(" );
|
||||
wrappedPath.appendHqlString( sb );
|
||||
sb.append( " as " );
|
||||
sb.append( treatTarget.getName() );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,11 +14,11 @@ import org.hibernate.query.sqm.tree.from.SqmEntityJoin;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SqmTreatedEntityJoin<T, S extends T> extends SqmEntityJoin<S> implements SqmTreatedPath<T,S> {
|
||||
private final SqmEntityJoin<T> wrapped;
|
||||
private final SqmEntityJoin<T> wrappedPath;
|
||||
private final EntityDomainType<S> treatTarget;
|
||||
|
||||
public SqmTreatedEntityJoin(
|
||||
SqmEntityJoin<T> wrapped,
|
||||
SqmEntityJoin<T> wrappedPath,
|
||||
EntityDomainType<S> treatTarget,
|
||||
String alias,
|
||||
SqmJoinType joinType) {
|
||||
|
@ -26,9 +26,9 @@ public class SqmTreatedEntityJoin<T, S extends T> extends SqmEntityJoin<S> imple
|
|||
treatTarget,
|
||||
alias,
|
||||
joinType,
|
||||
wrapped.getRoot()
|
||||
wrappedPath.getRoot()
|
||||
);
|
||||
this.wrapped = wrapped;
|
||||
this.wrappedPath = wrappedPath;
|
||||
this.treatTarget = treatTarget;
|
||||
}
|
||||
|
||||
|
@ -39,12 +39,21 @@ public class SqmTreatedEntityJoin<T, S extends T> extends SqmEntityJoin<S> imple
|
|||
|
||||
@Override
|
||||
public SqmPath<T> getWrappedPath() {
|
||||
return wrapped;
|
||||
return wrappedPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityDomainType<S> getReferencedPathSource() {
|
||||
//noinspection unchecked
|
||||
return (EntityDomainType<S>) wrapped.getReferencedPathSource();
|
||||
return (EntityDomainType<S>) wrappedPath.getReferencedPathSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "treat(" );
|
||||
wrappedPath.appendHqlString( sb );
|
||||
sb.append( " as " );
|
||||
sb.append( treatTarget.getName() );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,4 +66,13 @@ public class SqmTreatedListJoin<O,T, S extends T> extends SqmListJoin<O,S> imple
|
|||
//noinspection unchecked
|
||||
return new SqmTreatedListJoin( wrappedPath, treatTarget, getAlias() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "treat(" );
|
||||
wrappedPath.appendHqlString( sb );
|
||||
sb.append( " as " );
|
||||
sb.append( treatTarget.getName() );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,4 +60,13 @@ public class SqmTreatedMapJoin<O,K,V, S extends V> extends SqmMapJoin<O,K,S> imp
|
|||
getAlias()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "treat(" );
|
||||
wrappedPath.appendHqlString( sb );
|
||||
sb.append( " as " );
|
||||
sb.append( treatTarget.getName() );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,4 +93,13 @@ public class SqmTreatedRoot<T, S extends T> extends SqmRoot<S> implements SqmTre
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "treat(" );
|
||||
wrappedPath.appendHqlString( sb );
|
||||
sb.append( " as " );
|
||||
sb.append( treatTarget.getName() );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,4 +68,13 @@ public class SqmTreatedSetJoin<O,T, S extends T> extends SqmSetJoin<O,S> impleme
|
|||
//noinspection unchecked
|
||||
return new SqmTreatedSetJoin( wrappedPath, treatTarget, getAlias() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "treat(" );
|
||||
wrappedPath.appendHqlString( sb );
|
||||
sb.append( " as " );
|
||||
sb.append( treatTarget.getName() );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,4 +70,13 @@ public class SqmTreatedSimplePath<T, S extends T>
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitTreatedPath( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "treat(" );
|
||||
wrappedPath.appendHqlString( sb );
|
||||
sb.append( " as " );
|
||||
sb.append( treatTarget.getName() );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,4 +63,13 @@ public class SqmTreatedSingularJoin<O,T, S extends T> extends SqmSingularJoin<O,
|
|||
//noinspection unchecked
|
||||
return new SqmTreatedSingularJoin( wrappedPath, treatTarget, getAlias() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "treat(" );
|
||||
wrappedPath.appendHqlString( sb );
|
||||
sb.append( " as " );
|
||||
sb.append( treatTarget.getName() );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,4 +135,15 @@ public class JpaCriteriaParameter<T>
|
|||
public NamedCallableQueryMemento.ParameterMemento toMemento() {
|
||||
throw new UnsupportedOperationException( "ParameterMemento cannot be extracted from Criteria query parameter" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
if ( getName() == null ) {
|
||||
sb.append( value );
|
||||
}
|
||||
else {
|
||||
sb.append( ':' );
|
||||
sb.append( getName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,4 +33,8 @@ public class SqmAliasedNodeRef extends AbstractSqmExpression<Integer> {
|
|||
// `BaseSqmToSqlAstConverter#resolveGroupOrOrderByExpression`
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( position );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,4 +32,10 @@ public class SqmAny<T> extends AbstractSqmExpression<T> {
|
|||
return walker.visitAny( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "any " );
|
||||
subquery.appendHqlString( sb );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -106,4 +106,13 @@ public class SqmBinaryArithmetic<T> extends AbstractSqmExpression<T> implements
|
|||
return getOperator().toLoggableText( lhsOperand.asLoggableText(), rhsOperand.asLoggableText() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
lhsOperand.appendHqlString( sb );
|
||||
sb.append( ' ' );
|
||||
sb.append( operator.getOperatorSqlText() );
|
||||
sb.append( ' ' );
|
||||
rhsOperand.appendHqlString( sb );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,4 +39,10 @@ public class SqmByUnit extends AbstractSqmExpression<Long> {
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitByUnit( this );
|
||||
}
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
duration.appendHqlString( sb );
|
||||
sb.append( " by " );
|
||||
sb.append( unit.getUnit() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,6 +110,23 @@ public class SqmCaseSearched<R>
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "case" );
|
||||
for ( WhenFragment<R> whenFragment : whenFragments ) {
|
||||
sb.append( " when " );
|
||||
whenFragment.predicate.appendHqlString( sb );
|
||||
sb.append( " then " );
|
||||
whenFragment.result.appendHqlString( sb );
|
||||
}
|
||||
|
||||
if ( otherwise != null ) {
|
||||
sb.append( " else " );
|
||||
otherwise.appendHqlString( sb );
|
||||
}
|
||||
sb.append( " end" );
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// JPA
|
||||
|
|
|
@ -118,6 +118,24 @@ public class SqmCaseSimple<T,R>
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "case " );
|
||||
fixture.appendHqlString( sb );
|
||||
for ( WhenFragment<T, R> whenFragment : whenFragments ) {
|
||||
sb.append( " when " );
|
||||
whenFragment.checkValue.appendHqlString( sb );
|
||||
sb.append( " then " );
|
||||
whenFragment.result.appendHqlString( sb );
|
||||
}
|
||||
|
||||
if ( otherwise != null ) {
|
||||
sb.append( " else " );
|
||||
otherwise.appendHqlString( sb );
|
||||
}
|
||||
sb.append( " end" );
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// JPA
|
||||
|
|
|
@ -83,4 +83,23 @@ public class SqmCastTarget<T> extends AbstractSqmNode implements SqmTypedNode<T>
|
|||
public SqmExpressable getNodeType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( type.getTypeName() );
|
||||
if ( length != null ) {
|
||||
sb.append( '(' );
|
||||
sb.append( length );
|
||||
sb.append( ')' );
|
||||
}
|
||||
else if ( precision != null ) {
|
||||
sb.append( '(' );
|
||||
sb.append( precision );
|
||||
if ( scale != null ) {
|
||||
sb.append( ", " );
|
||||
sb.append( scale );
|
||||
}
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,17 @@ public class SqmCoalesce<T> extends AbstractSqmExpression<T> implements JpaCoale
|
|||
return "coalesce(...)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "coalesce(" );
|
||||
arguments.get( 0 ).appendHqlString( sb );
|
||||
for ( int i = 1; i < arguments.size(); i++ ) {
|
||||
sb.append(", ");
|
||||
arguments.get( i ).appendHqlString( sb );
|
||||
}
|
||||
sb.append( ')' );
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// JPA
|
||||
|
|
|
@ -35,4 +35,11 @@ public class SqmCollate<T> extends AbstractSqmExpression<T> {
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitCollate( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
expression.appendHqlString( sb );
|
||||
sb.append( " collate " );
|
||||
sb.append( collation );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,13 @@ public class SqmCollectionSize extends AbstractSqmExpression<Integer> implements
|
|||
return "SIZE(" + pluralPath.asLoggableText() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "size(" );
|
||||
pluralPath.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public DomainResult createDomainResult(
|
||||
// String resultVariable,
|
||||
|
|
|
@ -39,4 +39,9 @@ public class SqmDistinct<T> extends AbstractSqmNode implements SqmTypedNode<T>,
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitDistinct(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "distinct" );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public class SqmDurationUnit<T> extends AbstractSqmNode implements SqmTypedNode<T>, SqmVisitableNode {
|
||||
private TemporalUnit unit;
|
||||
private AllowableFunctionReturnType<T> type;
|
||||
private final TemporalUnit unit;
|
||||
private final AllowableFunctionReturnType<T> type;
|
||||
|
||||
public SqmDurationUnit(TemporalUnit unit, AllowableFunctionReturnType<T> type, NodeBuilder nodeBuilder) {
|
||||
super( nodeBuilder );
|
||||
|
@ -34,7 +34,7 @@ public class SqmDurationUnit<T> extends AbstractSqmNode implements SqmTypedNode<
|
|||
|
||||
@Override
|
||||
public <T> T accept(SemanticQueryWalker<T> walker) {
|
||||
return walker.visitDurationUnit(this);
|
||||
return walker.visitDurationUnit( this );
|
||||
}
|
||||
|
||||
public TemporalUnit getUnit() {
|
||||
|
@ -45,6 +45,11 @@ public class SqmDurationUnit<T> extends AbstractSqmNode implements SqmTypedNode<
|
|||
public SqmExpressable<T> getNodeType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( unit );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -128,4 +128,11 @@ public class SqmEnumLiteral<E extends Enum<E>> extends AbstractSqmExpression<E>
|
|||
return walker.visitEnumLiteral( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( enumValue.getDeclaringClass().getTypeName() );
|
||||
sb.append( '.' );
|
||||
sb.append( enumValueName );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,5 +31,10 @@ public class SqmEvery<T> extends AbstractSqmExpression<T> {
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitEvery( this );
|
||||
}
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "all " );
|
||||
subquery.appendHqlString( sb );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,6 +45,11 @@ public class SqmExtractUnit<T> extends AbstractSqmNode implements SqmTypedNode<T
|
|||
public SqmExpressable<T> getNodeType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( unit );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -119,6 +119,11 @@ public class SqmFieldLiteral<T> implements SqmExpression<T>, SqmExpressable<T>,
|
|||
return walker.visitFieldLiteral( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
SqmLiteral.appendHqlString( sb, getJavaTypeDescriptor(), getValue() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeBuilder nodeBuilder() {
|
||||
return nodeBuilder;
|
||||
|
|
|
@ -27,4 +27,9 @@ public class SqmFormat extends SqmLiteral<String> {
|
|||
public <R> R accept(SemanticQueryWalker<R> walker) {
|
||||
return walker.visitFormat( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( getLiteralValue() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
|||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -68,6 +69,110 @@ public abstract class SqmFunction<T> extends AbstractSqmExpression<T>
|
|||
return walker.visitFunction( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
// Special case a few functions with special syntax for rendering...
|
||||
// Unless we introduce dedicated SqmXXX classes that override this method, we have to render it this way
|
||||
switch ( functionName ) {
|
||||
case "cast": {
|
||||
sb.append( "cast(" );
|
||||
( (SqmSelectableNode<?>) arguments.get( 0 ) ).appendHqlString( sb );
|
||||
sb.append( " as " );
|
||||
( (SqmSelectableNode<?>) arguments.get( 1 ) ).appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
break;
|
||||
}
|
||||
case "extract": {
|
||||
sb.append( "extract(" );
|
||||
( (SqmSelectableNode<?>) arguments.get( 0 ) ).appendHqlString( sb );
|
||||
sb.append( " from " );
|
||||
( (SqmSelectableNode<?>) arguments.get( 1 ) ).appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
break;
|
||||
}
|
||||
case "format": {
|
||||
sb.append( "format(" );
|
||||
( (SqmSelectableNode<?>) arguments.get( 0 ) ).appendHqlString( sb );
|
||||
sb.append( " as " );
|
||||
( (SqmSelectableNode<?>) arguments.get( 1 ) ).appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
break;
|
||||
}
|
||||
case "overlay": {
|
||||
sb.append( "overlay(" );
|
||||
( (SqmSelectableNode<?>) arguments.get( 0 ) ).appendHqlString( sb );
|
||||
sb.append( " placing " );
|
||||
( (SqmSelectableNode<?>) arguments.get( 1 ) ).appendHqlString( sb );
|
||||
sb.append( " from " );
|
||||
( (SqmSelectableNode<?>) arguments.get( 2 ) ).appendHqlString( sb );
|
||||
if ( arguments.size() == 4 ) {
|
||||
sb.append( " for " );
|
||||
( (SqmSelectableNode<?>) arguments.get( 3 ) ).appendHqlString( sb );
|
||||
}
|
||||
sb.append( ')' );
|
||||
break;
|
||||
}
|
||||
case "trim": {
|
||||
sb.append( "trim(" );
|
||||
switch ( arguments.size() ) {
|
||||
case 1:
|
||||
( (SqmSelectableNode<?>) arguments.get( 0 ) ).appendHqlString( sb );
|
||||
break;
|
||||
case 2:
|
||||
( (SqmSelectableNode<?>) arguments.get( 0 ) ).appendHqlString( sb );
|
||||
sb.append( " from " );
|
||||
( (SqmSelectableNode<?>) arguments.get( 1 ) ).appendHqlString( sb );
|
||||
break;
|
||||
case 3:
|
||||
( (SqmSelectableNode<?>) arguments.get( 0 ) ).appendHqlString( sb );
|
||||
sb.append( ' ' );
|
||||
( (SqmSelectableNode<?>) arguments.get( 1 ) ).appendHqlString( sb );
|
||||
sb.append( " from " );
|
||||
( (SqmSelectableNode<?>) arguments.get( 3 ) ).appendHqlString( sb );
|
||||
break;
|
||||
}
|
||||
sb.append( ')' );
|
||||
break;
|
||||
}
|
||||
case "pad": {
|
||||
sb.append( "pad(" );
|
||||
( (SqmSelectableNode<?>) arguments.get( 0 ) ).appendHqlString( sb );
|
||||
sb.append( " with" );
|
||||
for ( int i = 1; i < arguments.size(); i++ ) {
|
||||
sb.append( ' ' );
|
||||
( (SqmSelectableNode<?>) arguments.get( i ) ).appendHqlString( sb );
|
||||
}
|
||||
sb.append( ')' );
|
||||
break;
|
||||
}
|
||||
case "position": {
|
||||
sb.append( "position(" );
|
||||
( (SqmSelectableNode<?>) arguments.get( 0 ) ).appendHqlString( sb );
|
||||
sb.append( " in " );
|
||||
( (SqmSelectableNode<?>) arguments.get( 1 ) ).appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sb.append( functionName );
|
||||
if ( arguments.isEmpty() ) {
|
||||
if ( functionDescriptor.alwaysIncludesParentheses() ) {
|
||||
sb.append( "()" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
sb.append( '(' );
|
||||
for ( int i = 1; i < arguments.size(); i++ ) {
|
||||
sb.append( ", " );
|
||||
( (SqmSelectableNode<?>) arguments.get( i ) ).appendHqlString( sb );
|
||||
}
|
||||
|
||||
sb.append( ')' );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// SemanticPathPart
|
||||
|
|
|
@ -110,6 +110,11 @@ public class SqmJpaCriteriaParameterWrapper<T>
|
|||
// nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
jpaCriteriaParameter.appendHqlString( sb );
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public Expression toSqlExpression(
|
||||
// Clause clause,
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.hibernate.query.sqm.NodeBuilder;
|
|||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.SqmExpressable;
|
||||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
/**
|
||||
* Represents a literal value in the sqm, e.g.<ul>
|
||||
|
@ -45,4 +46,27 @@ public class SqmLiteral<T>
|
|||
return "Literal( " + value + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
appendHqlString( sb, getJavaTypeDescriptor(), value );
|
||||
}
|
||||
|
||||
public static <T> void appendHqlString(StringBuilder sb, JavaTypeDescriptor<T> javaTypeDescriptor, T value) {
|
||||
final String string = javaTypeDescriptor.toString( value );
|
||||
if ( javaTypeDescriptor.getJavaTypeClass() == String.class ) {
|
||||
sb.append( '\'' );
|
||||
for ( int i = 0; i < string.length(); i++ ) {
|
||||
final char c = string.charAt( i );
|
||||
if ( c == '\'' ) {
|
||||
sb.append( '\'' );
|
||||
}
|
||||
sb.append( c );
|
||||
}
|
||||
sb.append( '\'' );
|
||||
}
|
||||
else {
|
||||
sb.append( string );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -85,4 +85,9 @@ public class SqmLiteralEntityType<T>
|
|||
throw new HqlInterpretationException( "Cannot dereference an entity name" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( entityType.getName() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,4 +36,9 @@ public class SqmLiteralNull<T> extends SqmLiteral<T> {
|
|||
}
|
||||
|
||||
private static SqmExpressable NULL_TYPE = () -> null;
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "null" );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,4 +55,10 @@ public class SqmNamedParameter<T> extends AbstractSqmParameter<T> {
|
|||
public SqmParameter<T> copy() {
|
||||
return new SqmNamedParameter<>( getName(), allowMultiValuedBinding(), this.getNodeType(), nodeBuilder() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( ':' );
|
||||
sb.append( getName() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,4 +41,11 @@ public class SqmParameterizedEntityType<T> extends AbstractSqmExpression<T> impl
|
|||
return walker.visitParameterizedEntityTypeExpression( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "type(" );
|
||||
discriminatorSource.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -59,4 +59,10 @@ public class SqmPositionalParameter<T> extends AbstractSqmParameter<T> {
|
|||
return "?" + getPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( '?' );
|
||||
sb.append( getPosition() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -61,4 +61,12 @@ public class SqmRestrictedSubQueryExpression<T> extends AbstractSqmExpression<T>
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitRestrictedSubQueryExpression( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( modifier );
|
||||
sb.append( " (" );
|
||||
subQuery.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,4 +32,9 @@ public class SqmSelfRenderingExpression<T> extends AbstractSqmExpression<T> {
|
|||
//noinspection unchecked
|
||||
return (X) renderer.apply( walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,5 +22,9 @@ public class SqmStar extends AbstractSqmExpression<Object> {
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitStar( this );
|
||||
}
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "*" );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,5 +43,16 @@ public class SqmSummarization<T> extends AbstractSqmExpression<T> {
|
|||
ROLLUP,
|
||||
CUBE
|
||||
}
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( kind );
|
||||
sb.append( " (" );
|
||||
groupings.get( 0 ).appendHqlString( sb );
|
||||
for ( int i = 1; i < groupings.size(); i++ ) {
|
||||
sb.append(", ");
|
||||
groupings.get( i ).appendHqlString( sb );
|
||||
}
|
||||
sb.append( ')' );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,6 +44,13 @@ public class SqmToDuration<T> extends AbstractSqmExpression<T> {
|
|||
public String asLoggableText() {
|
||||
return magnitude.asLoggableText() + " " + unit.getUnit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
magnitude.appendHqlString( sb );
|
||||
sb.append( ' ' );
|
||||
sb.append( unit.getUnit() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -46,4 +46,9 @@ public class SqmTrimSpecification extends AbstractSqmNode implements SqmTypedNod
|
|||
public SqmExpressable getNodeType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( specification );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,17 @@ public class SqmTuple<T>
|
|||
return walker.visitTuple( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( '(' );
|
||||
groupedExpressions.get( 0 ).appendHqlString( sb );
|
||||
for ( int i = 1; i < groupedExpressions.size(); i++ ) {
|
||||
sb.append(", ");
|
||||
groupedExpressions.get( i ).appendHqlString( sb );
|
||||
}
|
||||
sb.append( ')' );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asLoggableText() {
|
||||
return toString();
|
||||
|
|
|
@ -50,4 +50,9 @@ public class SqmUnaryOperation<T> extends AbstractSqmExpression<T> implements Sq
|
|||
public String asLoggableText() {
|
||||
return ( operation == UnaryArithmeticOperator.UNARY_MINUS ? '-' : '+' ) + operand.asLoggableText();
|
||||
}
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( operation == UnaryArithmeticOperator.UNARY_MINUS ? '-' : '+' );
|
||||
operand.appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,4 +57,19 @@ public abstract class AbstractSqmInsertStatement<T> extends AbstractSqmDmlStatem
|
|||
insertionTargetPaths.forEach( consumer );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "insert into " );
|
||||
sb.append( getTarget().getEntityName() );
|
||||
if ( insertionTargetPaths != null && !insertionTargetPaths.isEmpty() ) {
|
||||
sb.append( '(' );
|
||||
insertionTargetPaths.get( 0 ).appendHqlString( sb );
|
||||
for ( int i = 1; i < insertionTargetPaths.size(); i++ ) {
|
||||
sb.append( ", " );
|
||||
insertionTargetPaths.get( i ).appendHqlString( sb );
|
||||
}
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,4 +57,11 @@ public class SqmInsertSelectStatement<T> extends AbstractSqmInsertStatement<T> i
|
|||
// insert has no predicate
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
super.appendHqlString( sb );
|
||||
sb.append( ' ' );
|
||||
selectQueryPart.appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.hibernate.query.criteria.JpaPredicate;
|
|||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.SqmQuerySource;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||
import org.hibernate.query.sqm.tree.from.SqmRoot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -38,4 +39,27 @@ public class SqmInsertValuesStatement<T> extends AbstractSqmInsertStatement<T> {
|
|||
public JpaPredicate getRestriction() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
super.appendHqlString( sb );
|
||||
sb.append( " values (" );
|
||||
appendValues( valuesList.get( 0 ), sb );
|
||||
for ( int i = 1; i < valuesList.size(); i++ ) {
|
||||
sb.append( ", " );
|
||||
appendValues( valuesList.get( i ), sb );
|
||||
}
|
||||
sb.append( ')' );
|
||||
}
|
||||
|
||||
private static void appendValues(SqmValues sqmValues, StringBuilder sb) {
|
||||
final List<SqmExpression<?>> expressions = sqmValues.getExpressions();
|
||||
sb.append( '(' );
|
||||
expressions.get( 0 ).appendHqlString( sb );
|
||||
for ( int i = 1; i < expressions.size(); i++ ) {
|
||||
sb.append( ", " );
|
||||
expressions.get( i ).appendHqlString( sb );
|
||||
}
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,4 +63,25 @@ public class SqmAndPredicate extends AbstractSqmPredicate implements SqmJunctive
|
|||
public SqmPredicate not() {
|
||||
return new SqmNegatedPredicate( this, nodeBuilder() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
if ( leftHandPredicate instanceof SqmOrPredicate ) {
|
||||
sb.append( '(' );
|
||||
leftHandPredicate.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
else {
|
||||
leftHandPredicate.appendHqlString( sb );
|
||||
}
|
||||
sb.append( " and " );
|
||||
if ( rightHandPredicate instanceof SqmOrPredicate ) {
|
||||
sb.append( '(' );
|
||||
rightHandPredicate.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
else {
|
||||
rightHandPredicate.appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,4 +58,16 @@ public class SqmBetweenPredicate extends AbstractNegatableSqmPredicate {
|
|||
public <T> T accept(SemanticQueryWalker<T> walker) {
|
||||
return walker.visitBetweenPredicate( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
expression.appendHqlString( sb );
|
||||
if ( isNegated() ) {
|
||||
sb.append( " not" );
|
||||
}
|
||||
sb.append( " between " );
|
||||
lowerBound.appendHqlString( sb );
|
||||
sb.append( " and " );
|
||||
upperBound.appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,4 +46,9 @@ public class SqmBooleanExpressionPredicate extends AbstractNegatableSqmPredicate
|
|||
public List<Expression<Boolean>> getExpressions() {
|
||||
return Collections.singletonList( booleanExpression );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
booleanExpression.appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,4 +66,13 @@ public class SqmComparisonPredicate extends AbstractNegatableSqmPredicate {
|
|||
public <T> T accept(SemanticQueryWalker<T> walker) {
|
||||
return walker.visitComparisonPredicate( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
leftHandExpression.appendHqlString( sb );
|
||||
sb.append( ' ' );
|
||||
sb.append( operator.sqlText() );
|
||||
sb.append( ' ' );
|
||||
rightHandExpression.appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,4 +32,15 @@ public class SqmEmptinessPredicate extends AbstractNegatableSqmPredicate {
|
|||
public <T> T accept(SemanticQueryWalker<T> walker) {
|
||||
return walker.visitIsEmptyPredicate( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
pluralPath.appendHqlString( sb );
|
||||
if ( isNegated() ) {
|
||||
sb.append( " is not empty" );
|
||||
}
|
||||
else {
|
||||
sb.append( " is empty" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,4 +33,15 @@ public class SqmExistsPredicate extends AbstractNegatableSqmPredicate {
|
|||
public <T> T accept(SemanticQueryWalker<T> walker) {
|
||||
return walker.visitExistsPredicate( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
if ( isNegated() ) {
|
||||
sb.append( "not exists " );
|
||||
}
|
||||
else {
|
||||
sb.append( "exists " );
|
||||
}
|
||||
expression.appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,4 +47,10 @@ public class SqmGroupedPredicate extends AbstractSqmPredicate {
|
|||
public SqmPredicate not() {
|
||||
return new SqmNegatedPredicate( this, nodeBuilder() );
|
||||
}
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( '(' );
|
||||
subPredicate.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,4 +123,19 @@ public class SqmInListPredicate<T> extends AbstractNegatableSqmPredicate impleme
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitInListPredicate( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
testExpression.appendHqlString( sb );
|
||||
if ( isNegated() ) {
|
||||
sb.append( " not" );
|
||||
}
|
||||
sb.append( " in (" );
|
||||
listExpressions.get( 0 ).appendHqlString( sb );
|
||||
for ( int i = 1; i < listExpressions.size(); i++ ) {
|
||||
sb.append( ", " );
|
||||
listExpressions.get( i ).appendHqlString( sb );
|
||||
}
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,4 +82,14 @@ public class SqmInSubQueryPredicate<T> extends AbstractNegatableSqmPredicate imp
|
|||
public SqmInPredicate<T> value(JpaExpression value) {
|
||||
throw new UnsupportedOperationException( );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
testExpression.appendHqlString( sb );
|
||||
if ( isNegated() ) {
|
||||
sb.append( " not" );
|
||||
}
|
||||
sb.append( " in " );
|
||||
subQueryExpression.appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,4 +70,18 @@ public class SqmLikePredicate extends AbstractNegatableSqmPredicate {
|
|||
public <T> T accept(SemanticQueryWalker<T> walker) {
|
||||
return walker.visitLikePredicate( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
matchExpression.appendHqlString( sb );
|
||||
if ( isNegated() ) {
|
||||
sb.append( " not" );
|
||||
}
|
||||
sb.append( " like " );
|
||||
pattern.appendHqlString( sb );
|
||||
if ( escapeCharacter != null ) {
|
||||
sb.append( " escape " );
|
||||
escapeCharacter.appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,4 +46,14 @@ public class SqmMemberOfPredicate extends AbstractNegatableSqmPredicate {
|
|||
public <T> T accept(SemanticQueryWalker<T> walker) {
|
||||
return walker.visitMemberOfPredicate( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
leftHandExpression.appendHqlString( sb );
|
||||
if ( isNegated() ) {
|
||||
sb.append( " not" );
|
||||
}
|
||||
sb.append( " member of " );
|
||||
pluralPath.appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,4 +37,11 @@ public class SqmNegatedPredicate extends AbstractNegatableSqmPredicate {
|
|||
public <T> T accept(SemanticQueryWalker<T> walker) {
|
||||
return walker.visitNegatedPredicate( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "not (" );
|
||||
wrappedPredicate.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,4 +33,15 @@ public class SqmNullnessPredicate extends AbstractNegatableSqmPredicate {
|
|||
public <T> T accept(SemanticQueryWalker<T> walker) {
|
||||
return walker.visitIsNullPredicate( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
expression.appendHqlString( sb );
|
||||
if ( isNegated() ) {
|
||||
sb.append( " is not null" );
|
||||
}
|
||||
else {
|
||||
sb.append( " is null" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,4 +64,25 @@ public class SqmOrPredicate extends AbstractSqmExpression<Boolean> implements Sq
|
|||
public List<Expression<Boolean>> getExpressions() {
|
||||
return Arrays.asList( leftHandPredicate, rightHandPredicate );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
if ( leftHandPredicate instanceof SqmAndPredicate ) {
|
||||
sb.append( '(' );
|
||||
leftHandPredicate.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
else {
|
||||
leftHandPredicate.appendHqlString( sb );
|
||||
}
|
||||
sb.append( " or " );
|
||||
if ( rightHandPredicate instanceof SqmAndPredicate ) {
|
||||
sb.append( '(' );
|
||||
rightHandPredicate.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
else {
|
||||
rightHandPredicate.appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -236,4 +236,20 @@ public abstract class AbstractSqmSelectQuery<T>
|
|||
// this.offset = (ExpressionImplementor) offset;
|
||||
// return this;
|
||||
// }
|
||||
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
if ( !cteStatements.isEmpty() ) {
|
||||
sb.append( "with " );
|
||||
if ( withRecursive ) {
|
||||
sb.append( "recursive " );
|
||||
}
|
||||
for ( SqmCteStatement<?> value : cteStatements.values() ) {
|
||||
value.appendHqlString( sb );
|
||||
sb.append( ", " );
|
||||
}
|
||||
sb.setLength( sb.length() - 2 );
|
||||
}
|
||||
sqmQueryPart.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -171,6 +171,28 @@ public class SqmDynamicInstantiation<T>
|
|||
return walker.visitDynamicInstantiation( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "new " );
|
||||
if ( instantiationTarget.getNature() == LIST ) {
|
||||
sb.append( "list" );
|
||||
}
|
||||
else if ( instantiationTarget.getNature() == MAP ) {
|
||||
sb.append( "map" );
|
||||
}
|
||||
else {
|
||||
sb.append( instantiationTarget.getTargetTypeDescriptor().getJavaTypeClass().getTypeName() );
|
||||
}
|
||||
sb.append( '(' );
|
||||
( (SqmSelectableNode<?>) arguments.get( 0 ) ).appendHqlString( sb );
|
||||
for ( int i = 1; i < arguments.size(); i++ ) {
|
||||
sb.append(", ");
|
||||
( (SqmSelectableNode<?>) arguments.get( i ) ).appendHqlString( sb );
|
||||
}
|
||||
|
||||
sb.append( ')' );
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public SqmDynamicInstantiation<T> makeShallowCopy() {
|
||||
return new SqmDynamicInstantiation<>( getInstantiationTarget(), nodeBuilder() );
|
||||
|
|
|
@ -109,4 +109,14 @@ public class SqmJpaCompoundSelection<T>
|
|||
return walker.visitJpaCompoundSelection( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
selectableNodes.get( 0 ).appendHqlString( sb );
|
||||
for ( int i = 1; i < selectableNodes.size(); i++ ) {
|
||||
sb.append(", ");
|
||||
selectableNodes.get( i ).appendHqlString( sb );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -103,4 +103,27 @@ public class SqmQueryGroup<T> extends SqmQueryPart<T> implements JpaQueryGroup<T
|
|||
public SqmQueryGroup<T> setFetch(JpaExpression<?> fetch, FetchClauseType fetchClauseType) {
|
||||
return (SqmQueryGroup<T>) super.setFetch( fetch, fetchClauseType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
appendQueryPart( queryParts.get( 0 ), sb );
|
||||
for ( int i = 1; i < queryParts.size(); i++ ) {
|
||||
sb.append( ' ' );
|
||||
sb.append( setOperator.sqlString() );
|
||||
sb.append( ' ' );
|
||||
appendQueryPart( queryParts.get( i ), sb );
|
||||
}
|
||||
super.appendHqlString( sb );
|
||||
}
|
||||
|
||||
private static void appendQueryPart(SqmQueryPart<?> queryPart, StringBuilder sb) {
|
||||
final boolean needsParenthesis = !queryPart.isSimpleQueryPart();
|
||||
if ( needsParenthesis ) {
|
||||
sb.append( '(' );
|
||||
}
|
||||
queryPart.appendHqlString( sb );
|
||||
if ( needsParenthesis ) {
|
||||
sb.append( ')' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,4 +147,41 @@ public abstract class SqmQueryPart<T> implements SqmVisitableNode, JpaQueryPart<
|
|||
setFetchExpression( (SqmExpression<?>) fetch, fetchClauseType );
|
||||
return this;
|
||||
}
|
||||
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
if ( orderByClause == null ) {
|
||||
return;
|
||||
}
|
||||
sb.append( " order by " );
|
||||
final List<SqmSortSpecification> sortSpecifications = orderByClause.getSortSpecifications();
|
||||
sortSpecifications.get( 0 ).appendHqlString( sb );
|
||||
for ( int i = 1; i < sortSpecifications.size(); i++ ) {
|
||||
sb.append( ", " );
|
||||
sortSpecifications.get( i ).appendHqlString( sb );
|
||||
}
|
||||
|
||||
if ( offsetExpression != null ) {
|
||||
sb.append( " offset " );
|
||||
offsetExpression.appendHqlString( sb );
|
||||
sb.append( " rows " );
|
||||
}
|
||||
if ( fetchExpression != null ) {
|
||||
sb.append( " fetch first " );
|
||||
fetchExpression.appendHqlString( sb );
|
||||
switch ( fetchClauseType ) {
|
||||
case ROWS_ONLY:
|
||||
sb.append( " rows only" );
|
||||
break;
|
||||
case ROWS_WITH_TIES:
|
||||
sb.append( " rows with ties" );
|
||||
break;
|
||||
case PERCENT_ONLY:
|
||||
sb.append( " percent only" );
|
||||
break;
|
||||
case PERCENT_WITH_TIES:
|
||||
sb.append( " percent with ties" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ import org.hibernate.query.sqm.tree.SqmNode;
|
|||
import org.hibernate.query.sqm.tree.expression.SqmAliasedNodeRef;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
|
||||
import org.hibernate.query.sqm.tree.from.SqmCrossJoin;
|
||||
import org.hibernate.query.sqm.tree.from.SqmEntityJoin;
|
||||
import org.hibernate.query.sqm.tree.from.SqmFrom;
|
||||
import org.hibernate.query.sqm.tree.from.SqmFromClause;
|
||||
import org.hibernate.query.sqm.tree.from.SqmFromClauseContainer;
|
||||
|
@ -325,4 +327,137 @@ public class SqmQuerySpec<T> extends SqmQueryPart<T>
|
|||
setFetchExpression( (SqmExpression<?>) fetch, fetchClauseType );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
if ( selectClause != null ) {
|
||||
sb.append( "select " );
|
||||
if ( selectClause.isDistinct() ) {
|
||||
sb.append( "distinct " );
|
||||
}
|
||||
final List<SqmSelection> selections = selectClause.getSelections();
|
||||
selections.get( 0 ).appendHqlString( sb );
|
||||
for ( int i = 1; i < selections.size(); i++ ) {
|
||||
sb.append( ", " );
|
||||
selections.get( i ).appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
if ( fromClause != null ) {
|
||||
sb.append( " from " );
|
||||
String separator = "";
|
||||
for ( SqmRoot<?> root : fromClause.getRoots() ) {
|
||||
sb.append( separator );
|
||||
if ( root.isCorrelated() ) {
|
||||
if ( root.containsOnlyInnerJoins() ) {
|
||||
appendJoins( root, root.getCorrelationParent().getExplicitAlias(), sb );
|
||||
}
|
||||
else {
|
||||
sb.append( root.getCorrelationParent().getExplicitAlias() );
|
||||
if ( root.getExplicitAlias() != null ) {
|
||||
sb.append( ' ' ).append( root.getExplicitAlias() );
|
||||
}
|
||||
appendJoins( root, sb );
|
||||
}
|
||||
}
|
||||
else {
|
||||
sb.append( root.getEntityName() );
|
||||
if ( root.getExplicitAlias() != null ) {
|
||||
sb.append( ' ' ).append( root.getExplicitAlias() );
|
||||
}
|
||||
appendJoins( root, sb );
|
||||
}
|
||||
separator = ", ";
|
||||
}
|
||||
}
|
||||
if ( whereClause != null && whereClause.getPredicate() != null ) {
|
||||
sb.append( " where " );
|
||||
whereClause.getPredicate().appendHqlString( sb );
|
||||
}
|
||||
if ( !groupByClauseExpressions.isEmpty() ) {
|
||||
sb.append( " group by " );
|
||||
groupByClauseExpressions.get( 0 ).appendHqlString( sb );
|
||||
for ( int i = 1; i < groupByClauseExpressions.size(); i++ ) {
|
||||
sb.append( ", " );
|
||||
groupByClauseExpressions.get( i ).appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
if ( havingClausePredicate != null ) {
|
||||
sb.append( " having " );
|
||||
havingClausePredicate.appendHqlString( sb );
|
||||
}
|
||||
|
||||
super.appendHqlString( sb );
|
||||
}
|
||||
|
||||
private void appendJoins(SqmFrom<?, ?> sqmFrom, StringBuilder sb) {
|
||||
for ( SqmJoin<?, ?> sqmJoin : sqmFrom.getSqmJoins() ) {
|
||||
switch ( sqmJoin.getSqmJoinType() ) {
|
||||
case LEFT:
|
||||
sb.append( " left join " );
|
||||
break;
|
||||
case RIGHT:
|
||||
sb.append( " right join " );
|
||||
break;
|
||||
case INNER:
|
||||
sb.append( " join " );
|
||||
break;
|
||||
case FULL:
|
||||
sb.append( " full join " );
|
||||
break;
|
||||
case CROSS:
|
||||
sb.append( " cross join " );
|
||||
break;
|
||||
}
|
||||
if ( sqmJoin instanceof SqmAttributeJoin<?, ?> ) {
|
||||
final SqmAttributeJoin<?, ?> attributeJoin = (SqmAttributeJoin<?, ?>) sqmJoin;
|
||||
sb.append( sqmFrom.getExplicitAlias() ).append( '.' );
|
||||
sb.append( (attributeJoin).getAttribute().getName() );
|
||||
if ( sqmJoin.getExplicitAlias() != null ) {
|
||||
sb.append( ' ' ).append( sqmJoin.getExplicitAlias() );
|
||||
}
|
||||
if ( attributeJoin.getJoinPredicate() != null ) {
|
||||
sb.append( " on " );
|
||||
attributeJoin.getJoinPredicate().appendHqlString( sb );
|
||||
}
|
||||
appendJoins( sqmJoin, sb );
|
||||
}
|
||||
else if ( sqmJoin instanceof SqmCrossJoin<?> ) {
|
||||
sb.append( ( (SqmCrossJoin<?>) sqmJoin ).getEntityName() );
|
||||
if ( sqmJoin.getExplicitAlias() != null ) {
|
||||
sb.append( ' ' ).append( sqmJoin.getExplicitAlias() );
|
||||
}
|
||||
appendJoins( sqmJoin, sb );
|
||||
}
|
||||
else if ( sqmJoin instanceof SqmEntityJoin<?> ) {
|
||||
final SqmEntityJoin<?> sqmEntityJoin = (SqmEntityJoin<?>) sqmJoin;
|
||||
sb.append( (sqmEntityJoin).getEntityName() );
|
||||
if ( sqmJoin.getExplicitAlias() != null ) {
|
||||
sb.append( ' ' ).append( sqmJoin.getExplicitAlias() );
|
||||
}
|
||||
if ( sqmEntityJoin.getJoinPredicate() != null ) {
|
||||
sb.append( " on " );
|
||||
sqmEntityJoin.getJoinPredicate().appendHqlString( sb );
|
||||
}
|
||||
appendJoins( sqmJoin, sb );
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException( "Unsupported join: " + sqmJoin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void appendJoins(SqmFrom<?, ?> sqmFrom, String correlationPrefix, StringBuilder sb) {
|
||||
String separator = "";
|
||||
for ( SqmJoin<?, ?> sqmJoin : sqmFrom.getSqmJoins() ) {
|
||||
assert sqmJoin instanceof SqmAttributeJoin<?, ?>;
|
||||
sb.append( separator );
|
||||
sb.append( correlationPrefix ).append( '.' );
|
||||
sb.append( ( (SqmAttributeJoin<?, ?>) sqmJoin ).getAttribute().getName() );
|
||||
if ( sqmJoin.getExplicitAlias() != null ) {
|
||||
sb.append( ' ' ).append( sqmJoin.getExplicitAlias() );
|
||||
}
|
||||
appendJoins( sqmJoin, sb );
|
||||
separator = ", ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,4 +54,12 @@ public class SqmSelection<T> extends AbstractSqmNode implements SqmAliasedNode<T
|
|||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
return walker.visitSelection( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
selectableNode.appendHqlString( sb );
|
||||
if ( selectableNode.getAlias() != null ) {
|
||||
sb.append( " as " ).append( selectableNode.getAlias() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,4 +76,28 @@ public class SqmSortSpecification implements JpaOrder {
|
|||
public boolean isAscending() {
|
||||
return sortOrder == SortOrder.ASCENDING;
|
||||
}
|
||||
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sortExpression.appendHqlString( sb );
|
||||
if ( sortOrder == SortOrder.DESCENDING ) {
|
||||
sb.append( " desc" );
|
||||
if ( nullPrecedence != null ) {
|
||||
if ( nullPrecedence == NullPrecedence.FIRST ) {
|
||||
sb.append( " nulls first" );
|
||||
}
|
||||
else {
|
||||
sb.append( " nulls last" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( nullPrecedence != null ) {
|
||||
sb.append( " asc" );
|
||||
if ( nullPrecedence == NullPrecedence.FIRST ) {
|
||||
sb.append( " nulls first" );
|
||||
}
|
||||
else {
|
||||
sb.append( " nulls last" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -407,4 +407,11 @@ public class SqmSubQuery<T> extends AbstractSqmSelectQuery<T> implements SqmSele
|
|||
return walker.visitSubQueryExpression( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( '(' );
|
||||
super.appendHqlString( sb );
|
||||
sb.append( ')' );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm.tree.update;
|
||||
|
||||
import java.util.List;
|
||||
import javax.persistence.criteria.Expression;
|
||||
import javax.persistence.criteria.Path;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
|
@ -182,4 +183,34 @@ public class SqmUpdateStatement<T>
|
|||
}
|
||||
setClause.addAssignment( new SqmAssignment( targetPath, value ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHqlString(StringBuilder sb) {
|
||||
sb.append( "update " );
|
||||
if ( versioned ) {
|
||||
sb.append( "versioned " );
|
||||
}
|
||||
sb.append( getTarget().getEntityName() );
|
||||
if ( getTarget().getExplicitAlias() != null ) {
|
||||
sb.append( ' ' ).append( getTarget().getExplicitAlias() );
|
||||
}
|
||||
sb.append( " set " );
|
||||
final List<SqmAssignment> assignments = setClause.getAssignments();
|
||||
appendAssignment( assignments.get( 0 ), sb );
|
||||
for ( int i = 1; i < assignments.size(); i++ ) {
|
||||
sb.append( ", " );
|
||||
appendAssignment( assignments.get( i ), sb );
|
||||
}
|
||||
|
||||
if ( whereClause != null && whereClause.getPredicate() != null ) {
|
||||
sb.append( " where " );
|
||||
whereClause.getPredicate().appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendAssignment(SqmAssignment sqmAssignment, StringBuilder sb) {
|
||||
sqmAssignment.getTargetPath().appendHqlString( sb );
|
||||
sb.append( " = " );
|
||||
sqmAssignment.getValue().appendHqlString( sb );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue