-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
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
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
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
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
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
-d54d3b82c468b7e6dd39aac6aac56b26b3918c37
\ No newline at end of file
+82f502cdc1fead3bf7e3190d5c9db3aee6919ed4
\ No newline at end of file
** 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
** 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
** 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"
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:
** 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"
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:
** 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_"
}
}
- // 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.
//
*************************************************************************
** 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"
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);
}
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);
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);
}
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);
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);
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);
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 );
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);
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++){
/* 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 */
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) ){
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;
** 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"
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
** 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"
** 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;
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
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;
}
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);
}
}
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 ){
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;
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);
*/
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);
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)
** 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;
** 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_
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
**
** 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
**
** 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
*************************************************************************
** 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 */
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);
** 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"
{ "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 },
** 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"
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:
** 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_
*/
#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
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*);
** 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
** 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 */
** 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 */
** 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 */
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;
** 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{
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);
# 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]
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}
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
# 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]
[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
} 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 {
} 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 {
} 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 {