]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the column_origin_name() etc. APIs. (CVS 3069)
authordanielk1977 <danielk1977@noemail.net>
Fri, 10 Feb 2006 02:27:42 +0000 (02:27 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Fri, 10 Feb 2006 02:27:42 +0000 (02:27 +0000)
FossilOrigin-Name: 82f502cdc1fead3bf7e3190d5c9db3aee6919ed4

18 files changed:
manifest
manifest.uuid
src/btree.c
src/delete.c
src/insert.c
src/parse.y
src/pragma.c
src/prepare.c
src/select.c
src/sqlite.h.in
src/tclsqlite.c
src/test1.c
src/update.c
src/vdbe.h
src/vdbeapi.c
src/vdbeaux.c
test/capi2.test
test/capi3.test

index 6fbe27c0cd7e53b9baeafda09ffebf827b33c4d0..a9e5da37d0576f1edeb0890a4d8582a9d4ff2b32 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Ignore\serrors\swhen\swhen\scalling\sfsync()\son\sa\sdirectory.\s\sTicket\s#1657.\s(CVS\s3068)
-D 2006-02-09T23:05:51
+C Add\sthe\scolumn_origin_name()\setc.\sAPIs.\s(CVS\s3069)
+D 2006-02-10T02:27:42
 F Makefile.in 5d8dff443383918b700e495de42ec65bc1c8865b
 F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -34,19 +34,19 @@ F src/alter.c 451b34fc4eb2475ca76a2e86b21e1030a9428091
 F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a
 F src/attach.c d73a3505de3fb9e373d0a158978116c4212031d0
 F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2
-F src/btree.c f45f57e6cbd3b3db947cdd699db64e5215d20b2a
+F src/btree.c 66112ae6a5caab384010344b514e98b346f550c0
 F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
 F src/build.c d959aa9c2ab9c79d3d872ce91ef719698658210c
 F src/callback.c 1bf497306c32229114f826707054df7ebe10abf2
 F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
 F src/date.c cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e
-F src/delete.c 56ab34c3a384caa5d5ea06f5739944957e2e4213
+F src/delete.c ca404d5fd5f678e32f2f46377ad802cd0219aa99
 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
 F src/expr.c 1149c3380bfce27703f5e9bec7dfb8e51baaf9d9
 F src/func.c 93d004b453a5d9aa754e673eef75d3c9527e0f54
 F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863
 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
-F src/insert.c 7e931b7f06afbcefcbbaab175c02eff8268db33f
+F src/insert.c 67b3dc11831c58d8703eb502355ad3704ee18f66
 F src/legacy.c 86b669707b3cefd570e34154e2f6457547d1df4f
 F src/main.c 9a42464c44a6532003391486e802e65e88789cfc
 F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
@@ -61,19 +61,19 @@ F src/os_win.c c67a2c46d929cf54c8f80ec5e6079cf684a141a9
 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
 F src/pager.c b5b380ea7a36f84e50c3adc1a414820a0eb3baa6
 F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f
-F src/parse.y ce7182bfd47b7e5921bc55dcc399cda5cb879f19
-F src/pragma.c c26c810e9c7d3a95a2c617b507bf8e8d65be7721
-F src/prepare.c 40ae23c8aeb641dc7b9bb271eb5e295b815154a7
+F src/parse.y 6d666d60a3bb51ceeb0d30b395455a24856849b7
+F src/pragma.c 8e135979702f249dd5877402056df0a336ea5a12
+F src/prepare.c cf0fc8ebaf94409955ecb09ffeb0099c9ef44693
 F src/printf.c c7d6ad9efb71c466305297a448308f467b6e2b6e
 F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
-F src/select.c daee9b20702ba51cf3807fc1b130edd8846e3e48
+F src/select.c ace67e13cd1344aa8de552c8eab9bce58f97ec24
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c 738f55ed75fb36731e764bfdb40756ac43b90b08
-F src/sqlite.h.in 89120d384e949be60f36af0e9e9f1b2684a30d35
+F src/sqlite.h.in 7a76811fe3743522b531994dfbf90f24b2333f71
 F src/sqliteInt.h 0121298397ac14eb468ab1ba9d488ac7ed7d88a1
 F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
-F src/tclsqlite.c 7764ab34df617b3d3cfd5f0fdf3444ed219c11d6
-F src/test1.c 894df7bced48bd30be04ab9990350900ae33557d
+F src/tclsqlite.c d9c26374b52cd47233ae0620d0a858a59b601f89
+F src/test1.c 58ab748e96754f2e05c85282ac47f81f7b8c44a3
 F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b
 F src/test3.c 86e99724ee898b119ed575ef9f98618afe7e5e5d
 F src/test4.c ff4e9406b3d2809966d8f0e82468ac5508be9f56
@@ -85,15 +85,15 @@ F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3
 F src/test_server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/tokenize.c 382b3bb0ca26eb9153b5d20b246ef512a114a24f
 F src/trigger.c 4d3644cbd16959b568c95ae73493402be8021b08
-F src/update.c 14be4ba2f438919b4217085c02feff569e6cf1f2
+F src/update.c 050a7e0ddaac03dec5271712eee62f1a9e699049
 F src/utf.c 1199766bbb0157931a83aa6eede6b6381177be64
 F src/util.c 405f46fef062b476826d2c171ec21def29563b75
 F src/vacuum.c 3865673cc66acd0717ecd517f6b8fdb2a5e7924b
 F src/vdbe.c c92d7a4d3476136b8ab440f1e0547fab24112b34
-F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
+F src/vdbe.h 12e2326f256db62352f10764d1a3940d914ded59
 F src/vdbeInt.h eb3f86ab08ef11635bc78eb88c3ff13f923c233b
-F src/vdbeapi.c 54dfd0975151c859ec5b125d225ad5b3cb586497
-F src/vdbeaux.c 9bf50cdb6a6c40b8c06ca9a8d87cf90120a16797
+F src/vdbeapi.c 72569c560acfba3e961b3cc9245a79647ea7c5ea
+F src/vdbeaux.c 95f4ed0bc8ed45f16823d84504310495b5dc587d
 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
 F src/vdbemem.c 2034e93b32c14bda6e306bb54e3a8e930b963027
 F src/where.c c7d71d5e55c9c4c1e948089280fb0dec7c7d1ef6
@@ -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 b9354d6c37e6f8f858c08952ebc9709712581221
-F test/capi3.test f36912f21457fa713ace874e73f2b54d55d1b9dd
+F test/capi2.test ca76487c525b4e6085b9766cc02bcfcc53835f73
+F test/capi3.test e26c09ec40c5dddf215c5dd359b4989a53dde876
 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 0738ef818d4023a5159b6bee0a65f0b83d01c1d5
-R 9d82f47f56b8d05740c30b2797755d9b
-U drh
-Z ed0151d0fbc7fcca110e9a3939d74452
+P d54d3b82c468b7e6dd39aac6aac56b26b3918c37
+R 0b8bfdc13fc109c03d9eefa67aff0e14
+U danielk1977
+Z a17c7aa8ab9c9bcf9b5fa8f511de465d
index ed3e57245a750de2f011fd51974585fe80e03008..a2704a4219cdcde4f16f3a5e59a11c88069db5b8 100644 (file)
@@ -1 +1 @@
-d54d3b82c468b7e6dd39aac6aac56b26b3918c37
\ No newline at end of file
+82f502cdc1fead3bf7e3190d5c9db3aee6919ed4
\ No newline at end of file
index f0e749302f1f8c1bfd496de89d99ccc84c5dd719..ea6339f0a682bb7ce013fee584609517991008e7 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.311 2006/01/24 16:37:58 danielk1977 Exp $
+** $Id: btree.c,v 1.312 2006/02/10 02:27:42 danielk1977 Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -411,8 +411,8 @@ struct BtCursor {
 **   The table that this cursor was opened on still exists, but has been 
 **   modified since the cursor was last used. The cursor position is saved
 **   in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in 
-**   this state, restoreOrClearCursorPosition() can be called to attempt to seek 
-**   the cursor to the saved position.
+**   this state, restoreOrClearCursorPosition() can be called to attempt to
+**   seek the cursor to the saved position.
 */
 #define CURSOR_INVALID           0
 #define CURSOR_VALID             1
index f1b73a93a7507c7b02808af1701339f5097eedf7..85054acb96e3ad01aefa39fa820b73c481103fd8 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** in order to generate code for DELETE FROM statements.
 **
-** $Id: delete.c,v 1.120 2006/01/24 12:09:19 danielk1977 Exp $
+** $Id: delete.c,v 1.121 2006/02/10 02:27:43 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -343,7 +343,7 @@ void sqlite3DeleteFrom(
   if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
     sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
     sqlite3VdbeSetNumCols(v, 1);
-    sqlite3VdbeSetColName(v, 0, "rows deleted", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P3_STATIC);
   }
 
 delete_from_cleanup:
index 7899610e2503e7735dea37ac0e65e3317020571c..3029db3a4a1f81673e8f1e067bea92f3ce861b38 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements in SQLite.
 **
-** $Id: insert.c,v 1.160 2006/01/24 12:09:19 danielk1977 Exp $
+** $Id: insert.c,v 1.161 2006/02/10 02:27:43 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -703,7 +703,7 @@ void sqlite3Insert(
     sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0);
     sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
     sqlite3VdbeSetNumCols(v, 1);
-    sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", P3_STATIC);
   }
 
 insert_cleanup:
index 6c3da0dbee488e23f27a15d2adbb33dc3ed43881..106fda03637a35cc09902baef7584c0c75250517 100644 (file)
@@ -14,7 +14,7 @@
 ** the parser.  Lemon will also generate a header file containing
 ** numeric codes for all of the tokens.
 **
-** @(#) $Id: parse.y,v 1.194 2006/01/30 23:04:51 drh Exp $
+** @(#) $Id: parse.y,v 1.195 2006/02/10 02:27:43 danielk1977 Exp $
 */
 
 // All token codes are small integers with #defines that begin with "TK_"
@@ -476,7 +476,7 @@ seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). {
     }
   }
   
- // A seltablist_paren nonterminal represents anything in a FROM that
 // A seltablist_paren nonterminal represents anything in a FROM that
   // is contained inside parentheses.  This can be either a subquery or
   // a grouping of table and subqueries.
   //
index d4002c9c34ec439f81ed546e8c97e662811ec0f3..56a9a9cb2ff7c1ca3c84c02eb453c4c73902a359 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.116 2006/02/09 16:52:24 drh Exp $
+** $Id: pragma.c,v 1.117 2006/02/10 02:27:43 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -128,7 +128,7 @@ static void returnSingleInt(Parse *pParse, const char *zLabel, int value){
   sqlite3VdbeAddOp(v, OP_Integer, value, 0);
   if( pParse->explain==0 ){
     sqlite3VdbeSetNumCols(v, 1);
-    sqlite3VdbeSetColName(v, 0, zLabel, P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, P3_STATIC);
   }
   sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
 }
@@ -274,7 +274,7 @@ void sqlite3Pragma(
     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
     if( !zRight ){
       sqlite3VdbeSetNumCols(v, 1);
-      sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
+      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P3_STATIC);
       addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
       sqlite3VdbeChangeP1(v, addr, iDb);
       sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
@@ -392,7 +392,8 @@ void sqlite3Pragma(
     if( !zRight ){
       if( sqlite3_temp_directory ){
         sqlite3VdbeSetNumCols(v, 1);
-        sqlite3VdbeSetColName(v, 0, "temp_store_directory", P3_STATIC);
+        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, 
+            "temp_store_directory", P3_STATIC);
         sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0);
         sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
       }
@@ -470,12 +471,12 @@ void sqlite3Pragma(
       int i;
       Column *pCol;
       sqlite3VdbeSetNumCols(v, 6);
-      sqlite3VdbeSetColName(v, 0, "cid", P3_STATIC);
-      sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
-      sqlite3VdbeSetColName(v, 2, "type", P3_STATIC);
-      sqlite3VdbeSetColName(v, 3, "notnull", P3_STATIC);
-      sqlite3VdbeSetColName(v, 4, "dflt_value", P3_STATIC);
-      sqlite3VdbeSetColName(v, 5, "pk", P3_STATIC);
+      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", P3_STATIC);
+      sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
+      sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", P3_STATIC);
+      sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", P3_STATIC);
+      sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", P3_STATIC);
+      sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", P3_STATIC);
       sqlite3ViewGetColumnNames(pParse, pTab);
       for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
         sqlite3VdbeAddOp(v, OP_Integer, i, 0);
@@ -499,9 +500,9 @@ void sqlite3Pragma(
       int i;
       pTab = pIdx->pTable;
       sqlite3VdbeSetNumCols(v, 3);
-      sqlite3VdbeSetColName(v, 0, "seqno", P3_STATIC);
-      sqlite3VdbeSetColName(v, 1, "cid", P3_STATIC);
-      sqlite3VdbeSetColName(v, 2, "name", P3_STATIC);
+      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", P3_STATIC);
+      sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", P3_STATIC);
+      sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", P3_STATIC);
       for(i=0; i<pIdx->nColumn; i++){
         int cnum = pIdx->aiColumn[i];
         sqlite3VdbeAddOp(v, OP_Integer, i, 0);
@@ -524,9 +525,9 @@ void sqlite3Pragma(
       if( pIdx ){
         int i = 0; 
         sqlite3VdbeSetNumCols(v, 3);
-        sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
-        sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
-        sqlite3VdbeSetColName(v, 2, "unique", P3_STATIC);
+        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
+        sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
+        sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", P3_STATIC);
         while(pIdx){
           sqlite3VdbeAddOp(v, OP_Integer, i, 0);
           sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0);
@@ -543,9 +544,9 @@ void sqlite3Pragma(
     int i;
     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
     sqlite3VdbeSetNumCols(v, 3);
-    sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
-    sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
-    sqlite3VdbeSetColName(v, 2, "file", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
+    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
+    sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", P3_STATIC);
     for(i=0; i<db->nDb; i++){
       if( db->aDb[i].pBt==0 ) continue;
       assert( db->aDb[i].zName!=0 );
@@ -561,8 +562,8 @@ void sqlite3Pragma(
     int i = 0;
     HashElem *p;
     sqlite3VdbeSetNumCols(v, 2);
-    sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
-    sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
+    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
     for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
       CollSeq *pColl = (CollSeq *)sqliteHashData(p);
       sqlite3VdbeAddOp(v, OP_Integer, i++, 0);
@@ -584,11 +585,11 @@ void sqlite3Pragma(
       if( pFK ){
         int i = 0; 
         sqlite3VdbeSetNumCols(v, 5);
-        sqlite3VdbeSetColName(v, 0, "id", P3_STATIC);
-        sqlite3VdbeSetColName(v, 1, "seq", P3_STATIC);
-        sqlite3VdbeSetColName(v, 2, "table", P3_STATIC);
-        sqlite3VdbeSetColName(v, 3, "from", P3_STATIC);
-        sqlite3VdbeSetColName(v, 4, "to", P3_STATIC);
+        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", P3_STATIC);
+        sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", P3_STATIC);
+        sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", P3_STATIC);
+        sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", P3_STATIC);
+        sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", P3_STATIC);
         while(pFK){
           int j;
           for(j=0; j<pFK->nCol; j++){
@@ -650,7 +651,7 @@ void sqlite3Pragma(
     /* Initialize the VDBE program */
     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
     sqlite3VdbeSetNumCols(v, 1);
-    sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", P3_STATIC);
     sqlite3VdbeAddOp(v, OP_MemInt, 0, 0);  /* Initialize error count to 0 */
 
     /* Do an integrity check on each database file */
@@ -795,7 +796,7 @@ void sqlite3Pragma(
     if( !zRight ){    /* "PRAGMA encoding" */
       if( sqlite3ReadSchema(pParse) ) goto pragma_out;
       sqlite3VdbeSetNumCols(v, 1);
-      sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
+      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", P3_STATIC);
       sqlite3VdbeAddOp(v, OP_String8, 0, 0);
       for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
         if( pEnc->enc==ENC(pParse->db) ){
@@ -901,8 +902,8 @@ void sqlite3Pragma(
     int i;
     Vdbe *v = sqlite3GetVdbe(pParse);
     sqlite3VdbeSetNumCols(v, 2);
-    sqlite3VdbeSetColName(v, 0, "database", P3_STATIC);
-    sqlite3VdbeSetColName(v, 1, "status", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", P3_STATIC);
+    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", P3_STATIC);
     for(i=0; i<db->nDb; i++){
       Btree *pBt;
       Pager *pPager;
index 16e354f0f4745608b55bdd71701d5762f91b5451..c755d6b93ec487bdd184ac87a6bc731572e6ad2a 100644 (file)
@@ -13,7 +13,7 @@
 ** interface, and routines that contribute to loading the database schema
 ** from disk.
 **
-** $Id: prepare.c,v 1.30 2006/01/30 22:35:44 drh Exp $
+** $Id: prepare.c,v 1.31 2006/02/10 02:27:43 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -556,16 +556,16 @@ int sqlite3_prepare(
   if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
     if( sParse.explain==2 ){
       sqlite3VdbeSetNumCols(sParse.pVdbe, 3);
-      sqlite3VdbeSetColName(sParse.pVdbe, 0, "order", P3_STATIC);
-      sqlite3VdbeSetColName(sParse.pVdbe, 1, "from", P3_STATIC);
-      sqlite3VdbeSetColName(sParse.pVdbe, 2, "detail", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", P3_STATIC);
     }else{
       sqlite3VdbeSetNumCols(sParse.pVdbe, 5);
-      sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC);
-      sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC);
-      sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC);
-      sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC);
-      sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", P3_STATIC);
+      sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", P3_STATIC);
     }
   } 
 #endif
index 14d8a00c1405741c26290e9e7800b37cf23b8d38..4a3cdf74f7d6a2dda6a034b7dfa3ff75844a4f1c 100644 (file)
@@ -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.301 2006/01/24 12:09:19 danielk1977 Exp $
+** $Id: select.c,v 1.302 2006/02/10 02:27:43 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -762,14 +762,31 @@ static void generateSortTail(
 ** Return a pointer to a string containing the 'declaration type' of the
 ** expression pExpr. The string may be treated as static by the caller.
 **
-** If the declaration type is the exact datatype definition extracted from
-** the original CREATE TABLE statement if the expression is a column.
+** The declaration type is the exact datatype definition extracted from the
+** original CREATE TABLE statement if the expression is a column. The
+** declaration type for a ROWID field is INTEGER. Exactly when an expression
+** is considered a column can be complex in the presence of subqueries. The
+** result-set expression in all of the following SELECT statements is 
+** considered a column by this function.
+**
+**   SELECT col FROM tbl;
+**   SELECT (SELECT col FROM tbl;
+**   SELECT (SELECT col FROM tbl);
+**   SELECT abc FROM (SELECT col AS abc FROM tbl);
 ** 
-** The declaration type for an expression is either TEXT, NUMERIC or ANY.
-** The declaration type for a ROWID field is INTEGER.
+** The declaration type for any expression other than a column is NULL.
 */
-static const char *columnType(NameContext *pNC, Expr *pExpr){
-  char const *zType;
+static const char *columnType(
+  NameContext *pNC, 
+  Expr *pExpr,
+  const char **pzOriginDb,
+  const char **pzOriginTab,
+  const char **pzOriginCol
+){
+  char const *zType = 0;
+  char const *zOriginDb = 0;
+  char const *zOriginTab = 0;
+  char const *zOriginCol = 0;
   int j;
   if( pExpr==0 || pNC->pSrcList==0 ) return 0;
 
@@ -781,17 +798,24 @@ static const char *columnType(NameContext *pNC, Expr *pExpr){
 
   switch( pExpr->op ){
     case TK_COLUMN: {
-      Table *pTab = 0;
-      int iCol = pExpr->iColumn;
+      /* The expression is a column. Locate the table the column is being
+      ** extracted from in NameContext.pSrcList. This table may be real
+      ** database table or a subquery.
+      */
+      Table *pTab = 0;            /* Table structure column is extracted from */
+      Select *pS = 0;             /* Select the column is extracted from */
+      int iCol = pExpr->iColumn;  /* Index of column in pTab */
       while( pNC && !pTab ){
         SrcList *pTabList = pNC->pSrcList;
         for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
         if( j<pTabList->nSrc ){
           pTab = pTabList->a[j].pTab;
+          pS = pTabList->a[j].pSelect;
         }else{
           pNC = pNC->pNext;
         }
       }
+
       if( pTab==0 ){
         /* FIX ME:
         ** This can occurs if you have something like "SELECT new.x;" inside
@@ -806,30 +830,72 @@ static const char *columnType(NameContext *pNC, Expr *pExpr){
         zType = "TEXT";
         break;
       }
+
       assert( pTab );
-      if( iCol<0 ) iCol = pTab->iPKey;
-      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
-      if( iCol<0 ){
-        zType = "INTEGER";
-      }else{
-        zType = pTab->aCol[iCol].zType;
+#ifndef SQLITE_OMIT_SUBQUERY
+      if( pS ){
+        /* The "table" is actually a sub-select or a view in the FROM clause
+        ** of the SELECT statement. Return the declaration type and origin
+        ** data for the result-set column of the sub-select.
+        */
+        if( iCol>=0 && iCol<pS->pEList->nExpr ){
+          /* If iCol is less than zero, then the expression requests the
+          ** rowid of the sub-select or view. This expression is legal (see 
+          ** test case misc2.2.2) - it always evaluates to NULL.
+          */
+          NameContext sNC;
+          Expr *p = pS->pEList->a[iCol].pExpr;
+          sNC.pSrcList = pS->pSrc;
+          sNC.pNext = 0;
+          sNC.pParse = pNC->pParse;
+          zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); 
+        }
+      }else
+#endif
+      if( pTab->pSchema ){
+        /* A real table */
+        assert( !pS );
+        if( iCol<0 ) iCol = pTab->iPKey;
+        assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+        if( iCol<0 ){
+          zType = "INTEGER";
+          zOriginCol = "rowid";
+        }else{
+          zType = pTab->aCol[iCol].zType;
+          zOriginCol = pTab->aCol[iCol].zName;
+        }
+        zOriginTab = pTab->zName;
+        if( pNC->pParse ){
+          int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
+          zOriginDb = pNC->pParse->db->aDb[iDb].zName;
+        }
       }
       break;
     }
 #ifndef SQLITE_OMIT_SUBQUERY
     case TK_SELECT: {
+      /* The expression is a sub-select. Return the declaration type and
+      ** origin info for the single column in the result set of the SELECT
+      ** statement.
+      */
       NameContext sNC;
       Select *pS = pExpr->pSelect;
-      sNC.pSrcList = pExpr->pSelect->pSrc;
+      Expr *p = pS->pEList->a[0].pExpr;
+      sNC.pSrcList = pS->pSrc;
       sNC.pNext = pNC;
-      zType = columnType(&sNC, pS->pEList->a[0].pExpr); 
+      sNC.pParse = pNC->pParse;
+      zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); 
       break;
     }
 #endif
-    default:
-      zType = 0;
   }
   
+  if( pzOriginDb ){
+    assert( pzOriginTab && pzOriginCol );
+    *pzOriginDb = zOriginDb;
+    *pzOriginTab = zOriginTab;
+    *pzOriginCol = zOriginCol;
+  }
   return zType;
 }
 
@@ -846,14 +912,27 @@ static void generateColumnTypes(
   int i;
   NameContext sNC;
   sNC.pSrcList = pTabList;
+  sNC.pParse = pParse;
   for(i=0; i<pEList->nExpr; i++){
     Expr *p = pEList->a[i].pExpr;
-    const char *zType = columnType(&sNC, p);
-    if( zType==0 ) continue;
+    const char *zOrigDb = 0;
+    const char *zOrigTab = 0;
+    const char *zOrigCol = 0;
+    const char *zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
+
     /* The vdbe must make it's own copy of the column-type, in case the 
     ** schema is reset before this virtual machine is deleted.
+    **
+    ** TODO: Create some symbol that is better than "-20" to pass to 
+    ** sqlite3VdbeSetColName(). As is this is a ticking bomb. An alternative
+    ** is to pass the length of the string, but that means calling strlen()
+    ** here which consumes code space. By passing a negative value that is
+    ** not P3_DYNAMIC or P3_STATIC, strlen() is called by VdbeSetColName().
     */
-    sqlite3VdbeSetColName(v, i+pEList->nExpr, zType, strlen(zType));
+    sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, -20);
+    sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, -20);
+    sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, -20);
+    sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, -20);
   }
 }
 
@@ -891,7 +970,7 @@ static void generateColumnNames(
     if( p==0 ) continue;
     if( pEList->a[i].zName ){
       char *zName = pEList->a[i].zName;
-      sqlite3VdbeSetColName(v, i, zName, strlen(zName));
+      sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, strlen(zName));
       continue;
     }
     if( p->op==TK_COLUMN && pTabList ){
@@ -909,7 +988,7 @@ static void generateColumnNames(
         zCol = pTab->aCol[iCol].zName;
       }
       if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
-        sqlite3VdbeSetColName(v, i, (char*)p->span.z, p->span.n);
+        sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n);
       }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
         char *zName = 0;
         char *zTab;
@@ -917,18 +996,18 @@ static void generateColumnNames(
         zTab = pTabList->a[j].zAlias;
         if( fullNames || zTab==0 ) zTab = pTab->zName;
         sqlite3SetString(&zName, zTab, ".", zCol, (char*)0);
-        sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC);
+        sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, P3_DYNAMIC);
       }else{
-        sqlite3VdbeSetColName(v, i, zCol, strlen(zCol));
+        sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, strlen(zCol));
       }
     }else if( p->span.z && p->span.z[0] ){
-      sqlite3VdbeSetColName(v, i, (char*)p->span.z, p->span.n);
+      sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n);
       /* sqlite3VdbeCompressSpace(v, addr); */
     }else{
       char zName[30];
       assert( p->op!=TK_COLUMN || pTabList==0 );
       sprintf(zName, "column%d", i+1);
-      sqlite3VdbeSetColName(v, i, zName, 0);
+      sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, 0);
     }
   }
   generateColumnTypes(pParse, pTabList, pEList);
@@ -1036,7 +1115,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
     */
     memset(&sNC, 0, sizeof(sNC));
     sNC.pSrcList = pSelect->pSrc;
-    zType = sqliteStrDup(columnType(&sNC, p));
+    zType = sqliteStrDup(columnType(&sNC, p, 0, 0, 0));
     pCol->zType = zType;
     pCol->affinity = sqlite3ExprAffinity(p);
     pColl = sqlite3ExprCollSeq(pParse, p);
@@ -2783,13 +2862,6 @@ int sqlite3Select(
   v = sqlite3GetVdbe(pParse);
   if( v==0 ) goto select_end;
 
-  /* Identify column names if we will be using them in a callback.  This
-  ** step is skipped if the output is going to some other destination.
-  */
-  if( eDest==SRT_Callback ){
-    generateColumnNames(pParse, pTabList, pEList);
-  }
-
   /* Generate code for all sub-queries in the FROM clause
   */
 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
@@ -3217,6 +3289,14 @@ int sqlite3Select(
   ** successful coding of the SELECT.
   */
 select_end:
+
+  /* Identify column names if we will be using them in a callback.  This
+  ** step is skipped if the output is going to some other destination.
+  */
+  if( rc==SQLITE_OK && eDest==SRT_Callback ){
+    generateColumnNames(pParse, pTabList, pEList);
+  }
+
   sqliteFree(sAggInfo.aCol);
   sqliteFree(sAggInfo.aFunc);
   return rc;
index 79d64f4ff4118d3afd43a7513e4a70a840779c5d..762320f1a8e9b2cbab89c2ee417f35d970510886 100644 (file)
@@ -12,7 +12,7 @@
 ** This header file defines the interface that the SQLite library
 ** presents to client programs.
 **
-** @(#) $Id: sqlite.h.in,v 1.160 2006/02/09 22:13:42 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.161 2006/02/10 02:27:43 danielk1977 Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -725,6 +725,27 @@ int sqlite3_column_count(sqlite3_stmt *pStmt);
 const char *sqlite3_column_name(sqlite3_stmt*,int);
 const void *sqlite3_column_name16(sqlite3_stmt*,int);
 
+/*
+** The first parameter to the following calls is a compiled SQL statement.
+** These functions return information about the Nth column returned by 
+** the statement, where N is the second function argument.
+**
+** If the Nth column returned by the statement is not a column value,
+** then all of the functions return NULL. Otherwise, the return the 
+** name of the attached database, table and column that the expression
+** extracts a value from.
+**
+** As with all other SQLite APIs, those postfixed with "16" return UTF-16
+** encoded strings, the other functions return UTF-8. The memory containing
+** the returned strings is valid until the statement handle is finalized().
+*/
+const char *sqlite3_column_database_name(sqlite3_stmt*,int);
+const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
+const char *sqlite3_column_table_name(sqlite3_stmt*,int);
+const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
+const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
+const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
+
 /*
 ** The first parameter is a compiled SQL statement. If this statement
 ** is a SELECT statement, the Nth column of the returned result set 
@@ -737,7 +758,7 @@ const void *sqlite3_column_name16(sqlite3_stmt*,int);
 **
 ** And the following statement compiled:
 **
-** SELECT c1 + 1, 0 FROM t1;
+** SELECT c1 + 1, c1 FROM t1;
 **
 ** Then this routine would return the string "VARIANT" for the second
 ** result column (i==1), and a NULL pointer for the first result column
@@ -757,7 +778,7 @@ const char *sqlite3_column_decltype(sqlite3_stmt *, int i);
 **
 ** And the following statement compiled:
 **
-** SELECT c1 + 1, 0 FROM t1;
+** SELECT c1 + 1, c1 FROM t1;
 **
 ** Then this routine would return the string "INTEGER" for the second
 ** result column (i==1), and a NULL pointer for the first result column
index 427bc45ddb05a0690dab1d144c4cb455fcc802ab..914af2105a55d22e45563f7d5620e396e80a0af8 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** A TCL Interface to SQLite
 **
-** $Id: tclsqlite.c,v 1.150 2006/01/23 13:00:38 drh Exp $
+** $Id: tclsqlite.c,v 1.151 2006/02/10 02:27:43 danielk1977 Exp $
 */
 #ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */
 
@@ -1116,7 +1116,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
       if( i+1!=nCol ){
         char *zErr;
         zErr = malloc(200 + strlen(zFile));
-        sprintf(zErr,"Error: %s line %d: expected %d columns of data but found %d",
+        sprintf(zErr,
+           "Error: %s line %d: expected %d columns of data but found %d",
            zFile, lineno, nCol, i+1);
         Tcl_AppendResult(interp, zErr, 0);
         free(zErr);
index f8510cc23f25dd01280650d6076a87a58f9186ce..0ee8dadf6ee85eb29f647f13494b00886e24e640 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test1.c,v 1.204 2006/02/09 13:43:29 danielk1977 Exp $
+** $Id: test1.c,v 1.205 2006/02/10 02:27:43 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -3571,11 +3571,19 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      { "sqlite3_column_name",       test_stmt_utf8,  sqlite3_column_name      },
      { "sqlite3_column_int",        test_stmt_int,   sqlite3_column_int       },
      { "sqlite3_column_bytes",      test_stmt_int,   sqlite3_column_bytes     },
+{ "sqlite3_column_database_name", test_stmt_utf8, sqlite3_column_database_name},
+{ "sqlite3_column_table_name", test_stmt_utf8, sqlite3_column_table_name},
+{ "sqlite3_column_origin_name", test_stmt_utf8, sqlite3_column_origin_name},
+
 #ifndef SQLITE_OMIT_UTF16
      { "sqlite3_column_bytes16",    test_stmt_int,   sqlite3_column_bytes16   },
      { "sqlite3_column_text16",     test_stmt_utf16, sqlite3_column_text16    },
      { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16},
      { "sqlite3_column_name16",     test_stmt_utf16, sqlite3_column_name16    },
+{"sqlite3_column_database_name16",
+  test_stmt_utf16, sqlite3_column_database_name16},
+{"sqlite3_column_table_name16", test_stmt_utf16, sqlite3_column_table_name16},
+{"sqlite3_column_origin_name16", test_stmt_utf16, sqlite3_column_origin_name16},
 #endif
      { "sqlite3_global_recover",    test_global_recover, 0   },
 
index 83084d7ed04ba781ab1a8fdcec3931d2db741745..c506c8290108a310f29f86bda2e1e8023a7e1d3d 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.121 2006/01/18 16:51:36 danielk1977 Exp $
+** $Id: update.c,v 1.122 2006/02/10 02:27:43 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -494,7 +494,7 @@ void sqlite3Update(
   if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
     sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
     sqlite3VdbeSetNumCols(v, 1);
-    sqlite3VdbeSetColName(v, 0, "rows updated", P3_STATIC);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", P3_STATIC);
   }
 
 update_cleanup:
index bef16fdb494b3827af4b150344ee79d024554d3f..93f9dc61a0b55297d23b894481af7ae5db7230fe 100644 (file)
@@ -15,7 +15,7 @@
 ** or VDBE.  The VDBE implements an abstract machine that runs a
 ** simple program to access and modify the underlying database.
 **
-** $Id: vdbe.h,v 1.99 2005/09/20 17:42:23 drh Exp $
+** $Id: vdbe.h,v 1.100 2006/02/10 02:27:44 danielk1977 Exp $
 */
 #ifndef _SQLITE_VDBE_H_
 #define _SQLITE_VDBE_H_
@@ -79,6 +79,17 @@ typedef struct VdbeOpList VdbeOpList;
 */
 #define P3_KEYINFO_HANDOFF (-9)
 
+/*
+** The Vdbe.aColName array contains 5n Mem structures, where n is the 
+** number of columns of data returned by the statement.
+*/
+#define COLNAME_NAME     0
+#define COLNAME_DECLTYPE 1
+#define COLNAME_DATABASE 2
+#define COLNAME_TABLE    3
+#define COLNAME_COLUMN   4
+#define COLNAME_N        5      /* Number of COLNAME_xxx symbols */
+
 /*
 ** The following macro converts a relative address in the p2 field
 ** of a VdbeOp structure into a negative number so that 
@@ -117,7 +128,7 @@ void sqlite3VdbeTrace(Vdbe*,FILE*);
 int sqlite3VdbeReset(Vdbe*);
 int sqliteVdbeSetVariables(Vdbe*,int,const char**);
 void sqlite3VdbeSetNumCols(Vdbe*,int);
-int sqlite3VdbeSetColName(Vdbe*, int, const char *, int);
+int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int);
 void sqlite3VdbeCountChanges(Vdbe*);
 sqlite3 *sqlite3VdbeDb(Vdbe*);
 
index 497f6c00956f1b8b6abf8ba6254c75352e106fa1..e2866975a7c016881d790cc42415a9e94086636e 100644 (file)
@@ -521,11 +521,13 @@ static const void *columnName(
 ** statement pStmt.
 */
 const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 0);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME);
 }
 #ifndef SQLITE_OMIT_UTF16
 const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 0);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME);
 }
 #endif
 
@@ -534,26 +536,30 @@ const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
 ** of the result set of SQL statement pStmt.
 */
 const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 1);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE);
 }
 #ifndef SQLITE_OMIT_UTF16
 const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 1);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 
-#if !defined(SQLITE_OMIT_ORIGIN_NAMES) && 0
+#if !defined(SQLITE_OMIT_ORIGIN_NAMES)
 /*
 ** Return the name of the database from which a result column derives.
 ** NULL is returned if the result column is an expression or constant or
 ** anything else which is not an unabiguous reference to a database column.
 */
 const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 2);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE);
 }
 #ifndef SQLITE_OMIT_UTF16
 const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 2);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 
@@ -563,11 +569,13 @@ const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
 ** anything else which is not an unabiguous reference to a database column.
 */
 const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 3);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE);
 }
 #ifndef SQLITE_OMIT_UTF16
 const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 3);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 
@@ -577,11 +585,13 @@ const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
 ** anything else which is not an unabiguous reference to a database column.
 */
 const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 4);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN);
 }
 #ifndef SQLITE_OMIT_UTF16
 const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
-  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 4);
+  return columnName(
+      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 #endif /* SQLITE_OMIT_ORIGIN_NAMES */
index 04f9c9513f22a396d11185aae8ee439723d63400..33d2fbdceadd3a5a09ca792fe0bf47d1b2e70bfe 100644 (file)
@@ -871,9 +871,9 @@ static void Cleanup(Vdbe *p){
 void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
   Mem *pColName;
   int n;
-  releaseMemArray(p->aColName, p->nResColumn*2);
+  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
   sqliteFree(p->aColName);
-  n = nResColumn*2;
+  n = nResColumn*COLNAME_N;
   p->nResColumn = nResColumn;
   p->aColName = pColName = (Mem*)sqliteMalloc( sizeof(Mem)*n );
   if( p->aColName==0 ) return;
@@ -893,13 +893,14 @@ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
 ** the string is freed using sqliteFree() when the vdbe is finished with
 ** it. Otherwise, N bytes of zName are copied.
 */
-int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
+int sqlite3VdbeSetColName(Vdbe *p, int idx, int var, const char *zName, int N){
   int rc;
   Mem *pColName;
-  assert( idx<(2*p->nResColumn) );
+  assert( idx<p->nResColumn );
+  assert( var<COLNAME_N );
   if( sqlite3MallocFailed() ) return SQLITE_NOMEM;
   assert( p->aColName!=0 );
-  pColName = &(p->aColName[idx]);
+  pColName = &(p->aColName[idx+var*p->nResColumn]);
   if( N==P3_DYNAMIC || N==P3_STATIC ){
     rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
   }else{
@@ -1481,7 +1482,7 @@ void sqlite3VdbeDelete(Vdbe *p){
   releaseMemArray(p->aVar, p->nVar);
   sqliteFree(p->aLabel);
   sqliteFree(p->aStack);
-  releaseMemArray(p->aColName, p->nResColumn*2);
+  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
   sqliteFree(p->aColName);
   p->magic = VDBE_MAGIC_DEAD;
   sqliteFree(p);
index 3d52d0b6e51755aaf967c4076a70200cec2f215b..9fdd3617ed0bd59669c4b2e0e8c86f933588da2e 100644 (file)
@@ -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.27 2006/01/03 00:33:50 drh Exp $
+# $Id: capi2.test,v 1.28 2006/02/10 02:27:47 danielk1977 Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -638,6 +638,8 @@ do_test capi2-9.1 {
   sqlite3_finalize $VM1
 } {SQLITE_OK}
 
+# Test that passing a NULL pointer to sqlite3_finalize() or sqlite3_reset
+# does not cause an error.
 do_test capi2-10.1 {
   sqlite3_finalize 0
 } {SQLITE_OK}
@@ -645,6 +647,81 @@ do_test capi2-10.2 {
   sqlite3_reset 0
 } {SQLITE_OK}
 
+#---------------------------------------------------------------------------
+# The following tests - capi2-11.* - test the "column origin" APIs.
+#
+#   sqlite3_column_origin_name()
+#   sqlite3_column_database_name()
+#   sqlite3_column_table_name()
+#
+
+# This proc uses the database handle $::DB to compile the SQL statement passed
+# as a parameter. The return value of this procedure is a list with one
+# element for each column returned by the compiled statement. Each element of
+# this list is itself a list of length three, consisting of the origin
+# database, table and column for the corresponding returned column.
+proc check_origins {sql} {
+  set ret [list]
+  set ::STMT [sqlite3_prepare $::DB $sql -1 dummy]
+  for {set i 0} {$i < [sqlite3_column_count $::STMT]} {incr i} {
+    lappend ret [list                           \
+      [sqlite3_column_database_name $::STMT $i] \
+      [sqlite3_column_table_name $::STMT $i]    \
+      [sqlite3_column_origin_name $::STMT $i]   \
+    ]
+  }
+  sqlite3_finalize $::STMT
+  return $ret
+}
+do_test capi2-11.1 {
+  execsql {
+    CREATE TABLE tab1(col1, col2);
+  }
+} {}
+do_test capi2-11.2 {
+  check_origins {SELECT col2, col1 FROM tab1}
+} [list {main tab1 col2} {main tab1 col1}]
+do_test capi2-11.3 {
+  check_origins {SELECT col2 AS hello, col1 AS world FROM tab1}
+} [list {main tab1 col2} {main tab1 col1}]
+do_test capi2-11.4 {
+  check_origins {SELECT b, a FROM (SELECT col1 AS a, col2 AS b FROM tab1)}
+} [list {main tab1 col2} {main tab1 col1}]
+do_test capi2-11.5 {
+  check_origins {SELECT (SELECT col2 FROM tab1), (SELECT col1 FROM tab1)}
+} [list {main tab1 col2} {main tab1 col1}]
+do_test capi2-11.6 {
+  check_origins {SELECT (SELECT col2), (SELECT col1) FROM tab1}
+} [list {main tab1 col2} {main tab1 col1}]
+do_test capi2-11.7 {
+  check_origins {SELECT * FROM tab1}
+} [list {main tab1 col1} {main tab1 col2}]
+do_test capi2-11.8 {
+  check_origins {SELECT * FROM (SELECT * FROM tab1)}
+} [list {main tab1 col1} {main tab1 col2}]
+
+do_test capi2-12.1 {
+  execsql {
+    CREATE VIEW view1 AS SELECT * FROM  tab1;
+  }
+} {}
+do_test capi2-12.2 {
+breakpoint
+  check_origins {SELECT col2, col1 FROM view1}
+} [list {main tab1 col2} {main tab1 col1}]
+do_test capi2-12.3 {
+  check_origins {SELECT col2 AS hello, col1 AS world FROM view1}
+} [list {main tab1 col2} {main tab1 col1}]
+do_test capi2-12.4 {
+  check_origins {SELECT b, a FROM (SELECT col1 AS a, col2 AS b FROM view1)}
+} [list {main tab1 col2} {main tab1 col1}]
+do_test capi2-12.5 {
+  check_origins {SELECT (SELECT col2 FROM view1), (SELECT col1 FROM view1)}
+} [list {main tab1 col2} {main tab1 col1}]
+do_test capi2-12.6 {
+  check_origins {SELECT (SELECT col2), (SELECT col1) FROM view1}
+} [list {main tab1 col2} {main tab1 col1}]
+
 db2 close
 
 finish_test
index 21542e58845bbb3e6d5c43354fe588a961afccb6..3d6fe1c57179167fc43d6c316b9e10d3c473788a 100644 (file)
@@ -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.41 2006/01/30 22:35:44 drh Exp $
+# $Id: capi3.test,v 1.42 2006/02/10 02:27:47 danielk1977 Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -286,9 +286,94 @@ proc check_header {STMT test names decltypes} {
         [sqlite3_column_decltype16 $STMT $numcols]
     } {{} {} {} {} {} {} {} {}}
   }
-
 } 
 
+# This proc is used to test the following API calls:
+#
+# sqlite3_column_origin_name
+# sqlite3_column_origin_name16
+# sqlite3_column_table_name
+# sqlite3_column_table_name16
+# sqlite3_column_database_name
+# sqlite3_column_database_name16
+#
+# $STMT is a compiled SQL statement. $test is a prefix
+# to use for test names within this proc. $names is a list
+# of the column names that should be returned by $STMT.
+# $decltypes is a list of column declaration types for $STMT.
+#
+# Example:
+#
+# set STMT [sqlite3_prepare "SELECT 1, 2, 2;" -1 DUMMY]
+# 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 {
+      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 [sqlite3_column_table_name $STMT $i]} 
+    set cnamelist
+  } $tables
+
+  # 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 [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
+  }
+}
+
 # This proc is used to test the following APIs:
 #
 # sqlite3_data_count
@@ -450,11 +535,13 @@ do_test capi3-5.0 {
 } 3
 
 check_header $STMT capi3-5.1 {a b c} {VARINT BLOB VARCHAR(16)}
+check_origin_header $STMT capi3-5.1 {main main main} {t1 t1 t1} {a b c}
 do_test capi3-5.2 {
   sqlite3_step $STMT
 } SQLITE_ROW
 
 check_header $STMT capi3-5.3 {a b c} {VARINT BLOB VARCHAR(16)}
+check_origin_header $STMT capi3-5.3 {main main main} {t1 t1 t1} {a b c}
 check_data $STMT capi3-5.4 {INTEGER INTEGER TEXT} {1 2 3} {1.0 2.0 3.0} {1 2 3}
 
 do_test capi3-5.5 {
@@ -462,6 +549,7 @@ do_test capi3-5.5 {
 } SQLITE_ROW
 
 check_header $STMT capi3-5.6 {a b c} {VARINT BLOB VARCHAR(16)}
+check_origin_header $STMT capi3-5.6 {main main main} {t1 t1 t1} {a b c}
 check_data $STMT capi3-5.7 {TEXT TEXT NULL} {0 0 0} {0.0 0.0 0.0} {one two {}}
 
 do_test capi3-5.8 {
@@ -469,6 +557,7 @@ do_test capi3-5.8 {
 } SQLITE_ROW
 
 check_header $STMT capi3-5.9 {a b c} {VARINT BLOB VARCHAR(16)}
+check_origin_header $STMT capi3-5.9 {main main main} {t1 t1 t1} {a b c}
 check_data $STMT capi3-5.10 {FLOAT FLOAT TEXT} {1 1 1} {1.2 1.3 1.4} {1.2 1.3 1.4}
 
 do_test capi3-5.11 {