Improve SQL rendering performance by avoiding intermediate String objects

This commit is contained in:
Christian Beikov 2021-09-30 19:41:12 +02:00
parent 2cb1078fe3
commit c5baae7e11
47 changed files with 914 additions and 707 deletions

View File

@ -24,6 +24,7 @@ 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.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -335,17 +336,19 @@ public class CUBRIDDialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
//I do not know if CUBRID supports FM, but it //I do not know if CUBRID supports FM, but it
//seems that it does pad by default, so it needs it! //seems that it does pad by default, so it needs it!
return OracleDialect.datetimeFormat( format, true, false ) appender.appendSql(
OracleDialect.datetimeFormat( format, true, false )
.replace("SSSSSS", "FF") .replace("SSSSSS", "FF")
.replace("SSSSS", "FF") .replace("SSSSS", "FF")
.replace("SSSS", "FF") .replace("SSSS", "FF")
.replace("SSS", "FF") .replace("SSS", "FF")
.replace("SS", "FF") .replace("SS", "FF")
.replace("S", "FF") .replace("S", "FF")
.result(); .result()
);
} }
@Override @Override

View File

@ -31,6 +31,7 @@ import org.hibernate.query.spi.QueryEngine;
import org.hibernate.sql.JoinFragment; import org.hibernate.sql.JoinFragment;
import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -416,9 +417,9 @@ public class CacheDialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
//I don't think Cache needs FM //I don't think Cache needs FM
return OracleDialect.datetimeFormat( format, false, false ).result(); appender.appendSql( OracleDialect.datetimeFormat( format, false, false ).result() );
} }
} }

View File

@ -45,6 +45,7 @@ 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.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -68,7 +69,13 @@ import java.util.regex.Pattern;
import jakarta.persistence.TemporalType; import jakarta.persistence.TemporalType;
import static org.hibernate.type.descriptor.DateTimeUtils.formatAsTimestampWithMillis; import static org.hibernate.type.descriptor.DateTimeUtils.JDBC_ESCAPE_END;
import static org.hibernate.type.descriptor.DateTimeUtils.JDBC_ESCAPE_START_DATE;
import static org.hibernate.type.descriptor.DateTimeUtils.JDBC_ESCAPE_START_TIME;
import static org.hibernate.type.descriptor.DateTimeUtils.JDBC_ESCAPE_START_TIMESTAMP;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMillis;
/** /**
* An SQL dialect for Firebird 2.0 and above. * An SQL dialect for Firebird 2.0 and above.
@ -567,11 +574,14 @@ public class FirebirdDialect extends Dialect {
} }
@Override @Override
public String toBooleanValueString(boolean bool) { public void appendBooleanValueString(SqlAppender appender, boolean bool) {
//'boolean' type introduced in 3.0 //'boolean' type introduced in 3.0
return getVersion() < 300 if ( getVersion() < 300 ) {
? super.toBooleanValueString( bool ) appender.appendSql( bool ? '1' : '0' );
: bool ? "true" : "false"; }
else {
appender.appendSql( bool );
}
} }
@Override @Override
@ -704,23 +714,82 @@ public class FirebirdDialect extends Dialect {
} }
} }
@Override public void appendDateTimeLiteral(
protected String formatAsTimestamp(Date date, TimeZone jdbcTimeZone) { SqlAppender appender,
return formatAsTimestampWithMillis( date, jdbcTimeZone ); TemporalAccessor temporalAccessor,
TemporalType precision,
TimeZone jdbcTimeZone) {
switch ( precision ) {
case DATE:
appender.appendSql( JDBC_ESCAPE_START_DATE );
appendAsDate( appender, temporalAccessor );
appender.appendSql( JDBC_ESCAPE_END );
break;
case TIME:
appender.appendSql( JDBC_ESCAPE_START_TIME );
appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
appender.appendSql( JDBC_ESCAPE_END );
break;
case TIMESTAMP:
appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP );
appendAsTimestampWithMillis( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
appender.appendSql( JDBC_ESCAPE_END );
break;
default:
throw new IllegalArgumentException();
}
}
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
switch ( precision ) {
case DATE:
appender.appendSql( JDBC_ESCAPE_START_DATE );
appendAsDate( appender, date );
appender.appendSql( JDBC_ESCAPE_END );
break;
case TIME:
appender.appendSql( JDBC_ESCAPE_START_TIME );
appendAsTime( appender, date );
appender.appendSql( JDBC_ESCAPE_END );
break;
case TIMESTAMP:
appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP );
appendAsTimestampWithMillis( appender, date, jdbcTimeZone );
appender.appendSql( JDBC_ESCAPE_END );
break;
default:
throw new IllegalArgumentException();
}
}
public void appendDateTimeLiteral(
SqlAppender appender,
Calendar calendar,
TemporalType precision,
TimeZone jdbcTimeZone) {
switch ( precision ) {
case DATE:
appender.appendSql( JDBC_ESCAPE_START_DATE );
appendAsDate( appender, calendar );
appender.appendSql( JDBC_ESCAPE_END );
break;
case TIME:
appender.appendSql( JDBC_ESCAPE_START_TIME );
appendAsTime( appender, calendar );
appender.appendSql( JDBC_ESCAPE_END );
break;
case TIMESTAMP:
appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP );
appendAsTimestampWithMillis( appender, calendar, jdbcTimeZone );
appender.appendSql( JDBC_ESCAPE_END );
break;
default:
throw new IllegalArgumentException();
}
} }
@Override @Override
protected String formatAsTimestamp(Calendar calendar, TimeZone jdbcTimeZone) { public void appendDatetimeFormat(SqlAppender appender, String format) {
return formatAsTimestampWithMillis( calendar, jdbcTimeZone );
}
@Override
protected String formatAsTimestamp(TemporalAccessor temporalAccessor, TimeZone jdbcTimeZone) {
return formatAsTimestampWithMillis( temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
}
@Override
public String translateDatetimeFormat(String format) {
throw new NotYetImplementedFor6Exception( "format() function not supported on Firebird" ); throw new NotYetImplementedFor6Exception( "format() function not supported on Firebird" );
} }

View File

@ -45,6 +45,7 @@ import org.hibernate.query.sqm.sql.StandardSqmTranslatorFactory;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement; import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationContext;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
@ -432,8 +433,8 @@ public class InformixDialect extends Dialect {
} }
@Override @Override
public String toBooleanValueString(boolean bool) { public void appendBooleanValueString(SqlAppender appender, boolean bool) {
return bool ? "'t'" : "'f'"; appender.appendSql( bool ? "'t'" : "'f'" );
} }
@Override @Override
@ -447,9 +448,9 @@ public class InformixDialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
//Informix' own variation of MySQL //Informix' own variation of MySQL
return datetimeFormat( format ).result(); appender.appendSql( datetimeFormat( format ).result() );
} }
public static Replacer datetimeFormat(String format) { public static Replacer datetimeFormat(String format) {

View File

@ -41,6 +41,7 @@ import org.hibernate.query.sqm.sql.StandardSqmTranslatorFactory;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement; import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationContext;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
@ -197,10 +198,13 @@ public class IngresDialect extends Dialect {
} }
@Override @Override
public String toBooleanValueString(boolean bool) { public void appendBooleanValueString(SqlAppender appender, boolean bool) {
return getVersion() < 1000 if ( getVersion() < 1000 ) {
? super.toBooleanValueString( bool ) appender.appendSql( bool ? '1' : '0' );
: String.valueOf( bool ); }
else {
appender.appendSql( bool );
}
} }
@ -496,8 +500,8 @@ public class IngresDialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
return MySQLDialect.datetimeFormat( format ).result(); appender.appendSql( MySQLDialect.datetimeFormat( format ).result() );
} }
@Override @Override

View File

@ -25,6 +25,7 @@ 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.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -271,7 +272,7 @@ public class MimerSQLDialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
throw new NotYetImplementedFor6Exception("format() function not supported on Mimer SQL"); throw new NotYetImplementedFor6Exception("format() function not supported on Mimer SQL");
} }

View File

@ -26,6 +26,7 @@ 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.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -370,15 +371,17 @@ public class RDMSOS2200Dialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
return OracleDialect.datetimeFormat( format, true, false ) //Does it really support FM? appender.appendSql(
OracleDialect.datetimeFormat( format, true, false ) //Does it really support FM?
.replace("SSSSSS", "MLS") .replace("SSSSSS", "MLS")
.replace("SSSSS", "MLS") .replace("SSSSS", "MLS")
.replace("SSSS", "MLS") .replace("SSSS", "MLS")
.replace("SSS", "MLS") .replace("SSS", "MLS")
.replace("SS", "MLS") .replace("SS", "MLS")
.replace("S", "MLS") .replace("S", "MLS")
.result(); .result()
);
} }
@Override @Override

View File

@ -7,6 +7,11 @@
package org.hibernate.community.dialect; package org.hibernate.community.dialect;
import java.sql.Types; import java.sql.Types;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import jakarta.persistence.TemporalType; import jakarta.persistence.TemporalType;
import org.hibernate.ScrollMode; import org.hibernate.ScrollMode;
@ -39,6 +44,7 @@ import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolv
import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -53,6 +59,9 @@ import static org.hibernate.query.TemporalUnit.EPOCH;
import static org.hibernate.query.TemporalUnit.MONTH; import static org.hibernate.query.TemporalUnit.MONTH;
import static org.hibernate.query.TemporalUnit.QUARTER; import static org.hibernate.query.TemporalUnit.QUARTER;
import static org.hibernate.query.TemporalUnit.YEAR; import static org.hibernate.query.TemporalUnit.YEAR;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
/** /**
* An SQL dialect for SQLite. * An SQL dialect for SQLite.
@ -536,8 +545,8 @@ public class SQLiteDialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
return datetimeFormat( format ).result(); appender.appendSql( datetimeFormat( format ).result() );
} }
public static Replacer datetimeFormat(String format) { public static Replacer datetimeFormat(String format) {
@ -600,18 +609,80 @@ public class SQLiteDialect extends Dialect {
} }
@Override @Override
protected String wrapDateLiteral(String date) { public void appendDateTimeLiteral(
return "date(" + date + ")"; SqlAppender appender,
TemporalAccessor temporalAccessor,
TemporalType precision,
TimeZone jdbcTimeZone) {
switch ( precision ) {
case DATE:
appender.appendSql( "date(" );
appendAsDate( appender, temporalAccessor );
appender.appendSql( ')' );
break;
case TIME:
appender.appendSql( "time(" );
appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
appender.appendSql( ')' );
break;
case TIMESTAMP:
appender.appendSql( "datetime(" );
appendAsTimestampWithMicros( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
appender.appendSql( ')' );
break;
default:
throw new IllegalArgumentException();
}
} }
@Override @Override
protected String wrapTimeLiteral(String time) { public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
return "time(" + time + ")"; switch ( precision ) {
case DATE:
appender.appendSql( "date(" );
appendAsDate( appender, date );
appender.appendSql( ')' );
break;
case TIME:
appender.appendSql( "time(" );
appendAsTime( appender, date );
appender.appendSql( ')' );
break;
case TIMESTAMP:
appender.appendSql( "datetime(" );
appendAsTimestampWithMicros( appender, date, jdbcTimeZone );
appender.appendSql( ')' );
break;
default:
throw new IllegalArgumentException();
}
} }
@Override @Override
protected String wrapTimestampLiteral(String timestamp) { public void appendDateTimeLiteral(
return "datetime(" + timestamp + ")"; SqlAppender appender,
Calendar calendar,
TemporalType precision,
TimeZone jdbcTimeZone) {
switch ( precision ) {
case DATE:
appender.appendSql( "date(" );
appendAsDate( appender, calendar );
appender.appendSql( ')' );
break;
case TIME:
appender.appendSql( "time(" );
appendAsTime( appender, calendar );
appender.appendSql( ')' );
break;
case TIMESTAMP:
appender.appendSql( "datetime(" );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone );
appender.appendSql( ')' );
break;
default:
throw new IllegalArgumentException();
}
} }
} }

View File

@ -45,6 +45,7 @@ import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHANADatabaseImpl; import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHANADatabaseImpl;
@ -1551,10 +1552,13 @@ public abstract class AbstractHANADialect extends Dialect {
} }
@Override @Override
public String toBooleanValueString(boolean bool) { public void appendBooleanValueString(SqlAppender appender, boolean bool) {
return this.useLegacyBooleanType if ( this.useLegacyBooleanType ) {
? super.toBooleanValueString( bool ) appender.appendSql( bool ? '1' : '0' );
: String.valueOf( bool ); }
else {
appender.appendSql( bool );
}
} }
@Override @Override
@ -1630,9 +1634,9 @@ public abstract class AbstractHANADialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
//I don't think HANA needs FM //I don't think HANA needs FM
return OracleDialect.datetimeFormat( format, false, false ).result(); appender.appendSql( OracleDialect.datetimeFormat( format, false, false ).result() );
} }
@Override @Override

View File

@ -25,7 +25,9 @@ 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.spi.SqlAppender;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor; import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry; import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
@ -326,7 +328,8 @@ public abstract class AbstractTransactSQLDialect extends Dialect {
} }
@Override @Override
public String formatBinaryLiteral(byte[] bytes) { public void appendBinaryLiteral(SqlAppender appender, byte[] bytes) {
return "0x" + StandardBasicTypes.BINARY.toString( bytes ); appender.appendSql( "0x" );
PrimitiveByteArrayTypeDescriptor.INSTANCE.appendString( appender, bytes );
} }
} }

View File

@ -24,6 +24,7 @@ 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.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -32,15 +33,20 @@ import org.hibernate.type.StandardBasicTypes;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Types; import java.sql.Types;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.TimeZone;
import jakarta.persistence.TemporalType; import jakarta.persistence.TemporalType;
import static org.hibernate.query.TemporalUnit.DAY; import static org.hibernate.query.TemporalUnit.DAY;
import static org.hibernate.query.TemporalUnit.NATIVE; import static org.hibernate.query.TemporalUnit.NATIVE;
import static org.hibernate.type.descriptor.DateTimeUtils.wrapAsAnsiDateLiteral; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.wrapAsAnsiTimeLiteral; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
/** /**
* A dialect for CockroachDB. * A dialect for CockroachDB.
@ -135,8 +141,8 @@ public class CockroachDialect extends Dialect {
} }
@Override @Override
public String toBooleanValueString(boolean bool) { public void appendBooleanValueString(SqlAppender appender, boolean bool) {
return String.valueOf( bool ); appender.appendSql( bool );
} }
@Override @Override
@ -258,18 +264,80 @@ public class CockroachDialect extends Dialect {
} }
@Override @Override
protected String wrapDateLiteral(String date) { public void appendDateTimeLiteral(
return wrapAsAnsiDateLiteral(date); SqlAppender appender,
TemporalAccessor temporalAccessor,
TemporalType precision,
TimeZone jdbcTimeZone) {
switch ( precision ) {
case DATE:
appender.appendSql( "date '" );
appendAsDate( appender, temporalAccessor );
appender.appendSql( '\'' );
break;
case TIME:
appender.appendSql( "time '" );
appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
appender.appendSql( '\'' );
break;
case TIMESTAMP:
appender.appendSql( "timestamp with time zone '" );
appendAsTimestampWithMicros( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
appender.appendSql( '\'' );
break;
default:
throw new IllegalArgumentException();
}
} }
@Override @Override
protected String wrapTimeLiteral(String time) { public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
return wrapAsAnsiTimeLiteral(time); switch ( precision ) {
case DATE:
appender.appendSql( "date '" );
appendAsDate( appender, date );
appender.appendSql( '\'' );
break;
case TIME:
appender.appendSql( "time '" );
appendAsTime( appender, date );
appender.appendSql( '\'' );
break;
case TIMESTAMP:
appender.appendSql( "timestamp with time zone '" );
appendAsTimestampWithMicros( appender,date, jdbcTimeZone );
appender.appendSql( '\'' );
break;
default:
throw new IllegalArgumentException();
}
} }
@Override @Override
protected String wrapTimestampLiteral(String timestamp) { public void appendDateTimeLiteral(
return "timestamp with time zone '" + timestamp + "'"; SqlAppender appender,
Calendar calendar,
TemporalType precision,
TimeZone jdbcTimeZone) {
switch ( precision ) {
case DATE:
appender.appendSql( "date '" );
appendAsDate( appender, calendar );
appender.appendSql( '\'' );
break;
case TIME:
appender.appendSql( "time '" );
appendAsTime( appender, calendar );
appender.appendSql( '\'' );
break;
case TIMESTAMP:
appender.appendSql( "timestamp with time zone '" );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone );
appender.appendSql( '\'' );
break;
default:
throw new IllegalArgumentException();
}
} }
/** /**
@ -363,8 +431,8 @@ public class CockroachDialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
return SpannerDialect.datetimeFormat( format ).result(); appender.appendSql( SpannerDialect.datetimeFormat( format ).result() );
} }
@Override @Override

View File

@ -36,6 +36,7 @@ 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.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -44,6 +45,7 @@ import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNo
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor; import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.JavaObjectType; import org.hibernate.type.JavaObjectType;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.*; import org.hibernate.type.descriptor.jdbc.*;
import java.sql.CallableStatement; import java.sql.CallableStatement;
@ -593,8 +595,10 @@ public class DB2Dialect extends Dialect {
} }
@Override @Override
public String formatBinaryLiteral(byte[] bytes) { public void appendBinaryLiteral(SqlAppender appender, byte[] bytes) {
return "BX'" + StandardBasicTypes.BINARY.toString( bytes ) + "'"; appender.appendSql( "BX'" );
PrimitiveByteArrayTypeDescriptor.INSTANCE.appendString( appender, bytes );
appender.appendSql( '\'' );
} }
@Override @Override
@ -735,9 +739,9 @@ public class DB2Dialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
//DB2 does not need nor support FM //DB2 does not need nor support FM
return OracleDialect.datetimeFormat( format, false, false ).result(); appender.appendSql( OracleDialect.datetimeFormat( format, false, false ).result() );
} }
@Override @Override
@ -752,12 +756,12 @@ public class DB2Dialect extends Dialect {
} }
@Override @Override
public String toBooleanValueString(boolean bool) { public void appendBooleanValueString(SqlAppender appender, boolean bool) {
if ( getVersion() < 1100 ) { if ( getVersion() < 1100 ) {
return bool ? "1" : "0"; appender.appendSql( bool ? '1' : '0' );
} }
else { else {
return bool ? "true" : "false"; appender.appendSql( bool );
} }
} }

View File

@ -257,7 +257,7 @@ public class DB2SqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAst
} }
else if ( expression instanceof Summarization ) { else if ( expression instanceof Summarization ) {
Summarization summarization = (Summarization) expression; Summarization summarization = (Summarization) expression;
appendSql( summarization.getKind().name().toLowerCase() ); appendSql( summarization.getKind().sqlText() );
appendSql( OPEN_PARENTHESIS ); appendSql( OPEN_PARENTHESIS );
renderCommaSeparated( summarization.getGroupings() ); renderCommaSeparated( summarization.getGroupings() );
appendSql( CLOSE_PARENTHESIS ); appendSql( CLOSE_PARENTHESIS );

View File

@ -48,6 +48,7 @@ import org.hibernate.sql.DerbyCaseFragment;
import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -355,10 +356,13 @@ public class DerbyDialect extends Dialect {
} }
@Override @Override
public String toBooleanValueString(boolean bool) { public void appendBooleanValueString(SqlAppender appender, boolean bool) {
return getVersion() < 1070 if ( getVersion() < 1070 ) {
? super.toBooleanValueString( bool ) appender.appendSql( bool ? '1' : '0' );
: String.valueOf( bool ); }
else {
appender.appendSql( bool );
}
} }
@Override @Override
@ -608,7 +612,7 @@ public class DerbyDialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
throw new NotYetImplementedFor6Exception("format() function not supported on Derby"); throw new NotYetImplementedFor6Exception("format() function not supported on Derby");
} }

View File

@ -191,7 +191,7 @@ public class DerbySqlAstTranslator<T extends JdbcOperation> extends AbstractSqlA
} }
else if ( expression instanceof Summarization ) { else if ( expression instanceof Summarization ) {
Summarization summarization = (Summarization) expression; Summarization summarization = (Summarization) expression;
appendSql( summarization.getKind().name().toLowerCase() ); appendSql( summarization.getKind().sqlText() );
appendSql( OPEN_PARENTHESIS ); appendSql( OPEN_PARENTHESIS );
renderCommaSeparated( summarization.getGroupings() ); renderCommaSeparated( summarization.getGroupings() );
appendSql( CLOSE_PARENTHESIS ); appendSql( CLOSE_PARENTHESIS );

View File

@ -73,6 +73,7 @@ import org.hibernate.sql.*;
import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
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;
@ -82,6 +83,7 @@ import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor; import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor; import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.LongNVarcharTypeDescriptor; import org.hibernate.type.descriptor.jdbc.LongNVarcharTypeDescriptor;
@ -97,7 +99,6 @@ import java.sql.*;
import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAccessor;
import java.util.Date; import java.util.Date;
import java.util.*; import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static org.hibernate.type.descriptor.DateTimeUtils.*; import static org.hibernate.type.descriptor.DateTimeUtils.*;
@ -137,16 +138,10 @@ public abstract class Dialect implements ConversionContext {
* Characters used as closing for quoting SQL identifiers * Characters used as closing for quoting SQL identifiers
*/ */
public static final String CLOSED_QUOTE = "`\"]"; public static final String CLOSED_QUOTE = "`\"]";
private static final Pattern SINGLE_QUOTE_PATTERN = Pattern.compile(
"'",
Pattern.LITERAL
);
private static final Pattern ESCAPE_CLOSING_COMMENT_PATTERN = Pattern.compile( "\\*/" ); private static final Pattern ESCAPE_CLOSING_COMMENT_PATTERN = Pattern.compile( "\\*/" );
private static final Pattern ESCAPE_OPENING_COMMENT_PATTERN = Pattern.compile( "/\\*" ); private static final Pattern ESCAPE_OPENING_COMMENT_PATTERN = Pattern.compile( "/\\*" );
public static final String TWO_SINGLE_QUOTES_REPLACEMENT = Matcher.quoteReplacement( "''" );
private final TypeNames typeNames = new TypeNames(); private final TypeNames typeNames = new TypeNames();
private final TypeNames hibernateTypeNames = new TypeNames(); private final TypeNames hibernateTypeNames = new TypeNames();
@ -2399,7 +2394,13 @@ public abstract class Dialect implements ConversionContext {
* @return The appropriate SQL literal. * @return The appropriate SQL literal.
*/ */
public String toBooleanValueString(boolean bool) { public String toBooleanValueString(boolean bool) {
return bool ? "1" : "0"; final StringBuilder sb = new StringBuilder();
appendBooleanValueString( sb::append, bool );
return sb.toString();
}
public void appendBooleanValueString(SqlAppender appender, boolean bool) {
appender.appendSql( bool ? '1' : '0' );
} }
@ -3736,7 +3737,21 @@ public abstract class Dialect implements ConversionContext {
* @return escaped String * @return escaped String
*/ */
public String inlineLiteral(String literal) { public String inlineLiteral(String literal) {
return String.format( "\'%s\'", escapeLiteral( literal ) ); final StringBuilder sb = new StringBuilder( literal.length() + 2 );
appendLiteral( sb::append, literal );
return sb.toString();
}
public void appendLiteral(SqlAppender appender, String literal) {
appender.appendSql( '\'' );
for ( int i = 0; i < literal.length(); i++ ) {
final char c = literal.charAt( i );
if ( c == '\'' ) {
appender.appendSql( '\'' );
}
appender.appendSql( c );
}
appender.appendSql( '\'' );
} }
/** /**
@ -3751,15 +3766,6 @@ public abstract class Dialect implements ConversionContext {
return true; return true;
} }
/**
* Escape String literal.
*
* @return escaped String
*/
protected String escapeLiteral(String literal) {
return SINGLE_QUOTE_PATTERN.matcher( literal ).replaceAll( TWO_SINGLE_QUOTES_REPLACEMENT );
}
/** /**
* Modify the SQL, adding hints or comments, if necessary * Modify the SQL, adding hints or comments, if necessary
*/ */
@ -3943,8 +3949,10 @@ public abstract class Dialect implements ConversionContext {
return true; return true;
} }
public String formatBinaryLiteral(byte[] bytes) { public void appendBinaryLiteral(SqlAppender appender, byte[] bytes) {
return "X'" + StandardBasicTypes.BINARY.toString( bytes ) + "'"; appender.appendSql( "X'" );
PrimitiveByteArrayTypeDescriptor.INSTANCE.appendString( appender, bytes );
appender.appendSql( '\'' );
} }
public RowLockStrategy getLockRowIdentifier(LockMode lockMode) { public RowLockStrategy getLockRowIdentifier(LockMode lockMode) {
@ -4109,11 +4117,11 @@ public abstract class Dialect implements ConversionContext {
* @return a pattern accepted by the function that * @return a pattern accepted by the function that
* formats dates and times in this dialect * formats dates and times in this dialect
*/ */
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
//most databases support a datetime format //most databases support a datetime format
//copied from Oracle's to_char() function, //copied from Oracle's to_char() function,
//with some minor variation //with some minor variation
return OracleDialect.datetimeFormat( format, true, false ).result(); appender.appendSql( OracleDialect.datetimeFormat( format, true, false ).result() );
} }
/** /**
@ -4196,72 +4204,80 @@ public abstract class Dialect implements ConversionContext {
} }
} }
protected String wrapTimestampLiteral(String timestamp) { public void appendDateTimeLiteral(
return wrapAsJdbcTimestampLiteral( timestamp ); SqlAppender appender,
}
protected String wrapDateLiteral(String date) {
return wrapAsJdbcDateLiteral( date );
}
protected String wrapTimeLiteral(String time) {
return wrapAsJdbcTimeLiteral( time );
}
public String formatDateTimeLiteral(
TemporalAccessor temporalAccessor, TemporalAccessor temporalAccessor,
TemporalType precision, TemporalType precision,
TimeZone jdbcTimeZone) { TimeZone jdbcTimeZone) {
switch ( precision ) { switch ( precision ) {
case DATE: case DATE:
return wrapDateLiteral( formatAsDate( temporalAccessor ) ); appender.appendSql( JDBC_ESCAPE_START_DATE );
appendAsDate( appender, temporalAccessor );
appender.appendSql( JDBC_ESCAPE_END );
break;
case TIME: case TIME:
return wrapTimeLiteral( formatAsTime( temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone ) ); appender.appendSql( JDBC_ESCAPE_START_TIME );
appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
appender.appendSql( JDBC_ESCAPE_END );
break;
case TIMESTAMP: case TIMESTAMP:
return wrapTimestampLiteral( formatAsTimestamp( temporalAccessor, jdbcTimeZone ) ); appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP );
appendAsTimestampWithMicros( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
appender.appendSql( JDBC_ESCAPE_END );
break;
default: default:
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
} }
protected String formatAsTimestamp(TemporalAccessor temporalAccessor, TimeZone jdbcTimeZone) { public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
return formatAsTimestampWithMicros( temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
}
public String formatDateTimeLiteral(Date date, TemporalType precision, TimeZone jdbcTimeZone) {
switch ( precision ) { switch ( precision ) {
case DATE: case DATE:
return wrapDateLiteral( formatAsDate( date ) ); appender.appendSql( JDBC_ESCAPE_START_DATE );
appendAsDate( appender, date );
appender.appendSql( JDBC_ESCAPE_END );
break;
case TIME: case TIME:
return wrapTimeLiteral( formatAsTime( date ) ); appender.appendSql( JDBC_ESCAPE_START_TIME );
appendAsTime( appender, date );
appender.appendSql( JDBC_ESCAPE_END );
break;
case TIMESTAMP: case TIMESTAMP:
return wrapTimestampLiteral( formatAsTimestamp( date, jdbcTimeZone) ); appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP );
appendAsTimestampWithMicros( appender, date, jdbcTimeZone );
appender.appendSql( JDBC_ESCAPE_END );
break;
default: default:
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
} }
protected String formatAsTimestamp(Date date, TimeZone jdbcTimeZone) { public void appendDateTimeLiteral(
return formatAsTimestampWithMicros( date, jdbcTimeZone ); SqlAppender appender,
} Calendar calendar,
TemporalType precision,
public String formatDateTimeLiteral(Calendar calendar, TemporalType precision, TimeZone jdbcTimeZone) { TimeZone jdbcTimeZone) {
switch ( precision ) { switch ( precision ) {
case DATE: case DATE:
return wrapDateLiteral( formatAsDate( calendar ) ); appender.appendSql( JDBC_ESCAPE_START_DATE );
appendAsDate( appender, calendar );
appender.appendSql( JDBC_ESCAPE_END );
break;
case TIME: case TIME:
return wrapTimeLiteral( formatAsTime( calendar ) ); appender.appendSql( JDBC_ESCAPE_START_TIME );
appendAsTime( appender, calendar );
appender.appendSql( JDBC_ESCAPE_END );
break;
case TIMESTAMP: case TIMESTAMP:
return wrapTimestampLiteral( formatAsTimestamp( calendar, jdbcTimeZone ) ); appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone );
appender.appendSql( JDBC_ESCAPE_END );
break;
default: default:
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
} }
protected String formatAsTimestamp(Calendar calendar, TimeZone jdbcTimeZone) {
return formatAsTimestampWithMicros( calendar, jdbcTimeZone );
}
/** /**
* Whether the Dialect supports timezone offset in temporal literals. * Whether the Dialect supports timezone offset in temporal literals.
*/ */

View File

@ -44,6 +44,7 @@ import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -269,8 +270,8 @@ public class H2Dialect extends Dialect {
} }
@Override @Override
public String toBooleanValueString(boolean bool) { public void appendBooleanValueString(SqlAppender appender, boolean bool) {
return String.valueOf( bool ); appender.appendSql( bool );
} }
@Override @Override
@ -462,17 +463,21 @@ public class H2Dialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
if ( version == 104200 ) { if ( version == 104200 ) {
// See https://github.com/h2database/h2database/issues/2518 // See https://github.com/h2database/h2database/issues/2518
return OracleDialect.datetimeFormat( format, true, true ).result(); appender.appendSql( OracleDialect.datetimeFormat( format, true, true ).result() );
}
else {
appender.appendSql(
new Replacer( format, "'", "''" )
.replace("e", "u")
.replace( "xxx", "XXX" )
.replace( "xx", "XX" )
.replace( "x", "X" )
.result()
);
} }
return new Replacer( format, "'", "''" )
.replace("e", "u")
.replace( "xxx", "XXX" )
.replace( "xx", "XX" )
.replace( "x", "X" )
.result();
} }
public String translateExtractField(TemporalUnit unit) { public String translateExtractField(TemporalUnit unit) {

View File

@ -56,6 +56,7 @@ 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.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -646,8 +647,8 @@ public class HSQLDialect extends Dialect {
} }
@Override @Override
public String toBooleanValueString(boolean bool) { public void appendBooleanValueString(SqlAppender appender, boolean bool) {
return String.valueOf( bool ); appender.appendSql( bool );
} }
@Override @Override
@ -698,8 +699,9 @@ public class HSQLDialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
return OracleDialect.datetimeFormat( format, false, false ) appender.appendSql(
OracleDialect.datetimeFormat( format, false, false )
// HSQL is case sensitive i.e. requires MONTH and DAY instead of Month and Day // HSQL is case sensitive i.e. requires MONTH and DAY instead of Month and Day
.replace("MMMM", "MONTH") .replace("MMMM", "MONTH")
.replace("EEEE", "DAY") .replace("EEEE", "DAY")
@ -709,7 +711,8 @@ public class HSQLDialect extends Dialect {
.replace("SSS", "FF") .replace("SSS", "FF")
.replace("SS", "FF") .replace("SS", "FF")
.replace("S", "FF") .replace("S", "FF")
.result(); .result()
);
} }
@Override @Override

View File

@ -102,7 +102,7 @@ public class MariaDBSqlAstTranslator<T extends JdbcOperation> extends AbstractSq
Summarization summarization = (Summarization) expression; Summarization summarization = (Summarization) expression;
renderCommaSeparated( summarization.getGroupings() ); renderCommaSeparated( summarization.getGroupings() );
appendSql( " with " ); appendSql( " with " );
appendSql( summarization.getKind().name().toLowerCase() ); appendSql( summarization.getKind().sqlText() );
} }
else { else {
expression.accept( this ); expression.accept( this );

View File

@ -51,6 +51,7 @@ 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.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -940,13 +941,26 @@ public class MySQLDialect extends Dialect {
} }
@Override @Override
protected String escapeLiteral(String literal) { public void appendLiteral(SqlAppender appender, String literal) {
return super.escapeLiteral( literal ).replace("\\", "\\\\"); appender.appendSql( '\'' );
for ( int i = 0; i < literal.length(); i++ ) {
final char c = literal.charAt( i );
switch ( c ) {
case '\'':
appender.appendSql( '\'' );
break;
case '\\':
appender.appendSql( '\\' );
break;
}
appender.appendSql( c );
}
appender.appendSql( '\'' );
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
return datetimeFormat( format ).result(); appender.appendSql( datetimeFormat( format ).result() );
} }
public static Replacer datetimeFormat(String format) { public static Replacer datetimeFormat(String format) {

View File

@ -103,7 +103,7 @@ public class MySQLSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlA
Summarization summarization = (Summarization) expression; Summarization summarization = (Summarization) expression;
renderCommaSeparated( summarization.getGroupings() ); renderCommaSeparated( summarization.getGroupings() );
appendSql( " with " ); appendSql( " with " );
appendSql( summarization.getKind().name().toLowerCase() ); appendSql( summarization.getKind().sqlText() );
} }
else { else {
expression.accept( this ); expression.accept( this );

View File

@ -51,6 +51,7 @@ import org.hibernate.sql.*;
import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -59,6 +60,7 @@ import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
import org.hibernate.type.JavaObjectType; import org.hibernate.type.JavaObjectType;
import org.hibernate.type.NullType; import org.hibernate.type.NullType;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.BlobTypeDescriptor; import org.hibernate.type.descriptor.jdbc.BlobTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor; import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.NullJdbcTypeDescriptor; import org.hibernate.type.descriptor.jdbc.NullJdbcTypeDescriptor;
@ -1185,10 +1187,10 @@ public class OracleDialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
// Unlike other databases, Oracle requires an explicit reset for the fm modifier, // Unlike other databases, Oracle requires an explicit reset for the fm modifier,
// otherwise all following pattern variables trim zeros // otherwise all following pattern variables trim zeros
return datetimeFormat( format, true, true ).result(); appender.appendSql( datetimeFormat( format, true, true ).result() );
} }
public static Replacer datetimeFormat(String format, boolean useFm, boolean resetFm) { public static Replacer datetimeFormat(String format, boolean useFm, boolean resetFm) {
@ -1277,8 +1279,10 @@ public class OracleDialect extends Dialect {
} }
@Override @Override
public String formatBinaryLiteral(byte[] bytes) { public void appendBinaryLiteral(SqlAppender appender, byte[] bytes) {
return "hextoraw('" + StandardBasicTypes.BINARY.toString( bytes ) + "')"; appender.appendSql( "hextoraw('" );
PrimitiveByteArrayTypeDescriptor.INSTANCE.appendString( appender, bytes );
appender.appendSql( "')" );
} }
@Override @Override

View File

@ -318,7 +318,7 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends AbstractSql
} }
else if ( expression instanceof Summarization ) { else if ( expression instanceof Summarization ) {
Summarization summarization = (Summarization) expression; Summarization summarization = (Summarization) expression;
appendSql( summarization.getKind().name().toLowerCase() ); appendSql( summarization.getKind().sqlText() );
appendSql( OPEN_PARENTHESIS ); appendSql( OPEN_PARENTHESIS );
renderCommaSeparated( summarization.getGroupings() ); renderCommaSeparated( summarization.getGroupings() );
appendSql( CLOSE_PARENTHESIS ); appendSql( CLOSE_PARENTHESIS );

View File

@ -11,9 +11,14 @@ import java.sql.DatabaseMetaData;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Types; import java.sql.Types;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TimeZone;
import jakarta.persistence.TemporalType; import jakarta.persistence.TemporalType;
import org.hibernate.LockMode; import org.hibernate.LockMode;
@ -54,12 +59,14 @@ 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.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.type.JavaObjectType; import org.hibernate.type.JavaObjectType;
import org.hibernate.type.PostgresUUIDType; import org.hibernate.type.PostgresUUIDType;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.BlobTypeDescriptor; import org.hibernate.type.descriptor.jdbc.BlobTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor; import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor; import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
@ -67,8 +74,9 @@ import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcTypeDescript
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate; import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
import static org.hibernate.query.TemporalUnit.*; import static org.hibernate.query.TemporalUnit.*;
import static org.hibernate.type.descriptor.DateTimeUtils.wrapAsAnsiDateLiteral; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.wrapAsAnsiTimeLiteral; import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
/** /**
* An SQL dialect for Postgres 8 and above. * An SQL dialect for Postgres 8 and above.
@ -544,8 +552,8 @@ public class PostgreSQLDialect extends Dialect {
} }
@Override @Override
public String toBooleanValueString(boolean bool) { public void appendBooleanValueString(SqlAppender appender, boolean bool) {
return String.valueOf( bool ); appender.appendSql( bool );
} }
@Override @Override
@ -714,8 +722,8 @@ public class PostgreSQLDialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
return datetimeFormat( format ).result(); appender.appendSql( datetimeFormat( format ).result() );
} }
public Replacer datetimeFormat(String format) { public Replacer datetimeFormat(String format) {
@ -750,23 +758,87 @@ public class PostgreSQLDialect extends Dialect {
} }
@Override @Override
public String formatBinaryLiteral(byte[] bytes) { public void appendBinaryLiteral(SqlAppender appender, byte[] bytes) {
return "bytea '\\x" + StandardBasicTypes.BINARY.toString( bytes ) + "'"; appender.appendSql( "bytea '\\x" );
PrimitiveByteArrayTypeDescriptor.INSTANCE.appendString( appender, bytes );
appender.appendSql( '\'' );
} }
@Override @Override
protected String wrapDateLiteral(String date) { public void appendDateTimeLiteral(
return wrapAsAnsiDateLiteral(date); SqlAppender appender,
TemporalAccessor temporalAccessor,
TemporalType precision,
TimeZone jdbcTimeZone) {
switch ( precision ) {
case DATE:
appender.appendSql( "date '" );
appendAsDate( appender, temporalAccessor );
appender.appendSql( '\'' );
break;
case TIME:
appender.appendSql( "time '" );
appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
appender.appendSql( '\'' );
break;
case TIMESTAMP:
appender.appendSql( "timestamp with time zone '" );
appendAsTimestampWithMicros( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
appender.appendSql( '\'' );
break;
default:
throw new IllegalArgumentException();
}
} }
@Override @Override
protected String wrapTimeLiteral(String time) { public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
return wrapAsAnsiTimeLiteral(time); switch ( precision ) {
case DATE:
appender.appendSql( "date '" );
appendAsDate( appender, date );
appender.appendSql( '\'' );
break;
case TIME:
appender.appendSql( "time '" );
appendAsTime( appender, date );
appender.appendSql( '\'' );
break;
case TIMESTAMP:
appender.appendSql( "timestamp with time zone '" );
appendAsTimestampWithMicros( appender, date, jdbcTimeZone );
appender.appendSql( '\'' );
break;
default:
throw new IllegalArgumentException();
}
} }
@Override @Override
protected String wrapTimestampLiteral(String timestamp) { public void appendDateTimeLiteral(
return "timestamp with time zone '" + timestamp + "'"; SqlAppender appender,
Calendar calendar,
TemporalType precision,
TimeZone jdbcTimeZone) {
switch ( precision ) {
case DATE:
appender.appendSql( "date '" );
appendAsDate( appender, calendar );
appender.appendSql( '\'' );
break;
case TIME:
appender.appendSql( "time '" );
appendAsTime( appender, calendar );
appender.appendSql( '\'' );
break;
case TIMESTAMP:
appender.appendSql( "timestamp with time zone '" );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone );
appender.appendSql( '\'' );
break;
default:
throw new IllegalArgumentException();
}
} }
private String withTimeout(String lockString, int timeout) { private String withTimeout(String lockString, int timeout) {

View File

@ -129,7 +129,7 @@ public class PostgreSQLSqlAstTranslator<T extends JdbcOperation> extends Abstrac
else if ( expression instanceof Summarization ) { else if ( expression instanceof Summarization ) {
Summarization summarization = (Summarization) expression; Summarization summarization = (Summarization) expression;
if ( getDialect().getVersion() >= 950 ) { if ( getDialect().getVersion() >= 950 ) {
appendSql( summarization.getKind().name().toLowerCase() ); appendSql( summarization.getKind().sqlText() );
appendSql( OPEN_PARENTHESIS ); appendSql( OPEN_PARENTHESIS );
renderCommaSeparated( summarization.getGroupings() ); renderCommaSeparated( summarization.getGroupings() );
appendSql( CLOSE_PARENTHESIS ); appendSql( CLOSE_PARENTHESIS );

View File

@ -39,24 +39,33 @@ import org.hibernate.query.spi.QueryEngine;
import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
import org.hibernate.tool.schema.internal.StandardSequenceExporter; import org.hibernate.tool.schema.internal.StandardSequenceExporter;
import org.hibernate.tool.schema.spi.Exporter; import org.hibernate.tool.schema.spi.Exporter;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor; import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.SmallIntTypeDescriptor; import org.hibernate.type.descriptor.jdbc.SmallIntTypeDescriptor;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Types; import java.sql.Types;
import java.util.regex.Pattern; import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import jakarta.persistence.TemporalType; import jakarta.persistence.TemporalType;
import static java.util.regex.Pattern.compile; import static java.util.regex.Pattern.compile;
import static org.hibernate.query.TemporalUnit.NANOSECOND; import static org.hibernate.query.TemporalUnit.NANOSECOND;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsDate;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTime;
import static org.hibernate.type.descriptor.DateTimeUtils.appendAsTimestampWithMicros;
/** /**
* A dialect for Microsoft SQL Server 2000 and above * A dialect for Microsoft SQL Server 2000 and above
@ -674,8 +683,8 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
return datetimeFormat(format).result(); appender.appendSql( datetimeFormat(format).result() );
} }
public static Replacer datetimeFormat(String format) { public static Replacer datetimeFormat(String format) {
@ -717,31 +726,96 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
.replace("x", "zz"); .replace("x", "zz");
} }
private static final Pattern OFFSET_PATTERN = compile(".*[-+]\\d{2}(:\\d{2})?$");
@Override @Override
public String formatBinaryLiteral(byte[] bytes) { public void appendBinaryLiteral(SqlAppender appender, byte[] bytes) {
return "0x" + StandardBasicTypes.BINARY.toString( bytes ); appender.appendSql( "0x" );
PrimitiveByteArrayTypeDescriptor.INSTANCE.appendString( appender, bytes );
} }
@Override @Override
protected String wrapTimestampLiteral(String timestamp) { public void appendDateTimeLiteral(
//needed because the {ts ... } JDBC escape chokes on microseconds SqlAppender appender,
return OFFSET_PATTERN.matcher( timestamp ).matches() TemporalAccessor temporalAccessor,
? "cast('" + timestamp + "' as datetimeoffset)" TemporalType precision,
: "cast('" + timestamp + "' as datetime2)"; TimeZone jdbcTimeZone) {
switch ( precision ) {
case DATE:
appender.appendSql( "cast('" );
appendAsDate( appender, temporalAccessor );
appender.appendSql( "' as date)" );
break;
case TIME:
//needed because the {t ... } JDBC is just buggy
appender.appendSql( "cast('" );
appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
appender.appendSql( "' as time)" );
break;
case TIMESTAMP:
appender.appendSql( "cast('" );
appendAsTimestampWithMicros( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
//needed because the {ts ... } JDBC escape chokes on microseconds
if ( supportsTemporalLiteralOffset() && temporalAccessor.isSupported( ChronoField.OFFSET_SECONDS ) ) {
appender.appendSql( "' as datetimeoffset)" );
}
else {
appender.appendSql( "' as datetime2)" );
}
break;
default:
throw new IllegalArgumentException();
}
} }
@Override @Override
protected String wrapTimeLiteral(String time) { public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
//needed because the {t ... } JDBC is just buggy switch ( precision ) {
return "cast('" + time + "' as time)"; case DATE:
appender.appendSql( "cast('" );
appendAsDate( appender, date );
appender.appendSql( "' as date)" );
break;
case TIME:
//needed because the {t ... } JDBC is just buggy
appender.appendSql( "cast('" );
appendAsTime( appender, date );
appender.appendSql( "' as time)" );
break;
case TIMESTAMP:
appender.appendSql( "cast('" );
appendAsTimestampWithMicros( appender, date, jdbcTimeZone );
appender.appendSql( "' as datetimeoffset)" );
break;
default:
throw new IllegalArgumentException();
}
} }
@Override @Override
protected String wrapDateLiteral(String date) { public void appendDateTimeLiteral(
//possibly not needed SqlAppender appender,
return "cast('" + date + "' as date)"; Calendar calendar,
TemporalType precision,
TimeZone jdbcTimeZone) {
switch ( precision ) {
case DATE:
appender.appendSql( "cast('" );
appendAsDate( appender, calendar );
appender.appendSql( "' as date)" );
break;
case TIME:
//needed because the {t ... } JDBC is just buggy
appender.appendSql( "cast('" );
appendAsTime( appender, calendar );
appender.appendSql( "' as time)" );
break;
case TIMESTAMP:
appender.appendSql( "cast('" );
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone );
appender.appendSql( "' as datetime2)" );
break;
default:
throw new IllegalArgumentException();
}
} }
@Override @Override

View File

@ -52,12 +52,12 @@ public class SQLServerSqlAstTranslator<T extends JdbcOperation> extends Abstract
int searchIndex = 0; int searchIndex = 0;
int unionIndex; int unionIndex;
while ( ( unionIndex = tableExpression.indexOf( UNION_ALL, searchIndex ) ) != -1 ) { while ( ( unionIndex = tableExpression.indexOf( UNION_ALL, searchIndex ) ) != -1 ) {
appendSql( tableExpression.substring( searchIndex, unionIndex ) ); append( tableExpression, searchIndex, unionIndex );
renderLockHint( lockMode ); renderLockHint( lockMode );
appendSql( UNION_ALL ); appendSql( UNION_ALL );
searchIndex = unionIndex + UNION_ALL.length(); searchIndex = unionIndex + UNION_ALL.length();
} }
appendSql( tableExpression.substring( searchIndex, tableExpression.length() - 2 ) ); append( tableExpression, searchIndex, tableExpression.length() - 2 );
renderLockHint( lockMode ); renderLockHint( lockMode );
appendSql( " )" ); appendSql( " )" );
@ -82,24 +82,43 @@ public class SQLServerSqlAstTranslator<T extends JdbcOperation> extends Abstract
private void renderLockHint(LockMode lockMode) { private void renderLockHint(LockMode lockMode) {
if ( getDialect().getVersion() >= 9 ) { if ( getDialect().getVersion() >= 9 ) {
final int effectiveLockTimeout = getEffectiveLockTimeout( lockMode ); final int effectiveLockTimeout = getEffectiveLockTimeout( lockMode );
final String writeLockStr = effectiveLockTimeout == LockOptions.SKIP_LOCKED ? "updlock" : "updlock,holdlock";
final String readLockStr = effectiveLockTimeout == LockOptions.SKIP_LOCKED ? "updlock" : "holdlock";
final String noWaitStr = effectiveLockTimeout == LockOptions.NO_WAIT ? ",nowait" : "";
final String skipLockStr = effectiveLockTimeout == LockOptions.SKIP_LOCKED ? ",readpast" : "";
switch ( lockMode ) { switch ( lockMode ) {
//noinspection deprecation //noinspection deprecation
case UPGRADE: case UPGRADE:
case PESSIMISTIC_WRITE: case PESSIMISTIC_WRITE:
case WRITE: case WRITE:
appendSql( " with (" + writeLockStr + ",rowlock" + noWaitStr + skipLockStr + ")" ); switch ( effectiveLockTimeout ) {
case LockOptions.SKIP_LOCKED:
appendSql( " with (updlock,rowlock,readpast)" );
break;
case LockOptions.NO_WAIT:
appendSql( " with (updlock,holdlock,rowlock,nowait)" );
break;
default:
appendSql( " with (updlock,holdlock,rowlock)" );
break;
}
break; break;
case PESSIMISTIC_READ: case PESSIMISTIC_READ:
appendSql( " with (" + readLockStr + ",rowlock" + noWaitStr + skipLockStr + ")" ); switch ( effectiveLockTimeout ) {
case LockOptions.SKIP_LOCKED:
appendSql( " with (updlock,rowlock,readpast)" );
break;
case LockOptions.NO_WAIT:
appendSql( " with (holdlock,rowlock,nowait)");
break;
default:
appendSql( " with (holdlock,rowlock)");
break;
}
break; break;
case UPGRADE_SKIPLOCKED: case UPGRADE_SKIPLOCKED:
appendSql( " with (updlock,rowlock,readpast" + noWaitStr + ")" ); if ( effectiveLockTimeout == LockOptions.NO_WAIT ) {
appendSql( " with (updlock,rowlock,readpast,nowait)" );
}
else {
appendSql( " with (updlock,rowlock,readpast)" );
}
break; break;
case UPGRADE_NOWAIT: case UPGRADE_NOWAIT:
appendSql( " with (updlock,holdlock,rowlock,nowait)" ); appendSql( " with (updlock,holdlock,rowlock,nowait)" );
@ -322,7 +341,7 @@ public class SQLServerSqlAstTranslator<T extends JdbcOperation> extends Abstract
Summarization summarization = (Summarization) expression; Summarization summarization = (Summarization) expression;
renderCommaSeparated( summarization.getGroupings() ); renderCommaSeparated( summarization.getGroupings() );
appendSql( " with " ); appendSql( " with " );
appendSql( summarization.getKind().name().toLowerCase() ); appendSql( summarization.getKind().sqlText() );
} }
else { else {
expression.accept( this ); expression.accept( this );

View File

@ -34,6 +34,7 @@ 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.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
import org.hibernate.sql.exec.spi.JdbcOperation; import org.hibernate.sql.exec.spi.JdbcOperation;
@ -416,8 +417,8 @@ public class SpannerDialect extends Dialect {
} }
@Override @Override
public String toBooleanValueString(boolean bool) { public void appendBooleanValueString(SqlAppender appender, boolean bool) {
return String.valueOf( bool ); appender.appendSql( bool );
} }
@Override @Override
@ -489,8 +490,8 @@ public class SpannerDialect extends Dialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
return datetimeFormat( format ).result(); appender.appendSql( datetimeFormat( format ).result() );
} }
public static Replacer datetimeFormat(String format) { public static Replacer datetimeFormat(String format) {

View File

@ -32,6 +32,7 @@ import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.SqlAstNodeRenderingMode; import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.SqlAstTranslatorFactory; import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.sql.ast.spi.SqlAstCreationContext;
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory; import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.Statement; import org.hibernate.sql.ast.tree.Statement;
@ -317,7 +318,7 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
} }
@Override @Override
public String translateDatetimeFormat(String format) { public void appendDatetimeFormat(SqlAppender appender, String format) {
throw new NotYetImplementedFor6Exception( "format() function not supported on Sybase"); throw new NotYetImplementedFor6Exception( "format() function not supported on Sybase");
} }

View File

@ -105,7 +105,7 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
sqlAppender.appendSql( concatOperator ); sqlAppender.appendSql( concatOperator );
sqlAppender.appendSql( "''" ); sqlAppender.appendSql( "''" );
sqlAppender.appendSql( ",'\\0'),''),'\\0" ); sqlAppender.appendSql( ",'\\0'),''),'\\0" );
sqlAppender.appendSql( Integer.toString( argumentNumber ) ); sqlAppender.appendSql( argumentNumber );
sqlAppender.appendSql( "')" ); sqlAppender.appendSql( "')" );
sqlAppender.appendSql( concatOperator ); sqlAppender.appendSql( concatOperator );
sqlAppender.appendSql( "'\\0'" ); sqlAppender.appendSql( "'\\0'" );
@ -117,7 +117,7 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
sqlAppender.appendSql( concatOperator ); sqlAppender.appendSql( concatOperator );
sqlAppender.appendSql( "''" ); sqlAppender.appendSql( "''" );
sqlAppender.appendSql( ",'\\0'),''),'\\0" ); sqlAppender.appendSql( ",'\\0'),''),'\\0" );
sqlAppender.appendSql( Integer.toString( argumentNumber ) ); sqlAppender.appendSql( argumentNumber );
sqlAppender.appendSql( "')" ); sqlAppender.appendSql( "')" );
if ( caseWrapper ) { if ( caseWrapper ) {
sqlAppender.appendSql( " else null end" ); sqlAppender.appendSql( " else null end" );

View File

@ -38,7 +38,7 @@ public class CurrentFunction
SqlAppender sqlAppender, SqlAppender sqlAppender,
List<SqlAstNode> arguments, List<SqlAstNode> arguments,
SqlAstTranslator<?> walker) { SqlAstTranslator<?> walker) {
sqlAppender.appendSql(sql); sqlAppender.appendSql( sql );
} }
@Override @Override

View File

@ -58,7 +58,7 @@ public class SQLServerFormatEmulation extends AbstractSqmSelfRenderingFunctionDe
datetime.accept( walker ); datetime.accept( walker );
} }
sqlAppender.appendSql(",'"); sqlAppender.appendSql(",'");
sqlAppender.appendSql( dialect.translateDatetimeFormat( format.getFormat() ) ); dialect.appendDatetimeFormat( sqlAppender, format.getFormat() );
sqlAppender.appendSql("')"); sqlAppender.appendSql("')");
} }

View File

@ -16,7 +16,6 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TimeZone; import java.util.TimeZone;
@ -362,6 +361,34 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
sqlBuffer.append( fragment ); sqlBuffer.append( fragment );
} }
@Override
public void appendSql(int value) {
sqlBuffer.append( value );
}
@Override
public void appendSql(boolean value) {
sqlBuffer.append( value );
}
@Override
public Appendable append(CharSequence csq) {
sqlBuffer.append( csq );
return this;
}
@Override
public Appendable append(CharSequence csq, int start, int end) {
sqlBuffer.append( csq, start, end );
return this;
}
@Override
public Appendable append(char c) {
sqlBuffer.append( c );
return this;
}
protected JdbcServices getJdbcServices() { protected JdbcServices getJdbcServices() {
return getSessionFactory().getJdbcServices(); return getSessionFactory().getJdbcServices();
} }
@ -964,7 +991,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
} }
else { else {
forUpdate.merge( getLockOptions() ); forUpdate.merge( getLockOptions() );
forUpdate.applyAliases( dialect.getWriteRowLockStrategy(), querySpec ); forUpdate.applyAliases( getDialect().getWriteRowLockStrategy(), querySpec );
if ( LockMode.READ.lessThan( forUpdate.getLockMode() ) ) { if ( LockMode.READ.lessThan( forUpdate.getLockMode() ) ) {
final LockStrategy lockStrategy = determineLockingStrategy( final LockStrategy lockStrategy = determineLockingStrategy(
querySpec, querySpec,
@ -994,7 +1021,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
else if ( lockOptions.getLockMode() != LockMode.NONE ) { else if ( lockOptions.getLockMode() != LockMode.NONE ) {
final ForUpdateClause forUpdateClause = new ForUpdateClause(); final ForUpdateClause forUpdateClause = new ForUpdateClause();
forUpdateClause.merge( getLockOptions() ); forUpdateClause.merge( getLockOptions() );
forUpdateClause.applyAliases( dialect.getWriteRowLockStrategy(), querySpec ); forUpdateClause.applyAliases( getDialect().getWriteRowLockStrategy(), querySpec );
if ( LockMode.READ.lessThan( forUpdateClause.getLockMode() ) ) { if ( LockMode.READ.lessThan( forUpdateClause.getLockMode() ) ) {
final LockStrategy lockStrategy = determineLockingStrategy( final LockStrategy lockStrategy = determineLockingStrategy(
querySpec, querySpec,
@ -1021,7 +1048,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
} }
else if ( forUpdate != null ) { else if ( forUpdate != null ) {
forUpdate.merge( getLockOptions() ); forUpdate.merge( getLockOptions() );
forUpdate.applyAliases( dialect.getWriteRowLockStrategy(), querySpec ); forUpdate.applyAliases( getDialect().getWriteRowLockStrategy(), querySpec );
if ( LockMode.READ.lessThan( forUpdate.getLockMode() ) ) { if ( LockMode.READ.lessThan( forUpdate.getLockMode() ) ) {
final LockStrategy lockStrategy = determineLockingStrategy( querySpec, forUpdate, null ); final LockStrategy lockStrategy = determineLockingStrategy( querySpec, forUpdate, null );
switch ( lockStrategy ) { switch ( lockStrategy ) {
@ -1095,7 +1122,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
default: default:
if ( getDialect().supportsWait() ) { if ( getDialect().supportsWait() ) {
appendSql( " wait " ); appendSql( " wait " );
appendSql( Integer.toString( Math.round( timeoutMillis / 1e3f ) ) ); appendSql( Math.round( timeoutMillis / 1e3f ) );
} }
break; break;
} }
@ -1484,7 +1511,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
visitSelectClause( querySpec.getSelectClause() ); visitSelectClause( querySpec.getSelectClause() );
visitFromClause( querySpec.getFromClause() ); visitFromClause( querySpec.getFromClause() );
visitWhereClause( querySpec ); visitWhereClause( querySpec );
visitGroupByClause( querySpec, dialect.getGroupBySelectItemReferenceStrategy() ); visitGroupByClause( querySpec, getDialect().getGroupBySelectItemReferenceStrategy() );
visitHavingClause( querySpec ); visitHavingClause( querySpec );
visitOrderBy( querySpec.getSortSpecifications() ); visitOrderBy( querySpec.getSortSpecifications() );
visitOffsetFetchClause( querySpec ); visitOffsetFetchClause( querySpec );
@ -1681,7 +1708,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
} }
else if ( expression instanceof Summarization ) { else if ( expression instanceof Summarization ) {
Summarization summarization = (Summarization) expression; Summarization summarization = (Summarization) expression;
appendSql( summarization.getKind().name().toLowerCase() ); appendSql( summarization.getKind().sqlText() );
appendSql( OPEN_PARENTHESIS ); appendSql( OPEN_PARENTHESIS );
renderCommaSeparated( summarization.getGroupings() ); renderCommaSeparated( summarization.getGroupings() );
appendSql( CLOSE_PARENTHESIS ); appendSql( CLOSE_PARENTHESIS );
@ -2093,8 +2120,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
nullPrecedence = sessionFactory.getSessionFactoryOptions().getDefaultNullPrecedence(); nullPrecedence = sessionFactory.getSessionFactoryOptions().getDefaultNullPrecedence();
} }
final boolean renderNullPrecedence = nullPrecedence != null && final boolean renderNullPrecedence = nullPrecedence != null &&
!nullPrecedence.isDefaultOrdering( sortOrder, dialect.getNullOrdering() ); !nullPrecedence.isDefaultOrdering( sortOrder, getDialect().getNullOrdering() );
if ( renderNullPrecedence && !dialect.supportsNullPrecedence() ) { if ( renderNullPrecedence && !getDialect().supportsNullPrecedence() ) {
emulateSortSpecificationNullPrecedence( sortExpression, nullPrecedence ); emulateSortSpecificationNullPrecedence( sortExpression, nullPrecedence );
} }
@ -2112,9 +2139,9 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
appendSql( " desc" ); appendSql( " desc" );
} }
if ( renderNullPrecedence && dialect.supportsNullPrecedence() ) { if ( renderNullPrecedence && getDialect().supportsNullPrecedence() ) {
appendSql( " nulls " ); appendSql( " nulls " );
appendSql( nullPrecedence.name().toLowerCase( Locale.ROOT ) ); appendSql( nullPrecedence == NullPrecedence.LAST ? "last" : "first" );
} }
} }
@ -2397,7 +2424,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
renderOffsetExpression( offsetClauseExpression ); renderOffsetExpression( offsetClauseExpression );
if ( offset != 0 ) { if ( offset != 0 ) {
appendSql( '+' ); appendSql( '+' );
appendSql( Integer.toString( offset ) ); appendSql( offset );
} }
} }
@ -2407,7 +2434,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
int offset) { int offset) {
final Number offsetCount = interpretExpression( offsetClauseExpression, jdbcParameterBindings ); final Number offsetCount = interpretExpression( offsetClauseExpression, jdbcParameterBindings );
final Number fetchCount = interpretExpression( fetchClauseExpression, jdbcParameterBindings ); final Number fetchCount = interpretExpression( fetchClauseExpression, jdbcParameterBindings );
appendSql( Integer.toString( fetchCount.intValue() + offsetCount.intValue() + offset ) ); appendSql( fetchCount.intValue() + offsetCount.intValue() + offset );
} }
protected void renderFetchPlusOffsetExpressionAsSingleParameter( protected void renderFetchPlusOffsetExpressionAsSingleParameter(
@ -2418,7 +2445,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
final Number fetchCount = (Number) ( (Literal) fetchClauseExpression ).getLiteralValue(); final Number fetchCount = (Number) ( (Literal) fetchClauseExpression ).getLiteralValue();
if ( offsetClauseExpression instanceof Literal ) { if ( offsetClauseExpression instanceof Literal ) {
final Number offsetCount = (Number) ( (Literal) offsetClauseExpression ).getLiteralValue(); final Number offsetCount = (Number) ( (Literal) offsetClauseExpression ).getLiteralValue();
appendSql( Integer.toString( fetchCount.intValue() + offsetCount.intValue() + offset ) ); appendSql( fetchCount.intValue() + offsetCount.intValue() + offset );
} }
else { else {
appendSql( PARAM_MARKER ); appendSql( PARAM_MARKER );
@ -2653,7 +2680,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
} }
} }
else { else {
appendSql( Integer.toString( Integer.MAX_VALUE ) ); appendSql( Integer.MAX_VALUE );
} }
} }
else if ( fetchExpression != null ) { else if ( fetchExpression != null ) {
@ -2693,7 +2720,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
} }
else if ( offsetExpression != null ) { else if ( offsetExpression != null ) {
appendSql( " limit " ); appendSql( " limit " );
appendSql( Integer.toString( Integer.MAX_VALUE ) ); appendSql( Integer.MAX_VALUE );
} }
if ( offsetExpression != null ) { if ( offsetExpression != null ) {
final Stack<Clause> clauseStack = getClauseStack(); final Stack<Clause> clauseStack = getClauseStack();
@ -2784,7 +2811,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
appendSql( separator ); appendSql( separator );
appendSql( alias ); appendSql( alias );
appendSql( ".c" ); appendSql( ".c" );
appendSql( Integer.toString( i ) ); appendSql( i );
separator = COMA_SEPARATOR; separator = COMA_SEPARATOR;
} }
} }
@ -2944,7 +2971,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
protected void visitSqlSelections(SelectClause selectClause) { protected void visitSqlSelections(SelectClause selectClause) {
final List<SqlSelection> sqlSelections = selectClause.getSqlSelections(); final List<SqlSelection> sqlSelections = selectClause.getSqlSelections();
final int size = sqlSelections.size(); final int size = sqlSelections.size();
final SelectItemReferenceStrategy referenceStrategy = dialect.getGroupBySelectItemReferenceStrategy(); final SelectItemReferenceStrategy referenceStrategy = getDialect().getGroupBySelectItemReferenceStrategy();
// When the dialect needs to render the aliased expression and there are aliased group by items, // When the dialect needs to render the aliased expression and there are aliased group by items,
// we need to inline parameters as the database would otherwise not be able to match the group by item // we need to inline parameters as the database would otherwise not be able to match the group by item
// to the select item, ultimately leading to a query error // to the select item, ultimately leading to a query error
@ -2967,7 +2994,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
visitSqlSelection( sqlSelection ); visitSqlSelection( sqlSelection );
parameterRenderingMode = original; parameterRenderingMode = original;
appendSql( " c" ); appendSql( " c" );
appendSql( Integer.toString( i ) ); appendSql( i );
separator = COMA_SEPARATOR; separator = COMA_SEPARATOR;
} }
if ( queryPartForRowNumbering != null ) { if ( queryPartForRowNumbering != null ) {
@ -3218,9 +3245,10 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
appendSql( "case when " ); appendSql( "case when " );
expression.accept( this ); expression.accept( this );
appendSql( " then " ); appendSql( " then " );
appendSql( getDialect().toBooleanValueString( true ) ); final Dialect dialect = getDialect();
dialect.appendBooleanValueString( this, true );
appendSql( " else " ); appendSql( " else " );
appendSql( getDialect().toBooleanValueString( false ) ); dialect.appendBooleanValueString( this, false );
appendSql( " end" ); appendSql( " end" );
} }
else { else {
@ -3290,12 +3318,11 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
} }
} }
else { else {
appendSql( literalFormatter.appendJdbcLiteral(
literalFormatter.toJdbcLiteral( this,
literal.getLiteralValue(), literal.getLiteralValue(),
dialect, dialect,
getWrapperOptions() getWrapperOptions()
)
); );
} }
} }
@ -3557,9 +3584,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
@Override @Override
public void visitFormat(Format format) { public void visitFormat(Format format) {
final String dialectFormat = getDialect().translateDatetimeFormat( format.getFormat() );
appendSql( '\'' ); appendSql( '\'' );
appendSql( dialectFormat ); getDialect().appendDatetimeFormat( this, format.getFormat() );
appendSql( '\'' ); appendSql( '\'' );
} }
@ -3680,297 +3706,16 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
@Override @Override
public void visitSqlSelectionExpression(SqlSelectionExpression expression) { public void visitSqlSelectionExpression(SqlSelectionExpression expression) {
final boolean useSelectionPosition = dialect.supportsOrdinalSelectItemReference(); final boolean useSelectionPosition = getDialect().supportsOrdinalSelectItemReference();
if ( useSelectionPosition ) { if ( useSelectionPosition ) {
appendSql( Integer.toString( expression.getSelection().getJdbcResultSetIndex() ) ); appendSql( expression.getSelection().getJdbcResultSetIndex() );
} }
else { else {
expression.getSelection().getExpression().accept( this ); expression.getSelection().getExpression().accept( this );
} }
} }
// // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// // Expression : Function : Non-Standard
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitNonStandardFunctionExpression(NonStandardFunction function) {
// appendSql( function.getFunctionName() );
// if ( !function.getArguments().isEmpty() ) {
// appendSql( OPEN_PARENTHESIS );
// String separator = NO_SEPARATOR;
// for ( Expression argumentExpression : function.getArguments() ) {
// appendSql( separator );
// argumentExpression.accept( this );
// separator = COMA_SEPARATOR;
// }
// appendSql( CLOSE_PARENTHESIS );
// }
// }
//
//
// // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// // Expression : Function : Standard
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitAbsFunction(AbsFunction function) {
// appendSql( "abs(" );
// function.getArgument().accept( this );
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitAvgFunction(AvgFunction function) {
// appendSql( "avg(" );
// function.getArgument().accept( this );
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitBitLengthFunction(BitLengthFunction function) {
// appendSql( "bit_length(" );
// function.getArgument().accept( this );
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitCastFunction(CastFunction function) {
// sqlAppender.appendSql( "cast(" );
// function.getExpressionToCast().accept( this );
// sqlAppender.appendSql( AS_KEYWORD );
// sqlAppender.appendSql( determineCastTargetTypeSqlExpression( function ) );
// sqlAppender.appendSql( CLOSE_PARENTHESIS );
// }
//
// private String determineCastTargetTypeSqlExpression(CastFunction castFunction) {
// if ( castFunction.getExplicitCastTargetTypeSqlExpression() != null ) {
// return castFunction.getExplicitCastTargetTypeSqlExpression();
// }
//
// final SqlExpressableType castResultType = castFunction.getCastResultType();
//
// if ( castResultType == null ) {
// throw new SqlTreeException(
// "CastFunction did not define an explicit cast target SQL expression and its return type was null"
// );
// }
//
// final BasicJavaDescriptor javaTypeDescriptor = castResultType.getJavaTypeDescriptor();
// return getJdbcServices()
// .getDialect()
// .getCastTypeName( javaTypeDescriptor.getJdbcRecommendedSqlType( this ).getJdbcTypeCode() );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitConcatFunction(ConcatFunction function) {
// appendSql( "concat(" );
//
// boolean firstPass = true;
// for ( Expression expression : function.getExpressions() ) {
// if ( ! firstPass ) {
// appendSql( COMA_SEPARATOR );
// }
// expression.accept( this );
// firstPass = false;
// }
//
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitSubstrFunction(SubstrFunction function) {
// appendSql( "substr(" );
//
// boolean firstPass = true;
// for ( Expression expression : function.getExpressions() ) {
// if ( ! firstPass ) {
// appendSql( COMA_SEPARATOR );
// }
// expression.accept( this );
// firstPass = false;
// }
//
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitCountFunction(CountFunction function) {
// appendSql( "count(" );
// if ( function.isDistinct() ) {
// appendSql( DISTINCT_KEYWORD );
// }
// function.getArgument().accept( this );
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// public void visitCountStarFunction(CountStarFunction function) {
// appendSql( "count(" );
// if ( function.isDistinct() ) {
// appendSql( DISTINCT_KEYWORD );
// }
// appendSql( "*)" );
// }
//
// @Override
// public void visitCurrentDateFunction(CurrentDateFunction function) {
// appendSql( "current_date" );
// }
//
// @Override
// public void visitCurrentTimeFunction(CurrentTimeFunction function) {
// appendSql( "current_time" );
// }
//
// @Override
// public void visitCurrentTimestampFunction(CurrentTimestampFunction function) {
// appendSql( "current_timestamp" );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitExtractFunction(ExtractFunction extractFunction) {
// appendSql( "extract(" );
// extractFunction.getUnitToExtract().accept( this );
// appendSql( FROM_KEYWORD );
// extractFunction.getExtractionSource().accept( this );
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitLengthFunction(LengthFunction function) {
// sqlAppender.appendSql( "length(" );
// function.getArgument().accept( this );
// sqlAppender.appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitLocateFunction(LocateFunction function) {
// appendSql( "locate(" );
// function.getPatternString().accept( this );
// appendSql( COMA_SEPARATOR );
// function.getStringToSearch().accept( this );
// if ( function.getStartPosition() != null ) {
// appendSql( COMA_SEPARATOR );
// function.getStartPosition().accept( this );
// }
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitLowerFunction(LowerFunction function) {
// appendSql( "lower(" );
// function.getArgument().accept( this );
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitMaxFunction(MaxFunction function) {
// appendSql( "max(" );
// if ( function.isDistinct() ) {
// appendSql( DISTINCT_KEYWORD );
// }
// function.getArgument().accept( this );
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitMinFunction(MinFunction function) {
// appendSql( "min(" );
// if ( function.isDistinct() ) {
// appendSql( DISTINCT_KEYWORD );
// }
// function.getArgument().accept( this );
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitModFunction(ModFunction function) {
// sqlAppender.appendSql( "mod(" );
// function.getDividend().accept( this );
// sqlAppender.appendSql( COMA_SEPARATOR );
// function.getDivisor().accept( this );
// sqlAppender.appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitSqrtFunction(SqrtFunction function) {
// appendSql( "sqrt(" );
// function.getArgument().accept( this );
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitSumFunction(SumFunction function) {
// appendSql( "sum(" );
// if ( function.isDistinct() ) {
// appendSql( DISTINCT_KEYWORD );
// }
// function.getArgument().accept( this );
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitTrimFunction(TrimFunction function) {
// sqlAppender.appendSql( "trim(" );
// sqlAppender.appendSql( function.getSpecification().toSqlText() );
// sqlAppender.appendSql( EMPTY_STRING_SEPARATOR );
// function.getTrimCharacter().accept( this );
// sqlAppender.appendSql( FROM_KEYWORD );
// function.getSource().accept( this );
// sqlAppender.appendSql( CLOSE_PARENTHESIS );
//
// }
//
// @Override
// @SuppressWarnings("unchecked")
// public void visitUpperFunction(UpperFunction function) {
// appendSql( "upper(" );
// function.getArgument().accept( this );
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// public void visitCoalesceFunction(CoalesceFunction coalesceExpression) {
// appendSql( "coalesce(" );
// String separator = NO_SEPARATOR;
// for ( Expression expression : coalesceExpression.getValues() ) {
// appendSql( separator );
// expression.accept( this );
// separator = COMA_SEPARATOR;
// }
//
// appendSql( CLOSE_PARENTHESIS );
// }
//
// @Override
// public void visitNullifFunction(NullifFunction function) {
// appendSql( "nullif(" );
// function.getFirstArgument().accept( this );
// appendSql( COMA_SEPARATOR );
// function.getSecondArgument().accept( this );
// appendSql( CLOSE_PARENTHESIS );
// }
@Override @Override
public void visitEntityTypeLiteral(EntityTypeLiteral expression) { public void visitEntityTypeLiteral(EntityTypeLiteral expression) {
final EntityPersister entityTypeDescriptor = expression.getEntityTypeDescriptor(); final EntityPersister entityTypeDescriptor = expression.getEntityTypeDescriptor();
@ -4179,7 +3924,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
private void visitLiteral(Literal literal) { private void visitLiteral(Literal literal) {
if ( literal.getLiteralValue() == null ) { if ( literal.getLiteralValue() == null ) {
// todo : not sure we allow this "higher up"
appendSql( SqlAppender.NULL_KEYWORD ); appendSql( SqlAppender.NULL_KEYWORD );
} }
else { else {
@ -4199,12 +3943,11 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
throw new IllegalArgumentException( "Can't render parameter as literal, no literal formatter found" ); throw new IllegalArgumentException( "Can't render parameter as literal, no literal formatter found" );
} }
else { else {
appendSql( literalFormatter.appendJdbcLiteral(
literalFormatter.toJdbcLiteral( this,
literalValue, literalValue,
dialect, dialect,
getWrapperOptions() getWrapperOptions()
)
); );
} }
} }
@ -4248,7 +3991,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
// Most databases do not support boolean expressions in a predicate context, so we render `expr=true` // Most databases do not support boolean expressions in a predicate context, so we render `expr=true`
booleanExpressionPredicate.getExpression().accept( this ); booleanExpressionPredicate.getExpression().accept( this );
appendSql( '=' ); appendSql( '=' );
appendSql( getDialect().toBooleanValueString( true ) ); getDialect().appendBooleanValueString( this, true );
} }
@Override @Override
@ -4314,7 +4057,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
ComparisonOperator.NOT_EQUAL : ComparisonOperator.NOT_EQUAL :
ComparisonOperator.EQUAL; ComparisonOperator.EQUAL;
// Some DBs like Oracle support tuples only for the IN subquery predicate // Some DBs like Oracle support tuples only for the IN subquery predicate
if ( supportsRowValueConstructorSyntaxInInSubQuery() && dialect.supportsUnionAll() ) { if ( supportsRowValueConstructorSyntaxInInSubQuery() && getDialect().supportsUnionAll() ) {
inListPredicate.getTestExpression().accept( this ); inListPredicate.getTestExpression().accept( this );
if ( inListPredicate.isNegated() ) { if ( inListPredicate.isNegated() ) {
appendSql( " not" ); appendSql( " not" );
@ -4527,7 +4270,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
visitSelectClause( subQuery.getSelectClause() ); visitSelectClause( subQuery.getSelectClause() );
visitFromClause( subQuery.getFromClause() ); visitFromClause( subQuery.getFromClause() );
visitWhereClause( subQuery ); visitWhereClause( subQuery );
visitGroupByClause( subQuery, dialect.getGroupBySelectItemReferenceStrategy() ); visitGroupByClause( subQuery, getDialect().getGroupBySelectItemReferenceStrategy() );
visitHavingClause( subQuery ); visitHavingClause( subQuery );
appendSql( " order by " ); appendSql( " order by " );
@ -4544,7 +4287,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
appendSql( order ); appendSql( order );
for ( int i = 1; i < sqlSelections.size(); i++ ) { for ( int i = 1; i < sqlSelections.size(); i++ ) {
appendSql( COMA_SEPARATOR_CHAR ); appendSql( COMA_SEPARATOR_CHAR );
appendSql( Integer.toString( i + 1 ) ); appendSql( i + 1 );
appendSql( order ); appendSql( order );
} }
renderFetch( ONE_LITERAL, null, FetchClauseType.ROWS_ONLY ); renderFetch( ONE_LITERAL, null, FetchClauseType.ROWS_ONLY );
@ -4613,13 +4356,13 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
} }
} }
else { else {
if (dialect.supportsCaseInsensitiveLike()) { if (getDialect().supportsCaseInsensitiveLike()) {
likePredicate.getMatchExpression().accept( this ); likePredicate.getMatchExpression().accept( this );
if ( likePredicate.isNegated() ) { if ( likePredicate.isNegated() ) {
appendSql( " not" ); appendSql( " not" );
} }
appendSql( WHITESPACE ); appendSql( WHITESPACE );
appendSql( dialect.getCaseInsensitiveLike() ); appendSql( getDialect().getCaseInsensitiveLike() );
appendSql( WHITESPACE ); appendSql( WHITESPACE );
likePredicate.getPattern().accept( this ); likePredicate.getPattern().accept( this );
if ( likePredicate.getEscapeCharacter() != null ) { if ( likePredicate.getEscapeCharacter() != null ) {
@ -4637,7 +4380,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
protected void renderCaseInsensitiveLikeEmulation(Expression lhs, Expression rhs, Expression escapeCharacter, boolean negated) { protected void renderCaseInsensitiveLikeEmulation(Expression lhs, Expression rhs, Expression escapeCharacter, boolean negated) {
//LOWER(lhs) operator LOWER(rhs) //LOWER(lhs) operator LOWER(rhs)
appendSql( dialect.getLowercaseFunction() ); appendSql( getDialect().getLowercaseFunction() );
appendSql( OPEN_PARENTHESIS ); appendSql( OPEN_PARENTHESIS );
lhs.accept( this ); lhs.accept( this );
appendSql( CLOSE_PARENTHESIS ); appendSql( CLOSE_PARENTHESIS );
@ -4645,7 +4388,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
appendSql( " not" ); appendSql( " not" );
} }
appendSql( " like " ); appendSql( " like " );
appendSql( dialect.getLowercaseFunction() ); appendSql( getDialect().getLowercaseFunction() );
appendSql( OPEN_PARENTHESIS ); appendSql( OPEN_PARENTHESIS );
rhs.accept( this ); rhs.accept( this );
appendSql( CLOSE_PARENTHESIS ); appendSql( CLOSE_PARENTHESIS );

View File

@ -6,12 +6,14 @@
*/ */
package org.hibernate.sql.ast.spi; package org.hibernate.sql.ast.spi;
import java.io.IOException;
/** /**
* Access to appending SQL fragments to an in-flight buffer * Access to appending SQL fragments to an in-flight buffer
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface SqlAppender { public interface SqlAppender extends Appendable {
String NO_SEPARATOR = ""; String NO_SEPARATOR = "";
String COMA_SEPARATOR = ","; String COMA_SEPARATOR = ",";
char COMA_SEPARATOR_CHAR = ','; char COMA_SEPARATOR_CHAR = ',';
@ -29,17 +31,31 @@ public interface SqlAppender {
*/ */
void appendSql(String fragment); void appendSql(String fragment);
void appendSql(char fragment); default void appendSql(char fragment) {
appendSql( Character.toString( fragment ) );
default void appendQuoted(String value, char quoteChar) {
appendSql( quoteChar );
for ( int i = 0; i < value.length(); i++ ) {
final char c = value.charAt( i );
if ( c == quoteChar ) {
appendSql( quoteChar );
}
appendSql( c );
}
appendSql( quoteChar );
} }
default void appendSql(int value) {
appendSql( Integer.toString( value ) );
}
default void appendSql(boolean value) {
appendSql( String.valueOf( value ) );
}
default Appendable append(CharSequence csq) {
appendSql( csq.toString() );
return this;
}
default Appendable append(CharSequence csq, int start, int end) {
appendSql( csq.toString().substring( start, end ) );
return this;
}
default Appendable append(char c) {
appendSql( Character.toString( c ) );
return this;
}
} }

View File

@ -43,7 +43,17 @@ public class Summarization implements Expression {
} }
public enum Kind { public enum Kind {
ROLLUP, ROLLUP( "rollup" ),
CUBE CUBE( "cube" );
private final String sqlText;
Kind(String sqlText) {
this.sqlText = sqlText;
}
public String sqlText() {
return sqlText;
}
} }
} }

View File

@ -13,9 +13,13 @@ import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField; import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.TimeZone; import java.util.TimeZone;
import org.hibernate.sql.ast.spi.SqlAppender;
import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE; import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE;
import static java.time.format.DateTimeFormatter.ISO_LOCAL_TIME; import static java.time.format.DateTimeFormatter.ISO_LOCAL_TIME;
@ -71,8 +75,8 @@ public final class DateTimeUtils {
.optionalStart().appendZoneOrOffsetId().optionalEnd() .optionalStart().appendZoneOrOffsetId().optionalEnd()
.toFormatter(); .toFormatter();
private static final ThreadLocal<SimpleDateFormat> LOCAL_DATE_FORMAT = ThreadLocal.withInitial( DateTimeUtils::simpleDateFormatDate ); private static final ThreadLocal<SimpleDateFormat> LOCAL_DATE_FORMAT = ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_DATE, Locale.ENGLISH ) );
private static final ThreadLocal<SimpleDateFormat> LOCAL_TIME_FORMAT = ThreadLocal.withInitial( DateTimeUtils::simpleDateFormatTime ); private static final ThreadLocal<SimpleDateFormat> LOCAL_TIME_FORMAT = ThreadLocal.withInitial( () -> new SimpleDateFormat( FORMAT_STRING_TIME, Locale.ENGLISH ) );
private static final ThreadLocal<SimpleDateFormat> TIMESTAMP_WITH_MILLIS_FORMAT = ThreadLocal.withInitial( private static final ThreadLocal<SimpleDateFormat> TIMESTAMP_WITH_MILLIS_FORMAT = ThreadLocal.withInitial(
() -> new SimpleDateFormat( () -> new SimpleDateFormat(
FORMAT_STRING_TIMESTAMP_WITH_MILLIS, FORMAT_STRING_TIMESTAMP_WITH_MILLIS,
@ -103,201 +107,163 @@ public final class DateTimeUtils {
.appendOffset("+HH:mm", "+00") .appendOffset("+HH:mm", "+00")
.toFormatter(); .toFormatter();
public static String formatAsTimestampWithMicros(TemporalAccessor temporalAccessor, boolean supportsOffset, TimeZone jdbcTimeZone) { public static void appendAsTimestampWithMicros(
SqlAppender appender,
TemporalAccessor temporalAccessor,
boolean supportsOffset,
TimeZone jdbcTimeZone) {
if ( temporalAccessor.isSupported(ChronoField.OFFSET_SECONDS) ) { if ( temporalAccessor.isSupported(ChronoField.OFFSET_SECONDS) ) {
if ( supportsOffset ) { if ( supportsOffset ) {
return DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET.format( temporalAccessor ); DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET.formatTo( temporalAccessor, appender );
} }
else { else {
return DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS.format( DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS.formatTo(
LocalDateTime.ofInstant( LocalDateTime.ofInstant(
Instant.from( temporalAccessor ), Instant.from( temporalAccessor ),
jdbcTimeZone.toZoneId() jdbcTimeZone.toZoneId()
) ),
appender
); );
} }
} }
else { else {
return DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS.format( temporalAccessor ); DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS.formatTo( temporalAccessor, appender );
} }
} }
public static String formatAsTimestampWithMillis(TemporalAccessor temporalAccessor, boolean supportsOffset, TimeZone jdbcTimeZone) { public static void appendAsTimestampWithMillis(
SqlAppender appender,
TemporalAccessor temporalAccessor,
boolean supportsOffset,
TimeZone jdbcTimeZone) {
if ( temporalAccessor.isSupported(ChronoField.OFFSET_SECONDS) ) { if ( temporalAccessor.isSupported(ChronoField.OFFSET_SECONDS) ) {
if ( supportsOffset ) { if ( supportsOffset ) {
return DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET.format( temporalAccessor ); DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET.formatTo( temporalAccessor, appender );
} }
else { else {
return DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS.format( DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS.formatTo(
LocalDateTime.ofInstant( LocalDateTime.ofInstant(
Instant.from( temporalAccessor ), Instant.from( temporalAccessor ),
jdbcTimeZone.toZoneId() jdbcTimeZone.toZoneId()
) ),
appender
); );
} }
} }
else { else {
return DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS.format( temporalAccessor ); DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS.formatTo( temporalAccessor, appender );
} }
} }
public static String formatAsDate(TemporalAccessor temporalAccessor) { public static void appendAsDate(SqlAppender appender, TemporalAccessor temporalAccessor) {
return DATE_TIME_FORMATTER_DATE.format( temporalAccessor ); DATE_TIME_FORMATTER_DATE.formatTo( temporalAccessor, appender );
} }
public static String formatAsTime(TemporalAccessor temporalAccessor, boolean supportsOffset, TimeZone jdbcTimeZone) { public static void appendAsTime(
SqlAppender appender,
TemporalAccessor temporalAccessor,
boolean supportsOffset,
TimeZone jdbcTimeZone) {
if ( temporalAccessor.isSupported(ChronoField.OFFSET_SECONDS) ) { if ( temporalAccessor.isSupported(ChronoField.OFFSET_SECONDS) ) {
if ( supportsOffset ) { if ( supportsOffset ) {
return DATE_TIME_FORMATTER_TIME_WITH_OFFSET.format( temporalAccessor ); DATE_TIME_FORMATTER_TIME_WITH_OFFSET.formatTo( temporalAccessor, appender );
} }
else { else {
return DATE_TIME_FORMATTER_TIME.format( DATE_TIME_FORMATTER_TIME.formatTo(
LocalDateTime.ofInstant( LocalDateTime.ofInstant(
Instant.from( temporalAccessor ), Instant.from( temporalAccessor ),
jdbcTimeZone.toZoneId() jdbcTimeZone.toZoneId()
) ),
appender
); );
} }
} }
else { else {
return DATE_TIME_FORMATTER_TIME.format( temporalAccessor ); DATE_TIME_FORMATTER_TIME.formatTo( temporalAccessor, appender );
} }
} }
public static String formatAsTimestampWithMillis(java.util.Date date, TimeZone jdbcTimeZone) { public static void appendAsTimestampWithMillis(SqlAppender appender, java.util.Date date, TimeZone jdbcTimeZone) {
final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MILLIS_FORMAT.get(); final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MILLIS_FORMAT.get();
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone(); final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
try { try {
simpleDateFormat.setTimeZone( jdbcTimeZone ); simpleDateFormat.setTimeZone( jdbcTimeZone );
return simpleDateFormat.format( date ); appender.appendSql( simpleDateFormat.format( date ) );
} }
finally { finally {
simpleDateFormat.setTimeZone( originalTimeZone ); simpleDateFormat.setTimeZone( originalTimeZone );
} }
} }
public static String formatAsTimestampWithMicros(java.util.Date date, TimeZone jdbcTimeZone) { public static void appendAsTimestampWithMicros(SqlAppender appender, Date date, TimeZone jdbcTimeZone) {
final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MICROS_FORMAT.get(); final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MICROS_FORMAT.get();
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone(); final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
try { try {
simpleDateFormat.setTimeZone( jdbcTimeZone ); simpleDateFormat.setTimeZone( jdbcTimeZone );
return simpleDateFormat.format( date ); appender.appendSql( simpleDateFormat.format( date ) );
} }
finally { finally {
simpleDateFormat.setTimeZone( originalTimeZone ); simpleDateFormat.setTimeZone( originalTimeZone );
} }
} }
public static String wrapAsJdbcDateLiteral(String literal) { public static void appendAsDate(SqlAppender appender, Date date) {
return JDBC_ESCAPE_START_DATE + literal + JDBC_ESCAPE_END; appender.appendSql( LOCAL_DATE_FORMAT.get().format( date ) );
} }
public static String wrapAsJdbcTimeLiteral(String literal) { public static void appendAsTime(SqlAppender appender, java.util.Date date) {
return JDBC_ESCAPE_START_TIME + literal + JDBC_ESCAPE_END; appender.appendSql( LOCAL_TIME_FORMAT.get().format( date ) );
} }
public static String wrapAsJdbcTimestampLiteral(String literal) { public static void appendAsTimestampWithMillis(
return JDBC_ESCAPE_START_TIMESTAMP + literal + JDBC_ESCAPE_END; SqlAppender appender,
} java.util.Calendar calendar,
TimeZone jdbcTimeZone) {
public static String wrapAsAnsiDateLiteral(String literal) {
return "date '" + literal + "'";
}
public static String wrapAsAnsiTimeLiteral(String literal) {
return "time '" + literal + "'";
}
public static String wrapAsAnsiTimestampLiteral(String literal) {
return "timestamp '" + literal + "'";
}
public static String formatAsDate(java.util.Date date) {
return LOCAL_DATE_FORMAT.get().format( date );
}
public static SimpleDateFormat simpleDateFormatDate() {
return new SimpleDateFormat( FORMAT_STRING_DATE, Locale.ENGLISH );
}
public static String formatAsTime(java.util.Date date) {
return LOCAL_TIME_FORMAT.get().format( date );
}
public static SimpleDateFormat simpleDateFormatTime() {
return new SimpleDateFormat( FORMAT_STRING_TIME, Locale.ENGLISH );
}
public static String formatAsTimestampWithMillis(java.util.Calendar calendar, TimeZone jdbcTimeZone) {
final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MILLIS_FORMAT.get(); final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MILLIS_FORMAT.get();
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone(); final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
try { try {
simpleDateFormat.setTimeZone( jdbcTimeZone ); simpleDateFormat.setTimeZone( jdbcTimeZone );
return simpleDateFormat.format( calendar.getTime() ); appender.appendSql( simpleDateFormat.format( calendar.getTime() ) );
} }
finally { finally {
simpleDateFormat.setTimeZone( originalTimeZone ); simpleDateFormat.setTimeZone( originalTimeZone );
} }
} }
public static SimpleDateFormat simpleDateFormatTimestampWithMillis(TimeZone timeZone) { public static void appendAsTimestampWithMicros(SqlAppender appender, Calendar calendar, TimeZone jdbcTimeZone) {
final SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_STRING_TIMESTAMP_WITH_MILLIS, Locale.ENGLISH );
formatter.setTimeZone( timeZone );
return formatter;
}
public static String formatAsTimestampWithMicros(java.util.Calendar calendar, TimeZone jdbcTimeZone) {
final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MICROS_FORMAT.get(); final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MICROS_FORMAT.get();
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone(); final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
try { try {
simpleDateFormat.setTimeZone( jdbcTimeZone ); simpleDateFormat.setTimeZone( jdbcTimeZone );
return simpleDateFormat.format( calendar.getTime() ); appender.appendSql( simpleDateFormat.format( calendar.getTime() ) );
} }
finally { finally {
simpleDateFormat.setTimeZone( originalTimeZone ); simpleDateFormat.setTimeZone( originalTimeZone );
} }
} }
public static SimpleDateFormat simpleDateFormatTimestampWithMicros(TimeZone timeZone) { public static void appendAsDate(SqlAppender appender, java.util.Calendar calendar) {
final SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_STRING_TIMESTAMP_WITH_MICROS, Locale.ENGLISH );
formatter.setTimeZone( timeZone );
return formatter;
}
public static String formatAsDate(java.util.Calendar calendar) {
final SimpleDateFormat simpleDateFormat = LOCAL_DATE_FORMAT.get(); final SimpleDateFormat simpleDateFormat = LOCAL_DATE_FORMAT.get();
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone(); final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
try { try {
simpleDateFormat.setTimeZone( calendar.getTimeZone() ); simpleDateFormat.setTimeZone( calendar.getTimeZone() );
return simpleDateFormat.format( calendar.getTime() ); appender.appendSql( simpleDateFormat.format( calendar.getTime() ) );
} }
finally { finally {
simpleDateFormat.setTimeZone( originalTimeZone ); simpleDateFormat.setTimeZone( originalTimeZone );
} }
} }
public static SimpleDateFormat simpleDateFormatDate(TimeZone timeZone) { public static void appendAsTime(SqlAppender appender, java.util.Calendar calendar) {
final SimpleDateFormat formatter = new SimpleDateFormat( FORMAT_STRING_DATE, Locale.ENGLISH );
formatter.setTimeZone( timeZone );
return formatter;
}
public static String formatAsTime(java.util.Calendar calendar) {
final SimpleDateFormat simpleDateFormat = LOCAL_TIME_FORMAT.get(); final SimpleDateFormat simpleDateFormat = LOCAL_TIME_FORMAT.get();
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone(); final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
try { try {
simpleDateFormat.setTimeZone( calendar.getTimeZone() ); simpleDateFormat.setTimeZone( calendar.getTimeZone() );
return simpleDateFormat.format( calendar.getTime() ); appender.appendSql( simpleDateFormat.format( calendar.getTime() ) );
} }
finally { finally {
simpleDateFormat.setTimeZone( originalTimeZone ); simpleDateFormat.setTimeZone( originalTimeZone );
} }
} }
public static SimpleDateFormat simpleDateFormatTime(TimeZone timeZone) {
final SimpleDateFormat formatter = new SimpleDateFormat( FORMAT_STRING_TIME, Locale.ENGLISH );
formatter.setTimeZone( timeZone );
return formatter;
}
} }

View File

@ -16,6 +16,7 @@ import java.util.Comparator;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.engine.jdbc.BinaryStream; import org.hibernate.engine.jdbc.BinaryStream;
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl; import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
/** /**
@ -48,14 +49,18 @@ public class PrimitiveByteArrayTypeDescriptor extends AbstractClassTypeDescripto
public String toString(byte[] bytes) { public String toString(byte[] bytes) {
final StringBuilder buf = new StringBuilder( bytes.length * 2 ); final StringBuilder buf = new StringBuilder( bytes.length * 2 );
appendString( buf::append, bytes );
return buf.toString();
}
public void appendString(SqlAppender appender, byte[] bytes) {
for ( byte aByte : bytes ) { for ( byte aByte : bytes ) {
final String hexStr = Integer.toHexString( Byte.toUnsignedInt(aByte) ); final String hexStr = Integer.toHexString( Byte.toUnsignedInt(aByte) );
if ( hexStr.length() == 1 ) { if ( hexStr.length() == 1 ) {
buf.append( '0' ); appender.appendSql( '0' );
} }
buf.append( hexStr ); appender.appendSql( hexStr );
} }
return buf.toString();
} }
@Override @Override

View File

@ -7,6 +7,7 @@
package org.hibernate.type.descriptor.jdbc; package org.hibernate.type.descriptor.jdbc;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
/** /**
@ -24,5 +25,11 @@ import org.hibernate.type.descriptor.WrapperOptions;
public interface JdbcLiteralFormatter<T> { public interface JdbcLiteralFormatter<T> {
String NULL = "null"; String NULL = "null";
String toJdbcLiteral(T value, Dialect dialect, WrapperOptions wrapperOptions); default String toJdbcLiteral(T value, Dialect dialect, WrapperOptions wrapperOptions) {
final StringBuilder sb = new StringBuilder();
appendJdbcLiteral( sb::append, value, dialect, wrapperOptions );
return sb.toString();
}
void appendJdbcLiteral(SqlAppender appender, T value, Dialect dialect, WrapperOptions wrapperOptions);
} }

View File

@ -79,7 +79,7 @@ public interface JdbcTypeDescriptor extends Serializable {
* todo (6.0) : move to {@link org.hibernate.metamodel.mapping.JdbcMapping}? * todo (6.0) : move to {@link org.hibernate.metamodel.mapping.JdbcMapping}?
*/ */
default <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaTypeDescriptor<T> javaTypeDescriptor) { default <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaTypeDescriptor<T> javaTypeDescriptor) {
return (value, dialect, wrapperOptions) -> value.toString(); return (appender, value, dialect, wrapperOptions) -> appender.appendSql( value.toString() );
} }
/** /**

View File

@ -7,6 +7,7 @@
package org.hibernate.type.descriptor.jdbc.internal; package org.hibernate.type.descriptor.jdbc.internal;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter; import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
@ -17,12 +18,12 @@ import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
* @author Gavin King * @author Gavin King
*/ */
public class JdbcLiteralFormatterBinary extends BasicJdbcLiteralFormatter { public class JdbcLiteralFormatterBinary extends BasicJdbcLiteralFormatter {
public JdbcLiteralFormatterBinary(JavaTypeDescriptor javaTypeDescriptor) { public JdbcLiteralFormatterBinary(JavaTypeDescriptor<?> javaTypeDescriptor) {
super( javaTypeDescriptor ); super( javaTypeDescriptor );
} }
@Override @Override
public String toJdbcLiteral(Object value, Dialect dialect, WrapperOptions wrapperOptions) { public void appendJdbcLiteral(SqlAppender appender, Object value, Dialect dialect, WrapperOptions wrapperOptions) {
return dialect.formatBinaryLiteral( unwrap( value, byte[].class, wrapperOptions ) ); dialect.appendBinaryLiteral( appender, unwrap( value, byte[].class, wrapperOptions ) );
} }
} }

View File

@ -7,6 +7,7 @@
package org.hibernate.type.descriptor.jdbc.internal; package org.hibernate.type.descriptor.jdbc.internal;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter; import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
@ -17,12 +18,12 @@ import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class JdbcLiteralFormatterBoolean extends BasicJdbcLiteralFormatter { public class JdbcLiteralFormatterBoolean extends BasicJdbcLiteralFormatter {
public JdbcLiteralFormatterBoolean(JavaTypeDescriptor javaTypeDescriptor) { public JdbcLiteralFormatterBoolean(JavaTypeDescriptor<?> javaTypeDescriptor) {
super( javaTypeDescriptor ); super( javaTypeDescriptor );
} }
@Override @Override
public String toJdbcLiteral(Object value, Dialect dialect, WrapperOptions wrapperOptions) { public void appendJdbcLiteral(SqlAppender appender, Object value, Dialect dialect, WrapperOptions wrapperOptions) {
return dialect.toBooleanValueString( unwrap( value, Boolean.class, wrapperOptions ) ); dialect.appendBooleanValueString( appender, unwrap( value, Boolean.class, wrapperOptions ) );
} }
} }

View File

@ -7,6 +7,7 @@
package org.hibernate.type.descriptor.jdbc.internal; package org.hibernate.type.descriptor.jdbc.internal;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter; import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
@ -21,26 +22,21 @@ public class JdbcLiteralFormatterCharacterData extends BasicJdbcLiteralFormatter
private final boolean isNationalized; private final boolean isNationalized;
public JdbcLiteralFormatterCharacterData(JavaTypeDescriptor javaTypeDescriptor) { public JdbcLiteralFormatterCharacterData(JavaTypeDescriptor<?> javaTypeDescriptor) {
this( javaTypeDescriptor, false ); this( javaTypeDescriptor, false );
} }
public JdbcLiteralFormatterCharacterData(JavaTypeDescriptor javaTypeDescriptor, boolean isNationalized) { public JdbcLiteralFormatterCharacterData(JavaTypeDescriptor<?> javaTypeDescriptor, boolean isNationalized) {
super( javaTypeDescriptor ); super( javaTypeDescriptor );
this.isNationalized = isNationalized; this.isNationalized = isNationalized;
} }
@Override @Override
public String toJdbcLiteral(Object value, Dialect dialect, WrapperOptions wrapperOptions) { public void appendJdbcLiteral(SqlAppender appender, Object value, Dialect dialect, WrapperOptions wrapperOptions) {
final String literalValue = unwrap( value, String.class, wrapperOptions ); final String literalValue = unwrap( value, String.class, wrapperOptions );
final String inlineLiteral = dialect.inlineLiteral( literalValue );
if ( isNationalized ) { if ( isNationalized ) {
// is there a standardized form for n-string literals? This is the SQL Server syntax for sure appender.appendSql( NATIONALIZED_PREFIX );
return NATIONALIZED_PREFIX.concat( inlineLiteral );
} }
dialect.appendLiteral( appender, literalValue );
return inlineLiteral;
} }
} }

View File

@ -7,6 +7,7 @@
package org.hibernate.type.descriptor.jdbc.internal; package org.hibernate.type.descriptor.jdbc.internal;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter; import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
@ -18,14 +19,14 @@ public class JdbcLiteralFormatterNumericData extends BasicJdbcLiteralFormatter {
private final Class<? extends Number> unwrapJavaType; private final Class<? extends Number> unwrapJavaType;
public JdbcLiteralFormatterNumericData( public JdbcLiteralFormatterNumericData(
JavaTypeDescriptor javaTypeDescriptor, JavaTypeDescriptor<?> javaTypeDescriptor,
Class<? extends Number> unwrapJavaType) { Class<? extends Number> unwrapJavaType) {
super( javaTypeDescriptor ); super( javaTypeDescriptor );
this.unwrapJavaType = unwrapJavaType; this.unwrapJavaType = unwrapJavaType;
} }
@Override @Override
public String toJdbcLiteral(Object value, Dialect dialect, WrapperOptions wrapperOptions) { public void appendJdbcLiteral(SqlAppender appender, Object value, Dialect dialect, WrapperOptions wrapperOptions) {
return unwrap( value, unwrapJavaType, wrapperOptions ).toString(); appender.appendSql( unwrap( value, unwrapJavaType, wrapperOptions ).toString() );
} }
} }

View File

@ -11,6 +11,7 @@ import java.util.TimeZone;
import jakarta.persistence.TemporalType; import jakarta.persistence.TemporalType;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter; import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
@ -21,13 +22,13 @@ import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
public class JdbcLiteralFormatterTemporal extends BasicJdbcLiteralFormatter { public class JdbcLiteralFormatterTemporal extends BasicJdbcLiteralFormatter {
private final TemporalType precision; private final TemporalType precision;
public JdbcLiteralFormatterTemporal(JavaTypeDescriptor javaTypeDescriptor, TemporalType precision) { public JdbcLiteralFormatterTemporal(JavaTypeDescriptor<?> javaTypeDescriptor, TemporalType precision) {
super( javaTypeDescriptor ); super( javaTypeDescriptor );
this.precision = precision; this.precision = precision;
} }
@Override @Override
public String toJdbcLiteral(Object value, Dialect dialect, WrapperOptions wrapperOptions) { public void appendJdbcLiteral(SqlAppender appender, Object value, Dialect dialect, WrapperOptions wrapperOptions) {
final TimeZone jdbcTimeZone; final TimeZone jdbcTimeZone;
if ( wrapperOptions == null || wrapperOptions.getJdbcTimeZone() == null ) { if ( wrapperOptions == null || wrapperOptions.getJdbcTimeZone() == null ) {
jdbcTimeZone = TimeZone.getDefault(); jdbcTimeZone = TimeZone.getDefault();
@ -37,48 +38,55 @@ public class JdbcLiteralFormatterTemporal extends BasicJdbcLiteralFormatter {
} }
// for performance reasons, avoid conversions if we can // for performance reasons, avoid conversions if we can
if ( value instanceof java.util.Date ) { if ( value instanceof java.util.Date ) {
return dialect.formatDateTimeLiteral( dialect.appendDateTimeLiteral(
appender,
(java.util.Date) value, (java.util.Date) value,
precision, precision,
jdbcTimeZone jdbcTimeZone
); );
} }
else if ( value instanceof java.util.Calendar ) { else if ( value instanceof java.util.Calendar ) {
return dialect.formatDateTimeLiteral( dialect.appendDateTimeLiteral(
appender,
(java.util.Calendar) value, (java.util.Calendar) value,
precision, precision,
jdbcTimeZone jdbcTimeZone
); );
} }
else if ( value instanceof TemporalAccessor ) { else if ( value instanceof TemporalAccessor ) {
return dialect.formatDateTimeLiteral( dialect.appendDateTimeLiteral(
appender,
(TemporalAccessor) value, (TemporalAccessor) value,
precision, precision,
jdbcTimeZone jdbcTimeZone
); );
} }
else {
switch ( precision) { switch ( precision ) {
case DATE: { case DATE:
return dialect.formatDateTimeLiteral( dialect.appendDateTimeLiteral(
unwrap( value, java.sql.Date.class, wrapperOptions ), appender,
precision, unwrap( value, java.sql.Date.class, wrapperOptions ),
jdbcTimeZone precision,
); jdbcTimeZone
} );
case TIME: { break;
return dialect.formatDateTimeLiteral( case TIME:
unwrap( value, java.sql.Time.class, wrapperOptions ), dialect.appendDateTimeLiteral(
precision, appender,
jdbcTimeZone unwrap( value, java.sql.Time.class, wrapperOptions ),
); precision,
} jdbcTimeZone
default: { );
return dialect.formatDateTimeLiteral( break;
unwrap( value, java.util.Date.class, wrapperOptions ), default:
precision, dialect.appendDateTimeLiteral(
jdbcTimeZone appender,
); unwrap( value, java.util.Date.class, wrapperOptions ),
precision,
jdbcTimeZone
);
break;
} }
} }
} }

View File

@ -354,7 +354,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
private String sessionFactoryName; private String sessionFactoryName;
private String sessionFactoryUuid; private String sessionFactoryUuid;
private transient JdbcTypeDescriptorIndicators currentSqlTypeIndicators = new JdbcTypeDescriptorIndicators() { private final transient JdbcTypeDescriptorIndicators currentSqlTypeIndicators = new JdbcTypeDescriptorIndicators() {
@Override @Override
public TypeConfiguration getTypeConfiguration() { public TypeConfiguration getTypeConfiguration() {
return typeConfiguration; return typeConfiguration;

View File

@ -52,9 +52,17 @@ public class PGGeometryTypeDescriptor implements JdbcTypeDescriptor {
@Override @Override
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaTypeDescriptor<T> javaTypeDescriptor) { public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaTypeDescriptor<T> javaTypeDescriptor) {
if ( javaTypeDescriptor instanceof GeolatteGeometryJavaTypeDescriptor ) { if ( javaTypeDescriptor instanceof GeolatteGeometryJavaTypeDescriptor ) {
return (value, dialect, wrapperOptions) -> "ST_GeomFromEWKT('" + value + "')"; return (appender, value, dialect, wrapperOptions) -> {
appender.appendSql( "ST_GeomFromEWKT('" );
appender.appendSql( value.toString() );
appender.appendSql( "')" );
};
} }
return (value, dialect, wrapperOptions) -> "ST_GeomFromEWKT('" + jts2Gl( value ) + "')"; return (appender, value, dialect, wrapperOptions) -> {
appender.appendSql( "ST_GeomFromEWKT('" );
appender.appendSql( jts2Gl( value ).toString() );
appender.appendSql( "')" );
};
} }
private <T> Geometry<?> jts2Gl(T value) { private <T> Geometry<?> jts2Gl(T value) {

View File

@ -334,7 +334,7 @@ abstract public class DialectFeatureChecks {
public static class SupportsFormat implements DialectFeatureCheck { public static class SupportsFormat implements DialectFeatureCheck {
public boolean apply(Dialect dialect) { public boolean apply(Dialect dialect) {
try { try {
dialect.translateDatetimeFormat( "" ); dialect.appendDatetimeFormat( new StringBuilder()::append, "" );
return true; return true;
} }
catch (Exception ex) { catch (Exception ex) {
@ -346,7 +346,7 @@ abstract public class DialectFeatureChecks {
public static class SupportsTruncateThroughCast implements DialectFeatureCheck { public static class SupportsTruncateThroughCast implements DialectFeatureCheck {
public boolean apply(Dialect dialect) { public boolean apply(Dialect dialect) {
try { try {
dialect.translateDatetimeFormat( "" ); dialect.appendDatetimeFormat( new StringBuilder()::append, "" );
return true; return true;
} }
catch (Exception ex) { catch (Exception ex) {