]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Bring comments on the INSERT code generator up-to-date. Fix the INSERT code
authordrh <drh@noemail.net>
Sun, 19 Apr 2015 18:32:43 +0000 (18:32 +0000)
committerdrh <drh@noemail.net>
Sun, 19 Apr 2015 18:32:43 +0000 (18:32 +0000)
generator so that it correctly handles inserts from a SELECT into a virtual
table with non-terminal hidden columns.

FossilOrigin-Name: 4ac81fac6c6302c042be3df493a41630b733fff0

manifest
manifest.uuid
src/insert.c
src/sqliteInt.h
src/vtab.c
test/vtabA.test

index f1a2f3bac89e7a920f722afafa2702ae848c8d17..3f642604b2aedd216a1e4505e6b096840cf4fe3f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C The\ssqlite3_trace()\scallback\sdoes\snot\stry\sto\sexpand\sparameters\sin\sstatements\nthat\shave\sno\sparameter.
-D 2015-04-18T19:20:14.612
+C Bring\scomments\son\sthe\sINSERT\scode\sgenerator\sup-to-date.\s\sFix\sthe\sINSERT\scode\ngenerator\sso\sthat\sit\scorrectly\shandles\sinserts\sfrom\sa\sSELECT\sinto\sa\svirtual\ntable\swith\snon-terminal\shidden\scolumns.
+D 2015-04-19T18:32:43.531
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in faaf75b89840659d74501bea269c7e33414761c1
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -190,7 +190,7 @@ F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e
 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
-F src/insert.c 305dd3f9539d0affa4bf1c14cc7dffb34867e040
+F src/insert.c 9f5f25a9d645089973d2f451711b7402bfde6ab5
 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
 F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
@@ -235,7 +235,7 @@ F src/shell.c 28b3e1174a7fc00155d7d00880a33589a88508c9
 F src/sqlite.h.in ca27603a36fcacdaac5a19d8ee35aaff8ce8516f
 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
 F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
-F src/sqliteInt.h af228df2a02bf1a608d678b312d46aa480470b3c
+F src/sqliteInt.h 3a1fccc2bb62ab16750730b6f6f24305e686a0ce
 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
 F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
@@ -302,7 +302,7 @@ F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
 F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9
 F src/vdbesort.c 2e7f683464fd5db3be4beaa1ff2d39e24fcb64b8
 F src/vdbetrace.c f95c2dff9041fcf07f871789c22ebb0648ea0b7c
-F src/vtab.c be741af2a377bd894104d62504796e7394a04916
+F src/vtab.c 4feb365e2688dd02474e671e37f27e35784d2cff
 F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
 F src/wal.c 753995db83247f20361a8e8a874990b21a75abd9
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
@@ -1122,7 +1122,7 @@ F test/vtab6.test 5f5380c425e52993560ab4763db4f826d2ba7b09
 F test/vtab7.test ae560ebea870ed04e9aa4177cc302f910faaabb5
 F test/vtab8.test e19fa4a538fcd1bb66c22825fa8f71618fb13583
 F test/vtab9.test ea58d2b95d61955f87226381716b2d0b1d4e4f9b
-F test/vtabA.test c86e1990b7e1e2bb34602a06fffa4c69f2b516dc
+F test/vtabA.test 1317f06a03597eee29f40a49b6c21e1aaba4285f
 F test/vtabB.test 04df5dc531b9f44d9ca65b9c1b79f12b5922a796
 F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
@@ -1251,7 +1251,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 2eed41fda068f2cbac55e63d7c1875ddaa331508
-R fe8a360bbce7dedd87d096d07c896e4c
+P 917e3c36293a1bf052a16116c93e5037ed712f96
+R b611a70a7a5e6fee6ae7534de091ac22
 U drh
-Z 768a04b82f6060145bfe8edb7197ea08
+Z cc4a9846aabfd76674510baafeb05d26
index 98458ab03b6ca81fd2e9ca1d8dd638b81e5e9b1d..c59b152783efac4b0a6cb462c5570c868a7d2448 100644 (file)
@@ -1 +1 @@
-917e3c36293a1bf052a16116c93e5037ed712f96
\ No newline at end of file
+4ac81fac6c6302c042be3df493a41630b733fff0
\ No newline at end of file
index fc8895bbd63ccab1362599dd6ef40f76a743c86f..73c550b83264e588c2afae1a2de7a8fab1b0a754 100644 (file)
@@ -342,20 +342,23 @@ static int xferOptimization(
 /*
 ** This routine is called to handle SQL of the following forms:
 **
-**    insert into TABLE (IDLIST) values(EXPRLIST)
+**    insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),...
 **    insert into TABLE (IDLIST) select
+**    insert into TABLE (IDLIST) default values
 **
 ** The IDLIST following the table name is always optional.  If omitted,
-** then a list of all columns for the table is substituted.  The IDLIST
-** appears in the pColumn parameter.  pColumn is NULL if IDLIST is omitted.
+** then a list of all (non-hidden) columns for the table is substituted.
+** The IDLIST appears in the pColumn parameter.  pColumn is NULL if IDLIST
+** is omitted.
 **
-** The pList parameter holds EXPRLIST in the first form of the INSERT
-** statement above, and pSelect is NULL.  For the second form, pList is
-** NULL and pSelect is a pointer to the select statement used to generate
-** data for the insert.
+** For the pSelect parameter holds the values to be inserted for the
+** first two forms shown above.  A VALUES clause is really just short-hand
+** for a SELECT statement that omits the FROM clause and everything else
+** that follows.  If the pSelect parameter is NULL, that means that the
+** DEFAULT VALUES form of the INSERT statement is intended.
 **
 ** The code generated follows one of four templates.  For a simple
-** insert with data coming from a VALUES clause, the code executes
+** insert with data coming from a single-row VALUES clause, the code executes
 ** once straight down through.  Pseudo-code follows (we call this
 ** the "1st template"):
 **
@@ -462,7 +465,7 @@ void sqlite3Insert(
   u8 useTempTable = 0;  /* Store SELECT results in intermediate table */
   u8 appendFlag = 0;    /* True if the insert is likely to be an append */
   u8 withoutRowid;      /* 0 for normal table.  1 for WITHOUT ROWID table */
-  u8 bIdListInOrder = 1; /* True if IDLIST is in table order */
+  u8 bIdListInOrder;    /* True if IDLIST is in table order */
   ExprList *pList = 0;  /* List of VALUES() to be inserted  */
 
   /* Register allocations */
@@ -487,8 +490,8 @@ void sqlite3Insert(
   }
 
   /* If the Select object is really just a simple VALUES() list with a
-  ** single row values (the common case) then keep that one row of values
-  ** and go ahead and discard the Select object
+  ** single row (the common case) then keep that one row of values
+  ** and discard the other (unused) parts of the pSelect object
   */
   if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){
     pList = pSelect->pEList;
@@ -596,6 +599,7 @@ void sqlite3Insert(
   ** is appears in the original table.  (The index of the INTEGER
   ** PRIMARY KEY in the original table is pTab->iPKey.)
   */
+  bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0;
   if( pColumn ){
     for(i=0; i<pColumn->nId; i++){
       pColumn->a[i].idx = -1;
@@ -631,7 +635,8 @@ void sqlite3Insert(
   ** co-routine is the common header to the 3rd and 4th templates.
   */
   if( pSelect ){
-    /* Data is coming from a SELECT.  Generate a co-routine to run the SELECT */
+    /* Data is coming from a SELECT or from a multi-row VALUES clause.
+    ** Generate a co-routine to run the SELECT. */
     int regYield;       /* Register holding co-routine entry-point */
     int addrTop;        /* Top of the co-routine */
     int rc;             /* Result code */
@@ -693,8 +698,8 @@ void sqlite3Insert(
       sqlite3ReleaseTempReg(pParse, regTempRowid);
     }
   }else{
-    /* This is the case if the data for the INSERT is coming from a VALUES
-    ** clause
+    /* This is the case if the data for the INSERT is coming from a 
+    ** single-row VALUES clause
     */
     NameContext sNC;
     memset(&sNC, 0, sizeof(sNC));
index b1a2db3a28428b8602744f5d3a6b1ea365681e61..deab70fc48433a28ae55a39a1e6ec77fb6b5d2d4 100644 (file)
@@ -1622,6 +1622,12 @@ struct Table {
 
 /*
 ** Allowed values for Table.tabFlags.
+**
+** TF_OOOHidden applies to virtual tables that have hidden columns that are
+** followed by non-hidden columns.  Example:  "CREATE VIRTUAL TABLE x USING
+** vtab1(a HIDDEN, b);".  Since "b" is a non-hidden column but "a" is hidden,
+** the TF_OOOHidden attribute would apply in this case.  Such tables require
+** special handling during INSERT processing.
 */
 #define TF_Readonly        0x01    /* Read-only system table */
 #define TF_Ephemeral       0x02    /* An ephemeral table */
@@ -1629,6 +1635,7 @@ struct Table {
 #define TF_Autoincrement   0x08    /* Integer primary key is autoincrement */
 #define TF_Virtual         0x10    /* Is a virtual table */
 #define TF_WithoutRowid    0x20    /* No rowid used. PRIMARY KEY is the key */
+#define TF_OOOHidden       0x40    /* Out-of-Order hidden columns */
 
 
 /*
index 530c3f305e128d40567803ba5b98097effe0e8a4..ad65cdf7f4cfd4121dcf69979537bfa7616d3f20 100644 (file)
@@ -559,6 +559,7 @@ static int vtabCallConstructor(
       rc = SQLITE_ERROR;
     }else{
       int iCol;
+      u8 oooHidden = 0;
       /* If everything went according to plan, link the new VTable structure
       ** into the linked list headed by pTab->pVTable. Then loop through the 
       ** columns of the table to see if any of them contain the token "hidden".
@@ -571,7 +572,10 @@ static int vtabCallConstructor(
         char *zType = pTab->aCol[iCol].zType;
         int nType;
         int i = 0;
-        if( !zType ) continue;
+        if( !zType ){
+          pTab->tabFlags |= oooHidden;
+          continue;
+        }
         nType = sqlite3Strlen30(zType);
         if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
           for(i=0; i<nType; i++){
@@ -594,6 +598,9 @@ static int vtabCallConstructor(
             zType[i-1] = '\0';
           }
           pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
+          oooHidden = TF_OOOHidden;
+        }else{
+          pTab->tabFlags |= oooHidden;
         }
       }
     }
index 928cc2b703a0b129ff765f16c50e9e68d2371228..eddaa70d1f098eb239a2273405e7ec181220db5e 100644 (file)
@@ -74,28 +74,39 @@ do_test vtabA-1.6 {
     SELECT * FROM t1e;
   }
 } {{value a} {value c}}
+do_execsql_test vtabA-1.7 {
+  DELETE FROM t1e;
+  INSERT INTO t1e SELECT 'abc','def';
+} {}
+do_execsql_test vtabA-1.8 {
+  INSERT INTO t1e VALUES('ghi','jkl'),('mno','pqr'),('stu','vwx');
+} {}
+do_execsql_test vtabA-1.9 {
+  SELECT a,b,c, '|' FROM t1e ORDER BY 1;
+} {abc {} def | ghi {} jkl | mno {} pqr | stu {} vwx |}
+
 
 # Test that the expansion of a '*' expression in the result set of
 # a SELECT does not include the hidden column.
 #
-do_test vtabA-1.7 {
+do_test vtabA-1.20 {
   execsql {
     INSERT INTO t1e SELECT * FROM t1e;
   }
 } {}
-do_test vtabA-1.8 {
+do_test vtabA-1.21 {
   execsql {
-    SELECT * FROM t1e;
+    SELECT * FROM t1e ORDER BY 1;
   }
-} {{value a} {value c} {value a} {value c}}
+} {abc def abc def ghi jkl ghi jkl mno pqr mno pqr stu vwx stu vwx}
 
 # Test that the declaration type of the hidden column does not include
 # the token "HIDDEN".
 #
-do_test vtabA-1.9 {
+do_test vtabA-1.22 {
   get_decltype t1e b
 } {VARCHAR}
-do_test vtabA-1.10 {
+do_test vtabA-1.23 {
   get_collist t1e
 } {a c}