1: %%
    2: %% %CopyrightBegin%
    3: %%
    4: %% Copyright Ericsson AB 2002-2013. All Rights Reserved.
    5: %%
    6: %% The contents of this file are subject to the Erlang Public License,
    7: %% Version 1.1, (the "License"); you may not use this file except in
    8: %% compliance with the License. You should have received a copy of the
    9: %% Erlang Public License along with this software. If not, it can be
   10: %% retrieved online at http://www.erlang.org/.
   11: %%
   12: %% Software distributed under the License is distributed on an "AS IS"
   13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
   14: %% the License for the specific language governing rights and limitations
   15: %% under the License.
   16: %%
   17: %% %CopyrightEnd%
   18: %%
   19: 
   20: %%
   21: 
   22: -module(odbc_query_SUITE).
   23: 
   24: %% Note: This directive should only be used in test suites.
   25: -compile(export_all).
   26: 
   27: -include_lib("common_test/include/ct.hrl").
   28: -include("test_server_line.hrl").
   29: -include("odbc_test.hrl").
   30: 
   31: %%--------------------------------------------------------------------
   32: %% all(Arg) -> [Doc] | [Case] | {skip, Comment}
   33: %% Arg - doc | suite
   34: %% Doc - string()
   35: %% Case - atom() 
   36: %%	Name of a test case function. 
   37: %% Comment - string()
   38: %% Description: Returns documentation/test cases in this test suite
   39: %%		or a skip tuple if the platform is not supported.  
   40: %%--------------------------------------------------------------------
   41: suite() -> [{ct_hooks,[ts_install_cth]}].
   42: 
   43: all() -> 
   44:     case odbc_test_lib:odbc_check() of
   45: 	ok ->
   46: 	    [stored_proc, sql_query, next, {group, scrollable_cursors}, select_count,
   47: 	     select_next, select_relative, select_absolute,
   48: 	     create_table_twice, delete_table_twice, duplicate_key,
   49: 	     not_connection_owner, no_result_set, query_error,
   50: 	     {group, multiple_result_sets},
   51: 	     {group, parameterized_queries}, {group, describe_table},
   52: 	     delete_nonexisting_row];
   53: 	Other -> {skip, Other}
   54:     end.
   55: 
   56: groups() -> 
   57:     [{multiple_result_sets, [], [multiple_select_result_sets,
   58:                                  multiple_mix_result_sets,
   59:                                  multiple_result_sets_error]},
   60:      {scrollable_cursors, [],  [first, last, prev]},
   61:      {parameterized_queries, [],
   62:       [{group, param_integers}, param_insert_decimal,
   63:        param_insert_numeric, {group, param_insert_string},
   64:        param_insert_float, param_insert_real,
   65:        param_insert_double, param_insert_mix, param_update,
   66:        param_delete, param_select,
   67:        param_select_empty_params, param_delete_empty_params]},
   68:      {param_integers, [],
   69:       [param_insert_tiny_int, param_insert_small_int,
   70:        param_insert_int, param_insert_integer]},
   71:      {param_insert_string, [],
   72:       [param_insert_char, param_insert_character,
   73:        param_insert_char_varying,
   74:        param_insert_character_varying]},
   75:      {describe_table, [],
   76:       [describe_integer, describe_string, describe_floating,
   77:        describe_dec_num, describe_no_such_table]}].
   78: 
   79: init_per_group(multiple_result_sets, Config) ->
   80:     case is_supported_multiple_resultsets(?RDBMS) of
   81: 	true ->
   82: 	    Config;
   83: 	false ->
   84: 	    {skip, "Not supported by " ++ atom_to_list(?RDBMS) ++ "driver"}
   85:     end;
   86: init_per_group(scrollable_cursors, Config) ->
   87:     case proplists:get_value(scrollable_cursors, odbc_test_lib:platform_options()) of
   88: 	off ->
   89: 	    {skip, "Not supported by driver"};
   90: 	_ ->
   91: 	    Config
   92:     end;
   93: 
   94: init_per_group(_,Config) ->
   95:     Config.
   96: 
   97: end_per_group(_GroupName, Config) ->
   98:     Config.
   99: 
  100: %%--------------------------------------------------------------------
  101: %% Function: init_per_suite(Config) -> Config
  102: %% Config - [tuple()]
  103: %%   A list of key/value pairs, holding the test case configuration.
  104: %% Description: Initiation before the whole suite
  105: %%
  106: %% Note: This function is free to add any key/value pairs to the Config
  107: %% variable, but should NOT alter/remove any existing entries.
  108: %%--------------------------------------------------------------------
  109: init_per_suite(Config) when is_list(Config) ->
  110:     case odbc_test_lib:skip() of
  111: 	true ->
  112: 	    {skip, "ODBC not supported"};
  113: 	false ->
  114: 	    case (catch odbc:start()) of
  115: 		ok ->
  116: 		    [{tableName, odbc_test_lib:unique_table_name()}| Config];
  117: 		_ ->
  118: 		    {skip, "ODBC not startable"}
  119: 	    end
  120:     end.
  121: 
  122: %%--------------------------------------------------------------------
  123: %% Function: end_per_suite(Config) -> _
  124: %% Config - [tuple()]
  125: %%   A list of key/value pairs, holding the test case configuration.
  126: %% Description: Cleanup after the whole suite
  127: %%--------------------------------------------------------------------
  128: end_per_suite(_Config) ->
  129:     application:stop(odbc),
  130:     ok.
  131: 
  132: %%--------------------------------------------------------------------
  133: %% Function: init_per_testcase(Case, Config) -> Config
  134: %% Case - atom()
  135: %%   Name of the test case that is about to be run.
  136: %% Config - [tuple()]
  137: %%   A list of key/value pairs, holding the test case configuration.
  138: %%
  139: %% Description: Initiation before each test case
  140: %%
  141: %% Note: This function is free to add any key/value pairs to the Config
  142: %% variable, but should NOT alter/remove any existing entries.
  143: %%--------------------------------------------------------------------
  144: init_per_testcase(_Case, Config) ->
  145:     {ok, Ref} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
  146:     odbc_test_lib:strict(Ref, ?RDBMS),
  147:     Dog = test_server:timetrap(?default_timeout),
  148:     Temp = lists:keydelete(connection_ref, 1, Config),
  149:     NewConfig = lists:keydelete(watchdog, 1, Temp),
  150:     [{watchdog, Dog}, {connection_ref, Ref} | NewConfig].
  151: 
  152: %%--------------------------------------------------------------------
  153: %% Function: end_per_testcase(Case, Config) -> _
  154: %% Case - atom()
  155: %%   Name of the test case that is about to be run.
  156: %% Config - [tuple()]
  157: %%   A list of key/value pairs, holding the test case configuration.
  158: %% Description: Cleanup after each test case
  159: %%--------------------------------------------------------------------
  160: end_per_testcase(_Case, Config) ->
  161:     Ref = ?config(connection_ref, Config),
  162:     ok = odbc:disconnect(Ref),
  163:     %% Clean up if needed 
  164:     Table = ?config(tableName, Config),
  165:     {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), odbc_test_lib:platform_options()),
  166:     odbc:sql_query(NewRef, "DROP TABLE " ++ Table), 
  167:     odbc:disconnect(NewRef),
  168:     Dog = ?config(watchdog, Config),
  169:     test_server:timetrap_cancel(Dog),
  170:     ok.
  171: 
  172: %%-------------------------------------------------------------------------
  173: %% Test cases starts here.
  174: %%-------------------------------------------------------------------------
  175: stored_proc(doc)->
  176:     ["Test stored proc with OUT param"];
  177: stored_proc(suite) -> [];
  178: stored_proc(Config) when is_list(Config) ->
  179:     case ?RDBMS of
  180:         X when X == oracle; X == postgres->
  181:             Ref = ?config(connection_ref, Config),
  182:             {updated, _} =
  183:                 odbc:sql_query(Ref,
  184:                                ?RDBMS:stored_proc_integer_out()),
  185:             Result = ?RDBMS:query_result(),
  186:             Result =
  187:                 ?RDBMS:param_query(Ref),
  188:             {updated, _} =
  189:                 odbc:sql_query(Ref, ?RDBMS:drop_proc()),
  190:             ok;
  191:         _ ->
  192: 	    {skip, "stored proc not yet supported"}
  193:     end.
  194: 
  195: sql_query(doc)->
  196:     ["Test the common cases"];
  197: sql_query(suite) -> [];
  198: sql_query(Config) when is_list(Config) ->
  199:     Ref = ?config(connection_ref, Config),
  200:     Table = ?config(tableName, Config),
  201: 
  202:     {updated, _} =
  203: 	odbc:sql_query(Ref, 
  204: 		       "CREATE TABLE " ++ Table ++ 
  205: 		       " (ID integer, DATA varchar(10))"),
  206: 
  207:     {updated, Count} = 
  208: 	odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
  209: 
  210:     true = odbc_test_lib:check_row_count(1, Count),
  211: 
  212:     InsertResult = ?RDBMS:insert_result(),
  213:     InsertResult = 
  214: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
  215: 
  216:     {updated, NewCount} = 
  217: 	odbc:sql_query(Ref, "UPDATE " ++ Table ++ 
  218: 		       " SET DATA = 'foo' WHERE ID = 1"),
  219:     
  220:     true = odbc_test_lib:check_row_count(1, NewCount),
  221: 
  222:     UpdateResult = ?RDBMS:update_result(),
  223:     UpdateResult = 
  224: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
  225: 
  226:     {updated,  NewCount1} = odbc:sql_query(Ref, "DELETE FROM " ++ Table ++ 
  227: 				  " WHERE ID = 1"),
  228:     
  229:     true = odbc_test_lib:check_row_count(1, NewCount1),
  230: 
  231:     {selected, Fields, []} =
  232: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
  233: 
  234:     ["ID","DATA"] = odbc_test_lib:to_upper(Fields),
  235:     ok.
  236: 
  237: %%-------------------------------------------------------------------------
  238: select_count(doc) -> 
  239:     ["Tests select_count/[2,3]'s timeout, "
  240:      " select_count's functionality will be better tested by other tests "
  241:      " such as first."];
  242: select_count(sute) -> [];
  243: select_count(Config) when is_list(Config) ->
  244:     Ref = ?config(connection_ref, Config),
  245:     Table = ?config(tableName, Config),
  246: 
  247:     {updated, _} = odbc:sql_query(Ref, 
  248: 				  "CREATE TABLE " ++ Table ++
  249: 				  " (ID integer)"),
  250: 
  251:     {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  252: 				  " VALUES(1)"),
  253:     true = odbc_test_lib:check_row_count(1, Count),
  254:     {ok, _} = 
  255: 	odbc:select_count(Ref, "SELECT * FROM " ++ Table, ?TIMEOUT),
  256:     {'EXIT', {function_clause, _}} = 
  257: 	(catch odbc:select_count(Ref, "SELECT * FROM ", -1)),
  258:     ok.
  259: %%-------------------------------------------------------------------------
  260: first(doc) ->
  261:     ["Tests first/[1,2]"];
  262: first(suite) -> [];
  263: first(Config) when is_list(Config) ->
  264:     Ref = ?config(connection_ref, Config),
  265:     Table = ?config(tableName, Config),
  266: 
  267:     {updated, _} = odbc:sql_query(Ref, 
  268: 				  "CREATE TABLE " ++ Table ++
  269: 				  " (ID integer)"),
  270:     
  271:     {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  272: 				  " VALUES(1)"),
  273:     true = odbc_test_lib:check_row_count(1, Count),
  274:     {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  275: 				  " VALUES(2)"),
  276:     true = odbc_test_lib:check_row_count(1, NewCount),
  277:     {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
  278: 
  279: 
  280:     FirstResult = ?RDBMS:selected_ID(1, first),
  281:     FirstResult = odbc:first(Ref),
  282:     FirstResult = odbc:first(Ref, ?TIMEOUT), 
  283:     {'EXIT', {function_clause, _}} = (catch odbc:first(Ref, -1)),
  284:     ok.
  285: 
  286: %%-------------------------------------------------------------------------
  287: last(doc) ->
  288:     ["Tests last/[1,2]"];
  289: last(suite) -> [];
  290: last(Config) when is_list(Config) ->
  291:     Ref = ?config(connection_ref, Config),
  292:     Table = ?config(tableName, Config),
  293: 
  294:     {updated, _} = odbc:sql_query(Ref, 
  295: 				  "CREATE TABLE " ++ Table ++
  296: 				  " (ID integer)"),
  297: 
  298:     {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  299: 				  " VALUES(1)"),
  300:     true = odbc_test_lib:check_row_count(1, Count),
  301:     {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  302: 				  " VALUES(2)"),
  303:     true = odbc_test_lib:check_row_count(1, NewCount),
  304:     {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
  305: 
  306:     LastResult = ?RDBMS:selected_ID(2, last),
  307:     LastResult = odbc:last(Ref),
  308: 
  309:     LastResult = odbc:last(Ref, ?TIMEOUT), 
  310:     {'EXIT', {function_clause, _}} = (catch odbc:last(Ref, -1)),
  311:     ok.
  312: 
  313: %%-------------------------------------------------------------------------
  314: next(doc) ->
  315:     ["Tests next/[1,2]"];
  316: next(suite) -> [];
  317: next(Config) when is_list(Config) ->
  318:     Ref = ?config(connection_ref, Config),
  319:     Table = ?config(tableName, Config),
  320: 
  321:     {updated, _} = odbc:sql_query(Ref, 
  322: 				  "CREATE TABLE " ++ Table ++
  323: 				  " (ID integer)"),
  324: 
  325:     {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  326: 				  " VALUES(1)"),
  327:     true = odbc_test_lib:check_row_count(1, Count),
  328:     {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  329: 				  " VALUES(2)"),
  330:     true = odbc_test_lib:check_row_count(1, NewCount),
  331:     {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
  332: 
  333:     NextResult = ?RDBMS:selected_ID(1, next),
  334:     NextResult = odbc:next(Ref),
  335:     NextResult2 = ?RDBMS:selected_ID(2, next),
  336:     NextResult2 = odbc:next(Ref, ?TIMEOUT), 
  337:     {'EXIT', {function_clause, _}} = (catch odbc:next(Ref, -1)),
  338:     ok.
  339: %%-------------------------------------------------------------------------
  340: prev(doc) ->
  341:     ["Tests prev/[1,2]"];
  342: prev(suite) -> [];
  343: prev(Config) when is_list(Config) ->
  344:     Ref = ?config(connection_ref, Config),
  345:     Table = ?config(tableName, Config),
  346: 
  347:     {updated, _} = odbc:sql_query(Ref, 
  348: 				  "CREATE TABLE " ++ Table ++
  349: 				  " (ID integer)"),
  350: 
  351:     {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  352: 				  " VALUES(1)"),
  353:     true = odbc_test_lib:check_row_count(1, Count),
  354:     {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  355: 				  " VALUES(2)"),
  356:     true = odbc_test_lib:check_row_count(1, NewCount),
  357: 
  358:     {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
  359: 
  360:     odbc:last(Ref), % Position cursor last so there will be a prev
  361:     PrevResult = ?RDBMS:selected_ID(1, prev),
  362:     PrevResult = odbc:prev(Ref),
  363: 
  364:     odbc:last(Ref), % Position cursor last so there will be a prev
  365:     PrevResult = odbc:prev(Ref, ?TIMEOUT), 
  366:     {'EXIT', {function_clause, _}} = (catch odbc:prev(Ref, -1)),
  367:     ok.
  368: %%-------------------------------------------------------------------------
  369: select_next(doc) ->
  370:     ["Tests select/[4,5] with CursorRelation = next "];
  371: select_next(suit) -> [];
  372: select_next(Config) when is_list(Config) ->
  373:     Ref = ?config(connection_ref, Config),
  374:     Table = ?config(tableName, Config),
  375: 
  376:     {updated, _} = odbc:sql_query(Ref, 
  377: 				  "CREATE TABLE " ++ Table ++
  378: 				  " (ID integer)"),
  379: 
  380:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  381: 				  " VALUES(1)"),
  382:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  383: 				  " VALUES(2)"),
  384:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  385: 				  " VALUES(3)"),
  386:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  387: 				  " VALUES(4)"),
  388:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  389: 				  " VALUES(5)"),
  390: 
  391:     {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), 
  392: 
  393:     SelectResult1 = ?RDBMS:selected_next_N(1),
  394:     SelectResult1 = odbc:select(Ref, next, 3),
  395: 
  396:     %% Test that selecting stops at the end of the result set
  397:     SelectResult2 = ?RDBMS:selected_next_N(2),
  398:     SelectResult2 = odbc:select(Ref, next, 3, ?TIMEOUT), 
  399:     {'EXIT',{function_clause, _}} = 
  400: 	(catch odbc:select(Ref, next, 2, -1)),
  401: 
  402:     %% If you try fetching data beyond the the end of result set,
  403:     %% you get an empty list.
  404:     {selected, Fields, []} = odbc:select(Ref, next, 1),
  405: 
  406:     ["ID"] = odbc_test_lib:to_upper(Fields),
  407:     ok.
  408: 
  409: %%-------------------------------------------------------------------------
  410: select_relative(doc) ->
  411:     ["Tests select/[4,5] with CursorRelation = relative "];
  412: select_relative(suit) -> [];
  413: select_relative(Config) when is_list(Config) ->
  414:     Ref = ?config(connection_ref, Config),
  415:     Table = ?config(tableName, Config),
  416: 
  417:     {updated, _} = odbc:sql_query(Ref, 
  418: 				  "CREATE TABLE " ++ Table ++
  419: 				  " (ID integer)"),
  420: 
  421:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  422: 				  " VALUES(1)"),
  423:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  424: 				  " VALUES(2)"), 
  425:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  426: 				  " VALUES(3)"),
  427:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  428: 				  " VALUES(4)"),
  429:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  430: 				  " VALUES(5)"),
  431:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  432: 				  " VALUES(6)"),
  433:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  434: 				  " VALUES(7)"),
  435:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  436: 				  " VALUES(8)"),
  437: 
  438:     {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
  439: 
  440:     SelectResult1 = ?RDBMS:selected_relative_N(1),
  441:     SelectResult1 = odbc:select(Ref, {relative, 2}, 3),
  442: 
  443:     %% Test that selecting stops at the end of the result set
  444:     SelectResult2 = ?RDBMS:selected_relative_N(2),
  445:     SelectResult2 = odbc:select(Ref, {relative, 3}, 3, ?TIMEOUT),
  446:     {'EXIT',{function_clause, _}} = 
  447: 	(catch odbc:select(Ref, {relative, 3} , 2, -1)),
  448:     ok.
  449: 
  450: %%-------------------------------------------------------------------------
  451: select_absolute(doc) ->
  452:     ["Tests select/[4,5] with CursorRelation = absolute "];
  453: select_absolute(suit) -> [];
  454: select_absolute(Config) when is_list(Config) ->
  455:     Ref = ?config(connection_ref, Config),
  456:     Table = ?config(tableName, Config),
  457: 
  458:     {updated, _} = odbc:sql_query(Ref, 
  459: 				  "CREATE TABLE " ++ Table ++
  460: 				  " (ID integer)"),
  461: 
  462:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  463: 				  " VALUES(1)"),
  464:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  465: 				  " VALUES(2)"),
  466:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  467: 				  " VALUES(3)"),
  468:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  469: 				  " VALUES(4)"),
  470:     {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
  471: 				  " VALUES(5)"),
  472:     {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table), 
  473: 
  474:     SelectResult1 = ?RDBMS:selected_absolute_N(1),
  475:     SelectResult1 = odbc:select(Ref, {absolute, 1}, 3),
  476: 
  477:     %% Test that selecting stops at the end of the result set
  478:     SelectResult2 = ?RDBMS:selected_absolute_N(2),
  479:     SelectResult2 = odbc:select(Ref, {absolute, 1}, 6, ?TIMEOUT),
  480:     {'EXIT',{function_clause, _}} = 
  481: 	(catch odbc:select(Ref, {absolute, 1}, 2, -1)),
  482:     ok.
  483: 
  484: %%-------------------------------------------------------------------------
  485: create_table_twice(doc) ->
  486:     ["Test what happens if you try to create the same table twice."];
  487: create_table_twice(suite) -> [];
  488: create_table_twice(Config) when is_list(Config) ->
  489:     Ref = ?config(connection_ref, Config),   
  490:     Table = ?config(tableName, Config),
  491: 
  492:     {updated, _} = 
  493: 	odbc:sql_query(Ref, 
  494: 		       "CREATE TABLE " ++ Table ++
  495: 		       " (ID integer, DATA varchar(10))"),
  496:     {error, Error} = 
  497: 	odbc:sql_query(Ref, 
  498: 		       "CREATE TABLE " ++ Table ++
  499: 		       " (ID integer, DATA varchar(10))"),
  500:     is_driver_error(Error),
  501:     ok.
  502: 
  503: %%-------------------------------------------------------------------------
  504: delete_table_twice(doc) ->
  505:     ["Test what happens if you try to delete the same table twice."];
  506: delete_table_twice(suite) -> [];
  507: delete_table_twice(Config) when is_list(Config) ->
  508:     Ref = ?config(connection_ref, Config),   
  509:     Table = ?config(tableName, Config),
  510: 
  511:     {updated, _} = 
  512: 	odbc:sql_query(Ref, 
  513: 		       "CREATE TABLE " ++ Table ++
  514: 		       " (ID integer, DATA varchar(10))"),
  515:     {updated, _} = odbc:sql_query(Ref, "DROP TABLE " ++ Table),
  516:     {error, Error} = odbc:sql_query(Ref, "DROP TABLE " ++ Table),
  517:     is_driver_error(Error),
  518:     ok.
  519: 
  520: %-------------------------------------------------------------------------
  521: duplicate_key(doc) ->
  522:     ["Test what happens if you try to use the same key twice"];
  523: duplicate_key(suit) -> [];
  524: duplicate_key(Config) when is_list(Config) ->
  525:     Ref = ?config(connection_ref, Config),   
  526:     Table = ?config(tableName, Config),
  527: 
  528:     {updated, _} = 
  529: 	odbc:sql_query(Ref, 
  530: 		       "CREATE TABLE " ++ Table ++
  531: 		       " (ID integer, DATA char(10), PRIMARY KEY(ID))"),
  532: 
  533:     {updated, 1} = 
  534: 	odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
  535: 
  536:     {error, Error} =
  537: 	odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'foo')"),
  538:     is_driver_error(Error),
  539:     ok.
  540: 
  541: %%-------------------------------------------------------------------------
  542: not_connection_owner(doc) ->
  543:     ["Test what happens if a process that did not start the connection"
  544:      " tries to acess it."];
  545: not_connection_owner(suite) -> [];
  546: not_connection_owner(Config) when is_list(Config) ->
  547:     Ref = ?config(connection_ref, Config),   
  548:     Table = ?config(tableName, Config),
  549: 
  550:     spawn_link(?MODULE, not_owner, [self(), Ref, Table]),
  551: 
  552:     receive 
  553: 	continue ->
  554: 	    ok
  555:     end.
  556: 
  557: not_owner(Pid, Ref, Table) ->
  558:     {error, process_not_owner_of_odbc_connection} =
  559: 	odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ " (ID integer)"),
  560: 
  561:     {error, process_not_owner_of_odbc_connection} =
  562: 	odbc:disconnect(Ref),
  563: 
  564:     Pid ! continue.
  565: 
  566: %%-------------------------------------------------------------------------
  567: no_result_set(doc) ->
  568:     ["Tests what happens if you try to use a function that needs an "
  569:      "associated result set when there is none."];
  570: no_result_set(suite) -> [];
  571: no_result_set(Config) when is_list(Config) ->
  572:     Ref = ?config(connection_ref, Config),   
  573: 
  574:     {error, result_set_does_not_exist} = odbc:first(Ref),
  575:     {error, result_set_does_not_exist} = odbc:last(Ref),
  576:     {error, result_set_does_not_exist} = odbc:next(Ref),
  577:     {error, result_set_does_not_exist} = odbc:prev(Ref),
  578:     {error, result_set_does_not_exist} = odbc:select(Ref, next, 1),
  579:     {error, result_set_does_not_exist} = 
  580: 	odbc:select(Ref, {absolute, 2}, 1),
  581:     {error, result_set_does_not_exist} = 
  582: 	odbc:select(Ref, {relative, 2}, 1),
  583:     ok.
  584: %%-------------------------------------------------------------------------
  585: query_error(doc) ->
  586:     ["Test what happens if there is an error in the query."];
  587: query_error(suite) ->
  588:     [];
  589: query_error(Config) when is_list(Config) ->
  590:     Ref = ?config(connection_ref, Config),   
  591:     Table = ?config(tableName, Config),
  592: 
  593:     {updated, _} = 
  594: 	odbc:sql_query(Ref, 
  595: 		       "CREATE TABLE " ++ Table ++
  596: 		       " (ID integer, DATA char(10), PRIMARY KEY(ID))"),
  597:     {updated, 1} = 
  598: 	odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
  599: 
  600:     {error, _} = 
  601: 	odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
  602: 
  603:     {error, _} = 
  604: 	odbc:sql_query(Ref, "INSERT ONTO " ++ Table ++ " VALUES(1,'bar')"),
  605:     ok.
  606: 
  607: %%-------------------------------------------------------------------------
  608: multiple_select_result_sets(doc) ->
  609:     ["Test what happens if you have a batch of select queries."];
  610: multiple_select_result_sets(suite) ->
  611:     [];
  612: multiple_select_result_sets(Config) when is_list(Config) ->
  613:     case ?RDBMS of
  614: 	sqlserver ->
  615: 	    Ref = ?config(connection_ref, Config),   
  616: 	    Table = ?config(tableName, Config),
  617: 	    
  618: 	    {updated, _} = 
  619: 		odbc:sql_query(Ref, 
  620: 			       "CREATE TABLE " ++ Table ++
  621: 			       " (ID integer, DATA varchar(10), "
  622: 			       "PRIMARY KEY(ID))"),
  623: 	    {updated, 1} = 
  624: 		odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 
  625: 			       " VALUES(1,'bar')"),
  626: 	    
  627: 	    {updated, 1} = 
  628: 		odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 
  629: 			       " VALUES(2, 'foo')"),
  630: 	    
  631: 	    MultipleResult = ?RDBMS:multiple_select(),
  632: 	    
  633: 	    MultipleResult = 
  634: 		odbc:sql_query(Ref, "SELECT * FROM " ++ Table ++ 
  635: 			       "; SELECT DATA FROM "++ Table ++ 
  636: 			       " WHERE ID=2"),
  637: 	    ok;
  638: 	_ ->
  639: 	    {skip, "multiple result_set not supported"}
  640:     end.
  641: 	    
  642: %%-------------------------------------------------------------------------
  643: multiple_mix_result_sets(doc) ->
  644:     ["Test what happens if you have a batch of select and other type of"
  645:      " queries."];
  646: multiple_mix_result_sets(suite) ->
  647:     [];
  648: multiple_mix_result_sets(Config) when is_list(Config) ->
  649:     case ?RDBMS of
  650: 	sqlserver ->
  651: 	    Ref = ?config(connection_ref, Config),   
  652: 	    Table = ?config(tableName, Config),
  653: 	    
  654: 	    {updated, _} = 
  655: 		odbc:sql_query(Ref, 
  656: 			       "CREATE TABLE " ++ Table ++
  657: 			       " (ID integer, DATA varchar(10), "
  658: 			       "PRIMARY KEY(ID))"),
  659: 	    {updated, 1} = 
  660: 		odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 
  661: 			       " VALUES(1,'bar')"),
  662: 
  663: 	    MultipleResult = ?RDBMS:multiple_mix(),
  664: 	    
  665: 	    MultipleResult = 
  666: 		odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 
  667: 			       " VALUES(2,'foo'); UPDATE " ++ Table ++ 
  668: 			       " SET DATA = 'foobar' WHERE ID =1;SELECT "
  669: 			       "* FROM " 
  670: 			       ++ Table ++ ";DELETE FROM " ++ Table ++
  671: 			       " WHERE ID =1; SELECT DATA FROM " ++ Table),
  672: 	    ok;
  673: 	_ ->
  674: 	    {skip, "multiple result_set not supported"}
  675:     end.
  676: %%-------------------------------------------------------------------------
  677: multiple_result_sets_error(doc) ->
  678:     ["Test what happens if one of the batched queries fails."];
  679: multiple_result_sets_error(suite) ->
  680:     [];
  681: multiple_result_sets_error(Config) when is_list(Config) ->
  682:     case ?RDBMS of
  683: 	sqlserver ->
  684: 	    Ref = ?config(connection_ref, Config),   
  685: 	    Table = ?config(tableName, Config),
  686: 	    
  687: 	    {updated, _} = 
  688: 		odbc:sql_query(Ref, 
  689: 			       "CREATE TABLE " ++ Table ++
  690: 			       " (ID integer, DATA varchar(10), "
  691: 			       "PRIMARY KEY(ID))"),
  692: 	    {updated, 1} = 
  693: 		odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 
  694: 			       " VALUES(1,'bar')"),
  695: 	    
  696: 	    {error, Error} = 
  697: 		odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ 
  698: 			       " VALUES(1,'foo'); SELECT * FROM " ++ Table),
  699: 	    is_driver_error(Error),
  700: 	    
  701: 	    {error, NewError} = 
  702: 		odbc:sql_query(Ref, "SELECT * FROM " 
  703: 			       ++ Table ++ ";INSERT INTO " ++ Table ++ 
  704: 		       " VALUES(1,'foo')"),
  705: 	    is_driver_error(NewError),
  706: 	    ok;
  707: 	_ ->
  708: 	    {skip, "multiple result_set not supported"}
  709:     end.   
  710: 
  711: %%-------------------------------------------------------------------------
  712: param_insert_tiny_int(doc)->
  713:     ["Test insertion of tiny ints by parameterized queries."];
  714: param_insert_tiny_int(suite) ->
  715:     [];
  716: param_insert_tiny_int(Config) when is_list(Config) ->
  717:     case ?RDBMS of 
  718: 	sqlserver ->
  719: 	    Ref = ?config(connection_ref, Config),   
  720: 	    Table = ?config(tableName, Config),
  721: 	    
  722: 	    {updated, _} = 
  723: 		odbc:sql_query(Ref, 
  724: 			       "CREATE TABLE " ++ Table ++
  725: 			       " (FIELD TINYINT)"),
  726: 	    
  727: 	    {updated, Count} = 
  728: 		odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  729: 				 "(FIELD) VALUES(?)", 
  730: 				 [{sql_tinyint, [1, 2]}],
  731: 				 ?TIMEOUT),%Make sure to test timeout clause
  732: 	    
  733: 	    true = odbc_test_lib:check_row_count(2, Count),
  734: 	    
  735: 	    InsertResult = ?RDBMS:param_select_tiny_int(),
  736: 	    
  737: 	    InsertResult = 
  738: 		odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
  739: 	    
  740: 	    {'EXIT',{badarg,odbc,param_query,'Params'}} = 
  741: 		(catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  742: 				"(FIELD) VALUES(?)",
  743: 					[{sql_tinyint, [1, "2"]}])),
  744: 	    ok;
  745: 	_  ->
  746: 	    {skip, "Type tiniyint not supported"}
  747:     end.
  748: %%-------------------------------------------------------------------------
  749: param_insert_small_int(doc)->
  750:     ["Test insertion of small ints by parameterized queries."];
  751: param_insert_small_int(suite) ->
  752:     [];
  753: param_insert_small_int(Config) when is_list(Config) ->
  754:     Ref = ?config(connection_ref, Config),   
  755:     Table = ?config(tableName, Config),
  756: 
  757:     {updated, _} = 
  758: 	odbc:sql_query(Ref, 
  759: 		       "CREATE TABLE " ++ Table ++
  760: 		       " (FIELD SMALLINT)"),
  761: 
  762:     {updated, Count} = 
  763: 	odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  764: 			 "(FIELD) VALUES(?)", [{sql_smallint, [1, 2]}],
  765: 			 ?TIMEOUT), %% Make sure to test timeout clause
  766: 
  767:     true = odbc_test_lib:check_row_count(2, Count),
  768: 
  769:     InsertResult = ?RDBMS:param_select_small_int(),
  770: 
  771:     InsertResult = 
  772: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
  773: 
  774:     {'EXIT',{badarg,odbc,param_query,'Params'}} = 
  775: 	(catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  776: 				"(FIELD) VALUES(?)",
  777: 				[{sql_smallint, [1, "2"]}])),    
  778:     ok.
  779: 
  780: %%-------------------------------------------------------------------------
  781: param_insert_int(doc)->
  782:     ["Test insertion of ints by parameterized queries."];
  783: param_insert_int(suite) ->
  784:     [];
  785: param_insert_int(Config) when is_list(Config) ->
  786:     Ref = ?config(connection_ref, Config),   
  787:     Table = ?config(tableName, Config),
  788: 
  789:     {updated, _} = 
  790: 	odbc:sql_query(Ref, 
  791: 		       "CREATE TABLE " ++ Table ++
  792: 		       " (FIELD INT)"),
  793: 
  794:     Int = ?RDBMS:small_int_max() + 1,
  795: 
  796:     {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  797: 				   "(FIELD) VALUES(?)", 
  798: 				   [{sql_integer, [1, Int]}]),
  799:     true = odbc_test_lib:check_row_count(2, Count),
  800:     
  801:     InsertResult = ?RDBMS:param_select_int(),
  802: 
  803:     InsertResult = 
  804: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
  805: 
  806:     {'EXIT',{badarg,odbc,param_query,'Params'}} = 
  807: 	(catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  808: 				"(FIELD) VALUES(?)",
  809: 				[{sql_integer, [1, "2"]}])),
  810:     ok.
  811: 
  812: %%-------------------------------------------------------------------------
  813: param_insert_integer(doc)->
  814:     ["Test insertion of integers by parameterized queries."];
  815: param_insert_integer(suite) ->
  816:     [];
  817: param_insert_integer(Config) when is_list(Config) ->
  818:     Ref = ?config(connection_ref, Config),   
  819:     Table = ?config(tableName, Config),
  820: 
  821:     {updated, _} = 
  822: 	odbc:sql_query(Ref, 
  823: 		       "CREATE TABLE " ++ Table ++
  824: 		       " (FIELD INTEGER)"),
  825: 
  826:     Int = ?RDBMS:small_int_max() + 1,
  827: 
  828:     {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  829: 				    "(FIELD) VALUES(?)", 
  830: 				    [{sql_integer, [1, Int]}]),
  831:     true = odbc_test_lib:check_row_count(2, Count),
  832: 
  833:     InsertResult = ?RDBMS:param_select_int(),
  834: 
  835:     InsertResult = 
  836: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
  837: 
  838:     {'EXIT',{badarg,odbc,param_query,'Params'}} = 
  839: 	(catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  840: 				"(FIELD) VALUES(?)", 
  841: 				[{sql_integer, [1, 2.3]}])),  
  842:     ok.
  843: 
  844: %%-------------------------------------------------------------------------
  845: param_insert_decimal(doc)->
  846:     ["Test insertion of decimal numbers by parameterized queries."];
  847: param_insert_decimal(suite) ->
  848:     [];
  849: param_insert_decimal(Config) when is_list(Config) ->
  850:     Ref = ?config(connection_ref, Config),   
  851:     Table = ?config(tableName, Config),
  852: 
  853:     {updated, _} = 
  854: 	odbc:sql_query(Ref, 
  855: 		       "CREATE TABLE " ++ Table ++
  856: 		       " (FIELD DECIMAL (3,0))"),
  857: 
  858:     {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  859: 				    "(FIELD) VALUES(?)", 
  860: 				    [{{sql_decimal, 3, 0}, [1, 2]}]),
  861:     true = odbc_test_lib:check_row_count(2, Count),
  862:     
  863:     InsertResult = ?RDBMS:param_select_decimal(),
  864: 
  865:     InsertResult = 
  866: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
  867: 
  868:     {'EXIT',{badarg,odbc,param_query,'Params'}} = 
  869: 	(catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  870: 				"(FIELD) VALUES(?)", 
  871: 				[{{sql_decimal, 3, 0}, [1, "2"]}])),
  872: 
  873: 
  874:     odbc:sql_query(Ref, "DROP TABLE " ++ Table),
  875: 
  876:     {updated, _} = 
  877: 	odbc:sql_query(Ref, 
  878: 		       "CREATE TABLE " ++ Table ++
  879: 		       " (FIELD DECIMAL (3,1))"),
  880: 
  881:     {updated, NewCount} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  882: 					   "(FIELD) VALUES(?)", 
  883: 				    [{{sql_decimal, 3, 1}, [0.25]}]),
  884:     true = odbc_test_lib:check_row_count(1, NewCount),
  885:     
  886:     {selected, Fields, [{Value}]} = 
  887: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
  888: 
  889:     ["FIELD"] = odbc_test_lib:to_upper(Fields),
  890:     
  891:     odbc_test_lib:match_float(Value, 0.3, 0.01),
  892:     
  893:     ok.
  894: 
  895: %%-------------------------------------------------------------------------
  896: param_insert_numeric(doc)->
  897:     ["Test insertion of numeric numbers by parameterized queries."];
  898: param_insert_numeric(suite) ->
  899:     [];
  900: param_insert_numeric(Config) when is_list(Config) ->
  901:     Ref = ?config(connection_ref, Config),   
  902:     Table = ?config(tableName, Config),
  903: 
  904:     {updated, _} = 
  905: 	odbc:sql_query(Ref, 
  906: 		       "CREATE TABLE " ++ Table ++
  907: 		       " (FIELD NUMERIC (3,0))"),
  908: 
  909:     {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  910: 				   "(FIELD) VALUES(?)", 
  911: 				   [{{sql_numeric,3,0}, [1, 2]}]),
  912: 
  913:     true = odbc_test_lib:check_row_count(2, Count),
  914: 
  915:     InsertResult = ?RDBMS:param_select_numeric(),
  916: 
  917:     InsertResult = 
  918: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
  919: 
  920:     {'EXIT',{badarg,odbc,param_query,'Params'}} = 
  921: 	(catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  922: 				"(FIELD) VALUES(?)", 
  923: 				[{{sql_decimal, 3, 0}, [1, "2"]}])),    
  924: 
  925:     odbc:sql_query(Ref, "DROP TABLE " ++ Table),
  926: 
  927:     {updated, _} = 
  928: 	odbc:sql_query(Ref, 
  929: 		       "CREATE TABLE " ++ Table ++
  930: 		       " (FIELD NUMERIC (3,1))"),
  931: 
  932:     {updated, NewCount} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  933: 				    "(FIELD) VALUES(?)", 
  934: 				    [{{sql_numeric, 3, 1}, [0.25]}]),
  935: 
  936:     true = odbc_test_lib:check_row_count(1, NewCount),
  937: 
  938:     {selected, Fileds, [{Value}]} = 
  939: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
  940: 
  941:     ["FIELD"] = odbc_test_lib:to_upper(Fileds),
  942: 
  943:     odbc_test_lib:match_float(Value, 0.3, 0.01),
  944:     ok.
  945: 
  946: %%-------------------------------------------------------------------------
  947: param_insert_char(doc)->
  948:     ["Test insertion of fixed length string by parameterized queries."];
  949: param_insert_char(suite) ->
  950:     [];
  951: param_insert_char(Config) when is_list(Config) ->
  952:     Ref = ?config(connection_ref, Config),   
  953:     Table = ?config(tableName, Config),
  954: 
  955:     {updated, _} = 
  956: 	odbc:sql_query(Ref, 
  957: 		       "CREATE TABLE " ++ Table ++
  958: 		       " (FIELD CHAR (10))"),
  959: 
  960:     {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  961: 				   "(FIELD) VALUES(?)", 
  962: 				   [{{sql_char, 10}, 
  963: 				     ["foofoofoof", "0123456789"]}]),
  964:     true = odbc_test_lib:check_row_count(2, Count),
  965: 
  966:     {selected,Fileds,[{"foofoofoof"}, {"0123456789"}]} =
  967: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
  968: 
  969:     ["FIELD"] = odbc_test_lib:to_upper(Fileds),
  970: 
  971:     {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  972: 				  "(FIELD) VALUES(?)", 
  973: 				  [{{sql_char, 10}, 
  974: 				    ["foo", "01234567890"]}]),
  975: 
  976:     {'EXIT',{badarg,odbc,param_query,'Params'}} = 
  977: 	(catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  978: 				"(FIELD) VALUES(?)",
  979: 				[{{sql_char, 10}, ["1", 2.3]}])), 
  980:     ok.
  981: 
  982: %%-------------------------------------------------------------------------
  983: param_insert_character(doc)->
  984:     ["Test insertion of fixed length string by parameterized queries."];
  985: param_insert_character(suite) ->
  986:     [];
  987: param_insert_character(Config) when is_list(Config) ->
  988:     Ref = ?config(connection_ref, Config),   
  989:     Table = ?config(tableName, Config),
  990: 
  991:     {updated, _} = 
  992: 	odbc:sql_query(Ref, 
  993: 		       "CREATE TABLE " ++ Table ++
  994: 		       " (FIELD CHARACTER (10))"),
  995: 
  996:     {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
  997: 				   "(FIELD) VALUES(?)", 
  998: 				   [{{sql_char, 10}, 
  999: 				     ["foofoofoof", "0123456789"]}]),
 1000: 
 1001:     true = odbc_test_lib:check_row_count(2, Count),
 1002: 
 1003:     {selected, Fileds, [{"foofoofoof"}, {"0123456789"}]} =
 1004: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
 1005: 
 1006:     ["FIELD"] = odbc_test_lib:to_upper(Fileds),
 1007: 
 1008:     {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1009: 				  "(FIELD) VALUES(?)", 
 1010: 				  [{{sql_char, 10}, 
 1011: 				    ["foo", "01234567890"]}]),
 1012: 
 1013:     {'EXIT',{badarg,odbc,param_query,'Params'}} = 
 1014: 	(catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1015: 				"(FIELD) VALUES(?)", 
 1016: 				[{{sql_char, 10}, ["1", 2]}])), 
 1017:     ok.
 1018: 
 1019: %%------------------------------------------------------------------------
 1020: param_insert_char_varying(doc)->
 1021:     ["Test insertion of variable length strings by parameterized queries."];
 1022: param_insert_char_varying(suite) ->
 1023:     [];
 1024: param_insert_char_varying(Config) when is_list(Config) ->
 1025:     Ref = ?config(connection_ref, Config),   
 1026:     Table = ?config(tableName, Config),
 1027: 
 1028:     {updated, _} = 
 1029: 	odbc:sql_query(Ref, 
 1030: 		       "CREATE TABLE " ++ Table ++
 1031: 		       " (FIELD CHAR VARYING(10))"),
 1032: 
 1033:     {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1034: 				   "(FIELD) VALUES(?)", 
 1035: 				   [{{sql_varchar, 10}, 
 1036: 				     ["foo", "0123456789"]}]),
 1037:     
 1038:     true = odbc_test_lib:check_row_count(2, Count),
 1039: 
 1040:     {selected, Fileds, [{"foo"}, {"0123456789"}]} =
 1041: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
 1042: 
 1043:     ["FIELD"] = odbc_test_lib:to_upper(Fileds),
 1044: 
 1045:     {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1046: 				  "(FIELD) VALUES(?)", 
 1047: 				  [{{sql_varchar, 10}, 
 1048: 				    ["foo", "01234567890"]}]),
 1049: 
 1050:     {'EXIT',{badarg,odbc,param_query,'Params'}} = 
 1051: 	(catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1052: 				"(FIELD) VALUES(?)", 
 1053: 				[{{sql_varchar, 10}, ["1", 2.3]}])), 
 1054:     ok.
 1055: 
 1056: %%-------------------------------------------------------------------------
 1057: param_insert_character_varying(doc)->
 1058:     ["Test insertion of variable length strings by parameterized queries."];
 1059: param_insert_character_varying(suite) ->
 1060:     [];
 1061: param_insert_character_varying(Config) when is_list(Config) ->
 1062:     Ref = ?config(connection_ref, Config),   
 1063:     Table = ?config(tableName, Config),
 1064: 
 1065:     {updated, _} = 
 1066: 	odbc:sql_query(Ref, 
 1067: 		       "CREATE TABLE " ++ Table ++
 1068: 		       " (FIELD CHARACTER VARYING(10))"),
 1069: 
 1070: 
 1071:     {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1072: 				   "(FIELD) VALUES(?)", 
 1073: 				   [{{sql_varchar, 10}, 
 1074: 				     ["foo", "0123456789"]}]),
 1075: 
 1076:     true = odbc_test_lib:check_row_count(2, Count),
 1077: 
 1078:     {selected, Fileds, [{"foo"}, {"0123456789"}]} =
 1079: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
 1080: 
 1081:     ["FIELD"] = odbc_test_lib:to_upper(Fileds),
 1082: 
 1083:     {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1084: 				  "(FIELD) VALUES(?)", 
 1085: 				  [{{sql_varchar, 10}, 
 1086: 				    ["foo", "01234567890"]}]),
 1087: 
 1088:     {'EXIT',{badarg,odbc,param_query,'Params'}} = 
 1089: 	(catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1090: 				"(FIELD) VALUES(?)", 
 1091: 				[{{sql_varchar, 10}, ["1", 2]}])), 
 1092:     ok.
 1093: %%-------------------------------------------------------------------------
 1094: param_insert_float(doc)->
 1095:     ["Test insertion of floats by parameterized queries."];
 1096: param_insert_float(suite) ->
 1097:     [];
 1098: param_insert_float(Config) when is_list(Config) ->
 1099:     Ref = ?config(connection_ref, Config),   
 1100:     Table = ?config(tableName, Config),
 1101: 
 1102:     {updated, _} = 
 1103: 	odbc:sql_query(Ref, 
 1104: 		       "CREATE TABLE " ++ Table ++
 1105: 		       " (FIELD FLOAT(5))"),
 1106: 
 1107:     {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1108: 				    "(FIELD) VALUES(?)", 
 1109: 				    [{{sql_float,5}, [1.3, 1.2]}]),
 1110: 
 1111:     true = odbc_test_lib:check_row_count(2, Count),
 1112: 
 1113:     {selected, Fileds, [{Float1},{Float2}]} =
 1114: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
 1115: 
 1116:     ["FIELD"] = odbc_test_lib:to_upper(Fileds),
 1117: 
 1118:     case (odbc_test_lib:match_float(Float1, 1.3, 0.000001) and 
 1119: 	  odbc_test_lib:match_float(Float2, 1.2, 0.000001)) of
 1120: 	true ->
 1121: 	    ok;
 1122: 	false ->
 1123: 	    test_server:fail(float_numbers_do_not_match)
 1124:     end,
 1125: 
 1126:     {'EXIT',{badarg,odbc,param_query,'Params'}} = 
 1127: 	(catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1128: 				"(FIELD) VALUES(?)",
 1129: 				[{{sql_float, 5}, [1.0, "2"]}])),
 1130:     ok.
 1131: 
 1132: %%-------------------------------------------------------------------------
 1133: param_insert_real(doc)->
 1134:     ["Test insertion of real numbers by parameterized queries."];
 1135: param_insert_real(suite) ->
 1136:     [];
 1137: param_insert_real(Config) when is_list(Config) ->
 1138:     Ref = ?config(connection_ref, Config),   
 1139:     Table = ?config(tableName, Config),
 1140: 
 1141:     {updated, _} = 
 1142: 	odbc:sql_query(Ref, 
 1143: 		       "CREATE TABLE " ++ Table ++
 1144: 		       " (FIELD REAL)"),
 1145: 
 1146:     {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1147: 				   "(FIELD) VALUES(?)", 
 1148: 				   [{sql_real, [1.3, 1.2]}]),
 1149: 
 1150:     true = odbc_test_lib:check_row_count(2, Count),
 1151: 
 1152:     %_InsertResult = ?RDBMS:param_select_real(),
 1153: 
 1154:     {selected, Fileds, [{Real1},{Real2}]} =
 1155: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
 1156: 
 1157:     ["FIELD"] = odbc_test_lib:to_upper(Fileds),
 1158: 
 1159:     case (odbc_test_lib:match_float(Real1, 1.3, 0.000001) and 
 1160: 	  odbc_test_lib:match_float(Real2, 1.2, 0.000001)) of
 1161: 	true ->
 1162: 	    ok;
 1163: 	false ->
 1164: 	    test_server:fail(real_numbers_do_not_match)
 1165:     end,
 1166: 
 1167:     {'EXIT',{badarg,odbc,param_query,'Params'}} = 
 1168: 	(catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1169: 				"(FIELD) VALUES(?)",
 1170: 				[{sql_real,[1.0, "2"]}])),
 1171:     ok.
 1172: 
 1173: %%-------------------------------------------------------------------------
 1174: param_insert_double(doc)->
 1175:     ["Test insertion of doubles by parameterized queries."];
 1176: param_insert_double(suite) ->
 1177:     [];
 1178: param_insert_double(Config) when is_list(Config) ->
 1179:     Ref = ?config(connection_ref, Config),   
 1180:     Table = ?config(tableName, Config),
 1181: 
 1182:     {updated, _} = 
 1183: 	odbc:sql_query(Ref, 
 1184: 		       "CREATE TABLE " ++ Table ++
 1185: 		       " (FIELD DOUBLE PRECISION)"),
 1186: 
 1187:     {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1188: 				   "(FIELD) VALUES(?)", 
 1189: 				   [{sql_double, [1.3, 1.2]}]),
 1190: 
 1191:     true = odbc_test_lib:check_row_count(2, Count),
 1192: 
 1193:     {selected, Fileds, [{Double1},{Double2}]} =
 1194: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
 1195: 
 1196:     ["FIELD"] = odbc_test_lib:to_upper(Fileds),
 1197: 
 1198:     case (odbc_test_lib:match_float(Double1, 1.3, 0.000001) and 
 1199: 	  odbc_test_lib:match_float(Double2, 1.2, 0.000001)) of
 1200: 	true ->
 1201: 	    ok;
 1202: 	false ->
 1203: 	    test_server:fail(double_numbers_do_not_match)
 1204:     end,
 1205: 
 1206:     {'EXIT',{badarg,odbc,param_query,'Params'}} = 
 1207: 	(catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1208: 				"(FIELD) VALUES(?)", 
 1209: 				[{sql_double, [1.0, "2"]}])),
 1210:     ok.
 1211: 
 1212: %%-------------------------------------------------------------------------
 1213: param_insert_mix(doc)->
 1214:     ["Test insertion of a mixture of datatypes by parameterized queries."];
 1215: param_insert_mix(suite) ->
 1216:     [];
 1217: param_insert_mix(Config) when is_list(Config) ->
 1218:     Ref = ?config(connection_ref, Config),   
 1219:     Table = ?config(tableName, Config),
 1220: 
 1221:     {updated, _} = 
 1222: 	odbc:sql_query(Ref, 
 1223: 		       "CREATE TABLE " ++ Table ++
 1224: 		       " (ID INTEGER, DATA CHARACTER VARYING(10),"
 1225: 		       " PRIMARY KEY(ID))"),
 1226: 
 1227:     {updated, Count}  = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1228: 				    "(ID, DATA) VALUES(?, ?)",
 1229: 				    [{sql_integer, [1, 2]}, 
 1230: 				     {{sql_varchar, 10}, ["foo", "bar"]}]),
 1231: 
 1232:     true = odbc_test_lib:check_row_count(2, Count),
 1233: 
 1234:     InsertResult = ?RDBMS:param_select_mix(),
 1235: 
 1236:     InsertResult = 
 1237: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
 1238:     ok.
 1239: %%-------------------------------------------------------------------------
 1240: param_update(doc)->
 1241:     ["Test parameterized update query."];
 1242: param_update(suite) ->
 1243:     [];
 1244: param_update(Config) when is_list(Config) ->
 1245:     Ref = ?config(connection_ref, Config),   
 1246:     Table = ?config(tableName, Config),
 1247: 
 1248:     {updated, _} = 
 1249: 	odbc:sql_query(Ref, 
 1250: 		       "CREATE TABLE " ++ Table ++
 1251: 		       " (ID INTEGER, DATA CHARACTER VARYING(10),"
 1252: 		       " PRIMARY KEY(ID))"),
 1253: 
 1254:     {updated, Count}  = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1255: 				    "(ID, DATA) VALUES(?, ?)",
 1256: 				    [{sql_integer, [1, 2, 3]}, 
 1257: 				     {{sql_varchar, 10}, 
 1258: 				      ["foo", "bar", "baz"]}]),
 1259: 
 1260:     true = odbc_test_lib:check_row_count(3, Count),
 1261: 
 1262:     {updated, NewCount}  = odbc:param_query(Ref, "UPDATE " ++ Table ++
 1263: 				    " SET DATA = 'foobar' WHERE ID = ?",
 1264: 				    [{sql_integer, [1, 2]}]), 
 1265: 
 1266:      true = odbc_test_lib:check_row_count(2, NewCount),
 1267: 
 1268:     UpdateResult = ?RDBMS:param_update(),
 1269: 
 1270:     UpdateResult = 
 1271: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
 1272:     ok.
 1273: 
 1274: %%-------------------------------------------------------------------------
 1275: delete_nonexisting_row(doc) ->		% OTP-5759
 1276:     ["Make a delete...where with false conditions (0 rows deleted). ",
 1277:      "This used to give an error message (see ticket OTP-5759)."];
 1278: delete_nonexisting_row(Config) when is_list(Config) ->
 1279:     Ref = ?config(connection_ref, Config),   
 1280:     Table = ?config(tableName, Config),
 1281: 
 1282:     {updated, _} =
 1283: 	odbc:sql_query(Ref, "CREATE TABLE " ++ Table
 1284: 		       ++ " (ID INTEGER, DATA CHARACTER VARYING(10))"),
 1285:     {updated, Count} =
 1286: 	odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1287: 			 "(ID, DATA) VALUES(?, ?)",
 1288: 			 [{sql_integer, [1, 2, 3]},
 1289: 			  {{sql_varchar, 10}, ["foo", "bar", "baz"]}]),
 1290:      
 1291:     true = odbc_test_lib:check_row_count(3, Count),
 1292: 
 1293:     {updated, NewCount} =
 1294: 	odbc:sql_query(Ref, "DELETE FROM " ++ Table ++ " WHERE ID = 8"),
 1295: 
 1296:     true = odbc_test_lib:check_row_count(0, NewCount),
 1297: 
 1298:     {updated, _} =
 1299: 	odbc:sql_query(Ref, "DROP TABLE "++ Table),
 1300: 
 1301:     ok.
 1302: 
 1303: %%-------------------------------------------------------------------------
 1304: param_delete(doc) ->
 1305:     ["Test parameterized delete query."];
 1306: param_delete(suite) ->
 1307:     [];
 1308: param_delete(Config) when is_list(Config) ->
 1309:     Ref = ?config(connection_ref, Config),   
 1310:     Table = ?config(tableName, Config),
 1311: 
 1312:     {updated, _} = 
 1313: 	odbc:sql_query(Ref, 
 1314: 		       "CREATE TABLE " ++ Table ++
 1315: 		       " (ID INTEGER, DATA CHARACTER VARYING(10),"
 1316: 		       " PRIMARY KEY(ID))"),
 1317: 
 1318:     {updated, Count}  = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1319: 				    "(ID, DATA) VALUES(?, ?)",
 1320: 				    [{sql_integer, [1, 2, 3]}, 
 1321: 				     {{sql_varchar, 10}, 
 1322: 				      ["foo", "bar", "baz"]}]),
 1323:     true = odbc_test_lib:check_row_count(3, Count),
 1324: 
 1325:     {updated, NewCount}  = odbc:param_query(Ref, "DELETE FROM " ++ Table ++
 1326: 				    " WHERE ID = ?",
 1327: 				    [{sql_integer, [1, 2]}]), 
 1328: 
 1329:     true = odbc_test_lib:check_row_count(2, NewCount),
 1330: 
 1331:     UpdateResult = ?RDBMS:param_delete(),
 1332: 
 1333:     UpdateResult = 
 1334: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
 1335:     ok.
 1336: 
 1337: 
 1338: %%-------------------------------------------------------------------------
 1339: param_select(doc) ->
 1340:     ["Test parameterized select query."];
 1341: param_select(suite) ->
 1342:     [];
 1343: param_select(Config) when is_list(Config) ->
 1344:     Ref = ?config(connection_ref, Config),   
 1345:     Table = ?config(tableName, Config),
 1346: 
 1347:     {updated, _} = 
 1348: 	odbc:sql_query(Ref, 
 1349: 		       "CREATE TABLE " ++ Table ++
 1350: 		       " (ID INTEGER, DATA CHARACTER VARYING(10),"
 1351: 		       " PRIMARY KEY(ID))"),
 1352: 
 1353:     {updated, Count}  = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1354: 				    "(ID, DATA) VALUES(?, ?)",
 1355: 				    [{sql_integer, [1, 2, 3]}, 
 1356: 				     {{sql_varchar, 10}, 
 1357: 				      ["foo", "bar", "foo"]}]),
 1358: 
 1359:     true = odbc_test_lib:check_row_count(3, Count),
 1360: 
 1361:     SelectResult = ?RDBMS:param_select(),
 1362: 
 1363:     SelectResult = odbc:param_query(Ref, "SELECT * FROM " ++ Table ++
 1364: 				    " WHERE DATA = ?",
 1365: 				    [{{sql_varchar, 10}, ["foo"]}]), 
 1366:     ok.
 1367: 
 1368: %%-------------------------------------------------------------------------
 1369: param_select_empty_params(doc) ->
 1370:     ["Test parameterized select query with no parameters."];
 1371: param_select_empty_params(suite) ->
 1372:     [];
 1373: param_select_empty_params(Config) when is_list(Config) ->
 1374:     Ref = ?config(connection_ref, Config),   
 1375:     Table = ?config(tableName, Config),
 1376: 
 1377:     {updated, _} = 
 1378: 	odbc:sql_query(Ref, 
 1379: 		       "CREATE TABLE " ++ Table ++
 1380: 		       " (ID INTEGER, DATA CHARACTER VARYING(10),"
 1381: 		       " PRIMARY KEY(ID))"),
 1382: 
 1383:     {updated, Count}  = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1384: 				    "(ID, DATA) VALUES(?, ?)",
 1385: 				    [{sql_integer, [1, 2, 3]}, 
 1386: 				     {{sql_varchar, 10}, 
 1387: 				      ["foo", "bar", "foo"]}]),
 1388: 
 1389:     true = odbc_test_lib:check_row_count(3, Count),
 1390: 
 1391:     SelectResult = ?RDBMS:param_select(),
 1392: 
 1393:     SelectResult = odbc:param_query(Ref, "SELECT * FROM " ++ Table ++
 1394: 				    " WHERE DATA = \'foo\'",
 1395: 				    []), 
 1396:     ok.
 1397: 
 1398: %%-------------------------------------------------------------------------
 1399: param_delete_empty_params(doc) ->
 1400:     ["Test parameterized delete query with no parameters."];
 1401: param_delete_empty_params(suite) ->
 1402:     [];
 1403: param_delete_empty_params(Config) when is_list(Config) ->
 1404:     Ref = ?config(connection_ref, Config),   
 1405:     Table = ?config(tableName, Config),
 1406: 
 1407:     {updated, _} = 
 1408: 	odbc:sql_query(Ref, 
 1409: 		       "CREATE TABLE " ++ Table ++
 1410: 		       " (ID INTEGER, DATA CHARACTER VARYING(10),"
 1411: 		       " PRIMARY KEY(ID))"),
 1412: 
 1413:     {updated, Count}  = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ 
 1414: 				    "(ID, DATA) VALUES(?, ?)",
 1415: 				    [{sql_integer, [1, 2, 3]}, 
 1416: 				     {{sql_varchar, 10}, 
 1417: 				      ["foo", "bar", "baz"]}]),
 1418:     true = odbc_test_lib:check_row_count(3, Count),
 1419: 
 1420:     {updated, NewCount}  = odbc:param_query(Ref, "DELETE FROM " ++ Table ++
 1421: 				    " WHERE ID = 1 OR ID = 2",
 1422: 				    []), 
 1423: 
 1424:     true = odbc_test_lib:check_row_count(2, NewCount),
 1425: 
 1426:     UpdateResult = ?RDBMS:param_delete(),
 1427: 
 1428:     UpdateResult = 
 1429: 	odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
 1430:     ok.
 1431: 
 1432: %%-------------------------------------------------------------------------
 1433: describe_integer(doc) ->
 1434:     ["Test describe_table/[2,3] for integer columns."];
 1435: describe_integer(suite) ->
 1436:     [];
 1437: describe_integer(Config) when is_list(Config) ->    
 1438:     Ref = ?config(connection_ref, Config),   
 1439:     Table = ?config(tableName, Config),
 1440: 
 1441:     {updated, _} = 
 1442: 	odbc:sql_query(Ref, 
 1443: 		       "CREATE TABLE " ++ Table ++
 1444: 		       " (myint1 SMALLINT, myint2 INT, myint3 INTEGER)"),
 1445: 
 1446:     Decs = ?RDBMS:describe_integer(),
 1447:     %% Make sure to test timeout clause
 1448:     Decs = odbc:describe_table(Ref, Table, ?TIMEOUT), 
 1449:     ok.
 1450: 
 1451: %%-------------------------------------------------------------------------
 1452: describe_string(doc) ->
 1453:     ["Test describe_table/[2,3] for string columns."];
 1454: describe_string(suite) ->
 1455:     [];
 1456: describe_string(Config) when is_list(Config) ->
 1457:     Ref = ?config(connection_ref, Config),   
 1458:     Table = ?config(tableName, Config),
 1459: 
 1460:     {updated, _} = 
 1461: 	odbc:sql_query(Ref, 
 1462: 		       "CREATE TABLE " ++ Table ++
 1463: 		       " (str1 char(10), str2 character(10), "
 1464: 		       "str3 CHAR VARYING(10), str4 "
 1465: 		       "CHARACTER VARYING(10))"),
 1466: 
 1467:     Decs = ?RDBMS:describe_string(),
 1468: 
 1469:     Decs = odbc:describe_table(Ref, Table),
 1470:     ok.
 1471: 
 1472: %%-------------------------------------------------------------------------
 1473: describe_floating(doc) ->
 1474:     ["Test describe_table/[2,3] for floting columns."];
 1475: describe_floating(suite) ->
 1476:     [];
 1477: describe_floating(Config) when is_list(Config) ->
 1478:     Ref = ?config(connection_ref, Config),   
 1479:     Table = ?config(tableName, Config),
 1480: 
 1481:     {updated, _} = 
 1482: 	odbc:sql_query(Ref, 
 1483: 		       "CREATE TABLE " ++ Table ++
 1484: 		       " (f FLOAT(5), r REAL, "
 1485: 		       "d DOUBLE PRECISION)"),
 1486: 
 1487:     Decs = ?RDBMS:describe_floating(),
 1488: 
 1489:     Decs = odbc:describe_table(Ref, Table),
 1490:     ok.
 1491: 
 1492: %%-------------------------------------------------------------------------
 1493: describe_dec_num(doc) ->
 1494:     ["Test describe_table/[2,3] for decimal and numerical columns"];
 1495: describe_dec_num(suite) ->
 1496:     [];
 1497: describe_dec_num(Config) when is_list(Config) ->
 1498: 
 1499:     Ref = ?config(connection_ref, Config),   
 1500:     Table = ?config(tableName, Config),
 1501: 
 1502:     {updated, _} = 
 1503: 	odbc:sql_query(Ref, 
 1504: 		       "CREATE TABLE " ++ Table ++
 1505: 		       " (mydec DECIMAL(9,3), mynum NUMERIC(9,2))"),
 1506: 
 1507:     Decs = ?RDBMS:describe_dec_num(),
 1508: 
 1509:     Decs = odbc:describe_table(Ref, Table),
 1510:     ok.
 1511: 
 1512: 
 1513: %%-------------------------------------------------------------------------
 1514: describe_timestamp(doc) ->
 1515:     ["Test describe_table/[2,3] for tinmestap columns"];
 1516: describe_timestamp(suite) ->
 1517:     [];
 1518: describe_timestamp(Config) when is_list(Config) ->
 1519:     
 1520:     Ref = ?config(connection_ref, Config),   
 1521:     Table = ?config(tableName, Config),
 1522:     
 1523:     {updated, _} =  % Value == 0 || -1 driver dependent!
 1524: 	odbc:sql_query(Ref,  "CREATE TABLE " ++ Table ++ 
 1525: 		       ?RDBMS:create_timestamp_table()),
 1526: 
 1527:     Decs = ?RDBMS:describe_timestamp(),
 1528: 
 1529:     Decs = odbc:describe_table(Ref, Table),
 1530:     ok.
 1531: 
 1532: %%-------------------------------------------------------------------------
 1533: describe_no_such_table(doc) ->
 1534:     ["Test what happens if you try to describe a table that does not exist."];
 1535: describe_no_such_table(suite) ->
 1536:     [];
 1537: describe_no_such_table(Config) when is_list(Config) ->
 1538: 
 1539:     Ref = ?config(connection_ref, Config),   
 1540:     Table = ?config(tableName, Config),
 1541: 
 1542:     {error, _ } = odbc:describe_table(Ref, Table),
 1543:     ok.
 1544: 
 1545: %%-------------------------------------------------------------------------
 1546: %% Internal functions
 1547: %%-------------------------------------------------------------------------
 1548: 
 1549: is_driver_error(Error) ->
 1550:     case is_list(Error) of
 1551: 	true ->
 1552: 	    test_server:format("Driver error ~p~n", [Error]),
 1553: 	    ok;
 1554: 	false ->
 1555: 	    test_server:fail(Error)
 1556:     end.
 1557: is_supported_multiple_resultsets(sqlserver) ->
 1558:     true;
 1559: is_supported_multiple_resultsets(_) ->
 1560:     false.