| OLD | NEW |
| (Empty) |
| 1 # 2003 January 29 | |
| 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 SQLite library. The | |
| 12 # focus of this script testing the callback-free C/C++ API. | |
| 13 # | |
| 14 # $Id: capi2.test,v 1.37 2008/12/30 17:55:00 drh Exp $ | |
| 15 # | |
| 16 | |
| 17 set testdir [file dirname $argv0] | |
| 18 source $testdir/tester.tcl | |
| 19 | |
| 20 # Return the text values from the current row pointed at by STMT as a list. | |
| 21 proc get_row_values {STMT} { | |
| 22 set VALUES [list] | |
| 23 for {set i 0} {$i < [sqlite3_data_count $STMT]} {incr i} { | |
| 24 lappend VALUES [sqlite3_column_text $STMT $i] | |
| 25 } | |
| 26 return $VALUES | |
| 27 } | |
| 28 | |
| 29 # Return the column names followed by declaration types for the result set | |
| 30 # of the SQL statement STMT. | |
| 31 # | |
| 32 # i.e. for: | |
| 33 # CREATE TABLE abc(a text, b integer); | |
| 34 # SELECT * FROM abc; | |
| 35 # | |
| 36 # The result is {a b text integer} | |
| 37 proc get_column_names {STMT} { | |
| 38 set VALUES [list] | |
| 39 for {set i 0} {$i < [sqlite3_column_count $STMT]} {incr i} { | |
| 40 lappend VALUES [sqlite3_column_name $STMT $i] | |
| 41 } | |
| 42 for {set i 0} {$i < [sqlite3_column_count $STMT]} {incr i} { | |
| 43 lappend VALUES [sqlite3_column_decltype $STMT $i] | |
| 44 } | |
| 45 return $VALUES | |
| 46 } | |
| 47 | |
| 48 # Check basic functionality | |
| 49 # | |
| 50 do_test capi2-1.1 { | |
| 51 set DB [sqlite3_connection_pointer db] | |
| 52 execsql {CREATE TABLE t1(a,b,c)} | |
| 53 set VM [sqlite3_prepare $DB {SELECT name, rowid FROM sqlite_master} -1 TAIL] | |
| 54 set TAIL | |
| 55 } {} | |
| 56 do_test capi2-1.2 { | |
| 57 sqlite3_step $VM | |
| 58 } {SQLITE_ROW} | |
| 59 do_test capi2-1.3 { | |
| 60 sqlite3_data_count $VM | |
| 61 } {2} | |
| 62 do_test capi2-1.4 { | |
| 63 get_row_values $VM | |
| 64 } {t1 1} | |
| 65 do_test capi2-1.5 { | |
| 66 get_column_names $VM | |
| 67 } {name rowid text INTEGER} | |
| 68 do_test capi2-1.6 { | |
| 69 sqlite3_step $VM | |
| 70 } {SQLITE_DONE} | |
| 71 do_test capi2-1.7 { | |
| 72 list [sqlite3_column_count $VM] [get_row_values $VM] [get_column_names $VM] | |
| 73 } {2 {} {name rowid text INTEGER}} | |
| 74 do_test capi2-1.8-misuse { | |
| 75 sqlite3_step $VM | |
| 76 } {SQLITE_MISUSE} | |
| 77 | |
| 78 # Update: In v2, once SQLITE_MISUSE is returned the statement handle cannot | |
| 79 # be interrogated for more information. However in v3, since the column | |
| 80 # count, names and types are determined at compile time, these are still | |
| 81 # accessible after an SQLITE_MISUSE error. | |
| 82 do_test capi2-1.9 { | |
| 83 list [sqlite3_column_count $VM] [get_row_values $VM] [get_column_names $VM] | |
| 84 } {2 {} {name rowid text INTEGER}} | |
| 85 do_test capi2-1.10 { | |
| 86 sqlite3_data_count $VM | |
| 87 } {0} | |
| 88 | |
| 89 do_test capi2-1.11 { | |
| 90 sqlite3_finalize $VM | |
| 91 } {SQLITE_OK} | |
| 92 | |
| 93 # Check to make sure that the "tail" of a multi-statement SQL script | |
| 94 # is returned by sqlite3_prepare. | |
| 95 # | |
| 96 do_test capi2-2.1 { | |
| 97 set SQL { | |
| 98 SELECT name, rowid FROM sqlite_master; | |
| 99 SELECT name, rowid FROM sqlite_master WHERE 0; | |
| 100 -- A comment at the end | |
| 101 } | |
| 102 set VM [sqlite3_prepare $DB $SQL -1 SQL] | |
| 103 set SQL | |
| 104 } { | |
| 105 SELECT name, rowid FROM sqlite_master WHERE 0; | |
| 106 -- A comment at the end | |
| 107 } | |
| 108 do_test capi2-2.2 { | |
| 109 set r [sqlite3_step $VM] | |
| 110 lappend r [sqlite3_column_count $VM] \ | |
| 111 [get_row_values $VM] \ | |
| 112 [get_column_names $VM] | |
| 113 } {SQLITE_ROW 2 {t1 1} {name rowid text INTEGER}} | |
| 114 do_test capi2-2.3 { | |
| 115 set r [sqlite3_step $VM] | |
| 116 lappend r [sqlite3_column_count $VM] \ | |
| 117 [get_row_values $VM] \ | |
| 118 [get_column_names $VM] | |
| 119 } {SQLITE_DONE 2 {} {name rowid text INTEGER}} | |
| 120 do_test capi2-2.4 { | |
| 121 sqlite3_finalize $VM | |
| 122 } {SQLITE_OK} | |
| 123 do_test capi2-2.5 { | |
| 124 set VM [sqlite3_prepare $DB $SQL -1 SQL] | |
| 125 set SQL | |
| 126 } { | |
| 127 -- A comment at the end | |
| 128 } | |
| 129 do_test capi2-2.6 { | |
| 130 set r [sqlite3_step $VM] | |
| 131 lappend r [sqlite3_column_count $VM] \ | |
| 132 [get_row_values $VM] \ | |
| 133 [get_column_names $VM] | |
| 134 } {SQLITE_DONE 2 {} {name rowid text INTEGER}} | |
| 135 do_test capi2-2.7 { | |
| 136 sqlite3_finalize $VM | |
| 137 } {SQLITE_OK} | |
| 138 do_test capi2-2.8 { | |
| 139 set VM [sqlite3_prepare $DB $SQL -1 SQL] | |
| 140 list $SQL $VM | |
| 141 } {{} {}} | |
| 142 | |
| 143 # Check the error handling. | |
| 144 # | |
| 145 do_test capi2-3.1 { | |
| 146 set rc [catch { | |
| 147 sqlite3_prepare $DB {select bogus from sqlite_master} -1 TAIL | |
| 148 } msg] | |
| 149 lappend rc $msg $TAIL | |
| 150 } {1 {(1) no such column: bogus} {}} | |
| 151 do_test capi2-3.2 { | |
| 152 set rc [catch { | |
| 153 sqlite3_prepare $DB {select bogus from } -1 TAIL | |
| 154 } msg] | |
| 155 lappend rc $msg $TAIL | |
| 156 } {1 {(1) near " ": syntax error} {}} | |
| 157 do_test capi2-3.3 { | |
| 158 set rc [catch { | |
| 159 sqlite3_prepare $DB {;;;;select bogus from sqlite_master} -1 TAIL | |
| 160 } msg] | |
| 161 lappend rc $msg $TAIL | |
| 162 } {1 {(1) no such column: bogus} {}} | |
| 163 do_test capi2-3.4 { | |
| 164 set rc [catch { | |
| 165 sqlite3_prepare $DB {select bogus from sqlite_master;x;} -1 TAIL | |
| 166 } msg] | |
| 167 lappend rc $msg $TAIL | |
| 168 } {1 {(1) no such column: bogus} {x;}} | |
| 169 do_test capi2-3.5 { | |
| 170 set rc [catch { | |
| 171 sqlite3_prepare $DB {select bogus from sqlite_master;;;x;} -1 TAIL | |
| 172 } msg] | |
| 173 lappend rc $msg $TAIL | |
| 174 } {1 {(1) no such column: bogus} {;;x;}} | |
| 175 do_test capi2-3.6 { | |
| 176 set rc [catch { | |
| 177 sqlite3_prepare $DB {select 5/0} -1 TAIL | |
| 178 } VM] | |
| 179 lappend rc $TAIL | |
| 180 } {0 {}} | |
| 181 do_test capi2-3.7 { | |
| 182 list [sqlite3_step $VM] \ | |
| 183 [sqlite3_column_count $VM] \ | |
| 184 [get_row_values $VM] \ | |
| 185 [get_column_names $VM] | |
| 186 } {SQLITE_ROW 1 {{}} {5/0 {}}} | |
| 187 do_test capi2-3.8 { | |
| 188 sqlite3_finalize $VM | |
| 189 } {SQLITE_OK} | |
| 190 do_test capi2-3.9 { | |
| 191 execsql {CREATE UNIQUE INDEX i1 ON t1(a)} | |
| 192 set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(1,2,3)} -1 TAIL] | |
| 193 set TAIL | |
| 194 } {} | |
| 195 do_test capi2-3.9b {db changes} {0} | |
| 196 do_test capi2-3.10 { | |
| 197 list [sqlite3_step $VM] \ | |
| 198 [sqlite3_column_count $VM] \ | |
| 199 [get_row_values $VM] \ | |
| 200 [get_column_names $VM] | |
| 201 } {SQLITE_DONE 0 {} {}} | |
| 202 | |
| 203 # Update for v3 - the change has not actually happened until the query is | |
| 204 # finalized. Is this going to cause trouble for anyone? Lee Nelson maybe? | |
| 205 # (Later:) The change now happens just before SQLITE_DONE is returned. | |
| 206 do_test capi2-3.10b {db changes} {1} | |
| 207 do_test capi2-3.11 { | |
| 208 sqlite3_finalize $VM | |
| 209 } {SQLITE_OK} | |
| 210 do_test capi2-3.11b {db changes} {1} | |
| 211 #do_test capi2-3.12-misuse { | |
| 212 # sqlite3_finalize $VM | |
| 213 #} {SQLITE_MISUSE} | |
| 214 do_test capi2-3.13 { | |
| 215 set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(1,3,4)} -1 TAIL] | |
| 216 list [sqlite3_step $VM] \ | |
| 217 [sqlite3_column_count $VM] \ | |
| 218 [get_row_values $VM] \ | |
| 219 [get_column_names $VM] | |
| 220 } {SQLITE_ERROR 0 {} {}} | |
| 221 | |
| 222 # Update for v3: Preparing a statement does not affect the change counter. | |
| 223 # (Test result changes from 0 to 1). (Later:) change counter updates occur | |
| 224 # when sqlite3_step returns, not at finalize time. | |
| 225 do_test capi2-3.13b {db changes} {0} | |
| 226 | |
| 227 do_test capi2-3.14 { | |
| 228 list [sqlite3_finalize $VM] [sqlite3_errmsg $DB] | |
| 229 } {SQLITE_CONSTRAINT {column a is not unique}} | |
| 230 do_test capi2-3.15 { | |
| 231 set VM [sqlite3_prepare $DB {CREATE TABLE t2(a NOT NULL, b)} -1 TAIL] | |
| 232 set TAIL | |
| 233 } {} | |
| 234 do_test capi2-3.16 { | |
| 235 list [sqlite3_step $VM] \ | |
| 236 [sqlite3_column_count $VM] \ | |
| 237 [get_row_values $VM] \ | |
| 238 [get_column_names $VM] | |
| 239 } {SQLITE_DONE 0 {} {}} | |
| 240 do_test capi2-3.17 { | |
| 241 list [sqlite3_finalize $VM] [sqlite3_errmsg $DB] | |
| 242 } {SQLITE_OK {not an error}} | |
| 243 do_test capi2-3.18 { | |
| 244 set VM [sqlite3_prepare $DB {INSERT INTO t2 VALUES(NULL,2)} -1 TAIL] | |
| 245 list [sqlite3_step $VM] \ | |
| 246 [sqlite3_column_count $VM] \ | |
| 247 [get_row_values $VM] \ | |
| 248 [get_column_names $VM] | |
| 249 } {SQLITE_ERROR 0 {} {}} | |
| 250 do_test capi2-3.19 { | |
| 251 list [sqlite3_finalize $VM] [sqlite3_errmsg $DB] | |
| 252 } {SQLITE_CONSTRAINT {t2.a may not be NULL}} | |
| 253 | |
| 254 do_test capi2-3.20 { | |
| 255 execsql { | |
| 256 CREATE TABLE a1(message_id, name , UNIQUE(message_id, name) ); | |
| 257 INSERT INTO a1 VALUES(1, 1); | |
| 258 } | |
| 259 } {} | |
| 260 do_test capi2-3.21 { | |
| 261 set VM [sqlite3_prepare $DB {INSERT INTO a1 VALUES(1, 1)} -1 TAIL] | |
| 262 sqlite3_step $VM | |
| 263 } {SQLITE_ERROR} | |
| 264 do_test capi2-3.22 { | |
| 265 sqlite3_errcode $DB | |
| 266 } {SQLITE_ERROR} | |
| 267 do_test capi2-3.23 { | |
| 268 sqlite3_finalize $VM | |
| 269 } {SQLITE_CONSTRAINT} | |
| 270 do_test capi2-3.24 { | |
| 271 sqlite3_errcode $DB | |
| 272 } {SQLITE_CONSTRAINT} | |
| 273 | |
| 274 # Two or more virtual machines exists at the same time. | |
| 275 # | |
| 276 do_test capi2-4.1 { | |
| 277 set VM1 [sqlite3_prepare $DB {INSERT INTO t2 VALUES(1,2)} -1 TAIL] | |
| 278 set TAIL | |
| 279 } {} | |
| 280 do_test capi2-4.2 { | |
| 281 set VM2 [sqlite3_prepare $DB {INSERT INTO t2 VALUES(2,3)} -1 TAIL] | |
| 282 set TAIL | |
| 283 } {} | |
| 284 do_test capi2-4.3 { | |
| 285 set VM3 [sqlite3_prepare $DB {INSERT INTO t2 VALUES(3,4)} -1 TAIL] | |
| 286 set TAIL | |
| 287 } {} | |
| 288 do_test capi2-4.4 { | |
| 289 list [sqlite3_step $VM2] \ | |
| 290 [sqlite3_column_count $VM2] \ | |
| 291 [get_row_values $VM2] \ | |
| 292 [get_column_names $VM2] | |
| 293 } {SQLITE_DONE 0 {} {}} | |
| 294 do_test capi2-4.5 { | |
| 295 execsql {SELECT * FROM t2 ORDER BY a} | |
| 296 } {2 3} | |
| 297 do_test capi2-4.6 { | |
| 298 sqlite3_finalize $VM2 | |
| 299 } {SQLITE_OK} | |
| 300 do_test capi2-4.7 { | |
| 301 list [sqlite3_step $VM3] \ | |
| 302 [sqlite3_column_count $VM3] \ | |
| 303 [get_row_values $VM3] \ | |
| 304 [get_column_names $VM3] | |
| 305 } {SQLITE_DONE 0 {} {}} | |
| 306 do_test capi2-4.8 { | |
| 307 execsql {SELECT * FROM t2 ORDER BY a} | |
| 308 } {2 3 3 4} | |
| 309 do_test capi2-4.9 { | |
| 310 sqlite3_finalize $VM3 | |
| 311 } {SQLITE_OK} | |
| 312 do_test capi2-4.10 { | |
| 313 list [sqlite3_step $VM1] \ | |
| 314 [sqlite3_column_count $VM1] \ | |
| 315 [get_row_values $VM1] \ | |
| 316 [get_column_names $VM1] | |
| 317 } {SQLITE_DONE 0 {} {}} | |
| 318 do_test capi2-4.11 { | |
| 319 execsql {SELECT * FROM t2 ORDER BY a} | |
| 320 } {1 2 2 3 3 4} | |
| 321 do_test capi2-4.12 { | |
| 322 sqlite3_finalize $VM1 | |
| 323 } {SQLITE_OK} | |
| 324 | |
| 325 # Interleaved SELECTs | |
| 326 # | |
| 327 do_test capi2-5.1 { | |
| 328 set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL] | |
| 329 set VM2 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL] | |
| 330 set VM3 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL] | |
| 331 list [sqlite3_step $VM1] \ | |
| 332 [sqlite3_column_count $VM1] \ | |
| 333 [get_row_values $VM1] \ | |
| 334 [get_column_names $VM1] | |
| 335 } {SQLITE_ROW 2 {2 3} {a b {} {}}} | |
| 336 do_test capi2-5.2 { | |
| 337 list [sqlite3_step $VM2] \ | |
| 338 [sqlite3_column_count $VM2] \ | |
| 339 [get_row_values $VM2] \ | |
| 340 [get_column_names $VM2] | |
| 341 } {SQLITE_ROW 2 {2 3} {a b {} {}}} | |
| 342 do_test capi2-5.3 { | |
| 343 list [sqlite3_step $VM1] \ | |
| 344 [sqlite3_column_count $VM1] \ | |
| 345 [get_row_values $VM1] \ | |
| 346 [get_column_names $VM1] | |
| 347 } {SQLITE_ROW 2 {3 4} {a b {} {}}} | |
| 348 do_test capi2-5.4 { | |
| 349 list [sqlite3_step $VM3] \ | |
| 350 [sqlite3_column_count $VM3] \ | |
| 351 [get_row_values $VM3] \ | |
| 352 [get_column_names $VM3] | |
| 353 } {SQLITE_ROW 2 {2 3} {a b {} {}}} | |
| 354 do_test capi2-5.5 { | |
| 355 list [sqlite3_step $VM3] \ | |
| 356 [sqlite3_column_count $VM3] \ | |
| 357 [get_row_values $VM3] \ | |
| 358 [get_column_names $VM3] | |
| 359 } {SQLITE_ROW 2 {3 4} {a b {} {}}} | |
| 360 do_test capi2-5.6 { | |
| 361 list [sqlite3_step $VM3] \ | |
| 362 [sqlite3_column_count $VM3] \ | |
| 363 [get_row_values $VM3] \ | |
| 364 [get_column_names $VM3] | |
| 365 } {SQLITE_ROW 2 {1 2} {a b {} {}}} | |
| 366 do_test capi2-5.7 { | |
| 367 list [sqlite3_step $VM3] \ | |
| 368 [sqlite3_column_count $VM3] \ | |
| 369 [get_row_values $VM3] \ | |
| 370 [get_column_names $VM3] | |
| 371 } {SQLITE_DONE 2 {} {a b {} {}}} | |
| 372 do_test capi2-5.8 { | |
| 373 sqlite3_finalize $VM3 | |
| 374 } {SQLITE_OK} | |
| 375 do_test capi2-5.9 { | |
| 376 list [sqlite3_step $VM1] \ | |
| 377 [sqlite3_column_count $VM1] \ | |
| 378 [get_row_values $VM1] \ | |
| 379 [get_column_names $VM1] | |
| 380 } {SQLITE_ROW 2 {1 2} {a b {} {}}} | |
| 381 do_test capi2-5.10 { | |
| 382 sqlite3_finalize $VM1 | |
| 383 } {SQLITE_OK} | |
| 384 do_test capi2-5.11 { | |
| 385 list [sqlite3_step $VM2] \ | |
| 386 [sqlite3_column_count $VM2] \ | |
| 387 [get_row_values $VM2] \ | |
| 388 [get_column_names $VM2] | |
| 389 } {SQLITE_ROW 2 {3 4} {a b {} {}}} | |
| 390 do_test capi2-5.12 { | |
| 391 list [sqlite3_step $VM2] \ | |
| 392 [sqlite3_column_count $VM2] \ | |
| 393 [get_row_values $VM2] \ | |
| 394 [get_column_names $VM2] | |
| 395 } {SQLITE_ROW 2 {1 2} {a b {} {}}} | |
| 396 do_test capi2-5.11 { | |
| 397 sqlite3_finalize $VM2 | |
| 398 } {SQLITE_OK} | |
| 399 | |
| 400 # Check for proper SQLITE_BUSY returns. | |
| 401 # | |
| 402 do_test capi2-6.1 { | |
| 403 execsql { | |
| 404 BEGIN; | |
| 405 CREATE TABLE t3(x counter); | |
| 406 INSERT INTO t3 VALUES(1); | |
| 407 INSERT INTO t3 VALUES(2); | |
| 408 INSERT INTO t3 SELECT x+2 FROM t3; | |
| 409 INSERT INTO t3 SELECT x+4 FROM t3; | |
| 410 INSERT INTO t3 SELECT x+8 FROM t3; | |
| 411 COMMIT; | |
| 412 } | |
| 413 set VM1 [sqlite3_prepare $DB {SELECT * FROM t3} -1 TAIL] | |
| 414 sqlite3 db2 test.db | |
| 415 execsql {BEGIN} db2 | |
| 416 } {} | |
| 417 # Update for v3: BEGIN doesn't write-lock the database. It is quite | |
| 418 # difficult to get v3 to write-lock the database, which causes a few | |
| 419 # problems for test scripts. | |
| 420 # | |
| 421 # do_test capi2-6.2 { | |
| 422 # list [sqlite3_step $VM1] \ | |
| 423 # [sqlite3_column_count $VM1] \ | |
| 424 # [get_row_values $VM1] \ | |
| 425 # [get_column_names $VM1] | |
| 426 # } {SQLITE_BUSY 0 {} {}} | |
| 427 do_test capi2-6.3 { | |
| 428 execsql {COMMIT} db2 | |
| 429 } {} | |
| 430 do_test capi2-6.4 { | |
| 431 list [sqlite3_step $VM1] \ | |
| 432 [sqlite3_column_count $VM1] \ | |
| 433 [get_row_values $VM1] \ | |
| 434 [get_column_names $VM1] | |
| 435 } {SQLITE_ROW 1 1 {x counter}} | |
| 436 do_test capi2-6.5 { | |
| 437 catchsql {INSERT INTO t3 VALUES(10);} db2 | |
| 438 } {1 {database is locked}} | |
| 439 do_test capi2-6.6 { | |
| 440 list [sqlite3_step $VM1] \ | |
| 441 [sqlite3_column_count $VM1] \ | |
| 442 [get_row_values $VM1] \ | |
| 443 [get_column_names $VM1] | |
| 444 } {SQLITE_ROW 1 2 {x counter}} | |
| 445 do_test capi2-6.7 { | |
| 446 execsql {SELECT * FROM t2} db2 | |
| 447 } {2 3 3 4 1 2} | |
| 448 do_test capi2-6.8 { | |
| 449 list [sqlite3_step $VM1] \ | |
| 450 [sqlite3_column_count $VM1] \ | |
| 451 [get_row_values $VM1] \ | |
| 452 [get_column_names $VM1] | |
| 453 } {SQLITE_ROW 1 3 {x counter}} | |
| 454 do_test capi2-6.9 { | |
| 455 execsql {SELECT * FROM t2} | |
| 456 } {2 3 3 4 1 2} | |
| 457 do_test capi2-6.10 { | |
| 458 list [sqlite3_step $VM1] \ | |
| 459 [sqlite3_column_count $VM1] \ | |
| 460 [get_row_values $VM1] \ | |
| 461 [get_column_names $VM1] | |
| 462 } {SQLITE_ROW 1 4 {x counter}} | |
| 463 do_test capi2-6.11 { | |
| 464 execsql {BEGIN} | |
| 465 } {} | |
| 466 do_test capi2-6.12 { | |
| 467 list [sqlite3_step $VM1] \ | |
| 468 [sqlite3_column_count $VM1] \ | |
| 469 [get_row_values $VM1] \ | |
| 470 [get_column_names $VM1] | |
| 471 } {SQLITE_ROW 1 5 {x counter}} | |
| 472 | |
| 473 # A read no longer blocks a write in the same connection. | |
| 474 #do_test capi2-6.13 { | |
| 475 # catchsql {UPDATE t3 SET x=x+1} | |
| 476 #} {1 {database table is locked}} | |
| 477 | |
| 478 do_test capi2-6.14 { | |
| 479 list [sqlite3_step $VM1] \ | |
| 480 [sqlite3_column_count $VM1] \ | |
| 481 [get_row_values $VM1] \ | |
| 482 [get_column_names $VM1] | |
| 483 } {SQLITE_ROW 1 6 {x counter}} | |
| 484 do_test capi2-6.15 { | |
| 485 execsql {SELECT * FROM t1} | |
| 486 } {1 2 3} | |
| 487 do_test capi2-6.16 { | |
| 488 list [sqlite3_step $VM1] \ | |
| 489 [sqlite3_column_count $VM1] \ | |
| 490 [get_row_values $VM1] \ | |
| 491 [get_column_names $VM1] | |
| 492 } {SQLITE_ROW 1 7 {x counter}} | |
| 493 do_test capi2-6.17 { | |
| 494 catchsql {UPDATE t1 SET b=b+1} | |
| 495 } {0 {}} | |
| 496 do_test capi2-6.18 { | |
| 497 list [sqlite3_step $VM1] \ | |
| 498 [sqlite3_column_count $VM1] \ | |
| 499 [get_row_values $VM1] \ | |
| 500 [get_column_names $VM1] | |
| 501 } {SQLITE_ROW 1 8 {x counter}} | |
| 502 do_test capi2-6.19 { | |
| 503 execsql {SELECT * FROM t1} | |
| 504 } {1 3 3} | |
| 505 do_test capi2-6.20 { | |
| 506 list [sqlite3_step $VM1] \ | |
| 507 [sqlite3_column_count $VM1] \ | |
| 508 [get_row_values $VM1] \ | |
| 509 [get_column_names $VM1] | |
| 510 } {SQLITE_ROW 1 9 {x counter}} | |
| 511 #do_test capi2-6.21 { | |
| 512 # execsql {ROLLBACK; SELECT * FROM t1} | |
| 513 #} {1 2 3} | |
| 514 do_test capi2-6.22 { | |
| 515 list [sqlite3_step $VM1] \ | |
| 516 [sqlite3_column_count $VM1] \ | |
| 517 [get_row_values $VM1] \ | |
| 518 [get_column_names $VM1] | |
| 519 } {SQLITE_ROW 1 10 {x counter}} | |
| 520 #do_test capi2-6.23 { | |
| 521 # execsql {BEGIN TRANSACTION;} | |
| 522 #} {} | |
| 523 do_test capi2-6.24 { | |
| 524 list [sqlite3_step $VM1] \ | |
| 525 [sqlite3_column_count $VM1] \ | |
| 526 [get_row_values $VM1] \ | |
| 527 [get_column_names $VM1] | |
| 528 } {SQLITE_ROW 1 11 {x counter}} | |
| 529 do_test capi2-6.25 { | |
| 530 execsql { | |
| 531 INSERT INTO t1 VALUES(2,3,4); | |
| 532 SELECT * FROM t1; | |
| 533 } | |
| 534 } {1 3 3 2 3 4} | |
| 535 do_test capi2-6.26 { | |
| 536 list [sqlite3_step $VM1] \ | |
| 537 [sqlite3_column_count $VM1] \ | |
| 538 [get_row_values $VM1] \ | |
| 539 [get_column_names $VM1] | |
| 540 } {SQLITE_ROW 1 12 {x counter}} | |
| 541 do_test capi2-6.27 { | |
| 542 catchsql { | |
| 543 INSERT INTO t1 VALUES(2,4,5); | |
| 544 SELECT * FROM t1; | |
| 545 } | |
| 546 } {1 {column a is not unique}} | |
| 547 do_test capi2-6.28 { | |
| 548 list [sqlite3_step $VM1] \ | |
| 549 [sqlite3_column_count $VM1] \ | |
| 550 [get_row_values $VM1] \ | |
| 551 [get_column_names $VM1] | |
| 552 } {SQLITE_ROW 1 13 {x counter}} | |
| 553 do_test capi2-6.99 { | |
| 554 sqlite3_finalize $VM1 | |
| 555 } {SQLITE_OK} | |
| 556 catchsql {ROLLBACK} | |
| 557 | |
| 558 do_test capi2-7.1 { | |
| 559 stepsql $DB { | |
| 560 SELECT * FROM t1 | |
| 561 } | |
| 562 } {0 1 2 3} | |
| 563 do_test capi2-7.2 { | |
| 564 stepsql $DB { | |
| 565 PRAGMA count_changes=on | |
| 566 } | |
| 567 } {0} | |
| 568 do_test capi2-7.3 { | |
| 569 stepsql $DB { | |
| 570 UPDATE t1 SET a=a+10; | |
| 571 } | |
| 572 } {0 1} | |
| 573 do_test capi2-7.4 { | |
| 574 stepsql $DB { | |
| 575 INSERT INTO t1 SELECT a+1,b+1,c+1 FROM t1; | |
| 576 } | |
| 577 } {0 1} | |
| 578 do_test capi2-7.4b {sqlite3_changes $DB} {1} | |
| 579 do_test capi2-7.5 { | |
| 580 stepsql $DB { | |
| 581 UPDATE t1 SET a=a+10; | |
| 582 } | |
| 583 } {0 2} | |
| 584 do_test capi2-7.5b {sqlite3_changes $DB} {2} | |
| 585 do_test capi2-7.6 { | |
| 586 stepsql $DB { | |
| 587 SELECT * FROM t1; | |
| 588 } | |
| 589 } {0 21 2 3 22 3 4} | |
| 590 do_test capi2-7.7 { | |
| 591 stepsql $DB { | |
| 592 INSERT INTO t1 SELECT a+2,b+2,c+2 FROM t1; | |
| 593 } | |
| 594 } {0 2} | |
| 595 do_test capi2-7.8 { | |
| 596 sqlite3_changes $DB | |
| 597 } {2} | |
| 598 do_test capi2-7.9 { | |
| 599 stepsql $DB { | |
| 600 SELECT * FROM t1; | |
| 601 } | |
| 602 } {0 21 2 3 22 3 4 23 4 5 24 5 6} | |
| 603 do_test capi2-7.10 { | |
| 604 stepsql $DB { | |
| 605 UPDATE t1 SET a=a-20; | |
| 606 SELECT * FROM t1; | |
| 607 } | |
| 608 } {0 4 1 2 3 2 3 4 3 4 5 4 5 6} | |
| 609 | |
| 610 # Update for version 3: A SELECT statement no longer resets the change | |
| 611 # counter (Test result changes from 0 to 4). | |
| 612 do_test capi2-7.11 { | |
| 613 sqlite3_changes $DB | |
| 614 } {4} | |
| 615 do_test capi2-7.11a { | |
| 616 execsql {SELECT count(*) FROM t1} | |
| 617 } {4} | |
| 618 | |
| 619 ifcapable {explain} { | |
| 620 do_test capi2-7.12 { | |
| 621 set x [stepsql $DB {EXPLAIN SELECT * FROM t1}] | |
| 622 lindex $x 0 | |
| 623 } {0} | |
| 624 } | |
| 625 | |
| 626 # Ticket #261 - make sure we can finalize before the end of a query. | |
| 627 # | |
| 628 do_test capi2-8.1 { | |
| 629 set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL] | |
| 630 sqlite3_finalize $VM1 | |
| 631 } {SQLITE_OK} | |
| 632 | |
| 633 # Tickets #384 and #385 - make sure the TAIL argument to sqlite3_prepare | |
| 634 # and all of the return pointers in sqlite_step can be null. | |
| 635 # | |
| 636 do_test capi2-9.1 { | |
| 637 set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 DUMMY] | |
| 638 sqlite3_step $VM1 | |
| 639 sqlite3_finalize $VM1 | |
| 640 } {SQLITE_OK} | |
| 641 | |
| 642 # Test that passing a NULL pointer to sqlite3_finalize() or sqlite3_reset | |
| 643 # does not cause an error. | |
| 644 do_test capi2-10.1 { | |
| 645 sqlite3_finalize 0 | |
| 646 } {SQLITE_OK} | |
| 647 do_test capi2-10.2 { | |
| 648 sqlite3_reset 0 | |
| 649 } {SQLITE_OK} | |
| 650 | |
| 651 #--------------------------------------------------------------------------- | |
| 652 # The following tests - capi2-11.* - test the "column origin" APIs. | |
| 653 # | |
| 654 # sqlite3_column_origin_name() | |
| 655 # sqlite3_column_database_name() | |
| 656 # sqlite3_column_table_name() | |
| 657 # | |
| 658 | |
| 659 ifcapable columnmetadata { | |
| 660 | |
| 661 # This proc uses the database handle $::DB to compile the SQL statement passed | |
| 662 # as a parameter. The return value of this procedure is a list with one | |
| 663 # element for each column returned by the compiled statement. Each element of | |
| 664 # this list is itself a list of length three, consisting of the origin | |
| 665 # database, table and column for the corresponding returned column. | |
| 666 proc check_origins {sql} { | |
| 667 set ret [list] | |
| 668 set ::STMT [sqlite3_prepare $::DB $sql -1 dummy] | |
| 669 for {set i 0} {$i < [sqlite3_column_count $::STMT]} {incr i} { | |
| 670 lappend ret [list \ | |
| 671 [sqlite3_column_database_name $::STMT $i] \ | |
| 672 [sqlite3_column_table_name $::STMT $i] \ | |
| 673 [sqlite3_column_origin_name $::STMT $i] \ | |
| 674 ] | |
| 675 } | |
| 676 sqlite3_finalize $::STMT | |
| 677 return $ret | |
| 678 } | |
| 679 do_test capi2-11.1 { | |
| 680 execsql { | |
| 681 CREATE TABLE tab1(col1, col2); | |
| 682 } | |
| 683 } {} | |
| 684 do_test capi2-11.2 { | |
| 685 check_origins {SELECT col2, col1 FROM tab1} | |
| 686 } [list {main tab1 col2} {main tab1 col1}] | |
| 687 do_test capi2-11.3 { | |
| 688 check_origins {SELECT col2 AS hello, col1 AS world FROM tab1} | |
| 689 } [list {main tab1 col2} {main tab1 col1}] | |
| 690 | |
| 691 ifcapable subquery { | |
| 692 do_test capi2-11.4 { | |
| 693 check_origins {SELECT b, a FROM (SELECT col1 AS a, col2 AS b FROM tab1)} | |
| 694 } [list {main tab1 col2} {main tab1 col1}] | |
| 695 do_test capi2-11.5 { | |
| 696 check_origins {SELECT (SELECT col2 FROM tab1), (SELECT col1 FROM tab1)} | |
| 697 } [list {main tab1 col2} {main tab1 col1}] | |
| 698 do_test capi2-11.6 { | |
| 699 check_origins {SELECT (SELECT col2), (SELECT col1) FROM tab1} | |
| 700 } [list {main tab1 col2} {main tab1 col1}] | |
| 701 do_test capi2-11.7 { | |
| 702 check_origins {SELECT * FROM tab1} | |
| 703 } [list {main tab1 col1} {main tab1 col2}] | |
| 704 do_test capi2-11.8 { | |
| 705 check_origins {SELECT * FROM (SELECT * FROM tab1)} | |
| 706 } [list {main tab1 col1} {main tab1 col2}] | |
| 707 } | |
| 708 | |
| 709 ifcapable view&&subquery { | |
| 710 do_test capi2-12.1 { | |
| 711 execsql { | |
| 712 CREATE VIEW view1 AS SELECT * FROM tab1; | |
| 713 } | |
| 714 } {} | |
| 715 do_test capi2-12.2 { | |
| 716 check_origins {SELECT col2, col1 FROM view1} | |
| 717 } [list {main tab1 col2} {main tab1 col1}] | |
| 718 do_test capi2-12.3 { | |
| 719 check_origins {SELECT col2 AS hello, col1 AS world FROM view1} | |
| 720 } [list {main tab1 col2} {main tab1 col1}] | |
| 721 do_test capi2-12.4 { | |
| 722 check_origins {SELECT b, a FROM (SELECT col1 AS a, col2 AS b FROM view1)} | |
| 723 } [list {main tab1 col2} {main tab1 col1}] | |
| 724 do_test capi2-12.5 { | |
| 725 check_origins {SELECT (SELECT col2 FROM view1), (SELECT col1 FROM view1)} | |
| 726 } [list {main tab1 col2} {main tab1 col1}] | |
| 727 do_test capi2-12.6 { | |
| 728 check_origins {SELECT (SELECT col2), (SELECT col1) FROM view1} | |
| 729 } [list {main tab1 col2} {main tab1 col1}] | |
| 730 do_test capi2-12.7 { | |
| 731 check_origins {SELECT * FROM view1} | |
| 732 } [list {main tab1 col1} {main tab1 col2}] | |
| 733 do_test capi2-12.8 { | |
| 734 check_origins {select * from (select * from view1)} | |
| 735 } [list {main tab1 col1} {main tab1 col2}] | |
| 736 do_test capi2-12.9 { | |
| 737 check_origins {select * from (select * from (select * from view1))} | |
| 738 } [list {main tab1 col1} {main tab1 col2}] | |
| 739 do_test capi2-12.10 { | |
| 740 db close | |
| 741 sqlite3 db test.db | |
| 742 set ::DB [sqlite3_connection_pointer db] | |
| 743 check_origins {select * from (select * from (select * from view1))} | |
| 744 } [list {main tab1 col1} {main tab1 col2}] | |
| 745 | |
| 746 # This view will thwart the flattening optimization. | |
| 747 do_test capi2-13.1 { | |
| 748 execsql { | |
| 749 CREATE VIEW view2 AS SELECT * FROM tab1 limit 10 offset 10; | |
| 750 } | |
| 751 } {} | |
| 752 do_test capi2-13.2 { | |
| 753 check_origins {SELECT col2, col1 FROM view2} | |
| 754 } [list {main tab1 col2} {main tab1 col1}] | |
| 755 do_test capi2-13.3 { | |
| 756 check_origins {SELECT col2 AS hello, col1 AS world FROM view2} | |
| 757 } [list {main tab1 col2} {main tab1 col1}] | |
| 758 do_test capi2-13.4 { | |
| 759 check_origins {SELECT b, a FROM (SELECT col1 AS a, col2 AS b FROM view2)} | |
| 760 } [list {main tab1 col2} {main tab1 col1}] | |
| 761 do_test capi2-13.5 { | |
| 762 check_origins {SELECT (SELECT col2 FROM view2), (SELECT col1 FROM view2)} | |
| 763 } [list {main tab1 col2} {main tab1 col1}] | |
| 764 do_test capi2-13.6 { | |
| 765 check_origins {SELECT (SELECT col2), (SELECT col1) FROM view2} | |
| 766 } [list {main tab1 col2} {main tab1 col1}] | |
| 767 do_test capi2-13.7 { | |
| 768 check_origins {SELECT * FROM view2} | |
| 769 } [list {main tab1 col1} {main tab1 col2}] | |
| 770 do_test capi2-13.8 { | |
| 771 check_origins {select * from (select * from view2)} | |
| 772 } [list {main tab1 col1} {main tab1 col2}] | |
| 773 do_test capi2-13.9 { | |
| 774 check_origins {select * from (select * from (select * from view2))} | |
| 775 } [list {main tab1 col1} {main tab1 col2}] | |
| 776 do_test capi2-13.10 { | |
| 777 db close | |
| 778 sqlite3 db test.db | |
| 779 set ::DB [sqlite3_connection_pointer db] | |
| 780 check_origins {select * from (select * from (select * from view2))} | |
| 781 } [list {main tab1 col1} {main tab1 col2}] | |
| 782 do_test capi2-13.11 { | |
| 783 check_origins {select * from (select * from tab1 limit 10 offset 10)} | |
| 784 } [list {main tab1 col1} {main tab1 col2}] | |
| 785 } | |
| 786 | |
| 787 | |
| 788 } ;# ifcapable columnmetadata | |
| 789 | |
| 790 db2 close | |
| 791 finish_test | |
| OLD | NEW |