From e31dc59b4cffa519fc892b491c95d5866da9a66c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 14 Aug 2015 12:53:37 +0000 Subject: [PATCH 01/21] Duplicate the output of releasetest.tcl into releasetest-out.txt FossilOrigin-Name: 5e06a9c186f4b7478c73155613de219d702e0241 --- manifest | 14 +++---- manifest.uuid | 2 +- test/releasetest.tcl | 92 ++++++++++++++++++++++++++------------------ 3 files changed, 62 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index 3ec7d5e743..9ef66e0ebd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3rbu_savestate()\sfunction\sto\sthe\srbu\sextension.\sTo\sforce\srbu\sto\ssave\sits\sstate\sto\sdisk\swithout\sclosing\sthe\ssqlite3rbu*\shandle. -D 2015-08-13T18:26:09.242 +C Duplicate\sthe\soutput\sof\sreleasetest.tcl\sinto\sreleasetest-out.txt +D 2015-08-14T12:53:37.201 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -930,7 +930,7 @@ F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736 F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl b46812b9506f22d69c26f66808b90eb1b0318eec +F test/releasetest.tcl cd2de2749aab7f45b2fe91b4a05431fc08e1692a F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea F test/rollback2.test fc14cf6d1a2b250d2735ef16124b971bce152f14 @@ -1373,7 +1373,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ee966af8ff79189f8b90f3557dea21059517dfe2 -R 5dcd61cef4d3f59a3e6f61e4cf60159a -U dan -Z bdea05956aba407287af182409a84a65 +P 851a875ad6b81f90960caf4d03b116afc911858d +R 516c4f09812f47621a9f17c1076f8b21 +U drh +Z 7ae775e3576234c15153da91a23c9d24 diff --git a/manifest.uuid b/manifest.uuid index f6ed1de738..a49c7191a8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -851a875ad6b81f90960caf4d03b116afc911858d \ No newline at end of file +5e06a9c186f4b7478c73155613de219d702e0241 \ No newline at end of file diff --git a/test/releasetest.tcl b/test/releasetest.tcl index 73ca62c759..eadf69ce81 100644 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -286,6 +286,22 @@ foreach {key value} [array get ::Platforms] { } } +# Output log +# +set LOG [open releasetest-out.txt w] +proc PUTS {args} { + if {[llength $args]==2} { + puts [lindex $args 0] [lindex $args 1] + puts [lindex $args 0] $::LOG [lindex $args 1] + } else { + puts [lindex $args 0] + puts $::LOG [lindex $args 0] + } +} +puts $LOG "$argv0 $argv" +set tm0 [clock format [clock seconds] -format {%Y-%m-%d %H:%M:%S} -gmt 1] +puts $LOG "start-time: $tm0 UTC" + # Open the file $logfile and look for a report on the number of errors # and the number of test cases run. Add these values to the global # $::NERRCASE and $::NTESTCASE variables. @@ -408,7 +424,7 @@ proc run_test_suite {name testtarget config} { if {!$::TRACE} { set n [string length $title] - puts -nonewline "${title}[string repeat . [expr {63-$n}]]" + PUTS -nonewline "${title}[string repeat . [expr {63-$n}]]" flush stdout } @@ -433,12 +449,12 @@ proc run_test_suite {name testtarget config} { set seconds [expr {($tm2-$tm1)%60}] set tm [format (%02d:%02d:%02d) $hours $minutes $seconds] if {$rc} { - puts " FAIL $tm" + PUTS " FAIL $tm" incr ::NERR } else { - puts " Ok $tm" + PUTS " Ok $tm" } - if {$errmsg!=""} {puts " $errmsg"} + if {$errmsg!=""} {PUTS " $errmsg"} } } @@ -480,7 +496,7 @@ proc makeCommand { targets cflags opts } { # proc trace_cmd {args} { if {$::TRACE} { - puts $args + PUTS $args } if {!$::DRYRUN} { uplevel 1 $args @@ -548,25 +564,25 @@ proc process_options {argv} { } -info { - puts "Command-line Options:" - puts " --srcdir $::SRCDIR" - puts " --platform [list $platform]" - puts " --config [list $config]" + PUTS "Command-line Options:" + PUTS " --srcdir $::SRCDIR" + PUTS " --platform [list $platform]" + PUTS " --config [list $config]" if {$::QUICK} { - if {$::QUICK==1} {puts " --quick"} - if {$::QUICK==2} {puts " --veryquick"} + if {$::QUICK==1} {PUTS " --quick"} + if {$::QUICK==2} {PUTS " --veryquick"} } - if {$::MSVC} {puts " --msvc"} - if {$::BUILDONLY} {puts " --buildonly"} - if {$::DRYRUN} {puts " --dryrun"} - if {$::TRACE} {puts " --trace"} - puts "\nAvailable --platform options:" + if {$::MSVC} {PUTS " --msvc"} + if {$::BUILDONLY} {PUTS " --buildonly"} + if {$::DRYRUN} {PUTS " --dryrun"} + if {$::TRACE} {PUTS " --trace"} + PUTS "\nAvailable --platform options:" foreach y [lsort [array names ::Platforms]] { - puts " [list $y]" + PUTS " [list $y]" } - puts "\nAvailable --config options:" + PUTS "\nAvailable --config options:" foreach y [lsort [array names ::Configs]] { - puts " [list $y]" + PUTS " [list $y]" } exit } @@ -592,22 +608,22 @@ proc process_options {argv} { } default { - puts stderr "" - puts stderr [string trim $::USAGE_MESSAGE] + PUTS stderr "" + PUTS stderr [string trim $::USAGE_MESSAGE] exit -1 } } } if {0==[info exists ::Platforms($platform)]} { - puts "Unknown platform: $platform" - puts -nonewline "Set the -platform option to " + PUTS "Unknown platform: $platform" + PUTS -nonewline "Set the -platform option to " set print [list] foreach p [array names ::Platforms] { lappend print "\"$p\"" } lset print end "or [lindex $print end]" - puts "[join $print {, }]." + PUTS "[join $print {, }]." exit } @@ -617,17 +633,17 @@ proc process_options {argv} { } else { set ::CONFIGLIST $::Platforms($platform) } - puts "Running the following test configurations for $platform:" - puts " [string trim $::CONFIGLIST]" - puts -nonewline "Flags:" - if {$::DRYRUN} {puts -nonewline " --dryrun"} - if {$::BUILDONLY} {puts -nonewline " --buildonly"} - if {$::MSVC} {puts -nonewline " --msvc"} + PUTS "Running the following test configurations for $platform:" + PUTS " [string trim $::CONFIGLIST]" + PUTS -nonewline "Flags:" + if {$::DRYRUN} {PUTS -nonewline " --dryrun"} + if {$::BUILDONLY} {PUTS -nonewline " --buildonly"} + if {$::MSVC} {PUTS -nonewline " --msvc"} switch -- $::QUICK { - 1 {puts -nonewline " --quick"} - 2 {puts -nonewline " --veryquick"} + 1 {PUTS -nonewline " --quick"} + 2 {PUTS -nonewline " --veryquick"} } - puts "" + PUTS "" } # Main routine. @@ -637,7 +653,7 @@ proc main {argv} { # Process any command line options. set ::EXTRACONFIG {} process_options $argv - puts [string repeat * 79] + PUTS [string repeat * 79] set ::NERR 0 set ::NTEST 0 @@ -648,7 +664,7 @@ proc main {argv} { foreach {zConfig target} $::CONFIGLIST { if {$::MSVC && ($zConfig eq "Sanitize" || "checksymbols" in $target || "valgrindtest" in $target)} { - puts "Skipping $zConfig / $target for MSVC..." + PUTS "Skipping $zConfig / $target for MSVC..." continue } if {$target ne "checksymbols"} { @@ -693,10 +709,10 @@ proc main {argv} { set min [expr {($elapsetime/60)%60}] set sec [expr {$elapsetime%60}] set etime [format (%02d:%02d:%02d) $hr $min $sec] - puts [string repeat * 79] - puts "$::NERRCASE failures out of $::NTESTCASE tests in $etime" + PUTS [string repeat * 79] + PUTS "$::NERRCASE failures out of $::NTESTCASE tests in $etime" if {$::SQLITE_VERSION ne ""} { - puts "SQLite $::SQLITE_VERSION" + PUTS "SQLite $::SQLITE_VERSION" } } From d5a74c8e19b9f2e6a112dae4c307768b07250589 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 15 Aug 2015 16:32:50 +0000 Subject: [PATCH 02/21] Minor fix to the display of oversized KeyInfo structures in the P4 operand of Open opcodes in EXPLAIN output. FossilOrigin-Name: f65a9b4ab2c6f0b7028e16e2a0f83fd6d58ae1cd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9ef66e0ebd..64b99f5731 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Duplicate\sthe\soutput\sof\sreleasetest.tcl\sinto\sreleasetest-out.txt -D 2015-08-14T12:53:37.201 +C Minor\sfix\sto\sthe\sdisplay\sof\soversized\sKeyInfo\sstructures\sin\sthe\sP4\soperand\nof\sOpen\sopcodes\sin\sEXPLAIN\soutput. +D 2015-08-15T16:32:50.350 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -402,7 +402,7 @@ F src/vdbe.c 2ab1decd98925f8cd846993dde9dccaa69cdf0ef F src/vdbe.h 7a75045d879118b9d3af7e8b3c108f2f27c51473 F src/vdbeInt.h 8b54e01ad0463590e7cffabce0bc36da9ee4f816 F src/vdbeapi.c adabbd66eb2e3a10f3998485ee0be7e326d06ee4 -F src/vdbeaux.c 787f5f9d58f4c6f39294ed06909ba602d1a402e6 +F src/vdbeaux.c af2d86b2b114a106c94fc656503fc5c89594f5af F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090 F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b @@ -1373,7 +1373,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 851a875ad6b81f90960caf4d03b116afc911858d -R 516c4f09812f47621a9f17c1076f8b21 +P 5e06a9c186f4b7478c73155613de219d702e0241 +R e2d0516338dae0688a20852b1e6916a7 U drh -Z 7ae775e3576234c15153da91a23c9d24 +Z 80e45157bf277dcf2578e84040f9a7f0 diff --git a/manifest.uuid b/manifest.uuid index a49c7191a8..4f073b073f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e06a9c186f4b7478c73155613de219d702e0241 \ No newline at end of file +f65a9b4ab2c6f0b7028e16e2a0f83fd6d58ae1cd \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 08dc885df6..e866e9dcfe 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1094,8 +1094,9 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ zColl = "B"; n = 1; } - if( i+n>nTemp-6 ){ + if( i+n>nTemp-7 ){ memcpy(&zTemp[i],",...",4); + i += 4; break; } zTemp[i++] = ','; From 0cbb513a67b4d0a515ead8f925d5e0a8752dfcb8 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 18 Aug 2015 16:32:45 +0000 Subject: [PATCH 03/21] Fix harmless compiler warning in FTS5. FossilOrigin-Name: 02448a9fccd4532daa667e4ba6ff1dbb7f68008a --- ext/fts5/fts5_expr.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 559eead223..a713bb7c5a 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -1866,7 +1866,7 @@ static void fts5ExprFunction( int iArg = 1; if( nArg<1 ){ - char *zErr = sqlite3_mprintf("wrong number of arguments to function %s", + zErr = sqlite3_mprintf("wrong number of arguments to function %s", bTcl ? "fts5_expr_tcl" : "fts5_expr" ); sqlite3_result_error(pCtx, zErr, -1); diff --git a/manifest b/manifest index 64b99f5731..8add10892e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sfix\sto\sthe\sdisplay\sof\soversized\sKeyInfo\sstructures\sin\sthe\sP4\soperand\nof\sOpen\sopcodes\sin\sEXPLAIN\soutput. -D 2015-08-15T16:32:50.350 +C Fix\sharmless\scompiler\swarning\sin\sFTS5. +D 2015-08-18T16:32:45.211 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -110,7 +110,7 @@ F ext/fts5/fts5Int.h 45f2ceb3c030f70e2cc4c199e9f700c2f2367f77 F ext/fts5/fts5_aux.c 044cb176a815f4388308738437f6e130aa384fb0 F ext/fts5/fts5_buffer.c 80f9ba4431848cb857e3d2158f5280093dcd8015 F ext/fts5/fts5_config.c fdfa63ae8e527ecfaa50f94063c610429cc887cf -F ext/fts5/fts5_expr.c 495b24f47f4d71b63339572a5beaf9f6e1b486fe +F ext/fts5/fts5_expr.c d075d36c84975a1cfcf070442d28e28027b61c25 F ext/fts5/fts5_hash.c 4bf4b99708848357b8a2b5819e509eb6d3df9246 F ext/fts5/fts5_index.c 076c4995bf06a6d1559a6e31f9a86b90f2105374 F ext/fts5/fts5_main.c fc47ad734dfb55765b7542a345cee981170e7caa @@ -1373,7 +1373,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5e06a9c186f4b7478c73155613de219d702e0241 -R e2d0516338dae0688a20852b1e6916a7 -U drh -Z 80e45157bf277dcf2578e84040f9a7f0 +P f65a9b4ab2c6f0b7028e16e2a0f83fd6d58ae1cd +R 991670fb0c06e37ef5a984fb7f069a97 +U mistachkin +Z 6b28dc07256cbacd1d8439eff1dbe32a diff --git a/manifest.uuid b/manifest.uuid index 4f073b073f..355b99a2e1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f65a9b4ab2c6f0b7028e16e2a0f83fd6d58ae1cd \ No newline at end of file +02448a9fccd4532daa667e4ba6ff1dbb7f68008a \ No newline at end of file From c1e63be3601e5a287c97f946a2a49a4761509176 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 18 Aug 2015 19:09:28 +0000 Subject: [PATCH 04/21] Add test file spellfix2.test, which should have been checked in some time ago. FossilOrigin-Name: 8599402092537ab3df8926eb900661c12d738d4c --- manifest | 13 ++--- manifest.uuid | 2 +- test/spellfix2.test | 114 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 test/spellfix2.test diff --git a/manifest b/manifest index 8add10892e..e8d8f571a1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning\sin\sFTS5. -D 2015-08-18T16:32:45.211 +C Add\stest\sfile\sspellfix2.test,\swhich\sshould\shave\sbeen\schecked\sin\ssome\stime\sago. +D 2015-08-18T19:09:28.809 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1016,6 +1016,7 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/speedtest1.c 857439869d1cb4db35e1c720ee9c2756eb9ea2a0 F test/spellfix.test 0597065ff57042df1f138e6a2611ae19c2698135 +F test/spellfix2.test e5f2bc1dae046dbdd8008f2a84ed7749ff9b325e F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5 F test/sqllimits1.test e05786eaed7950ff6a2d00031d001d8a26131e68 F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf @@ -1373,7 +1374,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f65a9b4ab2c6f0b7028e16e2a0f83fd6d58ae1cd -R 991670fb0c06e37ef5a984fb7f069a97 -U mistachkin -Z 6b28dc07256cbacd1d8439eff1dbe32a +P 02448a9fccd4532daa667e4ba6ff1dbb7f68008a +R e8ec4f5131e6ed0a1e842df7f619d541 +U dan +Z 8dc6a1f25685915b0d47708aa8d01a68 diff --git a/manifest.uuid b/manifest.uuid index 355b99a2e1..5d84140b43 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -02448a9fccd4532daa667e4ba6ff1dbb7f68008a \ No newline at end of file +8599402092537ab3df8926eb900661c12d738d4c \ No newline at end of file diff --git a/test/spellfix2.test b/test/spellfix2.test new file mode 100644 index 0000000000..b4614a9e1f --- /dev/null +++ b/test/spellfix2.test @@ -0,0 +1,114 @@ +# 2012 July 12 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix spellfix2 + +ifcapable !vtab { finish_test ; return } +load_static_extension db spellfix nextchar + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE demo USING spellfix1; + INSERT INTO demo(word) VALUES ('amsterdam'); + INSERT INTO demo(word) VALUES ('amsterdammetje'); + INSERT INTO demo(word) VALUES ('amsterdamania'); + INSERT INTO demo(word) VALUES ('amsterdamweg'); + INSERT INTO demo(word) VALUES ('amsterdamsestraat'); + INSERT INTO demo(word) VALUES ('amsterdamlaan'); +} + +do_execsql_test 1.1 { + SELECT word, distance, matchlen FROM demo + WHERE word MATCH 'amstedam*' AND top=3; +} { + amsterdam 100 9 + amsterdammetje 100 9 + amsterdamania 100 9 +} + +do_execsql_test 1.2 { + SELECT word, distance, matchlen FROM demo WHERE + word MATCH 'amstedam*' AND top=3 AND distance <= 100; +} { + amsterdam 100 9 + amsterdammetje 100 9 + amsterdamania 100 9 +} + +do_execsql_test 1.3 { + SELECT word, distance, matchlen FROM demo WHERE + word MATCH 'amstedam*' AND distance <= 100; +} { + amsterdam 100 9 + amsterdammetje 100 9 + amsterdamania 100 9 + amsterdamweg 100 9 + amsterdamsestraat 100 9 + amsterdamlaan 100 9 +} + +do_test 1.4 { + foreach l {a b c d e f g h i j k l m n o p q r s t u v w x y z} { + execsql { INSERT INTO demo(word) VALUES ('amsterdam' || $l) } + } +} {} + +do_execsql_test 1.5 { + SELECT count(*) FROM demo WHERE word MATCH 'amstedam*' AND distance <= 100; + SELECT count(*) FROM demo + WHERE word MATCH 'amstedam*' AND distance <= 100 AND top=20; +} { + 32 20 +} + +do_execsql_test 1.6 { + SELECT word, distance, matchlen FROM demo + WHERE word MATCH 'amstedam*' AND distance <= 100; +} { + amsterdam 100 9 amsterdamh 100 9 + amsterdamm 100 9 amsterdamn 100 9 + amsterdama 100 9 amsterdame 100 9 + amsterdami 100 9 amsterdamo 100 9 + amsterdamu 100 9 amsterdamy 100 9 + amsterdammetje 100 9 amsterdamania 100 9 + amsterdamb 100 9 amsterdamf 100 9 + amsterdamp 100 9 amsterdamv 100 9 + amsterdamw 100 9 amsterdamweg 100 9 + amsterdamc 100 9 amsterdamg 100 9 + amsterdamj 100 9 amsterdamk 100 9 + amsterdamq 100 9 amsterdams 100 9 + amsterdamx 100 9 amsterdamz 100 9 + amsterdamsestraat 100 9 amsterdamd 100 9 + amsterdamt 100 9 amsterdaml 100 9 + amsterdamlaan 100 9 amsterdamr 100 9 +} + +do_execsql_test 1.7 { + SELECT word, distance, matchlen FROM demo + WHERE word MATCH 'amstedam*' AND distance <= 100 AND top=20; +} { + amsterdam 100 9 amsterdamh 100 9 + amsterdamm 100 9 amsterdamn 100 9 + amsterdama 100 9 amsterdame 100 9 + amsterdami 100 9 amsterdamo 100 9 + amsterdamu 100 9 amsterdamy 100 9 + amsterdammetje 100 9 amsterdamania 100 9 + amsterdamb 100 9 amsterdamf 100 9 + amsterdamp 100 9 amsterdamv 100 9 + amsterdamw 100 9 amsterdamweg 100 9 + amsterdamc 100 9 amsterdamg 100 9 +} + + +finish_test + From 51be3873c0ab0c8191f8e96b96dc908329b87014 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Aug 2015 02:32:25 +0000 Subject: [PATCH 05/21] Initial implementation of eponymous virtual table instances. FossilOrigin-Name: c1f43a7799a9298abea01b2f8531fc7cdadc4594 --- manifest | 23 ++++++++++-------- manifest.uuid | 2 +- src/build.c | 15 +++++++++--- src/main.c | 9 ++++++- src/sqliteInt.h | 4 ++++ src/vtab.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 100 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 8add10892e..6bf5e47402 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning\sin\sFTS5. -D 2015-08-18T16:32:45.211 +C Initial\simplementation\sof\seponymous\svirtual\stable\sinstances. +D 2015-08-19T02:32:25.892 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c f48b3ef91676c06a90a8832987ecef6b94c931ee F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 -F src/build.c 4acc35c4e0a2d94c906abd164568cd6fc989cfbb +F src/build.c 77a9683d9202c091349d8d0bb40922c8dcc4784d F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b @@ -300,7 +300,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c 92bafa308607dd985ca389a788cd9e0a2b608712 F src/loadext.c dfcee8c7c032cd0fd55af3e0fc1fcfb01e426df2 -F src/main.c 0a60b7ca8252c3a6f95438fa4ce8fe5b275c69f2 +F src/main.c e17fcffae4306a9b8334faf3bac80d7396850b54 F src/malloc.c 19461e159bccf0e2cf06a50e867963d0a7b124a8 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987 @@ -340,7 +340,7 @@ F src/shell.c b1f91e60918df3a68efad1e3a11696b9a7e23d23 F src/sqlite.h.in 447ead0a6b3293206f04a0896553955d07cfb4b9 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h a0b948ebc89bac13941254641326a6aa248c2cc4 -F src/sqliteInt.h 9401d7d9124210dfd5d283af45e0addbc1455c2e +F src/sqliteInt.h 683b48027374e20bea20e36180984be07bb03031 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -407,7 +407,7 @@ F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090 F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 -F src/vtab.c 082b35a25a26e3d36f365ca8cd73c1922532f05e +F src/vtab.c be5a43432b78ddea55bd9f81f23e791da7282814 F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 6fb6b68969e4692593c2552c4e7bff5882de2cb8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 @@ -1373,7 +1373,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f65a9b4ab2c6f0b7028e16e2a0f83fd6d58ae1cd -R 991670fb0c06e37ef5a984fb7f069a97 -U mistachkin -Z 6b28dc07256cbacd1d8439eff1dbe32a +P 02448a9fccd4532daa667e4ba6ff1dbb7f68008a +R ae3efec9cf124146c8c51adef7f17b8d +T *branch * eponymous-vtab +T *sym-eponymous-vtab * +T -sym-trunk * +U drh +Z fd6dce9accc0175e77ceea23601f0413 diff --git a/manifest.uuid b/manifest.uuid index 355b99a2e1..4dbd4bdb65 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -02448a9fccd4532daa667e4ba6ff1dbb7f68008a \ No newline at end of file +c1f43a7799a9298abea01b2f8531fc7cdadc4594 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 4731eb1869..7cf9fe2f90 100644 --- a/src/build.c +++ b/src/build.c @@ -355,6 +355,15 @@ Table *sqlite3LocateTable( p = sqlite3FindTable(pParse->db, zName, zDbase); if( p==0 ){ +#ifndef SQLITE_OMIT_VIRTUAL_TABLE + /* If zName is the not the name of a table in the schema created using + ** CREATE, then check to see if it is the name of an virtual table that + ** can be an eponymous virtual table. */ + Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName); + if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ + return pMod->pEpoTab; + } +#endif const char *zMsg = isView ? "no such view" : "no such table"; if( zDbase ){ sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); @@ -560,7 +569,7 @@ void sqlite3CommitInternalChanges(sqlite3 *db){ ** Delete memory allocated for the column names of a table or view (the ** Table.aCol[] array). */ -static void sqliteDeleteColumnNames(sqlite3 *db, Table *pTable){ +void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ int i; Column *pCol; assert( pTable!=0 ); @@ -627,7 +636,7 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ /* Delete the Table structure itself. */ - sqliteDeleteColumnNames(db, pTable); + sqlite3DeleteColumnNames(db, pTable); sqlite3DbFree(db, pTable->zName); sqlite3DbFree(db, pTable->zColAff); sqlite3SelectDelete(db, pTable->pSelect); @@ -2218,7 +2227,7 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){ for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){ Table *pTab = sqliteHashData(i); if( pTab->pSelect ){ - sqliteDeleteColumnNames(db, pTab); + sqlite3DeleteColumnNames(db, pTab); pTab->aCol = 0; pTab->nCol = 0; } diff --git a/src/main.c b/src/main.c index 36206eec8c..575cad92c5 100644 --- a/src/main.c +++ b/src/main.c @@ -932,17 +932,23 @@ static void functionDestroy(sqlite3 *db, FuncDef *p){ static void disconnectAllVtab(sqlite3 *db){ #ifndef SQLITE_OMIT_VIRTUALTABLE int i; + HashElem *p; sqlite3BtreeEnterAll(db); for(i=0; inDb; i++){ Schema *pSchema = db->aDb[i].pSchema; if( db->aDb[i].pSchema ){ - HashElem *p; for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ Table *pTab = (Table *)sqliteHashData(p); if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); } } } + for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){ + Module *pMod = (Module *)sqliteHashData(p); + if( pMod->pEpoTab ){ + sqlite3VtabDisconnect(db, pMod->pEpoTab); + } + } sqlite3VtabUnlockList(db); sqlite3BtreeLeaveAll(db); #else @@ -1120,6 +1126,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ if( pMod->xDestroy ){ pMod->xDestroy(pMod->pAux); } + sqlite3VtabEponymousTableClear(db, pMod); sqlite3DbFree(db, pMod); } sqlite3HashClear(&db->aModule); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9c79c91dfa..fb5067ef16 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1479,6 +1479,7 @@ struct Module { const char *zName; /* Name passed to create_module() */ void *pAux; /* pAux passed to create_module() */ void (*xDestroy)(void *); /* Module destructor function */ + Table *pEpoTab; /* Eponymous table for this module */ }; /* @@ -3248,6 +3249,7 @@ void sqlite3ResetOneSchema(sqlite3*,int); void sqlite3CollapseDatabaseArray(sqlite3*); void sqlite3BeginParse(Parse*,int); void sqlite3CommitInternalChanges(sqlite3*); +void sqlite3DeleteColumnNames(sqlite3*,Table*); Table *sqlite3ResultSetOfSelect(Parse*,Select*); void sqlite3OpenMasterTable(Parse *, int); Index *sqlite3PrimaryKeyIndex(Table*); @@ -3718,6 +3720,8 @@ void sqlite3AutoLoadExtensions(sqlite3*); VTable *sqlite3GetVTable(sqlite3*, Table*); # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) #endif +int sqlite3VtabEponymousTableInit(Parse*,Module*); +void sqlite3VtabEponymousTableClear(sqlite3*,Module*); void sqlite3VtabMakeWritable(Parse*,Table*); void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int); void sqlite3VtabFinishParse(Parse*, Token*); diff --git a/src/vtab.c b/src/vtab.c index 2ae861e67f..e0ed83ee39 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -58,6 +58,7 @@ static int createModule( pMod->pModule = pModule; pMod->pAux = pAux; pMod->xDestroy = xDestroy; + pMod->pEpoTab = 0; pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); assert( pDel==0 || pDel==pMod ); if( pDel ){ @@ -275,6 +276,7 @@ void sqlite3VtabClear(sqlite3 *db, Table *p){ if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]); } sqlite3DbFree(db, p->azModuleArg); + p->azModuleArg = 0; } } @@ -1092,6 +1094,66 @@ void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ } } +/* +** Check to see if virtual tale module pMod can be have an eponymous +** virtual table instance. If it can, create one if one does not already +** exist. Return non-zero if the eponymous virtual table instance exists +** when this routine returns, and return zero if it does not exist. +** +** An eponymous virtual table instance is one that is named after its +** module, and more importantly, does not require a CREATE VIRTUAL TABLE +** statement in order to come into existance. Eponymous virtual table +** instances always exist. They cannot be DROP-ed. +** +** Any virtual table module for which xConnect and xCreate are the same +** method can have an eponymous virtual table instance. +*/ +int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ + const sqlite3_module *pModule = pMod->pModule; + Table *pTab; + char *zErr = 0; + int nName; + int rc; + sqlite3 *db = pParse->db; + if( pMod->pEpoTab ) return 1; + if( pModule->xCreate!=pModule->xConnect ) return 0; + nName = sqlite3Strlen30(pMod->zName) + 1; + pTab = sqlite3DbMallocZero(db, sizeof(Table) + nName); + if( pTab==0 ) return 0; + pMod->pEpoTab = pTab; + pTab->zName = (char*)&pTab[1]; + memcpy(pTab->zName, pMod->zName, nName); + pTab->nRef = 1; + pTab->pSchema = db->aDb[0].pSchema; + pTab->tabFlags |= TF_Virtual; + pTab->nModuleArg = 0; + addModuleArgument(db, pTab, pTab->zName); + addModuleArgument(db, pTab, 0); + addModuleArgument(db, pTab, pTab->zName); + rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr); + if( rc ){ + sqlite3ErrorMsg(pParse, "%s", zErr); + sqlite3DbFree(db, zErr); + sqlite3VtabEponymousTableClear(db, pMod); + return 0; + } + return 1; +} + +/* +** Erase the eponymous virtual table instance associated with +** virtual table module pMod, if it exists. +*/ +void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){ + Table *pTab = pMod->pEpoTab; + if( (pTab = pMod->pEpoTab)!=0 ){ + sqlite3DeleteColumnNames(db, pTab); + sqlite3DbFree(db, pTab->azModuleArg); + sqlite3DbFree(db, pTab); + pMod->pEpoTab = 0; + } +} + /* ** Return the ON CONFLICT resolution mode in effect for the virtual ** table update operation currently in progress. From 5ef2b281aa6fed9a45b8bbe20a5f26c9a03cc677 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 19 Aug 2015 08:34:34 +0000 Subject: [PATCH 06/21] When updating a zipvfs database with RBU, set journal_mode=off to prevent the upper-level pager from creating a large temporary file. FossilOrigin-Name: dec14a3980dcf6c61b0b9ac4ba82fa963ac346d4 --- ext/rbu/sqlite3rbu.c | 15 +++++++++++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 403d4ebdcb..7c7480bcfc 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -3043,14 +3043,25 @@ sqlite3rbu *sqlite3rbu_open( if( p->rc==SQLITE_OK ){ if( p->eStage==RBU_STAGE_OAL ){ + sqlite3 *db = p->dbMain; /* Open transactions both databases. The *-oal file is opened or ** created at this point. */ - p->rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); + p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); if( p->rc==SQLITE_OK ){ p->rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); } - + + /* Check if the main database is a zipvfs db. If it is, set the upper + ** level pager to use "journal_mode=off". This prevents it from + ** generating a large journal using a temp file. */ + if( p->rc==SQLITE_OK ){ + int frc = sqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0); + if( frc==SQLITE_OK ){ + p->rc = sqlite3_exec(db, "PRAGMA journal_mode=off",0,0,&p->zErrmsg); + } + } + /* Point the object iterator at the first object */ if( p->rc==SQLITE_OK ){ p->rc = rbuObjIterFirst(p, &p->objiter); diff --git a/manifest b/manifest index e8d8f571a1..6862daf1ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\sfile\sspellfix2.test,\swhich\sshould\shave\sbeen\schecked\sin\ssome\stime\sago. -D 2015-08-18T19:09:28.809 +C When\supdating\sa\szipvfs\sdatabase\swith\sRBU,\sset\sjournal_mode=off\sto\sprevent\sthe\supper-level\spager\sfrom\screating\sa\slarge\stemporary\sfile. +D 2015-08-19T08:34:34.195 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -224,7 +224,7 @@ F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89 F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 -F ext/rbu/sqlite3rbu.c 08fddeae6b89aeb1e960f9330a2228968210170a +F ext/rbu/sqlite3rbu.c 1650e682b3568db0ed97ff2c7ba5d1c8ea060a84 F ext/rbu/sqlite3rbu.h 5357f070cd8c0bcad459b620651ec1656859e4d0 F ext/rbu/test_rbu.c 2a3652241fa45d5eaa141775e4ae68c1d3582c03 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1374,7 +1374,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 02448a9fccd4532daa667e4ba6ff1dbb7f68008a -R e8ec4f5131e6ed0a1e842df7f619d541 +P 8599402092537ab3df8926eb900661c12d738d4c +R 79cd53df2dc51b1e184555145183f89d U dan -Z 8dc6a1f25685915b0d47708aa8d01a68 +Z 080d9b0837b12f78f74559ebadf2ade0 diff --git a/manifest.uuid b/manifest.uuid index 5d84140b43..959045fb7f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8599402092537ab3df8926eb900661c12d738d4c \ No newline at end of file +dec14a3980dcf6c61b0b9ac4ba82fa963ac346d4 \ No newline at end of file From 0e07f6ae402bf01a0db96910cdf3ca8e3492553c Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Aug 2015 12:45:57 +0000 Subject: [PATCH 07/21] Simplification to error handling in addModuleArgument() in the virtual table processing. FossilOrigin-Name: c573b0a1aa3ba509234f07520fa94d008bcbb330 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vtab.c | 12 +++--------- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 6862daf1ee..f60e23602b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\supdating\sa\szipvfs\sdatabase\swith\sRBU,\sset\sjournal_mode=off\sto\sprevent\sthe\supper-level\spager\sfrom\screating\sa\slarge\stemporary\sfile. -D 2015-08-19T08:34:34.195 +C Simplification\sto\serror\shandling\sin\saddModuleArgument()\sin\sthe\svirtual\stable\nprocessing. +D 2015-08-19T12:45:57.389 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -407,7 +407,7 @@ F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090 F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 -F src/vtab.c 082b35a25a26e3d36f365ca8cd73c1922532f05e +F src/vtab.c 964dffd59c756874a2d73f74039344e63af6d80f F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 6fb6b68969e4692593c2552c4e7bff5882de2cb8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 @@ -1374,7 +1374,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8599402092537ab3df8926eb900661c12d738d4c -R 79cd53df2dc51b1e184555145183f89d -U dan -Z 080d9b0837b12f78f74559ebadf2ade0 +P dec14a3980dcf6c61b0b9ac4ba82fa963ac346d4 +R 9e79c5c3619781e4dd0837447f8e7872 +U drh +Z 95e599ba5e8b06b741ae2fef900bf405 diff --git a/manifest.uuid b/manifest.uuid index 959045fb7f..78e94e2abc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dec14a3980dcf6c61b0b9ac4ba82fa963ac346d4 \ No newline at end of file +c573b0a1aa3ba509234f07520fa94d008bcbb330 \ No newline at end of file diff --git a/src/vtab.c b/src/vtab.c index 2ae861e67f..d639e4f064 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -285,23 +285,17 @@ void sqlite3VtabClear(sqlite3 *db, Table *p){ ** deleted. */ static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){ - int i = pTable->nModuleArg++; - int nBytes = sizeof(char *)*(1+pTable->nModuleArg); + int nBytes = sizeof(char *)*(2+pTable->nModuleArg); char **azModuleArg; azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes); if( azModuleArg==0 ){ - int j; - for(j=0; jazModuleArg[j]); - } sqlite3DbFree(db, zArg); - sqlite3DbFree(db, pTable->azModuleArg); - pTable->nModuleArg = 0; }else{ + int i = pTable->nModuleArg++; azModuleArg[i] = zArg; azModuleArg[i+1] = 0; + pTable->azModuleArg = azModuleArg; } - pTable->azModuleArg = azModuleArg; } /* From 398f872d1f8d264068bc58ab9947cb7aa6a42427 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Aug 2015 13:54:20 +0000 Subject: [PATCH 08/21] Virtual table modules with a null xCreate method act as eponymous-only modules - they cannot be used in a CREATE VIRTUAL TABLE statement. Add the series.c extension that implements a postgres-like generate_series virtual table to demonstrate this capability. FossilOrigin-Name: c58426dbd5ea8b8440ebcc1214f79fa63d658216 --- Makefile.in | 1 + Makefile.msc | 1 + ext/misc/series.c | 290 ++++++++++++++++++++++++++++++++++++++++++++ main.mk | 1 + manifest | 22 ++-- manifest.uuid | 2 +- src/test1.c | 2 + src/vtab.c | 4 +- test/tabfunc01.test | 36 ++++++ 9 files changed, 346 insertions(+), 13 deletions(-) create mode 100644 ext/misc/series.c create mode 100644 test/tabfunc01.test diff --git a/Makefile.in b/Makefile.in index a0f536cb23..096c0cc284 100644 --- a/Makefile.in +++ b/Makefile.in @@ -420,6 +420,7 @@ TESTSRC += \ $(TOP)/ext/misc/nextchar.c \ $(TOP)/ext/misc/percentile.c \ $(TOP)/ext/misc/regexp.c \ + $(TOP)/ext/misc/series.c \ $(TOP)/ext/misc/spellfix.c \ $(TOP)/ext/misc/totype.c \ $(TOP)/ext/misc/wholenumber.c diff --git a/Makefile.msc b/Makefile.msc index 22d3fb523e..56fcbcf8ba 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1086,6 +1086,7 @@ TESTEXT = \ $(TOP)\ext\misc\nextchar.c \ $(TOP)\ext\misc\percentile.c \ $(TOP)\ext\misc\regexp.c \ + $(TOP)\ext\misc\series.c \ $(TOP)\ext\misc\spellfix.c \ $(TOP)\ext\misc\totype.c \ $(TOP)\ext\misc\wholenumber.c diff --git a/ext/misc/series.c b/ext/misc/series.c new file mode 100644 index 0000000000..93e9cd163b --- /dev/null +++ b/ext/misc/series.c @@ -0,0 +1,290 @@ +/* +** 2015-08-18 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements a virtual table that tries to replicate the +** behavior of the generate_series() table-valued-function in Postgres. +** +** Example: +** +** SELECT * FROM generate_series WHERE start=1 AND stop=9 AND step=2 +** +** Results in: +** +** 1 3 5 7 9 +** +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include +#include + +#ifndef SQLITE_OMIT_VIRTUALTABLE + + +/* A series cursor object */ +typedef struct series_cursor series_cursor; +struct series_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + sqlite3_int64 iValue; /* Current value */ + sqlite3_int64 mnValue; /* Mimimum value */ + sqlite3_int64 mxValue; /* Maximum value */ + sqlite3_int64 iStep; /* How much to increment on each step */ +}; + +/* Methods for the series module */ +static int seriesConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + sqlite3_vtab *pNew; + pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); + if( pNew==0 ) return SQLITE_NOMEM; + +#define SERIES_COLUMN_VALUE 0 +#define SERIES_COLUMN_START 1 +#define SERIES_COLUMN_STOP 2 +#define SERIES_COLUMN_STEP 3 + + sqlite3_declare_vtab(db, + "CREATE TABLE x(value,start hidden,stop hidden,step hidden)"); + memset(pNew, 0, sizeof(*pNew)); + return SQLITE_OK; +} + +static int seriesDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** Open a new series cursor. +*/ +static int seriesOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + series_cursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Close a series cursor. +*/ +static int seriesClose(sqlite3_vtab_cursor *cur){ + sqlite3_free(cur); + return SQLITE_OK; +} + + +/* +** Advance a cursor to its next row of output +*/ +static int seriesNext(sqlite3_vtab_cursor *cur){ + series_cursor *pCur = (series_cursor*)cur; + pCur->iValue += pCur->iStep; + return SQLITE_OK; +} + +/* +** Return the value associated with a series. +*/ +static int seriesColumn( + sqlite3_vtab_cursor *cur, + sqlite3_context *ctx, + int i +){ + series_cursor *pCur = (series_cursor*)cur; + sqlite3_int64 x; + switch( i ){ + case 0: x = pCur->iValue; break; + case 1: x = pCur->mnValue; break; + case 2: x = pCur->mxValue; break; + case 3: x = pCur->iStep; break; + } + sqlite3_result_int64(ctx, x); + return SQLITE_OK; +} + +/* +** The rowid. +*/ +static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + series_cursor *pCur = (series_cursor*)cur; + *pRowid = pCur->iValue; + return SQLITE_OK; +} + +/* +** Return TRUE if the last row has been output. +*/ +static int seriesEof(sqlite3_vtab_cursor *cur){ + series_cursor *pCur = (series_cursor*)cur; + return pCur->iValue>pCur->mxValue; +} + +/* +** Called to "rewind" a cursor back to the beginning so that +** it starts its output over again. Always called at least once +** prior to any seriesColumn, seriesRowid, or seriesEof call. +** +** idxNum is a bitmask showing which constraints are available: +** +** 1: start=VALUE +** 2: stop=VALUE +** 4: step=VALUE +** +*/ +static int seriesFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + series_cursor *pCur = (series_cursor *)pVtabCursor; + int i = 0; + if( idxNum & 1 ){ + pCur->mnValue = sqlite3_value_int64(argv[i++]); + }else{ + pCur->mnValue = 0; + } + pCur->iValue = pCur->mnValue; + if( idxNum & 2 ){ + pCur->mxValue = sqlite3_value_int64(argv[i++]); + }else{ + pCur->mxValue = 0xffffffff; + } + if( idxNum & 4 ){ + pCur->iStep = sqlite3_value_int64(argv[i++]); + }else{ + pCur->iStep = 1; + } + return SQLITE_OK; +} + +/* +** Search for terms of these forms: +** +** (1) start = $value +** (2) stop = $value +** (4) step = $value +** +** idxNum is an ORed combination of 1, 2, 4. +*/ +static int seriesBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; + int idxNum = 0; + int startIdx = -1; + int stopIdx = -1; + int stepIdx = -1; + int nArg = 0; + + const struct sqlite3_index_constraint *pConstraint; + pConstraint = pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pConstraint++){ + if( pConstraint->usable==0 ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + switch( pConstraint->iColumn ){ + case SERIES_COLUMN_START: + startIdx = i; + idxNum |= 1; + break; + case SERIES_COLUMN_STOP: + stopIdx = i; + idxNum |= 2; + break; + case SERIES_COLUMN_STEP: + stepIdx = i; + idxNum |= 4; + break; + } + } + pIdxInfo->idxNum = idxNum; + if( startIdx>=0 ){ + pIdxInfo->aConstraintUsage[startIdx].argvIndex = ++nArg; + pIdxInfo->aConstraintUsage[startIdx].omit = 1; + } + if( stopIdx>=0 ){ + pIdxInfo->aConstraintUsage[stopIdx].argvIndex = ++nArg; + pIdxInfo->aConstraintUsage[stopIdx].omit = 1; + } + if( stepIdx>=0 ){ + pIdxInfo->aConstraintUsage[stepIdx].argvIndex = ++nArg; + pIdxInfo->aConstraintUsage[stepIdx].omit = 1; + } + if( pIdxInfo->nOrderBy==1 + && pIdxInfo->aOrderBy[0].desc==0 + ){ + pIdxInfo->orderByConsumed = 1; + } + if( (idxNum & 3)==3 ){ + /* Both start= and stop= boundaries are available. This is the + ** the preferred case */ + pIdxInfo->estimatedCost = (double)1; + }else{ + /* If either boundary is missing, we have to generate a huge span + ** of numbers. Make this case very expensive so that the query + ** planner will work hard to avoid it. */ + pIdxInfo->estimatedCost = (double)2000000000; + } + return SQLITE_OK; +} + +/* +** A virtual table module that provides read-only access to a +** Tcl global variable namespace. +*/ +static sqlite3_module seriesModule = { + 0, /* iVersion */ + 0, /* xCreate */ + seriesConnect, + seriesBestIndex, + seriesDisconnect, + 0, /* xDestroy */ + seriesOpen, /* xOpen - open a cursor */ + seriesClose, /* xClose - close a cursor */ + seriesFilter, /* xFilter - configure scan constraints */ + seriesNext, /* xNext - advance a cursor */ + seriesEof, /* xEof - check for end of scan */ + seriesColumn, /* xColumn - read data */ + seriesRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ +}; + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_series_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); +#ifndef SQLITE_OMIT_VIRTUALTABLE + rc = sqlite3_create_module(db, "generate_series", &seriesModule, 0); +#endif + return rc; +} diff --git a/main.mk b/main.mk index f3bdae6a83..7ddc808ad2 100644 --- a/main.mk +++ b/main.mk @@ -300,6 +300,7 @@ TESTSRC += \ $(TOP)/ext/misc/nextchar.c \ $(TOP)/ext/misc/percentile.c \ $(TOP)/ext/misc/regexp.c \ + $(TOP)/ext/misc/series.c \ $(TOP)/ext/misc/spellfix.c \ $(TOP)/ext/misc/totype.c \ $(TOP)/ext/misc/wholenumber.c \ diff --git a/manifest b/manifest index 3b447c0494..94df9ac4dd 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Merge\schanges\sfrom\strunk. -D 2015-08-19T12:52:51.679 +C Virtual\stable\smodules\swith\sa\snull\sxCreate\smethod\sact\sas\seponymous-only\smodules\s-\nthey\scannot\sbe\sused\sin\sa\sCREATE\sVIRTUAL\sTABLE\sstatement.\s\sAdd\sthe\sseries.c\nextension\sthat\simplements\sa\spostgres-like\sgenerate_series\svirtual\stable\sto\ndemonstrate\sthis\scapability. +D 2015-08-19T13:54:20.227 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 +F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 5f7861c62c41fe8e3205ef14b90ebed28fa21f1b +F Makefile.msc cf63e11a5395cf887515ac7b78e2057dfe442fcd F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION ccfc4d1576dbfdeece0a4372a2e6a2e37d3e7975 @@ -196,6 +196,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a +F ext/misc/series.c c2be7ee41963cd2fcc1d7a226f5348fbe5f4f657 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c 86998fb73aefb7b5dc346ba8a58912f312da4996 F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 @@ -256,7 +257,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 73167b34b0e67c0be32c1da2d988a376851c9ab1 +F main.mk 702135e71d4438ea38c64b22fd6545a0fd87425c F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea F mkopcodeh.awk 0e7f04a8eb90f92259e47d80110e4e98d7ce337a F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 @@ -345,7 +346,7 @@ F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649 -F src/test1.c d339ae9b9baf9221c657c9628c9061d88bd831f6 +F src/test1.c c12ed85c22ac95f87f79de2ec9553334d115f71e F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -407,7 +408,7 @@ F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090 F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 -F src/vtab.c fddb32423d824831fbc42b8358ffadc2437edd97 +F src/vtab.c 1e3405f78e9f248bdee6ef7a8903fadaa7222f9c F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 6fb6b68969e4692593c2552c4e7bff5882de2cb8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 @@ -1030,6 +1031,7 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6 +F test/tabfunc01.test 239e336a556c92c6f81431f4f144f16311184880 F test/table.test 33bf0d1fd07f304582695184b8e6feb017303816 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1374,7 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c1f43a7799a9298abea01b2f8531fc7cdadc4594 c573b0a1aa3ba509234f07520fa94d008bcbb330 -R 04d75ba2dfa13388a455ec59c68a148d +P dddd792dedf0c73ebe74b4ff8d303e6216c16b6a +R 5f16282689e1192bf9396f5e61d5d753 U drh -Z d53ae36484d8828c21b5f9a23ee68eb5 +Z 970ed95f4f43231f807975375b2847aa diff --git a/manifest.uuid b/manifest.uuid index 0f7de90c02..59ff6ef355 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dddd792dedf0c73ebe74b4ff8d303e6216c16b6a \ No newline at end of file +c58426dbd5ea8b8440ebcc1214f79fa63d658216 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index ef9783a3c0..539c674d9a 100644 --- a/src/test1.c +++ b/src/test1.c @@ -6380,6 +6380,7 @@ static int tclLoadStaticExtensionCmd( extern int sqlite3_nextchar_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_regexp_init(sqlite3*,char**,const sqlite3_api_routines*); + extern int sqlite3_series_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_spellfix_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_totype_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_wholenumber_init(sqlite3*,char**,const sqlite3_api_routines*); @@ -6400,6 +6401,7 @@ static int tclLoadStaticExtensionCmd( { "nextchar", sqlite3_nextchar_init }, { "percentile", sqlite3_percentile_init }, { "regexp", sqlite3_regexp_init }, + { "series", sqlite3_series_init }, { "spellfix", sqlite3_spellfix_init }, { "totype", sqlite3_totype_init }, { "wholenumber", sqlite3_wholenumber_init }, diff --git a/src/vtab.c b/src/vtab.c index 23fd8b0fb4..cd1222f706 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -699,7 +699,7 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ ** invoke it now. If the module has not been registered, return an ** error. Otherwise, do nothing. */ - if( !pMod ){ + if( pMod==0 || pMod->pModule->xCreate==0 ){ *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod); rc = SQLITE_ERROR; }else{ @@ -1109,7 +1109,7 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ int rc; sqlite3 *db = pParse->db; if( pMod->pEpoTab ) return 1; - if( pModule->xCreate!=pModule->xConnect ) return 0; + if( pModule->xCreate!=0 && pModule->xCreate!=pModule->xConnect ) return 0; nName = sqlite3Strlen30(pMod->zName) + 1; pTab = sqlite3DbMallocZero(db, sizeof(Table) + nName); if( pTab==0 ) return 0; diff --git a/test/tabfunc01.test b/test/tabfunc01.test new file mode 100644 index 0000000000..3b672e91d7 --- /dev/null +++ b/test/tabfunc01.test @@ -0,0 +1,36 @@ +# 2015-08-19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements tests for table-valued-functions implemented using +# eponymous virtual tables. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix tabfunc01 + +ifcapable !vtab { + finish_test + return +} +load_static_extension db series + +do_execsql_test tabfunc01-1.1 { + SELECT *, '|' FROM generate_series WHERE start=1 AND stop=9 AND step=2; +} {1 | 3 | 5 | 7 | 9 |} +do_execsql_test tabfunc01-1.2 { + SELECT *, '|' FROM generate_series LIMIT 5; +} {0 | 1 | 2 | 3 | 4 |} +do_catchsql_test tabfunc01-1.3 { + CREATE VIRTUAL TABLE t1 USING generate_series; +} {} + +finish_test From 8a48b9c0b18e01b0fec665ad1c86a6fce5fbf1cf Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Aug 2015 15:20:00 +0000 Subject: [PATCH 09/21] Minor refactor of the SrcList object so that it is able to hold the argument list to a table-valued-function in the FROM clause. FossilOrigin-Name: b919376147597c4b73421abe5788f893baf1560b --- manifest | 30 +++++++++++++++--------------- manifest.uuid | 2 +- src/build.c | 16 ++++++++++------ src/expr.c | 16 +++++++++------- src/parse.y | 2 +- src/resolve.c | 12 ++++++------ src/select.c | 36 ++++++++++++++++++------------------ src/sqliteInt.h | 23 +++++++++++++++-------- src/treeview.c | 2 +- src/where.c | 40 ++++++++++++++++++++-------------------- src/wherecode.c | 6 +++--- test/tabfunc01.test | 2 +- 12 files changed, 100 insertions(+), 87 deletions(-) diff --git a/manifest b/manifest index 94df9ac4dd..97f862e1e2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Virtual\stable\smodules\swith\sa\snull\sxCreate\smethod\sact\sas\seponymous-only\smodules\s-\nthey\scannot\sbe\sused\sin\sa\sCREATE\sVIRTUAL\sTABLE\sstatement.\s\sAdd\sthe\sseries.c\nextension\sthat\simplements\sa\spostgres-like\sgenerate_series\svirtual\stable\sto\ndemonstrate\sthis\scapability. -D 2015-08-19T13:54:20.227 +C Minor\srefactor\sof\sthe\sSrcList\sobject\sso\sthat\sit\sis\sable\sto\shold\sthe\sargument\nlist\sto\sa\stable-valued-function\sin\sthe\sFROM\sclause. +D 2015-08-19T15:20:00.817 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -281,14 +281,14 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c f48b3ef91676c06a90a8832987ecef6b94c931ee F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 -F src/build.c 77a9683d9202c091349d8d0bb40922c8dcc4784d +F src/build.c 909416959d8948a436d86461ffacdb3b19ec8286 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b F src/date.c 8ec787fed4929d8ccdf6b1bc360fccc3e1d2ca58 F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a F src/delete.c 8857a6f27560718f65d43bdbec86c967ae1f8dfa -F src/expr.c c5c58e4d01c7ceb2266791d8d877f1b23a88e316 +F src/expr.c 9b9fa7f825290dee945007edc9fe8fdd9b8ce49e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c9b63a217d86582c22121699a47f22f524608869 F src/func.c 824bea430d3a2b7dbc62806ad54da8fdb8ed9e3f @@ -325,7 +325,7 @@ F src/os_win.c 40b3af7a47eb1107d0d69e592bec345a3b7b798a F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c aa916ca28606ccf4b6877dfc2b643ccbca86589f F src/pager.h 6d435f563b3f7fcae4b84433b76a6ac2730036e2 -F src/parse.y 6d60dda8f8d418b6dc034f1fbccd816c459983a8 +F src/parse.y 2ed6efe32ec400c765fec5f3253c650ffdfeb65b F src/pcache.c cde06aa50962595e412d497e22fd2e07878ba1f0 F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9 F src/pcache1.c d08939800abf3031bd0affd5a13fbc4d7ba3fb68 @@ -334,14 +334,14 @@ F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/printf.c 2bc439ff20a4aad0e0ad50a37a67b5eae7d20edc F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 2d47554370de8de6dd5be060cef9559eec315005 +F src/resolve.c cd1c44c853c3560b3fa85637f732a9b7fc0e9295 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 57ef3d98c4400b93eea318813be41b2af2da2217 +F src/select.c c46de38c1b66355f02a839bb72eb13f277e6d19c F src/shell.c b1f91e60918df3a68efad1e3a11696b9a7e23d23 F src/sqlite.h.in 447ead0a6b3293206f04a0896553955d07cfb4b9 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h a0b948ebc89bac13941254641326a6aa248c2cc4 -F src/sqliteInt.h 683b48027374e20bea20e36180984be07bb03031 +F src/sqliteInt.h 9fae37f6bcc2f9ed71fe0362972c263642326914 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -393,7 +393,7 @@ F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481 F src/tokenize.c 57cb3720f53f84d811def2069c2b169b6be539a5 -F src/treeview.c c84b1a8ebc7f1d00cd76ce4958eeb3ae1021beed +F src/treeview.c fda5cfc4635d4a436214c4593f3032d07688a0e2 F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f F src/update.c 487747b328b7216bb7f6af0695d6937d5c9e605f F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c @@ -413,9 +413,9 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 6fb6b68969e4692593c2552c4e7bff5882de2cb8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c c745d3aa78ad1aa8982febb99f2f17ee5cbac069 +F src/where.c a572b23993febb7bb72ee997c55da3b03d870be8 F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047 -F src/wherecode.c 5da5049224f12db314931ae7e0919b4914a2a0b1 +F src/wherecode.c 69f19535a6de0cceb10e16b31a3a03463e31bc24 F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1031,7 +1031,7 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6 -F test/tabfunc01.test 239e336a556c92c6f81431f4f144f16311184880 +F test/tabfunc01.test 0c1fb6ee8eba49c13b8a4c35b8f0726397debb33 F test/table.test 33bf0d1fd07f304582695184b8e6feb017303816 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1376,7 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P dddd792dedf0c73ebe74b4ff8d303e6216c16b6a -R 5f16282689e1192bf9396f5e61d5d753 +P c58426dbd5ea8b8440ebcc1214f79fa63d658216 +R 8f19410a9a93222f2a2f5ce9faa04ea9 U drh -Z 970ed95f4f43231f807975375b2847aa +Z 28752308589cee1f3c6d24275593910d diff --git a/manifest.uuid b/manifest.uuid index 59ff6ef355..d399910325 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c58426dbd5ea8b8440ebcc1214f79fa63d658216 \ No newline at end of file +b919376147597c4b73421abe5788f893baf1560b \ No newline at end of file diff --git a/src/build.c b/src/build.c index 7cf9fe2f90..3ff49d12b5 100644 --- a/src/build.c +++ b/src/build.c @@ -3709,7 +3709,8 @@ void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ sqlite3DbFree(db, pItem->zDatabase); sqlite3DbFree(db, pItem->zName); sqlite3DbFree(db, pItem->zAlias); - sqlite3DbFree(db, pItem->zIndexedBy); + if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); + if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); sqlite3DeleteTable(db, pItem->pTab); sqlite3SelectDelete(db, pItem->pSelect); sqlite3ExprDelete(db, pItem->pOn); @@ -3782,13 +3783,16 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ assert( pIndexedBy!=0 ); if( p && ALWAYS(p->nSrc>0) ){ struct SrcList_item *pItem = &p->a[p->nSrc-1]; - assert( pItem->notIndexed==0 && pItem->zIndexedBy==0 ); + assert( pItem->fg.notIndexed==0 ); + assert( pItem->fg.isIndexedBy==0 ); + assert( pItem->fg.isTabFunc==0 ); if( pIndexedBy->n==1 && !pIndexedBy->z ){ /* A "NOT INDEXED" clause was supplied. See parse.y ** construct "indexed_opt" for details. */ - pItem->notIndexed = 1; + pItem->fg.notIndexed = 1; }else{ - pItem->zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy); + pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy); + pItem->fg.isIndexedBy = (pItem->u1.zIndexedBy!=0); } } } @@ -3812,9 +3816,9 @@ void sqlite3SrcListShiftJoinType(SrcList *p){ if( p ){ int i; for(i=p->nSrc-1; i>0; i--){ - p->a[i].jointype = p->a[i-1].jointype; + p->a[i].fg.jointype = p->a[i-1].fg.jointype; } - p->a[0].jointype = 0; + p->a[0].fg.jointype = 0; } } diff --git a/src/expr.c b/src/expr.c index 5acb909667..1062733cb9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1034,16 +1034,18 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); - pNewItem->jointype = pOldItem->jointype; + pNewItem->fg = pOldItem->fg; pNewItem->iCursor = pOldItem->iCursor; pNewItem->addrFillSub = pOldItem->addrFillSub; pNewItem->regReturn = pOldItem->regReturn; - pNewItem->isCorrelated = pOldItem->isCorrelated; - pNewItem->viaCoroutine = pOldItem->viaCoroutine; - pNewItem->isRecursive = pOldItem->isRecursive; - pNewItem->zIndexedBy = sqlite3DbStrDup(db, pOldItem->zIndexedBy); - pNewItem->notIndexed = pOldItem->notIndexed; - pNewItem->pIndex = pOldItem->pIndex; + if( pNewItem->fg.isIndexedBy ){ + pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); + } + pNewItem->pIBIndex = pOldItem->pIBIndex; + if( pNewItem->fg.isTabFunc ){ + pNewItem->u1.pFuncArg = + sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); + } pTab = pNewItem->pTab = pOldItem->pTab; if( pTab ){ pTab->nRef++; diff --git a/src/parse.y b/src/parse.y index d7aa763683..9174abf7f9 100644 --- a/src/parse.y +++ b/src/parse.y @@ -586,7 +586,7 @@ from(A) ::= FROM seltablist(X). { // stl_prefix(A) ::= seltablist(X) joinop(Y). { A = X; - if( ALWAYS(A && A->nSrc>0) ) A->a[A->nSrc-1].jointype = (u8)Y; + if( ALWAYS(A && A->nSrc>0) ) A->a[A->nSrc-1].fg.jointype = (u8)Y; } stl_prefix(A) ::= . {A = 0;} seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) indexed_opt(I) diff --git a/src/resolve.c b/src/resolve.c index fd57fd7028..ecba89162a 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -306,7 +306,7 @@ static int lookupName( ** USING clause, then skip this match. */ if( cnt==1 ){ - if( pItem->jointype & JT_NATURAL ) continue; + if( pItem->fg.jointype & JT_NATURAL ) continue; if( nameInUsingClause(pItem->pUsing, zCol) ) continue; } cnt++; @@ -321,8 +321,8 @@ static int lookupName( pExpr->iTable = pMatch->iCursor; pExpr->pTab = pMatch->pTab; /* RIGHT JOIN not (yet) supported */ - assert( (pMatch->jointype & JT_RIGHT)==0 ); - if( (pMatch->jointype & JT_LEFT)!=0 ){ + assert( (pMatch->fg.jointype & JT_RIGHT)==0 ); + if( (pMatch->fg.jointype & JT_LEFT)!=0 ){ ExprSetProperty(pExpr, EP_CanBeNull); } pSchema = pExpr->pTab->pSchema; @@ -1215,7 +1215,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** parent contexts. After resolving references to expressions in ** pItem->pSelect, check if this value has changed. If so, then ** SELECT statement pItem->pSelect must be correlated. Set the - ** pItem->isCorrelated flag if this is the case. */ + ** pItem->fg.isCorrelated flag if this is the case. */ for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef; if( pItem->zName ) pParse->zAuthContext = pItem->zName; @@ -1224,8 +1224,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ if( pParse->nErr || db->mallocFailed ) return WRC_Abort; for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef; - assert( pItem->isCorrelated==0 && nRef<=0 ); - pItem->isCorrelated = (nRef!=0); + assert( pItem->fg.isCorrelated==0 && nRef<=0 ); + pItem->fg.isCorrelated = (nRef!=0); } } diff --git a/src/select.c b/src/select.c index 8ac98f1759..acc4c88a57 100644 --- a/src/select.c +++ b/src/select.c @@ -406,12 +406,12 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ int isOuter; if( NEVER(pLeftTab==0 || pRightTab==0) ) continue; - isOuter = (pRight->jointype & JT_OUTER)!=0; + isOuter = (pRight->fg.jointype & JT_OUTER)!=0; /* When the NATURAL keyword is present, add WHERE clause terms for ** every column that the two tables have in common. */ - if( pRight->jointype & JT_NATURAL ){ + if( pRight->fg.jointype & JT_NATURAL ){ if( pRight->pOn || pRight->pUsing ){ sqlite3ErrorMsg(pParse, "a NATURAL join may not have " "an ON or USING clause", 0); @@ -1933,7 +1933,7 @@ static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){ ** ** ** There is exactly one reference to the recursive-table in the FROM clause -** of recursive-query, marked with the SrcList->a[].isRecursive flag. +** of recursive-query, marked with the SrcList->a[].fg.isRecursive flag. ** ** The setup-query runs once to generate an initial set of rows that go ** into a Queue table. Rows are extracted from the Queue table one by @@ -1998,7 +1998,7 @@ static void generateWithRecursiveQuery( /* Locate the cursor number of the Current table */ for(i=0; ALWAYS(inSrc); i++){ - if( pSrc->a[i].isRecursive ){ + if( pSrc->a[i].fg.isRecursive ){ iCurrent = pSrc->a[i].iCursor; break; } @@ -3413,7 +3413,7 @@ static int flattenSubquery( ** is fraught with danger. Best to avoid the whole thing. If the ** subquery is the right term of a LEFT JOIN, then do not flatten. */ - if( (pSubitem->jointype & JT_OUTER)!=0 ){ + if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){ return 0; } @@ -3584,7 +3584,7 @@ static int flattenSubquery( if( pSrc ){ assert( pParent==p ); /* First time through the loop */ - jointype = pSubitem->jointype; + jointype = pSubitem->fg.jointype; }else{ assert( pParent!=p ); /* 2nd and subsequent times through the loop */ pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0); @@ -3624,7 +3624,7 @@ static int flattenSubquery( pSrc->a[i+iFrom] = pSubSrc->a[i]; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } - pSrc->a[iFrom].jointype = jointype; + pSrc->a[iFrom].fg.jointype = jointype; /* Now begin substituting subquery result set expressions for ** references to the iParent in the outer query. @@ -3875,9 +3875,9 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ ** pFrom->pIndex and return SQLITE_OK. */ int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){ - if( pFrom->pTab && pFrom->zIndexedBy ){ + if( pFrom->pTab && pFrom->fg.isIndexedBy ){ Table *pTab = pFrom->pTab; - char *zIndexedBy = pFrom->zIndexedBy; + char *zIndexedBy = pFrom->u1.zIndexedBy; Index *pIdx; for(pIdx=pTab->pIndex; pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); @@ -3888,7 +3888,7 @@ int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){ pParse->checkSchema = 1; return SQLITE_ERROR; } - pFrom->pIndex = pIdx; + pFrom->pIBIndex = pIdx; } return SQLITE_OK; } @@ -4083,7 +4083,7 @@ static int withExpand( && 0==sqlite3StrICmp(pItem->zName, pCte->zName) ){ pItem->pTab = pTab; - pItem->isRecursive = 1; + pItem->fg.isRecursive = 1; pTab->nRef++; pSel->selFlags |= SF_Recursive; } @@ -4213,8 +4213,8 @@ static int selectExpander(Walker *pWalker, Select *p){ */ for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ Table *pTab; - assert( pFrom->isRecursive==0 || pFrom->pTab ); - if( pFrom->isRecursive ) continue; + assert( pFrom->fg.isRecursive==0 || pFrom->pTab ); + if( pFrom->fg.isRecursive ) continue; if( pFrom->pTab!=0 ){ /* This statement has already been prepared. There is no need ** to go further. */ @@ -4377,7 +4377,7 @@ static int selectExpander(Walker *pWalker, Select *p){ tableSeen = 1; if( i>0 && zTName==0 ){ - if( (pFrom->jointype & JT_NATURAL)!=0 + if( (pFrom->fg.jointype & JT_NATURAL)!=0 && tableAndColumnIndex(pTabList, i, zName, 0, 0) ){ /* In a NATURAL join, omit the join columns from the @@ -4904,7 +4904,7 @@ int sqlite3Select( ** is sufficient, though the subroutine to manifest the view does need ** to be invoked again. */ if( pItem->addrFillSub ){ - if( pItem->viaCoroutine==0 ){ + if( pItem->fg.viaCoroutine==0 ){ sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub); } continue; @@ -4922,7 +4922,7 @@ int sqlite3Select( /* Make copies of constant WHERE-clause terms in the outer query down ** inside the subquery. This can help the subquery to run more efficiently. */ - if( (pItem->jointype & JT_OUTER)==0 + if( (pItem->fg.jointype & JT_OUTER)==0 && pushDownWhereTerms(db, pSub, p->pWhere, pItem->iCursor) ){ #if SELECTTRACE_ENABLED @@ -4951,7 +4951,7 @@ int sqlite3Select( explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow); - pItem->viaCoroutine = 1; + pItem->fg.viaCoroutine = 1; pItem->regResult = dest.iSdst; sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn); sqlite3VdbeJumpHere(v, addrTop-1); @@ -4969,7 +4969,7 @@ int sqlite3Select( pItem->regReturn = ++pParse->nMem; topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); pItem->addrFillSub = topAddr+1; - if( pItem->isCorrelated==0 ){ + if( pItem->fg.isCorrelated==0 ){ /* If the subquery is not correlated and if we are not inside of ** a trigger, then we only need to compute the value of the subquery ** once. */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index fb5067ef16..739678998d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1650,7 +1650,7 @@ struct Table { #endif #ifndef SQLITE_OMIT_VIRTUALTABLE int nModuleArg; /* Number of arguments to the module */ - char **azModuleArg; /* Text of all module args. [0] is module name */ + char **azModuleArg; /* 0: module 1: schema 2: vtab name 3...: args */ VTable *pVTable; /* List of VTable objects. */ #endif Trigger *pTrigger; /* List of triggers stored in pSchema */ @@ -2285,11 +2285,15 @@ struct SrcList { int addrFillSub; /* Address of subroutine to manifest a subquery */ int regReturn; /* Register holding return address of addrFillSub */ int regResult; /* Registers holding results of a co-routine */ - u8 jointype; /* Type of join between this able and the previous */ - unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ - unsigned isCorrelated :1; /* True if sub-query is correlated */ - unsigned viaCoroutine :1; /* Implemented as a co-routine */ - unsigned isRecursive :1; /* True for recursive reference in WITH */ + struct { + u8 jointype; /* Type of join between this able and the previous */ + unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ + unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ + unsigned isTabFunc :1; /* True if table-valued-function syntax */ + unsigned isCorrelated :1; /* True if sub-query is correlated */ + unsigned viaCoroutine :1; /* Implemented as a co-routine */ + unsigned isRecursive :1; /* True for recursive reference in WITH */ + } fg; #ifndef SQLITE_OMIT_EXPLAIN u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */ #endif @@ -2297,8 +2301,11 @@ struct SrcList { Expr *pOn; /* The ON clause of a join */ IdList *pUsing; /* The USING clause of a join */ Bitmask colUsed; /* Bit N (1<" clause */ - Index *pIndex; /* Index structure corresponding to zIndex, if any */ + union { + char *zIndexedBy; /* Identifier from "INDEXED BY " clause */ + ExprList *pFuncArg; /* Arguments to table-valued-function */ + } u1; + Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ } a[1]; /* One entry for each identifier on the list */ }; diff --git a/src/treeview.c b/src/treeview.c index 83bed664df..77a654477d 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -120,7 +120,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ if( pItem->zAlias ){ sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias); } - if( pItem->jointype & JT_LEFT ){ + if( pItem->fg.jointype & JT_LEFT ){ sqlite3XPrintf(&x, 0, " LEFT-JOIN"); } sqlite3StrAccumFinish(&x); diff --git a/src/where.c b/src/where.c index 3c0f767db6..2a84a5952a 100644 --- a/src/where.c +++ b/src/where.c @@ -709,7 +709,7 @@ static void constructAutomaticIndex( /* Fill the automatic index with content */ sqlite3ExprCachePush(pParse); pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom]; - if( pTabItem->viaCoroutine ){ + if( pTabItem->fg.viaCoroutine ){ int regYield = pTabItem->regReturn; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); @@ -728,10 +728,10 @@ static void constructAutomaticIndex( sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); - if( pTabItem->viaCoroutine ){ + if( pTabItem->fg.viaCoroutine ){ translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); - pTabItem->viaCoroutine = 0; + pTabItem->fg.viaCoroutine = 0; }else{ sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); } @@ -2128,7 +2128,7 @@ static int whereLoopAddBtreeIndex( assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); if( pNew->wsFlags & WHERE_BTM_LIMIT ){ opMask = WO_LT|WO_LE; - }else if( /*pProbe->tnum<=0 ||*/ (pSrc->jointype & JT_LEFT)!=0 ){ + }else if( /*pProbe->tnum<=0 ||*/ (pSrc->fg.jointype & JT_LEFT)!=0 ){ opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE; }else{ opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; @@ -2502,9 +2502,9 @@ static int whereLoopAddBtree( pWC = pBuilder->pWC; assert( !IsVirtual(pSrc->pTab) ); - if( pSrc->pIndex ){ + if( pSrc->pIBIndex ){ /* An INDEXED BY clause specifies a particular index to use */ - pProbe = pSrc->pIndex; + pProbe = pSrc->pIBIndex; }else if( !HasRowid(pTab) ){ pProbe = pTab->pIndex; }else{ @@ -2524,7 +2524,7 @@ static int whereLoopAddBtree( aiRowEstPk[0] = pTab->nRowLogEst; aiRowEstPk[1] = 0; pFirst = pSrc->pTab->pIndex; - if( pSrc->notIndexed==0 ){ + if( pSrc->fg.notIndexed==0 ){ /* The real indices of the table are only considered if the ** NOT INDEXED qualifier is omitted from the FROM clause */ sPk.pNext = pFirst; @@ -2536,14 +2536,14 @@ static int whereLoopAddBtree( #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* Automatic indexes */ - if( !pBuilder->pOrSet /* Not part of an OR optimization */ + if( !pBuilder->pOrSet /* Not part of an OR optimization */ && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 - && pSrc->pIndex==0 /* Has no INDEXED BY clause */ - && !pSrc->notIndexed /* Has no NOT INDEXED clause */ - && HasRowid(pTab) /* Is not a WITHOUT ROWID table. (FIXME: Why not?) */ - && !pSrc->isCorrelated /* Not a correlated subquery */ - && !pSrc->isRecursive /* Not a recursive common table expression. */ + && pSrc->pIBIndex==0 /* Has no INDEXED BY clause */ + && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */ + && HasRowid(pTab) /* Is not a WITHOUT ROWID table. (FIXME: Why not?) */ + && !pSrc->fg.isCorrelated /* Not a correlated subquery */ + && !pSrc->fg.isRecursive /* Not a recursive common table expression. */ ){ /* Generate auto-index WhereLoops */ WhereTerm *pTerm; @@ -2664,7 +2664,7 @@ static int whereLoopAddBtree( /* If there was an INDEXED BY clause, then only that one index is ** considered. */ - if( pSrc->pIndex ) break; + if( pSrc->pIBIndex ) break; } return rc; } @@ -3010,16 +3010,16 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ Bitmask mUnusable = 0; pNew->iTab = iTab; pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor); - if( ((pItem->jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){ + if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){ /* This condition is true when pItem is the FROM clause term on the ** right-hand-side of a LEFT or CROSS JOIN. */ mExtra = mPrior; } - priorJointype = pItem->jointype; + priorJointype = pItem->fg.jointype; if( IsVirtual(pItem->pTab) ){ struct SrcList_item *p; for(p=&pItem[1]; pjointype & (JT_LEFT|JT_CROSS)) ){ + if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){ mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); } } @@ -3749,7 +3749,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ pItem = pWInfo->pTabList->a; pTab = pItem->pTab; if( IsVirtual(pTab) ) return 0; - if( pItem->zIndexedBy ) return 0; + if( pItem->fg.isIndexedBy ) return 0; iCur = pItem->iCursor; pWC = &pWInfo->sWC; pLoop = pBuilder->pNew; @@ -4136,7 +4136,7 @@ WhereInfo *sqlite3WhereBegin( while( pWInfo->nLevel>=2 ){ WhereTerm *pTerm, *pEnd; pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop; - if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break; + if( (pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 ) break; if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 && (pLoop->wsFlags & WHERE_ONEROW)==0 ){ @@ -4429,7 +4429,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ ** the co-routine into OP_Copy of result contained in a register. ** OP_Rowid becomes OP_Null. */ - if( pTabItem->viaCoroutine && !db->mallocFailed ){ + if( pTabItem->fg.viaCoroutine && !db->mallocFailed ){ translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur, pTabItem->regResult); continue; diff --git a/src/wherecode.c b/src/wherecode.c index 9747f7f375..eb23d8f1a2 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -646,14 +646,14 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** initialize a memory cell that records if this table matches any ** row of the left table of the join. */ - if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){ + if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ pLevel->iLeftJoin = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); VdbeComment((v, "init LEFT JOIN no-match flag")); } /* Special case of a FROM clause subquery implemented as a co-routine */ - if( pTabItem->viaCoroutine ){ + if( pTabItem->fg.viaCoroutine ){ int regYield = pTabItem->regReturn; sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); @@ -1395,7 +1395,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( static const u8 aStep[] = { OP_Next, OP_Prev }; static const u8 aStart[] = { OP_Rewind, OP_Last }; assert( bRev==0 || bRev==1 ); - if( pTabItem->isRecursive ){ + if( pTabItem->fg.isRecursive ){ /* Tables marked isRecursive have only a single row that is stored in ** a pseudo-cursor. No need to Rewind or Next such cursors. */ pLevel->op = OP_Noop; diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 3b672e91d7..f657958440 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -31,6 +31,6 @@ do_execsql_test tabfunc01-1.2 { } {0 | 1 | 2 | 3 | 4 |} do_catchsql_test tabfunc01-1.3 { CREATE VIRTUAL TABLE t1 USING generate_series; -} {} +} {1 {no such module: generate_series}} finish_test From 01d230ce057ac505b064cdffcc01075eb387967c Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Aug 2015 17:11:37 +0000 Subject: [PATCH 10/21] A list of arguments following a table name translates into equality constraints against hidden columns in that table. FossilOrigin-Name: 40e12cfe4c29475417ba89fb637b4c763cf74016 --- manifest | 30 +++++++++++++++--------------- manifest.uuid | 2 +- src/build.c | 15 +++++++++++++++ src/parse.y | 5 +++++ src/resolve.c | 35 ++++++++++++++++++++++++++--------- src/sqliteInt.h | 2 ++ src/treeview.c | 3 +++ src/walker.c | 5 +++++ src/where.c | 1 + src/whereInt.h | 1 + src/whereexpr.c | 39 +++++++++++++++++++++++++++++++++++++++ test/tabfunc01.test | 19 +++++++++++++++++++ 12 files changed, 132 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 97f862e1e2..758e6c154c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\srefactor\sof\sthe\sSrcList\sobject\sso\sthat\sit\sis\sable\sto\shold\sthe\sargument\nlist\sto\sa\stable-valued-function\sin\sthe\sFROM\sclause. -D 2015-08-19T15:20:00.817 +C A\slist\sof\sarguments\sfollowing\sa\stable\sname\stranslates\sinto\sequality\nconstraints\sagainst\shidden\scolumns\sin\sthat\stable. +D 2015-08-19T17:11:37.512 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -281,7 +281,7 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c f48b3ef91676c06a90a8832987ecef6b94c931ee F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 -F src/build.c 909416959d8948a436d86461ffacdb3b19ec8286 +F src/build.c 16051071cd855c23e47b087b49ac99c65b1d8c39 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b @@ -325,7 +325,7 @@ F src/os_win.c 40b3af7a47eb1107d0d69e592bec345a3b7b798a F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c aa916ca28606ccf4b6877dfc2b643ccbca86589f F src/pager.h 6d435f563b3f7fcae4b84433b76a6ac2730036e2 -F src/parse.y 2ed6efe32ec400c765fec5f3253c650ffdfeb65b +F src/parse.y ad9af8552f6f340bd646577ca63356a6f82b6a7e F src/pcache.c cde06aa50962595e412d497e22fd2e07878ba1f0 F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9 F src/pcache1.c d08939800abf3031bd0affd5a13fbc4d7ba3fb68 @@ -334,14 +334,14 @@ F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/printf.c 2bc439ff20a4aad0e0ad50a37a67b5eae7d20edc F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c cd1c44c853c3560b3fa85637f732a9b7fc0e9295 +F src/resolve.c bbb4874decae6e60eee0395a31205d3b55cd2c00 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c c46de38c1b66355f02a839bb72eb13f277e6d19c F src/shell.c b1f91e60918df3a68efad1e3a11696b9a7e23d23 F src/sqlite.h.in 447ead0a6b3293206f04a0896553955d07cfb4b9 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h a0b948ebc89bac13941254641326a6aa248c2cc4 -F src/sqliteInt.h 9fae37f6bcc2f9ed71fe0362972c263642326914 +F src/sqliteInt.h 89e68539d645db597366a91411468b51e73c21a0 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -393,7 +393,7 @@ F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481 F src/tokenize.c 57cb3720f53f84d811def2069c2b169b6be539a5 -F src/treeview.c fda5cfc4635d4a436214c4593f3032d07688a0e2 +F src/treeview.c c15df00728034549ff92d78ae851b44952736d3b F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f F src/update.c 487747b328b7216bb7f6af0695d6937d5c9e605f F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c @@ -412,11 +412,11 @@ F src/vtab.c 1e3405f78e9f248bdee6ef7a8903fadaa7222f9c F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 6fb6b68969e4692593c2552c4e7bff5882de2cb8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 -F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c a572b23993febb7bb72ee997c55da3b03d870be8 -F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047 +F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba +F src/where.c 66518a14a1238611aa0744d6980b6b7f544f4816 +F src/whereInt.h 880a8599226ac1c00203490d934f3ed79b292572 F src/wherecode.c 69f19535a6de0cceb10e16b31a3a03463e31bc24 -F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652 +F src/whereexpr.c 6332ade8f72beebb6438734e92757da4631176e0 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1031,7 +1031,7 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6 -F test/tabfunc01.test 0c1fb6ee8eba49c13b8a4c35b8f0726397debb33 +F test/tabfunc01.test ca013d7012764f85185d0d1b77f158a7b1b3ad6d F test/table.test 33bf0d1fd07f304582695184b8e6feb017303816 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1376,7 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c58426dbd5ea8b8440ebcc1214f79fa63d658216 -R 8f19410a9a93222f2a2f5ce9faa04ea9 +P b919376147597c4b73421abe5788f893baf1560b +R 03d0a3c413d15fc0179aae3fc23d1837 U drh -Z 28752308589cee1f3c6d24275593910d +Z 86fabb010e68498602162c53cf0d6cc5 diff --git a/manifest.uuid b/manifest.uuid index d399910325..26e06bc1f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b919376147597c4b73421abe5788f893baf1560b \ No newline at end of file +40e12cfe4c29475417ba89fb637b4c763cf74016 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 3ff49d12b5..96dc03a825 100644 --- a/src/build.c +++ b/src/build.c @@ -3797,6 +3797,21 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ } } +/* +** Add the list of function arguments to the SrcList entry for a +** table-valued-function. +*/ +void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ + if( p && ALWAYS(p->nSrc>0) ){ + struct SrcList_item *pItem = &p->a[p->nSrc-1]; + assert( pItem->fg.notIndexed==0 ); + assert( pItem->fg.isIndexedBy==0 ); + assert( pItem->fg.isTabFunc==0 ); + pItem->u1.pFuncArg = pList; + pItem->fg.isTabFunc = 1; + } +} + /* ** When building up a FROM clause in the parser, the join operator ** is initially attached to the left operand. But the code generator diff --git a/src/parse.y b/src/parse.y index 9174abf7f9..3d186b28aa 100644 --- a/src/parse.y +++ b/src/parse.y @@ -594,6 +594,11 @@ seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) indexed_opt(I) A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U); sqlite3SrcListIndexedBy(pParse, A, &I); } +seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) LP exprlist(E) RP as(Z) + on_opt(N) using_opt(U). { + A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U); + sqlite3SrcListFuncArgs(pParse, A, E); +} %ifndef SQLITE_OMIT_SUBQUERY seltablist(A) ::= stl_prefix(X) LP select(S) RP as(Z) on_opt(N) using_opt(U). { diff --git a/src/resolve.c b/src/resolve.c index ecba89162a..72d5f319c1 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1142,7 +1142,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ int isCompound; /* True if p is a compound select */ int nCompound; /* Number of compound terms processed so far */ Parse *pParse; /* Parsing context */ - ExprList *pEList; /* Result set expression list */ int i; /* Loop counter */ ExprList *pGroupBy; /* The GROUP BY clause */ Select *pLeftmost; /* Left-most of SELECT of a compound */ @@ -1237,14 +1236,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ sNC.pNext = pOuterNC; /* Resolve names in the result set. */ - pEList = p->pEList; - assert( pEList!=0 ); - for(i=0; inExpr; i++){ - Expr *pX = pEList->a[i].pExpr; - if( sqlite3ResolveExprNames(&sNC, pX) ){ - return WRC_Abort; - } - } + if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort; /* If there are no aggregate functions in the result-set, and no GROUP BY ** expression, do not allow aggregates in any of the other expressions. @@ -1277,6 +1269,16 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; + /* Resolve names in table-valued-function arguments */ + for(i=0; ipSrc->nSrc; i++){ + struct SrcList_item *pItem = &p->pSrc->a[i]; + if( pItem->fg.isTabFunc + && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) + ){ + return WRC_Abort; + } + } + /* The ORDER BY and GROUP BY clauses may not refer to terms in ** outer queries */ @@ -1440,6 +1442,21 @@ int sqlite3ResolveExprNames( return ExprHasProperty(pExpr, EP_Error); } +/* +** Resolve all names for all expression in an expression list. This is +** just like sqlite3ResolveExprNames() except that it works for an expression +** list rather than a single expression. +*/ +int sqlite3ResolveExprListNames( + NameContext *pNC, /* Namespace to resolve expressions in. */ + ExprList *pList /* The expression list to be analyzed. */ +){ + int i; + for(i=0; inExpr; i++){ + if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort; + } + return WRC_Continue; +} /* ** Resolve all names in all expressions of a SELECT and in all diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 739678998d..96a7700210 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3328,6 +3328,7 @@ SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*); SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, Token*, Select*, Expr*, IdList*); void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); +void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); int sqlite3IndexedByLookup(Parse *, struct SrcList_item *); void sqlite3SrcListShiftJoinType(SrcList*); void sqlite3SrcListAssignCursors(Parse*, SrcList*); @@ -3619,6 +3620,7 @@ void sqlite3SelectPrep(Parse*, Select*, NameContext*); void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); int sqlite3ResolveExprNames(NameContext*, Expr*); +int sqlite3ResolveExprListNames(NameContext*, ExprList*); void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); diff --git a/src/treeview.c b/src/treeview.c index 77a654477d..fbe8fd46d5 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -128,6 +128,9 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ if( pItem->pSelect ){ sqlite3TreeViewSelect(pView, pItem->pSelect, 0); } + if( pItem->fg.isTabFunc ){ + sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); + } sqlite3TreeViewPop(pView); } sqlite3TreeViewPop(pView); diff --git a/src/walker.c b/src/walker.c index e30bb60b5a..81e0f2cd60 100644 --- a/src/walker.c +++ b/src/walker.c @@ -105,6 +105,11 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){ return WRC_Abort; } + if( pItem->fg.isTabFunc + && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) + ){ + return WRC_Abort; + } } } return WRC_Continue; diff --git a/src/where.c b/src/where.c index 2a84a5952a..bdcfeaa9aa 100644 --- a/src/where.c +++ b/src/where.c @@ -4030,6 +4030,7 @@ WhereInfo *sqlite3WhereBegin( */ for(ii=0; iinSrc; ii++){ createMask(pMaskSet, pTabList->a[ii].iCursor); + sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC); } #ifndef NDEBUG { diff --git a/src/whereInt.h b/src/whereInt.h index 8929d8c4be..76b665d971 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -475,6 +475,7 @@ void sqlite3WhereSplit(WhereClause*,Expr*,u8); Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*); Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); void sqlite3WhereExprAnalyze(SrcList*, WhereClause*); +void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); diff --git a/src/whereexpr.c b/src/whereexpr.c index 3607ef5352..a0f7c822af 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1247,3 +1247,42 @@ void sqlite3WhereExprAnalyze( exprAnalyze(pTabList, pWC, i); } } + +/* +** For table-valued-functions, transform the function arguments into +** new WHERE clause terms. +** +** Each function argument translates into an equality constraint against +** a HIDDEN column in the table. +*/ +void sqlite3WhereTabFuncArgs( + Parse *pParse, /* Parsing context */ + struct SrcList_item *pItem, /* The FROM clause term to process */ + WhereClause *pWC /* Xfer function arguments to here */ +){ + Table *pTab; + int j, k; + ExprList *pArgs; + Expr *pColRef; + Expr *pTerm; + if( pItem->fg.isTabFunc==0 ) return; + pTab = pItem->pTab; + assert( pTab!=0 ); + pArgs = pItem->u1.pFuncArg; + assert( pArgs!=0 ); + for(j=k=0; jnExpr; j++){ + while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){ k++; } + if( k>=pTab->nCol ){ + sqlite3ErrorMsg(pParse, "too many arguments on %s - max %d", + pTab->zName, j); + return; + } + pColRef = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); + if( pColRef==0 ) return; + pColRef->iTable = pItem->iCursor; + pColRef->iColumn = k++; + pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, + sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); + whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); + } +} diff --git a/test/tabfunc01.test b/test/tabfunc01.test index f657958440..7393238b94 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -32,5 +32,24 @@ do_execsql_test tabfunc01-1.2 { do_catchsql_test tabfunc01-1.3 { CREATE VIRTUAL TABLE t1 USING generate_series; } {1 {no such module: generate_series}} +do_execsql_test tabfunc01-1.4 { + SELECT * FROM generate_series(1,9,2); +} {1 3 5 7 9} +do_execsql_test tabfunc01-1.5 { + SELECT * FROM generate_series(1,9); +} {1 2 3 4 5 6 7 8 9} +do_execsql_test tabfunc01-1.6 { + SELECT * FROM generate_series(1,10) WHERE step=3; +} {1 4 7 10} +do_catchsql_test tabfunc01-1.7 { + SELECT * FROM generate_series(1,9,2,11); +} {1 {too many arguments on generate_series - max 3}} + +do_execsql_test tabfunc01-2.1 { + CREATE TABLE t1(x); + INSERT INTO t1(x) VALUES(2),(3); + SELECT *, '|' FROM t1, generate_series(1,x) ORDER BY 1, 2 + +} {2 1 | 2 2 | 3 1 | 3 2 | 3 3 |} finish_test From bc550df32f70697fe2de029198682b8a668d2785 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Aug 2015 18:19:49 +0000 Subject: [PATCH 11/21] Improved comments on the generate_series virtual table. Test cases for ORDER BY rowid DESC with generate_series. FossilOrigin-Name: fef44c37f31ca9fd7891cecdbe95cc46a987067b --- ext/misc/series.c | 208 +++++++++++++++++++++++++++++++++----------- manifest | 14 +-- manifest.uuid | 2 +- test/tabfunc01.test | 5 +- 4 files changed, 167 insertions(+), 62 deletions(-) diff --git a/ext/misc/series.c b/ext/misc/series.c index 93e9cd163b..b8f25a82c6 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -10,17 +10,63 @@ ** ************************************************************************* ** -** This file implements a virtual table that tries to replicate the -** behavior of the generate_series() table-valued-function in Postgres. +** This file demonstrates how to create a table-valued-function using +** a virtual table. This demo implements the generate_series() function +** which gives similar results to the eponymous function in PostgreSQL. +** Examples: ** -** Example: +** SELECT * FROM generate_series(0,100,5); ** -** SELECT * FROM generate_series WHERE start=1 AND stop=9 AND step=2 +** The query above returns integers from 0 through 100 counting by steps +** of 5. ** -** Results in: +** SELECT * FROM generate_series(0,100); ** -** 1 3 5 7 9 +** Integers from 0 through 100 with a step size of 1. ** +** SELECT * FROM generate_series(20) LIMIT 10; +** +** Integers 20 through 29. +** +** HOW IT WORKS +** +** The generate_series "function" is really a virtual table with the +** following schema: +** +** CREATE FUNCTION generate_series( +** value, +** start HIDDEN, +** stop HIDDEN, +** step HIDDEN +** ); +** +** Function arguments in queries against this virtual table are translated +** into equality constraints against successive hidden columns. In other +** words, the following pairs of queries are equivalent to each other: +** +** SELECT * FROM generate_series(0,100,5); +** SELECT * FROM generate_series WHERE start=0 AND stop=100 AND step=5; +** +** SELECT * FROM generate_series(0,100); +** SELECT * FROM generate_series WHERE start=0 AND stop=100; +** +** SELECT * FROM generate_series(20) LIMIT 10; +** SELECT * FROM generate_series WHERE start=20 LIMIT 10; +** +** The generate_series virtual table implementation leaves the xCreate method +** set to NULL. This means that it is not possible to do a CREATE VIRTUAL +** TABLE command with "generate_series" as the USING argument. Instead, there +** is a single generate_series virtual table that is always available without +** having to be created first. +** +** The xBestIndex method looks for equality constraints against the hidden +** start, stop, and step columns, and if present, it uses those constraints +** to bound the sequence of generated values. If the equality constraints +** are missing, it uses 0 for start, 4294967295 for stop, and 1 for step. +** xBestIndex returns a small cost when both start and stop are available, +** and a very large cost if either start or stop are unavailable. This +** encourages the query planner to order joins such that the bounds of the +** series are well-defined. */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 @@ -30,17 +76,33 @@ SQLITE_EXTENSION_INIT1 #ifndef SQLITE_OMIT_VIRTUALTABLE -/* A series cursor object */ +/* series_cursor is a subclas of sqlite3_vtab_cursor which will +** serve as the underlying representation of a cursor that scans +** over rows of the result +*/ typedef struct series_cursor series_cursor; struct series_cursor { sqlite3_vtab_cursor base; /* Base class - must be first */ - sqlite3_int64 iValue; /* Current value */ - sqlite3_int64 mnValue; /* Mimimum value */ - sqlite3_int64 mxValue; /* Maximum value */ - sqlite3_int64 iStep; /* How much to increment on each step */ + int isDesc; /* True to count down rather than up */ + sqlite3_int64 iValue; /* Current value ("value") */ + sqlite3_int64 mnValue; /* Mimimum value ("start") */ + sqlite3_int64 mxValue; /* Maximum value ("stop") */ + sqlite3_int64 iStep; /* Increment ("step") */ }; -/* Methods for the series module */ +/* +** The seriesConnect() method is invoked to create a new +** series_vtab that describes the generate_series virtual table. +** +** Think of this routine as the constructor for series_vtab objects. +** +** All this routine needs to do is: +** +** (1) Allocate the series_vtab object and initialize all fields. +** +** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the +** result set of queries against generate_series will look like. +*/ static int seriesConnect( sqlite3 *db, void *pAux, @@ -52,6 +114,7 @@ static int seriesConnect( pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); if( pNew==0 ) return SQLITE_NOMEM; +/* Column numbers */ #define SERIES_COLUMN_VALUE 0 #define SERIES_COLUMN_START 1 #define SERIES_COLUMN_STOP 2 @@ -63,13 +126,16 @@ static int seriesConnect( return SQLITE_OK; } +/* +** This method is the destructor for series_cursor objects. +*/ static int seriesDisconnect(sqlite3_vtab *pVtab){ sqlite3_free(pVtab); return SQLITE_OK; } /* -** Open a new series cursor. +** Constructor for a new series_cursor object. */ static int seriesOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ series_cursor *pCur; @@ -81,7 +147,7 @@ static int seriesOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ } /* -** Close a series cursor. +** Destructor for a series_cursor. */ static int seriesClose(sqlite3_vtab_cursor *cur){ sqlite3_free(cur); @@ -90,36 +156,42 @@ static int seriesClose(sqlite3_vtab_cursor *cur){ /* -** Advance a cursor to its next row of output +** Advance a series_cursor to its next row of output. */ static int seriesNext(sqlite3_vtab_cursor *cur){ series_cursor *pCur = (series_cursor*)cur; - pCur->iValue += pCur->iStep; + if( pCur->isDesc ){ + pCur->iValue -= pCur->iStep; + }else{ + pCur->iValue += pCur->iStep; + } return SQLITE_OK; } /* -** Return the value associated with a series. +** Return values of columns for the row at which the series_cursor +** is currently pointing. */ static int seriesColumn( - sqlite3_vtab_cursor *cur, - sqlite3_context *ctx, - int i + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ ){ series_cursor *pCur = (series_cursor*)cur; - sqlite3_int64 x; + sqlite3_int64 x = 0; switch( i ){ - case 0: x = pCur->iValue; break; - case 1: x = pCur->mnValue; break; - case 2: x = pCur->mxValue; break; - case 3: x = pCur->iStep; break; + case SERIES_COLUMN_START: x = pCur->mnValue; break; + case SERIES_COLUMN_STOP: x = pCur->mxValue; break; + case SERIES_COLUMN_STEP: x = pCur->iStep; break; + default: x = pCur->iValue; break; } sqlite3_result_int64(ctx, x); return SQLITE_OK; } /* -** The rowid. +** Return the rowid for the current row. In this implementation, the +** rowid is the same as the output value. */ static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ series_cursor *pCur = (series_cursor*)cur; @@ -128,24 +200,38 @@ static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ } /* -** Return TRUE if the last row has been output. +** Return TRUE if the cursor has been moved off of the last +** row of output. */ static int seriesEof(sqlite3_vtab_cursor *cur){ series_cursor *pCur = (series_cursor*)cur; - return pCur->iValue>pCur->mxValue; + if( pCur->isDesc ){ + return pCur->iValue < pCur->mnValue; + }else{ + return pCur->iValue > pCur->mxValue; + } } /* -** Called to "rewind" a cursor back to the beginning so that -** it starts its output over again. Always called at least once -** prior to any seriesColumn, seriesRowid, or seriesEof call. +** This method is called to "rewind" the series_cursor object back +** to the first row of output. This method is always called at least +** once prior to any call to seriesColumn() or seriesRowid() or +** seriesEof(). ** -** idxNum is a bitmask showing which constraints are available: +** The query plan selected by seriesBestIndex is passed in the idxNum +** parameter. (idxStr is not used in this implementation.) idxNum +** is a bitmask showing which constraints are available: ** ** 1: start=VALUE ** 2: stop=VALUE ** 4: step=VALUE ** +** Also, if bit 8 is set, that means that the series should be output +** in descending order rather than in ascending order. +** +** This routine should initialize the cursor and position it so that it +** is pointing at the first row, or pointing off the end of the table +** (so that seriesEof() will return true) if the table is empty. */ static int seriesFilter( sqlite3_vtab_cursor *pVtabCursor, @@ -159,7 +245,6 @@ static int seriesFilter( }else{ pCur->mnValue = 0; } - pCur->iValue = pCur->mnValue; if( idxNum & 2 ){ pCur->mxValue = sqlite3_value_int64(argv[i++]); }else{ @@ -167,31 +252,49 @@ static int seriesFilter( } if( idxNum & 4 ){ pCur->iStep = sqlite3_value_int64(argv[i++]); + if( pCur->iStep<1 ) pCur->iStep = 1; }else{ pCur->iStep = 1; } + if( idxNum & 8 ){ + pCur->isDesc = 1; + pCur->iValue = pCur->mxValue; + if( pCur->iStep>0 ){ + pCur->iValue -= (pCur->mxValue - pCur->mnValue)%pCur->iStep; + } + }else{ + pCur->isDesc = 0; + pCur->iValue = pCur->mnValue; + } return SQLITE_OK; } /* -** Search for terms of these forms: +** SQLite will invoke this method one or more times while planning a query +** that uses the generate_series virtual table. This routine needs to create +** a query plan for each invocation and compute an estimated cost for that +** plan. ** -** (1) start = $value -** (2) stop = $value -** (4) step = $value +** In this implementation idxNum is used to represent the +** query plan. idxStr is unused. ** -** idxNum is an ORed combination of 1, 2, 4. +** The query plan is represented by bits in idxNum: +** +** (1) start = $value -- constraint exists +** (2) stop = $value -- constraint exists +** (4) step = $value -- constraint exists +** (8) output in descending order */ static int seriesBestIndex( sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo ){ - int i; - int idxNum = 0; - int startIdx = -1; - int stopIdx = -1; - int stepIdx = -1; - int nArg = 0; + int i; /* Loop over constraints */ + int idxNum = 0; /* The query plan bitmask */ + int startIdx = -1; /* Index of the start= constraint, or -1 if none */ + int stopIdx = -1; /* Index of the stop= constraint, or -1 if none */ + int stepIdx = -1; /* Index of the step= constraint, or -1 if none */ + int nArg = 0; /* Number of arguments that seriesFilter() expects */ const struct sqlite3_index_constraint *pConstraint; pConstraint = pIdxInfo->aConstraint; @@ -213,7 +316,6 @@ static int seriesBestIndex( break; } } - pIdxInfo->idxNum = idxNum; if( startIdx>=0 ){ pIdxInfo->aConstraintUsage[startIdx].argvIndex = ++nArg; pIdxInfo->aConstraintUsage[startIdx].omit = 1; @@ -226,9 +328,8 @@ static int seriesBestIndex( pIdxInfo->aConstraintUsage[stepIdx].argvIndex = ++nArg; pIdxInfo->aConstraintUsage[stepIdx].omit = 1; } - if( pIdxInfo->nOrderBy==1 - && pIdxInfo->aOrderBy[0].desc==0 - ){ + if( pIdxInfo->nOrderBy==1 ){ + if( pIdxInfo->aOrderBy[0].desc ) idxNum |= 8; pIdxInfo->orderByConsumed = 1; } if( (idxNum & 3)==3 ){ @@ -241,19 +342,20 @@ static int seriesBestIndex( ** planner will work hard to avoid it. */ pIdxInfo->estimatedCost = (double)2000000000; } + pIdxInfo->idxNum = idxNum; return SQLITE_OK; } /* -** A virtual table module that provides read-only access to a -** Tcl global variable namespace. +** This following structure defines all the methods for the +** generate_series virtual table. */ static sqlite3_module seriesModule = { 0, /* iVersion */ 0, /* xCreate */ - seriesConnect, - seriesBestIndex, - seriesDisconnect, + seriesConnect, /* xConnect */ + seriesBestIndex, /* xBestIndex */ + seriesDisconnect, /* xDisconnect */ 0, /* xDestroy */ seriesOpen, /* xOpen - open a cursor */ seriesClose, /* xClose - close a cursor */ diff --git a/manifest b/manifest index 758e6c154c..fc133c6247 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\slist\sof\sarguments\sfollowing\sa\stable\sname\stranslates\sinto\sequality\nconstraints\sagainst\shidden\scolumns\sin\sthat\stable. -D 2015-08-19T17:11:37.512 +C Improved\scomments\son\sthe\sgenerate_series\svirtual\stable.\s\sTest\scases\sfor\nORDER\sBY\srowid\sDESC\swith\sgenerate_series. +D 2015-08-19T18:19:49.786 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -196,7 +196,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a -F ext/misc/series.c c2be7ee41963cd2fcc1d7a226f5348fbe5f4f657 +F ext/misc/series.c 1484bc674b5cd0fcf18cb803514101799800c0c8 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c 86998fb73aefb7b5dc346ba8a58912f312da4996 F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 @@ -1031,7 +1031,7 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6 -F test/tabfunc01.test ca013d7012764f85185d0d1b77f158a7b1b3ad6d +F test/tabfunc01.test d69034069c911094cfcd58abba60bf431e1be6b4 F test/table.test 33bf0d1fd07f304582695184b8e6feb017303816 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1376,7 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b919376147597c4b73421abe5788f893baf1560b -R 03d0a3c413d15fc0179aae3fc23d1837 +P 40e12cfe4c29475417ba89fb637b4c763cf74016 +R 9b15d3824a7951b7bf35b7a0abf173ef U drh -Z 86fabb010e68498602162c53cf0d6cc5 +Z a9a479d5c8daf866b811a88820752d86 diff --git a/manifest.uuid b/manifest.uuid index 26e06bc1f6..276e7ea952 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -40e12cfe4c29475417ba89fb637b4c763cf74016 \ No newline at end of file +fef44c37f31ca9fd7891cecdbe95cc46a987067b \ No newline at end of file diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 7393238b94..d6a2bc21d4 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -45,11 +45,14 @@ do_catchsql_test tabfunc01-1.7 { SELECT * FROM generate_series(1,9,2,11); } {1 {too many arguments on generate_series - max 3}} +do_execsql_test tabfunc01-1.8 { + SELECT * FROM generate_series(0,32,5) ORDER BY rowid DESC; +} {30 25 20 15 10 5 0} + do_execsql_test tabfunc01-2.1 { CREATE TABLE t1(x); INSERT INTO t1(x) VALUES(2),(3); SELECT *, '|' FROM t1, generate_series(1,x) ORDER BY 1, 2 - } {2 1 | 2 2 | 3 1 | 3 2 | 3 3 |} finish_test From 509c3fc004bda4dad2d7e529da19d2e0049f4876 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Aug 2015 19:01:28 +0000 Subject: [PATCH 12/21] Fix eponymous virtual tables so that they do not automatically make the first column the rowid. Enhance the generate_series virtual table to support rowid. FossilOrigin-Name: a325a08599759471047e234ef9cfcc3cb110aafd --- ext/misc/series.c | 5 ++++- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vtab.c | 1 + test/tabfunc01.test | 6 ++++++ 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/ext/misc/series.c b/ext/misc/series.c index b8f25a82c6..43de3b711b 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -84,6 +84,7 @@ typedef struct series_cursor series_cursor; struct series_cursor { sqlite3_vtab_cursor base; /* Base class - must be first */ int isDesc; /* True to count down rather than up */ + sqlite3_int64 iRowid; /* The rowid */ sqlite3_int64 iValue; /* Current value ("value") */ sqlite3_int64 mnValue; /* Mimimum value ("start") */ sqlite3_int64 mxValue; /* Maximum value ("stop") */ @@ -165,6 +166,7 @@ static int seriesNext(sqlite3_vtab_cursor *cur){ }else{ pCur->iValue += pCur->iStep; } + pCur->iRowid++; return SQLITE_OK; } @@ -195,7 +197,7 @@ static int seriesColumn( */ static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ series_cursor *pCur = (series_cursor*)cur; - *pRowid = pCur->iValue; + *pRowid = pCur->iRowid; return SQLITE_OK; } @@ -266,6 +268,7 @@ static int seriesFilter( pCur->isDesc = 0; pCur->iValue = pCur->mnValue; } + pCur->iRowid = 1; return SQLITE_OK; } diff --git a/manifest b/manifest index fc133c6247..38f503e8f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\son\sthe\sgenerate_series\svirtual\stable.\s\sTest\scases\sfor\nORDER\sBY\srowid\sDESC\swith\sgenerate_series. -D 2015-08-19T18:19:49.786 +C Fix\seponymous\svirtual\stables\sso\sthat\sthey\sdo\snot\sautomatically\smake\sthe\sfirst\ncolumn\sthe\srowid.\s\sEnhance\sthe\sgenerate_series\svirtual\stable\sto\ssupport\srowid. +D 2015-08-19T19:01:28.078 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -196,7 +196,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a -F ext/misc/series.c 1484bc674b5cd0fcf18cb803514101799800c0c8 +F ext/misc/series.c 5b84c6584af085b55ae07e2ee7b133b6db03e323 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c 86998fb73aefb7b5dc346ba8a58912f312da4996 F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 @@ -408,7 +408,7 @@ F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090 F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 -F src/vtab.c 1e3405f78e9f248bdee6ef7a8903fadaa7222f9c +F src/vtab.c 05395350f947ec0b1af25e8502b9cfec84f17ea7 F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 6fb6b68969e4692593c2552c4e7bff5882de2cb8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 @@ -1031,7 +1031,7 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6 -F test/tabfunc01.test d69034069c911094cfcd58abba60bf431e1be6b4 +F test/tabfunc01.test 61d185dde74aa2ff70085d33bc5f9a0ce8d6a318 F test/table.test 33bf0d1fd07f304582695184b8e6feb017303816 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1376,7 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 40e12cfe4c29475417ba89fb637b4c763cf74016 -R 9b15d3824a7951b7bf35b7a0abf173ef +P fef44c37f31ca9fd7891cecdbe95cc46a987067b +R a41603407a6c0b327e60b148f02b0042 U drh -Z a9a479d5c8daf866b811a88820752d86 +Z aa56d5c64521b30a9993ce3328198562 diff --git a/manifest.uuid b/manifest.uuid index 276e7ea952..8d7098b5e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fef44c37f31ca9fd7891cecdbe95cc46a987067b \ No newline at end of file +a325a08599759471047e234ef9cfcc3cb110aafd \ No newline at end of file diff --git a/src/vtab.c b/src/vtab.c index cd1222f706..fca8170d22 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -1120,6 +1120,7 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ pTab->pSchema = db->aDb[0].pSchema; pTab->tabFlags |= TF_Virtual; pTab->nModuleArg = 0; + pTab->iPKey = -1; addModuleArgument(db, pTab, pTab->zName); addModuleArgument(db, pTab, 0); addModuleArgument(db, pTab, pTab->zName); diff --git a/test/tabfunc01.test b/test/tabfunc01.test index d6a2bc21d4..8897893197 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -48,6 +48,12 @@ do_catchsql_test tabfunc01-1.7 { do_execsql_test tabfunc01-1.8 { SELECT * FROM generate_series(0,32,5) ORDER BY rowid DESC; } {30 25 20 15 10 5 0} +do_execsql_test tabfunc01-1.9 { + SELECT rowid, * FROM generate_series(0,32,5) ORDER BY value DESC; +} {1 30 2 25 3 20 4 15 5 10 6 5 7 0} +do_execsql_test tabfunc01-1.10 { + SELECT rowid, * FROM generate_series(0,32,5) ORDER BY +value DESC; +} {7 30 6 25 5 20 4 15 3 10 2 5 1 0} do_execsql_test tabfunc01-2.1 { CREATE TABLE t1(x); From 01dced109f78e8fd1eb5c20e57686717cd378e95 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 20 Aug 2015 16:16:37 +0000 Subject: [PATCH 13/21] Fix a typo in series.c. FossilOrigin-Name: 23db7f50f14801c2cf56c006d7c7f593908b7158 --- ext/misc/series.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/misc/series.c b/ext/misc/series.c index 43de3b711b..645ddeab15 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -76,7 +76,7 @@ SQLITE_EXTENSION_INIT1 #ifndef SQLITE_OMIT_VIRTUALTABLE -/* series_cursor is a subclas of sqlite3_vtab_cursor which will +/* series_cursor is a subclass of sqlite3_vtab_cursor which will ** serve as the underlying representation of a cursor that scans ** over rows of the result */ diff --git a/manifest b/manifest index 38f503e8f1..ab8f0ade60 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\seponymous\svirtual\stables\sso\sthat\sthey\sdo\snot\sautomatically\smake\sthe\sfirst\ncolumn\sthe\srowid.\s\sEnhance\sthe\sgenerate_series\svirtual\stable\sto\ssupport\srowid. -D 2015-08-19T19:01:28.078 +C Fix\sa\stypo\sin\sseries.c. +D 2015-08-20T16:16:37.345 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -196,7 +196,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a -F ext/misc/series.c 5b84c6584af085b55ae07e2ee7b133b6db03e323 +F ext/misc/series.c e9b658e442090f75ae01bbf4924feb52a759674c F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c 86998fb73aefb7b5dc346ba8a58912f312da4996 F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 @@ -1376,7 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P fef44c37f31ca9fd7891cecdbe95cc46a987067b -R a41603407a6c0b327e60b148f02b0042 -U drh -Z aa56d5c64521b30a9993ce3328198562 +P a325a08599759471047e234ef9cfcc3cb110aafd +R c7d0daf8fbeee011c3f976b2caec6772 +U dan +Z e8e4b80135954d12498e194483d7037d diff --git a/manifest.uuid b/manifest.uuid index 8d7098b5e3..f79d828421 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a325a08599759471047e234ef9cfcc3cb110aafd \ No newline at end of file +23db7f50f14801c2cf56c006d7c7f593908b7158 \ No newline at end of file From cbd8db35f58c647f63ae05d153a148efb4ed8ef3 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Aug 2015 17:18:32 +0000 Subject: [PATCH 14/21] Make SQLITE_BUSY_SNAPSHOT and SQLITE_BUSY_RECOVERY retryable, just as a plain SQLITE_BUSY is. FossilOrigin-Name: fd13dd950d99fd1996860f7a5f220fdc89180194 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 8 +++++--- src/vdbeapi.c | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index f60e23602b..f61e06cf6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sto\serror\shandling\sin\saddModuleArgument()\sin\sthe\svirtual\stable\nprocessing. -D 2015-08-19T12:45:57.389 +C Make\sSQLITE_BUSY_SNAPSHOT\sand\sSQLITE_BUSY_RECOVERY\sretryable,\sjust\sas\sa\splain\nSQLITE_BUSY\sis. +D 2015-08-20T17:18:32.370 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -398,10 +398,10 @@ F src/update.c 487747b328b7216bb7f6af0695d6937d5c9e605f F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c bc9dd64b5db544218b871b66243871c202b2781f F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 2ab1decd98925f8cd846993dde9dccaa69cdf0ef +F src/vdbe.c 6d85be995bd2308a5aa2a68c7b564c5d4cc1a6fb F src/vdbe.h 7a75045d879118b9d3af7e8b3c108f2f27c51473 F src/vdbeInt.h 8b54e01ad0463590e7cffabce0bc36da9ee4f816 -F src/vdbeapi.c adabbd66eb2e3a10f3998485ee0be7e326d06ee4 +F src/vdbeapi.c bda74ef4b5103d7b4a4be36f936d3cf2b56a7d6f F src/vdbeaux.c af2d86b2b114a106c94fc656503fc5c89594f5af F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090 @@ -1374,7 +1374,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P dec14a3980dcf6c61b0b9ac4ba82fa963ac346d4 -R 9e79c5c3619781e4dd0837447f8e7872 +P c573b0a1aa3ba509234f07520fa94d008bcbb330 +R 1e0943db53cafa4eb98e44dc50fad14a U drh -Z 95e599ba5e8b06b741ae2fef900bf405 +Z 77fc4debeb34981fd43290820f00ea8a diff --git a/manifest.uuid b/manifest.uuid index 78e94e2abc..4bc18f7bdf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c573b0a1aa3ba509234f07520fa94d008bcbb330 \ No newline at end of file +fd13dd950d99fd1996860f7a5f220fdc89180194 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f9c988cdf7..2c0034cf64 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -571,7 +571,7 @@ int sqlite3VdbeExec( ** sqlite3_column_text16() failed. */ goto no_mem; } - assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY ); + assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY ); assert( p->bIsReader || p->readOnly!=0 ); p->rc = SQLITE_OK; p->iCurrentTime = 0; @@ -3085,9 +3085,11 @@ case OP_Transaction: { if( pBt ){ rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); - if( rc==SQLITE_BUSY ){ + testcase( rc==SQLITE_BUSY_SNAPSHOT ); + testcase( rc==SQLITE_BUSY_RECOVERY ); + if( (rc&0xff)==SQLITE_BUSY ){ p->pc = (int)(pOp - aOp); - p->rc = rc = SQLITE_BUSY; + p->rc = rc; goto vdbe_return; } if( rc!=SQLITE_OK ){ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index ebd5ef29a2..15a8bba0d4 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -611,7 +611,7 @@ end_of_step: ** were called on statement p. */ assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR - || rc==SQLITE_BUSY || rc==SQLITE_MISUSE + || (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE ); assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp ); if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ From b81fba193079eb6276b3fc94849d847b47c5544e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Aug 2015 18:28:46 +0000 Subject: [PATCH 15/21] Prevent the series.c extension from loading on older versions of SQLite that do not support xCreate==NULL. FossilOrigin-Name: 3efc79427ef4686142d074cfe5b2f0a33af19b2e --- ext/misc/series.c | 5 +++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/ext/misc/series.c b/ext/misc/series.c index 645ddeab15..892426bacb 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -389,6 +389,11 @@ int sqlite3_series_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); #ifndef SQLITE_OMIT_VIRTUALTABLE + if( sqlite3_libversion_number()<3008012 ){ + *pzErrMsg = sqlite3_mprintf( + "generate_series() requires SQLite 3.8.12 or later"); + return SQLITE_ERROR; + } rc = sqlite3_create_module(db, "generate_series", &seriesModule, 0); #endif return rc; diff --git a/manifest b/manifest index ab8f0ade60..4b88941c4f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sseries.c. -D 2015-08-20T16:16:37.345 +C Prevent\sthe\sseries.c\sextension\sfrom\sloading\son\solder\sversions\sof\sSQLite\sthat\ndo\snot\ssupport\sxCreate==NULL. +D 2015-08-20T18:28:46.970 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -196,7 +196,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a -F ext/misc/series.c e9b658e442090f75ae01bbf4924feb52a759674c +F ext/misc/series.c 610bf80e8e85bedf3588907476d4dc2a8cdd013c F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c 86998fb73aefb7b5dc346ba8a58912f312da4996 F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 @@ -1376,7 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a325a08599759471047e234ef9cfcc3cb110aafd -R c7d0daf8fbeee011c3f976b2caec6772 -U dan -Z e8e4b80135954d12498e194483d7037d +P 23db7f50f14801c2cf56c006d7c7f593908b7158 +R d99fb6b924c5803dd958720cff95849c +U drh +Z a0d63a9f28ce5db0938546bd2b7f7c87 diff --git a/manifest.uuid b/manifest.uuid index f79d828421..e9329d72f7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -23db7f50f14801c2cf56c006d7c7f593908b7158 \ No newline at end of file +3efc79427ef4686142d074cfe5b2f0a33af19b2e \ No newline at end of file From d10dbad5e1e0a516b6fa0fcf9419fc92d71165af Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Aug 2015 20:13:37 +0000 Subject: [PATCH 16/21] Correctly handle empty function argument lists on table-valued functions. FossilOrigin-Name: a7acc7878b8bb8e27a0da67b2dbb7bd51df4859b --- manifest | 17 ++++++++--------- manifest.uuid | 2 +- src/build.c | 2 +- src/resolve.c | 8 +++++--- test/tabfunc01.test | 5 +++++ 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 3adf504c43..dddec336ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\stable-valued\sfunctions\sin\sthe\sFROM\sclause\simplemented\sas\nvirtual\stables. -D 2015-08-20T19:55:58.980 +C Correctly\shandle\sempty\sfunction\sargument\slists\son\stable-valued\sfunctions. +D 2015-08-20T20:13:37.543 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -281,7 +281,7 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c f48b3ef91676c06a90a8832987ecef6b94c931ee F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 -F src/build.c 16051071cd855c23e47b087b49ac99c65b1d8c39 +F src/build.c 2a2fd9547c06a71d0e83484acc22f1485f0e731b F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b @@ -334,7 +334,7 @@ F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/printf.c 2bc439ff20a4aad0e0ad50a37a67b5eae7d20edc F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c bbb4874decae6e60eee0395a31205d3b55cd2c00 +F src/resolve.c 1103be495dddaae9378626a484d5d350fcb9d5fa F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c c46de38c1b66355f02a839bb72eb13f277e6d19c F src/shell.c b1f91e60918df3a68efad1e3a11696b9a7e23d23 @@ -1031,7 +1031,7 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6 -F test/tabfunc01.test 61d185dde74aa2ff70085d33bc5f9a0ce8d6a318 +F test/tabfunc01.test ae7f4e5b67edbb423e63efeee37d672bb61d5a07 F test/table.test 33bf0d1fd07f304582695184b8e6feb017303816 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1376,8 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P fd13dd950d99fd1996860f7a5f220fdc89180194 3efc79427ef4686142d074cfe5b2f0a33af19b2e -R ed28318b8329f2834aba92a570f623d2 -T +closed 3efc79427ef4686142d074cfe5b2f0a33af19b2e +P 9b718b06b156163ae34115b6c5f6d163a7ee7cc3 +R 2b816e99c82340667135ddd4e70a16fb U drh -Z 557e316b28e61ca6cba28c2e6c7085e1 +Z d3ffbc216692d7d7c440600b0a1b96fc diff --git a/manifest.uuid b/manifest.uuid index 194a0d685f..54608e6e14 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b718b06b156163ae34115b6c5f6d163a7ee7cc3 \ No newline at end of file +a7acc7878b8bb8e27a0da67b2dbb7bd51df4859b \ No newline at end of file diff --git a/src/build.c b/src/build.c index 96dc03a825..6a5b50b0db 100644 --- a/src/build.c +++ b/src/build.c @@ -3802,7 +3802,7 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ ** table-valued-function. */ void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ - if( p && ALWAYS(p->nSrc>0) ){ + if( p && ALWAYS(p->nSrc>0) && pList ){ struct SrcList_item *pItem = &p->a[p->nSrc-1]; assert( pItem->fg.notIndexed==0 ); assert( pItem->fg.isIndexedBy==0 ); diff --git a/src/resolve.c b/src/resolve.c index 72d5f319c1..9799a136b9 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1451,9 +1451,11 @@ int sqlite3ResolveExprListNames( NameContext *pNC, /* Namespace to resolve expressions in. */ ExprList *pList /* The expression list to be analyzed. */ ){ - int i; - for(i=0; inExpr; i++){ - if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort; + if( pList ){ + int i; + for(i=0; inExpr; i++){ + if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort; + } } return WRC_Continue; } diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 8897893197..b3711baea0 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -61,4 +61,9 @@ do_execsql_test tabfunc01-2.1 { SELECT *, '|' FROM t1, generate_series(1,x) ORDER BY 1, 2 } {2 1 | 2 2 | 3 1 | 3 2 | 3 3 |} +do_execsql_test tabfunc01-2.2 { + SELECT * FROM generate_series() LIMIT 5; +} {0 1 2 3 4} + + finish_test From bc63ec1d6255065472e573d7fb3fea2288561280 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 20 Aug 2015 20:21:06 +0000 Subject: [PATCH 17/21] Fix stray variable declaration for C89. FossilOrigin-Name: 17eb7f18cb76170e109977a94b259b763cd86c47 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index dddec336ba..36b071cdc0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correctly\shandle\sempty\sfunction\sargument\slists\son\stable-valued\sfunctions. -D 2015-08-20T20:13:37.543 +C Fix\sstray\svariable\sdeclaration\sfor\sC89. +D 2015-08-20T20:21:06.528 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -281,7 +281,7 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c f48b3ef91676c06a90a8832987ecef6b94c931ee F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 -F src/build.c 2a2fd9547c06a71d0e83484acc22f1485f0e731b +F src/build.c 733a7b19f2c467775d5997d8467ce3677d2c8cc6 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b @@ -1376,7 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9b718b06b156163ae34115b6c5f6d163a7ee7cc3 -R 2b816e99c82340667135ddd4e70a16fb -U drh -Z d3ffbc216692d7d7c440600b0a1b96fc +P a7acc7878b8bb8e27a0da67b2dbb7bd51df4859b +R ab9999ab7b4e03861512ce91d476cfe4 +U mistachkin +Z 6bb10870cccae9f7d2b7bc147f067428 diff --git a/manifest.uuid b/manifest.uuid index 54608e6e14..eec676b836 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7acc7878b8bb8e27a0da67b2dbb7bd51df4859b \ No newline at end of file +17eb7f18cb76170e109977a94b259b763cd86c47 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 6a5b50b0db..5f8bf8488f 100644 --- a/src/build.c +++ b/src/build.c @@ -355,6 +355,7 @@ Table *sqlite3LocateTable( p = sqlite3FindTable(pParse->db, zName, zDbase); if( p==0 ){ + const char *zMsg; #ifndef SQLITE_OMIT_VIRTUAL_TABLE /* If zName is the not the name of a table in the schema created using ** CREATE, then check to see if it is the name of an virtual table that @@ -364,7 +365,7 @@ Table *sqlite3LocateTable( return pMod->pEpoTab; } #endif - const char *zMsg = isView ? "no such view" : "no such table"; + zMsg = isView ? "no such view" : "no such table"; if( zDbase ){ sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); }else{ From 1abbe28884026f6311b18c30ca5a780fec5d0261 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 20 Aug 2015 21:09:32 +0000 Subject: [PATCH 18/21] Fix compiler warnings in the sqldiff tool seen with MSVC. FossilOrigin-Name: 072279d458fbb74a812a9ee723041d6b7c662a88 --- manifest | 15 +++++++++------ manifest.uuid | 2 +- tool/sqldiff.c | 18 +++++++++++------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 36b071cdc0..297a655bf5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sstray\svariable\sdeclaration\sfor\sC89. -D 2015-08-20T20:21:06.528 +C Fix\scompiler\swarnings\sin\sthe\ssqldiff\stool\sseen\swith\sMSVC. +D 2015-08-20T21:09:32.725 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1365,7 +1365,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c -F tool/sqldiff.c a6988cc6e10e08662d73df28538df43b01dc371e +F tool/sqldiff.c b318efc2eaf7a7fac4d281a0ce736193cb2506df F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f @@ -1376,7 +1376,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a7acc7878b8bb8e27a0da67b2dbb7bd51df4859b -R ab9999ab7b4e03861512ce91d476cfe4 +P 17eb7f18cb76170e109977a94b259b763cd86c47 +R 104bda6f56c91429ce0a720bb365ee76 +T *branch * msvcWarn +T *sym-msvcWarn * +T -sym-trunk * U mistachkin -Z 6bb10870cccae9f7d2b7bc147f067428 +Z 3c2642f645417b50de6b6b4d431a1560 diff --git a/manifest.uuid b/manifest.uuid index eec676b836..60c52a42f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -17eb7f18cb76170e109977a94b259b763cd86c47 \ No newline at end of file +072279d458fbb74a812a9ee723041d6b7c662a88 \ No newline at end of file diff --git a/tool/sqldiff.c b/tool/sqldiff.c index 3a5c4e4f7c..9f0b705c40 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -810,9 +810,9 @@ static void hash_init(hash *pHash, const char *z){ */ static void hash_next(hash *pHash, int c){ u16 old = pHash->z[pHash->i]; - pHash->z[pHash->i] = c; + pHash->z[pHash->i] = (char)c; pHash->i = (pHash->i+1)&(NHASH-1); - pHash->a = pHash->a - old + c; + pHash->a = pHash->a - old + (char)c; pHash->b = pHash->b - NHASH*old + pHash->a; } @@ -849,7 +849,7 @@ static void putInt(unsigned int v, char **pz){ */ static int digit_count(int v){ unsigned int i, x; - for(i=1, x=64; v>=x; i++, x <<= 6){} + for(i=1, x=64; (unsigned int)v>=x; i++, x <<= 6){} return i; } @@ -956,7 +956,7 @@ static int rbuDeltaCreate( unsigned int lenOut, /* Length of the target file */ char *zDelta /* Write the delta into this buffer */ ){ - int i, base; + unsigned int i, base; char *zOrigDelta = zDelta; hash h; int nHash; /* Number of hash table entries */ @@ -1005,7 +1005,7 @@ static int rbuDeltaCreate( base = 0; /* We have already generated everything before zOut[base] */ while( base+NHASH Date: Thu, 20 Aug 2015 21:14:31 +0000 Subject: [PATCH 19/21] Skip calling the virtual table xDestroy method when it is null. FossilOrigin-Name: b73ad305a6b7cb84fe0a1efb334b8e4592e21c40 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vtab.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 36b071cdc0..3c5d640edd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sstray\svariable\sdeclaration\sfor\sC89. -D 2015-08-20T20:21:06.528 +C Skip\scalling\sthe\svirtual\stable\sxDestroy\smethod\swhen\sit\sis\snull. +D 2015-08-20T21:14:31.239 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -408,7 +408,7 @@ F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090 F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 -F src/vtab.c 05395350f947ec0b1af25e8502b9cfec84f17ea7 +F src/vtab.c ab36813224d5551cb60f87f3c7e58e0b32541e12 F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 6fb6b68969e4692593c2552c4e7bff5882de2cb8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 @@ -1376,7 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a7acc7878b8bb8e27a0da67b2dbb7bd51df4859b -R ab9999ab7b4e03861512ce91d476cfe4 +P 17eb7f18cb76170e109977a94b259b763cd86c47 +R 25130809f3babeec0691a193d02e4069 U mistachkin -Z 6bb10870cccae9f7d2b7bc147f067428 +Z f2d173175579a2040d53483e92ff71ba diff --git a/manifest.uuid b/manifest.uuid index eec676b836..fda47be90f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -17eb7f18cb76170e109977a94b259b763cd86c47 \ No newline at end of file +b73ad305a6b7cb84fe0a1efb334b8e4592e21c40 \ No newline at end of file diff --git a/src/vtab.c b/src/vtab.c index fca8170d22..8042e0e7bd 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -801,6 +801,7 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){ VTable *p; + int (*xDestroy)(sqlite3_vtab *); for(p=pTab->pVTable; p; p=p->pNext){ assert( p->pVtab ); if( p->pVtab->nRef>0 ){ @@ -808,7 +809,8 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ } } p = vtabDisconnectAll(db, pTab); - rc = p->pMod->pModule->xDestroy(p->pVtab); + xDestroy = p->pMod->pModule->xDestroy; + rc = xDestroy ? xDestroy(p->pVtab) : SQLITE_OK; /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ if( rc==SQLITE_OK ){ assert( pTab->pVTable==p && p->pNext==0 ); From d8b1bfc6bf2f9463c1dfc27e7c52e9207b291145 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Aug 2015 23:21:34 +0000 Subject: [PATCH 20/21] Fix corner-case memory management issues in table-valued functions. Change virtual table handling so that if xDestroy is missing the table is eponymous only even if xCreate is present. FossilOrigin-Name: 774e6a14b124bbae4da0e188b62aee9ffb8c3745 --- ext/misc/series.c | 13 ++++++++----- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/build.c | 7 ++++--- src/resolve.c | 9 ++++----- src/vtab.c | 11 ++++++----- src/whereexpr.c | 2 +- test/tabfunc01.test | 2 +- 8 files changed, 37 insertions(+), 33 deletions(-) diff --git a/ext/misc/series.c b/ext/misc/series.c index 892426bacb..21f95ccb74 100644 --- a/ext/misc/series.c +++ b/ext/misc/series.c @@ -112,8 +112,7 @@ static int seriesConnect( char **pzErr ){ sqlite3_vtab *pNew; - pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); - if( pNew==0 ) return SQLITE_NOMEM; + int rc; /* Column numbers */ #define SERIES_COLUMN_VALUE 0 @@ -121,10 +120,14 @@ static int seriesConnect( #define SERIES_COLUMN_STOP 2 #define SERIES_COLUMN_STEP 3 - sqlite3_declare_vtab(db, + rc = sqlite3_declare_vtab(db, "CREATE TABLE x(value,start hidden,stop hidden,step hidden)"); - memset(pNew, 0, sizeof(*pNew)); - return SQLITE_OK; + if( rc==SQLITE_OK ){ + pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + } + return rc; } /* diff --git a/manifest b/manifest index 3c5d640edd..06e7ddf3f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Skip\scalling\sthe\svirtual\stable\sxDestroy\smethod\swhen\sit\sis\snull. -D 2015-08-20T21:14:31.239 +C Fix\scorner-case\smemory\smanagement\sissues\sin\stable-valued\sfunctions.\s\sChange\nvirtual\stable\shandling\sso\sthat\sif\sxDestroy\sis\smissing\sthe\stable\sis\neponymous\sonly\seven\sif\sxCreate\sis\spresent. +D 2015-08-20T23:21:34.475 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -196,7 +196,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a -F ext/misc/series.c 610bf80e8e85bedf3588907476d4dc2a8cdd013c +F ext/misc/series.c 6f94daf590d0668187631dee2a4d7e1d8f3095c3 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c 86998fb73aefb7b5dc346ba8a58912f312da4996 F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 @@ -281,7 +281,7 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c f48b3ef91676c06a90a8832987ecef6b94c931ee F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 -F src/build.c 733a7b19f2c467775d5997d8467ce3677d2c8cc6 +F src/build.c 0ebd9d21500311ff4b7df52fe927e5f235ad1867 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b @@ -334,7 +334,7 @@ F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/printf.c 2bc439ff20a4aad0e0ad50a37a67b5eae7d20edc F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 1103be495dddaae9378626a484d5d350fcb9d5fa +F src/resolve.c 02e2c9ed5f45a22d41e799739c17b770dbb31866 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c c46de38c1b66355f02a839bb72eb13f277e6d19c F src/shell.c b1f91e60918df3a68efad1e3a11696b9a7e23d23 @@ -408,7 +408,7 @@ F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090 F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 -F src/vtab.c ab36813224d5551cb60f87f3c7e58e0b32541e12 +F src/vtab.c d31174e4c8f592febab3fa7f69e18320b4fd657a F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 6fb6b68969e4692593c2552c4e7bff5882de2cb8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 @@ -416,7 +416,7 @@ F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba F src/where.c 66518a14a1238611aa0744d6980b6b7f544f4816 F src/whereInt.h 880a8599226ac1c00203490d934f3ed79b292572 F src/wherecode.c 69f19535a6de0cceb10e16b31a3a03463e31bc24 -F src/whereexpr.c 6332ade8f72beebb6438734e92757da4631176e0 +F src/whereexpr.c f9dbd159127452150c92b558e184827ecb8f9229 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1031,7 +1031,7 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6 -F test/tabfunc01.test ae7f4e5b67edbb423e63efeee37d672bb61d5a07 +F test/tabfunc01.test d556af2def6af10b0a759b2f8a8f41135c2b634e F test/table.test 33bf0d1fd07f304582695184b8e6feb017303816 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1376,7 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 17eb7f18cb76170e109977a94b259b763cd86c47 -R 25130809f3babeec0691a193d02e4069 -U mistachkin -Z f2d173175579a2040d53483e92ff71ba +P b73ad305a6b7cb84fe0a1efb334b8e4592e21c40 +R f600d04c9db5494b68811630044e0207 +U drh +Z 52a18320de00f5816e7cb149e8e4308c diff --git a/manifest.uuid b/manifest.uuid index fda47be90f..903bbc12fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b73ad305a6b7cb84fe0a1efb334b8e4592e21c40 \ No newline at end of file +774e6a14b124bbae4da0e188b62aee9ffb8c3745 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 5f8bf8488f..d6ceb2c88e 100644 --- a/src/build.c +++ b/src/build.c @@ -355,7 +355,6 @@ Table *sqlite3LocateTable( p = sqlite3FindTable(pParse->db, zName, zDbase); if( p==0 ){ - const char *zMsg; #ifndef SQLITE_OMIT_VIRTUAL_TABLE /* If zName is the not the name of a table in the schema created using ** CREATE, then check to see if it is the name of an virtual table that @@ -365,7 +364,7 @@ Table *sqlite3LocateTable( return pMod->pEpoTab; } #endif - zMsg = isView ? "no such view" : "no such table"; + const char *zMsg = isView ? "no such view" : "no such table"; if( zDbase ){ sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); }else{ @@ -3803,13 +3802,15 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ ** table-valued-function. */ void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ - if( p && ALWAYS(p->nSrc>0) && pList ){ + if( p && pList ){ struct SrcList_item *pItem = &p->a[p->nSrc-1]; assert( pItem->fg.notIndexed==0 ); assert( pItem->fg.isIndexedBy==0 ); assert( pItem->fg.isTabFunc==0 ); pItem->u1.pFuncArg = pList; pItem->fg.isTabFunc = 1; + }else{ + sqlite3ExprListDelete(pParse->db, pList); } } diff --git a/src/resolve.c b/src/resolve.c index 9799a136b9..0908d4cd5d 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1451,11 +1451,10 @@ int sqlite3ResolveExprListNames( NameContext *pNC, /* Namespace to resolve expressions in. */ ExprList *pList /* The expression list to be analyzed. */ ){ - if( pList ){ - int i; - for(i=0; inExpr; i++){ - if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort; - } + assert( pList!=0 ); + int i; + for(i=0; inExpr; i++){ + if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort; } return WRC_Continue; } diff --git a/src/vtab.c b/src/vtab.c index 8042e0e7bd..1675ca2e31 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -699,7 +699,7 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ ** invoke it now. If the module has not been registered, return an ** error. Otherwise, do nothing. */ - if( pMod==0 || pMod->pModule->xCreate==0 ){ + if( pMod==0 || pMod->pModule->xCreate==0 || pMod->pModule->xDestroy==0 ){ *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod); rc = SQLITE_ERROR; }else{ @@ -810,7 +810,8 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ } p = vtabDisconnectAll(db, pTab); xDestroy = p->pMod->pModule->xDestroy; - rc = xDestroy ? xDestroy(p->pVtab) : SQLITE_OK; + assert( xDestroy!=0 ); /* Checked before the virtual table is created */ + rc = xDestroy(p->pVtab); /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ if( rc==SQLITE_OK ){ assert( pTab->pVTable==p && p->pNext==0 ); @@ -1123,9 +1124,9 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ pTab->tabFlags |= TF_Virtual; pTab->nModuleArg = 0; pTab->iPKey = -1; - addModuleArgument(db, pTab, pTab->zName); + addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName)); addModuleArgument(db, pTab, 0); - addModuleArgument(db, pTab, pTab->zName); + addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName)); rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr); if( rc ){ sqlite3ErrorMsg(pParse, "%s", zErr); @@ -1144,7 +1145,7 @@ void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){ Table *pTab = pMod->pEpoTab; if( (pTab = pMod->pEpoTab)!=0 ){ sqlite3DeleteColumnNames(db, pTab); - sqlite3DbFree(db, pTab->azModuleArg); + sqlite3VtabClear(db, pTab); sqlite3DbFree(db, pTab); pMod->pEpoTab = 0; } diff --git a/src/whereexpr.c b/src/whereexpr.c index a0f7c822af..d6f94b3e1a 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1273,7 +1273,7 @@ void sqlite3WhereTabFuncArgs( for(j=k=0; jnExpr; j++){ while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){ k++; } if( k>=pTab->nCol ){ - sqlite3ErrorMsg(pParse, "too many arguments on %s - max %d", + sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d", pTab->zName, j); return; } diff --git a/test/tabfunc01.test b/test/tabfunc01.test index b3711baea0..39264d2f05 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -43,7 +43,7 @@ do_execsql_test tabfunc01-1.6 { } {1 4 7 10} do_catchsql_test tabfunc01-1.7 { SELECT * FROM generate_series(1,9,2,11); -} {1 {too many arguments on generate_series - max 3}} +} {1 {too many arguments on generate_series() - max 3}} do_execsql_test tabfunc01-1.8 { SELECT * FROM generate_series(0,32,5) ORDER BY rowid DESC; From c743579e59d310769f1e53e5217e58ae74b249cf Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Aug 2015 23:28:18 +0000 Subject: [PATCH 21/21] Fix a couple C99-isms that cause compile errors on MSVC. FossilOrigin-Name: bc577fe6cbbe5385d81d6fa0f3c34bb1c833f0d6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 2 +- src/resolve.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 06e7ddf3f5..6bfc6a1697 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scorner-case\smemory\smanagement\sissues\sin\stable-valued\sfunctions.\s\sChange\nvirtual\stable\shandling\sso\sthat\sif\sxDestroy\sis\smissing\sthe\stable\sis\neponymous\sonly\seven\sif\sxCreate\sis\spresent. -D 2015-08-20T23:21:34.475 +C Fix\sa\scouple\sC99-isms\sthat\scause\scompile\serrors\son\sMSVC. +D 2015-08-20T23:28:18.956 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 4f663b6b4954b9b1eb0e6f08387688a93b57542d F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -281,7 +281,7 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c f48b3ef91676c06a90a8832987ecef6b94c931ee F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 -F src/build.c 0ebd9d21500311ff4b7df52fe927e5f235ad1867 +F src/build.c 5eb5d055a1d1cdaaea25e01b12607aa894bc0911 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b @@ -334,7 +334,7 @@ F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/printf.c 2bc439ff20a4aad0e0ad50a37a67b5eae7d20edc F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 02e2c9ed5f45a22d41e799739c17b770dbb31866 +F src/resolve.c 7a67cd2aebc9a9eeecd1d104eb6a9237388eb452 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c c46de38c1b66355f02a839bb72eb13f277e6d19c F src/shell.c b1f91e60918df3a68efad1e3a11696b9a7e23d23 @@ -1376,7 +1376,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b73ad305a6b7cb84fe0a1efb334b8e4592e21c40 -R f600d04c9db5494b68811630044e0207 +P 774e6a14b124bbae4da0e188b62aee9ffb8c3745 +R a705c27f52160ef69f13084e79416a63 U drh -Z 52a18320de00f5816e7cb149e8e4308c +Z 3baa7e86161b56868138f2b0a38c7271 diff --git a/manifest.uuid b/manifest.uuid index 903bbc12fa..0240b8ded9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -774e6a14b124bbae4da0e188b62aee9ffb8c3745 \ No newline at end of file +bc577fe6cbbe5385d81d6fa0f3c34bb1c833f0d6 \ No newline at end of file diff --git a/src/build.c b/src/build.c index d6ceb2c88e..e45908dc3b 100644 --- a/src/build.c +++ b/src/build.c @@ -355,6 +355,7 @@ Table *sqlite3LocateTable( p = sqlite3FindTable(pParse->db, zName, zDbase); if( p==0 ){ + const char *zMsg = isView ? "no such view" : "no such table"; #ifndef SQLITE_OMIT_VIRTUAL_TABLE /* If zName is the not the name of a table in the schema created using ** CREATE, then check to see if it is the name of an virtual table that @@ -364,7 +365,6 @@ Table *sqlite3LocateTable( return pMod->pEpoTab; } #endif - const char *zMsg = isView ? "no such view" : "no such table"; if( zDbase ){ sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); }else{ diff --git a/src/resolve.c b/src/resolve.c index 0908d4cd5d..c859e886a7 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1451,8 +1451,8 @@ int sqlite3ResolveExprListNames( NameContext *pNC, /* Namespace to resolve expressions in. */ ExprList *pList /* The expression list to be analyzed. */ ){ - assert( pList!=0 ); int i; + assert( pList!=0 ); for(i=0; inExpr; i++){ if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort; }