Fix the schemalint.tcl script to handle identifiers that require quoting.
FossilOrigin-Name: 451e0fafbe5b7e9c67d9b584d5e16796c3196881
This commit is contained in:
parent
323f7d3fc6
commit
c45bf341af
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
||||
C In\sthe\sCREATE\sINDEX\sstatements\soutput\sby\sschemalint.tcl,\savoid\sdeclaring\san\sexplicit\scollation\ssequence\sthat\sis\sthe\ssame\sas\sthe\scolumn's\sdefault.
|
||||
D 2015-11-23T18:28:07.584
|
||||
C Fix\sthe\sschemalint.tcl\sscript\sto\shandle\sidentifiers\sthat\srequire\squoting.
|
||||
D 2015-11-30T18:17:55.036
|
||||
F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc e928e68168df69b353300ac87c10105206653a03
|
||||
@ -416,7 +416,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||
F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
|
||||
F src/where.c 5804902239731a7025240f4338d98cdc57315636
|
||||
F src/where.c be09f4a0513f885845ae481324c2e07603f88b38
|
||||
F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647
|
||||
F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b
|
||||
F src/whereexpr.c bd4877cd4dd11f6ab551ef0054535ca3c6224950
|
||||
@ -973,7 +973,7 @@ F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
|
||||
F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38
|
||||
F test/schema4.test e6a66e20cc69f0e306667c08be7fda3d11707dc5
|
||||
F test/schema5.test 29699b4421f183c8f0e88bd28ce7d75d13ea653e
|
||||
F test/schemalint.test 7fba0e262353c8c3dd5ee406cb11cf90f8b566fe
|
||||
F test/schemalint.test cee9f375637fcc8c6e77d971abe044445c23e024
|
||||
F test/securedel.test 21749c32ccc30f1ea9e4b9f33295a6521ec20fa0
|
||||
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
|
||||
F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686
|
||||
@ -1381,7 +1381,7 @@ F tool/replace.tcl 7727c60a04299b65a92f5e1590896fea0f25b9e0
|
||||
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
|
||||
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
|
||||
F tool/run-speed-test.sh 0ae485af4fe9f826e2b494be8c81f8ca9e222a4a
|
||||
F tool/schemalint.tcl ad61083d39cb40e848b9acc1273e4c487bb55cd7
|
||||
F tool/schemalint.tcl 2f44d0874061a948f6ef53505062db4ac9806cf7
|
||||
F tool/showdb.c d4476e000a64eca9f5e2c2f68741e747b9778e8d
|
||||
F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818
|
||||
F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68
|
||||
@ -1406,7 +1406,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 8f1ef0904d055b5510ec9043810ebf22a8c5e253
|
||||
R 4b9b445c1607ad5c9f9bdcf33b4eb416
|
||||
P d3aa067c830e98f2074630c4613c557b0ce90a57
|
||||
R aed657578ea11902053a31be3048325d
|
||||
U dan
|
||||
Z 6d9149db2c512107280c4e32c490b8cb
|
||||
Z 94438cf65b515737c9a10851485e87ac
|
||||
|
@ -1 +1 @@
|
||||
d3aa067c830e98f2074630c4613c557b0ce90a57
|
||||
451e0fafbe5b7e9c67d9b584d5e16796c3196881
|
10
src/where.c
10
src/where.c
@ -3942,7 +3942,8 @@ static char *whereAppendSingleTerm(
|
||||
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
|
||||
|
||||
if( zOp ){
|
||||
const char *zFmt = bOr ? "%z{{%s %s %s %lld}}" : "%z{%s %s %s %lld}";
|
||||
const char *zFmt = bOr ? "%z{{%s \"%w\" \"%w\" %lld}}" :
|
||||
"%z{%s \"%w\" \"%w\" %lld}";
|
||||
zBuf = whereAppendPrintf(db, zFmt, zIn,
|
||||
zOp, pTab->aCol[pTerm->u.leftColumn].zName,
|
||||
(pColl ? pColl->zName : "BINARY"),
|
||||
@ -4025,7 +4026,7 @@ static void whereTraceBuilder(
|
||||
nCol = pTab->nCol;
|
||||
|
||||
/* Append the table name to the buffer. */
|
||||
zBuf = whereAppendPrintf(db, "%s", pTab->zName);
|
||||
zBuf = whereAppendPrintf(db, "\"%w\"", pTab->zName);
|
||||
|
||||
/* Append the list of columns required to create a covering index */
|
||||
zBuf = whereAppendPrintf(db, "%z {cols", zBuf);
|
||||
@ -4033,7 +4034,8 @@ static void whereTraceBuilder(
|
||||
for(iCol=0; iCol<nCol; iCol++){
|
||||
if( iCol==(sizeof(Bitmask)*8-1) ) break;
|
||||
if( pItem->colUsed & ((u64)1 << iCol) ){
|
||||
zBuf = whereAppendPrintf(db, "%z %s", zBuf, pTab->aCol[iCol].zName);
|
||||
const char *zName = pTab->aCol[iCol].zName;
|
||||
zBuf = whereAppendPrintf(db, "%z \"%w\"", zBuf, zName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4054,7 +4056,7 @@ static void whereTraceBuilder(
|
||||
if( pExpr->op==TK_COLUMN && pExpr->iTable==pItem->iCursor ){
|
||||
if( pExpr->iColumn>=0 ){
|
||||
const char *zName = pTab->aCol[pExpr->iColumn].zName;
|
||||
zBuf = whereAppendPrintf(db, "%z%s%s %s %s", zBuf,
|
||||
zBuf = whereAppendPrintf(db, "%z%s\"%w\" \"%w\" %s", zBuf,
|
||||
bFirst ? " {orderby " : " ", zName, pColl->zName,
|
||||
(pOrderBy->a[i].sortOrder ? "DESC" : "ASC")
|
||||
);
|
||||
|
@ -27,33 +27,33 @@ do_execsql_test 1.0 {
|
||||
do_trace_test 1.1 {
|
||||
SELECT b, c, y, z FROM t1, t2 WHERE c=? AND z=?
|
||||
} {
|
||||
{t1 {cols b c} {eq c BINARY 0}}
|
||||
{t2 {cols y z} {eq z BINARY 0}}
|
||||
{"t1" {cols "b" "c"} {eq "c" "BINARY" 0}}
|
||||
{"t2" {cols "y" "z"} {eq "z" "BINARY" 0}}
|
||||
}
|
||||
|
||||
do_trace_test 1.2 {
|
||||
SELECT a FROM t1 WHERE b>10
|
||||
} {
|
||||
{t1 {cols a b} {range b BINARY 0}}
|
||||
{"t1" {cols "a" "b"} {range "b" "BINARY" 0}}
|
||||
}
|
||||
|
||||
do_trace_test 1.3 {
|
||||
SELECT b FROM t1 WHERE b IN (10, 20, 30)
|
||||
} {
|
||||
{t1 {cols b} {eq b BINARY 0}}
|
||||
{"t1" {cols "b"} {eq "b" "BINARY" 0}}
|
||||
}
|
||||
|
||||
do_trace_test 1.4 {
|
||||
SELECT * FROM t1, t2 WHERE x=a
|
||||
} {
|
||||
{t1 {cols a b c} {eq a BINARY 2}}
|
||||
{t2 {cols x y z} {eq x BINARY 1}}
|
||||
{"t1" {cols "a" "b" "c"} {eq "a" "BINARY" 2}}
|
||||
{"t2" {cols "x" "y" "z"} {eq "x" "BINARY" 1}}
|
||||
}
|
||||
|
||||
do_trace_test 1.5 {
|
||||
SELECT * FROM t1 WHERE a IN (1, 2, 3)
|
||||
} {
|
||||
{t1 {cols a b c} {eq a BINARY 0}}
|
||||
{"t1" {cols "a" "b" "c"} {eq "a" "BINARY" 0}}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
@ -62,19 +62,19 @@ do_trace_test 1.5 {
|
||||
do_trace_test 2.1 {
|
||||
SELECT * FROM t1 WHERE a=? OR b=?
|
||||
} {
|
||||
{t1 {cols a b c} {or {{eq a BINARY 0}} {{eq b BINARY 0}}}}
|
||||
{"t1" {cols "a" "b" "c"} {or {{eq "a" "BINARY" 0}} {{eq "b" "BINARY" 0}}}}
|
||||
}
|
||||
|
||||
do_trace_test 2.2 {
|
||||
SELECT * FROM t1 WHERE a=? OR (b=? AND c=?)
|
||||
} {
|
||||
{t1 {cols a b c} {or {{eq a BINARY 0}} {{eq b BINARY 0} {eq c BINARY 0}}}}
|
||||
{"t1" {cols "a" "b" "c"} {or {{eq "a" "BINARY" 0}} {{eq "b" "BINARY" 0} {eq "c" "BINARY" 0}}}}
|
||||
}
|
||||
|
||||
do_trace_test 2.3 {
|
||||
SELECT * FROM t1 WHERE (a=? AND b=?) OR c=?
|
||||
} {
|
||||
{t1 {cols a b c} {or {{eq c BINARY 0}} {{eq a BINARY 0} {eq b BINARY 0}}}}
|
||||
{"t1" {cols "a" "b" "c"} {or {{eq "c" "BINARY" 0}} {{eq "a" "BINARY" 0} {eq "b" "BINARY" 0}}}}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
@ -82,19 +82,19 @@ do_trace_test 2.3 {
|
||||
#
|
||||
do_trace_test 3.1 {
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
} {{t1 {cols a b c} {orderby a BINARY ASC}}}
|
||||
} {{"t1" {cols "a" "b" "c"} {orderby "a" "BINARY" ASC}}}
|
||||
|
||||
do_trace_test 3.2 {
|
||||
SELECT * FROM t1 WHERE a=? ORDER BY b;
|
||||
} {{t1 {cols a b c} {eq a BINARY 0} {orderby b BINARY ASC}}}
|
||||
} {{"t1" {cols "a" "b" "c"} {eq "a" "BINARY" 0} {orderby "b" "BINARY" ASC}}}
|
||||
|
||||
do_trace_test 3.3 {
|
||||
SELECT min(a) FROM t1;
|
||||
} {{t1 {cols a} {orderby a BINARY ASC}}}
|
||||
} {{"t1" {cols "a"} {orderby "a" "BINARY" ASC}}}
|
||||
|
||||
do_trace_test 3.4 {
|
||||
SELECT max(a) FROM t1;
|
||||
} {{t1 {cols a} {orderby a BINARY DESC}}}
|
||||
} {{"t1" {cols "a"} {orderby "a" "BINARY" DESC}}}
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -11,6 +11,41 @@ proc usage {} {
|
||||
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]
|
||||
@ -139,11 +174,11 @@ proc eqset_to_index {ctxvar aCollVar tname eqset {range {}}} {
|
||||
|
||||
foreach {c collate dir} $rangeset {
|
||||
append idxname "_$c"
|
||||
set coldef $c
|
||||
set coldef [quote $c]
|
||||
|
||||
if {[string compare -nocase $collate $aColl($c)]!=0} {
|
||||
append idxname [string tolower $collate]
|
||||
append coldef " COLLATE $collate"
|
||||
append coldef " COLLATE [quote $collate]"
|
||||
}
|
||||
|
||||
if {$dir=="DESC"} {
|
||||
@ -153,7 +188,7 @@ proc eqset_to_index {ctxvar aCollVar tname eqset {range {}}} {
|
||||
lappend lCols $coldef
|
||||
}
|
||||
|
||||
set create_index "CREATE INDEX $idxname ON ${tname}("
|
||||
set create_index "CREATE INDEX [quote $idxname] ON [quote $tname]("
|
||||
append create_index [join $lCols ", "]
|
||||
append create_index ");"
|
||||
|
||||
@ -185,12 +220,27 @@ proc expand_or_cons {L} {
|
||||
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]
|
||||
db eval "PRAGMA table_info = $tname" x { lappend colnames $x(name) }
|
||||
db eval "CREATE INDEX schemalint_test ON ${tname}([join $colnames ,])"
|
||||
|
||||
set qname [quote $tname]
|
||||
db eval "PRAGMA table_info = $qname" x { lappend colnames $x(name) }
|
||||
db eval "CREATE INDEX schemalint_test ON ${qname}([list_to_sql $colnames])"
|
||||
db eval "PRAGMA index_xinfo = schemalint_test" x {
|
||||
set aColl($x(name)) $x(coll)
|
||||
}
|
||||
@ -348,6 +398,7 @@ proc sqlidx_one_test {tn schema select expected} {
|
||||
sqlidx_init_context C
|
||||
|
||||
sqlite3 db ""
|
||||
db collate "a b c" [list string compare]
|
||||
db eval $schema
|
||||
lappend C(lSelect) $select
|
||||
analyze_selects C
|
||||
@ -362,9 +413,14 @@ proc sqlidx_one_test {tn schema select expected} {
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -440,6 +496,58 @@ proc sqlidx_internal_tests {} {
|
||||
{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.
|
||||
|
Loading…
Reference in New Issue
Block a user