HHH-16765 - Cannot parse quoted table name

This commit is contained in:
Steve Ebersole 2023-07-19 12:08:12 -05:00
parent e2504647d4
commit cd24ddf8e6
2 changed files with 159 additions and 9 deletions

View File

@ -11,6 +11,7 @@ import java.util.Objects;
import org.hibernate.HibernateException;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.IllegalIdentifierException;
import org.hibernate.internal.util.StringHelper;
/**
* Parses a qualified name.
@ -114,6 +115,17 @@ public class QualifiedNameParser {
throw new IllegalIdentifierException( "Object name to parse must be specified, but found null" );
}
final int quoteCharCount = StringHelper.count( text, "`" );
final boolean wasQuotedInEntirety = quoteCharCount == 2 && text.startsWith( "`" ) && text.endsWith( "`" );
if ( wasQuotedInEntirety ) {
return new NameParts(
defaultCatalog,
defaultSchema,
Identifier.toIdentifier( unquote( text ), true )
);
}
String catalogName = null;
String schemaName = null;
String name;
@ -122,15 +134,6 @@ public class QualifiedNameParser {
boolean schemaWasQuoted = false;
boolean nameWasQuoted;
// Note that we try to handle both forms of quoting,
// 1) where the entire string was quoted
// 2) where one or more individual parts were quoted
boolean wasQuotedInEntirety = text.startsWith( "`" ) && text.endsWith( "`" );
if ( wasQuotedInEntirety ) {
text = unquote( text );
}
final String[] tokens = text.split( "\\." );
if ( tokens.length == 0 || tokens.length == 1 ) {
// we have just a local name...

View File

@ -0,0 +1,147 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.orm.test.naming;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.relational.QualifiedNameParser;
import org.hibernate.boot.model.relational.QualifiedNameParser.NameParts;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Steve Ebersole
*/
public class QualifiedNameParserTests {
private final Identifier NO_CATALOG = Identifier.toIdentifier( "" );
private final Identifier NO_SCHEMA = Identifier.toIdentifier( "" );
private final Identifier CATALOG1 = Identifier.toIdentifier( "catalog1", false );
private final Identifier SCHEMA1 = Identifier.toIdentifier( "schema1", false );
private final Identifier CATALOG2 = Identifier.toIdentifier( "catalog2", true );
private final Identifier SCHEMA2 = Identifier.toIdentifier( "schema2", true );
@Test
void testSimpleUnquoted() {
final String nameText = "tbl";
final Identifier name = Identifier.toIdentifier( nameText );
assert !name.isQuoted();
test(
nameText,
NO_CATALOG,
NO_SCHEMA,
NO_CATALOG,
NO_SCHEMA,
name
);
test(
nameText,
CATALOG1,
SCHEMA1,
CATALOG1,
SCHEMA1,
name
);
}
@Test
void testSimpleQuoted() {
final String nameText = "`tbl`";
final Identifier name = Identifier.toIdentifier( nameText );
assert name.isQuoted();
test(
nameText,
NO_CATALOG,
NO_SCHEMA,
NO_CATALOG,
NO_SCHEMA,
name
);
test(
nameText,
CATALOG1,
SCHEMA1,
CATALOG1,
SCHEMA1,
name
);
}
@Test
void testIndividualQuotes() {
final String name = "`schema2`.`catalog2`.`tbl`";
test(
name,
NO_CATALOG,
NO_SCHEMA,
CATALOG2,
SCHEMA2,
Identifier.toIdentifier( "tbl", true )
);
test(
name,
CATALOG1,
SCHEMA1,
CATALOG2,
SCHEMA2,
Identifier.toIdentifier( "tbl", true )
);
}
@Test
void testCrazyName() {
final String nameText = "`abc.def.ghi::other.stuff`";
final Identifier name = Identifier.toIdentifier( nameText );
assert name.isQuoted();
test(
nameText,
NO_CATALOG,
NO_SCHEMA,
NO_CATALOG,
NO_SCHEMA,
name
);
test(
nameText,
CATALOG1,
SCHEMA1,
CATALOG1,
SCHEMA1,
name
);
}
private static void test(
String name,
Identifier defaultCatalogName,
Identifier defaultSchemaName,
Identifier expectedCatalogName,
Identifier expectedSchemaName,
Identifier expectedName) {
final NameParts parsed = QualifiedNameParser.INSTANCE.parse( name, defaultCatalogName, defaultSchemaName );
assertSame( parsed.getCatalogName(), expectedCatalogName );
assertSame( parsed.getSchemaName(), expectedSchemaName );
assertSame( parsed.getObjectName(), expectedName );
}
private static void assertSame(Identifier one, Identifier another) {
if ( one == null ) {
assertThat( another ).isNull();
}
else {
assertThat( one ).isEqualTo( another );
}
}
}