6 - SQM based on JPA type system

- focus on reducing compilation errors
This commit is contained in:
Steve Ebersole 2019-07-10 12:19:56 -05:00 committed by Andrea Boriero
parent b39d9d22bd
commit f17895e2d5
44 changed files with 1360 additions and 1177 deletions

View File

@ -279,17 +279,6 @@ public interface SessionFactoryBuilder {
EntityMode entityMode,
Class<? extends EntityTuplizer> tuplizerClass);
/**
* How should Query-based updates and deletes be handled when the target spans multiple tables?
*
* @param strategy The strategy for handling multi-table updates and deletes.
*
* @return {@code this}, for method chaining
*
* @see org.hibernate.cfg.AvailableSettings#ID_TABLE_STRATEGY
*/
SessionFactoryBuilder applyMultiTableBulkIdStrategy(SqmMutationStrategy strategy);
SessionFactoryBuilder applyTempTableDdlTransactionHandling(TempTableDdlTransactionHandling handling);
/**
@ -752,21 +741,6 @@ public interface SessionFactoryBuilder {
*/
SessionFactoryBuilder enableJpaClosedCompliance(boolean enabled);
/**
* See the discussion on {@link org.hibernate.cfg.AvailableSettings#NATIVE_QUERY_ORDINAL_PARAMETER_BASE}
* <p/>
* The passed value will be validated to be either:<ul>
* <li>0</li>
* <li>1</li>
* <li>{@code null}</li>
* </ul>
*
* @param base The base to use.
*
* @return {@code this}, for method chaining
*/
SessionFactoryBuilder applyNonJpaNativeQueryOrdinalParameterBase(Integer base);
/**
* Allows unwrapping this builder as another, more specific type.
*

View File

@ -43,6 +43,7 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
private final MetadataImplementor metadata;
private final SessionFactoryOptionsBuilder optionsBuilder;
@SuppressWarnings("WeakerAccess")
public SessionFactoryBuilderImpl(MetadataImplementor metadata, BootstrapContext bootstrapContext) {
this( metadata, new SessionFactoryOptionsBuilder(
metadata.getMetadataBuildingOptions().getServiceRegistry(),
@ -50,6 +51,7 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
) );
}
@SuppressWarnings("WeakerAccess")
public SessionFactoryBuilderImpl(MetadataImplementor metadata, SessionFactoryOptionsBuilder optionsBuilder) {
this.metadata = metadata;
this.optionsBuilder = optionsBuilder;
@ -200,12 +202,6 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
return this;
}
@Override
public SessionFactoryBuilder applyMultiTableBulkIdStrategy(MultiTableBulkIdStrategy strategy) {
this.optionsBuilder.applyMultiTableBulkIdStrategy( strategy );
return this;
}
@Override
public SessionFactoryBuilder applyTempTableDdlTransactionHandling(TempTableDdlTransactionHandling handling) {
this.optionsBuilder.applyTempTableDdlTransactionHandling( handling );
@ -445,10 +441,6 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
this.optionsBuilder.disableJtaTransactionAccess();
}
public void enableJdbcStyleParamsZeroBased() {
this.optionsBuilder.enableJdbcStyleParamsZeroBased();
}
@Override
@SuppressWarnings("unchecked")
public <T extends SessionFactoryBuilder> T unwrap(Class<T> type) {

View File

@ -13,6 +13,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.Callable;
import java.util.function.Supplier;
import org.hibernate.ConnectionAcquisitionMode;
@ -24,12 +25,14 @@ import org.hibernate.EntityNameResolver;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.MultiTenancyStrategy;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.NullPrecedence;
import org.hibernate.SessionEventListener;
import org.hibernate.SessionFactoryObserver;
import org.hibernate.boot.SchemaAutoTooling;
import org.hibernate.boot.TempTableDdlTransactionHandling;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.boot.spi.SessionFactoryOptions;
@ -48,6 +51,7 @@ import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.id.uuid.LocalObjectUuidHelper;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.log.DeprecationLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.jpa.spi.JpaCompliance;
import org.hibernate.jpa.spi.MutableJpaCompliance;
@ -55,6 +59,9 @@ import org.hibernate.loader.BatchFetchStyle;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
import org.hibernate.query.criteria.LiteralHandlingMode;
import org.hibernate.query.hql.SemanticQueryProducer;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.query.sqm.produce.function.SqmFunctionRegistry;
import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
import org.hibernate.resource.jdbc.spi.StatementInspector;
import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder;
@ -74,6 +81,7 @@ import static org.hibernate.cfg.AvailableSettings.AUTO_SESSION_EVENTS_LISTENER;
import static org.hibernate.cfg.AvailableSettings.BATCH_FETCH_STYLE;
import static org.hibernate.cfg.AvailableSettings.BATCH_VERSIONED_DATA;
import static org.hibernate.cfg.AvailableSettings.CACHE_REGION_PREFIX;
import static org.hibernate.cfg.AvailableSettings.CALLABLE_NAMED_PARAMS_ENABLED;
import static org.hibernate.cfg.AvailableSettings.CHECK_NULLABILITY;
import static org.hibernate.cfg.AvailableSettings.COLLECTION_JOIN_SUBQUERY;
import static org.hibernate.cfg.AvailableSettings.CONNECTION_HANDLING;
@ -87,12 +95,11 @@ import static org.hibernate.cfg.AvailableSettings.ENABLE_LAZY_LOAD_NO_TRANS;
import static org.hibernate.cfg.AvailableSettings.FAIL_ON_PAGINATION_OVER_COLLECTION_FETCH;
import static org.hibernate.cfg.AvailableSettings.FLUSH_BEFORE_COMPLETION;
import static org.hibernate.cfg.AvailableSettings.GENERATE_STATISTICS;
import static org.hibernate.cfg.AvailableSettings.HQL_BULK_ID_STRATEGY;
import static org.hibernate.cfg.AvailableSettings.IMMUTABLE_ENTITY_UPDATE_QUERY_HANDLING_MODE;
import static org.hibernate.cfg.AvailableSettings.INTERCEPTOR;
import static org.hibernate.cfg.AvailableSettings.IN_CLAUSE_PARAMETER_PADDING;
import static org.hibernate.cfg.AvailableSettings.JDBC_TIME_ZONE;
import static org.hibernate.cfg.AvailableSettings.JDBC_TYLE_PARAMS_ZERO_BASE;
import static org.hibernate.cfg.AvailableSettings.JPA_CALLBACKS_ENABLED;
import static org.hibernate.cfg.AvailableSettings.JTA_TRACK_BY_THREAD;
import static org.hibernate.cfg.AvailableSettings.LOG_SESSION_METRICS;
import static org.hibernate.cfg.AvailableSettings.MAX_FETCH_DEPTH;
@ -100,12 +107,12 @@ import static org.hibernate.cfg.AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLV
import static org.hibernate.cfg.AvailableSettings.NATIVE_EXCEPTION_HANDLING_51_COMPLIANCE;
import static org.hibernate.cfg.AvailableSettings.OMIT_JOIN_OF_SUPERCLASS_TABLES;
import static org.hibernate.cfg.AvailableSettings.ORDER_INSERTS;
import static org.hibernate.cfg.AvailableSettings.JPA_CALLBACKS_ENABLED;
import static org.hibernate.cfg.AvailableSettings.ORDER_UPDATES;
import static org.hibernate.cfg.AvailableSettings.PREFER_USER_TRANSACTION;
import static org.hibernate.cfg.AvailableSettings.PROCEDURE_NULL_PARAM_PASSING;
import static org.hibernate.cfg.AvailableSettings.QUERY_CACHE_FACTORY;
import static org.hibernate.cfg.AvailableSettings.QUERY_STARTUP_CHECKING;
import static org.hibernate.cfg.AvailableSettings.QUERY_STATISTICS_MAX_SIZE;
import static org.hibernate.cfg.AvailableSettings.QUERY_SUBSTITUTIONS;
import static org.hibernate.cfg.AvailableSettings.RELEASE_CONNECTIONS;
import static org.hibernate.cfg.AvailableSettings.SESSION_FACTORY_NAME;
@ -114,7 +121,6 @@ import static org.hibernate.cfg.AvailableSettings.SESSION_SCOPED_INTERCEPTOR;
import static org.hibernate.cfg.AvailableSettings.STATEMENT_BATCH_SIZE;
import static org.hibernate.cfg.AvailableSettings.STATEMENT_FETCH_SIZE;
import static org.hibernate.cfg.AvailableSettings.STATEMENT_INSPECTOR;
import static org.hibernate.cfg.AvailableSettings.QUERY_STATISTICS_MAX_SIZE;
import static org.hibernate.cfg.AvailableSettings.USE_DIRECT_REFERENCE_CACHE_ENTRIES;
import static org.hibernate.cfg.AvailableSettings.USE_GET_GENERATED_KEYS;
import static org.hibernate.cfg.AvailableSettings.USE_IDENTIFIER_ROLLBACK;
@ -205,12 +211,14 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
private CurrentTenantIdentifierResolver currentTenantIdentifierResolver;
// Queries
private SemanticQueryProducer semanticQueryProducer;
private SqmMutationStrategy sqmMutationStrategy;
private Boolean useOfJdbcNamedParametersEnabled;
private Map querySubstitutions;
private boolean namedQueryStartupCheckingEnabled;
private boolean conventionalJavaConstants;
private final boolean procedureParameterNullPassingEnabled;
private final boolean collectionJoinSubqueryRewriteEnabled;
private boolean jdbcStyleParamsZeroBased;
private final boolean omitJoinOfSuperclassTablesEnabled;
// Caching
@ -348,6 +356,41 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
this.jtaTrackByThread = cfgService.getSetting( JTA_TRACK_BY_THREAD, BOOLEAN, true );
final String semanticQueryProducerImplName = ConfigurationHelper.extractValue(
AvailableSettings.SEMANTIC_QUERY_PRODUCER,
configurationSettings,
() -> ConfigurationHelper.extractPropertyValue(
AvailableSettings.QUERY_TRANSLATOR,
configurationSettings
)
);
this.semanticQueryProducer = resolveSemanticQueryProducer(
semanticQueryProducerImplName,
serviceRegistry,
strategySelector
);
final String sqmMutationStrategyImplName = ConfigurationHelper.extractValue(
AvailableSettings.QUERY_MULTI_TABLE_MUTATION_STRATEGY,
configurationSettings,
() -> ConfigurationHelper.extractValue(
AvailableSettings.ID_TABLE_STRATEGY,
configurationSettings,
() -> ConfigurationHelper.extractPropertyValue(
AvailableSettings.HQL_BULK_ID_STRATEGY,
configurationSettings
)
)
);
this.sqmMutationStrategy = resolveSqmMutationStrategy(
sqmMutationStrategyImplName,
serviceRegistry,
strategySelector
);
this.useOfJdbcNamedParametersEnabled = cfgService.getSetting( CALLABLE_NAMED_PARAMS_ENABLED, BOOLEAN, true );
this.querySubstitutions = ConfigurationHelper.toMap( QUERY_SUBSTITUTIONS, " ,=;:\n\t\r\f", configurationSettings );
this.namedQueryStartupCheckingEnabled = cfgService.getSetting( QUERY_STARTUP_CHECKING, BOOLEAN, true );
this.conventionalJavaConstants = cfgService.getSetting(
@ -485,12 +528,6 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
configurationSettings.get( CRITERIA_LITERAL_HANDLING_MODE )
);
this.jdbcStyleParamsZeroBased = ConfigurationHelper.getBoolean(
JDBC_TYLE_PARAMS_ZERO_BASE,
configurationSettings,
false
);
// added the boolean parameter in case we want to define some form of "all" as discussed
this.jpaCompliance = context.getJpaCompliance();
@ -528,6 +565,50 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
}
}
private SqmMutationStrategy resolveSqmMutationStrategy(
String strategyName,
StandardServiceRegistry serviceRegistry,
StrategySelector strategySelector) {
if ( strategyName == null ) {
return null;
}
//noinspection Convert2Lambda
return strategySelector.resolveDefaultableStrategy(
SqmMutationStrategy.class,
strategyName,
new Callable<SqmMutationStrategy>() {
@Override
public SqmMutationStrategy call() throws Exception {
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
return (SqmMutationStrategy) classLoaderService.classForName( strategyName ).newInstance();
}
}
);
}
private SemanticQueryProducer resolveSemanticQueryProducer(
String producerName,
StandardServiceRegistry serviceRegistry,
StrategySelector strategySelector) {
if ( StringHelper.isEmpty( producerName ) ) {
return null;
}
//noinspection Convert2Lambda
return strategySelector.resolveDefaultableStrategy(
SemanticQueryProducer.class,
producerName,
new Callable<SemanticQueryProducer>() {
@Override
public SemanticQueryProducer call() throws Exception {
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
return (SemanticQueryProducer) classLoaderService.classForName( producerName ).newInstance();
}
}
);
}
@SuppressWarnings("deprecation")
private static Interceptor determineInterceptor(Map configurationSettings, StrategySelector strategySelector) {
Object setting = configurationSettings.get( INTERCEPTOR );
@ -749,6 +830,26 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
return statelessInterceptorSupplier;
}
@Override
public SemanticQueryProducer getHqlTranslator() {
return semanticQueryProducer;
}
@Override
public SqmMutationStrategy getSqmMutationStrategy() {
return sqmMutationStrategy;
}
@Override
public boolean isUseOfJdbcNamedParametersEnabled() {
return this.useOfJdbcNamedParametersEnabled;
}
@Override
public SqmFunctionRegistry getSqmFunctionRegistry() {
throw new NotYetImplementedFor6Exception( getClass() );
}
@Override
public StatementInspector getStatementInspector() {
return statementInspector;
@ -1014,11 +1115,6 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
return immutableEntityUpdateQueryHandlingMode;
}
@Override
public boolean jdbcStyleParamsZeroBased() {
return this.jdbcStyleParamsZeroBased;
}
@Override
public boolean isFailOnPaginationOverCollectionFetchEnabled() {
return this.failOnPaginationOverCollectionFetchEnabled;
@ -1350,10 +1446,6 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
this.jtaTransactionAccessEnabled = false;
}
public void enableJdbcStyleParamsZeroBased() {
this.jdbcStyleParamsZeroBased = true;
}
public SessionFactoryOptions buildOptions() {
if ( MutableJpaCompliance.class.isInstance( this.jpaCompliance ) ) {
this.jpaCompliance = mutableJpaCompliance().immutableCopy();

View File

@ -174,12 +174,6 @@ public abstract class AbstractDelegatingSessionFactoryBuilder<T extends SessionF
return getThis();
}
@Override
public T applyMultiTableBulkIdStrategy(MultiTableBulkIdStrategy strategy) {
delegate.applyMultiTableBulkIdStrategy( strategy );
return getThis();
}
@Override
public T applyTempTableDdlTransactionHandling(TempTableDdlTransactionHandling handling) {
delegate.applyTempTableDdlTransactionHandling( handling );

View File

@ -30,6 +30,8 @@ import org.hibernate.loader.BatchFetchStyle;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
import org.hibernate.query.criteria.LiteralHandlingMode;
import org.hibernate.query.hql.SemanticQueryProducer;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
import org.hibernate.resource.jdbc.spi.StatementInspector;
import org.hibernate.tuple.entity.EntityTuplizerFactory;
@ -116,6 +118,16 @@ public class AbstractDelegatingSessionFactoryOptions implements SessionFactoryOp
return delegate.getInterceptor();
}
@Override
public SemanticQueryProducer getSemanticQueryProducer() {
return delegate.getSemanticQueryProducer();
}
@Override
public SqmMutationStrategy getSqmMutationStrategy() {
return delegate.getSqmMutationStrategy();
}
@Override
public StatementInspector getStatementInspector() {
return delegate.getStatementInspector();

View File

@ -21,11 +21,6 @@ public interface SessionFactoryBuilderImplementor extends SessionFactoryBuilder
default void disableRefreshDetachedEntity() {
}
/**
* @see org.hibernate.cfg.AvailableSettings#JDBC_TYLE_PARAMS_ZERO_BASE
*/
void enableJdbcStyleParamsZeroBased();
/**
* Build the SessionFactoryOptions that will ultimately be passed to SessionFactoryImpl constructor.
*

View File

@ -32,6 +32,8 @@ import org.hibernate.loader.BatchFetchStyle;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
import org.hibernate.query.criteria.LiteralHandlingMode;
import org.hibernate.query.hql.SemanticQueryProducer;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.query.sqm.produce.function.SqmFunctionRegistry;
import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
import org.hibernate.resource.jdbc.spi.StatementInspector;
@ -140,6 +142,10 @@ public interface SessionFactoryOptions {
};
}
SemanticQueryProducer getHqlTranslator();
SqmMutationStrategy getSqmMutationStrategy();
StatementInspector getStatementInspector();
SessionFactoryObserver[] getSessionFactoryObservers();
@ -272,8 +278,6 @@ public interface SessionFactoryOptions {
return LiteralHandlingMode.AUTO;
}
boolean jdbcStyleParamsZeroBased();
JpaCompliance getJpaCompliance();
boolean isFailOnPaginationOverCollectionFetchEnabled();
@ -313,8 +317,6 @@ public interface SessionFactoryOptions {
return false;
}
SqmFunctionRegistry getSqmFunctionRegistry();
/**
* See {@link org.hibernate.cfg.AvailableSettings#NATIVE_QUERY_ORDINAL_PARAMETER_BASE} and
* {@link org.hibernate.boot.SessionFactoryBuilder#applyNonJpaNativeQueryOrdinalParameterBase(Integer)} for details.

View File

@ -497,21 +497,6 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
*/
String JTA_CACHE_UT = "hibernate.jta.cacheUserTransaction";
/**
* `true` / `false - should zero be used as the base for JDBC-style parameters
* found in native-queries?
*
* @since 5.3
*
* @see DeprecationLogger#logUseOfDeprecatedZeroBasedJdbcStyleParams
*
* @deprecated This is a temporary backwards-compatibility setting to help applications
* using versions prior to 5.3 in upgrading. Deprecation warnings are issued when this
* is set to `true`.
*/
@Deprecated
String JDBC_TYLE_PARAMS_ZERO_BASE = "hibernate.query.sql.jdbc_style_params_base";
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// MetadataBuilder level settings
@ -932,9 +917,36 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
/**
* The classname of the HQL query parser factory
*
* @deprecated Use {@link #SEMANTIC_QUERY_PRODUCER}
*/
@Deprecated
String QUERY_TRANSLATOR = "hibernate.query.factory_class";
/**
* Names the {@link org.hibernate.query.hql.SemanticQueryProducer} class to use.
*/
String SEMANTIC_QUERY_PRODUCER = "hibernate.query.hql.translator";
/**
* @deprecated Use {@link #QUERY_MULTI_TABLE_MUTATION_STRATEGY} instead
*/
@Deprecated
String HQL_BULK_ID_STRATEGY = "hibernate.hql.bulk_id_strategy";
/**
* @deprecated Use {@link #QUERY_MULTI_TABLE_MUTATION_STRATEGY} instead
*/
@Deprecated
String ID_TABLE_STRATEGY = "hibernate.id_table_strategy";
/**
* Defines the "global" strategy to use for handling HQL and Criteria mutation queries.
*
* Names the {@link org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy} to use.
*/
String QUERY_MULTI_TABLE_MUTATION_STRATEGY = "hibernate.query.mutation_strategy";
/**
* A comma-separated list of token substitutions to use when translating a Hibernate
* query to SQL
@ -1664,14 +1676,6 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
String ENABLE_LAZY_LOAD_NO_TRANS = "hibernate.enable_lazy_load_no_trans";
/**
* @deprecated Use {@link #ID_TABLE_STRATEGY} instead
*/
@Deprecated
String HQL_BULK_ID_STRATEGY = "hibernate.hql.bulk_id_strategy";
String ID_TABLE_STRATEGY = "hibernate.id_table_strategy";
/**
* Names the {@link org.hibernate.loader.BatchFetchStyle} to use. Can specify either the
* {@link org.hibernate.loader.BatchFetchStyle} name (insensitively), or a

View File

@ -15,6 +15,7 @@ import java.util.Map;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.boot.TempTableDdlTransactionHandling;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.CharIndexFunction;
@ -24,6 +25,7 @@ import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.identity.AbstractTransactSQLIdentityColumnSupport;
import org.hibernate.dialect.identity.IdentityColumnSupport;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.type.StandardBasicTypes;
/**
@ -209,18 +211,20 @@ abstract class AbstractTransactSQLDialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new LocalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String generateIdTableName(String baseName) {
return "#" + baseName;
}
},
// sql-server, at least needed this dropped after use; strange!
AfterUseAction.DROP,
TempTableDdlTransactionHandling.NONE
);
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
// return new LocalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String generateIdTableName(String baseName) {
// return "#" + baseName;
// }
// },
// // sql-server, at least needed this dropped after use; strange!
// AfterUseAction.DROP,
// TempTableDdlTransactionHandling.NONE
// );
}
@Override

View File

@ -12,6 +12,7 @@ import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.LockMode;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.ConditionalParenthesisFunction;
import org.hibernate.dialect.function.ConvertFunction;
@ -38,6 +39,7 @@ import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.sql.CacheJoinFragment;
import org.hibernate.sql.JoinFragment;
import org.hibernate.type.StandardBasicTypes;
@ -441,22 +443,23 @@ public class Cache71Dialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new GlobalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String generateIdTableName(String baseName) {
final String name = super.generateIdTableName( baseName );
return name.length() > 25 ? name.substring( 1, 25 ) : name;
}
@Override
public String getCreateIdTableCommand() {
return "create global temporary table";
}
},
AfterUseAction.DROP
);
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
// return new GlobalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String generateIdTableName(String baseName) {
// final String name = super.generateIdTableName( baseName );
// return name.length() > 25 ? name.substring( 1, 25 ) : name;
// }
//
// @Override
// public String getCreateIdTableCommand() {
// return "create global temporary table";
// }
// },
// AfterUseAction.DROP
// );
}
@Override

View File

@ -8,7 +8,9 @@ package org.hibernate.dialect;
import java.sql.Types;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.dialect.function.DB2SubstringFunction;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.type.descriptor.sql.CharTypeDescriptor;
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
@ -33,28 +35,30 @@ public class DB297Dialect extends DB2Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
// Starting in DB2 9.7, "real" global temporary tables that can be shared between sessions
// are supported; (obviously) data is not shared between sessions.
return new GlobalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String generateIdTableName(String baseName) {
return super.generateIdTableName( baseName );
}
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getCreateIdTableCommand() {
return "create global temporary table";
}
@Override
public String getCreateIdTableStatementOptions() {
return "not logged";
}
},
AfterUseAction.CLEAN
);
// // Starting in DB2 9.7, "real" global temporary tables that can be shared between sessions
// // are supported; (obviously) data is not shared between sessions.
// return new GlobalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String generateIdTableName(String baseName) {
// return super.generateIdTableName( baseName );
// }
//
// @Override
// public String getCreateIdTableCommand() {
// return "create global temporary table";
// }
//
// @Override
// public String getCreateIdTableStatementOptions() {
// return "not logged";
// }
// },
// AfterUseAction.CLEAN
// );
}
@Override

View File

@ -14,6 +14,7 @@ import java.util.Locale;
import org.hibernate.JDBCException;
import org.hibernate.MappingException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.NullPrecedence;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.AvgWithArgumentCastFunction;
@ -36,6 +37,7 @@ import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.hql.spi.id.local.AfterUseAction;
import org.hibernate.hql.spi.id.local.LocalTemporaryTableBulkIdStrategy;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorDB2DatabaseImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
@ -394,30 +396,32 @@ public class DB2Dialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
// Prior to DB2 9.7, "real" global temporary tables that can be shared between sessions
// are *not* supported; even though the DB2 command says to declare a "global" temp table
// Hibernate treats it as a "local" temp table.
return new LocalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String generateIdTableName(String baseName) {
return "session." + super.generateIdTableName( baseName );
}
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getCreateIdTableCommand() {
return "declare global temporary table";
}
@Override
public String getCreateIdTableStatementOptions() {
return "not logged";
}
},
AfterUseAction.DROP,
null
);
// // Prior to DB2 9.7, "real" global temporary tables that can be shared between sessions
// // are *not* supported; even though the DB2 command says to declare a "global" temp table
// // Hibernate treats it as a "local" temp table.
// return new LocalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String generateIdTableName(String baseName) {
// return "session." + super.generateIdTableName( baseName );
// }
//
// @Override
// public String getCreateIdTableCommand() {
// return "declare global temporary table";
// }
//
// @Override
// public String getCreateIdTableStatementOptions() {
// return "not logged";
// }
// },
// AfterUseAction.DROP,
// null
// );
}
@Override

View File

@ -13,6 +13,7 @@ import java.sql.Types;
import java.util.Locale;
import org.hibernate.MappingException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.dialect.function.AnsiTrimFunction;
import org.hibernate.dialect.function.DerbyConcatFunction;
import org.hibernate.dialect.pagination.AbstractLimitHandler;
@ -23,6 +24,7 @@ import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.DerbyCaseFragment;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorDerbyDatabaseImpl;
@ -584,24 +586,26 @@ public class DerbyDialect extends DB2Dialect {
* will make temporary tables created at startup and hence unavailable for subsequent connections.<br/>
* see HHH-10238.
* </p>
*/
* @return
*/
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new LocalTemporaryTableBulkIdStrategy(new IdTableSupportStandardImpl() {
@Override
public String generateIdTableName(String baseName) {
return "session." + super.generateIdTableName( baseName );
}
@Override
public String getCreateIdTableCommand() {
return "declare global temporary table";
}
@Override
public String getCreateIdTableStatementOptions() {
return "not logged";
}
}, AfterUseAction.CLEAN, null);
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
// return new LocalTemporaryTableBulkIdStrategy(new IdTableSupportStandardImpl() {
// @Override
// public String generateIdTableName(String baseName) {
// return "session." + super.generateIdTableName( baseName );
// }
//
// @Override
// public String getCreateIdTableCommand() {
// return "declare global temporary table";
// }
//
// @Override
// public String getCreateIdTableStatementOptions() {
// return "not logged";
// }
// }, AfterUseAction.CLEAN, null);
}
}

View File

@ -35,6 +35,7 @@ import org.hibernate.Interceptor;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.MappingException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.NullPrecedence;
import org.hibernate.Query;
import org.hibernate.ScrollMode;
@ -77,8 +78,6 @@ import org.hibernate.exception.spi.ConversionContext;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.SQLExceptionConverter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
import org.hibernate.hql.spi.id.persistent.PersistentTableBulkIdStrategy;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
@ -99,6 +98,7 @@ import org.hibernate.procedure.internal.StandardCallableStatementSupport;
import org.hibernate.procedure.spi.CallableStatementSupport;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryOptions;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ANSICaseFragment;
import org.hibernate.sql.ANSIJoinFragment;
@ -1149,8 +1149,6 @@ public abstract class Dialect implements ConversionContext {
*
* @param zeroBasedFirstResult The user-supplied, zero-based first row offset.
* @return The corresponding db/dialect specific offset.
* @see Query#setFirstResult
* @see Criteria#setFirstResult
* @deprecated {@link #getLimitHandler()} should be overridden instead.
*/
@Deprecated
@ -1510,8 +1508,8 @@ public abstract class Dialect implements ConversionContext {
return getCreateTableString();
}
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new PersistentTableBulkIdStrategy();
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
}
// callable statement support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -10,6 +10,7 @@ import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.JDBCException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.PessimisticLockException;
import org.hibernate.boot.TempTableDdlTransactionHandling;
import org.hibernate.cfg.AvailableSettings;
@ -32,6 +33,7 @@ import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorH2DatabaseImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
@ -366,24 +368,26 @@ public class H2Dialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new LocalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String getCreateIdTableCommand() {
return "create cached local temporary table if not exists";
}
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getCreateIdTableStatementOptions() {
// actually 2 different options are specified here:
// 1) [on commit drop] - says to drop the table on transaction commit
// 2) [transactional] - says to not perform an implicit commit of any current transaction
return "on commit drop transactional"; }
},
AfterUseAction.CLEAN,
TempTableDdlTransactionHandling.NONE
);
// return new LocalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String getCreateIdTableCommand() {
// return "create cached local temporary table if not exists";
// }
//
// @Override
// public String getCreateIdTableStatementOptions() {
// // actually 2 different options are specified here:
// // 1) [on commit drop] - says to drop the table on transaction commit
// // 2) [transactional] - says to not perform an implicit commit of any current transaction
// return "on commit drop transactional"; }
// },
// AfterUseAction.CLEAN,
// TempTableDdlTransactionHandling.NONE
// );
}
@Override

View File

@ -6,9 +6,11 @@
*/
package org.hibernate.dialect;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.type.StandardBasicTypes;
/**
@ -45,19 +47,21 @@ public class HANAColumnStoreDialect extends AbstractHANADialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new GlobalTemporaryTableBulkIdStrategy( new IdTableSupportStandardImpl() {
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getCreateIdTableCommand() {
return "create global temporary column table";
}
@Override
public String getTruncateIdTableCommand() {
return "truncate table";
}
}, AfterUseAction.CLEAN );
// return new GlobalTemporaryTableBulkIdStrategy( new IdTableSupportStandardImpl() {
//
// @Override
// public String getCreateIdTableCommand() {
// return "create global temporary column table";
// }
//
// @Override
// public String getTruncateIdTableCommand() {
// return "truncate table";
// }
//
// }, AfterUseAction.CLEAN );
}
}

View File

@ -6,6 +6,9 @@
*/
package org.hibernate.dialect;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
/**
* An SQL dialect for the SAP HANA row store.
* <p>
@ -32,13 +35,15 @@ public class HANARowStoreDialect extends AbstractHANADialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new GlobalTemporaryTableBulkIdStrategy( new IdTableSupportStandardImpl() {
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getCreateIdTableCommand() {
return "create global temporary row table";
}
}, AfterUseAction.CLEAN );
// return new GlobalTemporaryTableBulkIdStrategy( new IdTableSupportStandardImpl() {
//
// @Override
// public String getCreateIdTableCommand() {
// return "create global temporary row table";
// }
// }, AfterUseAction.CLEAN );
}
}

View File

@ -15,6 +15,7 @@ import java.util.Locale;
import org.hibernate.JDBCException;
import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.StaleObjectStateException;
import org.hibernate.boot.TempTableDdlTransactionHandling;
import org.hibernate.cfg.Environment;
@ -44,7 +45,7 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHANADatabaseImpl;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHSQLDBDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
@ -503,53 +504,55 @@ public class HSQLDialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
// Hibernate uses this information for temporary tables that it uses for its own operations
// therefore the appropriate strategy is taken with different versions of HSQLDB
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
// All versions of HSQLDB support GLOBAL TEMPORARY tables where the table
// definition is shared by all users but data is private to the session
// HSQLDB 2.0 also supports session-based LOCAL TEMPORARY tables where
// the definition and data is private to the session and table declaration
// can happen in the middle of a transaction
if ( hsqldbVersion < 200 ) {
return new GlobalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String generateIdTableName(String baseName) {
return "HT_" + baseName;
}
@Override
public String getCreateIdTableCommand() {
return "create global temporary table";
}
},
// Version 1.8 GLOBAL TEMPORARY table definitions persist beyond the end
// of the session (by default, data is cleared at commit).
AfterUseAction.CLEAN
);
}
else {
return new LocalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String generateIdTableName(String baseName) {
// With HSQLDB 2.0, the table name is qualified with MODULE to assist the drop
// statement (in-case there is a global name beginning with HT_)
return "MODULE.HT_" + baseName;
}
@Override
public String getCreateIdTableCommand() {
return "declare local temporary table";
}
},
AfterUseAction.DROP,
TempTableDdlTransactionHandling.NONE
);
}
// // Hibernate uses this information for temporary tables that it uses for its own operations
// // therefore the appropriate strategy is taken with different versions of HSQLDB
//
// // All versions of HSQLDB support GLOBAL TEMPORARY tables where the table
// // definition is shared by all users but data is private to the session
// // HSQLDB 2.0 also supports session-based LOCAL TEMPORARY tables where
// // the definition and data is private to the session and table declaration
// // can happen in the middle of a transaction
//
// if ( hsqldbVersion < 200 ) {
// return new GlobalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String generateIdTableName(String baseName) {
// return "HT_" + baseName;
// }
//
// @Override
// public String getCreateIdTableCommand() {
// return "create global temporary table";
// }
// },
// // Version 1.8 GLOBAL TEMPORARY table definitions persist beyond the end
// // of the session (by default, data is cleared at commit).
// AfterUseAction.CLEAN
// );
// }
// else {
// return new LocalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String generateIdTableName(String baseName) {
// // With HSQLDB 2.0, the table name is qualified with MODULE to assist the drop
// // statement (in-case there is a global name beginning with HT_)
// return "MODULE.HT_" + baseName;
// }
//
// @Override
// public String getCreateIdTableCommand() {
// return "declare local temporary table";
// }
// },
// AfterUseAction.DROP,
// TempTableDdlTransactionHandling.NONE
// );
// }
}
// current timestamp support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -10,6 +10,7 @@ import java.sql.SQLException;
import java.sql.Types;
import java.util.Locale;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.NvlFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
@ -24,6 +25,7 @@ import org.hibernate.dialect.unique.UniqueDelegate;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorInformixDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
@ -276,22 +278,24 @@ public class InformixDialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new LocalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String getCreateIdTableCommand() {
return "create temp table";
}
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getCreateIdTableStatementOptions() {
return "with no log";
}
},
AfterUseAction.CLEAN,
null
);
// return new LocalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String getCreateIdTableCommand() {
// return "create temp table";
// }
//
// @Override
// public String getCreateIdTableStatementOptions() {
// return "with no log";
// }
// },
// AfterUseAction.CLEAN,
// null
// );
}
@Override

View File

@ -8,6 +8,7 @@ package org.hibernate.dialect;
import java.sql.Types;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
@ -16,6 +17,7 @@ import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.pagination.FirstLimitHandler;
import org.hibernate.dialect.pagination.LegacyFirstLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.tool.schema.extract.internal.SequenceNameExtractorImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
@ -267,26 +269,28 @@ public class IngresDialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new GlobalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String generateIdTableName(String baseName) {
return "session." + super.generateIdTableName( baseName );
}
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getCreateIdTableCommand() {
return "declare global temporary table";
}
@Override
public String getCreateIdTableStatementOptions() {
return "on commit preserve rows with norecovery";
}
},
AfterUseAction.CLEAN
);
// return new GlobalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String generateIdTableName(String baseName) {
// return "session." + super.generateIdTableName( baseName );
// }
//
// @Override
// public String getCreateIdTableCommand() {
// return "declare global temporary table";
// }
//
// @Override
// public String getCreateIdTableStatementOptions() {
// return "on commit preserve rows with norecovery";
// }
// },
// AfterUseAction.CLEAN
// );
}

View File

@ -14,6 +14,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.JDBCException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.NullPrecedence;
import org.hibernate.PessimisticLockException;
import org.hibernate.boot.TempTableDdlTransactionHandling;
@ -33,6 +34,7 @@ import org.hibernate.exception.LockTimeoutException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.mapping.Column;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.type.StandardBasicTypes;
/**
@ -341,22 +343,24 @@ public class MySQLDialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new LocalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String getCreateIdTableCommand() {
return "create temporary table if not exists";
}
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getDropIdTableCommand() {
return "drop temporary table";
}
},
AfterUseAction.DROP,
TempTableDdlTransactionHandling.NONE
);
// return new LocalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String getCreateIdTableCommand() {
// return "create temporary table if not exists";
// }
//
// @Override
// public String getDropIdTableCommand() {
// return "drop temporary table";
// }
// },
// AfterUseAction.DROP,
// TempTableDdlTransactionHandling.NONE
// );
}
@Override

View File

@ -15,6 +15,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.JDBCException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.QueryTimeoutException;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
@ -36,6 +37,7 @@ import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.procedure.internal.StandardCallableStatementSupport;
import org.hibernate.procedure.spi.CallableStatementSupport;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.DecodeCaseFragment;
import org.hibernate.sql.JoinFragment;
@ -612,27 +614,29 @@ public class Oracle8iDialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new GlobalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String generateIdTableName(String baseName) {
final String name = super.generateIdTableName( baseName );
return name.length() > 30 ? name.substring( 0, 30 ) : name;
}
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getCreateIdTableCommand() {
return "create global temporary table";
}
@Override
public String getCreateIdTableStatementOptions() {
return "on commit delete rows";
}
},
AfterUseAction.CLEAN
);
// return new GlobalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String generateIdTableName(String baseName) {
// final String name = super.generateIdTableName( baseName );
// return name.length() > 30 ? name.substring( 0, 30 ) : name;
// }
//
// @Override
// public String getCreateIdTableCommand() {
// return "create global temporary table";
// }
//
// @Override
// public String getCreateIdTableStatementOptions() {
// return "on commit delete rows";
// }
// },
// AfterUseAction.CLEAN
// );
}
@Override

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.dialect;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.NvlFunction;
@ -16,6 +17,7 @@ import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorOracleDatabaseImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.StandardBasicTypes;
@ -341,27 +343,29 @@ public class Oracle9Dialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new GlobalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String generateIdTableName(String baseName) {
final String name = super.generateIdTableName( baseName );
return name.length() > 30 ? name.substring( 0, 30 ) : name;
}
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getCreateIdTableCommand() {
return "create global temporary table";
}
@Override
public String getCreateIdTableStatementOptions() {
return "on commit delete rows";
}
},
AfterUseAction.CLEAN
);
// return new GlobalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String generateIdTableName(String baseName) {
// final String name = super.generateIdTableName( baseName );
// return name.length() > 30 ? name.substring( 0, 30 ) : name;
// }
//
// @Override
// public String getCreateIdTableCommand() {
// return "create global temporary table";
// }
//
// @Override
// public String getCreateIdTableStatementOptions() {
// return "on commit delete rows";
// }
// },
// AfterUseAction.CLEAN
// );
}
@Override

View File

@ -17,6 +17,7 @@ import java.util.Map;
import org.hibernate.JDBCException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.PessimisticLockException;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
@ -37,6 +38,7 @@ import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.procedure.internal.PostgresCallableStatementSupport;
import org.hibernate.procedure.spi.CallableStatementSupport;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.sql.BlobTypeDescriptor;
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
@ -363,22 +365,24 @@ public class PostgreSQL81Dialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new LocalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String getCreateIdTableCommand() {
return "create temporary table";
}
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getCreateIdTableStatementOptions() {
return "on commit drop";
}
},
AfterUseAction.CLEAN,
null
);
// return new LocalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String getCreateIdTableCommand() {
// return "create temporary table";
// }
//
// @Override
// public String getCreateIdTableStatementOptions() {
// return "on commit drop";
// }
// },
// AfterUseAction.CLEAN,
// null
// );
}
@Override

View File

@ -6,7 +6,9 @@
*/
package org.hibernate.dialect;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.PostgresUUIDType;
@ -30,22 +32,24 @@ public class PostgreSQL82Dialect extends PostgreSQL81Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new LocalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String getCreateIdTableCommand() {
return "create temporary table";
}
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getDropIdTableCommand() {
return "drop table";
}
},
AfterUseAction.DROP,
null
);
// return new LocalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String getCreateIdTableCommand() {
// return "create temporary table";
// }
//
// @Override
// public String getDropIdTableCommand() {
// return "drop table";
// }
// },
// AfterUseAction.DROP,
// null
// );
}
@Override

View File

@ -9,11 +9,13 @@ package org.hibernate.dialect;
import java.sql.DatabaseMetaData;
import java.sql.Types;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.DecodeCaseFragment;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorSAPDBDatabaseImpl;
@ -216,22 +218,24 @@ public class SAPDBDialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new LocalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String generateIdTableName(String baseName) {
return "temp." + super.generateIdTableName( baseName );
}
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getCreateIdTableStatementOptions() {
return "ignore rollback";
}
},
AfterUseAction.DROP,
null
);
// return new LocalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String generateIdTableName(String baseName) {
// return "temp." + super.generateIdTableName( baseName );
// }
//
// @Override
// public String getCreateIdTableStatementOptions() {
// return "ignore rollback";
// }
// },
// AfterUseAction.DROP,
// null
// );
}
@Override

View File

@ -8,9 +8,11 @@ package org.hibernate.dialect;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.type.StandardBasicTypes;
/**
@ -116,34 +118,35 @@ public class TeradataDialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new GlobalTemporaryTableBulkIdStrategy( this, AfterUseAction.CLEAN );
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
// return new GlobalTemporaryTableBulkIdStrategy( this, AfterUseAction.CLEAN );
}
@Override
public String generateIdTableName(String baseName) {
return IdTableSupportStandardImpl.INSTANCE.generateIdTableName( baseName );
}
@Override
public String getCreateIdTableCommand() {
return "create global temporary table";
}
@Override
public String getCreateIdTableStatementOptions() {
return " on commit preserve rows";
}
@Override
public String getDropIdTableCommand() {
return "drop table";
}
@Override
public String getTruncateIdTableCommand() {
return "delete from";
}
// @Override
// public String generateIdTableName(String baseName) {
// return IdTableSupportStandardImpl.INSTANCE.generateIdTableName( baseName );
// }
//
// @Override
// public String getCreateIdTableCommand() {
// return "create global temporary table";
// }
//
// @Override
// public String getCreateIdTableStatementOptions() {
// return " on commit preserve rows";
// }
//
// @Override
// public String getDropIdTableCommand() {
// return "drop table";
// }
//
// @Override
// public String getTruncateIdTableCommand() {
// return "delete from";
// }
/**
* Get the name of the database type associated with the given

View File

@ -9,6 +9,7 @@ package org.hibernate.dialect;
import java.sql.Types;
import org.hibernate.LockMode;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
@ -24,6 +25,7 @@ import org.hibernate.dialect.pagination.FirstLimitHandler;
import org.hibernate.dialect.pagination.LegacyFirstLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.sql.JoinFragment;
import org.hibernate.sql.OracleJoinFragment;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorTimesTenDatabaseImpl;
@ -215,27 +217,29 @@ public class TimesTenDialect extends Dialect {
}
@Override
public MultiTableBulkIdStrategy getDefaultMultiTableBulkIdStrategy() {
return new GlobalTemporaryTableBulkIdStrategy(
new IdTableSupportStandardImpl() {
@Override
public String generateIdTableName(String baseName) {
final String name = super.generateIdTableName( baseName );
return name.length() > 30 ? name.substring( 1, 30 ) : name;
}
public SqmMutationStrategy getFallbackSqmMutationStrategy() {
throw new NotYetImplementedFor6Exception( getClass() );
@Override
public String getCreateIdTableCommand() {
return "create global temporary table";
}
@Override
public String getCreateIdTableStatementOptions() {
return "on commit delete rows";
}
},
AfterUseAction.CLEAN
);
// return new GlobalTemporaryTableBulkIdStrategy(
// new IdTableSupportStandardImpl() {
// @Override
// public String generateIdTableName(String baseName) {
// final String name = super.generateIdTableName( baseName );
// return name.length() > 30 ? name.substring( 1, 30 ) : name;
// }
//
// @Override
// public String getCreateIdTableCommand() {
// return "create global temporary table";
// }
//
// @Override
// public String getCreateIdTableStatementOptions() {
// return "on commit delete rows";
// }
// },
// AfterUseAction.CLEAN
// );
}
@Override

View File

@ -1,684 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.engine.internal;
import java.util.*;
import java.util.Collections;
import org.hibernate.AssertionFailure;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.hql.internal.ast.tree.ImpliedFromElement;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.persister.collection.QueryableCollection;
import org.hibernate.persister.entity.AbstractEntityPersister;
import org.hibernate.persister.entity.Joinable;
import org.hibernate.sql.JoinFragment;
import org.hibernate.sql.JoinType;
import org.hibernate.sql.QueryJoinFragment;
import org.hibernate.type.AssociationType;
/**
* A sequence of {@link Join} delegates to make it "easier" to work with joins. The "easier" part is obviously
* subjective ;)
* <p/>
* Additionally JoinSequence is a directed graph of other JoinSequence instances, as represented by the
* {@link #next} ({@link #setNext(JoinSequence)}) pointer.
*
* @author Gavin King
* @author Steve Ebersole
*
* @see JoinFragment
*/
public class JoinSequence {
private final SessionFactoryImplementor factory;
private final boolean collectionJoinSubquery;
private final StringBuilder conditions = new StringBuilder();
private final List<Join> joins = new ArrayList<Join>();
private boolean useThetaStyle;
private String rootAlias;
private Joinable rootJoinable;
private Selector selector;
private JoinSequence next;
private boolean isFromPart;
private Set<String> queryReferencedTables;
/**
* Constructs a JoinSequence
*
* @param factory The SessionFactory
*/
public JoinSequence(SessionFactoryImplementor factory) {
this.factory = factory;
this.collectionJoinSubquery = factory.getSessionFactoryOptions().isCollectionJoinSubqueryRewriteEnabled();
}
/**
* 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;
}
private Set<String> treatAsDeclarations;
public void applyTreatAsDeclarations(Set<String> treatAsDeclarations) {
if ( treatAsDeclarations == null || treatAsDeclarations.isEmpty() ) {
return;
}
if ( this.treatAsDeclarations == null ) {
this.treatAsDeclarations = new HashSet<String>();
}
this.treatAsDeclarations.addAll( treatAsDeclarations );
}
protected Set<String> getTreatAsDeclarations() {
return treatAsDeclarations;
}
/**
* 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;
}
/**
* Add a join to this sequence
*
* @param associationType The type of the association representing the join
* @param alias The RHS alias for the join
* @param joinType The type of join (INNER, etc)
* @param referencingKey The LHS columns for the join condition
*
* @return The Join memento
*
* @throws MappingException Generally indicates a problem resolving the associationType to a {@link Joinable}
*/
public JoinSequence addJoin(
AssociationType associationType,
String alias,
JoinType joinType,
String[] referencingKey) throws MappingException {
joins.add( new Join( factory, associationType, alias, joinType, new String[][] { referencingKey } ) );
return this;
}
/**
* Add a join to this sequence
*
* @param associationType The type of the association representing the join
* @param alias The RHS alias for the join
* @param joinType The type of join (INNER, etc)
* @param referencingKeys The LHS columns for the join condition
*
* @return The Join memento
*
* @throws MappingException Generally indicates a problem resolving the associationType to a {@link Joinable}
*/
public JoinSequence addJoin(
AssociationType associationType,
String alias,
JoinType joinType,
String[][] referencingKeys) throws MappingException {
joins.add( new Join( factory, associationType, alias, joinType, referencingKeys ) );
return this;
}
/**
* Embedds an implied from element into this sequence
*
* @param fromElement The implied from element to embedd
* @return The Join memento
*/
public JoinSequence addJoin(ImpliedFromElement fromElement) {
joins.addAll( fromElement.getJoinSequence().joins );
return this;
}
/**
* Generate a JoinFragment
*
* @return The JoinFragment
*
* @throws MappingException Indicates a problem access the provided metadata, or incorrect metadata
*/
public JoinFragment toJoinFragment() throws MappingException {
return toJoinFragment( Collections.EMPTY_MAP, true );
}
/**
* Generate a JoinFragment
*
* @param enabledFilters The filters associated with the originating session to properly define join conditions
* @param includeAllSubclassJoins Should all subclass joins be added to the rendered JoinFragment?
*
* @return The JoinFragment
*
* @throws MappingException Indicates a problem access the provided metadata, or incorrect metadata
*/
public JoinFragment toJoinFragment(Map enabledFilters, boolean includeAllSubclassJoins) throws MappingException {
return toJoinFragment( enabledFilters, includeAllSubclassJoins, null );
}
/**
* Generate a JoinFragment
*
* @param enabledFilters The filters associated with the originating session to properly define join conditions
* @param includeAllSubclassJoins Should all subclass joins be added to the rendered JoinFragment?
* @param withClauseFragment The with clause (which represents additional join restrictions) fragment
*
* @return The JoinFragment
*
* @throws MappingException Indicates a problem access the provided metadata, or incorrect metadata
*/
public JoinFragment toJoinFragment(
Map enabledFilters,
boolean includeAllSubclassJoins,
String withClauseFragment) throws MappingException {
return toJoinFragment( enabledFilters, includeAllSubclassJoins, true, withClauseFragment );
}
public JoinFragment toJoinFragment(
Map enabledFilters,
boolean includeAllSubclassJoins,
boolean renderSubclassJoins,
String withClauseFragment) throws MappingException {
final QueryJoinFragment joinFragment = new QueryJoinFragment( factory.getDialect(), useThetaStyle );
Iterator<Join> iter;
Join first;
Joinable last;
if ( rootJoinable != null ) {
joinFragment.addCrossJoin( rootJoinable.getTableName(), rootAlias );
final String filterCondition = rootJoinable.filterFragment( rootAlias, enabledFilters, treatAsDeclarations );
// JoinProcessor needs to know if the where clause fragment came from a dynamic filter or not so it
// can put the where clause fragment in the right place in the SQL AST. 'hasFilterCondition' keeps track
// of that fact.
joinFragment.setHasFilterCondition( joinFragment.addCondition( filterCondition ) );
addSubclassJoins( joinFragment, rootAlias, rootJoinable, true, includeAllSubclassJoins, treatAsDeclarations );
last = rootJoinable;
}
else if ( needsTableGroupJoin( joins, withClauseFragment ) ) {
iter = joins.iterator();
first = iter.next();
final String joinString;
switch (first.joinType) {
case INNER_JOIN:
joinString = " inner join ";
break;
case LEFT_OUTER_JOIN:
joinString = " left outer join ";
break;
case RIGHT_OUTER_JOIN:
joinString = " right outer join ";
break;
case FULL_JOIN:
joinString = " full outer join ";
break;
default:
throw new AssertionFailure("undefined join type");
}
joinFragment.addFromFragmentString( joinString );
joinFragment.addFromFragmentString( " (" );
joinFragment.addFromFragmentString( first.joinable.getTableName() );
joinFragment.addFromFragmentString( " " );
joinFragment.addFromFragmentString( first.getAlias() );
for ( Join join : joins ) {
// Skip joining the first join node as it is contained in the subquery
if ( join != first ) {
joinFragment.addJoin(
join.getJoinable().getTableName(),
join.getAlias(),
join.getLHSColumns(),
JoinHelper.getRHSColumnNames( join.getAssociationType(), factory ),
join.joinType
);
}
addSubclassJoins(
joinFragment,
join.getAlias(),
join.getJoinable(),
// TODO: Think about if this could be made always true
join.joinType == JoinType.INNER_JOIN,
includeAllSubclassJoins,
// ugh.. this is needed because of how HQL parser (FromElementFactory/SessionFactoryHelper)
// builds the JoinSequence for HQL joins
treatAsDeclarations
);
}
joinFragment.addFromFragmentString( ")" );
joinFragment.addFromFragmentString( " on " );
final String rhsAlias = first.getAlias();
final String[][] lhsColumns = first.getLHSColumns();
final String[] rhsColumns = JoinHelper.getRHSColumnNames( first.getAssociationType(), factory );
if ( lhsColumns.length > 1 ) {
joinFragment.addFromFragmentString( "(" );
}
for ( int i = 0; i < lhsColumns.length; i++ ) {
for ( int j = 0; j < lhsColumns[i].length; j++ ) {
joinFragment.addFromFragmentString( lhsColumns[i][j] );
joinFragment.addFromFragmentString( "=" );
joinFragment.addFromFragmentString( rhsAlias );
joinFragment.addFromFragmentString( "." );
joinFragment.addFromFragmentString( rhsColumns[j] );
if ( j < lhsColumns[i].length - 1 ) {
joinFragment.addFromFragmentString( " and " );
}
}
if ( i < lhsColumns.length - 1 ) {
joinFragment.addFromFragmentString( " or " );
}
}
if ( lhsColumns.length > 1 ) {
joinFragment.addFromFragmentString( ")" );
}
joinFragment.addFromFragmentString( " and " );
joinFragment.addFromFragmentString( withClauseFragment );
return joinFragment;
}
else {
last = null;
}
for ( Join join : joins ) {
// technically the treatAsDeclarations should only apply to rootJoinable or to a single Join,
// but that is not possible atm given how these JoinSequence and Join objects are built.
// However, it is generally ok given how the HQL parser builds these JoinSequences (a HQL join
// results in a JoinSequence with an empty rootJoinable and a single Join). So we use that here
// as an assumption
final String on = join.getAssociationType().getOnCondition( join.getAlias(), factory, enabledFilters, treatAsDeclarations );
String condition;
if ( last != null
&& isManyToManyRoot( last )
&& ((QueryableCollection) last).getElementType() == join.getAssociationType() ) {
// the current join represents the join between a many-to-many association table
// and its "target" table. Here we need to apply any additional filters
// defined specifically on the many-to-many
final String manyToManyFilter = ( (QueryableCollection) last ).getManyToManyFilterFragment(
join.getAlias(),
enabledFilters
);
condition = "".equals( manyToManyFilter )
? on
: "".equals( on ) ? manyToManyFilter : on + " and " + manyToManyFilter;
}
else {
condition = on;
}
if ( withClauseFragment != null && !isManyToManyRoot( join.joinable )) {
condition += " and " + withClauseFragment;
}
joinFragment.addJoin(
join.getJoinable().getTableName(),
join.getAlias(),
join.getLHSColumns(),
JoinHelper.getRHSColumnNames( join.getAssociationType(), factory ),
join.joinType,
condition
);
if (renderSubclassJoins) {
addSubclassJoins(
joinFragment,
join.getAlias(),
join.getJoinable(),
join.joinType == JoinType.INNER_JOIN,
includeAllSubclassJoins,
// ugh.. this is needed because of how HQL parser (FromElementFactory/SessionFactoryHelper)
// builds the JoinSequence for HQL joins
treatAsDeclarations
);
}
last = join.getJoinable();
}
if ( next != null ) {
joinFragment.addFragment( next.toJoinFragment( enabledFilters, includeAllSubclassJoins ) );
}
joinFragment.addCondition( conditions.toString() );
if ( isFromPart ) {
joinFragment.clearWherePart();
}
return joinFragment;
}
private boolean needsTableGroupJoin(List<Join> joins, String withClauseFragment) {
// If the rewrite is disabled or we don't have a with clause, we don't need a table group join
if ( !collectionJoinSubquery || StringHelper.isEmpty( withClauseFragment ) ) {
return false;
}
// If we only have one join, a table group join is only necessary if subclass columns are used in the with clause
if ( joins.size() < 2 ) {
return isSubclassAliasDereferenced( joins.get( 0 ), withClauseFragment );
}
// If more than one table is involved and this is not an inner join, we definitely need a table group join
// i.e. a left join has to be made for the table group to retain the join semantics
if ( joins.get( 0 ).getJoinType() != JoinType.INNER_JOIN ) {
return true;
}
// If a subclass columns is used, we need a table group, otherwise we generate wrong SQL by putting the ON condition to the first join
if ( isSubclassAliasDereferenced( joins.get( 0 ), withClauseFragment ) ) {
return true;
}
// Normally, the ON condition of a HQL join is put on the ON clause of the first SQL join
// Since the ON condition could refer to columns from subsequently joined tables i.e. joins with index > 0
// or could refer to columns of subclass tables, the SQL could be wrong
// To avoid generating wrong SQL, we detect these cases here i.e. a subsequent join alias is used in the ON condition
// If we find out that this is the case, we return true and generate a table group join
// Skip the first since that is the driving join
for ( int i = 1; i < joins.size(); i++ ) {
Join join = joins.get( i );
if ( isAliasDereferenced( withClauseFragment, join.getAlias() ) || isSubclassAliasDereferenced( join, withClauseFragment ) ) {
return true;
}
}
return false;
}
private boolean isSubclassAliasDereferenced(Join join, String withClauseFragment) {
if ( join.getJoinable() instanceof AbstractEntityPersister ) {
AbstractEntityPersister persister = (AbstractEntityPersister) join.getJoinable();
int subclassTableSpan = persister.getSubclassTableSpan();
for ( int j = 1; j < subclassTableSpan; j++ ) {
String subclassAlias = AbstractEntityPersister.generateTableAlias( join.getAlias(), j );
if ( isAliasDereferenced( withClauseFragment, subclassAlias ) ) {
return true;
}
}
}
return false;
}
private boolean isAliasDereferenced(String withClauseFragment, String alias) {
// See if the with clause contains the join alias
int index = withClauseFragment.indexOf( alias );
int dotIndex = index + alias.length();
if ( index != -1
// Check that the join alias is not a suffix
&& ( index == 0 || !Character.isLetterOrDigit( withClauseFragment.charAt( index - 1 ) ) )
// Check that the join alias gets de-referenced i.e. the next char is a dot
&& dotIndex < withClauseFragment.length() && withClauseFragment.charAt( dotIndex ) == '.' ) {
return true;
}
return false;
}
@SuppressWarnings("SimplifiableIfStatement")
private boolean isManyToManyRoot(Joinable joinable) {
if ( joinable != null && joinable.isCollection() ) {
return ( (QueryableCollection) joinable ).isManyToMany();
}
return false;
}
private void addSubclassJoins(
JoinFragment joinFragment,
String alias,
Joinable joinable,
boolean innerJoin,
boolean includeSubclassJoins,
Set<String> treatAsDeclarations) {
final boolean include = includeSubclassJoins && isIncluded( alias );
joinFragment.addJoins(
joinable.fromJoinFragment( alias, innerJoin, include, treatAsDeclarations, queryReferencedTables ),
joinable.whereJoinFragment( alias, innerJoin, include, treatAsDeclarations )
);
}
protected boolean isIncluded(String alias) {
return selector != null && selector.includeSubclasses( alias );
}
/**
* Add a condition to this sequence.
*
* @param condition The condition
*
* @return {@link this}, for method chaining
*/
public JoinSequence addCondition(String condition) {
if ( condition.trim().length() != 0 ) {
if ( !condition.startsWith( " and " ) ) {
conditions.append( " and " );
}
conditions.append( condition );
}
return this;
}
/**
* Add a condition to this sequence. Typical usage here might be:
* <pre>
* addCondition( "a", {"c1", "c2"}, "?" )
* </pre>
* to represent:
* <pre>
* "... a.c1 = ? and a.c2 = ? ..."
* </pre>
*
* @param alias The alias to apply to the columns
* @param columns The columns to add checks for
* @param condition The conditions to check against the columns
*
* @return {@link this}, for method chaining
*/
public JoinSequence addCondition(String alias, String[] columns, String condition) {
for ( String column : columns ) {
conditions.append( " and " )
.append( alias )
.append( '.' )
.append( column )
.append( condition );
}
return this;
}
/**
* Set the root of this JoinSequence. In SQL terms, this would be the driving table.
*
* @param joinable The entity/collection that is the root of this JoinSequence
* @param alias The alias associated with that joinable.
*
* @return {@link this}, for method chaining
*/
public JoinSequence setRoot(Joinable joinable, String alias) {
this.rootAlias = alias;
this.rootJoinable = joinable;
return this;
}
/**
* Sets the next join sequence
*
* @param next The next JoinSequence in the directed graph
*
* @return {@code this}, for method chaining
*/
public JoinSequence setNext(JoinSequence next) {
this.next = next;
return this;
}
/**
* Set the Selector to use to determine how subclass joins should be applied.
*
* @param selector The selector to apply
*
* @return {@code this}, for method chaining
*/
public JoinSequence setSelector(Selector selector) {
this.selector = selector;
return this;
}
/**
* Should this JoinSequence use theta-style joining (both a FROM and WHERE component) in the rendered SQL?
*
* @param useThetaStyle {@code true} indicates that theta-style joins should be used.
*
* @return {@code this}, for method chaining
*/
public JoinSequence setUseThetaStyle(boolean useThetaStyle) {
this.useThetaStyle = useThetaStyle;
return this;
}
public boolean isThetaStyle() {
return useThetaStyle;
}
/**
* Set all tables the query refers to. It allows to optimize the query.
*
* @param queryReferencedTables
*/
public void setQueryReferencedTables(Set<String> queryReferencedTables) {
this.queryReferencedTables = queryReferencedTables;
}
public Join getFirstJoin() {
return joins.get( 0 );
}
/**
* A subclass join selector
*/
public static interface Selector {
/**
* Should subclasses be included in the rendered join sequence?
*
* @param alias The alias
*
* @return {@code true} if the subclass joins should be included
*/
public boolean includeSubclasses(String alias);
}
/**
* Represents a join
*/
public static final class Join {
private final AssociationType associationType;
private final Joinable joinable;
private final JoinType joinType;
private final String alias;
private final String[][] lhsColumns;
Join(
SessionFactoryImplementor factory,
AssociationType associationType,
String alias,
JoinType joinType,
String[][] lhsColumns) throws MappingException {
this.associationType = associationType;
this.joinable = associationType.getAssociatedJoinable( factory );
this.alias = alias;
this.joinType = joinType;
this.lhsColumns = lhsColumns;
}
public String getAlias() {
return alias;
}
public AssociationType getAssociationType() {
return associationType;
}
public Joinable getJoinable() {
return joinable;
}
public JoinType getJoinType() {
return joinType;
}
public String[][] getLHSColumns() {
return lhsColumns;
}
@Override
public String toString() {
return joinable.toString() + '[' + alias + ']';
}
}
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
public String toString() {
final StringBuilder buf = new StringBuilder();
buf.append( "JoinSequence{" );
if ( rootJoinable != null ) {
buf.append( rootJoinable )
.append( '[' )
.append( rootAlias )
.append( ']' );
}
for ( Join join : joins ) {
buf.append( "->" ).append( join );
}
return buf.append( '}' ).toString();
}
}

View File

@ -11,6 +11,7 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.function.Supplier;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.ArrayHelper;
@ -319,6 +320,18 @@ public final class ConfigurationHelper {
return value;
}
public static String extractValue(
String name,
Map values,
Supplier<String> fallbackValueFactory) {
final String value = extractPropertyValue( name, values );
if ( value != null ) {
return value;
}
return fallbackValueFactory.get();
}
/**
* Constructs a map from a property value.
* <p/>

View File

@ -0,0 +1,259 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.sqm.mutation.internal;
import java.util.List;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.mapping.RootClass;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.internal.QueryHelper;
import org.hibernate.query.sqm.internal.DomainParameterXref;
import org.hibernate.query.sqm.mutation.spi.DeleteHandler;
import org.hibernate.query.sqm.mutation.spi.HandlerCreationContext;
import org.hibernate.query.sqm.mutation.spi.SqmMutationStrategy;
import org.hibernate.query.sqm.mutation.spi.UpdateHandler;
import org.hibernate.query.sqm.tree.SqmDeleteOrUpdateStatement;
import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement;
import org.hibernate.query.sqm.tree.domain.SqmNavigableReference;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmJunctivePredicate;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.query.sqm.tree.select.SqmQuerySpec;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.exec.spi.JdbcSelect;
/**
* @author Steve Ebersole
*/
public class SqmMutationStrategyHelper {
/**
* Singleton access
*/
public static final SqmMutationStrategyHelper INSTANCE = new SqmMutationStrategyHelper();
private SqmMutationStrategyHelper() {
}
/**
* Standard resolution of SqmMutationStrategy to use for a given
* entity hierarchy.
*/
public static SqmMutationStrategy resolveStrategy(
RootClass bootRootEntityDescriptor,
EntityPersister runtimeRootEntityDescriptor,
SessionFactoryOptions options,
ServiceRegistry serviceRegistry) {
// todo (6.0) : Planned support for per-entity config
if ( options.getSqmMutationStrategy() != null ) {
return options.getSqmMutationStrategy();
}
return serviceRegistry.getService( JdbcServices.class )
.getJdbcEnvironment()
.getDialect()
.getFallbackSqmMutationStrategy( runtimeRootEntityDescriptor );
}
/**
* Specialized "Supplier" or "tri Function" for creating the
* fallback handler if the query matches no "special cases"
*/
public interface FallbackDeleteHandlerCreator {
DeleteHandler create(
SqmDeleteStatement sqmDelete,
DomainParameterXref domainParameterXref,
HandlerCreationContext creationContext);
}
/**
* Standard DeleteHandler resolution applying "special case" resolution
*/
public static DeleteHandler resolveDeleteHandler(
SqmDeleteStatement sqmDelete,
DomainParameterXref domainParameterXref,
HandlerCreationContext creationContext,
FallbackDeleteHandlerCreator fallbackCreator) {
if ( sqmDelete.getWhereClause() == null ) {
// special case : unrestricted
// -> delete all rows, no need to use the id table
}
else {
// if the predicate contains refers to any non-id Navigable, we will need to use the id table
if ( ! hasNonIdReferences( sqmDelete.getWhereClause().getPredicate() ) ) {
// special case : not restricted on non-id Navigable reference
// -> we can apply the original restriction to the individual
//
// todo (6.0) : technically non-id references where the reference is mapped to the primary table
// can also be handled by this special case. Really the special case condition is "has
// any non-id references to Navigables not mapped to the primary table of the container"
}
}
// otherwise, use the fallback....
return fallbackCreator.create( sqmDelete, domainParameterXref, creationContext );
}
/**
* Specialized "Supplier" or "tri Function" for creating the
* fallback handler if the query mmatches no "special cases"
*/
public interface FallbackUpdateHandlerCreator {
UpdateHandler create(
SqmUpdateStatement sqmUpdate,
DomainParameterXref domainParameterXref,
HandlerCreationContext creationContext);
}
/**
* Standard UpdateHandler resolution applying "special case" resolution
*/
public static UpdateHandler resolveUpdateHandler(
SqmUpdateStatement sqmUpdate,
DomainParameterXref domainParameterXref,
HandlerCreationContext creationContext,
FallbackUpdateHandlerCreator fallbackCreator) {
if ( sqmUpdate.getWhereClause() == null ) {
// special case : unrestricted
// -> delete all rows, no need to use the id table
}
else {
// see if the predicate contains any non-id Navigable references
if ( ! hasNonIdReferences( sqmUpdate.getWhereClause().getPredicate() ) ) {
// special case : not restricted on non-id Navigable reference
// -> we can apply the original restriction to the individual updates without needing to use the id-table
//
// todo (6.0) : technically non-id references where the reference is mapped to the primary table
// can also be handled by this special case. Really the special case condition is "has
// any non-id references to Navigables not mapped to the primary table of the container"
}
}
// todo (6.0) : implement the above special cases
// otherwise, use the fallback....
return fallbackCreator.create( sqmUpdate, domainParameterXref, creationContext );
}
/**
* Does the given `predicate` "non-identifier Navigable references"?
*
* @see #isNonIdentifierReference
*/
@SuppressWarnings("WeakerAccess")
public static boolean hasNonIdReferences(SqmPredicate predicate) {
if ( predicate instanceof SqmGroupedPredicate ) {
return hasNonIdReferences( ( (SqmGroupedPredicate) predicate ).getSubPredicate() );
}
if ( predicate instanceof SqmJunctivePredicate ) {
return hasNonIdReferences( ( (SqmJunctivePredicate) predicate ).getLeftHandPredicate() )
&& hasNonIdReferences( ( (SqmJunctivePredicate) predicate ).getRightHandPredicate() );
}
if ( predicate instanceof SqmComparisonPredicate ) {
final SqmExpression lhs = ( (SqmComparisonPredicate) predicate ).getLeftHandExpression();
final SqmExpression rhs = ( (SqmComparisonPredicate) predicate ).getRightHandExpression();
return isNonIdentifierReference( lhs ) || isNonIdentifierReference( rhs );
}
if ( predicate instanceof SqmInListPredicate ) {
final SqmInListPredicate<?> inPredicate = (SqmInListPredicate) predicate;
if ( isNonIdentifierReference( inPredicate.getTestExpression() ) ) {
return true;
}
for ( SqmExpression listExpression : inPredicate.getListExpressions() ) {
if ( isNonIdentifierReference( listExpression ) ) {
return true;
}
}
return false;
}
if ( predicate instanceof SqmBetweenPredicate ) {
final SqmBetweenPredicate betweenPredicate = (SqmBetweenPredicate) predicate;
return isNonIdentifierReference( betweenPredicate.getExpression() )
|| isNonIdentifierReference( betweenPredicate.getLowerBound() )
|| isNonIdentifierReference( betweenPredicate.getUpperBound() );
}
return false;
}
/**
* Is the given `expression` a `SqmNavigableReference` that is also a reference
* to a non-`EntityIdentifier` `Navigable`?
*
* @see SqmNavigableReference
*/
@SuppressWarnings("WeakerAccess")
public static boolean isNonIdentifierReference(SqmExpression expression) {
if ( expression instanceof SqmNavigableReference ) {
return ! EntityIdentifier.class.isInstance( expression );
}
return false;
}
/**
* Centralized selection of ids matching the restriction of the DELETE
* or UPDATE SQM query
*/
public static List<Object> selectMatchingIds(
DomainParameterXref domainParameterXref,
SqmDeleteOrUpdateStatement sqmDeleteStatement,
ExecutionContext executionContext) {
throw new NotYetImplementedFor6Exception( SqmMutationStrategyHelper.class );
// final SqmQuerySpec sqmIdSelectQuerySpec = SqmIdSelectGenerator.generateSqmEntityIdSelect(
// sqmDeleteStatement,
// executionContext.getSession().getSessionFactory()
// );
//
// final SqmSelectToSqlAstConverter sqmConverter = new SqmSelectToSqlAstConverter(
// executionContext.getQueryOptions(),
// domainParameterXref,
// executionContext.getDomainParameterBindingContext().getQueryParameterBindings(),
// executionContext.getLoadQueryInfluencers(),
// executionContext.getCallback(),
// executionContext.getSession().getSessionFactory()
// );
//
// final SqmSelectStatement sqmIdSelect = new SqmSelectStatement( sqmIdSelectQuerySpec );
//
// final SqmSelectInterpretation sqmSelectInterpretation = sqmConverter.interpret( sqmIdSelect );
//
// final JdbcSelect jdbcSelect = SqlAstSelectToJdbcSelectConverter.interpret(
// sqmSelectInterpretation,
// executionContext.getSession().getSessionFactory()
// );
//
// return JdbcSelectExecutorStandardImpl.INSTANCE.list(
// jdbcSelect,
// QueryHelper.buildJdbcParameterBindings(
// domainParameterXref,
// SqmConsumeHelper.generateJdbcParamsXref( domainParameterXref, sqmConverter ),
// executionContext
// ),
// executionContext,
// row -> row[0]
// );
}
}

View File

@ -8,11 +8,15 @@ package org.hibernate.sql.ast.spi;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.EntityTypeLiteral;
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
import org.hibernate.sql.ast.tree.expression.SelfRenderingExpression;
import org.hibernate.sql.ast.tree.expression.SqlSelectionExpression;
import org.hibernate.sql.ast.tree.expression.SqlTuple;
import org.hibernate.sql.ast.tree.expression.UnaryOperation;
import org.hibernate.sql.ast.tree.from.FromClause;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
@ -82,12 +86,8 @@ public interface SqlAstWalker {
void visitCaseSimpleExpression(CaseSimpleExpression caseSimpleExpression);
void visitNamedParameter(NamedParameter namedParameter);
void visitGenericParameter(GenericParameter parameter);
void visitPositionalParameter(PositionalParameter positionalParameter);
void visitQueryLiteral(QueryLiteral queryLiteral);
void visitUnaryOperationExpression(UnaryOperation unaryOperationExpression);
@ -126,13 +126,13 @@ public interface SqlAstWalker {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// functions
void visitExtractUnit(ExtractUnit unit);
void visitCastTarget(CastTarget castTarget);
void visitTrimSpecification(TrimSpecification trimSpecification);
void visitStar(Star star);
void visitDistinct(Distinct distinct);
// void visitExtractUnit(ExtractUnit unit);
//
// void visitCastTarget(CastTarget castTarget);
//
// void visitTrimSpecification(TrimSpecification trimSpecification);
//
// void visitStar(Star star);
//
// void visitDistinct(Distinct distinct);
}

View File

@ -0,0 +1,102 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.sql.ast.tree.expression;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.persister.SqlExpressableType;
import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.spi.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.exec.spi.JdbcParameterBinder;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.sql.results.internal.SqlSelectionImpl;
import org.hibernate.sql.results.spi.DomainResult;
import org.hibernate.sql.results.spi.DomainResultCreationState;
import org.hibernate.sql.results.spi.DomainResultProducer;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* We classify literals different based on their source so that we can handle then differently
* when rendering SQL. This class offers convenience for those implementations
* <p/>
* Can function as a ParameterBinder for cases where we want to treat literals using bind parameters.
*
* @author Steve Ebersole
*/
public abstract class AbstractLiteral
implements JdbcParameterBinder, Expression, SqlExpressable, DomainResultProducer {
private final Object value;
private final SqlExpressableType type;
private final Clause clause;
public AbstractLiteral(Object value, SqlExpressableType type, Clause clause) {
this.value = value;
this.type = type;
this.clause = clause;
}
public Object getValue() {
return value;
}
@Override
public SqlExpressableType getExpressableType() {
return type;
}
public boolean isInSelect() {
return clause == Clause.SELECT;
}
@Override
public SqlSelection createSqlSelection(
int jdbcPosition,
int valuesArrayPosition,
JavaTypeDescriptor javaTypeDescriptor,
TypeConfiguration typeConfiguration) {
// todo (6.0) : for literals and parameters consider simply pushing these values directly into the "current JDBC values" array
// rather than reading them (the same value over and over) from the ResultSet.
//
// see `org.hibernate.sql.ast.tree.expression.AbstractParameter.createSqlSelection`
return new SqlSelectionImpl(
jdbcPosition,
valuesArrayPosition,
this,
getType()
);
}
@Override
public DomainResult createDomainResult(
int valuesArrayPosition,
String resultVariable,
DomainResultCreationState creationState) {
throw new NotYetImplementedFor6Exception( getClass() );
}
@Override
@SuppressWarnings("unchecked")
public void bindParameterValue(
PreparedStatement statement,
int startPosition,
JdbcParameterBindings jdbcParameterBindings,
ExecutionContext executionContext) throws SQLException {
throw new NotYetImplementedFor6Exception( getClass() );
// getType().getJdbcValueBinder().bind( statement, startPosition, value, executionContext );
}
@Override
public SqlExpressableType getType() {
return type;
}
}

View File

@ -0,0 +1,119 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.sql.ast.tree.expression;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.persister.SqlExpressableType;
import org.hibernate.sql.ast.spi.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.results.internal.SqlSelectionImpl;
import org.hibernate.sql.results.spi.DomainResult;
import org.hibernate.sql.results.spi.DomainResultCreationState;
import org.hibernate.sql.results.spi.DomainResultProducer;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
*/
public class CaseSearchedExpression implements Expression, SqlExpressable, DomainResultProducer {
private final SqlExpressableType type;
private List<WhenFragment> whenFragments = new ArrayList<>();
private Expression otherwise;
public CaseSearchedExpression(SqlExpressableType type) {
this.type = type;
}
public List<WhenFragment> getWhenFragments() {
return whenFragments;
}
public Expression getOtherwise() {
return otherwise;
}
public void when(Predicate predicate, Expression result) {
whenFragments.add( new WhenFragment( predicate, result ) );
}
public void otherwise(Expression otherwiseExpression) {
this.otherwise = otherwiseExpression;
// todo : inject implied type?
}
@Override
public SqlExpressableType getExpressableType() {
return type;
}
@Override
public SqlExpressableType getType() {
return type;
}
@Override
public SqlSelection createSqlSelection(
int jdbcPosition,
int valuesArrayPosition,
JavaTypeDescriptor javaTypeDescriptor,
TypeConfiguration typeConfiguration) {
return new SqlSelectionImpl(
jdbcPosition,
valuesArrayPosition,
this,
getExpressableType()
);
}
@Override
public DomainResult createDomainResult(
int valuesArrayPosition,
String resultVariable,
DomainResultCreationState creationState) {
throw new NotYetImplementedFor6Exception( getClass() );
// return new BasicResultImpl(
// resultVariable,
// creationState.getSqlExpressionResolver().resolveSqlSelection(
// this,
// getType().getJavaTypeDescriptor(),
// creationState.getSqlAstCreationState().getCreationContext().getDomainModel().getTypeConfiguration()
// ),
// getType()
// );
}
@Override
public void accept(SqlAstWalker walker) {
walker.visitCaseSearchedExpression( this );
}
public static class WhenFragment {
private final Predicate predicate;
private final Expression result;
public WhenFragment(Predicate predicate, Expression result) {
this.predicate = predicate;
this.result = result;
}
public Predicate getPredicate() {
return predicate;
}
public Expression getResult() {
return result;
}
}
}

View File

@ -0,0 +1,123 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.sql.ast.tree.expression;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.persister.SqlExpressableType;
import org.hibernate.sql.ast.spi.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.results.internal.SqlSelectionImpl;
import org.hibernate.sql.results.spi.DomainResult;
import org.hibernate.sql.results.spi.DomainResultCreationState;
import org.hibernate.sql.results.spi.DomainResultProducer;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
*/
public class CaseSimpleExpression implements Expression, Selectable, SqlExpressable, DomainResultProducer {
private final SqlExpressableType type;
private final Expression fixture;
private List<WhenFragment> whenFragments = new ArrayList<>();
private Expression otherwise;
public CaseSimpleExpression(SqlExpressableType type, Expression fixture) {
this.type = type;
this.fixture = fixture;
}
public Expression getFixture() {
return fixture;
}
@Override
public SqlExpressableType getExpressableType() {
return type;
}
@Override
public SqlExpressableType getType() {
return type;
}
@Override
public SqlSelection createSqlSelection(
int jdbcPosition,
int valuesArrayPosition,
JavaTypeDescriptor javaTypeDescriptor,
TypeConfiguration typeConfiguration) {
return new SqlSelectionImpl(
jdbcPosition,
valuesArrayPosition,
this,
getExpressableType()
);
}
@Override
public void accept(SqlAstWalker walker) {
walker.visitCaseSimpleExpression( this );
}
@Override
public DomainResult createDomainResult(
int valuesArrayPosition,
String resultVariable,
DomainResultCreationState creationState) {
throw new NotYetImplementedFor6Exception( getClass() );
// return new BasicResultImpl(
// resultVariable,
// creationState.getSqlExpressionResolver().resolveSqlSelection(
// this,
// getType().getJavaTypeDescriptor(),
// creationState.getSqlAstCreationState().getCreationContext().getDomainModel().getTypeConfiguration()
// ),
// getType()
// );
}
public List<WhenFragment> getWhenFragments() {
return whenFragments;
}
public Expression getOtherwise() {
return otherwise;
}
public void otherwise(Expression otherwiseExpression) {
this.otherwise = otherwiseExpression;
}
public void when(Expression test, Expression result) {
whenFragments.add( new WhenFragment( test, result ) );
}
public static class WhenFragment {
private final Expression checkValue;
private final Expression result;
public WhenFragment(Expression checkValue, Expression result) {
this.checkValue = checkValue;
this.result = result;
}
public Expression getCheckValue() {
return checkValue;
}
public Expression getResult() {
return result;
}
}
}

View File

@ -30,31 +30,31 @@ public class ColumnReference implements Expression {
private String sqlFragment;
public ColumnReference(ColumnReferenceQualifier qualifier, Identifier columnName, SqlExpressableType sqlExpressableType) {
// the assumption with this assertion is that callers are expecting there
// to be a qualifier; otherwise, they would call the overload ctor form
// not accepting a qualifier
assert qualifier != null : "ColumnReferenceQualifier is null";
// public ColumnReference(ColumnReferenceQualifier qualifier, Identifier columnName, SqlExpressableType sqlExpressableType) {
// // the assumption with this assertion is that callers are expecting there
// // to be a qualifier; otherwise, they would call the overload ctor form
// // not accepting a qualifier
// assert qualifier != null : "ColumnReferenceQualifier is null";
//
// this.columnName = columnName;
// this.sqlExpressableType = sqlExpressableType;
// this.sqlFragment = renderSqlFragment( qualifier, columnName );
// }
this.columnName = columnName;
this.sqlExpressableType = sqlExpressableType;
this.sqlFragment = renderSqlFragment( qualifier, columnName );
}
private static String renderSqlFragment(ColumnReferenceQualifier qualifier, Identifier columnName) {
if ( qualifier == null ) {
return columnName.render();
}
else {
final TableReference tableReference = qualifier.locateTableReference( column.getSourceTable() );
return columnName.render( tableReference.getIdentificationVariable() );
}
}
// private static String renderSqlFragment(ColumnReferenceQualifier qualifier, Identifier columnName) {
// if ( qualifier == null ) {
// return columnName.render();
// }
// else {
// final TableReference tableReference = qualifier.locateTableReference( column.getSourceTable() );
// return columnName.render( tableReference.getIdentificationVariable() );
// }
// }
public ColumnReference(Identifier columnName, SqlExpressableType sqlExpressableType) {
this.columnName = columnName;
this.sqlExpressableType = sqlExpressableType;
this.sqlFragment = renderSqlFragment( null, columnName );
// this.sqlFragment = renderSqlFragment( null, columnName );
}
@Override

View File

@ -0,0 +1,27 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.sql.ast.tree.expression;
import org.hibernate.persister.SqlExpressableType;
import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.spi.SqlAstWalker;
/**
* A literal specified in the source query.
*
* @author Steve Ebersole
*/
public class QueryLiteral extends AbstractLiteral {
public QueryLiteral(Object value, SqlExpressableType expressableType, Clause clause) {
super( value, expressableType, clause );
}
@Override
public void accept(SqlAstWalker walker) {
walker.visitQueryLiteral( this );
}
}

View File

@ -0,0 +1,87 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.sql.ast.tree.expression;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.persister.SqlExpressableType;
import org.hibernate.query.UnaryArithmeticOperator;
import org.hibernate.sql.ast.spi.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.results.internal.SqlSelectionImpl;
import org.hibernate.sql.results.spi.DomainResult;
import org.hibernate.sql.results.spi.DomainResultCreationState;
import org.hibernate.sql.results.spi.DomainResultProducer;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
*/
public class UnaryOperation implements Expression, SqlExpressable, DomainResultProducer {
private final UnaryArithmeticOperator operator;
private final Expression operand;
private final SqlExpressableType type;
public UnaryOperation(UnaryArithmeticOperator operator, Expression operand, SqlExpressableType type) {
this.operator = operator;
this.operand = operand;
this.type = type;
}
public UnaryArithmeticOperator getOperator() {
return operator;
}
public Expression getOperand() {
return operand;
}
@Override
public SqlExpressableType getExpressableType() {
return type;
}
@Override
public SqlSelection createSqlSelection(
int jdbcPosition,
int valuesArrayPosition,
JavaTypeDescriptor javaTypeDescriptor,
TypeConfiguration typeConfiguration) {
return new SqlSelectionImpl(
jdbcPosition,
valuesArrayPosition,
this,
getExpressableType()
);
}
@Override
public void accept(SqlAstWalker walker) {
walker.visitUnaryOperationExpression( this );
}
@Override
public DomainResult createDomainResult(
int valuesArrayPosition,
String resultVariable,
DomainResultCreationState creationState) {
throw new NotYetImplementedFor6Exception( getClass() );
}
@Override
public void applySqlSelections(DomainResultCreationState creationState) {
throw new NotYetImplementedFor6Exception( getClass() );
}
@Override
public SqlExpressableType getType() {
return type;
}
}

View File

@ -6,7 +6,7 @@
*/
package org.hibernate.sql.exec.spi;
import org.hibernate.sql.SqlExpressableType;
import org.hibernate.persister.SqlExpressableType;
/**
* @author Steve Ebersole

View File

@ -95,7 +95,7 @@ public class DerbyDialectTestCase extends BaseUnitTestCase {
@Test
@TestForIssue(jiraKey = "HHH-10238")
public void testDefaultMultiTableBulkIdStrategyIsLocal() {
MultiTableBulkIdStrategy actual = new LocalDerbyDialect().getDefaultMultiTableBulkIdStrategy();
MultiTableBulkIdStrategy actual = new LocalDerbyDialect().getFallbackSqmMutationStrategy();
assertThat(actual, is(instanceOf(LocalTemporaryTableBulkIdStrategy.class)));
}
}

View File

@ -20,7 +20,7 @@ public class Oracle8iDialectTestCase extends BaseUnitTestCase {
@Test
@TestForIssue(jiraKey = "HHH-9290")
public void testTemporaryTableNameTruncation() throws Exception {
final AbstractMultiTableBulkIdStrategyImpl strategy = (AbstractMultiTableBulkIdStrategyImpl) new Oracle8iDialect().getDefaultMultiTableBulkIdStrategy();
final AbstractMultiTableBulkIdStrategyImpl strategy = (AbstractMultiTableBulkIdStrategyImpl) new Oracle8iDialect().getFallbackSqmMutationStrategy();
String temporaryTableName = strategy.getIdTableSupport().generateIdTableName(
"TABLE_NAME_THAT_EXCEEDS_30_CHARACTERS"

View File

@ -35,7 +35,7 @@ public abstract class AbstractBulkCompositeIdTest extends BaseCoreFunctionalTest
@Override
protected Configuration constructConfiguration() {
Configuration configuration = super.constructConfiguration();
configuration.setProperty( AvailableSettings.HQL_BULK_ID_STRATEGY, getMultiTableBulkIdStrategyClass().getName() );
configuration.setProperty( AvailableSettings.QUERY_MULTI_TABLE_MUTATION_STRATEGY, getMultiTableBulkIdStrategyClass().getName() );
return configuration;
}

View File

@ -34,7 +34,7 @@ public abstract class AbstractBulkIdTest extends BaseCoreFunctionalTestCase {
@Override
protected Configuration constructConfiguration() {
Configuration configuration = super.constructConfiguration();
configuration.setProperty( AvailableSettings.HQL_BULK_ID_STRATEGY, getMultiTableBulkIdStrategyClass().getName() );
configuration.setProperty( AvailableSettings.QUERY_MULTI_TABLE_MUTATION_STRATEGY, getMultiTableBulkIdStrategyClass().getName() );
return configuration;
}

View File

@ -46,7 +46,7 @@ public class GlobalQuotedIdentifiersBulkIdTest
@Override
protected void addConfigOptions(Map options) {
options.put( AvailableSettings.GLOBALLY_QUOTED_IDENTIFIERS, Boolean.TRUE );
options.put( AvailableSettings.HQL_BULK_ID_STRATEGY, InlineIdsOrClauseBulkIdStrategy.class.getName() );
options.put( AvailableSettings.QUERY_MULTI_TABLE_MUTATION_STRATEGY, InlineIdsOrClauseBulkIdStrategy.class.getName() );
}
@Before