HHH-15517 Fix for temporary table prefixing the qualified table name instead of just table name

This commit is contained in:
Christian Beikov 2022-09-19 15:06:35 +02:00
parent 398702a111
commit 544c1e0c94
4 changed files with 60 additions and 11 deletions

View File

@ -213,7 +213,7 @@ public class Identifier implements Comparable<Identifier> {
*/
public String render(Dialect dialect) {
return isQuoted
? dialect.openQuote() + getText() + dialect.closeQuote()
? dialect.toQuotedIdentifier( getText() )
: getText();
}

View File

@ -2360,6 +2360,22 @@ public abstract class Dialect implements ConversionContext {
return '"';
}
/**
* Apply dialect-specific quoting.
*
* @param name The value to be quoted.
* @return The quoted value.
* @see #openQuote()
* @see #closeQuote()
*/
public String toQuotedIdentifier(String name) {
if ( name == null ) {
return null;
}
return openQuote() + name + closeQuote();
}
/**
* Apply dialect-specific quoting.
* <p/>

View File

@ -599,6 +599,20 @@ public class SybaseASEDialect extends SybaseDialect {
return sql + new ForUpdateFragment( this, aliasedLockOptions, keyColumnNames ).toFragmentString();
}
@Override
public String toQuotedIdentifier(String name) {
if ( name == null || name.isEmpty() ) {
return name;
}
if ( name.charAt( 0 ) == '#' ) {
// Temporary tables must start with a '#' character,
// but Sybase doesn't support quoting of such identifiers,
// so we simply don't apply quoting in this case
return name;
}
return super.toQuotedIdentifier( name );
}
@Override
public ViolatedConstraintNameExtractor getViolatedConstraintNameExtractor() {
return EXTRACTOR;

View File

@ -14,6 +14,9 @@ import java.util.function.Function;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.relational.Exportable;
import org.hibernate.boot.model.relational.QualifiedNameParser;
import org.hibernate.boot.model.relational.QualifiedTableName;
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
import org.hibernate.dialect.Dialect;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.OptimizableGenerator;
@ -64,24 +67,38 @@ public class TemporaryTable implements Exportable, Contributable {
EntityMappingType entityDescriptor,
Function<String, String> temporaryTableNameAdjuster,
Dialect dialect,
SqlStringGenerationContext sqlStringGenerationContext,
Function<TemporaryTable, List<TemporaryTableColumn>> columnInitializer) {
this.entityDescriptor = entityDescriptor;
// The table name might be a sub-query, which is inappropriate for a temporary table name
final String originalTableName = entityDescriptor.getEntityPersister().getSynchronizedQuerySpaces()[0];
final String name;
if ( Identifier.isQuoted( originalTableName ) ) {
name = dialect.quote( temporaryTableNameAdjuster.apply( Identifier.unQuote( originalTableName ) ) );
final QualifiedNameParser.NameParts nameParts = QualifiedNameParser.INSTANCE.parse( originalTableName );
final QualifiedNameParser.NameParts adjustedNameParts = QualifiedNameParser.INSTANCE.parse(
temporaryTableNameAdjuster.apply( nameParts.getObjectName().getText() )
);
final String temporaryTableName = adjustedNameParts.getObjectName().getText();
final Identifier tableNameIdentifier;
if ( temporaryTableName.length() > dialect.getMaxIdentifierLength() ) {
tableNameIdentifier = new Identifier(
temporaryTableName.substring( 0, dialect.getMaxIdentifierLength() ),
nameParts.getObjectName().isQuoted()
);
}
else {
name = temporaryTableNameAdjuster.apply( originalTableName );
}
if ( name.length() > dialect.getMaxIdentifierLength() ) {
this.qualifiedTableName = name.substring( 0, dialect.getMaxIdentifierLength() );
}
else {
this.qualifiedTableName = name;
tableNameIdentifier = new Identifier( temporaryTableName, nameParts.getObjectName().isQuoted() );
}
this.qualifiedTableName = sqlStringGenerationContext.format(
new QualifiedTableName(
adjustedNameParts.getCatalogName() != null
? adjustedNameParts.getCatalogName()
: nameParts.getCatalogName(),
adjustedNameParts.getSchemaName() != null
? adjustedNameParts.getSchemaName()
: nameParts.getSchemaName(),
tableNameIdentifier
)
);
this.dialect = dialect;
if ( dialect.getSupportedTemporaryTableKind() == TemporaryTableKind.PERSISTENT ) {
final TypeConfiguration typeConfiguration = entityDescriptor.getEntityPersister()
@ -123,6 +140,7 @@ public class TemporaryTable implements Exportable, Contributable {
entityDescriptor,
temporaryTableNameAdjuster,
dialect,
runtimeModelCreationContext.getSessionFactory().getSqlStringGenerationContext(),
temporaryTable -> {
final List<TemporaryTableColumn> columns = new ArrayList<>();
final PersistentClass entityBinding = runtimeModelCreationContext.getBootModel()
@ -211,6 +229,7 @@ public class TemporaryTable implements Exportable, Contributable {
entityDescriptor,
temporaryTableNameAdjuster,
dialect,
runtimeModelCreationContext.getSessionFactory().getSqlStringGenerationContext(),
temporaryTable -> {
final List<TemporaryTableColumn> columns = new ArrayList<>();
final PersistentClass entityBinding = runtimeModelCreationContext.getBootModel()