diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/AltibaseDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/AltibaseDialect.java index 9a3457bfbd4d..01f6e18e19a4 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/AltibaseDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/AltibaseDialect.java @@ -5,6 +5,7 @@ package org.hibernate.community.dialect; import jakarta.persistence.TemporalType; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.TypeContributions; import org.hibernate.community.dialect.pagination.AltibaseLimitHandler; @@ -41,6 +42,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -295,8 +297,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new AltibaseSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new AltibaseSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/AltibaseSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/AltibaseSqlAstTranslator.java index d070871c6d3a..3a156916d047 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/AltibaseSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/AltibaseSqlAstTranslator.java @@ -6,12 +6,14 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.collections.Stack; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.query.common.FrameExclusion; import org.hibernate.query.common.FrameKind; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.delete.DeleteStatement; @@ -39,10 +41,15 @@ */ public class AltibaseSqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public AltibaseSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public AltibaseSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public void visitOffsetFetchClause(QueryPart queryPart) { if ( !isRowNumberingCurrentQueryPart() ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CUBRIDDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CUBRIDDialect.java index 6d63ea34a024..9cd15c040cd5 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CUBRIDDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CUBRIDDialect.java @@ -6,6 +6,7 @@ import java.sql.Types; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.TypeContributions; import org.hibernate.community.dialect.identity.CUBRIDIdentityColumnSupport; @@ -30,6 +31,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -368,8 +370,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new CUBRIDSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new CUBRIDSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CUBRIDSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CUBRIDSqlAstTranslator.java index e9daf6fd3ac4..7585c2d3b10d 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CUBRIDSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CUBRIDSqlAstTranslator.java @@ -6,8 +6,10 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -25,10 +27,15 @@ */ public class CUBRIDSqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public CUBRIDSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public CUBRIDSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public void visitOffsetFetchClause(QueryPart queryPart) { renderCombinedLimitClause( queryPart ); diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CacheDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CacheDialect.java index 1e3132cebd81..9cbe414d7971 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CacheDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CacheDialect.java @@ -6,6 +6,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.TemporalType; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.Locking; @@ -39,6 +40,7 @@ import org.hibernate.query.sqm.IntervalType; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.LockingClauseStrategy; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; @@ -340,8 +342,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new CacheSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new CacheSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CacheSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CacheSqlAstTranslator.java index 3a6a49e3e5a7..3f7690e02a71 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CacheSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CacheSqlAstTranslator.java @@ -6,9 +6,11 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Locking; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -28,10 +30,15 @@ */ public class CacheSqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public CacheSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public CacheSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected LockStrategy determineLockingStrategy( QuerySpec querySpec, diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java index 80dc0affc598..4f0c08f9e6f5 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java @@ -66,6 +66,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -701,8 +702,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new CockroachLegacySqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new CockroachLegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacySqlAstTranslator.java index 1cc740bb5d43..240e1948d133 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacySqlAstTranslator.java @@ -4,9 +4,11 @@ */ package org.hibernate.community.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Locking; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.cte.CteMaterialization; @@ -36,10 +38,15 @@ */ public class CockroachLegacySqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public CockroachLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public CockroachLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public void visitBinaryArithmeticExpression(BinaryArithmeticExpression arithmeticExpression) { if ( isIntegerDivisionEmulationRequired( arithmeticExpression ) ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java index 7b165775a200..a06b6709154b 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java @@ -71,6 +71,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -1273,8 +1274,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new DB2LegacySqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new DB2LegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java index 96095e245454..0ec7e43d84c4 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.dialect.DatabaseVersion; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -19,6 +20,7 @@ import org.hibernate.query.common.FetchClauseType; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.MutationStatement; @@ -65,10 +67,15 @@ public class DB2LegacySqlAstTranslator extends Abstract // We have to track whether we are in a later query for applying lateral during window emulation private boolean inLateral; + @Deprecated(forRemoval = true, since = "7.1") public DB2LegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public DB2LegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected boolean needsRecursiveKeywordInWithClause() { return false; diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2iLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2iLegacyDialect.java index 09daa7b7b99e..b29a70e9d516 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2iLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2iLegacyDialect.java @@ -4,6 +4,7 @@ */ package org.hibernate.community.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.dialect.DatabaseVersion; import org.hibernate.dialect.function.CommonFunctionFactory; @@ -27,6 +28,7 @@ import org.hibernate.mapping.Column; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -158,11 +160,10 @@ public boolean supportsRecursiveCTE() { @Override public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { - @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new DB2iLegacySqlAstTranslator<>( sessionFactory, statement, getVersion() ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new DB2iLegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo, getVersion() ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2iLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2iLegacySqlAstTranslator.java index 0b317ad48713..3bbaf3c485bb 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2iLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2iLegacySqlAstTranslator.java @@ -4,9 +4,11 @@ */ package org.hibernate.community.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.DatabaseVersion; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Literal; @@ -25,11 +27,17 @@ public class DB2iLegacySqlAstTranslator extends DB2Lega private final DatabaseVersion version; + @Deprecated(forRemoval = true, since = "7.1") public DB2iLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, DatabaseVersion version) { super( sessionFactory, statement ); this.version = version; } + public DB2iLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo, DatabaseVersion version) { + super( sessionFactory, statement, parameterInfo ); + this.version = version; + } + @Override protected boolean shouldEmulateFetchClause(QueryPart queryPart) { // Check if current query part is already row numbering to avoid infinite recursion diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2zLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2zLegacyDialect.java index 3ce2acb8cb71..760dda6d41d9 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2zLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2zLegacyDialect.java @@ -5,6 +5,7 @@ package org.hibernate.community.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.dialect.DatabaseVersion; import org.hibernate.dialect.TimeZoneSupport; @@ -29,6 +30,7 @@ import org.hibernate.query.common.TemporalUnit; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -227,8 +229,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new DB2zLegacySqlAstTranslator<>( sessionFactory, statement, getVersion() ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new DB2zLegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo, getVersion() ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2zLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2zLegacySqlAstTranslator.java index 7bbd45a1cc84..3d5f2b67d1f5 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2zLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2zLegacySqlAstTranslator.java @@ -4,9 +4,11 @@ */ package org.hibernate.community.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.DatabaseVersion; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.Literal; @@ -26,11 +28,17 @@ public class DB2zLegacySqlAstTranslator extends DB2Lega private final DatabaseVersion version; + @Deprecated(forRemoval = true, since = "7.1") public DB2zLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, DatabaseVersion version) { super( sessionFactory, statement ); this.version = version; } + public DB2zLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo, DatabaseVersion version) { + super( sessionFactory, statement, parameterInfo ); + this.version = version; + } + @Override protected boolean shouldEmulateFetchClause(QueryPart queryPart) { // Percent fetches or ties fetches aren't supported in DB2 z/OS diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyDialect.java index 6da693aca935..bcbe3dfab0dc 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyDialect.java @@ -6,6 +6,7 @@ import jakarta.persistence.TemporalType; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockOptions; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.TypeContributions; @@ -62,6 +63,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.internal.PessimisticLockKind; import org.hibernate.sql.ast.spi.LockingClauseStrategy; import org.hibernate.sql.ast.spi.SqlAppender; @@ -405,8 +407,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new DerbySqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new DerbySqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyLegacyDialect.java index 791da6a11282..214d37f52ede 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyLegacyDialect.java @@ -6,6 +6,7 @@ import jakarta.persistence.TemporalType; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockOptions; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.TypeContributions; @@ -61,6 +62,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.internal.PessimisticLockKind; import org.hibernate.sql.ast.spi.LockingClauseStrategy; import org.hibernate.sql.ast.spi.SqlAppender; @@ -409,8 +411,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new DerbyLegacySqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new DerbyLegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyLegacySqlAstTranslator.java index 41ad6b3776b5..30cfe5bc4a87 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbyLegacySqlAstTranslator.java @@ -7,11 +7,13 @@ import java.util.List; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.collections.Stack; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -37,10 +39,15 @@ */ public class DerbyLegacySqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public DerbyLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public DerbyLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitDeleteStatementOnly(DeleteStatement statement) { if ( hasNonTrivialFromClause( statement.getFromClause() ) ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbySqlAstTranslator.java index 873bcea0f36c..5a630f711944 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DerbySqlAstTranslator.java @@ -7,11 +7,13 @@ import java.util.List; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.collections.Stack; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -37,10 +39,15 @@ */ public class DerbySqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public DerbySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public DerbySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitDeleteStatementOnly(DeleteStatement statement) { if ( hasNonTrivialFromClause( statement.getFromClause() ) ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/FirebirdDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/FirebirdDialect.java index 61b59ef77390..fbba1f8b0152 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/FirebirdDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/FirebirdDialect.java @@ -5,6 +5,7 @@ package org.hibernate.community.dialect; import jakarta.persistence.TemporalType; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.boot.Metadata; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.TypeContributions; @@ -59,6 +60,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -417,8 +419,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new FirebirdSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new FirebirdSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/FirebirdSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/FirebirdSqlAstTranslator.java index ec59a0d4e3fa..347e08c9ac73 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/FirebirdSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/FirebirdSqlAstTranslator.java @@ -7,11 +7,13 @@ import java.util.List; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.collections.Stack; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.SqlSelection; @@ -51,10 +53,15 @@ public class FirebirdSqlAstTranslator extends AbstractS private boolean inFunction; + @Deprecated(forRemoval = true, since = "7.1") public FirebirdSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public FirebirdSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitInsertStatementOnly(InsertSelectStatement statement) { if ( statement.getConflictClause() == null || statement.getConflictClause().isDoNothing() ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBDialect.java index eb9f7f6cf90a..53b1d9060ac3 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBDialect.java @@ -67,6 +67,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; @@ -777,8 +778,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new GaussDBSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new GaussDBSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBSqlAstTranslator.java index 4436d49b37dd..308697e38bab 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/GaussDBSqlAstTranslator.java @@ -4,11 +4,13 @@ */ package org.hibernate.community.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.metamodel.mapping.JdbcMappingContainer; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.query.common.FetchClauseType; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAstTranslatorWithMerge; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.cte.CteMaterialization; @@ -44,10 +46,15 @@ */ public class GaussDBSqlAstTranslator extends SqlAstTranslatorWithMerge { + @Deprecated(forRemoval = true, since = "7.1") public GaussDBSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public GaussDBSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public void visitInArrayPredicate(InArrayPredicate inArrayPredicate) { inArrayPredicate.getTestExpression().accept( this ); diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacyDialect.java index 091295f07581..98a6a806de60 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacyDialect.java @@ -69,6 +69,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -546,8 +547,8 @@ public String currentTimestampWithTimeZone() { public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override - protected SqlAstTranslator buildTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { - return new H2LegacySqlAstTranslator<>( sessionFactory, statement ); + protected SqlAstTranslator buildTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new H2LegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacySqlAstTranslator.java index 4e823e8ace8a..3fa3a9462991 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacySqlAstTranslator.java @@ -6,6 +6,7 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.dialect.identity.H2IdentityColumnSupport; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -15,6 +16,7 @@ import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -55,10 +57,15 @@ public class H2LegacySqlAstTranslator extends AbstractS private boolean renderAsArray; + @Deprecated(forRemoval = true, since = "7.1") public H2LegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public H2LegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public void visitStandardTableInsert(TableInsertStandard tableInsert) { if ( getDialect().getVersion().isSameOrAfter( 2 ) diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HANALegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HANALegacyDialect.java index a213bca84000..2702184f24cd 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HANALegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HANALegacyDialect.java @@ -6,6 +6,7 @@ import jakarta.persistence.TemporalType; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.ScrollMode; @@ -33,7 +34,6 @@ import org.hibernate.dialect.pagination.LimitOffsetLimitHandler; import org.hibernate.dialect.sequence.HANASequenceSupport; import org.hibernate.dialect.sequence.SequenceSupport; -import org.hibernate.dialect.sql.ast.HANASqlAstTranslator; import org.hibernate.dialect.temptable.HANAGlobalTemporaryTableStrategy; import org.hibernate.dialect.temptable.TemporaryTableKind; import org.hibernate.dialect.temptable.TemporaryTableStrategy; @@ -73,6 +73,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -545,8 +546,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, org.hibernate.sql.ast.tree.Statement statement) { - return new HANASqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, org.hibernate.sql.ast.tree.Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new HANALegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HANALegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HANALegacySqlAstTranslator.java index a30399d5c175..9614ad6d5a06 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HANALegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HANALegacySqlAstTranslator.java @@ -6,6 +6,7 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.MappingException; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.collections.Stack; @@ -16,6 +17,7 @@ import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.tree.SqlAstNode; import org.hibernate.sql.ast.tree.Statement; @@ -48,10 +50,15 @@ public class HANALegacySqlAstTranslator extends Abstrac private boolean inLateral; + @Deprecated(forRemoval = true, since = "7.1") public HANALegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public HANALegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public void visitBinaryArithmeticExpression(BinaryArithmeticExpression arithmeticExpression) { if ( isIntegerDivisionEmulationRequired( arithmeticExpression ) ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacyDialect.java index 737bf0a109e6..15e60405ced6 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacyDialect.java @@ -70,6 +70,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -329,8 +330,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new HSQLLegacySqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new HSQLLegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java index d84f91fea50a..0ed9d2a05b5a 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Locking; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.metamodel.mapping.JdbcMappingContainer; @@ -14,6 +15,7 @@ import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -42,10 +44,15 @@ */ public class HSQLLegacySqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public HSQLLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public HSQLLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitInsertStatementOnly(InsertSelectStatement statement) { if ( statement.getConflictClause() == null || statement.getConflictClause().isDoNothing() ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixDialect.java index 57d5231c4e04..d63a2d1a8afd 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixDialect.java @@ -42,6 +42,7 @@ import org.hibernate.query.sqm.IntervalType; import org.hibernate.query.sqm.function.SqmFunctionRegistry; import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.type.BasicType; import org.hibernate.dialect.lock.internal.LockingSupportSimple; import org.hibernate.dialect.lock.spi.LockingSupport; @@ -440,8 +441,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new InformixSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new InformixSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixSqlAstTranslator.java index 824b4d9ef648..2565a7a4eb55 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixSqlAstTranslator.java @@ -6,11 +6,13 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.IllegalQueryOperationException; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.query.sqm.sql.internal.SqmParameterInterpretation; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAstTranslatorWithMerge; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -41,10 +43,15 @@ */ public class InformixSqlAstTranslator extends SqlAstTranslatorWithMerge { + @Deprecated(forRemoval = true, since = "7.1") public InformixSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public InformixSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitQueryClauses(QuerySpec querySpec) { visitSelectClause( querySpec.getSelectClause() ); diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/IngresDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/IngresDialect.java index 163323cf63e8..4929d220805b 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/IngresDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/IngresDialect.java @@ -7,6 +7,7 @@ import java.sql.Types; import jakarta.persistence.TemporalType; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockOptions; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.community.dialect.identity.Ingres10IdentityColumnSupport; @@ -49,6 +50,7 @@ import org.hibernate.query.sqm.tree.select.SqmSelectStatement; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.LockingClauseStrategy; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.SqlAstCreationContext; @@ -335,8 +337,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new IngresSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new IngresSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/IngresSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/IngresSqlAstTranslator.java index bc111dedc109..b61b3884f129 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/IngresSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/IngresSqlAstTranslator.java @@ -6,9 +6,11 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Locking; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -28,10 +30,15 @@ */ public class IngresSqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public IngresSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public IngresSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected LockStrategy determineLockingStrategy( QuerySpec querySpec, diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacyDialect.java index 6f5d4e6e702e..4f3e3dd07efa 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacyDialect.java @@ -7,6 +7,7 @@ import java.sql.DatabaseMetaData; import java.sql.SQLException; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.TypeContributions; import org.hibernate.dialect.*; @@ -29,6 +30,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -189,8 +191,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new MariaDBLegacySqlAstTranslator<>( sessionFactory, statement, MariaDBLegacyDialect.this ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new MariaDBLegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo, MariaDBLegacyDialect.this ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacySqlAstTranslator.java index 96e57dc4ef63..bbc9a6cbc816 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacySqlAstTranslator.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.DmlTargetColumnQualifierSupport; import org.hibernate.dialect.sql.ast.MySQLSqlAstTranslator; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -14,6 +15,7 @@ import org.hibernate.metamodel.mapping.JdbcMappingContainer; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.tree.MutationStatement; import org.hibernate.sql.ast.tree.Statement; @@ -48,11 +50,17 @@ public class MariaDBLegacySqlAstTranslator extends Abst private final MariaDBLegacyDialect dialect; + @Deprecated(forRemoval = true, since = "7.1") public MariaDBLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, MariaDBLegacyDialect dialect) { super( sessionFactory, statement ); this.dialect = dialect; } + public MariaDBLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo, MariaDBLegacyDialect dialect) { + super( sessionFactory, statement, parameterInfo ); + this.dialect = dialect; + } + @Override protected void visitInsertSource(InsertSelectStatement statement) { if ( statement.getSourceSelectStatement() != null ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MaxDBDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MaxDBDialect.java index 3f5fe8b6de6e..01e342786fea 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MaxDBDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MaxDBDialect.java @@ -7,6 +7,7 @@ import java.sql.DatabaseMetaData; import java.sql.Types; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.community.dialect.sequence.MaxDBSequenceSupport; import org.hibernate.community.dialect.sequence.SequenceInformationExtractorSAPDBDatabaseImpl; @@ -34,6 +35,7 @@ import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -196,8 +198,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new MaxDBSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new MaxDBSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MaxDBSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MaxDBSqlAstTranslator.java index ba9db385bce3..b428a15c9f8d 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MaxDBSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MaxDBSqlAstTranslator.java @@ -6,8 +6,10 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -26,10 +28,15 @@ */ public class MaxDBSqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public MaxDBSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public MaxDBSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public void visitOffsetFetchClause(QueryPart queryPart) { renderLimitOffsetClause( queryPart ); diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MimerSQLDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MimerSQLDialect.java index 1cd814671090..ec15982b781a 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MimerSQLDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MimerSQLDialect.java @@ -5,6 +5,7 @@ package org.hibernate.community.dialect; import jakarta.persistence.TemporalType; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.TypeContributions; import org.hibernate.community.dialect.identity.MimerSQLIdentityColumnSupport; @@ -27,6 +28,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -179,8 +181,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new MimerSQLSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new MimerSQLSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MimerSQLSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MimerSQLSqlAstTranslator.java index 90853fa54b07..80e1177f32a2 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MimerSQLSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MimerSQLSqlAstTranslator.java @@ -6,8 +6,10 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -25,10 +27,15 @@ */ public class MimerSQLSqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public MimerSQLSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public MimerSQLSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public void visitOffsetFetchClause(QueryPart queryPart) { assertRowsOnlyFetchClauseType( queryPart ); diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java index 130f86be7bef..ac6753927e39 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java @@ -6,6 +6,7 @@ import jakarta.persistence.TemporalType; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.PessimisticLockException; import org.hibernate.Timeouts; import org.hibernate.boot.model.FunctionContributions; @@ -70,6 +71,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -762,8 +764,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new MySQLLegacySqlAstTranslator<>( sessionFactory, statement, MySQLLegacyDialect.this ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new MySQLLegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo, MySQLLegacyDialect.this ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacySqlAstTranslator.java index 7326c6868df3..9784276b4207 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacySqlAstTranslator.java @@ -7,12 +7,14 @@ import java.util.ArrayList; import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.DmlTargetColumnQualifierSupport; import org.hibernate.dialect.sql.ast.MySQLSqlAstTranslator; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.collections.Stack; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.tree.MutationStatement; import org.hibernate.sql.ast.tree.Statement; @@ -49,11 +51,17 @@ public class MySQLLegacySqlAstTranslator extends Abstra private final MySQLLegacyDialect dialect; + @Deprecated(forRemoval = true, since = "7.1") public MySQLLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, MySQLLegacyDialect dialect) { super( sessionFactory, statement ); this.dialect = dialect; } + public MySQLLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo, MySQLLegacyDialect dialect) { + super( sessionFactory, statement, parameterInfo ); + this.dialect = dialect; + } + @Override protected void visitInsertSource(InsertSelectStatement statement) { if ( statement.getSourceSelectStatement() != null ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacyDialect.java index 91c59b8af375..059bd8c0a209 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacyDialect.java @@ -20,6 +20,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.TemporalType; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.QueryTimeoutException; import org.hibernate.Timeouts; import org.hibernate.boot.model.FunctionContributions; @@ -96,6 +97,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -404,8 +406,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new OracleLegacySqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new OracleLegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacySqlAstTranslator.java index 7a69ccaca791..9128ec85c428 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacySqlAstTranslator.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Locking; import org.hibernate.dialect.type.OracleArrayJdbcType; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -26,6 +27,7 @@ import org.hibernate.query.sqm.sql.internal.SqmPathInterpretation; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.SqlAstNode; @@ -74,10 +76,15 @@ */ public class OracleLegacySqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public OracleLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public OracleLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitInsertStatementOnly(InsertSelectStatement statement) { if ( statement.getConflictClause() == null || statement.getConflictClause().isDoNothing() ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java index 91debe50d7dd..bd168f098ff7 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java @@ -90,6 +90,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -1037,8 +1038,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new PostgreSQLLegacySqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new PostgreSQLLegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacySqlAstTranslator.java index ce17185addc5..3c2cc09ac56b 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacySqlAstTranslator.java @@ -4,11 +4,13 @@ */ package org.hibernate.community.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.metamodel.mapping.JdbcMappingContainer; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.query.common.FetchClauseType; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.cte.CteMaterialization; @@ -42,10 +44,15 @@ */ public class PostgreSQLLegacySqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public PostgreSQLLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public PostgreSQLLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public void visitInArrayPredicate(InArrayPredicate inArrayPredicate) { inArrayPredicate.getTestExpression().accept( this ); diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgresPlusLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgresPlusLegacyDialect.java index e1c3870663b6..3bb803b1f834 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgresPlusLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgresPlusLegacyDialect.java @@ -9,6 +9,7 @@ import java.sql.SQLException; import java.sql.Types; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.dialect.DatabaseVersion; import org.hibernate.dialect.function.CommonFunctionFactory; @@ -19,6 +20,7 @@ import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression; @@ -143,8 +145,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new PostgreSQLLegacySqlAstTranslator<>( sessionFactory, statement ) { + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new PostgreSQLLegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo ) { @Override public void visitBinaryArithmeticExpression(BinaryArithmeticExpression arithmeticExpression) { if ( isIntegerDivisionEmulationRequired( arithmeticExpression ) ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/RDMSOS2200Dialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/RDMSOS2200Dialect.java index 3f6d29eb1463..850976142406 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/RDMSOS2200Dialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/RDMSOS2200Dialect.java @@ -5,6 +5,7 @@ package org.hibernate.community.dialect; import jakarta.persistence.TemporalType; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.Locking; @@ -33,6 +34,7 @@ import org.hibernate.query.sqm.TrimSpec; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.LockingClauseStrategy; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; @@ -246,8 +248,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new RDMSOS2200SqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new RDMSOS2200SqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/RDMSOS2200SqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/RDMSOS2200SqlAstTranslator.java index 3696ea64f6ed..dde1b082442a 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/RDMSOS2200SqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/RDMSOS2200SqlAstTranslator.java @@ -6,10 +6,12 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Locking; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.query.common.FetchClauseType; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -29,10 +31,15 @@ */ public class RDMSOS2200SqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public RDMSOS2200SqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public RDMSOS2200SqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected LockStrategy determineLockingStrategy( QuerySpec querySpec, diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacyDialect.java index 8f9a692afded..7d6f981aa560 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacyDialect.java @@ -6,6 +6,7 @@ import jakarta.persistence.TemporalType; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Length; import org.hibernate.LockMode; import org.hibernate.LockOptions; @@ -77,6 +78,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -565,8 +567,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new SQLServerLegacySqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new SQLServerLegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java index aea08621b817..f2b78125b45a 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java @@ -6,6 +6,7 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Internal; import org.hibernate.LockMode; import org.hibernate.Locking; @@ -24,6 +25,7 @@ import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstJoinType; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.SqlAstNode; @@ -62,10 +64,15 @@ public class SQLServerLegacySqlAstTranslator extends Ab private Predicate lateralPredicate; + @Deprecated(forRemoval = true, since = "7.1") public SQLServerLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public SQLServerLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitInsertStatementOnly(InsertSelectStatement statement) { if ( statement.getConflictClause() == null || statement.getConflictClause().isDoNothing() ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLiteDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLiteDialect.java index 75be6ae017ac..34191a347945 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLiteDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLiteDialect.java @@ -5,6 +5,7 @@ package org.hibernate.community.dialect; import jakarta.persistence.TemporalType; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockOptions; import org.hibernate.ScrollMode; import org.hibernate.boot.Metadata; @@ -45,6 +46,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.LockingClauseStrategy; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; @@ -435,8 +437,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new SQLiteSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new SQLiteSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLiteSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLiteSqlAstTranslator.java index aa21fd377e3a..cd4e5f30e443 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLiteSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLiteSqlAstTranslator.java @@ -4,9 +4,11 @@ */ package org.hibernate.community.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Locking; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.cte.CteMaterialization; @@ -28,10 +30,15 @@ */ public class SQLiteSqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public SQLiteSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public SQLiteSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected LockStrategy determineLockingStrategy( QuerySpec querySpec, diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SingleStoreDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SingleStoreDialect.java index a1ed90516f95..dabf7b314399 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SingleStoreDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SingleStoreDialect.java @@ -6,6 +6,7 @@ import jakarta.persistence.TemporalType; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Length; import org.hibernate.PessimisticLockException; import org.hibernate.boot.Metadata; @@ -87,6 +88,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -812,8 +814,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new SingleStoreSqlAstTranslator<>( sessionFactory, statement, SingleStoreDialect.this ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new SingleStoreSqlAstTranslator<>( sessionFactory, statement, parameterInfo, SingleStoreDialect.this ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SingleStoreSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SingleStoreSqlAstTranslator.java index 188840b1491c..3544816d294e 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SingleStoreSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SingleStoreSqlAstTranslator.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Locale; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.DmlTargetColumnQualifierSupport; import org.hibernate.engine.jdbc.Size; @@ -16,6 +17,7 @@ import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.query.sqm.SetOperator; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.MutationStatement; @@ -54,11 +56,17 @@ public class SingleStoreSqlAstTranslator extends Abstra private static final int MAX_CHAR_SIZE = 8192; private final SingleStoreDialect dialect; + @Deprecated(forRemoval = true, since = "7.1") public SingleStoreSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, SingleStoreDialect dialect) { super( sessionFactory, statement ); this.dialect = dialect; } + public SingleStoreSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo, SingleStoreDialect dialect) { + super( sessionFactory, statement, parameterInfo ); + this.dialect = dialect; + } + @Override public void visitBinaryArithmeticExpression(BinaryArithmeticExpression arithmeticExpression) { if ( isIntegerDivisionEmulationRequired( arithmeticExpression ) ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacyDialect.java index 535650ac9cb8..54509fdef3fb 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacyDialect.java @@ -5,6 +5,7 @@ package org.hibernate.community.dialect; import jakarta.persistence.TemporalType; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.QueryTimeoutException; @@ -33,6 +34,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -226,8 +228,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new SybaseASELegacySqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new SybaseASELegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacySqlAstTranslator.java index d35dd8d395c0..908c071dd3d2 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacySqlAstTranslator.java @@ -4,6 +4,7 @@ */ package org.hibernate.community.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.Locking; import org.hibernate.dialect.DmlTargetColumnQualifierSupport; @@ -14,6 +15,7 @@ import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.MutationStatement; @@ -55,10 +57,15 @@ public class SybaseASELegacySqlAstTranslator extends Ab private static final String UNION_ALL = " union all "; + @Deprecated(forRemoval = true, since = "7.1") public SybaseASELegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public SybaseASELegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitInsertStatementOnly(InsertSelectStatement statement) { if ( statement.getConflictClause() == null || statement.getConflictClause().isDoNothing() ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseAnywhereDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseAnywhereDialect.java index eddbd5df5edf..bf646a8c1931 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseAnywhereDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseAnywhereDialect.java @@ -5,6 +5,7 @@ package org.hibernate.community.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Length; import org.hibernate.LockOptions; import org.hibernate.boot.model.FunctionContributions; @@ -23,6 +24,7 @@ import org.hibernate.sql.ForUpdateFragment; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -114,8 +116,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new SybaseAnywhereSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new SybaseAnywhereSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseAnywhereSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseAnywhereSqlAstTranslator.java index ce6b3b3b860a..bae846705e3f 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseAnywhereSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseAnywhereSqlAstTranslator.java @@ -7,11 +7,13 @@ import java.util.List; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.dialect.sql.ast.SybaseSqlAstTranslator; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -38,10 +40,15 @@ public class SybaseAnywhereSqlAstTranslator extends Abs private static final String UNION_ALL = " union all "; + @Deprecated(forRemoval = true, since = "7.1") public SybaseAnywhereSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public SybaseAnywhereSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + // Sybase Anywhere does not allow CASE expressions where all result arms contain plain parameters. // At least one result arm must provide some type context for inference, // so we cast the first result arm if we encounter this condition diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacyDialect.java index d025598c4c15..8745a6d8cee4 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacyDialect.java @@ -5,6 +5,7 @@ package org.hibernate.community.dialect; import jakarta.persistence.TemporalType; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.TypeContributions; import org.hibernate.dialect.AbstractTransactSQLDialect; @@ -45,6 +46,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; @@ -210,8 +212,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new SybaseLegacySqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new SybaseLegacySqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacySqlAstTranslator.java index 8a745e9f81c0..5a30097eac54 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacySqlAstTranslator.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.Locking; import org.hibernate.dialect.sql.ast.SybaseSqlAstTranslator; @@ -16,6 +17,7 @@ import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -47,10 +49,15 @@ public class SybaseLegacySqlAstTranslator extends Abstr private static final String UNION_ALL = " union all "; + @Deprecated(forRemoval = true, since = "7.1") public SybaseLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public SybaseLegacySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitInsertStatementOnly(InsertSelectStatement statement) { if ( statement.getConflictClause() == null || statement.getConflictClause().isDoNothing() ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TeradataDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TeradataDialect.java index fa76a017e3cd..8258e3a1489b 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TeradataDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TeradataDialect.java @@ -4,6 +4,7 @@ */ package org.hibernate.community.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockOptions; import org.hibernate.Timeouts; import org.hibernate.boot.Metadata; @@ -43,6 +44,7 @@ import org.hibernate.sql.ForUpdateFragment; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.internal.NonLockingClauseStrategy; import org.hibernate.sql.ast.internal.PessimisticLockKind; import org.hibernate.sql.ast.spi.LockingClauseStrategy; @@ -190,8 +192,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new TeradataSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new TeradataSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TeradataSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TeradataSqlAstTranslator.java index 01bd12bad1dc..f2d7c362a8fa 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TeradataSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TeradataSqlAstTranslator.java @@ -6,9 +6,11 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Locking; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.LockingClauseStrategy; import org.hibernate.sql.ast.spi.SqlSelection; @@ -30,8 +32,13 @@ public class TeradataSqlAstTranslator extends AbstractSqlAstTranslator { private final boolean supportsLocking; + @Deprecated(forRemoval = true, since = "7.1") public TeradataSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { - super( sessionFactory, statement ); + this( sessionFactory, statement, null ); + } + + public TeradataSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); supportsLocking = getDialect().getVersion().isSameOrAfter( 14 ); } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TiDBDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TiDBDialect.java index c176699b7f11..991c59518640 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TiDBDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TiDBDialect.java @@ -6,6 +6,7 @@ import jakarta.persistence.TemporalType; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Timeouts; import org.hibernate.community.dialect.sequence.SequenceInformationExtractorTiDBDatabaseImpl; import org.hibernate.community.dialect.sequence.TiDBSequenceSupport; @@ -25,6 +26,7 @@ import org.hibernate.query.sqm.IntervalType; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -116,8 +118,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new TiDBSqlAstTranslator<>( sessionFactory, statement, TiDBDialect.this ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new TiDBSqlAstTranslator<>( sessionFactory, statement, parameterInfo, TiDBDialect.this ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TiDBSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TiDBSqlAstTranslator.java index 77789b6ae34b..91199fd57398 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TiDBSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TiDBSqlAstTranslator.java @@ -4,12 +4,14 @@ */ package org.hibernate.community.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.DmlTargetColumnQualifierSupport; import org.hibernate.dialect.sql.ast.MySQLSqlAstTranslator; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.collections.Stack; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.tree.MutationStatement; import org.hibernate.sql.ast.tree.Statement; @@ -50,11 +52,17 @@ public class TiDBSqlAstTranslator extends AbstractSqlAs private final TiDBDialect dialect; + @Deprecated(forRemoval = true, since = "7.1") public TiDBSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, TiDBDialect dialect) { super( sessionFactory, statement ); this.dialect = dialect; } + public TiDBSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo, TiDBDialect dialect) { + super( sessionFactory, statement, parameterInfo ); + this.dialect = dialect; + } + @Override public void visitBinaryArithmeticExpression(BinaryArithmeticExpression arithmeticExpression) { if ( isIntegerDivisionEmulationRequired( arithmeticExpression ) ) { diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TimesTenDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TimesTenDialect.java index 4c5123f651df..e60a742081e6 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TimesTenDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TimesTenDialect.java @@ -7,6 +7,7 @@ import java.sql.Types; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.Locking; import org.hibernate.Timeouts; @@ -38,6 +39,7 @@ import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -185,8 +187,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new TimesTenSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new TimesTenSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TimesTenSqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TimesTenSqlAstTranslator.java index f8a636ccae46..b4bd53858a41 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TimesTenSqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/TimesTenSqlAstTranslator.java @@ -6,10 +6,12 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Locking; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.IllegalQueryOperationException; import org.hibernate.query.sqm.ComparisonOperator; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -30,10 +32,15 @@ */ public class TimesTenSqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public TimesTenSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public TimesTenSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected LockStrategy determineLockingStrategy( QuerySpec querySpec, diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/AltibaseLimitHandler.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/AltibaseLimitHandler.java index a95be7931045..85b8ab238f7d 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/AltibaseLimitHandler.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/AltibaseLimitHandler.java @@ -5,6 +5,7 @@ package org.hibernate.community.dialect.pagination; import org.hibernate.dialect.pagination.LimitLimitHandler; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; /** * Limit handler for {@link org.hibernate.community.dialect.AltibaseDialect}. @@ -19,8 +20,24 @@ protected String limitClause(boolean hasFirstRow) { return hasFirstRow ? " limit 1+?,?" : " limit ?"; } + @Override + protected String limitClause(boolean hasFirstRow, int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + final String firstParameter = parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ); + if ( hasFirstRow ) { + return " limit 1+" + firstParameter + "," + parameterMarkerStrategy.createMarker( jdbcParameterCount + 2, null ); + } + else { + return " limit " + firstParameter; + } + } + @Override protected String offsetOnlyClause() { return " limit 1+?," + Integer.MAX_VALUE; } + + @Override + protected String offsetOnlyClause(int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + return " limit 1+" + parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ) + "," + Integer.MAX_VALUE; + } } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/FirstLimitHandler.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/FirstLimitHandler.java index 3dd03b74ca14..fd181e374cae 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/FirstLimitHandler.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/FirstLimitHandler.java @@ -6,6 +6,8 @@ import org.hibernate.dialect.pagination.AbstractNoOffsetLimitHandler; import org.hibernate.dialect.pagination.LimitHandler; +import org.hibernate.query.spi.Limit; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; /** * A {@link LimitHandler} for older versions of Informix, Ingres, @@ -27,6 +29,11 @@ protected String limitClause() { return " first ?"; } + @Override + protected String limitClause(int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + return " first " + parameterMarkerStrategy.createMarker( 1, null ) + " rows only"; + } + @Override protected String insert(String first, String sql) { return insertAfterSelect( first, sql ); @@ -36,4 +43,14 @@ protected String insert(String first, String sql) { public boolean bindLimitParametersFirst() { return true; } + + @Override + public boolean processSqlMutatesState() { + return false; + } + + @Override + public int getParameterPositionStart(Limit limit) { + return hasMaxRows( limit ) && supportsVariableLimit() ? 2 : 1; + } } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/FirstSkipLimitHandler.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/FirstSkipLimitHandler.java index d8d4adf69d5b..db969c3b07b5 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/FirstSkipLimitHandler.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/FirstSkipLimitHandler.java @@ -4,9 +4,13 @@ */ package org.hibernate.community.dialect.pagination; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.pagination.AbstractLimitHandler; import org.hibernate.dialect.pagination.LimitHandler; import org.hibernate.query.spi.Limit; +import org.hibernate.query.spi.QueryOptions; +import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; /** * A {@link LimitHandler} for Firebird 2.5 and older which supports the syntax @@ -18,6 +22,15 @@ public class FirstSkipLimitHandler extends AbstractLimitHandler { @Override public String processSql(String sql, Limit limit) { + return processSql( sql, -1, null, limit ); + } + + @Override + public String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, QueryOptions queryOptions) { + return processSql( sql, jdbcParameterCount, parameterMarkerStrategy, queryOptions.getLimit() ); + } + + private String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, Limit limit) { boolean hasFirstRow = hasFirstRow( limit ); boolean hasMaxRows = hasMaxRows( limit ); @@ -27,13 +40,26 @@ public String processSql(String sql, Limit limit) { StringBuilder skipFirst = new StringBuilder(); - if ( hasMaxRows ) { - skipFirst.append( " first ?" ); + if ( ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy ) ) { + if ( hasMaxRows ) { + skipFirst.append( " first ?" ); + } + if ( hasFirstRow ) { + skipFirst.append( " skip ?" ); + } } - if ( hasFirstRow ) { - skipFirst.append( " skip ?" ); + else { + String marker = parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ); + if ( hasMaxRows ) { + skipFirst.append( " first " ); + skipFirst.append( marker ); + marker = parameterMarkerStrategy.createMarker( jdbcParameterCount + 2, null ); + } + if ( hasFirstRow ) { + skipFirst.append( " skip " ); + skipFirst.append( marker ); + } } - return insertAfterSelect( skipFirst.toString(), sql ); } @@ -57,4 +83,16 @@ public final boolean bindLimitParametersFirst() { return true; } + @Override + public boolean processSqlMutatesState() { + return false; + } + + @Override + public int getParameterPositionStart(Limit limit) { + return hasMaxRows( limit ) + ? hasFirstRow( limit ) ? 3 : 2 + : hasFirstRow( limit ) ? 2 : 1; + } + } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/LegacyHSQLLimitHandler.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/LegacyHSQLLimitHandler.java index 63ec85a897e5..04a62dcf2511 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/LegacyHSQLLimitHandler.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/LegacyHSQLLimitHandler.java @@ -6,6 +6,8 @@ import org.hibernate.dialect.pagination.AbstractSimpleLimitHandler; import org.hibernate.dialect.pagination.LimitHandler; +import org.hibernate.query.spi.Limit; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; /** * A {@link LimitHandler} for HSQL prior to 2.0. @@ -19,6 +21,17 @@ protected String limitClause(boolean hasFirstRow) { return hasFirstRow ? " limit ? ?" : " top ?"; } + @Override + protected String limitClause(boolean hasFirstRow, int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + final String firstParameter = parameterMarkerStrategy.createMarker( 1, null ); + if ( hasFirstRow ) { + return " limit 1+" + firstParameter + " " + parameterMarkerStrategy.createMarker( 2, null ); + } + else { + return " top " + firstParameter; + } + } + @Override protected String insert(String limitOrTop, String sql) { return insertAfterSelect( limitOrTop, sql ); @@ -28,4 +41,16 @@ protected String insert(String limitOrTop, String sql) { public final boolean bindLimitParametersFirst() { return true; } + + @Override + public boolean processSqlMutatesState() { + return false; + } + + @Override + public int getParameterPositionStart(Limit limit) { + return hasMaxRows( limit ) + ? hasFirstRow( limit ) ? 3 : 2 + : hasFirstRow( limit ) ? 2 : 1; + } } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/LegacyOracleLimitHandler.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/LegacyOracleLimitHandler.java index 2000e8401f45..00682cef4407 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/LegacyOracleLimitHandler.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/LegacyOracleLimitHandler.java @@ -4,10 +4,14 @@ */ package org.hibernate.community.dialect.pagination; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.DatabaseVersion; import org.hibernate.dialect.pagination.AbstractLimitHandler; import org.hibernate.dialect.pagination.LimitHandler; import org.hibernate.query.spi.Limit; +import org.hibernate.query.spi.QueryOptions; +import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; import java.util.regex.Matcher; @@ -23,6 +27,15 @@ public LegacyOracleLimitHandler(DatabaseVersion version) { @Override public String processSql(String sql, Limit limit) { + return processSql( sql, -1, limit, null ); + } + + @Override + public String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, QueryOptions queryOptions) { + return processSql( sql, jdbcParameterCount, queryOptions.getLimit(), parameterMarkerStrategy ); + } + + private String processSql(String sql, int jdbcParameterCount, @Nullable Limit limit, @Nullable ParameterMarkerStrategy parameterMarkerStrategy) { final boolean hasOffset = hasFirstRow( limit ); sql = sql.trim(); @@ -36,17 +49,42 @@ public String processSql(String sql, Limit limit) { } final StringBuilder pagingSelect = new StringBuilder( sql.length() + 100 ); - if ( hasOffset ) { - pagingSelect.append( "select * from (select row_.*,rownum rownum_ from (" ).append( sql ); - if ( version.isBefore( 9 ) ) { - pagingSelect.append( ") row_) where rownum_<=? and rownum_>?" ); + if ( ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy ) ) { + if ( hasOffset ) { + pagingSelect.append( "select * from (select row_.*,rownum rownum_ from (" ).append( sql ); + if ( version.isBefore( 9 ) ) { + pagingSelect.append( ") row_) where rownum_<=? and rownum_>?" ); + } + else { + pagingSelect.append( ") row_ where rownum<=?) where rownum_>?" ); + } } else { - pagingSelect.append( ") row_ where rownum<=?) where rownum_>?" ); + pagingSelect.append( "select * from (" ).append( sql ).append( ") where rownum<=?" ); } } else { - pagingSelect.append( "select * from (" ).append( sql ).append( ") where rownum<=?" ); + final String firstParameter = parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ); + if ( hasOffset ) { + final String secondParameter = parameterMarkerStrategy.createMarker( jdbcParameterCount + 2, null ); + pagingSelect.append( "select * from (select row_.*,rownum rownum_ from (" ).append( sql ); + if ( version.isBefore( 9 ) ) { + pagingSelect.append( ") row_) where rownum_<=" ); + pagingSelect.append( firstParameter ); + pagingSelect.append( " and rownum_>" ); + pagingSelect.append( secondParameter ); + } + else { + pagingSelect.append( ") row_ where rownum<=" ); + pagingSelect.append( firstParameter ); + pagingSelect.append( ") where rownum_>" ); + pagingSelect.append( secondParameter ); + } + } + else { + pagingSelect.append( "select * from (" ).append( sql ).append( ") where rownum<=" ); + pagingSelect.append( firstParameter ); + } } if ( forUpdateClause != null ) { @@ -80,4 +118,9 @@ public boolean bindLimitParametersInReverseOrder() { public boolean useMaxForLimit() { return true; } + + @Override + public boolean processSqlMutatesState() { + return false; + } } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/RowsLimitHandler.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/RowsLimitHandler.java index e666d9184094..ce31a7e4a606 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/RowsLimitHandler.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/RowsLimitHandler.java @@ -8,6 +8,7 @@ import org.hibernate.dialect.pagination.AbstractSimpleLimitHandler; import org.hibernate.dialect.pagination.LimitHandler; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; import static java.util.regex.Pattern.CASE_INSENSITIVE; import static java.util.regex.Pattern.compile; @@ -29,11 +30,27 @@ protected String limitClause(boolean hasFirstRow) { return hasFirstRow ? " rows ? to ?" : " rows ?"; } + @Override + protected String limitClause(boolean hasFirstRow, int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + final String firstParameter = parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ); + if ( hasFirstRow ) { + return " rows " + firstParameter + " to " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 2, null ); + } + else { + return " rows " + firstParameter; + } + } + @Override protected String offsetOnlyClause() { return " rows ? to " + Integer.MAX_VALUE; } + @Override + protected String offsetOnlyClause(int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + return " rows " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ) + " to " + Integer.MAX_VALUE; + } + @Override public final boolean useMaxForLimit() { return true; @@ -56,4 +73,9 @@ protected Pattern getForUpdatePattern() { public boolean supportsOffset() { return true; } + + @Override + public boolean processSqlMutatesState() { + return false; + } } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/SQLServer2005LimitHandler.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/SQLServer2005LimitHandler.java index e48e94e60204..73c0fcdea1dd 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/SQLServer2005LimitHandler.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/pagination/SQLServer2005LimitHandler.java @@ -11,10 +11,14 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.pagination.AbstractLimitHandler; import org.hibernate.dialect.pagination.LimitHandler; import org.hibernate.internal.util.StringHelper; import org.hibernate.query.spi.Limit; +import org.hibernate.query.spi.QueryOptions; +import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; import static java.util.regex.Pattern.CASE_INSENSITIVE; import static java.util.regex.Pattern.compile; @@ -80,6 +84,15 @@ public int convertToFirstRowValue(int zeroBasedFirstResult) { */ @Override public String processSql(String sql, Limit limit) { + return processSql( sql, -1, null, limit ); + } + + @Override + public String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, QueryOptions queryOptions) { + return processSql( sql, jdbcParameterCount, parameterMarkerStrategy, queryOptions.getLimit() ); + } + + private String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, @Nullable Limit limit) { sql = sql.trim(); if ( sql.endsWith(";") ) { sql = sql.substring( 0, sql.length()-1 ); @@ -96,7 +109,13 @@ public String processSql(String sql, Limit limit) { final StringBuilder result = new StringBuilder( sql ); if ( !hasFirstRow || hasOrderBy ) { - result.insert( afterSelectOffset, " top(?)" ); + if ( ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy ) ) { + result.insert( afterSelectOffset, " top(?)" ); + } + else { + final String parameterMarker = parameterMarkerStrategy.createMarker( 1, null ); + result.insert( afterSelectOffset, " top(" + parameterMarker + ")" ); + } topAdded = true; } @@ -109,7 +128,16 @@ public String processSql(String sql, Limit limit) { result.insert( selectOffset, ( hasCommonTables ? "," : "with" ) + " query_ as (select row_.*,row_number() over (order by current_timestamp) as rownumber_ from (" ) .append( ") row_) select " ).append( aliases ) - .append( " from query_ where rownumber_>=? and rownumber_=" ); + if ( ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy ) ) { + result.append( "? and rownumber_ Assertions.assertEquals( 69, s.createSelectionQuery( "select count from Constrained", int.class).getSingleResult())); } + private String withLimit(String sql, Limit limit) { + return new DerbyDialect().getLimitHandler().processSql( sql, -1, null, new LimitQueryOptions( limit ) ); + } + private Limit toRowSelection(int firstRow, int maxRows) { Limit selection = new Limit(); selection.setFirstRow( firstRow ); diff --git a/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/DerbyLegacyDialectTestCase.java b/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/DerbyLegacyDialectTestCase.java index 6eb127580196..a224bfb40bc9 100644 --- a/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/DerbyLegacyDialectTestCase.java +++ b/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/DerbyLegacyDialectTestCase.java @@ -5,6 +5,7 @@ package org.hibernate.community.dialect; import org.hibernate.dialect.DatabaseVersion; +import org.hibernate.orm.test.dialect.LimitQueryOptions; import org.hibernate.query.spi.Limit; import static org.junit.Assert.assertEquals; @@ -27,7 +28,7 @@ public void testInsertLimitClause() { final String input = "select * from tablename t where t.cat = 5"; final String expected = "select * from tablename t where t.cat = 5 fetch first " + limit + " rows only"; - final String actual = new DerbyLegacyDialect( DatabaseVersion.make( 10, 5 ) ).getLimitHandler().processSql( input, toRowSelection( 0, limit ) ); + final String actual = withLimit( input, toRowSelection( 0, limit ) ); assertEquals( expected, actual ); } @@ -39,7 +40,7 @@ public void testInsertLimitWithOffsetClause() { final String input = "select * from tablename t where t.cat = 5"; final String expected = "select * from tablename t where t.cat = 5 offset " + offset + " rows fetch next " + limit + " rows only"; - final String actual = new DerbyLegacyDialect( DatabaseVersion.make( 10, 5 ) ).getLimitHandler().processSql( input, toRowSelection( offset, limit ) ); + final String actual = withLimit( input, toRowSelection( offset, limit ) ); assertEquals( expected, actual ); } @@ -52,7 +53,7 @@ public void testInsertLimitWithForUpdateClause() { final String expected = "select c11 as col1, c12 as col2, c13 as col13 from t1 offset " + offset + " rows fetch next " + limit + " rows only for update of c11, c13"; - final String actual = new DerbyLegacyDialect( DatabaseVersion.make( 10, 5 ) ).getLimitHandler().processSql( input, toRowSelection( offset, limit ) ); + final String actual = withLimit( input, toRowSelection( offset, limit ) ); assertEquals( expected, actual ); } @@ -65,7 +66,7 @@ public void testInsertLimitWithWithClause() { final String expected = "select c11 as col1, c12 as col2, c13 as col13 from t1 where flight_id between 'AA1111' and 'AA1112' offset " + offset + " rows fetch next " + limit + " rows only with rr"; - final String actual = new DerbyLegacyDialect( DatabaseVersion.make( 10, 5 ) ).getLimitHandler().processSql( input, toRowSelection( offset, limit ) ); + final String actual = withLimit( input, toRowSelection( offset, limit ) ); assertEquals( expected, actual ); } @@ -78,10 +79,14 @@ public void testInsertLimitWithForUpdateAndWithClauses() { final String expected = "select c11 as col1, c12 as col2, c13 as col13 from t1 where flight_id between 'AA1111' and 'AA1112' offset " + offset + " rows fetch next " + limit + " rows only for update of c11,c13 with rr"; - final String actual = new DerbyLegacyDialect( DatabaseVersion.make( 10, 5 ) ).getLimitHandler().processSql( input, toRowSelection( offset, limit ) ); + final String actual = withLimit( input, toRowSelection( offset, limit ) ); assertEquals( expected, actual ); } + private String withLimit(String sql, Limit limit) { + return new DerbyLegacyDialect( DatabaseVersion.make( 10, 5 ) ).getLimitHandler().processSql( sql, -1, null, new LimitQueryOptions( limit ) ); + } + private Limit toRowSelection(int firstRow, int maxRows) { Limit selection = new Limit(); selection.setFirstRow( firstRow ); diff --git a/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/FirebirdDialectTest.java b/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/FirebirdDialectTest.java index f8439b52d2da..36f9e19d93b0 100644 --- a/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/FirebirdDialectTest.java +++ b/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/FirebirdDialectTest.java @@ -5,6 +5,7 @@ package org.hibernate.community.dialect; import org.hibernate.dialect.DatabaseVersion; +import org.hibernate.orm.test.dialect.LimitQueryOptions; import org.hibernate.query.spi.Limit; import org.hibernate.testing.orm.junit.JiraKey; @@ -29,7 +30,7 @@ class FirebirdDialectTest { void insertOffsetLimitClause(int major, int minor, int offset, int limit, String expectedSql) { String input = "select * from tablename t where t.cat = 5"; FirebirdDialect dialect = new FirebirdDialect( DatabaseVersion.make( major, minor ) ); - String actual = dialect.getLimitHandler().processSql( input, new Limit( offset, limit ) ); + String actual = dialect.getLimitHandler().processSql( input, -1, null, new LimitQueryOptions( new Limit( offset, limit ) ) ); assertEquals( expectedSql, actual ); } } diff --git a/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/SQLServer2005DialectTestCase.java b/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/SQLServer2005DialectTestCase.java index 329cbcacfba5..6144b87416ce 100644 --- a/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/SQLServer2005DialectTestCase.java +++ b/hibernate-community-dialects/src/test/java/org/hibernate/community/dialect/SQLServer2005DialectTestCase.java @@ -9,6 +9,7 @@ import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.dialect.DatabaseVersion; +import org.hibernate.orm.test.dialect.LimitQueryOptions; import org.hibernate.query.spi.Limit; import org.hibernate.testing.orm.junit.JiraKey; @@ -48,7 +49,7 @@ public void testGetLimitString() { "with query_ as (select row_.*,row_number() over (order by current_timestamp) as rownumber_ from (" + "select distinct top(?) f1 as f53245 from table849752 order by f234, f67 desc) row_)" + " select f53245 from query_ where rownumber_>=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_0 then 'ADDED' else 'UNMODIFIED' end from table2 t2 WHERE (t2.c1 in (?))) as col_1_0 from table1 t1 WHERE 1=1 ORDER BY t1.c1 ASC) row_) " + "select col_0_0,col_1_0 from query_ where rownumber_>=? and rownumber_=? and rownumber_0 then 'ADDED' else 'UNMODIFIED' end from table2 t2 WHERE (t2.c1 in (?))) as col_1_0 from table1 t1 WHERE 1=1 ORDER BY t1.c1 ASC", - dialect.getLimitHandler().processSql( query, toRowSelection( 0, 5 ) ) + withLimit( query, toRowSelection( 0, 5 ) ) ); } @@ -418,14 +419,14 @@ public void testGetLimitStringUsingCTEQueryNoOffset() { final String query1 = "WITH a (c1, c2) AS (SELECT c1, c2 FROM t) SELECT c1, c2 FROM a"; assertEquals( "WITH a (c1, c2) AS (SELECT c1, c2 FROM t) SELECT top(?) c1, c2 FROM a", - dialect.getLimitHandler().processSql( query1, selection ) + withLimit( query1, selection ) ); // test top-based CTE with single CTE query_ definition and various tab, newline spaces final String query2 = " \n\tWITH a (c1\n\t,c2)\t\nAS (SELECT\n\tc1,c2 FROM t)\t\nSELECT c1, c2 FROM a"; assertEquals( "WITH a (c1\n\t,c2)\t\nAS (SELECT\n\tc1,c2 FROM t)\t\nSELECT top(?) c1, c2 FROM a", - dialect.getLimitHandler().processSql( query2, selection ) + withLimit( query2, selection ) ); // test top-based CTE with multiple CTE query_ definitions with no odd formatting @@ -434,7 +435,7 @@ public void testGetLimitStringUsingCTEQueryNoOffset() { assertEquals( "WITH a (c1, c2) AS (SELECT c1, c2 FROM t1), b (b1, b2) AS (SELECT b1, b2 FROM t2) " + "SELECT top(?) c1, c2, b1, b2 FROM t1, t2 WHERE t1.c1 = t2.b1", - dialect.getLimitHandler().processSql( query3, selection ) + withLimit( query3, selection ) ); // test top-based CTE with multiple CTE query_ definitions and various tab, newline spaces @@ -443,7 +444,7 @@ public void testGetLimitStringUsingCTEQueryNoOffset() { assertEquals( "WITH a (c1, c2) AS\n\r (SELECT c1, c2 FROM t1)\n\r, b (b1, b2)\tAS\t(SELECT b1, b2 FROM t2)" + " SELECT top(?) c1, c2, b1, b2 FROM t1, t2 WHERE t1.c1 = t2.b1", - dialect.getLimitHandler().processSql( query4, selection ) + withLimit( query4, selection ) ); } @@ -459,7 +460,7 @@ public void testGetLimitStringUsingCTEQueryWithOffset() { "(order by current_timestamp) as rownumber_ from (SELECT c1 as col0_, c2 as col1_ " + "FROM a) row_) select col0_,col1_ from query_ where rownumber_>=? " + "and rownumber_=" + "? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_=? and rownumber_0 then 'ADDED' else 'UNMODIFIED' end from table2 t2 WHERE (t2.c1 in (?))) as col_1_0 from table1 t1 WHERE 1=1 ORDER BY t1.c1 ASC) row_) " + "select col_0_0,col_1_0 from query_ where rownumber_>=? and rownumber_=? and rownumber_0 then 'ADDED' else 'UNMODIFIED' end from table2 t2 WHERE (t2.c1 in (?))) as col_1_0 from table1 t1 WHERE 1=1 ORDER BY t1.c1 ASC", - dialect.getLimitHandler().processSql( query, toRowSelection( 0, 5 ) ) + withLimit( query, toRowSelection( 0, 5 ) ) ); } @@ -419,14 +420,14 @@ public void testGetLimitStringUsingCTEQueryNoOffset() { final String query1 = "WITH a (c1, c2) AS (SELECT c1, c2 FROM t) SELECT c1, c2 FROM a"; assertEquals( "WITH a (c1, c2) AS (SELECT c1, c2 FROM t) SELECT top(?) c1, c2 FROM a", - dialect.getLimitHandler().processSql( query1, selection ) + withLimit( query1, selection ) ); // test top-based CTE with single CTE query_ definition and various tab, newline spaces final String query2 = " \n\tWITH a (c1\n\t,c2)\t\nAS (SELECT\n\tc1,c2 FROM t)\t\nSELECT c1, c2 FROM a"; assertEquals( "WITH a (c1\n\t,c2)\t\nAS (SELECT\n\tc1,c2 FROM t)\t\nSELECT top(?) c1, c2 FROM a", - dialect.getLimitHandler().processSql( query2, selection ) + withLimit( query2, selection ) ); // test top-based CTE with multiple CTE query_ definitions with no odd formatting @@ -435,7 +436,7 @@ public void testGetLimitStringUsingCTEQueryNoOffset() { assertEquals( "WITH a (c1, c2) AS (SELECT c1, c2 FROM t1), b (b1, b2) AS (SELECT b1, b2 FROM t2) " + "SELECT top(?) c1, c2, b1, b2 FROM t1, t2 WHERE t1.c1 = t2.b1", - dialect.getLimitHandler().processSql( query3, selection ) + withLimit( query3, selection ) ); // test top-based CTE with multiple CTE query_ definitions and various tab, newline spaces @@ -444,7 +445,7 @@ public void testGetLimitStringUsingCTEQueryNoOffset() { assertEquals( "WITH a (c1, c2) AS\n\r (SELECT c1, c2 FROM t1)\n\r, b (b1, b2)\tAS\t(SELECT b1, b2 FROM t2)" + " SELECT top(?) c1, c2, b1, b2 FROM t1, t2 WHERE t1.c1 = t2.b1", - dialect.getLimitHandler().processSql( query4, selection ) + withLimit( query4, selection ) ); } @@ -460,7 +461,7 @@ public void testGetLimitStringUsingCTEQueryWithOffset() { "(order by current_timestamp) as rownumber_ from (SELECT c1 as col0_, c2 as col1_ " + "FROM a) row_) select col0_,col1_ from query_ where rownumber_>=? " + "and rownumber_=" + "? and rownumber_=? and rownumber_=? and rownumber_ SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new CockroachSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new CockroachSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java index b879a94a7f3c..cc90538f31f2 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java @@ -6,6 +6,7 @@ import jakarta.persistence.TemporalType; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Timeouts; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.TypeContributions; @@ -63,6 +64,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -1057,8 +1059,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new DB2SqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new DB2SqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/DB2iDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/DB2iDialect.java index 9dfa69717397..6ac4527ce384 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/DB2iDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/DB2iDialect.java @@ -5,6 +5,7 @@ package org.hibernate.dialect; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Timeouts; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.dialect.function.DB2SubstringFunction; @@ -25,6 +26,7 @@ import org.hibernate.mapping.Column; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -148,8 +150,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new DB2iSqlAstTranslator<>( sessionFactory, statement, getVersion() ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new DB2iSqlAstTranslator<>( sessionFactory, statement, parameterInfo, getVersion() ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/DB2zDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/DB2zDialect.java index 29135c068c74..5fed3a71250a 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/DB2zDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/DB2zDialect.java @@ -5,6 +5,7 @@ package org.hibernate.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.identity.DB2zIdentityColumnSupport; import org.hibernate.dialect.identity.IdentityColumnSupport; import org.hibernate.dialect.lock.internal.DB2LockingSupport; @@ -21,6 +22,7 @@ import org.hibernate.query.common.TemporalUnit; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -187,8 +189,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new DB2zSqlAstTranslator<>( sessionFactory, statement, getVersion() ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new DB2zSqlAstTranslator<>( sessionFactory, statement, parameterInfo, getVersion() ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java index ef2f0a9256ac..165d8d691f1d 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java @@ -57,6 +57,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; @@ -482,8 +483,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new H2SqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new H2SqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/HANADialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/HANADialect.java index 613ea3390a85..43d2eae6cb49 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/HANADialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/HANADialect.java @@ -6,6 +6,7 @@ import jakarta.persistence.TemporalType; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.ScrollMode; @@ -69,6 +70,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -548,8 +550,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, org.hibernate.sql.ast.tree.Statement statement) { - return new HANASqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, org.hibernate.sql.ast.tree.Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new HANASqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/HSQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/HSQLDialect.java index a97bd8778da0..078d2d732f0b 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/HSQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/HSQLDialect.java @@ -50,6 +50,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.LockingClauseStrategy; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; @@ -276,8 +277,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new HSQLSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new HSQLSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/MariaDBDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/MariaDBDialect.java index e2527fa8193e..9b1940dbb800 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/MariaDBDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/MariaDBDialect.java @@ -4,6 +4,7 @@ */ package org.hibernate.dialect; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.QueryTimeoutException; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.TypeContributions; @@ -37,6 +38,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -218,8 +220,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new MariaDBSqlAstTranslator<>( sessionFactory, statement, MariaDBDialect.this ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new MariaDBSqlAstTranslator<>( sessionFactory, statement, parameterInfo, MariaDBDialect.this ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java index 2ccd40a23ecf..0c986916aa9f 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java @@ -6,6 +6,7 @@ import jakarta.persistence.TemporalType; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Length; import org.hibernate.QueryTimeoutException; import org.hibernate.Timeouts; @@ -62,6 +63,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -736,8 +738,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new MySQLSqlAstTranslator<>( sessionFactory, statement, MySQLDialect.this ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new MySQLSqlAstTranslator<>( sessionFactory, statement, parameterInfo, MySQLDialect.this ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java index e9e75adcc0ef..35de768a4b8b 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java @@ -7,6 +7,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.TemporalType; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Length; import org.hibernate.QueryTimeoutException; import org.hibernate.Timeouts; @@ -81,6 +82,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -462,8 +464,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new OracleSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new OracleSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java index 54fd00b75940..add5478c7be2 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java @@ -78,6 +78,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; @@ -1009,8 +1010,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new PostgreSQLSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new PostgreSQLSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgresPlusDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgresPlusDialect.java index fe925b3a2777..c2a1e5c61f5c 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgresPlusDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgresPlusDialect.java @@ -8,6 +8,7 @@ import java.sql.SQLException; import java.sql.Types; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.dialect.function.CommonFunctionFactory; import org.hibernate.dialect.sql.ast.PostgreSQLSqlAstTranslator; @@ -18,6 +19,7 @@ import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression; @@ -137,8 +139,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new PostgreSQLSqlAstTranslator<>( sessionFactory, statement ) { + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new PostgreSQLSqlAstTranslator<>( sessionFactory, statement, parameterInfo ) { @Override public void visitBinaryArithmeticExpression(BinaryArithmeticExpression arithmeticExpression) { if ( isIntegerDivisionEmulationRequired( arithmeticExpression ) ) { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerDialect.java index f89f53f5d2bb..cee7a709d713 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerDialect.java @@ -5,6 +5,7 @@ package org.hibernate.dialect; import jakarta.persistence.TemporalType; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Length; import org.hibernate.LockMode; import org.hibernate.LockOptions; @@ -68,6 +69,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; @@ -530,8 +532,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new SQLServerSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new SQLServerSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SpannerDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SpannerDialect.java index f1d82629dd10..7324e144ebbe 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SpannerDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SpannerDialect.java @@ -6,6 +6,7 @@ import jakarta.persistence.TemporalType; import jakarta.persistence.Timeout; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.StaleObjectStateException; @@ -39,6 +40,7 @@ import org.hibernate.query.sqm.IntervalType; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.LockingClauseStrategy; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; @@ -491,8 +493,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new SpannerSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new SpannerSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASEDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASEDialect.java index 4626104e2d03..c5ac949e75b6 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASEDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASEDialect.java @@ -5,6 +5,7 @@ package org.hibernate.dialect; import jakarta.persistence.TemporalType; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Length; import org.hibernate.LockMode; import org.hibernate.LockOptions; @@ -34,6 +35,7 @@ import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -265,8 +267,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new SybaseASESqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new SybaseASESqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java index 12d72e9d3f43..579aaae36c80 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseDialect.java @@ -5,6 +5,7 @@ package org.hibernate.dialect; import jakarta.persistence.TemporalType; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.HibernateException; import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.TypeContributions; @@ -47,6 +48,7 @@ import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; @@ -203,8 +205,8 @@ public SqlAstTranslatorFactory getSqlAstTranslatorFactory() { return new StandardSqlAstTranslatorFactory() { @Override protected SqlAstTranslator buildTranslator( - SessionFactoryImplementor sessionFactory, Statement statement) { - return new SybaseSqlAstTranslator<>( sessionFactory, statement ); + SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return new SybaseSqlAstTranslator<>( sessionFactory, statement, parameterInfo ); } }; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractLimitHandler.java b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractLimitHandler.java index 649c9959d730..5f99af6d90be 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractLimitHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractLimitHandler.java @@ -22,7 +22,12 @@ */ public abstract class AbstractLimitHandler implements LimitHandler { - public static LimitHandler NO_LIMIT = new AbstractLimitHandler(){}; + public static LimitHandler NO_LIMIT = new AbstractLimitHandler(){ + @Override + public boolean processSqlMutatesState() { + return false; + } + }; private static final Pattern SELECT_PATTERN = compile( "^\\s*select\\b", CASE_INSENSITIVE ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractNoOffsetLimitHandler.java b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractNoOffsetLimitHandler.java index 0f1f7fb5f94d..9faa3cc5b1ed 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractNoOffsetLimitHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractNoOffsetLimitHandler.java @@ -4,7 +4,11 @@ */ package org.hibernate.dialect.pagination; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.query.spi.Limit; +import org.hibernate.query.spi.QueryOptions; +import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; import static java.lang.String.valueOf; @@ -28,14 +32,30 @@ public AbstractNoOffsetLimitHandler(boolean variableLimit) { */ protected abstract String limitClause(); + protected String limitClause(int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + return limitClause(); + } + protected abstract String insert(String limitClause, String sql); + @Override + public String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, QueryOptions queryOptions) { + return processSql( sql, jdbcParameterCount, parameterMarkerStrategy, queryOptions.getLimit() ); + } + @Override public String processSql(String sql, Limit limit) { + return processSql( sql, -1, null, limit ); + } + + private String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, @Nullable Limit limit) { if ( !hasMaxRows( limit ) ) { return sql; } - String limitClause = limitClause(); + + String limitClause = ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy ) + || !supportsVariableLimit() ? limitClause() + : limitClause( jdbcParameterCount, parameterMarkerStrategy ); if ( !supportsVariableLimit() ) { String limitLiteral = valueOf( getMaxOrLimit( limit ) ); limitClause = limitClause.replace( "?", limitLiteral ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractSimpleLimitHandler.java b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractSimpleLimitHandler.java index f5ac4f7f454c..7c22c0c1c5ab 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractSimpleLimitHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/AbstractSimpleLimitHandler.java @@ -4,7 +4,11 @@ */ package org.hibernate.dialect.pagination; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.query.spi.Limit; +import org.hibernate.query.spi.QueryOptions; +import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; /** * Superclass for simple {@link LimitHandler}s that don't @@ -16,20 +20,42 @@ public abstract class AbstractSimpleLimitHandler extends AbstractLimitHandler { protected abstract String limitClause(boolean hasFirstRow); + protected String limitClause(boolean hasFirstRow, int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + return limitClause( hasFirstRow ); + } + protected String offsetOnlyClause() { return null; } + protected String offsetOnlyClause(int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + return offsetOnlyClause(); + } + @Override public String processSql(String sql, Limit limit) { + return processSql( sql, -1, null, limit ); + } + + @Override + public String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, QueryOptions queryOptions) { + return processSql( sql, jdbcParameterCount, parameterMarkerStrategy, queryOptions.getLimit() ); + } + + private String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, @Nullable Limit limit) { + final boolean hasFirstRow = hasFirstRow( limit ); if ( !hasMaxRows( limit ) ) { - final String offsetOnlyClause = offsetOnlyClause(); - if ( offsetOnlyClause != null && hasFirstRow( limit ) ) { + final String offsetOnlyClause = + ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy ) + ? offsetOnlyClause() : offsetOnlyClause( jdbcParameterCount, parameterMarkerStrategy ); + if ( offsetOnlyClause != null && hasFirstRow ) { return insert( offsetOnlyClause, sql ); } return sql; } - return insert( limitClause( hasFirstRow( limit ) ), sql ); + final String limitClause = ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy ) + ? limitClause( hasFirstRow ) : limitClause( hasFirstRow, jdbcParameterCount, parameterMarkerStrategy ); + return insert( limitClause, sql ); } protected String insert(String limitClause, String sql) { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/FetchLimitHandler.java b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/FetchLimitHandler.java index 1d63ce3fed42..00bd2b46328c 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/FetchLimitHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/FetchLimitHandler.java @@ -4,6 +4,8 @@ */ package org.hibernate.dialect.pagination; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; + /** * A {@link LimitHandler} for databases which support the ANSI * SQL standard syntax {@code FETCH FIRST m ROWS ONLY} but not @@ -24,6 +26,11 @@ protected String limitClause() { return " fetch first ? rows only"; } + @Override + protected String limitClause(int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + return " fetch first " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ) + " rows only"; + } + @Override protected String insert(String fetch, String sql) { return insertBeforeForUpdate( fetch, sql ); @@ -34,4 +41,9 @@ public boolean bindLimitParametersFirst() { return false; } + @Override + public boolean processSqlMutatesState() { + return false; + } + } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LegacyDB2LimitHandler.java b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LegacyDB2LimitHandler.java index a83350f5d950..63912cba5f67 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LegacyDB2LimitHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LegacyDB2LimitHandler.java @@ -50,4 +50,9 @@ public final boolean useMaxForLimit() { public final boolean supportsVariableLimit() { return false; } + + @Override + public boolean processSqlMutatesState() { + return false; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitHandler.java b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitHandler.java index 936c5f49bdb5..2746cc6c12a4 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitHandler.java @@ -7,8 +7,10 @@ import java.sql.PreparedStatement; import java.sql.SQLException; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.query.spi.Limit; import org.hibernate.query.spi.QueryOptions; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; /** * Contract defining dialect-specific limit and offset handling. @@ -39,16 +41,46 @@ public interface LimitHandler { */ boolean supportsLimitOffset(); + @Deprecated(forRemoval = true) String processSql(String sql, Limit limit); + @Deprecated(forRemoval = true) default String processSql(String sql, Limit limit, QueryOptions queryOptions) { return processSql( sql, limit ); } + /** + * Applies the limit from the {@link QueryOptions} to the SQL with the given {@link ParameterMarkerStrategy}. + * + * @since 7.1 + */ + default String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, QueryOptions queryOptions) { + return processSql( sql, queryOptions.getLimit(), queryOptions ); + } + int bindLimitParametersAtStartOfQuery(Limit limit, PreparedStatement statement, int index) throws SQLException; int bindLimitParametersAtEndOfQuery(Limit limit, PreparedStatement statement, int index) throws SQLException; + /** + * Returns whether {@link #processSql(String, int, ParameterMarkerStrategy, QueryOptions)} mutates the state of this limit handler and + * needs to be called for certain other methods to work correctly. + * + * @since 7.1 + */ + default boolean processSqlMutatesState() { + return true; + } + + /** + * Returns the position at which to start binding parameters after {@link #bindLimitParametersAtStartOfQuery(Limit, PreparedStatement, int)}. + * + * @since 7.1 + */ + default int getParameterPositionStart(Limit limit) { + return 1; + } + void setMaxRows(Limit limit, PreparedStatement statement) throws SQLException; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitLimitHandler.java b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitLimitHandler.java index f06ae3e8b408..4063dd6dc5ef 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitLimitHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitLimitHandler.java @@ -4,6 +4,8 @@ */ package org.hibernate.dialect.pagination; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; + import java.util.regex.Pattern; import static java.util.regex.Pattern.CASE_INSENSITIVE; @@ -26,11 +28,27 @@ protected String limitClause(boolean hasFirstRow) { return hasFirstRow ? " limit ?,?" : " limit ?"; } + @Override + protected String limitClause(boolean hasFirstRow, int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + final String firstParameter = parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ); + if ( hasFirstRow ) { + return " limit " + firstParameter + "," + parameterMarkerStrategy.createMarker( jdbcParameterCount + 2, null ); + } + else { + return " limit " + firstParameter; + } + } + @Override protected String offsetOnlyClause() { return " limit ?," + Integer.MAX_VALUE; } + @Override + protected String offsetOnlyClause(int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + return " limit " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ) +"," + Integer.MAX_VALUE; + } + private static final Pattern FOR_UPDATE_PATTERN = compile("\\s+for\\s+update\\b|\\s+lock\\s+in\\s+shared\\s+mode\\b|\\s*;?\\s*$", CASE_INSENSITIVE); @@ -43,4 +61,9 @@ protected Pattern getForUpdatePattern() { public boolean supportsOffset() { return true; } + + @Override + public boolean processSqlMutatesState() { + return false; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitOffsetLimitHandler.java b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitOffsetLimitHandler.java index 11b0fe0eb30e..aa64e14ec8dd 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitOffsetLimitHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/LimitOffsetLimitHandler.java @@ -4,6 +4,8 @@ */ package org.hibernate.dialect.pagination; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; + /** * A {@link LimitHandler} for databases like PostgreSQL, H2, * and HSQL that support the syntax {@code LIMIT n OFFSET m}. @@ -18,6 +20,10 @@ public class LimitOffsetLimitHandler extends AbstractSimpleLimitHandler { protected String offsetOnlyClause() { return " offset ?"; } + @Override + protected String offsetOnlyClause(int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + return " offset " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ); + } }; @Override @@ -25,11 +31,27 @@ protected String limitClause(boolean hasFirstRow) { return hasFirstRow ? " limit ? offset ?" : " limit ?"; } + @Override + protected String limitClause(boolean hasFirstRow, int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + final String firstParameter = parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ); + if ( hasFirstRow ) { + return " limit " + firstParameter + " offset " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 2, null ); + } + else { + return " limit " + firstParameter; + } + } + @Override protected String offsetOnlyClause() { return " limit " + Integer.MAX_VALUE + " offset ?"; } + @Override + protected String offsetOnlyClause(int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + return " limit " + Integer.MAX_VALUE + " offset " + parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ); + } + @Override public final boolean bindLimitParametersInReverseOrder() { return true; @@ -39,4 +61,9 @@ public final boolean bindLimitParametersInReverseOrder() { public boolean supportsOffset() { return true; } + + @Override + public boolean processSqlMutatesState() { + return false; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/NoopLimitHandler.java b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/NoopLimitHandler.java index 1df76e561fda..5313971979a0 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/NoopLimitHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/NoopLimitHandler.java @@ -49,4 +49,9 @@ public void setMaxRows(Limit limit, PreparedStatement statement) throws SQLExcep } } } + + @Override + public boolean processSqlMutatesState() { + return false; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/OffsetFetchLimitHandler.java b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/OffsetFetchLimitHandler.java index 0697d1c0cac5..92913df08460 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/OffsetFetchLimitHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/OffsetFetchLimitHandler.java @@ -4,7 +4,11 @@ */ package org.hibernate.dialect.pagination; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.query.spi.Limit; +import org.hibernate.query.spi.QueryOptions; +import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; /** * A {@link LimitHandler} for databases which support the @@ -23,9 +27,17 @@ public OffsetFetchLimitHandler(boolean variableLimit) { this.variableLimit = variableLimit; } + @Override + public String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, QueryOptions queryOptions) { + return processSql( sql, jdbcParameterCount, parameterMarkerStrategy, queryOptions.getLimit() ); + } + @Override public String processSql(String sql, Limit limit) { + return processSql( sql, -1, null, limit ); + } + private String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, @Nullable Limit limit) { boolean hasFirstRow = hasFirstRow(limit); boolean hasMaxRows = hasMaxRows(limit); @@ -40,7 +52,12 @@ public String processSql(String sql, Limit limit) { if ( hasFirstRow ) { offsetFetch.append( " offset " ); if ( supportsVariableLimit() ) { - offsetFetch.append( "?" ); + if ( ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy ) ) { + offsetFetch.append( "?" ); + } + else { + offsetFetch.append( parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ) ); + } } else { offsetFetch.append( limit.getFirstRow() ); @@ -58,7 +75,13 @@ public String processSql(String sql, Limit limit) { offsetFetch.append( " fetch first " ); } if ( supportsVariableLimit() ) { - offsetFetch.append( "?" ); + if ( ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy ) ) { + offsetFetch.append( "?" ); + } + else { + offsetFetch.append( + parameterMarkerStrategy.createMarker( jdbcParameterCount + (hasFirstRow ? 2 : 1), null ) ); + } } else { offsetFetch.append( getMaxOrLimit( limit ) ); @@ -93,4 +116,9 @@ public final boolean supportsVariableLimit() { protected boolean renderOffsetRowsKeyword() { return true; } + + @Override + public boolean processSqlMutatesState() { + return false; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/Oracle12LimitHandler.java b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/Oracle12LimitHandler.java index 87b26052288e..877813496b96 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/Oracle12LimitHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/Oracle12LimitHandler.java @@ -6,10 +6,13 @@ import java.util.Locale; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.query.spi.Limit; import org.hibernate.query.spi.QueryOptions; +import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; /** * A {@link LimitHandler} for databases which support the @@ -31,6 +34,15 @@ public class Oracle12LimitHandler extends AbstractLimitHandler { @Override public String processSql(String sql, Limit limit, QueryOptions queryOptions) { + return processSql( sql, -1, limit, null, queryOptions ); + } + + @Override + public String processSql(String sql, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, QueryOptions queryOptions) { + return processSql( sql, jdbcParameterCount, queryOptions.getLimit(), parameterMarkerStrategy, queryOptions ); + } + + private String processSql(String sql, int jdbcParameterCount, @Nullable Limit limit, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, QueryOptions queryOptions) { final boolean hasFirstRow = hasFirstRow( limit ); final boolean hasMaxRows = hasMaxRows( limit ); @@ -42,11 +54,17 @@ public String processSql(String sql, Limit limit, QueryOptions queryOptions) { sql, hasFirstRow, hasMaxRows, + jdbcParameterCount, + parameterMarkerStrategy, queryOptions.getLockOptions() ); } protected String processSql(String sql, boolean hasFirstRow, boolean hasMaxRows, LockOptions lockOptions) { + return processSql( sql, hasFirstRow, hasMaxRows, -1, null, lockOptions ); + } + + protected String processSql(String sql, boolean hasFirstRow, boolean hasMaxRows, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy, LockOptions lockOptions) { if ( lockOptions != null ) { final LockMode lockMode = lockOptions.getLockMode(); switch ( lockMode ) { @@ -55,17 +73,21 @@ protected String processSql(String sql, boolean hasFirstRow, boolean hasMaxRows, case UPGRADE_NOWAIT: case PESSIMISTIC_FORCE_INCREMENT: case UPGRADE_SKIPLOCKED: { - return processSql( sql, getForUpdateIndex( sql ), hasFirstRow, hasMaxRows ); + return processSql( sql, getForUpdateIndex( sql ), hasFirstRow, hasMaxRows, jdbcParameterCount, parameterMarkerStrategy ); } default: { - return processSqlOffsetFetch( sql, hasFirstRow, hasMaxRows ); + return processSqlOffsetFetch( sql, hasFirstRow, hasMaxRows, jdbcParameterCount, parameterMarkerStrategy ); } } } - return processSqlOffsetFetch( sql, hasFirstRow, hasMaxRows ); + return processSqlOffsetFetch( sql, hasFirstRow, hasMaxRows, jdbcParameterCount, parameterMarkerStrategy ); } protected String processSqlOffsetFetch(String sql, boolean hasFirstRow, boolean hasMaxRows) { + return processSqlOffsetFetch( sql, hasFirstRow, hasMaxRows, -1, null ); + } + + protected String processSqlOffsetFetch(String sql, boolean hasFirstRow, boolean hasMaxRows, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy) { final int forUpdateLastIndex = getForUpdateIndex( sql ); @@ -78,20 +100,39 @@ protected String processSqlOffsetFetch(String sql, boolean hasFirstRow, boolean supportOffset = true; final String offsetFetchString; - if ( hasFirstRow && hasMaxRows ) { - offsetFetchString = " offset ? rows fetch next ? rows only"; - } - else if ( hasFirstRow ) { - offsetFetchString = " offset ? rows"; + if ( ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy ) ) { + if ( hasFirstRow && hasMaxRows ) { + offsetFetchString = " offset ? rows fetch next ? rows only"; + } + else if ( hasFirstRow ) { + offsetFetchString = " offset ? rows"; + } + else { + offsetFetchString = " fetch first ? rows only"; + } } else { - offsetFetchString = " fetch first ? rows only"; + final String firstParameter = parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ); + if ( hasFirstRow && hasMaxRows ) { + final String secondParameter = parameterMarkerStrategy.createMarker( jdbcParameterCount + 2, null ); + offsetFetchString = " offset " + firstParameter + " rows fetch next " + secondParameter + " rows only"; + } + else if ( hasFirstRow ) { + offsetFetchString = " offset " + firstParameter + " rows"; + } + else { + offsetFetchString = " fetch first " + firstParameter + " rows only"; + } } return insertAtEnd(offsetFetchString, sql); } protected String processSql(String sql, int forUpdateIndex, boolean hasFirstRow, boolean hasMaxRows) { + return processSql( sql, forUpdateIndex, hasFirstRow, hasMaxRows, -1, null ); + } + + protected String processSql(String sql, int forUpdateIndex, boolean hasFirstRow, boolean hasMaxRows, int jdbcParameterCount, @Nullable ParameterMarkerStrategy parameterMarkerStrategy) { bindLimitParametersInReverseOrder = true; useMaxForLimit = true; supportOffset = false; @@ -115,23 +156,52 @@ protected String processSql(String sql, int forUpdateIndex, boolean hasFirstRow, forUpdateClauseLength = forUpdateClause.length() + 1; } - if ( hasFirstRow && hasMaxRows ) { - pagingSelect = new StringBuilder( sql.length() + forUpdateClauseLength + 98 ); - pagingSelect.append( "select * from (select row_.*,rownum rownum_ from (" ); - pagingSelect.append( sql ); - pagingSelect.append( ") row_ where rownum<=?) where rownum_>?" ); - } - else if ( hasFirstRow ) { - pagingSelect = new StringBuilder( sql.length() + forUpdateClauseLength + 98 ); - pagingSelect.append( "select * from (" ); - pagingSelect.append( sql ); - pagingSelect.append( ") row_ where rownum>?" ); + if ( ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy ) ) { + if ( hasFirstRow && hasMaxRows ) { + pagingSelect = new StringBuilder( sql.length() + forUpdateClauseLength + 98 ); + pagingSelect.append( "select * from (select row_.*,rownum rownum_ from (" ); + pagingSelect.append( sql ); + pagingSelect.append( ") row_ where rownum<=?) where rownum_>?" ); + } + else if ( hasFirstRow ) { + pagingSelect = new StringBuilder( sql.length() + forUpdateClauseLength + 98 ); + pagingSelect.append( "select * from (" ); + pagingSelect.append( sql ); + pagingSelect.append( ") row_ where rownum>?" ); + } + else { + pagingSelect = new StringBuilder( sql.length() + forUpdateClauseLength + 37 ); + pagingSelect.append( "select * from (" ); + pagingSelect.append( sql ); + pagingSelect.append( ") where rownum<=?" ); + } } else { - pagingSelect = new StringBuilder( sql.length() + forUpdateClauseLength + 37 ); - pagingSelect.append( "select * from (" ); - pagingSelect.append( sql ); - pagingSelect.append( ") where rownum<=?" ); + final String firstParameter = parameterMarkerStrategy.createMarker( jdbcParameterCount + 1, null ); + if ( hasFirstRow && hasMaxRows ) { + final String secondParameter = parameterMarkerStrategy.createMarker( jdbcParameterCount + 2, null ); + pagingSelect = new StringBuilder( sql.length() + forUpdateClauseLength + 98 ); + pagingSelect.append( "select * from (select row_.*,rownum rownum_ from (" ); + pagingSelect.append( sql ); + pagingSelect.append( ") row_ where rownum<=" ); + pagingSelect.append( firstParameter ); + pagingSelect.append( ") where rownum_>" ); + pagingSelect.append( secondParameter ); + } + else if ( hasFirstRow ) { + pagingSelect = new StringBuilder( sql.length() + forUpdateClauseLength + 98 ); + pagingSelect.append( "select * from (" ); + pagingSelect.append( sql ); + pagingSelect.append( ") row_ where rownum>" ); + pagingSelect.append( firstParameter ); + } + else { + pagingSelect = new StringBuilder( sql.length() + forUpdateClauseLength + 37 ); + pagingSelect.append( "select * from (" ); + pagingSelect.append( sql ); + pagingSelect.append( ") where rownum<=" ); + pagingSelect.append( firstParameter ); + } } if ( isForUpdate ) { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/TopLimitHandler.java b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/TopLimitHandler.java index 2a3974e321a3..21c575ff5f56 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/pagination/TopLimitHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/pagination/TopLimitHandler.java @@ -4,6 +4,9 @@ */ package org.hibernate.dialect.pagination; +import org.hibernate.query.spi.Limit; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; + /** * A {@link LimitHandler} for Transact SQL and similar * databases which support the syntax {@code SELECT TOP n}. @@ -25,6 +28,11 @@ protected String limitClause() { return " top ? "; } + @Override + protected String limitClause(int jdbcParameterCount, ParameterMarkerStrategy parameterMarkerStrategy) { + return " top " + parameterMarkerStrategy.createMarker( 1, null ) + " rows only"; + } + @Override protected String insert(String limitClause, String sql) { return insertAfterDistinct( limitClause, sql ); @@ -35,4 +43,13 @@ public boolean bindLimitParametersFirst() { return true; } + @Override + public boolean processSqlMutatesState() { + return false; + } + + @Override + public int getParameterPositionStart(Limit limit) { + return hasMaxRows( limit ) && supportsVariableLimit() ? 2 : 1; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/CockroachSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/CockroachSqlAstTranslator.java index 85bdacbc40ab..60a836058ca7 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/CockroachSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/CockroachSqlAstTranslator.java @@ -4,8 +4,10 @@ */ package org.hibernate.dialect.sql.ast; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.cte.CteMaterialization; @@ -35,10 +37,15 @@ */ public class CockroachSqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public CockroachSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public CockroachSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public void visitBinaryArithmeticExpression(BinaryArithmeticExpression arithmeticExpression) { if ( isIntegerDivisionEmulationRequired( arithmeticExpression ) ) { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/DB2SqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/DB2SqlAstTranslator.java index e990995fcf57..c4327bc15747 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/DB2SqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/DB2SqlAstTranslator.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.dialect.DatabaseVersion; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -19,6 +20,7 @@ import org.hibernate.query.common.FetchClauseType; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAstTranslatorWithMerge; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.MutationStatement; @@ -63,10 +65,15 @@ public class DB2SqlAstTranslator extends SqlAstTranslat // We have to track whether we are in a later query for applying lateral during window emulation private boolean inLateral; + @Deprecated(forRemoval = true, since = "7.1") public DB2SqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public DB2SqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected boolean needsRecursiveKeywordInWithClause() { return false; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/DB2iSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/DB2iSqlAstTranslator.java index 1c23fd495dc6..6b2c43c0ff99 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/DB2iSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/DB2iSqlAstTranslator.java @@ -4,9 +4,11 @@ */ package org.hibernate.dialect.sql.ast; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.DatabaseVersion; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -22,11 +24,17 @@ public class DB2iSqlAstTranslator extends DB2SqlAstTran private final DatabaseVersion version; + @Deprecated(forRemoval = true, since = "7.1") public DB2iSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, DatabaseVersion version) { super( sessionFactory, statement ); this.version = version; } + public DB2iSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo, DatabaseVersion version) { + super( sessionFactory, statement, parameterInfo ); + this.version = version; + } + @Override protected void renderComparison(Expression lhs, ComparisonOperator operator, Expression rhs) { renderComparisonStandard( lhs, operator, rhs ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/DB2zSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/DB2zSqlAstTranslator.java index aafa7174ebf4..2b3bb867e8df 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/DB2zSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/DB2zSqlAstTranslator.java @@ -4,9 +4,11 @@ */ package org.hibernate.dialect.sql.ast; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.DatabaseVersion; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.from.QueryPartTableReference; @@ -24,11 +26,17 @@ public class DB2zSqlAstTranslator extends DB2SqlAstTran private final DatabaseVersion version; + @Deprecated(forRemoval = true, since = "7.1") public DB2zSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, DatabaseVersion version) { super( sessionFactory, statement ); this.version = version; } + public DB2zSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo, DatabaseVersion version) { + super( sessionFactory, statement, parameterInfo ); + this.version = version; + } + @Override protected boolean shouldEmulateFetchClause(QueryPart queryPart) { // Percent fetches or ties fetches aren't supported in DB2 z/OS diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/H2SqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/H2SqlAstTranslator.java index 2b4c24a35156..780266ec9755 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/H2SqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/H2SqlAstTranslator.java @@ -6,6 +6,7 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.LockMode; import org.hibernate.dialect.identity.H2IdentityColumnSupport; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -14,6 +15,7 @@ import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAstTranslatorWithMerge; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -52,10 +54,15 @@ public class H2SqlAstTranslator extends SqlAstTranslato private boolean renderAsArray; + @Deprecated(forRemoval = true, since = "7.1") public H2SqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public H2SqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public void visitStandardTableInsert(TableInsertStandard tableInsert) { final boolean closeWrapper = renderReturningClause( tableInsert.getReturningColumns() ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/HANASqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/HANASqlAstTranslator.java index c904e10db81b..1489ae01961d 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/HANASqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/HANASqlAstTranslator.java @@ -6,6 +6,7 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.MappingException; import org.hibernate.dialect.HANADialect; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -17,6 +18,7 @@ import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.tree.SqlAstNode; import org.hibernate.sql.ast.tree.Statement; @@ -51,10 +53,15 @@ public class HANASqlAstTranslator extends AbstractSqlAs private boolean inLateral; + @Deprecated(forRemoval = true, since = "7.1") public HANASqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public HANASqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public void visitBinaryArithmeticExpression(BinaryArithmeticExpression arithmeticExpression) { if ( isIntegerDivisionEmulationRequired( arithmeticExpression ) ) { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/HSQLSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/HSQLSqlAstTranslator.java index c220e1fb412e..0e886629e825 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/HSQLSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/HSQLSqlAstTranslator.java @@ -7,12 +7,14 @@ import java.util.List; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.metamodel.mapping.JdbcMappingContainer; import org.hibernate.query.IllegalQueryOperationException; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAstTranslatorWithMerge; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -42,10 +44,15 @@ */ public class HSQLSqlAstTranslator extends SqlAstTranslatorWithMerge { + @Deprecated(forRemoval = true, since = "7.1") public HSQLSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public HSQLSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitInsertStatementOnly(InsertSelectStatement statement) { if ( statement.getConflictClause() == null || statement.getConflictClause().isDoNothing() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/MariaDBSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/MariaDBSqlAstTranslator.java index 30958f0fe4eb..1c140e787310 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/MariaDBSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/MariaDBSqlAstTranslator.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.DmlTargetColumnQualifierSupport; import org.hibernate.dialect.MariaDBDialect; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -14,6 +15,7 @@ import org.hibernate.metamodel.mapping.JdbcMappingContainer; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.delete.DeleteStatement; import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression; @@ -48,11 +50,17 @@ public class MariaDBSqlAstTranslator extends SqlAstTran private final MariaDBDialect dialect; + @Deprecated(forRemoval = true, since = "7.1") public MariaDBSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, MariaDBDialect dialect) { super( sessionFactory, statement ); this.dialect = dialect; } + public MariaDBSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo, MariaDBDialect dialect) { + super( sessionFactory, statement, parameterInfo ); + this.dialect = dialect; + } + @Override public void visitBinaryArithmeticExpression(BinaryArithmeticExpression arithmeticExpression) { if ( isIntegerDivisionEmulationRequired( arithmeticExpression ) ) { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/MySQLSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/MySQLSqlAstTranslator.java index f71014d744f8..291dee1f5117 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/MySQLSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/MySQLSqlAstTranslator.java @@ -4,6 +4,7 @@ */ package org.hibernate.dialect.sql.ast; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.DmlTargetColumnQualifierSupport; import org.hibernate.dialect.MySQLDialect; @@ -12,6 +13,7 @@ import org.hibernate.internal.util.collections.Stack; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.delete.DeleteStatement; import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression; @@ -55,11 +57,17 @@ public class MySQLSqlAstTranslator extends SqlAstTransl private final MySQLDialect dialect; + @Deprecated(forRemoval = true, since = "7.1") public MySQLSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, MySQLDialect dialect) { super( sessionFactory, statement ); this.dialect = dialect; } + public MySQLSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo, MySQLDialect dialect) { + super( sessionFactory, statement, parameterInfo ); + this.dialect = dialect; + } + public static String getSqlType(CastTarget castTarget, SessionFactoryImplementor factory) { final String sqlType = getCastTypeName( castTarget, factory.getTypeConfiguration() ); return getSqlType( castTarget, sqlType, factory.getJdbcServices().getDialect() ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/OracleSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/OracleSqlAstTranslator.java index 1c561ac2a6aa..bb6008042d00 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/OracleSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/OracleSqlAstTranslator.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.AssertionFailure; import org.hibernate.LockOptions; import org.hibernate.Locking; @@ -27,6 +28,7 @@ import org.hibernate.query.sqm.sql.internal.SqmPathInterpretation; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAstTranslatorWithUpsert; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.SqlAstNode; @@ -78,10 +80,15 @@ */ public class OracleSqlAstTranslator extends SqlAstTranslatorWithUpsert { + @Deprecated(forRemoval = true, since = "7.1") public OracleSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public OracleSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitInsertStatementOnly(InsertSelectStatement statement) { if ( statement.getConflictClause() == null || statement.getConflictClause().isDoNothing() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/PostgreSQLSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/PostgreSQLSqlAstTranslator.java index da605ae88d61..d070013adb3a 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/PostgreSQLSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/PostgreSQLSqlAstTranslator.java @@ -4,11 +4,13 @@ */ package org.hibernate.dialect.sql.ast; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.metamodel.mapping.JdbcMappingContainer; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.query.common.FetchClauseType; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAstTranslatorWithMerge; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.cte.CteMaterialization; @@ -42,10 +44,15 @@ */ public class PostgreSQLSqlAstTranslator extends SqlAstTranslatorWithMerge { + @Deprecated(forRemoval = true, since = "7.1") public PostgreSQLSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public PostgreSQLSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public void visitInArrayPredicate(InArrayPredicate inArrayPredicate) { inArrayPredicate.getTestExpression().accept( this ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SQLServerSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SQLServerSqlAstTranslator.java index daa990d3b4f5..764160301758 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SQLServerSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SQLServerSqlAstTranslator.java @@ -4,6 +4,7 @@ */ package org.hibernate.dialect.sql.ast; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Internal; import org.hibernate.LockMode; import org.hibernate.Locking; @@ -19,6 +20,7 @@ import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstJoinType; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAstTranslatorWithMerge; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.SqlAstNode; @@ -62,10 +64,15 @@ public class SQLServerSqlAstTranslator extends SqlAstTr private Predicate lateralPredicate; + @Deprecated(forRemoval = true, since = "7.1") public SQLServerSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public SQLServerSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitInsertStatementOnly(InsertSelectStatement statement) { if ( statement.getConflictClause() == null || statement.getConflictClause().isDoNothing() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SpannerSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SpannerSqlAstTranslator.java index 2a46627baa6e..ecdffce34559 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SpannerSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SpannerSqlAstTranslator.java @@ -6,10 +6,12 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Locking; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -33,10 +35,15 @@ public class SpannerSqlAstTranslator extends AbstractSq // Spanner lacks the lateral keyword and instead has an unnest/array mechanism private boolean correlated; + @Deprecated(forRemoval = true, since = "7.1") public SpannerSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public SpannerSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected LockStrategy determineLockingStrategy( QuerySpec querySpec, diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SqlAstTranslatorWithOnDuplicateKeyUpdate.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SqlAstTranslatorWithOnDuplicateKeyUpdate.java index 73fab31d26ca..c88d6658108d 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SqlAstTranslatorWithOnDuplicateKeyUpdate.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SqlAstTranslatorWithOnDuplicateKeyUpdate.java @@ -5,9 +5,11 @@ package org.hibernate.dialect.sql.ast; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.dialect.MySQLDeleteOrUpsertOperation; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.persister.entity.mutation.EntityTableMapping; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.SqlAstTranslatorWithUpsert; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; @@ -23,10 +25,15 @@ */ public class SqlAstTranslatorWithOnDuplicateKeyUpdate extends SqlAstTranslatorWithUpsert { + @Deprecated(forRemoval = true, since = "7.1") public SqlAstTranslatorWithOnDuplicateKeyUpdate(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public SqlAstTranslatorWithOnDuplicateKeyUpdate(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override public MutationOperation createMergeOperation(OptionalTableUpdate optionalTableUpdate) { assert optionalTableUpdate.getNumberOfOptimisticLockBindings() == 0; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SybaseASESqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SybaseASESqlAstTranslator.java index b39816dfea54..1575589149d8 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SybaseASESqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SybaseASESqlAstTranslator.java @@ -4,6 +4,7 @@ */ package org.hibernate.dialect.sql.ast; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Internal; import org.hibernate.LockMode; import org.hibernate.Locking; @@ -16,6 +17,7 @@ import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.MutationStatement; @@ -58,10 +60,15 @@ public class SybaseASESqlAstTranslator extends Abstract private static final String UNION_ALL = " union all "; + @Deprecated(forRemoval = true, since = "7.1") public SybaseASESqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public SybaseASESqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitInsertStatementOnly(InsertSelectStatement statement) { if ( statement.getConflictClause() == null || statement.getConflictClause().isDoNothing() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SybaseSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SybaseSqlAstTranslator.java index a07c80809d46..e35986d3a9d8 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SybaseSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SybaseSqlAstTranslator.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.Internal; import org.hibernate.LockMode; import org.hibernate.Locking; @@ -16,6 +17,7 @@ import org.hibernate.query.sqm.ComparisonOperator; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.Statement; @@ -47,10 +49,15 @@ public class SybaseSqlAstTranslator extends AbstractSql private static final String UNION_ALL = " union all "; + @Deprecated(forRemoval = true, since = "7.1") public SybaseSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public SybaseSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + @Override protected void visitInsertStatementOnly(InsertSelectStatement statement) { if ( statement.getConflictClause() == null || statement.getConflictClause().isDoNothing() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java b/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java index 46f7a61ffe40..ee5a3933a34d 100644 --- a/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java @@ -661,11 +661,10 @@ private ProcedureOutputsImpl buildOutputs() { for ( JdbcParameterBinder parameterBinder : call.getParameterBinders() ) { parameterBinder.bindParameterValue( statement, - paramBindingPosition, + paramBindingPosition++, jdbcParameterBindings, executionContext ); - paramBindingPosition++; } } catch (SQLException e) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheDisabledImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheDisabledImpl.java index 5de05004e0ab..961d56ba3485 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheDisabledImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheDisabledImpl.java @@ -60,6 +60,15 @@ public SelectQueryPlan resolveSelectQueryPlan(Key key, Supplier SelectQueryPlan resolveSelectQueryPlan(K key, Function> creator) { + final StatisticsImplementor statistics = getStatistics(); + if ( statistics.isStatisticsEnabled() ) { + statistics.queryPlanCacheMiss( key.getQueryString() ); + } + return creator.apply( key ); + } + @Override public NonSelectQueryPlan getNonSelectQueryPlan(Key key) { return null; diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheStandardImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheStandardImpl.java index ae8c3d182be6..2ea8121b460a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheStandardImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheStandardImpl.java @@ -76,6 +76,13 @@ private StatisticsImplementor getStatistics() { public SelectQueryPlan resolveSelectQueryPlan( Key key, Supplier> creator) { + return resolveSelectQueryPlan( key, k -> creator.get() ); + } + + @Override + public SelectQueryPlan resolveSelectQueryPlan( + K key, + Function> creator) { log.tracef( "Resolving cached query plan for [%s]", key ); final StatisticsImplementor statistics = getStatistics(); final boolean stats = statistics.isStatisticsEnabled(); @@ -89,7 +96,7 @@ public SelectQueryPlan resolveSelectQueryPlan( return cached; } - final SelectQueryPlan plan = creator.get(); + final SelectQueryPlan plan = creator.apply( key ); queryPlanCache.put( key.prepareForStore(), plan ); if ( stats ) { statistics.queryPlanCacheMiss( key.getQueryString() ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMapping.java b/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMapping.java index 2ef874bfc632..3564169f3288 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMapping.java @@ -98,4 +98,7 @@ static ResultSetMapping resolveResultSetMapping(String name, boolean isDynamic, return sessionFactory.getJdbcValuesMappingProducerProvider() .buildResultSetMapping( name, isDynamic, sessionFactory ); } + + @Override + ResultSetMapping cacheKeyInstance(); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/internal/ResultSetMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/query/results/internal/ResultSetMappingImpl.java index 98aff703491b..4b92de3d23b7 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/internal/ResultSetMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/internal/ResultSetMappingImpl.java @@ -20,7 +20,6 @@ import org.hibernate.sql.results.graph.basic.BasicResult; import org.hibernate.sql.results.graph.entity.EntityResult; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMapping; -import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; import org.hibernate.type.BasicType; @@ -329,7 +328,7 @@ public NamedResultSetMappingMemento toMemento(String name) { } @Override - public JdbcValuesMappingProducer cacheKeyInstance() { + public ResultSetMapping cacheKeyInstance() { return new ResultSetMappingImpl( this ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryInterpretationCache.java b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryInterpretationCache.java index 178bda50bb8f..ca3482e37f8f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryInterpretationCache.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryInterpretationCache.java @@ -45,6 +45,9 @@ static Key createInterpretationsKey(InterpretationsKeySource keySource) { void cacheHqlInterpretation(Object cacheKey, HqlInterpretation hqlInterpretation); SelectQueryPlan resolveSelectQueryPlan(Key key, Supplier> creator); + default SelectQueryPlan resolveSelectQueryPlan(K key, Function> creator) { + return resolveSelectQueryPlan( key, () -> creator.apply( key ) ); + } NonSelectQueryPlan getNonSelectQueryPlan(Key key); void cacheNonSelectQueryPlan(Key key, NonSelectQueryPlan plan); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java index 1af5735720e7..347bae9447e6 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java @@ -24,6 +24,8 @@ import org.hibernate.CacheMode; import org.hibernate.FlushMode; import org.hibernate.Locking; +import org.hibernate.dialect.pagination.LimitHandler; +import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.jpa.spi.NativeQueryArrayTransformer; @@ -78,6 +80,7 @@ import org.hibernate.query.results.internal.implicit.ImplicitResultClassBuilder; import org.hibernate.query.spi.AbstractQuery; import org.hibernate.query.spi.DomainQueryExecutionContext; +import org.hibernate.query.spi.Limit; import org.hibernate.query.spi.MutableQueryOptions; import org.hibernate.query.spi.NonSelectQueryPlan; import org.hibernate.query.spi.ParameterMetadataImplementor; @@ -97,6 +100,8 @@ import org.hibernate.query.sql.spi.ParameterInterpretation; import org.hibernate.query.sql.spi.ParameterOccurrence; import org.hibernate.query.sql.spi.SelectInterpretationsKey; +import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; import org.hibernate.sql.exec.internal.CallbackImpl; import org.hibernate.sql.exec.spi.Callback; import org.hibernate.sql.results.graph.Fetchable; @@ -791,15 +796,33 @@ else if ( !isResultTypeAlwaysAllowed( resultType ) mapping = resultSetMapping; } checkResultType( resultType, mapping ); - return isCacheableQuery() - ? getInterpretationCache() - .resolveSelectQueryPlan( selectInterpretationsKey( mapping ), () -> createQueryPlan( mapping ) ) - : createQueryPlan( mapping ); + int parameterStartPosition = 1; + final JdbcServices jdbcServices = getSessionFactory().getJdbcServices(); + if ( !ParameterMarkerStrategyStandard.isStandardRenderer( jdbcServices.getParameterMarkerStrategy() ) + && hasLimit( getQueryOptions().getLimit() ) ) { + final LimitHandler limitHandler = jdbcServices.getDialect().getLimitHandler(); + if ( limitHandler.processSqlMutatesState() ) { + limitHandler.processSql( sqlString, -1, null, getQueryOptions() ); + } + // A non-standard parameter marker strategy is in use, and the limit handler wants to bind parameters + // before the main parameters. This requires recording the start position in the cache key + // because the generated SQL depends on this information + parameterStartPosition = limitHandler.getParameterPositionStart( getQueryOptions().getLimit() ); + } + if ( isCacheableQuery() ) { + return getInterpretationCache().resolveSelectQueryPlan( + selectInterpretationsKey( mapping, parameterStartPosition ), + key -> createQueryPlan( key.getResultSetMapping(), key.getStartPosition() ) + ); + } + else { + return createQueryPlan( mapping, parameterStartPosition ); + } } - private NativeSelectQueryPlan createQueryPlan(ResultSetMapping resultSetMapping) { + private NativeSelectQueryPlan createQueryPlan(ResultSetMapping resultSetMapping, int parameterStartPosition) { final NativeSelectQueryDefinition queryDefinition = new NativeSelectQueryDefinition<>() { - final String sqlString = expandParameterLists(); + final String sqlString = expandParameterLists( parameterStartPosition ); @Override public String getSqlString() { @@ -835,7 +858,7 @@ public Set getAffectedTableNames() { protected NativeSelectQueryPlan createCountQueryPlan() { final NativeSelectQueryDefinition queryDefinition = new NativeSelectQueryDefinition<>() { final BasicType longType = getTypeConfiguration().getBasicTypeForJavaType(Long.class); - final String sqlString = expandParameterLists(); + final String sqlString = expandParameterLists( 1 ); @Override public String getSqlString() { @@ -871,7 +894,7 @@ private NativeQueryInterpreter getNativeQueryInterpreter() { return getSessionFactory().getQueryEngine().getNativeQueryInterpreter(); } - protected String expandParameterLists() { + protected String expandParameterLists(int parameterStartPosition) { if ( parameterOccurrences == null || parameterOccurrences.isEmpty() ) { return sqlString; } @@ -881,11 +904,15 @@ protected String expandParameterLists() { final Dialect dialect = factory.getJdbcServices().getDialect(); final boolean paddingEnabled = factory.getSessionFactoryOptions().inClauseParameterPaddingEnabled(); final int inExprLimit = dialect.getInExpressionCountLimit(); + final ParameterMarkerStrategy parameterMarkerStrategy = factory.getJdbcServices().getParameterMarkerStrategy(); + final boolean needsMarker = !ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy ); - StringBuilder sql = null; + StringBuilder sql = !needsMarker ? null + : new StringBuilder( sqlString.length() + parameterOccurrences.size() * 10 ).append( sqlString ); // Handle parameter lists int offset = 0; + int parameterPosition = parameterStartPosition; for ( ParameterOccurrence occurrence : parameterOccurrences ) { final QueryParameterImplementor queryParameter = occurrence.parameter(); final QueryParameterBinding binding = parameterBindings.getBinding( queryParameter ); @@ -906,15 +933,38 @@ protected String expandParameterLists() { } final int bindValueMaxCount = determineBindValueMaxCount( paddingEnabled, inExprLimit, bindValueCount ); - final String expansionListAsString = - expandList( bindValueMaxCount, isEnclosedInParens ); + final String expansionListAsString = expandList( + bindValueMaxCount, + isEnclosedInParens, + parameterPosition, + parameterMarkerStrategy, + needsMarker + ); final int start = sourcePosition + offset; final int end = start + 1; sql.replace( start, end, expansionListAsString ); offset += expansionListAsString.length() - 1; + parameterPosition += bindValueMaxCount; + } + else if ( needsMarker ) { + final int start = sourcePosition + offset; + final int end = start + 1; + final String parameterMarker = parameterMarkerStrategy.createMarker( parameterPosition, null ); + sql.replace( start, end, parameterMarker ); + offset += parameterMarker.length() - 1; + parameterPosition++; } } } + else if ( needsMarker ) { + final int sourcePosition = occurrence.sourcePosition(); + final int start = sourcePosition + offset; + final int end = start + 1; + final String parameterMarker = parameterMarkerStrategy.createMarker( parameterPosition, null ); + sql.replace( start, end, parameterMarker ); + offset += parameterMarker.length() - 1; + parameterPosition++; + } } return sql == null ? sqlString : sql.toString(); } @@ -934,11 +984,26 @@ private static void logTooManyExpressions( } } - private static String expandList(int bindValueMaxCount, boolean isEnclosedInParens) { + private static String expandList(int bindValueMaxCount, boolean isEnclosedInParens, int parameterPosition, ParameterMarkerStrategy parameterMarkerStrategy, boolean needsMarker) { // HHH-8901 if ( bindValueMaxCount == 0 ) { return isEnclosedInParens ? "null" : "(null)"; } + else if ( needsMarker ) { + final StringBuilder sb = new StringBuilder( bindValueMaxCount * 4 ); + if ( !isEnclosedInParens ) { + sb.append( '(' ); + } + for ( int i = 0; i < bindValueMaxCount; i++ ) { + sb.append( parameterMarkerStrategy.createMarker( parameterPosition + i, null ) ); + sb.append( ',' ); + } + sb.setLength( sb.length() - 1 ); + if ( !isEnclosedInParens ) { + sb.append( ')' ); + } + return sb.toString(); + } else { // Shift 1 bit instead of multiplication by 2 final char[] chars; @@ -1006,11 +1071,12 @@ public static int determineBindValueMaxCount(boolean paddingEnabled, int inExprL return bindValueMaxCount; } - private SelectInterpretationsKey selectInterpretationsKey(ResultSetMapping resultSetMapping) { + private SelectInterpretationsKey selectInterpretationsKey(ResultSetMapping resultSetMapping, int parameterStartPosition) { return new SelectInterpretationsKey( getQueryString(), resultSetMapping, - getSynchronizedQuerySpaces() + getSynchronizedQuerySpaces(), + parameterStartPosition ); } @@ -1026,6 +1092,10 @@ private boolean isCacheableQuery() { return !parameterBindings.hasAnyMultiValuedBindings(); } + private boolean hasLimit(Limit limit) { + return limit != null && !limit.isEmpty(); + } + @Override protected ScrollableResultsImplementor doScroll(ScrollMode scrollMode) { return resolveSelectQueryPlan().performScroll( scrollMode, this ); @@ -1052,7 +1122,7 @@ private NonSelectQueryPlan resolveNonSelectQueryPlan() { } if ( queryPlan == null ) { - final String sqlString = expandParameterLists(); + final String sqlString = expandParameterLists( 1 ); queryPlan = new NativeNonSelectQueryPlanImpl( sqlString, querySpaces, parameterOccurrences ); if ( cacheKey != null ) { getInterpretationCache().cacheNonSelectQueryPlan( cacheKey, queryPlan ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/SelectInterpretationsKey.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/SelectInterpretationsKey.java index da7c3864f1ec..e742f26893a6 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/SelectInterpretationsKey.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/SelectInterpretationsKey.java @@ -10,6 +10,7 @@ import org.hibernate.query.ResultListTransformer; import org.hibernate.query.TupleTransformer; +import org.hibernate.query.results.ResultSetMapping; import org.hibernate.query.spi.QueryInterpretationCache; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer; @@ -18,8 +19,9 @@ */ public class SelectInterpretationsKey implements QueryInterpretationCache.Key { private final String sql; - private final JdbcValuesMappingProducer jdbcValuesMappingProducer; + private final ResultSetMapping resultSetMapping; private final Collection querySpaces; + private final int parameterStartPosition; private final int hash; @Deprecated(forRemoval = true) @@ -32,24 +34,36 @@ public SelectInterpretationsKey( this( sql, jdbcValuesMappingProducer, querySpaces ); } + @Deprecated(forRemoval = true) public SelectInterpretationsKey( String sql, JdbcValuesMappingProducer jdbcValuesMappingProducer, Collection querySpaces) { + this( sql, (ResultSetMapping) jdbcValuesMappingProducer, querySpaces, 1 ); + } + + public SelectInterpretationsKey( + String sql, + ResultSetMapping jdbcValuesMappingProducer, + Collection querySpaces, + int parameterStartPosition) { this.sql = sql; - this.jdbcValuesMappingProducer = jdbcValuesMappingProducer; + this.resultSetMapping = jdbcValuesMappingProducer; this.querySpaces = querySpaces; + this.parameterStartPosition = parameterStartPosition; this.hash = generateHashCode(); } private SelectInterpretationsKey( String sql, - JdbcValuesMappingProducer jdbcValuesMappingProducer, + ResultSetMapping resultSetMapping, Collection querySpaces, + int parameterStartPosition, int hash) { this.sql = sql; - this.jdbcValuesMappingProducer = jdbcValuesMappingProducer; + this.resultSetMapping = resultSetMapping; this.querySpaces = querySpaces; + this.parameterStartPosition = parameterStartPosition; this.hash = hash; } @@ -58,12 +72,21 @@ public String getQueryString() { return sql; } + public ResultSetMapping getResultSetMapping() { + return resultSetMapping; + } + + public int getStartPosition() { + return parameterStartPosition; + } + @Override public QueryInterpretationCache.Key prepareForStore() { return new SelectInterpretationsKey( sql, - jdbcValuesMappingProducer.cacheKeyInstance(), + resultSetMapping.cacheKeyInstance(), new HashSet<>( querySpaces ), + parameterStartPosition, hash ); } @@ -86,7 +109,8 @@ public boolean equals(Object o) { return false; } return sql.equals( that.sql ) - && Objects.equals( jdbcValuesMappingProducer, that.jdbcValuesMappingProducer ) - && Objects.equals( querySpaces, that.querySpaces ); + && Objects.equals( resultSetMapping, that.resultSetMapping ) + && Objects.equals( querySpaces, that.querySpaces ) + && parameterStartPosition == that.parameterStartPosition; } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java index 1fdd79ec3585..e37561fbf6e8 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java @@ -493,7 +493,7 @@ private static CacheableSqmInterpretation buildCacheableSqmInterpretation( final SqlAstTranslator selectTranslator = sessionFactory.getJdbcServices().getJdbcEnvironment().getSqlAstTranslatorFactory() - .buildSelectTranslator( sessionFactory, sqmInterpretation.getSqlAst() ); + .buildSelectTranslator( sessionFactory, sqmInterpretation.getSqlAst(), sqmInterpretation.getParameterInfo() ); final var jdbcParamsXref = generateJdbcParamsXref( domainParameterXref, sqmInterpretation::getJdbcParamsBySqmParam ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleDeleteQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleDeleteQueryPlan.java index b2770075706e..fbc8a0611054 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleDeleteQueryPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleDeleteQueryPlan.java @@ -212,7 +212,7 @@ protected SqlAstTranslator createTranslato return factory.getJdbcServices() .getJdbcEnvironment() .getSqlAstTranslatorFactory() - .buildMutationTranslator( factory, ast ); + .buildMutationTranslator( factory, ast, sqmInterpretation.getParameterInfo() ); } private MutationStatement createDeleteAst() { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleInsertQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleInsertQueryPlan.java index 0371196a46aa..44d87a8cefb2 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleInsertQueryPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleInsertQueryPlan.java @@ -68,7 +68,7 @@ private SqlAstTranslator createInsertTrans return factory.getJdbcServices() .getJdbcEnvironment() .getSqlAstTranslatorFactory() - .buildMutationTranslator( factory, sqmInterpretation.getSqlAst() ); + .buildMutationTranslator( factory, sqmInterpretation.getSqlAst(), sqmInterpretation.getParameterInfo() ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleUpdateQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleUpdateQueryPlan.java index cf7b4dbb434f..21b4bda27032 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleUpdateQueryPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleUpdateQueryPlan.java @@ -113,6 +113,6 @@ private SqlAstTranslator createUpdateTrans this.sqmParamMappingTypeResolutions = sqmInterpretation.getSqmParameterMappingModelTypeResolutions(); return factory.getJdbcServices().getJdbcEnvironment().getSqlAstTranslatorFactory() - .buildMutationTranslator( factory, sqmInterpretation.getSqlAst() ); + .buildMutationTranslator( factory, sqmInterpretation.getSqlAst(), sqmInterpretation.getParameterInfo() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java index 15e5cfc8e31d..97b6436aa85f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java @@ -274,7 +274,7 @@ public static List selectMatchingIds( final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment(); final SqlAstTranslator sqlAstSelectTranslator = jdbcEnvironment .getSqlAstTranslatorFactory() - .buildSelectTranslator( factory, translation.getSqlAst() ); + .buildSelectTranslator( factory, translation.getSqlAst(), translation.getParameterInfo() ); final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings( executionContext.getQueryParameterBindings(), diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqmTranslation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqmTranslation.java index ea44a6918d26..683ce9e79810 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqmTranslation.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqmTranslation.java @@ -9,6 +9,7 @@ import org.hibernate.metamodel.mapping.MappingModelExpressible; import org.hibernate.query.sqm.tree.expression.SqmParameter; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.spi.FromClauseAccess; import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.tree.Statement; @@ -25,4 +26,11 @@ public interface SqmTranslation { FromClauseAccess getFromClauseAccess(); Map, List>> getJdbcParamsBySqmParam(); Map, MappingModelExpressible> getSqmParameterMappingModelTypeResolutions(); + + /** + * The parameter information for the SQL AST. + * + * @since 7.1 + */ + JdbcParameterMetadata getParameterInfo(); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/StandardSqmTranslation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/StandardSqmTranslation.java index 4890f4756189..74f1e5a5de11 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/StandardSqmTranslation.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/StandardSqmTranslation.java @@ -4,11 +4,15 @@ */ package org.hibernate.query.sqm.sql; +import java.util.Collections; +import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import org.hibernate.metamodel.mapping.MappingModelExpressible; import org.hibernate.query.sqm.tree.expression.SqmParameter; +import org.hibernate.sql.ast.JdbcParameterMetadata; +import org.hibernate.sql.ast.internal.JdbcParameterMetadataImpl; import org.hibernate.sql.ast.spi.FromClauseAccess; import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.tree.Statement; @@ -24,6 +28,7 @@ public class StandardSqmTranslation implements SqmTranslati private final Map, MappingModelExpressible> parameterMappingModelTypeMap; private final SqlExpressionResolver sqlExpressionResolver; private final FromClauseAccess fromClauseAccess; + private final JdbcParameterMetadata parameterInfo; public StandardSqmTranslation( T sqlAst, @@ -36,6 +41,19 @@ public StandardSqmTranslation( this.parameterMappingModelTypeMap = parameterMappingModelTypeMap; this.sqlExpressionResolver = sqlExpressionResolver; this.fromClauseAccess = fromClauseAccess; + final IdentityHashMap parameterIdMap = new IdentityHashMap<>(); + int parameterId = 0; + for ( Map.Entry, List>> entry : jdbcParamMap.entrySet() ) { + final List> parameterUses = entry.getValue(); + final int baseId = parameterId; + for ( List jdbcParameters : parameterUses ) { + for ( int i = 0; i < jdbcParameters.size(); i++ ) { + parameterIdMap.put( jdbcParameters.get( i ), baseId + i ); + } + } + parameterId += parameterUses.get( 0 ).size(); + } + this.parameterInfo = new JdbcParameterMetadataImpl( Collections.unmodifiableMap( parameterIdMap ), parameterId ); } @Override @@ -62,4 +80,9 @@ public SqlExpressionResolver getSqlExpressionResolver() { public FromClauseAccess getFromClauseAccess() { return fromClauseAccess; } + + @Override + public JdbcParameterMetadata getParameterInfo() { + return parameterInfo; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/JdbcParameterMetadata.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/JdbcParameterMetadata.java new file mode 100644 index 000000000000..99067c4143a8 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/JdbcParameterMetadata.java @@ -0,0 +1,24 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.sql.ast; + +import org.hibernate.sql.ast.tree.expression.JdbcParameter; + +/** + * Parameter information for {@link JdbcParameter} within a SQL query. + * + * @since 7.1 + */ +public interface JdbcParameterMetadata { + /** + * Returns the parameter id for the given {@link JdbcParameter}. + */ + int getParameterId(JdbcParameter jdbcParameter); + + /** + * Returns the number of parameters. + */ + int getParameterIdCount(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstTranslatorFactory.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstTranslatorFactory.java index 91f35924bdc1..79798a938af4 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstTranslatorFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstTranslatorFactory.java @@ -23,11 +23,23 @@ public interface SqlAstTranslatorFactory { */ SqlAstTranslator buildSelectTranslator(SessionFactoryImplementor sessionFactory, SelectStatement statement); + /** + * Builds a single-use select translator + * + * @since 7.1 + */ + SqlAstTranslator buildSelectTranslator(SessionFactoryImplementor sessionFactory, SelectStatement statement, JdbcParameterMetadata parameterInfo); + /** * Builds a single-use mutation translator */ SqlAstTranslator buildMutationTranslator(SessionFactoryImplementor sessionFactory, MutationStatement statement); + /** + * Builds a single-use mutation translator + */ + SqlAstTranslator buildMutationTranslator(SessionFactoryImplementor sessionFactory, MutationStatement statement, JdbcParameterMetadata parameterInfo); + /** * Builds a single-use translator for dealing with model mutations */ diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/internal/JdbcParameterMetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/internal/JdbcParameterMetadataImpl.java new file mode 100644 index 000000000000..119c55a1e334 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/internal/JdbcParameterMetadataImpl.java @@ -0,0 +1,38 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.sql.ast.internal; + +import org.hibernate.sql.ast.JdbcParameterMetadata; +import org.hibernate.sql.ast.tree.expression.JdbcParameter; + +import java.util.Map; + +/** + * @since 7.0 + */ +public class JdbcParameterMetadataImpl implements JdbcParameterMetadata { + + private final Map parameterIdMap; + private final int parameterIdCount; + + public JdbcParameterMetadataImpl(Map parameterIdMap, int parameterIdCount) { + this.parameterIdMap = parameterIdMap; + this.parameterIdCount = parameterIdCount; + } + + @Override + public int getParameterId(JdbcParameter jdbcParameter) { + final Integer id = parameterIdMap.get( jdbcParameter ); + if ( id == null ) { + throw new IllegalArgumentException( "JdbcParameter " + jdbcParameter + " not found in SqlParameterInfoImpl." ); + } + return id; + } + + @Override + public int getParameterIdCount() { + return parameterIdCount; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java index e31ebdff8b00..1a80193627c3 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java @@ -4,6 +4,7 @@ */ package org.hibernate.sql.ast.spi; +import org.checkerframework.checker.nullness.qual.Nullable; import jakarta.persistence.criteria.Nulls; import org.hibernate.AssertionFailure; import org.hibernate.Internal; @@ -69,9 +70,10 @@ import org.hibernate.sql.ast.SqlAstJoinType; import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstTranslator; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.SqlTreeCreationException; -import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard; import org.hibernate.sql.ast.internal.TableGroupHelper; +import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard; import org.hibernate.sql.ast.tree.AbstractUpdateOrDeleteStatement; import org.hibernate.sql.ast.tree.MutationStatement; import org.hibernate.sql.ast.tree.SqlAstNode; @@ -135,7 +137,6 @@ import org.hibernate.sql.exec.internal.AbstractJdbcParameter; import org.hibernate.sql.exec.internal.JdbcOperationQueryInsertImpl; import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl; -import org.hibernate.sql.exec.internal.JdbcParametersImpl; import org.hibernate.sql.exec.internal.SqlTypedMappingJdbcParameter; import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.exec.spi.JdbcLockStrategy; @@ -260,7 +261,8 @@ public abstract class AbstractSqlAstTranslator implemen private final StringBuilder sqlBuffer = new StringBuilder(); private final List parameterBinders = new ArrayList<>(); - private final JdbcParametersImpl jdbcParameters = new JdbcParametersImpl(); + private final @Nullable int[] parameterIdToBinderIndex; + private final @Nullable JdbcParameterMetadata parameterInfo; private JdbcParameterBindings jdbcParameterBindings; private Map appliedParameterBindings = Collections.emptyMap(); private SqlAstNodeRenderingMode parameterRenderingMode = SqlAstNodeRenderingMode.DEFAULT; @@ -307,12 +309,19 @@ public abstract class AbstractSqlAstTranslator implemen private JdbcParameter offsetParameter; private JdbcParameter limitParameter; + @Deprecated(forRemoval = true, since = "7.1") protected AbstractSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { + this( sessionFactory, statement, null ); + } + + protected AbstractSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { this.sessionFactory = sessionFactory; final JdbcServices jdbcServices = sessionFactory.getJdbcServices(); this.dialect = jdbcServices.getDialect(); this.statementStack.push( statement ); this.parameterMarkerStrategy = jdbcServices.getParameterMarkerStrategy(); + this.parameterInfo = parameterInfo; + this.parameterIdToBinderIndex = parameterInfo == null ? null : new int[parameterInfo.getParameterIdCount()]; if ( statement instanceof SelectStatement selectStatement ) { // ideally we'd only do this if there are LockOptions, @@ -4607,11 +4616,10 @@ protected void renderFetchPlusOffsetExpressionAsSingleParameter( appendSql( fetchCount.intValue() + offsetCount.intValue() + offset ); } else { - appendSql( PARAM_MARKER ); final JdbcParameter offsetParameter = (JdbcParameter) offsetClauseExpression; final int offsetValue = offset + fetchCount.intValue(); - jdbcParameters.addParameter( offsetParameter ); - parameterBinders.add( + final int parameterPosition = addParameterBinder( + offsetParameter, (statement, startPosition, jdbcParameterBindings, executionContext) -> { final JdbcParameterBinding binding = jdbcParameterBindings.getBinding( offsetParameter ); if ( binding == null ) { @@ -4627,44 +4635,29 @@ protected void renderFetchPlusOffsetExpressionAsSingleParameter( ); } ); + renderParameterAsParameter( parameterPosition, offsetParameter ); } } else { - appendSql( PARAM_MARKER ); final JdbcParameter offsetParameter = (JdbcParameter) offsetClauseExpression; final JdbcParameter fetchParameter = (JdbcParameter) fetchClauseExpression; - final OffsetReceivingParameterBinder fetchBinder = new OffsetReceivingParameterBinder( + final FetchPlusOffsetParameterBinder fetchBinder = new FetchPlusOffsetParameterBinder( offsetParameter, fetchParameter, offset ); - // We don't register and bind the special OffsetJdbcParameter as that comes from the query options - // And in this case, we only want to bind a single JDBC parameter - if ( !( offsetParameter instanceof OffsetJdbcParameter ) ) { - jdbcParameters.addParameter( offsetParameter ); - parameterBinders.add( - (statement, startPosition, jdbcParameterBindings, executionContext) -> { - final JdbcParameterBinding binding = jdbcParameterBindings.getBinding( offsetParameter ); - if ( binding == null ) { - throw new ExecutionException( "JDBC parameter value not bound - " + offsetParameter ); - } - fetchBinder.dynamicOffset = (Number) binding.getBindValue(); - } - ); - } - jdbcParameters.addParameter( fetchParameter ); - parameterBinders.add( fetchBinder ); + final int parameterPosition = addParameterBinder( fetchParameter, fetchBinder ); + renderParameterAsParameter( parameterPosition, fetchParameter ); } } - private static class OffsetReceivingParameterBinder implements JdbcParameterBinder { + private static class FetchPlusOffsetParameterBinder implements JdbcParameterBinder { private final JdbcParameter offsetParameter; private final JdbcParameter fetchParameter; private final int staticOffset; - private Number dynamicOffset; - public OffsetReceivingParameterBinder( + public FetchPlusOffsetParameterBinder( JdbcParameter offsetParameter, JdbcParameter fetchParameter, int staticOffset) { @@ -4695,8 +4688,11 @@ public void bindParameterValue( offsetValue = executionContext.getQueryOptions().getEffectiveLimit().getFirstRow(); } else { - offsetValue = dynamicOffset.intValue() + staticOffset; - dynamicOffset = null; + final JdbcParameterBinding binding = jdbcParameterBindings.getBinding( offsetParameter ); + if ( binding == null ) { + throw new ExecutionException( "JDBC parameter value not bound - " + offsetParameter ); + } + offsetValue = ((Number) binding.getBindValue()).intValue() + staticOffset; } //noinspection unchecked fetchParameter.getExpressionType().getSingleJdbcMapping().getJdbcValueBinder().bind( @@ -5670,15 +5666,15 @@ protected void renderLiteral(Literal literal, boolean castParameter) { final JdbcLiteralFormatter literalFormatter = literal.getJdbcMapping().getJdbcLiteralFormatter(); // If we encounter a plain literal in the select clause which has no literal formatter, we must render it as parameter if ( literalFormatter == null ) { - parameterBinders.add( literal ); + final int parameterPosition = addParameterBinderOnly( literal ); final JdbcType jdbcType = literal.getJdbcMapping().getJdbcType(); - final String marker = parameterMarkerStrategy.createMarker( parameterBinders.size(), jdbcType ); - final LiteralAsParameter jdbcParameter = new LiteralAsParameter<>( literal, marker ); + final String marker = parameterMarkerStrategy.createMarker( parameterPosition, jdbcType ); + if ( castParameter ) { - renderCasted( jdbcParameter ); + renderCasted( new LiteralAsParameter<>( literal, marker ) ); } else { - jdbcParameter.renderToSql( this, this, sessionFactory ); + jdbcType.appendWriteExpression( marker, this, dialect ); } } else { @@ -7002,15 +6998,8 @@ public void visitParameter(JdbcParameter jdbcParameter) { } protected void visitParameterAsParameter(JdbcParameter jdbcParameter) { - renderParameterAsParameter( jdbcParameter ); - parameterBinders.add( jdbcParameter.getParameterBinder() ); - jdbcParameters.addParameter( jdbcParameter ); - } - - protected final void renderParameterAsParameter(JdbcParameter jdbcParameter) { - final JdbcType jdbcType = jdbcParameter.getExpressionType().getJdbcMapping( 0 ).getJdbcType(); - assert jdbcType != null; - renderParameterAsParameter( parameterBinders.size() + 1, jdbcParameter ); + final int parameterPosition = addParameterBinder( jdbcParameter ); + renderParameterAsParameter( parameterPosition, jdbcParameter ); } protected void renderWrappedParameter(JdbcParameter jdbcParameter) { @@ -7037,6 +7026,30 @@ protected void renderParameterAsParameter(int position, JdbcParameter jdbcParame jdbcType.appendWriteExpression( parameterMarker, this, dialect ); } + protected final int addParameterBinder(JdbcParameter parameter) { + return addParameterBinder( parameter, parameter.getParameterBinder() ); + } + + protected final int addParameterBinder(JdbcParameter parameter, JdbcParameterBinder parameterBinder) { + if ( parameterInfo == null || ParameterMarkerStrategyStandard.isStandardRenderer( parameterMarkerStrategy ) + // Filter parameters are unique and they are not tracked via parameterInfo + || parameter instanceof FilterJdbcParameter ) { + return addParameterBinderOnly( parameterBinder ); + } + else { + final int parameterId = parameterInfo.getParameterId( parameter ); + if ( parameterIdToBinderIndex[parameterId] == 0 ) { + parameterIdToBinderIndex[parameterId] = addParameterBinderOnly( parameterBinder ); + } + return parameterIdToBinderIndex[parameterId]; + } + } + + private int addParameterBinderOnly(JdbcParameterBinder parameterBinder) { + parameterBinders.add( parameterBinder ); + return parameterBinders.size(); + } + @Override public void render(SqlAstNode sqlAstNode, SqlAstNodeRenderingMode renderingMode) { final SqlAstNodeRenderingMode original = this.parameterRenderingMode; @@ -8495,7 +8508,7 @@ public void visitCustomTableInsert(TableInsertCustomSql tableInsert) { assert sqlBuffer.toString().isEmpty(); sqlBuffer.append( tableInsert.getCustomSql() ); - tableInsert.forEachParameter( this::applyParameter ); + tableInsert.forEachParameter( this::addParameterBinder ); } @Override @@ -8604,7 +8617,7 @@ public void visitCustomTableUpdate(TableUpdateCustomSql tableUpdate) { assert sqlBuffer.toString().isEmpty(); sqlBuffer.append( tableUpdate.getCustomSql() ); - tableUpdate.forEachParameter( this::applyParameter ); + tableUpdate.forEachParameter( this::addParameterBinder ); } @Override @@ -8668,13 +8681,7 @@ public void visitCustomTableDelete(TableDeleteCustomSql tableDelete) { assert sqlBuffer.toString().isEmpty(); sqlBuffer.append( tableDelete.getCustomSql() ); - tableDelete.forEachParameter( this::applyParameter ); - } - - protected void applyParameter(ColumnValueParameter parameter) { - assert parameter != null; - parameterBinders.add( parameter.getParameterBinder() ); - jdbcParameters.addParameter( parameter ); + tableDelete.forEachParameter( this::addParameterBinder ); } @Override @@ -8711,10 +8718,6 @@ public void visitColumnWriteFragment(ColumnWriteFragment columnWriteFragment) { protected void simpleColumnWriteFragmentRendering(ColumnWriteFragment columnWriteFragment) { appendSql( columnWriteFragment.getFragment() ); - - for ( ColumnValueParameter parameter : columnWriteFragment.getParameters() ) { - parameterBinders.add( parameter.getParameterBinder() ); - jdbcParameters.addParameter( parameter ); - } + columnWriteFragment.getParameters().forEach( this::addParameterBinder ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstTranslatorWithMerge.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstTranslatorWithMerge.java index a0232c239cf4..e703fd5f40c0 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstTranslatorWithMerge.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstTranslatorWithMerge.java @@ -6,8 +6,10 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.StringHelper; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.model.ast.ColumnValueBinding; @@ -26,10 +28,15 @@ * @author Steve Ebersole */ public abstract class SqlAstTranslatorWithMerge extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public SqlAstTranslatorWithMerge(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + public SqlAstTranslatorWithMerge(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + /** * Create the MutationOperation for performing a MERGE. *

diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstTranslatorWithUpsert.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstTranslatorWithUpsert.java index bf0ef1795e34..3f9b423453e0 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstTranslatorWithUpsert.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstTranslatorWithUpsert.java @@ -6,8 +6,10 @@ import java.util.List; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.persister.entity.mutation.EntityTableMapping; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.model.MutationOperation; @@ -22,10 +24,15 @@ * @author Steve Ebersole */ public class SqlAstTranslatorWithUpsert extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") protected SqlAstTranslatorWithUpsert(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + protected SqlAstTranslatorWithUpsert(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } + /** * Create the MutationOperation for performing the DELETE or UPSERT */ diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstTranslator.java index 21b792d8a680..c330040a421a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstTranslator.java @@ -4,7 +4,9 @@ */ package org.hibernate.sql.ast.spi; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperationQuerySelect; @@ -18,7 +20,12 @@ */ public class StandardSqlAstTranslator extends AbstractSqlAstTranslator { + @Deprecated(forRemoval = true, since = "7.1") public StandardSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { super( sessionFactory, statement ); } + + public StandardSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + super( sessionFactory, statement, parameterInfo ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstTranslatorFactory.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstTranslatorFactory.java index 8bedd80c6213..2779f40183b5 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstTranslatorFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/StandardSqlAstTranslatorFactory.java @@ -4,9 +4,11 @@ */ package org.hibernate.sql.ast.spi; +import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslatorFactory; +import org.hibernate.sql.ast.JdbcParameterMetadata; import org.hibernate.sql.ast.tree.MutationStatement; import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.select.SelectStatement; @@ -22,27 +24,44 @@ * @author Steve Ebersole */ public class StandardSqlAstTranslatorFactory implements SqlAstTranslatorFactory { - @Override public SqlAstTranslator buildSelectTranslator(SessionFactoryImplementor sessionFactory, SelectStatement statement) { - return buildTranslator( sessionFactory, statement ); + return buildTranslator( sessionFactory, statement, null ); + } + + @Override + public SqlAstTranslator buildSelectTranslator(SessionFactoryImplementor sessionFactory, SelectStatement statement, JdbcParameterMetadata parameterInfo) { + return buildTranslator( sessionFactory, statement, parameterInfo ); } @Override public SqlAstTranslator buildMutationTranslator(SessionFactoryImplementor sessionFactory, MutationStatement statement) { - return buildTranslator( sessionFactory, statement ); + return buildTranslator( sessionFactory, statement, null ); + } + + @Override + public SqlAstTranslator buildMutationTranslator(SessionFactoryImplementor sessionFactory, MutationStatement statement, JdbcParameterMetadata parameterInfo) { + return buildTranslator( sessionFactory, statement, parameterInfo ); } @Override public SqlAstTranslator buildModelMutationTranslator(TableMutation mutation, SessionFactoryImplementor sessionFactory) { - return buildTranslator( sessionFactory, mutation ); + return buildTranslator( sessionFactory, mutation, null ); } /** * Consolidated building of a translator for all Query cases */ + @Deprecated(forRemoval = true, since = "7.1") protected SqlAstTranslator buildTranslator(SessionFactoryImplementor sessionFactory, Statement statement) { - return new StandardSqlAstTranslator<>( sessionFactory, statement ); + return new StandardSqlAstTranslator<>( sessionFactory, statement, null ); + } + + /** + * Consolidated building of a translator for all Query cases + */ + protected SqlAstTranslator buildTranslator(SessionFactoryImplementor sessionFactory, Statement statement, @Nullable JdbcParameterMetadata parameterInfo) { + return buildTranslator( sessionFactory, statement ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/StandardJdbcMutationExecutor.java b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/StandardJdbcMutationExecutor.java index e90924258694..ad2716c5bad8 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/StandardJdbcMutationExecutor.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/exec/internal/StandardJdbcMutationExecutor.java @@ -6,6 +6,7 @@ import java.sql.PreparedStatement; import java.sql.SQLException; +import java.util.List; import java.util.function.BiConsumer; import java.util.function.Function; @@ -59,11 +60,11 @@ public int execute( // bind parameters // todo : validate that all query parameters were bound? - int paramBindingPosition = 1; - for ( JdbcParameterBinder parameterBinder : jdbcMutation.getParameterBinders() ) { - parameterBinder.bindParameterValue( + final List parameterBinders = jdbcMutation.getParameterBinders(); + for ( int i = 0; i < parameterBinders.size(); i++ ) { + parameterBinders.get( i ).bindParameterValue( preparedStatement, - paramBindingPosition++, + i + 1, jdbcParameterBindings, executionContext ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/DeferredResultSetAccess.java b/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/DeferredResultSetAccess.java index a36c4b2e5c48..f2d3c9e8292a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/DeferredResultSetAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/DeferredResultSetAccess.java @@ -91,9 +91,14 @@ public DeferredResultSetAccess( final String sql = jdbcSelect.getSqlString(); limit = queryOptions.getLimit(); - final boolean hasLimit = hasLimit( jdbcSelect ); - limitHandler = hasLimit ? NoopLimitHandler.NO_LIMIT : dialect.getLimitHandler(); - final String sqlWithLimit = hasLimit ? sql : limitHandler.processSql( sql, limit, queryOptions ); + final boolean needsLimitHandler = needsLimitHandler( jdbcSelect ); + limitHandler = needsLimitHandler ? dialect.getLimitHandler() : NoopLimitHandler.NO_LIMIT; + final String sqlWithLimit = !needsLimitHandler ? sql : limitHandler.processSql( + sql, + jdbcParameterBindings.getBindings().size(), + jdbcServices.getParameterMarkerStrategy(), + queryOptions + ); final LockOptions lockOptions = queryOptions.getLockOptions(); final JdbcLockStrategy jdbcLockStrategy = jdbcSelect.getLockStrategy(); @@ -120,8 +125,8 @@ public DeferredResultSetAccess( } } - private boolean hasLimit(JdbcOperationQuerySelect jdbcSelect) { - return limit == null || limit.isEmpty() || jdbcSelect.usesLimitParameters(); + private boolean needsLimitHandler(JdbcOperationQuerySelect jdbcSelect) { + return limit != null && !limit.isEmpty() && !jdbcSelect.usesLimitParameters(); } private static boolean hasLocking(JdbcLockStrategy jdbcLockStrategy, LockOptions lockOptions) { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/AbstractLimitHandlerTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/AbstractLimitHandlerTest.java index 39f4f7fda54d..c8fb684e1f4e 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/AbstractLimitHandlerTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/AbstractLimitHandlerTest.java @@ -7,7 +7,6 @@ import org.hibernate.dialect.pagination.LimitHandler; import org.hibernate.dialect.pagination.OffsetFetchLimitHandler; import org.hibernate.query.spi.Limit; -import org.hibernate.query.spi.QueryOptions; import org.junit.jupiter.api.Test; import static org.hibernate.dialect.pagination.AbstractLimitHandler.hasFirstRow; @@ -42,7 +41,8 @@ public void testSqlWithSemicolonInsideQuotedStringAndEndsWithSemicolon() { } protected void assertGenerateExpectedSql(String expected, String sql) { - assertEquals(expected, getLimitHandler().processSql(sql, getLimit(), QueryOptions.NONE)); + assertEquals( expected, getLimitHandler().processSql( sql, 0, null, + new LimitQueryOptions( AbstractLimitHandlerTest.this.getLimit() ) ) ); } protected abstract LimitHandler getLimitHandler(); @@ -68,4 +68,5 @@ else if (hasFirstRow(limit)) { } return " limit ?"; } + } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/DB2DialectTestCase.java b/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/DB2DialectTestCase.java index b3bb82f6f225..688f39bea409 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/DB2DialectTestCase.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/DB2DialectTestCase.java @@ -83,7 +83,7 @@ public void testIntegerOverflowForMaxResults() { Limit rowSelection = new Limit(); rowSelection.setFirstRow(1); rowSelection.setMaxRows(Integer.MAX_VALUE); - String sql = dialect.getLimitHandler().processSql( "select a.id from tbl_a a order by a.id", rowSelection ); + String sql = dialect.getLimitHandler().processSql( "select a.id from tbl_a a order by a.id", -1, null, new LimitQueryOptions( rowSelection ) ); assertTrue( "Integer overflow for max rows in: " + sql, sql.contains("fetch next ? rows only") diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/LimitQueryOptions.java b/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/LimitQueryOptions.java new file mode 100644 index 000000000000..f029e1c1dc0f --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/LimitQueryOptions.java @@ -0,0 +1,22 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.dialect; + +import org.hibernate.query.spi.Limit; +import org.hibernate.query.spi.QueryOptionsAdapter; + +public class LimitQueryOptions extends QueryOptionsAdapter { + + private final Limit limit; + + public LimitQueryOptions(Limit limit) { + this.limit = limit; + } + + @Override + public Limit getLimit() { + return limit; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/function/AnsiTrimEmulationFunctionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/function/AnsiTrimEmulationFunctionTest.java index 43d18509ed34..4eef8395a8b1 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/function/AnsiTrimEmulationFunctionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/function/AnsiTrimEmulationFunctionTest.java @@ -126,6 +126,7 @@ private String render( Mockito.doReturn( dialect ).when( jdbcServices ).getDialect(); StandardSqlAstTranslator walker = new StandardSqlAstTranslator<>( factory, + null, null ); List sqlAstArguments = new ArrayList<>(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/NativeParameterMarkerStrategyTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/NativeParameterMarkerStrategyTests.java new file mode 100644 index 000000000000..3ac69011e9de --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/NativeParameterMarkerStrategyTests.java @@ -0,0 +1,178 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.sql.ast; + +import java.util.List; + +import org.hibernate.query.NativeQuery; +import org.hibernate.query.sql.spi.NativeQueryImplementor; +import org.hibernate.sql.ast.spi.ParameterMarkerStrategy; +import org.hibernate.type.descriptor.jdbc.IntegerJdbcType; +import org.hibernate.type.descriptor.jdbc.JdbcType; + +import org.hibernate.testing.jdbc.SQLStatementInspector; +import org.hibernate.testing.orm.junit.DialectContext; +import org.hibernate.testing.orm.junit.DialectFeatureChecks; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.Jira; +import org.hibernate.testing.orm.junit.RequiresDialectFeature; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.SessionFactoryScopeAware; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Nathan Xu + */ +@ServiceRegistry( services = @ServiceRegistry.Service( + role = ParameterMarkerStrategy.class, + impl = NativeParameterMarkerStrategyTests.DialectParameterMarkerStrategy.class +) ) +@DomainModel( annotatedClasses = NativeParameterMarkerStrategyTests.Book.class ) +@SessionFactory( useCollectingStatementInspector = true ) +@RequiresDialectFeature( feature = DialectFeatureChecks.SupportsNonStandardNativeParameterRendering.class ) +@Jira( "https://hibernate.atlassian.net/browse/HHH-16283" ) +class NativeParameterMarkerStrategyTests implements SessionFactoryScopeAware { + + private enum ParameterStyle { + JDBC, + ORDINAL, + NAMED + } + + public static class DialectParameterMarkerStrategy implements ParameterMarkerStrategy { + + public static final DialectParameterMarkerStrategy INSTANCE = new DialectParameterMarkerStrategy(); + + @Override + public String createMarker(int position, JdbcType jdbcType) { + return DialectContext.getDialect().getNativeParameterMarkerStrategy().createMarker( position, jdbcType ); + } + } + + private SessionFactoryScope scope; + private SQLStatementInspector statementInspector; + + @Override + public void injectSessionFactoryScope(SessionFactoryScope scope) { + this.scope = scope; + } + + @BeforeEach + void setUp() { + statementInspector = scope.getCollectingStatementInspector(); + statementInspector.clear(); + } + + @ParameterizedTest + @EnumSource(ParameterStyle.class) + void testHappyPath(ParameterStyle style) { + scope.inTransaction( (session) -> { + final NativeQueryImplementor nativeQuery; + final var parameterValue = "War and Peace"; + if ( style == ParameterStyle.NAMED ) { + nativeQuery = session.createNativeQuery( "select * from books b where b.title = :title", Book.class ) + .setParameter( "title", parameterValue ); + } else { + nativeQuery = session.createNativeQuery( "select * from books b where b.title = " + ( style == ParameterStyle.ORDINAL ? "?1" : "?" ), Book.class ) + .setParameter( 1, parameterValue ); + }; + nativeQuery.list(); + assertNativeQueryContainsMarkers( 1 ); + } ); + } + + @ParameterizedTest + @EnumSource(ParameterStyle.class) + void testParameterExpansion(ParameterStyle style) { + final var parameterValue = List.of( "Moby-Dick", "Don Quixote", "In Search of Lost Time" ); + + scope.inTransaction( (session) -> { + final NativeQuery nativeQuery; + if ( style == ParameterStyle.NAMED ) { + nativeQuery = session.createNativeQuery( "select * from books b where b.title in :titles", Book.class ) + .setParameterList( "titles", parameterValue ); + } else { + nativeQuery = session.createNativeQuery( "select * from books b where b.title in " + ( style == ParameterStyle.ORDINAL ? "?1" : "?" ), Book.class ) + .setParameterList( 1, parameterValue ); + }; + nativeQuery.list(); + assertNativeQueryContainsMarkers( parameterValue.size() ); + } ); + } + + @ParameterizedTest + @EnumSource(ParameterStyle.class) + void testLimitHandler(ParameterStyle style) { + scope.inTransaction( (session) -> { + final NativeQueryImplementor nativeQuery; + final var parameterValue = "Herman Melville"; + if ( style == ParameterStyle.NAMED ) { + nativeQuery = session.createNativeQuery( "select * from books b where b.author = :author", Book.class ) + .setParameter( "author", parameterValue ); + } else { + nativeQuery = session.createNativeQuery( "select * from books b where b.author = " + ( style == ParameterStyle.ORDINAL ? "?1" : "?" ), Book.class ) + .setParameter( 1, parameterValue ); + }; + nativeQuery.setFirstResult( 2 ).setMaxResults( 1 ).list(); + + assertNativeQueryContainsMarkers( 3 ); + } ); + } + + @ParameterizedTest + @EnumSource(ParameterStyle.class) + void test_parameterExpansionAndLimitHandler(ParameterStyle style) { + final var parameterValue = List.of( "Moby-Dick", "Don Quixote", "In Search of Lost Time" ); + + scope.inTransaction( (session) -> { + final NativeQueryImplementor nativeQuery; + if ( style == ParameterStyle.NAMED ) { + nativeQuery = session.createNativeQuery( "select * from books b where b.title in :titles", Book.class ) + .setParameterList( "titles", parameterValue ); + } else { + nativeQuery = session.createNativeQuery( "select * from books b where b.title in " + ( style == ParameterStyle.ORDINAL ? "?1" : "?" ), Book.class ) + .setParameterList( 1, parameterValue ); + }; + nativeQuery.setFirstResult( 1 ).setMaxResults( 3 ).list(); + + assertNativeQueryContainsMarkers( parameterValue.size() + 2 ); + } ); + } + + private void assertNativeQueryContainsMarkers(int expectedMarkerNum) { + + final var strategy = DialectParameterMarkerStrategy.INSTANCE; + + final var expectedMarkers = new String[expectedMarkerNum]; + for ( int i = 1; i <= expectedMarkerNum; i++ ) { + expectedMarkers[i - 1] = strategy.createMarker( i, IntegerJdbcType.INSTANCE ); + } + + final var unexpectedMarker = strategy.createMarker( expectedMarkerNum + 1, IntegerJdbcType.INSTANCE ); + + assertThat( statementInspector.getSqlQueries() ) + .singleElement() + .satisfies( query -> assertThat( query ).contains( expectedMarkers ).doesNotContain( unexpectedMarker ) ); + } + + @Entity + @Table(name = "books") + static class Book { + @Id + int id; + String title; + String author; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/ParameterMarkerStrategyTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/ParameterMarkerStrategyTests.java index 3258f8b8ee1b..69abd19105b2 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/ParameterMarkerStrategyTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/ParameterMarkerStrategyTests.java @@ -153,6 +153,24 @@ public void testNativeQuery(SessionFactoryScope scope) { } ); } + @Test + @Jira( "https://hibernate.atlassian.net/browse/HHH-19632" ) + public void testQueryParamReuse(SessionFactoryScope scope) { + final String queryString = "select e from EntityOfBasics e where e.id = :id and e.id = :id"; + + final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector(); + statementInspector.clear(); + + scope.inTransaction( (session) -> { + session.createSelectionQuery( queryString, EntityOfBasics.class ).setParameter( "id", 1 ).list(); + } ); + + assertThat( statementInspector.getSqlQueries() ).hasSize( 1 ); + final String sql = statementInspector.getSqlQueries().get( 0 ); + assertThat( sql ).contains( "?1" ); + assertThat( sql ).doesNotContain( "?2" ); + } + @AfterEach public void cleanUpTestData(SessionFactoryScope scope) { scope.getSessionFactory().getSchemaManager().truncate(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/SmokeTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/SmokeTests.java index 23b9044efb0b..38d875836b23 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/SmokeTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/SmokeTests.java @@ -90,10 +90,9 @@ public void testSimpleHqlInterpretation(SessionFactoryScope scope) { assertThat( sqlSelection.getValuesArrayPosition(), is( 0 ) ); assertThat( sqlSelection.getJdbcValueExtractor(), notNullValue() ); - final JdbcOperationQuerySelect jdbcSelectOperation = new StandardSqlAstTranslator( - session.getSessionFactory(), - sqlAst - ).translate( null, QueryOptions.NONE ); + final JdbcOperationQuerySelect jdbcSelectOperation = + new StandardSqlAstTranslator( session.getSessionFactory(), sqlAst, null ) + .translate( null, QueryOptions.NONE ); assertThat( jdbcSelectOperation.getSqlString(), @@ -180,7 +179,8 @@ public void testConvertedHqlInterpretation(SessionFactoryScope scope) { final JdbcOperationQuerySelect jdbcSelectOperation = new StandardSqlAstTranslator( session.getSessionFactory(), - sqlAst + sqlAst, + null ).translate( null, QueryOptions.NONE ); assertThat( diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectFeatureChecks.java b/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectFeatureChecks.java index d0dc5ec754f8..7bb583f3801f 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectFeatureChecks.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/orm/junit/DialectFeatureChecks.java @@ -88,6 +88,7 @@ import org.hibernate.query.sqm.function.SqmFunctionDescriptor; import org.hibernate.query.sqm.function.SqmFunctionRegistry; import org.hibernate.service.ServiceRegistry; +import org.hibernate.sql.ast.internal.ParameterMarkerStrategyStandard; import org.hibernate.sql.ast.spi.StringBuilderSqlAppender; import org.hibernate.testing.boot.BootstrapContextImpl; import org.hibernate.type.SqlTypes; @@ -1164,6 +1165,13 @@ public boolean apply(Dialect dialect) { } } + public static class SupportsNonStandardNativeParameterRendering implements DialectFeatureCheck { + @Override + public boolean apply(Dialect dialect) { + return !ParameterMarkerStrategyStandard.isStandardRenderer( dialect.getNativeParameterMarkerStrategy() ); + } + } + private static SqmFunctionRegistry getSqmFunctionRegistry(Dialect dialect) { SqmFunctionRegistry sqmFunctionRegistry = FUNCTION_REGISTRIES.get( dialect );