-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
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
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
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
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
-d3aa067c830e98f2074630c4613c557b0ce90a57
\ No newline at end of file
+451e0fafbe5b7e9c67d9b584d5e16796c3196881
\ No newline at end of file
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"),
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);
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);
}
}
}
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")
);
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}}
}
#-----------------------------------------------------------------------
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}}}}
}
#-----------------------------------------------------------------------
#
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
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]
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"} {
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 ");"
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)
}
sqlidx_init_context C
sqlite3 db ""
+ db collate "a b c" [list string compare]
db eval $schema
lappend C(lSelect) $select
analyze_selects C
}
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 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.