Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix the schemalint.tcl script to handle identifiers that require quoting. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | schemalint |
Files: | files | file ages | folders |
SHA1: |
451e0fafbe5b7e9c67d9b584d5e16796 |
User & Date: | dan 2015-11-30 18:17:55.036 |
Context
2015-11-30
| ||
19:16 | Add a rule to main.mk to build the schemalint.tcl script into an executable. Similar to the way the sqlite3_analyzer executable is built. (check-in: b8251065db user: dan tags: schemalint) | |
18:17 | Fix the schemalint.tcl script to handle identifiers that require quoting. (check-in: 451e0fafbe user: dan tags: schemalint) | |
2015-11-23
| ||
18:28 | In the CREATE INDEX statements output by schemalint.tcl, avoid declaring an explicit collation sequence that is the same as the column's default. (check-in: d3aa067c83 user: dan tags: schemalint) | |
Changes
Changes to src/where.c.
︙ | |||
3938 3939 3940 3941 3942 3943 3944 | 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 | - + + | zOp = "eq"; }else if( pTerm->eOperator & (WO_LT|WO_LE|WO_GE|WO_GT) ){ zOp = "range"; } pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); if( zOp ){ |
︙ | |||
4021 4022 4023 4024 4025 4026 4027 | 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 | - + + - + - + | struct SrcList_item *pItem = &pWInfo->pTabList->a[ii]; if( pItem->pSelect ) continue; pTab = pItem->pTab; nCol = pTab->nCol; /* Append the table name to the buffer. */ |
︙ |
Changes to test/schemalint.test.
︙ | |||
23 24 25 26 27 28 29 | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | - - + + - + - + - - + + - + - + - + - + - + - + - + - + | CREATE TABLE t1(a, b, c); CREATE TABLE t2(x, y, z); } do_trace_test 1.1 { SELECT b, c, y, z FROM t1, t2 WHERE c=? AND z=? } { |
Changes to tool/schemalint.tcl.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | set ::VERBOSE 0 proc usage {} { puts stderr "Usage: $::argv0 ?SWITCHES? DATABASE/SCHEMA" puts stderr " Switches are:" puts stderr " -select SQL (recommend indexes for SQL statement)" puts stderr " -verbose (increase verbosity of output)" puts stderr " -test (run internal tests and then exit)" puts stderr "" exit } # Return the quoted version of identfier $id. Quotes are only added if # they are required by SQLite. # # This command currently assumes that quotes are required if the # identifier contains any ASCII-range characters that are not # alpha-numeric or underscores. # proc quote {id} { if {[requires_quote $id]} { set x [string map {\" \"\"} $id] return "\"$x\"" } return $id } proc requires_quote {id} { foreach c [split $id {}] { if {[string is alnum $c]==0 && $c!="_"} { return 1 } } return 0 } # The argument passed to this command is a Tcl list of identifiers. The # value returned is the same list, except with each item quoted and the # elements comma-separated. # proc list_to_sql {L} { set ret [list] foreach l $L { lappend ret [quote $l] } join $ret ", " } proc process_cmdline_args {ctxvar argv} { upvar $ctxvar G set nArg [llength $argv] set G(database) [lindex $argv end] for {set i 0} {$i < [llength $argv]-1} {incr i} { |
︙ | |||
135 136 137 138 139 140 141 | 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | - + - + - + | set rangeset [concat $rangeset $range] set lCols [list] set idxname $tname foreach {c collate dir} $rangeset { append idxname "_$c" |
︙ | |||
181 182 183 184 185 186 187 188 189 190 | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | + + + + + + + + + + + + + + + + - - + + - | } set lRet $lNew } } return $lRet } #-------------------------------------------------------------------------- # Argument $tname is the name of a table in the main database opened by # database handle [db]. $arrayvar is the name of an array variable in the # caller's context. This command populates the array with an entry mapping # from column name to default collation sequence for each column of table # $tname. For example, if a table is declared: # # CREATE TABLE t1(a COLLATE nocase, b, c COLLATE binary) # # the mapping is populated with: # # map(a) -> "nocase" # map(b) -> "binary" # map(c) -> "binary" # proc sqlidx_get_coll_map {tname arrayvar} { upvar $arrayvar aColl set colnames [list] set qname [quote $tname] |
︙ | |||
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 | + + + + + + | # The following is test code only. # proc sqlidx_one_test {tn schema select expected} { # if {$tn!=2} return sqlidx_init_context C sqlite3 db "" db collate "a b c" [list string compare] db eval $schema lappend C(lSelect) $select analyze_selects C find_trial_indexes C set idxlist [run_trials C] if {$idxlist != [list {*}$expected]} { puts stderr "Test $tn failed" puts stderr "Expected: $expected" puts stderr "Got: $idxlist" exit -1 } db close upvar nTest nTest incr nTest } proc sqlidx_internal_tests {} { set nTest 0 # No indexes for a query with no constraints. sqlidx_one_test 0 { CREATE TABLE t1(a, b, c); } { SELECT * FROM t1; } { |
︙ | |||
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 | 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | CREATE TABLE t1(a COLLATE NOCase, b, c); } { SELECT * FROM t1 WHERE a=? } { {CREATE INDEX t1_a ON t1(a);} } # Tables with names that require quotes. # sqlidx_one_test 8.1 { CREATE TABLE "t t"(a, b, c); } { SELECT * FROM "t t" WHERE a=? } { {CREATE INDEX "t t_a" ON "t t"(a);} } sqlidx_one_test 8.2 { CREATE TABLE "t t"(a, b, c); } { SELECT * FROM "t t" WHERE b BETWEEN ? AND ? } { {CREATE INDEX "t t_b" ON "t t"(b);} } # Columns with names that require quotes. # sqlidx_one_test 9.1 { CREATE TABLE t3(a, "b b", c); } { SELECT * FROM t3 WHERE "b b" = ? } { {CREATE INDEX "t3_b b" ON t3("b b");} } sqlidx_one_test 9.2 { CREATE TABLE t3(a, "b b", c); } { SELECT * FROM t3 ORDER BY "b b" } { {CREATE INDEX "t3_b b" ON t3("b b");} } # Collations with names that require quotes. # sqlidx_one_test 10.1 { CREATE TABLE t4(a, b, c); } { SELECT * FROM t4 ORDER BY c COLLATE "a b c" } { {CREATE INDEX "t4_ca b c" ON t4(c COLLATE "a b c");} } sqlidx_one_test 10.2 { CREATE TABLE t4(a, b, c); } { SELECT * FROM t4 WHERE c = ? COLLATE "a b c" } { {CREATE INDEX "t4_ca b c" ON t4(c COLLATE "a b c");} } puts "All $nTest tests passed" exit } # End of internal test code. #------------------------------------------------------------------------- sqlidx_init_context D process_cmdline_args D $argv open_database D analyze_selects D find_trial_indexes D foreach idx [run_trials D] { puts $idx } |