Improve SQL rendering performance by avoiding intermediate String objects
This commit is contained in:
parent
2cb1078fe3
commit
c5baae7e11
|
@ -24,6 +24,7 @@ import org.hibernate.query.TemporalUnit;
|
|||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
|
@ -335,17 +336,19 @@ public class CUBRIDDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
//I do not know if CUBRID supports FM, but 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("SSSSS", "FF")
|
||||
.replace("SSSS", "FF")
|
||||
.replace("SSS", "FF")
|
||||
.replace("SS", "FF")
|
||||
.replace("S", "FF")
|
||||
.result();
|
||||
.result()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.hibernate.query.spi.QueryEngine;
|
|||
import org.hibernate.sql.JoinFragment;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
|
@ -416,9 +417,9 @@ public class CacheDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
//I don't think Cache needs FM
|
||||
return OracleDialect.datetimeFormat( format, false, false ).result();
|
||||
appender.appendSql( OracleDialect.datetimeFormat( format, false, false ).result() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
|||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.tree.Statement;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
|
@ -68,7 +69,13 @@ import java.util.regex.Pattern;
|
|||
|
||||
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.
|
||||
|
@ -567,11 +574,14 @@ public class FirebirdDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
public void appendBooleanValueString(SqlAppender appender, boolean bool) {
|
||||
//'boolean' type introduced in 3.0
|
||||
return getVersion() < 300
|
||||
? super.toBooleanValueString( bool )
|
||||
: bool ? "true" : "false";
|
||||
if ( getVersion() < 300 ) {
|
||||
appender.appendSql( bool ? '1' : '0' );
|
||||
}
|
||||
else {
|
||||
appender.appendSql( bool );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -704,23 +714,82 @@ public class FirebirdDialect extends Dialect {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String formatAsTimestamp(Date date, TimeZone jdbcTimeZone) {
|
||||
return formatAsTimestampWithMillis( date, jdbcTimeZone );
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
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
|
||||
protected String formatAsTimestamp(Calendar calendar, TimeZone jdbcTimeZone) {
|
||||
return formatAsTimestampWithMillis( calendar, jdbcTimeZone );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String formatAsTimestamp(TemporalAccessor temporalAccessor, TimeZone jdbcTimeZone) {
|
||||
return formatAsTimestampWithMillis( temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
throw new NotYetImplementedFor6Exception( "format() function not supported on Firebird" );
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.hibernate.query.sqm.sql.StandardSqmTranslatorFactory;
|
|||
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.tree.Statement;
|
||||
|
@ -432,8 +433,8 @@ public class InformixDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return bool ? "'t'" : "'f'";
|
||||
public void appendBooleanValueString(SqlAppender appender, boolean bool) {
|
||||
appender.appendSql( bool ? "'t'" : "'f'" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -447,9 +448,9 @@ public class InformixDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
//Informix' own variation of MySQL
|
||||
return datetimeFormat( format ).result();
|
||||
appender.appendSql( datetimeFormat( format ).result() );
|
||||
}
|
||||
|
||||
public static Replacer datetimeFormat(String format) {
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.hibernate.query.sqm.sql.StandardSqmTranslatorFactory;
|
|||
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.tree.Statement;
|
||||
|
@ -197,10 +198,13 @@ public class IngresDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return getVersion() < 1000
|
||||
? super.toBooleanValueString( bool )
|
||||
: String.valueOf( bool );
|
||||
public void appendBooleanValueString(SqlAppender appender, boolean bool) {
|
||||
if ( getVersion() < 1000 ) {
|
||||
appender.appendSql( bool ? '1' : '0' );
|
||||
}
|
||||
else {
|
||||
appender.appendSql( bool );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -496,8 +500,8 @@ public class IngresDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
return MySQLDialect.datetimeFormat( format ).result();
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
appender.appendSql( MySQLDialect.datetimeFormat( format ).result() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.hibernate.query.TemporalUnit;
|
|||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
|
@ -271,7 +272,7 @@ public class MimerSQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
throw new NotYetImplementedFor6Exception("format() function not supported on Mimer SQL");
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.hibernate.sql.CaseFragment;
|
|||
import org.hibernate.sql.DecodeCaseFragment;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
|
@ -370,15 +371,17 @@ public class RDMSOS2200Dialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
return OracleDialect.datetimeFormat( format, true, false ) //Does it really support FM?
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
appender.appendSql(
|
||||
OracleDialect.datetimeFormat( format, true, false ) //Does it really support FM?
|
||||
.replace("SSSSSS", "MLS")
|
||||
.replace("SSSSS", "MLS")
|
||||
.replace("SSSS", "MLS")
|
||||
.replace("SSS", "MLS")
|
||||
.replace("SS", "MLS")
|
||||
.replace("S", "MLS")
|
||||
.result();
|
||||
.result()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
package org.hibernate.community.dialect;
|
||||
|
||||
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 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.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
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.QUARTER;
|
||||
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.
|
||||
|
@ -536,8 +545,8 @@ public class SQLiteDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
return datetimeFormat( format ).result();
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
appender.appendSql( datetimeFormat( format ).result() );
|
||||
}
|
||||
|
||||
public static Replacer datetimeFormat(String format) {
|
||||
|
@ -600,18 +609,80 @@ public class SQLiteDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected String wrapDateLiteral(String date) {
|
||||
return "date(" + date + ")";
|
||||
public void appendDateTimeLiteral(
|
||||
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
|
||||
protected String wrapTimeLiteral(String time) {
|
||||
return "time(" + time + ")";
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
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
|
||||
protected String wrapTimestampLiteral(String timestamp) {
|
||||
return "datetime(" + timestamp + ")";
|
||||
public void appendDateTimeLiteral(
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.hibernate.service.ServiceRegistry;
|
|||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorHANADatabaseImpl;
|
||||
|
@ -1551,10 +1552,13 @@ public abstract class AbstractHANADialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return this.useLegacyBooleanType
|
||||
? super.toBooleanValueString( bool )
|
||||
: String.valueOf( bool );
|
||||
public void appendBooleanValueString(SqlAppender appender, boolean bool) {
|
||||
if ( this.useLegacyBooleanType ) {
|
||||
appender.appendSql( bool ? '1' : '0' );
|
||||
}
|
||||
else {
|
||||
appender.appendSql( bool );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1630,9 +1634,9 @@ public abstract class AbstractHANADialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
//I don't think HANA needs FM
|
||||
return OracleDialect.datetimeFormat( format, false, false ).result();
|
||||
appender.appendSql( OracleDialect.datetimeFormat( format, false, false ).result() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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.TempIdTableExporter;
|
||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
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.spi.JdbcTypeDescriptorRegistry;
|
||||
|
||||
|
@ -326,7 +328,8 @@ public abstract class AbstractTransactSQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String formatBinaryLiteral(byte[] bytes) {
|
||||
return "0x" + StandardBasicTypes.BINARY.toString( bytes );
|
||||
public void appendBinaryLiteral(SqlAppender appender, byte[] bytes) {
|
||||
appender.appendSql( "0x" );
|
||||
PrimitiveByteArrayTypeDescriptor.INSTANCE.appendString( appender, bytes );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.hibernate.query.TemporalUnit;
|
|||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
|
@ -32,15 +33,20 @@ import org.hibernate.type.StandardBasicTypes;
|
|||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import jakarta.persistence.TemporalType;
|
||||
|
||||
import static org.hibernate.query.TemporalUnit.DAY;
|
||||
import static org.hibernate.query.TemporalUnit.NATIVE;
|
||||
import static org.hibernate.type.descriptor.DateTimeUtils.wrapAsAnsiDateLiteral;
|
||||
import static org.hibernate.type.descriptor.DateTimeUtils.wrapAsAnsiTimeLiteral;
|
||||
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 CockroachDB.
|
||||
|
@ -135,8 +141,8 @@ public class CockroachDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return String.valueOf( bool );
|
||||
public void appendBooleanValueString(SqlAppender appender, boolean bool) {
|
||||
appender.appendSql( bool );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -258,18 +264,80 @@ public class CockroachDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected String wrapDateLiteral(String date) {
|
||||
return wrapAsAnsiDateLiteral(date);
|
||||
public void appendDateTimeLiteral(
|
||||
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
|
||||
protected String wrapTimeLiteral(String time) {
|
||||
return wrapAsAnsiTimeLiteral(time);
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
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
|
||||
protected String wrapTimestampLiteral(String timestamp) {
|
||||
return "timestamp with time zone '" + timestamp + "'";
|
||||
public void appendDateTimeLiteral(
|
||||
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
|
||||
public String translateDatetimeFormat(String format) {
|
||||
return SpannerDialect.datetimeFormat( format ).result();
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
appender.appendSql( SpannerDialect.datetimeFormat( format ).result() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
|||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
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.type.JavaObjectType;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.*;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
|
@ -593,8 +595,10 @@ public class DB2Dialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String formatBinaryLiteral(byte[] bytes) {
|
||||
return "BX'" + StandardBasicTypes.BINARY.toString( bytes ) + "'";
|
||||
public void appendBinaryLiteral(SqlAppender appender, byte[] bytes) {
|
||||
appender.appendSql( "BX'" );
|
||||
PrimitiveByteArrayTypeDescriptor.INSTANCE.appendString( appender, bytes );
|
||||
appender.appendSql( '\'' );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -735,9 +739,9 @@ public class DB2Dialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
//DB2 does not need nor support FM
|
||||
return OracleDialect.datetimeFormat( format, false, false ).result();
|
||||
appender.appendSql( OracleDialect.datetimeFormat( format, false, false ).result() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -752,12 +756,12 @@ public class DB2Dialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
public void appendBooleanValueString(SqlAppender appender, boolean bool) {
|
||||
if ( getVersion() < 1100 ) {
|
||||
return bool ? "1" : "0";
|
||||
appender.appendSql( bool ? '1' : '0' );
|
||||
}
|
||||
else {
|
||||
return bool ? "true" : "false";
|
||||
appender.appendSql( bool );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -257,7 +257,7 @@ public class DB2SqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAst
|
|||
}
|
||||
else if ( expression instanceof Summarization ) {
|
||||
Summarization summarization = (Summarization) expression;
|
||||
appendSql( summarization.getKind().name().toLowerCase() );
|
||||
appendSql( summarization.getKind().sqlText() );
|
||||
appendSql( OPEN_PARENTHESIS );
|
||||
renderCommaSeparated( summarization.getGroupings() );
|
||||
appendSql( CLOSE_PARENTHESIS );
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.hibernate.sql.DerbyCaseFragment;
|
|||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
|
@ -355,10 +356,13 @@ public class DerbyDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return getVersion() < 1070
|
||||
? super.toBooleanValueString( bool )
|
||||
: String.valueOf( bool );
|
||||
public void appendBooleanValueString(SqlAppender appender, boolean bool) {
|
||||
if ( getVersion() < 1070 ) {
|
||||
appender.appendSql( bool ? '1' : '0' );
|
||||
}
|
||||
else {
|
||||
appender.appendSql( bool );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -608,7 +612,7 @@ public class DerbyDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
throw new NotYetImplementedFor6Exception("format() function not supported on Derby");
|
||||
}
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ public class DerbySqlAstTranslator<T extends JdbcOperation> extends AbstractSqlA
|
|||
}
|
||||
else if ( expression instanceof Summarization ) {
|
||||
Summarization summarization = (Summarization) expression;
|
||||
appendSql( summarization.getKind().name().toLowerCase() );
|
||||
appendSql( summarization.getKind().sqlText() );
|
||||
appendSql( OPEN_PARENTHESIS );
|
||||
renderCommaSeparated( summarization.getGroupings() );
|
||||
appendSql( CLOSE_PARENTHESIS );
|
||||
|
|
|
@ -73,6 +73,7 @@ import org.hibernate.sql.*;
|
|||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
|
||||
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.Type;
|
||||
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.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.LongNVarcharTypeDescriptor;
|
||||
|
@ -97,7 +99,6 @@ import java.sql.*;
|
|||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Date;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
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
|
||||
*/
|
||||
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_OPENING_COMMENT_PATTERN = Pattern.compile( "/\\*" );
|
||||
|
||||
public static final String TWO_SINGLE_QUOTES_REPLACEMENT = Matcher.quoteReplacement( "''" );
|
||||
|
||||
private final TypeNames typeNames = new TypeNames();
|
||||
private final TypeNames hibernateTypeNames = new TypeNames();
|
||||
|
||||
|
@ -2399,7 +2394,13 @@ public abstract class Dialect implements ConversionContext {
|
|||
* @return The appropriate SQL literal.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
@ -3943,8 +3949,10 @@ public abstract class Dialect implements ConversionContext {
|
|||
return true;
|
||||
}
|
||||
|
||||
public String formatBinaryLiteral(byte[] bytes) {
|
||||
return "X'" + StandardBasicTypes.BINARY.toString( bytes ) + "'";
|
||||
public void appendBinaryLiteral(SqlAppender appender, byte[] bytes) {
|
||||
appender.appendSql( "X'" );
|
||||
PrimitiveByteArrayTypeDescriptor.INSTANCE.appendString( appender, bytes );
|
||||
appender.appendSql( '\'' );
|
||||
}
|
||||
|
||||
public RowLockStrategy getLockRowIdentifier(LockMode lockMode) {
|
||||
|
@ -4109,11 +4117,11 @@ public abstract class Dialect implements ConversionContext {
|
|||
* @return a pattern accepted by the function that
|
||||
* 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
|
||||
//copied from Oracle's to_char() function,
|
||||
//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) {
|
||||
return wrapAsJdbcTimestampLiteral( timestamp );
|
||||
}
|
||||
|
||||
protected String wrapDateLiteral(String date) {
|
||||
return wrapAsJdbcDateLiteral( date );
|
||||
}
|
||||
|
||||
protected String wrapTimeLiteral(String time) {
|
||||
return wrapAsJdbcTimeLiteral( time );
|
||||
}
|
||||
|
||||
public String formatDateTimeLiteral(
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
return wrapDateLiteral( formatAsDate( temporalAccessor ) );
|
||||
appender.appendSql( JDBC_ESCAPE_START_DATE );
|
||||
appendAsDate( appender, temporalAccessor );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
break;
|
||||
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:
|
||||
return wrapTimestampLiteral( formatAsTimestamp( temporalAccessor, jdbcTimeZone ) );
|
||||
appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP );
|
||||
appendAsTimestampWithMicros( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
protected String formatAsTimestamp(TemporalAccessor temporalAccessor, TimeZone jdbcTimeZone) {
|
||||
return formatAsTimestampWithMicros( temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
|
||||
}
|
||||
|
||||
public String formatDateTimeLiteral(Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
return wrapDateLiteral( formatAsDate( date ) );
|
||||
appender.appendSql( JDBC_ESCAPE_START_DATE );
|
||||
appendAsDate( appender, date );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
break;
|
||||
case TIME:
|
||||
return wrapTimeLiteral( formatAsTime( date ) );
|
||||
appender.appendSql( JDBC_ESCAPE_START_TIME );
|
||||
appendAsTime( appender, date );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
break;
|
||||
case TIMESTAMP:
|
||||
return wrapTimestampLiteral( formatAsTimestamp( date, jdbcTimeZone) );
|
||||
appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP );
|
||||
appendAsTimestampWithMicros( appender, date, jdbcTimeZone );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
protected String formatAsTimestamp(Date date, TimeZone jdbcTimeZone) {
|
||||
return formatAsTimestampWithMicros( date, jdbcTimeZone );
|
||||
}
|
||||
|
||||
public String formatDateTimeLiteral(Calendar calendar, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
Calendar calendar,
|
||||
TemporalType precision,
|
||||
TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
case DATE:
|
||||
return wrapDateLiteral( formatAsDate( calendar ) );
|
||||
appender.appendSql( JDBC_ESCAPE_START_DATE );
|
||||
appendAsDate( appender, calendar );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
break;
|
||||
case TIME:
|
||||
return wrapTimeLiteral( formatAsTime( calendar ) );
|
||||
appender.appendSql( JDBC_ESCAPE_START_TIME );
|
||||
appendAsTime( appender, calendar );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
break;
|
||||
case TIMESTAMP:
|
||||
return wrapTimestampLiteral( formatAsTimestamp( calendar, jdbcTimeZone ) );
|
||||
appender.appendSql( JDBC_ESCAPE_START_TIMESTAMP );
|
||||
appendAsTimestampWithMicros( appender, calendar, jdbcTimeZone );
|
||||
appender.appendSql( JDBC_ESCAPE_END );
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
protected String formatAsTimestamp(Calendar calendar, TimeZone jdbcTimeZone) {
|
||||
return formatAsTimestampWithMicros( calendar, jdbcTimeZone );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the Dialect supports timezone offset in temporal literals.
|
||||
*/
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
|||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
|
@ -269,8 +270,8 @@ public class H2Dialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return String.valueOf( bool );
|
||||
public void appendBooleanValueString(SqlAppender appender, boolean bool) {
|
||||
appender.appendSql( bool );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -462,17 +463,21 @@ public class H2Dialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
if ( version == 104200 ) {
|
||||
// See https://github.com/h2database/h2database/issues/2518
|
||||
return OracleDialect.datetimeFormat( format, true, true ).result();
|
||||
appender.appendSql( OracleDialect.datetimeFormat( format, true, true ).result() );
|
||||
}
|
||||
return new Replacer( format, "'", "''" )
|
||||
else {
|
||||
appender.appendSql(
|
||||
new Replacer( format, "'", "''" )
|
||||
.replace("e", "u")
|
||||
.replace( "xxx", "XXX" )
|
||||
.replace( "xx", "XX" )
|
||||
.replace( "x", "X" )
|
||||
.result();
|
||||
.result()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public String translateExtractField(TemporalUnit unit) {
|
||||
|
|
|
@ -56,6 +56,7 @@ import org.hibernate.query.sqm.mutation.internal.idtable.TempIdTableExporter;
|
|||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.tree.Statement;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
|
@ -646,8 +647,8 @@ public class HSQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return String.valueOf( bool );
|
||||
public void appendBooleanValueString(SqlAppender appender, boolean bool) {
|
||||
appender.appendSql( bool );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -698,8 +699,9 @@ public class HSQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
return OracleDialect.datetimeFormat( format, false, false )
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
appender.appendSql(
|
||||
OracleDialect.datetimeFormat( format, false, false )
|
||||
// HSQL is case sensitive i.e. requires MONTH and DAY instead of Month and Day
|
||||
.replace("MMMM", "MONTH")
|
||||
.replace("EEEE", "DAY")
|
||||
|
@ -709,7 +711,8 @@ public class HSQLDialect extends Dialect {
|
|||
.replace("SSS", "FF")
|
||||
.replace("SS", "FF")
|
||||
.replace("S", "FF")
|
||||
.result();
|
||||
.result()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -102,7 +102,7 @@ public class MariaDBSqlAstTranslator<T extends JdbcOperation> extends AbstractSq
|
|||
Summarization summarization = (Summarization) expression;
|
||||
renderCommaSeparated( summarization.getGroupings() );
|
||||
appendSql( " with " );
|
||||
appendSql( summarization.getKind().name().toLowerCase() );
|
||||
appendSql( summarization.getKind().sqlText() );
|
||||
}
|
||||
else {
|
||||
expression.accept( this );
|
||||
|
|
|
@ -51,6 +51,7 @@ import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
|||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
|
@ -940,13 +941,26 @@ public class MySQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected String escapeLiteral(String literal) {
|
||||
return super.escapeLiteral( literal ).replace("\\", "\\\\");
|
||||
public void appendLiteral(SqlAppender appender, String literal) {
|
||||
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
|
||||
public String translateDatetimeFormat(String format) {
|
||||
return datetimeFormat( format ).result();
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
appender.appendSql( datetimeFormat( format ).result() );
|
||||
}
|
||||
|
||||
public static Replacer datetimeFormat(String format) {
|
||||
|
|
|
@ -103,7 +103,7 @@ public class MySQLSqlAstTranslator<T extends JdbcOperation> extends AbstractSqlA
|
|||
Summarization summarization = (Summarization) expression;
|
||||
renderCommaSeparated( summarization.getGroupings() );
|
||||
appendSql( " with " );
|
||||
appendSql( summarization.getKind().name().toLowerCase() );
|
||||
appendSql( summarization.getKind().sqlText() );
|
||||
}
|
||||
else {
|
||||
expression.accept( this );
|
||||
|
|
|
@ -51,6 +51,7 @@ import org.hibernate.sql.*;
|
|||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
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.NullType;
|
||||
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.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.NullJdbcTypeDescriptor;
|
||||
|
@ -1185,10 +1187,10 @@ public class OracleDialect extends Dialect {
|
|||
}
|
||||
|
||||
@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,
|
||||
// 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) {
|
||||
|
@ -1277,8 +1279,10 @@ public class OracleDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String formatBinaryLiteral(byte[] bytes) {
|
||||
return "hextoraw('" + StandardBasicTypes.BINARY.toString( bytes ) + "')";
|
||||
public void appendBinaryLiteral(SqlAppender appender, byte[] bytes) {
|
||||
appender.appendSql( "hextoraw('" );
|
||||
PrimitiveByteArrayTypeDescriptor.INSTANCE.appendString( appender, bytes );
|
||||
appender.appendSql( "')" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -318,7 +318,7 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends AbstractSql
|
|||
}
|
||||
else if ( expression instanceof Summarization ) {
|
||||
Summarization summarization = (Summarization) expression;
|
||||
appendSql( summarization.getKind().name().toLowerCase() );
|
||||
appendSql( summarization.getKind().sqlText() );
|
||||
appendSql( OPEN_PARENTHESIS );
|
||||
renderCommaSeparated( summarization.getGroupings() );
|
||||
appendSql( CLOSE_PARENTHESIS );
|
||||
|
|
|
@ -11,9 +11,14 @@ import java.sql.DatabaseMetaData;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import jakarta.persistence.TemporalType;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
|
@ -54,12 +59,14 @@ import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
|||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
import org.hibernate.type.JavaObjectType;
|
||||
import org.hibernate.type.PostgresUUIDType;
|
||||
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.ClobTypeDescriptor;
|
||||
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.query.TemporalUnit.*;
|
||||
import static org.hibernate.type.descriptor.DateTimeUtils.wrapAsAnsiDateLiteral;
|
||||
import static org.hibernate.type.descriptor.DateTimeUtils.wrapAsAnsiTimeLiteral;
|
||||
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 Postgres 8 and above.
|
||||
|
@ -544,8 +552,8 @@ public class PostgreSQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return String.valueOf( bool );
|
||||
public void appendBooleanValueString(SqlAppender appender, boolean bool) {
|
||||
appender.appendSql( bool );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -714,8 +722,8 @@ public class PostgreSQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
return datetimeFormat( format ).result();
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
appender.appendSql( datetimeFormat( format ).result() );
|
||||
}
|
||||
|
||||
public Replacer datetimeFormat(String format) {
|
||||
|
@ -750,23 +758,87 @@ public class PostgreSQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String formatBinaryLiteral(byte[] bytes) {
|
||||
return "bytea '\\x" + StandardBasicTypes.BINARY.toString( bytes ) + "'";
|
||||
public void appendBinaryLiteral(SqlAppender appender, byte[] bytes) {
|
||||
appender.appendSql( "bytea '\\x" );
|
||||
PrimitiveByteArrayTypeDescriptor.INSTANCE.appendString( appender, bytes );
|
||||
appender.appendSql( '\'' );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String wrapDateLiteral(String date) {
|
||||
return wrapAsAnsiDateLiteral(date);
|
||||
public void appendDateTimeLiteral(
|
||||
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
|
||||
protected String wrapTimeLiteral(String time) {
|
||||
return wrapAsAnsiTimeLiteral(time);
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
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
|
||||
protected String wrapTimestampLiteral(String timestamp) {
|
||||
return "timestamp with time zone '" + timestamp + "'";
|
||||
public void appendDateTimeLiteral(
|
||||
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) {
|
||||
|
|
|
@ -129,7 +129,7 @@ public class PostgreSQLSqlAstTranslator<T extends JdbcOperation> extends Abstrac
|
|||
else if ( expression instanceof Summarization ) {
|
||||
Summarization summarization = (Summarization) expression;
|
||||
if ( getDialect().getVersion() >= 950 ) {
|
||||
appendSql( summarization.getKind().name().toLowerCase() );
|
||||
appendSql( summarization.getKind().sqlText() );
|
||||
appendSql( OPEN_PARENTHESIS );
|
||||
renderCommaSeparated( summarization.getGroupings() );
|
||||
appendSql( CLOSE_PARENTHESIS );
|
||||
|
|
|
@ -39,24 +39,33 @@ import org.hibernate.query.spi.QueryEngine;
|
|||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
import org.hibernate.tool.schema.internal.StandardSequenceExporter;
|
||||
import org.hibernate.tool.schema.spi.Exporter;
|
||||
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.SmallIntTypeDescriptor;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
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 static java.util.regex.Pattern.compile;
|
||||
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
|
||||
|
@ -674,8 +683,8 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
return datetimeFormat(format).result();
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
appender.appendSql( datetimeFormat(format).result() );
|
||||
}
|
||||
|
||||
public static Replacer datetimeFormat(String format) {
|
||||
|
@ -717,31 +726,96 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
|
|||
.replace("x", "zz");
|
||||
}
|
||||
|
||||
private static final Pattern OFFSET_PATTERN = compile(".*[-+]\\d{2}(:\\d{2})?$");
|
||||
|
||||
@Override
|
||||
public String formatBinaryLiteral(byte[] bytes) {
|
||||
return "0x" + StandardBasicTypes.BINARY.toString( bytes );
|
||||
public void appendBinaryLiteral(SqlAppender appender, byte[] bytes) {
|
||||
appender.appendSql( "0x" );
|
||||
PrimitiveByteArrayTypeDescriptor.INSTANCE.appendString( appender, bytes );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String wrapTimestampLiteral(String timestamp) {
|
||||
//needed because the {ts ... } JDBC escape chokes on microseconds
|
||||
return OFFSET_PATTERN.matcher( timestamp ).matches()
|
||||
? "cast('" + timestamp + "' as datetimeoffset)"
|
||||
: "cast('" + timestamp + "' as datetime2)";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String wrapTimeLiteral(String time) {
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
TemporalAccessor temporalAccessor,
|
||||
TemporalType precision,
|
||||
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
|
||||
return "cast('" + time + "' as time)";
|
||||
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
|
||||
protected String wrapDateLiteral(String date) {
|
||||
//possibly not needed
|
||||
return "cast('" + date + "' as date)";
|
||||
public void appendDateTimeLiteral(SqlAppender appender, Date date, TemporalType precision, TimeZone jdbcTimeZone) {
|
||||
switch ( precision ) {
|
||||
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
|
||||
public void appendDateTimeLiteral(
|
||||
SqlAppender appender,
|
||||
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
|
||||
|
|
|
@ -52,12 +52,12 @@ public class SQLServerSqlAstTranslator<T extends JdbcOperation> extends Abstract
|
|||
int searchIndex = 0;
|
||||
int unionIndex;
|
||||
while ( ( unionIndex = tableExpression.indexOf( UNION_ALL, searchIndex ) ) != -1 ) {
|
||||
appendSql( tableExpression.substring( searchIndex, unionIndex ) );
|
||||
append( tableExpression, searchIndex, unionIndex );
|
||||
renderLockHint( lockMode );
|
||||
appendSql( UNION_ALL );
|
||||
searchIndex = unionIndex + UNION_ALL.length();
|
||||
}
|
||||
appendSql( tableExpression.substring( searchIndex, tableExpression.length() - 2 ) );
|
||||
append( tableExpression, searchIndex, tableExpression.length() - 2 );
|
||||
renderLockHint( lockMode );
|
||||
appendSql( " )" );
|
||||
|
||||
|
@ -82,24 +82,43 @@ public class SQLServerSqlAstTranslator<T extends JdbcOperation> extends Abstract
|
|||
private void renderLockHint(LockMode lockMode) {
|
||||
if ( getDialect().getVersion() >= 9 ) {
|
||||
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 ) {
|
||||
//noinspection deprecation
|
||||
case UPGRADE:
|
||||
case PESSIMISTIC_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;
|
||||
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;
|
||||
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;
|
||||
case UPGRADE_NOWAIT:
|
||||
appendSql( " with (updlock,holdlock,rowlock,nowait)" );
|
||||
|
@ -322,7 +341,7 @@ public class SQLServerSqlAstTranslator<T extends JdbcOperation> extends Abstract
|
|||
Summarization summarization = (Summarization) expression;
|
||||
renderCommaSeparated( summarization.getGroupings() );
|
||||
appendSql( " with " );
|
||||
appendSql( summarization.getKind().name().toLowerCase() );
|
||||
appendSql( summarization.getKind().sqlText() );
|
||||
}
|
||||
else {
|
||||
expression.accept( this );
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.hibernate.query.TemporalUnit;
|
|||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.tree.Statement;
|
||||
import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||
|
@ -416,8 +417,8 @@ public class SpannerDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toBooleanValueString(boolean bool) {
|
||||
return String.valueOf( bool );
|
||||
public void appendBooleanValueString(SqlAppender appender, boolean bool) {
|
||||
appender.appendSql( bool );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -489,8 +490,8 @@ public class SpannerDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
return datetimeFormat( format ).result();
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
appender.appendSql( datetimeFormat( format ).result() );
|
||||
}
|
||||
|
||||
public static Replacer datetimeFormat(String format) {
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.service.ServiceRegistry;
|
|||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
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.StandardSqlAstTranslatorFactory;
|
||||
import org.hibernate.sql.ast.tree.Statement;
|
||||
|
@ -317,7 +318,7 @@ public class SybaseDialect extends AbstractTransactSQLDialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String translateDatetimeFormat(String format) {
|
||||
public void appendDatetimeFormat(SqlAppender appender, String format) {
|
||||
throw new NotYetImplementedFor6Exception( "format() function not supported on Sybase");
|
||||
}
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
sqlAppender.appendSql( concatOperator );
|
||||
sqlAppender.appendSql( "''" );
|
||||
sqlAppender.appendSql( ",'\\0'),''),'\\0" );
|
||||
sqlAppender.appendSql( Integer.toString( argumentNumber ) );
|
||||
sqlAppender.appendSql( argumentNumber );
|
||||
sqlAppender.appendSql( "')" );
|
||||
sqlAppender.appendSql( concatOperator );
|
||||
sqlAppender.appendSql( "'\\0'" );
|
||||
|
@ -117,7 +117,7 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
sqlAppender.appendSql( concatOperator );
|
||||
sqlAppender.appendSql( "''" );
|
||||
sqlAppender.appendSql( ",'\\0'),''),'\\0" );
|
||||
sqlAppender.appendSql( Integer.toString( argumentNumber ) );
|
||||
sqlAppender.appendSql( argumentNumber );
|
||||
sqlAppender.appendSql( "')" );
|
||||
if ( caseWrapper ) {
|
||||
sqlAppender.appendSql( " else null end" );
|
||||
|
|
|
@ -58,7 +58,7 @@ public class SQLServerFormatEmulation extends AbstractSqmSelfRenderingFunctionDe
|
|||
datetime.accept( walker );
|
||||
}
|
||||
sqlAppender.appendSql(",'");
|
||||
sqlAppender.appendSql( dialect.translateDatetimeFormat( format.getFormat() ) );
|
||||
dialect.appendDatetimeFormat( sqlAppender, format.getFormat() );
|
||||
sqlAppender.appendSql("')");
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
|
@ -362,6 +361,34 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
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() {
|
||||
return getSessionFactory().getJdbcServices();
|
||||
}
|
||||
|
@ -964,7 +991,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
else {
|
||||
forUpdate.merge( getLockOptions() );
|
||||
forUpdate.applyAliases( dialect.getWriteRowLockStrategy(), querySpec );
|
||||
forUpdate.applyAliases( getDialect().getWriteRowLockStrategy(), querySpec );
|
||||
if ( LockMode.READ.lessThan( forUpdate.getLockMode() ) ) {
|
||||
final LockStrategy lockStrategy = determineLockingStrategy(
|
||||
querySpec,
|
||||
|
@ -994,7 +1021,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
else if ( lockOptions.getLockMode() != LockMode.NONE ) {
|
||||
final ForUpdateClause forUpdateClause = new ForUpdateClause();
|
||||
forUpdateClause.merge( getLockOptions() );
|
||||
forUpdateClause.applyAliases( dialect.getWriteRowLockStrategy(), querySpec );
|
||||
forUpdateClause.applyAliases( getDialect().getWriteRowLockStrategy(), querySpec );
|
||||
if ( LockMode.READ.lessThan( forUpdateClause.getLockMode() ) ) {
|
||||
final LockStrategy lockStrategy = determineLockingStrategy(
|
||||
querySpec,
|
||||
|
@ -1021,7 +1048,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
else if ( forUpdate != null ) {
|
||||
forUpdate.merge( getLockOptions() );
|
||||
forUpdate.applyAliases( dialect.getWriteRowLockStrategy(), querySpec );
|
||||
forUpdate.applyAliases( getDialect().getWriteRowLockStrategy(), querySpec );
|
||||
if ( LockMode.READ.lessThan( forUpdate.getLockMode() ) ) {
|
||||
final LockStrategy lockStrategy = determineLockingStrategy( querySpec, forUpdate, null );
|
||||
switch ( lockStrategy ) {
|
||||
|
@ -1095,7 +1122,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
default:
|
||||
if ( getDialect().supportsWait() ) {
|
||||
appendSql( " wait " );
|
||||
appendSql( Integer.toString( Math.round( timeoutMillis / 1e3f ) ) );
|
||||
appendSql( Math.round( timeoutMillis / 1e3f ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1484,7 +1511,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
visitSelectClause( querySpec.getSelectClause() );
|
||||
visitFromClause( querySpec.getFromClause() );
|
||||
visitWhereClause( querySpec );
|
||||
visitGroupByClause( querySpec, dialect.getGroupBySelectItemReferenceStrategy() );
|
||||
visitGroupByClause( querySpec, getDialect().getGroupBySelectItemReferenceStrategy() );
|
||||
visitHavingClause( querySpec );
|
||||
visitOrderBy( querySpec.getSortSpecifications() );
|
||||
visitOffsetFetchClause( querySpec );
|
||||
|
@ -1681,7 +1708,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
else if ( expression instanceof Summarization ) {
|
||||
Summarization summarization = (Summarization) expression;
|
||||
appendSql( summarization.getKind().name().toLowerCase() );
|
||||
appendSql( summarization.getKind().sqlText() );
|
||||
appendSql( OPEN_PARENTHESIS );
|
||||
renderCommaSeparated( summarization.getGroupings() );
|
||||
appendSql( CLOSE_PARENTHESIS );
|
||||
|
@ -2093,8 +2120,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
nullPrecedence = sessionFactory.getSessionFactoryOptions().getDefaultNullPrecedence();
|
||||
}
|
||||
final boolean renderNullPrecedence = nullPrecedence != null &&
|
||||
!nullPrecedence.isDefaultOrdering( sortOrder, dialect.getNullOrdering() );
|
||||
if ( renderNullPrecedence && !dialect.supportsNullPrecedence() ) {
|
||||
!nullPrecedence.isDefaultOrdering( sortOrder, getDialect().getNullOrdering() );
|
||||
if ( renderNullPrecedence && !getDialect().supportsNullPrecedence() ) {
|
||||
emulateSortSpecificationNullPrecedence( sortExpression, nullPrecedence );
|
||||
}
|
||||
|
||||
|
@ -2112,9 +2139,9 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
appendSql( " desc" );
|
||||
}
|
||||
|
||||
if ( renderNullPrecedence && dialect.supportsNullPrecedence() ) {
|
||||
if ( renderNullPrecedence && getDialect().supportsNullPrecedence() ) {
|
||||
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 );
|
||||
if ( offset != 0 ) {
|
||||
appendSql( '+' );
|
||||
appendSql( Integer.toString( offset ) );
|
||||
appendSql( offset );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2407,7 +2434,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
int offset) {
|
||||
final Number offsetCount = interpretExpression( offsetClauseExpression, jdbcParameterBindings );
|
||||
final Number fetchCount = interpretExpression( fetchClauseExpression, jdbcParameterBindings );
|
||||
appendSql( Integer.toString( fetchCount.intValue() + offsetCount.intValue() + offset ) );
|
||||
appendSql( fetchCount.intValue() + offsetCount.intValue() + offset );
|
||||
}
|
||||
|
||||
protected void renderFetchPlusOffsetExpressionAsSingleParameter(
|
||||
|
@ -2418,7 +2445,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
final Number fetchCount = (Number) ( (Literal) fetchClauseExpression ).getLiteralValue();
|
||||
if ( offsetClauseExpression instanceof Literal ) {
|
||||
final Number offsetCount = (Number) ( (Literal) offsetClauseExpression ).getLiteralValue();
|
||||
appendSql( Integer.toString( fetchCount.intValue() + offsetCount.intValue() + offset ) );
|
||||
appendSql( fetchCount.intValue() + offsetCount.intValue() + offset );
|
||||
}
|
||||
else {
|
||||
appendSql( PARAM_MARKER );
|
||||
|
@ -2653,7 +2680,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
}
|
||||
else {
|
||||
appendSql( Integer.toString( Integer.MAX_VALUE ) );
|
||||
appendSql( Integer.MAX_VALUE );
|
||||
}
|
||||
}
|
||||
else if ( fetchExpression != null ) {
|
||||
|
@ -2693,7 +2720,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
else if ( offsetExpression != null ) {
|
||||
appendSql( " limit " );
|
||||
appendSql( Integer.toString( Integer.MAX_VALUE ) );
|
||||
appendSql( Integer.MAX_VALUE );
|
||||
}
|
||||
if ( offsetExpression != null ) {
|
||||
final Stack<Clause> clauseStack = getClauseStack();
|
||||
|
@ -2784,7 +2811,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
appendSql( separator );
|
||||
appendSql( alias );
|
||||
appendSql( ".c" );
|
||||
appendSql( Integer.toString( i ) );
|
||||
appendSql( i );
|
||||
separator = COMA_SEPARATOR;
|
||||
}
|
||||
}
|
||||
|
@ -2944,7 +2971,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
protected void visitSqlSelections(SelectClause selectClause) {
|
||||
final List<SqlSelection> sqlSelections = selectClause.getSqlSelections();
|
||||
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,
|
||||
// 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
|
||||
|
@ -2967,7 +2994,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
visitSqlSelection( sqlSelection );
|
||||
parameterRenderingMode = original;
|
||||
appendSql( " c" );
|
||||
appendSql( Integer.toString( i ) );
|
||||
appendSql( i );
|
||||
separator = COMA_SEPARATOR;
|
||||
}
|
||||
if ( queryPartForRowNumbering != null ) {
|
||||
|
@ -3218,9 +3245,10 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
appendSql( "case when " );
|
||||
expression.accept( this );
|
||||
appendSql( " then " );
|
||||
appendSql( getDialect().toBooleanValueString( true ) );
|
||||
final Dialect dialect = getDialect();
|
||||
dialect.appendBooleanValueString( this, true );
|
||||
appendSql( " else " );
|
||||
appendSql( getDialect().toBooleanValueString( false ) );
|
||||
dialect.appendBooleanValueString( this, false );
|
||||
appendSql( " end" );
|
||||
}
|
||||
else {
|
||||
|
@ -3290,12 +3318,11 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
}
|
||||
else {
|
||||
appendSql(
|
||||
literalFormatter.toJdbcLiteral(
|
||||
literalFormatter.appendJdbcLiteral(
|
||||
this,
|
||||
literal.getLiteralValue(),
|
||||
dialect,
|
||||
getWrapperOptions()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -3557,9 +3584,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
|
||||
@Override
|
||||
public void visitFormat(Format format) {
|
||||
final String dialectFormat = getDialect().translateDatetimeFormat( format.getFormat() );
|
||||
appendSql( '\'' );
|
||||
appendSql( dialectFormat );
|
||||
getDialect().appendDatetimeFormat( this, format.getFormat() );
|
||||
appendSql( '\'' );
|
||||
}
|
||||
|
||||
|
@ -3680,297 +3706,16 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
|
||||
@Override
|
||||
public void visitSqlSelectionExpression(SqlSelectionExpression expression) {
|
||||
final boolean useSelectionPosition = dialect.supportsOrdinalSelectItemReference();
|
||||
final boolean useSelectionPosition = getDialect().supportsOrdinalSelectItemReference();
|
||||
|
||||
if ( useSelectionPosition ) {
|
||||
appendSql( Integer.toString( expression.getSelection().getJdbcResultSetIndex() ) );
|
||||
appendSql( expression.getSelection().getJdbcResultSetIndex() );
|
||||
}
|
||||
else {
|
||||
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
|
||||
public void visitEntityTypeLiteral(EntityTypeLiteral expression) {
|
||||
final EntityPersister entityTypeDescriptor = expression.getEntityTypeDescriptor();
|
||||
|
@ -4179,7 +3924,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
|
||||
private void visitLiteral(Literal literal) {
|
||||
if ( literal.getLiteralValue() == null ) {
|
||||
// todo : not sure we allow this "higher up"
|
||||
appendSql( SqlAppender.NULL_KEYWORD );
|
||||
}
|
||||
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" );
|
||||
}
|
||||
else {
|
||||
appendSql(
|
||||
literalFormatter.toJdbcLiteral(
|
||||
literalFormatter.appendJdbcLiteral(
|
||||
this,
|
||||
literalValue,
|
||||
dialect,
|
||||
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`
|
||||
booleanExpressionPredicate.getExpression().accept( this );
|
||||
appendSql( '=' );
|
||||
appendSql( getDialect().toBooleanValueString( true ) );
|
||||
getDialect().appendBooleanValueString( this, true );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -4314,7 +4057,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
ComparisonOperator.NOT_EQUAL :
|
||||
ComparisonOperator.EQUAL;
|
||||
// Some DBs like Oracle support tuples only for the IN subquery predicate
|
||||
if ( supportsRowValueConstructorSyntaxInInSubQuery() && dialect.supportsUnionAll() ) {
|
||||
if ( supportsRowValueConstructorSyntaxInInSubQuery() && getDialect().supportsUnionAll() ) {
|
||||
inListPredicate.getTestExpression().accept( this );
|
||||
if ( inListPredicate.isNegated() ) {
|
||||
appendSql( " not" );
|
||||
|
@ -4527,7 +4270,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
visitSelectClause( subQuery.getSelectClause() );
|
||||
visitFromClause( subQuery.getFromClause() );
|
||||
visitWhereClause( subQuery );
|
||||
visitGroupByClause( subQuery, dialect.getGroupBySelectItemReferenceStrategy() );
|
||||
visitGroupByClause( subQuery, getDialect().getGroupBySelectItemReferenceStrategy() );
|
||||
visitHavingClause( subQuery );
|
||||
|
||||
appendSql( " order by " );
|
||||
|
@ -4544,7 +4287,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
appendSql( order );
|
||||
for ( int i = 1; i < sqlSelections.size(); i++ ) {
|
||||
appendSql( COMA_SEPARATOR_CHAR );
|
||||
appendSql( Integer.toString( i + 1 ) );
|
||||
appendSql( i + 1 );
|
||||
appendSql( order );
|
||||
}
|
||||
renderFetch( ONE_LITERAL, null, FetchClauseType.ROWS_ONLY );
|
||||
|
@ -4613,13 +4356,13 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (dialect.supportsCaseInsensitiveLike()) {
|
||||
if (getDialect().supportsCaseInsensitiveLike()) {
|
||||
likePredicate.getMatchExpression().accept( this );
|
||||
if ( likePredicate.isNegated() ) {
|
||||
appendSql( " not" );
|
||||
}
|
||||
appendSql( WHITESPACE );
|
||||
appendSql( dialect.getCaseInsensitiveLike() );
|
||||
appendSql( getDialect().getCaseInsensitiveLike() );
|
||||
appendSql( WHITESPACE );
|
||||
likePredicate.getPattern().accept( this );
|
||||
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) {
|
||||
//LOWER(lhs) operator LOWER(rhs)
|
||||
appendSql( dialect.getLowercaseFunction() );
|
||||
appendSql( getDialect().getLowercaseFunction() );
|
||||
appendSql( OPEN_PARENTHESIS );
|
||||
lhs.accept( this );
|
||||
appendSql( CLOSE_PARENTHESIS );
|
||||
|
@ -4645,7 +4388,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
appendSql( " not" );
|
||||
}
|
||||
appendSql( " like " );
|
||||
appendSql( dialect.getLowercaseFunction() );
|
||||
appendSql( getDialect().getLowercaseFunction() );
|
||||
appendSql( OPEN_PARENTHESIS );
|
||||
rhs.accept( this );
|
||||
appendSql( CLOSE_PARENTHESIS );
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
*/
|
||||
package org.hibernate.sql.ast.spi;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Access to appending SQL fragments to an in-flight buffer
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface SqlAppender {
|
||||
public interface SqlAppender extends Appendable {
|
||||
String NO_SEPARATOR = "";
|
||||
String COMA_SEPARATOR = ",";
|
||||
char COMA_SEPARATOR_CHAR = ',';
|
||||
|
@ -29,17 +31,31 @@ public interface SqlAppender {
|
|||
*/
|
||||
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 );
|
||||
default void appendSql(int value) {
|
||||
appendSql( Integer.toString( value ) );
|
||||
}
|
||||
appendSql( c );
|
||||
|
||||
default void appendSql(boolean value) {
|
||||
appendSql( String.valueOf( value ) );
|
||||
}
|
||||
appendSql( quoteChar );
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,7 +43,17 @@ public class Summarization implements Expression {
|
|||
}
|
||||
|
||||
public enum Kind {
|
||||
ROLLUP,
|
||||
CUBE
|
||||
ROLLUP( "rollup" ),
|
||||
CUBE( "cube" );
|
||||
|
||||
private final String sqlText;
|
||||
|
||||
Kind(String sqlText) {
|
||||
this.sqlText = sqlText;
|
||||
}
|
||||
|
||||
public String sqlText() {
|
||||
return sqlText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,9 +13,13 @@ import java.time.format.DateTimeFormatter;
|
|||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
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_TIME;
|
||||
|
||||
|
@ -71,8 +75,8 @@ public final class DateTimeUtils {
|
|||
.optionalStart().appendZoneOrOffsetId().optionalEnd()
|
||||
.toFormatter();
|
||||
|
||||
private static final ThreadLocal<SimpleDateFormat> LOCAL_DATE_FORMAT = ThreadLocal.withInitial( DateTimeUtils::simpleDateFormatDate );
|
||||
private static final ThreadLocal<SimpleDateFormat> LOCAL_TIME_FORMAT = ThreadLocal.withInitial( DateTimeUtils::simpleDateFormatTime );
|
||||
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( () -> new SimpleDateFormat( FORMAT_STRING_TIME, Locale.ENGLISH ) );
|
||||
private static final ThreadLocal<SimpleDateFormat> TIMESTAMP_WITH_MILLIS_FORMAT = ThreadLocal.withInitial(
|
||||
() -> new SimpleDateFormat(
|
||||
FORMAT_STRING_TIMESTAMP_WITH_MILLIS,
|
||||
|
@ -103,201 +107,163 @@ public final class DateTimeUtils {
|
|||
.appendOffset("+HH:mm", "+00")
|
||||
.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 ( supportsOffset ) {
|
||||
return DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET.format( temporalAccessor );
|
||||
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS_AND_OFFSET.formatTo( temporalAccessor, appender );
|
||||
}
|
||||
else {
|
||||
return DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS.format(
|
||||
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MICROS.formatTo(
|
||||
LocalDateTime.ofInstant(
|
||||
Instant.from( temporalAccessor ),
|
||||
jdbcTimeZone.toZoneId()
|
||||
)
|
||||
),
|
||||
appender
|
||||
);
|
||||
}
|
||||
}
|
||||
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 ( supportsOffset ) {
|
||||
return DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET.format( temporalAccessor );
|
||||
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS_AND_OFFSET.formatTo( temporalAccessor, appender );
|
||||
}
|
||||
else {
|
||||
return DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS.format(
|
||||
DATE_TIME_FORMATTER_TIMESTAMP_WITH_MILLIS.formatTo(
|
||||
LocalDateTime.ofInstant(
|
||||
Instant.from( temporalAccessor ),
|
||||
jdbcTimeZone.toZoneId()
|
||||
)
|
||||
),
|
||||
appender
|
||||
);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
return DATE_TIME_FORMATTER_DATE.format( temporalAccessor );
|
||||
public static void appendAsDate(SqlAppender appender, TemporalAccessor 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 ( supportsOffset ) {
|
||||
return DATE_TIME_FORMATTER_TIME_WITH_OFFSET.format( temporalAccessor );
|
||||
DATE_TIME_FORMATTER_TIME_WITH_OFFSET.formatTo( temporalAccessor, appender );
|
||||
}
|
||||
else {
|
||||
return DATE_TIME_FORMATTER_TIME.format(
|
||||
DATE_TIME_FORMATTER_TIME.formatTo(
|
||||
LocalDateTime.ofInstant(
|
||||
Instant.from( temporalAccessor ),
|
||||
jdbcTimeZone.toZoneId()
|
||||
)
|
||||
),
|
||||
appender
|
||||
);
|
||||
}
|
||||
}
|
||||
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 TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
|
||||
try {
|
||||
simpleDateFormat.setTimeZone( jdbcTimeZone );
|
||||
return simpleDateFormat.format( date );
|
||||
appender.appendSql( simpleDateFormat.format( date ) );
|
||||
}
|
||||
finally {
|
||||
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 TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
|
||||
try {
|
||||
simpleDateFormat.setTimeZone( jdbcTimeZone );
|
||||
return simpleDateFormat.format( date );
|
||||
appender.appendSql( simpleDateFormat.format( date ) );
|
||||
}
|
||||
finally {
|
||||
simpleDateFormat.setTimeZone( originalTimeZone );
|
||||
}
|
||||
}
|
||||
|
||||
public static String wrapAsJdbcDateLiteral(String literal) {
|
||||
return JDBC_ESCAPE_START_DATE + literal + JDBC_ESCAPE_END;
|
||||
public static void appendAsDate(SqlAppender appender, Date date) {
|
||||
appender.appendSql( LOCAL_DATE_FORMAT.get().format( date ) );
|
||||
}
|
||||
|
||||
public static String wrapAsJdbcTimeLiteral(String literal) {
|
||||
return JDBC_ESCAPE_START_TIME + literal + JDBC_ESCAPE_END;
|
||||
public static void appendAsTime(SqlAppender appender, java.util.Date date) {
|
||||
appender.appendSql( LOCAL_TIME_FORMAT.get().format( date ) );
|
||||
}
|
||||
|
||||
public static String wrapAsJdbcTimestampLiteral(String literal) {
|
||||
return JDBC_ESCAPE_START_TIMESTAMP + literal + JDBC_ESCAPE_END;
|
||||
}
|
||||
|
||||
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) {
|
||||
public static void appendAsTimestampWithMillis(
|
||||
SqlAppender appender,
|
||||
java.util.Calendar calendar,
|
||||
TimeZone jdbcTimeZone) {
|
||||
final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MILLIS_FORMAT.get();
|
||||
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
|
||||
try {
|
||||
simpleDateFormat.setTimeZone( jdbcTimeZone );
|
||||
return simpleDateFormat.format( calendar.getTime() );
|
||||
appender.appendSql( simpleDateFormat.format( calendar.getTime() ) );
|
||||
}
|
||||
finally {
|
||||
simpleDateFormat.setTimeZone( originalTimeZone );
|
||||
}
|
||||
}
|
||||
|
||||
public static SimpleDateFormat simpleDateFormatTimestampWithMillis(TimeZone timeZone) {
|
||||
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) {
|
||||
public static void appendAsTimestampWithMicros(SqlAppender appender, Calendar calendar, TimeZone jdbcTimeZone) {
|
||||
final SimpleDateFormat simpleDateFormat = TIMESTAMP_WITH_MICROS_FORMAT.get();
|
||||
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
|
||||
try {
|
||||
simpleDateFormat.setTimeZone( jdbcTimeZone );
|
||||
return simpleDateFormat.format( calendar.getTime() );
|
||||
appender.appendSql( simpleDateFormat.format( calendar.getTime() ) );
|
||||
}
|
||||
finally {
|
||||
simpleDateFormat.setTimeZone( originalTimeZone );
|
||||
}
|
||||
}
|
||||
|
||||
public static SimpleDateFormat simpleDateFormatTimestampWithMicros(TimeZone timeZone) {
|
||||
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) {
|
||||
public static void appendAsDate(SqlAppender appender, java.util.Calendar calendar) {
|
||||
final SimpleDateFormat simpleDateFormat = LOCAL_DATE_FORMAT.get();
|
||||
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
|
||||
try {
|
||||
simpleDateFormat.setTimeZone( calendar.getTimeZone() );
|
||||
return simpleDateFormat.format( calendar.getTime() );
|
||||
appender.appendSql( simpleDateFormat.format( calendar.getTime() ) );
|
||||
}
|
||||
finally {
|
||||
simpleDateFormat.setTimeZone( originalTimeZone );
|
||||
}
|
||||
}
|
||||
|
||||
public static SimpleDateFormat simpleDateFormatDate(TimeZone timeZone) {
|
||||
final SimpleDateFormat formatter = new SimpleDateFormat( FORMAT_STRING_DATE, Locale.ENGLISH );
|
||||
formatter.setTimeZone( timeZone );
|
||||
return formatter;
|
||||
}
|
||||
|
||||
public static String formatAsTime(java.util.Calendar calendar) {
|
||||
public static void appendAsTime(SqlAppender appender, java.util.Calendar calendar) {
|
||||
final SimpleDateFormat simpleDateFormat = LOCAL_TIME_FORMAT.get();
|
||||
final TimeZone originalTimeZone = simpleDateFormat.getTimeZone();
|
||||
try {
|
||||
simpleDateFormat.setTimeZone( calendar.getTimeZone() );
|
||||
return simpleDateFormat.format( calendar.getTime() );
|
||||
appender.appendSql( simpleDateFormat.format( calendar.getTime() ) );
|
||||
}
|
||||
finally {
|
||||
simpleDateFormat.setTimeZone( originalTimeZone );
|
||||
}
|
||||
}
|
||||
|
||||
public static SimpleDateFormat simpleDateFormatTime(TimeZone timeZone) {
|
||||
final SimpleDateFormat formatter = new SimpleDateFormat( FORMAT_STRING_TIME, Locale.ENGLISH );
|
||||
formatter.setTimeZone( timeZone );
|
||||
return formatter;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.util.Comparator;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.jdbc.BinaryStream;
|
||||
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
|
||||
/**
|
||||
|
@ -48,14 +49,18 @@ public class PrimitiveByteArrayTypeDescriptor extends AbstractClassTypeDescripto
|
|||
|
||||
public String toString(byte[] bytes) {
|
||||
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 ) {
|
||||
final String hexStr = Integer.toHexString( Byte.toUnsignedInt(aByte) );
|
||||
if ( hexStr.length() == 1 ) {
|
||||
buf.append( '0' );
|
||||
appender.appendSql( '0' );
|
||||
}
|
||||
buf.append( hexStr );
|
||||
appender.appendSql( hexStr );
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.type.descriptor.jdbc;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
|
||||
/**
|
||||
|
@ -24,5 +25,11 @@ import org.hibernate.type.descriptor.WrapperOptions;
|
|||
public interface JdbcLiteralFormatter<T> {
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ public interface JdbcTypeDescriptor extends Serializable {
|
|||
* todo (6.0) : move to {@link org.hibernate.metamodel.mapping.JdbcMapping}?
|
||||
*/
|
||||
default <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaTypeDescriptor<T> javaTypeDescriptor) {
|
||||
return (value, dialect, wrapperOptions) -> value.toString();
|
||||
return (appender, value, dialect, wrapperOptions) -> appender.appendSql( value.toString() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.type.descriptor.jdbc.internal;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
|
||||
|
@ -17,12 +18,12 @@ import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public class JdbcLiteralFormatterBinary extends BasicJdbcLiteralFormatter {
|
||||
public JdbcLiteralFormatterBinary(JavaTypeDescriptor javaTypeDescriptor) {
|
||||
public JdbcLiteralFormatterBinary(JavaTypeDescriptor<?> javaTypeDescriptor) {
|
||||
super( javaTypeDescriptor );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJdbcLiteral(Object value, Dialect dialect, WrapperOptions wrapperOptions) {
|
||||
return dialect.formatBinaryLiteral( unwrap( value, byte[].class, wrapperOptions ) );
|
||||
public void appendJdbcLiteral(SqlAppender appender, Object value, Dialect dialect, WrapperOptions wrapperOptions) {
|
||||
dialect.appendBinaryLiteral( appender, unwrap( value, byte[].class, wrapperOptions ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.type.descriptor.jdbc.internal;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
|
||||
|
@ -17,12 +18,12 @@ import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JdbcLiteralFormatterBoolean extends BasicJdbcLiteralFormatter {
|
||||
public JdbcLiteralFormatterBoolean(JavaTypeDescriptor javaTypeDescriptor) {
|
||||
public JdbcLiteralFormatterBoolean(JavaTypeDescriptor<?> javaTypeDescriptor) {
|
||||
super( javaTypeDescriptor );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJdbcLiteral(Object value, Dialect dialect, WrapperOptions wrapperOptions) {
|
||||
return dialect.toBooleanValueString( unwrap( value, Boolean.class, wrapperOptions ) );
|
||||
public void appendJdbcLiteral(SqlAppender appender, Object value, Dialect dialect, WrapperOptions wrapperOptions) {
|
||||
dialect.appendBooleanValueString( appender, unwrap( value, Boolean.class, wrapperOptions ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.type.descriptor.jdbc.internal;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
|
||||
|
@ -21,26 +22,21 @@ public class JdbcLiteralFormatterCharacterData extends BasicJdbcLiteralFormatter
|
|||
|
||||
private final boolean isNationalized;
|
||||
|
||||
public JdbcLiteralFormatterCharacterData(JavaTypeDescriptor javaTypeDescriptor) {
|
||||
public JdbcLiteralFormatterCharacterData(JavaTypeDescriptor<?> javaTypeDescriptor) {
|
||||
this( javaTypeDescriptor, false );
|
||||
}
|
||||
|
||||
public JdbcLiteralFormatterCharacterData(JavaTypeDescriptor javaTypeDescriptor, boolean isNationalized) {
|
||||
public JdbcLiteralFormatterCharacterData(JavaTypeDescriptor<?> javaTypeDescriptor, boolean isNationalized) {
|
||||
super( javaTypeDescriptor );
|
||||
this.isNationalized = isNationalized;
|
||||
}
|
||||
|
||||
@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 inlineLiteral = dialect.inlineLiteral( literalValue );
|
||||
|
||||
if ( isNationalized ) {
|
||||
// is there a standardized form for n-string literals? This is the SQL Server syntax for sure
|
||||
return NATIONALIZED_PREFIX.concat( inlineLiteral );
|
||||
appender.appendSql( NATIONALIZED_PREFIX );
|
||||
}
|
||||
|
||||
return inlineLiteral;
|
||||
dialect.appendLiteral( appender, literalValue );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.type.descriptor.jdbc.internal;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.BasicJdbcLiteralFormatter;
|
||||
|
@ -18,14 +19,14 @@ public class JdbcLiteralFormatterNumericData extends BasicJdbcLiteralFormatter {
|
|||
private final Class<? extends Number> unwrapJavaType;
|
||||
|
||||
public JdbcLiteralFormatterNumericData(
|
||||
JavaTypeDescriptor javaTypeDescriptor,
|
||||
JavaTypeDescriptor<?> javaTypeDescriptor,
|
||||
Class<? extends Number> unwrapJavaType) {
|
||||
super( javaTypeDescriptor );
|
||||
this.unwrapJavaType = unwrapJavaType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJdbcLiteral(Object value, Dialect dialect, WrapperOptions wrapperOptions) {
|
||||
return unwrap( value, unwrapJavaType, wrapperOptions ).toString();
|
||||
public void appendJdbcLiteral(SqlAppender appender, Object value, Dialect dialect, WrapperOptions wrapperOptions) {
|
||||
appender.appendSql( unwrap( value, unwrapJavaType, wrapperOptions ).toString() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.TimeZone;
|
|||
import jakarta.persistence.TemporalType;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
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 {
|
||||
private final TemporalType precision;
|
||||
|
||||
public JdbcLiteralFormatterTemporal(JavaTypeDescriptor javaTypeDescriptor, TemporalType precision) {
|
||||
public JdbcLiteralFormatterTemporal(JavaTypeDescriptor<?> javaTypeDescriptor, TemporalType precision) {
|
||||
super( javaTypeDescriptor );
|
||||
this.precision = precision;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJdbcLiteral(Object value, Dialect dialect, WrapperOptions wrapperOptions) {
|
||||
public void appendJdbcLiteral(SqlAppender appender, Object value, Dialect dialect, WrapperOptions wrapperOptions) {
|
||||
final TimeZone jdbcTimeZone;
|
||||
if ( wrapperOptions == null || wrapperOptions.getJdbcTimeZone() == null ) {
|
||||
jdbcTimeZone = TimeZone.getDefault();
|
||||
|
@ -37,48 +38,55 @@ public class JdbcLiteralFormatterTemporal extends BasicJdbcLiteralFormatter {
|
|||
}
|
||||
// for performance reasons, avoid conversions if we can
|
||||
if ( value instanceof java.util.Date ) {
|
||||
return dialect.formatDateTimeLiteral(
|
||||
dialect.appendDateTimeLiteral(
|
||||
appender,
|
||||
(java.util.Date) value,
|
||||
precision,
|
||||
jdbcTimeZone
|
||||
);
|
||||
}
|
||||
else if ( value instanceof java.util.Calendar ) {
|
||||
return dialect.formatDateTimeLiteral(
|
||||
dialect.appendDateTimeLiteral(
|
||||
appender,
|
||||
(java.util.Calendar) value,
|
||||
precision,
|
||||
jdbcTimeZone
|
||||
);
|
||||
}
|
||||
else if ( value instanceof TemporalAccessor ) {
|
||||
return dialect.formatDateTimeLiteral(
|
||||
dialect.appendDateTimeLiteral(
|
||||
appender,
|
||||
(TemporalAccessor) value,
|
||||
precision,
|
||||
jdbcTimeZone
|
||||
);
|
||||
}
|
||||
|
||||
else {
|
||||
switch ( precision ) {
|
||||
case DATE: {
|
||||
return dialect.formatDateTimeLiteral(
|
||||
case DATE:
|
||||
dialect.appendDateTimeLiteral(
|
||||
appender,
|
||||
unwrap( value, java.sql.Date.class, wrapperOptions ),
|
||||
precision,
|
||||
jdbcTimeZone
|
||||
);
|
||||
}
|
||||
case TIME: {
|
||||
return dialect.formatDateTimeLiteral(
|
||||
break;
|
||||
case TIME:
|
||||
dialect.appendDateTimeLiteral(
|
||||
appender,
|
||||
unwrap( value, java.sql.Time.class, wrapperOptions ),
|
||||
precision,
|
||||
jdbcTimeZone
|
||||
);
|
||||
}
|
||||
default: {
|
||||
return dialect.formatDateTimeLiteral(
|
||||
break;
|
||||
default:
|
||||
dialect.appendDateTimeLiteral(
|
||||
appender,
|
||||
unwrap( value, java.util.Date.class, wrapperOptions ),
|
||||
precision,
|
||||
jdbcTimeZone
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -354,7 +354,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
|||
private String sessionFactoryName;
|
||||
private String sessionFactoryUuid;
|
||||
|
||||
private transient JdbcTypeDescriptorIndicators currentSqlTypeIndicators = new JdbcTypeDescriptorIndicators() {
|
||||
private final transient JdbcTypeDescriptorIndicators currentSqlTypeIndicators = new JdbcTypeDescriptorIndicators() {
|
||||
@Override
|
||||
public TypeConfiguration getTypeConfiguration() {
|
||||
return typeConfiguration;
|
||||
|
|
|
@ -52,9 +52,17 @@ public class PGGeometryTypeDescriptor implements JdbcTypeDescriptor {
|
|||
@Override
|
||||
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaTypeDescriptor<T> javaTypeDescriptor) {
|
||||
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) {
|
||||
|
|
|
@ -334,7 +334,7 @@ abstract public class DialectFeatureChecks {
|
|||
public static class SupportsFormat implements DialectFeatureCheck {
|
||||
public boolean apply(Dialect dialect) {
|
||||
try {
|
||||
dialect.translateDatetimeFormat( "" );
|
||||
dialect.appendDatetimeFormat( new StringBuilder()::append, "" );
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
|
@ -346,7 +346,7 @@ abstract public class DialectFeatureChecks {
|
|||
public static class SupportsTruncateThroughCast implements DialectFeatureCheck {
|
||||
public boolean apply(Dialect dialect) {
|
||||
try {
|
||||
dialect.translateDatetimeFormat( "" );
|
||||
dialect.appendDatetimeFormat( new StringBuilder()::append, "" );
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
|
|
Loading…
Reference in New Issue