HHH-9768 - Maintain explicit list of ANSI SQL keywords
This commit is contained in:
parent
490fb1cf7b
commit
dd314f492d
|
@ -130,10 +130,20 @@ class HibernateBuildPlugin implements Plugin<Project> {
|
|||
SourceSet mainSourceSet = project.getConvention().findPlugin( JavaPluginConvention.class ).sourceSets.findByName( "main" )
|
||||
JavaCompile compileTask = project.tasks.findByName( mainSourceSet.compileJavaTaskName ) as JavaCompile
|
||||
|
||||
// NOTE : this aptDir stuff is needed until we can have IntelliJ run annotation processors for us
|
||||
// which cannot happen until we can fold hibernate-testing back into hibernate-core/src/test
|
||||
// which cannot happen until... ugh
|
||||
File aptDir = project.file( "${project.buildDir}/generated-src/apt/main" )
|
||||
mainSourceSet.allJava.srcDir( aptDir )
|
||||
|
||||
compileTask.options.compilerArgs += [
|
||||
"-nowarn",
|
||||
"-encoding", "UTF-8"
|
||||
"-encoding", "UTF-8",
|
||||
"-s", "${aptDir.absolutePath}"
|
||||
]
|
||||
compileTask.doFirst {
|
||||
aptDir.mkdirs()
|
||||
}
|
||||
|
||||
if ( javaTargetExtension.version.java8Compatible ) {
|
||||
compileTask.options.compilerArgs += [
|
||||
|
@ -161,6 +171,25 @@ class HibernateBuildPlugin implements Plugin<Project> {
|
|||
}
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Apply to test compile task
|
||||
|
||||
SourceSet testSourceSet = project.getConvention().findPlugin( JavaPluginConvention.class ).sourceSets.findByName( "test" )
|
||||
JavaCompile compileTestTask = project.tasks.findByName( testSourceSet.compileJavaTaskName ) as JavaCompile
|
||||
|
||||
// NOTE : see the note abovewrt aptDir
|
||||
File testAptDir = project.file( "${project.buildDir}/generated-src/apt/test" )
|
||||
testSourceSet.allJava.srcDir( testAptDir )
|
||||
|
||||
compileTestTask.options.compilerArgs += [
|
||||
"-nowarn",
|
||||
"-encoding", "UTF-8",
|
||||
"-s", "${testAptDir.absolutePath}"
|
||||
]
|
||||
compileTestTask.doFirst {
|
||||
testAptDir.mkdirs()
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Apply to test tasks
|
||||
|
||||
|
|
|
@ -110,6 +110,12 @@ public abstract class ObjectNameNormalizer {
|
|||
return logicalName;
|
||||
}
|
||||
|
||||
public String applyGlobalQuoting(String text) {
|
||||
return database().getJdbcEnvironment().getIdentifierHelper().applyGlobalQuoting( text )
|
||||
.render( database().getDialect() );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Access the contextual information related to the current process of building metadata. Here,
|
||||
* that typically might be needed for accessing:<ul>
|
||||
|
|
|
@ -555,7 +555,7 @@ public class Ejb3Column {
|
|||
sqlType = null;
|
||||
}
|
||||
else {
|
||||
sqlType = normalizer.toDatabaseIdentifierText( col.columnDefinition() );
|
||||
sqlType = normalizer.applyGlobalQuoting( col.columnDefinition() );
|
||||
}
|
||||
|
||||
final String tableName;
|
||||
|
|
|
@ -69,6 +69,7 @@ import org.hibernate.dialect.unique.DefaultUniqueDelegate;
|
|||
import org.hibernate.dialect.unique.UniqueDelegate;
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
import org.hibernate.engine.jdbc.env.internal.DefaultSchemaNameResolver;
|
||||
import org.hibernate.engine.jdbc.env.spi.AnsiSqlKeywords;
|
||||
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
|
||||
import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
|
@ -713,7 +714,7 @@ public abstract class Dialect implements ConversionContext {
|
|||
protected void registerFunction(String name, SQLFunction function) {
|
||||
// HHH-7721: SQLFunctionRegistry expects all lowercase. Enforce,
|
||||
// just in case a user's customer dialect uses mixed cases.
|
||||
sqlFunctions.put( name.toLowerCase(Locale.ROOT), function );
|
||||
sqlFunctions.put( name.toLowerCase( Locale.ROOT ), function );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -727,17 +728,6 @@ public abstract class Dialect implements ConversionContext {
|
|||
}
|
||||
|
||||
|
||||
// keyword support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
protected void registerKeyword(String word) {
|
||||
sqlKeywords.add( word );
|
||||
}
|
||||
|
||||
public Set<String> getKeywords() {
|
||||
return sqlKeywords;
|
||||
}
|
||||
|
||||
|
||||
// native identifier generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
|
@ -1863,6 +1853,43 @@ public abstract class Dialect implements ConversionContext {
|
|||
}
|
||||
|
||||
|
||||
// keyword support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
protected void registerKeyword(String word) {
|
||||
sqlKeywords.add( word );
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated See {@link #determineKeywordsForAutoQuoting} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public Set<String> getKeywords() {
|
||||
return sqlKeywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook into auto-quoting of identifiers that are deemed to be keywords. By default we
|
||||
* return all of the following here:<ul>
|
||||
* <li>all keywords as defined by ANSI SQL:2003 specification</li>
|
||||
* <li>all "extra" keywords reported by the JDBC driver </li>
|
||||
* <li>all Dialect-registered "extra" keywords</li>
|
||||
* </ul>
|
||||
* NOTE: The code that ultimately consumes these and uses them stores them in a case-insensitive
|
||||
* Set, so case here does not matter.
|
||||
*
|
||||
* @see org.hibernate.engine.jdbc.env.spi.AnsiSqlKeywords#sql2003()
|
||||
* @see java.sql.DatabaseMetaData#getSQLKeywords()
|
||||
* @see #registerKeyword
|
||||
*/
|
||||
public Set<String> determineKeywordsForAutoQuoting(Set<String> databaseMetadataReportedKeywords) {
|
||||
final Set<String> keywords = new HashSet<String>();
|
||||
keywords.addAll( AnsiSqlKeywords.INSTANCE.sql2003() );
|
||||
keywords.addAll( databaseMetadataReportedKeywords );
|
||||
keywords.addAll( sqlKeywords );
|
||||
return keywords;
|
||||
}
|
||||
|
||||
|
||||
// identifier quoting support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,9 +26,9 @@ package org.hibernate.engine.jdbc.env.internal;
|
|||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
|
@ -38,7 +38,6 @@ import org.hibernate.cfg.AvailableSettings;
|
|||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.config.spi.StandardConverters;
|
||||
import org.hibernate.engine.jdbc.env.spi.AnsiSqlKeywords;
|
||||
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
|
@ -89,8 +88,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
|||
this.sqlExceptionHelper = buildSqlExceptionHelper( dialect );
|
||||
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this ).build();
|
||||
|
||||
reservedWords.addAll( AnsiSqlKeywords.INSTANCE.sql2003() );
|
||||
reservedWords.addAll( dialect.getKeywords() );
|
||||
reservedWords.addAll( dialect.determineKeywordsForAutoQuoting( Collections.<String>emptySet() ) );
|
||||
|
||||
final boolean globallyQuoteIdentifiers = serviceRegistry.getService( ConfigurationService.class )
|
||||
.getSetting( AvailableSettings.GLOBALLY_QUOTED_IDENTIFIERS, StandardConverters.BOOLEAN, false );
|
||||
|
@ -142,9 +140,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
|||
nameQualifierSupport = determineNameQualifierSupport( databaseMetaData );
|
||||
}
|
||||
|
||||
reservedWords.addAll( AnsiSqlKeywords.INSTANCE.sql2003() );
|
||||
reservedWords.addAll( dialect.getKeywords() );
|
||||
reservedWords.addAll( extractedMetaDataSupport.getExtraKeywords() );
|
||||
reservedWords.addAll( dialect.determineKeywordsForAutoQuoting( extractedMetaDataSupport.getExtraKeywords() ) );
|
||||
|
||||
final boolean globallyQuoteIdentifiers = false;
|
||||
|
||||
|
@ -217,9 +213,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
|||
nameQualifierSupport = determineNameQualifierSupport( databaseMetaData );
|
||||
}
|
||||
|
||||
reservedWords.addAll( AnsiSqlKeywords.INSTANCE.sql2003() );
|
||||
reservedWords.addAll( dialect.getKeywords() );
|
||||
reservedWords.addAll( extractedMetaDataSupport.getExtraKeywords() );
|
||||
reservedWords.addAll( dialect.determineKeywordsForAutoQuoting( extractedMetaDataSupport.getExtraKeywords() ) );
|
||||
|
||||
final boolean globallyQuoteIdentifiers = serviceRegistry.getService( ConfigurationService.class )
|
||||
.getSetting( AvailableSettings.GLOBALLY_QUOTED_IDENTIFIERS, StandardConverters.BOOLEAN, false );
|
||||
|
|
|
@ -124,6 +124,11 @@ public class NormalizingIdentifierHelperImpl implements IdentifierHelper {
|
|||
return normalizeQuoting( Identifier.toIdentifier( text, quoted ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier applyGlobalQuoting(String text) {
|
||||
return Identifier.toIdentifier( text, globallyQuoteIdentifiers );
|
||||
}
|
||||
|
||||
// In the DatabaseMetaData method params for catalog and schema name have the following meaning:
|
||||
// 1) <""> means to match things "without a catalog/schema"
|
||||
// 2) <null> means to not limit results based on this field
|
||||
|
|
|
@ -69,6 +69,17 @@ public interface IdentifierHelper {
|
|||
*/
|
||||
public Identifier toIdentifier(String text, boolean quoted);
|
||||
|
||||
/**
|
||||
* Needed to account for certain fields ({@link javax.persistence.Column#columnDefinition()} comes to mind)
|
||||
* that need to be quoted id global identifier quoting is requested, but only for spec compliance. TBH, I can
|
||||
* not think of a argument why column-definitions should ever be *globally* quoted, but the spec is the spec.
|
||||
*
|
||||
* @param text The text to be (possibly) quoted
|
||||
*
|
||||
* @return The identifier form
|
||||
*/
|
||||
public Identifier applyGlobalQuoting(String text);
|
||||
|
||||
/**
|
||||
* Render the Identifier representation of a catalog name into the String form needed
|
||||
* in {@link java.sql.DatabaseMetaData} calls.
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.resource.transaction.backend.jta.internal;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.logging.annotations.MessageLogger;
|
||||
import org.jboss.logging.annotations.ValidIdRange;
|
||||
|
||||
/**
|
||||
* Acts as the {@link org.jboss.logging.annotations.MessageLogger} related to
|
||||
* JTA transaction processing
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@MessageLogger( projectCode = "HHH" )
|
||||
@ValidIdRange( min = 10001001, max = 10002000 )
|
||||
public interface JtaMessageLogger {
|
||||
public static final JtaMessageLogger INSTANCE = Logger.getMessageLogger(
|
||||
JtaMessageLogger.class,
|
||||
"org.hibernate.orm.txn.backend.jta"
|
||||
);
|
||||
|
||||
|
||||
}
|
74
hibernate-core/src/test/java/org/hibernate/test/jdbc/env/TestKeywordRecognition.java
vendored
Normal file
74
hibernate-core/src/test/java/org/hibernate/test/jdbc/env/TestKeywordRecognition.java
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2015, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.jdbc.env;
|
||||
|
||||
import org.hibernate.boot.model.naming.Identifier;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.engine.jdbc.env.spi.AnsiSqlKeywords;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class TestKeywordRecognition extends BaseUnitTestCase {
|
||||
private StandardServiceRegistry serviceRegistry;
|
||||
|
||||
@Before
|
||||
public void prepareServiveRegistry() {
|
||||
serviceRegistry = new StandardServiceRegistryBuilder().build();
|
||||
}
|
||||
|
||||
@After
|
||||
public void releaseServiveRegistry() {
|
||||
if ( serviceRegistry != null ) {
|
||||
StandardServiceRegistryBuilder.destroy( serviceRegistry );
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH_9768" )
|
||||
public void testAnsiSqlKeyword() {
|
||||
// END is ANSI SQL keyword
|
||||
|
||||
// keywords are kept defined in upper case in here...
|
||||
assertTrue( AnsiSqlKeywords.INSTANCE.sql2003().contains( "END" ) );
|
||||
|
||||
// But JdbcEnvironment uses a case-insensitive Set to store them...
|
||||
JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||
assertTrue( jdbcEnvironment.isReservedWord( "end" ) );
|
||||
assertTrue( jdbcEnvironment.isReservedWord( "END" ) );
|
||||
|
||||
Identifier identifier = jdbcEnvironment.getIdentifierHelper().toIdentifier( "end" );
|
||||
assertTrue( identifier.isQuoted() );
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
<sql-query name="loadC">
|
||||
<return alias="c" class="CompositeIdId"/>
|
||||
select system as {c.system}, id as {c.id}, name as {c.name}, foo as {c.composite.foo}, bar as {c.composite.bar} from CompositeIdId where system=? and id=?
|
||||
select "system" as {c.system}, id as {c.id}, name as {c.name}, foo as {c.composite.foo}, bar as {c.composite.bar} from CompositeIdId where "system"=? and id=?
|
||||
</sql-query>
|
||||
|
||||
</hibernate-mapping>
|
|
@ -6,21 +6,24 @@ import java.util.ArrayList;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.SQLQuery;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.HSQLDialect;
|
||||
import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.dialect.PostgreSQL81Dialect;
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
import org.hibernate.dialect.TimesTenDialect;
|
||||
|
||||
import org.hibernate.testing.DialectCheck;
|
||||
import org.hibernate.testing.FailureExpected;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
@ -695,8 +698,17 @@ public class SQLLoaderTest extends LegacyTestCase {
|
|||
session.close();
|
||||
}
|
||||
|
||||
public static class DoubleQuoteDialect implements DialectCheck {
|
||||
@Override
|
||||
public boolean isMatch(Dialect dialect) {
|
||||
return '"' == dialect.openQuote() && '"' == dialect.closeQuote();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-21" )
|
||||
// because the XML mapping defines the loader for CompositeIdId using a column name that needs to be quoted
|
||||
@RequiresDialectFeature( DoubleQuoteDialect.class )
|
||||
public void testCompositeIdId() throws HibernateException, SQLException {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
|
@ -711,7 +723,17 @@ public class SQLLoaderTest extends LegacyTestCase {
|
|||
s = openSession();
|
||||
s.beginTransaction();
|
||||
// having a composite id with one property named id works since the map used by sqlloader to map names to properties handles it.
|
||||
String sql = "select system as {c.system}, id as {c.id}, name as {c.name}, foo as {c.composite.foo}, bar as {c.composite.bar} from CompositeIdId where system=? and id=?";
|
||||
// NOTE : SYSTEM is an ANSI SQL defined keyword, so it gets quoted; so it needs to get quoted here too
|
||||
String sql = String.format(
|
||||
"select %1$s as {c.system}, " +
|
||||
" id as {c.id}, name as {c.name}, " +
|
||||
" foo as {c.composite.foo}, " +
|
||||
" bar as {c.composite.bar} " +
|
||||
"from CompositeIdId " +
|
||||
"where %1$s=? and id=?",
|
||||
getDialect().openQuote() + "system" + getDialect().closeQuote()
|
||||
);
|
||||
|
||||
SQLQuery query = s.createSQLQuery( sql ).addEntity( "c", CompositeIdId.class );
|
||||
query.setString(0, "c64");
|
||||
query.setString(1, "games");
|
||||
|
|
|
@ -85,7 +85,7 @@ public class LegacyJpaNamingWithAnnotationBindingTests extends BaseAnnotationBin
|
|||
|
||||
@Override
|
||||
protected void validateOrderPrimaryTableName(String name) {
|
||||
assertEquals( "Order", name );
|
||||
assertEquals( "`Order`", name );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -189,7 +189,7 @@ public class LegacyJpaNamingWithAnnotationBindingTests extends BaseAnnotationBin
|
|||
|
||||
@Override
|
||||
protected void validateCustomerOrdersTableName(String name) {
|
||||
assertEquals( "Order", name );
|
||||
assertEquals( "`Order`", name );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -91,7 +91,8 @@ public class LegacyJpaNamingWithHbmBindingTests extends BaseHbmBindingTests {
|
|||
|
||||
@Override
|
||||
protected void validateOrderPrimaryTableName(String name) {
|
||||
assertEquals( "Order", name );
|
||||
// quoted because "order" is an ansi sql keyword
|
||||
assertEquals( "`Order`", name );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -191,7 +192,8 @@ public class LegacyJpaNamingWithHbmBindingTests extends BaseHbmBindingTests {
|
|||
|
||||
@Override
|
||||
protected void validateCustomerOrdersTableName(String name) {
|
||||
assertEquals( "Order", name );
|
||||
// quoted because "order" is an ansi sql keyword
|
||||
assertEquals( "`Order`", name );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue