Skip to content

HHH-14584 Allow PhysicalNamingStrategy implementations to detect when a name is implicit or explicit #10366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,11 @@ public Identifier toIdentifier(String text, boolean quoted) {
return normalizeQuoting( Identifier.toIdentifier( text, quoted ) );
}

@Override
public Identifier toIdentifier(String text, boolean quoted, boolean isExplicit) {
return normalizeQuoting( Identifier.toIdentifier( text, quoted, isExplicit ) );
}

@Override
public Identifier normalizeQuoting(Identifier identifier) {
Identifier normalizedIdentifier = this.helper.normalizeQuoting( identifier );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -917,15 +917,16 @@ public Table addTable(
String name,
String subselectFragment,
boolean isAbstract,
MetadataBuildingContext buildingContext) {
MetadataBuildingContext buildingContext,
boolean isExplicit) {
final Namespace namespace = getDatabase().locateNamespace(
getDatabase().toIdentifier( catalogName ),
getDatabase().toIdentifier( schemaName )
);

// annotation binding depends on the "table name" for @Subselect bindings
// being set into the generated table (mainly to avoid later NPE), but for now we need to keep that :(
final Identifier logicalName = name != null ? getDatabase().toIdentifier( name ) : null;
final Identifier logicalName = name != null ? getDatabase().toIdentifier( name, isExplicit ) : null;

if ( subselectFragment != null ) {
return new Table( buildingContext.getCurrentContributorName(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,10 @@ public boolean isNameDeferred() {
* @return {@code true} if a name could be inferred
*/
boolean inferColumnNameIfPossible(String columnName, String propertyName, boolean applyNamingStrategy) {
if ( !isEmpty( columnName ) || !isEmpty( propertyName ) ) {
if ( isNotEmpty( columnName ) || isNotEmpty( propertyName ) ) {
final String logicalColumnName = resolveLogicalColumnName( columnName, propertyName );
mappingColumn.setName( processColumnName( logicalColumnName, applyNamingStrategy ) );
mappingColumn.setName(
processColumnName( logicalColumnName, applyNamingStrategy, isNotEmpty( columnName ) ) );
return true;
}
else {
Expand Down Expand Up @@ -411,11 +412,12 @@ private String applyEmbeddedColumnNaming(String inferredColumnName, ComponentPro
return result;
}

protected String processColumnName(String columnName, boolean applyNamingStrategy) {
protected String processColumnName(String columnName, boolean applyNamingStrategy, boolean isExplicit) {
if ( applyNamingStrategy ) {
final Database database = getDatabase();
return getPhysicalNamingStrategy()
.toPhysicalColumnName( database.toIdentifier( columnName ), database.getJdbcEnvironment() )
.toPhysicalColumnName( database.toIdentifier( columnName, isExplicit ),
database.getJdbcEnvironment() )
.render( database.getDialect() );
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,8 @@ public void overrideFromReferencedColumnIfNecessary(Column column) {
@Override
boolean inferColumnNameIfPossible(String columnName, String propertyName, boolean applyNamingStrategy) {
if ( isNotEmpty( columnName ) ) {
getMappingColumn().setName( processColumnName( columnName, applyNamingStrategy ) );
getMappingColumn().setName(
processColumnName( columnName, applyNamingStrategy, isNotEmpty( columnName ) ) );
return true;
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1773,7 +1773,8 @@ public MetadataBuildingContext getBuildingContext() {

@Override
public Identifier handleExplicitName(String explicitName, MetadataBuildingContext buildingContext) {
return jdbcEnvironment( buildingContext ).getIdentifierHelper().toIdentifier( explicitName );
return jdbcEnvironment( buildingContext ).getIdentifierHelper()
.toIdentifier( explicitName, false, true );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,8 @@ private static Table addTable(
logicalName.render(),
subselect,
isAbstract,
buildingContext
buildingContext,
logicalName.isExplicit()
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
public class Identifier implements Comparable<Identifier> {
private final String text;
private final boolean isQuoted;
private final boolean isExplicit;

/**
* Means to generate an {@link Identifier} instance from its simple text form.
Expand Down Expand Up @@ -62,7 +63,7 @@ public static Identifier toIdentifier(String text) {
* @return The identifier form, or {@code null} if text was {@code null}
*/
public static Identifier toIdentifier(String text, boolean quote) {
return toIdentifier( text, quote, true );
return toIdentifier( text, quote, true, false );
}

/**
Expand All @@ -81,6 +82,25 @@ public static Identifier toIdentifier(String text, boolean quote) {
* @return The identifier form, or {@code null} if text was {@code null}
*/
public static Identifier toIdentifier(String text, boolean quote, boolean autoquote) {
return toIdentifier( text, quote, autoquote, false );
}

/**
* Means to generate an {@link Identifier} instance from its simple text form.
* <p>
* If passed {@code text} is {@code null}, {@code null} is returned.
* <p>
* If passed {@code text} is surrounded in quote markers, the returned Identifier
* is considered quoted. Quote markers include back-ticks (`), double-quotes ("),
* and brackets ([ and ]).
*
* @param text The text form
* @param quote Whether to quote unquoted text forms
* @param autoquote Whether to quote the result if it contains special characters
* @param isExplicit Whether the name is explicitly set
* @return The identifier form, or {@code null} if text was {@code null}
*/
public static Identifier toIdentifier(String text, boolean quote, boolean autoquote, boolean isExplicit) {
if ( isBlank( text ) ) {
return null;
}
Expand All @@ -106,7 +126,7 @@ public static Identifier toIdentifier(String text, boolean quote, boolean autoqu
else if ( autoquote && !quote ) {
quote = autoquote( text, start, end );
}
return new Identifier( text.substring( start, end ), quote );
return new Identifier( text.substring( start, end ), quote, isExplicit );
}

private static boolean autoquote(String text, int start, int end) {
Expand Down Expand Up @@ -184,6 +204,17 @@ public static String unQuote(String name) {
* @param quoted Is this a quoted identifier?
*/
public Identifier(String text, boolean quoted) {
this( text, quoted, false );
}

/**
* Constructs an identifier instance.
*
* @param text The identifier text.
* @param quoted Is this a quoted identifier?
* @param isExplicit Whether the name is explicitly set
*/
public Identifier(String text, boolean quoted, boolean isExplicit) {
if ( isEmpty( text ) ) {
throw new IllegalIdentifierException( "Identifier text cannot be null" );
}
Expand All @@ -192,6 +223,7 @@ public Identifier(String text, boolean quoted) {
}
this.text = text;
this.isQuoted = quoted;
this.isExplicit = isExplicit;
}

/**
Expand All @@ -202,6 +234,7 @@ public Identifier(String text, boolean quoted) {
protected Identifier(String text) {
this.text = text;
this.isQuoted = false;
this.isExplicit = false;
}

/**
Expand Down Expand Up @@ -295,4 +328,8 @@ public static boolean areEqual(Identifier id1, Identifier id2) {
public static Identifier quote(Identifier identifier) {
return identifier.quoted();
}

public boolean isExplicit() {
return isExplicit;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,24 @@ public JdbcEnvironment getJdbcEnvironment() {
* @return The wrapped Identifier form
*/
public Identifier toIdentifier(String text) {
return text == null ? null : jdbcEnvironment.getIdentifierHelper().toIdentifier( text );
return toIdentifier( text, false );
}

/**
* Wrap the raw name of a database object in its Identifier form accounting
* for quoting from any of:
* <ul>
* <li>explicit quoting in the name itself</li>
* <li>global request to quote all identifiers</li>
* </ul>
*
* @param text The raw object name
* @param isExplicit Whether the name is explicitly set
* @return The wrapped Identifier form
* @implNote Quoting from database keywords happens only when building physical identifiers.
*/
public Identifier toIdentifier(String text, boolean isExplicit) {
return text == null ? null : jdbcEnvironment.getIdentifierHelper().toIdentifier( text, false, isExplicit );
}

public PhysicalNamingStrategy getPhysicalNamingStrategy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public NameParts parse(String text, Identifier defaultCatalog, Identifier defaul
return new NameParts(
defaultCatalog,
defaultSchema,
Identifier.toIdentifier( unquote( text ), true )
Identifier.toIdentifier( unquote( text ), true, true, true )
);
}

Expand Down Expand Up @@ -173,7 +173,7 @@ else if ( defaultCatalog != null ) {
return new NameParts(
Identifier.toIdentifier( catalogName, wasQuotedInEntirety||catalogWasQuoted ),
Identifier.toIdentifier( schemaName, wasQuotedInEntirety||schemaWasQuoted ),
Identifier.toIdentifier( name, wasQuotedInEntirety||nameWasQuoted )
Identifier.toIdentifier( name, wasQuotedInEntirety || nameWasQuoted, true, true )
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ default AnnotationDescriptorRegistry getAnnotationDescriptorRegistry() {
* @param subselect A select statement which defines a logical table, much
* like a DB view.
* @param isAbstract Is the table abstract (i.e. not really existing in the DB)?
* @param isExplicit Whether the name is explicitly set
*
* @return The created table metadata, or the existing reference.
*/
Expand All @@ -150,7 +151,8 @@ Table addTable(
String name,
String subselect,
boolean isAbstract,
MetadataBuildingContext buildingContext);
MetadataBuildingContext buildingContext,
boolean isExplicit);

/**
* Adds a 'denormalized table' to this repository.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,11 @@ public Identifier toIdentifier(String text, boolean quoted) {
return normalizeQuoting( Identifier.toIdentifier( text, quoted ) );
}

@Override
public Identifier toIdentifier(String text, boolean quoted, boolean isExplicit) {
return normalizeQuoting( Identifier.toIdentifier( text, quoted, isExplicit ) );
}

@Override
public Identifier normalizeQuoting(Identifier identifier) {
Identifier normalizedIdentifier = this.helper.normalizeQuoting( identifier );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ public Identifier toIdentifier(String text, boolean quoted) {
return normalizeQuoting( Identifier.toIdentifier( text, quoted ) );
}

@Override
public Identifier toIdentifier(String text, boolean quoted, boolean isExplicit) {
return normalizeQuoting( Identifier.toIdentifier( text, quoted, true, isExplicit ) );
}

@Override
public Identifier applyGlobalQuoting(String text) {
return Identifier.toIdentifier( text, globallyQuoteIdentifiers && !globallyQuoteIdentifiersSkipColumnDefinitions, false );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,21 @@ public interface IdentifierHelper {
*/
Identifier toIdentifier(String text, boolean quoted);

/**
* Generate an Identifier instance from its simple name as obtained from mapping
* information. Additionally, this form takes a boolean indicating whether to
* explicitly quote the Identifier.
* <p>
* Note that Identifiers returned from here may be implicitly quoted based on
* 'globally quoted identifiers' or based on reserved words.
*
* @param text The text form of a name as obtained from mapping information.
* @param quoted Is the identifier to be quoted explicitly.
* @param isExplicit Whether the name is explicitly set
* @return The identifier form of the name.
*/
Identifier toIdentifier(String text, boolean quoted, boolean isExplicit);

/**
* Intended only for use in handling quoting requirements for {@code column-definition}
* as defined by {@link jakarta.persistence.Column#columnDefinition()},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,10 @@ private static QualifiedName sequenceName(
IdentifierHelper identifierHelper) {
if ( isNotEmpty( explicitSequenceName ) ) {
// we have an explicit name, use it
return explicitSequenceName.contains(".")
return explicitSequenceName.contains( "." )
? QualifiedNameParser.INSTANCE.parse( explicitSequenceName )
: new QualifiedNameParser.NameParts( catalog, schema,
identifierHelper.toIdentifier( explicitSequenceName ) );
identifierHelper.toIdentifier( explicitSequenceName, false, true ) );
}
else {
// otherwise, determine an implicit name to use
Expand Down
Loading