From 2a5e62752b38f4ed85f7b906f6f354b77e8f71f6 Mon Sep 17 00:00:00 2001 From: Alex Kasko Date: Wed, 10 Apr 2024 07:43:55 +0100 Subject: [PATCH] Support for testing DatabaseMetaData API in JDBC tests (#2433) JDBC specification includes introspection API contained in [DatabaseMetaData](https://docs.oracle.com/en/java/javase/17/docs/api/java.sql/java/sql/DatabaseMetaData.html) class. These methods are widely used by Java applications like DB browser, visualization and BI tools. From the point of view of client apps, correctness of implementation of these methods is guaranteed by JDBC lib vendor (DB vendor in most cases) and it is more reliable to use these methods instead of trying to do introspection with `INFORMATION_SCHEMA` or DB-specific SQL. The implementation of some of these methods is done by calling system stored procedures like `sp_tables` or `sp_columns`. While these procedures in Babelfish are already covered with direct SQL tests, it is suggested to add additional test coverage by running these Java methods as part of JDBC test suite. These methods call system procedures with a particular set of arguments (partially hardcoded in implementation lib). And, in theory, these calls and arguments can be different in newer versions of implementation lib. Currently test harness uses [very old version of mssql-jdbc lib](https://github.com/babelfish-for-postgresql/babelfish_extensions/blob/b38e6e2c0261725627d9ac751721e50501af6eef/test/JDBC/pom.xml#L51). Its update is not trivial, because error output differs in different versions (thus a large number of output files need to be updated as well). But when the time will come to update the version (or to run JDBC tests with multiple versions) it may be beneficial to have `DatabaseMetaData` API coverage in place. Besides that, the alternative JDBC implementation in jTDS lib also implements the subset of `DatabaseMetaData` API, proposed new tests can run on jTDS as well. Signed-off-by: Alex Kasko --- test/JDBC/README.md | 44 +++ test/JDBC/expected/database_metadata.out | 292 ++++++++++++++++ test/JDBC/input/database_metadata.txt | 70 ++++ .../java/com/sqlsamples/HandleException.java | 2 + .../java/com/sqlsamples/JDBCMetadata.java | 327 ++++++++++++++++++ .../main/java/com/sqlsamples/batch_run.java | 11 +- 6 files changed, 743 insertions(+), 3 deletions(-) create mode 100644 test/JDBC/expected/database_metadata.out create mode 100644 test/JDBC/input/database_metadata.txt create mode 100644 test/JDBC/src/main/java/com/sqlsamples/JDBCMetadata.java diff --git a/test/JDBC/README.md b/test/JDBC/README.md index 3ffc9501ce..3e6ff16153 100644 --- a/test/JDBC/README.md +++ b/test/JDBC/README.md @@ -14,6 +14,7 @@ The JDBC test framework for Babelfish uses the JDBC Driver for SQL Server for da - [Using a transaction](#using-a-transaction) - [Using a cursor](#using-a-cursor) - [Verifying SQL Authentication test cases](#verifying-sql-authentication-test-cases) + - [Using DatabaseMetaData API](#using-databasemetadata-api) - [Intermixing queries in T-SQL and PL/pgSQL dialect](#intermixing-queries-in-t-sql-and-plpgsql-dialect-cross-dialect-test-cases) - [IMPORTANT](#important) - [Adding the test cases](#adding-the-test-cases) @@ -246,6 +247,49 @@ Input file type: `.txt` --- +### Using DatabaseMetaData API + +To call methods from [DatabaseMetaData JDBC API](https://docs.oracle.com/en/java/javase/21/docs/api/java.sql/java/sql/DatabaseMetaData.html): + +``` +dbmeta#!##!#||...| +``` + +The supported method names are: + + - `getCatalogs` + - `getColumnPrivileges` + - `getTables` + - `getColumns` + - `getFunctions` + - `getFunctionColumns` + - `getBestRowIdentifier` + - `getCrossReference` + - `getExportedKeys` + - `getImportedKeys` + - `getIndexInfo` + - `getMaxConnections` + - `getPrimaryKeys` + - `getProcedureColumns` + - `getProcedures` + - `getSchemas` + - `getTablePrivileges` + - `getTypeInfo` + - `getUserName` + - `getVersionColumns` + +**Example** + +To perform the `getColumns(String catalog, String schema, String table, String column)` call: + +``` +dbmeta#!#getColumns#!#master|dbo|tab1|col1 +``` + +Input file type: `.txt` + +--- + ### Intermixing queries in T-SQL and PL/pgSQL dialect (cross dialect test cases) A SQL Batch in T-SQL should be added as: ```tsql diff --git a/test/JDBC/expected/database_metadata.out b/test/JDBC/expected/database_metadata.out new file mode 100644 index 0000000000..4da60aaee2 --- /dev/null +++ b/test/JDBC/expected/database_metadata.out @@ -0,0 +1,292 @@ + +create table dbmeta_tab1(col1 int primary key, col2 nvarchar(max) not null) +create table dbmeta_tab2(fcol1 int not null, foreign key (fcol1) references dbmeta_tab1(col1)) +create view dbmeta_view1 as select * from dbmeta_tab1 +create function dbmeta_func1() returns int as begin return 1 end +create function dbmeta_func2(@par1 int) returns table return select cast(@par1 as int) as col1, cast ('foo' as nvarchar(max)) as col2 +create index idx1 on dbmeta_tab1(col2) +create unique index idx2 on dbmeta_tab1(col2) +create procedure dbmeta_proc1 as begin return end +create procedure dbmeta_proc2 @par1 int as select cast(@par1 as int) as col1, cast ('foo' as nvarchar(max)) as col2 + +dbmeta#!#getCatalogs +~~START~~ +varchar +master +msdb +tempdb +~~END~~ + + +dbmeta#!#getColumnPrivileges#!#master|dbo|dbmeta_tab1|col1 +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar +master#!#dbo#!#dbmeta_tab1#!#col1#!#dbo#!#dbo#!#INSERT#!#YES +master#!#dbo#!#dbmeta_tab1#!#col1#!#dbo#!#dbo#!#REFERENCES#!#YES +master#!#dbo#!#dbmeta_tab1#!#col1#!#dbo#!#dbo#!#SELECT#!#YES +master#!#dbo#!#dbmeta_tab1#!#col1#!#dbo#!#dbo#!#UPDATE#!#YES +~~END~~ + + +dbmeta#!#getTables#!#master|dbo|dbmeta_% +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +master#!#dbo#!#dbmeta_tab1#!#TABLE#!# +master#!#dbo#!#dbmeta_tab2#!#TABLE#!# +master#!#dbo#!#dbmeta_view1#!#VIEW#!# +~~END~~ + +dbmeta#!#getTables#!#master|dbo|dbmeta_%|TABLE|VIEW +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar +master#!#dbo#!#dbmeta_tab1#!#TABLE#!# +master#!#dbo#!#dbmeta_tab2#!#TABLE#!# +master#!#dbo#!#dbmeta_view1#!#VIEW#!# +~~END~~ + + +dbmeta#!#getColumns#!#master|dbo|dbmeta_tab1 +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#int#!#int#!#int#!#tinyint#!#text#!#text#!#smallint#!#smallint#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +master#!#dbo#!#dbmeta_tab1#!#col1#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#1#!#NO#!##!##!##!#38#!#NO#!#NO#!#0#!#0#!##!##!##!##!##!# +master#!#dbo#!#dbmeta_tab1#!#col2#!#-9#!#nvarchar#!#2147483647#!#2147483647#!##!##!#0#!##!##!#-9#!##!#2147483647#!#2#!#NO#!##!##!##!#39#!#NO#!#NO#!#0#!#0#!##!##!##!##!##!# +~~END~~ + +dbmeta#!#getColumns#!#master|dbo|dbmeta_tab1|col1 +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#int#!#int#!#int#!#tinyint#!#text#!#text#!#smallint#!#smallint#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +master#!#dbo#!#dbmeta_tab1#!#col1#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#1#!#NO#!##!##!##!#38#!#NO#!#NO#!#0#!#0#!##!##!##!##!##!# +~~END~~ + + +dbmeta#!#getFunctions#!#master|dbo|dbmeta_% +~~START~~ +varchar#!#varchar#!#nvarchar#!#int#!#int#!#int#!#varchar#!#smallint +master#!#dbo#!#dbmeta_func1;0#!#-1#!#-1#!#-1#!##!#2 +master#!#dbo#!#dbmeta_func2;0#!#-1#!#-1#!#-1#!##!#2 +master#!#dbo#!#dbmeta_proc1;1#!#-1#!#-1#!#-1#!##!#2 +master#!#dbo#!#dbmeta_proc2;1#!#-1#!#-1#!#-1#!##!#2 +~~END~~ + +dbmeta#!#getFunctions#!#master|dbo|dbmeta_func1 +~~START~~ +varchar#!#varchar#!#nvarchar#!#int#!#int#!#int#!#varchar#!#smallint +master#!#dbo#!#dbmeta_func1;0#!#-1#!#-1#!#-1#!##!#2 +~~END~~ + + +dbmeta#!#getFunctionColumns#!#master|dbo|dbmeta_% +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +master#!#dbo#!#dbmeta_func1;0#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#1#!##!##!#4#!##!##!#0#!#YES#!#38 +master#!#dbo#!#dbmeta_func2;0#!#@TABLE_RETURN_VALUE#!#3#!##!#table#!#2147483647#!#2147483647#!#0#!#0#!#0#!#Result table returned by table valued function#!##!##!#0#!##!#0#!#NO#!#0 +master#!#dbo#!#dbmeta_func2;0#!#@par1#!#1#!#4#!#int#!#10#!#4#!#0#!#10#!#1#!##!##!#4#!##!##!#1#!#YES#!#38 +master#!#dbo#!#dbmeta_proc1;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +master#!#dbo#!#dbmeta_proc2;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +master#!#dbo#!#dbmeta_proc2;1#!#@par1#!#1#!#4#!#int#!#10#!#4#!#0#!#10#!#1#!##!##!#4#!##!##!#1#!#YES#!#38 +~~END~~ + +dbmeta#!#getFunctionColumns#!#master|dbo|dbmeta_func2|@par1 +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +master#!#dbo#!#dbmeta_func2;0#!#@par1#!#1#!#4#!#int#!#10#!#4#!#0#!#10#!#1#!##!##!#4#!##!##!#1#!#YES#!#38 +~~END~~ + + +dbmeta#!#getBestRowIdentifier#!#master|dbo|dbmeta_tab1|1|true +~~START~~ +smallint#!#varchar#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint +1#!#col1#!#4#!#int#!#10#!#4#!#0#!#1 +~~END~~ + + +dbmeta#!#getCrossReference#!#master|dbo|dbmeta_tab1|master|dbo|dbmeta_tab2 +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#smallint#!#int#!#int#!#varchar#!#varchar#!#smallint +master#!#dbo#!#dbmeta_tab1#!#col1#!#master#!#dbo#!#dbmeta_tab2#!#fcol1#!#1#!#3#!#3#!#dbmeta_tab2_fcol1_fkey#!#dbmeta_tab1_pkey#!#7 +~~END~~ + + +dbmeta#!#getExportedKeys#!#master|dbo|dbmeta_tab1 +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#smallint#!#int#!#int#!#varchar#!#varchar#!#smallint +master#!#dbo#!#dbmeta_tab1#!#col1#!#master#!#dbo#!#dbmeta_tab2#!#fcol1#!#1#!#3#!#3#!#dbmeta_tab2_fcol1_fkey#!#dbmeta_tab1_pkey#!#7 +~~END~~ + +dbmeta#!#getExportedKeys#!#master|dbo|dbmeta_tab2 +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#smallint#!#int#!#int#!#varchar#!#varchar#!#smallint +~~END~~ + + +dbmeta#!#getImportedKeys#!#master|dbo|dbmeta_tab1 +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#smallint#!#int#!#int#!#varchar#!#varchar#!#smallint +~~END~~ + +dbmeta#!#getImportedKeys#!#master|dbo|dbmeta_tab2 +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#smallint#!#int#!#int#!#varchar#!#varchar#!#smallint +master#!#dbo#!#dbmeta_tab1#!#col1#!#master#!#dbo#!#dbmeta_tab2#!#fcol1#!#1#!#3#!#3#!#dbmeta_tab2_fcol1_fkey#!#dbmeta_tab1_pkey#!#7 +~~END~~ + + +dbmeta#!#getIndexInfo#!#master|dbo|dbmeta_tab1|false|true +~~START~~ +varchar#!#varchar#!#varchar#!#smallint#!#varchar#!#varchar#!#smallint#!#smallint#!#varchar#!#varchar#!#int#!#int#!#varchar +master#!#dbo#!#dbmeta_tab1#!#0#!#dbmeta_tab1#!#dbmeta_tab1_pkey#!#3#!#1#!#col1#!#A#!##!#0#!# +master#!#dbo#!#dbmeta_tab1#!#0#!#dbmeta_tab1#!#idx2#!#3#!#1#!#col2#!#A#!##!#0#!# +master#!#dbo#!#dbmeta_tab1#!#1#!#dbmeta_tab1#!#idx1#!#3#!#1#!#col2#!#A#!##!#0#!# +master#!#dbo#!#dbmeta_tab1#!##!##!##!#0#!##!##!##!#-1#!#0#!# +~~END~~ + +dbmeta#!#getIndexInfo#!#master|dbo|dbmeta_tab2|true|true +~~START~~ +varchar#!#varchar#!#varchar#!#smallint#!#varchar#!#varchar#!#smallint#!#smallint#!#varchar#!#varchar#!#int#!#int#!#varchar +master#!#dbo#!#dbmeta_tab2#!##!##!##!#0#!##!##!##!#-1#!#0#!# +~~END~~ + + +dbmeta#!#getMaxConnections +~~START~~ +0 +~~END~~ + + +dbmeta#!#getPrimaryKeys#!#master|dbo|dbmeta_tab1 +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#smallint#!#varchar +master#!#dbo#!#dbmeta_tab1#!#col1#!#1#!#dbmeta_tab1_pkey +~~END~~ + +dbmeta#!#getPrimaryKeys#!#master|dbo|dbmeta_tab2 +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#smallint#!#varchar +~~END~~ + + +dbmeta#!#getProcedureColumns#!#master|dbo|dbmeta_% +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +master#!#dbo#!#dbmeta_func1;0#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#1#!##!##!#4#!##!##!#0#!#YES#!#38 +master#!#dbo#!#dbmeta_func2;0#!#@TABLE_RETURN_VALUE#!#3#!##!#table#!#2147483647#!#2147483647#!#0#!#0#!#0#!#Result table returned by table valued function#!##!##!#0#!##!#0#!#NO#!#0 +master#!#dbo#!#dbmeta_func2;0#!#@par1#!#1#!#4#!#int#!#10#!#4#!#0#!#10#!#1#!##!##!#4#!##!##!#1#!#YES#!#38 +master#!#dbo#!#dbmeta_proc1;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +master#!#dbo#!#dbmeta_proc2;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +master#!#dbo#!#dbmeta_proc2;1#!#@par1#!#1#!#4#!#int#!#10#!#4#!#0#!#10#!#1#!##!##!#4#!##!##!#1#!#YES#!#38 +~~END~~ + +dbmeta#!#getProcedureColumns#!#master|dbo|dbmeta_proc2|@par1 +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +master#!#dbo#!#dbmeta_proc2;1#!#@par1#!#1#!#4#!#int#!#10#!#4#!#0#!#10#!#1#!##!##!#4#!##!##!#1#!#YES#!#38 +~~END~~ + + +dbmeta#!#getProcedures#!#master|dbo|dbmeta_% +~~START~~ +varchar#!#varchar#!#nvarchar#!#int#!#int#!#int#!#varchar#!#smallint +master#!#dbo#!#dbmeta_func1;0#!#-1#!#-1#!#-1#!##!#2 +master#!#dbo#!#dbmeta_func2;0#!#-1#!#-1#!#-1#!##!#2 +master#!#dbo#!#dbmeta_proc1;1#!#-1#!#-1#!#-1#!##!#2 +master#!#dbo#!#dbmeta_proc2;1#!#-1#!#-1#!#-1#!##!#2 +~~END~~ + +dbmeta#!#getProcedures#!#master|dbo|dbmeta_proc1 +~~START~~ +varchar#!#varchar#!#nvarchar#!#int#!#int#!#int#!#varchar#!#smallint +master#!#dbo#!#dbmeta_proc1;1#!#-1#!#-1#!#-1#!##!#2 +~~END~~ + + +dbmeta#!#getSchemas#!#master +~~START~~ +varchar#!#text +dbo#!# +guest#!# +~~END~~ + +dbmeta#!#getSchemas#!#master|dbo +~~START~~ +varchar#!#text +dbo#!# +~~END~~ + + +dbmeta#!#getTablePrivileges#!#master|dbo|dbmeta_tab1 +~~START~~ +varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar#!#varchar +master#!#dbo#!#dbmeta_tab1#!#dbo#!#dbo#!#DELETE#!#YES +master#!#dbo#!#dbmeta_tab1#!#dbo#!#dbo#!#INSERT#!#YES +master#!#dbo#!#dbmeta_tab1#!#dbo#!#dbo#!#REFERENCES#!#YES +master#!#dbo#!#dbmeta_tab1#!#dbo#!#dbo#!#SELECT#!#YES +master#!#dbo#!#dbmeta_tab1#!#dbo#!#dbo#!#UPDATE#!#YES +~~END~~ + + +dbmeta#!#getTypeInfo +~~START~~ +varchar#!#int#!#bigint#!#varchar#!#varchar#!#char#!#int#!#int#!#int#!#int#!#int#!#int#!#varchar#!#int#!#int#!#int#!#int#!#int#!#int#!#int +vector#!#-2147483648#!#0#!#'#!#'#!##!#1#!#0#!#0#!##!#0#!##!#vector#!##!##!#-2147483648#!##!##!##!#-2147483648 +datetimeoffset#!#-155#!#34#!#'#!#'#!#scale #!#1#!#0#!#3#!##!#0#!##!#datetimeoffset#!#0#!#7#!#-155#!#0#!##!##!#0 +time#!#92#!#16#!#'#!#'#!#scale #!#1#!#0#!#3#!##!#0#!##!#time#!#0#!#7#!#-154#!#0#!##!##!#0 +xml#!#-16#!#0#!#N'#!#'#!##!#1#!#1#!#0#!##!#0#!##!#xml#!##!##!#-152#!##!##!##!#0 +geography#!#-3#!#0#!##!##!##!#1#!#1#!#0#!##!#0#!##!#geography#!##!##!#-151#!##!##!##!#0 +geometry#!#-3#!#0#!##!##!##!#1#!#1#!#0#!##!#0#!##!#geometry#!##!##!#-151#!##!##!##!#0 +sql_variant#!#-150#!#8000#!##!##!##!#1#!#0#!#2#!##!#0#!##!#sql_variant#!#0#!#0#!#-150#!##!#10#!##!#0 +uniqueidentifier#!#1#!#36#!#'#!#'#!##!#1#!#0#!#2#!##!#0#!##!#uniqueidentifier#!##!##!#-11#!##!##!##!#0 +ntext#!#-16#!#1073741823#!#N'#!#'#!##!#1#!#1#!#1#!##!#0#!##!#ntext#!##!##!#-10#!##!##!##!#0 +nvarchar#!#-9#!#4000#!#N'#!#'#!#max length #!#1#!#1#!#3#!##!#0#!##!#nvarchar#!##!##!#-9#!##!##!##!#0 +sysname#!#-9#!#128#!#N'#!#'#!##!#0#!#1#!#3#!##!#0#!##!#sysname#!##!##!#-9#!##!##!##!#18 +nchar#!#-15#!#4000#!#N'#!#'#!#length #!#1#!#1#!#3#!##!#0#!##!#nchar#!##!##!#-8#!##!##!##!#0 +bit#!#-7#!#1#!##!##!##!#1#!#0#!#2#!##!#0#!##!#bit#!#0#!#0#!#-7#!##!##!##!#16 +tinyint#!#-6#!#3#!##!##!##!#1#!#0#!#2#!#1#!#0#!#0#!#tinyint#!#0#!#0#!#-6#!##!#10#!##!#5 +tinyint identity#!#-6#!#3#!##!##!##!#0#!#0#!#2#!#1#!#0#!#1#!#tinyint identity#!#0#!#0#!#-6#!##!#10#!##!#5 +bigint#!#-5#!#19#!##!##!##!#1#!#0#!#2#!#0#!#0#!#0#!#bigint#!#0#!#0#!#-5#!##!#10#!##!#0 +bigint identity#!#-5#!#19#!##!##!##!#0#!#0#!#2#!#0#!#0#!#1#!#bigint identity#!#0#!#0#!#-5#!##!#10#!##!#0 +image#!#-4#!#2147483647#!#0x#!##!##!#1#!#0#!#0#!##!#0#!##!#image#!##!##!#-4#!##!##!##!#20 +varbinary#!#-3#!#8000#!#0x#!##!#max length #!#1#!#0#!#2#!##!#0#!##!#varbinary#!##!##!#-3#!##!##!##!#4 +binary#!#-2#!#8000#!#0x#!##!#length #!#1#!#0#!#2#!##!#0#!##!#binary#!##!##!#-2#!##!##!##!#3 +timestamp#!#-2#!#8#!#0x#!##!##!#0#!#0#!#2#!##!#0#!##!#timestamp#!##!##!#-2#!##!##!##!#80 +text#!#-1#!#2147483647#!#'#!#'#!##!#1#!#1#!#1#!##!#0#!##!#text#!##!##!#-1#!##!##!##!#19 +char#!#1#!#8000#!#'#!#'#!#length #!#1#!#1#!#3#!##!#0#!##!#char#!##!##!#1#!##!##!##!#1 +numeric#!#2#!#38#!##!##!#precision,scale #!#1#!#0#!#2#!#0#!#0#!#0#!#numeric#!#0#!#38#!#2#!##!#10#!##!#10 +numeric() identity#!#2#!#38#!##!##!#precision #!#0#!#0#!#2#!#0#!#0#!#1#!#numeric() identity#!#0#!#0#!#2#!##!#10#!##!#10 +decimal#!#3#!#38#!##!##!#precision,scale #!#1#!#0#!#2#!#0#!#0#!#0#!#decimal#!#0#!#38#!#3#!##!#10#!##!#24 +money#!#3#!#19#!#$#!##!##!#1#!#0#!#2#!#0#!#1#!#0#!#money#!#4#!#4#!#3#!##!#10#!##!#11 +smallmoney#!#3#!#10#!#$#!##!##!#1#!#0#!#2#!#0#!#1#!#0#!#smallmoney#!#4#!#4#!#3#!##!#10#!##!#21 +decimal() identity#!#3#!#38#!##!##!#precision #!#0#!#0#!#2#!#0#!#0#!#1#!#decimal() identity#!#0#!#0#!#3#!##!#10#!##!#24 +int#!#4#!#10#!##!##!##!#1#!#0#!#2#!#0#!#0#!#0#!#int#!#0#!#0#!#4#!##!#10#!##!#7 +int identity#!#4#!#10#!##!##!##!#0#!#0#!#2#!#0#!#0#!#1#!#int identity#!#0#!#0#!#4#!##!#10#!##!#7 +smallint#!#5#!#5#!##!##!##!#1#!#0#!#2#!#0#!#0#!#0#!#smallint#!#0#!#0#!#5#!##!#10#!##!#6 +smallint identity#!#5#!#5#!##!##!##!#0#!#0#!#2#!#0#!#0#!#1#!#smallint identity#!#0#!#0#!#5#!##!#10#!##!#6 +float#!#8#!#53#!##!##!##!#1#!#0#!#2#!#0#!#0#!#0#!#float#!##!##!#6#!##!#2#!##!#8 +real#!#7#!#24#!##!##!##!#1#!#0#!#2#!#0#!#0#!#0#!#real#!##!##!#7#!##!#2#!##!#23 +varchar#!#12#!#8000#!#'#!#'#!#max length #!#1#!#1#!#3#!##!#0#!##!#varchar#!##!##!#12#!##!##!##!#2 +date#!#91#!#10#!#'#!#'#!##!#1#!#0#!#3#!##!#0#!##!#date#!##!#0#!#9#!#1#!##!##!#0 +datetime2#!#93#!#27#!#'#!#'#!#scale #!#1#!#0#!#3#!##!#0#!##!#datetime2#!#0#!#7#!#9#!#3#!##!##!#0 +datetime#!#93#!#23#!#'#!#'#!##!#1#!#0#!#3#!##!#0#!##!#datetime#!#3#!#3#!#9#!#3#!##!##!#12 +smalldatetime#!#93#!#16#!#'#!#'#!##!#1#!#0#!#3#!##!#0#!##!#smalldatetime#!#0#!#0#!#9#!#3#!##!##!#22 +~~END~~ + + +dbmeta#!#getUserName +~~START~~ +jdbc_user +~~END~~ + + +# sp_special_columns called with @col_type = 'V' +dbmeta#!#getVersionColumns#!#master|dbo|dbmeta_tab1 +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: TIMESTAMP datatype is not currently supported in Babelfish)~~ + + +drop view dbmeta_view1 +drop table dbmeta_tab2 +drop table dbmeta_tab1 +drop function dbmeta_func1 +drop function dbmeta_func2 +drop procedure dbmeta_proc1 +drop procedure dbmeta_proc2 diff --git a/test/JDBC/input/database_metadata.txt b/test/JDBC/input/database_metadata.txt new file mode 100644 index 0000000000..de04086711 --- /dev/null +++ b/test/JDBC/input/database_metadata.txt @@ -0,0 +1,70 @@ + +create table dbmeta_tab1(col1 int primary key, col2 nvarchar(max) not null) +create table dbmeta_tab2(fcol1 int not null, foreign key (fcol1) references dbmeta_tab1(col1)) +create view dbmeta_view1 as select * from dbmeta_tab1 +create function dbmeta_func1() returns int as begin return 1 end +create function dbmeta_func2(@par1 int) returns table return select cast(@par1 as int) as col1, cast ('foo' as nvarchar(max)) as col2 +create index idx1 on dbmeta_tab1(col2) +create unique index idx2 on dbmeta_tab1(col2) +create procedure dbmeta_proc1 as begin return end +create procedure dbmeta_proc2 @par1 int as select cast(@par1 as int) as col1, cast ('foo' as nvarchar(max)) as col2 + +dbmeta#!#getCatalogs + +dbmeta#!#getColumnPrivileges#!#master|dbo|dbmeta_tab1|col1 + +dbmeta#!#getTables#!#master|dbo|dbmeta_% +dbmeta#!#getTables#!#master|dbo|dbmeta_%|TABLE|VIEW + +dbmeta#!#getColumns#!#master|dbo|dbmeta_tab1 +dbmeta#!#getColumns#!#master|dbo|dbmeta_tab1|col1 + +dbmeta#!#getFunctions#!#master|dbo|dbmeta_% +dbmeta#!#getFunctions#!#master|dbo|dbmeta_func1 + +dbmeta#!#getFunctionColumns#!#master|dbo|dbmeta_% +dbmeta#!#getFunctionColumns#!#master|dbo|dbmeta_func2|@par1 + +dbmeta#!#getBestRowIdentifier#!#master|dbo|dbmeta_tab1|1|true + +dbmeta#!#getCrossReference#!#master|dbo|dbmeta_tab1|master|dbo|dbmeta_tab2 + +dbmeta#!#getExportedKeys#!#master|dbo|dbmeta_tab1 +dbmeta#!#getExportedKeys#!#master|dbo|dbmeta_tab2 + +dbmeta#!#getImportedKeys#!#master|dbo|dbmeta_tab1 +dbmeta#!#getImportedKeys#!#master|dbo|dbmeta_tab2 + +dbmeta#!#getIndexInfo#!#master|dbo|dbmeta_tab1|false|true +dbmeta#!#getIndexInfo#!#master|dbo|dbmeta_tab2|true|true + +dbmeta#!#getMaxConnections + +dbmeta#!#getPrimaryKeys#!#master|dbo|dbmeta_tab1 +dbmeta#!#getPrimaryKeys#!#master|dbo|dbmeta_tab2 + +dbmeta#!#getProcedureColumns#!#master|dbo|dbmeta_% +dbmeta#!#getProcedureColumns#!#master|dbo|dbmeta_proc2|@par1 + +dbmeta#!#getProcedures#!#master|dbo|dbmeta_% +dbmeta#!#getProcedures#!#master|dbo|dbmeta_proc1 + +dbmeta#!#getSchemas#!#master +dbmeta#!#getSchemas#!#master|dbo + +dbmeta#!#getTablePrivileges#!#master|dbo|dbmeta_tab1 + +dbmeta#!#getTypeInfo + +dbmeta#!#getUserName + +# sp_special_columns called with @col_type = 'V' +dbmeta#!#getVersionColumns#!#master|dbo|dbmeta_tab1 + +drop view dbmeta_view1 +drop table dbmeta_tab2 +drop table dbmeta_tab1 +drop function dbmeta_func1 +drop function dbmeta_func2 +drop procedure dbmeta_proc1 +drop procedure dbmeta_proc2 diff --git a/test/JDBC/src/main/java/com/sqlsamples/HandleException.java b/test/JDBC/src/main/java/com/sqlsamples/HandleException.java index ea29ad7e8b..d975c0b267 100644 --- a/test/JDBC/src/main/java/com/sqlsamples/HandleException.java +++ b/test/JDBC/src/main/java/com/sqlsamples/HandleException.java @@ -60,6 +60,8 @@ else if(e instanceof SQLServerException) { errorMsg = errorMsg.substring(0, index); } bw.write("~~ERROR (Message: "+ errorMsg + ")~~"); + } else { + bw.write("~~ERROR (Message: " + e.getMessage() + ")~~"); } } else { bw.write("~~ERROR~~"); diff --git a/test/JDBC/src/main/java/com/sqlsamples/JDBCMetadata.java b/test/JDBC/src/main/java/com/sqlsamples/JDBCMetadata.java new file mode 100644 index 0000000000..746a2df1e7 --- /dev/null +++ b/test/JDBC/src/main/java/com/sqlsamples/JDBCMetadata.java @@ -0,0 +1,327 @@ +package com.sqlsamples; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; + +import org.apache.logging.log4j.Logger; + +import static com.sqlsamples.HandleException.handleSQLExceptionWithFile; + +public class JDBCMetadata { + + static void testDatabaseMetadata(BufferedWriter bw, Logger logger, Connection con_bbl, + String method, String data) throws IOException { + try { + DatabaseMetaData dbmeta = con_bbl.getMetaData(); + switch (method) { + case "getCatalogs": testGetCatalogs(bw, logger, dbmeta); break; + case "getColumnPrivileges": testGetColumnPrivileges(bw, logger, dbmeta, data); break; + case "getTables": testGetTables(bw, logger, dbmeta, data); break; + case "getColumns": testGetColumns(bw, logger, dbmeta, data); break; + case "getFunctions": testGetFunctions(bw, logger, dbmeta, data); break; + case "getFunctionColumns": testGetFunctionColumns(bw, logger, dbmeta, data); break; + case "getBestRowIdentifier": testGetBestRowIdentifier(bw, logger, dbmeta, data); break; + case "getCrossReference": testGetCrossReference(bw, logger, dbmeta, data); break; + case "getExportedKeys": testGetExportedKeys(bw, logger, dbmeta, data); break; + case "getImportedKeys": testGetImportedKeys(bw, logger, dbmeta, data); break; + case "getIndexInfo": testGetIndexInfo(bw, logger, dbmeta, data); break; + case "getMaxConnections": testGetMaxConnections(bw, dbmeta); break; + case "getPrimaryKeys": testGetPrimaryKeys(bw, logger, dbmeta, data); break; + case "getProcedureColumns": testGetProcedureColumns(bw, logger, dbmeta, data); break; + case "getProcedures": testGetProcedures(bw, logger, dbmeta, data); break; + case "getSchemas": testGetSchemas(bw, logger, dbmeta, data); break; + case "getTablePrivileges": testGetTablePrivileges(bw, logger, dbmeta, data); break; + case "getTypeInfo": testGetTypeInfo(bw, logger, dbmeta); break; + case "getUserName": testGetUserName(bw, dbmeta); break; + case "getVersionColumns": testGetVersionColumns(bw, logger, dbmeta, data); break; + default: throw new SQLException("Unexpected Metadata method: " + method); + } + + } catch (SQLException e) { + handleSQLExceptionWithFile(e, bw, logger); + } + } + + private static void testGetCatalogs(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta) throws SQLException { + ResultSet rs = dbmeta.getCatalogs(); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetColumnPrivileges(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 4) { + throw new SQLException("Invalid number of parameters for 'getColumnPrivileges'," + + " expected: '#!#getColumnPrivileges#!#catalog|schema|table|column'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String table = parts[2]; + String column = parts[3]; + ResultSet rs = dbmeta.getColumnPrivileges(catalog, schema, table, column); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetTables(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length < 3) { + throw new SQLException("Invalid number of parameters for 'getTables'," + + " expected: '#!#getTables#!#catalog|schema|table[|type1|...|typeN]'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String table = parts[2]; + String[] types = null; + if (parts.length > 3) { + types = Arrays.copyOfRange(parts, 3, parts.length); + } + ResultSet rs = dbmeta.getTables(catalog, schema, table, types); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetColumns(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 3 && parts.length != 4) { + throw new SQLException("Invalid number of parameters for 'getColumns'," + + " expected: '#!#getColumns#!#catalog|schema|table[|column]'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String table = parts[2]; + String column = null; + if (parts.length == 4) { + column = parts[3]; + } + ResultSet rs = dbmeta.getColumns(catalog, schema, table, column); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetFunctions(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 2 && parts.length != 3) { + throw new SQLException("Invalid number of parameters for 'getFunctions'," + + " expected: '#!#getFunctions#!#catalog|schema[|function]'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String function = null; + if (parts.length == 3) { + function = parts[2]; + } + ResultSet rs = dbmeta.getFunctions(catalog, schema, function); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetFunctionColumns(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 3 && parts.length != 4) { + throw new SQLException("Invalid number of parameters for 'getFunctionColumns'," + + " expected: '#!#getFunctionColumns#!#catalog|schema|function[|column]'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String function = parts[2]; + String column = null; + if (parts.length == 4) { + column = parts[3]; + } + ResultSet rs = dbmeta.getFunctionColumns(catalog, schema, function, column); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetBestRowIdentifier(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 5) { + throw new SQLException("Invalid number of parameters for 'getBestRowIdentifier'," + + " expected: '#!#getBestRowIdentifier#!#catalog|schema|table|scope|nullable'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String table = parts[2]; + int scope = Integer.parseInt(parts[3]); + boolean nullable = Boolean.parseBoolean(parts[4]); + ResultSet rs = dbmeta.getBestRowIdentifier(catalog, schema, table, scope, nullable); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetCrossReference(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 6) { + throw new SQLException("Invalid number of parameters for 'getCrossReference'," + + " expected: '#!#getCrossReference#!#catalog1|schema1|table1|catalog2|schema2|table2'"); + } + String catalog1 = parts[0]; + String schema1 = parts[1]; + String table1 = parts[2]; + String catalog2 = parts[3]; + String schema2 = parts[4]; + String table2 = parts[5]; + ResultSet rs = dbmeta.getCrossReference(catalog1, schema1, table1, catalog2, schema2, table2); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetExportedKeys(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 3) { + throw new SQLException("Invalid number of parameters for 'getExportedKeys'," + + " expected: '#!#getExportedKeys#!#catalog|schema|table'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String table = parts[2]; + ResultSet rs = dbmeta.getExportedKeys(catalog, schema, table); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetImportedKeys(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 3) { + throw new SQLException("Invalid number of parameters for 'getImportedKeys'," + + " expected: '#!#getImportedKeys#!#catalog|schema|table'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String table = parts[2]; + ResultSet rs = dbmeta.getImportedKeys(catalog, schema, table); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetIndexInfo(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 5) { + throw new SQLException("Invalid number of parameters for 'getIndexInfo'," + + " expected: '#!#getIndexInfo#!#catalog|schema|table|unique|approximate'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String table = parts[2]; + boolean unique = Boolean.parseBoolean(parts[3]); + boolean approximate = Boolean.parseBoolean(parts[4]); + ResultSet rs = dbmeta.getIndexInfo(catalog, schema, table, unique, approximate); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetMaxConnections(BufferedWriter bw, DatabaseMetaData dbmeta) throws SQLException, IOException { + int maxConn = dbmeta.getMaxConnections(); + + bw.write("~~START~~"); + bw.newLine(); + + bw.write(String.valueOf(maxConn)); + bw.newLine(); + + bw.write("~~END~~"); + bw.newLine(); + bw.newLine(); + } + + private static void testGetPrimaryKeys(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 3) { + throw new SQLException("Invalid number of parameters for 'getPrimaryKeys'," + + " expected: '#!#getPrimaryKeys#!#catalog|schema|table'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String table = parts[2]; + ResultSet rs = dbmeta.getPrimaryKeys(catalog, schema, table); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetProcedureColumns(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 3 && parts.length != 4) { + throw new SQLException("Invalid number of parameters for 'getProcedureColumns'," + + " expected: '#!#getProcedureColumns#!#catalog|schema|procedure[|column]'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String procedure = parts[2]; + String column = null; + if (parts.length == 4) { + column = parts[3]; + } + ResultSet rs = dbmeta.getProcedureColumns(catalog, schema, procedure, column); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetProcedures(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 2 && parts.length != 3) { + throw new SQLException("Invalid number of parameters for 'getProcedures'," + + " expected: '#!#getProcedures#!#catalog|schema[|procedure]'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String procedure = null; + if (parts.length == 3) { + procedure = parts[2]; + } + ResultSet rs = dbmeta.getProcedures(catalog, schema, procedure); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetSchemas(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 1 && parts.length != 2) { + throw new SQLException("Invalid number of parameters for 'getSchemas'," + + " expected: '#!#getSchemas#!#catalog[|schema]'"); + } + String catalog = parts[0]; + String schema = null; + if (parts.length == 2) { + schema = parts[1]; + } + ResultSet rs = dbmeta.getSchemas(catalog, schema); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetTablePrivileges(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 3) { + throw new SQLException("Invalid number of parameters for 'getTablePrivileges'," + + " expected: '#!#getTablePrivileges#!#catalog|schema|table'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String table = parts[2]; + ResultSet rs = dbmeta.getTablePrivileges(catalog, schema, table); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetTypeInfo(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta) throws SQLException { + ResultSet rs = dbmeta.getTypeInfo(); + CompareResults.writeResultSetToFile(bw, rs, logger); + } + + private static void testGetUserName(BufferedWriter bw, DatabaseMetaData dbmeta) throws SQLException, IOException { + String userName = dbmeta.getUserName(); + + bw.write("~~START~~"); + bw.newLine(); + + bw.write(userName); + bw.newLine(); + + bw.write("~~END~~"); + bw.newLine(); + bw.newLine(); + } + + private static void testGetVersionColumns(BufferedWriter bw, Logger logger, DatabaseMetaData dbmeta, String data) throws SQLException { + String[] parts = data.split("\\|"); + if (parts.length != 3) { + throw new SQLException("Invalid number of parameters for 'getVersionColumns'," + + " expected: '#!#getVersionColumns#!#catalog|schema|table'"); + } + String catalog = parts[0]; + String schema = parts[1]; + String table = parts[2]; + ResultSet rs = dbmeta.getVersionColumns(catalog, schema, table); + CompareResults.writeResultSetToFile(bw, rs, logger); + } +} diff --git a/test/JDBC/src/main/java/com/sqlsamples/batch_run.java b/test/JDBC/src/main/java/com/sqlsamples/batch_run.java index 09ce2edd34..108e863918 100644 --- a/test/JDBC/src/main/java/com/sqlsamples/batch_run.java +++ b/test/JDBC/src/main/java/com/sqlsamples/batch_run.java @@ -4,9 +4,6 @@ import java.io.*; import java.sql.*; -import java.util.*; - -import static java.util.Objects.isNull; import static com.sqlsamples.Config.*; import static com.sqlsamples.Statistics.exec_times; @@ -228,7 +225,15 @@ static void batch_run_sql(Connection con_bbl, BufferedWriter bw, String testFile String sourceTable = result[1]; String destinationTable = result[2]; jdbcBulkCopy.executeInsertBulk(con_bbl, destinationTable, sourceTable, logger, bw); + } else if (strLine.startsWith("dbmeta")) { + bw.write(strLine); + bw.newLine(); + + String[] result = strLine.split("#!#"); + String method = result[1]; + String data = result.length >= 3 ? result[2] : ""; + JDBCMetadata.testDatabaseMetadata(bw, logger, con_bbl, method, data); } else if (isCrossDialectFile && ( (tsqlDialect = strLine.toLowerCase().startsWith("-- tsql")) || (psqlDialect = strLine.toLowerCase().startsWith("-- psql")))) { // Cross dialect testing