From: danielk1977 Date: Fri, 10 Feb 2006 07:07:14 +0000 (+0000) Subject: Fix the origin APIs so that they correctly handle views and subqueries that cannot... X-Git-Tag: version-3.6.10~3095 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=1787ccabed3c606f0c993a2a9c71c9912417a475;p=thirdparty%2Fsqlite.git Fix the origin APIs so that they correctly handle views and subqueries that cannot be flattened. (CVS 3072) FossilOrigin-Name: 5e8611e13de08d704cea6c9c4466c3af842a7a1a --- diff --git a/manifest b/manifest index 69539ebe78..61c6228494 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sdeadlock\sproblem\sin\sthe\sunix\smutex.\s\sTicket\s#1672.\s(CVS\s3071) -D 2006-02-10T04:33:12 +C Fix\sthe\sorigin\sAPIs\sso\sthat\sthey\scorrectly\shandle\sviews\sand\ssubqueries\sthat\scannot\sbe\sflattened.\s(CVS\s3072) +D 2006-02-10T07:07:14 F Makefile.in 5d8dff443383918b700e495de42ec65bc1c8865b F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -36,13 +36,13 @@ F src/attach.c d73a3505de3fb9e373d0a158978116c4212031d0 F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2 F src/btree.c 66112ae6a5caab384010344b514e98b346f550c0 F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184 -F src/build.c d959aa9c2ab9c79d3d872ce91ef719698658210c +F src/build.c 11798f165cdcf3b46f4b10b2ba3853b8c370eac2 F src/callback.c 1bf497306c32229114f826707054df7ebe10abf2 F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675 F src/date.c cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e F src/delete.c ca404d5fd5f678e32f2f46377ad802cd0219aa99 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b -F src/expr.c 1149c3380bfce27703f5e9bec7dfb8e51baaf9d9 +F src/expr.c 9c957fabf95ef62288151eecd5c490a629470666 F src/func.c 93d004b453a5d9aa754e673eef75d3c9527e0f54 F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84 @@ -66,11 +66,11 @@ F src/pragma.c 8e135979702f249dd5877402056df0a336ea5a12 F src/prepare.c cf0fc8ebaf94409955ecb09ffeb0099c9ef44693 F src/printf.c c7d6ad9efb71c466305297a448308f467b6e2b6e F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261 -F src/select.c 7ed6f28cdcf7c317de317f6ce51c28c667d76e24 +F src/select.c 7d069e875d0eec05129c7e8b9c99422d7c9c6321 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c 738f55ed75fb36731e764bfdb40756ac43b90b08 F src/sqlite.h.in bc78a247fd9f294b30a4c03894f93fcb1e166410 -F src/sqliteInt.h 0121298397ac14eb468ab1ba9d488ac7ed7d88a1 +F src/sqliteInt.h fe74eaa6aa953ace27c3db3272a470d279b6e3e5 F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316 F src/tclsqlite.c d9c26374b52cd47233ae0620d0a858a59b601f89 F src/test1.c ca8cb34747c53479e0748c11d1a10cc07d582bb8 @@ -131,8 +131,8 @@ F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027 F test/btree7.test a6d3b842db22af97dd14b989e90a2fd96066b72f F test/btree8.test fadc112bcbd6a0c622d34c813fc8a648eacf8804 F test/busy.test 0271c854738e23ad76e10d4096a698e5af29d211 -F test/capi2.test fe07532d7595cd2cc0423f8537a1cbb831bd8607 -F test/capi3.test e26c09ec40c5dddf215c5dd359b4989a53dde876 +F test/capi2.test e7d3f2e719726c7e3be2c1c69eb4177c5165fad8 +F test/capi3.test 6f9f22408b03ee1cef747caa15f7ed55cbe0d08c F test/capi3b.test 5f0bc94b104e11086b1103b20277e1910f59c7f4 F test/cast.test aabdcb3873bb2f40d855bf63950f6d99a5a196c7 F test/check.test 55ad950d7ad24d6eb3328c54149f90d38a39a962 @@ -351,7 +351,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 6ebb8f9bb2f6a3f7fde19267727aa4e2d878a416 -R f2123b74208f8dc7a90c193c43dfdac6 -U drh -Z 902f2f44199cd95ee9b139b42f49b143 +P a6c30be214bb575f9ecfa299b7a597d21e3d3aca +R 41b2424fdff209e4871bfdf191620183 +U danielk1977 +Z d531a3addcf6506678bf78af10fce292 diff --git a/manifest.uuid b/manifest.uuid index d2afe34e09..c4d6312f4c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a6c30be214bb575f9ecfa299b7a597d21e3d3aca \ No newline at end of file +5e8611e13de08d704cea6c9c4466c3af842a7a1a \ No newline at end of file diff --git a/src/build.c b/src/build.c index 9caf713e7f..a49beb4ee4 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.384 2006/02/05 18:55:20 drh Exp $ +** $Id: build.c,v 1.385 2006/02/10 07:07:14 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -2847,6 +2847,7 @@ SrcList *sqlite3SrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){ pItem->zName = sqlite3NameFromToken(pTable); pItem->zDatabase = sqlite3NameFromToken(pDatabase); pItem->iCursor = -1; + pItem->isPopulated = 0; pList->nSrc++; return pList; } diff --git a/src/expr.c b/src/expr.c index 9a1e046334..5a05f513a2 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.253 2006/01/30 14:36:59 drh Exp $ +** $Id: expr.c,v 1.254 2006/02/10 07:07:15 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -495,6 +495,7 @@ SrcList *sqlite3SrcListDup(SrcList *p){ pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias); pNewItem->jointype = pOldItem->jointype; pNewItem->iCursor = pOldItem->iCursor; + pNewItem->isPopulated = pOldItem->isPopulated; pTab = pNewItem->pTab = pOldItem->pTab; if( pTab ){ pTab->nRef++; diff --git a/src/select.c b/src/select.c index 9eb2a1004f..3f2197582e 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.303 2006/02/10 03:06:10 danielk1977 Exp $ +** $Id: select.c,v 1.304 2006/02/10 07:07:16 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -2865,7 +2865,7 @@ int sqlite3Select( int needRestoreContext; struct SrcList_item *pItem = &pTabList->a[i]; - if( pItem->pSelect==0 ) continue; + if( pItem->pSelect==0 || pItem->isPopulated ) continue; if( pItem->zName!=0 ){ zSavedAuthContext = pParse->zAuthContext; pParse->zAuthContext = pItem->zName; @@ -3259,15 +3259,14 @@ int sqlite3Select( #ifndef SQLITE_OMIT_SUBQUERY /* If this was a subquery, we have now converted the subquery into a - ** temporary table. So delete the subquery structure from the parent - ** to prevent this subquery from being evaluated again and to force the - ** the use of the temporary table. + ** temporary table. So set the SrcList_item.isPopulated flag to prevent + ** this subquery from being evaluated again and to force the use of + ** the temporary table. */ if( pParent ){ assert( pParent->pSrc->nSrc>parentTab ); assert( pParent->pSrc->a[parentTab].pSelect==p ); - sqlite3SelectDelete(p); - pParent->pSrc->a[parentTab].pSelect = 0; + pParent->pSrc->a[parentTab].isPopulated = 1; } #endif diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 20bf1c5e8b..1a76292470 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.479 2006/01/24 16:37:58 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.480 2006/02/10 07:07:16 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1069,6 +1069,7 @@ struct SrcList { char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ Table *pTab; /* An SQL table corresponding to zName */ Select *pSelect; /* A SELECT statement used in place of a table name */ + u8 isPopulated; /* Temporary table associated with SELECT is populated */ u8 jointype; /* Type of join between this table and the next */ i16 iCursor; /* The VDBE cursor number used to access this table */ Expr *pOn; /* The ON clause of a join */ diff --git a/test/capi2.test b/test/capi2.test index 0c1c46b4c1..3181a498ee 100644 --- a/test/capi2.test +++ b/test/capi2.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script testing the callback-free C/C++ API. # -# $Id: capi2.test,v 1.29 2006/02/10 03:06:10 danielk1977 Exp $ +# $Id: capi2.test,v 1.30 2006/02/10 07:07:16 danielk1977 Exp $ # set testdir [file dirname $argv0] @@ -722,8 +722,65 @@ do_test capi2-12.5 { do_test capi2-12.6 { check_origins {SELECT (SELECT col2), (SELECT col1) FROM view1} } [list {main tab1 col2} {main tab1 col1}] -db2 close +do_test capi2-12.7 { + check_origins {SELECT * FROM view1} +} [list {main tab1 col1} {main tab1 col2}] +do_test capi2-12.8 { + check_origins {select * from (select * from view1)} +} [list {main tab1 col1} {main tab1 col2}] +do_test capi2-12.9 { + check_origins {select * from (select * from (select * from view1))} +} [list {main tab1 col1} {main tab1 col2}] +do_test capi2-12.10 { + db close + sqlite3 db test.db + set ::DB [sqlite3_connection_pointer db] + check_origins {select * from (select * from (select * from view1))} +} [list {main tab1 col1} {main tab1 col2}] + +# This view will thwart the flattening optimization. +do_test capi2-13.1 { + execsql { + CREATE VIEW view2 AS SELECT * FROM tab1 limit 10 offset 10; + } +} {} +breakpoint +do_test capi2-13.2 { + check_origins {SELECT col2, col1 FROM view2} +} [list {main tab1 col2} {main tab1 col1}] +do_test capi2-13.3 { + check_origins {SELECT col2 AS hello, col1 AS world FROM view2} +} [list {main tab1 col2} {main tab1 col1}] +do_test capi2-13.4 { + check_origins {SELECT b, a FROM (SELECT col1 AS a, col2 AS b FROM view2)} +} [list {main tab1 col2} {main tab1 col1}] +do_test capi2-13.5 { + check_origins {SELECT (SELECT col2 FROM view2), (SELECT col1 FROM view2)} +} [list {main tab1 col2} {main tab1 col1}] +do_test capi2-13.6 { + check_origins {SELECT (SELECT col2), (SELECT col1) FROM view2} +} [list {main tab1 col2} {main tab1 col1}] +do_test capi2-13.7 { + check_origins {SELECT * FROM view2} +} [list {main tab1 col1} {main tab1 col2}] +do_test capi2-13.8 { + check_origins {select * from (select * from view2)} +} [list {main tab1 col1} {main tab1 col2}] +do_test capi2-13.9 { + check_origins {select * from (select * from (select * from view2))} +} [list {main tab1 col1} {main tab1 col2}] +do_test capi2-13.10 { + db close + sqlite3 db test.db + set ::DB [sqlite3_connection_pointer db] + check_origins {select * from (select * from (select * from view2))} +} [list {main tab1 col1} {main tab1 col2}] +do_test capi2-13.11 { + check_origins {select * from (select * from tab1 limit 10 offset 10)} +} [list {main tab1 col1} {main tab1 col2}] + } ;# ifcapable columnmetadata +db2 close finish_test diff --git a/test/capi3.test b/test/capi3.test index 3d6fe1c571..fdff97e412 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script testing the callback-free C/C++ API. # -# $Id: capi3.test,v 1.42 2006/02/10 02:27:47 danielk1977 Exp $ +# $Id: capi3.test,v 1.43 2006/02/10 07:07:16 danielk1977 Exp $ # set testdir [file dirname $argv0] @@ -308,69 +308,76 @@ proc check_header {STMT test names decltypes} { # check_header test1.1 {1 2 3} {"" "" ""} # proc check_origin_header {STMT test dbs tables cols} { - # Use the return value of sqlite3_column_count() to build - # a list of column indexes. i.e. If sqlite3_column_count - # is 3, build the list {0 1 2}. - set ::idxlist [list] - set ::numcols [sqlite3_column_count $STMT] - for {set i 0} {$i < $::numcols} {incr i} {lappend ::idxlist $i} - - # Database names in UTF-8 - do_test $test.8 { - set cnamelist [list] - foreach i $idxlist { - lappend cnamelist [sqlite3_column_database_name $STMT $i] - } - set cnamelist - } $dbs - - # Database names in UTF-16 - ifcapable {utf16} { - do_test $test.9 { + # If sqlite3_column_origin_name() and friends are not compiled into + # this build, this proc is a no-op. +ifcapable columnmetadata { + + # Use the return value of sqlite3_column_count() to build + # a list of column indexes. i.e. If sqlite3_column_count + # is 3, build the list {0 1 2}. + set ::idxlist [list] + set ::numcols [sqlite3_column_count $STMT] + for {set i 0} {$i < $::numcols} {incr i} {lappend ::idxlist $i} + + # Database names in UTF-8 + do_test $test.8 { set cnamelist [list] foreach i $idxlist { - lappend cnamelist [utf8 [sqlite3_column_database_name16 $STMT $i]] - } + lappend cnamelist [sqlite3_column_database_name $STMT $i] + } set cnamelist } $dbs - } - - # Table names in UTF-8 - do_test $test.10 { - set cnamelist [list] - foreach i $idxlist {lappend cnamelist [sqlite3_column_table_name $STMT $i]} - set cnamelist - } $tables - - # Table names in UTF-16 - ifcapable {utf16} { - do_test $test.11 { + + # Database names in UTF-16 + ifcapable {utf16} { + do_test $test.9 { + set cnamelist [list] + foreach i $idxlist { + lappend cnamelist [utf8 [sqlite3_column_database_name16 $STMT $i]] + } + set cnamelist + } $dbs + } + + # Table names in UTF-8 + do_test $test.10 { set cnamelist [list] foreach i $idxlist { - lappend cnamelist [utf8 [sqlite3_column_table_name16 $STMT $i]] - } + lappend cnamelist [sqlite3_column_table_name $STMT $i] + } set cnamelist } $tables - } - - # Origin names in UTF-8 - do_test $test.12 { - set cnamelist [list] - foreach i $idxlist { - lappend cnamelist [sqlite3_column_origin_name $STMT $i] - } - set cnamelist - } $cols - - # Origin declaration types in UTF-16 - ifcapable {utf16} { - do_test $test.13 { + + # Table names in UTF-16 + ifcapable {utf16} { + do_test $test.11 { + set cnamelist [list] + foreach i $idxlist { + lappend cnamelist [utf8 [sqlite3_column_table_name16 $STMT $i]] + } + set cnamelist + } $tables + } + + # Origin names in UTF-8 + do_test $test.12 { set cnamelist [list] foreach i $idxlist { - lappend cnamelist [utf8 [sqlite3_column_origin_name16 $STMT $i]] - } + lappend cnamelist [sqlite3_column_origin_name $STMT $i] + } set cnamelist } $cols + + # Origin declaration types in UTF-16 + ifcapable {utf16} { + do_test $test.13 { + set cnamelist [list] + foreach i $idxlist { + lappend cnamelist [utf8 [sqlite3_column_origin_name16 $STMT $i]] + } + set cnamelist + } $cols + } } }