Add support for FETCH clause, CTEs and set operations
This commit is contained in:
parent
f54072df4e
commit
4efffca23b
10
ci/build.sh
10
ci/build.sh
|
@ -4,15 +4,15 @@ goal=
|
||||||
if [ "$RDBMS" == "derby" ]; then
|
if [ "$RDBMS" == "derby" ]; then
|
||||||
goal="-Pdb=derby"
|
goal="-Pdb=derby"
|
||||||
elif [ "$RDBMS" == "mariadb" ]; then
|
elif [ "$RDBMS" == "mariadb" ]; then
|
||||||
goal="-Pdb=mariadb"
|
goal="-Pdb=mariadb_ci"
|
||||||
elif [ "$RDBMS" == "postgresql" ]; then
|
elif [ "$RDBMS" == "postgresql" ]; then
|
||||||
goal="-Pdb=pgsql"
|
goal="-Pdb=pgsql_ci"
|
||||||
elif [ "$RDBMS" == "oracle" ]; then
|
elif [ "$RDBMS" == "oracle" ]; then
|
||||||
goal="-Pdb=oracle -Dhibernate.connection.url=jdbc:oracle:thin:@localhost:1521:XE -Dhibernate.connection.username=SYSTEM -Dhibernate.connection.password=Oracle18"
|
goal="-Pdb=oracle_ci"
|
||||||
elif [ "$RDBMS" == "db2" ]; then
|
elif [ "$RDBMS" == "db2" ]; then
|
||||||
goal="-Pdb=db2 -Dhibernate.connection.url=jdbc:db2://localhost:50000/orm_test -Dhibernate.connection.username=orm_test -Dhibernate.connection.password=orm_test"
|
goal="-Pdb=db2_ci"
|
||||||
elif [ "$RDBMS" == "mssql" ]; then
|
elif [ "$RDBMS" == "mssql" ]; then
|
||||||
goal="-Pdb=mssql -Dhibernate.connection.url=jdbc:sqlserver://localhost:1433;databaseName= -Dhibernate.connection.username=sa -Dhibernate.connection.password=Hibernate_orm_test"
|
goal="-Pdb=mssql_ci"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec ./gradlew check ${goal} -Plog-test-progress=true --stacktrace
|
exec ./gradlew check ${goal} -Plog-test-progress=true --stacktrace
|
28
docker_db.sh
28
docker_db.sh
|
@ -12,7 +12,7 @@ mysql_8_0() {
|
||||||
|
|
||||||
mariadb() {
|
mariadb() {
|
||||||
docker rm -f mariadb || true
|
docker rm -f mariadb || true
|
||||||
docker run --name mariadb -e MYSQL_USER=hibernate_orm_test -e MYSQL_PASSWORD=hibernate_orm_test -e MYSQL_DATABASE=hibernate_orm_test -e MYSQL_ALLOW_EMPTY_PASSWORD=true -p3306:3306 -d mariadb:10.5.8 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
docker run --name mariadb -e MYSQL_USER=hibernate_orm_test -e MYSQL_PASSWORD=hibernate_orm_test -e MYSQL_DATABASE=hibernate_orm_test -e MYSQL_ROOT_PASSWORD=hibernate_orm_test -p3306:3306 -d mariadb:10.5.8 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||||
}
|
}
|
||||||
|
|
||||||
postgresql_9_5() {
|
postgresql_9_5() {
|
||||||
|
@ -20,12 +20,17 @@ postgresql_9_5() {
|
||||||
docker run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 -d postgres:9.5
|
docker run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 -d postgres:9.5
|
||||||
}
|
}
|
||||||
|
|
||||||
|
postgresql_13() {
|
||||||
|
docker rm -f postgres || true
|
||||||
|
docker run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 -d postgres:13.0
|
||||||
|
}
|
||||||
|
|
||||||
db2() {
|
db2() {
|
||||||
docker rm -f db2 || true
|
docker rm -f db2 || true
|
||||||
docker run --name db2 --privileged -e DB2INSTANCE=orm_test -e DB2INST1_PASSWORD=orm_test -e DBNAME=orm_test -e LICENSE=accept -p 50000:50000 -d ibmcom/db2:11.5.0.0a
|
docker run --name db2 --privileged -e DB2INSTANCE=orm_test -e DB2INST1_PASSWORD=orm_test -e DBNAME=orm_test -e LICENSE=accept -e AUTOCONFIG=false -e ARCHIVE_LOGS=false -e TO_CREATE_SAMPLEDB=false -e REPODB=false -p 50000:50000 -d ibmcom/db2:11.5.5.0
|
||||||
# Give the container some time to start
|
# Give the container some time to start
|
||||||
OUTPUT=
|
OUTPUT=
|
||||||
while [[ $OUTPUT != *"Setup has completed"* ]]; do
|
while [[ $OUTPUT != *"INSTANCE"* ]]; do
|
||||||
echo "Waiting for DB2 to start..."
|
echo "Waiting for DB2 to start..."
|
||||||
sleep 10
|
sleep 10
|
||||||
OUTPUT=$(docker logs db2)
|
OUTPUT=$(docker logs db2)
|
||||||
|
@ -36,6 +41,22 @@ db2() {
|
||||||
mssql() {
|
mssql() {
|
||||||
docker rm -f mssql || true
|
docker rm -f mssql || true
|
||||||
docker run --name mssql -d -p 1433:1433 -e "SA_PASSWORD=Hibernate_orm_test" -e ACCEPT_EULA=Y microsoft/mssql-server-linux:2017-CU13
|
docker run --name mssql -d -p 1433:1433 -e "SA_PASSWORD=Hibernate_orm_test" -e ACCEPT_EULA=Y microsoft/mssql-server-linux:2017-CU13
|
||||||
|
sleep 5
|
||||||
|
n=0
|
||||||
|
until [ "$n" -ge 5 ]
|
||||||
|
do
|
||||||
|
# We need a database that uses a non-lock based MVCC approach
|
||||||
|
# https://github.com/microsoft/homebrew-mssql-release/issues/2#issuecomment-682285561
|
||||||
|
docker exec mssql bash -c 'echo "create database hibernate_orm_test collate SQL_Latin1_General_CP1_CI_AS; alter database hibernate_orm_test set READ_COMMITTED_SNAPSHOT ON" | /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Hibernate_orm_test -i /dev/stdin' && break
|
||||||
|
echo "Waiting for SQL Server to start..."
|
||||||
|
n=$((n+1))
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
if [ "$n" -ge 5 ]; then
|
||||||
|
echo "SQL Server failed to start and configure after 25 seconds"
|
||||||
|
else
|
||||||
|
echo "SQL Server successfully started"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
oracle() {
|
oracle() {
|
||||||
|
@ -52,6 +73,7 @@ if [ -z ${1} ]; then
|
||||||
echo -e "\tmysql_8_0"
|
echo -e "\tmysql_8_0"
|
||||||
echo -e "\tmariadb"
|
echo -e "\tmariadb"
|
||||||
echo -e "\tpostgresql_9_5"
|
echo -e "\tpostgresql_9_5"
|
||||||
|
echo -e "\tpostgresql_13"
|
||||||
echo -e "\tdb2"
|
echo -e "\tdb2"
|
||||||
echo -e "\tmssql"
|
echo -e "\tmssql"
|
||||||
echo -e "\toracle"
|
echo -e "\toracle"
|
||||||
|
|
|
@ -10,6 +10,7 @@ import org.apache.tools.ant.filters.ReplaceTokens
|
||||||
// build a map of the database settings to use.
|
// build a map of the database settings to use.
|
||||||
ext {
|
ext {
|
||||||
db = project.hasProperty('db') ? project.getProperty('db') : 'h2'
|
db = project.hasProperty('db') ? project.getProperty('db') : 'h2'
|
||||||
|
def dbHost = System.getProperty( 'dbHost', 'localhost' )
|
||||||
dbBundle = [
|
dbBundle = [
|
||||||
h2 : [
|
h2 : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.H2Dialect',
|
'db.dialect' : 'org.hibernate.dialect.H2Dialect',
|
||||||
|
@ -26,47 +27,61 @@ ext {
|
||||||
'jdbc.url' : 'jdbc:hsqldb:mem:test'
|
'jdbc.url' : 'jdbc:hsqldb:mem:test'
|
||||||
],
|
],
|
||||||
derby : [
|
derby : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.DerbyTenSevenDialect',
|
'db.dialect' : 'org.hibernate.dialect.DerbyDialect',
|
||||||
'jdbc.driver': 'org.apache.derby.jdbc.EmbeddedDriver',
|
'jdbc.driver': 'org.apache.derby.jdbc.EmbeddedDriver',
|
||||||
'jdbc.user' : 'hibernate_orm_test',
|
'jdbc.user' : 'hibernate_orm_test',
|
||||||
'jdbc.pass' : 'hibernate_orm_test',
|
'jdbc.pass' : 'hibernate_orm_test',
|
||||||
'jdbc.url' : 'jdbc:derby:target/tmp/derby/hibernate_orm_test;databaseName=hibernate_orm_test;create=true'
|
'jdbc.url' : 'jdbc:derby:target/tmp/derby/hibernate_orm_test;databaseName=hibernate_orm_test;create=true'
|
||||||
],
|
],
|
||||||
pgsql : [
|
pgsql : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.PostgreSQL95Dialect',
|
'db.dialect' : 'org.hibernate.dialect.PostgreSQLDialect',
|
||||||
'jdbc.driver': 'org.postgresql.Driver',
|
'jdbc.driver': 'org.postgresql.Driver',
|
||||||
'jdbc.user' : 'hibernate_orm_test',
|
'jdbc.user' : 'hibernate_orm_test',
|
||||||
'jdbc.pass' : 'hibernate_orm_test',
|
'jdbc.pass' : 'hibernate_orm_test',
|
||||||
'jdbc.url' : 'jdbc:postgresql:hibernate_orm_test'
|
'jdbc.url' : 'jdbc:postgresql:hibernate_orm_test'
|
||||||
],
|
],
|
||||||
pgsql_docker : [
|
pgsql_docker : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.PostgreSQL95Dialect',
|
'db.dialect' : 'org.hibernate.dialect.PostgreSQLDialect',
|
||||||
'jdbc.driver': 'org.postgresql.Driver',
|
'jdbc.driver': 'org.postgresql.Driver',
|
||||||
'jdbc.user' : 'hibernate_orm_test',
|
'jdbc.user' : 'hibernate_orm_test',
|
||||||
'jdbc.pass' : 'hibernate_orm_test',
|
'jdbc.pass' : 'hibernate_orm_test',
|
||||||
'jdbc.url' : 'jdbc:postgresql://127.0.0.1/hibernate_orm_test'
|
'jdbc.url' : 'jdbc:postgresql://127.0.0.1/hibernate_orm_test'
|
||||||
],
|
],
|
||||||
|
pgsql_ci : [
|
||||||
|
'db.dialect' : 'org.hibernate.dialect.PostgreSQLDialect',
|
||||||
|
'jdbc.driver': 'org.postgresql.Driver',
|
||||||
|
'jdbc.user' : 'hibernate_orm_test',
|
||||||
|
'jdbc.pass' : 'hibernate_orm_test',
|
||||||
|
'jdbc.url' : 'jdbc:postgresql://' + dbHost + '/hibernate_orm_test'
|
||||||
|
],
|
||||||
mysql : [
|
mysql : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.MySQL57Dialect',
|
'db.dialect' : 'org.hibernate.dialect.MySQLDialect',
|
||||||
'jdbc.driver': 'com.mysql.jdbc.Driver',
|
'jdbc.driver': 'com.mysql.jdbc.Driver',
|
||||||
'jdbc.user' : 'hibernateormtest',
|
'jdbc.user' : 'hibernateormtest',
|
||||||
'jdbc.pass' : 'hibernateormtest',
|
'jdbc.pass' : 'hibernateormtest',
|
||||||
'jdbc.url' : 'jdbc:mysql://localhost/hibernate_orm_test'
|
'jdbc.url' : 'jdbc:mysql://localhost/hibernate_orm_test'
|
||||||
],
|
],
|
||||||
mysql_docker : [
|
mysql_docker : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.MySQL57Dialect',
|
'db.dialect' : 'org.hibernate.dialect.MySQLDialect',
|
||||||
'jdbc.driver': 'com.mysql.jdbc.Driver',
|
'jdbc.driver': 'com.mysql.jdbc.Driver',
|
||||||
'jdbc.user' : 'hibernate_orm_test',
|
'jdbc.user' : 'hibernate_orm_test',
|
||||||
'jdbc.pass' : 'hibernate_orm_test',
|
'jdbc.pass' : 'hibernate_orm_test',
|
||||||
'jdbc.url' : 'jdbc:mysql://127.0.0.1/hibernate_orm_test?useSSL=false'
|
'jdbc.url' : 'jdbc:mysql://127.0.0.1/hibernate_orm_test?useSSL=false'
|
||||||
],
|
],
|
||||||
mariadb : [
|
mariadb : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.MariaDB103Dialect',
|
'db.dialect' : 'org.hibernate.dialect.MariaDBDialect',
|
||||||
'jdbc.driver': 'org.mariadb.jdbc.Driver',
|
'jdbc.driver': 'org.mariadb.jdbc.Driver',
|
||||||
'jdbc.user' : 'hibernate_orm_test',
|
'jdbc.user' : 'hibernate_orm_test',
|
||||||
'jdbc.pass' : 'hibernate_orm_test',
|
'jdbc.pass' : 'hibernate_orm_test',
|
||||||
'jdbc.url' : 'jdbc:mariadb://127.0.0.1/hibernate_orm_test'
|
'jdbc.url' : 'jdbc:mariadb://127.0.0.1/hibernate_orm_test'
|
||||||
],
|
],
|
||||||
|
mariadb_ci : [
|
||||||
|
'db.dialect' : 'org.hibernate.dialect.MariaDBDialect',
|
||||||
|
'jdbc.driver': 'org.mariadb.jdbc.Driver',
|
||||||
|
'jdbc.user' : 'root',
|
||||||
|
'jdbc.pass' : 'hibernate_orm_test',
|
||||||
|
'jdbc.url' : 'jdbc:mariadb://' + dbHost + '/hibernate_orm_test'
|
||||||
|
],
|
||||||
postgis : [
|
postgis : [
|
||||||
'db.dialect' : 'org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect',
|
'db.dialect' : 'org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect',
|
||||||
'jdbc.driver': 'org.postgresql.Driver',
|
'jdbc.driver': 'org.postgresql.Driver',
|
||||||
|
@ -75,7 +90,7 @@ ext {
|
||||||
'jdbc.url' : 'jdbc:postgresql:hibernate_orm_test'
|
'jdbc.url' : 'jdbc:postgresql:hibernate_orm_test'
|
||||||
],
|
],
|
||||||
oracle : [
|
oracle : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.Oracle10gDialect',
|
'db.dialect' : 'org.hibernate.dialect.OracleDialect',
|
||||||
'jdbc.driver': 'oracle.jdbc.OracleDriver',
|
'jdbc.driver': 'oracle.jdbc.OracleDriver',
|
||||||
'jdbc.user' : 'hibernate_orm_test',
|
'jdbc.user' : 'hibernate_orm_test',
|
||||||
'jdbc.pass' : 'hibernate_orm_test',
|
'jdbc.pass' : 'hibernate_orm_test',
|
||||||
|
@ -85,19 +100,33 @@ ext {
|
||||||
// After registering to get access (see instructions at above link), start it for testing with:
|
// After registering to get access (see instructions at above link), start it for testing with:
|
||||||
// docker run --ulimit memlock=-1:-1 -it --rm=true --memory-swappiness=0 --name ORCLCDB -p 1521:1521 store/oracle/database-enterprise:12.2.0.1-slim
|
// docker run --ulimit memlock=-1:-1 -it --rm=true --memory-swappiness=0 --name ORCLCDB -p 1521:1521 store/oracle/database-enterprise:12.2.0.1-slim
|
||||||
oracle_docker : [
|
oracle_docker : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.Oracle12cDialect',
|
'db.dialect' : 'org.hibernate.dialect.OracleDialect',
|
||||||
'jdbc.driver': 'oracle.jdbc.OracleDriver',
|
'jdbc.driver': 'oracle.jdbc.OracleDriver',
|
||||||
'jdbc.user' : 'sys as sysdba',
|
'jdbc.user' : 'sys as sysdba',
|
||||||
'jdbc.pass' : 'Oradoc_db1',
|
'jdbc.pass' : 'Oradoc_db1',
|
||||||
'jdbc.url' : 'jdbc:oracle:thin:@localhost:1521:ORCLCDB'
|
'jdbc.url' : 'jdbc:oracle:thin:@localhost:1521:ORCLCDB'
|
||||||
],
|
],
|
||||||
|
oracle_ci : [
|
||||||
|
'db.dialect' : 'org.hibernate.dialect.OracleDialect',
|
||||||
|
'jdbc.driver': 'oracle.jdbc.OracleDriver',
|
||||||
|
'jdbc.user' : 'SYSTEM',
|
||||||
|
'jdbc.pass' : 'Oracle18',
|
||||||
|
'jdbc.url' : 'jdbc:oracle:thin:@' + dbHost + ':1521:XE'
|
||||||
|
],
|
||||||
mssql : [
|
mssql : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.SQLServer2012Dialect',
|
'db.dialect' : 'org.hibernate.dialect.SQLServerDialect',
|
||||||
'jdbc.driver': 'com.microsoft.sqlserver.jdbc.SQLServerDriver',
|
'jdbc.driver': 'com.microsoft.sqlserver.jdbc.SQLServerDriver',
|
||||||
'jdbc.user' : 'hibernate_orm_test',
|
'jdbc.user' : 'hibernate_orm_test',
|
||||||
'jdbc.pass' : 'hibernate_orm_test',
|
'jdbc.pass' : 'hibernate_orm_test',
|
||||||
'jdbc.url' : 'jdbc:sqlserver://localhost;instance=SQLEXPRESS;databaseName=hibernate_orm_test'
|
'jdbc.url' : 'jdbc:sqlserver://localhost;instance=SQLEXPRESS;databaseName=hibernate_orm_test'
|
||||||
],
|
],
|
||||||
|
mssql_ci : [
|
||||||
|
'db.dialect' : 'org.hibernate.dialect.SQLServerDialect',
|
||||||
|
'jdbc.driver': 'com.microsoft.sqlserver.jdbc.SQLServerDriver',
|
||||||
|
'jdbc.user' : 'sa',
|
||||||
|
'jdbc.pass' : 'Hibernate_orm_test',
|
||||||
|
'jdbc.url' : 'jdbc:sqlserver://' + dbHost + ';databaseName=hibernate_orm_test'
|
||||||
|
],
|
||||||
informix : [
|
informix : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.InformixDialect',
|
'db.dialect' : 'org.hibernate.dialect.InformixDialect',
|
||||||
'jdbc.driver': 'com.informix.jdbc.IfxDriver',
|
'jdbc.driver': 'com.informix.jdbc.IfxDriver',
|
||||||
|
@ -112,6 +141,13 @@ ext {
|
||||||
'jdbc.pass' : 'db2inst1-pwd',
|
'jdbc.pass' : 'db2inst1-pwd',
|
||||||
'jdbc.url' : 'jdbc:db2://127.0.0.1:50000/hibern8'
|
'jdbc.url' : 'jdbc:db2://127.0.0.1:50000/hibern8'
|
||||||
],
|
],
|
||||||
|
db2_ci : [
|
||||||
|
'db.dialect' : 'org.hibernate.dialect.DB2Dialect',
|
||||||
|
'jdbc.driver': 'com.ibm.db2.jcc.DB2Driver',
|
||||||
|
'jdbc.user' : 'orm_test',
|
||||||
|
'jdbc.pass' : 'orm_test',
|
||||||
|
'jdbc.url' : 'jdbc:db2://' + dbHost + ':50000/orm_test'
|
||||||
|
],
|
||||||
hana : [
|
hana : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.HANAColumnStoreDialect',
|
'db.dialect' : 'org.hibernate.dialect.HANAColumnStoreDialect',
|
||||||
'jdbc.driver': 'com.sap.db.jdbc.Driver',
|
'jdbc.driver': 'com.sap.db.jdbc.Driver',
|
||||||
|
@ -134,7 +170,7 @@ ext {
|
||||||
'jdbc.url' : 'jdbc:sap://localhost:39015/'
|
'jdbc.url' : 'jdbc:sap://localhost:39015/'
|
||||||
],
|
],
|
||||||
cockroachdb : [
|
cockroachdb : [
|
||||||
'db.dialect' : 'org.hibernate.dialect.CockroachDB192Dialect',
|
'db.dialect' : 'org.hibernate.dialect.CockroachDialect',
|
||||||
// CockroachDB uses the same pgwire protocol as PostgreSQL, so the driver is the same.
|
// CockroachDB uses the same pgwire protocol as PostgreSQL, so the driver is the same.
|
||||||
'jdbc.driver': 'org.postgresql.Driver',
|
'jdbc.driver': 'org.postgresql.Driver',
|
||||||
'jdbc.user' : 'root',
|
'jdbc.user' : 'root',
|
||||||
|
|
|
@ -111,10 +111,10 @@ dependencies {
|
||||||
testRuntime( libraries.hana )
|
testRuntime( libraries.hana )
|
||||||
testRuntime( libraries.cockroachdb )
|
testRuntime( libraries.cockroachdb )
|
||||||
|
|
||||||
if ( db.equalsIgnoreCase( 'oracle' ) || db.equalsIgnoreCase( 'oracle_docker' ) ) {
|
if ( db.startsWith( 'oracle' ) ) {
|
||||||
testRuntime( libraries.oracle )
|
testRuntime( libraries.oracle )
|
||||||
}
|
}
|
||||||
else if ( db.equalsIgnoreCase( 'db2' ) ) {
|
else if ( db.startsWith( 'db2' ) ) {
|
||||||
testRuntime( libraries.db2 )
|
testRuntime( libraries.db2 )
|
||||||
}
|
}
|
||||||
else if ( db.equalsIgnoreCase( 'hana' ) ) {
|
else if ( db.equalsIgnoreCase( 'hana' ) ) {
|
||||||
|
|
|
@ -121,7 +121,7 @@ PLUS : '+';
|
||||||
MINUS : '-';
|
MINUS : '-';
|
||||||
ASTERISK : '*';
|
ASTERISK : '*';
|
||||||
SLASH : '/';
|
SLASH : '/';
|
||||||
PERCENT : '%';
|
PERCENT_OP : '%';
|
||||||
AMPERSAND : '&';
|
AMPERSAND : '&';
|
||||||
SEMICOLON : ';';
|
SEMICOLON : ';';
|
||||||
COLON : ':';
|
COLON : ':';
|
||||||
|
@ -176,6 +176,7 @@ END : [eE] [nN] [dD];
|
||||||
ENTRY : [eE] [nN] [tT] [rR] [yY];
|
ENTRY : [eE] [nN] [tT] [rR] [yY];
|
||||||
ESCAPE : [eE] [sS] [cC] [aA] [pP] [eE];
|
ESCAPE : [eE] [sS] [cC] [aA] [pP] [eE];
|
||||||
EVERY : [eE] [vV] [eE] [rR] [yY];
|
EVERY : [eE] [vV] [eE] [rR] [yY];
|
||||||
|
EXCEPT : [eE] [xX] [cC] [eE] [pP] [tT];
|
||||||
EXISTS : [eE] [xX] [iI] [sS] [tT] [sS];
|
EXISTS : [eE] [xX] [iI] [sS] [tT] [sS];
|
||||||
EXP : [eE] [xX] [pP];
|
EXP : [eE] [xX] [pP];
|
||||||
EXTRACT : [eE] [xX] [tT] [rR] [aA] [cC] [tT];
|
EXTRACT : [eE] [xX] [tT] [rR] [aA] [cC] [tT];
|
||||||
|
@ -197,6 +198,7 @@ INDEX : [iI] [nN] [dD] [eE] [xX];
|
||||||
INNER : [iI] [nN] [nN] [eE] [rR];
|
INNER : [iI] [nN] [nN] [eE] [rR];
|
||||||
INSERT : [iI] [nN] [sS] [eE] [rR] [tT];
|
INSERT : [iI] [nN] [sS] [eE] [rR] [tT];
|
||||||
INSTANT : [iI] [nN] [sS] [tT] [aA] [nN] [tT];
|
INSTANT : [iI] [nN] [sS] [tT] [aA] [nN] [tT];
|
||||||
|
INTERSECT : [iI] [nN] [tT] [eE] [rR] [sS] [eE] [cC] [tT];
|
||||||
INTO : [iI] [nN] [tT] [oO];
|
INTO : [iI] [nN] [tT] [oO];
|
||||||
IS : [iI] [sS];
|
IS : [iI] [sS];
|
||||||
JOIN : [jJ] [oO] [iI] [nN];
|
JOIN : [jJ] [oO] [iI] [nN];
|
||||||
|
@ -230,6 +232,7 @@ MINUTE : [mM] [iI] [nN] [uU] [tT] [eE];
|
||||||
MOD : [mM] [oO] [dD];
|
MOD : [mM] [oO] [dD];
|
||||||
MONTH : [mM] [oO] [nN] [tT] [hH];
|
MONTH : [mM] [oO] [nN] [tT] [hH];
|
||||||
NANOSECOND : [nN] [aA] [nN] [oO] [sS] [eE] [cC] [oO] [nN] [dD];
|
NANOSECOND : [nN] [aA] [nN] [oO] [sS] [eE] [cC] [oO] [nN] [dD];
|
||||||
|
NEXT : [nN] [eE] [xX] [tT];
|
||||||
NEW : [nN] [eE] [wW];
|
NEW : [nN] [eE] [wW];
|
||||||
NOT : [nN] [oO] [tT];
|
NOT : [nN] [oO] [tT];
|
||||||
NULLIF : [nN] [uU] [lL] [lL] [iI] [fF];
|
NULLIF : [nN] [uU] [lL] [lL] [iI] [fF];
|
||||||
|
@ -239,11 +242,13 @@ OF : [oO] [fF];
|
||||||
OFFSET : [oO] [fF] [fF] [sS] [eE] [tT];
|
OFFSET : [oO] [fF] [fF] [sS] [eE] [tT];
|
||||||
OFFSET_DATETIME : [oO] [fF] [fF] [sS] [eE] [tT] '_' [dD] [aA] [tT] [eE] [tT] [iI] [mM] [eE];
|
OFFSET_DATETIME : [oO] [fF] [fF] [sS] [eE] [tT] '_' [dD] [aA] [tT] [eE] [tT] [iI] [mM] [eE];
|
||||||
ON : [oO] [nN];
|
ON : [oO] [nN];
|
||||||
|
ONLY : [oO] [nN] [lL] [yY];
|
||||||
OR : [oO] [rR];
|
OR : [oO] [rR];
|
||||||
ORDER : [oO] [rR] [dD] [eE] [rR];
|
ORDER : [oO] [rR] [dD] [eE] [rR];
|
||||||
OUTER : [oO] [uU] [tT] [eE] [rR];
|
OUTER : [oO] [uU] [tT] [eE] [rR];
|
||||||
OVERLAY : [oO] [vV] [eE] [rR] [lL] [aA] [yY];
|
OVERLAY : [oO] [vV] [eE] [rR] [lL] [aA] [yY];
|
||||||
PAD : [pP] [aA] [dD];
|
PAD : [pP] [aA] [dD];
|
||||||
|
PERCENT : [pP] [eE] [rR] [cC] [eE] [nN] [tT];
|
||||||
PLACING : [pP] [lL] [aA] [cC] [iI] [nN] [gG];
|
PLACING : [pP] [lL] [aA] [cC] [iI] [nN] [gG];
|
||||||
POSITION : [pP] [oO] [sS] [iI] [tT] [iI] [oO] [nN];
|
POSITION : [pP] [oO] [sS] [iI] [tT] [iI] [oO] [nN];
|
||||||
POWER : [pP] [oO] [wW] [eE] [rR];
|
POWER : [pP] [oO] [wW] [eE] [rR];
|
||||||
|
@ -252,6 +257,8 @@ REPLACE : [rR] [eE] [pP] [lL] [aA] [cC] [eE];
|
||||||
RIGHT : [rR] [iI] [gG] [hH] [tT];
|
RIGHT : [rR] [iI] [gG] [hH] [tT];
|
||||||
ROLLUP : [rR] [oO] [lL] [lL] [uU] [pP];
|
ROLLUP : [rR] [oO] [lL] [lL] [uU] [pP];
|
||||||
ROUND : [rR] [oO] [uU] [nN] [dD];
|
ROUND : [rR] [oO] [uU] [nN] [dD];
|
||||||
|
ROWS : [rR] [oO] [wW] [sS];
|
||||||
|
ROW : [rR] [oO] [wW];
|
||||||
SECOND : [sS] [eE] [cC] [oO] [nN] [dD];
|
SECOND : [sS] [eE] [cC] [oO] [nN] [dD];
|
||||||
SELECT : [sS] [eE] [lL] [eE] [cC] [tT];
|
SELECT : [sS] [eE] [lL] [eE] [cC] [tT];
|
||||||
SET : [sS] [eE] [tT];
|
SET : [sS] [eE] [tT];
|
||||||
|
@ -263,6 +270,7 @@ STR : [sS] [tT] [rR];
|
||||||
SUBSTRING : [sS] [uU] [bB] [sS] [tT] [rR] [iI] [nN] [gG];
|
SUBSTRING : [sS] [uU] [bB] [sS] [tT] [rR] [iI] [nN] [gG];
|
||||||
SUM : [sS] [uU] [mM];
|
SUM : [sS] [uU] [mM];
|
||||||
THEN : [tT] [hH] [eE] [nN];
|
THEN : [tT] [hH] [eE] [nN];
|
||||||
|
TIES : [tT] [iI] [eE] [sS];
|
||||||
TIME : [tT] [iI] [mM] [eE];
|
TIME : [tT] [iI] [mM] [eE];
|
||||||
TIMESTAMP : [tT] [iI] [mM] [eE] [sS] [tT] [aA] [mM] [pP];
|
TIMESTAMP : [tT] [iI] [mM] [eE] [sS] [tT] [aA] [mM] [pP];
|
||||||
TIMEZONE_HOUR : [tT] [iI] [mM] [eE] [zZ] [oO] [nN] [eE] '_' [hH] [oO] [uU] [rR];
|
TIMEZONE_HOUR : [tT] [iI] [mM] [eE] [zZ] [oO] [nN] [eE] '_' [hH] [oO] [uU] [rR];
|
||||||
|
@ -271,6 +279,7 @@ TRAILING : [tT] [rR] [aA] [iI] [lL] [iI] [nN] [gG];
|
||||||
TREAT : [tT] [rR] [eE] [aA] [tT];
|
TREAT : [tT] [rR] [eE] [aA] [tT];
|
||||||
TRIM : [tT] [rR] [iI] [mM];
|
TRIM : [tT] [rR] [iI] [mM];
|
||||||
TYPE : [tT] [yY] [pP] [eE];
|
TYPE : [tT] [yY] [pP] [eE];
|
||||||
|
UNION : [uU] [nN] [iI] [oO] [nN];
|
||||||
UPDATE : [uU] [pP] [dD] [aA] [tT] [eE];
|
UPDATE : [uU] [pP] [dD] [aA] [tT] [eE];
|
||||||
UPPER : [uU] [pP] [pP] [eE] [rR];
|
UPPER : [uU] [pP] [pP] [eE] [rR];
|
||||||
VALUE : [vV] [aA] [lL] [uU] [eE];
|
VALUE : [vV] [aA] [lL] [uU] [eE];
|
||||||
|
|
|
@ -28,11 +28,11 @@ statement
|
||||||
;
|
;
|
||||||
|
|
||||||
selectStatement
|
selectStatement
|
||||||
: querySpec
|
: queryExpression
|
||||||
;
|
;
|
||||||
|
|
||||||
subQuery
|
subQuery
|
||||||
: querySpec
|
: queryExpression
|
||||||
;
|
;
|
||||||
|
|
||||||
dmlTarget
|
dmlTarget
|
||||||
|
@ -56,7 +56,7 @@ assignment
|
||||||
;
|
;
|
||||||
|
|
||||||
insertStatement
|
insertStatement
|
||||||
: INSERT INTO? dmlTarget targetFieldsSpec (querySpec | valuesList)
|
: INSERT INTO? dmlTarget targetFieldsSpec (queryExpression | valuesList)
|
||||||
;
|
;
|
||||||
|
|
||||||
targetFieldsSpec
|
targetFieldsSpec
|
||||||
|
@ -74,9 +74,30 @@ values
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// QUERY SPEC - general structure of root sqm or sub sqm
|
// QUERY SPEC - general structure of root sqm or sub sqm
|
||||||
|
|
||||||
|
queryExpression
|
||||||
|
: queryGroup queryOrder?
|
||||||
|
;
|
||||||
|
|
||||||
|
queryGroup
|
||||||
|
: querySpec # QuerySpecQueryGroup
|
||||||
|
| LEFT_PAREN queryGroup RIGHT_PAREN # NestedQueryGroup
|
||||||
|
| queryGroup queryOrder? (setOperator (querySpec | LEFT_PAREN queryGroup RIGHT_PAREN))+ # SetQueryGroup
|
||||||
|
;
|
||||||
|
|
||||||
|
setOperator
|
||||||
|
: UNION ALL?
|
||||||
|
| INTERSECT ALL?
|
||||||
|
| EXCEPT ALL?
|
||||||
|
;
|
||||||
|
|
||||||
|
queryOrder
|
||||||
|
: orderByClause limitClause? offsetClause? fetchClause?
|
||||||
|
;
|
||||||
|
|
||||||
querySpec
|
querySpec
|
||||||
: selectClause fromClause? whereClause? ( groupByClause havingClause? )? orderByClause? limitClause? offsetClause?
|
// TODO: add with clause
|
||||||
| fromClause whereClause? ( groupByClause havingClause? )? selectClause? orderByClause? limitClause? offsetClause?
|
: selectClause fromClause? whereClause? ( groupByClause havingClause? )?
|
||||||
|
| fromClause whereClause? ( groupByClause havingClause? )? selectClause?
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -340,16 +361,27 @@ orderingSpecification
|
||||||
// LIMIT/OFFSET clause
|
// LIMIT/OFFSET clause
|
||||||
|
|
||||||
limitClause
|
limitClause
|
||||||
: LIMIT parameterOrNumberLiteral
|
: LIMIT parameterOrIntegerLiteral
|
||||||
;
|
;
|
||||||
|
|
||||||
offsetClause
|
offsetClause
|
||||||
: OFFSET parameterOrNumberLiteral
|
: OFFSET parameterOrIntegerLiteral (ROW | ROWS)?
|
||||||
|
;
|
||||||
|
|
||||||
|
fetchClause
|
||||||
|
: FETCH (FIRST | NEXT) (parameterOrIntegerLiteral | parameterOrNumberLiteral PERCENT) (ROW | ROWS) (ONLY | WITH TIES)
|
||||||
|
;
|
||||||
|
|
||||||
|
parameterOrIntegerLiteral
|
||||||
|
: parameter
|
||||||
|
| INTEGER_LITERAL
|
||||||
;
|
;
|
||||||
|
|
||||||
parameterOrNumberLiteral
|
parameterOrNumberLiteral
|
||||||
: parameter
|
: parameter
|
||||||
| INTEGER_LITERAL
|
| INTEGER_LITERAL
|
||||||
|
| FLOAT_LITERAL
|
||||||
|
| DOUBLE_LITERAL
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -427,7 +459,7 @@ primaryExpression
|
||||||
|
|
||||||
multiplicativeOperator
|
multiplicativeOperator
|
||||||
: SLASH
|
: SLASH
|
||||||
| PERCENT
|
| PERCENT_OP
|
||||||
| ASTERISK
|
| ASTERISK
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The kind of CTE search clause.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public enum CteSearchClauseKind {
|
||||||
|
/**
|
||||||
|
* Use depth first for a recursive CTE.
|
||||||
|
*/
|
||||||
|
DEPTH_FIRST,
|
||||||
|
/**
|
||||||
|
* Use breadth first for a recursive CTE.
|
||||||
|
*/
|
||||||
|
BREADTH_FIRST;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The kind of fetch to use for the FETCH clause.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public enum FetchClauseType {
|
||||||
|
/**
|
||||||
|
* Exact row count like for LIMIT clause or FETCH FIRST x ROWS ONLY.
|
||||||
|
*/
|
||||||
|
ROWS_ONLY,
|
||||||
|
/**
|
||||||
|
* Also fetches ties if the last value is not unique FETCH FIRST x ROWS WITH TIES.
|
||||||
|
*/
|
||||||
|
ROWS_WITH_TIES,
|
||||||
|
/**
|
||||||
|
* Row count in percent FETCH FIRST x PERCENT ROWS ONLY.
|
||||||
|
*/
|
||||||
|
PERCENT_ONLY,
|
||||||
|
/**
|
||||||
|
* Also fetches ties if the last value is not unique FETCH FIRST x PERCENT ROWS WITH TIES.
|
||||||
|
*/
|
||||||
|
PERCENT_WITH_TIES;
|
||||||
|
}
|
|
@ -75,6 +75,14 @@ public class LockOptions implements Serializable {
|
||||||
this.lockMode = lockMode;
|
this.lockMode = lockMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the lock options are empty.
|
||||||
|
*
|
||||||
|
* @return If the lock options is equivalent to {@link LockOptions#NONE}.
|
||||||
|
*/
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return lockMode == LockMode.NONE && timeout == WAIT_FOREVER && followOnLocking == null && !scope && !hasAliasSpecificLockModes();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the overall lock mode in effect for this set of options.
|
* Retrieve the overall lock mode in effect for this set of options.
|
||||||
|
@ -329,4 +337,30 @@ public class LockOptions implements Serializable {
|
||||||
destination.setFollowOnLocking( source.getFollowOnLocking() );
|
destination.setFollowOnLocking( source.getFollowOnLocking() );
|
||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isCompatible(LockOptions that) {
|
||||||
|
if ( that == null ) {
|
||||||
|
return isEmpty();
|
||||||
|
}
|
||||||
|
else if ( this == that ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( timeout != that.timeout ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( scope != that.scope ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( lockMode != that.lockMode ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( aliasSpecificLockModes != null ?
|
||||||
|
!aliasSpecificLockModes.equals( that.aliasSpecificLockModes ) :
|
||||||
|
that.aliasSpecificLockModes != null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return followOnLocking != null ? followOnLocking.equals( that.followOnLocking ) : that.followOnLocking == null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The order of null.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public enum NullOrdering {
|
||||||
|
/**
|
||||||
|
* Null is treated as the smallest value.
|
||||||
|
*/
|
||||||
|
SMALLEST,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Null is treated as the greatest value.
|
||||||
|
*/
|
||||||
|
GREATEST,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Null is always ordered first.
|
||||||
|
*/
|
||||||
|
FIRST,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Null is always ordered last.
|
||||||
|
*/
|
||||||
|
LAST;
|
||||||
|
}
|
|
@ -15,17 +15,53 @@ public enum NullPrecedence {
|
||||||
/**
|
/**
|
||||||
* Null precedence not specified. Relies on the RDBMS implementation.
|
* Null precedence not specified. Relies on the RDBMS implementation.
|
||||||
*/
|
*/
|
||||||
NONE,
|
NONE {
|
||||||
|
@Override
|
||||||
|
public boolean isDefaultOrdering(SortOrder sortOrder, NullOrdering nullOrdering) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Null values appear at the beginning of the sorted collection.
|
* Null values appear at the beginning of the sorted collection.
|
||||||
*/
|
*/
|
||||||
FIRST,
|
FIRST {
|
||||||
|
@Override
|
||||||
|
public boolean isDefaultOrdering(SortOrder sortOrder, NullOrdering nullOrdering) {
|
||||||
|
switch ( nullOrdering ) {
|
||||||
|
case FIRST:
|
||||||
|
return true;
|
||||||
|
case SMALLEST:
|
||||||
|
return sortOrder == SortOrder.ASCENDING;
|
||||||
|
case GREATEST:
|
||||||
|
return sortOrder == SortOrder.DESCENDING;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Null values appear at the end of the sorted collection.
|
* Null values appear at the end of the sorted collection.
|
||||||
*/
|
*/
|
||||||
LAST;
|
LAST {
|
||||||
|
@Override
|
||||||
|
public boolean isDefaultOrdering(SortOrder sortOrder, NullOrdering nullOrdering) {
|
||||||
|
switch ( nullOrdering ) {
|
||||||
|
case LAST:
|
||||||
|
return true;
|
||||||
|
case SMALLEST:
|
||||||
|
return sortOrder == SortOrder.DESCENDING;
|
||||||
|
case GREATEST:
|
||||||
|
return sortOrder == SortOrder.ASCENDING;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this null precedence the default for the given sort order and null ordering.
|
||||||
|
*/
|
||||||
|
public abstract boolean isDefaultOrdering(SortOrder sortOrder, NullOrdering nullOrdering);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interprets a string representation of a NullPrecedence, returning {@code null} by default. For
|
* Interprets a string representation of a NullPrecedence, returning {@code null} by default. For
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The SQL set operators.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public enum SetOperator {
|
||||||
|
/**
|
||||||
|
* Union of sets that removes duplicate rows.
|
||||||
|
*/
|
||||||
|
UNION("union"),
|
||||||
|
/**
|
||||||
|
* Union of bags that retains all elements.
|
||||||
|
*/
|
||||||
|
UNION_ALL("union all"),
|
||||||
|
/**
|
||||||
|
* Intersection of sets that removes duplicate rows.
|
||||||
|
*/
|
||||||
|
INTERSECT("intersect"),
|
||||||
|
/**
|
||||||
|
* Intersection of bags that retains duplicate matches.
|
||||||
|
*/
|
||||||
|
INTERSECT_ALL("intersect all"),
|
||||||
|
/**
|
||||||
|
* Exclusion of set elements of the set on the right-hand side.
|
||||||
|
*/
|
||||||
|
EXCEPT("except"),
|
||||||
|
/**
|
||||||
|
* Exclusion of bag elements of the bag on the right-hand side that retains duplicates.
|
||||||
|
*/
|
||||||
|
EXCEPT_ALL("except all");
|
||||||
|
|
||||||
|
private final String sqlString;
|
||||||
|
|
||||||
|
private SetOperator(String sqlString) {
|
||||||
|
this.sqlString = sqlString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String sqlString() {
|
||||||
|
return sqlString;
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ import org.hibernate.engine.config.spi.StandardConverters;
|
||||||
import org.hibernate.engine.jdbc.*;
|
import org.hibernate.engine.jdbc.*;
|
||||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
import org.hibernate.engine.jdbc.env.spi.*;
|
import org.hibernate.engine.jdbc.env.spi.*;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.exception.ConstraintViolationException;
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
import org.hibernate.exception.LockAcquisitionException;
|
import org.hibernate.exception.LockAcquisitionException;
|
||||||
import org.hibernate.exception.LockTimeoutException;
|
import org.hibernate.exception.LockTimeoutException;
|
||||||
|
@ -39,6 +40,10 @@ import org.hibernate.procedure.spi.CallableStatementSupport;
|
||||||
import org.hibernate.query.TemporalUnit;
|
import org.hibernate.query.TemporalUnit;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHANADatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHANADatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
import org.hibernate.tool.schema.internal.StandardTableExporter;
|
import org.hibernate.tool.schema.internal.StandardTableExporter;
|
||||||
|
@ -821,6 +826,17 @@ public abstract class AbstractHANADialect extends Dialect {
|
||||||
CommonFunctionFactory.currentUtcdatetimetimestamp( queryEngine );
|
CommonFunctionFactory.currentUtcdatetimetimestamp( queryEngine );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, org.hibernate.sql.ast.tree.Statement statement) {
|
||||||
|
return new HANASqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HANA has no extract() function, but we can emulate
|
* HANA has no extract() function, but we can emulate
|
||||||
* it using the appropriate named functions instead of
|
* it using the appropriate named functions instead of
|
||||||
|
@ -1158,11 +1174,6 @@ public abstract class AbstractHANADialect extends Dialect {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsUnionAll() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean dropConstraints() {
|
public boolean dropConstraints() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
|
import org.hibernate.NullOrdering;
|
||||||
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||||
|
@ -223,6 +224,11 @@ abstract class AbstractTransactSQLDialect extends Dialect {
|
||||||
return GroupByConstantRenderingStrategy.COLUMN_REFERENCE;
|
return GroupByConstantRenderingStrategy.COLUMN_REFERENCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NullOrdering getNullOrdering() {
|
||||||
|
return NullOrdering.SMALLEST;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
|
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
|
||||||
EntityMappingType entityDescriptor,
|
EntityMappingType entityDescriptor,
|
||||||
|
@ -254,11 +260,6 @@ abstract class AbstractTransactSQLDialect extends Dialect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsUnionAll() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsExistsInSelect() {
|
public boolean supportsExistsInSelect() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -16,9 +16,15 @@ import org.hibernate.dialect.pagination.LimitLimitHandler;
|
||||||
import org.hibernate.dialect.sequence.CUBRIDSequenceSupport;
|
import org.hibernate.dialect.sequence.CUBRIDSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.engine.jdbc.Size;
|
import org.hibernate.engine.jdbc.Size;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.SemanticException;
|
import org.hibernate.query.SemanticException;
|
||||||
import org.hibernate.query.TemporalUnit;
|
import org.hibernate.query.TemporalUnit;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorCUBRIDDatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorCUBRIDDatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
|
|
||||||
|
@ -238,11 +244,6 @@ public class CUBRIDDialect extends Dialect {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsUnionAll() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsCurrentTimestampSelection() {
|
public boolean supportsCurrentTimestampSelection() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -273,6 +274,17 @@ public class CUBRIDDialect extends Dialect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new CUBRIDSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LimitHandler getLimitHandler() {
|
public LimitHandler getLimitHandler() {
|
||||||
return LimitLimitHandler.INSTANCE;
|
return LimitLimitHandler.INSTANCE;
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for CUBRID.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class CUBRIDSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public CUBRIDSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
renderCombinedLimitClause( queryPart );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// CUBRID does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// CUBRID does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ import org.hibernate.dialect.pagination.LimitHandler;
|
||||||
import org.hibernate.dialect.pagination.TopLimitHandler;
|
import org.hibernate.dialect.pagination.TopLimitHandler;
|
||||||
import org.hibernate.dialect.sequence.CacheSequenceSupport;
|
import org.hibernate.dialect.sequence.CacheSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.exception.ConstraintViolationException;
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
import org.hibernate.exception.DataException;
|
import org.hibernate.exception.DataException;
|
||||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||||
|
@ -27,6 +28,11 @@ import org.hibernate.query.TemporalUnit;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
import org.hibernate.sql.CacheJoinFragment;
|
import org.hibernate.sql.CacheJoinFragment;
|
||||||
import org.hibernate.sql.JoinFragment;
|
import org.hibernate.sql.JoinFragment;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
|
||||||
import java.sql.CallableStatement;
|
import java.sql.CallableStatement;
|
||||||
|
@ -277,6 +283,17 @@ public class CacheDialect extends Dialect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new CacheSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// LIMIT support (ala TOP) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// LIMIT support (ala TOP) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.ast.tree.select.SelectClause;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Cache.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class CacheSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public CacheSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needsRowsToSkip() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitSqlSelections(SelectClause selectClause) {
|
||||||
|
renderTopClause( (QuerySpec) getQueryPartStack().getCurrent(), true );
|
||||||
|
super.visitSqlSelections( selectClause );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderTopClause(QuerySpec querySpec, boolean addOffset) {
|
||||||
|
assertRowsOnlyFetchClauseType( querySpec );
|
||||||
|
super.renderTopClause( querySpec, addOffset );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderFetchPlusOffsetExpression(
|
||||||
|
Expression fetchClauseExpression,
|
||||||
|
Expression offsetClauseExpression,
|
||||||
|
int offset) {
|
||||||
|
renderFetchPlusOffsetExpressionAsSingleParameter( fetchClauseExpression, offsetClauseExpression, offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
// Cache only supports the TOP clause
|
||||||
|
if ( !queryPart.isRoot() && queryPart.getOffsetClauseExpression() != null ) {
|
||||||
|
throw new IllegalArgumentException( "Can't emulate offset clause in subquery" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// Cache does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// Cache does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,8 +12,14 @@ import org.hibernate.dialect.pagination.OffsetFetchLimitHandler;
|
||||||
import org.hibernate.dialect.sequence.PostgreSQLSequenceSupport;
|
import org.hibernate.dialect.sequence.PostgreSQLSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.TemporalUnit;
|
import org.hibernate.query.TemporalUnit;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
@ -169,11 +175,6 @@ public class CockroachDialect extends Dialect {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsUnionAll() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getNoColumnsInsertString() {
|
public String getNoColumnsInsertString() {
|
||||||
return "default values";
|
return "default values";
|
||||||
|
@ -209,6 +210,17 @@ public class CockroachDialect extends Dialect {
|
||||||
return "select sequence_name, sequence_schema, sequence_catalog, start_value, minimum_value, maximum_value, increment from information_schema.sequences";
|
return "select sequence_name, sequence_schema, sequence_catalog, start_value, minimum_value, maximum_value, increment from information_schema.sequences";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new CockroachSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsNationalizedTypes() {
|
public boolean supportsNationalizedTypes() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.FetchClauseType;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Cockroach.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class CockroachSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public CockroachSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
|
||||||
|
// Check if current query part is already row numbering to avoid infinite recursion
|
||||||
|
return useOffsetFetchClause( queryPart ) && getQueryPartForRowNumbering() != queryPart
|
||||||
|
&& !isRowsOnlyFetchClauseType( queryPart );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQueryGroup(QueryGroup queryGroup) {
|
||||||
|
if ( shouldEmulateFetchClause( queryGroup ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( queryGroup, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQueryGroup( queryGroup );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQuerySpec(QuerySpec querySpec) {
|
||||||
|
if ( shouldEmulateFetchClause( querySpec ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( querySpec, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQuerySpec( querySpec );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( !isRowNumberingCurrentQueryPart() ) {
|
||||||
|
renderLimitOffsetClause( queryPart );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// Cockroach does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// Cockroach does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.dialect.unique.DB2UniqueDelegate;
|
import org.hibernate.dialect.unique.DB2UniqueDelegate;
|
||||||
import org.hibernate.dialect.unique.UniqueDelegate;
|
import org.hibernate.dialect.unique.UniqueDelegate;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.exception.LockTimeoutException;
|
import org.hibernate.exception.LockTimeoutException;
|
||||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||||
|
@ -30,11 +31,13 @@ import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
import org.hibernate.query.CastType;
|
import org.hibernate.query.CastType;
|
||||||
import org.hibernate.query.TemporalUnit;
|
import org.hibernate.query.TemporalUnit;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.AfterUseAction;
|
import org.hibernate.query.sqm.mutation.internal.cte.CteStrategy;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.GlobalTemporaryTableStrategy;
|
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
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.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorDB2DatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorDB2DatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
|
@ -407,11 +410,6 @@ public class DB2Dialect extends Dialect {
|
||||||
return "nullif(" + literal + ", " + literal + ')';
|
return "nullif(" + literal + ", " + literal + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsUnionAll() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
|
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
|
||||||
return col;
|
return col;
|
||||||
|
@ -437,47 +435,7 @@ public class DB2Dialect extends Dialect {
|
||||||
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
|
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
|
||||||
EntityMappingType rootEntityDescriptor,
|
EntityMappingType rootEntityDescriptor,
|
||||||
RuntimeModelCreationContext runtimeModelCreationContext) {
|
RuntimeModelCreationContext runtimeModelCreationContext) {
|
||||||
|
return new CteStrategy( rootEntityDescriptor, runtimeModelCreationContext );
|
||||||
if ( getVersion() >= 970 ) {
|
|
||||||
// Starting in DB2 9.7, "real" global temporary tables that can be shared between sessions
|
|
||||||
// are supported; (obviously) data is not shared between sessions.
|
|
||||||
return new GlobalTemporaryTableStrategy(
|
|
||||||
new IdTable( rootEntityDescriptor, name -> "HT_" + name, this ),
|
|
||||||
() -> new TempIdTableExporter( false, this::getTypeName ) {
|
|
||||||
@Override
|
|
||||||
protected String getCreateOptions() {
|
|
||||||
return "not logged";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
AfterUseAction.CLEAN,
|
|
||||||
runtimeModelCreationContext.getSessionFactory()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.getFallbackSqmMutationStrategy( rootEntityDescriptor, runtimeModelCreationContext );
|
|
||||||
// // Prior to DB2 9.7, "real" global temporary tables that can be shared between sessions
|
|
||||||
// // are *not* supported; even though the DB2 command says to declare a "global" temp table
|
|
||||||
// // Hibernate treats it as a "local" temp table.
|
|
||||||
// return new LocalTemporaryTableBulkIdStrategy(
|
|
||||||
// new IdTableSupportStandardImpl() {
|
|
||||||
// @Override
|
|
||||||
// public String generateIdTableName(String baseName) {
|
|
||||||
// return "session." + super.generateIdTableName( baseName );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public String getCreateIdTableCommand() {
|
|
||||||
// return "declare global temporary table";
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public String getCreateIdTableStatementOptions() {
|
|
||||||
// return "not logged";
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// AfterUseAction.DROP,
|
|
||||||
// null
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -639,6 +597,17 @@ public class DB2Dialect extends Dialect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new DB2SqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle DB2 "support" for null precedence...
|
* Handle DB2 "support" for null precedence...
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.FetchClauseType;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.MutationStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.delete.DeleteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Literal;
|
||||||
|
import org.hibernate.sql.ast.tree.insert.InsertStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.ast.tree.update.UpdateStatement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for DB2.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class DB2SqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public DB2SqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
|
||||||
|
// Percent fetches or ties fetches aren't supported in DB2
|
||||||
|
// According to LegacyDB2LimitHandler, variable limit also isn't supported before 11.1
|
||||||
|
// Check if current query part is already row numbering to avoid infinite recursion
|
||||||
|
return getQueryPartForRowNumbering() != queryPart && (
|
||||||
|
useOffsetFetchClause( queryPart ) && !isRowsOnlyFetchClauseType( queryPart )
|
||||||
|
|| getDialect().getVersion() < 1110 && ( queryPart.isRoot() && hasLimit() || !( queryPart.getFetchClauseExpression() instanceof Literal ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean supportsOffsetClause() {
|
||||||
|
return getDialect().getVersion() >= 1110;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQueryGroup(QueryGroup queryGroup) {
|
||||||
|
final boolean emulateFetchClause = shouldEmulateFetchClause( queryGroup );
|
||||||
|
if ( emulateFetchClause || hasOffset( queryGroup ) && !supportsOffsetClause() ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( queryGroup, emulateFetchClause );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQueryGroup( queryGroup );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQuerySpec(QuerySpec querySpec) {
|
||||||
|
final boolean emulateFetchClause = shouldEmulateFetchClause( querySpec );
|
||||||
|
if ( emulateFetchClause || hasOffset( querySpec ) && !supportsOffsetClause() ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( querySpec, emulateFetchClause );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQuerySpec( querySpec );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( !isRowNumberingCurrentQueryPart() ) {
|
||||||
|
if ( !hasOffset( queryPart ) || supportsOffsetClause() ) {
|
||||||
|
renderOffsetFetchClause( queryPart, true );
|
||||||
|
}
|
||||||
|
else if ( queryPart.isRoot() && hasLimit() ) {
|
||||||
|
renderFetch( getLimitParameter(), null, FetchClauseType.ROWS_ONLY );
|
||||||
|
}
|
||||||
|
else if ( queryPart.getFetchClauseExpression() != null ) {
|
||||||
|
renderFetch( queryPart.getFetchClauseExpression(), null, queryPart.getFetchClauseType() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitDeleteStatementOnly(DeleteStatement statement) {
|
||||||
|
final boolean closeWrapper = renderReturningClause( statement );
|
||||||
|
super.visitDeleteStatementOnly( statement );
|
||||||
|
if ( closeWrapper ) {
|
||||||
|
appendSql( ')' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitUpdateStatementOnly(UpdateStatement statement) {
|
||||||
|
final boolean closeWrapper = renderReturningClause( statement );
|
||||||
|
super.visitUpdateStatementOnly( statement );
|
||||||
|
if ( closeWrapper ) {
|
||||||
|
appendSql( ')' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitInsertStatementOnly(InsertStatement statement) {
|
||||||
|
final boolean closeWrapper = renderReturningClause( statement );
|
||||||
|
super.visitInsertStatementOnly( statement );
|
||||||
|
if ( closeWrapper ) {
|
||||||
|
appendSql( ')' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean renderReturningClause(MutationStatement statement) {
|
||||||
|
final List<ColumnReference> returningColumns = statement.getReturningColumns();
|
||||||
|
final int size = returningColumns.size();
|
||||||
|
if ( size == 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
appendSql( "select " );
|
||||||
|
String separator = "";
|
||||||
|
for ( int i = 0; i < size; i++ ) {
|
||||||
|
appendSql( separator );
|
||||||
|
appendSql( returningColumns.get( i ).getColumnExpression() );
|
||||||
|
separator = ", ";
|
||||||
|
}
|
||||||
|
if ( statement instanceof DeleteStatement ) {
|
||||||
|
appendSql( " from old table (" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appendSql( " from final table (" );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitReturningColumns(MutationStatement mutationStatement) {
|
||||||
|
// For DB2 we use #renderReturningClause to render a wrapper around the DML statement
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -15,10 +15,15 @@ import org.hibernate.dialect.pagination.LimitHandler;
|
||||||
import org.hibernate.dialect.sequence.DB2iSequenceSupport;
|
import org.hibernate.dialect.sequence.DB2iSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.NoSequenceSupport;
|
import org.hibernate.dialect.sequence.NoSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.dialect.unique.DB2UniqueDelegate;
|
|
||||||
import org.hibernate.dialect.unique.DefaultUniqueDelegate;
|
import org.hibernate.dialect.unique.DefaultUniqueDelegate;
|
||||||
import org.hibernate.dialect.unique.UniqueDelegate;
|
import org.hibernate.dialect.unique.UniqueDelegate;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An SQL dialect for DB2 for iSeries previously known as DB2/400.
|
* An SQL dialect for DB2 for iSeries previously known as DB2/400.
|
||||||
|
@ -90,10 +95,10 @@ public class DB2iDialect extends DB2Dialect {
|
||||||
@Override
|
@Override
|
||||||
public LimitHandler getLimitHandler() {
|
public LimitHandler getLimitHandler() {
|
||||||
if ( getIVersion() >= 730) {
|
if ( getIVersion() >= 730) {
|
||||||
return LegacyDB2LimitHandler.INSTANCE;
|
return FetchLimitHandler.INSTANCE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return FetchLimitHandler.INSTANCE;
|
return LegacyDB2LimitHandler.INSTANCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,4 +111,15 @@ public class DB2iDialect extends DB2Dialect {
|
||||||
return new DB2390IdentityColumnSupport();
|
return new DB2390IdentityColumnSupport();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new DB2iSqlAstTranslator<>( sessionFactory, statement, version );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.FetchClauseType;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Literal;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for DB2i.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class DB2iSqlAstTranslator<T extends JdbcOperation> extends DB2SqlAstTranslator<T> {
|
||||||
|
|
||||||
|
private final int version;
|
||||||
|
|
||||||
|
public DB2iSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, int version) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
|
||||||
|
// Percent fetches or ties fetches aren't supported in DB2 iSeries
|
||||||
|
// According to LegacyDB2LimitHandler, variable limit also isn't supported before 7.1
|
||||||
|
return getQueryPartForRowNumbering() != queryPart && (
|
||||||
|
useOffsetFetchClause( queryPart ) && !isRowsOnlyFetchClauseType( queryPart )
|
||||||
|
|| version < 710 && ( queryPart.isRoot() && hasLimit() || !( queryPart.getFetchClauseExpression() instanceof Literal ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean supportsOffsetClause() {
|
||||||
|
return version >= 710;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -18,7 +18,13 @@ import org.hibernate.dialect.sequence.DB2390SequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.NoSequenceSupport;
|
import org.hibernate.dialect.sequence.NoSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.TemporalUnit;
|
import org.hibernate.query.TemporalUnit;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An SQL dialect for DB2 for z/OS, previously known as known as Db2 UDB for z/OS and Db2 UDB for z/OS and OS/390.
|
* An SQL dialect for DB2 for z/OS, previously known as known as Db2 UDB for z/OS and Db2 UDB for z/OS and OS/390.
|
||||||
|
@ -128,4 +134,15 @@ public class DB2zDialect extends DB2Dialect {
|
||||||
pattern.append(")");
|
pattern.append(")");
|
||||||
return pattern.toString();
|
return pattern.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new DB2zSqlAstTranslator<>( sessionFactory, statement, version );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.FetchClauseType;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Literal;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for DB2z.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class DB2zSqlAstTranslator<T extends JdbcOperation> extends DB2SqlAstTranslator<T> {
|
||||||
|
|
||||||
|
private final int version;
|
||||||
|
|
||||||
|
public DB2zSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement, int version) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
|
||||||
|
// Percent fetches or ties fetches aren't supported in DB2 z/OS
|
||||||
|
// Also, variable limit isn't supported before 12.0
|
||||||
|
return getQueryPartForRowNumbering() != queryPart && (
|
||||||
|
useOffsetFetchClause( queryPart ) && !isRowsOnlyFetchClauseType( queryPart )
|
||||||
|
|| version < 1200 && queryPart.isRoot() && hasLimit()
|
||||||
|
|| version < 1200 && queryPart.getFetchClauseExpression() != null && !( queryPart.getFetchClauseExpression() instanceof Literal )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean supportsOffsetClause() {
|
||||||
|
return version >= 1200;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ import org.hibernate.engine.jdbc.Size;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
|
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.exception.LockTimeoutException;
|
import org.hibernate.exception.LockTimeoutException;
|
||||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||||
|
@ -39,6 +40,11 @@ import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||||
import org.hibernate.sql.CaseFragment;
|
import org.hibernate.sql.CaseFragment;
|
||||||
import org.hibernate.sql.DerbyCaseFragment;
|
import org.hibernate.sql.DerbyCaseFragment;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorDerbyDatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorDerbyDatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
|
@ -202,6 +208,17 @@ public class DerbyDialect extends Dialect {
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new DerbySqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Derby doesn't have an extract() function, and has
|
* Derby doesn't have an extract() function, and has
|
||||||
* no functions at all for calendaring, but we can
|
* no functions at all for calendaring, but we can
|
||||||
|
@ -410,11 +427,6 @@ public class DerbyDialect extends Dialect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsUnionAll() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsCurrentTimestampSelection() {
|
public boolean supportsCurrentTimestampSelection() {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.FetchClauseType;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteContainer;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Derby.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class DerbySqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public DerbySqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitCteContainer(CteContainer cteContainer) {
|
||||||
|
if ( cteContainer.isWithRecursive() ) {
|
||||||
|
throw new IllegalArgumentException( "Recursive CTEs can't be emulated" );
|
||||||
|
}
|
||||||
|
super.visitCteContainer( cteContainer );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// Derby does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// Derby does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
// Derby only supports the OFFSET and FETCH clause with ROWS
|
||||||
|
assertRowsOnlyFetchClauseType( queryPart );
|
||||||
|
if ( supportsOffsetFetchClause() ) {
|
||||||
|
renderOffsetFetchClause( queryPart, true );
|
||||||
|
}
|
||||||
|
else if ( !getClauseStack().isEmpty() ) {
|
||||||
|
throw new IllegalArgumentException( "Can't render offset and fetch clause for subquery" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderFetchExpression(Expression fetchExpression) {
|
||||||
|
if ( supportsParameterOffsetFetchExpression() ) {
|
||||||
|
super.renderFetchExpression( fetchExpression );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderExpressionAsLiteral( fetchExpression, getJdbcParameterBindings() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderOffsetExpression(Expression offsetExpression) {
|
||||||
|
if ( supportsParameterOffsetFetchExpression() ) {
|
||||||
|
super.renderOffsetExpression( offsetExpression );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderExpressionAsLiteral( offsetExpression, getJdbcParameterBindings() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needsRowsToSkip() {
|
||||||
|
return !supportsOffsetFetchClause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needsMaxRows() {
|
||||||
|
return !supportsOffsetFetchClause();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsParameterOffsetFetchExpression() {
|
||||||
|
return getDialect().getVersion() >= 1060;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsOffsetFetchClause() {
|
||||||
|
// Before version 10.5 Derby didn't support OFFSET and FETCH
|
||||||
|
return getDialect().getVersion() >= 1050;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ import org.hibernate.LockMode;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
|
import org.hibernate.NullOrdering;
|
||||||
import org.hibernate.NullPrecedence;
|
import org.hibernate.NullPrecedence;
|
||||||
import org.hibernate.ScrollMode;
|
import org.hibernate.ScrollMode;
|
||||||
import org.hibernate.boot.model.TypeContributions;
|
import org.hibernate.boot.model.TypeContributions;
|
||||||
|
@ -1877,16 +1878,14 @@ public abstract class Dialect implements ConversionContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does this dialect support UNION ALL, which is generally a faster
|
* Does this dialect support UNION ALL.
|
||||||
* variant of UNION?
|
|
||||||
*
|
*
|
||||||
* @return True if UNION ALL is supported; false otherwise.
|
* @return True if UNION ALL is supported; false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean supportsUnionAll() {
|
public boolean supportsUnionAll() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// miscellaneous support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// miscellaneous support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
@ -2690,6 +2689,15 @@ public abstract class Dialect implements ConversionContext {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ordering of null.
|
||||||
|
*
|
||||||
|
* @since 6.0.0
|
||||||
|
*/
|
||||||
|
public NullOrdering getNullOrdering() {
|
||||||
|
return NullOrdering.GREATEST;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean supportsNullPrecedence() {
|
public boolean supportsNullPrecedence() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2705,7 +2713,9 @@ public abstract class Dialect implements ConversionContext {
|
||||||
* if expression has not been explicitly specified.
|
* if expression has not been explicitly specified.
|
||||||
* @param nulls Nulls precedence. Default value: {@link NullPrecedence#NONE}.
|
* @param nulls Nulls precedence. Default value: {@link NullPrecedence#NONE}.
|
||||||
* @return Renders single element of {@code ORDER BY} clause.
|
* @return Renders single element of {@code ORDER BY} clause.
|
||||||
|
* @deprecated todo (6.0): remove?
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public String renderOrderByElement(String expression, String collation, String order, NullPrecedence nulls) {
|
public String renderOrderByElement(String expression, String collation, String order, NullPrecedence nulls) {
|
||||||
final StringBuilder orderByElement = new StringBuilder( expression );
|
final StringBuilder orderByElement = new StringBuilder( expression );
|
||||||
if ( collation != null ) {
|
if ( collation != null ) {
|
||||||
|
@ -2980,7 +2990,9 @@ public abstract class Dialect implements ConversionContext {
|
||||||
* @param expression The expression to negate
|
* @param expression The expression to negate
|
||||||
*
|
*
|
||||||
* @return The negated expression
|
* @return The negated expression
|
||||||
|
* @deprecated todo (6.0): Remove
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public String getNotExpression(String expression) {
|
public String getNotExpression(String expression) {
|
||||||
return "not " + expression;
|
return "not " + expression;
|
||||||
}
|
}
|
||||||
|
@ -3215,14 +3227,6 @@ public abstract class Dialect implements ConversionContext {
|
||||||
return String.format( "\'%s\'", escapeLiteral( literal ) );
|
return String.format( "\'%s\'", escapeLiteral( literal ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Appends the collate clause for the given collation name to the SQL appender.
|
|
||||||
*/
|
|
||||||
public void appendCollate(SqlAppender sqlAppender, String collationName) {
|
|
||||||
sqlAppender.appendSql( " collate " );
|
|
||||||
sqlAppender.appendSql( collationName );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the JDBC {@link java.sql.Connection} supports creating LOBs via {@link Connection#createBlob()},
|
* Check whether the JDBC {@link java.sql.Connection} supports creating LOBs via {@link Connection#createBlob()},
|
||||||
* {@link Connection#createNClob()} or {@link Connection#createClob()}.
|
* {@link Connection#createNClob()} or {@link Connection#createClob()}.
|
||||||
|
@ -3249,17 +3253,16 @@ public abstract class Dialect implements ConversionContext {
|
||||||
*/
|
*/
|
||||||
public String addSqlHintOrComment(
|
public String addSqlHintOrComment(
|
||||||
String sql,
|
String sql,
|
||||||
// QueryParameters parameters,
|
QueryOptions queryOptions,
|
||||||
boolean commentsEnabled) {
|
boolean commentsEnabled) {
|
||||||
|
|
||||||
// Keep this here, rather than moving to Select. Some Dialects may need the hint to be appended to the very
|
// Keep this here, rather than moving to Select. Some Dialects may need the hint to be appended to the very
|
||||||
// end or beginning of the finalized SQL statement, so wait until everything is processed.
|
// end or beginning of the finalized SQL statement, so wait until everything is processed.
|
||||||
// if ( parameters.getQueryHints() != null && parameters.getQueryHints().size() > 0 ) {
|
if ( queryOptions.getDatabaseHints() != null && queryOptions.getDatabaseHints().size() > 0 ) {
|
||||||
// sql = getQueryHintString( sql, parameters.getQueryHints() );
|
sql = getQueryHintString( sql, queryOptions.getDatabaseHints() );
|
||||||
// }
|
}
|
||||||
// if ( commentsEnabled && parameters.getComment() != null ){
|
if ( commentsEnabled && queryOptions.getComment() != null ) {
|
||||||
// sql = prependComment( sql, parameters.getComment() );
|
sql = prependComment( sql, queryOptions.getComment() );
|
||||||
// }
|
}
|
||||||
|
|
||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
@ -3296,7 +3299,7 @@ public abstract class Dialect implements ConversionContext {
|
||||||
* Note that {@link SessionFactoryOptions#getCustomSqmTranslatorFactory()} has higher
|
* Note that {@link SessionFactoryOptions#getCustomSqmTranslatorFactory()} has higher
|
||||||
* precedence as it comes directly from the user config
|
* precedence as it comes directly from the user config
|
||||||
*
|
*
|
||||||
* @see org.hibernate.query.sqm.sql.internal.StandardSqmSelectTranslator
|
* @see org.hibernate.query.sqm.sql.internal.StandardSqmTranslator
|
||||||
* @see QueryEngine#getSqmTranslatorFactory()
|
* @see QueryEngine#getSqmTranslatorFactory()
|
||||||
*/
|
*/
|
||||||
public SqmTranslatorFactory getSqmTranslatorFactory() {
|
public SqmTranslatorFactory getSqmTranslatorFactory() {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.hibernate.engine.jdbc.Size;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
|
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.exception.ConstraintViolationException;
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
import org.hibernate.exception.LockAcquisitionException;
|
import org.hibernate.exception.LockAcquisitionException;
|
||||||
import org.hibernate.exception.LockTimeoutException;
|
import org.hibernate.exception.LockTimeoutException;
|
||||||
|
@ -38,6 +39,11 @@ import org.hibernate.query.sqm.mutation.internal.idtable.GlobalTemporaryTableStr
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
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.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorFirebirdDatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorFirebirdDatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceNameExtractorImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceNameExtractorImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
|
@ -196,6 +202,17 @@ public class FirebirdDialect extends Dialect {
|
||||||
).setArgumentListSignature("(pattern, string[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new FirebirdSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Firebird 2.5 doesn't have a real {@link java.sql.Types#BOOLEAN}
|
* Firebird 2.5 doesn't have a real {@link java.sql.Types#BOOLEAN}
|
||||||
* type, so...
|
* type, so...
|
||||||
|
@ -289,11 +306,6 @@ public class FirebirdDialect extends Dialect {
|
||||||
return "add";
|
return "add";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsUnionAll() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getNoColumnsInsertString() {
|
public String getNoColumnsInsertString() {
|
||||||
return "default values";
|
return "default values";
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.internal.util.collections.Stack;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.ast.tree.select.SelectClause;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Firebird.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class FirebirdSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public FirebirdSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
|
||||||
|
// Percent fetches or ties fetches aren't supported in Firebird
|
||||||
|
// Before 3.0 there was also no support for window functions
|
||||||
|
// Check if current query part is already row numbering to avoid infinite recursion
|
||||||
|
return useOffsetFetchClause( queryPart ) && getQueryPartForRowNumbering() != queryPart
|
||||||
|
&& getDialect().getVersion() >= 300 && !isRowsOnlyFetchClauseType( queryPart );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQueryGroup(QueryGroup queryGroup) {
|
||||||
|
if ( shouldEmulateFetchClause( queryGroup ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( queryGroup, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQueryGroup( queryGroup );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQuerySpec(QuerySpec querySpec) {
|
||||||
|
if ( shouldEmulateFetchClause( querySpec ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( querySpec, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQuerySpec( querySpec );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSelectClause(SelectClause selectClause) {
|
||||||
|
Stack<Clause> clauseStack = getClauseStack();
|
||||||
|
clauseStack.push( Clause.SELECT );
|
||||||
|
|
||||||
|
try {
|
||||||
|
appendSql( "select " );
|
||||||
|
visitSqlSelections( selectClause );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
clauseStack.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitSqlSelections(SelectClause selectClause) {
|
||||||
|
if ( !supportsOffsetFetchClause() ) {
|
||||||
|
renderFirstSkipClause( (QuerySpec) getQueryPartStack().getCurrent() );
|
||||||
|
}
|
||||||
|
if ( selectClause.isDistinct() ) {
|
||||||
|
appendSql( "distinct " );
|
||||||
|
}
|
||||||
|
super.visitSqlSelections( selectClause );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( supportsOffsetFetchClause() ) {
|
||||||
|
// Firebird only supports a FIRST and SKIP clause before 3.0 which is handled in visitSqlSelections
|
||||||
|
if ( !isRowNumberingCurrentQueryPart() ) {
|
||||||
|
renderOffsetFetchClause( queryPart, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// Firebird does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// Firebird does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsOffsetFetchClause() {
|
||||||
|
return getDialect().getVersion() >= 300;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ import java.sql.Types;
|
||||||
|
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
import org.hibernate.NullOrdering;
|
||||||
import org.hibernate.PessimisticLockException;
|
import org.hibernate.PessimisticLockException;
|
||||||
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
@ -23,6 +24,7 @@ import org.hibernate.dialect.pagination.OffsetFetchLimitHandler;
|
||||||
import org.hibernate.dialect.sequence.H2SequenceSupport;
|
import org.hibernate.dialect.sequence.H2SequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.exception.ConstraintViolationException;
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
import org.hibernate.exception.LockAcquisitionException;
|
import org.hibernate.exception.LockAcquisitionException;
|
||||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||||
|
@ -38,6 +40,11 @@ import org.hibernate.query.sqm.mutation.internal.idtable.AfterUseAction;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.LocalTemporaryTableStrategy;
|
import org.hibernate.query.sqm.mutation.internal.idtable.LocalTemporaryTableStrategy;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
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.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorH2DatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorH2DatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
|
||||||
|
@ -72,31 +79,35 @@ public class H2Dialect extends Dialect {
|
||||||
}
|
}
|
||||||
|
|
||||||
public H2Dialect(int version, int buildId) {
|
public H2Dialect(int version, int buildId) {
|
||||||
|
this(version + buildId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public H2Dialect(int version) {
|
||||||
super();
|
super();
|
||||||
this.version = version;
|
this.version = version;
|
||||||
//TODO: actually I think all builds of 1.4 support OFFSET FETCH
|
// https://github.com/h2database/h2database/commit/b2cdf84e0b84eb8a482fa7dccdccc1ab95241440
|
||||||
limitHandler = version > 140 || version == 140 && buildId >= 199
|
limitHandler = version >= 104195
|
||||||
? OffsetFetchLimitHandler.INSTANCE
|
? OffsetFetchLimitHandler.INSTANCE
|
||||||
: LimitOffsetLimitHandler.INSTANCE;
|
: LimitOffsetLimitHandler.INSTANCE;
|
||||||
|
|
||||||
//Note: H2 'bit' is a synonym for 'boolean', not a proper bit type
|
//Note: H2 'bit' is a synonym for 'boolean', not a proper bit type
|
||||||
// registerColumnType( Types.BIT, "bit" );
|
// registerColumnType( Types.BIT, "bit" );
|
||||||
final int majorVersion = version / 100;
|
if ( version < 102139 ) {
|
||||||
final int minorVersion = version % 100 / 10;
|
final int majorVersion = version / 100000;
|
||||||
if ( version < 120 || version == 120 && buildId < 139 ) {
|
final int minorVersion = version % 100000 / 1000;
|
||||||
|
final int buildId = version % 1000;
|
||||||
LOG.unsupportedMultiTableBulkHqlJpaql( majorVersion, minorVersion, buildId );
|
LOG.unsupportedMultiTableBulkHqlJpaql( majorVersion, minorVersion, buildId );
|
||||||
}
|
}
|
||||||
supportsTuplesInSubqueries = majorVersion > 1 || minorVersion > 4 || buildId >= 198;
|
supportsTuplesInSubqueries = version >= 104198;
|
||||||
// Prior to 1.4.200 the 'cascade' in 'drop table' was implicit
|
// Prior to 1.4.200 the 'cascade' in 'drop table' was implicit
|
||||||
cascadeConstraints = version > 140 || version == 140 && buildId >= 200;
|
cascadeConstraints = version >= 104200;
|
||||||
|
|
||||||
getDefaultProperties().setProperty( AvailableSettings.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
|
getDefaultProperties().setProperty( AvailableSettings.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
|
||||||
// http://code.google.com/p/h2database/issues/detail?id=235
|
// http://code.google.com/p/h2database/issues/detail?id=235
|
||||||
getDefaultProperties().setProperty( AvailableSettings.NON_CONTEXTUAL_LOB_CREATION, "true" );
|
getDefaultProperties().setProperty( AvailableSettings.NON_CONTEXTUAL_LOB_CREATION, "true" );
|
||||||
|
|
||||||
if ( buildId >= 32 ) {
|
if ( version >= 104032 ) {
|
||||||
this.sequenceInformationExtractor = buildId >= 201
|
this.sequenceInformationExtractor = version >= 104201
|
||||||
? SequenceInformationExtractorLegacyImpl.INSTANCE
|
? SequenceInformationExtractorLegacyImpl.INSTANCE
|
||||||
: SequenceInformationExtractorH2DatabaseImpl.INSTANCE;
|
: SequenceInformationExtractorH2DatabaseImpl.INSTANCE;
|
||||||
this.querySequenceString = "select * from INFORMATION_SCHEMA.SEQUENCES";
|
this.querySequenceString = "select * from INFORMATION_SCHEMA.SEQUENCES";
|
||||||
|
@ -115,8 +126,8 @@ public class H2Dialect extends Dialect {
|
||||||
|
|
||||||
public H2Dialect(DialectResolutionInfo info) {
|
public H2Dialect(DialectResolutionInfo info) {
|
||||||
this(
|
this(
|
||||||
info.getDatabaseMajorVersion()*100
|
info.getDatabaseMajorVersion() * 100000
|
||||||
+ info.getDatabaseMinorVersion()*10,
|
+ info.getDatabaseMinorVersion() * 1000,
|
||||||
parseBuildId( info )
|
parseBuildId( info )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -174,6 +185,17 @@ public class H2Dialect extends Dialect {
|
||||||
CommonFunctionFactory.rownum( queryEngine );
|
CommonFunctionFactory.rownum( queryEngine );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new H2SqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In H2, the extract() function does not return
|
* In H2, the extract() function does not return
|
||||||
* fractional seconds for the the field
|
* fractional seconds for the the field
|
||||||
|
@ -269,6 +291,11 @@ public class H2Dialect extends Dialect {
|
||||||
return "from dual";
|
return "from dual";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NullOrdering getNullOrdering() {
|
||||||
|
return NullOrdering.FIRST;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
|
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
|
||||||
EntityMappingType entityDescriptor,
|
EntityMappingType entityDescriptor,
|
||||||
|
@ -342,11 +369,6 @@ public class H2Dialect extends Dialect {
|
||||||
return "call current_timestamp()";
|
return "call current_timestamp()";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsUnionAll() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for H2.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class H2SqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public H2SqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( isRowsOnlyFetchClauseType( queryPart ) ) {
|
||||||
|
if ( supportsOffsetFetchClause() ) {
|
||||||
|
renderOffsetFetchClause( queryPart, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderLimitOffsetClause( queryPart );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( supportsOffsetFetchClausePercentWithTies() ) {
|
||||||
|
renderOffsetFetchClause( queryPart, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// FETCH PERCENT and WITH TIES were introduced along with window functions
|
||||||
|
throw new IllegalArgumentException( "Can't emulate fetch clause type: " + queryPart.getFetchClauseType() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// H2 does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// H2 does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsOffsetFetchClause() {
|
||||||
|
return getDialect().getVersion() >= 104195;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsOffsetFetchClausePercentWithTies() {
|
||||||
|
// Introduction of TIES clause https://github.com/h2database/h2database/commit/876e9fbe7baf11d01675bfe871aac2cf1b6104ce
|
||||||
|
// Introduction of PERCENT support https://github.com/h2database/h2database/commit/f45913302e5f6ad149155a73763c0c59d8205849
|
||||||
|
return getDialect().getVersion() >= 104198;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for HANA.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class HANASqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public HANASqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
|
||||||
|
// HANA only supports the LIMIT + OFFSET syntax but also window functions
|
||||||
|
// Check if current query part is already row numbering to avoid infinite recursion
|
||||||
|
return useOffsetFetchClause( queryPart ) && getQueryPartForRowNumbering() != queryPart
|
||||||
|
&& !isRowsOnlyFetchClauseType( queryPart );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQueryGroup(QueryGroup queryGroup) {
|
||||||
|
if ( shouldEmulateFetchClause( queryGroup ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( queryGroup, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQueryGroup( queryGroup );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQuerySpec(QuerySpec querySpec) {
|
||||||
|
if ( shouldEmulateFetchClause( querySpec ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( querySpec, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQuerySpec( querySpec );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( !isRowNumberingCurrentQueryPart() ) {
|
||||||
|
renderLimitOffsetClause( queryPart );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// HANA does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// HANA does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import javax.persistence.TemporalType;
|
||||||
|
|
||||||
import org.hibernate.JDBCException;
|
import org.hibernate.JDBCException;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.NullOrdering;
|
||||||
import org.hibernate.StaleObjectStateException;
|
import org.hibernate.StaleObjectStateException;
|
||||||
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
|
@ -34,6 +35,7 @@ import org.hibernate.dialect.sequence.HSQLSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
|
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
||||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||||
|
@ -52,6 +54,11 @@ import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.LocalTemporaryTableStrategy;
|
import org.hibernate.query.sqm.mutation.internal.idtable.LocalTemporaryTableStrategy;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
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.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHSQLDBDatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHSQLDBDatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
|
|
||||||
|
@ -205,6 +212,17 @@ public class HSQLDialect extends Dialect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new HSQLSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String castPattern(CastType from, CastType to) {
|
public String castPattern(CastType from, CastType to) {
|
||||||
if ( from== BOOLEAN
|
if ( from== BOOLEAN
|
||||||
|
@ -429,8 +447,8 @@ public class HSQLDialect extends Dialect {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsUnionAll() {
|
public NullOrdering getNullOrdering() {
|
||||||
return true;
|
return NullOrdering.FIRST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for HSQL.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class HSQLSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public HSQLSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( supportsOffsetFetchClause() ) {
|
||||||
|
assertRowsOnlyFetchClauseType( queryPart );
|
||||||
|
renderOffsetFetchClause( queryPart, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderLimitOffsetClause( queryPart );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// HSQL does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// HSQL does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsOffsetFetchClause() {
|
||||||
|
return getDialect().getVersion() >= 250;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.dialect.unique.InformixUniqueDelegate;
|
import org.hibernate.dialect.unique.InformixUniqueDelegate;
|
||||||
import org.hibernate.dialect.unique.UniqueDelegate;
|
import org.hibernate.dialect.unique.UniqueDelegate;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
||||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||||
|
@ -30,6 +31,11 @@ import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.LocalTemporaryTableStrategy;
|
import org.hibernate.query.sqm.mutation.internal.idtable.LocalTemporaryTableStrategy;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
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.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorInformixDatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorInformixDatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
@ -159,6 +165,17 @@ public class InformixDialect extends Dialect {
|
||||||
//coalesce() and nullif() both supported since Informix 12
|
//coalesce() and nullif() both supported since Informix 12
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new InformixSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Informix has no extract() function, but we can
|
* Informix has no extract() function, but we can
|
||||||
* partially emulate it by using the appropriate
|
* partially emulate it by using the appropriate
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.ast.tree.select.SelectClause;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Informix.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class InformixSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public InformixSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitSqlSelections(SelectClause selectClause) {
|
||||||
|
if ( supportsSkipFirstClause() ) {
|
||||||
|
renderSkipFirstClause( (QuerySpec) getQueryPartStack().getCurrent() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderFirstClause( (QuerySpec) getQueryPartStack().getCurrent() );
|
||||||
|
}
|
||||||
|
super.visitSqlSelections( selectClause );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needsRowsToSkip() {
|
||||||
|
return !supportsSkipFirstClause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderFetchPlusOffsetExpression(
|
||||||
|
Expression fetchClauseExpression,
|
||||||
|
Expression offsetClauseExpression,
|
||||||
|
int offset) {
|
||||||
|
renderFetchPlusOffsetExpressionAsSingleParameter( fetchClauseExpression, offsetClauseExpression, offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderFetchExpression(Expression fetchExpression) {
|
||||||
|
if ( supportsParameterOffsetFetchExpression() ) {
|
||||||
|
super.renderFetchExpression( fetchExpression );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderExpressionAsLiteral( fetchExpression, getJdbcParameterBindings() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderOffsetExpression(Expression offsetExpression) {
|
||||||
|
if ( supportsParameterOffsetFetchExpression() ) {
|
||||||
|
super.renderOffsetExpression( offsetExpression );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderExpressionAsLiteral( offsetExpression, getJdbcParameterBindings() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
// Informix only supports the SKIP clause in the top level query
|
||||||
|
if ( !queryPart.isRoot() && queryPart.getOffsetClauseExpression() != null ) {
|
||||||
|
throw new IllegalArgumentException( "Can't emulate offset clause in subquery" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// Informix does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// Informix does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsParameterOffsetFetchExpression() {
|
||||||
|
return getDialect().getVersion() >= 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsSkipFirstClause() {
|
||||||
|
return getDialect().getVersion() >= 11;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ import org.hibernate.dialect.pagination.LimitHandler;
|
||||||
import org.hibernate.dialect.sequence.ANSISequenceSupport;
|
import org.hibernate.dialect.sequence.ANSISequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
import org.hibernate.query.TemporalUnit;
|
import org.hibernate.query.TemporalUnit;
|
||||||
|
@ -26,6 +27,11 @@ import org.hibernate.query.sqm.mutation.internal.idtable.GlobalTemporaryTableStr
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
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.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceNameExtractorImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceNameExtractorImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
@ -223,6 +229,17 @@ public class IngresDialect extends Dialect {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new IngresSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType) {
|
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType) {
|
||||||
return "timestampadd(?1, ?2, ?3)";
|
return "timestampadd(?1, ?2, ?3)";
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.ast.tree.select.SelectClause;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Ingres.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class IngresSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public IngresSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderFetchPlusOffsetExpression(
|
||||||
|
Expression fetchClauseExpression,
|
||||||
|
Expression offsetClauseExpression,
|
||||||
|
int offset) {
|
||||||
|
renderFetchPlusOffsetExpressionAsSingleParameter( fetchClauseExpression, offsetClauseExpression, offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitSqlSelections(SelectClause selectClause) {
|
||||||
|
if ( !supportsOffsetFetchClause() ) {
|
||||||
|
renderFirstClause( (QuerySpec) getQueryPartStack().getCurrent() );
|
||||||
|
}
|
||||||
|
super.visitSqlSelections( selectClause );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderFetchExpression(Expression fetchExpression) {
|
||||||
|
if ( supportsParameterOffsetFetchExpression() ) {
|
||||||
|
super.renderFetchExpression( fetchExpression );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderExpressionAsLiteral( fetchExpression, getJdbcParameterBindings() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderOffsetExpression(Expression offsetExpression) {
|
||||||
|
if ( supportsParameterOffsetFetchExpression() ) {
|
||||||
|
super.renderOffsetExpression( offsetExpression );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderExpressionAsLiteral( offsetExpression, getJdbcParameterBindings() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( supportsOffsetFetchClause() ) {
|
||||||
|
renderOffsetFetchClause( queryPart, false );
|
||||||
|
}
|
||||||
|
else if ( !queryPart.isRoot() && queryPart.getOffsetClauseExpression() != null ) {
|
||||||
|
throw new IllegalArgumentException( "Can't emulate offset clause in subquery" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// Ingres does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// Ingres does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needsRowsToSkip() {
|
||||||
|
return !supportsOffsetFetchClause();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsParameterOffsetFetchExpression() {
|
||||||
|
return getDialect().getVersion() >= 930;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsOffsetFetchClause() {
|
||||||
|
return getDialect().getVersion() >= 930;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,11 +6,16 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.dialect;
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.dialect.sequence.MariaDBSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.ANSISequenceSupport;
|
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorMariaDBDatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorMariaDBDatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
@ -25,39 +30,51 @@ public class MariaDBDialect extends MySQLDialect {
|
||||||
|
|
||||||
private final int version;
|
private final int version;
|
||||||
|
|
||||||
int getMariaVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MariaDBDialect() {
|
public MariaDBDialect() {
|
||||||
this(500);
|
this(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MariaDBDialect(DialectResolutionInfo info) {
|
||||||
|
this( info.getDatabaseMajorVersion() * 100 + info.getDatabaseMinorVersion() * 10 );
|
||||||
|
}
|
||||||
|
|
||||||
public MariaDBDialect(int version) {
|
public MariaDBDialect(int version) {
|
||||||
super( version < 530 ? 500 : 570 );
|
super( version < 530 ? 500 : 570 );
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MariaDBDialect(DialectResolutionInfo info) {
|
@Override
|
||||||
this( info.getDatabaseMajorVersion() * 100 + info.getDatabaseMinorVersion() * 10 );
|
public int getVersion() {
|
||||||
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initializeFunctionRegistry(QueryEngine queryEngine) {
|
public void initializeFunctionRegistry(QueryEngine queryEngine) {
|
||||||
super.initializeFunctionRegistry(queryEngine);
|
super.initializeFunctionRegistry(queryEngine);
|
||||||
|
|
||||||
if ( getMariaVersion() >= 1020 ) {
|
if ( getVersion() >= 1020 ) {
|
||||||
queryEngine.getSqmFunctionRegistry().registerNamed("json_valid", StandardBasicTypes.NUMERIC_BOOLEAN);
|
queryEngine.getSqmFunctionRegistry().registerNamed("json_valid", StandardBasicTypes.NUMERIC_BOOLEAN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new MariaDBSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public boolean supportsRowValueConstructorSyntaxInInList() {
|
public boolean supportsRowValueConstructorSyntaxInInList() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsColumnCheck() {
|
public boolean supportsColumnCheck() {
|
||||||
return getMariaVersion() >= 1020;
|
return getVersion() >= 1020;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,14 +84,14 @@ public class MariaDBDialect extends MySQLDialect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsIfExistsBeforeConstraintName() {
|
public boolean supportsIfExistsBeforeConstraintName() {
|
||||||
return getMariaVersion() >= 1000;
|
return getVersion() >= 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SequenceSupport getSequenceSupport() {
|
public SequenceSupport getSequenceSupport() {
|
||||||
return getMariaVersion() < 1030
|
return getVersion() < 1030
|
||||||
? super.getSequenceSupport()
|
? super.getSequenceSupport()
|
||||||
: ANSISequenceSupport.INSTANCE;
|
: MariaDBSequenceSupport.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for MariaDB.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class MariaDBSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public MariaDBSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
|
||||||
|
// Check if current query part is already row numbering to avoid infinite recursion
|
||||||
|
return useOffsetFetchClause( queryPart ) && getQueryPartForRowNumbering() != queryPart && supportsWindowFunctions() && !isRowsOnlyFetchClauseType( queryPart );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQueryGroup(QueryGroup queryGroup) {
|
||||||
|
if ( shouldEmulateFetchClause( queryGroup ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( queryGroup, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQueryGroup( queryGroup );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQuerySpec(QuerySpec querySpec) {
|
||||||
|
if ( shouldEmulateFetchClause( querySpec ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( querySpec, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQuerySpec( querySpec );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( !isRowNumberingCurrentQueryPart() ) {
|
||||||
|
renderCombinedLimitClause( queryPart );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// MariaDB does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// MariaDB does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsWindowFunctions() {
|
||||||
|
return getDialect().getVersion() >= 1020;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,8 +9,11 @@ package org.hibernate.dialect;
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||||
|
import org.hibernate.dialect.pagination.LimitHandler;
|
||||||
|
import org.hibernate.dialect.pagination.LimitOffsetLimitHandler;
|
||||||
import org.hibernate.dialect.sequence.MaxDBSequenceSupport;
|
import org.hibernate.dialect.sequence.MaxDBSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
import org.hibernate.query.TrimSpec;
|
import org.hibernate.query.TrimSpec;
|
||||||
|
@ -18,6 +21,11 @@ import org.hibernate.query.spi.QueryEngine;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||||
import org.hibernate.sql.CaseFragment;
|
import org.hibernate.sql.CaseFragment;
|
||||||
import org.hibernate.sql.DecodeCaseFragment;
|
import org.hibernate.sql.DecodeCaseFragment;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorSAPDBDatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorSAPDBDatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
@ -60,6 +68,11 @@ public class MaxDBDialect extends Dialect {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LimitHandler getLimitHandler() {
|
||||||
|
return LimitOffsetLimitHandler.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initializeFunctionRegistry(QueryEngine queryEngine) {
|
public void initializeFunctionRegistry(QueryEngine queryEngine) {
|
||||||
super.initializeFunctionRegistry( queryEngine );
|
super.initializeFunctionRegistry( queryEngine );
|
||||||
|
@ -112,6 +125,17 @@ public class MaxDBDialect extends Dialect {
|
||||||
).setArgumentListSignature("(pattern, string[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new MaxDBSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String trimPattern(TrimSpec specification, char character) {
|
public String trimPattern(TrimSpec specification, char character) {
|
||||||
return AbstractTransactSQLDialect.replaceLtrimRtrim(specification, character);
|
return AbstractTransactSQLDialect.replaceLtrimRtrim(specification, character);
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for MaxDB.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class MaxDBSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public MaxDBSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
renderLimitOffsetClause( queryPart );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// MaxDB does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// MaxDB does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,10 +15,16 @@ import org.hibernate.dialect.pagination.OffsetFetchLimitHandler;
|
||||||
import org.hibernate.dialect.sequence.MimerSequenceSupport;
|
import org.hibernate.dialect.sequence.MimerSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.engine.jdbc.Size;
|
import org.hibernate.engine.jdbc.Size;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.CastType;
|
import org.hibernate.query.CastType;
|
||||||
import org.hibernate.query.SemanticException;
|
import org.hibernate.query.SemanticException;
|
||||||
import org.hibernate.query.TemporalUnit;
|
import org.hibernate.query.TemporalUnit;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorMimerSQLDatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorMimerSQLDatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
|
|
||||||
|
@ -107,6 +113,17 @@ public class MimerSQLDialect extends Dialect {
|
||||||
CommonFunctionFactory.localtimeLocaltimestamp( queryEngine );
|
CommonFunctionFactory.localtimeLocaltimestamp( queryEngine );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new MimerSQLSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mimer does have a real {@link java.sql.Types#BOOLEAN}
|
* Mimer does have a real {@link java.sql.Types#BOOLEAN}
|
||||||
* type, but it doesn't know how to cast to it.
|
* type, but it doesn't know how to cast to it.
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for MimerSQL.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class MimerSQLSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public MimerSQLSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
assertRowsOnlyFetchClauseType( queryPart );
|
||||||
|
renderOffsetFetchClause( queryPart, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// MimerSQL does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// MimerSQL does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.dialect;
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
|
import org.hibernate.NullOrdering;
|
||||||
import org.hibernate.NullPrecedence;
|
import org.hibernate.NullPrecedence;
|
||||||
import org.hibernate.PessimisticLockException;
|
import org.hibernate.PessimisticLockException;
|
||||||
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
||||||
|
@ -22,6 +23,7 @@ import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.dialect.unique.MySQLUniqueDelegate;
|
import org.hibernate.dialect.unique.MySQLUniqueDelegate;
|
||||||
import org.hibernate.dialect.unique.UniqueDelegate;
|
import org.hibernate.dialect.unique.UniqueDelegate;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.exception.LockAcquisitionException;
|
import org.hibernate.exception.LockAcquisitionException;
|
||||||
import org.hibernate.exception.LockTimeoutException;
|
import org.hibernate.exception.LockTimeoutException;
|
||||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||||
|
@ -39,6 +41,11 @@ import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.LocalTemporaryTableStrategy;
|
import org.hibernate.query.sqm.mutation.internal.idtable.LocalTemporaryTableStrategy;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
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.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
|
||||||
import java.sql.CallableStatement;
|
import java.sql.CallableStatement;
|
||||||
|
@ -59,8 +66,8 @@ import static org.hibernate.query.CastType.BOOLEAN;
|
||||||
public class MySQLDialect extends Dialect {
|
public class MySQLDialect extends Dialect {
|
||||||
|
|
||||||
private final UniqueDelegate uniqueDelegate;
|
private final UniqueDelegate uniqueDelegate;
|
||||||
private MySQLStorageEngine storageEngine;
|
private final MySQLStorageEngine storageEngine;
|
||||||
private int version;
|
private final int version;
|
||||||
|
|
||||||
public MySQLDialect(DialectResolutionInfo info) {
|
public MySQLDialect(DialectResolutionInfo info) {
|
||||||
this( info.getDatabaseMajorVersion() * 100 + info.getDatabaseMinorVersion() * 10 );
|
this( info.getDatabaseMajorVersion() * 100 + info.getDatabaseMinorVersion() * 10 );
|
||||||
|
@ -95,7 +102,7 @@ public class MySQLDialect extends Dialect {
|
||||||
|
|
||||||
registerColumnType( Types.NUMERIC, "decimal($p,$s)" ); //it's just a synonym
|
registerColumnType( Types.NUMERIC, "decimal($p,$s)" ); //it's just a synonym
|
||||||
|
|
||||||
if ( getVersion() < 570) {
|
if ( getMySQLVersion() < 570) {
|
||||||
registerColumnType( Types.TIMESTAMP, "datetime" );
|
registerColumnType( Types.TIMESTAMP, "datetime" );
|
||||||
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "timestamp" );
|
registerColumnType( Types.TIMESTAMP_WITH_TIMEZONE, "timestamp" );
|
||||||
}
|
}
|
||||||
|
@ -107,7 +114,7 @@ public class MySQLDialect extends Dialect {
|
||||||
}
|
}
|
||||||
|
|
||||||
// max length for VARCHAR changed in 5.0.3
|
// max length for VARCHAR changed in 5.0.3
|
||||||
final int maxVarcharLen = getVersion() < 500 ? 255 : 65_535;
|
final int maxVarcharLen = getMySQLVersion() < 500 ? 255 : 65_535;
|
||||||
|
|
||||||
registerColumnType( Types.VARCHAR, maxVarcharLen, "varchar($l)" );
|
registerColumnType( Types.VARCHAR, maxVarcharLen, "varchar($l)" );
|
||||||
registerColumnType( Types.VARBINARY, maxVarcharLen, "varbinary($l)" );
|
registerColumnType( Types.VARBINARY, maxVarcharLen, "varbinary($l)" );
|
||||||
|
@ -144,7 +151,7 @@ public class MySQLDialect extends Dialect {
|
||||||
registerColumnType( Types.NCLOB, maxLobLen, "text" );
|
registerColumnType( Types.NCLOB, maxLobLen, "text" );
|
||||||
registerColumnType( Types.NCLOB, maxTinyLobLen, "tinytext" );
|
registerColumnType( Types.NCLOB, maxTinyLobLen, "tinytext" );
|
||||||
|
|
||||||
if ( getVersion() >= 570) {
|
if ( getMySQLVersion() >= 570) {
|
||||||
// MySQL 5.7 brings JSON native support with a dedicated datatype
|
// MySQL 5.7 brings JSON native support with a dedicated datatype
|
||||||
// https://dev.mysql.com/doc/refman/5.7/en/json.html
|
// https://dev.mysql.com/doc/refman/5.7/en/json.html
|
||||||
registerColumnType(Types.JAVA_OBJECT, "json");
|
registerColumnType(Types.JAVA_OBJECT, "json");
|
||||||
|
@ -163,6 +170,10 @@ public class MySQLDialect extends Dialect {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getMySQLVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getDefaultLobLength() {
|
public long getDefaultLobLength() {
|
||||||
//max length for mediumblob or mediumtext
|
//max length for mediumblob or mediumtext
|
||||||
|
@ -237,7 +248,7 @@ public class MySQLDialect extends Dialect {
|
||||||
CommonFunctionFactory.format_dateFormat( queryEngine );
|
CommonFunctionFactory.format_dateFormat( queryEngine );
|
||||||
CommonFunctionFactory.makedateMaketime( queryEngine );
|
CommonFunctionFactory.makedateMaketime( queryEngine );
|
||||||
|
|
||||||
if ( getVersion() < 570 ) {
|
if ( getMySQLVersion() < 570 ) {
|
||||||
CommonFunctionFactory.sysdateParens( queryEngine );
|
CommonFunctionFactory.sysdateParens( queryEngine );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -247,6 +258,17 @@ public class MySQLDialect extends Dialect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new MySQLSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private void time(QueryEngine queryEngine) {
|
private void time(QueryEngine queryEngine) {
|
||||||
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "time" )
|
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "time" )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
|
@ -266,7 +288,7 @@ public class MySQLDialect extends Dialect {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String currentTimestamp() {
|
public String currentTimestamp() {
|
||||||
return getVersion() < 570 ? super.currentTimestamp() : "current_timestamp(6)";
|
return getMySQLVersion() < 570 ? super.currentTimestamp() : "current_timestamp(6)";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -367,12 +389,12 @@ public class MySQLDialect extends Dialect {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsRowValueConstructorSyntaxInInList() {
|
public boolean supportsRowValueConstructorSyntaxInInList() {
|
||||||
return getVersion() >= 570;
|
return getMySQLVersion() >= 570;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsUnionAll() {
|
public boolean supportsUnionAll() {
|
||||||
return getVersion() >= 500;
|
return getMySQLVersion() >= 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -382,7 +404,7 @@ public class MySQLDialect extends Dialect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getQueryHintString(String query, String hints) {
|
public String getQueryHintString(String query, String hints) {
|
||||||
return getVersion() < 500
|
return getMySQLVersion() < 500
|
||||||
? super.getQueryHintString( query, hints )
|
? super.getQueryHintString( query, hints )
|
||||||
: IndexQueryHintHandler.INSTANCE.addQueryHints( query, hints );
|
: IndexQueryHintHandler.INSTANCE.addQueryHints( query, hints );
|
||||||
}
|
}
|
||||||
|
@ -396,7 +418,7 @@ public class MySQLDialect extends Dialect {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ViolatedConstraintNameExtractor getViolatedConstraintNameExtractor() {
|
public ViolatedConstraintNameExtractor getViolatedConstraintNameExtractor() {
|
||||||
return getVersion() < 500 ? super.getViolatedConstraintNameExtractor() : EXTRACTOR;
|
return getMySQLVersion() < 500 ? super.getViolatedConstraintNameExtractor() : EXTRACTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final ViolatedConstraintNameExtractor EXTRACTOR =
|
private static final ViolatedConstraintNameExtractor EXTRACTOR =
|
||||||
|
@ -508,6 +530,11 @@ public class MySQLDialect extends Dialect {
|
||||||
return " comment '" + comment + "'";
|
return " comment '" + comment + "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NullOrdering getNullOrdering() {
|
||||||
|
return NullOrdering.SMALLEST;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
|
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
|
||||||
EntityMappingType rootEntityDescriptor,
|
EntityMappingType rootEntityDescriptor,
|
||||||
|
@ -723,7 +750,7 @@ public class MySQLDialect extends Dialect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTableTypeString() {
|
public String getTableTypeString() {
|
||||||
String engineKeyword = getVersion() < 500 ? "type" : "engine";
|
String engineKeyword = getMySQLVersion() < 500 ? "type" : "engine";
|
||||||
return storageEngine.getTableTypeString( engineKeyword );
|
return storageEngine.getTableTypeString( engineKeyword );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,7 +765,7 @@ public class MySQLDialect extends Dialect {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MySQLStorageEngine getDefaultMySQLStorageEngine() {
|
protected MySQLStorageEngine getDefaultMySQLStorageEngine() {
|
||||||
return getVersion() < 550 ? MyISAMStorageEngine.INSTANCE : InnoDBStorageEngine.INSTANCE;
|
return getMySQLVersion() < 550 ? MyISAMStorageEngine.INSTANCE : InnoDBStorageEngine.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -900,12 +927,12 @@ public class MySQLDialect extends Dialect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsSkipLocked() {
|
public boolean supportsSkipLocked() {
|
||||||
return getVersion() >= 800;
|
return getMySQLVersion() >= 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsNoWait() {
|
public boolean supportsNoWait() {
|
||||||
return getVersion() >= 800;
|
return getMySQLVersion() >= 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean supportsWait() {
|
public boolean supportsWait() {
|
||||||
|
@ -914,11 +941,11 @@ public class MySQLDialect extends Dialect {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean supportsForShare() {
|
boolean supportsForShare() {
|
||||||
return getVersion() >= 800;
|
return getMySQLVersion() >= 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean supportsAliasLocks() {
|
boolean supportsAliasLocks() {
|
||||||
return getVersion() >= 800;
|
return getMySQLVersion() >= 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for MySQL.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class MySQLSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public MySQLSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
|
||||||
|
// Check if current query part is already row numbering to avoid infinite recursion
|
||||||
|
return useOffsetFetchClause( queryPart ) && getQueryPartForRowNumbering() != queryPart
|
||||||
|
&& supportsWindowFunctions() && !isRowsOnlyFetchClauseType( queryPart );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQueryGroup(QueryGroup queryGroup) {
|
||||||
|
if ( shouldEmulateFetchClause( queryGroup ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( queryGroup, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQueryGroup( queryGroup );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQuerySpec(QuerySpec querySpec) {
|
||||||
|
if ( shouldEmulateFetchClause( querySpec ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( querySpec, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQuerySpec( querySpec );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( !isRowNumberingCurrentQueryPart() ) {
|
||||||
|
renderCombinedLimitClause( queryPart );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// MySQL does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// MySQL does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsWindowFunctions() {
|
||||||
|
return getDialect().getVersion() >= 802;
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
import org.hibernate.engine.config.spi.StandardConverters;
|
import org.hibernate.engine.config.spi.StandardConverters;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.exception.ConstraintViolationException;
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
import org.hibernate.exception.LockAcquisitionException;
|
import org.hibernate.exception.LockAcquisitionException;
|
||||||
import org.hibernate.exception.LockTimeoutException;
|
import org.hibernate.exception.LockTimeoutException;
|
||||||
|
@ -46,6 +47,11 @@ import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.sql.*;
|
import org.hibernate.sql.*;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorOracleDatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorOracleDatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
@ -179,6 +185,17 @@ public class OracleDialect extends Dialect {
|
||||||
).setArgumentListSignature("(pattern, string[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new OracleSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String currentDate() {
|
public String currentDate() {
|
||||||
return getVersion() < 9 ? currentTimestamp() : "current_date";
|
return getVersion() < 9 ? currentTimestamp() : "current_date";
|
||||||
|
@ -783,11 +800,6 @@ public class OracleDialect extends Dialect {
|
||||||
return (ResultSet) ps.getObject( 1 );
|
return (ResultSet) ps.getObject( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsUnionAll() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsCommentOn() {
|
public boolean supportsCommentOn() {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.FetchClauseType;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.ast.tree.select.SelectClause;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Oracle.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class OracleSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public OracleSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
|
||||||
|
// Check if current query part is already row numbering to avoid infinite recursion
|
||||||
|
return getQueryPartForRowNumbering() != queryPart && !supportsOffsetFetchClause() && (
|
||||||
|
queryPart.isRoot() && hasLimit() || queryPart.getFetchClauseExpression() != null || queryPart.getOffsetClauseExpression() != null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQueryGroup(QueryGroup queryGroup) {
|
||||||
|
if ( shouldEmulateFetchClause( queryGroup ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( queryGroup, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQueryGroup( queryGroup );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQuerySpec(QuerySpec querySpec) {
|
||||||
|
if ( shouldEmulateFetchClause( querySpec ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( querySpec, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQuerySpec( querySpec );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( !isRowNumberingCurrentQueryPart() ) {
|
||||||
|
if ( supportsOffsetFetchClause() ) {
|
||||||
|
renderOffsetFetchClause( queryPart, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertRowsOnlyFetchClauseType( queryPart );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderRowNumber(SelectClause selectClause, QueryPart queryPart) {
|
||||||
|
if ( supportsOffsetFetchClause() || selectClause.isDistinct() ) {
|
||||||
|
super.renderRowNumber( selectClause, queryPart );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appendSql( "rownum" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsOffsetFetchClause() {
|
||||||
|
return getDialect().getVersion() >= 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,7 +9,6 @@ package org.hibernate.dialect;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
import org.hibernate.PessimisticLockException;
|
import org.hibernate.PessimisticLockException;
|
||||||
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
|
||||||
import org.hibernate.boot.model.TypeContributions;
|
import org.hibernate.boot.model.TypeContributions;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||||
|
@ -21,6 +20,7 @@ import org.hibernate.dialect.pagination.OffsetFetchLimitHandler;
|
||||||
import org.hibernate.dialect.sequence.PostgreSQLSequenceSupport;
|
import org.hibernate.dialect.sequence.PostgreSQLSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.exception.LockAcquisitionException;
|
import org.hibernate.exception.LockAcquisitionException;
|
||||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
||||||
|
@ -33,12 +33,14 @@ import org.hibernate.procedure.spi.CallableStatementSupport;
|
||||||
import org.hibernate.query.SemanticException;
|
import org.hibernate.query.SemanticException;
|
||||||
import org.hibernate.query.TemporalUnit;
|
import org.hibernate.query.TemporalUnit;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.AfterUseAction;
|
import org.hibernate.query.sqm.mutation.internal.cte.CteStrategy;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.LocalTemporaryTableStrategy;
|
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
import org.hibernate.type.descriptor.ValueBinder;
|
import org.hibernate.type.descriptor.ValueBinder;
|
||||||
import org.hibernate.type.descriptor.ValueExtractor;
|
import org.hibernate.type.descriptor.ValueExtractor;
|
||||||
|
@ -460,11 +462,6 @@ public class PostgreSQLDialect extends Dialect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsUnionAll() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Workaround for postgres bug #1453
|
* Workaround for postgres bug #1453
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -505,26 +502,22 @@ public class PostgreSQLDialect extends Dialect {
|
||||||
return String.valueOf( bool );
|
return String.valueOf( bool );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
|
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
|
||||||
EntityMappingType rootEntityDescriptor,
|
EntityMappingType rootEntityDescriptor,
|
||||||
RuntimeModelCreationContext runtimeModelCreationContext) {
|
RuntimeModelCreationContext runtimeModelCreationContext) {
|
||||||
return new LocalTemporaryTableStrategy(
|
return new CteStrategy( rootEntityDescriptor, runtimeModelCreationContext );
|
||||||
new IdTable( rootEntityDescriptor, base -> "HT_" + base, this ),
|
|
||||||
() -> new TempIdTableExporter( true, this::getTypeName ) {
|
|
||||||
@Override
|
|
||||||
protected String getCreateCommand() {
|
|
||||||
return "create temporary table";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getCreateOptions() {
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
return "on commit drop";
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new PostgreSQLSqlAstTranslator<>( sessionFactory, statement );
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
AfterUseAction.CLEAN,
|
|
||||||
TempTableDdlTransactionHandling.NONE,
|
|
||||||
runtimeModelCreationContext.getSessionFactory()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.FetchClauseType;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.MutationStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Literal;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for PostgreSQL.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class PostgreSQLSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public PostgreSQLSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
|
||||||
|
// Check if current query part is already row numbering to avoid infinite recursion
|
||||||
|
if ( getQueryPartForRowNumbering() == queryPart || isRowsOnlyFetchClauseType( queryPart ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final FetchClauseType fetchClauseType = queryPart.getFetchClauseType();
|
||||||
|
switch ( fetchClauseType ) {
|
||||||
|
case PERCENT_ONLY:
|
||||||
|
case PERCENT_WITH_TIES:
|
||||||
|
return !supportsOffsetFetchClausePercent();
|
||||||
|
case ROWS_WITH_TIES:
|
||||||
|
return !supportsOffsetFetchClauseWithTies();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQueryGroup(QueryGroup queryGroup) {
|
||||||
|
if ( shouldEmulateFetchClause( queryGroup ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( queryGroup, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQueryGroup( queryGroup );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQuerySpec(QuerySpec querySpec) {
|
||||||
|
if ( shouldEmulateFetchClause( querySpec ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( querySpec, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQuerySpec( querySpec );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( !isRowNumberingCurrentQueryPart() ) {
|
||||||
|
if ( supportsOffsetFetchClause() ) {
|
||||||
|
renderOffsetFetchClause( queryPart, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderLimitOffsetClause( queryPart );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// PostgreSQL does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// PostgreSQL does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsOffsetFetchClause() {
|
||||||
|
return getDialect().getVersion() >= 840;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsOffsetFetchClauseWithTies() {
|
||||||
|
return getDialect().getVersion() >= 1300;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsOffsetFetchClausePercent() {
|
||||||
|
// Currently, percent always has to be emulated
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.FetchClauseType;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.query.Limit;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Unisys 2200.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class RDBMSOS2200SqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public RDBMSOS2200SqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( queryPart.isRoot() ) {
|
||||||
|
if ( hasLimit() ) {
|
||||||
|
prepareLimitOffsetParameters();
|
||||||
|
renderFetch( getLimitParameter(), getOffsetParameter(), FetchClauseType.ROWS_ONLY );
|
||||||
|
}
|
||||||
|
else if ( queryPart.getFetchClauseExpression() != null ) {
|
||||||
|
renderFetch( queryPart.getFetchClauseExpression(), queryPart.getOffsetClauseExpression(), queryPart.getFetchClauseType() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( queryPart.getOffsetClauseExpression() != null ) {
|
||||||
|
throw new IllegalArgumentException( "Can't emulate offset clause in subquery" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderFetchPlusOffsetExpression(
|
||||||
|
Expression fetchClauseExpression,
|
||||||
|
Expression offsetClauseExpression,
|
||||||
|
int offset) {
|
||||||
|
renderFetchPlusOffsetExpressionAsSingleParameter( fetchClauseExpression, offsetClauseExpression, offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needsRowsToSkip() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// Unisys 2200 does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// Unisys 2200 does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import org.hibernate.dialect.pagination.FetchLimitHandler;
|
||||||
import org.hibernate.dialect.pagination.LimitHandler;
|
import org.hibernate.dialect.pagination.LimitHandler;
|
||||||
import org.hibernate.dialect.sequence.RDMSSequenceSupport;
|
import org.hibernate.dialect.sequence.RDMSSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.persister.entity.Lockable;
|
import org.hibernate.persister.entity.Lockable;
|
||||||
import org.hibernate.query.TemporalUnit;
|
import org.hibernate.query.TemporalUnit;
|
||||||
|
@ -20,6 +21,12 @@ import org.hibernate.query.TrimSpec;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
import org.hibernate.sql.CaseFragment;
|
import org.hibernate.sql.CaseFragment;
|
||||||
import org.hibernate.sql.DecodeCaseFragment;
|
import org.hibernate.sql.DecodeCaseFragment;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
@ -151,6 +158,17 @@ public class RDMSOS2200Dialect extends Dialect {
|
||||||
CommonFunctionFactory.monthsBetween( queryEngine );
|
CommonFunctionFactory.monthsBetween( queryEngine );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new RDBMSOS2200SqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getFractionalSecondPrecisionInNanos() {
|
public long getFractionalSecondPrecisionInNanos() {
|
||||||
return 1_000; //microseconds
|
return 1_000; //microseconds
|
||||||
|
@ -290,12 +308,6 @@ public class RDMSOS2200Dialect extends Dialect {
|
||||||
return FetchLimitHandler.INSTANCE;
|
return FetchLimitHandler.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsUnionAll() {
|
|
||||||
// RDMS supports the UNION ALL clause.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFromDual() {
|
public String getFromDual() {
|
||||||
return "from rdms.rdms_dummy where key_col = 1";
|
return "from rdms.rdms_dummy where key_col = 1";
|
||||||
|
|
|
@ -18,11 +18,17 @@ import org.hibernate.dialect.sequence.ANSISequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.NoSequenceSupport;
|
import org.hibernate.dialect.sequence.NoSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.exception.LockTimeoutException;
|
import org.hibernate.exception.LockTimeoutException;
|
||||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||||
import org.hibernate.query.TemporalUnit;
|
import org.hibernate.query.TemporalUnit;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
import org.hibernate.type.descriptor.sql.SmallIntTypeDescriptor;
|
import org.hibernate.type.descriptor.sql.SmallIntTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||||
|
@ -175,6 +181,17 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new SQLServerSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String currentTimestamp() {
|
public String currentTimestamp() {
|
||||||
return "sysdatetime()";
|
return "sysdatetime()";
|
||||||
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.FetchClauseType;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.ast.tree.select.SelectClause;
|
||||||
|
import org.hibernate.sql.ast.tree.select.SortSpecification;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for SQL Server.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class SQLServerSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public SQLServerSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected OffsetFetchClauseMode getOffsetFetchClauseMode(QueryPart queryPart) {
|
||||||
|
final int version = getDialect().getVersion();
|
||||||
|
final boolean hasLimit;
|
||||||
|
final boolean hasOffset;
|
||||||
|
if ( queryPart.isRoot() && hasLimit() ) {
|
||||||
|
hasLimit = getLimit().getMaxRowsJpa() != Integer.MAX_VALUE;
|
||||||
|
hasOffset = getLimit().getFirstRowJpa() != 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hasLimit = queryPart.getFetchClauseExpression() != null;
|
||||||
|
hasOffset = queryPart.getOffsetClauseExpression() != null;
|
||||||
|
}
|
||||||
|
if ( version < 9 || !hasOffset ) {
|
||||||
|
return hasLimit ? OffsetFetchClauseMode.TOP_ONLY : null;
|
||||||
|
}
|
||||||
|
else if ( version < 11 || !isRowsOnlyFetchClauseType( queryPart ) ) {
|
||||||
|
return OffsetFetchClauseMode.EMULATED;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return OffsetFetchClauseMode.STANDARD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
|
||||||
|
// Check if current query part is already row numbering to avoid infinite recursion
|
||||||
|
return getQueryPartForRowNumbering() != queryPart && getOffsetFetchClauseMode( queryPart ) == OffsetFetchClauseMode.EMULATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQueryGroup(QueryGroup queryGroup) {
|
||||||
|
if ( shouldEmulateFetchClause( queryGroup ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( queryGroup, !isRowsOnlyFetchClauseType( queryGroup ) );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQueryGroup( queryGroup );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitQuerySpec(QuerySpec querySpec) {
|
||||||
|
if ( shouldEmulateFetchClause( querySpec ) ) {
|
||||||
|
emulateFetchOffsetWithWindowFunctions( querySpec, !isRowsOnlyFetchClauseType( querySpec ) );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.visitQuerySpec( querySpec );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needsRowsToSkip() {
|
||||||
|
return getDialect().getVersion() < 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderFetchPlusOffsetExpression(
|
||||||
|
Expression fetchClauseExpression,
|
||||||
|
Expression offsetClauseExpression,
|
||||||
|
int offset) {
|
||||||
|
renderFetchPlusOffsetExpressionAsSingleParameter( fetchClauseExpression, offsetClauseExpression, offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitSqlSelections(SelectClause selectClause) {
|
||||||
|
final QuerySpec querySpec = (QuerySpec) getQueryPartStack().getCurrent();
|
||||||
|
final OffsetFetchClauseMode offsetFetchClauseMode = getOffsetFetchClauseMode( querySpec );
|
||||||
|
if ( offsetFetchClauseMode == OffsetFetchClauseMode.TOP_ONLY ) {
|
||||||
|
renderTopClause( querySpec, true );
|
||||||
|
}
|
||||||
|
else if ( offsetFetchClauseMode == OffsetFetchClauseMode.EMULATED ) {
|
||||||
|
renderTopClause( querySpec, isRowsOnlyFetchClauseType( querySpec ) );
|
||||||
|
}
|
||||||
|
super.visitSqlSelections( selectClause );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderOrderBy(boolean addWhitespace, List<SortSpecification> sortSpecifications) {
|
||||||
|
if ( sortSpecifications != null && !sortSpecifications.isEmpty() ) {
|
||||||
|
super.renderOrderBy( addWhitespace, sortSpecifications );
|
||||||
|
}
|
||||||
|
else if ( getClauseStack().getCurrent() == Clause.OVER ) {
|
||||||
|
if ( addWhitespace ) {
|
||||||
|
appendSql( ' ' );
|
||||||
|
}
|
||||||
|
renderEmptyOrderBy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderEmptyOrderBy() {
|
||||||
|
// Always need an order by clause: https://blog.jooq.org/2014/05/13/sql-server-trick-circumvent-missing-order-by-clause/
|
||||||
|
appendSql( "order by @@version" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
if ( !isRowNumberingCurrentQueryPart() ) {
|
||||||
|
if ( getDialect().getVersion() < 9 && !queryPart.isRoot() && queryPart.getOffsetClauseExpression() != null ) {
|
||||||
|
throw new IllegalArgumentException( "Can't emulate offset clause in subquery" );
|
||||||
|
}
|
||||||
|
// Note that SQL Server is very strict i.e. it requires an order by clause for TOP or OFFSET
|
||||||
|
final OffsetFetchClauseMode offsetFetchClauseMode = getOffsetFetchClauseMode( queryPart );
|
||||||
|
if ( offsetFetchClauseMode == OffsetFetchClauseMode.STANDARD ) {
|
||||||
|
if ( !queryPart.hasSortSpecifications() ) {
|
||||||
|
appendSql( ' ' );
|
||||||
|
renderEmptyOrderBy();
|
||||||
|
}
|
||||||
|
final Expression offsetExpression;
|
||||||
|
final Expression fetchExpression;
|
||||||
|
final FetchClauseType fetchClauseType;
|
||||||
|
if ( queryPart.isRoot() && hasLimit() ) {
|
||||||
|
prepareLimitOffsetParameters();
|
||||||
|
offsetExpression = getOffsetParameter();
|
||||||
|
fetchExpression = getLimitParameter();
|
||||||
|
fetchClauseType = FetchClauseType.ROWS_ONLY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offsetExpression = queryPart.getOffsetClauseExpression();
|
||||||
|
fetchExpression = queryPart.getFetchClauseExpression();
|
||||||
|
fetchClauseType = queryPart.getFetchClauseType();
|
||||||
|
}
|
||||||
|
if ( offsetExpression == null ) {
|
||||||
|
appendSql( " offset 0 rows" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderOffset( offsetExpression, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( fetchExpression != null ) {
|
||||||
|
renderFetch( fetchExpression, null, fetchClauseType );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( offsetFetchClauseMode == OffsetFetchClauseMode.TOP_ONLY && !queryPart.hasSortSpecifications() ) {
|
||||||
|
appendSql( ' ' );
|
||||||
|
renderEmptyOrderBy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// SQL Server does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// SQL Server does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
|
||||||
|
enum OffsetFetchClauseMode {
|
||||||
|
STANDARD,
|
||||||
|
TOP_ONLY,
|
||||||
|
EMULATED;
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ import org.hibernate.dialect.pagination.LimitHandler;
|
||||||
import org.hibernate.dialect.pagination.LimitOffsetLimitHandler;
|
import org.hibernate.dialect.pagination.LimitOffsetLimitHandler;
|
||||||
import org.hibernate.dialect.unique.UniqueDelegate;
|
import org.hibernate.dialect.unique.UniqueDelegate;
|
||||||
import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;
|
import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
import org.hibernate.mapping.Column;
|
import org.hibernate.mapping.Column;
|
||||||
|
@ -31,6 +32,11 @@ import org.hibernate.persister.entity.Lockable;
|
||||||
import org.hibernate.query.SemanticException;
|
import org.hibernate.query.SemanticException;
|
||||||
import org.hibernate.query.TemporalUnit;
|
import org.hibernate.query.TemporalUnit;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.spi.Exporter;
|
import org.hibernate.tool.schema.spi.Exporter;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
|
||||||
|
@ -377,6 +383,17 @@ public class SpannerDialect extends Dialect {
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new SpannerSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Exporter<Table> getTableExporter() {
|
public Exporter<Table> getTableExporter() {
|
||||||
return this.spannerTableExporter;
|
return this.spannerTableExporter;
|
||||||
|
@ -404,11 +421,6 @@ public class SpannerDialect extends Dialect {
|
||||||
return String.valueOf( bool );
|
return String.valueOf( bool );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsUnionAll() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String translateExtractField(TemporalUnit unit) {
|
public String translateExtractField(TemporalUnit unit) {
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
|
@ -769,7 +781,7 @@ public class SpannerDialect extends Dialect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LimitHandler getLimitHandler() {
|
public LimitHandler getLimitHandler() {
|
||||||
return new LimitOffsetLimitHandler();
|
return LimitOffsetLimitHandler.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Type conversion and casting */
|
/* Type conversion and casting */
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.FetchClauseType;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Spanner.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class SpannerSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public SpannerSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
renderLimitOffsetClause( queryPart );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// Spanner does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// Spanner does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ import org.hibernate.LockOptions;
|
||||||
import org.hibernate.dialect.pagination.LimitHandler;
|
import org.hibernate.dialect.pagination.LimitHandler;
|
||||||
import org.hibernate.dialect.pagination.TopLimitHandler;
|
import org.hibernate.dialect.pagination.TopLimitHandler;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.exception.ConstraintViolationException;
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
import org.hibernate.exception.LockTimeoutException;
|
import org.hibernate.exception.LockTimeoutException;
|
||||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||||
|
@ -18,6 +19,11 @@ import org.hibernate.query.TrimSpec;
|
||||||
import org.hibernate.sql.ForUpdateFragment;
|
import org.hibernate.sql.ForUpdateFragment;
|
||||||
import org.hibernate.sql.JoinFragment;
|
import org.hibernate.sql.JoinFragment;
|
||||||
import org.hibernate.sql.Sybase11JoinFragment;
|
import org.hibernate.sql.Sybase11JoinFragment;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.sql.TinyIntTypeDescriptor;
|
import org.hibernate.type.descriptor.sql.TinyIntTypeDescriptor;
|
||||||
|
|
||||||
|
@ -70,6 +76,17 @@ public class SybaseASEDialect extends SybaseDialect {
|
||||||
registerSybaseKeywords();
|
registerSybaseKeywords();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new SybaseASESqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Sybase ASE {@code BIT} type does not allow
|
* The Sybase ASE {@code BIT} type does not allow
|
||||||
* null values, so we don't use it.
|
* null values, so we don't use it.
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.FetchClauseType;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.ast.tree.select.SelectClause;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Sybase ASE.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class SybaseASESqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public SybaseASESqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// Sybase ASE does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// Sybase ASE does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitSqlSelections(SelectClause selectClause) {
|
||||||
|
if ( supportsTopClause() ) {
|
||||||
|
renderTopClause( (QuerySpec) getQueryPartStack().getCurrent(), true );
|
||||||
|
}
|
||||||
|
super.visitSqlSelections( selectClause );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderFetchPlusOffsetExpression(
|
||||||
|
Expression fetchClauseExpression,
|
||||||
|
Expression offsetClauseExpression,
|
||||||
|
int offset) {
|
||||||
|
renderFetchPlusOffsetExpressionAsSingleParameter( fetchClauseExpression, offsetClauseExpression, offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
assertRowsOnlyFetchClauseType( queryPart );
|
||||||
|
if ( !queryPart.isRoot() && queryPart.hasOffsetOrFetchClause() ) {
|
||||||
|
if ( queryPart.getFetchClauseExpression() != null && !supportsTopClause() || queryPart.getOffsetClauseExpression() != null ) {
|
||||||
|
throw new IllegalArgumentException( "Can't emulate offset fetch clause in subquery" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderFetchExpression(Expression fetchExpression) {
|
||||||
|
if ( supportsParameterOffsetFetchExpression() ) {
|
||||||
|
super.renderFetchExpression( fetchExpression );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderExpressionAsLiteral( fetchExpression, getJdbcParameterBindings() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderOffsetExpression(Expression offsetExpression) {
|
||||||
|
if ( supportsParameterOffsetFetchExpression() ) {
|
||||||
|
super.renderOffsetExpression( offsetExpression );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderExpressionAsLiteral( offsetExpression, getJdbcParameterBindings() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needsRowsToSkip() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needsMaxRows() {
|
||||||
|
return !supportsTopClause();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsTopClause() {
|
||||||
|
return getDialect().getVersion() >= 1250;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsParameterOffsetFetchExpression() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,12 @@ import org.hibernate.dialect.identity.SybaseAnywhereIdentityColumnSupport;
|
||||||
import org.hibernate.dialect.pagination.LimitHandler;
|
import org.hibernate.dialect.pagination.LimitHandler;
|
||||||
import org.hibernate.dialect.pagination.TopLimitHandler;
|
import org.hibernate.dialect.pagination.TopLimitHandler;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.type.descriptor.sql.BitTypeDescriptor;
|
import org.hibernate.type.descriptor.sql.BitTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||||
|
|
||||||
|
@ -56,6 +62,17 @@ public class SybaseAnywhereDialect extends SybaseDialect {
|
||||||
registerColumnType( Types.VARBINARY, "long binary)" );
|
registerColumnType( Types.VARBINARY, "long binary)" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new SybaseAnywhereSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsTimezoneTypes() {
|
public boolean supportsTimezoneTypes() {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.ast.tree.select.SelectClause;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Sybase Anywhere.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class SybaseAnywhereSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public SybaseAnywhereSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needsRowsToSkip() {
|
||||||
|
return getDialect().getVersion() < 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderFetchPlusOffsetExpression(
|
||||||
|
Expression fetchClauseExpression,
|
||||||
|
Expression offsetClauseExpression,
|
||||||
|
int offset) {
|
||||||
|
renderFetchPlusOffsetExpressionAsSingleParameter( fetchClauseExpression, offsetClauseExpression, offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitSqlSelections(SelectClause selectClause) {
|
||||||
|
if ( getDialect().getVersion() < 900 ) {
|
||||||
|
renderTopClause( (QuerySpec) getQueryPartStack().getCurrent(), true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
renderTopStartAtClause( (QuerySpec) getQueryPartStack().getCurrent() );
|
||||||
|
}
|
||||||
|
super.visitSqlSelections( selectClause );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderTopClause(QuerySpec querySpec, boolean addOffset) {
|
||||||
|
assertRowsOnlyFetchClauseType( querySpec );
|
||||||
|
super.renderTopClause( querySpec, addOffset );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderTopStartAtClause(QuerySpec querySpec) {
|
||||||
|
assertRowsOnlyFetchClauseType( querySpec );
|
||||||
|
super.renderTopStartAtClause( querySpec );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
// Sybase Anywhere only supports the TOP clause
|
||||||
|
if ( getDialect().getVersion() < 900 && !queryPart.isRoot()
|
||||||
|
&& useOffsetFetchClause( queryPart ) && queryPart.getOffsetClauseExpression() != null ) {
|
||||||
|
throw new IllegalArgumentException( "Can't emulate offset clause in subquery" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// Sybase Anywhere does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// Sybase Anywhere does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,8 +8,14 @@ package org.hibernate.dialect;
|
||||||
|
|
||||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.TemporalUnit;
|
import org.hibernate.query.TemporalUnit;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.type.descriptor.sql.BlobTypeDescriptor;
|
import org.hibernate.type.descriptor.sql.BlobTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
|
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||||
|
@ -45,6 +51,17 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
|
||||||
registerColumnType( Types.BIGINT, "numeric(19,0)" );
|
registerColumnType( Types.BIGINT, "numeric(19,0)" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new SybaseSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getVersion() {
|
public int getVersion() {
|
||||||
return version;
|
return version;
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.FetchClauseType;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Sybase.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class SybaseSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public SybaseSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// Sybase does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// Sybase does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
assertRowsOnlyFetchClauseType( queryPart );
|
||||||
|
if ( !queryPart.isRoot() && queryPart.getOffsetClauseExpression() != null ) {
|
||||||
|
throw new IllegalArgumentException( "Can't emulate offset clause in subquery" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needsRowsToSkip() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needsMaxRows() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ import org.hibernate.dialect.pagination.LimitHandler;
|
||||||
import org.hibernate.dialect.pagination.TopLimitHandler;
|
import org.hibernate.dialect.pagination.TopLimitHandler;
|
||||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
|
||||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
|
||||||
import org.hibernate.mapping.Column;
|
import org.hibernate.mapping.Column;
|
||||||
|
@ -34,6 +35,11 @@ import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||||
import org.hibernate.sql.ForUpdateFragment;
|
import org.hibernate.sql.ForUpdateFragment;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.internal.StandardIndexExporter;
|
import org.hibernate.tool.schema.internal.StandardIndexExporter;
|
||||||
import org.hibernate.tool.schema.spi.Exporter;
|
import org.hibernate.tool.schema.spi.Exporter;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
@ -116,6 +122,17 @@ public class TeradataDialect extends Dialect {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new TeradataSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getVersion() {
|
public int getVersion() {
|
||||||
return version;
|
return version;
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.ast.tree.select.SelectClause;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for Teradata.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class TeradataSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public TeradataSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needsRowsToSkip() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderFetchPlusOffsetExpression(
|
||||||
|
Expression fetchClauseExpression,
|
||||||
|
Expression offsetClauseExpression,
|
||||||
|
int offset) {
|
||||||
|
renderFetchPlusOffsetExpressionAsSingleParameter( fetchClauseExpression, offsetClauseExpression, offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitSqlSelections(SelectClause selectClause) {
|
||||||
|
renderTopClause( (QuerySpec) getQueryPartStack().getCurrent(), true );
|
||||||
|
super.visitSqlSelections( selectClause );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
// Teradata only supports the TOP clause
|
||||||
|
if ( !queryPart.isRoot() && queryPart.getOffsetClauseExpression() != null ) {
|
||||||
|
throw new IllegalArgumentException( "Can't emulate offset clause in subquery" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// Teradata does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// Teradata does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ import org.hibernate.dialect.pagination.LimitHandler;
|
||||||
import org.hibernate.dialect.pagination.TimesTenLimitHandler;
|
import org.hibernate.dialect.pagination.TimesTenLimitHandler;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.TimesTenSequenceSupport;
|
import org.hibernate.dialect.sequence.TimesTenSequenceSupport;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
import org.hibernate.persister.entity.Lockable;
|
import org.hibernate.persister.entity.Lockable;
|
||||||
|
@ -24,6 +25,11 @@ import org.hibernate.query.sqm.mutation.internal.idtable.GlobalTemporaryTableStr
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
import org.hibernate.query.sqm.mutation.internal.idtable.IdTable;
|
||||||
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
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.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorTimesTenDatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorTimesTenDatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
@ -129,6 +135,17 @@ public class TimesTenDialect extends Dialect {
|
||||||
).setArgumentListSignature("(pattern, string[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
@Override
|
||||||
|
protected <T extends JdbcOperation> SqlAstTranslator<T> buildTranslator(
|
||||||
|
SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
return new TimesTenSqlAstTranslator<>( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType) {
|
public String timestampaddPattern(TemporalUnit unit, TemporalType temporalType) {
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
|
@ -262,11 +279,6 @@ public class TimesTenDialect extends Dialect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supportsUnionAll() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsCircularCascadeDeleteConstraints() {
|
public boolean supportsCircularCascadeDeleteConstraints() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
import org.hibernate.sql.ast.tree.select.SelectClause;
|
||||||
|
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SQL AST translator for TimesTen.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class TimesTenSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAstTranslator<T> {
|
||||||
|
|
||||||
|
public TimesTenSqlAstTranslator(SessionFactoryImplementor sessionFactory, Statement statement) {
|
||||||
|
super( sessionFactory, statement );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSearchClause(CteStatement cte) {
|
||||||
|
// TimesTen does not support this, but it's just a hint anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderCycleClause(CteStatement cte) {
|
||||||
|
// TimesTen does not support this, but it can be emulated
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitSqlSelections(SelectClause selectClause) {
|
||||||
|
renderRowsToClause( (QuerySpec) getQueryPartStack().getCurrent() );
|
||||||
|
super.visitSqlSelections( selectClause );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderFetchPlusOffsetExpression(
|
||||||
|
Expression fetchClauseExpression,
|
||||||
|
Expression offsetClauseExpression,
|
||||||
|
int offset) {
|
||||||
|
renderFetchPlusOffsetExpressionAsSingleParameter( fetchClauseExpression, offsetClauseExpression, offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOffsetFetchClause(QueryPart queryPart) {
|
||||||
|
// TimesTen uses ROWS TO clause
|
||||||
|
}
|
||||||
|
}
|
|
@ -101,6 +101,7 @@ public final class TypeNames {
|
||||||
* the default type name otherwise
|
* the default type name otherwise
|
||||||
*/
|
*/
|
||||||
public String get(int typeCode, Long size, Integer precision, Integer scale) {
|
public String get(int typeCode, Long size, Integer precision, Integer scale) {
|
||||||
|
if ( size != null ) {
|
||||||
final Map<Long, String> map = weighted.get( typeCode );
|
final Map<Long, String> map = weighted.get( typeCode );
|
||||||
if ( map != null && map.size() > 0 ) {
|
if ( map != null && map.size() > 0 ) {
|
||||||
// iterate entries ordered by capacity to find first fit
|
// iterate entries ordered by capacity to find first fit
|
||||||
|
@ -110,6 +111,7 @@ public final class TypeNames {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if we get here one of 2 things happened:
|
// if we get here one of 2 things happened:
|
||||||
// 1) There was no weighted registration for that typeCode
|
// 1) There was no weighted registration for that typeCode
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.RowSelection;
|
import org.hibernate.engine.spi.RowSelection;
|
||||||
|
import org.hibernate.query.Limit;
|
||||||
|
|
||||||
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||||
import static java.util.regex.Pattern.compile;
|
import static java.util.regex.Pattern.compile;
|
||||||
|
@ -270,6 +271,143 @@ public abstract class AbstractLimitHandler implements LimitHandler {
|
||||||
return convertToFirstRowValue( selection.getFirstRow() );
|
return convertToFirstRowValue( selection.getFirstRow() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String processSql(String sql, Limit limit) {
|
||||||
|
throw new UnsupportedOperationException( "Paged queries not supported by " + getClass().getName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bindLimitParametersAtStartOfQuery(Limit limit, PreparedStatement statement, int index)
|
||||||
|
throws SQLException {
|
||||||
|
return bindLimitParametersFirst()
|
||||||
|
? bindLimitParameters( limit, statement, index )
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bindLimitParametersAtEndOfQuery(Limit limit, PreparedStatement statement, int index)
|
||||||
|
throws SQLException {
|
||||||
|
return !bindLimitParametersFirst()
|
||||||
|
? bindLimitParameters( limit, statement, index )
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxRows(Limit limit, PreparedStatement statement) throws SQLException {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default implementation of binding parameter values needed by the LIMIT clause.
|
||||||
|
*
|
||||||
|
* @param limit the limit.
|
||||||
|
* @param statement Statement to which to bind limit parameter values.
|
||||||
|
* @param index Index from which to start binding.
|
||||||
|
* @return The number of parameter values bound.
|
||||||
|
* @throws SQLException Indicates problems binding parameter values.
|
||||||
|
*/
|
||||||
|
protected final int bindLimitParameters(Limit limit, PreparedStatement statement, int index)
|
||||||
|
throws SQLException {
|
||||||
|
|
||||||
|
if ( !supportsVariableLimit() ) {
|
||||||
|
//never any parameters to bind
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean hasMaxRows = hasMaxRows( limit );
|
||||||
|
final boolean hasFirstRow = hasFirstRow( limit );
|
||||||
|
|
||||||
|
final boolean bindLimit
|
||||||
|
= hasMaxRows && supportsLimit()
|
||||||
|
|| forceLimitUsage();
|
||||||
|
final boolean bindOffset
|
||||||
|
= hasFirstRow && supportsOffset()
|
||||||
|
|| hasFirstRow && hasMaxRows && supportsLimitOffset();
|
||||||
|
|
||||||
|
if ( !bindLimit && !bindOffset ) {
|
||||||
|
//no parameters to bind this time
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean reverse = bindLimitParametersInReverseOrder();
|
||||||
|
|
||||||
|
if ( bindOffset ) {
|
||||||
|
statement.setInt(
|
||||||
|
index + ( reverse || !bindLimit ? 1 : 0 ),
|
||||||
|
getFirstRow( limit )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ( bindLimit ) {
|
||||||
|
statement.setInt(
|
||||||
|
index + ( reverse || !bindOffset ? 0 : 1 ),
|
||||||
|
getMaxOrLimit( limit )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bindOffset && bindLimit ? 2 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is a max row limit indicated?
|
||||||
|
*
|
||||||
|
* @param limit The limit
|
||||||
|
*
|
||||||
|
* @return Whether a max row limit was indicated
|
||||||
|
*/
|
||||||
|
public static boolean hasMaxRows(Limit limit) {
|
||||||
|
return limit != null
|
||||||
|
&& limit.getMaxRows() != null
|
||||||
|
&& limit.getMaxRows() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is a first row limit indicated?
|
||||||
|
*
|
||||||
|
* @param limit The limit
|
||||||
|
*
|
||||||
|
* @return Whether a first row limit was indicated
|
||||||
|
*/
|
||||||
|
public static boolean hasFirstRow(Limit limit) {
|
||||||
|
return limit != null
|
||||||
|
&& limit.getFirstRow() != null
|
||||||
|
&& limit.getFirstRow() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some dialect-specific LIMIT clauses require the maximum last row number
|
||||||
|
* (aka, first_row_number + total_row_count), while others require the maximum
|
||||||
|
* returned row count (the total maximum number of rows to return).
|
||||||
|
*
|
||||||
|
* @param limit The limit
|
||||||
|
*
|
||||||
|
* @return The appropriate value to bind into the limit clause.
|
||||||
|
*/
|
||||||
|
protected final int getMaxOrLimit(Limit limit) {
|
||||||
|
if ( limit == null || limit.getMaxRows() == null ) {
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
final int firstRow = getFirstRow( limit );
|
||||||
|
final int maxRows = limit.getMaxRows();
|
||||||
|
final int maxOrLimit = useMaxForLimit()
|
||||||
|
? maxRows + firstRow //TODO: maxRows + firstRow - 1, surely?
|
||||||
|
: maxRows;
|
||||||
|
// Use Integer.MAX_VALUE on overflow
|
||||||
|
return maxOrLimit < 0 ? Integer.MAX_VALUE : maxOrLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the indicated first row for pagination
|
||||||
|
*
|
||||||
|
* @param limit The limit
|
||||||
|
*
|
||||||
|
* @return The first row
|
||||||
|
*/
|
||||||
|
protected final int getFirstRow(Limit limit) {
|
||||||
|
if ( limit == null || limit.getFirstRow() == null ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return convertToFirstRowValue( limit.getFirstRow() );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a fragment of SQL right after
|
* Insert a fragment of SQL right after
|
||||||
* {@code SELECT}, but before {@code DISTINCT}
|
* {@code SELECT}, but before {@code DISTINCT}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.dialect.pagination;
|
package org.hibernate.dialect.pagination;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.RowSelection;
|
import org.hibernate.engine.spi.RowSelection;
|
||||||
|
import org.hibernate.query.Limit;
|
||||||
|
|
||||||
import static java.lang.String.valueOf;
|
import static java.lang.String.valueOf;
|
||||||
|
|
||||||
|
@ -39,8 +40,21 @@ public abstract class AbstractNoOffsetLimitHandler extends AbstractLimitHandler
|
||||||
}
|
}
|
||||||
String limitClause = limitClause();
|
String limitClause = limitClause();
|
||||||
if ( !supportsVariableLimit() ) {
|
if ( !supportsVariableLimit() ) {
|
||||||
String limit = valueOf( getMaxOrLimit(selection) );
|
String limitLiteral = valueOf( getMaxOrLimit(selection) );
|
||||||
limitClause = limitClause.replace( "?", limit );
|
limitClause = limitClause.replace( "?", limitLiteral );
|
||||||
|
}
|
||||||
|
return insert( limitClause, sql );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String processSql(String sql, Limit limit) {
|
||||||
|
if ( !hasMaxRows( limit ) ) {
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
String limitClause = limitClause();
|
||||||
|
if ( !supportsVariableLimit() ) {
|
||||||
|
String limitLiteral = valueOf( getMaxOrLimit( limit ) );
|
||||||
|
limitClause = limitClause.replace( "?", limitLiteral );
|
||||||
}
|
}
|
||||||
return insert( limitClause, sql );
|
return insert( limitClause, sql );
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.dialect.pagination;
|
package org.hibernate.dialect.pagination;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.RowSelection;
|
import org.hibernate.engine.spi.RowSelection;
|
||||||
|
import org.hibernate.query.Limit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Superclass for simple {@link LimitHandler}s that don't
|
* Superclass for simple {@link LimitHandler}s that don't
|
||||||
|
@ -26,6 +27,14 @@ public abstract class AbstractSimpleLimitHandler extends AbstractLimitHandler {
|
||||||
return insert( limitClause( hasFirstRow( selection ) ), sql );
|
return insert( limitClause( hasFirstRow( selection ) ), sql );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String processSql(String sql, Limit limit) {
|
||||||
|
if ( !hasMaxRows( limit ) ) {
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
return insert( limitClause( hasFirstRow( limit ) ), sql );
|
||||||
|
}
|
||||||
|
|
||||||
protected String insert(String limitClause, String sql) {
|
protected String insert(String limitClause, String sql) {
|
||||||
return insertBeforeForUpdate( limitClause, sql );
|
return insertBeforeForUpdate( limitClause, sql );
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.dialect.pagination;
|
package org.hibernate.dialect.pagination;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.RowSelection;
|
import org.hibernate.engine.spi.RowSelection;
|
||||||
|
import org.hibernate.query.Limit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link LimitHandler} for DB2. Uses {@code FETCH FIRST n ROWS ONLY},
|
* A {@link LimitHandler} for DB2. Uses {@code FETCH FIRST n ROWS ONLY},
|
||||||
|
@ -34,8 +35,29 @@ public class LegacyDB2LimitHandler extends AbstractLimitHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String fetchFirstRows(RowSelection selection) {
|
private String fetchFirstRows(RowSelection limit) {
|
||||||
return " fetch first " + getMaxOrLimit( selection ) + " rows only";
|
return " fetch first " + getMaxOrLimit( limit ) + " rows only";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String processSql(String sql, Limit limit) {
|
||||||
|
if ( hasFirstRow( limit ) ) {
|
||||||
|
//nest the main query in an outer select
|
||||||
|
return "select * from ( select row_.*, rownumber() over(order by order of row_) as rownumber_ from ( "
|
||||||
|
+ sql + fetchFirstRows( limit )
|
||||||
|
+ " ) as row_ ) as query_ where rownumber_ > "
|
||||||
|
+ limit.getFirstRow()
|
||||||
|
+ " order by rownumber_";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//on DB2, offset/fetch comes after all the
|
||||||
|
//various "for update"ish clauses
|
||||||
|
return insertAtEnd( fetchFirstRows( limit ), sql );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String fetchFirstRows(Limit limit) {
|
||||||
|
return " fetch first " + getMaxOrLimit( limit ) + " rows only";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.pagination;
|
||||||
|
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.spi.RowSelection;
|
import org.hibernate.engine.spi.RowSelection;
|
||||||
|
import org.hibernate.query.Limit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stub {@link LimitHandler} that delegates all operations
|
* Stub {@link LimitHandler} that delegates all operations
|
||||||
|
@ -81,4 +82,20 @@ public class LegacyLimitHandler extends AbstractLimitHandler {
|
||||||
getMaxOrLimit( selection )
|
getMaxOrLimit( selection )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String processSql(String sql, Limit limit) {
|
||||||
|
final boolean useLimitOffset
|
||||||
|
= supportsOffset()
|
||||||
|
&& hasFirstRow( limit )
|
||||||
|
|| supportsLimit()
|
||||||
|
&& supportsLimitOffset()
|
||||||
|
&& hasFirstRow( limit )
|
||||||
|
&& hasMaxRows( limit );
|
||||||
|
return dialect.getLimitString(
|
||||||
|
sql,
|
||||||
|
useLimitOffset ? getFirstRow( limit ) : 0,
|
||||||
|
getMaxOrLimit( limit )
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.dialect.pagination;
|
package org.hibernate.dialect.pagination;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.RowSelection;
|
import org.hibernate.engine.spi.RowSelection;
|
||||||
|
import org.hibernate.query.Limit;
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
@ -56,6 +57,41 @@ public class LegacyOracleLimitHandler extends AbstractLimitHandler {
|
||||||
return pagingSelect.toString();
|
return pagingSelect.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String processSql(String sql, Limit limit) {
|
||||||
|
final boolean hasOffset = hasFirstRow( limit );
|
||||||
|
sql = sql.trim();
|
||||||
|
|
||||||
|
String forUpdateClause = null;
|
||||||
|
Matcher forUpdateMatcher = getForUpdatePattern().matcher( sql );
|
||||||
|
if ( forUpdateMatcher.find() ) {
|
||||||
|
int forUpdateIndex = forUpdateMatcher.start();
|
||||||
|
// save 'for update ...' and then remove it
|
||||||
|
forUpdateClause = sql.substring( forUpdateIndex );
|
||||||
|
sql = sql.substring( 0, forUpdateIndex );
|
||||||
|
}
|
||||||
|
|
||||||
|
final StringBuilder pagingSelect = new StringBuilder( sql.length() + 100 );
|
||||||
|
if ( hasOffset ) {
|
||||||
|
pagingSelect.append( "select * from (select row_.*, rownum rownum_ from (" ).append( sql );
|
||||||
|
if ( version < 9 ) {
|
||||||
|
pagingSelect.append( ") row_) where rownum_ <= ? and rownum_ > ?" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pagingSelect.append( ") row_ where rownum <= ?) where rownum_ > ?" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pagingSelect.append( "select * from (" ).append( sql ).append( ") where rownum <= ?" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( forUpdateClause != null ) {
|
||||||
|
pagingSelect.append( forUpdateClause );
|
||||||
|
}
|
||||||
|
|
||||||
|
return pagingSelect.toString();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsLimit() {
|
public boolean supportsLimit() {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -10,6 +10,8 @@ import java.sql.PreparedStatement;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.RowSelection;
|
import org.hibernate.engine.spi.RowSelection;
|
||||||
|
import org.hibernate.query.Limit;
|
||||||
|
import org.hibernate.query.spi.QueryOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contract defining dialect-specific limit and offset handling.
|
* Contract defining dialect-specific limit and offset handling.
|
||||||
|
@ -40,6 +42,58 @@ public interface LimitHandler {
|
||||||
*/
|
*/
|
||||||
boolean supportsLimitOffset();
|
boolean supportsLimitOffset();
|
||||||
|
|
||||||
|
default String processSql(String sql, Limit limit) {
|
||||||
|
return processSql(
|
||||||
|
sql,
|
||||||
|
limit == null ? null : new RowSelection(
|
||||||
|
limit.getFirstRow(),
|
||||||
|
limit.getMaxRows(),
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
default int bindLimitParametersAtStartOfQuery(Limit limit, PreparedStatement statement, int index)
|
||||||
|
throws SQLException {
|
||||||
|
return bindLimitParametersAtStartOfQuery(
|
||||||
|
limit == null ? null : new RowSelection(
|
||||||
|
limit.getFirstRow(),
|
||||||
|
limit.getMaxRows(),
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
),
|
||||||
|
statement,
|
||||||
|
index
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
default int bindLimitParametersAtEndOfQuery(Limit limit, PreparedStatement statement, int index)
|
||||||
|
throws SQLException {
|
||||||
|
return bindLimitParametersAtEndOfQuery(
|
||||||
|
limit == null ? null : new RowSelection(
|
||||||
|
limit.getFirstRow(),
|
||||||
|
limit.getMaxRows(),
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
),
|
||||||
|
statement,
|
||||||
|
index
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void setMaxRows(Limit limit, PreparedStatement statement) throws SQLException {
|
||||||
|
setMaxRows(
|
||||||
|
limit == null ? null : new RowSelection(
|
||||||
|
limit.getFirstRow(),
|
||||||
|
limit.getMaxRows(),
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
),
|
||||||
|
statement
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return processed SQL query.
|
* Return processed SQL query.
|
||||||
*
|
*
|
||||||
|
@ -47,7 +101,9 @@ public interface LimitHandler {
|
||||||
* @param selection the selection criteria for rows.
|
* @param selection the selection criteria for rows.
|
||||||
*
|
*
|
||||||
* @return Query statement with LIMIT clause applied.
|
* @return Query statement with LIMIT clause applied.
|
||||||
|
* @deprecated todo (6.0): remove in favor of Limit version?
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
String processSql(String sql, RowSelection selection);
|
String processSql(String sql, RowSelection selection);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +116,9 @@ public interface LimitHandler {
|
||||||
* @param index Index from which to start binding.
|
* @param index Index from which to start binding.
|
||||||
* @return The number of parameter values bound.
|
* @return The number of parameter values bound.
|
||||||
* @throws SQLException Indicates problems binding parameter values.
|
* @throws SQLException Indicates problems binding parameter values.
|
||||||
|
* @deprecated todo (6.0): remove in favor of Limit version?
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
int bindLimitParametersAtStartOfQuery(RowSelection selection, PreparedStatement statement, int index)
|
int bindLimitParametersAtStartOfQuery(RowSelection selection, PreparedStatement statement, int index)
|
||||||
throws SQLException;
|
throws SQLException;
|
||||||
|
|
||||||
|
@ -74,7 +132,9 @@ public interface LimitHandler {
|
||||||
* @param index Index from which to start binding.
|
* @param index Index from which to start binding.
|
||||||
* @return The number of parameter values bound.
|
* @return The number of parameter values bound.
|
||||||
* @throws SQLException Indicates problems binding parameter values.
|
* @throws SQLException Indicates problems binding parameter values.
|
||||||
|
* @deprecated todo (6.0): remove in favor of Limit version?
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
int bindLimitParametersAtEndOfQuery(RowSelection selection, PreparedStatement statement, int index)
|
int bindLimitParametersAtEndOfQuery(RowSelection selection, PreparedStatement statement, int index)
|
||||||
throws SQLException;
|
throws SQLException;
|
||||||
|
|
||||||
|
@ -86,6 +146,8 @@ public interface LimitHandler {
|
||||||
* @param selection the selection criteria for rows.
|
* @param selection the selection criteria for rows.
|
||||||
* @param statement Statement which number of returned rows shall be limited.
|
* @param statement Statement which number of returned rows shall be limited.
|
||||||
* @throws SQLException Indicates problems while limiting maximum rows returned.
|
* @throws SQLException Indicates problems while limiting maximum rows returned.
|
||||||
|
* @deprecated todo (6.0): remove in favor of Limit version?
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
void setMaxRows(RowSelection selection, PreparedStatement statement) throws SQLException;
|
void setMaxRows(RowSelection selection, PreparedStatement statement) throws SQLException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect.pagination;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.RowSelection;
|
||||||
|
import org.hibernate.query.Limit;
|
||||||
|
|
||||||
|
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||||
|
import static java.util.regex.Pattern.compile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler not supporting query LIMIT clause. JDBC API is used to set maximum number of returned rows.
|
||||||
|
*
|
||||||
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
|
*/
|
||||||
|
public class NoopLimitHandler extends AbstractLimitHandler {
|
||||||
|
|
||||||
|
public static final NoopLimitHandler INSTANCE = new NoopLimitHandler();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String processSql(String sql, RowSelection selection) {
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bindLimitParametersAtStartOfQuery(RowSelection selection, PreparedStatement statement, int index) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bindLimitParametersAtEndOfQuery(RowSelection selection, PreparedStatement statement, int index) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxRows(RowSelection selection, PreparedStatement statement) throws SQLException {
|
||||||
|
if ( selection != null && selection.getMaxRows() != null && selection.getMaxRows() > 0 ) {
|
||||||
|
final int maxRows = selection.getMaxRows() + convertToFirstRowValue(
|
||||||
|
selection.getFirstRow() == null ? 0 : selection.getFirstRow()
|
||||||
|
);
|
||||||
|
// Use Integer.MAX_VALUE on overflow
|
||||||
|
if ( maxRows < 0 ) {
|
||||||
|
statement.setMaxRows( Integer.MAX_VALUE );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
statement.setMaxRows( maxRows );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String processSql(String sql, Limit limit) {
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bindLimitParametersAtStartOfQuery(Limit limit, PreparedStatement statement, int index) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bindLimitParametersAtEndOfQuery(Limit limit, PreparedStatement statement, int index) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxRows(Limit limit, PreparedStatement statement) throws SQLException {
|
||||||
|
if ( limit != null && limit.getMaxRows() != null && limit.getMaxRows() > 0 ) {
|
||||||
|
final int maxRows = limit.getMaxRows() + convertToFirstRowValue(
|
||||||
|
limit.getFirstRow() == null ? 0 : limit.getFirstRow()
|
||||||
|
);
|
||||||
|
// Use Integer.MAX_VALUE on overflow
|
||||||
|
if ( maxRows < 0 ) {
|
||||||
|
statement.setMaxRows( Integer.MAX_VALUE );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
statement.setMaxRows( maxRows );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.dialect.pagination;
|
package org.hibernate.dialect.pagination;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.RowSelection;
|
import org.hibernate.engine.spi.RowSelection;
|
||||||
|
import org.hibernate.query.Limit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link LimitHandler} for databases which support the
|
* A {@link LimitHandler} for databases which support the
|
||||||
|
@ -71,6 +72,52 @@ public class OffsetFetchLimitHandler extends AbstractLimitHandler {
|
||||||
return insert( offsetFetch.toString(), sql );
|
return insert( offsetFetch.toString(), sql );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String processSql(String sql, Limit limit) {
|
||||||
|
|
||||||
|
boolean hasFirstRow = hasFirstRow(limit);
|
||||||
|
boolean hasMaxRows = hasMaxRows(limit);
|
||||||
|
|
||||||
|
if ( !hasFirstRow && !hasMaxRows ) {
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder offsetFetch = new StringBuilder();
|
||||||
|
|
||||||
|
begin(sql, offsetFetch, hasFirstRow, hasMaxRows);
|
||||||
|
|
||||||
|
if ( hasFirstRow ) {
|
||||||
|
offsetFetch.append( " offset " );
|
||||||
|
if ( supportsVariableLimit() ) {
|
||||||
|
offsetFetch.append( "?" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offsetFetch.append( limit.getFirstRow() );
|
||||||
|
}
|
||||||
|
if ( !isIngres() ) {
|
||||||
|
offsetFetch.append( " rows" );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if ( hasMaxRows ) {
|
||||||
|
if ( hasFirstRow ) {
|
||||||
|
offsetFetch.append( " fetch next " );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offsetFetch.append( " fetch first " );
|
||||||
|
}
|
||||||
|
if ( supportsVariableLimit() ) {
|
||||||
|
offsetFetch.append( "?" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offsetFetch.append( getMaxOrLimit( limit ) );
|
||||||
|
}
|
||||||
|
offsetFetch.append( " rows only" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return insert( offsetFetch.toString(), sql );
|
||||||
|
}
|
||||||
|
|
||||||
void begin(String sql, StringBuilder offsetFetch, boolean hasFirstRow, boolean hasMaxRows) {}
|
void begin(String sql, StringBuilder offsetFetch, boolean hasFirstRow, boolean hasMaxRows) {}
|
||||||
|
|
||||||
String insert(String offsetFetch, String sql) {
|
String insert(String offsetFetch, String sql) {
|
||||||
|
|
|
@ -15,6 +15,7 @@ import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.RowSelection;
|
import org.hibernate.engine.spi.RowSelection;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
import org.hibernate.query.Limit;
|
||||||
|
|
||||||
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||||
import static java.util.regex.Pattern.compile;
|
import static java.util.regex.Pattern.compile;
|
||||||
|
@ -132,6 +133,84 @@ public class SQLServer2005LimitHandler extends AbstractLimitHandler {
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the offset of the given {@link RowSelection} is {@literal 0},
|
||||||
|
* add a {@code top(?)} clause to the given SQL query. When the offset
|
||||||
|
* is non-zero, wrap the given query in an outer query that limits the
|
||||||
|
* results using the {@code row_number()} window function.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* with query_ as (
|
||||||
|
* select row_.*, row_number()
|
||||||
|
* over (order by current_timestamp) AS rownumber_
|
||||||
|
* from ( [original-query] ) row_
|
||||||
|
* )
|
||||||
|
* select [alias-list] from query_
|
||||||
|
* where rownumber_ >= ? and rownumber_ < ?
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* Where {@code [original-query]} is the original SQL query, with a
|
||||||
|
* {@code top()} clause added iff the query has an {@code order by}
|
||||||
|
* clause, and with generated aliases added to any elements of the
|
||||||
|
* projection list that don't already have aliases, and
|
||||||
|
* {@code [alias-list]} is a list of aliases in the projection list.
|
||||||
|
*
|
||||||
|
* @return A new SQL statement
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String processSql(String sql, Limit limit) {
|
||||||
|
sql = sql.trim();
|
||||||
|
if ( sql.endsWith(";") ) {
|
||||||
|
sql = sql.substring( 0, sql.length()-1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
final int selectOffset = Keyword.SELECT.rootOffset( sql );
|
||||||
|
final int afterSelectOffset = Keyword.SELECT.endOffset( sql, selectOffset );
|
||||||
|
final int fromOffset = Keyword.FROM.rootOffset( sql ); //TODO: what if there is no 'from' clause?!
|
||||||
|
|
||||||
|
boolean hasCommonTables = Keyword.WITH.occursAt( sql, 0 );
|
||||||
|
boolean hasOrderBy = Keyword.ORDER_BY.rootOffset( sql ) > 0;
|
||||||
|
boolean hasFirstRow = hasFirstRow( limit );
|
||||||
|
|
||||||
|
final StringBuilder result = new StringBuilder( sql );
|
||||||
|
|
||||||
|
if ( !hasFirstRow || hasOrderBy ) {
|
||||||
|
result.insert( afterSelectOffset, " top(?)" );
|
||||||
|
topAdded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( hasFirstRow ) {
|
||||||
|
|
||||||
|
// enclose original SQL statement with outer query
|
||||||
|
// that provides the rownumber_ column
|
||||||
|
|
||||||
|
String aliases = selectAliases( sql, afterSelectOffset, fromOffset, result ); //warning: changes result by side-effect
|
||||||
|
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_ < ?" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bindLimitParametersAtStartOfQuery(Limit limit, PreparedStatement statement, int index) throws SQLException {
|
||||||
|
if ( topAdded ) {
|
||||||
|
// bind parameter to top(?)
|
||||||
|
statement.setInt( index, getMaxOrLimit( limit ) - 1 );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bindLimitParametersAtEndOfQuery(Limit limit, PreparedStatement statement, int index) throws SQLException {
|
||||||
|
return hasFirstRow( limit )
|
||||||
|
? super.bindLimitParametersAtEndOfQuery( limit, statement, index )
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add any missing aliases to the given {@code select} list, and return
|
* Add any missing aliases to the given {@code select} list, and return
|
||||||
* comma-separated list of all aliases in the list, unless the given list
|
* comma-separated list of all aliases in the list, unless the given list
|
||||||
|
|
|
@ -52,7 +52,8 @@ public class SQLServer2012LimitHandler extends OffsetFetchLimitHandler {
|
||||||
//if we can find the end of the select
|
//if we can find the end of the select
|
||||||
//clause, we will add a dummy column to
|
//clause, we will add a dummy column to
|
||||||
//it below, so order by that column
|
//it below, so order by that column
|
||||||
offsetFetch.append("zero_");
|
// Always need an order by clause: https://blog.jooq.org/2014/05/13/sql-server-trick-circumvent-missing-order-by-clause/
|
||||||
|
offsetFetch.append("@@version");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//otherwise order by the first column
|
//otherwise order by the first column
|
||||||
|
@ -66,22 +67,4 @@ public class SQLServer2012LimitHandler extends OffsetFetchLimitHandler {
|
||||||
offsetFetch.append(" offset 0 rows");
|
offsetFetch.append(" offset 0 rows");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
String insert(String offsetFetch, String sql) {
|
|
||||||
String result = super.insert( offsetFetch, sql );
|
|
||||||
if ( Keyword.ORDER_BY.rootOffset( sql ) <= 0 ) {
|
|
||||||
int from = Keyword.FROM.rootOffset( sql );
|
|
||||||
if ( from > 0 ) {
|
|
||||||
//insert the dummy column at the end of
|
|
||||||
//the select list (don't add it at the
|
|
||||||
//start, 'cos that would mess up reading
|
|
||||||
//results by index)
|
|
||||||
return new StringBuilder( result )
|
|
||||||
.insert( from, ", 0 as zero_ " )
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.dialect.pagination;
|
package org.hibernate.dialect.pagination;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.RowSelection;
|
import org.hibernate.engine.spi.RowSelection;
|
||||||
|
import org.hibernate.query.Limit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link LimitHandler} for Informix which supports the syntax
|
* A {@link LimitHandler} for Informix which supports the syntax
|
||||||
|
@ -56,6 +57,40 @@ public class SkipFirstLimitHandler extends AbstractLimitHandler {
|
||||||
return insertAfterSelect( sql, skipFirst.toString() );
|
return insertAfterSelect( sql, skipFirst.toString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String processSql(String sql, Limit limit) {
|
||||||
|
|
||||||
|
boolean hasFirstRow = hasFirstRow( limit );
|
||||||
|
boolean hasMaxRows = hasMaxRows( limit );
|
||||||
|
|
||||||
|
if ( !hasFirstRow && !hasMaxRows ) {
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder skipFirst = new StringBuilder();
|
||||||
|
|
||||||
|
if ( supportsVariableLimit() ) {
|
||||||
|
if ( hasFirstRow ) {
|
||||||
|
skipFirst.append( " skip ?" );
|
||||||
|
}
|
||||||
|
if ( hasMaxRows ) {
|
||||||
|
skipFirst.append( " first ?" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( hasFirstRow ) {
|
||||||
|
skipFirst.append( " skip " )
|
||||||
|
.append( limit.getFirstRow() );
|
||||||
|
}
|
||||||
|
if ( hasMaxRows ) {
|
||||||
|
skipFirst.append( " first " )
|
||||||
|
.append( getMaxOrLimit( limit ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return insertAfterSelect( sql, skipFirst.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean supportsLimit() {
|
public final boolean supportsLimit() {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect.sequence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sequence support for {@link org.hibernate.dialect.MariaDBDialect}.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public final class MariaDBSequenceSupport extends ANSISequenceSupport {
|
||||||
|
|
||||||
|
public static final SequenceSupport INSTANCE = new MariaDBSequenceSupport();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean sometimesNeedsStartingValue() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,9 @@ package org.hibernate.engine.spi;
|
||||||
* Represents a selection criteria for rows in a JDBC {@link java.sql.ResultSet}
|
* Represents a selection criteria for rows in a JDBC {@link java.sql.ResultSet}
|
||||||
*
|
*
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
|
* @deprecated todo (6.0): remove in favor of Limit within QueryOptions?
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public final class RowSelection {
|
public final class RowSelection {
|
||||||
private Integer firstRow;
|
private Integer firstRow;
|
||||||
private Integer maxRows;
|
private Integer maxRows;
|
||||||
|
|
|
@ -275,6 +275,18 @@ public final class CollectionHelper {
|
||||||
return objects == null || objects.length == 0;
|
return objects == null || objects.length == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> List<T> listOf(T value1) {
|
||||||
|
final List<T> list = new ArrayList<>( 1 );
|
||||||
|
list.add( value1 );
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> List<T> listOf(T... values) {
|
||||||
|
final List<T> list = new ArrayList<>( values.length );
|
||||||
|
Collections.addAll( list, values );
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> Set<T> setOf(T... values) {
|
public static <T> Set<T> setOf(T... values) {
|
||||||
final HashSet<T> set = new HashSet<>( determineProperSizing( values.length ) );
|
final HashSet<T> set = new HashSet<>( determineProperSizing( values.length ) );
|
||||||
Collections.addAll( set, values );
|
Collections.addAll( set, values );
|
||||||
|
|
|
@ -99,11 +99,10 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
|
||||||
sessionFactory
|
sessionFactory
|
||||||
);
|
);
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlSelect );
|
|
||||||
|
|
||||||
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
||||||
|
|
||||||
applyNaturalIdAsJdbcParameters( bindValue, jdbcParameters, jdbcParamBindings, session );
|
applyNaturalIdAsJdbcParameters( bindValue, jdbcParameters, jdbcParamBindings, session );
|
||||||
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlSelect )
|
||||||
|
.translate( jdbcParamBindings, QueryOptions.NONE );
|
||||||
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
final List<T> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
|
final List<T> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
|
||||||
|
@ -179,8 +178,6 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
|
||||||
sessionFactory
|
sessionFactory
|
||||||
);
|
);
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlSelect );
|
|
||||||
|
|
||||||
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
||||||
applyNaturalIdAsJdbcParameters(
|
applyNaturalIdAsJdbcParameters(
|
||||||
bindValue,
|
bindValue,
|
||||||
|
@ -188,6 +185,8 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
|
||||||
jdbcParamBindings,
|
jdbcParamBindings,
|
||||||
session
|
session
|
||||||
);
|
);
|
||||||
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlSelect )
|
||||||
|
.translate( jdbcParamBindings, QueryOptions.NONE );
|
||||||
|
|
||||||
final List<?> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
|
final List<?> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
|
||||||
jdbcSelect,
|
jdbcSelect,
|
||||||
|
@ -252,10 +251,7 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
|
||||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlSelect );
|
|
||||||
|
|
||||||
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
||||||
|
|
||||||
int offset = jdbcParamBindings.registerParametersForEachJdbcValue(
|
int offset = jdbcParamBindings.registerParametersForEachJdbcValue(
|
||||||
id,
|
id,
|
||||||
Clause.WHERE,
|
Clause.WHERE,
|
||||||
|
@ -264,6 +260,8 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
|
||||||
session
|
session
|
||||||
);
|
);
|
||||||
assert offset == jdbcParameters.size();
|
assert offset == jdbcParameters.size();
|
||||||
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlSelect )
|
||||||
|
.translate( jdbcParamBindings, QueryOptions.NONE );
|
||||||
|
|
||||||
final List<Object[]> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
|
final List<Object[]> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
|
||||||
jdbcSelect,
|
jdbcSelect,
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
package org.hibernate.loader.ast.internal;
|
package org.hibernate.loader.ast.internal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
|
@ -30,7 +29,6 @@ import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
|
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
||||||
import org.hibernate.sql.exec.spi.Callback;
|
import org.hibernate.sql.exec.spi.Callback;
|
||||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||||
|
@ -116,11 +114,7 @@ public class CollectionElementLoaderByIndex implements Loader {
|
||||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory )
|
|
||||||
.translate( sqlAst );
|
|
||||||
|
|
||||||
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount );
|
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount );
|
||||||
jdbcSelect.bindFilterJdbcParameters( jdbcParameterBindings );
|
|
||||||
|
|
||||||
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
|
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
|
||||||
key,
|
key,
|
||||||
|
@ -138,6 +132,8 @@ public class CollectionElementLoaderByIndex implements Loader {
|
||||||
session
|
session
|
||||||
);
|
);
|
||||||
assert offset == jdbcParameters.size();
|
assert offset == jdbcParameters.size();
|
||||||
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlAst )
|
||||||
|
.translate( jdbcParameterBindings, QueryOptions.NONE );
|
||||||
|
|
||||||
List<Object> list = jdbcServices.getJdbcSelectExecutor().list(
|
List<Object> list = jdbcServices.getJdbcSelectExecutor().list(
|
||||||
jdbcSelect,
|
jdbcSelect,
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
package org.hibernate.loader.ast.internal;
|
package org.hibernate.loader.ast.internal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
|
@ -27,7 +26,6 @@ import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
|
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
||||||
import org.hibernate.sql.exec.spi.Callback;
|
import org.hibernate.sql.exec.spi.Callback;
|
||||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||||
|
@ -159,7 +157,8 @@ public class CollectionLoaderBatchKey implements CollectionLoader {
|
||||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlAst );
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlAst )
|
||||||
|
.translate( null, QueryOptions.NONE );
|
||||||
|
|
||||||
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount * smallBatchLength );
|
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount * smallBatchLength );
|
||||||
jdbcSelect.bindFilterJdbcParameters( jdbcParameterBindings );
|
jdbcSelect.bindFilterJdbcParameters( jdbcParameterBindings );
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
package org.hibernate.loader.ast.internal;
|
package org.hibernate.loader.ast.internal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
|
@ -26,7 +25,6 @@ import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
|
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
||||||
import org.hibernate.sql.exec.spi.Callback;
|
import org.hibernate.sql.exec.spi.Callback;
|
||||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||||
|
@ -95,11 +93,7 @@ public class CollectionLoaderSingleKey implements CollectionLoader {
|
||||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlAst );
|
|
||||||
|
|
||||||
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount );
|
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount );
|
||||||
jdbcSelect.bindFilterJdbcParameters( jdbcParameterBindings );
|
|
||||||
|
|
||||||
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
|
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
|
||||||
key,
|
key,
|
||||||
Clause.WHERE,
|
Clause.WHERE,
|
||||||
|
@ -108,6 +102,8 @@ public class CollectionLoaderSingleKey implements CollectionLoader {
|
||||||
session
|
session
|
||||||
);
|
);
|
||||||
assert offset == jdbcParameters.size();
|
assert offset == jdbcParameters.size();
|
||||||
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlAst )
|
||||||
|
.translate( jdbcParameterBindings, QueryOptions.NONE );
|
||||||
|
|
||||||
jdbcServices.getJdbcSelectExecutor().list(
|
jdbcServices.getJdbcSelectExecutor().list(
|
||||||
jdbcSelect,
|
jdbcSelect,
|
||||||
|
|
|
@ -68,7 +68,8 @@ public class CollectionLoaderSubSelectFetch implements CollectionLoader {
|
||||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlAst );
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlAst )
|
||||||
|
.translate( subselect.getLoadingJdbcParameterBindings(), QueryOptions.NONE );
|
||||||
|
|
||||||
jdbcServices.getJdbcSelectExecutor().list(
|
jdbcServices.getJdbcSelectExecutor().list(
|
||||||
jdbcSelect,
|
jdbcSelect,
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
package org.hibernate.loader.ast.internal;
|
package org.hibernate.loader.ast.internal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
@ -32,7 +31,6 @@ import org.hibernate.sql.ast.tree.from.TableReference;
|
||||||
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
|
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
|
||||||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
|
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
|
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
|
||||||
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
|
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
|
||||||
|
@ -185,7 +183,8 @@ class DatabaseSnapshotExecutor {
|
||||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||||
|
|
||||||
jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( selectStatement );
|
jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, selectStatement )
|
||||||
|
.translate( null, QueryOptions.NONE );
|
||||||
}
|
}
|
||||||
|
|
||||||
Object[] loadDatabaseSnapshot(Object id, SharedSessionContractImplementor session) {
|
Object[] loadDatabaseSnapshot(Object id, SharedSessionContractImplementor session) {
|
||||||
|
|
|
@ -64,6 +64,7 @@ import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
|
||||||
import org.hibernate.sql.ast.tree.predicate.InListPredicate;
|
import org.hibernate.sql.ast.tree.predicate.InListPredicate;
|
||||||
import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate;
|
import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate;
|
||||||
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
|
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
|
||||||
|
@ -882,7 +883,7 @@ public class LoaderSelectBuilder {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private QuerySpec generateSubSelect(
|
private QueryPart generateSubSelect(
|
||||||
PluralAttributeMapping attributeMapping,
|
PluralAttributeMapping attributeMapping,
|
||||||
TableGroup rootTableGroup,
|
TableGroup rootTableGroup,
|
||||||
SubselectFetch subselect,
|
SubselectFetch subselect,
|
||||||
|
|
|
@ -25,7 +25,7 @@ import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.ResultListTransformer;
|
import org.hibernate.query.ResultListTransformer;
|
||||||
import org.hibernate.query.TupleTransformer;
|
import org.hibernate.query.TupleTransformer;
|
||||||
import org.hibernate.query.spi.QueryOptions;
|
import org.hibernate.query.spi.QueryOptions;
|
||||||
import org.hibernate.query.sqm.sql.internal.SqlAstQuerySpecProcessingStateImpl;
|
import org.hibernate.query.sqm.sql.internal.SqlAstQueryPartProcessingStateImpl;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.spi.FromClauseAccess;
|
import org.hibernate.sql.ast.spi.FromClauseAccess;
|
||||||
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
|
import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator;
|
||||||
|
@ -35,6 +35,7 @@ import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstProcessingState;
|
import org.hibernate.sql.ast.spi.SqlAstProcessingState;
|
||||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
import org.hibernate.sql.results.graph.Fetch;
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
|
@ -49,11 +50,10 @@ public class LoaderSqlAstCreationState
|
||||||
List<Fetch> visitFetches(FetchParent fetchParent, QuerySpec querySpec, LoaderSqlAstCreationState creationState);
|
List<Fetch> visitFetches(FetchParent fetchParent, QuerySpec querySpec, LoaderSqlAstCreationState creationState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final QuerySpec querySpec;
|
|
||||||
private final SqlAliasBaseManager sqlAliasBaseManager;
|
private final SqlAliasBaseManager sqlAliasBaseManager;
|
||||||
private final boolean forceIdentifierSelection;
|
private final boolean forceIdentifierSelection;
|
||||||
private final SqlAstCreationContext sf;
|
private final SqlAstCreationContext sf;
|
||||||
private final SqlAstQuerySpecProcessingStateImpl processingState;
|
private final SqlAstQueryPartProcessingStateImpl processingState;
|
||||||
private final FromClauseAccess fromClauseAccess;
|
private final FromClauseAccess fromClauseAccess;
|
||||||
private final LockOptions lockOptions;
|
private final LockOptions lockOptions;
|
||||||
private final FetchProcessor fetchProcessor;
|
private final FetchProcessor fetchProcessor;
|
||||||
|
@ -61,22 +61,21 @@ public class LoaderSqlAstCreationState
|
||||||
private Set<AssociationKey> visitedAssociationKeys = new HashSet<>();
|
private Set<AssociationKey> visitedAssociationKeys = new HashSet<>();
|
||||||
|
|
||||||
public LoaderSqlAstCreationState(
|
public LoaderSqlAstCreationState(
|
||||||
QuerySpec querySpec,
|
QueryPart queryPart,
|
||||||
SqlAliasBaseManager sqlAliasBaseManager,
|
SqlAliasBaseManager sqlAliasBaseManager,
|
||||||
FromClauseAccess fromClauseAccess,
|
FromClauseAccess fromClauseAccess,
|
||||||
LockOptions lockOptions,
|
LockOptions lockOptions,
|
||||||
FetchProcessor fetchProcessor,
|
FetchProcessor fetchProcessor,
|
||||||
boolean forceIdentifierSelection,
|
boolean forceIdentifierSelection,
|
||||||
SqlAstCreationContext sf) {
|
SqlAstCreationContext sf) {
|
||||||
this.querySpec = querySpec;
|
|
||||||
this.sqlAliasBaseManager = sqlAliasBaseManager;
|
this.sqlAliasBaseManager = sqlAliasBaseManager;
|
||||||
this.fromClauseAccess = fromClauseAccess;
|
this.fromClauseAccess = fromClauseAccess;
|
||||||
this.lockOptions = lockOptions;
|
this.lockOptions = lockOptions;
|
||||||
this.fetchProcessor = fetchProcessor;
|
this.fetchProcessor = fetchProcessor;
|
||||||
this.forceIdentifierSelection = forceIdentifierSelection;
|
this.forceIdentifierSelection = forceIdentifierSelection;
|
||||||
this.sf = sf;
|
this.sf = sf;
|
||||||
processingState = new SqlAstQuerySpecProcessingStateImpl(
|
this.processingState = new SqlAstQueryPartProcessingStateImpl(
|
||||||
querySpec,
|
queryPart,
|
||||||
this,
|
this,
|
||||||
this,
|
this,
|
||||||
() -> Clause.IRRELEVANT
|
() -> Clause.IRRELEVANT
|
||||||
|
@ -99,10 +98,6 @@ public class LoaderSqlAstCreationState
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QuerySpec getQuerySpec() {
|
|
||||||
return querySpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlAstCreationContext getCreationContext() {
|
public SqlAstCreationContext getCreationContext() {
|
||||||
return sf;
|
return sf;
|
||||||
|
@ -135,7 +130,7 @@ public class LoaderSqlAstCreationState
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Fetch> visitFetches(FetchParent fetchParent) {
|
public List<Fetch> visitFetches(FetchParent fetchParent) {
|
||||||
return fetchProcessor.visitFetches( fetchParent, getQuerySpec(), this );
|
return fetchProcessor.visitFetches( fetchParent, processingState.getInflightQueryPart().getFirstQuerySpec(), this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -9,7 +9,6 @@ package org.hibernate.loader.ast.internal;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
|
@ -38,7 +37,6 @@ import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
|
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
||||||
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
|
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
|
||||||
import org.hibernate.sql.exec.spi.Callback;
|
import org.hibernate.sql.exec.spi.Callback;
|
||||||
|
@ -255,8 +253,6 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
||||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlAst );
|
|
||||||
|
|
||||||
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
|
@ -275,6 +271,8 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
||||||
|
|
||||||
// we should have used all of the JdbcParameter references (created bindings for all)
|
// we should have used all of the JdbcParameter references (created bindings for all)
|
||||||
assert offset == jdbcParameters.size();
|
assert offset == jdbcParameters.size();
|
||||||
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlAst )
|
||||||
|
.translate( jdbcParameterBindings, QueryOptions.NONE );
|
||||||
|
|
||||||
final LoadingEntityCollector loadingEntityCollector;
|
final LoadingEntityCollector loadingEntityCollector;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
package org.hibernate.loader.ast.internal;
|
package org.hibernate.loader.ast.internal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
|
@ -19,17 +18,14 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.loader.ast.spi.MultiNaturalIdLoadOptions;
|
import org.hibernate.loader.ast.spi.MultiNaturalIdLoadOptions;
|
||||||
import org.hibernate.metamodel.mapping.Bindable;
|
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
import org.hibernate.query.spi.QueryOptions;
|
import org.hibernate.query.spi.QueryOptions;
|
||||||
import org.hibernate.query.spi.QueryParameterBindings;
|
import org.hibernate.query.spi.QueryParameterBindings;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstSelectTranslator;
|
|
||||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
|
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
||||||
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
|
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
|
||||||
import org.hibernate.sql.exec.spi.Callback;
|
import org.hibernate.sql.exec.spi.Callback;
|
||||||
|
@ -95,8 +91,8 @@ public class MultiNaturalIdLoadingBatcher {
|
||||||
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
|
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
|
||||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||||
final SqlAstSelectTranslator sqlAstTranslator = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory );
|
this.jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlSelect )
|
||||||
this.jdbcSelect = sqlAstTranslator.translate( sqlSelect );
|
.translate( null, QueryOptions.NONE );
|
||||||
}
|
}
|
||||||
|
|
||||||
public <E> List<E> multiLoad(Object[] naturalIdValues, MultiNaturalIdLoadOptions options, SharedSessionContractImplementor session) {
|
public <E> List<E> multiLoad(Object[] naturalIdValues, MultiNaturalIdLoadOptions options, SharedSessionContractImplementor session) {
|
||||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.loader.ast.internal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
@ -29,7 +28,6 @@ import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
|
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
||||||
import org.hibernate.sql.exec.spi.Callback;
|
import org.hibernate.sql.exec.spi.Callback;
|
||||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||||
|
@ -101,10 +99,7 @@ public class SimpleNaturalIdLoader<T> extends AbstractNaturalIdLoader<T> {
|
||||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlSelect );
|
|
||||||
|
|
||||||
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
||||||
|
|
||||||
jdbcParamBindings.registerParametersForEachJdbcValue(
|
jdbcParamBindings.registerParametersForEachJdbcValue(
|
||||||
id,
|
id,
|
||||||
Clause.WHERE,
|
Clause.WHERE,
|
||||||
|
@ -112,7 +107,8 @@ public class SimpleNaturalIdLoader<T> extends AbstractNaturalIdLoader<T> {
|
||||||
jdbcParameters,
|
jdbcParameters,
|
||||||
session
|
session
|
||||||
);
|
);
|
||||||
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlSelect )
|
||||||
|
.translate( jdbcParamBindings, QueryOptions.NONE );
|
||||||
|
|
||||||
final List<Object[]> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
|
final List<Object[]> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
|
||||||
jdbcSelect,
|
jdbcSelect,
|
||||||
|
@ -186,8 +182,6 @@ public class SimpleNaturalIdLoader<T> extends AbstractNaturalIdLoader<T> {
|
||||||
);
|
);
|
||||||
assert jdbcParameters.size() == 1;
|
assert jdbcParameters.size() == 1;
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlSelect );
|
|
||||||
|
|
||||||
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
||||||
|
|
||||||
final SingularAttributeMapping attributeMapping = naturalIdMapping().getAttribute();
|
final SingularAttributeMapping attributeMapping = naturalIdMapping().getAttribute();
|
||||||
|
@ -198,7 +192,8 @@ public class SimpleNaturalIdLoader<T> extends AbstractNaturalIdLoader<T> {
|
||||||
jdbcParameters,
|
jdbcParameters,
|
||||||
session
|
session
|
||||||
);
|
);
|
||||||
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlSelect )
|
||||||
|
.translate( jdbcParamBindings, QueryOptions.NONE );
|
||||||
|
|
||||||
final List<?> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
|
final List<?> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
|
||||||
jdbcSelect,
|
jdbcSelect,
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
package org.hibernate.loader.ast.internal;
|
package org.hibernate.loader.ast.internal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
|
@ -26,7 +25,6 @@ import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
|
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
||||||
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
|
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
|
||||||
import org.hibernate.sql.exec.spi.Callback;
|
import org.hibernate.sql.exec.spi.Callback;
|
||||||
|
@ -102,8 +100,6 @@ public class SingleIdEntityLoaderDynamicBatch<T> extends SingleIdEntityLoaderSup
|
||||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlAst );
|
|
||||||
|
|
||||||
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl(
|
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl(
|
||||||
getLoadable().getIdentifierMapping().getJdbcTypeCount()
|
getLoadable().getIdentifierMapping().getJdbcTypeCount()
|
||||||
);
|
);
|
||||||
|
@ -118,6 +114,8 @@ public class SingleIdEntityLoaderDynamicBatch<T> extends SingleIdEntityLoaderSup
|
||||||
);
|
);
|
||||||
assert offset == jdbcParameters.size();
|
assert offset == jdbcParameters.size();
|
||||||
}
|
}
|
||||||
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlAst )
|
||||||
|
.translate( jdbcParameterBindings, QueryOptions.NONE );
|
||||||
|
|
||||||
JdbcSelectExecutorStandardImpl.INSTANCE.list(
|
JdbcSelectExecutorStandardImpl.INSTANCE.list(
|
||||||
jdbcSelect,
|
jdbcSelect,
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.loader.ast.internal;
|
package org.hibernate.loader.ast.internal;
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
|
@ -23,7 +22,6 @@ import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
|
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
||||||
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
|
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
|
||||||
import org.hibernate.sql.exec.spi.Callback;
|
import org.hibernate.sql.exec.spi.Callback;
|
||||||
|
@ -96,13 +94,10 @@ public class SingleIdLoadPlan<T> implements SingleEntityLoadPlan {
|
||||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlAst );
|
|
||||||
|
|
||||||
final int jdbcTypeCount = restrictivePart.getJdbcTypeCount();
|
final int jdbcTypeCount = restrictivePart.getJdbcTypeCount();
|
||||||
assert jdbcParameters.size() % jdbcTypeCount == 0;
|
assert jdbcParameters.size() % jdbcTypeCount == 0;
|
||||||
|
|
||||||
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcTypeCount );
|
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcTypeCount );
|
||||||
jdbcSelect.bindFilterJdbcParameters( jdbcParameterBindings );
|
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
while ( offset < jdbcParameters.size() ) {
|
while ( offset < jdbcParameters.size() ) {
|
||||||
|
@ -116,6 +111,8 @@ public class SingleIdLoadPlan<T> implements SingleEntityLoadPlan {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
assert offset == jdbcParameters.size();
|
assert offset == jdbcParameters.size();
|
||||||
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlAst )
|
||||||
|
.translate( jdbcParameterBindings, QueryOptions.NONE );
|
||||||
|
|
||||||
final List list = JdbcSelectExecutorStandardImpl.INSTANCE.list(
|
final List list = JdbcSelectExecutorStandardImpl.INSTANCE.list(
|
||||||
jdbcSelect,
|
jdbcSelect,
|
||||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.loader.ast.internal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
|
@ -29,7 +28,6 @@ import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
|
|
||||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
||||||
import org.hibernate.sql.exec.spi.Callback;
|
import org.hibernate.sql.exec.spi.Callback;
|
||||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||||
|
@ -86,8 +84,6 @@ public class SingleUniqueKeyEntityLoaderStandard<T> implements SingleUniqueKeyEn
|
||||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlAst );
|
|
||||||
|
|
||||||
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
||||||
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
|
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
|
||||||
ukValue,
|
ukValue,
|
||||||
|
@ -97,6 +93,8 @@ public class SingleUniqueKeyEntityLoaderStandard<T> implements SingleUniqueKeyEn
|
||||||
session
|
session
|
||||||
);
|
);
|
||||||
assert offset == jdbcParameters.size();
|
assert offset == jdbcParameters.size();
|
||||||
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlAst )
|
||||||
|
.translate( jdbcParameterBindings, QueryOptions.NONE );
|
||||||
|
|
||||||
final List<Object> list = sessionFactory.getJdbcServices().getJdbcSelectExecutor().list(
|
final List<Object> list = sessionFactory.getJdbcServices().getJdbcSelectExecutor().list(
|
||||||
jdbcSelect,
|
jdbcSelect,
|
||||||
|
@ -164,8 +162,6 @@ public class SingleUniqueKeyEntityLoaderStandard<T> implements SingleUniqueKeyEn
|
||||||
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
|
||||||
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
|
||||||
|
|
||||||
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlAst );
|
|
||||||
|
|
||||||
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
|
||||||
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
|
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
|
||||||
ukValue,
|
ukValue,
|
||||||
|
@ -175,6 +171,8 @@ public class SingleUniqueKeyEntityLoaderStandard<T> implements SingleUniqueKeyEn
|
||||||
session
|
session
|
||||||
);
|
);
|
||||||
assert offset == jdbcParameters.size();
|
assert offset == jdbcParameters.size();
|
||||||
|
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory, sqlAst )
|
||||||
|
.translate( jdbcParameterBindings, QueryOptions.NONE );
|
||||||
|
|
||||||
final List<Object> list = sessionFactory.getJdbcServices().getJdbcSelectExecutor().list(
|
final List<Object> list = sessionFactory.getJdbcServices().getJdbcSelectExecutor().list(
|
||||||
jdbcSelect,
|
jdbcSelect,
|
||||||
|
|
|
@ -7,12 +7,14 @@
|
||||||
package org.hibernate.metamodel.mapping;
|
package org.hibernate.metamodel.mapping;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.mapping.IndexedConsumer;
|
import org.hibernate.mapping.IndexedConsumer;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
|
@ -59,6 +61,17 @@ public interface EntityValuedModelPart extends FetchableContainer {
|
||||||
getEntityMappingType().applySqlSelections( navigablePath, tableGroup, creationState );
|
getEntityMappingType().applySqlSelections( navigablePath, tableGroup, creationState );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void applySqlSelections(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup tableGroup,
|
||||||
|
DomainResultCreationState creationState,
|
||||||
|
BiConsumer<SqlSelection,JdbcMapping> selectionConsumer) {
|
||||||
|
// this is really only valid for root entity returns, not really many-to-ones, etc.. but this should
|
||||||
|
// really only ever be called as part of creating a root-return.
|
||||||
|
getEntityMappingType().applySqlSelections( navigablePath, tableGroup, creationState, selectionConsumer );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default int getJdbcTypeCount() {
|
default int getJdbcTypeCount() {
|
||||||
int span = 0;
|
int span = 0;
|
||||||
|
|
|
@ -172,6 +172,29 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
|
||||||
TableGroup tableGroup,
|
TableGroup tableGroup,
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
|
final SqlSelection sqlSelection = resolveSqlSelection( navigablePath, tableGroup, creationState );
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
return new BasicResult(
|
||||||
|
sqlSelection.getValuesArrayPosition(),
|
||||||
|
resultVariable,
|
||||||
|
entityPersister.getIdentifierMapping().getMappedType().getMappedJavaTypeDescriptor(),
|
||||||
|
navigablePath
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applySqlSelections(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup tableGroup,
|
||||||
|
DomainResultCreationState creationState) {
|
||||||
|
resolveSqlSelection( navigablePath, tableGroup, creationState );
|
||||||
|
}
|
||||||
|
|
||||||
|
private SqlSelection resolveSqlSelection(
|
||||||
|
NavigablePath navigablePath,
|
||||||
|
TableGroup tableGroup,
|
||||||
|
DomainResultCreationState creationState) {
|
||||||
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState()
|
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState()
|
||||||
.getSqlExpressionResolver();
|
.getSqlExpressionResolver();
|
||||||
final TableReference rootTableReference;
|
final TableReference rootTableReference;
|
||||||
|
@ -194,7 +217,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
|
||||||
final Expression expression = expressionResolver.resolveSqlExpression(
|
final Expression expression = expressionResolver.resolveSqlExpression(
|
||||||
SqlExpressionResolver.createColumnReferenceKey( rootTableReference, pkColumnName ),
|
SqlExpressionResolver.createColumnReferenceKey( rootTableReference, pkColumnName ),
|
||||||
sqlAstProcessingState -> new ColumnReference(
|
sqlAstProcessingState -> new ColumnReference(
|
||||||
rootTableReference.getIdentificationVariable(),
|
rootTableReference,
|
||||||
pkColumnName,
|
pkColumnName,
|
||||||
false,
|
false,
|
||||||
null,
|
null,
|
||||||
|
@ -204,45 +227,7 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
final SqlSelection sqlSelection = expressionResolver.resolveSqlSelection(
|
return expressionResolver.resolveSqlSelection(
|
||||||
expression,
|
|
||||||
idType.getExpressableJavaTypeDescriptor(),
|
|
||||||
sessionFactory.getTypeConfiguration()
|
|
||||||
);
|
|
||||||
|
|
||||||
//noinspection unchecked
|
|
||||||
return new BasicResult(
|
|
||||||
sqlSelection.getValuesArrayPosition(),
|
|
||||||
resultVariable,
|
|
||||||
entityPersister.getIdentifierMapping().getMappedType().getMappedJavaTypeDescriptor(),
|
|
||||||
navigablePath
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void applySqlSelections(
|
|
||||||
NavigablePath navigablePath,
|
|
||||||
TableGroup tableGroup,
|
|
||||||
DomainResultCreationState creationState) {
|
|
||||||
final SqlExpressionResolver expressionResolver = creationState.getSqlAstCreationState()
|
|
||||||
.getSqlExpressionResolver();
|
|
||||||
final TableReference rootTableReference = tableGroup.resolveTableReference( rootTable );
|
|
||||||
|
|
||||||
final Expression expression = expressionResolver.resolveSqlExpression(
|
|
||||||
SqlExpressionResolver.createColumnReferenceKey( rootTableReference, pkColumnName ),
|
|
||||||
sqlAstProcessingState -> new ColumnReference(
|
|
||||||
rootTable,
|
|
||||||
pkColumnName,
|
|
||||||
false,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
( (BasicValuedModelPart) entityPersister.getIdentifierType() ).getJdbcMapping(),
|
|
||||||
sessionFactory
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// the act of resolving the expression -> selection applies it
|
|
||||||
expressionResolver.resolveSqlSelection(
|
|
||||||
expression,
|
expression,
|
||||||
idType.getExpressableJavaTypeDescriptor(),
|
idType.getExpressableJavaTypeDescriptor(),
|
||||||
sessionFactory.getTypeConfiguration()
|
sessionFactory.getTypeConfiguration()
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue