modernc.org/cc@v1.0.1/v2/testdata/_sqlite/test/tclsqlite.test (about)

     1  # 2001 September 15
     2  #
     3  # The author disclaims copyright to this source code.  In place of
     4  # a legal notice, here is a blessing:
     5  #
     6  #    May you do good and not evil.
     7  #    May you find forgiveness for yourself and forgive others.
     8  #    May you share freely, never taking more than you give.
     9  #
    10  #***********************************************************************
    11  # This file implements regression tests for TCL interface to the
    12  # SQLite library. 
    13  #
    14  # Actually, all tests are based on the TCL interface, so the main
    15  # interface is pretty well tested.  This file contains some addition
    16  # tests for fringe issues that the main test suite does not cover.
    17  #
    18  # $Id: tclsqlite.test,v 1.73 2009/03/16 13:19:36 danielk1977 Exp $
    19  
    20  set testdir [file dirname $argv0]
    21  source $testdir/tester.tcl
    22  
    23  # Check the error messages generated by tclsqlite
    24  #
    25  set r "sqlite_orig HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
    26  if {[sqlite3 -has-codec]} {
    27    append r " ?-key CODECKEY?"
    28  }
    29  do_test tcl-1.1 {
    30    set v [catch {sqlite3 bogus} msg]
    31    regsub {really_sqlite3} $msg {sqlite3} msg
    32    lappend v $msg
    33  } [list 1 "wrong # args: should be \"$r\""]
    34  do_test tcl-1.2 {
    35    set v [catch {db bogus} msg]
    36    lappend v $msg
    37  } {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}}
    38  do_test tcl-1.2.1 {
    39    set v [catch {db cache bogus} msg]
    40    lappend v $msg
    41  } {1 {bad option "bogus": must be flush or size}}
    42  do_test tcl-1.2.2 {
    43    set v [catch {db cache} msg]
    44    lappend v $msg
    45  } {1 {wrong # args: should be "db cache option ?arg?"}}
    46  do_test tcl-1.3 {
    47    execsql {CREATE TABLE t1(a int, b int)}
    48    execsql {INSERT INTO t1 VALUES(10,20)}
    49    set v [catch {
    50      db eval {SELECT * FROM t1} data {
    51        error "The error message"
    52      }
    53    } msg]
    54    lappend v $msg
    55  } {1 {The error message}}
    56  do_test tcl-1.4 {
    57    set v [catch {
    58      db eval {SELECT * FROM t2} data {
    59        error "The error message"
    60      }
    61    } msg]
    62    lappend v $msg
    63  } {1 {no such table: t2}}
    64  do_test tcl-1.5 {
    65    set v [catch {
    66      db eval {SELECT * FROM t1} data {
    67        break
    68      }
    69    } msg]
    70    lappend v $msg
    71  } {0 {}}
    72  catch {expr x*} msg
    73  do_test tcl-1.6 {
    74    set v [catch {
    75      db eval {SELECT * FROM t1} data {
    76        expr x*
    77      }
    78    } msg]
    79    lappend v $msg
    80  } [list 1 $msg]
    81  do_test tcl-1.7 {
    82    set v [catch {db} msg]
    83    lappend v $msg
    84  } {1 {wrong # args: should be "db SUBCOMMAND ..."}}
    85  if {[catch {db auth {}}]==0} {
    86    do_test tcl-1.8 {
    87      set v [catch {db authorizer 1 2 3} msg]
    88      lappend v $msg
    89    } {1 {wrong # args: should be "db authorizer ?CALLBACK?"}}
    90  }
    91  do_test tcl-1.9 {
    92    set v [catch {db busy 1 2 3} msg]
    93    lappend v $msg
    94  } {1 {wrong # args: should be "db busy CALLBACK"}}
    95  do_test tcl-1.10 {
    96    set v [catch {db progress 1} msg]
    97    lappend v $msg
    98  } {1 {wrong # args: should be "db progress N CALLBACK"}}
    99  do_test tcl-1.11 {
   100    set v [catch {db changes xyz} msg]
   101    lappend v $msg
   102  } {1 {wrong # args: should be "db changes "}}
   103  do_test tcl-1.12 {
   104    set v [catch {db commit_hook a b c} msg]
   105    lappend v $msg
   106  } {1 {wrong # args: should be "db commit_hook ?CALLBACK?"}}
   107  ifcapable {complete} {
   108    do_test tcl-1.13 {
   109      set v [catch {db complete} msg]
   110      lappend v $msg
   111    } {1 {wrong # args: should be "db complete SQL"}}
   112  }
   113  do_test tcl-1.14 {
   114    set v [catch {db eval} msg]
   115    lappend v $msg
   116  } {1 {wrong # args: should be "db eval ?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?"}}
   117  do_test tcl-1.15 {
   118    set v [catch {db function} msg]
   119    lappend v $msg
   120  } {1 {wrong # args: should be "db function NAME ?SWITCHES? SCRIPT"}}
   121  do_test tcl-1.16 {
   122    set v [catch {db last_insert_rowid xyz} msg]
   123    lappend v $msg
   124  } {1 {wrong # args: should be "db last_insert_rowid "}}
   125  do_test tcl-1.17 {
   126    set v [catch {db rekey} msg]
   127    lappend v $msg
   128  } {1 {wrong # args: should be "db rekey KEY"}}
   129  do_test tcl-1.18 {
   130    set v [catch {db timeout} msg]
   131    lappend v $msg
   132  } {1 {wrong # args: should be "db timeout MILLISECONDS"}}
   133  do_test tcl-1.19 {
   134    set v [catch {db collate} msg]
   135    lappend v $msg
   136  } {1 {wrong # args: should be "db collate NAME SCRIPT"}}
   137  do_test tcl-1.20 {
   138    set v [catch {db collation_needed} msg]
   139    lappend v $msg
   140  } {1 {wrong # args: should be "db collation_needed SCRIPT"}}
   141  do_test tcl-1.21 {
   142    set v [catch {db total_changes xyz} msg]
   143    lappend v $msg
   144  } {1 {wrong # args: should be "db total_changes "}}
   145  do_test tcl-1.22 {
   146    set v [catch {db copy} msg]
   147    lappend v $msg
   148  } {1 {wrong # args: should be "db copy CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"}}
   149  do_test tcl-1.23 {
   150    set v [catch {sqlite3 db2 test.db -vfs nosuchvfs} msg]
   151    lappend v $msg
   152  } {1 {no such vfs: nosuchvfs}}
   153  
   154  catch {unset ::result}
   155  do_test tcl-2.1 {
   156    execsql "CREATE TABLE t\u0123x(a int, b\u1235 float)"
   157  } {}
   158  ifcapable schema_pragmas {
   159    do_test tcl-2.2 {
   160      execsql "PRAGMA table_info(t\u0123x)"
   161    } "0 a int 0 {} 0 1 b\u1235 float 0 {} 0"
   162  }
   163  do_test tcl-2.3 {
   164    execsql "INSERT INTO t\u0123x VALUES(1,2.3)"
   165    db eval "SELECT * FROM t\u0123x" result break
   166    set result(*)
   167  } "a b\u1235"
   168  
   169  
   170  # Test the onecolumn method
   171  #
   172  do_test tcl-3.1 {
   173    execsql {
   174      INSERT INTO t1 SELECT a*2, b*2 FROM t1;
   175      INSERT INTO t1 SELECT a*2+1, b*2+1 FROM t1;
   176      INSERT INTO t1 SELECT a*2+3, b*2+3 FROM t1;
   177    }
   178    set rc [catch {db onecolumn {SELECT * FROM t1 ORDER BY a}} msg]
   179    lappend rc $msg
   180  } {0 10}
   181  do_test tcl-3.2 {
   182    db onecolumn {SELECT * FROM t1 WHERE a<0}
   183  } {}
   184  do_test tcl-3.3 {
   185    set rc [catch {db onecolumn} errmsg]
   186    lappend rc $errmsg
   187  } {1 {wrong # args: should be "db onecolumn SQL"}}
   188  do_test tcl-3.4 {
   189    set rc [catch {db onecolumn {SELECT bogus}} errmsg]
   190    lappend rc $errmsg
   191  } {1 {no such column: bogus}}
   192  ifcapable {tclvar} {
   193    do_test tcl-3.5 {
   194      set b 50
   195      set rc [catch {db one {SELECT * FROM t1 WHERE b>$b}} msg]
   196      lappend rc $msg
   197    } {0 41}
   198    do_test tcl-3.6 {
   199      set b 500
   200      set rc [catch {db one {SELECT * FROM t1 WHERE b>$b}} msg]
   201      lappend rc $msg
   202    } {0 {}}
   203    do_test tcl-3.7 {
   204      set b 500
   205      set rc [catch {db one {
   206        INSERT INTO t1 VALUES(99,510);
   207        SELECT * FROM t1 WHERE b>$b
   208      }} msg]
   209      lappend rc $msg
   210    } {0 99}
   211  }
   212  ifcapable {!tclvar} {
   213     execsql {INSERT INTO t1 VALUES(99,510)}
   214  }
   215  
   216  # Turn the busy handler on and off
   217  #
   218  do_test tcl-4.1 {
   219    proc busy_callback {cnt} {
   220      break
   221    }
   222    db busy busy_callback
   223    db busy
   224  } {busy_callback}
   225  do_test tcl-4.2 {
   226    db busy {}
   227    db busy
   228  } {}
   229  
   230  ifcapable {tclvar} {
   231    # Parsing of TCL variable names within SQL into bound parameters.
   232    #
   233    do_test tcl-5.1 {
   234      execsql {CREATE TABLE t3(a,b,c)}
   235      catch {unset x}
   236      set x(1) A
   237      set x(2) B
   238      execsql {
   239        INSERT INTO t3 VALUES($::x(1),$::x(2),$::x(3));
   240        SELECT * FROM t3
   241      }
   242    } {A B {}}
   243    do_test tcl-5.2 {
   244      execsql {
   245        SELECT typeof(a), typeof(b), typeof(c) FROM t3
   246      }
   247    } {text text null}
   248    do_test tcl-5.3 {
   249      catch {unset x}
   250      set x [binary format h12 686900686f00]
   251      execsql {
   252        UPDATE t3 SET a=$::x;
   253      }
   254      db eval {
   255        SELECT a FROM t3
   256      } break
   257      binary scan $a h12 adata
   258      set adata
   259    } {686900686f00}
   260    do_test tcl-5.4 {
   261      execsql {
   262        SELECT typeof(a), typeof(b), typeof(c) FROM t3
   263      }
   264    } {blob text null}
   265  }
   266  
   267  # Operation of "break" and "continue" within row scripts
   268  #
   269  do_test tcl-6.1 {
   270    db eval {SELECT * FROM t1} {
   271      break
   272    }
   273    lappend a $b
   274  } {10 20}
   275  do_test tcl-6.2 {
   276    set cnt 0
   277    db eval {SELECT * FROM t1} {
   278      if {$a>40} continue
   279      incr cnt
   280    }
   281    set cnt
   282  } {4}
   283  do_test tcl-6.3 {
   284    set cnt 0
   285    db eval {SELECT * FROM t1} {
   286      if {$a<40} continue
   287      incr cnt
   288    }
   289    set cnt
   290  } {5}
   291  do_test tcl-6.4 {
   292    proc return_test {x} {
   293      db eval {SELECT * FROM t1} {
   294        if {$a==$x} {return $b}
   295      }
   296    }
   297    return_test 10
   298  } 20
   299  do_test tcl-6.5 {
   300    return_test 20
   301  } 40
   302  do_test tcl-6.6 {
   303    return_test 99
   304  } 510
   305  do_test tcl-6.7 {
   306    return_test 0
   307  } {}
   308  
   309  do_test tcl-7.1 {
   310    db version
   311    expr 0
   312  } {0}
   313  
   314  # modify and reset the NULL representation
   315  #
   316  do_test tcl-8.1 {
   317    db nullvalue NaN
   318    execsql {INSERT INTO t1 VALUES(30,NULL)}
   319    db eval {SELECT * FROM t1 WHERE b IS NULL}
   320  } {30 NaN}
   321  proc concatFunc args {return [join $args {}]}
   322  do_test tcl-8.2 {
   323    db function concat concatFunc
   324    db eval {SELECT concat('a', b, 'z') FROM t1 WHERE b is NULL}
   325  } {aNaNz}
   326  do_test tcl-8.3 {
   327    db nullvalue NULL
   328    db nullvalue
   329  } {NULL}
   330  do_test tcl-8.4 {
   331    db nullvalue {}
   332    db eval {SELECT * FROM t1 WHERE b IS NULL}
   333  } {30 {}}
   334  do_test tcl-8.5 {
   335    db function concat concatFunc
   336    db eval {SELECT concat('a', b, 'z') FROM t1 WHERE b is NULL}
   337  } {az}
   338  
   339  # Test the return type of user-defined functions
   340  #
   341  do_test tcl-9.1 {
   342    db function ret_str {return "hi"}
   343    execsql {SELECT typeof(ret_str())}
   344  } {text}
   345  do_test tcl-9.2 {
   346    db function ret_dbl {return [expr {rand()*0.5}]}
   347    execsql {SELECT typeof(ret_dbl())}
   348  } {real}
   349  do_test tcl-9.3 {
   350    db function ret_int {return [expr {int(rand()*200)}]}
   351    execsql {SELECT typeof(ret_int())}
   352  } {integer}
   353  
   354  # Recursive calls to the same user-defined function
   355  #
   356  ifcapable tclvar {
   357    do_test tcl-9.10 {
   358      proc userfunc_r1 {n} {
   359        if {$n<=0} {return 0}
   360        set nm1 [expr {$n-1}]
   361        return [expr {[db eval {SELECT r1($nm1)}]+$n}]
   362      }
   363      db function r1 userfunc_r1
   364      execsql {SELECT r1(10)}
   365    } {55}
   366    do_test tcl-9.11 {
   367      execsql {SELECT r1(100)}
   368    } {5050}
   369  }
   370  
   371  # Tests for the new transaction method
   372  #
   373  do_test tcl-10.1 {
   374    db transaction {}
   375  } {}
   376  do_test tcl-10.2 {
   377    db transaction deferred {}
   378  } {}
   379  do_test tcl-10.3 {
   380    db transaction immediate {}
   381  } {}
   382  do_test tcl-10.4 {
   383    db transaction exclusive {}
   384  } {}
   385  do_test tcl-10.5 {
   386    set rc [catch {db transaction xyzzy {}} msg]
   387    lappend rc $msg
   388  } {1 {bad transaction type "xyzzy": must be deferred, exclusive, or immediate}}
   389  do_test tcl-10.6 {
   390    set rc [catch {db transaction {error test-error}} msg]
   391    lappend rc $msg
   392  } {1 test-error}
   393  do_test tcl-10.7 {
   394    db transaction {
   395      db eval {CREATE TABLE t4(x)}
   396      db transaction {
   397        db eval {INSERT INTO t4 VALUES(1)}
   398      }
   399    }
   400    db eval {SELECT * FROM t4}
   401  } 1
   402  do_test tcl-10.8 {
   403    catch {
   404      db transaction {
   405        db eval {INSERT INTO t4 VALUES(2)}
   406        db eval {INSERT INTO t4 VALUES(3)}
   407        db eval {INSERT INTO t4 VALUES(4)}
   408        error test-error
   409      }
   410    }
   411    db eval {SELECT * FROM t4}
   412  } 1
   413  do_test tcl-10.9 {
   414    db transaction {
   415      db eval {INSERT INTO t4 VALUES(2)}
   416      catch {
   417        db transaction {
   418          db eval {INSERT INTO t4 VALUES(3)}
   419          db eval {INSERT INTO t4 VALUES(4)}
   420          error test-error
   421        }
   422      }
   423    }
   424    db eval {SELECT * FROM t4}
   425  } {1 2}
   426  do_test tcl-10.10 {
   427    for {set i 0} {$i<1} {incr i} {
   428      db transaction {
   429        db eval {INSERT INTO t4 VALUES(5)}
   430        continue
   431      }
   432      error "This line should not be run"
   433    }
   434    db eval {SELECT * FROM t4}
   435  } {1 2 5}
   436  do_test tcl-10.11 {
   437    for {set i 0} {$i<10} {incr i} {
   438      db transaction {
   439        db eval {INSERT INTO t4 VALUES(6)}
   440        break
   441      }
   442    }
   443    db eval {SELECT * FROM t4}
   444  } {1 2 5 6}
   445  do_test tcl-10.12 {
   446    set rc [catch {
   447      for {set i 0} {$i<10} {incr i} {
   448        db transaction {
   449          db eval {INSERT INTO t4 VALUES(7)}
   450          return
   451        }
   452      }
   453    }]
   454  } {2}
   455  do_test tcl-10.13 {
   456    db eval {SELECT * FROM t4}
   457  } {1 2 5 6 7}
   458  
   459  # Now test that [db transaction] commands may be nested with 
   460  # the expected results.
   461  #
   462  do_test tcl-10.14 {
   463    db transaction {
   464      db eval {
   465        DELETE FROM t4;
   466        INSERT INTO t4 VALUES('one');
   467      }
   468  
   469      catch { 
   470        db transaction {
   471          db eval { INSERT INTO t4 VALUES('two') }
   472          db transaction {
   473            db eval { INSERT INTO t4 VALUES('three') }
   474            error "throw an error!"
   475          }
   476        }
   477      }
   478    }
   479  
   480    db eval {SELECT * FROM t4}
   481  } {one}
   482  do_test tcl-10.15 {
   483    # Make sure a transaction has not been left open.
   484    db eval {BEGIN ; COMMIT}
   485  } {}
   486  do_test tcl-10.16 {
   487    db transaction {
   488      db eval { INSERT INTO t4 VALUES('two'); }
   489      db transaction {
   490        db eval { INSERT INTO t4 VALUES('three') }
   491        db transaction {
   492          db eval { INSERT INTO t4 VALUES('four') }
   493        }
   494      }
   495    }
   496    db eval {SELECT * FROM t4}
   497  } {one two three four}
   498  do_test tcl-10.17 {
   499    catch {
   500      db transaction {
   501        db eval { INSERT INTO t4 VALUES('A'); }
   502        db transaction {
   503          db eval { INSERT INTO t4 VALUES('B') }
   504          db transaction {
   505            db eval { INSERT INTO t4 VALUES('C') }
   506            error "throw an error!"
   507          }
   508        }
   509      }
   510    }
   511    db eval {SELECT * FROM t4}
   512  } {one two three four}
   513  do_test tcl-10.18 {
   514    # Make sure a transaction has not been left open.
   515    db eval {BEGIN ; COMMIT}
   516  } {}
   517  
   518  # Mess up a [db transaction] command by locking the database using a
   519  # second connection when it tries to commit. Make sure the transaction
   520  # is not still open after the "database is locked" exception is thrown.
   521  #
   522  do_test tcl-10.18 {
   523    sqlite3 db2 test.db
   524    db2 eval {
   525      BEGIN;
   526      SELECT * FROM sqlite_master;
   527    }
   528  
   529    set rc [catch {
   530      db transaction {
   531        db eval {INSERT INTO t4 VALUES('five')}
   532      }
   533    } msg]
   534    list $rc $msg
   535  } {1 {database is locked}}
   536  do_test tcl-10.19 {
   537    db eval {BEGIN ; COMMIT}
   538  } {}
   539  
   540  # Thwart a [db transaction] command by locking the database using a
   541  # second connection with "BEGIN EXCLUSIVE". Make sure no transaction is 
   542  # open after the "database is locked" exception is thrown.
   543  #
   544  do_test tcl-10.20 {
   545    db2 eval {
   546      COMMIT;
   547      BEGIN EXCLUSIVE;
   548    }
   549    set rc [catch {
   550      db transaction {
   551        db eval {INSERT INTO t4 VALUES('five')}
   552      }
   553    } msg]
   554    list $rc $msg
   555  } {1 {database is locked}}
   556  do_test tcl-10.21 {
   557    db2 close
   558    db eval {BEGIN ; COMMIT}
   559  } {}
   560  do_test tcl-10.22 {
   561    sqlite3 db2 test.db
   562    db transaction exclusive {
   563      catch { db2 eval {SELECT * FROM sqlite_master} } msg
   564      set msg "db2: $msg"
   565    }
   566    set msg
   567  } {db2: database is locked}
   568  db2 close
   569  
   570  do_test tcl-11.1 {
   571    db eval {INSERT INTO t4 VALUES(6)}
   572    db exists {SELECT x,x*2,x+x FROM t4 WHERE x==6}
   573  } {1}
   574  do_test tcl-11.2 {
   575    db exists {SELECT 0 FROM t4 WHERE x==6}
   576  } {1}
   577  do_test tcl-11.3 {
   578    db exists {SELECT 1 FROM t4 WHERE x==8}
   579  } {0}
   580  do_test tcl-11.3.1 {
   581    tcl_objproc db exists {SELECT 1 FROM t4 WHERE x==8}
   582  } {0}
   583  
   584  do_test tcl-12.1 {
   585    unset -nocomplain a b c version
   586    set version [db version]
   587    scan $version "%d.%d.%d" a b c
   588    expr $a*1000000 + $b*1000 + $c
   589  } [sqlite3_libversion_number]
   590  
   591  
   592  # Check to see that when bindings of the form @aaa are used instead
   593  # of $aaa, that objects are treated as bytearray and are inserted
   594  # as BLOBs.
   595  #
   596  ifcapable tclvar {
   597    do_test tcl-13.1 {
   598      db eval {CREATE TABLE t5(x BLOB)}
   599      set x abc123
   600      db eval {INSERT INTO t5 VALUES($x)}
   601      db eval {SELECT typeof(x) FROM t5}
   602    } {text}
   603    do_test tcl-13.2 {
   604      binary scan $x H notUsed
   605      db eval {
   606        DELETE FROM t5;
   607        INSERT INTO t5 VALUES($x);
   608        SELECT typeof(x) FROM t5;
   609      }
   610    } {text}
   611    do_test tcl-13.3 {
   612      db eval {
   613        DELETE FROM t5;
   614        INSERT INTO t5 VALUES(@x);
   615        SELECT typeof(x) FROM t5;
   616      }
   617    } {blob}
   618    do_test tcl-13.4 {
   619      set y 1234
   620      db eval {
   621        DELETE FROM t5;
   622        INSERT INTO t5 VALUES(@y);
   623        SELECT hex(x), typeof(x) FROM t5
   624      }
   625    } {31323334 blob}
   626  }
   627  
   628  db func xCall xCall
   629  proc xCall {} { return "value" }
   630  do_execsql_test tcl-14.1 {
   631    CREATE TABLE t6(x);
   632    INSERT INTO t6 VALUES(1);
   633  }
   634  do_test tcl-14.2 {
   635    db one {SELECT x FROM t6 WHERE xCall()!='value'}
   636  } {}
   637  
   638  # Verify that the "exists" and "onecolumn" methods work when
   639  # a "profile" is registered.
   640  #
   641  catch {db close}
   642  sqlite3 db :memory:
   643  proc noop-profile {args} {
   644    return
   645  }
   646  do_test tcl-15.0 {
   647    db eval {CREATE TABLE t1(a); INSERT INTO t1 VALUES(1),(2),(3);}
   648    db onecolumn {SELECT a FROM t1 WHERE a>2}
   649  } {3}
   650  do_test tcl-15.1 {
   651    db exists {SELECT a FROM t1 WHERE a>2}
   652  } {1}
   653  do_test tcl-15.2 {
   654    db exists {SELECT a FROM t1 WHERE a>3}
   655  } {0}
   656  db profile noop-profile
   657  do_test tcl-15.3 {
   658    db onecolumn {SELECT a FROM t1 WHERE a>2}
   659  } {3}
   660  do_test tcl-15.4 {
   661    db exists {SELECT a FROM t1 WHERE a>2}
   662  } {1}
   663  do_test tcl-15.5 {
   664    db exists {SELECT a FROM t1 WHERE a>3}
   665  } {0}
   666  
   667  
   668  # 2017-06-26: The --withoutnulls flag to "db eval".
   669  #
   670  # In the "db eval --withoutnulls SQL ARRAY" form, NULL results cause the
   671  # corresponding array entry to be unset.  The default behavior (without
   672  # the -withoutnulls flags) is for the corresponding array value to get
   673  # the [db nullvalue] string.
   674  #
   675  catch {db close}
   676  forcedelete test.db
   677  sqlite3 db test.db
   678  do_execsql_test tcl-16.100 {
   679    CREATE TABLE t1(a,b);
   680    INSERT INTO t1 VALUES(1,2),(2,NULL),(3,'xyz');
   681  }
   682  do_test tcl-16.101 {
   683    set res {}
   684    unset -nocomplain x
   685    db eval {SELECT * FROM t1} x {
   686      lappend res $x(a) [array names x]
   687    }
   688    set res
   689  } {1 {a b *} 2 {a b *} 3 {a b *}}
   690  do_test tcl-16.102 {
   691    set res [catch {
   692      db eval -unknown {SELECT * FROM t1} x {
   693        lappend res $x(a) [array names x]
   694      }
   695    } rc]
   696    lappend res $rc
   697  } {1 {unknown option: "-unknown"}}
   698  do_test tcl-16.103 {
   699    set res {}
   700    unset -nocomplain x
   701    db eval -withoutnulls {SELECT * FROM t1} x {
   702      lappend res $x(a) [array names x]
   703    }
   704    set res
   705  } {1 {a b *} 2 {a *} 3 {a b *}}
   706  
   707  
   708  
   709  
   710  
   711  finish_test