Skip to content

Commit d50563a

Browse files
peter1123581321yrodiere
authored andcommitted
HHH-14584 Allow PhysicalNamingStrategy implementations to detect when a name is implicit or explicit
1 parent 66a030e commit d50563a

File tree

17 files changed

+316
-18
lines changed

17 files changed

+316
-18
lines changed

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HANALegacyDialect.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,11 @@ public Identifier toIdentifier(String text, boolean quoted) {
935935
return normalizeQuoting( Identifier.toIdentifier( text, quoted ) );
936936
}
937937

938+
@Override
939+
public Identifier toIdentifier(String text, boolean quoted, boolean isExplicit) {
940+
return normalizeQuoting( Identifier.toIdentifier( text, quoted, isExplicit ) );
941+
}
942+
938943
@Override
939944
public Identifier normalizeQuoting(Identifier identifier) {
940945
Identifier normalizedIdentifier = this.helper.normalizeQuoting( identifier );

hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -900,14 +900,15 @@ public Table addTable(
900900
String name,
901901
String subselectFragment,
902902
boolean isAbstract,
903-
MetadataBuildingContext buildingContext) {
903+
MetadataBuildingContext buildingContext,
904+
boolean isExplicit) {
904905
final Namespace namespace = getDatabase().locateNamespace(
905906
getDatabase().toIdentifier( catalogName ),
906907
getDatabase().toIdentifier( schemaName )
907908
);
908909
// annotation binding depends on the "table name" for @Subselect bindings
909910
// being set into the generated table (mainly to avoid later NPE), but for now we need to keep that :(
910-
final Identifier logicalName = name != null ? getDatabase().toIdentifier( name ) : null;
911+
final Identifier logicalName = name != null ? getDatabase().toIdentifier( name, isExplicit ) : null;
911912
if ( subselectFragment != null ) {
912913
return new Table( buildingContext.getCurrentContributorName(),
913914
namespace, logicalName, subselectFragment, isAbstract );

hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedColumn.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,10 @@ public boolean isNameDeferred() {
353353
* @return {@code true} if a name could be inferred
354354
*/
355355
boolean inferColumnNameIfPossible(String columnName, String propertyName, boolean applyNamingStrategy) {
356-
if ( !isEmpty( columnName ) || !isEmpty( propertyName ) ) {
356+
if ( isNotEmpty( columnName ) || isNotEmpty( propertyName ) ) {
357357
final String logicalColumnName = resolveLogicalColumnName( columnName, propertyName );
358-
mappingColumn.setName( processColumnName( logicalColumnName, applyNamingStrategy ) );
358+
mappingColumn.setName(
359+
processColumnName( logicalColumnName, applyNamingStrategy, isNotEmpty( columnName ) ) );
359360
return true;
360361
}
361362
else {
@@ -403,11 +404,12 @@ private String applyEmbeddedColumnNaming(String inferredColumnName, ComponentPro
403404
return result;
404405
}
405406

406-
protected String processColumnName(String columnName, boolean applyNamingStrategy) {
407+
protected String processColumnName(String columnName, boolean applyNamingStrategy, boolean isExplicit) {
407408
if ( applyNamingStrategy ) {
408409
final var database = getDatabase();
409410
return getPhysicalNamingStrategy()
410-
.toPhysicalColumnName( database.toIdentifier( columnName ), database.getJdbcEnvironment() )
411+
.toPhysicalColumnName( database.toIdentifier( columnName, isExplicit ),
412+
database.getJdbcEnvironment() )
411413
.render( database.getDialect() );
412414
}
413415
else {

hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedJoinColumn.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,8 @@ public void overrideFromReferencedColumnIfNecessary(Column column) {
458458
@Override
459459
boolean inferColumnNameIfPossible(String columnName, String propertyName, boolean applyNamingStrategy) {
460460
if ( isNotEmpty( columnName ) ) {
461-
getMappingColumn().setName( processColumnName( columnName, applyNamingStrategy ) );
461+
getMappingColumn().setName(
462+
processColumnName( columnName, applyNamingStrategy, isNotEmpty( columnName ) ) );
462463
return true;
463464
}
464465
else {

hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1760,7 +1760,8 @@ public MetadataBuildingContext getBuildingContext() {
17601760

17611761
@Override
17621762
public Identifier handleExplicitName(String explicitName, MetadataBuildingContext buildingContext) {
1763-
return jdbcEnvironment( buildingContext ).getIdentifierHelper().toIdentifier( explicitName );
1763+
return jdbcEnvironment( buildingContext ).getIdentifierHelper()
1764+
.toIdentifier( explicitName, false, true );
17641765
}
17651766

17661767
@Override

hibernate-core/src/main/java/org/hibernate/boot/model/internal/TableBinder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,8 @@ private static Table addTable(
542542
logicalName.render(),
543543
subselect,
544544
isAbstract,
545-
buildingContext
545+
buildingContext,
546+
logicalName.isExplicit()
546547
);
547548
}
548549
}

hibernate-core/src/main/java/org/hibernate/boot/model/naming/Identifier.java

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
public class Identifier implements Comparable<Identifier> {
2424
private final String text;
2525
private final boolean isQuoted;
26+
private final boolean isExplicit;
2627

2728
/**
2829
* Means to generate an {@link Identifier} instance from its simple text form.
@@ -62,7 +63,7 @@ public static Identifier toIdentifier(String text) {
6263
* @return The identifier form, or {@code null} if text was {@code null}
6364
*/
6465
public static Identifier toIdentifier(String text, boolean quote) {
65-
return toIdentifier( text, quote, true );
66+
return toIdentifier( text, quote, true, false );
6667
}
6768

6869
/**
@@ -81,6 +82,25 @@ public static Identifier toIdentifier(String text, boolean quote) {
8182
* @return The identifier form, or {@code null} if text was {@code null}
8283
*/
8384
public static Identifier toIdentifier(String text, boolean quote, boolean autoquote) {
85+
return toIdentifier( text, quote, autoquote, false );
86+
}
87+
88+
/**
89+
* Means to generate an {@link Identifier} instance from its simple text form.
90+
* <p>
91+
* If passed {@code text} is {@code null}, {@code null} is returned.
92+
* <p>
93+
* If passed {@code text} is surrounded in quote markers, the returned Identifier
94+
* is considered quoted. Quote markers include back-ticks (`), double-quotes ("),
95+
* and brackets ([ and ]).
96+
*
97+
* @param text The text form
98+
* @param quote Whether to quote unquoted text forms
99+
* @param autoquote Whether to quote the result if it contains special characters
100+
* @param isExplicit Whether the name is explicitly set
101+
* @return The identifier form, or {@code null} if text was {@code null}
102+
*/
103+
public static Identifier toIdentifier(String text, boolean quote, boolean autoquote, boolean isExplicit) {
84104
if ( isBlank( text ) ) {
85105
return null;
86106
}
@@ -106,7 +126,7 @@ public static Identifier toIdentifier(String text, boolean quote, boolean autoqu
106126
else if ( autoquote && !quote ) {
107127
quote = autoquote( text, start, end );
108128
}
109-
return new Identifier( text.substring( start, end ), quote );
129+
return new Identifier( text.substring( start, end ), quote, isExplicit );
110130
}
111131

112132
private static boolean autoquote(String text, int start, int end) {
@@ -184,6 +204,17 @@ public static String unQuote(String name) {
184204
* @param quoted Is this a quoted identifier?
185205
*/
186206
public Identifier(String text, boolean quoted) {
207+
this( text, quoted, false );
208+
}
209+
210+
/**
211+
* Constructs an identifier instance.
212+
*
213+
* @param text The identifier text.
214+
* @param quoted Is this a quoted identifier?
215+
* @param isExplicit Whether the name is explicitly set
216+
*/
217+
public Identifier(String text, boolean quoted, boolean isExplicit) {
187218
if ( isEmpty( text ) ) {
188219
throw new IllegalIdentifierException( "Identifier text cannot be null" );
189220
}
@@ -192,6 +223,7 @@ public Identifier(String text, boolean quoted) {
192223
}
193224
this.text = text;
194225
this.isQuoted = quoted;
226+
this.isExplicit = isExplicit;
195227
}
196228

197229
/**
@@ -202,6 +234,7 @@ public Identifier(String text, boolean quoted) {
202234
protected Identifier(String text) {
203235
this.text = text;
204236
this.isQuoted = false;
237+
this.isExplicit = false;
205238
}
206239

207240
/**
@@ -295,4 +328,8 @@ public static boolean areEqual(Identifier id1, Identifier id2) {
295328
public static Identifier quote(Identifier identifier) {
296329
return identifier.quoted();
297330
}
331+
332+
public boolean isExplicit() {
333+
return isExplicit;
334+
}
298335
}

hibernate-core/src/main/java/org/hibernate/boot/model/relational/Database.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,24 @@ public JdbcEnvironment getJdbcEnvironment() {
103103
* @return The wrapped Identifier form
104104
*/
105105
public Identifier toIdentifier(String text) {
106-
return text == null ? null : jdbcEnvironment.getIdentifierHelper().toIdentifier( text );
106+
return toIdentifier( text, false );
107+
}
108+
109+
/**
110+
* Wrap the raw name of a database object in its Identifier form accounting
111+
* for quoting from any of:
112+
* <ul>
113+
* <li>explicit quoting in the name itself</li>
114+
* <li>global request to quote all identifiers</li>
115+
* </ul>
116+
*
117+
* @param text The raw object name
118+
* @param isExplicit Whether the name is explicitly set
119+
* @return The wrapped Identifier form
120+
* @implNote Quoting from database keywords happens only when building physical identifiers.
121+
*/
122+
public Identifier toIdentifier(String text, boolean isExplicit) {
123+
return text == null ? null : jdbcEnvironment.getIdentifierHelper().toIdentifier( text, false, isExplicit );
107124
}
108125

109126
public PhysicalNamingStrategy getPhysicalNamingStrategy() {

hibernate-core/src/main/java/org/hibernate/boot/model/relational/QualifiedNameParser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public NameParts parse(String text, Identifier defaultCatalog, Identifier defaul
110110

111111
if ( isQuotedInEntirety( text ) ) {
112112
return new NameParts( defaultCatalog, defaultSchema,
113-
Identifier.toIdentifier( unquote( text ), true ) );
113+
Identifier.toIdentifier( unquote( text ), true, true, true ) );
114114
}
115115

116116
String catalogName = null;
@@ -169,7 +169,7 @@ else if ( defaultCatalog != null ) {
169169
return new NameParts(
170170
Identifier.toIdentifier( catalogName, catalogWasQuoted ),
171171
Identifier.toIdentifier( schemaName, schemaWasQuoted ),
172-
Identifier.toIdentifier( name, nameWasQuoted )
172+
Identifier.toIdentifier( name, nameWasQuoted, true, true )
173173
);
174174
}
175175

hibernate-core/src/main/java/org/hibernate/boot/spi/InFlightMetadataCollector.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ default AnnotationDescriptorRegistry getAnnotationDescriptorRegistry() {
140140
* @param subselect A select statement which defines a logical table, much
141141
* like a DB view.
142142
* @param isAbstract Is the table abstract (i.e. not really existing in the DB)?
143+
* @param isExplicit Whether the name is explicitly set
143144
*
144145
* @return The created table metadata, or the existing reference.
145146
*/
@@ -149,7 +150,8 @@ Table addTable(
149150
String name,
150151
String subselect,
151152
boolean isAbstract,
152-
MetadataBuildingContext buildingContext);
153+
MetadataBuildingContext buildingContext,
154+
boolean isExplicit);
153155

154156
/**
155157
* Adds a 'denormalized table' to this repository.

0 commit comments

Comments
 (0)