xref: /sqlite-3.40.0/test/shell1.test (revision 697c9eaa)
18df9185cSdrh# 2009 Nov 11
28df9185cSdrh#
38df9185cSdrh# The author disclaims copyright to this source code.  In place of
48df9185cSdrh# a legal notice, here is a blessing:
58df9185cSdrh#
68df9185cSdrh#    May you do good and not evil.
78df9185cSdrh#    May you find forgiveness for yourself and forgive others.
88df9185cSdrh#    May you share freely, never taking more than you give.
98df9185cSdrh#
108df9185cSdrh#***********************************************************************
118df9185cSdrh#
128df9185cSdrh# The focus of this file is testing the CLI shell tool.
138df9185cSdrh#
148df9185cSdrh#
158df9185cSdrh
168df9185cSdrh# Test plan:
178df9185cSdrh#
188df9185cSdrh#   shell1-1.*: Basic command line option handling.
198df9185cSdrh#   shell1-2.*: Basic "dot" command token parsing.
208df9185cSdrh#   shell1-3.*: Basic test that "dot" command can be called.
218df9185cSdrh#
228df9185cSdrhset testdir [file dirname $argv0]
238df9185cSdrhsource $testdir/tester.tcl
24089555c8Sdanset CLI [test_find_cli]
258df9185cSdrhdb close
268df9185cSdrhforcedelete test.db test.db-journal test.db-wal
278df9185cSdrhsqlite3 db test.db
288df9185cSdrh
298df9185cSdrh#----------------------------------------------------------------------------
308df9185cSdrh# Test cases shell1-1.*: Basic command line option handling.
318df9185cSdrh#
328df9185cSdrh
338df9185cSdrh# invalid option
348df9185cSdrhdo_test shell1-1.1.1 {
358df9185cSdrh  set res [catchcmd "-bad test.db" ""]
368df9185cSdrh  set rc [lindex $res 0]
378df9185cSdrh  list $rc \
388df9185cSdrh       [regexp {Error: unknown option: -bad} $res]
398df9185cSdrh} {1 1}
40ac5649a9Sdrhdo_test shell1-1.1.1b {
41ac5649a9Sdrh  set res [catchcmd "test.db -bad" ""]
42ac5649a9Sdrh  set rc [lindex $res 0]
43ac5649a9Sdrh  list $rc \
44ac5649a9Sdrh       [regexp {Error: unknown option: -bad} $res]
45ac5649a9Sdrh} {1 1}
468df9185cSdrh# error on extra options
478df9185cSdrhdo_test shell1-1.1.2 {
4860c4249fSdrh  catchcmd "test.db \"select+3\" \"select+4\"" ""
49ac5649a9Sdrh} {0 {3
50ac5649a9Sdrh4}}
518df9185cSdrh# error on extra options
528df9185cSdrhdo_test shell1-1.1.3 {
53ac5649a9Sdrh  catchcmd "test.db FOO test.db BAD" ".quit"
54ac5649a9Sdrh} {1 {Error: near "FOO": syntax error}}
558df9185cSdrh
568df9185cSdrh# -help
578df9185cSdrhdo_test shell1-1.2.1 {
588df9185cSdrh  set res [catchcmd "-help test.db" ""]
598df9185cSdrh  set rc [lindex $res 0]
608df9185cSdrh  list $rc \
618df9185cSdrh       [regexp {Usage} $res] \
628df9185cSdrh       [regexp {\-init} $res] \
638df9185cSdrh       [regexp {\-version} $res]
648df9185cSdrh} {1 1 1 1}
658df9185cSdrh
668df9185cSdrh# -init filename       read/process named file
678df9185cSdrhdo_test shell1-1.3.1 {
688df9185cSdrh  catchcmd "-init FOO test.db" ""
698df9185cSdrh} {0 {}}
708df9185cSdrhdo_test shell1-1.3.2 {
71ac5649a9Sdrh  catchcmd "-init FOO test.db .quit BAD" ""
72ac5649a9Sdrh} {0 {}}
73ac5649a9Sdrhdo_test shell1-1.3.3 {
74ac5649a9Sdrh  catchcmd "-init FOO test.db BAD .quit" ""
75ac5649a9Sdrh} {1 {Error: near "BAD": syntax error}}
768df9185cSdrh
778df9185cSdrh# -echo                print commands before execution
788df9185cSdrhdo_test shell1-1.4.1 {
798df9185cSdrh  catchcmd "-echo test.db" ""
808df9185cSdrh} {0 {}}
818df9185cSdrh
828df9185cSdrh# -[no]header          turn headers on or off
838df9185cSdrhdo_test shell1-1.5.1 {
848df9185cSdrh  catchcmd "-header test.db" ""
858df9185cSdrh} {0 {}}
868df9185cSdrhdo_test shell1-1.5.2 {
878df9185cSdrh  catchcmd "-noheader test.db" ""
888df9185cSdrh} {0 {}}
898df9185cSdrh
908df9185cSdrh# -bail                stop after hitting an error
918df9185cSdrhdo_test shell1-1.6.1 {
928df9185cSdrh  catchcmd "-bail test.db" ""
938df9185cSdrh} {0 {}}
948df9185cSdrh
958df9185cSdrh# -interactive         force interactive I/O
968df9185cSdrhdo_test shell1-1.7.1 {
978df9185cSdrh  set res [catchcmd "-interactive test.db" ".quit"]
988df9185cSdrh  set rc [lindex $res 0]
998df9185cSdrh  list $rc \
1008df9185cSdrh       [regexp {SQLite version} $res] \
10139a3088dSdrh       [regexp {Enter ".help" for usage hints} $res]
1028df9185cSdrh} {0 1 1}
1038df9185cSdrh
1048df9185cSdrh# -batch               force batch I/O
1058df9185cSdrhdo_test shell1-1.8.1 {
1068df9185cSdrh  catchcmd "-batch test.db" ""
1078df9185cSdrh} {0 {}}
1088df9185cSdrh
1098df9185cSdrh# -column              set output mode to 'column'
1108df9185cSdrhdo_test shell1-1.9.1 {
1118df9185cSdrh  catchcmd "-column test.db" ""
1128df9185cSdrh} {0 {}}
1138df9185cSdrh
1148df9185cSdrh# -csv                 set output mode to 'csv'
1158df9185cSdrhdo_test shell1-1.10.1 {
1168df9185cSdrh  catchcmd "-csv test.db" ""
1178df9185cSdrh} {0 {}}
1188df9185cSdrh
1198df9185cSdrh# -html                set output mode to HTML
1208df9185cSdrhdo_test shell1-1.11.1 {
1218df9185cSdrh  catchcmd "-html test.db" ""
1228df9185cSdrh} {0 {}}
1238df9185cSdrh
1248df9185cSdrh# -line                set output mode to 'line'
1258df9185cSdrhdo_test shell1-1.12.1 {
1268df9185cSdrh  catchcmd "-line test.db" ""
1278df9185cSdrh} {0 {}}
1288df9185cSdrh
1298df9185cSdrh# -list                set output mode to 'list'
1308df9185cSdrhdo_test shell1-1.13.1 {
1318df9185cSdrh  catchcmd "-list test.db" ""
1328df9185cSdrh} {0 {}}
1338df9185cSdrh
1348df9185cSdrh# -separator 'x'       set output field separator (|)
1358df9185cSdrhdo_test shell1-1.14.1 {
1368df9185cSdrh  catchcmd "-separator 'x' test.db" ""
1378df9185cSdrh} {0 {}}
1388df9185cSdrhdo_test shell1-1.14.2 {
1398df9185cSdrh  catchcmd "-separator x test.db" ""
1408df9185cSdrh} {0 {}}
1418df9185cSdrhdo_test shell1-1.14.3 {
1428df9185cSdrh  set res [catchcmd "-separator" ""]
1438df9185cSdrh  set rc [lindex $res 0]
1448df9185cSdrh  list $rc \
14598d312fcSdrh       [regexp {Error: missing argument to -separator} $res]
1468df9185cSdrh} {1 1}
1478df9185cSdrh
1488df9185cSdrh# -stats               print memory stats before each finalize
1498df9185cSdrhdo_test shell1-1.14b.1 {
1508df9185cSdrh  catchcmd "-stats test.db" ""
1518df9185cSdrh} {0 {}}
1528df9185cSdrh
1538df9185cSdrh# -nullvalue 'text'    set text string for NULL values
1548df9185cSdrhdo_test shell1-1.15.1 {
1558df9185cSdrh  catchcmd "-nullvalue 'x' test.db" ""
1568df9185cSdrh} {0 {}}
1578df9185cSdrhdo_test shell1-1.15.2 {
1588df9185cSdrh  catchcmd "-nullvalue x test.db" ""
1598df9185cSdrh} {0 {}}
1608df9185cSdrhdo_test shell1-1.15.3 {
1618df9185cSdrh  set res [catchcmd "-nullvalue" ""]
1628df9185cSdrh  set rc [lindex $res 0]
1638df9185cSdrh  list $rc \
16498d312fcSdrh       [regexp {Error: missing argument to -nullvalue} $res]
1658df9185cSdrh} {1 1}
1668df9185cSdrh
1678df9185cSdrh# -version             show SQLite version
1688df9185cSdrhdo_test shell1-1.16.1 {
1698df9185cSdrh  set x [catchcmd "-version test.db" ""]
170b24c61a2Sdrh} {/3.[0-9.]+ 20\d\d-[01]\d-\d\d \d\d:\d\d:\d\d [0-9a-f]+/}
1718df9185cSdrh
1728df9185cSdrh#----------------------------------------------------------------------------
1738df9185cSdrh# Test cases shell1-2.*: Basic "dot" command token parsing.
1748df9185cSdrh#
1758df9185cSdrh
1768df9185cSdrh# check first token handling
1778df9185cSdrhdo_test shell1-2.1.1 {
1788df9185cSdrh  catchcmd "test.db" ".foo"
1798df9185cSdrh} {1 {Error: unknown command or invalid arguments:  "foo". Enter ".help" for help}}
1808df9185cSdrhdo_test shell1-2.1.2 {
1818df9185cSdrh  catchcmd "test.db" ".\"foo OFF\""
1828df9185cSdrh} {1 {Error: unknown command or invalid arguments:  "foo OFF". Enter ".help" for help}}
1838df9185cSdrhdo_test shell1-2.1.3 {
1848df9185cSdrh  catchcmd "test.db" ".\'foo OFF\'"
1858df9185cSdrh} {1 {Error: unknown command or invalid arguments:  "foo OFF". Enter ".help" for help}}
1868df9185cSdrh
1878df9185cSdrh# unbalanced quotes
1888df9185cSdrhdo_test shell1-2.2.1 {
1898df9185cSdrh  catchcmd "test.db" ".\"foo OFF"
1908df9185cSdrh} {1 {Error: unknown command or invalid arguments:  "foo OFF". Enter ".help" for help}}
1918df9185cSdrhdo_test shell1-2.2.2 {
1928df9185cSdrh  catchcmd "test.db" ".\'foo OFF"
1938df9185cSdrh} {1 {Error: unknown command or invalid arguments:  "foo OFF". Enter ".help" for help}}
1948df9185cSdrhdo_test shell1-2.2.3 {
1958df9185cSdrh  catchcmd "test.db" ".explain \"OFF"
1968df9185cSdrh} {0 {}}
1978df9185cSdrhdo_test shell1-2.2.4 {
1988df9185cSdrh  catchcmd "test.db" ".explain \'OFF"
1998df9185cSdrh} {0 {}}
2008df9185cSdrhdo_test shell1-2.2.5 {
2018df9185cSdrh  catchcmd "test.db" ".mode \"insert FOO"
202636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}}
2038df9185cSdrhdo_test shell1-2.2.6 {
2048df9185cSdrh  catchcmd "test.db" ".mode \'insert FOO"
205636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}}
2068df9185cSdrh
2078df9185cSdrh# check multiple tokens, and quoted tokens
2088df9185cSdrhdo_test shell1-2.3.1 {
2098df9185cSdrh  catchcmd "test.db" ".explain 1"
2108df9185cSdrh} {0 {}}
2118df9185cSdrhdo_test shell1-2.3.2 {
2128df9185cSdrh  catchcmd "test.db" ".explain on"
2138df9185cSdrh} {0 {}}
2148df9185cSdrhdo_test shell1-2.3.3 {
2158df9185cSdrh  catchcmd "test.db" ".explain \"1 2 3\""
216173ba099Sdrh} {1 {ERROR: Not a boolean value: "1 2 3". Assuming "no".}}
2178df9185cSdrhdo_test shell1-2.3.4 {
2188df9185cSdrh  catchcmd "test.db" ".explain \"OFF\""
2198df9185cSdrh} {0 {}}
2208df9185cSdrhdo_test shell1-2.3.5 {
2218df9185cSdrh  catchcmd "test.db" ".\'explain\' \'OFF\'"
2228df9185cSdrh} {0 {}}
2238df9185cSdrhdo_test shell1-2.3.6 {
2248df9185cSdrh  catchcmd "test.db" ".explain \'OFF\'"
2258df9185cSdrh} {0 {}}
2268df9185cSdrhdo_test shell1-2.3.7 {
2278df9185cSdrh  catchcmd "test.db" ".\'explain\' \'OFF\'"
2288df9185cSdrh} {0 {}}
2298df9185cSdrh
2308df9185cSdrh# check quoted args are unquoted
2318df9185cSdrhdo_test shell1-2.4.1 {
2328df9185cSdrh  catchcmd "test.db" ".mode FOO"
233636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}}
2348df9185cSdrhdo_test shell1-2.4.2 {
2358df9185cSdrh  catchcmd "test.db" ".mode csv"
2368df9185cSdrh} {0 {}}
2378df9185cSdrhdo_test shell1-2.4.2 {
2388df9185cSdrh  catchcmd "test.db" ".mode \"csv\""
2398df9185cSdrh} {0 {}}
2408df9185cSdrh
2418df9185cSdrh
2428df9185cSdrh#----------------------------------------------------------------------------
2438df9185cSdrh# Test cases shell1-3.*: Basic test that "dot" command can be called.
2448df9185cSdrh#
2458df9185cSdrh
2468df9185cSdrh# .backup ?DB? FILE      Backup DB (default "main") to FILE
2478df9185cSdrhdo_test shell1-3.1.1 {
2488df9185cSdrh  catchcmd "test.db" ".backup"
249bc46f02cSdrh} {1 {missing FILENAME argument on .backup}}
2508df9185cSdrhdo_test shell1-3.1.2 {
2518df9185cSdrh  catchcmd "test.db" ".backup FOO"
2528df9185cSdrh} {0 {}}
2538df9185cSdrhdo_test shell1-3.1.3 {
2548df9185cSdrh  catchcmd "test.db" ".backup FOO BAR"
2558df9185cSdrh} {1 {Error: unknown database FOO}}
2568df9185cSdrhdo_test shell1-3.1.4 {
2578df9185cSdrh  # too many arguments
2588df9185cSdrh  catchcmd "test.db" ".backup FOO BAR BAD"
259bc46f02cSdrh} {1 {too many arguments to .backup}}
2608df9185cSdrh
2618df9185cSdrh# .bail ON|OFF           Stop after hitting an error.  Default OFF
2628df9185cSdrhdo_test shell1-3.2.1 {
2638df9185cSdrh  catchcmd "test.db" ".bail"
264c2ce0beaSdrh} {1 {Usage: .bail on|off}}
2658df9185cSdrhdo_test shell1-3.2.2 {
2668df9185cSdrh  catchcmd "test.db" ".bail ON"
2678df9185cSdrh} {0 {}}
2688df9185cSdrhdo_test shell1-3.2.3 {
2698df9185cSdrh  catchcmd "test.db" ".bail OFF"
2708df9185cSdrh} {0 {}}
2718df9185cSdrhdo_test shell1-3.2.4 {
2728df9185cSdrh  # too many arguments
2738df9185cSdrh  catchcmd "test.db" ".bail OFF BAD"
274c2ce0beaSdrh} {1 {Usage: .bail on|off}}
2758df9185cSdrh
2768df9185cSdrh# .databases             List names and files of attached databases
2778df9185cSdrhdo_test shell1-3.3.1 {
278eaa544d4Sdrh  catchcmd "-csv test.db" ".databases"
27915707ac9Sdrh} "/0.+main.+[string map {/ ".{1,2}"} [string range [get_pwd] 0 10]].*/"
2808df9185cSdrhdo_test shell1-3.3.2 {
281c2ce0beaSdrh  # extra arguments ignored
282eaa544d4Sdrh  catchcmd "test.db" ".databases BAD"
28315707ac9Sdrh} "/0.+main.+[string map {/ ".{1,2}"} [string range [get_pwd] 0 10]].*/"
2848df9185cSdrh
2858df9185cSdrh# .dump ?TABLE? ...      Dump the database in an SQL text format
2868df9185cSdrh#                          If TABLE specified, only dump tables matching
2878df9185cSdrh#                          LIKE pattern TABLE.
2888df9185cSdrhdo_test shell1-3.4.1 {
2898df9185cSdrh  set res [catchcmd "test.db" ".dump"]
2908df9185cSdrh  list [regexp {BEGIN TRANSACTION;} $res] \
2918df9185cSdrh       [regexp {COMMIT;} $res]
2928df9185cSdrh} {1 1}
2938df9185cSdrhdo_test shell1-3.4.2 {
2948df9185cSdrh  set res [catchcmd "test.db" ".dump FOO"]
2958df9185cSdrh  list [regexp {BEGIN TRANSACTION;} $res] \
2968df9185cSdrh       [regexp {COMMIT;} $res]
2978df9185cSdrh} {1 1}
2988df9185cSdrhdo_test shell1-3.4.3 {
2998df9185cSdrh  # too many arguments
3008df9185cSdrh  catchcmd "test.db" ".dump FOO BAD"
301c2ce0beaSdrh} {1 {Usage: .dump ?LIKE-PATTERN?}}
3028df9185cSdrh
3038df9185cSdrh# .echo ON|OFF           Turn command echo on or off
3048df9185cSdrhdo_test shell1-3.5.1 {
3058df9185cSdrh  catchcmd "test.db" ".echo"
306c2ce0beaSdrh} {1 {Usage: .echo on|off}}
3078df9185cSdrhdo_test shell1-3.5.2 {
3088df9185cSdrh  catchcmd "test.db" ".echo ON"
3098df9185cSdrh} {0 {}}
3108df9185cSdrhdo_test shell1-3.5.3 {
3118df9185cSdrh  catchcmd "test.db" ".echo OFF"
3128df9185cSdrh} {0 {}}
3138df9185cSdrhdo_test shell1-3.5.4 {
3148df9185cSdrh  # too many arguments
3158df9185cSdrh  catchcmd "test.db" ".echo OFF BAD"
316c2ce0beaSdrh} {1 {Usage: .echo on|off}}
3178df9185cSdrh
3188df9185cSdrh# .exit                  Exit this program
3198df9185cSdrhdo_test shell1-3.6.1 {
3208df9185cSdrh  catchcmd "test.db" ".exit"
3218df9185cSdrh} {0 {}}
3228df9185cSdrh
3238df9185cSdrh# .explain ON|OFF        Turn output mode suitable for EXPLAIN on or off.
3248df9185cSdrhdo_test shell1-3.7.1 {
3258df9185cSdrh  catchcmd "test.db" ".explain"
3268df9185cSdrh  # explain is the exception to the booleans.  without an option, it turns it on.
3278df9185cSdrh} {0 {}}
3288df9185cSdrhdo_test shell1-3.7.2 {
3298df9185cSdrh  catchcmd "test.db" ".explain ON"
3308df9185cSdrh} {0 {}}
3318df9185cSdrhdo_test shell1-3.7.3 {
3328df9185cSdrh  catchcmd "test.db" ".explain OFF"
3338df9185cSdrh} {0 {}}
3348df9185cSdrhdo_test shell1-3.7.4 {
335c2ce0beaSdrh  # extra arguments ignored
3368df9185cSdrh  catchcmd "test.db" ".explain OFF BAD"
337c2ce0beaSdrh} {0 {}}
3388df9185cSdrh
3398df9185cSdrh
3408df9185cSdrh# .header(s) ON|OFF      Turn display of headers on or off
3418df9185cSdrhdo_test shell1-3.9.1 {
3428df9185cSdrh  catchcmd "test.db" ".header"
343c2ce0beaSdrh} {1 {Usage: .headers on|off}}
3448df9185cSdrhdo_test shell1-3.9.2 {
3458df9185cSdrh  catchcmd "test.db" ".header ON"
3468df9185cSdrh} {0 {}}
3478df9185cSdrhdo_test shell1-3.9.3 {
3488df9185cSdrh  catchcmd "test.db" ".header OFF"
3498df9185cSdrh} {0 {}}
3508df9185cSdrhdo_test shell1-3.9.4 {
3518df9185cSdrh  # too many arguments
3528df9185cSdrh  catchcmd "test.db" ".header OFF BAD"
353c2ce0beaSdrh} {1 {Usage: .headers on|off}}
3548df9185cSdrh
3558df9185cSdrhdo_test shell1-3.9.5 {
3568df9185cSdrh  catchcmd "test.db" ".headers"
357c2ce0beaSdrh} {1 {Usage: .headers on|off}}
3588df9185cSdrhdo_test shell1-3.9.6 {
3598df9185cSdrh  catchcmd "test.db" ".headers ON"
3608df9185cSdrh} {0 {}}
3618df9185cSdrhdo_test shell1-3.9.7 {
3628df9185cSdrh  catchcmd "test.db" ".headers OFF"
3638df9185cSdrh} {0 {}}
3648df9185cSdrhdo_test shell1-3.9.8 {
3658df9185cSdrh  # too many arguments
3668df9185cSdrh  catchcmd "test.db" ".headers OFF BAD"
367c2ce0beaSdrh} {1 {Usage: .headers on|off}}
3688df9185cSdrh
3698df9185cSdrh# .help                  Show this message
3708df9185cSdrhdo_test shell1-3.10.1 {
3718df9185cSdrh  set res [catchcmd "test.db" ".help"]
3728df9185cSdrh  # look for a few of the possible help commands
3738df9185cSdrh  list [regexp {.help} $res] \
3748df9185cSdrh       [regexp {.quit} $res] \
3758df9185cSdrh       [regexp {.show} $res]
3768df9185cSdrh} {1 1 1}
3778df9185cSdrhdo_test shell1-3.10.2 {
3788df9185cSdrh  # we allow .help to take extra args (it is help after all)
3798df9185cSdrh  set res [catchcmd "test.db" ".help BAD"]
3808df9185cSdrh  # look for a few of the possible help commands
3818df9185cSdrh  list [regexp {.help} $res] \
3828df9185cSdrh       [regexp {.quit} $res] \
3838df9185cSdrh       [regexp {.show} $res]
3848df9185cSdrh} {1 1 1}
3858df9185cSdrh
3868df9185cSdrh# .import FILE TABLE     Import data from FILE into TABLE
3878df9185cSdrhdo_test shell1-3.11.1 {
3888df9185cSdrh  catchcmd "test.db" ".import"
389c2ce0beaSdrh} {1 {Usage: .import FILE TABLE}}
3908df9185cSdrhdo_test shell1-3.11.2 {
3918df9185cSdrh  catchcmd "test.db" ".import FOO"
392c2ce0beaSdrh} {1 {Usage: .import FILE TABLE}}
393db95f68bSdrh#do_test shell1-3.11.2 {
394db95f68bSdrh#  catchcmd "test.db" ".import FOO BAR"
395db95f68bSdrh#} {1 {Error: no such table: BAR}}
3968df9185cSdrhdo_test shell1-3.11.3 {
3978df9185cSdrh  # too many arguments
3988df9185cSdrh  catchcmd "test.db" ".import FOO BAR BAD"
399c2ce0beaSdrh} {1 {Usage: .import FILE TABLE}}
4008df9185cSdrh
4010e55db1cSdrh# .indexes ?TABLE?       Show names of all indexes
4020e55db1cSdrh#                          If TABLE specified, only show indexes for tables
4038df9185cSdrh#                          matching LIKE pattern TABLE.
4048df9185cSdrhdo_test shell1-3.12.1 {
4050e55db1cSdrh  catchcmd "test.db" ".indexes"
4068df9185cSdrh} {0 {}}
4078df9185cSdrhdo_test shell1-3.12.2 {
4080e55db1cSdrh  catchcmd "test.db" ".indexes FOO"
4090e55db1cSdrh} {0 {}}
4100e55db1cSdrhdo_test shell1-3.12.2-legacy {
4118df9185cSdrh  catchcmd "test.db" ".indices FOO"
4128df9185cSdrh} {0 {}}
4138df9185cSdrhdo_test shell1-3.12.3 {
4148df9185cSdrh  # too many arguments
4150e55db1cSdrh  catchcmd "test.db" ".indexes FOO BAD"
4160e55db1cSdrh} {1 {Usage: .indexes ?LIKE-PATTERN?}}
4178df9185cSdrh
4188df9185cSdrh# .mode MODE ?TABLE?     Set output mode where MODE is one of:
419e0d6885fSmistachkin#                          ascii    Columns/rows delimited by 0x1F and 0x1E
4208df9185cSdrh#                          csv      Comma-separated values
4218df9185cSdrh#                          column   Left-aligned columns.  (See .width)
4228df9185cSdrh#                          html     HTML <table> code
4238df9185cSdrh#                          insert   SQL insert statements for TABLE
4248df9185cSdrh#                          line     One value per line
425e0d6885fSmistachkin#                          list     Values delimited by .separator strings
4268df9185cSdrh#                          tabs     Tab-separated values
4278df9185cSdrh#                          tcl      TCL list elements
4288df9185cSdrhdo_test shell1-3.13.1 {
4298df9185cSdrh  catchcmd "test.db" ".mode"
430636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}}
4318df9185cSdrhdo_test shell1-3.13.2 {
4328df9185cSdrh  catchcmd "test.db" ".mode FOO"
433636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}}
4348df9185cSdrhdo_test shell1-3.13.3 {
4358df9185cSdrh  catchcmd "test.db" ".mode csv"
4368df9185cSdrh} {0 {}}
4378df9185cSdrhdo_test shell1-3.13.4 {
4388df9185cSdrh  catchcmd "test.db" ".mode column"
4398df9185cSdrh} {0 {}}
4408df9185cSdrhdo_test shell1-3.13.5 {
4418df9185cSdrh  catchcmd "test.db" ".mode html"
4428df9185cSdrh} {0 {}}
4438df9185cSdrhdo_test shell1-3.13.6 {
4448df9185cSdrh  catchcmd "test.db" ".mode insert"
4458df9185cSdrh} {0 {}}
4468df9185cSdrhdo_test shell1-3.13.7 {
4478df9185cSdrh  catchcmd "test.db" ".mode line"
4488df9185cSdrh} {0 {}}
4498df9185cSdrhdo_test shell1-3.13.8 {
4508df9185cSdrh  catchcmd "test.db" ".mode list"
4518df9185cSdrh} {0 {}}
4528df9185cSdrhdo_test shell1-3.13.9 {
4538df9185cSdrh  catchcmd "test.db" ".mode tabs"
4548df9185cSdrh} {0 {}}
4558df9185cSdrhdo_test shell1-3.13.10 {
4568df9185cSdrh  catchcmd "test.db" ".mode tcl"
4578df9185cSdrh} {0 {}}
4588df9185cSdrhdo_test shell1-3.13.11 {
459c2ce0beaSdrh  # extra arguments ignored
4608df9185cSdrh  catchcmd "test.db" ".mode tcl BAD"
461c2ce0beaSdrh} {0 {}}
4628df9185cSdrh
4638df9185cSdrh# don't allow partial mode type matches
4648df9185cSdrhdo_test shell1-3.13.12 {
4658df9185cSdrh  catchcmd "test.db" ".mode l"
466636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}}
4678df9185cSdrhdo_test shell1-3.13.13 {
4688df9185cSdrh  catchcmd "test.db" ".mode li"
469636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}}
4708df9185cSdrhdo_test shell1-3.13.14 {
4718df9185cSdrh  catchcmd "test.db" ".mode lin"
472c2ce0beaSdrh} {0 {}}
4738df9185cSdrh
4748df9185cSdrh# .nullvalue STRING      Print STRING in place of NULL values
4758df9185cSdrhdo_test shell1-3.14.1 {
4768df9185cSdrh  catchcmd "test.db" ".nullvalue"
477c2ce0beaSdrh} {1 {Usage: .nullvalue STRING}}
4788df9185cSdrhdo_test shell1-3.14.2 {
4798df9185cSdrh  catchcmd "test.db" ".nullvalue FOO"
4808df9185cSdrh} {0 {}}
4818df9185cSdrhdo_test shell1-3.14.3 {
4828df9185cSdrh  # too many arguments
4838df9185cSdrh  catchcmd "test.db" ".nullvalue FOO BAD"
484c2ce0beaSdrh} {1 {Usage: .nullvalue STRING}}
4858df9185cSdrh
4868df9185cSdrh# .output FILENAME       Send output to FILENAME
4878df9185cSdrhdo_test shell1-3.15.1 {
4888df9185cSdrh  catchcmd "test.db" ".output"
489c2ce0beaSdrh} {0 {}}
4908df9185cSdrhdo_test shell1-3.15.2 {
4918df9185cSdrh  catchcmd "test.db" ".output FOO"
4928df9185cSdrh} {0 {}}
4938df9185cSdrhdo_test shell1-3.15.3 {
4948df9185cSdrh  # too many arguments
4958df9185cSdrh  catchcmd "test.db" ".output FOO BAD"
496c2ce0beaSdrh} {1 {Usage: .output FILE}}
4978df9185cSdrh
4988df9185cSdrh# .output stdout         Send output to the screen
4998df9185cSdrhdo_test shell1-3.16.1 {
5008df9185cSdrh  catchcmd "test.db" ".output stdout"
5018df9185cSdrh} {0 {}}
5028df9185cSdrhdo_test shell1-3.16.2 {
5038df9185cSdrh  # too many arguments
5048df9185cSdrh  catchcmd "test.db" ".output stdout BAD"
505c2ce0beaSdrh} {1 {Usage: .output FILE}}
5068df9185cSdrh
5078df9185cSdrh# .prompt MAIN CONTINUE  Replace the standard prompts
5088df9185cSdrhdo_test shell1-3.17.1 {
5098df9185cSdrh  catchcmd "test.db" ".prompt"
510c2ce0beaSdrh} {0 {}}
5118df9185cSdrhdo_test shell1-3.17.2 {
5128df9185cSdrh  catchcmd "test.db" ".prompt FOO"
5138df9185cSdrh} {0 {}}
5148df9185cSdrhdo_test shell1-3.17.3 {
5158df9185cSdrh  catchcmd "test.db" ".prompt FOO BAR"
5168df9185cSdrh} {0 {}}
5178df9185cSdrhdo_test shell1-3.17.4 {
5188df9185cSdrh  # too many arguments
5198df9185cSdrh  catchcmd "test.db" ".prompt FOO BAR BAD"
520c2ce0beaSdrh} {0 {}}
5218df9185cSdrh
5228df9185cSdrh# .quit                  Exit this program
5238df9185cSdrhdo_test shell1-3.18.1 {
5248df9185cSdrh  catchcmd "test.db" ".quit"
5258df9185cSdrh} {0 {}}
5268df9185cSdrhdo_test shell1-3.18.2 {
5278df9185cSdrh  # too many arguments
5288df9185cSdrh  catchcmd "test.db" ".quit BAD"
529c2ce0beaSdrh} {0 {}}
5308df9185cSdrh
5318df9185cSdrh# .read FILENAME         Execute SQL in FILENAME
5328df9185cSdrhdo_test shell1-3.19.1 {
5338df9185cSdrh  catchcmd "test.db" ".read"
534c2ce0beaSdrh} {1 {Usage: .read FILE}}
5358df9185cSdrhdo_test shell1-3.19.2 {
5369ac99313Smistachkin  forcedelete FOO
5378df9185cSdrh  catchcmd "test.db" ".read FOO"
5388df9185cSdrh} {1 {Error: cannot open "FOO"}}
5398df9185cSdrhdo_test shell1-3.19.3 {
5408df9185cSdrh  # too many arguments
5418df9185cSdrh  catchcmd "test.db" ".read FOO BAD"
542c2ce0beaSdrh} {1 {Usage: .read FILE}}
5438df9185cSdrh
5448df9185cSdrh# .restore ?DB? FILE     Restore content of DB (default "main") from FILE
5458df9185cSdrhdo_test shell1-3.20.1 {
5468df9185cSdrh  catchcmd "test.db" ".restore"
547c2ce0beaSdrh} {1 {Usage: .restore ?DB? FILE}}
5488df9185cSdrhdo_test shell1-3.20.2 {
5498df9185cSdrh  catchcmd "test.db" ".restore FOO"
5508df9185cSdrh} {0 {}}
5518df9185cSdrhdo_test shell1-3.20.3 {
5528df9185cSdrh  catchcmd "test.db" ".restore FOO BAR"
5538df9185cSdrh} {1 {Error: unknown database FOO}}
5548df9185cSdrhdo_test shell1-3.20.4 {
5558df9185cSdrh  # too many arguments
5568df9185cSdrh  catchcmd "test.db" ".restore FOO BAR BAD"
557c2ce0beaSdrh} {1 {Usage: .restore ?DB? FILE}}
5588df9185cSdrh
5598df9185cSdrh# .schema ?TABLE?        Show the CREATE statements
5608df9185cSdrh#                          If TABLE specified, only show tables matching
5618df9185cSdrh#                          LIKE pattern TABLE.
5628df9185cSdrhdo_test shell1-3.21.1 {
5638df9185cSdrh  catchcmd "test.db" ".schema"
5648df9185cSdrh} {0 {}}
5658df9185cSdrhdo_test shell1-3.21.2 {
5668df9185cSdrh  catchcmd "test.db" ".schema FOO"
5678df9185cSdrh} {0 {}}
5688df9185cSdrhdo_test shell1-3.21.3 {
5698df9185cSdrh  # too many arguments
5708df9185cSdrh  catchcmd "test.db" ".schema FOO BAD"
5714926fec9Sdrh} {1 {Usage: .schema ?--indent? ?LIKE-PATTERN?}}
5728df9185cSdrh
573ac43e98dSdrhdo_test shell1-3.21.4 {
574ac43e98dSdrh  catchcmd "test.db" {
575ac43e98dSdrh     CREATE TABLE t1(x);
576ac43e98dSdrh     CREATE VIEW v2 AS SELECT x+1 AS y FROM t1;
577ac43e98dSdrh     CREATE VIEW v1 AS SELECT y+1 FROM v2;
578ac43e98dSdrh  }
579ac43e98dSdrh  catchcmd "test.db" ".schema"
580ac43e98dSdrh} {0 {CREATE TABLE t1(x);
581ac43e98dSdrhCREATE VIEW v2 AS SELECT x+1 AS y FROM t1;
582ac43e98dSdrhCREATE VIEW v1 AS SELECT y+1 FROM v2;}}
583ac43e98dSdrhdb eval {DROP VIEW v1; DROP VIEW v2; DROP TABLE t1;}
584ac43e98dSdrh
585636bf9f7Smistachkin# .separator STRING  Change column separator used by output and .import
5868df9185cSdrhdo_test shell1-3.22.1 {
5878df9185cSdrh  catchcmd "test.db" ".separator"
588e0d6885fSmistachkin} {1 {Usage: .separator COL ?ROW?}}
5898df9185cSdrhdo_test shell1-3.22.2 {
5908df9185cSdrh  catchcmd "test.db" ".separator FOO"
5918df9185cSdrh} {0 {}}
5928df9185cSdrhdo_test shell1-3.22.3 {
5936976c212Sdrh  catchcmd "test.db" ".separator ABC XYZ"
5946976c212Sdrh} {0 {}}
5956976c212Sdrhdo_test shell1-3.22.4 {
5968df9185cSdrh  # too many arguments
5976976c212Sdrh  catchcmd "test.db" ".separator FOO BAD BAD2"
598e0d6885fSmistachkin} {1 {Usage: .separator COL ?ROW?}}
5998df9185cSdrh
6008df9185cSdrh# .show                  Show the current values for various settings
6018df9185cSdrhdo_test shell1-3.23.1 {
6028df9185cSdrh  set res [catchcmd "test.db" ".show"]
6038df9185cSdrh  list [regexp {echo:} $res] \
6048df9185cSdrh       [regexp {explain:} $res] \
6058df9185cSdrh       [regexp {headers:} $res] \
6068df9185cSdrh       [regexp {mode:} $res] \
6078df9185cSdrh       [regexp {nullvalue:} $res] \
6088df9185cSdrh       [regexp {output:} $res] \
609636bf9f7Smistachkin       [regexp {colseparator:} $res] \
610636bf9f7Smistachkin       [regexp {rowseparator:} $res] \
6118df9185cSdrh       [regexp {stats:} $res] \
6128df9185cSdrh       [regexp {width:} $res]
613e0d6885fSmistachkin} {1 1 1 1 1 1 1 1 1 1}
6148df9185cSdrhdo_test shell1-3.23.2 {
6158df9185cSdrh  # too many arguments
6168df9185cSdrh  catchcmd "test.db" ".show BAD"
617c2ce0beaSdrh} {1 {Usage: .show}}
6188df9185cSdrh
6198df9185cSdrh# .stats ON|OFF          Turn stats on or off
62034784903Sdrh#do_test shell1-3.23b.1 {
62134784903Sdrh#  catchcmd "test.db" ".stats"
62234784903Sdrh#} {1 {Usage: .stats on|off}}
6238df9185cSdrhdo_test shell1-3.23b.2 {
6248df9185cSdrh  catchcmd "test.db" ".stats ON"
6258df9185cSdrh} {0 {}}
6268df9185cSdrhdo_test shell1-3.23b.3 {
6278df9185cSdrh  catchcmd "test.db" ".stats OFF"
6288df9185cSdrh} {0 {}}
6298df9185cSdrhdo_test shell1-3.23b.4 {
6308df9185cSdrh  # too many arguments
6318df9185cSdrh  catchcmd "test.db" ".stats OFF BAD"
63234784903Sdrh} {1 {Usage: .stats ?on|off?}}
6338df9185cSdrh
6348df9185cSdrh# .tables ?TABLE?        List names of tables
6358df9185cSdrh#                          If TABLE specified, only list tables matching
6368df9185cSdrh#                          LIKE pattern TABLE.
6378df9185cSdrhdo_test shell1-3.24.1 {
6388df9185cSdrh  catchcmd "test.db" ".tables"
6398df9185cSdrh} {0 {}}
6408df9185cSdrhdo_test shell1-3.24.2 {
6418df9185cSdrh  catchcmd "test.db" ".tables FOO"
6428df9185cSdrh} {0 {}}
6438df9185cSdrhdo_test shell1-3.24.3 {
6448df9185cSdrh  # too many arguments
6458df9185cSdrh  catchcmd "test.db" ".tables FOO BAD"
646c2ce0beaSdrh} {0 {}}
6478df9185cSdrh
6488df9185cSdrh# .timeout MS            Try opening locked tables for MS milliseconds
6498df9185cSdrhdo_test shell1-3.25.1 {
6508df9185cSdrh  catchcmd "test.db" ".timeout"
651c2ce0beaSdrh} {0 {}}
6528df9185cSdrhdo_test shell1-3.25.2 {
6538df9185cSdrh  catchcmd "test.db" ".timeout zzz"
6548df9185cSdrh  # this should be treated the same as a '0' timeout
6558df9185cSdrh} {0 {}}
6568df9185cSdrhdo_test shell1-3.25.3 {
6578df9185cSdrh  catchcmd "test.db" ".timeout 1"
6588df9185cSdrh} {0 {}}
6598df9185cSdrhdo_test shell1-3.25.4 {
6608df9185cSdrh  # too many arguments
6618df9185cSdrh  catchcmd "test.db" ".timeout 1 BAD"
662c2ce0beaSdrh} {0 {}}
6638df9185cSdrh
6648df9185cSdrh# .width NUM NUM ...     Set column widths for "column" mode
6658df9185cSdrhdo_test shell1-3.26.1 {
6668df9185cSdrh  catchcmd "test.db" ".width"
667c2ce0beaSdrh} {0 {}}
6688df9185cSdrhdo_test shell1-3.26.2 {
6698df9185cSdrh  catchcmd "test.db" ".width xxx"
6708df9185cSdrh  # this should be treated the same as a '0' width for col 1
6718df9185cSdrh} {0 {}}
6728df9185cSdrhdo_test shell1-3.26.3 {
6738df9185cSdrh  catchcmd "test.db" ".width xxx yyy"
6748df9185cSdrh  # this should be treated the same as a '0' width for col 1 and 2
6758df9185cSdrh} {0 {}}
6768df9185cSdrhdo_test shell1-3.26.4 {
6778df9185cSdrh  catchcmd "test.db" ".width 1 1"
6788df9185cSdrh  # this should be treated the same as a '1' width for col 1 and 2
6798df9185cSdrh} {0 {}}
680078b1fdaSdrhdo_test shell1-3.26.5 {
681078b1fdaSdrh  catchcmd "test.db" ".mode column\n.width 10 -10\nSELECT 'abcdefg', 123456;"
682078b1fdaSdrh  # this should be treated the same as a '1' width for col 1 and 2
683078b1fdaSdrh} {0 {abcdefg         123456}}
684078b1fdaSdrhdo_test shell1-3.26.6 {
685078b1fdaSdrh  catchcmd "test.db" ".mode column\n.width -10 10\nSELECT 'abcdefg', 123456;"
686078b1fdaSdrh  # this should be treated the same as a '1' width for col 1 and 2
687078b1fdaSdrh} {0 {   abcdefg  123456    }}
688078b1fdaSdrh
6898df9185cSdrh
6908df9185cSdrh# .timer ON|OFF          Turn the CPU timer measurement on or off
6918df9185cSdrhdo_test shell1-3.27.1 {
6928df9185cSdrh  catchcmd "test.db" ".timer"
693c2ce0beaSdrh} {1 {Usage: .timer on|off}}
6948df9185cSdrhdo_test shell1-3.27.2 {
6958df9185cSdrh  catchcmd "test.db" ".timer ON"
6968df9185cSdrh} {0 {}}
6978df9185cSdrhdo_test shell1-3.27.3 {
6988df9185cSdrh  catchcmd "test.db" ".timer OFF"
6998df9185cSdrh} {0 {}}
7008df9185cSdrhdo_test shell1-3.27.4 {
7018df9185cSdrh  # too many arguments
7028df9185cSdrh  catchcmd "test.db" ".timer OFF BAD"
703c2ce0beaSdrh} {1 {Usage: .timer on|off}}
7048df9185cSdrh
7058df9185cSdrhdo_test shell1-3-28.1 {
7068df9185cSdrh  catchcmd test.db \
7078df9185cSdrh     ".log stdout\nSELECT coalesce(sqlite_log(123,'hello'),'456');"
7088df9185cSdrh} "0 {(123) hello\n456}"
7098df9185cSdrh
710078b1fdaSdrhdo_test shell1-3-29.1 {
711078b1fdaSdrh  catchcmd "test.db" ".print this is a test"
712078b1fdaSdrh} {0 {this is a test}}
713078b1fdaSdrh
7144c56b99fSdrh# dot-command argument quoting
7154c56b99fSdrhdo_test shell1-3-30.1 {
7164c56b99fSdrh  catchcmd {test.db} {.print "this\"is'a\055test" 'this\"is\\a\055test'}
7174c56b99fSdrh} {0 {this"is'a-test this\"is\\a\055test}}
7184c56b99fSdrhdo_test shell1-3-31.1 {
7194c56b99fSdrh  catchcmd {test.db} {.print "this\nis\ta\\test" 'this\nis\ta\\test'}
7204c56b99fSdrh} [list 0 "this\nis\ta\\test this\\nis\\ta\\\\test"]
7214c56b99fSdrh
7224c56b99fSdrh
7235128e85cSdrh# Test the output of the ".dump" command
7245128e85cSdrh#
7255128e85cSdrhdo_test shell1-4.1 {
72655a1b308Sdrh  db close
72755a1b308Sdrh  forcedelete test.db
72855a1b308Sdrh  sqlite3 db test.db
7295128e85cSdrh  db eval {
73055a1b308Sdrh    PRAGMA encoding=UTF16;
7315128e85cSdrh    CREATE TABLE t1(x);
732585dcb25Smistachkin    INSERT INTO t1 VALUES(null), (''), (1), (2.25), ('hello'), (x'807f');
733151c75adSmistachkin    CREATE TABLE t3(x,y);
734151c75adSmistachkin    INSERT INTO t3 VALUES(1,null), (2,''), (3,1),
735151c75adSmistachkin                         (4,2.25), (5,'hello'), (6,x'807f');
7365128e85cSdrh  }
7375128e85cSdrh  catchcmd test.db {.dump}
7385128e85cSdrh} {0 {PRAGMA foreign_keys=OFF;
7395128e85cSdrhBEGIN TRANSACTION;
7405128e85cSdrhCREATE TABLE t1(x);
7415128e85cSdrhINSERT INTO "t1" VALUES(NULL);
742585dcb25SmistachkinINSERT INTO "t1" VALUES('');
7435128e85cSdrhINSERT INTO "t1" VALUES(1);
7445128e85cSdrhINSERT INTO "t1" VALUES(2.25);
7455128e85cSdrhINSERT INTO "t1" VALUES('hello');
7465128e85cSdrhINSERT INTO "t1" VALUES(X'807F');
747151c75adSmistachkinCREATE TABLE t3(x,y);
748151c75adSmistachkinINSERT INTO "t3" VALUES(1,NULL);
749151c75adSmistachkinINSERT INTO "t3" VALUES(2,'');
750151c75adSmistachkinINSERT INTO "t3" VALUES(3,1);
751151c75adSmistachkinINSERT INTO "t3" VALUES(4,2.25);
752151c75adSmistachkinINSERT INTO "t3" VALUES(5,'hello');
753151c75adSmistachkinINSERT INTO "t3" VALUES(6,X'807F');
7545128e85cSdrhCOMMIT;}}
7555128e85cSdrh
7565128e85cSdrh# Test the output of ".mode insert"
7575128e85cSdrh#
758151c75adSmistachkindo_test shell1-4.2.1 {
7595128e85cSdrh  catchcmd test.db ".mode insert t1\nselect * from t1;"
7605128e85cSdrh} {0 {INSERT INTO t1 VALUES(NULL);
761585dcb25SmistachkinINSERT INTO t1 VALUES('');
7625128e85cSdrhINSERT INTO t1 VALUES(1);
7635128e85cSdrhINSERT INTO t1 VALUES(2.25);
7645128e85cSdrhINSERT INTO t1 VALUES('hello');
7655128e85cSdrhINSERT INTO t1 VALUES(X'807f');}}
7665128e85cSdrh
767151c75adSmistachkin# Test the output of ".mode insert" with headers
768151c75adSmistachkin#
769151c75adSmistachkindo_test shell1-4.2.2 {
770151c75adSmistachkin  catchcmd test.db ".mode insert t1\n.headers on\nselect * from t1;"
771151c75adSmistachkin} {0 {INSERT INTO t1(x) VALUES(NULL);
772151c75adSmistachkinINSERT INTO t1(x) VALUES('');
773151c75adSmistachkinINSERT INTO t1(x) VALUES(1);
774151c75adSmistachkinINSERT INTO t1(x) VALUES(2.25);
775151c75adSmistachkinINSERT INTO t1(x) VALUES('hello');
776151c75adSmistachkinINSERT INTO t1(x) VALUES(X'807f');}}
777151c75adSmistachkin
778151c75adSmistachkin# Test the output of ".mode insert"
779151c75adSmistachkin#
780151c75adSmistachkindo_test shell1-4.2.3 {
781151c75adSmistachkin  catchcmd test.db ".mode insert t3\nselect * from t3;"
782151c75adSmistachkin} {0 {INSERT INTO t3 VALUES(1,NULL);
783151c75adSmistachkinINSERT INTO t3 VALUES(2,'');
784151c75adSmistachkinINSERT INTO t3 VALUES(3,1);
785151c75adSmistachkinINSERT INTO t3 VALUES(4,2.25);
786151c75adSmistachkinINSERT INTO t3 VALUES(5,'hello');
787151c75adSmistachkinINSERT INTO t3 VALUES(6,X'807f');}}
788151c75adSmistachkin
789151c75adSmistachkin# Test the output of ".mode insert" with headers
790151c75adSmistachkin#
791cc445402Smistachkindo_test shell1-4.2.4 {
792151c75adSmistachkin  catchcmd test.db ".mode insert t3\n.headers on\nselect * from t3;"
793151c75adSmistachkin} {0 {INSERT INTO t3(x,y) VALUES(1,NULL);
794151c75adSmistachkinINSERT INTO t3(x,y) VALUES(2,'');
795151c75adSmistachkinINSERT INTO t3(x,y) VALUES(3,1);
796151c75adSmistachkinINSERT INTO t3(x,y) VALUES(4,2.25);
797151c75adSmistachkinINSERT INTO t3(x,y) VALUES(5,'hello');
798151c75adSmistachkinINSERT INTO t3(x,y) VALUES(6,X'807f');}}
799151c75adSmistachkin
800585dcb25Smistachkin# Test the output of ".mode tcl"
801585dcb25Smistachkin#
802585dcb25Smistachkindo_test shell1-4.3 {
80355a1b308Sdrh  db close
80455a1b308Sdrh  forcedelete test.db
80555a1b308Sdrh  sqlite3 db test.db
80655a1b308Sdrh  db eval {
80755a1b308Sdrh    PRAGMA encoding=UTF8;
80855a1b308Sdrh    CREATE TABLE t1(x);
80955a1b308Sdrh    INSERT INTO t1 VALUES(null), (''), (1), (2.25), ('hello'), (x'807f');
81055a1b308Sdrh  }
811585dcb25Smistachkin  catchcmd test.db ".mode tcl\nselect * from t1;"
812585dcb25Smistachkin} {0 {""
813585dcb25Smistachkin""
814585dcb25Smistachkin"1"
815585dcb25Smistachkin"2.25"
816585dcb25Smistachkin"hello"
817585dcb25Smistachkin"\200\177"}}
818585dcb25Smistachkin
819585dcb25Smistachkin# Test the output of ".mode tcl" with multiple columns
820585dcb25Smistachkin#
821585dcb25Smistachkindo_test shell1-4.4 {
822585dcb25Smistachkin  db eval {
823585dcb25Smistachkin    CREATE TABLE t2(x,y);
824585dcb25Smistachkin    INSERT INTO t2 VALUES(null, ''), (1, 2.25), ('hello', x'807f');
825585dcb25Smistachkin  }
826585dcb25Smistachkin  catchcmd test.db ".mode tcl\nselect * from t2;"
827585dcb25Smistachkin} {0 {"" ""
828585dcb25Smistachkin"1" "2.25"
829585dcb25Smistachkin"hello" "\200\177"}}
830585dcb25Smistachkin
831585dcb25Smistachkin# Test the output of ".mode tcl" with ".nullvalue"
832585dcb25Smistachkin#
833585dcb25Smistachkindo_test shell1-4.5 {
834585dcb25Smistachkin  catchcmd test.db ".mode tcl\n.nullvalue NULL\nselect * from t2;"
835585dcb25Smistachkin} {0 {"NULL" ""
836585dcb25Smistachkin"1" "2.25"
837585dcb25Smistachkin"hello" "\200\177"}}
838585dcb25Smistachkin
839585dcb25Smistachkin# Test the output of ".mode tcl" with Tcl reserved characters
840585dcb25Smistachkin#
841585dcb25Smistachkindo_test shell1-4.6 {
842585dcb25Smistachkin  db eval {
843585dcb25Smistachkin    CREATE TABLE tcl1(x);
844585dcb25Smistachkin    INSERT INTO tcl1 VALUES('"'), ('['), (']'), ('\{'), ('\}'), (';'), ('$');
845585dcb25Smistachkin  }
846585dcb25Smistachkin  foreach {x y} [catchcmd test.db ".mode tcl\nselect * from tcl1;"] break
847585dcb25Smistachkin  list $x $y [llength $y]
848585dcb25Smistachkin} {0 {"\""
849585dcb25Smistachkin"["
850585dcb25Smistachkin"]"
851585dcb25Smistachkin"\\{"
852585dcb25Smistachkin"\\}"
853585dcb25Smistachkin";"
854585dcb25Smistachkin"$"} 7}
8555128e85cSdrh
856f21979dfSmistachkin# Test using arbitrary byte data with the shell via standard input/output.
857f21979dfSmistachkin#
858f21979dfSmistachkindo_test shell1-5.0 {
859f21979dfSmistachkin  #
860f21979dfSmistachkin  # NOTE: Skip NUL byte because it appears to be incompatible with command
861f21979dfSmistachkin  #       shell argument parsing.
862f21979dfSmistachkin  #
863f21979dfSmistachkin  for {set i 1} {$i < 256} {incr i} {
864f21979dfSmistachkin    #
86546a6b994Smistachkin    # NOTE: Due to how the Tcl [exec] command works (i.e. where it treats
86646a6b994Smistachkin    #       command channels opened for it as textual ones), the carriage
86746a6b994Smistachkin    #       return character (and on Windows, the end-of-file character)
86846a6b994Smistachkin    #       cannot be used here.
869f21979dfSmistachkin    #
87046a6b994Smistachkin    if {$i==0x0D || ($tcl_platform(platform)=="windows" && $i==0x1A)} {
871f21979dfSmistachkin      continue
872f21979dfSmistachkin    }
873f21979dfSmistachkin    set hex [format %02X $i]
874f21979dfSmistachkin    set char [subst \\x$hex]; set oldChar $char
8750acee513Smistachkin    set escapes [list]
8760acee513Smistachkin    if {$tcl_platform(platform)=="windows"} {
8770acee513Smistachkin      #
8780acee513Smistachkin      # NOTE: On Windows, we need to escape all the whitespace characters,
8790acee513Smistachkin      #       the alarm (\a) character, and those with special meaning to
8800acee513Smistachkin      #       the SQLite shell itself.
8810acee513Smistachkin      #
8820acee513Smistachkin      set escapes [list \
883f21979dfSmistachkin          \a \\a \b \\b \t \\t \n \\n \v \\v \f \\f \r \\r \
8840acee513Smistachkin          " " "\" \"" \" \\\" ' \"'\" \\ \\\\]
8850acee513Smistachkin    } else {
8860acee513Smistachkin      #
8870acee513Smistachkin      # NOTE: On Unix, we need to escape most of the whitespace characters
8880acee513Smistachkin      #       and those with special meaning to the SQLite shell itself.
8890acee513Smistachkin      #       The alarm (\a), backspace (\b), and carriage-return (\r)
8900acee513Smistachkin      #       characters do not appear to require escaping on Unix.  For
8910acee513Smistachkin      #       the alarm and backspace characters, this is probably due to
8920acee513Smistachkin      #       differences in the command shell.  For the carriage-return,
8930acee513Smistachkin      #       it is probably due to differences in how Tcl handles command
8940acee513Smistachkin      #       channel end-of-line translations.
8950acee513Smistachkin      #
8960acee513Smistachkin      set escapes [list \
8970acee513Smistachkin          \t \\t \n \\n \v \\v \f \\f \
8980acee513Smistachkin          " " "\" \"" \" \\\" ' \"'\" \\ \\\\]
8990acee513Smistachkin    }
9000acee513Smistachkin    set char [string map $escapes $char]
901bfefa4c2Smistachkin    set x [catchcmdex test.db ".print $char\n"]
902f21979dfSmistachkin    set code [lindex $x 0]
903f21979dfSmistachkin    set res [lindex $x 1]
904f21979dfSmistachkin    if {$code ne "0"} {
905f21979dfSmistachkin      error "failed with error: $res"
906f21979dfSmistachkin    }
907f21979dfSmistachkin    if {$res ne "$oldChar\n"} {
90848dcf2b6Smistachkin      if {[llength $res] > 0} {
90948dcf2b6Smistachkin        set got [format %02X [scan $res %c]]
91048dcf2b6Smistachkin      } else {
91148dcf2b6Smistachkin        set got <empty>
91248dcf2b6Smistachkin      }
91348dcf2b6Smistachkin      error "failed with byte $hex mismatch, got $got"
914f21979dfSmistachkin    }
915f21979dfSmistachkin  }
9161fe36bb8Smistachkin} {}
9171fe36bb8Smistachkin
918*697c9eaaSdrh# These test cases do not work on MinGW
919*697c9eaaSdrhif 0 {
920*697c9eaaSdrh
92149e1125bSmistachkin# The string used here is the word "test" in Chinese.
9221fe36bb8Smistachkin# In UTF-8, it is encoded as: \xE6\xB5\x8B\xE8\xAF\x95
92349e1125bSmistachkinset test \u6D4B\u8BD5
92449e1125bSmistachkin
92549e1125bSmistachkindo_test shell1-6.0 {
92649e1125bSmistachkin  set fileName $test; append fileName .db
92749e1125bSmistachkin  catch {forcedelete $fileName}
9281fe36bb8Smistachkin  set x [catchcmdex $fileName "CREATE TABLE t1(x);\n.schema\n"]
9291fe36bb8Smistachkin  set code [lindex $x 0]
9301fe36bb8Smistachkin  set res [string trim [lindex $x 1]]
9311fe36bb8Smistachkin  if {$code ne "0"} {
9321fe36bb8Smistachkin    error "failed with error: $res"
9331fe36bb8Smistachkin  }
9341fe36bb8Smistachkin  if {$res ne "CREATE TABLE t1(x);"} {
9351fe36bb8Smistachkin    error "failed with mismatch: $res"
9361fe36bb8Smistachkin  }
9371fe36bb8Smistachkin  if {![file exists $fileName]} {
9381810f228Smistachkin    error "file \"$fileName\" (Unicode) does not exist"
9391fe36bb8Smistachkin  }
9401fe36bb8Smistachkin  forcedelete $fileName
941f21979dfSmistachkin} {}
942f21979dfSmistachkin
94349e1125bSmistachkindo_test shell1-6.1 {
94449e1125bSmistachkin  catch {forcedelete test3.db}
94549e1125bSmistachkin  set x [catchcmdex test3.db \
94649e1125bSmistachkin      "CREATE TABLE [encoding convertto utf-8 $test](x);\n.schema\n"]
94749e1125bSmistachkin  set code [lindex $x 0]
94849e1125bSmistachkin  set res [string trim [lindex $x 1]]
94949e1125bSmistachkin  if {$code ne "0"} {
95049e1125bSmistachkin    error "failed with error: $res"
95149e1125bSmistachkin  }
95249e1125bSmistachkin  if {$res ne "CREATE TABLE ${test}(x);"} {
95349e1125bSmistachkin    error "failed with mismatch: $res"
95449e1125bSmistachkin  }
95549e1125bSmistachkin  forcedelete test3.db
95649e1125bSmistachkin} {}
957*697c9eaaSdrh}
95849e1125bSmistachkin
9598df9185cSdrhfinish_test
960