"Fossies" - the Fresh Open Source Software Archive

Member "seed7/prg/chkdb.sd7" (14 Feb 2020, 334567 Bytes) of package /linux/misc/seed7_05_20210223.tgz:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 
    2 (********************************************************************)
    3 (*                                                                  *)
    4 (*  chkdb.sd7     Checks the database interface.                    *)
    5 (*  Copyright (C) 2014, 2017 - 2019  Thomas Mertes                  *)
    6 (*                                                                  *)
    7 (*  This program is free software; you can redistribute it and/or   *)
    8 (*  modify it under the terms of the GNU General Public License as  *)
    9 (*  published by the Free Software Foundation; either version 2 of  *)
   10 (*  the License, or (at your option) any later version.             *)
   11 (*                                                                  *)
   12 (*  This program is distributed in the hope that it will be useful, *)
   13 (*  but WITHOUT ANY WARRANTY; without even the implied warranty of  *)
   14 (*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   *)
   15 (*  GNU General Public License for more details.                    *)
   16 (*                                                                  *)
   17 (*  You should have received a copy of the GNU General Public       *)
   18 (*  License along with this program; if not, write to the           *)
   19 (*  Free Software Foundation, Inc., 51 Franklin Street,             *)
   20 (*  Fifth Floor, Boston, MA  02110-1301, USA.                       *)
   21 (*                                                                  *)
   22 (********************************************************************)
   23 
   24 
   25 $ include "seed7_05.s7i";
   26   include "keybd.s7i";
   27   include "console.s7i";
   28   include "editline.s7i";
   29   include "sql_base.s7i";
   30   include "db_prop.s7i";
   31   include "bstring.s7i";
   32   include "time.s7i";
   33   include "duration.s7i";
   34 
   35 
   36 const type: connectData is new struct
   37     var dbCategory: driver       is NO_DB;
   38     var string:     dbName       is "";
   39     var string:     user         is "";
   40     var string:     password     is "";
   41     var dbCategory: databaseKind is NO_DB;
   42   end struct;
   43 
   44 
   45 const func connectData: connectData (in dbCategory: driver, in string: dbName,
   46     in string: user, in string: password, in dbCategory: databaseKind) is func
   47   result
   48     var connectData: connData is connectData.value;
   49   begin
   50     connData.driver       := driver;
   51     connData.dbName       := dbName;
   52     connData.user         := user;
   53     connData.password     := password;
   54     connData.databaseKind := databaseKind;
   55   end func;
   56 
   57 
   58 const type: testState is new struct
   59     var string: tableName is "";
   60     var string: fieldName is "";
   61     var sqlStatement: statement is sqlStatement.value;
   62     var boolean: okay is TRUE;
   63     var boolean: details is FALSE;
   64   end struct;
   65 
   66 
   67 const func testState: testState (in string: tableName,
   68     in string: fieldName, in boolean: details) is func
   69   result
   70     var testState: state is testState.value;
   71   begin
   72     state.tableName := tableName;
   73     state.fieldName := fieldName;
   74     state.details := details;
   75   end func;
   76 
   77 
   78 const boolean: infiniteAllowed is FALSE;
   79 const boolean: nanAllowed is FALSE;
   80 
   81 
   82 const func boolean: raisesRangeError (ref proc: expression) is func
   83   result
   84     var boolean: raisesRangeError is FALSE;
   85   begin
   86     block
   87       expression;
   88     exception
   89       catch RANGE_ERROR: raisesRangeError := TRUE;
   90     end block;
   91   end func;
   92 
   93 
   94 const func boolean: raisesDatabaseError (ref proc: expression) is func
   95   result
   96     var boolean: raisesDatabaseError is FALSE;
   97   begin
   98     block
   99       expression;
  100     exception
  101       catch DATABASE_ERROR: raisesDatabaseError := TRUE;
  102     end block;
  103   end func;
  104 
  105 
  106 const proc: DECL_INSERT (in type: elemType) is func
  107   begin
  108 
  109     const proc: insert (inout sqlStatement: statement, in elemType: anElement,
  110         in proc: succeedAction) is func
  111       local
  112         var boolean: succeeded is TRUE;
  113       begin
  114         block
  115           bind(statement, 1, anElement);
  116           execute(statement);
  117         exception
  118           otherwise: succeeded := FALSE;
  119         end block;
  120         if succeeded then
  121           succeedAction;
  122         else
  123           writeln(" *** Cannot insert " <& literal(anElement));
  124         end if;
  125       end func;
  126 
  127     const proc: insert (inout testState: state, in elemType: anElement,
  128         in proc: succeedAction) is func
  129       local
  130         var boolean: succeeded is TRUE;
  131       begin
  132         block
  133           bind(state.statement, 1, anElement);
  134           execute(state.statement);
  135         exception
  136           otherwise: succeeded := FALSE;
  137         end block;
  138         if succeeded then
  139           succeedAction;
  140         else
  141           state.okay := FALSE;
  142           if state.details then
  143             writeln(" *** Cannot insert " <& literal(anElement));
  144           end if;
  145         end if;
  146       end func;
  147 
  148     const proc: insInf (inout testState: state, in elemType: num,
  149         in proc: succeedAction) is func
  150       local
  151         var boolean: succeeded is TRUE;
  152       begin
  153         block
  154           bind(state.statement, 1, num);
  155           execute(state.statement);
  156         exception
  157           otherwise: succeeded := FALSE;
  158         end block;
  159         if succeeded then
  160           succeedAction;
  161           if not infiniteAllowed then
  162             state.okay := FALSE;
  163             if state.details then
  164               writeln(" *** Insert " <& num <& " succeeded, but it is not allowed");
  165             end if;
  166           end if
  167         elsif infiniteAllowed then
  168           state.okay := FALSE;
  169           if state.details then
  170             writeln(" *** Cannot insert " <& num);
  171           end if;
  172         end if;
  173       end func;
  174 
  175     const proc: insNaN (inout testState: state, in elemType: num,
  176         in proc: succeedAction) is func
  177       local
  178         var boolean: succeeded is TRUE;
  179       begin
  180         block
  181           bind(state.statement, 1, num);
  182           execute(state.statement);
  183         exception
  184           otherwise: succeeded := FALSE;
  185         end block;
  186         if succeeded then
  187           succeedAction;
  188           if not nanAllowed then
  189             state.okay := FALSE;
  190             if state.details then
  191               writeln(" *** Insert " <& num <& " succeeded, but it is not allowed");
  192             end if;
  193           end if
  194         elsif nanAllowed then
  195           state.okay := FALSE;
  196           if state.details then
  197             writeln(" *** Cannot insert " <& num);
  198           end if;
  199         end if;
  200       end func;
  201 
  202     const proc: insert (inout testState: state, in elemType: anElement,
  203         in proc: succeedAction, RANGE_CHECK) is func
  204       local
  205         var boolean: succeeded is TRUE;
  206       begin
  207         block
  208           bind(state.statement, 1, anElement);
  209           execute(state.statement);
  210         exception
  211           otherwise: succeeded := FALSE;
  212         end block;
  213         if succeeded then
  214           succeedAction;
  215           state.okay := FALSE;
  216           if state.details then
  217             writeln(" *** Insert " <& anElement <& " did not trigger an exception.");
  218           end if;
  219         end if;
  220       end func;
  221 
  222    end func;
  223 
  224 
  225 DECL_INSERT(boolean);
  226 DECL_INSERT(integer);
  227 DECL_INSERT(bigInteger);
  228 DECL_INSERT(float);
  229 DECL_INSERT(bigRational);
  230 DECL_INSERT(string);
  231 DECL_INSERT(bstring);
  232 DECL_INSERT(time);
  233 DECL_INSERT(duration);
  234 
  235 
  236 const proc: insert (inout sqlStatement: statement, NULL,
  237     in proc: succeedAction) is func
  238   local
  239     var boolean: succeeded is TRUE;
  240   begin
  241     block
  242       bind(statement, 1, NULL);
  243       execute(statement);
  244     exception
  245       otherwise: succeeded := FALSE;
  246     end block;
  247     if succeeded then
  248       succeedAction;
  249     else
  250       writeln(" *** Cannot insert NULL");
  251     end if;
  252   end func;
  253 
  254 
  255 const proc: insert (inout testState: state, NULL, in proc: succeedAction) is func
  256   local
  257     var boolean: succeeded is TRUE;
  258   begin
  259     block
  260       bind(state.statement, 1, NULL);
  261       execute(state.statement);
  262     exception
  263       otherwise: succeeded := FALSE;
  264     end block;
  265     if succeeded then
  266       succeedAction;
  267     else
  268       state.okay := FALSE;
  269       if state.details then
  270         writeln(" *** Cannot insert NULL");
  271       end if;
  272     end if;
  273   end func;
  274 
  275 
  276 const proc: insert (in database: testDb, inout testState: state,
  277     in string: aValue, in proc: succeedAction) is func
  278   local
  279     var sqlStatement: statement is sqlStatement.value;
  280   begin
  281     if succeeds(statement :=
  282           prepare(testDb, "INSERT INTO " & state.tableName &
  283                   " (" & state.fieldName & ") VALUES (" & aValue & ")")) and
  284         succeeds(execute(statement)) then
  285       succeedAction;
  286     else
  287       state.okay := FALSE;
  288       if state.details then
  289         writeln(" *** Cannot insert " <& literal(aValue));
  290       end if;
  291     end if;
  292   end func;
  293 
  294 
  295 const proc: create (in database: testDb, inout testState: state,
  296     in string: fieldDeclarationName, in string: fieldName) is func
  297   begin
  298     if succeeds(state.statement :=
  299           prepare(testDb, "CREATE TABLE " & state.tableName &
  300                   " (" & fieldDeclarationName & " CHAR)")) and
  301         succeeds(execute(state.statement)) then
  302       block
  303         state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
  304         execute(state.statement);
  305         if columnName(state.statement, 1) <> fieldName then
  306           state.okay := FALSE;
  307           if state.details then
  308             writeln(" *** Column name expected: " <& fieldName <& " found: " <&
  309                     columnName(state.statement, 1));
  310           end if;
  311         end if;
  312       exception
  313         catch RANGE_ERROR:
  314           state.okay := FALSE;
  315           writeln(" *** RANGE_ERROR was raised");
  316         catch FILE_ERROR:
  317           state.okay := FALSE;
  318           writeln(" *** FILE_ERROR was raised");
  319         catch DATABASE_ERROR:
  320           state.okay := FALSE;
  321           writeln(" *** DATABASE_ERROR was raised");
  322       end block;
  323       state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
  324       execute(state.statement);
  325     else
  326       state.okay := FALSE;
  327       if state.details then
  328         writeln(" *** Cannot create table with field " <& literal(fieldName));
  329       end if;
  330     end if;
  331   end func;
  332 
  333 
  334 const proc: testPrepareAndExecute (in database: testDb, in dbCategory: databaseKind) is func
  335   local
  336     var testState: state is testState("testPrepAndExecTable", "charField", FALSE);
  337     var database: emptyDb is database.value;
  338   begin
  339     if state.details then
  340       writeln("testPrepareAndExecute");
  341     end if;
  342     block
  343       execute(state.statement); # Executing an empty statement does nothing.
  344       if  not raisesRangeError(bind(state.statement, 1, 1_)) or
  345           not raisesRangeError(bind(state.statement, 1, 1_ / 1_)) or
  346           not raisesRangeError(bind(state.statement, 1, TRUE)) or
  347           not raisesRangeError(bind(state.statement, 1, bstring("x"))) or
  348           not raisesRangeError(bind(state.statement, 1, duration("P1D"))) or
  349           not raisesRangeError(bind(state.statement, 1, 1.0)) or
  350           not raisesRangeError(bind(state.statement, 1, 1)) or
  351           not raisesRangeError(bind(state.statement, 1, NULL)) or
  352           not raisesRangeError(bind(state.statement, 1, "x")) or
  353           not raisesRangeError(bind(state.statement, 1, time("2010-11-12 13:14:15.16"))) then
  354         state.okay := FALSE;
  355         if state.details then
  356           writeln(" *** Binding an empty statement succeeds.");
  357         end if;
  358       end if;
  359       if not raisesRangeError(state.statement := prepare(emptyDb,
  360                                   "CREATE TABLE " & state.tableName &
  361                                   " (" & state.fieldName & " CHAR)")) then
  362         state.okay := FALSE;
  363         if state.details then
  364           writeln(" *** Preparing with empty database succeeds.");
  365         end if;
  366       end if;
  367 
  368       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
  369                                  " (" & state.fieldName & " CHAR)");
  370       execute(state.statement);
  371 
  372       if raisesDatabaseError(
  373           state.statement := prepare(testDb, "SELECT * FROM " & state.tableName &
  374                                      " WHERE " & state.fieldName & " = 'x' /* ? */")) then
  375         state.okay := FALSE;
  376         if state.details then
  377           writeln(" *** Prepare: Question mark in comment interpreted as parameter placeholder.");
  378         end if;
  379       elsif raisesDatabaseError(execute(state.statement)) then
  380         state.okay := FALSE;
  381         if state.details then
  382           writeln(" *** Execute: Question mark in comment interpreted as parameter placeholder.");
  383         end if;
  384       end if;
  385       # Reset statement before a fetch is done to make sure that the next prepare works.
  386       state.statement := sqlStatement.value;
  387 
  388       if raisesDatabaseError(
  389           state.statement := prepare(testDb, "SELECT * FROM " & state.tableName &
  390                                      " WHERE " & state.fieldName & " = 'x' -- ? \n")) then
  391         state.okay := FALSE;
  392         if state.details then
  393           writeln(" *** Prepare: Question mark in line comment interpreted as parameter placeholder.");
  394         end if;
  395       elsif raisesDatabaseError(execute(state.statement)) then
  396         state.okay := FALSE;
  397         if state.details then
  398           writeln(" *** Execute: Question mark in line comment interpreted as parameter placeholder.");
  399         end if;
  400       end if;
  401       # Reset statement before a fetch is done to make sure that the next prepare works.
  402       state.statement := sqlStatement.value;
  403 
  404       if raisesDatabaseError(
  405           state.statement := prepare(testDb, "SELECT * FROM/* */" & state.tableName &
  406                                      "/* */WHERE " & state.fieldName & " = 'x'")) then
  407         state.okay := FALSE;
  408         if state.details then
  409           writeln(" *** Prepare: Comments to not separate words from each other.");
  410         end if;
  411       elsif raisesDatabaseError(execute(state.statement)) then
  412         state.okay := FALSE;
  413         if state.details then
  414           writeln(" *** Execute: Comments to not separate words from each other.");
  415         end if;
  416       end if;
  417       # Reset statement before a fetch is done to make sure that the next prepare works.
  418       state.statement := sqlStatement.value;
  419 
  420       if raisesDatabaseError(
  421           state.statement := prepare(testDb, "SELECT * FROM-- \n" & state.tableName &
  422                                      "-- \nWHERE " & state.fieldName & " = 'x'")) then
  423         state.okay := FALSE;
  424         if state.details then
  425           writeln(" *** Prepare: Line comments to not separate words from each other.");
  426         end if;
  427       elsif raisesDatabaseError(execute(state.statement)) then
  428         state.okay := FALSE;
  429         if state.details then
  430           writeln(" *** Execute: Line comments to not separate words from each other.");
  431         end if;
  432       end if;
  433       # Reset statement before a fetch is done to make sure that the next prepare works.
  434       state.statement := sqlStatement.value;
  435 
  436       if raisesDatabaseError(
  437           state.statement := prepare(testDb, "SELECT * FROM " & state.tableName &
  438                                      " WHERE " & state.fieldName & " = /*'*/?/*'*/")) then
  439         state.okay := FALSE;
  440         if state.details then
  441           writeln(" *** Prepare: Quotation characters in comments are interpreted as literal. (1)");
  442         end if;
  443       elsif raisesRangeError(bind(state.statement, 1, "x")) then
  444         state.okay := FALSE;
  445         if state.details then
  446           writeln(" *** Bind: Quotation characters in comments are interpreted as literal. (1)");
  447         end if;
  448       end if;
  449 
  450       if raisesDatabaseError(
  451           state.statement := prepare(testDb, "SELECT * FROM " & state.tableName &
  452                                      " WHERE " & state.fieldName & " = /*'*/'x'/*'*/")) then
  453         state.okay := FALSE;
  454         if state.details then
  455           writeln(" *** Prepare: Quotation characters in comments are interpreted as literal. (2)");
  456         end if;
  457       end if;
  458 
  459       if raisesDatabaseError(
  460           state.statement := prepare(testDb, "SELECT * FROM " & state.tableName &
  461                                      " WHERE " & state.fieldName & " = /*'*/'\\'/*'*/")) then
  462         state.okay := FALSE;
  463         if state.details then
  464           writeln(" *** Prepare: Quotation characters in comments are interpreted as literal. (3)");
  465         end if;
  466       end if;
  467 
  468       if raisesDatabaseError(
  469           state.statement := prepare(testDb, "SELECT * FROM " & state.tableName &
  470                                      " WHERE " & state.fieldName & " = '/*'")) then
  471         state.okay := FALSE;
  472         if state.details then
  473           writeln(" *** Prepare: Comment sequence in literal triggers error.");
  474         end if;
  475       elsif raisesDatabaseError(execute(state.statement)) then
  476         state.okay := FALSE;
  477         if state.details then
  478           writeln(" *** Execute: Comment sequence in literal triggers error.");
  479         end if;
  480       end if;
  481       # Reset statement before a fetch is done to make sure that the next prepare works.
  482       state.statement := sqlStatement.value;
  483 
  484       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName &
  485                                  " WHERE " & state.fieldName & " = ?");
  486       if not raisesDatabaseError(execute(state.statement)) then
  487         # Reset statement to make sure that the next prepare works:
  488         state.statement := sqlStatement.value;
  489         state.okay := FALSE;
  490         if state.details then
  491           writeln(" *** Omitted binding did not raise DATABASE_ERROR.");
  492         end if;
  493       end if;
  494       if not raisesRangeError(bind(state.statement, 0, "x")) then
  495         state.okay := FALSE;
  496         if state.details then
  497           writeln(" *** Binding of parameter 0 did not raise RANGE_ERROR.");
  498         end if;
  499       end if;
  500       if not raisesRangeError(bind(state.statement, 2, "x")) then
  501         state.okay := FALSE;
  502         if state.details then
  503           writeln(" *** Binding of non-existing parameter did not raise RANGE_ERROR.");
  504         end if;
  505       end if;
  506       if raisesRangeError(bind(state.statement, 1, "x")) then
  507         state.okay := FALSE;
  508         if state.details then
  509           writeln(" *** Binding of existing parameter raises RANGE_ERROR.");
  510         end if;
  511       end if;
  512       if raisesDatabaseError(execute(state.statement)) then
  513         # Reset statement to make sure that the next prepare works:
  514         state.statement := sqlStatement.value;
  515         state.okay := FALSE;
  516         if state.details then
  517           writeln(" *** Execute select statement with bind variable raises DATABASE_ERROR.");
  518         end if;
  519       elsif fetch(state.statement) then
  520         state.okay := FALSE;
  521         if state.details then
  522           writeln(" *** Fetching data from an empty table succeeds.");
  523         end if;
  524       end if;
  525 
  526       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName &
  527                                  " WHERE " & state.fieldName & " = 'x'");
  528       execute(state.statement);
  529       # Prepare next statement before the result of executed statement is fetched.
  530       if raisesDatabaseError(
  531           state.statement := prepare(testDb, "SELECT * FROM " & state.tableName & " WHERE " & state.fieldName & " = ?")) then
  532         # Reset statement to make sure that the next prepare works:
  533         state.statement := sqlStatement.value;
  534         state.okay := FALSE;
  535         if state.details then
  536           writeln(" *** Preparing a statement before a fetch of a previous statement is done raises DATABASE_ERROR. (empty table)");
  537         end if;
  538       end if;
  539 
  540       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
  541                                  " (" & state.fieldName & ") VALUES ('x')");
  542       execute(state.statement);
  543 
  544       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName &
  545                                  " WHERE " & state.fieldName & " = ?");
  546       bind(state.statement, 1, "x");
  547       execute(state.statement);
  548       if not fetch(state.statement) then
  549         state.okay := FALSE;
  550         if state.details then
  551           writeln(" *** Cannot fetch data from table with one entry.");
  552         end if;
  553       elsif fetch(state.statement) then
  554         # Reset statement to make sure that the next prepare works:
  555         state.statement := sqlStatement.value;
  556         state.okay := FALSE;
  557         if state.details then
  558           writeln(" *** Can fetch two entries from table with one entry.)");
  559         end if;
  560       end if;
  561 
  562       execute(state.statement);
  563       # Execute a second time before fetching data from the first execute.
  564       if raisesDatabaseError(execute(state.statement)) then
  565         state.okay := FALSE;
  566         if state.details then
  567           writeln(" *** Cannot execute a second time before fetching data from the first execute.");
  568         end if;
  569       elsif not fetch(state.statement) then
  570         state.okay := FALSE;
  571         if state.details then
  572           writeln(" *** Cannot fetch data from table with one entry, when executing again.");
  573         end if;
  574       elsif fetch(state.statement) then
  575         # Reset statement to make sure that the next prepare works:
  576         state.statement := sqlStatement.value;
  577         state.okay := FALSE;
  578         if state.details then
  579           writeln(" *** Can fetch two entries from table with one entry, when executing again.)");
  580         end if;
  581       end if;
  582 
  583       if state.okay then
  584         # Bind and execute again.
  585         bind(state.statement, 1, "x");
  586         execute(state.statement);
  587         if not fetch(state.statement) then
  588           state.okay := FALSE;
  589           if state.details then
  590             writeln(" *** Cannot fetch data from table with one entry.");
  591           end if;
  592         elsif fetch(state.statement) then
  593           # Reset statement to make sure that the next prepare works:
  594           state.statement := sqlStatement.value;
  595           state.okay := FALSE;
  596           if state.details then
  597             writeln(" *** Can fetch two entries from table with one entry.)");
  598           end if;
  599         end if;
  600       end if;
  601 
  602       if state.okay then
  603         execute(state.statement);
  604         # Bind and execute again although a previous execute is not fetched.
  605         bind(state.statement, 1, "x");
  606         execute(state.statement);
  607         if not fetch(state.statement) then
  608           state.okay := FALSE;
  609           if state.details then
  610             writeln(" *** Cannot fetch data from table with one entry.");
  611           end if;
  612         elsif fetch(state.statement) then
  613           # Reset statement to make sure that the next prepare works:
  614           state.statement := sqlStatement.value;
  615           state.okay := FALSE;
  616           if state.details then
  617             writeln(" *** Can fetch two entries from table with one entry.)");
  618           end if;
  619         end if;
  620       end if;
  621 
  622       if state.okay then
  623         # Prepare next statement before the result of executed statement is fetched.
  624         execute(state.statement);
  625         if raisesDatabaseError(
  626             state.statement := prepare(testDb, "SELECT * FROM " & state.tableName &
  627                                        " WHERE " & state.fieldName & " = ?")) then
  628           # Reset statement to make sure that the next prepare works:
  629           state.statement := sqlStatement.value;
  630           state.okay := FALSE;
  631           if state.details then
  632             writeln(" *** Preparing a statement before a fetch of a previous statement is done raises DATABASE_ERROR. (non-empty table)");
  633           end if;
  634         end if;
  635       end if;
  636 
  637     exception
  638       catch RANGE_ERROR:
  639         state.okay := FALSE;
  640         writeln(" *** RANGE_ERROR was raised");
  641       catch FILE_ERROR:
  642         state.okay := FALSE;
  643         writeln(" *** FILE_ERROR was raised");
  644       catch DATABASE_ERROR:
  645         state.okay := FALSE;
  646         writeln(" *** DATABASE_ERROR was raised");
  647     end block;
  648     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
  649     if not succeeds(execute(state.statement)) then
  650       state.okay := FALSE;
  651       if state.details then
  652         writeln(" *** Execute: Cannot drop table.");
  653       end if;
  654     end if;
  655 
  656     if state.okay then
  657       writeln("Preparing and executing prepared statements works okay.");
  658     else
  659       writeln(" *** Preparing and executing prepared statements does not work okay.");
  660     end if;
  661   end func;
  662 
  663 
  664 const proc: testFieldNames (in database: testDb, in dbCategory: databaseKind) is func
  665   local
  666     var testState: state is testState("testTable", "unused", FALSE);
  667   begin
  668     if state.details then
  669       writeln("testFieldNames");
  670     end if;
  671     create(testDb, state, "\"ch a\"",    "ch a");   # Space in name
  672     if allowedInFieldName(databaseKind, '\"') then
  673       create(testDb, state, "\"ch\"\"a\"", "ch\"a");  # Double quote in name
  674     end if;
  675     create(testDb, state, "\"ch'a\"",    "ch'a");   # Single quote in name
  676     create(testDb, state, "\"ch`a\"",    "ch`a");   # Backtick in name
  677     create(testDb, state, "\"ch\\a\"",   "ch\\a");  # Backslash in name
  678     create(testDb, state, "\"ch\ta\"",   "ch\ta");
  679     create(testDb, state, "\"ch\na\"",   "ch\na");
  680     create(testDb, state, "\"ch€a\"",    "ch€a");
  681     create(testDb, state, "\"chµa\"",    "chµa");
  682 
  683     if allowedInFieldName(databaseKind, '\0;') then
  684       create(testDb, state, "\"\0;\"",         "\0;");
  685     end if;
  686     create(testDb, state, "\"\1;\"",         "\1;");
  687     create(testDb, state, "\"\2;\"",         "\2;");
  688     create(testDb, state, "\"\3;\"",         "\3;");
  689     create(testDb, state, "\"\4;\"",         "\4;");
  690     create(testDb, state, "\"\5;\"",         "\5;");
  691     create(testDb, state, "\"\6;\"",         "\6;");
  692     create(testDb, state, "\"\7;\"",         "\7;");
  693     create(testDb, state, "\"\8;\"",         "\8;");
  694     if allowedInFieldName(databaseKind, '\9;') then
  695       create(testDb, state, "\"\9;\"",         "\9;");
  696     end if;
  697     if allowedInFieldName(databaseKind, '\10;') then
  698       create(testDb, state, "\"\10;\"",        "\10;");
  699     end if;
  700     if allowedInFieldName(databaseKind, '\9;') and
  701         allowedInFieldName(databaseKind, '\10;') then
  702       create(testDb, state, "\"\1;\2;\3;\4;\5;\6;\7;\8;\9;\10;\"",
  703                               "\1;\2;\3;\4;\5;\6;\7;\8;\9;\10;");
  704     else
  705       create(testDb, state, "\"\1;\2;\3;\4;\5;\6;\7;\8;\"",
  706                               "\1;\2;\3;\4;\5;\6;\7;\8;");
  707     end if;
  708     create(testDb, state, "\"\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\"",
  709                             "\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;");
  710     create(testDb, state, "\"\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;\"",
  711                             "\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;");
  712 
  713     if allowedInFieldName(databaseKind, ' ') then
  714       create(testDb, state, "\" \"",                   " ");
  715     end if;
  716     if allowedInFieldName(databaseKind, '\"') then
  717       create(testDb, state, "\"!\"\"#$%&'()*+,-./\"",  "!\"#$%&'()*+,-./");
  718     else
  719       create(testDb, state, "\"!#$%&'()*+,-./\"",      "!#$%&'()*+,-./");
  720     end if;
  721     create(testDb, state, "\"0123456789\"",          "0123456789");
  722     create(testDb, state, "\":;<=>?@\"",             ":;<=>?@");
  723     create(testDb, state, "\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"",
  724                             "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  725     create(testDb, state, "\"[\\^_`\"",              "[\\^_`");
  726     create(testDb, state, "\"abcdefghijklmnopqrstuvwxyz\"",
  727                             "abcdefghijklmnopqrstuvwxyz");
  728     create(testDb, state, "\"{|}~\"",                "{|}~");
  729     create(testDb, state, "\"\127;\"",               "\127;");
  730 
  731     create(testDb, state, "\"\128;\129;\130;\131;\132;\133;\134;\135;\"",
  732                             "\128;\129;\130;\131;\132;\133;\134;\135;");
  733     create(testDb, state, "\"\136;\137;\138;\139;\140;\141;\142;\143;\"",
  734                             "\136;\137;\138;\139;\140;\141;\142;\143;");
  735     create(testDb, state, "\"\144;\145;\146;\147;\148;\149;\150;\151;\"",
  736                             "\144;\145;\146;\147;\148;\149;\150;\151;");
  737     create(testDb, state, "\"\152;\153;\154;\155;\156;\157;\158;\159;\"",
  738                             "\152;\153;\154;\155;\156;\157;\158;\159;");
  739     create(testDb, state, "\"\160;\"",               "\160;");
  740 
  741     create(testDb, state, "\"¡¢£¤¥¦§¨©ª«¬­®¯\"",     "¡¢£¤¥¦§¨©ª«¬­®¯");
  742     create(testDb, state, "\"°±²³´µ¶·\"",            "°±²³´µ¶·");
  743     create(testDb, state, "\"¸¹º»¼½¾¿\"",            "¸¹º»¼½¾¿");
  744     create(testDb, state, "\"ÀÁÂÃÄÅÆÇ\"",            "ÀÁÂÃÄÅÆÇ");
  745     create(testDb, state, "\"ÈÉÊËÌÍÎÏ\"",            "ÈÉÊËÌÍÎÏ");
  746     create(testDb, state, "\"ÐÑÒÓÔÕÖ×\"",            "ÐÑÒÓÔÕÖ×");
  747     create(testDb, state, "\"ØÙÚÛÜÝÞß\"",            "ØÙÚÛÜÝÞß");
  748     create(testDb, state, "\"àáâãäåæç\"",            "àáâãäåæç");
  749     create(testDb, state, "\"èéêëìíîï\"",            "èéêëìíîï");
  750     create(testDb, state, "\"ðñòóôõö÷\"",            "ðñòóôõö÷");
  751     create(testDb, state, "\"øùúûüýþÿ\"",            "øùúûüýþÿ");
  752 
  753     if state.okay then
  754       writeln("Creating tables with allowed characters in field names works okay.");
  755     else
  756       writeln(" *** Creating tables with allowed characters in field names does not work okay.");
  757     end if;
  758   end func;
  759 
  760 
  761 
  762 const proc: testWithAutoCommit (in database: testDb, inout testState: state,
  763     in database: secondDbConnection) is func
  764   local
  765     var sqlStatement: secondStmt is sqlStatement.value;
  766   begin
  767     secondStmt := prepare(secondDbConnection, "CREATE TABLE " & state.tableName &
  768                                               " (" & state.fieldName & " CHAR(32))");
  769     execute(secondStmt);
  770 
  771     state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
  772     if not succeeds(execute(state.statement)) then
  773       state.okay := FALSE;
  774       if state.details then
  775         writeln(" *** Execute: Table created by other connection does not exist. (1)");
  776       end if;
  777     elsif fetch(state.statement) then
  778       state.okay := FALSE;
  779       if state.details then
  780         writeln(" *** Fetch: Fetch succeeds for table created by other connection. (1)");
  781       end if;
  782     end if;
  783 
  784     secondStmt := prepare(secondDbConnection, "INSERT INTO " & state.tableName &
  785                                               " (" & state.fieldName & ") VALUES (NULL)");
  786     execute(secondStmt);
  787 
  788     if not succeeds(execute(state.statement)) then
  789       state.okay := FALSE;
  790       if state.details then
  791         writeln(" *** Execute: Table created by other connection does not exist. (2)");
  792       end if;
  793     elsif not fetch(state.statement) then
  794       state.okay := FALSE;
  795       if state.details then
  796         writeln(" *** Fetch: Fetch fails for table created by other connection. (1)");
  797       end if;
  798     end if;
  799 
  800     secondStmt := prepare(secondDbConnection, "DELETE FROM " & state.tableName);
  801     if not succeeds(execute(secondStmt)) then
  802       state.okay := FALSE;
  803       if state.details then
  804         writeln(" *** Execute: Cannot delete from table while another database connection is open.");
  805       end if;
  806     end if;
  807 
  808     state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
  809     if not succeeds(execute(state.statement)) then
  810       state.okay := FALSE;
  811       if state.details then
  812         writeln(" *** Execute: Table created by other connection does not exist. (3)");
  813       end if;
  814     elsif fetch(state.statement) then
  815       state.okay := FALSE;
  816       if state.details then
  817         writeln(" *** Fetch: Fetch succeeds for table created by other connection. (2)");
  818       end if;
  819     end if;
  820 
  821     secondStmt := prepare(secondDbConnection, "DROP TABLE " & state.tableName);
  822     if not succeeds(execute(secondStmt)) then
  823       state.okay := FALSE;
  824       if state.details then
  825         writeln(" *** Execute: Cannot drop table while another database connection is open.");
  826       end if;
  827     end if;
  828 
  829     if succeeds(execute(state.statement)) then
  830       state.okay := FALSE;
  831       if state.details then
  832         writeln(" *** Execute: Table dropped by other connection still does exist. (1)");
  833       end if;
  834     end if;
  835   end func;
  836 
  837 
  838 const proc: testAutoCommit (in database: testDb, in connectData: dbConnectData) is func
  839   local
  840     var testState: state is testState("testTable", "charField", FALSE);
  841     var database: secondDbConnection is database.value;
  842     var sqlStatement: secondStmt is sqlStatement.value;
  843   begin
  844     if state.details then
  845       writeln("testAutoCommit");
  846     end if;
  847     block
  848       secondDbConnection := openDatabase(dbConnectData.driver,
  849                                          dbConnectData.dbName,
  850                                          dbConnectData.user,
  851                                          dbConnectData.password);
  852     exception
  853       catch DATABASE_ERROR:
  854         state.okay := FALSE;
  855         if state.details then
  856           writeln(" *** Cannot open database " <& dbConnectData.dbName <&
  857                   " with driver " <& dbConnectData.driver);
  858           writeln(" *** Database error: " <& errMessage(DATABASE_ERROR));
  859         end if;
  860       otherwise:
  861         state.okay := FALSE;
  862         if state.details then
  863           writeln(" *** Cannot open database " <& dbConnectData.dbName <&
  864                   " with driver " <& dbConnectData.driver);
  865         end if;
  866     end block;
  867     if secondDbConnection <> database.value then
  868       block
  869         if not getAutoCommit(secondDbConnection) then
  870           state.okay := FALSE;
  871           if state.details then
  872             writeln(" *** AutoCommit is off on a new created connection.");
  873           end if;
  874         else
  875           testWithAutoCommit(testDb, state, secondDbConnection);
  876         end if;
  877       exception
  878         catch RANGE_ERROR:
  879           state.okay := FALSE;
  880           writeln(" *** RANGE_ERROR was raised");
  881         catch FILE_ERROR:
  882           state.okay := FALSE;
  883           writeln(" *** FILE_ERROR was raised");
  884         catch DATABASE_ERROR:
  885           state.okay := FALSE;
  886           writeln(" *** DATABASE_ERROR was raised");
  887       end block;
  888       close(secondDbConnection);
  889       if not state.okay then
  890         block
  891           state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
  892           execute(state.statement);
  893         exception
  894           otherwise:
  895             noop;
  896         end block;
  897       end if;
  898     end if;
  899 
  900     if state.okay then
  901       writeln("Autocommit works okay.");
  902     else
  903       writeln(" *** Autocommit does not work okay.");
  904     end if;
  905   end func;
  906 
  907 
  908 const proc: testWithoutAutoCommit (in database: testDb, inout testState: state,
  909     in database: secondDbConnection) is func
  910   local
  911     var sqlStatement: secondStmt is sqlStatement.value;
  912   begin
  913     secondStmt := prepare(secondDbConnection, "CREATE TABLE " & state.tableName &
  914                                               " (" & state.fieldName & " CHAR(32))");
  915     execute(secondStmt);
  916 
  917     if not succeeds(
  918         state.statement := prepare(testDb, "SELECT * FROM " & state.tableName)) then
  919       state.okay := FALSE;
  920       if state.details then
  921         writeln(" *** Prepare: Select from table created by other connection fails.");
  922       end if;
  923     elsif not succeeds(execute(state.statement)) then
  924       state.okay := FALSE;
  925       if state.details then
  926         writeln(" *** Execute: Table created by other connection does not exist. (1)");
  927       end if;
  928     elsif fetch(state.statement) then
  929       state.okay := FALSE;
  930       if state.details then
  931         writeln(" *** Fetch: Fetch succeeds for table created by other connection. (1)");
  932       end if;
  933     end if;
  934 
  935     secondStmt := prepare(secondDbConnection, "INSERT INTO " & state.tableName &
  936                                               " (" & state.fieldName & ") VALUES (NULL)");
  937     execute(secondStmt);
  938 
  939     if state.statement <> sqlStatement.value then
  940       if not succeeds(execute(state.statement)) then
  941         state.okay := FALSE;
  942         if state.details then
  943           writeln(" *** Execute: Table created by other connection does not exist. (2)");
  944         end if;
  945       elsif fetch(state.statement) then
  946         state.okay := FALSE;
  947         if state.details then
  948           writeln(" *** Fetch: Fetch succeeds for table created by other connection. (2)");
  949         end if;
  950       end if;
  951     end if;
  952 
  953     commit(secondDbConnection);
  954 
  955     if state.statement <> sqlStatement.value then
  956       if not succeeds(execute(state.statement)) then
  957         state.okay := FALSE;
  958         if state.details then
  959           writeln(" *** Execute: Table created by other connection does not exist. (3)");
  960         end if;
  961       elsif not fetch(state.statement) then
  962         state.okay := FALSE;
  963         if state.details then
  964           writeln(" *** Fetch: Fetch fails for table created by other connection. (1)");
  965         end if;
  966       end if;
  967     end if;
  968 
  969     secondStmt := prepare(secondDbConnection, "DELETE FROM " & state.tableName);
  970     execute(secondStmt);
  971 
  972     if state.statement <> sqlStatement.value then
  973       if not succeeds(execute(state.statement)) then
  974         state.okay := FALSE;
  975         if state.details then
  976           writeln(" *** Execute: Table created by other connection does not exist. (4)");
  977         end if;
  978       elsif not fetch(state.statement) then
  979         state.okay := FALSE;
  980         if state.details then
  981           writeln(" *** Fetch: Fetch fails for table created by other connection. (2)");
  982         end if;
  983       end if;
  984     end if;
  985 
  986     rollback(secondDbConnection);
  987 
  988     if state.statement <> sqlStatement.value then
  989       if not succeeds(execute(state.statement)) then
  990         state.okay := FALSE;
  991         if state.details then
  992           writeln(" *** Execute: Table created by other connection does not exist. (5)");
  993         end if;
  994       elsif not fetch(state.statement) then
  995         state.okay := FALSE;
  996         if state.details then
  997           writeln(" *** Fetch: Fetch fails for table created by other connection. (3)");
  998         end if;
  999       end if;
 1000     end if;
 1001 
 1002     secondStmt := prepare(secondDbConnection, "DROP TABLE " & state.tableName);
 1003     execute(secondStmt);
 1004 
 1005     if state.statement <> sqlStatement.value then
 1006       if succeeds(execute(state.statement)) then
 1007         state.okay := FALSE;
 1008         if state.details then
 1009           writeln(" *** Execute: Table dropped by other connection still does exist. (1)");
 1010         end if;
 1011       end if;
 1012     end if;
 1013   end func;
 1014 
 1015 
 1016 const proc: testTransactions (in database: testDb, in connectData: dbConnectData) is func
 1017   local
 1018     var testState: state is testState("testTable", "charField", FALSE);
 1019     var database: secondDbConnection is database.value;
 1020     var sqlStatement: secondStmt is sqlStatement.value;
 1021   begin
 1022     if state.details then
 1023       writeln("testTransactions");
 1024     end if;
 1025     if transactionLocks(dbConnectData.databaseKind) then
 1026       state.okay := FALSE;
 1027       if state.details then
 1028         writeln(" *** Transaction locks database or column.");
 1029       end if;
 1030     else
 1031       block
 1032         secondDbConnection := openDatabase(dbConnectData.driver,
 1033                                            dbConnectData.dbName,
 1034                                            dbConnectData.user,
 1035                                            dbConnectData.password);
 1036       exception
 1037         catch DATABASE_ERROR:
 1038           state.okay := FALSE;
 1039           if state.details then
 1040             writeln(" *** Cannot open database " <& dbConnectData.dbName <&
 1041                     " with driver " <& dbConnectData.driver);
 1042             writeln(" *** Database error: " <& errMessage(DATABASE_ERROR));
 1043           end if;
 1044         otherwise:
 1045           state.okay := FALSE;
 1046           if state.details then
 1047             writeln(" *** Cannot open database " <& dbConnectData.dbName <&
 1048                     " with driver " <& dbConnectData.driver);
 1049           end if;
 1050       end block;
 1051     end if;
 1052     if secondDbConnection <> database.value then
 1053       block
 1054         setAutoCommit(secondDbConnection, FALSE);
 1055         if getAutoCommit(secondDbConnection) then
 1056           state.okay := FALSE;
 1057           if state.details then
 1058             writeln(" *** AutoCommit is still on after switching it off.");
 1059           end if;
 1060         else
 1061           testWithoutAutoCommit(testDb, state, secondDbConnection);
 1062         end if;
 1063       exception
 1064         catch RANGE_ERROR:
 1065           state.okay := FALSE;
 1066           writeln(" *** RANGE_ERROR was raised");
 1067         catch FILE_ERROR:
 1068           state.okay := FALSE;
 1069           writeln(" *** FILE_ERROR was raised");
 1070         catch DATABASE_ERROR:
 1071           state.okay := FALSE;
 1072           writeln(" *** DATABASE_ERROR was raised");
 1073       end block;
 1074       close(secondDbConnection);
 1075       if not state.okay then
 1076         block
 1077           state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 1078           execute(state.statement);
 1079         exception
 1080           otherwise:
 1081             noop;
 1082         end block;
 1083       end if;
 1084     end if;
 1085 
 1086     if state.okay then
 1087       writeln("Database transactions work okay.");
 1088     else
 1089       writeln(" *** Database transactions do not work okay.");
 1090     end if;
 1091   end func;
 1092 
 1093 
 1094 const proc: testBooleanField (in database: testDb, in dbCategory: databaseKind) is func
 1095   local
 1096     var testState: state is testState("booleanTest", "booleanField", FALSE);
 1097     var array boolean: expect is 0 times FALSE;
 1098     var boolean: booleanColumn is FALSE;
 1099     var integer: integerColumn is 0;
 1100     var bigInteger: bigIntColumn is 0_;
 1101     var bigRational: bigRatColumn is 0_/1_;
 1102     var integer: row is 1;
 1103   begin
 1104     if state.details then
 1105       writeln("testBooleanField: " <& databaseKind);
 1106     end if;
 1107     block
 1108       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 1109                                  " (" & state.fieldName & " CHAR)");
 1110       execute(state.statement);
 1111       insert(testDb, state, "NULL", expect &:= FALSE);
 1112       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 1113                                  " (" & state.fieldName & ") VALUES (?)");
 1114       insert(state,  NULL,  expect &:= FALSE);
 1115 
 1116       insert(testDb, state,    "0", expect &:= FALSE);
 1117       insert(testDb, state,    "1", expect &:=  TRUE);
 1118 
 1119       insert(state, FALSE,  expect &:= FALSE);
 1120       insert(state,  TRUE,  expect &:=  TRUE);
 1121 
 1122       insert(state,     0,  expect &:= FALSE);
 1123       insert(state,     1,  expect &:=  TRUE);
 1124 
 1125       insert(state,     0_, expect &:= FALSE);
 1126       insert(state,     1_, expect &:=  TRUE);
 1127 
 1128       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 1129       execute(state.statement);
 1130       while fetch(state.statement) do
 1131         booleanColumn := column(state.statement, 1, boolean);
 1132         if booleanColumn <> expect[row] then
 1133           state.okay := FALSE;
 1134           if state.details then
 1135             writeln(" *** testBooleanField: Row: " <& row <&
 1136                     " Expected " <& expect[row] <& " found boolean " <& booleanColumn);
 1137           end if;
 1138         end if;
 1139         if row <= 2 and not isNull(state.statement, 1) then
 1140           state.okay := FALSE;
 1141           if state.details then
 1142             writeln(" *** testBooleanField: Row: " <& row <&
 1143                     " Expected NULL found boolean " <& booleanColumn);
 1144           end if;
 1145         end if;
 1146 (*
 1147         integerColumn := column(state.statement, 1, integer);
 1148         if integerColumn <> ord(expect[row]) then
 1149           state.okay := FALSE;
 1150           if state.details then
 1151             writeln(" *** testBooleanField: Row: " <& row <&
 1152                     " Expected " <& expect[row] <& " found integer " <& integerColumn);
 1153           end if;
 1154         end if;
 1155         if row <= 2 and not isNull(state.statement, 1) then
 1156           state.okay := FALSE;
 1157           if state.details then
 1158             writeln(" *** testBooleanField: Row: " <& row <&
 1159                     " Expected NULL found integer " <& integerColumn);
 1160           end if;
 1161         end if;
 1162         bigIntColumn := column(state.statement, 1, bigInteger);
 1163         if bigIntColumn <> bigInteger(ord(expect[row])) then
 1164           state.okay := FALSE;
 1165           if state.details then
 1166             writeln(" *** testBooleanField: Row: " <& row <&
 1167                     " Expected " <& expect[row] <& " found bigInteger " <& bigIntColumn);
 1168           end if;
 1169         end if;
 1170         if row <= 2 and not isNull(state.statement, 1) then
 1171           state.okay := FALSE;
 1172           if state.details then
 1173             writeln(" *** testBooleanField: Row: " <& row <&
 1174                     " Expected NULL found bigInteger " <& bigIntColumn);
 1175           end if;
 1176         end if;
 1177         bigRatColumn := column(state.statement, 1, bigRational);
 1178         if bigRatColumn <> bigRational(ord(expect[row])) then
 1179           state.okay := FALSE;
 1180           if state.details then
 1181             writeln(" *** testBooleanField: Row: " <& row <&
 1182                     " Expected " <& expect[row] <& " found bigRational " <& bigRatColumn);
 1183           end if;
 1184         end if;
 1185         if row <= 2 and not isNull(state.statement, 1) then
 1186           state.okay := FALSE;
 1187           if state.details then
 1188             writeln(" *** testBooleanField: Row: " <& row <&
 1189                     " Expected NULL found bigRational " <& bigRatColumn);
 1190           end if;
 1191         end if;
 1192 *)
 1193         if row > 2 and isNull(state.statement, 1) then
 1194           state.okay := FALSE;
 1195           if state.details then
 1196             writeln(" *** testBooleanField: Row: " <& row <&
 1197                     " Expected " <& expect[row] <& " found NULL");
 1198           end if;
 1199         end if;
 1200         incr(row);
 1201       end while;
 1202     exception
 1203       catch RANGE_ERROR:
 1204         state.okay := FALSE;
 1205         writeln(" *** RANGE_ERROR was raised");
 1206       catch FILE_ERROR:
 1207         state.okay := FALSE;
 1208         writeln(" *** FILE_ERROR was raised");
 1209       catch DATABASE_ERROR:
 1210         state.okay := FALSE;
 1211         writeln(" *** DATABASE_ERROR was raised");
 1212     end block;
 1213     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 1214     execute(state.statement);
 1215 
 1216     if state.okay then
 1217       writeln("Inserting and fetching booleanFields works okay.");
 1218     else
 1219       writeln(" *** Inserting and fetching booleanFields does not work okay.");
 1220     end if;
 1221   end func;
 1222 
 1223 
 1224 const proc: testInt8Field (in database: testDb, in dbCategory: databaseKind) is func
 1225   local
 1226     var testState: state is testState("int8Test", "int8Field", FALSE);
 1227     var array integer: expect is 0 times 0;
 1228     var integer: integerColumn is 0;
 1229     var bigInteger: bigIntColumn is 0_;
 1230     var bigRational: bigRatColumn is 0_/1_;
 1231     var float: floatColumn is 0.0;
 1232     var boolean: booleanColumn is FALSE;
 1233     var integer: row is 1;
 1234   begin
 1235     if state.details then
 1236       writeln("testInt8Field: " <& databaseKind);
 1237     end if;
 1238     block
 1239       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 1240                                  " (" & state.fieldName & " " & int8Type(databaseKind) & ")");
 1241       execute(state.statement);
 1242       insert(testDb, state, "NULL", expect &:= 0);
 1243       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 1244                                  " (" & state.fieldName & ") VALUES (?)");
 1245       insert(state, NULL,  expect &:=    0);
 1246 
 1247       insert(testDb, state,   "0", expect &:=   0);
 1248       insert(testDb, state,   "1", expect &:=   1);
 1249       insert(testDb, state, "127", expect &:= 127);
 1250       if maxInt8Value(databaseKind) = 255 then
 1251         insert(testDb, state,  "128", expect &:=  128);
 1252         insert(testDb, state,  "255", expect &:=  255);
 1253       else
 1254         insert(testDb, state,   "-1", expect &:=   -1);
 1255         insert(testDb, state, "-128", expect &:= -128);
 1256       end if;
 1257 
 1258       insert(state,   0, expect &:=   0);
 1259       insert(state,   1, expect &:=   1);
 1260       insert(state, 127, expect &:= 127);
 1261       if maxInt8Value(databaseKind) = 255 then
 1262         insert(state,  128, expect &:=  128);
 1263         insert(state,  255, expect &:=  255);
 1264         if int8Type(databaseKind) = "TINYINT" and withRangeCheck(databaseKind) then
 1265           insert(state, 256, expect &:= 256, RANGE_CHECK);
 1266           insert(state,  -1, expect &:=  -1, RANGE_CHECK);
 1267         end if;
 1268       else
 1269         insert(state,   -1, expect &:=   -1);
 1270         insert(state, -128, expect &:= -128);
 1271         if int8Type(databaseKind) = "TINYINT" and withRangeCheck(databaseKind) then
 1272           insert(state,  128, expect &:=  128, RANGE_CHECK);
 1273           insert(state, -129, expect &:= -129, RANGE_CHECK);
 1274         end if;
 1275       end if;
 1276 
 1277       insert(state,   0_, expect &:=   0);
 1278       insert(state,   1_, expect &:=   1);
 1279       insert(state, 127_, expect &:= 127);
 1280       if maxInt8Value(databaseKind) = 255 then
 1281         insert(state,  128_, expect &:=  128);
 1282         insert(state,  255_, expect &:=  255);
 1283         if int8Type(databaseKind) = "TINYINT" and withRangeCheck(databaseKind) then
 1284           insert(state, 256_, expect &:= 256, RANGE_CHECK);
 1285           insert(state,  -1_, expect &:=  -1, RANGE_CHECK);
 1286         end if;
 1287       else
 1288         insert(state,   -1_, expect &:=   -1);
 1289         insert(state, -128_, expect &:= -128);
 1290         if int8Type(databaseKind) = "TINYINT" and withRangeCheck(databaseKind) then
 1291           insert(state,  128_, expect &:=  128, RANGE_CHECK);
 1292           insert(state, -129_, expect &:= -129, RANGE_CHECK);
 1293         end if;
 1294       end if;
 1295 
 1296       insert(state, FALSE, expect &:= 0);
 1297       insert(state,  TRUE, expect &:= 1);
 1298 
 1299       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 1300       execute(state.statement);
 1301       while fetch(state.statement) do
 1302         integerColumn := column(state.statement, 1, integer);
 1303         if integerColumn <> expect[row] then
 1304           state.okay := FALSE;
 1305           if state.details then
 1306             writeln(" *** testInt8Field: Row: " <& row <&
 1307                     " Expected " <& expect[row] <& " found integer " <& integerColumn);
 1308           end if;
 1309         end if;
 1310         if row <= 2 and not isNull(state.statement, 1) then
 1311           state.okay := FALSE;
 1312           if state.details then
 1313             writeln(" *** testInt8Field: Row: " <& row <&
 1314                     " Expected NULL found integer " <& integerColumn);
 1315           end if;
 1316         end if;
 1317         bigIntColumn := column(state.statement, 1, bigInteger);
 1318         if bigIntColumn <> bigInteger(expect[row]) then
 1319           state.okay := FALSE;
 1320           if state.details then
 1321             writeln(" *** testInt8Field: Row: " <& row <&
 1322                     " Expected " <& expect[row] <& " found bigInteger " <& bigIntColumn);
 1323           end if;
 1324         end if;
 1325         if row <= 2 and not isNull(state.statement, 1) then
 1326           state.okay := FALSE;
 1327           if state.details then
 1328             writeln(" *** testInt8Field: Row: " <& row <&
 1329                     " Expected NULL found bigInteger " <& bigIntColumn);
 1330           end if;
 1331         end if;
 1332         bigRatColumn := column(state.statement, 1, bigRational);
 1333         if bigRatColumn <> bigRational(expect[row]) then
 1334           state.okay := FALSE;
 1335           if state.details then
 1336             writeln(" *** testInt8Field: Row: " <& row <&
 1337                     " Expected " <& expect[row] <& " found bigRational " <& bigRatColumn);
 1338           end if;
 1339         end if;
 1340         if row <= 2 and not isNull(state.statement, 1) then
 1341           state.okay := FALSE;
 1342           if state.details then
 1343             writeln(" *** testInt8Field: Row: " <& row <&
 1344                     " Expected NULL found bigRational " <& bigRatColumn);
 1345           end if;
 1346         end if;
 1347         floatColumn := column(state.statement, 1, float);
 1348         if floatColumn <> float(expect[row]) then
 1349           state.okay := FALSE;
 1350           if state.details then
 1351             writeln(" *** testInt8Field: Row: " <& row <&
 1352                     " Expected " <& expect[row] <& " found float " <& floatColumn);
 1353           end if;
 1354         end if;
 1355         if row <= 2 and not isNull(state.statement, 1) then
 1356           state.okay := FALSE;
 1357           if state.details then
 1358             writeln(" *** testInt8Field: Row: " <& row <&
 1359                     " Expected NULL found float " <& floatColumn);
 1360           end if;
 1361         end if;
 1362         if row > 2 and isNull(state.statement, 1) then
 1363           state.okay := FALSE;
 1364           if state.details then
 1365             writeln(" *** testInt8Field: Row: " <& row <&
 1366                     " Expected " <& expect[row] <& " found NULL");
 1367           end if;
 1368         end if;
 1369         if expect[row] in {0, 1} then
 1370           booleanColumn := column(state.statement, 1, boolean);
 1371           if booleanColumn <> boolean(expect[row]) then
 1372             state.okay := FALSE;
 1373             if state.details then
 1374               writeln(" *** testInt8Field: Row: " <& row <&
 1375                       " Expected " <& expect[row] <& " found boolean " <& booleanColumn);
 1376             end if;
 1377           end if;
 1378           if row <= 2 and not isNull(state.statement, 1) then
 1379             state.okay := FALSE;
 1380             if state.details then
 1381               writeln(" *** testInt8Field: Row: " <& row <&
 1382                       " Expected NULL found boolean " <& booleanColumn);
 1383             end if;
 1384           end if;
 1385         end if;
 1386         incr(row);
 1387       end while;
 1388     exception
 1389       catch RANGE_ERROR:
 1390         state.okay := FALSE;
 1391         writeln(" *** RANGE_ERROR was raised");
 1392       catch FILE_ERROR:
 1393         state.okay := FALSE;
 1394         writeln(" *** FILE_ERROR was raised");
 1395       catch DATABASE_ERROR:
 1396         state.okay := FALSE;
 1397         writeln(" *** DATABASE_ERROR was raised");
 1398     end block;
 1399     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 1400     execute(state.statement);
 1401 
 1402     if state.okay then
 1403       writeln("Inserting and fetching int8Fields works okay.");
 1404     else
 1405       writeln(" *** Inserting and fetching int8Fields does not work okay.");
 1406     end if;
 1407   end func;
 1408 
 1409 
 1410 const proc: testInt16Field (in database: testDb, in dbCategory: databaseKind) is func
 1411   local
 1412     var testState: state is testState("int16Test", "int16Field", FALSE);
 1413     var array integer: expect is 0 times 0;
 1414     var integer: integerColumn is 0;
 1415     var bigInteger: bigIntColumn is 0_;
 1416     var bigRational: bigRatColumn is 0_/1_;
 1417     var float: floatColumn is 0.0;
 1418     var boolean: booleanColumn is FALSE;
 1419     var integer: row is 1;
 1420   begin
 1421     if state.details then
 1422       writeln("testInt16Field: " <& databaseKind);
 1423     end if;
 1424     block
 1425       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 1426                                  " (" & state.fieldName & " SMALLINT)");
 1427       execute(state.statement);
 1428       insert(testDb, state, "NULL", expect &:= 0);
 1429       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 1430                                  " (" & state.fieldName & ") VALUES (?)");
 1431       insert(state, NULL, expect &:= 0);
 1432 
 1433       insert(testDb, state,      "0", expect &:=      0);
 1434       insert(testDb, state,      "1", expect &:=      1);
 1435       insert(testDb, state,  "32767", expect &:=  32767);
 1436       insert(testDb, state,     "-1", expect &:=     -1);
 1437       insert(testDb, state, "-32768", expect &:= -32768);
 1438 
 1439       insert(state,      0, expect &:=      0);
 1440       insert(state,      1, expect &:=      1);
 1441       insert(state,  32767, expect &:=  32767);
 1442       insert(state,     -1, expect &:=     -1);
 1443       insert(state, -32768, expect &:= -32768);
 1444       if withRangeCheck(databaseKind) then
 1445         insert(state,  32768, expect &:=  32768, RANGE_CHECK);
 1446         insert(state, -32769, expect &:= -32769, RANGE_CHECK);
 1447       end if;
 1448 
 1449       insert(state,      0_, expect &:=      0);
 1450       insert(state,      1_, expect &:=      1);
 1451       insert(state,  32767_, expect &:=  32767);
 1452       insert(state,     -1_, expect &:=     -1);
 1453       insert(state, -32768_, expect &:= -32768);
 1454       if withRangeCheck(databaseKind) then
 1455         insert(state,  32768_, expect &:=  32768, RANGE_CHECK);
 1456         insert(state, -32769_, expect &:=  32769, RANGE_CHECK);
 1457       end if;
 1458 
 1459       insert(state, FALSE, expect &:= 0);
 1460       insert(state,  TRUE, expect &:= 1);
 1461 
 1462       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 1463       execute(state.statement);
 1464       while fetch(state.statement) do
 1465         integerColumn := column(state.statement, 1, integer);
 1466         if integerColumn <> expect[row] then
 1467           state.okay := FALSE;
 1468           if state.details then
 1469             writeln(" *** testInt16Field: Row: " <& row <&
 1470                     " Expected " <& expect[row] <& " found integer " <& integerColumn);
 1471           end if;
 1472         end if;
 1473         if row <= 2 and not isNull(state.statement, 1) then
 1474           state.okay := FALSE;
 1475           if state.details then
 1476             writeln(" *** testInt16Field: Row: " <& row <&
 1477                     " Expected NULL found integer " <& integerColumn);
 1478           end if;
 1479         end if;
 1480         bigIntColumn := column(state.statement, 1, bigInteger);
 1481         if bigIntColumn <> bigInteger(expect[row]) then
 1482           state.okay := FALSE;
 1483           if state.details then
 1484             writeln(" *** testInt16Field: Row: " <& row <&
 1485                     " Expected " <& expect[row] <& " found bigInteger " <& bigIntColumn);
 1486           end if;
 1487         end if;
 1488         if row <= 2 and not isNull(state.statement, 1) then
 1489           state.okay := FALSE;
 1490           if state.details then
 1491             writeln(" *** testInt16Field: Row: " <& row <&
 1492                     " Expected NULL found bigInteger " <& bigIntColumn);
 1493           end if;
 1494         end if;
 1495         bigRatColumn := column(state.statement, 1, bigRational);
 1496         if bigRatColumn <> bigRational(expect[row]) then
 1497           state.okay := FALSE;
 1498           if state.details then
 1499             writeln(" *** testInt16Field: Row: " <& row <&
 1500                     " Expected " <& expect[row] <& " found bigRational " <& bigRatColumn);
 1501           end if;
 1502         end if;
 1503         if row <= 2 and not isNull(state.statement, 1) then
 1504           state.okay := FALSE;
 1505           if state.details then
 1506             writeln(" *** testInt16Field: Row: " <& row <&
 1507                     " Expected NULL found bigRational " <& bigRatColumn);
 1508           end if;
 1509         end if;
 1510         floatColumn := column(state.statement, 1, float);
 1511         if floatColumn <> float(expect[row]) then
 1512           state.okay := FALSE;
 1513           if state.details then
 1514             writeln(" *** testInt16Field: Row: " <& row <&
 1515                     " Expected " <& expect[row] <& " found float " <& floatColumn);
 1516           end if;
 1517         end if;
 1518         if row <= 2 and not isNull(state.statement, 1) then
 1519           state.okay := FALSE;
 1520           if state.details then
 1521             writeln(" *** testInt16Field: Row: " <& row <&
 1522                     " Expected NULL found float " <& floatColumn);
 1523           end if;
 1524         end if;
 1525         if row > 2 and isNull(state.statement, 1) then
 1526           state.okay := FALSE;
 1527           if state.details then
 1528             writeln(" *** testInt16Field: Row: " <& row <&
 1529                     " Expected " <& expect[row] <& " found NULL");
 1530           end if;
 1531         end if;
 1532         if expect[row] in {0, 1} then
 1533           booleanColumn := column(state.statement, 1, boolean);
 1534           if booleanColumn <> boolean(expect[row]) then
 1535             state.okay := FALSE;
 1536             if state.details then
 1537               writeln(" *** testInt16Field: Row: " <& row <&
 1538                       " Expected " <& expect[row] <& " found boolean " <& booleanColumn);
 1539             end if;
 1540           end if;
 1541           if row <= 2 and not isNull(state.statement, 1) then
 1542             state.okay := FALSE;
 1543             if state.details then
 1544               writeln(" *** testInt16Field: Row: " <& row <&
 1545                       " Expected NULL found boolean " <& booleanColumn);
 1546             end if;
 1547           end if;
 1548         end if;
 1549         incr(row);
 1550       end while;
 1551     exception
 1552       catch RANGE_ERROR:
 1553         state.okay := FALSE;
 1554         writeln(" *** RANGE_ERROR was raised");
 1555       catch FILE_ERROR:
 1556         state.okay := FALSE;
 1557         writeln(" *** FILE_ERROR was raised");
 1558       catch DATABASE_ERROR:
 1559         state.okay := FALSE;
 1560         writeln(" *** DATABASE_ERROR was raised");
 1561     end block;
 1562     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 1563     execute(state.statement);
 1564 
 1565     if state.okay then
 1566       writeln("Inserting and fetching int16Fields works okay.");
 1567     else
 1568       writeln(" *** Inserting and fetching int16Fields does not work okay.");
 1569     end if;
 1570   end func;
 1571 
 1572 
 1573 const proc: testInt32Field (in database: testDb, in dbCategory: databaseKind) is func
 1574   local
 1575     var testState: state is testState("int32Test", "int32Field", FALSE);
 1576     var array integer: expect is 0 times 0;
 1577     var integer: integerColumn is 0;
 1578     var bigInteger: bigIntColumn is 0_;
 1579     var bigRational: bigRatColumn is 0_/1_;
 1580     var float: floatColumn is 0.0;
 1581     var boolean: booleanColumn is FALSE;
 1582     var integer: row is 1;
 1583   begin
 1584     if state.details then
 1585       writeln("testInt32Field: " <& databaseKind);
 1586     end if;
 1587     block
 1588       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 1589                                  " (" & state.fieldName & " INTEGER)");
 1590       execute(state.statement);
 1591       insert(testDb, state, "NULL", expect &:= 0);
 1592       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 1593                                  " (" & state.fieldName & ") VALUES (?)");
 1594       insert(state, NULL, expect &:= 0);
 1595 
 1596       insert(testDb, state,           "0", expect &:=           0);
 1597       insert(testDb, state,           "1", expect &:=           1);
 1598       insert(testDb, state,  "2147483647", expect &:=  2147483647);
 1599       insert(testDb, state,          "-1", expect &:=          -1);
 1600       insert(testDb, state, "-2147483648", expect &:= -2147483648);
 1601 
 1602       insert(state,           0, expect &:=           0);
 1603       insert(state,           1, expect &:=           1);
 1604       insert(state,     1048578, expect &:=     1048578); # Zero bytes in binary representation.
 1605       insert(state,  2147483647, expect &:=  2147483647);
 1606       insert(state,          -1, expect &:=          -1);
 1607       insert(state, -2147483648, expect &:= -2147483648);
 1608       if withRangeCheck(databaseKind) then
 1609         insert(state,  2147483648, expect &:=  2147483648, RANGE_CHECK);
 1610         insert(state, -2147483649, expect &:= -2147483649, RANGE_CHECK);
 1611       end if;
 1612 
 1613       insert(state,           0_, expect &:=           0);
 1614       insert(state,           1_, expect &:=           1);
 1615       insert(state,     1048578_, expect &:=     1048578); # Zero bytes in binary representation.
 1616       insert(state,  2147483647_, expect &:=  2147483647);
 1617       insert(state,          -1_, expect &:=          -1);
 1618       insert(state, -2147483648_, expect &:= -2147483648);
 1619       if withRangeCheck(databaseKind) then
 1620         insert(state,  2147483648_, expect &:=  2147483648, RANGE_CHECK);
 1621         insert(state, -2147483649_, expect &:= -2147483649, RANGE_CHECK);
 1622       end if;
 1623 
 1624       insert(state, FALSE, expect &:= 0);
 1625       insert(state,  TRUE, expect &:= 1);
 1626 
 1627       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 1628       execute(state.statement);
 1629       while fetch(state.statement) do
 1630         integerColumn := column(state.statement, 1, integer);
 1631         if integerColumn <> expect[row] then
 1632           state.okay := FALSE;
 1633           if state.details then
 1634             writeln(" *** testInt32Field: Row: " <& row <&
 1635                     " Expected " <& expect[row] <& " found integer " <& integerColumn);
 1636           end if;
 1637         end if;
 1638         if row <= 2 and not isNull(state.statement, 1) then
 1639           state.okay := FALSE;
 1640           if state.details then
 1641             writeln(" *** testInt32Field: Row: " <& row <&
 1642                     " Expected NULL found integer " <& integerColumn);
 1643           end if;
 1644         end if;
 1645         bigIntColumn := column(state.statement, 1, bigInteger);
 1646         if bigIntColumn <> bigInteger(expect[row]) then
 1647           state.okay := FALSE;
 1648           if state.details then
 1649             writeln(" *** testInt32Field: Row: " <& row <&
 1650                     " Expected " <& expect[row] <& " found bigInteger " <& bigIntColumn);
 1651           end if;
 1652         end if;
 1653         if row <= 2 and not isNull(state.statement, 1) then
 1654           state.okay := FALSE;
 1655           if state.details then
 1656             writeln(" *** testInt32Field: Row: " <& row <&
 1657                     " Expected NULL found bigInteger " <& bigIntColumn);
 1658           end if;
 1659         end if;
 1660         bigRatColumn := column(state.statement, 1, bigRational);
 1661         if bigRatColumn <> bigRational(expect[row]) then
 1662           state.okay := FALSE;
 1663           if state.details then
 1664             writeln(" *** testInt32Field: Row: " <& row <&
 1665                     " Expected " <& expect[row] <& " found bigRational " <& bigRatColumn);
 1666           end if;
 1667         end if;
 1668         if row <= 2 and not isNull(state.statement, 1) then
 1669           state.okay := FALSE;
 1670           if state.details then
 1671             writeln(" *** testInt32Field: Row: " <& row <&
 1672                     " Expected NULL found bigRational " <& bigRatColumn);
 1673           end if;
 1674         end if;
 1675         floatColumn := column(state.statement, 1, float);
 1676         if floatColumn <> float(expect[row]) then
 1677           state.okay := FALSE;
 1678           if state.details then
 1679             writeln(" *** testInt32Field: Row: " <& row <&
 1680                     " Expected " <& expect[row] <& " found float " <& floatColumn);
 1681           end if;
 1682         end if;
 1683         if row <= 2 and not isNull(state.statement, 1) then
 1684           state.okay := FALSE;
 1685           if state.details then
 1686             writeln(" *** testInt32Field: Row: " <& row <&
 1687                     " Expected NULL found float " <& floatColumn);
 1688           end if;
 1689         end if;
 1690         if row > 2 and isNull(state.statement, 1) then
 1691           state.okay := FALSE;
 1692           if state.details then
 1693             writeln(" *** testInt32Field: Row: " <& row <&
 1694                     " Expected " <& expect[row] <& " found NULL");
 1695           end if;
 1696         end if;
 1697         if expect[row] in {0, 1} then
 1698           booleanColumn := column(state.statement, 1, boolean);
 1699           if booleanColumn <> boolean(expect[row]) then
 1700             state.okay := FALSE;
 1701             if state.details then
 1702               writeln(" *** testInt32Field: Row: " <& row <&
 1703                       " Expected " <& expect[row] <& " found boolean " <& booleanColumn);
 1704             end if;
 1705           end if;
 1706           if row <= 2 and not isNull(state.statement, 1) then
 1707             state.okay := FALSE;
 1708             if state.details then
 1709               writeln(" *** testInt32Field: Row: " <& row <&
 1710                       " Expected NULL found boolean " <& booleanColumn);
 1711             end if;
 1712           end if;
 1713         end if;
 1714         incr(row);
 1715       end while;
 1716     exception
 1717       catch RANGE_ERROR:
 1718         state.okay := FALSE;
 1719         writeln(" *** RANGE_ERROR was raised");
 1720       catch FILE_ERROR:
 1721         state.okay := FALSE;
 1722         writeln(" *** FILE_ERROR was raised");
 1723       catch DATABASE_ERROR:
 1724         state.okay := FALSE;
 1725         writeln(" *** DATABASE_ERROR was raised");
 1726     end block;
 1727     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 1728     execute(state.statement);
 1729 
 1730     if state.okay then
 1731       writeln("Inserting and fetching int32Fields works okay.");
 1732     else
 1733       writeln(" *** Inserting and fetching int32Fields does not work okay.");
 1734     end if;
 1735   end func;
 1736 
 1737 
 1738 const proc: testInt64Field (in database: testDb, in dbCategory: databaseKind) is func
 1739   local
 1740     var testState: state is testState("int64Test", "int64Field", FALSE);
 1741     var array integer: expect is 0 times 0;
 1742     var integer: integerColumn is 0;
 1743     var bigInteger: bigIntColumn is 0_;
 1744     var bigRational: bigRatColumn is 0_/1_;
 1745     var float: floatColumn is 0.0;
 1746     var string: floatAsString is "";
 1747     var boolean: booleanColumn is FALSE;
 1748     var integer: row is 1;
 1749   begin
 1750     if state.details then
 1751       writeln("testInt64Field: " <& databaseKind);
 1752     end if;
 1753     block
 1754       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 1755                                  " (" & state.fieldName & " " & int64Type(databaseKind) & ")");
 1756       execute(state.statement);
 1757       insert(testDb, state, "NULL", expect &:= 0);
 1758       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 1759                                  " (" & state.fieldName & ") VALUES (?)");
 1760       insert(state, NULL, expect &:= 0);
 1761 
 1762       insert(testDb, state,                    "0", expect &:=                         0);
 1763       insert(testDb, state,                    "1", expect &:=                         1);
 1764       insert(testDb, state,             "16777215", expect &:=                  16777215); # Maximum odd float
 1765       insert(testDb, state,             "16777216", expect &:=                  16777216);
 1766       insert(testDb, state,             "16777217", expect &:=                  16777217);
 1767       insert(testDb, state,     "9007199254740991", expect &:=          9007199254740991); # Maximum odd double
 1768       insert(testDb, state,     "9007199254740992", expect &:=          9007199254740992);
 1769       insert(testDb, state,     "9007199254740993", expect &:=          9007199254740993);
 1770       insert(testDb, state,  "9223372036854775807", expect &:=       9223372036854775807);
 1771       insert(testDb, state,                   "-1", expect &:=                        -1);
 1772       insert(testDb, state,            "-16777215", expect &:=                 -16777215); # Minimum odd float
 1773       insert(testDb, state,            "-16777216", expect &:=                 -16777216);
 1774       insert(testDb, state,            "-16777217", expect &:=                 -16777217);
 1775       insert(testDb, state,    "-9007199254740991", expect &:=         -9007199254740991); # Minimum odd double
 1776       insert(testDb, state,    "-9007199254740992", expect &:=         -9007199254740992);
 1777       insert(testDb, state,    "-9007199254740993", expect &:=         -9007199254740993);
 1778       insert(testDb, state, "-9223372036854775808", expect &:= pred(-9223372036854775807));
 1779 
 1780       insert(state,                         0,  expect &:=                         0);
 1781       insert(state,                         1,  expect &:=                         1);
 1782       insert(state,                  16777215,  expect &:=                  16777215); # Maximum odd float
 1783       insert(state,                  16777216,  expect &:=                  16777216);
 1784       insert(state,                  16777217,  expect &:=                  16777217);
 1785       insert(state,                4297064452,  expect &:=                4297064452); # Zero bytes in binary representation.
 1786       insert(state,          9007199254740991,  expect &:=          9007199254740991); # Maximum odd double
 1787       insert(state,          9007199254740992,  expect &:=          9007199254740992);
 1788       insert(state,          9007199254740993,  expect &:=          9007199254740993);
 1789       insert(state,       9223372036854775807,  expect &:=       9223372036854775807);
 1790       insert(state,                        -1,  expect &:=                        -1);
 1791       insert(state,                 -16777215,  expect &:=                 -16777215); # Maximum odd float
 1792       insert(state,                 -16777216,  expect &:=                 -16777216);
 1793       insert(state,                 -16777217,  expect &:=                 -16777217);
 1794       insert(state,         -9007199254740991,  expect &:=         -9007199254740991); # Maximum odd double
 1795       insert(state,         -9007199254740992,  expect &:=         -9007199254740992);
 1796       insert(state,         -9007199254740993,  expect &:=         -9007199254740993);
 1797       insert(state, pred(-9223372036854775807), expect &:= pred(-9223372036854775807));
 1798 
 1799       insert(state,                    0_, expect &:=                         0);
 1800       insert(state,                    1_, expect &:=                         1);
 1801       insert(state,             16777215_, expect &:=                  16777215); # Maximum odd float
 1802       insert(state,             16777216_, expect &:=                  16777216);
 1803       insert(state,             16777217_, expect &:=                  16777217);
 1804       insert(state,           4297064452_, expect &:=                4297064452); # Zero bytes in binary representation.
 1805       insert(state,     9007199254740991_, expect &:=          9007199254740991); # Maximum odd double
 1806       insert(state,     9007199254740992_, expect &:=          9007199254740992);
 1807       insert(state,     9007199254740993_, expect &:=          9007199254740993);
 1808       insert(state,  9223372036854775807_, expect &:=       9223372036854775807);
 1809       insert(state,                   -1_, expect &:=                        -1);
 1810       insert(state,            -16777215_, expect &:=                 -16777215); # Maximum odd float
 1811       insert(state,            -16777216_, expect &:=                 -16777216);
 1812       insert(state,            -16777217_, expect &:=                 -16777217);
 1813       insert(state,    -9007199254740991_, expect &:=         -9007199254740991); # Maximum odd double
 1814       insert(state,    -9007199254740992_, expect &:=         -9007199254740992);
 1815       insert(state,    -9007199254740993_, expect &:=         -9007199254740993);
 1816       insert(state, -9223372036854775808_, expect &:= pred(-9223372036854775807));
 1817       if withRangeCheck(databaseKind) then
 1818         insert(state,  9223372036854775808_, expect &:= 0, RANGE_CHECK); # No valid value to expect.
 1819         insert(state, -9223372036854775809_, expect &:= 0, RANGE_CHECK); # No valid value to expect.
 1820       end if;
 1821 
 1822       insert(state, FALSE, expect &:= 0);
 1823       insert(state,  TRUE, expect &:= 1);
 1824 
 1825       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 1826       execute(state.statement);
 1827       while fetch(state.statement) do
 1828         integerColumn := column(state.statement, 1, integer);
 1829         if integerColumn <> expect[row] then
 1830           state.okay := FALSE;
 1831           if state.details then
 1832             writeln(" *** testInt64Field: Row: " <& row <&
 1833                     " Expected " <& expect[row] <& " found integer " <& integerColumn);
 1834           end if;
 1835         end if;
 1836         if row <= 2 and not isNull(state.statement, 1) then
 1837           state.okay := FALSE;
 1838           if state.details then
 1839             writeln(" *** testInt64Field: Row: " <& row <&
 1840                     " Expected NULL found integer " <& integerColumn);
 1841           end if;
 1842         end if;
 1843         bigIntColumn := column(state.statement, 1, bigInteger);
 1844         if bigIntColumn <> bigInteger(expect[row]) then
 1845           state.okay := FALSE;
 1846           if state.details then
 1847             writeln(" *** testInt64Field: Row: " <& row <&
 1848                     " Expected " <& expect[row] <& " found bigInteger " <& bigIntColumn);
 1849           end if;
 1850         end if;
 1851         if row <= 2 and not isNull(state.statement, 1) then
 1852           state.okay := FALSE;
 1853           if state.details then
 1854             writeln(" *** testInt64Field: Row: " <& row <&
 1855                     " Expected NULL found bigInteger " <& bigIntColumn);
 1856           end if;
 1857         end if;
 1858         bigRatColumn := column(state.statement, 1, bigRational);
 1859         if bigRatColumn <> bigRational(expect[row]) then
 1860           state.okay := FALSE;
 1861           if state.details then
 1862             writeln(" *** testInt64Field: Row: " <& row <&
 1863                     " Expected " <& expect[row] <& " found " <& bigRatColumn);
 1864           end if;
 1865         end if;
 1866         if row <= 2 and not isNull(state.statement, 1) then
 1867           state.okay := FALSE;
 1868           if state.details then
 1869             writeln(" *** testInt64Field: Row: " <& row <&
 1870                     " Expected NULL found bigRational " <& bigRatColumn);
 1871           end if;
 1872         end if;
 1873         floatAsString := str(float(str(expect[row])));
 1874         if endsWith(floatAsString, ".0") and
 1875             str(expect[row]) = floatAsString[.. length(floatAsString) - 2] then
 1876           # The expected value is representable as float.
 1877           floatColumn := column(state.statement, 1, float);
 1878           if floatColumn <> float(str(expect[row])) then
 1879             state.okay := FALSE;
 1880             if state.details then
 1881               writeln(" *** testInt64Field 2: Row: " <& row <&
 1882                       " Expected " <& expect[row] <& " found float " <& floatColumn);
 1883             end if;
 1884           end if;
 1885           if row <= 2 and not isNull(state.statement, 1) then
 1886             state.okay := FALSE;
 1887             if state.details then
 1888               writeln(" *** testInt64Field: Row: " <& row <&
 1889                       " Expected NULL found float " <& floatColumn);
 1890             end if;
 1891           end if;
 1892         end if;
 1893         if row > 2 and isNull(state.statement, 1) then
 1894           state.okay := FALSE;
 1895           if state.details then
 1896             writeln(" *** testInt64Field: Row: " <& row <&
 1897                     " Expected " <& expect[row] <& " found NULL");
 1898           end if;
 1899         end if;
 1900         if expect[row] in {0, 1} then
 1901           booleanColumn := column(state.statement, 1, boolean);
 1902           if booleanColumn <> boolean(expect[row]) then
 1903             state.okay := FALSE;
 1904             if state.details then
 1905               writeln(" *** testInt64Field: Row: " <& row <&
 1906                       " Expected " <& expect[row] <& " found boolean " <& booleanColumn);
 1907             end if;
 1908           end if;
 1909           if row <= 2 and not isNull(state.statement, 1) then
 1910             state.okay := FALSE;
 1911             if state.details then
 1912               writeln(" *** testInt64Field: Row: " <& row <&
 1913                       " Expected NULL found boolean " <& booleanColumn);
 1914             end if;
 1915           end if;
 1916         end if;
 1917         incr(row);
 1918       end while;
 1919     exception
 1920       catch RANGE_ERROR:
 1921         state.okay := FALSE;
 1922         writeln(" *** RANGE_ERROR was raised");
 1923       catch FILE_ERROR:
 1924         state.okay := FALSE;
 1925         writeln(" *** FILE_ERROR was raised");
 1926       catch DATABASE_ERROR:
 1927         state.okay := FALSE;
 1928         writeln(" *** DATABASE_ERROR was raised");
 1929     end block;
 1930     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 1931     execute(state.statement);
 1932 
 1933     if state.okay then
 1934       writeln("Inserting and fetching int64Fields works okay.");
 1935     else
 1936       writeln(" *** Inserting and fetching int64Fields does not work okay.");
 1937     end if;
 1938   end func;
 1939 
 1940 
 1941 const proc: testBigIntField (in database: testDb, in dbCategory: databaseKind) is func
 1942   local
 1943     var testState: state is testState("bigIntTest", "bigIntField", FALSE);
 1944     var array bigInteger: expect is 0 times 0_;
 1945     var sqlStatement: statement is sqlStatement.value;
 1946     var bigInteger: bigIntColumn is 0_;
 1947     var integer: row is 1;
 1948   begin
 1949     if state.details then
 1950       writeln("testBigIntField: " <& databaseKind);
 1951     end if;
 1952     block
 1953       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 1954                                  " (" & state.fieldName & " " & bigIntType(databaseKind) & ")");
 1955       execute(state.statement);
 1956       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 1957                                  " (" & state.fieldName & ") VALUES (?)");
 1958       insert(state,                      NULL,  expect &:=                    0_);
 1959       insert(state,                         1,  expect &:=                    1_);
 1960       insert(state,                         2,  expect &:=                    2_);
 1961       insert(state,       -999999999999999999,  expect &:=  -999999999999999999_);
 1962       insert(state,        999999999999999999,  expect &:=   999999999999999999_);
 1963       insert(state,      -1000000000000000000,  expect &:= -1000000000000000000_);
 1964       insert(state,       1000000000000000000,  expect &:=  1000000000000000000_);
 1965       insert(state,      -1234567890123456789,  expect &:= -1234567890123456789_);
 1966       insert(state,       1234567890123456789,  expect &:=  1234567890123456789_);
 1967       insert(state, pred(-9223372036854775807), expect &:= -9223372036854775808_);
 1968       insert(state,       9223372036854775807,  expect &:=  9223372036854775807_);
 1969 
 1970       insert(state,                    1_, expect &:=                    1_);
 1971       insert(state,                    2_, expect &:=                    2_);
 1972       insert(state,  -999999999999999999_, expect &:=  -999999999999999999_);
 1973       insert(state,   999999999999999999_, expect &:=   999999999999999999_);
 1974       insert(state, -1000000000000000000_, expect &:= -1000000000000000000_);
 1975       insert(state,  1000000000000000000_, expect &:=  1000000000000000000_);
 1976       insert(state, -1234567890123456789_, expect &:= -1234567890123456789_);
 1977       insert(state,  1234567890123456789_, expect &:=  1234567890123456789_);
 1978       insert(state, -9223372036854775808_, expect &:= -9223372036854775808_);
 1979       insert(state,  9223372036854775807_, expect &:=  9223372036854775807_);
 1980       if bigIntTypeBits(databaseKind) >= 127 then
 1981         insert(state,  -9223372036854775809_, expect &:=  -9223372036854775809_);
 1982         insert(state,   9223372036854775808_, expect &:=   9223372036854775808_);
 1983         insert(state,  -9999999999999999999_, expect &:=  -9999999999999999999_);
 1984         insert(state,   9999999999999999999_, expect &:=   9999999999999999999_);
 1985         insert(state, -10000000000000000000_, expect &:= -10000000000000000000_);
 1986         insert(state,  10000000000000000000_, expect &:=  10000000000000000000_);
 1987         insert(state,  -9999999999999999999999999999999999999_, expect &:=  -9999999999999999999999999999999999999_);
 1988         insert(state,   9999999999999999999999999999999999999_, expect &:=   9999999999999999999999999999999999999_);
 1989         insert(state, -10000000000000000000000000000000000000_, expect &:= -10000000000000000000000000000000000000_);
 1990         insert(state,  10000000000000000000000000000000000000_, expect &:=  10000000000000000000000000000000000000_);
 1991         insert(state, -85070591730234615865843651857942052864_, expect &:= -85070591730234615865843651857942052864_);
 1992         insert(state,  85070591730234615865843651857942052863_, expect &:=  85070591730234615865843651857942052863_);
 1993       end if;
 1994       if bigIntTypeBits(databaseKind) >= 216 then
 1995         insert(state,   -85070591730234615865843651857942052864_, expect &:=   -85070591730234615865843651857942052864_);
 1996         insert(state,    85070591730234615865843651857942052863_, expect &:=    85070591730234615865843651857942052863_);
 1997         insert(state,   -99999999999999999999999999999999999999_, expect &:=   -99999999999999999999999999999999999999_);
 1998         insert(state,    99999999999999999999999999999999999999_, expect &:=    99999999999999999999999999999999999999_);
 1999         insert(state,  -100000000000000000000000000000000000000_, expect &:=  -100000000000000000000000000000000000000_);
 2000         insert(state,   100000000000000000000000000000000000000_, expect &:=   100000000000000000000000000000000000000_);
 2001         insert(state,  -170141183460469231731687303715884105728_, expect &:=  -170141183460469231731687303715884105728_);
 2002         insert(state,   170141183460469231731687303715884105727_, expect &:=   170141183460469231731687303715884105727_);
 2003         insert(state,  -340282366920938463463374607431768211455_, expect &:=  -340282366920938463463374607431768211455_);
 2004         insert(state,   340282366920938463463374607431768211455_, expect &:=   340282366920938463463374607431768211455_);
 2005         insert(state, -1000000000000000000000000000000000000000_, expect &:= -1000000000000000000000000000000000000000_);
 2006         insert(state,  1000000000000000000000000000000000000000_, expect &:=  1000000000000000000000000000000000000000_);
 2007       end if;
 2008 
 2009       insert(state, FALSE, expect &:= 0_);
 2010       insert(state,  TRUE, expect &:= 1_);
 2011 
 2012       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 2013       execute(state.statement);
 2014       while fetch(state.statement) do
 2015         bigIntColumn := column(state.statement, 1, bigInteger);
 2016         if bigIntColumn <> expect[row] then
 2017           state.okay := FALSE;
 2018           if state.details then
 2019             writeln(" *** testBigIntField: Row: " <& row <&
 2020                     " Expected " <& expect[row] <& " found bigInteger " <& bigIntColumn);
 2021           end if;
 2022         end if;
 2023         if row = 1 and not isNull(state.statement, 1) then
 2024           state.okay := FALSE;
 2025           if state.details then
 2026             writeln(" *** testBigIntField: Row: " <& row <&
 2027                     " Expected NULL found bigInteger " <& bigIntColumn);
 2028           end if;
 2029         end if;
 2030         if row > 1 and isNull(state.statement, 1) then
 2031           state.okay := FALSE;
 2032           if state.details then
 2033             writeln(" *** testBigIntField: Row: " <& row <&
 2034                     " Expected " <& expect[row] <& " found NULL");
 2035           end if;
 2036         end if;
 2037         incr(row);
 2038       end while;
 2039     exception
 2040       catch RANGE_ERROR:
 2041         state.okay := FALSE;
 2042         writeln(" *** RANGE_ERROR was raised");
 2043       catch FILE_ERROR:
 2044         state.okay := FALSE;
 2045         writeln(" *** FILE_ERROR was raised");
 2046       catch DATABASE_ERROR:
 2047         state.okay := FALSE;
 2048         writeln(" *** DATABASE_ERROR was raised");
 2049     end block;
 2050     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 2051     execute(state.statement);
 2052 
 2053     if state.okay then
 2054       writeln("Inserting and fetching bigInteger fields works okay.");
 2055     else
 2056       writeln(" *** Inserting and fetching bigInteger fields does not work okay.");
 2057     end if;
 2058   end func;
 2059 
 2060 
 2061 const proc: testFloatField (in database: testDb, in dbCategory: databaseKind) is func
 2062   local
 2063     var testState: state is testState("floatTest", "floatField", FALSE);
 2064     var array float: expect is 0 times 0.0;
 2065     var float: floatColumn is 0.0;
 2066     var boolean: isEqual is FALSE;
 2067     var integer: row is 1;
 2068   begin
 2069     if state.details then
 2070       writeln("testFloatField: " <& databaseKind);
 2071     end if;
 2072     block
 2073       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 2074                                  " (" & state.fieldName & " " & floatType(databaseKind) & ")");
 2075       execute(state.statement);
 2076       insert(testDb, state, "NULL", expect &:= 0.0);
 2077       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2078                                  " (" & state.fieldName & ") VALUES (?)");
 2079       insert(state, NULL, expect &:= 0.0);
 2080 
 2081       insert(testDb, state,            "-16777215",     expect &:=            -16777215.0);
 2082       insert(testDb, state,                   "-1",     expect &:=                   -1.0);
 2083       insert(testDb, state,                    "0",     expect &:=                    0.0);
 2084       insert(testDb, state,                    "1",     expect &:=                    1.0);
 2085       insert(testDb, state,             "16777215",     expect &:=             16777215.0);
 2086 
 2087       insert(testDb, state, "-9223372036854775809.0",   expect &:= -9223372036854775809.0);
 2088       insert(testDb, state, "-9223372036854775808.0",   expect &:= -9223372036854775808.0);
 2089       insert(testDb, state,    "0.0",                   expect &:=    0.0);
 2090       insert(testDb, state,    "5.9604644775390625e-8", expect &:=    5.9604644775390625e-8);
 2091       insert(testDb, state,    "2.384185791015625e-7",  expect &:=    2.384185791015625e-7);
 2092       insert(testDb, state,    "4.76837158203125e-7",   expect &:=    4.76837158203125e-7);
 2093       insert(testDb, state,    "9.5367431640625e-7",    expect &:=    9.5367431640625e-7);
 2094       insert(testDb, state,    "0.000244140625",        expect &:=    0.000244140625);
 2095       insert(testDb, state,    "0.0009765625",          expect &:=    0.0009765625);
 2096       insert(testDb, state,    "3.5",                   expect &:=    3.5);
 2097       insert(testDb, state,    "4.125",                 expect &:=    4.125);
 2098       insert(testDb, state, "4882.8125",                expect &:= 4882.8125);
 2099       insert(testDb, state,  "9223372036854775807.0",   expect &:=  9223372036854775807.0);
 2100       insert(testDb, state,  "9223372036854775808.0",   expect &:=  9223372036854775808.0);
 2101 
 2102       insert(state, 1,                          expect &:=                    1.0);
 2103       insert(state, pred(-9223372036854775807), expect &:= -9223372036854775808.0);
 2104       insert(state, 9223372036854775807,        expect &:=  9223372036854775807.0);
 2105 
 2106       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2107                                  " (" & state.fieldName & ") VALUES (?)");
 2108       insert(state,                    2_,      expect &:=                    2.0);
 2109       insert(state, -9223372036854775809_,      expect &:= -9223372036854775809.0);
 2110       insert(state,  9223372036854775808_,      expect &:=  9223372036854775808.0);
 2111 
 2112       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2113                                  " (" & state.fieldName & ") VALUES (?)");
 2114       insert(state,  7_/2_,                     expect &:=  3.5);
 2115       insert(state,  5000000_ / 1024_,          expect &:=  4882.8125);
 2116       insert(state, -9223372036854775808_/1_,   expect &:= -9223372036854775808.0);
 2117       insert(state,  9223372036854775807_/1_,   expect &:=  9223372036854775807.0);
 2118       insInf(state, -1_/0_,                     expect &:= -Infinity);
 2119       insInf(state,  1_/0_,                     expect &:=  Infinity);
 2120       insNaN(state,  0_/0_,                     expect &:=  NaN);
 2121 
 2122       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2123                                  " (" & state.fieldName & ") VALUES (?)");
 2124       insert(state, -9223372036854775809.0,     expect &:= -9223372036854775809.0);
 2125       insert(state, -9223372036854775808.0,     expect &:= -9223372036854775808.0);
 2126       insert(state,    0.0,                     expect &:=    0.0);
 2127       insert(state,    5.9604644775390625e-8,   expect &:=    5.9604644775390625e-8);
 2128       insert(state,    2.384185791015625e-7,    expect &:=    2.384185791015625e-7);
 2129       insert(state,    4.76837158203125e-7,     expect &:=    4.76837158203125e-7);
 2130       insert(state,    9.5367431640625e-7,      expect &:=    9.5367431640625e-7);
 2131       insert(state,    0.000244140625,          expect &:=    0.000244140625);
 2132       insert(state,    0.0009765625,            expect &:=    0.0009765625);
 2133       insert(state,    3.5,                     expect &:=    3.5);
 2134       insert(state,    4.125,                   expect &:=    4.125);
 2135       insert(state, 4882.8125,                  expect &:= 4882.8125);
 2136       insert(state,  9223372036854775807.0,     expect &:=  9223372036854775807.0);
 2137       insert(state,  9223372036854775808.0,     expect &:=  9223372036854775808.0);
 2138       insInf(state, -Infinity,                  expect &:= -Infinity);
 2139       insInf(state,  Infinity,                  expect &:=  Infinity);
 2140       insNaN(state,  NaN,                       expect &:=  NaN);
 2141 
 2142       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 2143       execute(state.statement);
 2144       while fetch(state.statement) do
 2145         floatColumn := column(state.statement, 1, float);
 2146         if compareFloatAsDecimalString(databaseKind) then
 2147           isEqual := str(floatColumn) = str(expect[row]);
 2148         else
 2149           isEqual := floatColumn = expect[row];
 2150         end if;
 2151         if not isEqual and
 2152             (not isNaN(floatColumn) or not isNaN(expect[row])) then
 2153           state.okay := FALSE;
 2154           if state.details then
 2155             writeln(" *** testFloatField: Row: " <& row <&
 2156                     " Expected " <& expect[row] <& " found float " <& floatColumn);
 2157           end if;
 2158         end if;
 2159         if row <= 2 and not isNull(state.statement, 1) then
 2160           state.okay := FALSE;
 2161           if state.details then
 2162             writeln(" *** testFloatField: Row: " <& row <&
 2163                     " Expected NULL found float " <& floatColumn);
 2164           end if;
 2165         end if;
 2166         if row > 2 and isNull(state.statement, 1) then
 2167           state.okay := FALSE;
 2168           if state.details then
 2169             writeln(" *** testFloatField: Row: " <& row <&
 2170                     " Expected " <& expect[row] <& " found NULL");
 2171           end if;
 2172         end if;
 2173         incr(row);
 2174       end while;
 2175     exception
 2176       catch RANGE_ERROR:
 2177         state.okay := FALSE;
 2178         writeln(" *** RANGE_ERROR was raised");
 2179       catch FILE_ERROR:
 2180         state.okay := FALSE;
 2181         writeln(" *** FILE_ERROR was raised");
 2182       catch DATABASE_ERROR:
 2183         state.okay := FALSE;
 2184         writeln(" *** DATABASE_ERROR was raised");
 2185     end block;
 2186     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 2187     execute(state.statement);
 2188 
 2189     if state.okay then
 2190       writeln("Inserting and fetching float fields works okay.");
 2191     else
 2192       writeln(" *** Inserting and fetching float fields does not work okay.");
 2193     end if;
 2194   end func;
 2195 
 2196 
 2197 const proc: testDoubleField (in database: testDb, in dbCategory: databaseKind) is func
 2198   local
 2199     var testState: state is testState("doubleTest", "doubleField", FALSE);
 2200     var array float: expect is 0 times 0.0;
 2201     var float: doubleColumn is 0.0;
 2202     var boolean: isEqual is FALSE;
 2203     var integer: row is 1;
 2204   begin
 2205     if state.details then
 2206       writeln("testDoubleField: " <& databaseKind);
 2207     end if;
 2208     block
 2209       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 2210                            " (" & state.fieldName & " " & doubleType(databaseKind) & ")");
 2211       execute(state.statement);
 2212       insert(testDb, state, "NULL", expect &:= 0.0);
 2213       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2214                                  " (" & state.fieldName & ") VALUES (?)");
 2215       insert(state, NULL, expect &:= 0.0);
 2216 
 2217       insert(testDb, state,    "-9007199254740991",     expect &:=    -9007199254740991.0);
 2218       insert(testDb, state,                   "-1",     expect &:=                   -1.0);
 2219       insert(testDb, state,                    "0",     expect &:=                    0.0);
 2220       insert(testDb, state,                    "1",     expect &:=                    1.0);
 2221       insert(testDb, state,     "9007199254740991",     expect &:=     9007199254740991.0);
 2222 
 2223       insert(testDb, state, "-9223372036854775809.0",   expect &:= -9223372036854775809.0);
 2224       insert(testDb, state, "-9223372036854775808.0",   expect &:= -9223372036854775808.0);
 2225       insert(testDb, state,    "0.0",                   expect &:=    0.0);
 2226       insert(testDb, state,    "5.9604644775390625e-8", expect &:=    5.9604644775390625e-8);
 2227       insert(testDb, state,    "2.384185791015625e-7",  expect &:=    2.384185791015625e-7);
 2228       insert(testDb, state,    "4.76837158203125e-7",   expect &:=    4.76837158203125e-7);
 2229       insert(testDb, state,    "9.5367431640625e-7",    expect &:=    9.5367431640625e-7);
 2230       insert(testDb, state,    "0.000244140625",        expect &:=    0.000244140625);
 2231       insert(testDb, state,    "0.0009765625",          expect &:=    0.0009765625);
 2232       insert(testDb, state,    "3.5",                   expect &:=    3.5);
 2233       insert(testDb, state,    "4.125",                 expect &:=    4.125);
 2234       insert(testDb, state, "4882.8125",                expect &:= 4882.8125);
 2235       insert(testDb, state,  "9223372036854775807.0",   expect &:=  9223372036854775807.0);
 2236       insert(testDb, state,  "9223372036854775808.0",   expect &:=  9223372036854775808.0);
 2237 
 2238       insert(state, 1,                          expect &:=                    1.0);
 2239       insert(state, pred(-9223372036854775807), expect &:= -9223372036854775808.0);
 2240       insert(state, 9223372036854775807,        expect &:=  9223372036854775807.0);
 2241 
 2242       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2243                                  " (" & state.fieldName & ") VALUES (?)");
 2244       insert(state, 2_,                         expect &:=                    2.0);
 2245       insert(state, -9223372036854775809_,      expect &:= -9223372036854775809.0);
 2246       insert(state, 9223372036854775808_,       expect &:=  9223372036854775808.0);
 2247 
 2248       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2249                                  " (" & state.fieldName & ") VALUES (?)");
 2250       insert(state,  7_/2_,                     expect &:=  3.5);
 2251       insert(state,  1234567654321_ / 781250_,  expect &:=  1580246.59753088);
 2252       insert(state, -9223372036854775808_/1_,   expect &:= -9223372036854775808.0);
 2253       insert(state,  9223372036854775807_/1_,   expect &:=  9223372036854775807.0);
 2254       insInf(state, -1_/0_,                     expect &:= -Infinity);
 2255       insInf(state,  1_/0_,                     expect &:=  Infinity);
 2256       insNaN(state,  0_/0_,                     expect &:=  NaN);
 2257 
 2258       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2259                                  " (" & state.fieldName & ") VALUES (?)");
 2260       insert(state, -9223372036854775809.0,     expect &:= -9223372036854775809.0);
 2261       insert(state, -9223372036854775808.0,     expect &:= -9223372036854775808.0);
 2262       insert(state,    0.0,                     expect &:=    0.0);
 2263       insert(state,    5.9604644775390625e-8,   expect &:=    5.9604644775390625e-8);
 2264       insert(state,    2.384185791015625e-7,    expect &:=    2.384185791015625e-7);
 2265       insert(state,    4.76837158203125e-7,     expect &:=    4.76837158203125e-7);
 2266       insert(state,    9.5367431640625e-7,      expect &:=    9.5367431640625e-7);
 2267       insert(state,    0.000244140625,          expect &:=    0.000244140625);
 2268       insert(state,    0.0009765625,            expect &:=    0.0009765625);
 2269       insert(state,    3.5,                     expect &:=    3.5);
 2270       insert(state,    4.125,                   expect &:=    4.125);
 2271       insert(state, 4882.8125,                  expect &:= 4882.8125);
 2272       insert(state,  9223372036854775807.0,     expect &:=  9223372036854775807.0);
 2273       insert(state,  9223372036854775808.0,     expect &:=  9223372036854775808.0);
 2274       insInf(state, -Infinity,                  expect &:= -Infinity);
 2275       insInf(state,  Infinity,                  expect &:=  Infinity);
 2276       insNaN(state,  NaN,                       expect &:=  NaN);
 2277 
 2278       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 2279       execute(state.statement);
 2280       while fetch(state.statement) do
 2281         doubleColumn := column(state.statement, 1, float);
 2282         if compareDoubleAsDecimalString(databaseKind) then
 2283           isEqual := str(doubleColumn) = str(expect[row]);
 2284         else
 2285           isEqual := doubleColumn = expect[row];
 2286         end if;
 2287         if not isEqual and
 2288             (not isNaN(doubleColumn) or not isNaN(expect[row])) then
 2289           state.okay := FALSE;
 2290           if state.details then
 2291             writeln(" *** testDoubleField: Row: " <& row <&
 2292                     " Expected " <& expect[row] <& " found double " <& doubleColumn);
 2293           end if;
 2294         end if;
 2295         if row <= 2 and not isNull(state.statement, 1) then
 2296           state.okay := FALSE;
 2297           if state.details then
 2298             writeln(" *** testDoubleField: Row: " <& row <&
 2299                     " Expected NULL found double " <& doubleColumn);
 2300           end if;
 2301         end if;
 2302         if row > 2 and isNull(state.statement, 1) then
 2303           state.okay := FALSE;
 2304           if state.details then
 2305             writeln(" *** testDoubleField: Row: " <& row <&
 2306                     " Expected " <& expect[row] <& " found NULL");
 2307           end if;
 2308         end if;
 2309         incr(row);
 2310       end while;
 2311     exception
 2312       catch RANGE_ERROR:
 2313         state.okay := FALSE;
 2314         writeln(" *** RANGE_ERROR was raised");
 2315       catch FILE_ERROR:
 2316         state.okay := FALSE;
 2317         writeln(" *** FILE_ERROR was raised");
 2318       catch DATABASE_ERROR:
 2319         state.okay := FALSE;
 2320         writeln(" *** DATABASE_ERROR was raised");
 2321     end block;
 2322     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 2323     execute(state.statement);
 2324 
 2325     if state.okay then
 2326       writeln("Inserting and fetching double fields works okay.");
 2327     else
 2328       writeln(" *** Inserting and fetching double fields does not work okay.");
 2329     end if;
 2330   end func;
 2331 
 2332 
 2333 const proc: testBigRatField (in database: testDb, in dbCategory: databaseKind) is func
 2334   local
 2335     var testState: state is testState("bigRatTest", "bigRatField", FALSE);
 2336     var array bigRational: expect is 0 times 0_/1_;
 2337     var bigRational: bigRatColumn is bigRational.value;
 2338     var float: floatColumn is 0.0;
 2339     var integer: row is 1;
 2340     var bigInteger: numerator is 0_;
 2341   begin
 2342     if state.details then
 2343       writeln("testBigRatField: " <& databaseKind);
 2344     end if;
 2345     block
 2346       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 2347                                  " (" & state.fieldName & " " & bigRatType(databaseKind) & ")");
 2348       execute(state.statement);
 2349       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2350                                  " (" & state.fieldName & ") VALUES (?)");
 2351       insert(state,                      NULL,  expect &:=                    0_/1_);
 2352       insert(state,                         0,  expect &:=                    0_/1_);
 2353       insert(state,                         1,  expect &:=                    1_/1_);
 2354       insert(state, pred(-9223372036854775807), expect &:= -9223372036854775808_/1_);
 2355       insert(state,       9223372036854775807,  expect &:=  9223372036854775807_/1_);
 2356 
 2357       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2358                                  " (" & state.fieldName & ") VALUES (?)");
 2359       insert(state,                    2_,      expect &:=                    2_/1_);
 2360       insert(state, -9223372036854775809_,      expect &:= -9223372036854775809_/1_);
 2361       insert(state,  9223372036854775808_,      expect &:=  9223372036854775808_/1_);
 2362 
 2363       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2364                            " (" & state.fieldName & ") VALUES (?)");
 2365       insert(state,  0_/1_,                     expect &:=  0_/1_);
 2366       insert(state,  1_/1_,                     expect &:=  1_/1_);
 2367       insert(state,  7_/2_,                     expect &:=  7_/2_);
 2368       insert(state,  9223372036854775807_/1_,   expect &:=  9223372036854775807_/1_);
 2369       insert(state,  9223372036854775808_/1_,   expect &:=  9223372036854775808_/1_);
 2370       insert(state,  12345678901234500000000_/1_,
 2371           expect &:= 12345678901234500000000_/1_);
 2372       insert(state,  123456789012345600000000_/1_,
 2373           expect &:= 123456789012345600000000_/1_);
 2374       insert(state,  12345678901234567890123400000000_/1_,
 2375           expect &:= 12345678901234567890123400000000_/1_);
 2376       insert(state,  12345678901234567890123456789012000_/1_,
 2377           expect &:= 12345678901234567890123456789012000_/1_);
 2378       insert(state,  1234567890123450_/1_,
 2379           expect &:= 1234567890123450_/1_);
 2380       insert(state,  12345678901234560_/1_,
 2381           expect &:= 12345678901234560_/1_);
 2382       insert(state,  1234567890123456789012340_/1_,
 2383           expect &:= 1234567890123456789012340_/1_);
 2384       insert(state,  123456789012345678901234567890120_/1_,
 2385           expect &:= 123456789012345678901234567890120_/1_);
 2386       insert(state,  123456789012345_/1_,
 2387           expect &:= 123456789012345_/1_);
 2388       insert(state,  1234567890123456_/1_,
 2389           expect &:= 1234567890123456_/1_);
 2390       insert(state,  123456789012345678901234_/1_,
 2391           expect &:= 123456789012345678901234_/1_);
 2392       insert(state,  12345678901234567890123456789012_/1_,
 2393           expect &:= 12345678901234567890123456789012_/1_);
 2394       insert(state,  123456789012345_/10_,
 2395           expect &:= 123456789012345_/10_);
 2396       insert(state,  1234567890123456_/10_,
 2397           expect &:= 1234567890123456_/10_);
 2398       insert(state,  123456789012345678901234_/10_,
 2399           expect &:= 123456789012345678901234_/10_);
 2400       insert(state,  12345678901234567890123456789012_/10_,
 2401           expect &:= 12345678901234567890123456789012_/10_);
 2402       insert(state,  123456789012345_/10000000_,
 2403           expect &:= 123456789012345_/10000000_);
 2404       insert(state,  1234567890123456_/100000000_,
 2405           expect &:= 1234567890123456_/100000000_);
 2406       insert(state,  123456789012345678901234_/1000000000000_,
 2407           expect &:= 123456789012345678901234_/1000000000000_);
 2408       insert(state,  12345678901234567890123456789012_/10000000000000000_,
 2409           expect &:= 12345678901234567890123456789012_/10000000000000000_);
 2410       insert(state,  123456789012345678901234567890123456789_/100000000000000000000_,
 2411           expect &:= 123456789012345678901234567890123456789_/100000000000000000000_);
 2412       insert(state,  123456789012345_/100000000000000_,
 2413           expect &:= 123456789012345_/100000000000000_);
 2414       insert(state,  1234567890123456_/1000000000000000_,
 2415           expect &:= 1234567890123456_/1000000000000000_);
 2416       insert(state,  123456789012345678901234_/100000000000000000000000_,
 2417           expect &:= 123456789012345678901234_/100000000000000000000000_);
 2418       insert(state,  1234567890123456789012345678901_/1000000000000000000000000000000_,
 2419           expect &:= 1234567890123456789012345678901_/1000000000000000000000000000000_);
 2420       insert(state,  123456789012345_/1000000000000000_,
 2421           expect &:= 123456789012345_/1000000000000000_);
 2422       insert(state,  1234567890123456_/10000000000000000_,
 2423           expect &:= 1234567890123456_/10000000000000000_);
 2424       insert(state,  123456789012345678901234_/1000000000000000000000000_,
 2425           expect &:= 123456789012345678901234_/1000000000000000000000000_);
 2426       insert(state,  123456789012345678901234567891_/1000000000000000000000000000000_,
 2427           expect &:= 123456789012345678901234567891_/1000000000000000000000000000000_);
 2428       insert(state,  123456789012345_/10000000000000000_,
 2429           expect &:= 123456789012345_/10000000000000000_);
 2430       insert(state,  1234567890123456_/100000000000000000_,
 2431           expect &:= 1234567890123456_/100000000000000000_);
 2432       insert(state,  123456789012345678901234_/10000000000000000000000000_,
 2433           expect &:= 123456789012345678901234_/10000000000000000000000000_);
 2434       insert(state,  12345678901234567890123456789_/1000000000000000000000000000000_,
 2435           expect &:= 12345678901234567890123456789_/1000000000000000000000000000000_);
 2436       insert(state,  123456789012345_/10000000000000000000_,
 2437           expect &:= 123456789012345_/10000000000000000000_);
 2438       insert(state,  1234567890123456_/100000000000000000000_,
 2439           expect &:= 1234567890123456_/100000000000000000000_);
 2440       insert(state,  123456789012345678901234_/1000000000000000000000000000000_,
 2441           expect &:= 123456789012345678901234_/1000000000000000000000000000000_);
 2442       insert(state, -0_/1_,                     expect &:= -0_/1_);
 2443       insert(state, -1_/1_,                     expect &:= -1_/1_);
 2444       insert(state, -7_/2_,                     expect &:= -7_/2_);
 2445       insert(state, -9223372036854775807_/1_,   expect &:= -9223372036854775807_/1_);
 2446       insert(state, -9223372036854775808_/1_,   expect &:= -9223372036854775808_/1_);
 2447       insert(state,  -12345678901234500000000_/1_,
 2448           expect &:= -12345678901234500000000_/1_);
 2449       insert(state,  -123456789012345600000000_/1_,
 2450           expect &:= -123456789012345600000000_/1_);
 2451       insert(state,  -12345678901234567890123400000000_/1_,
 2452           expect &:= -12345678901234567890123400000000_/1_);
 2453       insert(state,  -1234567890123456789012345678901200_/1_,
 2454           expect &:= -1234567890123456789012345678901200_/1_);
 2455       insert(state,  -1234567890123450_/1_,
 2456           expect &:= -1234567890123450_/1_);
 2457       insert(state,  -12345678901234560_/1_,
 2458           expect &:= -12345678901234560_/1_);
 2459       insert(state,  -1234567890123456789012340_/1_,
 2460           expect &:= -1234567890123456789012340_/1_);
 2461       insert(state,  -123456789012345678901234567890120_/1_,
 2462           expect &:= -123456789012345678901234567890120_/1_);
 2463       insert(state,  -123456789012345_/1_,
 2464           expect &:= -123456789012345_/1_);
 2465       insert(state,  -1234567890123456_/1_,
 2466           expect &:= -1234567890123456_/1_);
 2467       insert(state,  -123456789012345678901234_/1_,
 2468           expect &:= -123456789012345678901234_/1_);
 2469       insert(state,  -12345678901234567890123456789012_/1_,
 2470           expect &:= -12345678901234567890123456789012_/1_);
 2471       insert(state,  -123456789012345_/10_,
 2472           expect &:= -123456789012345_/10_);
 2473       insert(state,  -1234567890123456_/10_,
 2474           expect &:= -1234567890123456_/10_);
 2475       insert(state,  -123456789012345678901234_/10_,
 2476           expect &:= -123456789012345678901234_/10_);
 2477       insert(state,  -12345678901234567890123456789012_/10_,
 2478           expect &:= -12345678901234567890123456789012_/10_);
 2479       insert(state,  -123456789012345_/10000000_,
 2480           expect &:= -123456789012345_/10000000_);
 2481       insert(state,  -1234567890123456_/100000000_,
 2482           expect &:= -1234567890123456_/100000000_);
 2483       insert(state,  -123456789012345678901234_/1000000000000_,
 2484           expect &:= -123456789012345678901234_/1000000000000_);
 2485       insert(state,  -12345678901234567890123456789012_/10000000000000000_,
 2486           expect &:= -12345678901234567890123456789012_/10000000000000000_);
 2487       insert(state,  -123456789012345678901234567890123456789_/100000000000000000000_,
 2488           expect &:= -123456789012345678901234567890123456789_/100000000000000000000_);
 2489       insert(state,  -123456789012345_/100000000000000_,
 2490           expect &:= -123456789012345_/100000000000000_);
 2491       insert(state,  -1234567890123456_/1000000000000000_,
 2492           expect &:= -1234567890123456_/1000000000000000_);
 2493       insert(state,  -123456789012345678901234_/100000000000000000000000_,
 2494           expect &:= -123456789012345678901234_/100000000000000000000000_);
 2495       insert(state,  -1234567890123456789012345678901_/1000000000000000000000000000000_,
 2496           expect &:= -1234567890123456789012345678901_/1000000000000000000000000000000_);
 2497       insert(state,  -123456789012345_/1000000000000000_,
 2498           expect &:= -123456789012345_/1000000000000000_);
 2499       insert(state,  -1234567890123456_/10000000000000000_,
 2500           expect &:= -1234567890123456_/10000000000000000_);
 2501       insert(state,  -123456789012345678901234_/1000000000000000000000000_,
 2502           expect &:= -123456789012345678901234_/1000000000000000000000000_);
 2503       insert(state,  -123456789012345678901234567891_/1000000000000000000000000000000_,
 2504           expect &:= -123456789012345678901234567891_/1000000000000000000000000000000_);
 2505       insert(state,  -123456789012345_/10000000000000000_,
 2506           expect &:= -123456789012345_/10000000000000000_);
 2507       insert(state,  -1234567890123456_/100000000000000000_,
 2508           expect &:= -1234567890123456_/100000000000000000_);
 2509       insert(state,  -123456789012345678901234_/10000000000000000000000000_,
 2510           expect &:= -123456789012345678901234_/10000000000000000000000000_);
 2511       insert(state,  -12345678901234567890123456789_/1000000000000000000000000000000_,
 2512           expect &:= -12345678901234567890123456789_/1000000000000000000000000000000_);
 2513       insert(state,  -123456789012345_/10000000000000000000_,
 2514           expect &:= -123456789012345_/10000000000000000000_);
 2515       insert(state,  -1234567890123456_/100000000000000000000_,
 2516           expect &:= -1234567890123456_/100000000000000000000_);
 2517       insert(state,  -123456789012345678901234_/1000000000000000000000000000000_,
 2518           expect &:= -123456789012345678901234_/1000000000000000000000000000000_);
 2519       if supportsFloatingDecimals(databaseKind) then
 2520         insert(state,   12345678901234567890123456789012345678900000000_/1_,
 2521             expect &:=  12345678901234567890123456789012345678900000000_/1_);
 2522         insert(state,   1234567890123456789012345678901234567890_/1_,
 2523             expect &:=  1234567890123456789012345678901234567890_/1_);
 2524         insert(state,   123456789012345678901234567890123456789_/1_,
 2525             expect &:=  123456789012345678901234567890123456789_/1_);
 2526         insert(state,   123456789012345678901234567890123456789_/10_,
 2527             expect &:=  123456789012345678901234567890123456789_/10_);
 2528         insert(state,   123456789012345678901234567890123456789_/100000000000000000000000000000000000000_,
 2529             expect &:=  123456789012345678901234567890123456789_/100000000000000000000000000000000000000_);
 2530         insert(state,   123456789012345678901234567890123456789_/1000000000000000000000000000000000000000_,
 2531             expect &:=  123456789012345678901234567890123456789_/1000000000000000000000000000000000000000_);
 2532         insert(state,   123456789012345678901234567890123456789_/10000000000000000000000000000000000000000_,
 2533             expect &:=  123456789012345678901234567890123456789_/10000000000000000000000000000000000000000_);
 2534         insert(state,   12345678901234567890123456789012_/10000000000000000000000000000000000000000_,
 2535             expect &:=  12345678901234567890123456789012_/10000000000000000000000000000000000000000_);
 2536         insert(state,   123456789012345678901234567890123456789_/100000000000000000000000000000000000000000000000_,
 2537             expect &:=  123456789012345678901234567890123456789_/100000000000000000000000000000000000000000000000_);
 2538         insert(state,  -12345678901234567890123456789012345678900000000_/1_,
 2539             expect &:= -12345678901234567890123456789012345678900000000_/1_);
 2540         insert(state,  -1234567890123456789012345678901234567890_/1_,
 2541             expect &:= -1234567890123456789012345678901234567890_/1_);
 2542         insert(state,  -123456789012345678901234567890123456789_/1_,
 2543             expect &:= -123456789012345678901234567890123456789_/1_);
 2544         insert(state,  -123456789012345678901234567890123456789_/10_,
 2545             expect &:= -123456789012345678901234567890123456789_/10_);
 2546         insert(state,  -123456789012345678901234567890123456789_/100000000000000000000000000000000000000_,
 2547             expect &:= -123456789012345678901234567890123456789_/100000000000000000000000000000000000000_);
 2548         insert(state,  -123456789012345678901234567890123456789_/1000000000000000000000000000000000000000_,
 2549             expect &:= -123456789012345678901234567890123456789_/1000000000000000000000000000000000000000_);
 2550         insert(state,  -123456789012345678901234567890123456789_/10000000000000000000000000000000000000000_,
 2551             expect &:= -123456789012345678901234567890123456789_/10000000000000000000000000000000000000000_);
 2552         insert(state,  -12345678901234567890123456789012_/10000000000000000000000000000000000000000_,
 2553             expect &:= -12345678901234567890123456789012_/10000000000000000000000000000000000000000_);
 2554         insert(state,  -123456789012345678901234567890123456789_/100000000000000000000000000000000000000000000000_,
 2555             expect &:= -123456789012345678901234567890123456789_/100000000000000000000000000000000000000000000000_);
 2556       end if;
 2557       insInf(state, -1_/0_,                     expect &:= -1_/0_);
 2558       insInf(state,  1_/0_,                     expect &:=  1_/0_);
 2559       insNaN(state,  0_/0_,                     expect &:=  0_/0_);
 2560       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 2561       execute(state.statement);
 2562       while fetch(state.statement) do
 2563         bigRatColumn := column(state.statement, 1, bigRational);
 2564         if bigRatColumn <> expect[row] then
 2565           state.okay := FALSE;
 2566           if state.details then
 2567             writeln(" *** testBigRatField: Row: " <& row <&
 2568                     " Expected " <& expect[row] <& " found " <& bigRatColumn);
 2569           end if;
 2570         end if;
 2571         if row = 1 and not isNull(state.statement, 1) then
 2572           state.okay := FALSE;
 2573           if state.details then
 2574             writeln(" *** testBigRatField: Row: " <& row <&
 2575                     " Expected NULL found " <& bigRatColumn);
 2576           end if;
 2577         end if;
 2578         floatColumn := column(state.statement, 1, float);
 2579         if floatColumn <> float(str(expect[row])) then
 2580           state.okay := FALSE;
 2581           if state.details then
 2582             writeln(" *** testBigRatField: Row: " <& row <&
 2583                     " Expected " <& expect[row] <& " found float " <& floatColumn);
 2584           end if;
 2585         end if;
 2586         if row = 1 and not isNull(state.statement, 1) then
 2587           state.okay := FALSE;
 2588           if state.details then
 2589             writeln(" *** testBigRatField: Row: " <& row <&
 2590                     " Expected NULL found float " <& floatColumn);
 2591           end if;
 2592         end if;
 2593         if row > 1 and isNull(state.statement, 1) then
 2594           state.okay := FALSE;
 2595           if state.details then
 2596             writeln(" *** testBigRatField: Row: " <& row <&
 2597                     " Expected " <& expect[row] <& " found NULL");
 2598           end if;
 2599         end if;
 2600         incr(row);
 2601       end while;
 2602     exception
 2603       catch RANGE_ERROR:
 2604         state.okay := FALSE;
 2605         writeln(" *** RANGE_ERROR was raised");
 2606       catch FILE_ERROR:
 2607         state.okay := FALSE;
 2608         writeln(" *** FILE_ERROR was raised");
 2609       catch DATABASE_ERROR:
 2610         state.okay := FALSE;
 2611         writeln(" *** DATABASE_ERROR was raised");
 2612     end block;
 2613     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 2614     execute(state.statement);
 2615 
 2616     if state.okay then
 2617       writeln("Inserting and fetching bigRational fields works okay.");
 2618     else
 2619       writeln(" *** Inserting and fetching bigRational fields does not work okay.");
 2620     end if;
 2621   end func;
 2622 
 2623 
 2624 const proc: testAnyIntegerField (in database: testDb, inout testState: state,
 2625     in string: fieldType, in integer: precision, in integer: sqlIntLiteralBits) is func
 2626   local
 2627     var array bigInteger: expect is 0 times 0_;
 2628     var integer: integerColumn is 0;
 2629     var bigInteger: bigIntColumn is 0_;
 2630     var bigRational: bigRatColumn is bigRational.value;
 2631     var float: floatColumn is 0.0;
 2632     var string: floatAsString is "";
 2633     var integer: row is 1;
 2634   begin
 2635     block
 2636       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 2637                                  " (" & state.fieldName & " " & fieldType & ")");
 2638       execute(state.statement);
 2639       insert(testDb, state, "NULL", expect &:= 0_);
 2640       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2641                                  " (" & state.fieldName & ") VALUES (?)");
 2642       insert(state, NULL,  expect &:= 0_);
 2643 
 2644       insert(testDb, state,  "0", expect &:=  0_);
 2645       insert(testDb, state,  "1", expect &:=  1_);
 2646       insert(testDb, state, "-1", expect &:= -1_);
 2647       if precision >= 18 then
 2648         insert(testDb, state,  "123456789012345678", expect &:=  123456789012345678_);
 2649         insert(testDb, state,  "999999999999999999", expect &:=  999999999999999999_);
 2650         insert(testDb, state, "-123456789012345678", expect &:= -123456789012345678_);
 2651         insert(testDb, state, "-999999999999999999", expect &:= -999999999999999999_);
 2652       end if;
 2653       if sqlIntLiteralBits = 64 then
 2654         insert(testDb, state,  "1000000000000000000", expect &:=  1000000000000000000_);
 2655         insert(testDb, state,  "1234567890123456789", expect &:=  1234567890123456789_);
 2656         insert(testDb, state,  "9223372036854775807", expect &:=  9223372036854775807_);
 2657         insert(testDb, state, "-1000000000000000000", expect &:= -1000000000000000000_);
 2658         insert(testDb, state, "-1234567890123456789", expect &:= -1234567890123456789_);
 2659         insert(testDb, state, "-9223372036854775808", expect &:= -9223372036854775808_);
 2660       end if;
 2661       if sqlIntLiteralBits > 64 then
 2662         insert(testDb, state,  "9223372036854775808", expect &:=  9223372036854775808_);
 2663         insert(testDb, state,  "9999999999999999999", expect &:=  9999999999999999999_);
 2664         insert(testDb, state, "-9223372036854775809", expect &:= -9223372036854775809_);
 2665         insert(testDb, state, "-9999999999999999999", expect &:= -9999999999999999999_);
 2666         if precision >= 19 then
 2667           insert(testDb, state,  "1000000000000000000", expect &:=  1000000000000000000_);
 2668           insert(testDb, state,  "1234567890123456789", expect &:=  1234567890123456789_);
 2669           insert(testDb, state,  "9223372036854775807", expect &:=  9223372036854775807_);
 2670           insert(testDb, state,  "9999999999999999999", expect &:=  9999999999999999999_);
 2671           insert(testDb, state, "-1000000000000000000", expect &:= -1000000000000000000_);
 2672           insert(testDb, state, "-1234567890123456789", expect &:= -1234567890123456789_);
 2673           insert(testDb, state, "-9223372036854775808", expect &:= -9223372036854775808_);
 2674           insert(testDb, state, "-9999999999999999999", expect &:= -9999999999999999999_);
 2675         end if;
 2676         if precision >= 38 then
 2677           insert(testDb, state,  "12345678901234567890123456789012345678",
 2678                       expect &:=  12345678901234567890123456789012345678_);
 2679           insert(testDb, state,  "99999999999999999999999999999999999999",
 2680                       expect &:=  99999999999999999999999999999999999999_);
 2681           insert(testDb, state, "-12345678901234567890123456789012345678",
 2682                       expect &:= -12345678901234567890123456789012345678_);
 2683           insert(testDb, state, "-99999999999999999999999999999999999999",
 2684                       expect &:= -99999999999999999999999999999999999999_);
 2685         end if;
 2686         if precision >= 65 then
 2687           insert(testDb, state,  "12345678901234567890123456789012345678901234567890123456789012345",
 2688                       expect &:=  12345678901234567890123456789012345678901234567890123456789012345_);
 2689           insert(testDb, state,  "99999999999999999999999999999999999999999999999999999999999999999",
 2690                       expect &:=  99999999999999999999999999999999999999999999999999999999999999999_);
 2691           insert(testDb, state, "-12345678901234567890123456789012345678901234567890123456789012345",
 2692                       expect &:= -12345678901234567890123456789012345678901234567890123456789012345_);
 2693           insert(testDb, state, "-99999999999999999999999999999999999999999999999999999999999999999",
 2694                       expect &:= -99999999999999999999999999999999999999999999999999999999999999999_);
 2695         end if;
 2696         if precision >= 100 then
 2697           insert(testDb, state,
 2698                         "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
 2699               expect &:= 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_);
 2700           insert(testDb, state,
 2701                         "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999",
 2702               expect &:= 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999_);
 2703           insert(testDb, state,
 2704                         "-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
 2705               expect &:= -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_);
 2706           insert(testDb, state,
 2707                         "-9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999",
 2708               expect &:= -9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999_);
 2709         end if;
 2710       end if;
 2711 
 2712       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2713                                  " (" & state.fieldName & ") VALUES (?)");
 2714       insert(state, 0, expect &:= 0_);
 2715       insert(state, 1, expect &:= 1_);
 2716       insert(state, -1, expect &:= -1_);
 2717       if precision >= 18 then
 2718         insert(state,  123456789012345678, expect &:=  123456789012345678_);
 2719         insert(state,  999999999999999999, expect &:=  999999999999999999_);
 2720         insert(state, -123456789012345678, expect &:= -123456789012345678_);
 2721         insert(state, -999999999999999999, expect &:= -999999999999999999_);
 2722       end if;
 2723       if precision >= 19 then
 2724         insert(state,       1000000000000000000,  expect &:=  1000000000000000000_);
 2725         insert(state,       1234567890123456789,  expect &:=  1234567890123456789_);
 2726         insert(state,       9223372036854775807,  expect &:=  9223372036854775807_);
 2727         insert(state,      -1000000000000000000,  expect &:= -1000000000000000000_);
 2728         insert(state,      -1234567890123456789,  expect &:= -1234567890123456789_);
 2729         insert(state, pred(-9223372036854775807), expect &:= -9223372036854775808_);
 2730       end if;
 2731 
 2732       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2733                                  " (" & state.fieldName & ") VALUES (?)");
 2734       insert(state, 0_, expect &:= 0_);
 2735       insert(state, 1_, expect &:= 1_);
 2736       insert(state, -1_, expect &:= -1_);
 2737       if precision >= 18 then
 2738         insert(state,  123456789012345678_, expect &:=  123456789012345678_);
 2739         insert(state,  999999999999999999_, expect &:=  999999999999999999_);
 2740         insert(state, -123456789012345678_, expect &:= -123456789012345678_);
 2741         insert(state, -999999999999999999_, expect &:= -999999999999999999_);
 2742       end if;
 2743       if precision >= 19 then
 2744         insert(state,  1000000000000000000_, expect &:=  1000000000000000000_);
 2745         insert(state,  1234567890123456789_, expect &:=  1234567890123456789_);
 2746         insert(state,  9223372036854775807_, expect &:=  9223372036854775807_);
 2747         insert(state,  9223372036854775808_, expect &:=  9223372036854775808_);
 2748         insert(state,  9999999999999999999_, expect &:=  9999999999999999999_);
 2749         insert(state, -1000000000000000000_, expect &:= -1000000000000000000_);
 2750         insert(state, -1234567890123456789_, expect &:= -1234567890123456789_);
 2751         insert(state, -9223372036854775808_, expect &:= -9223372036854775808_);
 2752         insert(state, -9223372036854775809_, expect &:= -9223372036854775809_);
 2753         insert(state, -9999999999999999999_, expect &:= -9999999999999999999_);
 2754       end if;
 2755       if precision >= 38 then
 2756         insert(state,   12345678901234567890123456789012345678_,
 2757             expect &:=  12345678901234567890123456789012345678_);
 2758         insert(state,   99999999999999999999999999999999999999_,
 2759             expect &:=  99999999999999999999999999999999999999_);
 2760         insert(state,  -12345678901234567890123456789012345678_,
 2761             expect &:= -12345678901234567890123456789012345678_);
 2762         insert(state,  -99999999999999999999999999999999999999_,
 2763             expect &:= -99999999999999999999999999999999999999_);
 2764       end if;
 2765       if precision >= 65 then
 2766         insert(state,   12345678901234567890123456789012345678901234567890123456789012345_,
 2767             expect &:=  12345678901234567890123456789012345678901234567890123456789012345_);
 2768         insert(state,   99999999999999999999999999999999999999999999999999999999999999999_,
 2769             expect &:=  99999999999999999999999999999999999999999999999999999999999999999_);
 2770         insert(state,  -12345678901234567890123456789012345678901234567890123456789012345_,
 2771             expect &:= -12345678901234567890123456789012345678901234567890123456789012345_);
 2772         insert(state,  -99999999999999999999999999999999999999999999999999999999999999999_,
 2773             expect &:= -99999999999999999999999999999999999999999999999999999999999999999_);
 2774       end if;
 2775       if precision >= 100 then
 2776         insert(state,   1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_,
 2777             expect &:=  1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_);
 2778         insert(state,   9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999_,
 2779             expect &:=  9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999_);
 2780         insert(state,  -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_,
 2781             expect &:= -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_);
 2782         insert(state,  -9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999_,
 2783             expect &:= -9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999_);
 2784       end if;
 2785 
 2786       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2787                                  " (" & state.fieldName & ") VALUES (?)");
 2788       insert(state, 0_/1_, expect &:= 0_);
 2789       insert(state, 1_/1_, expect &:= 1_);
 2790       insert(state, -1_/1_, expect &:= -1_);
 2791       if precision >= 18 then
 2792         insert(state,  123456789012345678_/1_, expect &:=  123456789012345678_);
 2793         insert(state,  999999999999999999_/1_, expect &:=  999999999999999999_);
 2794         insert(state, -123456789012345678_/1_, expect &:= -123456789012345678_);
 2795         insert(state, -999999999999999999_/1_, expect &:= -999999999999999999_);
 2796       end if;
 2797       if precision >= 19 then
 2798         insert(state,  1000000000000000000_/1_, expect &:=  1000000000000000000_);
 2799         insert(state,  1234567890123456789_/1_, expect &:=  1234567890123456789_);
 2800         insert(state,  9223372036854775807_/1_, expect &:=  9223372036854775807_);
 2801         insert(state,  9223372036854775808_/1_, expect &:=  9223372036854775808_);
 2802         insert(state,  9999999999999999999_/1_, expect &:=  9999999999999999999_);
 2803         insert(state, -1000000000000000000_/1_, expect &:= -1000000000000000000_);
 2804         insert(state, -1234567890123456789_/1_, expect &:= -1234567890123456789_);
 2805         insert(state, -9223372036854775808_/1_, expect &:= -9223372036854775808_);
 2806         insert(state, -9223372036854775809_/1_, expect &:= -9223372036854775809_);
 2807         insert(state, -9999999999999999999_/1_, expect &:= -9999999999999999999_);
 2808       end if;
 2809       if precision >= 38 then
 2810         insert(state,   12345678901234567890123456789012345678_/1_,
 2811             expect &:=  12345678901234567890123456789012345678_);
 2812         insert(state,   99999999999999999999999999999999999999_/1_,
 2813             expect &:=  99999999999999999999999999999999999999_);
 2814         insert(state,  -12345678901234567890123456789012345678_/1_,
 2815             expect &:= -12345678901234567890123456789012345678_);
 2816         insert(state,  -99999999999999999999999999999999999999_/1_,
 2817             expect &:= -99999999999999999999999999999999999999_);
 2818       end if;
 2819       if precision >= 65 then
 2820         insert(state,   12345678901234567890123456789012345678901234567890123456789012345_/1_,
 2821             expect &:=  12345678901234567890123456789012345678901234567890123456789012345_);
 2822         insert(state,   99999999999999999999999999999999999999999999999999999999999999999_/1_,
 2823             expect &:=  99999999999999999999999999999999999999999999999999999999999999999_);
 2824         insert(state,  -12345678901234567890123456789012345678901234567890123456789012345_/1_,
 2825             expect &:= -12345678901234567890123456789012345678901234567890123456789012345_);
 2826         insert(state,  -99999999999999999999999999999999999999999999999999999999999999999_/1_,
 2827             expect &:= -99999999999999999999999999999999999999999999999999999999999999999_);
 2828       end if;
 2829       if precision >= 100 then
 2830         insert(state,   1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_/1_,
 2831             expect &:=  1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_);
 2832         insert(state,   9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999_/1_,
 2833             expect &:=  9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999_);
 2834         insert(state,  -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_/1_,
 2835             expect &:= -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_);
 2836         insert(state,  -9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999_/1_,
 2837             expect &:= -9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999_);
 2838       end if;
 2839 
 2840       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 2841       execute(state.statement);
 2842       while fetch(state.statement) do
 2843         if expect[row] >= bigInteger(integer.first) and
 2844             expect[row] <= bigInteger(integer.last) then
 2845           integerColumn := column(state.statement, 1, integer);
 2846           if integerColumn <> integer(expect[row]) then
 2847             state.okay := FALSE;
 2848             if state.details then
 2849               writeln(" *** testAnyIntegerField " <& state.tableName <& ": Row: " <& row <&
 2850                       " Expected " <& expect[row] <& " found integer " <& integerColumn);
 2851             end if;
 2852           end if;
 2853           if row <= 2 and not isNull(state.statement, 1) then
 2854             state.okay := FALSE;
 2855             if state.details then
 2856               writeln(" *** testAnyIntegerField " <& state.tableName <& ": Row: " <& row <&
 2857                       " Expected NULL found integer " <& integerColumn);
 2858             end if;
 2859           end if;
 2860         end if;
 2861         bigIntColumn := column(state.statement, 1, bigInteger);
 2862         if bigIntColumn <> expect[row] then
 2863           state.okay := FALSE;
 2864           if state.details then
 2865             writeln(" *** testAnyIntegerField " <& state.tableName <& ": Row: " <& row <&
 2866                     " Expected " <& expect[row] <& " found bigInteger " <& bigIntColumn);
 2867           end if;
 2868         end if;
 2869         if row <= 2 and not isNull(state.statement, 1) then
 2870           state.okay := FALSE;
 2871           if state.details then
 2872             writeln(" *** testAnyIntegerField " <& state.tableName <& ": Row: " <& row <&
 2873                     " Expected NULL found bigInteger " <& bigIntColumn);
 2874           end if;
 2875         end if;
 2876         bigRatColumn := column(state.statement, 1, bigRational);
 2877         if bigRatColumn <> expect[row] / 1_ then
 2878           state.okay := FALSE;
 2879           if state.details then
 2880             writeln(" *** testAnyIntegerField " <& state.tableName <& ": Row: " <& row <&
 2881                     " Expected " <& expect[row] <& " found bigRational " <& bigRatColumn);
 2882           end if;
 2883         end if;
 2884         if row <= 2 and not isNull(state.statement, 1) then
 2885           state.okay := FALSE;
 2886           if state.details then
 2887             writeln(" *** testAnyIntegerField " <& state.tableName <& ": Row: " <& row <&
 2888                     " Expected NULL found bigRational " <& bigRatColumn);
 2889           end if;
 2890         end if;
 2891         floatAsString := str(float(str(expect[row])));
 2892         if endsWith(floatAsString, ".0") and
 2893             expect[row] = bigInteger(floatAsString[.. length(floatAsString) - 2]) then
 2894           # The expected value is representable as float.
 2895           floatColumn := column(state.statement, 1, float);
 2896           if floatColumn <> float(str(expect[row])) then
 2897             state.okay := FALSE;
 2898             if state.details then
 2899               writeln(" *** testAnyIntegerField: Row: " <& row <&
 2900                       " Expected " <& expect[row] <& " found float " <& floatColumn);
 2901             end if;
 2902           end if;
 2903           if row <= 2 and not isNull(state.statement, 1) then
 2904             state.okay := FALSE;
 2905             if state.details then
 2906               writeln(" *** testAnyIntegerField: Row: " <& row <&
 2907                     " Expected NULL found float " <& floatColumn);
 2908             end if;
 2909           end if;
 2910         end if;
 2911         if row > 2 and isNull(state.statement, 1) then
 2912           state.okay := FALSE;
 2913           if state.details then
 2914             writeln(" *** testAnyIntegerField " <& state.tableName <& ": Row: " <& row <&
 2915                     " Expected " <& expect[row] <& " found NULL");
 2916           end if;
 2917         end if;
 2918         incr(row);
 2919       end while;
 2920     exception
 2921       catch RANGE_ERROR:
 2922         state.okay := FALSE;
 2923         writeln(" *** RANGE_ERROR was raised");
 2924       catch FILE_ERROR:
 2925         state.okay := FALSE;
 2926         writeln(" *** FILE_ERROR was raised");
 2927       catch DATABASE_ERROR:
 2928         state.okay := FALSE;
 2929         writeln(" *** DATABASE_ERROR was raised");
 2930     end block;
 2931     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 2932     execute(state.statement);
 2933   end func;
 2934 
 2935 
 2936 const proc: testDecimalIntField (in database: testDb, in dbCategory: databaseKind) is func
 2937   local
 2938     var testState: state is testState("decimalTest", "decimalField", FALSE);
 2939   begin
 2940     if state.details then
 2941       writeln("testDecimalIntField: " <& databaseKind);
 2942     end if;
 2943     testAnyIntegerField(testDb, state, decimalIntType(databaseKind),
 2944                         maxDecimalPrecision(databaseKind), sqlIntLiteralBits(databaseKind));
 2945 
 2946     if state.okay then
 2947       writeln("Inserting and fetching decimal fields with integers works okay.");
 2948     else
 2949       writeln(" *** Inserting and fetching decimal fields with integers does not work okay.");
 2950     end if;
 2951   end func;
 2952 
 2953 
 2954 const proc: testNumericIntField (in database: testDb, in dbCategory: databaseKind) is func
 2955   local
 2956     var testState: state is testState("numericTest", "numericField", FALSE);
 2957   begin
 2958     if state.details then
 2959       writeln("testNumericIntField: " <& databaseKind);
 2960     end if;
 2961     testAnyIntegerField(testDb, state, numericIntType(databaseKind),
 2962                         maxNumericPrecision(databaseKind), sqlIntLiteralBits(databaseKind));
 2963 
 2964     if state.okay then
 2965       writeln("Inserting and fetching numeric fields with integers works okay.");
 2966     else
 2967       writeln(" *** Inserting and fetching numeric fields with integers does not work okay.");
 2968     end if;
 2969   end func;
 2970 
 2971 
 2972 const proc: testAnyRationalField (in database: testDb, inout testState: state,
 2973     in string: fieldType, in integer: precision, in integer: literalPrecision,
 2974     in integer: scale) is func
 2975   local
 2976     var bigRational: bigValue is bigRational.value;
 2977     var array bigRational: expect is 0 times 0_/1_;
 2978     var bigRational: bigRatColumn is bigRational.value;
 2979     var float: floatColumn is 0.0;
 2980     var integer: integerColumn is 0;
 2981     var integer: row is 1;
 2982   begin
 2983     block
 2984       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 2985                                  " (" & state.fieldName & " " & fieldType & ")");
 2986       execute(state.statement);
 2987       insert(testDb, state, "NULL", expect &:= 0_/1_);
 2988       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 2989                                  " (" & state.fieldName & ") VALUES (?)");
 2990       insert(state, NULL,  expect &:= 0_/1_);
 2991 
 2992       if scale > 0 then
 2993         # Positive values
 2994         insert(testDb, state, str(1_ / 10_ ** scale), expect &:= 1_ / 10_ ** scale);
 2995         bigValue := pred(10_ ** literalPrecision) / 10_ ** scale;
 2996         insert(testDb, state, str(bigValue), expect &:= bigValue);
 2997         bigValue := 10_ ** pred(literalPrecision) / 10_ ** scale;
 2998         insert(testDb, state, str(bigValue), expect &:= bigValue);
 2999         bigValue := 1234567890_ / 10_ ** scale;
 3000         insert(testDb, state, str(bigValue), expect &:= bigValue);
 3001         bigValue := 123456789012345_ / 10_ ** scale;
 3002         insert(testDb, state, str(bigValue), expect &:= bigValue);
 3003         bigValue := (1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_ div
 3004                      10_ ** (100 - literalPrecision)) / 10_ ** scale;
 3005         insert(testDb, state, str(bigValue), expect &:= bigValue);
 3006 
 3007         # Negative values:
 3008         insert(testDb, state, str(-1_ / 10_ ** scale), expect &:= -1_ / 10_ ** scale);
 3009         bigValue := -pred(10_ ** literalPrecision) / 10_ ** scale;
 3010         insert(testDb, state, str(bigValue), expect &:= bigValue);
 3011         bigValue := -10_ ** pred(literalPrecision) / 10_ ** scale;
 3012         insert(testDb, state, str(bigValue), expect &:= bigValue);
 3013         bigValue := -1234567890_ / 10_ ** scale;
 3014         insert(testDb, state, str(bigValue), expect &:= bigValue);
 3015         bigValue := -123456789012345_ / 10_ ** scale;
 3016         insert(testDb, state, str(bigValue), expect &:= bigValue);
 3017         bigValue := -(1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_ div
 3018                      10_ ** (100 - literalPrecision)) / 10_ ** scale;
 3019         insert(testDb, state, str(bigValue), expect &:= bigValue);
 3020       else
 3021         # We use integer literals here, because some databases (Firebird)
 3022         # refuse some floating point literals (999999999999999999.0),
 3023         # when the scale is zero and the literalPrecision is at the maximum (18).
 3024         # Positive values
 3025         insert(testDb, state, 10_ ** (-scale) / 1_ digits 0, expect &:= 10_ ** (-scale) / 1_);
 3026         bigValue := pred(10_ ** literalPrecision) * 10_ ** (-scale) / 1_;
 3027         insert(testDb, state, bigValue digits 0, expect &:= bigValue);
 3028         bigValue := (1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_ div
 3029                      10_ ** (100 - literalPrecision)) * 10_ ** (-scale) / 1_;
 3030         insert(testDb, state, bigValue digits 0, expect &:= bigValue);
 3031 
 3032         # Negative values:
 3033         insert(testDb, state, -10_ ** (-scale) / 1_ digits 0, expect &:= -10_ ** (-scale) / 1_);
 3034         bigValue := -pred(10_ ** literalPrecision) * 10_ ** (-scale) / 1_;
 3035         insert(testDb, state, bigValue digits 0, expect &:= bigValue);
 3036         bigValue := -(1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_ div
 3037                      10_ ** (100 - literalPrecision)) * 10_ ** (-scale) / 1_;
 3038         insert(testDb, state, bigValue digits 0, expect &:= bigValue);
 3039       end if;
 3040 
 3041       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 3042                                  " (" & state.fieldName & ") VALUES (?)");
 3043       insert(state, 0_/1_, expect &:= 0_/1_);
 3044       if scale > 0 then
 3045         # Positive values
 3046         insert(state, 1_ / 10_ ** scale, expect &:= 1_ / 10_ ** scale);
 3047         bigValue := pred(10_ ** precision) / 10_ ** scale;
 3048         insert(state, bigValue, expect &:= bigValue);
 3049         bigValue := 10_ ** pred(precision) / 10_ ** scale;
 3050         insert(state, bigValue, expect &:= bigValue);
 3051         bigValue := 1234567890_ / 10_ ** scale;
 3052         insert(state, bigValue, expect &:= bigValue);
 3053         bigValue := 123456789012345_ / 10_ ** scale;
 3054         insert(state, bigValue, expect &:= bigValue);
 3055         bigValue := (1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_ div
 3056                      10_ ** (100 - precision)) / 10_ ** scale;
 3057         insert(state, bigValue, expect &:= bigValue);
 3058 
 3059         # Negative values:
 3060         insert(state, -1_ / 10_ ** scale, expect &:= -1_ / 10_ ** scale);
 3061         bigValue := -pred(10_ ** precision) / 10_ ** scale;
 3062         insert(state, bigValue, expect &:= bigValue);
 3063         bigValue := -10_ ** pred(precision) / 10_ ** scale;
 3064         insert(state, bigValue, expect &:= bigValue);
 3065         bigValue := -1234567890_ / 10_ ** scale;
 3066         insert(state, bigValue, expect &:= bigValue);
 3067         bigValue := -123456789012345_ / 10_ ** scale;
 3068         insert(state, bigValue, expect &:= bigValue);
 3069         bigValue := -(1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_ div
 3070                      10_ ** (100 - precision)) / 10_ ** scale;
 3071         insert(state, bigValue, expect &:= bigValue);
 3072       else
 3073         # Positive values
 3074         insert(state, 10_ ** (-scale) / 1_, expect &:= 10_ ** (-scale) / 1_);
 3075         bigValue := pred(10_ ** precision) * 10_ ** (-scale) / 1_;
 3076         insert(state, bigValue, expect &:= bigValue);
 3077         bigValue := (1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_ div
 3078                      10_ ** (100 - precision)) * 10_ ** (-scale) / 1_;
 3079         insert(state, bigValue, expect &:= bigValue);
 3080 
 3081         # Negative values:
 3082         insert(state, -10_ ** (-scale) / 1_, expect &:= -10_ ** (-scale) / 1_);
 3083         bigValue := -pred(10_ ** precision) * 10_ ** (-scale) / 1_;
 3084         insert(state, bigValue, expect &:= bigValue);
 3085         bigValue := -(1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890_ div
 3086                      10_ ** (100 - precision)) * 10_ ** (-scale) / 1_;
 3087         insert(state, bigValue, expect &:= bigValue);
 3088       end if;
 3089       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 3090       execute(state.statement);
 3091       while fetch(state.statement) do
 3092         bigRatColumn := column(state.statement, 1, bigRational);
 3093         if bigRatColumn <> expect[row] then
 3094           state.okay := FALSE;
 3095           if state.details then
 3096             writeln(" *** testAnyRationalField: Row: " <& row <&
 3097                     " Expected " <& expect[row] <& " found bigRational " <& bigRatColumn);
 3098           end if;
 3099         end if;
 3100         if row <= 2 and not isNull(state.statement, 1) then
 3101           state.okay := FALSE;
 3102           if state.details then
 3103             writeln(" *** testAnyRationalField: Row: " <& row <&
 3104                     " Expected NULL found bigRational " <& bigRatColumn);
 3105           end if;
 3106         end if;
 3107         if expect[row] = bigRational(str(float(str(expect[row])))) then
 3108           # The expected value is representable as float.
 3109           floatColumn := column(state.statement, 1, float);
 3110           if floatColumn <> float(str(expect[row])) then
 3111             state.okay := FALSE;
 3112             if state.details then
 3113               writeln(" *** testAnyRationalField: Row: " <& row <&
 3114                       " Expected " <& expect[row] <& " found float " <& floatColumn);
 3115               # writeln("numerator: " <& expect[row].numerator);
 3116               # writeln("denominator: " <& expect[row].denominator);
 3117             end if;
 3118           end if;
 3119           if row <= 2 and not isNull(state.statement, 1) then
 3120             state.okay := FALSE;
 3121             if state.details then
 3122               writeln(" *** testAnyRationalField: Row: " <& row <&
 3123                       " Expected NULL found float " <& floatColumn);
 3124             end if;
 3125           end if;
 3126         end if;
 3127         if scale = 0 and trunc(expect[row]) >= bigInteger(integer.first) and
 3128             trunc(expect[row]) <= bigInteger(integer.last) then
 3129           integerColumn := column(state.statement, 1, integer);
 3130           if integerColumn <> integer(expect[row] digits 0) then
 3131             state.okay := FALSE;
 3132             if state.details then
 3133               writeln(" *** testAnyRationalField: Row: " <& row <&
 3134                       " Expected " <& expect[row] digits 0 <& " found integer " <& integerColumn);
 3135             end if;
 3136           end if;
 3137           if row <= 2 and not isNull(state.statement, 1) then
 3138             state.okay := FALSE;
 3139             if state.details then
 3140               writeln(" *** testAnyRationalField: Row: " <& row <&
 3141                     " Expected NULL found integer " <& integerColumn);
 3142             end if;
 3143           end if;
 3144         end if;
 3145         if row > 2 and isNull(state.statement, 1) then
 3146           state.okay := FALSE;
 3147           if state.details then
 3148             writeln(" *** testAnyRationalField " <& state.tableName <& ": Row: " <& row <&
 3149                     " Expected " <& expect[row] <& " found NULL");
 3150           end if;
 3151         end if;
 3152         incr(row);
 3153       end while;
 3154     exception
 3155       catch RANGE_ERROR:
 3156         state.okay := FALSE;
 3157         writeln(" *** RANGE_ERROR was raised");
 3158       catch FILE_ERROR:
 3159         state.okay := FALSE;
 3160         writeln(" *** FILE_ERROR was raised");
 3161       catch DATABASE_ERROR:
 3162         state.okay := FALSE;
 3163         writeln(" *** DATABASE_ERROR was raised");
 3164     end block;
 3165     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 3166     execute(state.statement);
 3167   end func;
 3168 
 3169 
 3170 const proc: testDecimalField (in database: testDb, in dbCategory: databaseKind) is func
 3171   local
 3172     var testState: state is testState("decimalTest", "decimalField", FALSE);
 3173     var integer: scale is 0;
 3174   begin
 3175     if state.details then
 3176       writeln("testDecimalField: " <& databaseKind);
 3177     end if;
 3178     for scale range minDecimalScale(databaseKind) to maxDecimalScale(databaseKind) do
 3179       testAnyRationalField(testDb, state,
 3180                            decimalType(databaseKind, scale),
 3181                            maxDecimalPrecision(databaseKind),
 3182                            maxDecimalLiteralPrecision(databaseKind), scale);
 3183     end for;
 3184 
 3185     if state.okay then
 3186       writeln("Inserting and fetching decimal fields works okay.");
 3187     else
 3188       writeln(" *** Inserting and fetching decimal fields does not work okay.");
 3189     end if;
 3190   end func;
 3191 
 3192 
 3193 const proc: testNumericField (in database: testDb, in dbCategory: databaseKind) is func
 3194   local
 3195     var testState: state is testState("numericTest", "numericField", FALSE);
 3196     var integer: scale is 0;
 3197   begin
 3198     if state.details then
 3199       writeln("testNumericField: " <& databaseKind);
 3200     end if;
 3201     for scale range minNumericScale(databaseKind) to maxNumericScale(databaseKind) do
 3202       testAnyRationalField(testDb, state,
 3203                            numericType(databaseKind, scale),
 3204                            maxNumericPrecision(databaseKind),
 3205                            maxNumericLiteralPrecision(databaseKind), scale);
 3206     end for;
 3207 
 3208     if state.okay then
 3209       writeln("Inserting and fetching numeric fields works okay.");
 3210     else
 3211       writeln(" *** Inserting and fetching numeric fields does not work okay.");
 3212     end if;
 3213   end func;
 3214 
 3215 
 3216 const proc: testChar1AsciiField (in database: testDb, in dbCategory: databaseKind) is func
 3217   local
 3218     var testState: state is testState("char1AsciiTest", "char1AsciiField", FALSE);
 3219     var array string: expect is 0 times "";
 3220     var string: stringColumn is "";
 3221     var integer: row is 1;
 3222   begin
 3223     if state.details then
 3224       writeln("testChar1AsciiField: " <& databaseKind);
 3225     end if;
 3226     block
 3227       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 3228                                  " (" & state.fieldName & " CHAR)");
 3229       execute(state.statement);
 3230       insert(testDb, state, "NULL", expect &:= "");
 3231       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 3232                                  " (" & state.fieldName & ") VALUES (?)");
 3233       insert(state, NULL,  expect &:= "");
 3234 
 3235       insert(testDb, state, "''",      expect &:= "");
 3236       if nullAllowedInStringLiteral(databaseKind) then
 3237         insert(testDb, state, "'\0;'", expect &:= "\0;");
 3238       end if;
 3239       insert(testDb, state, "'\1;'",   expect &:= "\1;");
 3240       insert(testDb, state, "'\2;'",   expect &:= "\2;");
 3241       insert(testDb, state, "'\3;'",   expect &:= "\3;");
 3242       insert(testDb, state, "'\4;'",   expect &:= "\4;");
 3243       insert(testDb, state, "'\5;'",   expect &:= "\5;");
 3244       insert(testDb, state, "'\6;'",   expect &:= "\6;");
 3245       insert(testDb, state, "'\7;'",   expect &:= "\7;");
 3246       insert(testDb, state, "'\8;'",   expect &:= "\8;");
 3247       insert(testDb, state, "'\9;'",   expect &:= "\9;");
 3248       insert(testDb, state, "'\10;'",  expect &:= "\10;");
 3249       insert(testDb, state, "'\11;'",  expect &:= "\11;");
 3250       insert(testDb, state, "'\12;'",  expect &:= "\12;");
 3251       insert(testDb, state, "'\13;'",  expect &:= "\13;");
 3252       insert(testDb, state, "'\14;'",  expect &:= "\14;");
 3253       insert(testDb, state, "'\15;'",  expect &:= "\15;");
 3254       insert(testDb, state, "'\16;'",  expect &:= "\16;");
 3255       insert(testDb, state, "'\17;'",  expect &:= "\17;");
 3256       insert(testDb, state, "'\18;'",  expect &:= "\18;");
 3257       insert(testDb, state, "'\19;'",  expect &:= "\19;");
 3258       insert(testDb, state, "'\20;'",  expect &:= "\20;");
 3259       insert(testDb, state, "'\21;'",  expect &:= "\21;");
 3260       insert(testDb, state, "'\22;'",  expect &:= "\22;");
 3261       insert(testDb, state, "'\23;'",  expect &:= "\23;");
 3262       insert(testDb, state, "'\24;'",  expect &:= "\24;");
 3263       insert(testDb, state, "'\25;'",  expect &:= "\25;");
 3264       insert(testDb, state, "'\26;'",  expect &:= "\26;");
 3265       insert(testDb, state, "'\27;'",  expect &:= "\27;");
 3266       insert(testDb, state, "'\28;'",  expect &:= "\28;");
 3267       insert(testDb, state, "'\29;'",  expect &:= "\29;");
 3268       insert(testDb, state, "'\30;'",  expect &:= "\30;");
 3269       insert(testDb, state, "'\31;'",  expect &:= "\31;");
 3270       if charFieldPreservesTrailingSpaces(databaseKind) then
 3271         # Reading a char field preserves trailing spaces.
 3272         insert(testDb, state, "' '",   expect &:= " ");
 3273       else
 3274         # Reading a char field removes trailing spaces.
 3275         insert(testDb, state, "' '",   expect &:= "");
 3276       end if;
 3277       insert(testDb, state, "'!'",     expect &:= "!");
 3278       insert(testDb, state, "'\"'",    expect &:= "\"");
 3279       insert(testDb, state, "'#'",     expect &:= "#");
 3280       insert(testDb, state, "'$'",     expect &:= "$");
 3281       insert(testDb, state, "'%'",     expect &:= "%");
 3282       insert(testDb, state, "'&'",     expect &:= "&");
 3283       insert(testDb, state, "''''",    expect &:= "'");
 3284       insert(testDb, state, "'('",     expect &:= "(");
 3285       insert(testDb, state, "')'",     expect &:= ")");
 3286       insert(testDb, state, "'*'",     expect &:= "*");
 3287       insert(testDb, state, "'+'",     expect &:= "+");
 3288       insert(testDb, state, "','",     expect &:= ",");
 3289       insert(testDb, state, "'-'",     expect &:= "-");
 3290       insert(testDb, state, "'.'",     expect &:= ".");
 3291       insert(testDb, state, "'/'",     expect &:= "/");
 3292       insert(testDb, state, "'0'",     expect &:= "0");
 3293       insert(testDb, state, "'1'",     expect &:= "1");
 3294       insert(testDb, state, "'9'",     expect &:= "9");
 3295       insert(testDb, state, "':'",     expect &:= ":");
 3296       insert(testDb, state, "';'",     expect &:= ";");
 3297       insert(testDb, state, "'<'",     expect &:= "<");
 3298       insert(testDb, state, "'='",     expect &:= "=");
 3299       insert(testDb, state, "'>'",     expect &:= ">");
 3300       insert(testDb, state, "'?'",     expect &:= "?");
 3301       insert(testDb, state, "'@'",     expect &:= "@");
 3302       insert(testDb, state, "'A'",     expect &:= "A");
 3303       insert(testDb, state, "'Z'",     expect &:= "Z");
 3304       insert(testDb, state, "'['",     expect &:= "[");
 3305       insert(testDb, state, "'\\'",    expect &:= "\\");
 3306       insert(testDb, state, "']'",     expect &:= "]");
 3307       insert(testDb, state, "'^'",     expect &:= "^");
 3308       insert(testDb, state, "'_'",     expect &:= "_");
 3309       insert(testDb, state, "'`'",     expect &:= "`");
 3310       insert(testDb, state, "'a'",     expect &:= "a");
 3311       insert(testDb, state, "'z'",     expect &:= "z");
 3312       insert(testDb, state, "'{'",     expect &:= "{");
 3313       insert(testDb, state, "'|'",     expect &:= "|");
 3314       insert(testDb, state, "'}'",     expect &:= "}");
 3315       insert(testDb, state, "'~'",     expect &:= "~");
 3316       insert(testDb, state, "'\127;'", expect &:= "\127;");
 3317 
 3318       insert(testDb, state, "0",     expect &:= "0");
 3319       insert(testDb, state, "1",     expect &:= "1");
 3320       insert(testDb, state, "9",     expect &:= "9");
 3321 
 3322       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 3323                                  " (" & state.fieldName & ") VALUES (?)");
 3324       insert(state, "",    expect &:= "");
 3325       if nullAllowedInString(databaseKind) then
 3326         insert(state, "\0;", expect &:= "\0;");
 3327       end if;
 3328       insert(state, "\1;",   expect &:= "\1;");
 3329       insert(state, "\2;",   expect &:= "\2;");
 3330       insert(state, "\3;",   expect &:= "\3;");
 3331       insert(state, "\4;",   expect &:= "\4;");
 3332       insert(state, "\5;",   expect &:= "\5;");
 3333       insert(state, "\6;",   expect &:= "\6;");
 3334       insert(state, "\7;",   expect &:= "\7;");
 3335       insert(state, "\8;",   expect &:= "\8;");
 3336       insert(state, "\9;",   expect &:= "\9;");
 3337       insert(state, "\10;",  expect &:= "\10;");
 3338       insert(state, "\11;",  expect &:= "\11;");
 3339       insert(state, "\12;",  expect &:= "\12;");
 3340       insert(state, "\13;",  expect &:= "\13;");
 3341       insert(state, "\14;",  expect &:= "\14;");
 3342       insert(state, "\15;",  expect &:= "\15;");
 3343       insert(state, "\16;",  expect &:= "\16;");
 3344       insert(state, "\17;",  expect &:= "\17;");
 3345       insert(state, "\18;",  expect &:= "\18;");
 3346       insert(state, "\19;",  expect &:= "\19;");
 3347       insert(state, "\20;",  expect &:= "\20;");
 3348       insert(state, "\21;",  expect &:= "\21;");
 3349       insert(state, "\22;",  expect &:= "\22;");
 3350       insert(state, "\23;",  expect &:= "\23;");
 3351       insert(state, "\24;",  expect &:= "\24;");
 3352       insert(state, "\25;",  expect &:= "\25;");
 3353       insert(state, "\26;",  expect &:= "\26;");
 3354       insert(state, "\27;",  expect &:= "\27;");
 3355       insert(state, "\28;",  expect &:= "\28;");
 3356       insert(state, "\29;",  expect &:= "\29;");
 3357       insert(state, "\30;",  expect &:= "\30;");
 3358       insert(state, "\31;",  expect &:= "\31;");
 3359       if charFieldPreservesTrailingSpaces(databaseKind) then
 3360         # Reading a char field preserves trailing spaces.
 3361         insert(state, " ",   expect &:= " ");
 3362       else
 3363         # Reading a char field removes trailing spaces.
 3364         insert(state, " ",   expect &:= "");
 3365       end if;
 3366       insert(state, "!",     expect &:= "!");
 3367       insert(state, "\"",    expect &:= "\"");
 3368       insert(state, "#",     expect &:= "#");
 3369       insert(state, "$",     expect &:= "$");
 3370       insert(state, "%",     expect &:= "%");
 3371       insert(state, "&",     expect &:= "&");
 3372       insert(state, "'",     expect &:= "'");
 3373       insert(state, "(",     expect &:= "(");
 3374       insert(state, ")",     expect &:= ")");
 3375       insert(state, "*",     expect &:= "*");
 3376       insert(state, "+",     expect &:= "+");
 3377       insert(state, ",",     expect &:= ",");
 3378       insert(state, "-",     expect &:= "-");
 3379       insert(state, ".",     expect &:= ".");
 3380       insert(state, "/",     expect &:= "/");
 3381       insert(state, "0",     expect &:= "0");
 3382       insert(state, "1",     expect &:= "1");
 3383       insert(state, "9",     expect &:= "9");
 3384       insert(state, ":",     expect &:= ":");
 3385       insert(state, ";",     expect &:= ";");
 3386       insert(state, "<",     expect &:= "<");
 3387       insert(state, "=",     expect &:= "=");
 3388       insert(state, ">",     expect &:= ">");
 3389       insert(state, "?",     expect &:= "?");
 3390       insert(state, "@",     expect &:= "@");
 3391       insert(state, "A",     expect &:= "A");
 3392       insert(state, "Z",     expect &:= "Z");
 3393       insert(state, "[",     expect &:= "[");
 3394       insert(state, "\\",    expect &:= "\\");
 3395       insert(state, "]",     expect &:= "]");
 3396       insert(state, "^",     expect &:= "^");
 3397       insert(state, "_",     expect &:= "_");
 3398       insert(state, "`",     expect &:= "`");
 3399       insert(state, "a",     expect &:= "a");
 3400       insert(state, "z",     expect &:= "z");
 3401       insert(state, "{",     expect &:= "{");
 3402       insert(state, "|",     expect &:= "|");
 3403       insert(state, "}",     expect &:= "}");
 3404       insert(state, "~",     expect &:= "~");
 3405       insert(state, "\127;", expect &:= "\127;");
 3406 
 3407       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 3408                                  " (" & state.fieldName & ") VALUES (?)");
 3409       insert(state, 0,     expect &:= "0");
 3410       insert(state, 1,     expect &:= "1");
 3411       insert(state, 9,     expect &:= "9");
 3412 
 3413       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 3414                                  " (" & state.fieldName & ") VALUES (?)");
 3415       insert(state, 0_,    expect &:= "0");
 3416       insert(state, 1_,    expect &:= "1");
 3417       insert(state, 9_,    expect &:= "9");
 3418 
 3419       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 3420       execute(state.statement);
 3421       while fetch(state.statement) do
 3422         stringColumn := column(state.statement, 1, string);
 3423         if stringColumn <> expect[row] then
 3424           state.okay := FALSE;
 3425           if state.details then
 3426             writeln(" *** testChar1AsciiField: Row: " <& row <&
 3427                     " Expected " <& literal(expect[row]) <&
 3428                     " found " <& literal(stringColumn));
 3429           end if;
 3430         end if;
 3431         if row <= 2 and not isNull(state.statement, 1) then
 3432           state.okay := FALSE;
 3433           if state.details then
 3434             writeln(" *** testChar1AsciiField: Row: " <& row <&
 3435                     " Expected NULL found " <& stringColumn);
 3436           end if;
 3437         end if;
 3438         if expect[row] <> "" and isNull(state.statement, 1) then
 3439           state.okay := FALSE;
 3440           if state.details then
 3441             writeln(" *** testChar1AsciiField: Row: " <& row <&
 3442                     " Expected " <& expect[row] <& " found NULL");
 3443           end if;
 3444         end if;
 3445         incr(row);
 3446       end while;
 3447     exception
 3448       catch RANGE_ERROR:
 3449         state.okay := FALSE;
 3450         writeln(" *** RANGE_ERROR was raised");
 3451       catch FILE_ERROR:
 3452         state.okay := FALSE;
 3453         writeln(" *** FILE_ERROR was raised");
 3454       catch DATABASE_ERROR:
 3455         state.okay := FALSE;
 3456         writeln(" *** DATABASE_ERROR was raised");
 3457     end block;
 3458     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 3459     execute(state.statement);
 3460 
 3461     if state.okay then
 3462       writeln("Inserting and fetching char(1) fields with ASCII characters works okay.");
 3463     else
 3464       writeln(" *** Inserting and fetching char(1) fields with ASCII characters does not work okay.");
 3465     end if;
 3466   end func;
 3467 
 3468 
 3469 const proc: testChar1Latin1Field (in database: testDb, in dbCategory: databaseKind) is func
 3470   local
 3471     var testState: state is testState("char1Latin1Test", "char1Latin1Field", FALSE);
 3472     var array string: expect is 0 times "";
 3473     var string: stringColumn is "";
 3474     var integer: row is 1;
 3475   begin
 3476     if state.details then
 3477       writeln("testChar1Latin1Field: " <& databaseKind);
 3478     end if;
 3479     block
 3480       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 3481                                  " (" & state.fieldName & " CHAR)");
 3482       execute(state.statement);
 3483       insert(testDb, state, "NULL", expect &:= "");
 3484       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 3485                                  " (" & state.fieldName & ") VALUES (?)");
 3486       insert(state, NULL,  expect &:= "");
 3487 
 3488       insert(testDb, state, "''",      expect &:= "");
 3489       if nullAllowedInStringLiteral(databaseKind) then
 3490         insert(testDb, state, "'\0;'", expect &:= "\0;");
 3491       end if;
 3492       insert(testDb, state, "'\1;'",   expect &:= "\1;");
 3493       insert(testDb, state, "'\b'",    expect &:= "\b");
 3494       insert(testDb, state, "'\t'",    expect &:= "\t");
 3495       insert(testDb, state, "'\n'",    expect &:= "\n");
 3496       insert(testDb, state, "'\e'",    expect &:= "\e");
 3497       if charFieldPreservesTrailingSpaces(databaseKind) then
 3498         # Reading a char field preserves trailing spaces.
 3499         insert(testDb, state, "' '",   expect &:= " ");
 3500       else
 3501         # Reading a char field removes trailing spaces.
 3502         insert(testDb, state, "' '",   expect &:= "");
 3503       end if;
 3504       insert(testDb, state, "'!'",     expect &:= "!");
 3505       insert(testDb, state, "'\"'",    expect &:= "\"");
 3506       insert(testDb, state, "''''",    expect &:= "'");
 3507       insert(testDb, state, "'0'",     expect &:= "0");
 3508       insert(testDb, state, "'1'",     expect &:= "1");
 3509       insert(testDb, state, "'9'",     expect &:= "9");
 3510       insert(testDb, state, "'?'",     expect &:= "?");
 3511       insert(testDb, state, "'X'",     expect &:= "X");
 3512       insert(testDb, state, "'\\'",    expect &:= "\\");
 3513       insert(testDb, state, "'^'",     expect &:= "^");
 3514       insert(testDb, state, "'`'",     expect &:= "`");
 3515       insert(testDb, state, "'a'",     expect &:= "a");
 3516       insert(testDb, state, "'~'",     expect &:= "~");
 3517       insert(testDb, state, "'\127;'", expect &:= "\127;");
 3518       insert(testDb, state, "'\128;'", expect &:= "\128;");
 3519       insert(testDb, state, "'\129;'", expect &:= "\129;");
 3520       insert(testDb, state, "'\130;'", expect &:= "\130;");
 3521       insert(testDb, state, "'\131;'", expect &:= "\131;");
 3522       insert(testDb, state, "'\132;'", expect &:= "\132;");
 3523       insert(testDb, state, "'\133;'", expect &:= "\133;");
 3524       insert(testDb, state, "'\134;'", expect &:= "\134;");
 3525       insert(testDb, state, "'\135;'", expect &:= "\135;");
 3526       insert(testDb, state, "'\136;'", expect &:= "\136;");
 3527       insert(testDb, state, "'\137;'", expect &:= "\137;");
 3528       insert(testDb, state, "'\138;'", expect &:= "\138;");
 3529       insert(testDb, state, "'\139;'", expect &:= "\139;");
 3530       insert(testDb, state, "'\140;'", expect &:= "\140;");
 3531       insert(testDb, state, "'\141;'", expect &:= "\141;");
 3532       insert(testDb, state, "'\142;'", expect &:= "\142;");
 3533       insert(testDb, state, "'\143;'", expect &:= "\143;");
 3534       insert(testDb, state, "'\144;'", expect &:= "\144;");
 3535       insert(testDb, state, "'\145;'", expect &:= "\145;");
 3536       insert(testDb, state, "'\146;'", expect &:= "\146;");
 3537       insert(testDb, state, "'\147;'", expect &:= "\147;");
 3538       insert(testDb, state, "'\148;'", expect &:= "\148;");
 3539       insert(testDb, state, "'\149;'", expect &:= "\149;");
 3540       insert(testDb, state, "'\150;'", expect &:= "\150;");
 3541       insert(testDb, state, "'\151;'", expect &:= "\151;");
 3542       insert(testDb, state, "'\152;'", expect &:= "\152;");
 3543       insert(testDb, state, "'\153;'", expect &:= "\153;");
 3544       insert(testDb, state, "'\154;'", expect &:= "\154;");
 3545       insert(testDb, state, "'\155;'", expect &:= "\155;");
 3546       insert(testDb, state, "'\156;'", expect &:= "\156;");
 3547       insert(testDb, state, "'\157;'", expect &:= "\157;");
 3548       insert(testDb, state, "'\158;'", expect &:= "\158;");
 3549       insert(testDb, state, "'\159;'", expect &:= "\159;");
 3550       insert(testDb, state, "'\160;'", expect &:= "\160;");
 3551       insert(testDb, state, "'¡'",     expect &:= "¡");
 3552       insert(testDb, state, "'¤'",     expect &:= "¤");
 3553       insert(testDb, state, "'§'",     expect &:= "§");
 3554       insert(testDb, state, "'¬'",     expect &:= "¬");
 3555       insert(testDb, state, "'­'",     expect &:= "­");
 3556       insert(testDb, state, "'µ'",     expect &:= "µ");
 3557       insert(testDb, state, "'¿'",     expect &:= "¿");
 3558       insert(testDb, state, "'Ä'",     expect &:= "Ä");
 3559       insert(testDb, state, "'×'",     expect &:= "×");
 3560       insert(testDb, state, "'ß'",     expect &:= "ß");
 3561       insert(testDb, state, "'ä'",     expect &:= "ä");
 3562       insert(testDb, state, "'÷'",     expect &:= "÷");
 3563       insert(testDb, state, "'ÿ'",     expect &:= "ÿ");
 3564 
 3565       insert(testDb, state, "0",     expect &:= "0");
 3566       insert(testDb, state, "1",     expect &:= "1");
 3567       insert(testDb, state, "9",     expect &:= "9");
 3568 
 3569       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 3570                                  " (" & state.fieldName & ") VALUES (?)");
 3571       insert(state, "",    expect &:= "");
 3572       if nullAllowedInString(databaseKind) then
 3573         insert(state, "\0;", expect &:= "\0;");
 3574       end if;
 3575       insert(state, "\1;",   expect &:= "\1;");
 3576       insert(state, "\b",    expect &:= "\b");
 3577       insert(state, "\t",    expect &:= "\t");
 3578       insert(state, "\n",    expect &:= "\n");
 3579       insert(state, "\e",    expect &:= "\e");
 3580       if charFieldPreservesTrailingSpaces(databaseKind) then
 3581         # Reading a char field preserves trailing spaces.
 3582         insert(state, " ",   expect &:= " ");
 3583       else
 3584         # Reading a char field removes trailing spaces.
 3585         insert(state, " ",   expect &:= "");
 3586       end if;
 3587       insert(state, "!",     expect &:= "!");
 3588       insert(state, "\"",    expect &:= "\"");
 3589       insert(state, "'",     expect &:= "'");
 3590       insert(state, "0",     expect &:= "0");
 3591       insert(state, "1",     expect &:= "1");
 3592       insert(state, "9",     expect &:= "9");
 3593       insert(state, "?",     expect &:= "?");
 3594       insert(state, "X",     expect &:= "X");
 3595       insert(state, "\\",    expect &:= "\\");
 3596       insert(state, "^",     expect &:= "^");
 3597       insert(state, "`",     expect &:= "`");
 3598       insert(state, "a",     expect &:= "a");
 3599       insert(state, "~",     expect &:= "~");
 3600       insert(state, "\127;", expect &:= "\127;");
 3601       insert(state, "\128;", expect &:= "\128;");
 3602       insert(state, "\129;", expect &:= "\129;");
 3603       insert(state, "\130;", expect &:= "\130;");
 3604       insert(state, "\131;", expect &:= "\131;");
 3605       insert(state, "\132;", expect &:= "\132;");
 3606       insert(state, "\133;", expect &:= "\133;");
 3607       insert(state, "\134;", expect &:= "\134;");
 3608       insert(state, "\135;", expect &:= "\135;");
 3609       insert(state, "\136;", expect &:= "\136;");
 3610       insert(state, "\137;", expect &:= "\137;");
 3611       insert(state, "\138;", expect &:= "\138;");
 3612       insert(state, "\139;", expect &:= "\139;");
 3613       insert(state, "\140;", expect &:= "\140;");
 3614       insert(state, "\141;", expect &:= "\141;");
 3615       insert(state, "\142;", expect &:= "\142;");
 3616       insert(state, "\143;", expect &:= "\143;");
 3617       insert(state, "\144;", expect &:= "\144;");
 3618       insert(state, "\145;", expect &:= "\145;");
 3619       insert(state, "\146;", expect &:= "\146;");
 3620       insert(state, "\147;", expect &:= "\147;");
 3621       insert(state, "\148;", expect &:= "\148;");
 3622       insert(state, "\149;", expect &:= "\149;");
 3623       insert(state, "\150;", expect &:= "\150;");
 3624       insert(state, "\151;", expect &:= "\151;");
 3625       insert(state, "\152;", expect &:= "\152;");
 3626       insert(state, "\153;", expect &:= "\153;");
 3627       insert(state, "\154;", expect &:= "\154;");
 3628       insert(state, "\155;", expect &:= "\155;");
 3629       insert(state, "\156;", expect &:= "\156;");
 3630       insert(state, "\157;", expect &:= "\157;");
 3631       insert(state, "\158;", expect &:= "\158;");
 3632       insert(state, "\159;", expect &:= "\159;");
 3633       insert(state, "\160;", expect &:= "\160;");
 3634       insert(state, "¡",     expect &:= "¡");
 3635       insert(state, "¤",     expect &:= "¤");
 3636       insert(state, "§",     expect &:= "§");
 3637       insert(state, "¬",     expect &:= "¬");
 3638       insert(state, "­",     expect &:= "­");
 3639       insert(state, "µ",     expect &:= "µ");
 3640       insert(state, "¿",     expect &:= "¿");
 3641       insert(state, "Ä",     expect &:= "Ä");
 3642       insert(state, "×",     expect &:= "×");
 3643       insert(state, "ß",     expect &:= "ß");
 3644       insert(state, "ä",     expect &:= "ä");
 3645       insert(state, "÷",     expect &:= "÷");
 3646       insert(state, "ÿ",     expect &:= "ÿ");
 3647 
 3648       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 3649                                  " (" & state.fieldName & ") VALUES (?)");
 3650       insert(state, 0,     expect &:= "0");
 3651       insert(state, 1,     expect &:= "1");
 3652       insert(state, 9,     expect &:= "9");
 3653 
 3654       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 3655                                  " (" & state.fieldName & ") VALUES (?)");
 3656       insert(state, 0_,    expect &:= "0");
 3657       insert(state, 1_,    expect &:= "1");
 3658       insert(state, 9_,    expect &:= "9");
 3659 
 3660       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 3661       execute(state.statement);
 3662       while fetch(state.statement) do
 3663         stringColumn := column(state.statement, 1, string);
 3664         if stringColumn <> expect[row] then
 3665           state.okay := FALSE;
 3666           if state.details then
 3667             writeln(" *** testChar1Latin1Field: Row: " <& row <&
 3668                     " Expected " <& literal(expect[row]) <&
 3669                     " found " <& literal(stringColumn));
 3670           end if;
 3671         end if;
 3672         if row <= 2 and not isNull(state.statement, 1) then
 3673           state.okay := FALSE;
 3674           if state.details then
 3675             writeln(" *** testChar1Latin1Field: Row: " <& row <&
 3676                     " Expected NULL found " <& stringColumn);
 3677           end if;
 3678         end if;
 3679         if expect[row] <> "" and isNull(state.statement, 1) then
 3680           state.okay := FALSE;
 3681           if state.details then
 3682             writeln(" *** testChar1Latin1Field: Row: " <& row <&
 3683                     " Expected " <& expect[row] <& " found NULL");
 3684           end if;
 3685         end if;
 3686         incr(row);
 3687       end while;
 3688     exception
 3689       catch RANGE_ERROR:
 3690         state.okay := FALSE;
 3691         writeln(" *** RANGE_ERROR was raised");
 3692       catch FILE_ERROR:
 3693         state.okay := FALSE;
 3694         writeln(" *** FILE_ERROR was raised");
 3695       catch DATABASE_ERROR:
 3696         state.okay := FALSE;
 3697         writeln(" *** DATABASE_ERROR was raised");
 3698     end block;
 3699     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 3700     execute(state.statement);
 3701 
 3702     if state.okay then
 3703       writeln("Inserting and fetching char(1) fields with LATIN-1 characters works okay.");
 3704     else
 3705       writeln(" *** Inserting and fetching char(1) fields with LATIN-1 characters does not work okay.");
 3706     end if;
 3707   end func;
 3708 
 3709 
 3710 const proc: testCodePageField (in database: testDb, in integer: codePage,
 3711     in dbCategory: databaseKind) is func
 3712   local
 3713     var testState: state is testState("codePageTest", "codePageField", FALSE);
 3714     var array string: expect is 0 times "";
 3715     var string: stringColumn is "";
 3716     var integer: row is 1;
 3717   begin
 3718     if state.details then
 3719       writeln("testCodePageField: Code page: " <& codePage <& " " <& databaseKind);
 3720     end if;
 3721     block
 3722       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 3723                                  " (" & state.fieldName & " CHAR)");
 3724       execute(state.statement);
 3725       insert(testDb, state, "NULL", expect &:= "");
 3726       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 3727                                  " (" & state.fieldName & ") VALUES (?)");
 3728       insert(state, NULL,  expect &:= "");
 3729 
 3730       insert(testDb, state, "''",      expect &:= "");
 3731       if nullAllowedInStringLiteral(databaseKind) then
 3732         insert(testDb, state, "'\0;'", expect &:= "\0;");
 3733       end if;
 3734       insert(testDb, state, "'\1;'",   expect &:= "\1;");
 3735       insert(testDb, state, "'\b'",    expect &:= "\b");
 3736       insert(testDb, state, "'\t'",    expect &:= "\t");
 3737       insert(testDb, state, "'\n'",    expect &:= "\n");
 3738       insert(testDb, state, "'\e'",    expect &:= "\e");
 3739       if charFieldPreservesTrailingSpaces(databaseKind) then
 3740         # Reading a char field preserves trailing spaces.
 3741         insert(testDb, state, "' '",   expect &:= " ");
 3742       else
 3743         # Reading a char field removes trailing spaces.
 3744         insert(testDb, state, "' '",   expect &:= "");
 3745       end if;
 3746       insert(testDb, state, "'!'",     expect &:= "!");
 3747       insert(testDb, state, "'\"'",    expect &:= "\"");
 3748       insert(testDb, state, "''''",    expect &:= "'");
 3749       insert(testDb, state, "'0'",     expect &:= "0");
 3750       insert(testDb, state, "'1'",     expect &:= "1");
 3751       insert(testDb, state, "'9'",     expect &:= "9");
 3752       insert(testDb, state, "'?'",     expect &:= "?");
 3753       insert(testDb, state, "'X'",     expect &:= "X");
 3754       insert(testDb, state, "'\\'",    expect &:= "\\");
 3755       insert(testDb, state, "'^'",     expect &:= "^");
 3756       insert(testDb, state, "'`'",     expect &:= "`");
 3757       insert(testDb, state, "'a'",     expect &:= "a");
 3758       insert(testDb, state, "'~'",     expect &:= "~");
 3759       insert(testDb, state, "'\127;'", expect &:= "\127;");
 3760 
 3761       insert(testDb, state, "'€'",     expect &:= "€");
 3762       insert(testDb, state, "'\129;'", expect &:= "\129;");
 3763       insert(testDb, state, "'‚'",     expect &:= "‚");
 3764       # insert(testDb, state, "'\131;'", expect &:= "\131;");
 3765       insert(testDb, state, "'„'",     expect &:= "„");
 3766       insert(testDb, state, "'…'",     expect &:= "…");
 3767       insert(testDb, state, "'†'",     expect &:= "†");
 3768       insert(testDb, state, "'‡'",     expect &:= "‡");
 3769       # insert(testDb, state, "'\136;'", expect &:= "\136;");
 3770       insert(testDb, state, "'‰'",     expect &:= "‰");
 3771       insert(testDb, state, "'Š'",     expect &:= "Š");
 3772       insert(testDb, state, "'‹'",     expect &:= "‹");
 3773       if codePage = 1250 then
 3774         insert(testDb, state, "'Ś'",   expect &:= "Ś");
 3775         insert(testDb, state, "'Ť'",   expect &:= "Ť");
 3776       elsif codePage = 1252 then
 3777         insert(testDb, state, "'Œ'",   expect &:= "Œ");
 3778       end if;
 3779       insert(testDb, state, "'Ž'",     expect &:= "Ž");
 3780       if codePage = 1250 then
 3781         insert(testDb, state, "'Ź'",   expect &:= "Ź");
 3782       end if;
 3783       insert(testDb, state, "'\144;'", expect &:= "\144;");
 3784       insert(testDb, state, "'‘'",     expect &:= "‘");
 3785       insert(testDb, state, "'’'",     expect &:= "’");
 3786       insert(testDb, state, "'“'",     expect &:= "“");
 3787       insert(testDb, state, "'”'",     expect &:= "”");
 3788       insert(testDb, state, "'•'",     expect &:= "•");
 3789       insert(testDb, state, "'–'",     expect &:= "–");
 3790       insert(testDb, state, "'—'",     expect &:= "—");
 3791       # insert(testDb, state, "'\152;'", expect &:= "\152;");
 3792       insert(testDb, state, "'™'",     expect &:= "™");
 3793       insert(testDb, state, "'š'",     expect &:= "š");
 3794       insert(testDb, state, "'›'",     expect &:= "›");
 3795       if codePage = 1250 then
 3796         insert(testDb, state, "'ś'",   expect &:= "ś");
 3797         insert(testDb, state, "'ť'",   expect &:= "ť");
 3798       elsif codePage = 1252 then
 3799         insert(testDb, state, "'œ'",   expect &:= "œ");
 3800       end if;
 3801       insert(testDb, state, "'ž'",     expect &:= "ž");
 3802       if codePage = 1250 then
 3803         insert(testDb, state, "'ź'",   expect &:= "ź");
 3804       elsif codePage = 1252 then
 3805         insert(testDb, state, "'Ÿ'",   expect &:= "Ÿ");
 3806       end if;
 3807 
 3808       insert(testDb, state, "'\160;'", expect &:= "\160;");
 3809       insert(testDb, state, "'¡'",     expect &:= "¡");
 3810       insert(testDb, state, "'¤'",     expect &:= "¤");
 3811       insert(testDb, state, "'§'",     expect &:= "§");
 3812       insert(testDb, state, "'¬'",     expect &:= "¬");
 3813       insert(testDb, state, "'­'",     expect &:= "­");
 3814       insert(testDb, state, "'µ'",     expect &:= "µ");
 3815       insert(testDb, state, "'¿'",     expect &:= "¿");
 3816       insert(testDb, state, "'Ä'",     expect &:= "Ä");
 3817       insert(testDb, state, "'×'",     expect &:= "×");
 3818       insert(testDb, state, "'ß'",     expect &:= "ß");
 3819       insert(testDb, state, "'ä'",     expect &:= "ä");
 3820       insert(testDb, state, "'÷'",     expect &:= "÷");
 3821       insert(testDb, state, "'ÿ'",     expect &:= "ÿ");
 3822 
 3823       insert(testDb, state, "0",     expect &:= "0");
 3824       insert(testDb, state, "1",     expect &:= "1");
 3825       insert(testDb, state, "9",     expect &:= "9");
 3826 
 3827       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 3828                                  " (" & state.fieldName & ") VALUES (?)");
 3829       insert(state, "",    expect &:= "");
 3830       if nullAllowedInString(databaseKind) then
 3831         insert(state, "\0;", expect &:= "\0;");
 3832       end if;
 3833       insert(state, "\1;",   expect &:= "\1;");
 3834       insert(state, "\b",    expect &:= "\b");
 3835       insert(state, "\t",    expect &:= "\t");
 3836       insert(state, "\n",    expect &:= "\n");
 3837       insert(state, "\e",    expect &:= "\e");
 3838       if charFieldPreservesTrailingSpaces(databaseKind) then
 3839         # Reading a char field preserves trailing spaces.
 3840         insert(state, " ",   expect &:= " ");
 3841       else
 3842         # Reading a char field removes trailing spaces.
 3843         insert(state, " ",   expect &:= "");
 3844       end if;
 3845       insert(state, "!",     expect &:= "!");
 3846       insert(state, "\"",    expect &:= "\"");
 3847       insert(state, "'",     expect &:= "'");
 3848       insert(state, "0",     expect &:= "0");
 3849       insert(state, "1",     expect &:= "1");
 3850       insert(state, "9",     expect &:= "9");
 3851       insert(state, "?",     expect &:= "?");
 3852       insert(state, "X",     expect &:= "X");
 3853       insert(state, "\\",    expect &:= "\\");
 3854       insert(state, "^",     expect &:= "^");
 3855       insert(state, "`",     expect &:= "`");
 3856       insert(state, "a",     expect &:= "a");
 3857       insert(state, "~",     expect &:= "~");
 3858       insert(state, "\127;", expect &:= "\127;");
 3859 
 3860       insert(state, "€",     expect &:= "€");
 3861       insert(state, "\129;", expect &:= "\129;");
 3862       insert(state, "‚",     expect &:= "‚");
 3863       # insert(state, "\131;", expect &:= "\131;");
 3864       insert(state, "„",     expect &:= "„");
 3865       insert(state, "…",     expect &:= "…");
 3866       insert(state, "†",     expect &:= "†");
 3867       insert(state, "‡",     expect &:= "‡");
 3868       # insert(state, "\136;", expect &:= "\136;");
 3869       insert(state, "‰",     expect &:= "‰");
 3870       insert(state, "Š",     expect &:= "Š");
 3871       insert(state, "‹",     expect &:= "‹");
 3872       if codePage = 1250 then
 3873         insert(state, "Ś",   expect &:= "Ś");
 3874         insert(state, "Ť",   expect &:= "Ť");
 3875       elsif codePage = 1252 then
 3876         insert(state, "Œ",   expect &:= "Œ");
 3877       end if;
 3878       insert(state, "Ž",     expect &:= "Ž");
 3879       if codePage = 1250 then
 3880         insert(state, "Ź",   expect &:= "Ź");
 3881       end if;
 3882       insert(state, "\144;", expect &:= "\144;");
 3883       insert(state, "‘",     expect &:= "‘");
 3884       insert(state, "’",     expect &:= "’");
 3885       insert(state, "“",     expect &:= "“");
 3886       insert(state, "”",     expect &:= "”");
 3887       insert(state, "•",     expect &:= "•");
 3888       insert(state, "–",     expect &:= "–");
 3889       insert(state, "—",     expect &:= "—");
 3890       # insert(state, "\152;", expect &:= "\152;");
 3891       insert(state, "™",     expect &:= "™");
 3892       insert(state, "š",     expect &:= "š");
 3893       insert(state, "›",     expect &:= "›");
 3894       if codePage = 1250 then
 3895         insert(state, "ś",   expect &:= "ś");
 3896         insert(state, "ť",   expect &:= "ť");
 3897       elsif codePage = 1252 then
 3898         insert(state, "œ",   expect &:= "œ");
 3899       end if;
 3900       insert(state, "ž",     expect &:= "ž");
 3901       if codePage = 1250 then
 3902         insert(state, "ź",   expect &:= "ź");
 3903       elsif codePage = 1252 then
 3904         insert(state, "Ÿ",   expect &:= "Ÿ");
 3905       end if;
 3906 
 3907       insert(state, "\160;", expect &:= "\160;");
 3908       insert(state, "¡",     expect &:= "¡");
 3909       insert(state, "¤",     expect &:= "¤");
 3910       insert(state, "§",     expect &:= "§");
 3911       insert(state, "¬",     expect &:= "¬");
 3912       insert(state, "­",     expect &:= "­");
 3913       insert(state, "µ",     expect &:= "µ");
 3914       insert(state, "¿",     expect &:= "¿");
 3915       insert(state, "Ä",     expect &:= "Ä");
 3916       insert(state, "×",     expect &:= "×");
 3917       insert(state, "ß",     expect &:= "ß");
 3918       insert(state, "ä",     expect &:= "ä");
 3919       insert(state, "÷",     expect &:= "÷");
 3920       insert(state, "ÿ",     expect &:= "ÿ");
 3921 
 3922       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 3923                                  " (" & state.fieldName & ") VALUES (?)");
 3924       insert(state, 0,     expect &:= "0");
 3925       insert(state, 1,     expect &:= "1");
 3926       insert(state, 9,     expect &:= "9");
 3927 
 3928       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 3929                                  " (" & state.fieldName & ") VALUES (?)");
 3930       insert(state, 0_,    expect &:= "0");
 3931       insert(state, 1_,    expect &:= "1");
 3932       insert(state, 9_,    expect &:= "9");
 3933 
 3934       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 3935       execute(state.statement);
 3936       while fetch(state.statement) do
 3937         stringColumn := column(state.statement, 1, string);
 3938         if stringColumn <> expect[row] then
 3939           state.okay := FALSE;
 3940           if state.details then
 3941             writeln(" *** testCodePageField: Code page: " <& codePage <& " Row: " <& row <&
 3942                     " Expected " <& literal(expect[row]) <&
 3943                     " found " <& literal(stringColumn));
 3944           end if;
 3945         end if;
 3946         if row <= 2 and not isNull(state.statement, 1) then
 3947           state.okay := FALSE;
 3948           if state.details then
 3949             writeln(" *** testCodePageField: Code page: " <& codePage <& " Row: " <& row <&
 3950                     " Expected NULL found " <& stringColumn);
 3951           end if;
 3952         end if;
 3953         if expect[row] <> "" and isNull(state.statement, 1) then
 3954           state.okay := FALSE;
 3955           if state.details then
 3956             writeln(" *** testCodePageField: Code page: " <& codePage <& " Row: " <& row <&
 3957                     " Expected " <& expect[row] <& " found NULL");
 3958           end if;
 3959         end if;
 3960         incr(row);
 3961       end while;
 3962     exception
 3963       catch RANGE_ERROR:
 3964         state.okay := FALSE;
 3965         writeln(" *** RANGE_ERROR was raised");
 3966       catch FILE_ERROR:
 3967         state.okay := FALSE;
 3968         writeln(" *** FILE_ERROR was raised");
 3969       catch DATABASE_ERROR:
 3970         state.okay := FALSE;
 3971         writeln(" *** DATABASE_ERROR was raised");
 3972     end block;
 3973     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 3974     execute(state.statement);
 3975 
 3976     if state.okay then
 3977       writeln("Inserting and fetching char(1) fields with code page " <& codePage <& " characters works okay.");
 3978     else
 3979       writeln(" *** Inserting and fetching char(1) fields with code page " <& codePage <& " characters does not work okay.");
 3980     end if;
 3981   end func;
 3982 
 3983 
 3984 const proc: testChar1Field (in database: testDb, in dbCategory: databaseKind) is func
 3985   local
 3986     var testState: state is testState("char1Test", "char1Field", FALSE);
 3987     var array string: expect is 0 times "";
 3988     var string: stringColumn is "";
 3989     var integer: row is 1;
 3990   begin
 3991     if state.details then
 3992       writeln("testChar1Field: " <& databaseKind);
 3993     end if;
 3994     block
 3995       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 3996                                  " (" & state.fieldName & " CHAR)");
 3997       execute(state.statement);
 3998       insert(testDb, state, "NULL", expect &:= "");
 3999       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4000                                  " (" & state.fieldName & ") VALUES (?)");
 4001       insert(state, NULL,  expect &:= "");
 4002 
 4003       insert(testDb, state, "''",      expect &:= "");
 4004       if nullAllowedInStringLiteral(databaseKind) then
 4005         insert(testDb, state, "'\0;'", expect &:= "\0;");
 4006       end if;
 4007       insert(testDb, state, "'\1;'",   expect &:= "\1;");
 4008       insert(testDb, state, "'\2;'",   expect &:= "\2;");
 4009       insert(testDb, state, "'\3;'",   expect &:= "\3;");
 4010       insert(testDb, state, "'\4;'",   expect &:= "\4;");
 4011       insert(testDb, state, "'\5;'",   expect &:= "\5;");
 4012       insert(testDb, state, "'\6;'",   expect &:= "\6;");
 4013       insert(testDb, state, "'\7;'",   expect &:= "\7;");
 4014       insert(testDb, state, "'\8;'",   expect &:= "\8;");
 4015       insert(testDb, state, "'\9;'",   expect &:= "\9;");
 4016       insert(testDb, state, "'\10;'",  expect &:= "\10;");
 4017       insert(testDb, state, "'\11;'",  expect &:= "\11;");
 4018       insert(testDb, state, "'\12;'",  expect &:= "\12;");
 4019       insert(testDb, state, "'\13;'",  expect &:= "\13;");
 4020       insert(testDb, state, "'\14;'",  expect &:= "\14;");
 4021       insert(testDb, state, "'\15;'",  expect &:= "\15;");
 4022       insert(testDb, state, "'\16;'",  expect &:= "\16;");
 4023       insert(testDb, state, "'\17;'",  expect &:= "\17;");
 4024       insert(testDb, state, "'\18;'",  expect &:= "\18;");
 4025       insert(testDb, state, "'\19;'",  expect &:= "\19;");
 4026       insert(testDb, state, "'\20;'",  expect &:= "\20;");
 4027       insert(testDb, state, "'\21;'",  expect &:= "\21;");
 4028       insert(testDb, state, "'\22;'",  expect &:= "\22;");
 4029       insert(testDb, state, "'\23;'",  expect &:= "\23;");
 4030       insert(testDb, state, "'\24;'",  expect &:= "\24;");
 4031       insert(testDb, state, "'\25;'",  expect &:= "\25;");
 4032       insert(testDb, state, "'\26;'",  expect &:= "\26;");
 4033       insert(testDb, state, "'\27;'",  expect &:= "\27;");
 4034       insert(testDb, state, "'\28;'",  expect &:= "\28;");
 4035       insert(testDb, state, "'\29;'",  expect &:= "\29;");
 4036       insert(testDb, state, "'\30;'",  expect &:= "\30;");
 4037       insert(testDb, state, "'\31;'",  expect &:= "\31;");
 4038       if charFieldPreservesTrailingSpaces(databaseKind) then
 4039         # Reading a char field preserves trailing spaces.
 4040         insert(testDb, state, "' '",   expect &:= " ");
 4041       else
 4042         # Reading a char field removes trailing spaces.
 4043         insert(testDb, state, "' '",   expect &:= "");
 4044       end if;
 4045       insert(testDb, state, "'!'",     expect &:= "!");
 4046       insert(testDb, state, "'\"'",    expect &:= "\"");
 4047       insert(testDb, state, "'#'",     expect &:= "#");
 4048       insert(testDb, state, "'$'",     expect &:= "$");
 4049       insert(testDb, state, "'%'",     expect &:= "%");
 4050       insert(testDb, state, "'&'",     expect &:= "&");
 4051       insert(testDb, state, "''''",    expect &:= "'");
 4052       insert(testDb, state, "'('",     expect &:= "(");
 4053       insert(testDb, state, "')'",     expect &:= ")");
 4054       insert(testDb, state, "'*'",     expect &:= "*");
 4055       insert(testDb, state, "'+'",     expect &:= "+");
 4056       insert(testDb, state, "','",     expect &:= ",");
 4057       insert(testDb, state, "'-'",     expect &:= "-");
 4058       insert(testDb, state, "'.'",     expect &:= ".");
 4059       insert(testDb, state, "'/'",     expect &:= "/");
 4060       insert(testDb, state, "'0'",     expect &:= "0");
 4061       insert(testDb, state, "'1'",     expect &:= "1");
 4062       insert(testDb, state, "'9'",     expect &:= "9");
 4063       insert(testDb, state, "':'",     expect &:= ":");
 4064       insert(testDb, state, "';'",     expect &:= ";");
 4065       insert(testDb, state, "'<'",     expect &:= "<");
 4066       insert(testDb, state, "'='",     expect &:= "=");
 4067       insert(testDb, state, "'>'",     expect &:= ">");
 4068       insert(testDb, state, "'?'",     expect &:= "?");
 4069       insert(testDb, state, "'@'",     expect &:= "@");
 4070       insert(testDb, state, "'A'",     expect &:= "A");
 4071       insert(testDb, state, "'Z'",     expect &:= "Z");
 4072       insert(testDb, state, "'['",     expect &:= "[");
 4073       insert(testDb, state, "'\\'",    expect &:= "\\");
 4074       insert(testDb, state, "']'",     expect &:= "]");
 4075       insert(testDb, state, "'^'",     expect &:= "^");
 4076       insert(testDb, state, "'_'",     expect &:= "_");
 4077       insert(testDb, state, "'`'",     expect &:= "`");
 4078       insert(testDb, state, "'a'",     expect &:= "a");
 4079       insert(testDb, state, "'z'",     expect &:= "z");
 4080       insert(testDb, state, "'{'",     expect &:= "{");
 4081       insert(testDb, state, "'|'",     expect &:= "|");
 4082       insert(testDb, state, "'}'",     expect &:= "}");
 4083       insert(testDb, state, "'~'",     expect &:= "~");
 4084       insert(testDb, state, "'\127;'", expect &:= "\127;");
 4085       if maxChar1FieldCharacter(databaseKind) >= '\255;' then
 4086         insert(testDb, state, "'\160;'", expect &:= "\160;");
 4087         insert(testDb, state, "'¡'",     expect &:= "¡");
 4088         insert(testDb, state, "'¤'",     expect &:= "¤");
 4089         insert(testDb, state, "'§'",     expect &:= "§");
 4090         insert(testDb, state, "'¬'",     expect &:= "¬");
 4091         insert(testDb, state, "'­'",     expect &:= "­");
 4092         insert(testDb, state, "'µ'",     expect &:= "µ");
 4093         insert(testDb, state, "'¿'",     expect &:= "¿");
 4094         insert(testDb, state, "'Ä'",     expect &:= "Ä");
 4095         insert(testDb, state, "'×'",     expect &:= "×");
 4096         insert(testDb, state, "'ß'",     expect &:= "ß");
 4097         insert(testDb, state, "'ä'",     expect &:= "ä");
 4098         insert(testDb, state, "'÷'",     expect &:= "÷");
 4099         insert(testDb, state, "'ÿ'",     expect &:= "ÿ");
 4100       end if;
 4101       if maxChar1FieldCharacter(databaseKind) >= '\8888;' then # Code page 1252
 4102         insert(testDb, state, "'Œ'",        expect &:= "Œ");
 4103         insert(testDb, state, "'Š'",        expect &:= "Š");
 4104         insert(testDb, state, "'ƒ'",        expect &:= "ƒ");
 4105         insert(testDb, state, "'†'",        expect &:= "†");
 4106         insert(testDb, state, "'•'",        expect &:= "•");
 4107         insert(testDb, state, "'‰'",        expect &:= "‰");
 4108         insert(testDb, state, "'€'",        expect &:= "€");
 4109         insert(testDb, state, "'™'",        expect &:= "™");
 4110       end if;
 4111       if maxChar1FieldCharacter(databaseKind) >= '\65535;' then
 4112         insert(testDb, state, "'Ā'",        expect &:= "Ā");
 4113         insert(testDb, state, "'\65535;'",  expect &:= "\65535;");
 4114       end if;
 4115       if maxChar1FieldCharacter(databaseKind) >= '\16#10ffff;' then
 4116         insert(testDb, state, "'\65536;'",  expect &:= "\65536;");
 4117         insert(testDb, state, "'\16#10ffff;'",  expect &:= "\16#10ffff;");
 4118       end if;
 4119 
 4120       insert(testDb, state, "0",     expect &:= "0");
 4121       insert(testDb, state, "1",     expect &:= "1");
 4122       insert(testDb, state, "9",     expect &:= "9");
 4123 
 4124       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4125                                  " (" & state.fieldName & ") VALUES (?)");
 4126       insert(state, "",    expect &:= "");
 4127       if nullAllowedInString(databaseKind) then
 4128         insert(state, "\0;", expect &:= "\0;");
 4129       end if;
 4130       insert(state, "\1;",   expect &:= "\1;");
 4131       insert(state, "\2;",   expect &:= "\2;");
 4132       insert(state, "\3;",   expect &:= "\3;");
 4133       insert(state, "\4;",   expect &:= "\4;");
 4134       insert(state, "\5;",   expect &:= "\5;");
 4135       insert(state, "\6;",   expect &:= "\6;");
 4136       insert(state, "\7;",   expect &:= "\7;");
 4137       insert(state, "\8;",   expect &:= "\8;");
 4138       insert(state, "\9;",   expect &:= "\9;");
 4139       insert(state, "\10;",  expect &:= "\10;");
 4140       insert(state, "\11;",  expect &:= "\11;");
 4141       insert(state, "\12;",  expect &:= "\12;");
 4142       insert(state, "\13;",  expect &:= "\13;");
 4143       insert(state, "\14;",  expect &:= "\14;");
 4144       insert(state, "\15;",  expect &:= "\15;");
 4145       insert(state, "\16;",  expect &:= "\16;");
 4146       insert(state, "\17;",  expect &:= "\17;");
 4147       insert(state, "\18;",  expect &:= "\18;");
 4148       insert(state, "\19;",  expect &:= "\19;");
 4149       insert(state, "\20;",  expect &:= "\20;");
 4150       insert(state, "\21;",  expect &:= "\21;");
 4151       insert(state, "\22;",  expect &:= "\22;");
 4152       insert(state, "\23;",  expect &:= "\23;");
 4153       insert(state, "\24;",  expect &:= "\24;");
 4154       insert(state, "\25;",  expect &:= "\25;");
 4155       insert(state, "\26;",  expect &:= "\26;");
 4156       insert(state, "\27;",  expect &:= "\27;");
 4157       insert(state, "\28;",  expect &:= "\28;");
 4158       insert(state, "\29;",  expect &:= "\29;");
 4159       insert(state, "\30;",  expect &:= "\30;");
 4160       insert(state, "\31;",  expect &:= "\31;");
 4161       if charFieldPreservesTrailingSpaces(databaseKind) then
 4162         # Reading a char field preserves trailing spaces.
 4163         insert(state, " ",   expect &:= " ");
 4164       else
 4165         # Reading a char field removes trailing spaces.
 4166         insert(state, " ",   expect &:= "");
 4167       end if;
 4168       insert(state, "!",     expect &:= "!");
 4169       insert(state, "\"",    expect &:= "\"");
 4170       insert(state, "#",     expect &:= "#");
 4171       insert(state, "$",     expect &:= "$");
 4172       insert(state, "%",     expect &:= "%");
 4173       insert(state, "&",     expect &:= "&");
 4174       insert(state, "'",     expect &:= "'");
 4175       insert(state, "(",     expect &:= "(");
 4176       insert(state, ")",     expect &:= ")");
 4177       insert(state, "*",     expect &:= "*");
 4178       insert(state, "+",     expect &:= "+");
 4179       insert(state, ",",     expect &:= ",");
 4180       insert(state, "-",     expect &:= "-");
 4181       insert(state, ".",     expect &:= ".");
 4182       insert(state, "/",     expect &:= "/");
 4183       insert(state, "0",     expect &:= "0");
 4184       insert(state, "1",     expect &:= "1");
 4185       insert(state, "9",     expect &:= "9");
 4186       insert(state, ":",     expect &:= ":");
 4187       insert(state, ";",     expect &:= ";");
 4188       insert(state, "<",     expect &:= "<");
 4189       insert(state, "=",     expect &:= "=");
 4190       insert(state, ">",     expect &:= ">");
 4191       insert(state, "?",     expect &:= "?");
 4192       insert(state, "@",     expect &:= "@");
 4193       insert(state, "A",     expect &:= "A");
 4194       insert(state, "Z",     expect &:= "Z");
 4195       insert(state, "[",     expect &:= "[");
 4196       insert(state, "\\",    expect &:= "\\");
 4197       insert(state, "]",     expect &:= "]");
 4198       insert(state, "^",     expect &:= "^");
 4199       insert(state, "_",     expect &:= "_");
 4200       insert(state, "`",     expect &:= "`");
 4201       insert(state, "a",     expect &:= "a");
 4202       insert(state, "z",     expect &:= "z");
 4203       insert(state, "{",     expect &:= "{");
 4204       insert(state, "|",     expect &:= "|");
 4205       insert(state, "}",     expect &:= "}");
 4206       insert(state, "~",     expect &:= "~");
 4207       insert(state, "\127;", expect &:= "\127;");
 4208       if maxChar1FieldCharacter(databaseKind) >= '\255;' then
 4209         insert(state, "\160;", expect &:= "\160;");
 4210         insert(state, "¡",     expect &:= "¡");
 4211         insert(state, "¤",     expect &:= "¤");
 4212         insert(state, "§",     expect &:= "§");
 4213         insert(state, "¬",     expect &:= "¬");
 4214         insert(state, "­",     expect &:= "­");
 4215         insert(state, "µ",     expect &:= "µ");
 4216         insert(state, "¿",     expect &:= "¿");
 4217         insert(state, "Ä",     expect &:= "Ä");
 4218         insert(state, "×",     expect &:= "×");
 4219         insert(state, "ß",     expect &:= "ß");
 4220         insert(state, "ä",     expect &:= "ä");
 4221         insert(state, "÷",     expect &:= "÷");
 4222         insert(state, "ÿ",     expect &:= "ÿ");
 4223       end if;
 4224       if maxChar1FieldCharacter(databaseKind) >= '\8888;' then # Code page 1252
 4225         insert(state, "Œ",        expect &:= "Œ");
 4226         insert(state, "Š",        expect &:= "Š");
 4227         insert(state, "ƒ",        expect &:= "ƒ");
 4228         insert(state, "†",        expect &:= "†");
 4229         insert(state, "•",        expect &:= "•");
 4230         insert(state, "‰",        expect &:= "‰");
 4231         insert(state, "€",        expect &:= "€");
 4232         insert(state, "™",        expect &:= "™");
 4233       end if;
 4234       if maxChar1FieldCharacter(databaseKind) >= '\65535;' then
 4235         insert(state, "Ā",        expect &:= "Ā");
 4236         insert(state, "\65535;",  expect &:= "\65535;");
 4237       end if;
 4238       if maxChar1FieldCharacter(databaseKind) >= '\16#10ffff;' then
 4239         insert(state, "\65536;",      expect &:= "\65536;");
 4240         insert(state, "\16#10ffff;",  expect &:= "\16#10ffff;");
 4241       end if;
 4242 
 4243       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4244                                  " (" & state.fieldName & ") VALUES (?)");
 4245       insert(state, 0,     expect &:= "0");
 4246       insert(state, 1,     expect &:= "1");
 4247       insert(state, 9,     expect &:= "9");
 4248 
 4249       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4250                                  " (" & state.fieldName & ") VALUES (?)");
 4251       insert(state, 0_,    expect &:= "0");
 4252       insert(state, 1_,    expect &:= "1");
 4253       insert(state, 9_,    expect &:= "9");
 4254 
 4255       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 4256       execute(state.statement);
 4257       while fetch(state.statement) do
 4258         stringColumn := column(state.statement, 1, string);
 4259         if stringColumn <> expect[row] then
 4260           state.okay := FALSE;
 4261           if state.details then
 4262             writeln(" *** testChar1Field: Row: " <& row <&
 4263                     " Expected " <& literal(expect[row]) <&
 4264                     " found " <& literal(stringColumn));
 4265           end if;
 4266         end if;
 4267         if row <= 2 and not isNull(state.statement, 1) then
 4268           state.okay := FALSE;
 4269           if state.details then
 4270             writeln(" *** testChar1Field: Row: " <& row <&
 4271                     " Expected NULL found " <& stringColumn);
 4272           end if;
 4273         end if;
 4274         if expect[row] <> "" and isNull(state.statement, 1) then
 4275           state.okay := FALSE;
 4276           if state.details then
 4277             writeln(" *** testChar1Field: Row: " <& row <&
 4278                     " Expected " <& expect[row] <& " found NULL");
 4279           end if;
 4280         end if;
 4281         incr(row);
 4282       end while;
 4283     exception
 4284       catch RANGE_ERROR:
 4285         state.okay := FALSE;
 4286         writeln(" *** RANGE_ERROR was raised");
 4287       catch FILE_ERROR:
 4288         state.okay := FALSE;
 4289         writeln(" *** FILE_ERROR was raised");
 4290       catch DATABASE_ERROR:
 4291         state.okay := FALSE;
 4292         writeln(" *** DATABASE_ERROR was raised");
 4293     end block;
 4294     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 4295     execute(state.statement);
 4296 
 4297     if state.okay then
 4298       writeln("Inserting and fetching char(1) fields works okay.");
 4299     else
 4300       writeln(" *** Inserting and fetching char(1) fields does not work okay.");
 4301     end if;
 4302   end func;
 4303 
 4304 
 4305 const proc: testCharField (in database: testDb, in dbCategory: databaseKind) is func
 4306   local
 4307     var testState: state is testState("charTest", "charField", FALSE);
 4308     var array string: expect is 0 times "";
 4309     var string: stringColumn is "";
 4310     var integer: row is 1;
 4311   begin
 4312     if state.details then
 4313       writeln("testCharField: " <& databaseKind);
 4314     end if;
 4315     block
 4316       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 4317                                  " (" & state.fieldName & " CHAR(32))");
 4318       execute(state.statement);
 4319       insert(testDb, state, "NULL", expect &:= "");
 4320       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4321                                  " (" & state.fieldName & ") VALUES (?)");
 4322       insert(state, NULL,         expect &:= "");
 4323 
 4324       insert(testDb, state, "''",           expect &:= "");
 4325       insert(testDb, state, "'X'",          expect &:= "X");
 4326       insert(testDb, state, "'Ab2'",        expect &:= "Ab2");
 4327       insert(testDb, state, "'abcdefghij'", expect &:= "abcdefghij");
 4328       insert(testDb, state, "'ÄäÖöÜüß'",    expect &:= "ÄäÖöÜüß");
 4329       insert(testDb, state, "'€µ¹²³¼½«»¬'", expect &:= "€µ¹²³¼½«»¬");
 4330       # Chars that are defined with different ordinal in code page 1252:
 4331       insert(testDb, state, "'€‚ƒ„…†‡ˆ‰'",  expect &:= "€‚ƒ„…†‡ˆ‰");
 4332       insert(testDb, state, "'Š‹ŒŽ‘’“”•'",  expect &:= "Š‹ŒŽ‘’“”•");
 4333       insert(testDb, state, "'–—˜™š›œžŸ'",  expect &:= "–—˜™š›œžŸ");
 4334       insert(testDb, state, "'" & "x" mult 32 & "'",  expect &:= "x" mult 32);
 4335       insert(testDb, state, "'A B'",        expect &:= "A B");
 4336       if nullAllowedInStringLiteral(databaseKind) then
 4337         insert(testDb, state, "'A\0;B'",    expect &:= "A\0;B");
 4338       end if;
 4339       insert(testDb, state, "'\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4340                             \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4341                             \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;'",
 4342                  expect &:= "\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4343                             \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4344                             \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;");
 4345       insert(testDb, state, "' !\"#$%&''()*+,-./'",         expect &:= " !\"#$%&'()*+,-./");
 4346       insert(testDb, state, "'0123456789:;<=>?@'",          expect &:= "0123456789:;<=>?@");
 4347       insert(testDb, state, "'ABCDEFGHIJKLMNOPQRSTUVWXYZ'", expect &:= "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
 4348       insert(testDb, state, "'[\\]^_`{|}~\127;'",           expect &:= "[\\]^_`{|}~\127;");
 4349       insert(testDb, state, "'abcdefghijklmnopqrstuvwxyz'", expect &:= "abcdefghijklmnopqrstuvwxyz");
 4350       insert(testDb, state, "'\160;¡¢£¤¥¦§¨©ª«¬­®¯'",       expect &:= "\160;¡¢£¤¥¦§¨©ª«¬­®¯");
 4351       insert(testDb, state, "'°±²³´µ¶·¸¹º»¼½¾¿'",           expect &:= "°±²³´µ¶·¸¹º»¼½¾¿");
 4352       insert(testDb, state, "'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ'",           expect &:= "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ");
 4353       insert(testDb, state, "'ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß'",           expect &:= "ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß");
 4354       insert(testDb, state, "'àáâãäåæçèéêëìíîï'",           expect &:= "àáâãäåæçèéêëìíîï");
 4355       insert(testDb, state, "'ðñòóôõö÷øùúûüýþÿ'",           expect &:= "ðñòóôõö÷øùúûüýþÿ");
 4356       if charFieldPreservesTrailingSpaces(databaseKind) then
 4357         # Reading a char field preserves trailing spaces.
 4358         insert(testDb, state, "'a '",       expect &:= "a ");
 4359         # insert(testDb, state, "'" & "b" mult 3999 & " '", expect &:= "b" mult 3999 & " ");
 4360       else
 4361         # Reading a char field removes trailing spaces.
 4362         insert(testDb, state, "'a '",       expect &:= "a");
 4363         # insert(testDb, state, "'" & "b" mult 3999 & " '", expect &:= "b" mult 3999);
 4364       end if;
 4365 
 4366       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4367                                  " (" & state.fieldName & ") VALUES (?)");
 4368       insert(state, "",           expect &:= "");
 4369       insert(state, "X",          expect &:= "X");
 4370       insert(state, "Ab2",        expect &:= "Ab2");
 4371       insert(state, "abcdefghij", expect &:= "abcdefghij");
 4372       insert(state, "ÄäÖöÜüß",    expect &:= "ÄäÖöÜüß");
 4373       insert(state, "€µ¹²³¼½«»¬", expect &:= "€µ¹²³¼½«»¬");
 4374       # Chars that are defined with different ordinal in code page 1252:
 4375       insert(state, "€‚ƒ„…†‡ˆ‰",  expect &:= "€‚ƒ„…†‡ˆ‰");
 4376       insert(state, "Š‹ŒŽ‘’“”•",  expect &:= "Š‹ŒŽ‘’“”•");
 4377       insert(state, "–—˜™š›œžŸ",  expect &:= "–—˜™š›œžŸ");
 4378       insert(state, "x" mult 32,  expect &:= "x" mult 32);
 4379       insert(state, "A B",        expect &:= "A B");
 4380       if nullAllowedInString(databaseKind) then
 4381         insert(state, "A\0;B",    expect &:= "A\0;B");
 4382       end if;
 4383       insert(state, "\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4384                     \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4385                     \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;",
 4386          expect &:= "\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4387                     \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4388                     \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;");
 4389       insert(state, " !\"#$%&'()*+,-./",          expect &:= " !\"#$%&'()*+,-./");
 4390       insert(state, "0123456789:;<=>?@",          expect &:= "0123456789:;<=>?@");
 4391       insert(state, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", expect &:= "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
 4392       insert(state, "[\\]^_`{|}~\127;",           expect &:= "[\\]^_`{|}~\127;");
 4393       insert(state, "abcdefghijklmnopqrstuvwxyz", expect &:= "abcdefghijklmnopqrstuvwxyz");
 4394       insert(state, "\160;¡¢£¤¥¦§¨©ª«¬­®¯",       expect &:= "\160;¡¢£¤¥¦§¨©ª«¬­®¯");
 4395       insert(state, "°±²³´µ¶·¸¹º»¼½¾¿",           expect &:= "°±²³´µ¶·¸¹º»¼½¾¿");
 4396       insert(state, "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ",           expect &:= "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ");
 4397       insert(state, "ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß",           expect &:= "ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß");
 4398       insert(state, "àáâãäåæçèéêëìíîï",           expect &:= "àáâãäåæçèéêëìíîï");
 4399       insert(state, "ðñòóôõö÷øùúûüýþÿ",           expect &:= "ðñòóôõö÷øùúûüýþÿ");
 4400       if charFieldPreservesTrailingSpaces(databaseKind) then
 4401         # Reading a char field preserves trailing spaces.
 4402         insert(state, "a ",         expect &:= "a ");
 4403         # insert(state, "b" mult 3999 & " ",      expect &:= "b" mult 3999 & " ");
 4404       else
 4405         # Reading a char field removes trailing spaces.
 4406         insert(state, "a ",         expect &:= "a");
 4407         # insert(state, "b" mult 3999 & " ",      expect &:= "b" mult 3999);
 4408       end if;
 4409 
 4410       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4411                                  " (" & state.fieldName & ") VALUES (?)");
 4412       insert(state,          0,   expect &:= "0");
 4413       insert(state,          1,   expect &:= "1");
 4414       insert(state, 1234567890,   expect &:= "1234567890");
 4415 
 4416       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4417                                  " (" & state.fieldName & ") VALUES (?)");
 4418       insert(state,          0_,  expect &:= "0");
 4419       insert(state,          1_,  expect &:= "1");
 4420       insert(state, 1234567890_,  expect &:= "1234567890");
 4421 
 4422       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 4423       execute(state.statement);
 4424       while fetch(state.statement) do
 4425         stringColumn := column(state.statement, 1, string);
 4426         if stringColumn <> expect[row] then
 4427           state.okay := FALSE;
 4428           if state.details then
 4429             writeln(" *** testCharField: Row: " <& row <&
 4430                     " Expected " <& literal(expect[row]) <&
 4431                     " found string " <& literal(stringColumn));
 4432             writeln("Expected length: " <& length(expect[row]));
 4433             writeln("Length found:    " <& length(stringColumn));
 4434           end if;
 4435         end if;
 4436         if row <= 2 and not isNull(state.statement, 1) then
 4437           state.okay := FALSE;
 4438           if state.details then
 4439             writeln(" *** testCharField: Row: " <& row <&
 4440                     " Expected NULL found string " <& stringColumn);
 4441           end if;
 4442         end if;
 4443         if expect[row] <> "" and isNull(state.statement, 1) then
 4444           state.okay := FALSE;
 4445           if state.details then
 4446             writeln(" *** testCharField: Row: " <& row <&
 4447                     " Expected " <& literal(expect[row]) <& " found NULL");
 4448           end if;
 4449         end if;
 4450         incr(row);
 4451       end while;
 4452     exception
 4453       catch RANGE_ERROR:
 4454         state.okay := FALSE;
 4455         writeln(" *** RANGE_ERROR was raised");
 4456       catch FILE_ERROR:
 4457         state.okay := FALSE;
 4458         writeln(" *** FILE_ERROR was raised");
 4459       catch DATABASE_ERROR:
 4460         state.okay := FALSE;
 4461         writeln(" *** DATABASE_ERROR was raised");
 4462     end block;
 4463     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 4464     execute(state.statement);
 4465 
 4466     if state.okay then
 4467       writeln("Inserting and fetching char fields works okay.");
 4468     else
 4469       writeln(" *** Inserting and fetching char fields does not work okay.");
 4470     end if;
 4471   end func;
 4472 
 4473 
 4474 const proc: testCharField2 (in database: testDb, in dbCategory: databaseKind) is func
 4475   local
 4476     var testState: state is testState("charTest", "charField", FALSE);
 4477     var array string: expect is 0 times "";
 4478     var string: stringColumn is "";
 4479     var integer: row is 1;
 4480   begin
 4481     if state.details then
 4482       writeln("testCharField2: " <& databaseKind);
 4483     end if;
 4484     block
 4485       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 4486                                  " (" & state.fieldName & " CHAR(32))");
 4487       execute(state.statement);
 4488       insert(testDb, state, "NULL", expect &:= "");
 4489       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4490                                  " (" & state.fieldName & ") VALUES (?)");
 4491       insert(state, NULL,         expect &:= "");
 4492 
 4493       insert(testDb, state, "\"\"",           expect &:= "");
 4494       insert(testDb, state, "\"X\"",          expect &:= "X");
 4495       insert(testDb, state, "\"Ab2\"",        expect &:= "Ab2");
 4496       insert(testDb, state, "\"abcdefghij\"", expect &:= "abcdefghij");
 4497       insert(testDb, state, "\"ÄäÖöÜüß\"",    expect &:= "ÄäÖöÜüß");
 4498       insert(testDb, state, "\"€µ¹²³¼½«»¬\"", expect &:= "€µ¹²³¼½«»¬");
 4499       # Chars that are defined with different ordinal in code page 1252:
 4500       insert(testDb, state, "\"€‚ƒ„…†‡ˆ‰\"",  expect &:= "€‚ƒ„…†‡ˆ‰");
 4501       insert(testDb, state, "\"Š‹ŒŽ‘’“”•\"",  expect &:= "Š‹ŒŽ‘’“”•");
 4502       insert(testDb, state, "\"–—˜™š›œžŸ\"",  expect &:= "–—˜™š›œžŸ");
 4503       insert(testDb, state, "\"" & "x" mult 32 & "\"",  expect &:= "x" mult 32);
 4504       insert(testDb, state, "\"A B\"",        expect &:= "A B");
 4505       if nullAllowedInStringLiteral(databaseKind) then
 4506         insert(testDb, state, "\"A\0;B\"",    expect &:= "A\0;B");
 4507       end if;
 4508       insert(testDb, state, "\"\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4509                             \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4510                             \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;\"",
 4511                  expect &:= "\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4512                             \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4513                             \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;");
 4514       insert(testDb, state, "\" !\"\"#$%&'()*+,-./\"",         expect &:= " !\"#$%&'()*+,-./");
 4515       insert(testDb, state, "\"0123456789:;<=>?@\"",          expect &:= "0123456789:;<=>?@");
 4516       insert(testDb, state, "\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"", expect &:= "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
 4517       insert(testDb, state, "\"[\\]^_`{|}~\127;\"",           expect &:= "[\\]^_`{|}~\127;");
 4518       insert(testDb, state, "\"abcdefghijklmnopqrstuvwxyz\"", expect &:= "abcdefghijklmnopqrstuvwxyz");
 4519       insert(testDb, state, "\"\160;¡¢£¤¥¦§¨©ª«¬­®¯\"",       expect &:= "\160;¡¢£¤¥¦§¨©ª«¬­®¯");
 4520       insert(testDb, state, "\"°±²³´µ¶·¸¹º»¼½¾¿\"",           expect &:= "°±²³´µ¶·¸¹º»¼½¾¿");
 4521       insert(testDb, state, "\"ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ\"",           expect &:= "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ");
 4522       insert(testDb, state, "\"ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß\"",           expect &:= "ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß");
 4523       insert(testDb, state, "\"àáâãäåæçèéêëìíîï\"",           expect &:= "àáâãäåæçèéêëìíîï");
 4524       insert(testDb, state, "\"ðñòóôõö÷øùúûüýþÿ\"",           expect &:= "ðñòóôõö÷øùúûüýþÿ");
 4525       if charFieldPreservesTrailingSpaces(databaseKind) then
 4526         # Reading a char field preserves trailing spaces.
 4527         insert(testDb, state, "\"a \"",       expect &:= "a ");
 4528         # insert(testDb, state, "\"" & "b" mult 3999 & " \"", expect &:= "b" mult 3999 & " ");
 4529       else
 4530         # Reading a char field removes trailing spaces.
 4531         insert(testDb, state, "\"a \"",       expect &:= "a");
 4532         # insert(testDb, state, "\"" & "b" mult 3999 & " \"", expect &:= "b" mult 3999);
 4533       end if;
 4534 
 4535       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 4536       execute(state.statement);
 4537       while fetch(state.statement) do
 4538         stringColumn := column(state.statement, 1, string);
 4539         if stringColumn <> expect[row] then
 4540           state.okay := FALSE;
 4541           if state.details then
 4542             writeln(" *** testCharField2: Row: " <& row <&
 4543                     " Expected " <& literal(expect[row]) <&
 4544                     " found string " <& literal(stringColumn));
 4545             writeln("Expected length: " <& length(expect[row]));
 4546             writeln("Length found:    " <& length(stringColumn));
 4547           end if;
 4548         end if;
 4549         if row <= 2 and not isNull(state.statement, 1) then
 4550           state.okay := FALSE;
 4551           if state.details then
 4552             writeln(" *** testCharField2: Row: " <& row <&
 4553                     " Expected NULL found string " <& stringColumn);
 4554           end if;
 4555         end if;
 4556         if expect[row] <> "" and isNull(state.statement, 1) then
 4557           state.okay := FALSE;
 4558           if state.details then
 4559             writeln(" *** testCharField2: Row: " <& row <&
 4560                     " Expected " <& literal(expect[row]) <& " found NULL");
 4561           end if;
 4562         end if;
 4563         incr(row);
 4564       end while;
 4565     exception
 4566       catch RANGE_ERROR:
 4567         state.okay := FALSE;
 4568         writeln(" *** RANGE_ERROR was raised");
 4569       catch FILE_ERROR:
 4570         state.okay := FALSE;
 4571         writeln(" *** FILE_ERROR was raised");
 4572       catch DATABASE_ERROR:
 4573         state.okay := FALSE;
 4574         writeln(" *** DATABASE_ERROR was raised");
 4575     end block;
 4576     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 4577     execute(state.statement);
 4578 
 4579     if state.okay then
 4580       writeln("Inserting and fetching char fields works okay.");
 4581     else
 4582       writeln(" *** Inserting and fetching char fields does not work okay.");
 4583     end if;
 4584   end func;
 4585 
 4586 
 4587 const proc: testVarcharField (in database: testDb, in dbCategory: databaseKind) is func
 4588   local
 4589     var testState: state is testState("varcharTest", "varcharField", FALSE);
 4590     var array string: expect is 0 times "";
 4591     var string: stringColumn is "";
 4592     var integer: row is 1;
 4593   begin
 4594     if state.details then
 4595       writeln("testVarcharField: " <& databaseKind);
 4596     end if;
 4597     block
 4598       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 4599                                  " (" & state.fieldName & " " & varcharType(databaseKind) & "(32))");
 4600       execute(state.statement);
 4601       insert(testDb, state, "NULL", expect &:= "");
 4602       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4603                                  " (" & state.fieldName & ") VALUES (?)");
 4604       insert(state, NULL,         expect &:= "");
 4605 
 4606       insert(testDb, state, "''",           expect &:= "");
 4607       insert(testDb, state, "'X'",          expect &:= "X");
 4608       insert(testDb, state, "'Ab2'",        expect &:= "Ab2");
 4609       insert(testDb, state, "'abcdefghij'", expect &:= "abcdefghij");
 4610       insert(testDb, state, "'ÄäÖöÜüß'",    expect &:= "ÄäÖöÜüß");
 4611       insert(testDb, state, "'€µ¹²³¼½«»¬'", expect &:= "€µ¹²³¼½«»¬");
 4612       # Chars that are defined with different ordinal in code page 1252:
 4613       insert(testDb, state, "'€‚ƒ„…†‡ˆ‰'",  expect &:= "€‚ƒ„…†‡ˆ‰");
 4614       insert(testDb, state, "'Š‹ŒŽ‘’“”•'",  expect &:= "Š‹ŒŽ‘’“”•");
 4615       insert(testDb, state, "'–—˜™š›œžŸ'",  expect &:= "–—˜™š›œžŸ");
 4616       insert(testDb, state, "'" & "x" mult 32 & "'",  expect &:= "x" mult 32);
 4617       insert(testDb, state, "'A B'",        expect &:= "A B");
 4618       if nullAllowedInStringLiteral(databaseKind) then
 4619         insert(testDb, state, "'A\0;B'",    expect &:= "A\0;B");
 4620       end if;
 4621       insert(testDb, state, "'\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4622                             \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4623                             \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;'",
 4624                  expect &:= "\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4625                             \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4626                             \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;");
 4627       insert(testDb, state, "' !\"#$%&''()*+,-./'",         expect &:= " !\"#$%&'()*+,-./");
 4628       insert(testDb, state, "'0123456789:;<=>?@'",          expect &:= "0123456789:;<=>?@");
 4629       insert(testDb, state, "'ABCDEFGHIJKLMNOPQRSTUVWXYZ'", expect &:= "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
 4630       insert(testDb, state, "'[\\]^_`{|}~\127;'",           expect &:= "[\\]^_`{|}~\127;");
 4631       insert(testDb, state, "'abcdefghijklmnopqrstuvwxyz'", expect &:= "abcdefghijklmnopqrstuvwxyz");
 4632       insert(testDb, state, "'\160;¡¢£¤¥¦§¨©ª«¬­®¯'",       expect &:= "\160;¡¢£¤¥¦§¨©ª«¬­®¯");
 4633       insert(testDb, state, "'°±²³´µ¶·¸¹º»¼½¾¿'",           expect &:= "°±²³´µ¶·¸¹º»¼½¾¿");
 4634       insert(testDb, state, "'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ'",           expect &:= "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ");
 4635       insert(testDb, state, "'ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß'",           expect &:= "ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß");
 4636       insert(testDb, state, "'àáâãäåæçèéêëìíîï'",           expect &:= "àáâãäåæçèéêëìíîï");
 4637       insert(testDb, state, "'ðñòóôõö÷øùúûüýþÿ'",           expect &:= "ðñòóôõö÷øùúûüýþÿ");
 4638       # Reading a varchar field preserves trailing spaces.
 4639       insert(testDb, state, "'a '",         expect &:= "a ");
 4640       # insert(testDb, state, "'" & "b" mult 3999 & " '",     expect &:= "b" mult 3999 & " ");
 4641 
 4642       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4643                                  " (" & state.fieldName & ") VALUES (?)");
 4644       insert(state, "",           expect &:= "");
 4645       insert(state, "X",          expect &:= "X");
 4646       insert(state, "Ab2",        expect &:= "Ab2");
 4647       insert(state, "abcdefghij", expect &:= "abcdefghij");
 4648       insert(state, "ÄäÖöÜüß",    expect &:= "ÄäÖöÜüß");
 4649       insert(state, "€µ¹²³¼½«»¬", expect &:= "€µ¹²³¼½«»¬");
 4650       # Chars that are defined with different ordinal in code page 1252:
 4651       insert(state, "€‚ƒ„…†‡ˆ‰",  expect &:= "€‚ƒ„…†‡ˆ‰");
 4652       insert(state, "Š‹ŒŽ‘’“”•",  expect &:= "Š‹ŒŽ‘’“”•");
 4653       insert(state, "–—˜™š›œžŸ",  expect &:= "–—˜™š›œžŸ");
 4654       insert(state, "x" mult 32,  expect &:= "x" mult 32);
 4655       insert(state, "A B",        expect &:= "A B");
 4656       if nullAllowedInString(databaseKind) then
 4657         insert(state, "A\0;B",    expect &:= "A\0;B");
 4658       end if;
 4659       insert(state, "\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4660                     \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4661                     \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;",
 4662          expect &:= "\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4663                     \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4664                     \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;");
 4665       insert(state, " !\"#$%&'()*+,-./",          expect &:= " !\"#$%&'()*+,-./");
 4666       insert(state, "0123456789:;<=>?@",          expect &:= "0123456789:;<=>?@");
 4667       insert(state, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", expect &:= "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
 4668       insert(state, "[\\]^_`{|}~\127;",           expect &:= "[\\]^_`{|}~\127;");
 4669       insert(state, "abcdefghijklmnopqrstuvwxyz", expect &:= "abcdefghijklmnopqrstuvwxyz");
 4670       insert(state, "\160;¡¢£¤¥¦§¨©ª«¬­®¯",       expect &:= "\160;¡¢£¤¥¦§¨©ª«¬­®¯");
 4671       insert(state, "°±²³´µ¶·¸¹º»¼½¾¿",           expect &:= "°±²³´µ¶·¸¹º»¼½¾¿");
 4672       insert(state, "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ",           expect &:= "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ");
 4673       insert(state, "ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß",           expect &:= "ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß");
 4674       insert(state, "àáâãäåæçèéêëìíîï",           expect &:= "àáâãäåæçèéêëìíîï");
 4675       insert(state, "ðñòóôõö÷øùúûüýþÿ",           expect &:= "ðñòóôõö÷øùúûüýþÿ");
 4676       # Reading a varchar field preserves trailing spaces.
 4677       insert(state, "a ",         expect &:= "a ");
 4678       # insert(state, "b" mult 3999 & " ",          expect &:= "b" mult 3999 & " ");
 4679 
 4680       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4681                                  " (" & state.fieldName & ") VALUES (?)");
 4682       insert(state,          0,   expect &:= "0");
 4683       insert(state,          1,   expect &:= "1");
 4684       insert(state, 1234567890,   expect &:= "1234567890");
 4685 
 4686       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4687                                  " (" & state.fieldName & ") VALUES (?)");
 4688       insert(state,          0_,  expect &:= "0");
 4689       insert(state,          1_,  expect &:= "1");
 4690       insert(state, 1234567890_,  expect &:= "1234567890");
 4691 #      state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4692 #                           " (" & state.fieldName & ") VALUES (N'" <&
 4693 #                           "\128;\129;\130;\131;\132;\133;\134;\135;\
 4694 #                           \\136;\137;\138;\139;\140;\141;\142;\143;\144;\145;\146;\147;\148;\
 4695 #                           \\149;\150;\151;\152;\153;\154;\155;\156;\157;\158;\159;" & "')");
 4696 #      state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4697 #                           " (" & state.fieldName & ") VALUES (\
 4698 #                           \CHAR(128) + CHAR(129) + CHAR(130) + CHAR(131) + CHAR(132) + CHAR(133) + CHAR(134) + CHAR(135) + CHAR(136) + CHAR(137) + \
 4699 #                           \CHAR(138) + CHAR(139) + CHAR(140) + CHAR(141) + CHAR(142) + CHAR(143) + CHAR(144) + CHAR(145) + CHAR(146) + CHAR(147) + \
 4700 #                           \CHAR(148) + CHAR(149) + CHAR(150) + CHAR(151) + CHAR(152) + CHAR(153) + CHAR(154) + CHAR(155) + CHAR(156) + CHAR(157) + \
 4701 #                           \CHAR(158) + CHAR(159))");
 4702 #      execute(state.statement);
 4703 #      expect &:= "\128;\129;\130;\131;\132;\133;\134;\135;\
 4704 #                 \\136;\137;\138;\139;\140;\141;\142;\143;\144;\145;\146;\147;\148;\
 4705 #                 \\149;\150;\151;\152;\153;\154;\155;\156;\157;\158;\159;";
 4706       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 4707       execute(state.statement);
 4708       while fetch(state.statement) do
 4709         stringColumn := column(state.statement, 1, string);
 4710         if stringColumn <> expect[row] then
 4711           state.okay := FALSE;
 4712           if state.details then
 4713             writeln(" *** testVarcharField: Row: " <& row <&
 4714                     " Expected " <& literal(expect[row]) <&
 4715                     " found string " <& literal(stringColumn));
 4716             writeln("Expected length: " <& length(expect[row]));
 4717             writeln("Length found:    " <& length(stringColumn));
 4718           end if;
 4719         end if;
 4720         if row <= 2 and not isNull(state.statement, 1) then
 4721           state.okay := FALSE;
 4722           if state.details then
 4723             writeln(" *** testVarcharField: Row: " <& row <&
 4724                     " Expected NULL found string " <& stringColumn);
 4725           end if;
 4726         end if;
 4727         if expect[row] <> "" and isNull(state.statement, 1) then
 4728           state.okay := FALSE;
 4729           if state.details then
 4730             writeln(" *** testVarcharField: Row: " <& row <&
 4731                     " Expected " <& literal(expect[row]) <& " found NULL");
 4732           end if;
 4733         end if;
 4734         incr(row);
 4735       end while;
 4736     exception
 4737       catch RANGE_ERROR:
 4738         state.okay := FALSE;
 4739         writeln(" *** RANGE_ERROR was raised");
 4740       catch FILE_ERROR:
 4741         state.okay := FALSE;
 4742         writeln(" *** FILE_ERROR was raised");
 4743       catch DATABASE_ERROR:
 4744         state.okay := FALSE;
 4745         writeln(" *** DATABASE_ERROR was raised");
 4746     end block;
 4747     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 4748     execute(state.statement);
 4749 
 4750     if state.okay then
 4751       writeln("Inserting and fetching varchar fields works okay.");
 4752     else
 4753       writeln(" *** Inserting and fetching varchar fields does not work okay.");
 4754     end if;
 4755   end func;
 4756 
 4757 
 4758 const proc: testBlobField (in database: testDb, in dbCategory: databaseKind) is func
 4759   local
 4760     var testState: state is testState("blobTest", "blobField", FALSE);
 4761     var array bstring: expect is 0 times bstring("");
 4762     var bstring: bstringColumn is bstring("");
 4763     var string: stringColumn is "";
 4764     var integer: row is 1;
 4765   begin
 4766     if state.details then
 4767       writeln("testBlobField: " <& databaseKind);
 4768     end if;
 4769     block
 4770       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 4771                          " (" & state.fieldName & " " & blobType(databaseKind) & ")");
 4772       execute(state.statement);
 4773       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4774                            " (" & state.fieldName & ") VALUES (?)");
 4775       insert(state, NULL,                  expect &:= bstring(""));
 4776       insert(state, bstring(""),           expect &:= bstring(""));
 4777       insert(state, bstring("X"),          expect &:= bstring("X"));
 4778       insert(state, bstring("!~"),         expect &:= bstring("!~"));
 4779       insert(state, bstring("Ab2"),        expect &:= bstring("Ab2"));
 4780       insert(state, bstring("abcdefghij"), expect &:= bstring("abcdefghij"));
 4781       insert(state, bstring("ÄäÖöÜüß"),    expect &:= bstring("ÄäÖöÜüß"));
 4782       insert(state, bstring("µ¹²³¼½«»¬"),  expect &:= bstring("µ¹²³¼½«»¬"));
 4783       insert(state, bstring("x" mult 65535), expect &:= bstring("x" mult 65535));
 4784       insert(state, bstring("y" mult 1000000), expect &:= bstring("y" mult 1000000));
 4785       # BStrings that contain all possible byte values (from 0 to 255):
 4786       insert(state, bstring("\0;\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4787                             \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4788                             \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;\127;"),
 4789          expect &:= bstring("\0;\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4790                             \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4791                             \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;\127;"));
 4792       insert(state, bstring("\128;\129;\130;\131;\132;\133;\134;\135;\
 4793                             \\136;\137;\138;\139;\140;\141;\142;\143;\144;\145;\146;\147;\148;\
 4794                             \\149;\150;\151;\152;\153;\154;\155;\156;\157;\158;\159;\160;"),
 4795          expect &:= bstring("\128;\129;\130;\131;\132;\133;\134;\135;\
 4796                             \\136;\137;\138;\139;\140;\141;\142;\143;\144;\145;\146;\147;\148;\
 4797                             \\149;\150;\151;\152;\153;\154;\155;\156;\157;\158;\159;\160;"));
 4798       insert(state, bstring(" !\"#$%&'()*+,-./"),          expect &:= bstring(" !\"#$%&'()*+,-./"));
 4799       insert(state, bstring("0123456789:;<=>?@"),          expect &:= bstring("0123456789:;<=>?@"));
 4800       insert(state, bstring("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), expect &:= bstring("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
 4801       insert(state, bstring("[\\]^_`{|}~\127;"),           expect &:= bstring("[\\]^_`{|}~\127;"));
 4802       insert(state, bstring("abcdefghijklmnopqrstuvwxyz"), expect &:= bstring("abcdefghijklmnopqrstuvwxyz"));
 4803       insert(state, bstring("\160;¡¢£¤¥¦§¨©ª«¬­®¯"),       expect &:= bstring("\160;¡¢£¤¥¦§¨©ª«¬­®¯"));
 4804       insert(state, bstring("°±²³´µ¶·¸¹º»¼½¾¿"),           expect &:= bstring("°±²³´µ¶·¸¹º»¼½¾¿"));
 4805       insert(state, bstring("ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ"),           expect &:= bstring("ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ"));
 4806       insert(state, bstring("ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß"),           expect &:= bstring("ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß"));
 4807       insert(state, bstring("àáâãäåæçèéêëìíîï"),           expect &:= bstring("àáâãäåæçèéêëìíîï"));
 4808       insert(state, bstring("ðñòóôõö÷øùúûüýþÿ"),           expect &:= bstring("ðñòóôõö÷øùúûüýþÿ"));
 4809       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 4810       execute(state.statement);
 4811       while fetch(state.statement) do
 4812         bstringColumn := column(state.statement, 1, bstring);
 4813         if bstringColumn <> expect[row] then
 4814           state.okay := FALSE;
 4815           if state.details then
 4816             if length(expect[row]) <= 1000 and length(bstringColumn) <= 1000 then
 4817               writeln(" *** testBlobField: Row: " <& row <&
 4818                       " Expected " <& literal(str(expect[row])) <&
 4819                       " found bstring " <& literal(str(bstringColumn)));
 4820             else
 4821               writeln(" *** testBlobField: Row: " <& row <&
 4822                       " Expected length: " <& length(expect[row]) <&
 4823                       " bstring length found: " <& length(bstringColumn));
 4824             end if;
 4825           end if;
 4826         end if;
 4827         if row = 1 and not isNull(state.statement, 1) then
 4828           state.okay := FALSE;
 4829           if state.details then
 4830             writeln(" *** testBlobField: Row: " <& row <&
 4831                     " Expected NULL found " <& bstringColumn);
 4832           end if;
 4833         end if;
 4834         stringColumn := column(state.statement, 1, string);
 4835         if stringColumn <> string(expect[row]) then
 4836           state.okay := FALSE;
 4837           if state.details then
 4838             if length(expect[row]) <= 1000 and length(stringColumn) <= 1000 then
 4839               writeln(" *** testBlobField: Row: " <& row <&
 4840                       " Expected " <& literal(str(expect[row])) <&
 4841                       " found string " <& literal(str(stringColumn)));
 4842             else
 4843               writeln(" *** testBlobField: Row: " <& row <&
 4844                       " Expected length: " <& length(expect[row]) <&
 4845                       " string length found: " <& length(stringColumn));
 4846             end if;
 4847           end if;
 4848         end if;
 4849         if row = 1 and not isNull(state.statement, 1) then
 4850           state.okay := FALSE;
 4851           if state.details then
 4852             writeln(" *** testBlobField: Row: " <& row <&
 4853                     " Expected NULL found " <& stringColumn);
 4854           end if;
 4855         end if;
 4856         if length(expect[row]) <> 0 and isNull(state.statement, 1) then
 4857           state.okay := FALSE;
 4858           if state.details then
 4859             writeln(" *** testBlobField: Row: " <& row <&
 4860                     " Expected " <& literal(str(expect[row])) <& " found NULL");
 4861           end if;
 4862         end if;
 4863         incr(row);
 4864       end while;
 4865     exception
 4866       catch RANGE_ERROR:
 4867         state.okay := FALSE;
 4868         writeln(" *** RANGE_ERROR was raised");
 4869       catch FILE_ERROR:
 4870         state.okay := FALSE;
 4871         writeln(" *** FILE_ERROR was raised");
 4872       catch DATABASE_ERROR:
 4873         state.okay := FALSE;
 4874         writeln(" *** DATABASE_ERROR was raised");
 4875     end block;
 4876     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 4877     execute(state.statement);
 4878 
 4879     if state.okay then
 4880       writeln("Inserting and fetching blob fields works okay.");
 4881     else
 4882       writeln(" *** Inserting and fetching blob fields does not work okay.");
 4883     end if;
 4884   end func;
 4885 
 4886 
 4887 const proc: testClobField (in database: testDb, in dbCategory: databaseKind) is func
 4888   local
 4889     var testState: state is testState("clobTest", "clobField", FALSE);
 4890     var array string: expect is 0 times "";
 4891     var string: stringColumn is "";
 4892     var integer: row is 1;
 4893   begin
 4894     if state.details then
 4895       writeln("testClobField: " <& databaseKind);
 4896     end if;
 4897     block
 4898       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 4899                          " (" & state.fieldName & " " & clobType(databaseKind) & ")");
 4900       execute(state.statement);
 4901       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 4902                            " (" & state.fieldName & ") VALUES (?)");
 4903       insert(state, NULL,         expect &:= "");
 4904       insert(state, "",           expect &:= "");
 4905       insert(state, "X",          expect &:= "X");
 4906       insert(state, "Ab2",        expect &:= "Ab2");
 4907       insert(state, "abcdefghij", expect &:= "abcdefghij");
 4908       insert(state, "ÄäÖöÜüß",    expect &:= "ÄäÖöÜüß");
 4909       insert(state, "€µ¹²³¼½«»¬", expect &:= "€µ¹²³¼½«»¬");
 4910       # Chars that are defined with different ordinal in code page 1252:
 4911       insert(state, "€‚ƒ„…†‡ˆ‰",  expect &:= "€‚ƒ„…†‡ˆ‰");
 4912       insert(state, "Š‹ŒŽ‘’“”•",  expect &:= "Š‹ŒŽ‘’“”•");
 4913       insert(state, "–—˜™š›œžŸ",  expect &:= "–—˜™š›œžŸ");
 4914       insert(state, "x" mult 32,  expect &:= "x" mult 32);
 4915       insert(state, "A B",        expect &:= "A B");
 4916       insert(state, "x" mult 65535,   expect &:= "x" mult 65535);
 4917       insert(state, "y" mult 1000000, expect &:= "y" mult 1000000);
 4918       if nullAllowedInString(databaseKind) then
 4919         insert(state, "A\0;B",    expect &:= "A\0;B");
 4920       end if;
 4921       insert(state, "\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4922                     \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4923                     \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;\127;",
 4924          expect &:= "\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 4925                     \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 4926                     \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;\127;");
 4927       insert(state, " !\"#$%&'()*+,-./",          expect &:= " !\"#$%&'()*+,-./");
 4928       insert(state, "0123456789:;<=>?@",          expect &:= "0123456789:;<=>?@");
 4929       insert(state, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", expect &:= "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
 4930       insert(state, "[\\]^_`{|}~\127;",           expect &:= "[\\]^_`{|}~\127;");
 4931       insert(state, "abcdefghijklmnopqrstuvwxyz", expect &:= "abcdefghijklmnopqrstuvwxyz");
 4932       insert(state, "\160;¡¢£¤¥¦§¨©ª«¬­®¯",       expect &:= "\160;¡¢£¤¥¦§¨©ª«¬­®¯");
 4933       insert(state, "°±²³´µ¶·¸¹º»¼½¾¿",           expect &:= "°±²³´µ¶·¸¹º»¼½¾¿");
 4934       insert(state, "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ",           expect &:= "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ");
 4935       insert(state, "ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß",           expect &:= "ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß");
 4936       insert(state, "àáâãäåæçèéêëìíîï",           expect &:= "àáâãäåæçèéêëìíîï");
 4937       insert(state, "ðñòóôõö÷øùúûüýþÿ",           expect &:= "ðñòóôõö÷øùúûüýþÿ");
 4938       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 4939       execute(state.statement);
 4940       while fetch(state.statement) do
 4941         stringColumn := column(state.statement, 1, string);
 4942         if stringColumn <> expect[row] then
 4943           state.okay := FALSE;
 4944           if state.details then
 4945             if length(expect[row]) <= 1000 and length(stringColumn) <= 1000 then
 4946               writeln(" *** testClobField: Row: " <& row <&
 4947                       " Expected " <& literal(expect[row]) <&
 4948                       " found string " <& literal(str(stringColumn)));
 4949             else
 4950               writeln(" *** testClobField: Row: " <& row <&
 4951                       " Expected length: " <& length(expect[row]) <&
 4952                       " string length found: " <& length(stringColumn));
 4953             end if;
 4954           end if;
 4955         end if;
 4956         if row = 1 and not isNull(state.statement, 1) then
 4957           state.okay := FALSE;
 4958           if state.details then
 4959             writeln(" *** testClobField: Row: " <& row <&
 4960                     " Expected NULL found " <& stringColumn);
 4961           end if;
 4962         end if;
 4963         if length(expect[row]) <> 0 and isNull(state.statement, 1) then
 4964           state.okay := FALSE;
 4965           if state.details then
 4966             writeln(" *** testClobField: Row: " <& row <&
 4967                     " Expected " <& literal(str(expect[row])) <& " found NULL");
 4968           end if;
 4969         end if;
 4970         incr(row);
 4971       end while;
 4972     exception
 4973       catch RANGE_ERROR:
 4974         state.okay := FALSE;
 4975         writeln(" *** RANGE_ERROR was raised");
 4976       catch FILE_ERROR:
 4977         state.okay := FALSE;
 4978         writeln(" *** FILE_ERROR was raised");
 4979       catch DATABASE_ERROR:
 4980         state.okay := FALSE;
 4981         writeln(" *** DATABASE_ERROR was raised");
 4982     end block;
 4983     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 4984     execute(state.statement);
 4985 
 4986     if state.okay then
 4987       writeln("Inserting and fetching clob fields works okay.");
 4988     else
 4989       writeln(" *** Inserting and fetching clob fields does not work okay.");
 4990     end if;
 4991   end func;
 4992 
 4993 
 4994 const proc: testDateField (in database: testDb, in dbCategory: databaseKind) is func
 4995   local
 4996     var testState: state is testState("dateTest", "dateField", FALSE);
 4997     var array time: expect is 0 times time.value;
 4998     var time: dateColumn is time.value;
 4999     var integer: row is 1;
 5000   begin
 5001     if state.details then
 5002       writeln("testDateField: " <& databaseKind);
 5003     end if;
 5004     block
 5005       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 5006                                  " (" & state.fieldName & " DATE)");
 5007       execute(state.statement);
 5008       insert(testDb, state, "NULL", expect &:= time.value);
 5009       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 5010                                  " (" & state.fieldName & ") VALUES (?)");
 5011       insert(state, NULL,               expect &:= time.value);
 5012 
 5013       if minDate(databaseKind) <= time("-4711-1-1 0:0:0") then
 5014         insert(testDb, state, toDate(databaseKind, "-4711-1-1"),   expect &:= time("-4711-1-1"));
 5015         insert(testDb, state, toDate(databaseKind, "-4711-12-31"), expect &:= time("-4711-12-31"));
 5016         insert(testDb, state, toDate(databaseKind, "-999-12-31"),  expect &:= time("-999-12-31"));
 5017         insert(testDb, state, toDate(databaseKind, "-123-1-23"),   expect &:= time("-123-1-23"));
 5018         insert(testDb, state, toDate(databaseKind, "-42-4-2"),     expect &:= time("-42-4-2"));
 5019         insert(testDb, state, toDate(databaseKind, "-1-1-1"),      expect &:= time("-1-1-1"));
 5020         insert(testDb, state, toDate(databaseKind, "-1-12-31"),    expect &:= time("-1-12-31"));
 5021       end if;
 5022       if minDate(databaseKind) < time("1-1-1 0:0:0") then
 5023         insert(testDb, state, toDate(databaseKind, "0-1-1"),       expect &:= time("0-1-1"));
 5024         insert(testDb, state, toDate(databaseKind, "0-12-31"),     expect &:= time("0-12-31"));
 5025       end if;
 5026       insert(testDb, state, toDate(databaseKind, "1-1-1"),       expect &:= time("1-1-1"));
 5027       insert(testDb, state, toDate(databaseKind, "1-12-31"),     expect &:= time("1-12-31"));
 5028       insert(testDb, state, toDate(databaseKind, "42-4-2"),      expect &:= time("42-4-2"));
 5029       insert(testDb, state, toDate(databaseKind, "123-1-23"),    expect &:= time("123-1-23"));
 5030       insert(testDb, state, toDate(databaseKind, "999-12-31"),   expect &:= time("999-12-31"));
 5031       insert(testDb, state, toDate(databaseKind, "1000-1-1"),    expect &:= time("1000-1-1"));
 5032       insert(testDb, state, toDate(databaseKind, "1752-12-31"),  expect &:= time("1752-12-31"));
 5033       insert(testDb, state, toDate(databaseKind, "1753-1-1"),    expect &:= time("1753-1-1"));
 5034       insert(testDb, state, toDate(databaseKind, "1800-1-1"),    expect &:= time("1800-1-1"));
 5035       insert(testDb, state, toDate(databaseKind, "1899-12-31"),  expect &:= time("1899-12-31"));
 5036       insert(testDb, state, toDate(databaseKind, "1900-1-1"),    expect &:= time("1900-1-1"));
 5037       insert(testDb, state, toDate(databaseKind, "1961-1-9"),    expect &:= time("1961-1-9"));
 5038       insert(testDb, state, toDate(databaseKind, "1969-12-31"),  expect &:= time("1969-12-31"));
 5039       insert(testDb, state, toDate(databaseKind, "1970-1-1"),    expect &:= time("1970-1-1"));
 5040       insert(testDb, state, toDate(databaseKind, "1979-12-31"),  expect &:= time("1979-12-31"));
 5041       insert(testDb, state, toDate(databaseKind, "1980-1-1"),    expect &:= time("1980-1-1"));
 5042       insert(testDb, state, toDate(databaseKind, "2010-11-12"),  expect &:= time("2010-11-12"));
 5043       insert(testDb, state, toDate(databaseKind, "2011-11-11"),  expect &:= time("2011-11-11"));
 5044       insert(testDb, state, toDate(databaseKind, "2012-12-12"),  expect &:= time("2012-12-12"));
 5045 
 5046       if minDate(databaseKind) <= time("-4711-1-1 0:0:0") then
 5047         insert(state, time("-4711-1-1"),   expect &:= time("-4711-1-1"));
 5048         insert(state, time("-4711-12-31"), expect &:= time("-4711-12-31"));
 5049         insert(state, time("-999-12-31"),  expect &:= time("-999-12-31"));
 5050         insert(state, time("-123-1-23"),   expect &:= time("-123-1-23"));
 5051         insert(state, time("-42-4-2"),     expect &:= time("-42-4-2"));
 5052         insert(state, time("-1-1-1"),      expect &:= time("-1-1-1"));
 5053         insert(state, time("-1-12-31"),    expect &:= time("-1-12-31"));
 5054       end if;
 5055       if minDate(databaseKind) < time("1-1-1 0:0:0") then
 5056         insert(state, time("0-1-1"),       expect &:= time("0-1-1"));
 5057         insert(state, time("0-12-31"),     expect &:= time("0-12-31"));
 5058       end if;
 5059       insert(state, time("1-1-1"),       expect &:= time("1-1-1"));
 5060       insert(state, time("1-12-31"),     expect &:= time("1-12-31"));
 5061       insert(state, time("42-4-2"),      expect &:= time("42-4-2"));
 5062       insert(state, time("123-1-23"),    expect &:= time("123-1-23"));
 5063       insert(state, time("999-12-31"),   expect &:= time("999-12-31"));
 5064       insert(state, time("1000-1-1"),    expect &:= time("1000-1-1"));
 5065       insert(state, time("1752-12-31"),  expect &:= time("1752-12-31"));
 5066       insert(state, time("1753-1-1"),    expect &:= time("1753-1-1"));
 5067       insert(state, time("1800-1-1"),    expect &:= time("1800-1-1"));
 5068       insert(state, time("1899-12-31"),  expect &:= time("1899-12-31"));
 5069       insert(state, time("1900-1-1"),    expect &:= time("1900-1-1"));
 5070       insert(state, time("1961-1-9"),    expect &:= time("1961-1-9"));
 5071       insert(state, time("1969-12-31"),  expect &:= time("1969-12-31"));
 5072       insert(state, time("1970-1-1"),    expect &:= time("1970-1-1"));
 5073       insert(state, time("1979-12-31"),  expect &:= time("1979-12-31"));
 5074       insert(state, time("1980-1-1"),    expect &:= time("1980-1-1"));
 5075       insert(state, time("2010-11-12"),  expect &:= time("2010-11-12"));
 5076       insert(state, time("2011-11-11"),  expect &:= time("2011-11-11"));
 5077       insert(state, time("2012-12-12"),  expect &:= time("2012-12-12"));
 5078 
 5079       if minDate(databaseKind) <= time("-4711-1-1 0:0:0") then
 5080         insert(state, setLocalTZ(time("-4711-1-1")),   expect &:= setLocalTZ(time("-4711-1-1")));
 5081         insert(state, setLocalTZ(time("-4711-12-31")), expect &:= setLocalTZ(time("-4711-12-31")));
 5082         insert(state, setLocalTZ(time("-999-12-31")),  expect &:= setLocalTZ(time("-999-12-31")));
 5083         insert(state, setLocalTZ(time("-123-1-23")),   expect &:= setLocalTZ(time("-123-1-23")));
 5084         insert(state, setLocalTZ(time("-42-4-2")),     expect &:= setLocalTZ(time("-42-4-2")));
 5085         insert(state, setLocalTZ(time("-1-1-1")),      expect &:= setLocalTZ(time("-1-1-1")));
 5086         insert(state, setLocalTZ(time("-1-12-31")),    expect &:= setLocalTZ(time("-1-12-31")));
 5087       end if;
 5088       if minDate(databaseKind) < time("1-1-1 0:0:0") then
 5089         insert(state, setLocalTZ(time("0-1-1")),       expect &:= setLocalTZ(time("0-1-1")));
 5090         insert(state, setLocalTZ(time("0-12-31")),     expect &:= setLocalTZ(time("0-12-31")));
 5091       end if;
 5092       insert(state, setLocalTZ(time("1-1-1")),       expect &:= setLocalTZ(time("1-1-1")));
 5093       insert(state, setLocalTZ(time("42-4-2")),      expect &:= setLocalTZ(time("42-4-2")));
 5094       insert(state, setLocalTZ(time("123-1-23")),    expect &:= setLocalTZ(time("123-1-23")));
 5095       insert(state, setLocalTZ(time("999-12-31")),   expect &:= setLocalTZ(time("999-12-31")));
 5096       insert(state, setLocalTZ(time("1000-1-1")),    expect &:= setLocalTZ(time("1000-1-1")));
 5097       insert(state, setLocalTZ(time("1752-12-31")),  expect &:= setLocalTZ(time("1752-12-31")));
 5098       insert(state, setLocalTZ(time("1753-1-1")),    expect &:= setLocalTZ(time("1753-1-1")));
 5099       insert(state, setLocalTZ(time("1800-1-1")),    expect &:= setLocalTZ(time("1800-1-1")));
 5100       insert(state, setLocalTZ(time("1899-12-31")),  expect &:= setLocalTZ(time("1899-12-31")));
 5101       insert(state, setLocalTZ(time("1900-1-1")),    expect &:= setLocalTZ(time("1900-1-1")));
 5102       insert(state, setLocalTZ(time("1961-1-9")),    expect &:= setLocalTZ(time("1961-1-9")));
 5103       insert(state, setLocalTZ(time("1969-12-31")),  expect &:= setLocalTZ(time("1969-12-31")));
 5104       insert(state, setLocalTZ(time("1970-1-1")),    expect &:= setLocalTZ(time("1970-1-1")));
 5105       insert(state, setLocalTZ(time("1979-12-31")),  expect &:= setLocalTZ(time("1979-12-31")));
 5106       insert(state, setLocalTZ(time("1980-1-1")),    expect &:= setLocalTZ(time("1980-1-1")));
 5107       insert(state, setLocalTZ(time("2010-11-12")),  expect &:= setLocalTZ(time("2010-11-12")));
 5108       insert(state, setLocalTZ(time("2011-11-11")),  expect &:= setLocalTZ(time("2011-11-11")));
 5109       insert(state, setLocalTZ(time("2012-12-12")),  expect &:= setLocalTZ(time("2012-12-12")));
 5110 
 5111       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 5112       execute(state.statement);
 5113       while fetch(state.statement) do
 5114         dateColumn := column(state.statement, 1, time);
 5115         if dateColumn <> expect[row] then
 5116           state.okay := FALSE;
 5117           if state.details then
 5118             writeln(" *** testDateField: Row: " <& row <&
 5119                     " Expected " <& literal(str(expect[row])) <&
 5120                     " found " <& literal(str(dateColumn)));
 5121           end if;
 5122         end if;
 5123         if row <= 2 and not isNull(state.statement, 1) then
 5124           state.okay := FALSE;
 5125           if state.details then
 5126             writeln(" *** testDateField: Row: " <& row <&
 5127                     " Expected NULL found " <& dateColumn);
 5128           end if;
 5129         end if;
 5130         if row > 2 and isNull(state.statement, 1) then
 5131           state.okay := FALSE;
 5132           if state.details then
 5133             writeln(" *** testDateField: Row: " <& row <&
 5134                     " Expected " <& literal(expect[row]) <& " found NULL");
 5135           end if;
 5136         end if;
 5137         incr(row);
 5138       end while;
 5139     exception
 5140       catch RANGE_ERROR:
 5141         state.okay := FALSE;
 5142         writeln(" *** RANGE_ERROR was raised");
 5143       catch FILE_ERROR:
 5144         state.okay := FALSE;
 5145         writeln(" *** FILE_ERROR was raised");
 5146       catch DATABASE_ERROR:
 5147         state.okay := FALSE;
 5148         writeln(" *** DATABASE_ERROR was raised");
 5149     end block;
 5150     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 5151     execute(state.statement);
 5152 
 5153     if state.okay then
 5154       writeln("Inserting and fetching date fields works okay.");
 5155     else
 5156       writeln(" *** Inserting and fetching date fields does not work okay.");
 5157     end if;
 5158   end func;
 5159 
 5160 
 5161 const proc: testTimeField (in database: testDb, in dbCategory: databaseKind) is func
 5162   local
 5163     var testState: state is testState("timeTest", "timeField", FALSE);
 5164     var array time: expect is 0 times time.value;
 5165     var time: timeColumn is time.value;
 5166     var integer: row is 1;
 5167   begin
 5168     if state.details then
 5169       writeln("testTimeField: " <& databaseKind);
 5170     end if;
 5171     block
 5172       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 5173                                  " (" & state.fieldName & " " & timeType(databaseKind) & ")");
 5174       execute(state.statement);
 5175       insert(testDb, state, "NULL", expect &:= time.value);
 5176       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 5177                                  " (" & state.fieldName & ") VALUES (?)");
 5178       insert(state, NULL,               expect &:= time.value);
 5179 
 5180       insert(testDb, state, toTime(databaseKind, "0:0:0"),           expect &:= time("0:0:0"));
 5181       insert(testDb, state, toTime(databaseKind, "0:0:59"),          expect &:= time("0:0:59"));
 5182       insert(testDb, state, toTime(databaseKind, "0:59:59"),         expect &:= time("0:59:59"));
 5183       insert(testDb, state, toTime(databaseKind, "1:0:0"),           expect &:= time("1:0:0"));
 5184       insert(testDb, state, toTime(databaseKind, "11:59:59"),        expect &:= time("11:59:59"));
 5185       insert(testDb, state, toTime(databaseKind, "12:0:0"),          expect &:= time("12:0:0"));
 5186       insert(testDb, state, toTime(databaseKind, "23:59:59"),        expect &:= time("23:59:59"));
 5187 
 5188       insert(state, time("0:0:0"),           expect &:= time("0:0:0"));
 5189       insert(state, time("0:0:59"),          expect &:= time("0:0:59"));
 5190       insert(state, time("0:59:59"),         expect &:= time("0:59:59"));
 5191       insert(state, time("1:0:0"),           expect &:= time("1:0:0"));
 5192       insert(state, time("11:59:59"),        expect &:= time("11:59:59"));
 5193       insert(state, time("12:0:0"),          expect &:= time("12:0:0"));
 5194       insert(state, time("23:59:59"),        expect &:= time("23:59:59"));
 5195 
 5196       insert(state, setLocalTZ(time("0:0:0")),           expect &:= setLocalTZ(time("0:0:0")));
 5197       insert(state, setLocalTZ(time("0:0:59")),          expect &:= setLocalTZ(time("0:0:59")));
 5198       insert(state, setLocalTZ(time("0:59:59")),         expect &:= setLocalTZ(time("0:59:59")));
 5199       insert(state, setLocalTZ(time("1:0:0")),           expect &:= setLocalTZ(time("1:0:0")));
 5200       insert(state, setLocalTZ(time("11:59:59")),        expect &:= setLocalTZ(time("11:59:59")));
 5201       insert(state, setLocalTZ(time("12:0:0")),          expect &:= setLocalTZ(time("12:0:0")));
 5202       insert(state, setLocalTZ(time("23:59:59")),        expect &:= setLocalTZ(time("23:59:59")));
 5203 
 5204       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 5205       execute(state.statement);
 5206       while fetch(state.statement) do
 5207         timeColumn := column(state.statement, 1, time);
 5208         if timeColumn <> expect[row] then
 5209           state.okay := FALSE;
 5210           if state.details then
 5211             writeln(" *** testTimeField: Row: " <& row <&
 5212                     " Expected " <& literal(str(expect[row])) <&
 5213                     " found " <& literal(str(timeColumn)));
 5214           end if;
 5215         end if;
 5216         if row <= 2 and not isNull(state.statement, 1) then
 5217           state.okay := FALSE;
 5218           if state.details then
 5219             writeln(" *** testTimeField: Row: " <& row <&
 5220                     " Expected NULL found " <& timeColumn);
 5221           end if;
 5222         end if;
 5223         if row > 2 and isNull(state.statement, 1) then
 5224           state.okay := FALSE;
 5225           if state.details then
 5226             writeln(" *** testTimeField: Row: " <& row <&
 5227                     " Expected " <& literal(expect[row]) <& " found NULL");
 5228           end if;
 5229         end if;
 5230         incr(row);
 5231       end while;
 5232     exception
 5233       catch RANGE_ERROR:
 5234         state.okay := FALSE;
 5235         writeln(" *** RANGE_ERROR was raised");
 5236       catch FILE_ERROR:
 5237         state.okay := FALSE;
 5238         writeln(" *** FILE_ERROR was raised");
 5239       catch DATABASE_ERROR:
 5240         state.okay := FALSE;
 5241         writeln(" *** DATABASE_ERROR was raised");
 5242     end block;
 5243     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 5244     execute(state.statement);
 5245 
 5246     if state.okay then
 5247       writeln("Inserting and fetching time fields works okay.");
 5248     else
 5249       writeln(" *** Inserting and fetching time fields does not work okay.");
 5250     end if;
 5251   end func;
 5252 
 5253 
 5254 const proc: testDateTimeField (in database: testDb, in dbCategory: databaseKind) is func
 5255   local
 5256     var testState: state is testState("dateTimeTest", "dateTimeField", FALSE);
 5257     var array time: expect is 0 times time.value;
 5258     var time: dateTimeColumn is time.value;
 5259     var integer: row is 1;
 5260   begin
 5261     if state.details then
 5262       writeln("testDateTimeField: " <& databaseKind);
 5263     end if;
 5264     block
 5265       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 5266                                  " (" & state.fieldName & " " & dateTimeType(databaseKind) & ")");
 5267       execute(state.statement);
 5268       insert(testDb, state, "NULL", expect &:= time.value);
 5269       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 5270                                  " (" & state.fieldName & ") VALUES (?)");
 5271       insert(state, NULL,                           expect &:= time.value);
 5272 
 5273       if minDate(databaseKind) <= time("-4711-1-1 0:0:0") then
 5274         insert(testDb, state, toDateTime(databaseKind, "-4711-1-1 0:0:0"),      expect &:= time("-4711-1-1 0:0:0"));
 5275         insert(testDb, state, toDateTime(databaseKind, "-4711-12-31 23:59:59"), expect &:= time("-4711-12-31 23:59:59"));
 5276         insert(testDb, state, toDateTime(databaseKind, "-999-12-31 23:59:59"),  expect &:= time("-999-12-31 23:59:59"));
 5277         insert(testDb, state, toDateTime(databaseKind, "-123-1-23 12:31:12"),   expect &:= time("-123-1-23 12:31:12"));
 5278         insert(testDb, state, toDateTime(databaseKind, "-42-4-2 4:42:42"),      expect &:= time("-42-4-2 4:42:42"));
 5279         insert(testDb, state, toDateTime(databaseKind, "-1-1-1 0:0:0"),         expect &:= time("-1-1-1 0:0:0"));
 5280         insert(testDb, state, toDateTime(databaseKind, "-1-12-31 23:59:59"),    expect &:= time("-1-12-31 23:59:59"));
 5281       end if;
 5282       if minDate(databaseKind) < time("1-1-1 0:0:0") then
 5283         insert(testDb, state, toDateTime(databaseKind, "0-1-1 0:0:0"),          expect &:= time("0-1-1 0:0:0"));
 5284         insert(testDb, state, toDateTime(databaseKind, "0-12-31 23:59:59"),     expect &:= time("0-12-31 23:59:59"));
 5285       end if;
 5286       insert(testDb, state, toDateTime(databaseKind, "1-1-1 0:0:0"),          expect &:= time("1-1-1 0:0:0"));
 5287       insert(testDb, state, toDateTime(databaseKind, "1-12-31 23:59:59"),     expect &:= time("1-12-31 23:59:59"));
 5288       insert(testDb, state, toDateTime(databaseKind, "42-4-2 4:42:42"),       expect &:= time("42-4-2 4:42:42"));
 5289       insert(testDb, state, toDateTime(databaseKind, "123-1-23 12:31:12"),    expect &:= time("123-1-23 12:31:12"));
 5290       insert(testDb, state, toDateTime(databaseKind, "999-12-31 23:59:59"),   expect &:= time("999-12-31 23:59:59"));
 5291       insert(testDb, state, toDateTime(databaseKind, "1000-1-1 0:0:0"),       expect &:= time("1000-1-1 0:0:0"));
 5292       insert(testDb, state, toDateTime(databaseKind, "1752-12-31 23:59:59"),  expect &:= time("1752-12-31 23:59:59"));
 5293       insert(testDb, state, toDateTime(databaseKind, "1753-1-1 0:0:0"),       expect &:= time("1753-1-1 0:0:0"));
 5294       insert(testDb, state, toDateTime(databaseKind, "1800-1-1 0:0:0"),       expect &:= time("1800-1-1 0:0:0"));
 5295       insert(testDb, state, toDateTime(databaseKind, "1899-12-31 23:59:59"),  expect &:= time("1899-12-31 23:59:59"));
 5296       insert(testDb, state, toDateTime(databaseKind, "1900-1-1 0:0:0"),       expect &:= time("1900-1-1 0:0:0"));
 5297       insert(testDb, state, toDateTime(databaseKind, "1961-1-9 6:1:0"),       expect &:= time("1961-1-9 6:1:0"));
 5298       insert(testDb, state, toDateTime(databaseKind, "1969-12-31 23:59:59"),  expect &:= time("1969-12-31 23:59:59"));
 5299       insert(testDb, state, toDateTime(databaseKind, "1970-1-1 0:0:0"),       expect &:= time("1970-1-1 0:0:0"));
 5300       insert(testDb, state, toDateTime(databaseKind, "1979-12-31 23:59:59"),  expect &:= time("1979-12-31 23:59:59"));
 5301       insert(testDb, state, toDateTime(databaseKind, "1980-1-1 0:0:0"),       expect &:= time("1980-1-1 0:0:0"));
 5302       insert(testDb, state, toDateTime(databaseKind, "2010-11-12 13:14:15"),  expect &:= time("2010-11-12 13:14:15"));
 5303       insert(testDb, state, toDateTime(databaseKind, "2011-11-11 11:11:11"),  expect &:= time("2011-11-11 11:11:11"));
 5304       insert(testDb, state, toDateTime(databaseKind, "2012-12-12 12:12:12"),  expect &:= time("2012-12-12 12:12:12"));
 5305 
 5306       if minDate(databaseKind) <= time("-4711-1-1 0:0:0") then
 5307         insert(state, time("-4711-1-1 0:0:0"),      expect &:= time("-4711-1-1 0:0:0"));
 5308         insert(state, time("-4711-12-31 23:59:59"), expect &:= time("-4711-12-31 23:59:59"));
 5309         insert(state, time("-999-12-31 23:59:59"),  expect &:= time("-999-12-31 23:59:59"));
 5310         insert(state, time("-123-1-23 12:31:12"),   expect &:= time("-123-1-23 12:31:12"));
 5311         insert(state, time("-42-4-2 4:42:42"),      expect &:= time("-42-4-2 4:42:42"));
 5312         insert(state, time("-1-1-1 0:0:0"),         expect &:= time("-1-1-1 0:0:0"));
 5313         insert(state, time("-1-12-31 23:59:59"),    expect &:= time("-1-12-31 23:59:59"));
 5314       end if;
 5315       if minDate(databaseKind) < time("1-1-1 0:0:0") then
 5316         insert(state, time("0-1-1 0:0:0"),          expect &:= time("0-1-1 0:0:0"));
 5317         insert(state, time("0-12-31 23:59:59"),     expect &:= time("0-12-31 23:59:59"));
 5318       end if;
 5319       insert(state, time("1-1-1 0:0:0"),          expect &:= time("1-1-1 0:0:0"));
 5320       insert(state, time("1-12-31 23:59:59"),     expect &:= time("1-12-31 23:59:59"));
 5321       insert(state, time("42-4-2 4:42:42"),       expect &:= time("42-4-2 4:42:42"));
 5322       insert(state, time("123-1-23 12:31:12"),    expect &:= time("123-1-23 12:31:12"));
 5323       insert(state, time("999-12-31 23:59:59"),   expect &:= time("999-12-31 23:59:59"));
 5324       insert(state, time("1000-1-1 0:0:0"),       expect &:= time("1000-1-1 0:0:0"));
 5325       insert(state, time("1752-12-31 23:59:59"),  expect &:= time("1752-12-31 23:59:59"));
 5326       insert(state, time("1753-1-1 0:0:0"),       expect &:= time("1753-1-1 0:0:0"));
 5327       insert(state, time("1800-1-1 0:0:0"),       expect &:= time("1800-1-1 0:0:0"));
 5328       insert(state, time("1899-12-31 23:59:59"),  expect &:= time("1899-12-31 23:59:59"));
 5329       insert(state, time("1900-1-1 0:0:0"),       expect &:= time("1900-1-1 0:0:0"));
 5330       insert(state, time("1961-1-9 6:1:0"),       expect &:= time("1961-1-9 6:1:0"));
 5331       insert(state, time("1969-12-31 23:59:59"),  expect &:= time("1969-12-31 23:59:59"));
 5332       insert(state, time("1970-1-1 0:0:0"),       expect &:= time("1970-1-1 0:0:0"));
 5333       insert(state, time("1979-12-31 23:59:59"),  expect &:= time("1979-12-31 23:59:59"));
 5334       insert(state, time("1980-1-1 0:0:0"),       expect &:= time("1980-1-1 0:0:0"));
 5335       insert(state, time("2010-11-12 13:14:15"),  expect &:= time("2010-11-12 13:14:15"));
 5336       insert(state, time("2011-11-11 11:11:11"),  expect &:= time("2011-11-11 11:11:11"));
 5337       insert(state, time("2012-12-12 12:12:12"),  expect &:= time("2012-12-12 12:12:12"));
 5338 
 5339       if minDate(databaseKind) <= time("-4711-1-1 0:0:0") then
 5340         insert(state, setLocalTZ(time("-4711-1-1 0:0:0")),      expect &:= setLocalTZ(time("-4711-1-1 0:0:0")));
 5341         insert(state, setLocalTZ(time("-4711-12-31 23:59:59")), expect &:= setLocalTZ(time("-4711-12-31 23:59:59")));
 5342         insert(state, setLocalTZ(time("-999-12-31 23:59:59")),  expect &:= setLocalTZ(time("-999-12-31 23:59:59")));
 5343         insert(state, setLocalTZ(time("-123-1-23 12:31:12")),   expect &:= setLocalTZ(time("-123-1-23 12:31:12")));
 5344         insert(state, setLocalTZ(time("-42-4-2 4:42:42")),      expect &:= setLocalTZ(time("-42-4-2 4:42:42")));
 5345         insert(state, setLocalTZ(time("-1-1-1 0:0:0")),         expect &:= setLocalTZ(time("-1-1-1 0:0:0")));
 5346         insert(state, setLocalTZ(time("-1-12-31 23:59:59")),    expect &:= setLocalTZ(time("-1-12-31 23:59:59")));
 5347       end if;
 5348       if minDate(databaseKind) < time("1-1-1 0:0:0") then
 5349         insert(state, setLocalTZ(time("0-1-1 0:0:0")),          expect &:= setLocalTZ(time("0-1-1 0:0:0")));
 5350         insert(state, setLocalTZ(time("0-12-31 23:59:59")),     expect &:= setLocalTZ(time("0-12-31 23:59:59")));
 5351       end if;
 5352       insert(state, setLocalTZ(time("1-1-1 0:0:0")),          expect &:= setLocalTZ(time("1-1-1 0:0:0")));
 5353       insert(state, setLocalTZ(time("42-4-2 4:42:42")),       expect &:= setLocalTZ(time("42-4-2 4:42:42")));
 5354       insert(state, setLocalTZ(time("123-1-23 12:31:12")),    expect &:= setLocalTZ(time("123-1-23 12:31:12")));
 5355       insert(state, setLocalTZ(time("999-12-31 23:59:59")),   expect &:= setLocalTZ(time("999-12-31 23:59:59")));
 5356       insert(state, setLocalTZ(time("1000-1-1 0:0:0")),       expect &:= setLocalTZ(time("1000-1-1 0:0:0")));
 5357       insert(state, setLocalTZ(time("1752-12-31 23:59:59")),  expect &:= setLocalTZ(time("1752-12-31 23:59:59")));
 5358       insert(state, setLocalTZ(time("1753-1-1 0:0:0")),       expect &:= setLocalTZ(time("1753-1-1 0:0:0")));
 5359       insert(state, setLocalTZ(time("1800-1-1 0:0:0")),       expect &:= setLocalTZ(time("1800-1-1 0:0:0")));
 5360       insert(state, setLocalTZ(time("1899-12-31 23:59:59")),  expect &:= setLocalTZ(time("1899-12-31 23:59:59")));
 5361       insert(state, setLocalTZ(time("1900-1-1 0:0:0")),       expect &:= setLocalTZ(time("1900-1-1 0:0:0")));
 5362       insert(state, setLocalTZ(time("1961-1-9 6:1:0")),       expect &:= setLocalTZ(time("1961-1-9 6:1:0")));
 5363       insert(state, setLocalTZ(time("1969-12-31 23:59:59")),  expect &:= setLocalTZ(time("1969-12-31 23:59:59")));
 5364       insert(state, setLocalTZ(time("1970-1-1 0:0:0")),       expect &:= setLocalTZ(time("1970-1-1 0:0:0")));
 5365       insert(state, setLocalTZ(time("1979-12-31 23:59:59")),  expect &:= setLocalTZ(time("1979-12-31 23:59:59")));
 5366       insert(state, setLocalTZ(time("1980-1-1 0:0:0")),       expect &:= setLocalTZ(time("1980-1-1 0:0:0")));
 5367       insert(state, setLocalTZ(time("2010-11-12 13:14:15")),  expect &:= setLocalTZ(time("2010-11-12 13:14:15")));
 5368       insert(state, setLocalTZ(time("2011-11-11 11:11:11")),  expect &:= setLocalTZ(time("2011-11-11 11:11:11")));
 5369       insert(state, setLocalTZ(time("2012-12-12 12:12:12")),  expect &:= setLocalTZ(time("2012-12-12 12:12:12")));
 5370 
 5371       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 5372       execute(state.statement);
 5373       while fetch(state.statement) do
 5374         dateTimeColumn := column(state.statement, 1, time);
 5375         if dateTimeColumn <> expect[row] then
 5376           state.okay := FALSE;
 5377           if state.details then
 5378             writeln(" *** testDateTimeField: Row: " <& row <&
 5379                     " Expected " <& literal(str(expect[row])) <&
 5380                     " found " <& literal(str(dateTimeColumn)));
 5381           end if;
 5382         end if;
 5383         if row <= 2 and not isNull(state.statement, 1) then
 5384           state.okay := FALSE;
 5385           if state.details then
 5386             writeln(" *** testDateTimeField: Row: " <& row <&
 5387                     " Expected NULL found " <& dateTimeColumn);
 5388           end if;
 5389         end if;
 5390         if row > 2 and isNull(state.statement, 1) then
 5391           state.okay := FALSE;
 5392           if state.details then
 5393             writeln(" *** testDateTimeField: Row: " <& row <&
 5394                     " Expected " <& literal(expect[row]) <& " found NULL");
 5395           end if;
 5396         end if;
 5397         incr(row);
 5398       end while;
 5399     exception
 5400       catch RANGE_ERROR:
 5401         state.okay := FALSE;
 5402         writeln(" *** RANGE_ERROR was raised");
 5403       catch FILE_ERROR:
 5404         state.okay := FALSE;
 5405         writeln(" *** FILE_ERROR was raised");
 5406       catch DATABASE_ERROR:
 5407         state.okay := FALSE;
 5408         writeln(" *** DATABASE_ERROR was raised");
 5409     end block;
 5410     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 5411     execute(state.statement);
 5412 
 5413     if state.okay then
 5414       writeln("Inserting and fetching dateTime fields works okay.");
 5415     else
 5416       writeln(" *** Inserting and fetching dateTime fields does not work okay.");
 5417     end if;
 5418   end func;
 5419 
 5420 
 5421 const proc: testTimeStampField (in database: testDb, in dbCategory: databaseKind) is func
 5422   local
 5423     var testState: state is testState("timeStampTest", "timeStampField", FALSE);
 5424     var array time: expect is 0 times time.value;
 5425     var time: timeColumn is time.value;
 5426     var integer: row is 1;
 5427   begin
 5428     if state.details then
 5429       writeln("testTimeStampField: " <& databaseKind);
 5430     end if;
 5431     block
 5432       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 5433                                  " (" & state.fieldName & " " & timeStampType(databaseKind) & ")");
 5434       execute(state.statement);
 5435       insert(testDb, state, "NULL", expect &:= time.value);
 5436       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 5437                                  " (" & state.fieldName & ") VALUES (?)");
 5438       insert(state, NULL,                           expect &:= time.value);
 5439 
 5440       if minTimeStamp(databaseKind) <= time("-4711-1-1 0:0:0") then
 5441         insert(testDb, state, toTimeStamp(databaseKind, "-4711-1-1 0:0:0"),      expect &:= time("-4711-1-1 0:0:0"));
 5442         insert(testDb, state, toTimeStamp(databaseKind, "-4711-12-31 23:59:59"), expect &:= time("-4711-12-31 23:59:59"));
 5443         insert(testDb, state, toTimeStamp(databaseKind, "-4711-12-31 23:59:59.123456"),
 5444                expect &:= time("-4711-12-31 23:59:59.123456"));
 5445         insert(testDb, state, toTimeStamp(databaseKind, "-999-12-31 23:59:59"),  expect &:= time("-999-12-31 23:59:59"));
 5446         insert(testDb, state, toTimeStamp(databaseKind, "-123-1-23 12:31:12"),   expect &:= time("-123-1-23 12:31:12"));
 5447         insert(testDb, state, toTimeStamp(databaseKind, "-42-4-2 4:42:42"),      expect &:= time("-42-4-2 4:42:42"));
 5448         insert(testDb, state, toTimeStamp(databaseKind, "-1-1-1 0:0:0"),         expect &:= time("-1-1-1 0:0:0"));
 5449         insert(testDb, state, toTimeStamp(databaseKind, "-1-12-31 23:59:59"),    expect &:= time("-1-12-31 23:59:59"));
 5450         insert(testDb, state, toTimeStamp(databaseKind, "-1-12-31 23:59:59.999999"),
 5451                expect &:= time("-1-12-31 23:59:59.999999"));
 5452       end if;
 5453       if minTimeStamp(databaseKind) < time("1-1-1 0:0:0") then
 5454         insert(testDb, state, toTimeStamp(databaseKind, "0-1-1 0:0:0"),            expect &:= time("0-1-1 0:0:0"));
 5455         insert(testDb, state, toTimeStamp(databaseKind, "0-12-31 23:59:59"),       expect &:= time("0-12-31 23:59:59"));
 5456         insert(testDb, state, toTimeStamp(databaseKind, "0-12-31 23:59:59.123456"),
 5457                expect &:= time("0-12-31 23:59:59.123456"));
 5458         insert(testDb, state, toTimeStamp(databaseKind, "0-12-31 23:59:59.999999"),
 5459                expect &:= time("0-12-31 23:59:59.999999"));
 5460       end if;
 5461       if minTimeStamp(databaseKind) < time("1970-1-1 0:0:0") then
 5462         insert(testDb, state, toTimeStamp(databaseKind, "1-1-1 0:0:0"),            expect &:= time("1-1-1 0:0:0"));
 5463         insert(testDb, state, toTimeStamp(databaseKind, "1-12-31 23:59:59"),       expect &:= time("1-12-31 23:59:59"));
 5464         insert(testDb, state, toTimeStamp(databaseKind, "1-12-31 23:59:59.123456"),
 5465                expect &:= time("1-12-31 23:59:59.123456"));
 5466         insert(testDb, state, toTimeStamp(databaseKind, "1-12-31 23:59:59.999999"),
 5467                expect &:= time("1-12-31 23:59:59.999999"));
 5468         insert(testDb, state, toTimeStamp(databaseKind, "42-4-2 4:42:42"),         expect &:= time("42-4-2 4:42:42"));
 5469         insert(testDb, state, toTimeStamp(databaseKind, "123-1-23 12:31:12"),      expect &:= time("123-1-23 12:31:12"));
 5470         insert(testDb, state, toTimeStamp(databaseKind, "999-12-31 23:59:59"),     expect &:= time("999-12-31 23:59:59"));
 5471         insert(testDb, state, toTimeStamp(databaseKind, "1000-1-1 0:0:0"),         expect &:= time("1000-1-1 0:0:0"));
 5472         insert(testDb, state, toTimeStamp(databaseKind, "1752-12-31 23:59:59"),    expect &:= time("1752-12-31 23:59:59"));
 5473         insert(testDb, state, toTimeStamp(databaseKind, "1753-1-1 0:0:0"),         expect &:= time("1753-1-1 0:0:0"));
 5474         insert(testDb, state, toTimeStamp(databaseKind, "1800-1-1 0:0:0"),         expect &:= time("1800-1-1 0:0:0"));
 5475         insert(testDb, state, toTimeStamp(databaseKind, "1899-12-31 23:59:59"),    expect &:= time("1899-12-31 23:59:59"));
 5476         insert(testDb, state, toTimeStamp(databaseKind, "1900-1-1 0:0:0"),         expect &:= time("1900-1-1 0:0:0"));
 5477         insert(testDb, state, toTimeStamp(databaseKind, "1961-1-9 6:1:0"),         expect &:= time("1961-1-9 6:1:0"));
 5478         insert(testDb, state, toTimeStamp(databaseKind, "1969-12-31 23:59:59"),    expect &:= time("1969-12-31 23:59:59"));
 5479       end if;
 5480       if minTimeStamp(databaseKind) < time("1970-1-2 0:0:0") then
 5481         insert(testDb, state, toTimeStamp(databaseKind, "1970-1-1 0:0:0"),         expect &:= time("1970-1-1 0:0:0"));
 5482       end if;
 5483       insert(testDb, state, toTimeStamp(databaseKind, "1970-1-2 0:0:0"),         expect &:= time("1970-1-2 0:0:0"));
 5484       insert(testDb, state, toTimeStamp(databaseKind, "1979-12-31 23:59:59"),    expect &:= time("1979-12-31 23:59:59"));
 5485       insert(testDb, state, toTimeStamp(databaseKind, "1980-1-1 0:0:0"),         expect &:= time("1980-1-1 0:0:0"));
 5486       insert(testDb, state, toTimeStamp(databaseKind, "2010-11-12 13:14:15.16"), expect &:= time("2010-11-12 13:14:15.16"));
 5487       insert(testDb, state, toTimeStamp(databaseKind, "2011-11-11 11:11:11.11"), expect &:= time("2011-11-11 11:11:11.11"));
 5488       insert(testDb, state, toTimeStamp(databaseKind, "2012-12-12 12:12:12.12"), expect &:= time("2012-12-12 12:12:12.12"));
 5489 
 5490       if minTimeStamp(databaseKind) <= time("-4711-1-1 0:0:0") then
 5491         insert(state, time("-4711-1-1 0:0:0"),      expect &:= time("-4711-1-1 0:0:0"));
 5492         insert(state, time("-4711-12-31 23:59:59"), expect &:= time("-4711-12-31 23:59:59"));
 5493         insert(state, time("-4711-12-31 23:59:59.123456"),
 5494                expect &:= time("-4711-12-31 23:59:59.123456"));
 5495         insert(state, time("-999-12-31 23:59:59"),  expect &:= time("-999-12-31 23:59:59"));
 5496         insert(state, time("-123-1-23 12:31:12"),   expect &:= time("-123-1-23 12:31:12"));
 5497         insert(state, time("-42-4-2 4:42:42"),      expect &:= time("-42-4-2 4:42:42"));
 5498         insert(state, time("-1-1-1 0:0:0"),         expect &:= time("-1-1-1 0:0:0"));
 5499         insert(state, time("-1-12-31 23:59:59"),    expect &:= time("-1-12-31 23:59:59"));
 5500         insert(state, time("-1-12-31 23:59:59.999999"),
 5501                expect &:= time("-1-12-31 23:59:59.999999"));
 5502       end if;
 5503       if minTimeStamp(databaseKind) < time("1-1-1 0:0:0") then
 5504         insert(state, time("0-1-1 0:0:0"),            expect &:= time("0-1-1 0:0:0"));
 5505         insert(state, time("0-12-31 23:59:59"),       expect &:= time("0-12-31 23:59:59"));
 5506         insert(state, time("0-12-31 23:59:59.123456"),
 5507                expect &:= time("0-12-31 23:59:59.123456"));
 5508         insert(state, time("0-12-31 23:59:59.999999"),
 5509                expect &:= time("0-12-31 23:59:59.999999"));
 5510       end if;
 5511       if minTimeStamp(databaseKind) < time("1970-1-1 0:0:0") then
 5512         insert(state, time("1-1-1 0:0:0"),            expect &:= time("1-1-1 0:0:0"));
 5513         insert(state, time("1-12-31 23:59:59"),       expect &:= time("1-12-31 23:59:59"));
 5514         insert(state, time("1-12-31 23:59:59.123456"),
 5515                expect &:= time("1-12-31 23:59:59.123456"));
 5516         insert(state, time("1-12-31 23:59:59.999999"),
 5517                expect &:= time("1-12-31 23:59:59.999999"));
 5518         insert(state, time("42-4-2 4:42:42"),         expect &:= time("42-4-2 4:42:42"));
 5519         insert(state, time("123-1-23 12:31:12"),      expect &:= time("123-1-23 12:31:12"));
 5520         insert(state, time("999-12-31 23:59:59"),     expect &:= time("999-12-31 23:59:59"));
 5521         insert(state, time("1000-1-1 0:0:0"),         expect &:= time("1000-1-1 0:0:0"));
 5522         insert(state, time("1752-12-31 23:59:59"),    expect &:= time("1752-12-31 23:59:59"));
 5523         insert(state, time("1753-1-1 0:0:0"),         expect &:= time("1753-1-1 0:0:0"));
 5524         insert(state, time("1800-1-1 0:0:0"),         expect &:= time("1800-1-1 0:0:0"));
 5525         insert(state, time("1899-12-31 23:59:59"),    expect &:= time("1899-12-31 23:59:59"));
 5526         insert(state, time("1900-1-1 0:0:0"),         expect &:= time("1900-1-1 0:0:0"));
 5527         insert(state, time("1961-1-9 6:1:0"),         expect &:= time("1961-1-9 6:1:0"));
 5528         insert(state, time("1969-12-31 23:59:59"),    expect &:= time("1969-12-31 23:59:59"));
 5529       end if;
 5530       if minTimeStamp(databaseKind) < time("1970-1-2 0:0:0") then
 5531         insert(state, time("1970-1-1 0:0:0"),         expect &:= time("1970-1-1 0:0:0"));
 5532       end if;
 5533       insert(state, time("1970-1-2 0:0:0"),         expect &:= time("1970-1-2 0:0:0"));
 5534       insert(state, time("1979-12-31 23:59:59"),    expect &:= time("1979-12-31 23:59:59"));
 5535       insert(state, time("1980-1-1 0:0:0"),         expect &:= time("1980-1-1 0:0:0"));
 5536       insert(state, time("2010-11-12 13:14:15.16"), expect &:= time("2010-11-12 13:14:15.16"));
 5537       insert(state, time("2011-11-11 11:11:11.11"), expect &:= time("2011-11-11 11:11:11.11"));
 5538       insert(state, time("2012-12-12 12:12:12.12"), expect &:= time("2012-12-12 12:12:12.12"));
 5539 
 5540       if minTimeStamp(databaseKind) <= time("-4711-1-1 0:0:0") then
 5541         insert(state, setLocalTZ(time("-4711-1-1 0:0:0")),      expect &:= setLocalTZ(time("-4711-1-1 0:0:0")));
 5542         insert(state, setLocalTZ(time("-4711-12-31 23:59:59")), expect &:= setLocalTZ(time("-4711-12-31 23:59:59")));
 5543         insert(state, setLocalTZ(time("-4711-12-31 23:59:59.123456")),
 5544                expect &:= setLocalTZ(time("-4711-12-31 23:59:59.123456")));
 5545         insert(state, setLocalTZ(time("-999-12-31 23:59:59")),  expect &:= setLocalTZ(time("-999-12-31 23:59:59")));
 5546         insert(state, setLocalTZ(time("-123-1-23 12:31:12")),   expect &:= setLocalTZ(time("-123-1-23 12:31:12")));
 5547         insert(state, setLocalTZ(time("-42-4-2 4:42:42")),      expect &:= setLocalTZ(time("-42-4-2 4:42:42")));
 5548         insert(state, setLocalTZ(time("-1-1-1 0:0:0")),         expect &:= setLocalTZ(time("-1-1-1 0:0:0")));
 5549         insert(state, setLocalTZ(time("-1-12-31 23:59:59")),    expect &:= setLocalTZ(time("-1-12-31 23:59:59")));
 5550         insert(state, setLocalTZ(time("-1-12-31 23:59:59.999999")),
 5551                expect &:= setLocalTZ(time("-1-12-31 23:59:59.999999")));
 5552       end if;
 5553       if minTimeStamp(databaseKind) < time("1-1-1 0:0:0") then
 5554         insert(state, setLocalTZ(time("0-1-1 0:0:0")),            expect &:= setLocalTZ(time("0-1-1 0:0:0")));
 5555         insert(state, setLocalTZ(time("0-12-31 23:59:59")),       expect &:= setLocalTZ(time("0-12-31 23:59:59")));
 5556         insert(state, setLocalTZ(time("0-12-31 23:59:59.123456")),
 5557                expect &:= setLocalTZ(time("0-12-31 23:59:59.123456")));
 5558       end if;
 5559       if minTimeStamp(databaseKind) < time("1970-1-1 0:0:0") then
 5560         insert(state, setLocalTZ(time("1-1-1 0:0:0")),            expect &:= setLocalTZ(time("1-1-1 0:0:0")));
 5561         insert(state, setLocalTZ(time("1-12-31 23:59:59")),       expect &:= setLocalTZ(time("1-12-31 23:59:59")));
 5562         insert(state, setLocalTZ(time("1-12-31 23:59:59.123456")),
 5563                expect &:= setLocalTZ(time("1-12-31 23:59:59.123456")));
 5564         insert(state, setLocalTZ(time("1-12-31 23:59:59.999999")),
 5565                expect &:= setLocalTZ(time("1-12-31 23:59:59.999999")));
 5566         insert(state, setLocalTZ(time("42-4-2 4:42:42")),         expect &:= setLocalTZ(time("42-4-2 4:42:42")));
 5567         insert(state, setLocalTZ(time("123-1-23 12:31:12")),      expect &:= setLocalTZ(time("123-1-23 12:31:12")));
 5568         insert(state, setLocalTZ(time("999-12-31 23:59:59")),     expect &:= setLocalTZ(time("999-12-31 23:59:59")));
 5569         insert(state, setLocalTZ(time("1000-1-1 0:0:0")),         expect &:= setLocalTZ(time("1000-1-1 0:0:0")));
 5570         insert(state, setLocalTZ(time("1752-12-31 23:59:59")),    expect &:= setLocalTZ(time("1752-12-31 23:59:59")));
 5571         insert(state, setLocalTZ(time("1753-1-1 0:0:0")),         expect &:= setLocalTZ(time("1753-1-1 0:0:0")));
 5572         insert(state, setLocalTZ(time("1800-1-1 0:0:0")),         expect &:= setLocalTZ(time("1800-1-1 0:0:0")));
 5573         insert(state, setLocalTZ(time("1899-12-31 23:59:59")),    expect &:= setLocalTZ(time("1899-12-31 23:59:59")));
 5574         insert(state, setLocalTZ(time("1900-1-1 0:0:0")),         expect &:= setLocalTZ(time("1900-1-1 0:0:0")));
 5575         insert(state, setLocalTZ(time("1961-1-9 6:1:0")),         expect &:= setLocalTZ(time("1961-1-9 6:1:0")));
 5576         insert(state, setLocalTZ(time("1969-12-31 23:59:59")),    expect &:= setLocalTZ(time("1969-12-31 23:59:59")));
 5577       end if;
 5578       if minTimeStamp(databaseKind) < time("1970-1-2 0:0:0") then
 5579         insert(state, setLocalTZ(time("1970-1-1 0:0:0")),         expect &:= setLocalTZ(time("1970-1-1 0:0:0")));
 5580       end if;
 5581       insert(state, setLocalTZ(time("1970-1-2 0:0:0")),         expect &:= setLocalTZ(time("1970-1-2 0:0:0")));
 5582       insert(state, setLocalTZ(time("1979-12-31 23:59:59")),    expect &:= setLocalTZ(time("1979-12-31 23:59:59")));
 5583       insert(state, setLocalTZ(time("1980-1-1 0:0:0")),         expect &:= setLocalTZ(time("1980-1-1 0:0:0")));
 5584       insert(state, setLocalTZ(time("2010-11-12 13:14:15.16")), expect &:= setLocalTZ(time("2010-11-12 13:14:15.16")));
 5585       insert(state, setLocalTZ(time("2011-11-11 11:11:11.11")), expect &:= setLocalTZ(time("2011-11-11 11:11:11.11")));
 5586       insert(state, setLocalTZ(time("2012-12-12 12:12:12.12")), expect &:= setLocalTZ(time("2012-12-12 12:12:12.12")));
 5587 
 5588       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 5589       execute(state.statement);
 5590       while fetch(state.statement) do
 5591         timeColumn := column(state.statement, 1, time);
 5592         if timeColumn <> expect[row] then
 5593           state.okay := FALSE;
 5594           if state.details then
 5595             writeln(" *** testTimeStampField: Row: " <& row <&
 5596                     " Expected " <& literal(str(expect[row])) <&
 5597                     " found " <& literal(str(timeColumn)));
 5598           end if;
 5599         end if;
 5600         if row <= 2 and not isNull(state.statement, 1) then
 5601           state.okay := FALSE;
 5602           if state.details then
 5603             writeln(" *** testTimeStampField: Row: " <& row <&
 5604                     " Expected NULL found " <& timeColumn);
 5605           end if;
 5606         end if;
 5607         if row > 2 and isNull(state.statement, 1) then
 5608           state.okay := FALSE;
 5609           if state.details then
 5610             writeln(" *** testTimeStampField: Row: " <& row <&
 5611                     " Expected " <& literal(expect[row]) <& " found NULL");
 5612           end if;
 5613         end if;
 5614         incr(row);
 5615       end while;
 5616     exception
 5617       catch RANGE_ERROR:
 5618         state.okay := FALSE;
 5619         writeln(" *** RANGE_ERROR was raised");
 5620       catch FILE_ERROR:
 5621         state.okay := FALSE;
 5622         writeln(" *** FILE_ERROR was raised");
 5623       catch DATABASE_ERROR:
 5624         state.okay := FALSE;
 5625         writeln(" *** DATABASE_ERROR was raised");
 5626     end block;
 5627     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 5628     execute(state.statement);
 5629 
 5630     if state.okay then
 5631       writeln("Inserting and fetching timeStamp fields works okay.");
 5632     else
 5633       writeln(" *** Inserting and fetching timeStamp fields does not work okay.");
 5634     end if;
 5635   end func;
 5636 
 5637 
 5638 const proc: testTimeStampTzField (in database: testDb, in dbCategory: databaseKind) is func
 5639   local
 5640     var testState: state is testState("timeStampTzTest", "timeStampTzField", FALSE);
 5641     var array time: expect is 0 times time.value;
 5642     var time: timeColumn is time.value;
 5643     var integer: row is 1;
 5644   begin
 5645     if state.details then
 5646       writeln("testTimeStampTzField: " <& databaseKind);
 5647     end if;
 5648     block
 5649       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 5650                                  " (" & state.fieldName & " " & timeStampTzType(databaseKind) & ")");
 5651       execute(state.statement);
 5652       insert(testDb, state, "NULL", expect &:= time.value);
 5653       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 5654                                  " (" & state.fieldName & ") VALUES (?)");
 5655       insert(state, NULL,                           expect &:= time.value);
 5656 
 5657       if minTimeStamp(databaseKind) <= time("-4711-1-1 0:0:0") then
 5658         insert(testDb, state, toTimeStamp(databaseKind, "-4711-1-1 0:0:0"),      expect &:= setLocalTZ(time("-4711-1-1 0:0:0")));
 5659         insert(testDb, state, toTimeStamp(databaseKind, "-4711-12-31 23:59:59"), expect &:= setLocalTZ(time("-4711-12-31 23:59:59")));
 5660         insert(testDb, state, toTimeStamp(databaseKind, "-4711-12-31 23:59:59.123456"),
 5661                expect &:= setLocalTZ(time("-4711-12-31 23:59:59.123456")));
 5662         insert(testDb, state, toTimeStamp(databaseKind, "-999-12-31 23:59:59"),  expect &:= setLocalTZ(time("-999-12-31 23:59:59")));
 5663         insert(testDb, state, toTimeStamp(databaseKind, "-123-1-23 12:31:12"),   expect &:= setLocalTZ(time("-123-1-23 12:31:12")));
 5664         insert(testDb, state, toTimeStamp(databaseKind, "-42-4-2 4:42:42"),      expect &:= setLocalTZ(time("-42-4-2 4:42:42")));
 5665         insert(testDb, state, toTimeStamp(databaseKind, "-1-1-1 0:0:0"),         expect &:= setLocalTZ(time("-1-1-1 0:0:0")));
 5666         insert(testDb, state, toTimeStamp(databaseKind, "-1-12-31 23:59:59"),    expect &:= setLocalTZ(time("-1-12-31 23:59:59")));
 5667         insert(testDb, state, toTimeStamp(databaseKind, "-1-12-31 23:59:59.999999"),
 5668                expect &:= setLocalTZ(time("-1-12-31 23:59:59.999999")));
 5669       end if;
 5670       if minTimeStamp(databaseKind) < time("1-1-1 0:0:0") then
 5671         insert(testDb, state, toTimeStamp(databaseKind, "0-1-1 0:0:0"),            expect &:= setLocalTZ(time("0-1-1 0:0:0")));
 5672         insert(testDb, state, toTimeStamp(databaseKind, "0-12-31 23:59:59"),       expect &:= setLocalTZ(time("0-12-31 23:59:59")));
 5673         insert(testDb, state, toTimeStamp(databaseKind, "0-12-31 23:59:59.123456"),
 5674                expect &:= setLocalTZ(time("0-12-31 23:59:59.123456")));
 5675         insert(testDb, state, toTimeStamp(databaseKind, "0-12-31 23:59:59.999999"),
 5676                expect &:= setLocalTZ(time("0-12-31 23:59:59.999999")));
 5677       end if;
 5678       if minTimeStamp(databaseKind) < time("1970-1-1 0:0:0") then
 5679         insert(testDb, state, toTimeStamp(databaseKind, "1-1-1 0:0:0"),            expect &:= setLocalTZ(time("1-1-1 0:0:0")));
 5680         insert(testDb, state, toTimeStamp(databaseKind, "1-12-31 23:59:59"),       expect &:= setLocalTZ(time("1-12-31 23:59:59")));
 5681         insert(testDb, state, toTimeStamp(databaseKind, "1-12-31 23:59:59.123456"),
 5682                expect &:= setLocalTZ(time("1-12-31 23:59:59.123456")));
 5683         insert(testDb, state, toTimeStamp(databaseKind, "1-12-31 23:59:59.999999"),
 5684                expect &:= setLocalTZ(time("1-12-31 23:59:59.999999")));
 5685         insert(testDb, state, toTimeStamp(databaseKind, "42-4-2 4:42:42"),         expect &:= setLocalTZ(time("42-4-2 4:42:42")));
 5686         insert(testDb, state, toTimeStamp(databaseKind, "123-1-23 12:31:12"),      expect &:= setLocalTZ(time("123-1-23 12:31:12")));
 5687         insert(testDb, state, toTimeStamp(databaseKind, "999-12-31 23:59:59"),     expect &:= setLocalTZ(time("999-12-31 23:59:59")));
 5688         insert(testDb, state, toTimeStamp(databaseKind, "1000-1-1 0:0:0"),         expect &:= setLocalTZ(time("1000-1-1 0:0:0")));
 5689         insert(testDb, state, toTimeStamp(databaseKind, "1752-12-31 23:59:59"),    expect &:= setLocalTZ(time("1752-12-31 23:59:59")));
 5690         insert(testDb, state, toTimeStamp(databaseKind, "1753-1-1 0:0:0"),         expect &:= setLocalTZ(time("1753-1-1 0:0:0")));
 5691         insert(testDb, state, toTimeStamp(databaseKind, "1800-1-1 0:0:0"),         expect &:= setLocalTZ(time("1800-1-1 0:0:0")));
 5692         insert(testDb, state, toTimeStamp(databaseKind, "1899-12-31 23:59:59"),    expect &:= setLocalTZ(time("1899-12-31 23:59:59")));
 5693         insert(testDb, state, toTimeStamp(databaseKind, "1900-1-1 0:0:0"),         expect &:= setLocalTZ(time("1900-1-1 0:0:0")));
 5694         insert(testDb, state, toTimeStamp(databaseKind, "1961-1-9 6:1:0"),         expect &:= setLocalTZ(time("1961-1-9 6:1:0")));
 5695         insert(testDb, state, toTimeStamp(databaseKind, "1969-12-31 23:59:59"),    expect &:= setLocalTZ(time("1969-12-31 23:59:59")));
 5696       end if;
 5697       if minTimeStamp(databaseKind) < time("1970-1-2 0:0:0") then
 5698         insert(testDb, state, toTimeStamp(databaseKind, "1970-1-1 0:0:0"),         expect &:= setLocalTZ(time("1970-1-1 0:0:0")));
 5699       end if;
 5700       insert(testDb, state, toTimeStamp(databaseKind, "1970-1-2 0:0:0"),         expect &:= setLocalTZ(time("1970-1-2 0:0:0")));
 5701       insert(testDb, state, toTimeStamp(databaseKind, "1979-12-31 23:59:59"),    expect &:= setLocalTZ(time("1979-12-31 23:59:59")));
 5702       insert(testDb, state, toTimeStamp(databaseKind, "1980-1-1 0:0:0"),         expect &:= setLocalTZ(time("1980-1-1 0:0:0")));
 5703       insert(testDb, state, toTimeStamp(databaseKind, "2010-11-12 13:14:15.16"), expect &:= setLocalTZ(time("2010-11-12 13:14:15.16")));
 5704       insert(testDb, state, toTimeStamp(databaseKind, "2011-11-11 11:11:11.11"), expect &:= setLocalTZ(time("2011-11-11 11:11:11.11")));
 5705       insert(testDb, state, toTimeStamp(databaseKind, "2012-12-12 12:12:12.12"), expect &:= setLocalTZ(time("2012-12-12 12:12:12.12")));
 5706 
 5707       if minTimeStamp(databaseKind) <= time("-4711-1-1 0:0:0") then
 5708         insert(state, time("-4711-1-1 0:0:0"),      expect &:= time("-4711-1-1 0:0:0"));
 5709         insert(state, time("-4711-12-31 23:59:59"), expect &:= time("-4711-12-31 23:59:59"));
 5710         insert(state, time("-4711-12-31 23:59:59.123456"),
 5711                expect &:= time("-4711-12-31 23:59:59.123456"));
 5712         insert(state, time("-999-12-31 23:59:59"),  expect &:= time("-999-12-31 23:59:59"));
 5713         insert(state, time("-123-1-23 12:31:12"),   expect &:= time("-123-1-23 12:31:12"));
 5714         insert(state, time("-42-4-2 4:42:42"),      expect &:= time("-42-4-2 4:42:42"));
 5715         insert(state, time("-1-1-1 0:0:0"),         expect &:= time("-1-1-1 0:0:0"));
 5716         insert(state, time("-1-12-31 23:59:59"),    expect &:= time("-1-12-31 23:59:59"));
 5717         insert(state, time("-1-12-31 23:59:59.999999"),
 5718                expect &:= time("-1-12-31 23:59:59.999999"));
 5719       end if;
 5720       if minTimeStamp(databaseKind) < time("1-1-1 0:0:0") then
 5721         insert(state, time("0-1-1 0:0:0"),            expect &:= time("0-1-1 0:0:0"));
 5722         insert(state, time("0-12-31 23:59:59"),       expect &:= time("0-12-31 23:59:59"));
 5723         insert(state, time("0-12-31 23:59:59.123456"),
 5724                expect &:= time("0-12-31 23:59:59.123456"));
 5725         insert(state, time("0-12-31 23:59:59.999999"),
 5726                expect &:= time("0-12-31 23:59:59.999999"));
 5727       end if;
 5728       if minTimeStamp(databaseKind) < time("1970-1-1 0:0:0") then
 5729         insert(state, time("1-1-1 0:0:0"),            expect &:= time("1-1-1 0:0:0"));
 5730         insert(state, time("1-12-31 23:59:59"),       expect &:= time("1-12-31 23:59:59"));
 5731         insert(state, time("1-12-31 23:59:59.123456"),
 5732                expect &:= time("1-12-31 23:59:59.123456"));
 5733         insert(state, time("1-12-31 23:59:59.999999"),
 5734                expect &:= time("1-12-31 23:59:59.999999"));
 5735         insert(state, time("42-4-2 4:42:42"),         expect &:= time("42-4-2 4:42:42"));
 5736         insert(state, time("123-1-23 12:31:12"),      expect &:= time("123-1-23 12:31:12"));
 5737         insert(state, time("999-12-31 23:59:59"),     expect &:= time("999-12-31 23:59:59"));
 5738         insert(state, time("1000-1-1 0:0:0"),         expect &:= time("1000-1-1 0:0:0"));
 5739         insert(state, time("1752-12-31 23:59:59"),    expect &:= time("1752-12-31 23:59:59"));
 5740         insert(state, time("1753-1-1 0:0:0"),         expect &:= time("1753-1-1 0:0:0"));
 5741         insert(state, time("1800-1-1 0:0:0"),         expect &:= time("1800-1-1 0:0:0"));
 5742         insert(state, time("1899-12-31 23:59:59"),    expect &:= time("1899-12-31 23:59:59"));
 5743         insert(state, time("1900-1-1 0:0:0"),         expect &:= time("1900-1-1 0:0:0"));
 5744         insert(state, time("1961-1-9 6:1:0"),         expect &:= time("1961-1-9 6:1:0"));
 5745         insert(state, time("1969-12-31 23:59:59"),    expect &:= time("1969-12-31 23:59:59"));
 5746       end if;
 5747       if minTimeStamp(databaseKind) < time("1970-1-2 0:0:0") then
 5748         insert(state, time("1970-1-1 0:0:0"),         expect &:= time("1970-1-1 0:0:0"));
 5749       end if;
 5750       insert(state, time("1970-1-2 0:0:0"),         expect &:= time("1970-1-2 0:0:0"));
 5751       insert(state, time("1979-12-31 23:59:59"),    expect &:= time("1979-12-31 23:59:59"));
 5752       insert(state, time("1980-1-1 0:0:0"),         expect &:= time("1980-1-1 0:0:0"));
 5753       insert(state, time("2010-11-12 13:14:15.16"), expect &:= time("2010-11-12 13:14:15.16"));
 5754       insert(state, time("2011-11-11 11:11:11.11"), expect &:= time("2011-11-11 11:11:11.11"));
 5755       insert(state, time("2012-12-12 12:12:12.12"), expect &:= time("2012-12-12 12:12:12.12"));
 5756 
 5757       if minTimeStamp(databaseKind) <= time("-4711-1-1 0:0:0") then
 5758         insert(state, setLocalTZ(time("-4711-1-1 0:0:0")),      expect &:= setLocalTZ(time("-4711-1-1 0:0:0")));
 5759         insert(state, setLocalTZ(time("-4711-12-31 23:59:59")), expect &:= setLocalTZ(time("-4711-12-31 23:59:59")));
 5760         insert(state, setLocalTZ(time("-4711-12-31 23:59:59.123456")),
 5761                expect &:= setLocalTZ(time("-4711-12-31 23:59:59.123456")));
 5762         insert(state, setLocalTZ(time("-999-12-31 23:59:59")),  expect &:= setLocalTZ(time("-999-12-31 23:59:59")));
 5763         insert(state, setLocalTZ(time("-123-1-23 12:31:12")),   expect &:= setLocalTZ(time("-123-1-23 12:31:12")));
 5764         insert(state, setLocalTZ(time("-42-4-2 4:42:42")),      expect &:= setLocalTZ(time("-42-4-2 4:42:42")));
 5765         insert(state, setLocalTZ(time("-1-1-1 0:0:0")),         expect &:= setLocalTZ(time("-1-1-1 0:0:0")));
 5766         insert(state, setLocalTZ(time("-1-12-31 23:59:59")),    expect &:= setLocalTZ(time("-1-12-31 23:59:59")));
 5767         insert(state, setLocalTZ(time("-1-12-31 23:59:59.999999")),
 5768                expect &:= setLocalTZ(time("-1-12-31 23:59:59.999999")));
 5769       end if;
 5770       if minTimeStamp(databaseKind) < time("1-1-1 0:0:0") then
 5771         insert(state, setLocalTZ(time("0-1-1 0:0:0")),            expect &:= setLocalTZ(time("0-1-1 0:0:0")));
 5772         insert(state, setLocalTZ(time("0-12-31 23:59:59")),       expect &:= setLocalTZ(time("0-12-31 23:59:59")));
 5773         insert(state, setLocalTZ(time("0-12-31 23:59:59.123456")),
 5774                expect &:= setLocalTZ(time("0-12-31 23:59:59.123456")));
 5775         insert(state, setLocalTZ(time("0-12-31 23:59:59.999999")),
 5776                expect &:= setLocalTZ(time("0-12-31 23:59:59.999999")));
 5777       end if;
 5778       if minTimeStamp(databaseKind) < time("1970-1-1 0:0:0") then
 5779         insert(state, setLocalTZ(time("1-1-1 0:0:0")),            expect &:= setLocalTZ(time("1-1-1 0:0:0")));
 5780         insert(state, setLocalTZ(time("1-12-31 23:59:59")),       expect &:= setLocalTZ(time("1-12-31 23:59:59")));
 5781         insert(state, setLocalTZ(time("1-12-31 23:59:59.123456")),
 5782                expect &:= setLocalTZ(time("1-12-31 23:59:59.123456")));
 5783         insert(state, setLocalTZ(time("1-12-31 23:59:59.999999")),
 5784                expect &:= setLocalTZ(time("1-12-31 23:59:59.999999")));
 5785         insert(state, setLocalTZ(time("42-4-2 4:42:42")),         expect &:= setLocalTZ(time("42-4-2 4:42:42")));
 5786         insert(state, setLocalTZ(time("123-1-23 12:31:12")),      expect &:= setLocalTZ(time("123-1-23 12:31:12")));
 5787         insert(state, setLocalTZ(time("999-12-31 23:59:59")),     expect &:= setLocalTZ(time("999-12-31 23:59:59")));
 5788         insert(state, setLocalTZ(time("1000-1-1 0:0:0")),         expect &:= setLocalTZ(time("1000-1-1 0:0:0")));
 5789         insert(state, setLocalTZ(time("1752-12-31 23:59:59")),    expect &:= setLocalTZ(time("1752-12-31 23:59:59")));
 5790         insert(state, setLocalTZ(time("1753-1-1 0:0:0")),         expect &:= setLocalTZ(time("1753-1-1 0:0:0")));
 5791         insert(state, setLocalTZ(time("1800-1-1 0:0:0")),         expect &:= setLocalTZ(time("1800-1-1 0:0:0")));
 5792         insert(state, setLocalTZ(time("1899-12-31 23:59:59")),    expect &:= setLocalTZ(time("1899-12-31 23:59:59")));
 5793         insert(state, setLocalTZ(time("1900-1-1 0:0:0")),         expect &:= setLocalTZ(time("1900-1-1 0:0:0")));
 5794         insert(state, setLocalTZ(time("1961-1-9 6:1:0")),         expect &:= setLocalTZ(time("1961-1-9 6:1:0")));
 5795         insert(state, setLocalTZ(time("1969-12-31 23:59:59")),    expect &:= setLocalTZ(time("1969-12-31 23:59:59")));
 5796       end if;
 5797       if minTimeStamp(databaseKind) < time("1970-1-2 0:0:0") then
 5798         insert(state, setLocalTZ(time("1970-1-1 0:0:0")),         expect &:= setLocalTZ(time("1970-1-1 0:0:0")));
 5799       end if;
 5800       insert(state, setLocalTZ(time("1970-1-2 0:0:0")),         expect &:= setLocalTZ(time("1970-1-2 0:0:0")));
 5801       insert(state, setLocalTZ(time("1979-12-31 23:59:59")),    expect &:= setLocalTZ(time("1979-12-31 23:59:59")));
 5802       insert(state, setLocalTZ(time("1980-1-1 0:0:0")),         expect &:= setLocalTZ(time("1980-1-1 0:0:0")));
 5803       insert(state, setLocalTZ(time("2010-11-12 13:14:15.16")), expect &:= setLocalTZ(time("2010-11-12 13:14:15.16")));
 5804       insert(state, setLocalTZ(time("2011-11-11 11:11:11.11")), expect &:= setLocalTZ(time("2011-11-11 11:11:11.11")));
 5805       insert(state, setLocalTZ(time("2012-12-12 12:12:12.12")), expect &:= setLocalTZ(time("2012-12-12 12:12:12.12")));
 5806 
 5807       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 5808       execute(state.statement);
 5809       while fetch(state.statement) do
 5810         timeColumn := column(state.statement, 1, time);
 5811         if timeColumn <> expect[row] then
 5812           state.okay := FALSE;
 5813           if state.details then
 5814             writeln(" *** testTimeStampTzField: Row: " <& row <&
 5815                     " Expected " <& literal(str(expect[row])) <&
 5816                     " found " <& literal(str(timeColumn)));
 5817           end if;
 5818         end if;
 5819         if timeColumn.timeZone <> expect[row].timeZone then
 5820           state.okay := FALSE;
 5821           if state.details then
 5822             writeln(" *** testTimeStampTzField: Row: " <& row <&
 5823                     " Expected time zone " <& expect[row] <&
 5824                     " found " <& timeColumn);
 5825           end if;
 5826         end if;
 5827         if row <= 2 and not isNull(state.statement, 1) then
 5828           state.okay := FALSE;
 5829           if state.details then
 5830             writeln(" *** testTimeStampTzField: Row: " <& row <&
 5831                     " Expected NULL found " <& timeColumn);
 5832           end if;
 5833         end if;
 5834         if row > 2 and isNull(state.statement, 1) then
 5835           state.okay := FALSE;
 5836           if state.details then
 5837             writeln(" *** testTimeStampTzField: Row: " <& row <&
 5838                     " Expected " <& literal(expect[row]) <& " found NULL");
 5839           end if;
 5840         end if;
 5841         incr(row);
 5842       end while;
 5843     exception
 5844       catch RANGE_ERROR:
 5845         state.okay := FALSE;
 5846         writeln(" *** RANGE_ERROR was raised");
 5847       catch FILE_ERROR:
 5848         state.okay := FALSE;
 5849         writeln(" *** FILE_ERROR was raised");
 5850       catch DATABASE_ERROR:
 5851         state.okay := FALSE;
 5852         writeln(" *** DATABASE_ERROR was raised");
 5853     end block;
 5854     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 5855     execute(state.statement);
 5856 
 5857     if state.okay then
 5858       writeln("Inserting and fetching timeStampTz fields works okay.");
 5859     else
 5860       writeln(" *** Inserting and fetching timeStampTz fields does not work okay.");
 5861     end if;
 5862   end func;
 5863 
 5864 
 5865 const proc: testDurationField (in database: testDb, in dbCategory: databaseKind) is func
 5866   local
 5867     var testState: state is testState("durationTest", "durationField", FALSE);
 5868     var array duration: expect is 0 times duration.value;
 5869     var duration: durationColumn is duration.value;
 5870     var integer: row is 1;
 5871   begin
 5872     if state.details then
 5873       writeln("testDurationField: " <& databaseKind);
 5874     end if;
 5875     block
 5876       state.statement := prepare(testDb, "CREATE TABLE " & state.tableName &
 5877                                  " (" & state.fieldName & " " & durationType(databaseKind) & ")");
 5878       execute(state.statement);
 5879       state.statement := prepare(testDb, "INSERT INTO " & state.tableName &
 5880                                  " (" & state.fieldName & ") VALUES (?)");
 5881       insert(state, NULL,                       expect &:= duration.value);
 5882       insert(state, duration("P0D"),            expect &:= duration("P0D"));
 5883       insert(state, duration("P1Y"),            expect &:= duration("P1Y"));
 5884       insert(state, duration("P1M"),            expect &:= duration("P1M"));
 5885       insert(state, duration("P1D"),            expect &:= duration("P1D"));
 5886       insert(state, duration("PT1H"),           expect &:= duration("PT1H"));
 5887       insert(state, duration("PT1M"),           expect &:= duration("PT1M"));
 5888       insert(state, duration("PT1S"),           expect &:= duration("PT1S"));
 5889       insert(state, duration("PT0.1S"),         expect &:= duration("PT0.1S"));
 5890       insert(state, duration("P-1Y"),           expect &:= duration("P-1Y"));
 5891       insert(state, duration("P-1M"),           expect &:= duration("P-1M"));
 5892       insert(state, duration("P-1D"),           expect &:= duration("P-1D"));
 5893       insert(state, duration("PT-1H"),          expect &:= duration("PT-1H"));
 5894       insert(state, duration("PT-1M"),          expect &:= duration("PT-1M"));
 5895       insert(state, duration("PT-1S"),          expect &:= duration("PT-1S"));
 5896       insert(state, duration("PT-0.1S"),        expect &:= duration("PT-0.1S"));
 5897       insert(state, duration("P1Y1M"),          expect &:= duration("P1Y1M"));
 5898       insert(state, duration("P1Y-1M"),         expect &:= duration("P1Y-1M"));
 5899       insert(state, duration("P1Y1D"),          expect &:= duration("P1Y1D"));
 5900       insert(state, duration("P1Y-1D"),         expect &:= duration("P1Y-1D"));
 5901       insert(state, duration("P1YT1H"),         expect &:= duration("P1YT1H"));
 5902       insert(state, duration("P1YT-1H"),        expect &:= duration("P1YT-1H"));
 5903       insert(state, duration("P1YT1M"),         expect &:= duration("P1YT1M"));
 5904       insert(state, duration("P1YT-1M"),        expect &:= duration("P1YT-1M"));
 5905       insert(state, duration("P1YT1S"),         expect &:= duration("P1YT1S"));
 5906       insert(state, duration("P1YT-1S"),        expect &:= duration("P1YT-1S"));
 5907       insert(state, duration("P1YT0.1S"),       expect &:= duration("P1YT0.1S"));
 5908       insert(state, duration("P1YT-0.1S"),      expect &:= duration("P1YT-0.1S"));
 5909       insert(state, duration("P-1Y1M"),         expect &:= duration("P-1Y1M"));
 5910       insert(state, duration("P-1Y-1M"),        expect &:= duration("P-1Y-1M"));
 5911       insert(state, duration("P-1Y1D"),         expect &:= duration("P-1Y1D"));
 5912       insert(state, duration("P-1Y-1D"),        expect &:= duration("P-1Y-1D"));
 5913       insert(state, duration("P-1YT1H"),        expect &:= duration("P-1YT1H"));
 5914       insert(state, duration("P-1YT-1H"),       expect &:= duration("P-1YT-1H"));
 5915       insert(state, duration("P-1YT1M"),        expect &:= duration("P-1YT1M"));
 5916       insert(state, duration("P-1YT-1M"),       expect &:= duration("P-1YT-1M"));
 5917       insert(state, duration("P-1YT1S"),        expect &:= duration("P-1YT1S"));
 5918       insert(state, duration("P-1YT-1S"),       expect &:= duration("P-1YT-1S"));
 5919       insert(state, duration("P-1YT0.1S"),      expect &:= duration("P-1YT0.1S"));
 5920       insert(state, duration("P-1YT-0.1S"),     expect &:= duration("P-1YT-0.1S"));
 5921 
 5922       state.statement := prepare(testDb, "SELECT * FROM " & state.tableName);
 5923       execute(state.statement);
 5924       while fetch(state.statement) do
 5925         durationColumn := column(state.statement, 1, duration);
 5926         if durationColumn <> expect[row] then
 5927           state.okay := FALSE;
 5928           if state.details then
 5929             writeln(" *** testDurationField: Row: " <& row <&
 5930                     " Expected " <& literal(str(expect[row])) <&
 5931                     " found " <& literal(str(durationColumn)));
 5932           end if;
 5933         end if;
 5934         if row = 1 and not isNull(state.statement, 1) then
 5935           state.okay := FALSE;
 5936           if state.details then
 5937             writeln(" *** testDurationField: Row: " <& row <&
 5938                     " Expected NULL found " <& durationColumn);
 5939           end if;
 5940         end if;
 5941         incr(row);
 5942       end while;
 5943     exception
 5944       catch RANGE_ERROR:
 5945         state.okay := FALSE;
 5946         writeln(" *** RANGE_ERROR was raised");
 5947       catch FILE_ERROR:
 5948         state.okay := FALSE;
 5949         writeln(" *** FILE_ERROR was raised");
 5950       catch DATABASE_ERROR:
 5951         state.okay := FALSE;
 5952         writeln(" *** DATABASE_ERROR was raised");
 5953     end block;
 5954     state.statement := prepare(testDb, "DROP TABLE " & state.tableName);
 5955     execute(state.statement);
 5956 
 5957     if state.okay then
 5958       writeln("Inserting and fetching duration fields works okay.");
 5959     else
 5960       writeln(" *** Inserting and fetching duration fields does not work okay.");
 5961     end if;
 5962   end func;
 5963 
 5964 
 5965 const proc: testFloatField2 (in database: testDb, in dbCategory: databaseKind) is func
 5966   local
 5967     const string: tableName is "floatTest";
 5968     var sqlStatement: statement is sqlStatement.value;
 5969     var float: floatColumn is 0.0;
 5970     var integer: row is 1;
 5971   begin
 5972     writeln("testFloatField2: " <& databaseKind);
 5973     statement := prepare(testDb, "CREATE TABLE " & tableName & " (floatField " & floatType(databaseKind) & ")");
 5974     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (floatField FLOAT)");
 5975     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (floatField REAL)");
 5976     execute(statement);
 5977     block
 5978       # statement := prepare(testDb, "INSERT INTO " & tableName & " (floatField) VALUES (NULL)");
 5979       statement := prepare(testDb, "INSERT INTO " & tableName & " (floatField) VALUES (-9223372036854775808.0)");
 5980       execute(statement);
 5981       statement := prepare(testDb, "SELECT * FROM " & tableName);
 5982       execute(statement);
 5983       while fetch(statement) do
 5984         writeln(column(statement, 1, float));
 5985         incr(row);
 5986       end while;
 5987     exception
 5988       catch RANGE_ERROR:
 5989         writeln(" *** RANGE_ERROR was raised");
 5990       catch FILE_ERROR:
 5991         writeln(" *** FILE_ERROR was raised");
 5992       catch DATABASE_ERROR:
 5993         writeln(" *** DATABASE_ERROR was raised");
 5994     end block;
 5995     statement := prepare(testDb, "DROP TABLE " & tableName);
 5996     execute(statement);
 5997   end func;
 5998 
 5999 
 6000 const proc: testBigRatField2 (in database: testDb, in dbCategory: databaseKind) is func
 6001   local
 6002     const string: tableName is "bigRatTest";
 6003     var sqlStatement: statement is sqlStatement.value;
 6004     var bigRational: bigRatColumn is bigRational.value;
 6005     var integer: row is 1;
 6006   begin
 6007     writeln("testBigRatField2: " <& databaseKind);
 6008     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (bigRatField " & bigRatType(databaseKind) & ")");
 6009     statement := prepare(testDb, "CREATE TABLE " & tableName & " (bigRatField NUMERIC(38,15))");
 6010     execute(statement);
 6011     block
 6012       # statement := prepare(testDb, "INSERT INTO " & tableName & " (bigRatField) VALUES (1)");
 6013       statement := prepare(testDb, "INSERT INTO " & tableName & " (bigRatField) VALUES (?)"); bind(statement, 1, 1_ / 1_);
 6014       execute(statement);
 6015       statement := prepare(testDb, "SELECT * FROM " & tableName);
 6016       execute(statement);
 6017       while fetch(statement) do
 6018         writeln(column(statement, 1, bigRational));
 6019         incr(row);
 6020       end while;
 6021     exception
 6022       catch RANGE_ERROR:
 6023         writeln(" *** RANGE_ERROR was raised");
 6024       catch FILE_ERROR:
 6025         writeln(" *** FILE_ERROR was raised");
 6026       catch DATABASE_ERROR:
 6027         writeln(" *** DATABASE_ERROR was raised");
 6028     end block;
 6029     statement := prepare(testDb, "DROP TABLE " & tableName);
 6030     execute(statement);
 6031   end func;
 6032 
 6033 
 6034 const proc: testBlobField2 (in database: testDb, in dbCategory: databaseKind) is func
 6035   local
 6036     const string: tableName is "blobTest";
 6037     var sqlStatement: statement is sqlStatement.value;
 6038     var bstring: bstringColumn is bstring("");
 6039     var string: stringColumn is "";
 6040     var integer: row is 1;
 6041   begin
 6042     writeln("testBlobField2: " <& databaseKind);
 6043     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (blobField " & blobType(databaseKind) & ")");
 6044     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (blobField BLOB)");
 6045     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (blobField VARBINARY(MAX))");
 6046     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (blobField VARCHAR(MAX))");
 6047     # statement := prepare(testDb, "CREATE TABLE blobTest (int32Field INTEGER, blobField BLOB, varcharField VARCHAR(32))");
 6048     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (int32Field INTEGER, blobField " & blobType(databaseKind) & ", varcharField " & varcharType(databaseKind) & "(32))");
 6049     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (int32Field INTEGER, blobField " & blobType(databaseKind) & ", numericField " & numericType(databaseKind) & ")");
 6050     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (int32Field INTEGER, numericField " & numericType(databaseKind) & ")");
 6051     execute(statement);
 6052     block
 6053       # statement := prepare(testDb, "INSERT INTO " & tableName & " (blobField) VALUES (NULL)");
 6054       # statement := prepare(testDb, "INSERT INTO " & tableName & " (blobField) VALUES (0xfedcba9876543210)");
 6055       # statement := prepare(testDb, "INSERT INTO " & tableName & " (blobField) VALUES ('some text')");
 6056       # statement := prepare(testDb, "INSERT INTO " & tableName & " (blobField) VALUES (?)"); bind(statement, 1, bstring(""));
 6057       # statement := prepare(testDb, "INSERT INTO " & tableName & " (blobField) VALUES (?)"); bind(statement, 1, bstring(getf("data.txt")));
 6058       # statement := prepare(testDb, "INSERT INTO " & tableName & " (blobField) VALUES (?)"); bind(statement, 1, bstring("\16#fe;\16#dc;\16#ba;\16#98;\16#76;\16#54;\16#32;\16#10;"));
 6059       # statement := prepare(testDb, "INSERT INTO " & tableName & " (blobField) VALUES (?)"); bind(statement, 1, bstring("abcdefgh" mult 1024 * 1024 * 16));
 6060       # statement := prepare(testDb, "INSERT INTO " & tableName & " (blobField) VALUES (?)"); bind(statement, 1, "abcdefgh" mult 1024 * 1024);
 6061       # statement := prepare(testDb, "INSERT INTO " & tableName & " (int32Field, blobField, varcharField) VALUES (123, 0xfedcba9876543210, 'some text')");
 6062       # statement := prepare(testDb, "INSERT INTO " & tableName & " (int32Field, blobField, numericField) VALUES (123, 0xfedcba9876543210, 0.123456789)");
 6063       # statement := prepare(testDb, "INSERT INTO " & tableName & " (int32Field, numericField) VALUES (123, 0.123456789)");
 6064       execute(statement);
 6065       statement := prepare(testDb, "SELECT * FROM " & tableName);
 6066       execute(statement);
 6067       while fetch(statement) do
 6068         # writeln(column(statement, 1, bstring));
 6069         # writeln(column(statement, 1, string));
 6070         # writeln(column(statement, 1, integer));
 6071         # writeln(column(statement, 2, bstring));
 6072         # writeln(column(statement, 2, bigRational));
 6073         # writeln(column(statement, 3, string));
 6074         # writeln(column(statement, 3, bigRational));
 6075         # writeln(length(column(statement, 1, bstring)));
 6076         # writeln(length(column(statement, 1, string)));
 6077         # putf("data2.txt", str(column(statement, 1, bstring)));
 6078        incr(row);
 6079       end while;
 6080     exception
 6081       catch RANGE_ERROR:
 6082         writeln(" *** RANGE_ERROR was raised");
 6083       catch FILE_ERROR:
 6084         writeln(" *** FILE_ERROR was raised");
 6085       catch DATABASE_ERROR:
 6086         writeln(" *** DATABASE_ERROR was raised");
 6087     end block;
 6088     statement := prepare(testDb, "DROP TABLE " & tableName);
 6089     execute(statement);
 6090   end func;
 6091 
 6092 
 6093 const proc: testTimeField2 (in database: testDb, in dbCategory: databaseKind) is func
 6094   local
 6095     const string: tableName is "timeTest";
 6096     var array time: expect is 0 times time.value;
 6097     var sqlStatement: statement is sqlStatement.value;
 6098     var integer: row is 1;
 6099   begin
 6100     writeln("testTimeField2: " <& databaseKind);
 6101      statement := prepare(testDb, "CREATE TABLE " & tableName & " (timeField TIMESTAMP)");
 6102     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (timeField TIMESTAMPTZ)");
 6103     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (timeField DATE)");
 6104     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (timeField DATETIME)");
 6105     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (timeField DATETIME2(7))");
 6106     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (timeField TIME)");
 6107     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (timeField TIMETZ)");
 6108     execute(statement);
 6109     block
 6110       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES ('0010-11-12 13:14:15 BC')");
 6111       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES ('0001-01-01 00:00:00 BC')");
 6112       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES ('0001-01-01 00:00:00')");
 6113       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES ('2017-03-14')");
 6114       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES ('2017-03-14 15:16:17.18')");
 6115       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES ('1893-04-01 00:00:00.00')");
 6116       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES ('1893-03-31 23:54:38.999999')");  # UTC+1:5 ??
 6117       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES ('1893-03-31 23:54:39.00')");      # UTC+1
 6118       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES (current_date)");
 6119       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES (getdate)");
 6120       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES (current_timestamp)");
 6121       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES ('16:17:18.19')");
 6122       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES ('2010-11-12 13:14:15.16')");
 6123       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES (?)"); bind(statement, 1, time(NOW));
 6124        statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES (?)"); bind(statement, 1, toUTC(time(NOW)));
 6125       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES (?)"); bind(statement, 1, setLocalTZ(time("2010-11-12 13:14:15.16")));
 6126       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES (?)"); bind(statement, 1, setLocalTZ(time("-10-11-12 13:14:15")));
 6127       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES (?)"); bind(statement, 1, time("0-1-1 0:0:0"));
 6128       # statement := prepare(testDb, "INSERT INTO " & tableName & " (timeField) VALUES (?)"); bind(statement, 1, setLocalTZ(time("0-1-1 0:0:0")));
 6129       execute(statement);
 6130       statement := prepare(testDb, "SELECT * FROM " & tableName);
 6131       execute(statement);
 6132       while fetch(statement) do
 6133         writeln(" *** testTimeField2: Row: " <& row <& " Found " <& literal(str(column(statement, 1, time))));
 6134         # writeln(" *** testTimeField2: Row: " <& row <& " Found " <& column(statement, 1, string));
 6135         incr(row);
 6136       end while;
 6137     exception
 6138       catch RANGE_ERROR:
 6139         writeln(" *** RANGE_ERROR was raised");
 6140       catch FILE_ERROR:
 6141         writeln(" *** FILE_ERROR was raised");
 6142       catch DATABASE_ERROR:
 6143         writeln(" *** DATABASE_ERROR was raised");
 6144     end block;
 6145     statement := prepare(testDb, "DROP TABLE " & tableName);
 6146     execute(statement);
 6147   end func;
 6148 
 6149 
 6150 const proc: testDurationField2 (in database: testDb, in dbCategory: databaseKind) is func
 6151   local
 6152     const string: tableName is "durationTest";
 6153     var array duration: expect is 0 times duration.value;
 6154     var sqlStatement: statement is sqlStatement.value;
 6155     var duration: durationColumn is duration.value;
 6156     var integer: row is 1;
 6157   begin
 6158     writeln("testDurationField2: " <& databaseKind);
 6159     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (durationField TIMESTAMP)");
 6160     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (durationField TIMESTAMPTZ)");
 6161     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (durationField DATE)");
 6162      statement := prepare(testDb, "CREATE TABLE " & tableName & " (durationField DATETIME)");
 6163     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (durationField TIME)");
 6164     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (durationField TIMETZ)");
 6165     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (durationField INTERVAL)");
 6166     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (durationField VARCHAR(32))");
 6167     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (durationField INTERVAL DAY(3) TO SECOND(6))");
 6168     execute(statement);
 6169     block
 6170       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES ('2017-03-14')");
 6171       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES ('2017-03-14 15:16:17.18')");
 6172       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES (current_date)");
 6173       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES (current_timestamp)");
 6174       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES ('16:17:18.19')");
 6175       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES ('2010-11-12T13:14:15')");
 6176       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES ('2010-11-12 13:14:15.16')");
 6177       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES ('0010-11-12 13:14:15.16')");
 6178       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES ('P1Y2M3DT4H5M6S')");
 6179       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES ('P1Y2M3DT4H5M6.7S')");
 6180        statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES ('P1Y2M3DT4H5M6.7890123S')");
 6181       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES ('P-1Y-2M-3DT-4H-5M-6.7S')");
 6182       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES (?)"); bind(statement, 1, time(NOW));
 6183       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES (?)"); bind(statement, 1, duration("P2010Y11M12DT13H14M15.16S"));
 6184       # statement := prepare(testDb, "INSERT INTO " & tableName & " (durationField) VALUES (?)"); bind(statement, 1, duration("P10Y11M12DT13H14M15.16S"));
 6185       execute(statement);
 6186       statement := prepare(testDb, "SELECT * FROM " & tableName);
 6187       execute(statement);
 6188       while fetch(statement) do
 6189         durationColumn := column(statement, 1, duration);
 6190         writeln(" *** testDurationField: Row: " <& row <&
 6191                 " Found " <& literal(str(durationColumn)));
 6192         incr(row);
 6193       end while;
 6194     exception
 6195       catch RANGE_ERROR:
 6196         writeln(" *** RANGE_ERROR was raised");
 6197       catch FILE_ERROR:
 6198         writeln(" *** FILE_ERROR was raised");
 6199       catch DATABASE_ERROR:
 6200         writeln(" *** DATABASE_ERROR was raised");
 6201     end block;
 6202     statement := prepare(testDb, "DROP TABLE " & tableName);
 6203     execute(statement);
 6204   end func;
 6205 
 6206 
 6207 const proc: testNumericField2 (in database: testDb, in dbCategory: databaseKind) is func
 6208   local
 6209     const string: tableName is "numericTest";
 6210     var sqlStatement: statement is sqlStatement.value;
 6211     var integer: integerColumn is 0;
 6212     var bigInteger: bigIntColumn is 0_;
 6213     var bigRational: bigRatColumn is 0_/1_;
 6214     var float: floatColumn is 0.0;
 6215     var integer: row is 1;
 6216   begin
 6217     writeln("testNumericField2: " <& databaseKind);
 6218      statement := prepare(testDb, "CREATE TABLE " & tableName & " (numericField NUMERIC(38,15))");
 6219     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (numericField NUMERIC(38,30))");
 6220     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (numericField NUMERIC(38,38))");
 6221     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (numericField NUMERIC(38,0))");
 6222     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (numericField NUMERIC(38,-1))");
 6223     # statement := prepare(testDb, "CREATE TABLE " & tableName & " (numericField NUMERIC(38,15))");
 6224     execute(statement);
 6225     block
 6226       # statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (NULL)");
 6227       # statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (12345.678901)");
 6228       # statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (-12345.678901)");
 6229       # statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (0.12345678901234567890123456789012345678)");
 6230        statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (0.00000000000000000000000000000000000001)");
 6231       # statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (-12345.678901234567890123456789012345)");
 6232       # statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (-0.12345678901234567890123456789012345678)");
 6233       # statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (-12345678901234567890123456789012345678)");
 6234       # statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (-123456789012345678901234567890123456780)");
 6235       # statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (?)"); bind(statement, 1, 12345.678901);
 6236       # statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (?)"); bind(statement, 1, -12345678901234567890123456789012345678_);
 6237       # statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (?)"); bind(statement, 1, -12345678901234567890123456789012345678_ / 1_);
 6238       # statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (?)"); bind(statement, 1, 12345678901234560000000_/1_);
 6239       # statement := prepare(testDb, "INSERT INTO " & tableName & " (numericField) VALUES (?)"); bind(statement, 1, 123456789012345600000000_/1_);
 6240       execute(statement);
 6241       statement := prepare(testDb, "SELECT * FROM " & tableName);
 6242       execute(statement);
 6243       while fetch(statement) do
 6244         writeln("isNull: " <& isNull(statement, 1));
 6245         writeln(column(statement, 1, float));
 6246         writeln(column(statement, 1, bigRational));
 6247         writeln(column(statement, 1, bigInteger));
 6248         writeln(column(statement, 1, integer));
 6249         incr(row);
 6250       end while;
 6251     exception
 6252       catch RANGE_ERROR:
 6253         writeln(" *** RANGE_ERROR was raised");
 6254       catch FILE_ERROR:
 6255         writeln(" *** FILE_ERROR was raised");
 6256       catch DATABASE_ERROR:
 6257         writeln(" *** DATABASE_ERROR was raised");
 6258     end block;
 6259     statement := prepare(testDb, "DROP TABLE " & tableName);
 6260     execute(statement);
 6261   end func;
 6262 
 6263 
 6264 const proc: testVarcharField2 (in database: testDb, in dbCategory: databaseKind) is func
 6265   local
 6266     const string: tableName is "varcharTest2";
 6267     var array string: expect is 0 times "";
 6268     var sqlStatement: statement is sqlStatement.value;
 6269     var string: stringColumn is "";
 6270     var integer: row is 1;
 6271   begin
 6272     writeln("testVarcharField: " <& databaseKind);
 6273     statement := prepare(testDb, "CREATE TABLE " & tableName &
 6274                          " (varcharField varchar(32765))");
 6275     execute(statement);
 6276     block
 6277       statement := prepare(testDb, "INSERT INTO " & tableName &
 6278                            " (varcharField) VALUES (?)");
 6279      # insert(statement, "09876543210987654321",  expect &:= "09876543210987654321");
 6280      # insert(statement, "123456789012345678901",  expect &:= "123456789012345678901");
 6281       insert(statement, "x" mult 32765, expect &:= "x" mult 32765);
 6282 (*
 6283       insert(statement, NULL,         expect &:= "");
 6284       insert(statement, "",           expect &:= "");
 6285       insert(statement, "X",          expect &:= "X");
 6286       insert(statement, "Ab2",        expect &:= "Ab2");
 6287       insert(statement, "abcdefghij", expect &:= "abcdefghij");
 6288       insert(statement, "ÄäÖöÜüß",    expect &:= "ÄäÖöÜüß");
 6289       insert(statement, "€µ¹²³¼½«»¬", expect &:= "€µ¹²³¼½«»¬");
 6290       insert(statement, "x" mult 32,  expect &:= "x" mult 32);
 6291       insert(statement, "\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 6292                         \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 6293                         \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;",
 6294                         expect &:= "\1;\2;\3;\4;\5;\6;\7;\8;\9;\
 6295                         \\10;\11;\12;\13;\14;\15;\16;\17;\18;\19;\20;\
 6296                         \\21;\22;\23;\24;\25;\26;\27;\28;\29;\30;\31;");
 6297       statement := prepare(testDb, "INSERT INTO " & tableName &
 6298                            " (varcharField) VALUES (?)");
 6299       insert(statement,          0,   expect &:= "0");
 6300       insert(statement,          1,   expect &:= "1");
 6301       insert(statement, 1234567890,   expect &:= "1234567890");
 6302       statement := prepare(testDb, "INSERT INTO " & tableName &
 6303                            " (varcharField) VALUES (?)");
 6304       insert(statement,          0_,  expect &:= "0");
 6305       insert(statement,          1_,  expect &:= "1");
 6306       insert(statement, 1234567890_,  expect &:= "1234567890");
 6307 *)
 6308 #      statement := prepare(testDb, "INSERT INTO " & tableName &
 6309 #                           " (varcharField) VALUES (N'" <&
 6310 #                           "\128;\129;\130;\131;\132;\133;\134;\135;\
 6311 #                           \\136;\137;\138;\139;\140;\141;\142;\143;\144;\145;\146;\147;\148;\
 6312 #                           \\149;\150;\151;\152;\153;\154;\155;\156;\157;\158;\159;" & "')");
 6313 #      statement := prepare(testDb, "INSERT INTO " & tableName &
 6314 #                           " (varcharField) VALUES (\
 6315 #                           \CHAR(128) + CHAR(129) + CHAR(130) + CHAR(131) + CHAR(132) + CHAR(133) + CHAR(134) + CHAR(135) + CHAR(136) + CHAR(137) + \
 6316 #                           \CHAR(138) + CHAR(139) + CHAR(140) + CHAR(141) + CHAR(142) + CHAR(143) + CHAR(144) + CHAR(145) + CHAR(146) + CHAR(147) + \
 6317 #                           \CHAR(148) + CHAR(149) + CHAR(150) + CHAR(151) + CHAR(152) + CHAR(153) + CHAR(154) + CHAR(155) + CHAR(156) + CHAR(157) + \
 6318 #                           \CHAR(158) + CHAR(159))");
 6319 #      execute(statement);
 6320 #      expect &:= "\128;\129;\130;\131;\132;\133;\134;\135;\
 6321 #                 \\136;\137;\138;\139;\140;\141;\142;\143;\144;\145;\146;\147;\148;\
 6322 #                 \\149;\150;\151;\152;\153;\154;\155;\156;\157;\158;\159;";
 6323       statement := prepare(testDb, "SELECT * FROM " & tableName);
 6324       execute(statement);
 6325       while fetch(statement) do
 6326         stringColumn := column(statement, 1, string);
 6327         # writeln("testVarcharField: Row: " <& row <& ": " <& stringColumn);
 6328         writeln("testVarcharField: Row: " <& row <& " length: " <& length(stringColumn));
 6329         incr(row);
 6330       end while;
 6331     exception
 6332       catch RANGE_ERROR:
 6333         writeln(" *** RANGE_ERROR was raised");
 6334       catch FILE_ERROR:
 6335         writeln(" *** FILE_ERROR was raised");
 6336       catch DATABASE_ERROR:
 6337         writeln(" *** DATABASE_ERROR was raised");
 6338     end block;
 6339     statement := prepare(testDb, "DROP TABLE " & tableName);
 6340     execute(statement);
 6341   end func;
 6342 
 6343 
 6344 const proc: testDb (in database: testDb, in connectData: dbConnectData) is func
 6345   local
 6346     var dbCategory: databaseKind is NO_DB;
 6347   begin
 6348     databaseKind := dbConnectData.databaseKind;
 6349     testPrepareAndExecute(testDb, databaseKind);
 6350     testFieldNames(testDb, databaseKind);
 6351     testAutoCommit(testDb, dbConnectData);
 6352     testTransactions(testDb, dbConnectData);
 6353     testBooleanField(testDb, databaseKind);
 6354     testInt8Field(testDb, databaseKind);
 6355     testInt16Field(testDb, databaseKind);
 6356     testInt32Field(testDb, databaseKind);
 6357     testInt64Field(testDb, databaseKind);
 6358     testBigIntField(testDb, databaseKind);
 6359     testFloatField(testDb, databaseKind);
 6360     testDoubleField(testDb, databaseKind);
 6361     # testBigRatField(testDb, databaseKind);
 6362     testDecimalIntField(testDb, databaseKind);
 6363     testNumericIntField(testDb, databaseKind);
 6364     testDecimalField(testDb, databaseKind);
 6365     testNumericField(testDb, databaseKind);
 6366     testChar1AsciiField(testDb, databaseKind);
 6367     testChar1Latin1Field(testDb, databaseKind);
 6368     testCodePageField(testDb, 1250, databaseKind);
 6369     testCodePageField(testDb, 1252, databaseKind);
 6370     testChar1Field(testDb, databaseKind);
 6371     testCharField(testDb, databaseKind);
 6372     testVarcharField(testDb, databaseKind);
 6373     testBlobField(testDb, databaseKind);
 6374     testClobField(testDb, databaseKind);
 6375     testDateField(testDb, databaseKind);
 6376     testTimeField(testDb, databaseKind);
 6377     testDateTimeField(testDb, databaseKind);
 6378     testTimeStampField(testDb, databaseKind);
 6379     testTimeStampTzField(testDb, databaseKind);
 6380     testDurationField(testDb, databaseKind);
 6381     # testFloatField2(testDb, databaseKind);
 6382     # testBigRatField2(testDb, databaseKind);
 6383     # testCharField2(testDb, databaseKind);
 6384     # testBlobField2(testDb, databaseKind);
 6385     # testTimeField2(testDb, databaseKind);
 6386     # testDurationField2(testDb, databaseKind);
 6387     # testNumericField2(testDb, databaseKind);
 6388     # testVarcharField2(testDb, databaseKind);
 6389   end func;
 6390 
 6391 
 6392 const func boolean: failed (in proc: statement) is func
 6393   result
 6394     var boolean: failed is FALSE;
 6395   begin
 6396     block
 6397       statement;
 6398     exception
 6399       catch RANGE_ERROR:
 6400         failed := TRUE;
 6401       catch FILE_ERROR:
 6402         failed := TRUE;
 6403       catch DATABASE_ERROR:
 6404         failed := TRUE;
 6405     end block;
 6406   end func;
 6407 
 6408 
 6409 const proc: testDatabase (in connectData: dbConnectData) is func
 6410   local
 6411     var database: testDb is database.value;
 6412   begin
 6413     writeln("Test " <& dbConnectData.dbName <& " with driver " <&
 6414             dbConnectData.driver);
 6415     block
 6416       testDb := openDatabase(dbConnectData.driver,
 6417                              dbConnectData.dbName,
 6418                              dbConnectData.user,
 6419                              dbConnectData.password);
 6420     exception
 6421       catch DATABASE_ERROR:
 6422         writeln(" *** Cannot open database " <& dbConnectData.dbName <&
 6423                 " with driver " <& dbConnectData.driver);
 6424         writeln(" *** Database error: " <& errMessage(DATABASE_ERROR));
 6425       otherwise:
 6426         writeln(" *** Cannot open database " <& dbConnectData.dbName <&
 6427                 " with driver " <& dbConnectData.driver);
 6428     end block;
 6429     if testDb <> database.value then
 6430       testDb(testDb, dbConnectData);
 6431       close(testDb);
 6432     end if;
 6433   end func;
 6434 
 6435 
 6436 const proc: main is func
 6437   local
 6438     const array connectData: dbConnectDataList is [] (
 6439         connectData(DB_ODBC,       "test",             "", "", DB_ODBC),
 6440         connectData(DB_SQL_SERVER, "test",             "test", "test", DB_SQL_SERVER),
 6441         connectData(DB_FIRE,       "test",             "test", "test", DB_FIRE),
 6442         # connectData(DB_MYSQL,      "penguin/test",     "test", "test", DB_MYSQL),
 6443         # connectData(DB_ODBC,       "penguin_mysql",    "test", "test", DB_MYSQL),
 6444         # connectData(DB_POSTGRESQL, "penguin/test",     "test", "test", DB_POSTGRESQL),
 6445         # connectData(DB_ODBC,       "penguin_postgres", "test", "test", DB_POSTGRESQL),
 6446         connectData(DB_MYSQL,      "test",             "test", "test", DB_MYSQL),
 6447         connectData(DB_SQLITE,     "test",             "test", "test", DB_SQLITE),
 6448         connectData(DB_POSTGRESQL, "test",             "test", "test", DB_POSTGRESQL),
 6449         # connectData(DB_OCI,        "XE",               "test", "test", DB_OCI),
 6450         # connectData(DB_OCI,        "192.168.2.99/XE",  "test", "test", DB_OCI),
 6451         connectData(DB_ODBC,       "wurx",             "test", "test", DB_MYSQL),
 6452         connectData(DB_ODBC,       "my",               "test", "test", DB_MYSQL),
 6453         connectData(DB_ODBC,       "lite",             "test", "test", DB_SQLITE),
 6454         connectData(DB_ODBC,       "post",             "test", "test", DB_POSTGRESQL));
 6455     var integer: index is 0;
 6456     var string: driverName is "";
 6457     var boolean: okay is TRUE;
 6458     var integer: paramNum is 0;
 6459     var string: databaseKindName is "";
 6460     var connectData: dbConnectData is connectData.value;
 6461   begin
 6462     OUT := STD_CONSOLE;
 6463     IN := openEditLine(KEYBOARD, OUT);
 6464     if length(argv(PROGRAM)) = 0 then
 6465       writeln("usage: chkdb driver [-d databaseKind] [dbName [user [password]]]");
 6466       writeln("       chkdb all");
 6467     elsif length(argv(PROGRAM)) = 1 and argv(PROGRAM)[1] = "all" then
 6468       for key index range dbConnectDataList do
 6469         testDatabase(dbConnectDataList[index]);
 6470       end for;
 6471     else
 6472       driverName := argv(PROGRAM)[1];
 6473       dbConnectData.driver := dbCategory(driverName);
 6474       if dbConnectData.driver = NO_DB then
 6475         writeln("*** " <& literal(driverName) <& " is not a valid database driver.");
 6476       else
 6477         paramNum := 2;
 6478         if length(argv(PROGRAM)) >= paramNum then
 6479           if argv(PROGRAM)[paramNum] = "-d" then
 6480             incr(paramNum);
 6481             if length(argv(PROGRAM)) >= paramNum then
 6482               databaseKindName := argv(PROGRAM)[paramNum];
 6483               dbConnectData.databaseKind := dbCategory(databaseKindName);
 6484               if dbConnectData.databaseKind = NO_DB then
 6485                 writeln("*** " <& literal(databaseKindName) <& " is not a valid database kind.");
 6486                 okay := FALSE;
 6487               end if;
 6488               incr(paramNum);
 6489             else
 6490               writeln("*** Database kind parameter missing.");
 6491               okay := FALSE;
 6492             end if;
 6493           end if;
 6494         end if;
 6495         if dbConnectData.databaseKind = NO_DB then
 6496           if (dbConnectData.driver = DB_ODBC or dbConnectData.driver = DB_TDS) then
 6497             writeln("** For the " <& dbConnectData.driver <& " driver a database kind must be specified.");
 6498             okay := FALSE;
 6499           else
 6500             dbConnectData.databaseKind := dbConnectData.driver;
 6501           end if;
 6502         end if;
 6503         if okay then
 6504           dbConnectData.dbName := "test";
 6505           dbConnectData.user := "test";
 6506           dbConnectData.password := "";
 6507           if length(argv(PROGRAM)) >= paramNum then
 6508             dbConnectData.dbName := argv(PROGRAM)[paramNum];
 6509             incr(paramNum);
 6510             if length(argv(PROGRAM)) >= paramNum then
 6511               dbConnectData.user := argv(PROGRAM)[paramNum];
 6512               incr(paramNum);
 6513               if length(argv(PROGRAM)) >= paramNum then
 6514                 dbConnectData.password := argv(PROGRAM)[paramNum];
 6515               end if;
 6516             end if;
 6517           end if;
 6518           if dbConnectData.password = "" then
 6519             write("Password: ");
 6520             flush(OUT);
 6521             dbConnectData.password := readPassword(IN);
 6522           end if;
 6523           if dbConnectData.databaseKind <> NO_DB then
 6524             testDatabase(dbConnectData);
 6525           end if;
 6526         end if;
 6527       end if;
 6528     end if;
 6529   end func;