mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Add the column_origin_name() etc. APIs. (CVS 3069)
FossilOrigin-Name: 82f502cdc1fead3bf7e3190d5c9db3aee6919ed4
This commit is contained in:
44
manifest
44
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Ignore\serrors\swhen\swhen\scalling\sfsync()\son\sa\sdirectory.\s\sTicket\s#1657.\s(CVS\s3068)
|
C Add\sthe\scolumn_origin_name()\setc.\sAPIs.\s(CVS\s3069)
|
||||||
D 2006-02-09T23:05:51
|
D 2006-02-10T02:27:42
|
||||||
F Makefile.in 5d8dff443383918b700e495de42ec65bc1c8865b
|
F Makefile.in 5d8dff443383918b700e495de42ec65bc1c8865b
|
||||||
F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec
|
F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -34,19 +34,19 @@ F src/alter.c 451b34fc4eb2475ca76a2e86b21e1030a9428091
|
|||||||
F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a
|
F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a
|
||||||
F src/attach.c d73a3505de3fb9e373d0a158978116c4212031d0
|
F src/attach.c d73a3505de3fb9e373d0a158978116c4212031d0
|
||||||
F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2
|
F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2
|
||||||
F src/btree.c f45f57e6cbd3b3db947cdd699db64e5215d20b2a
|
F src/btree.c 66112ae6a5caab384010344b514e98b346f550c0
|
||||||
F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
|
F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
|
||||||
F src/build.c d959aa9c2ab9c79d3d872ce91ef719698658210c
|
F src/build.c d959aa9c2ab9c79d3d872ce91ef719698658210c
|
||||||
F src/callback.c 1bf497306c32229114f826707054df7ebe10abf2
|
F src/callback.c 1bf497306c32229114f826707054df7ebe10abf2
|
||||||
F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
|
F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
|
||||||
F src/date.c cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e
|
F src/date.c cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e
|
||||||
F src/delete.c 56ab34c3a384caa5d5ea06f5739944957e2e4213
|
F src/delete.c ca404d5fd5f678e32f2f46377ad802cd0219aa99
|
||||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||||
F src/expr.c 1149c3380bfce27703f5e9bec7dfb8e51baaf9d9
|
F src/expr.c 1149c3380bfce27703f5e9bec7dfb8e51baaf9d9
|
||||||
F src/func.c 93d004b453a5d9aa754e673eef75d3c9527e0f54
|
F src/func.c 93d004b453a5d9aa754e673eef75d3c9527e0f54
|
||||||
F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863
|
F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863
|
||||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||||
F src/insert.c 7e931b7f06afbcefcbbaab175c02eff8268db33f
|
F src/insert.c 67b3dc11831c58d8703eb502355ad3704ee18f66
|
||||||
F src/legacy.c 86b669707b3cefd570e34154e2f6457547d1df4f
|
F src/legacy.c 86b669707b3cefd570e34154e2f6457547d1df4f
|
||||||
F src/main.c 9a42464c44a6532003391486e802e65e88789cfc
|
F src/main.c 9a42464c44a6532003391486e802e65e88789cfc
|
||||||
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
||||||
@@ -61,19 +61,19 @@ F src/os_win.c c67a2c46d929cf54c8f80ec5e6079cf684a141a9
|
|||||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||||
F src/pager.c b5b380ea7a36f84e50c3adc1a414820a0eb3baa6
|
F src/pager.c b5b380ea7a36f84e50c3adc1a414820a0eb3baa6
|
||||||
F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f
|
F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f
|
||||||
F src/parse.y ce7182bfd47b7e5921bc55dcc399cda5cb879f19
|
F src/parse.y 6d666d60a3bb51ceeb0d30b395455a24856849b7
|
||||||
F src/pragma.c c26c810e9c7d3a95a2c617b507bf8e8d65be7721
|
F src/pragma.c 8e135979702f249dd5877402056df0a336ea5a12
|
||||||
F src/prepare.c 40ae23c8aeb641dc7b9bb271eb5e295b815154a7
|
F src/prepare.c cf0fc8ebaf94409955ecb09ffeb0099c9ef44693
|
||||||
F src/printf.c c7d6ad9efb71c466305297a448308f467b6e2b6e
|
F src/printf.c c7d6ad9efb71c466305297a448308f467b6e2b6e
|
||||||
F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
|
F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
|
||||||
F src/select.c daee9b20702ba51cf3807fc1b130edd8846e3e48
|
F src/select.c ace67e13cd1344aa8de552c8eab9bce58f97ec24
|
||||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||||
F src/shell.c 738f55ed75fb36731e764bfdb40756ac43b90b08
|
F src/shell.c 738f55ed75fb36731e764bfdb40756ac43b90b08
|
||||||
F src/sqlite.h.in 89120d384e949be60f36af0e9e9f1b2684a30d35
|
F src/sqlite.h.in 7a76811fe3743522b531994dfbf90f24b2333f71
|
||||||
F src/sqliteInt.h 0121298397ac14eb468ab1ba9d488ac7ed7d88a1
|
F src/sqliteInt.h 0121298397ac14eb468ab1ba9d488ac7ed7d88a1
|
||||||
F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
|
F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
|
||||||
F src/tclsqlite.c 7764ab34df617b3d3cfd5f0fdf3444ed219c11d6
|
F src/tclsqlite.c d9c26374b52cd47233ae0620d0a858a59b601f89
|
||||||
F src/test1.c 894df7bced48bd30be04ab9990350900ae33557d
|
F src/test1.c 58ab748e96754f2e05c85282ac47f81f7b8c44a3
|
||||||
F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b
|
F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b
|
||||||
F src/test3.c 86e99724ee898b119ed575ef9f98618afe7e5e5d
|
F src/test3.c 86e99724ee898b119ed575ef9f98618afe7e5e5d
|
||||||
F src/test4.c ff4e9406b3d2809966d8f0e82468ac5508be9f56
|
F src/test4.c ff4e9406b3d2809966d8f0e82468ac5508be9f56
|
||||||
@@ -85,15 +85,15 @@ F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3
|
|||||||
F src/test_server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
F src/test_server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||||
F src/tokenize.c 382b3bb0ca26eb9153b5d20b246ef512a114a24f
|
F src/tokenize.c 382b3bb0ca26eb9153b5d20b246ef512a114a24f
|
||||||
F src/trigger.c 4d3644cbd16959b568c95ae73493402be8021b08
|
F src/trigger.c 4d3644cbd16959b568c95ae73493402be8021b08
|
||||||
F src/update.c 14be4ba2f438919b4217085c02feff569e6cf1f2
|
F src/update.c 050a7e0ddaac03dec5271712eee62f1a9e699049
|
||||||
F src/utf.c 1199766bbb0157931a83aa6eede6b6381177be64
|
F src/utf.c 1199766bbb0157931a83aa6eede6b6381177be64
|
||||||
F src/util.c 405f46fef062b476826d2c171ec21def29563b75
|
F src/util.c 405f46fef062b476826d2c171ec21def29563b75
|
||||||
F src/vacuum.c 3865673cc66acd0717ecd517f6b8fdb2a5e7924b
|
F src/vacuum.c 3865673cc66acd0717ecd517f6b8fdb2a5e7924b
|
||||||
F src/vdbe.c c92d7a4d3476136b8ab440f1e0547fab24112b34
|
F src/vdbe.c c92d7a4d3476136b8ab440f1e0547fab24112b34
|
||||||
F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
|
F src/vdbe.h 12e2326f256db62352f10764d1a3940d914ded59
|
||||||
F src/vdbeInt.h eb3f86ab08ef11635bc78eb88c3ff13f923c233b
|
F src/vdbeInt.h eb3f86ab08ef11635bc78eb88c3ff13f923c233b
|
||||||
F src/vdbeapi.c 54dfd0975151c859ec5b125d225ad5b3cb586497
|
F src/vdbeapi.c 72569c560acfba3e961b3cc9245a79647ea7c5ea
|
||||||
F src/vdbeaux.c 9bf50cdb6a6c40b8c06ca9a8d87cf90120a16797
|
F src/vdbeaux.c 95f4ed0bc8ed45f16823d84504310495b5dc587d
|
||||||
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
||||||
F src/vdbemem.c 2034e93b32c14bda6e306bb54e3a8e930b963027
|
F src/vdbemem.c 2034e93b32c14bda6e306bb54e3a8e930b963027
|
||||||
F src/where.c c7d71d5e55c9c4c1e948089280fb0dec7c7d1ef6
|
F src/where.c c7d71d5e55c9c4c1e948089280fb0dec7c7d1ef6
|
||||||
@@ -131,8 +131,8 @@ F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
|
|||||||
F test/btree7.test a6d3b842db22af97dd14b989e90a2fd96066b72f
|
F test/btree7.test a6d3b842db22af97dd14b989e90a2fd96066b72f
|
||||||
F test/btree8.test fadc112bcbd6a0c622d34c813fc8a648eacf8804
|
F test/btree8.test fadc112bcbd6a0c622d34c813fc8a648eacf8804
|
||||||
F test/busy.test 0271c854738e23ad76e10d4096a698e5af29d211
|
F test/busy.test 0271c854738e23ad76e10d4096a698e5af29d211
|
||||||
F test/capi2.test b9354d6c37e6f8f858c08952ebc9709712581221
|
F test/capi2.test ca76487c525b4e6085b9766cc02bcfcc53835f73
|
||||||
F test/capi3.test f36912f21457fa713ace874e73f2b54d55d1b9dd
|
F test/capi3.test e26c09ec40c5dddf215c5dd359b4989a53dde876
|
||||||
F test/capi3b.test 5f0bc94b104e11086b1103b20277e1910f59c7f4
|
F test/capi3b.test 5f0bc94b104e11086b1103b20277e1910f59c7f4
|
||||||
F test/cast.test aabdcb3873bb2f40d855bf63950f6d99a5a196c7
|
F test/cast.test aabdcb3873bb2f40d855bf63950f6d99a5a196c7
|
||||||
F test/check.test 55ad950d7ad24d6eb3328c54149f90d38a39a962
|
F test/check.test 55ad950d7ad24d6eb3328c54149f90d38a39a962
|
||||||
@@ -351,7 +351,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
||||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||||
P 0738ef818d4023a5159b6bee0a65f0b83d01c1d5
|
P d54d3b82c468b7e6dd39aac6aac56b26b3918c37
|
||||||
R 9d82f47f56b8d05740c30b2797755d9b
|
R 0b8bfdc13fc109c03d9eefa67aff0e14
|
||||||
U drh
|
U danielk1977
|
||||||
Z ed0151d0fbc7fcca110e9a3939d74452
|
Z a17c7aa8ab9c9bcf9b5fa8f511de465d
|
||||||
|
@@ -1 +1 @@
|
|||||||
d54d3b82c468b7e6dd39aac6aac56b26b3918c37
|
82f502cdc1fead3bf7e3190d5c9db3aee6919ed4
|
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** 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.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** For a detailed discussion of BTrees, refer to
|
** 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
|
** 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
|
** modified since the cursor was last used. The cursor position is saved
|
||||||
** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in
|
** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in
|
||||||
** this state, restoreOrClearCursorPosition() can be called to attempt to seek
|
** this state, restoreOrClearCursorPosition() can be called to attempt to
|
||||||
** the cursor to the saved position.
|
** seek the cursor to the saved position.
|
||||||
*/
|
*/
|
||||||
#define CURSOR_INVALID 0
|
#define CURSOR_INVALID 0
|
||||||
#define CURSOR_VALID 1
|
#define CURSOR_VALID 1
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** in order to generate code for DELETE FROM statements.
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -343,7 +343,7 @@ void sqlite3DeleteFrom(
|
|||||||
if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
|
if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, "rows deleted", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P3_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_from_cleanup:
|
delete_from_cleanup:
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle INSERT statements in SQLite.
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -703,7 +703,7 @@ void sqlite3Insert(
|
|||||||
sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0);
|
sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", P3_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_cleanup:
|
insert_cleanup:
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
** the parser. Lemon will also generate a header file containing
|
** the parser. Lemon will also generate a header file containing
|
||||||
** numeric codes for all of the tokens.
|
** 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_"
|
// All token codes are small integers with #defines that begin with "TK_"
|
||||||
|
61
src/pragma.c
61
src/pragma.c
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the PRAGMA command.
|
** 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 "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -128,7 +128,7 @@ static void returnSingleInt(Parse *pParse, const char *zLabel, int value){
|
|||||||
sqlite3VdbeAddOp(v, OP_Integer, value, 0);
|
sqlite3VdbeAddOp(v, OP_Integer, value, 0);
|
||||||
if( pParse->explain==0 ){
|
if( pParse->explain==0 ){
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, zLabel, P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, P3_STATIC);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||||
}
|
}
|
||||||
@@ -274,7 +274,7 @@ void sqlite3Pragma(
|
|||||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||||
if( !zRight ){
|
if( !zRight ){
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
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);
|
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
|
||||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||||
sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
|
sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
|
||||||
@@ -392,7 +392,8 @@ void sqlite3Pragma(
|
|||||||
if( !zRight ){
|
if( !zRight ){
|
||||||
if( sqlite3_temp_directory ){
|
if( sqlite3_temp_directory ){
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
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);
|
sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0);
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||||
}
|
}
|
||||||
@@ -470,12 +471,12 @@ void sqlite3Pragma(
|
|||||||
int i;
|
int i;
|
||||||
Column *pCol;
|
Column *pCol;
|
||||||
sqlite3VdbeSetNumCols(v, 6);
|
sqlite3VdbeSetNumCols(v, 6);
|
||||||
sqlite3VdbeSetColName(v, 0, "cid", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 2, "type", P3_STATIC);
|
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 3, "notnull", P3_STATIC);
|
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 4, "dflt_value", P3_STATIC);
|
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 5, "pk", P3_STATIC);
|
sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", P3_STATIC);
|
||||||
sqlite3ViewGetColumnNames(pParse, pTab);
|
sqlite3ViewGetColumnNames(pParse, pTab);
|
||||||
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
|
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||||
@@ -499,9 +500,9 @@ void sqlite3Pragma(
|
|||||||
int i;
|
int i;
|
||||||
pTab = pIdx->pTable;
|
pTab = pIdx->pTable;
|
||||||
sqlite3VdbeSetNumCols(v, 3);
|
sqlite3VdbeSetNumCols(v, 3);
|
||||||
sqlite3VdbeSetColName(v, 0, "seqno", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, "cid", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 2, "name", P3_STATIC);
|
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", P3_STATIC);
|
||||||
for(i=0; i<pIdx->nColumn; i++){
|
for(i=0; i<pIdx->nColumn; i++){
|
||||||
int cnum = pIdx->aiColumn[i];
|
int cnum = pIdx->aiColumn[i];
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||||
@@ -524,9 +525,9 @@ void sqlite3Pragma(
|
|||||||
if( pIdx ){
|
if( pIdx ){
|
||||||
int i = 0;
|
int i = 0;
|
||||||
sqlite3VdbeSetNumCols(v, 3);
|
sqlite3VdbeSetNumCols(v, 3);
|
||||||
sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 2, "unique", P3_STATIC);
|
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", P3_STATIC);
|
||||||
while(pIdx){
|
while(pIdx){
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0);
|
sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0);
|
||||||
@@ -543,9 +544,9 @@ void sqlite3Pragma(
|
|||||||
int i;
|
int i;
|
||||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||||
sqlite3VdbeSetNumCols(v, 3);
|
sqlite3VdbeSetNumCols(v, 3);
|
||||||
sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 2, "file", P3_STATIC);
|
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", P3_STATIC);
|
||||||
for(i=0; i<db->nDb; i++){
|
for(i=0; i<db->nDb; i++){
|
||||||
if( db->aDb[i].pBt==0 ) continue;
|
if( db->aDb[i].pBt==0 ) continue;
|
||||||
assert( db->aDb[i].zName!=0 );
|
assert( db->aDb[i].zName!=0 );
|
||||||
@@ -561,8 +562,8 @@ void sqlite3Pragma(
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
HashElem *p;
|
HashElem *p;
|
||||||
sqlite3VdbeSetNumCols(v, 2);
|
sqlite3VdbeSetNumCols(v, 2);
|
||||||
sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC);
|
||||||
for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
|
for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
|
||||||
CollSeq *pColl = (CollSeq *)sqliteHashData(p);
|
CollSeq *pColl = (CollSeq *)sqliteHashData(p);
|
||||||
sqlite3VdbeAddOp(v, OP_Integer, i++, 0);
|
sqlite3VdbeAddOp(v, OP_Integer, i++, 0);
|
||||||
@@ -584,11 +585,11 @@ void sqlite3Pragma(
|
|||||||
if( pFK ){
|
if( pFK ){
|
||||||
int i = 0;
|
int i = 0;
|
||||||
sqlite3VdbeSetNumCols(v, 5);
|
sqlite3VdbeSetNumCols(v, 5);
|
||||||
sqlite3VdbeSetColName(v, 0, "id", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, "seq", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 2, "table", P3_STATIC);
|
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 3, "from", P3_STATIC);
|
sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 4, "to", P3_STATIC);
|
sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", P3_STATIC);
|
||||||
while(pFK){
|
while(pFK){
|
||||||
int j;
|
int j;
|
||||||
for(j=0; j<pFK->nCol; j++){
|
for(j=0; j<pFK->nCol; j++){
|
||||||
@@ -650,7 +651,7 @@ void sqlite3Pragma(
|
|||||||
/* Initialize the VDBE program */
|
/* Initialize the VDBE program */
|
||||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
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 */
|
sqlite3VdbeAddOp(v, OP_MemInt, 0, 0); /* Initialize error count to 0 */
|
||||||
|
|
||||||
/* Do an integrity check on each database file */
|
/* Do an integrity check on each database file */
|
||||||
@@ -795,7 +796,7 @@ void sqlite3Pragma(
|
|||||||
if( !zRight ){ /* "PRAGMA encoding" */
|
if( !zRight ){ /* "PRAGMA encoding" */
|
||||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", P3_STATIC);
|
||||||
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
sqlite3VdbeAddOp(v, OP_String8, 0, 0);
|
||||||
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
|
for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
|
||||||
if( pEnc->enc==ENC(pParse->db) ){
|
if( pEnc->enc==ENC(pParse->db) ){
|
||||||
@@ -901,8 +902,8 @@ void sqlite3Pragma(
|
|||||||
int i;
|
int i;
|
||||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||||
sqlite3VdbeSetNumCols(v, 2);
|
sqlite3VdbeSetNumCols(v, 2);
|
||||||
sqlite3VdbeSetColName(v, 0, "database", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(v, 1, "status", P3_STATIC);
|
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", P3_STATIC);
|
||||||
for(i=0; i<db->nDb; i++){
|
for(i=0; i<db->nDb; i++){
|
||||||
Btree *pBt;
|
Btree *pBt;
|
||||||
Pager *pPager;
|
Pager *pPager;
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
** interface, and routines that contribute to loading the database schema
|
** interface, and routines that contribute to loading the database schema
|
||||||
** from disk.
|
** 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 "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -556,16 +556,16 @@ int sqlite3_prepare(
|
|||||||
if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
|
if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
|
||||||
if( sParse.explain==2 ){
|
if( sParse.explain==2 ){
|
||||||
sqlite3VdbeSetNumCols(sParse.pVdbe, 3);
|
sqlite3VdbeSetNumCols(sParse.pVdbe, 3);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 0, "order", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 1, "from", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 2, "detail", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", P3_STATIC);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeSetNumCols(sParse.pVdbe, 5);
|
sqlite3VdbeSetNumCols(sParse.pVdbe, 5);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", P3_STATIC);
|
||||||
sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC);
|
sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", P3_STATIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
140
src/select.c
140
src/select.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -762,14 +762,31 @@ static void generateSortTail(
|
|||||||
** Return a pointer to a string containing the 'declaration type' of the
|
** Return a pointer to a string containing the 'declaration type' of the
|
||||||
** expression pExpr. The string may be treated as static by the caller.
|
** expression pExpr. The string may be treated as static by the caller.
|
||||||
**
|
**
|
||||||
** If the declaration type is the exact datatype definition extracted from
|
** The declaration type is the exact datatype definition extracted from the
|
||||||
** the original CREATE TABLE statement if the expression is a column.
|
** 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.
|
||||||
**
|
**
|
||||||
** The declaration type for an expression is either TEXT, NUMERIC or ANY.
|
** SELECT col FROM tbl;
|
||||||
** The declaration type for a ROWID field is INTEGER.
|
** SELECT (SELECT col FROM tbl;
|
||||||
|
** SELECT (SELECT col FROM tbl);
|
||||||
|
** SELECT abc FROM (SELECT col AS abc FROM tbl);
|
||||||
|
**
|
||||||
|
** The declaration type for any expression other than a column is NULL.
|
||||||
*/
|
*/
|
||||||
static const char *columnType(NameContext *pNC, Expr *pExpr){
|
static const char *columnType(
|
||||||
char const *zType;
|
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;
|
int j;
|
||||||
if( pExpr==0 || pNC->pSrcList==0 ) return 0;
|
if( pExpr==0 || pNC->pSrcList==0 ) return 0;
|
||||||
|
|
||||||
@@ -781,17 +798,24 @@ static const char *columnType(NameContext *pNC, Expr *pExpr){
|
|||||||
|
|
||||||
switch( pExpr->op ){
|
switch( pExpr->op ){
|
||||||
case TK_COLUMN: {
|
case TK_COLUMN: {
|
||||||
Table *pTab = 0;
|
/* The expression is a column. Locate the table the column is being
|
||||||
int iCol = pExpr->iColumn;
|
** 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 ){
|
while( pNC && !pTab ){
|
||||||
SrcList *pTabList = pNC->pSrcList;
|
SrcList *pTabList = pNC->pSrcList;
|
||||||
for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
|
for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
|
||||||
if( j<pTabList->nSrc ){
|
if( j<pTabList->nSrc ){
|
||||||
pTab = pTabList->a[j].pTab;
|
pTab = pTabList->a[j].pTab;
|
||||||
|
pS = pTabList->a[j].pSelect;
|
||||||
}else{
|
}else{
|
||||||
pNC = pNC->pNext;
|
pNC = pNC->pNext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pTab==0 ){
|
if( pTab==0 ){
|
||||||
/* FIX ME:
|
/* FIX ME:
|
||||||
** This can occurs if you have something like "SELECT new.x;" inside
|
** 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";
|
zType = "TEXT";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( pTab );
|
assert( pTab );
|
||||||
|
#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;
|
if( iCol<0 ) iCol = pTab->iPKey;
|
||||||
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
|
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
|
||||||
if( iCol<0 ){
|
if( iCol<0 ){
|
||||||
zType = "INTEGER";
|
zType = "INTEGER";
|
||||||
|
zOriginCol = "rowid";
|
||||||
}else{
|
}else{
|
||||||
zType = pTab->aCol[iCol].zType;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_SUBQUERY
|
#ifndef SQLITE_OMIT_SUBQUERY
|
||||||
case TK_SELECT: {
|
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;
|
NameContext sNC;
|
||||||
Select *pS = pExpr->pSelect;
|
Select *pS = pExpr->pSelect;
|
||||||
sNC.pSrcList = pExpr->pSelect->pSrc;
|
Expr *p = pS->pEList->a[0].pExpr;
|
||||||
|
sNC.pSrcList = pS->pSrc;
|
||||||
sNC.pNext = pNC;
|
sNC.pNext = pNC;
|
||||||
zType = columnType(&sNC, pS->pEList->a[0].pExpr);
|
sNC.pParse = pNC->pParse;
|
||||||
|
zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
default:
|
|
||||||
zType = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( pzOriginDb ){
|
||||||
|
assert( pzOriginTab && pzOriginCol );
|
||||||
|
*pzOriginDb = zOriginDb;
|
||||||
|
*pzOriginTab = zOriginTab;
|
||||||
|
*pzOriginCol = zOriginCol;
|
||||||
|
}
|
||||||
return zType;
|
return zType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -846,14 +912,27 @@ static void generateColumnTypes(
|
|||||||
int i;
|
int i;
|
||||||
NameContext sNC;
|
NameContext sNC;
|
||||||
sNC.pSrcList = pTabList;
|
sNC.pSrcList = pTabList;
|
||||||
|
sNC.pParse = pParse;
|
||||||
for(i=0; i<pEList->nExpr; i++){
|
for(i=0; i<pEList->nExpr; i++){
|
||||||
Expr *p = pEList->a[i].pExpr;
|
Expr *p = pEList->a[i].pExpr;
|
||||||
const char *zType = columnType(&sNC, p);
|
const char *zOrigDb = 0;
|
||||||
if( zType==0 ) continue;
|
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
|
/* The vdbe must make it's own copy of the column-type, in case the
|
||||||
** schema is reset before this virtual machine is deleted.
|
** 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( p==0 ) continue;
|
||||||
if( pEList->a[i].zName ){
|
if( pEList->a[i].zName ){
|
||||||
char *zName = 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;
|
continue;
|
||||||
}
|
}
|
||||||
if( p->op==TK_COLUMN && pTabList ){
|
if( p->op==TK_COLUMN && pTabList ){
|
||||||
@@ -909,7 +988,7 @@ static void generateColumnNames(
|
|||||||
zCol = pTab->aCol[iCol].zName;
|
zCol = pTab->aCol[iCol].zName;
|
||||||
}
|
}
|
||||||
if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
|
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) ){
|
}else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
|
||||||
char *zName = 0;
|
char *zName = 0;
|
||||||
char *zTab;
|
char *zTab;
|
||||||
@@ -917,18 +996,18 @@ static void generateColumnNames(
|
|||||||
zTab = pTabList->a[j].zAlias;
|
zTab = pTabList->a[j].zAlias;
|
||||||
if( fullNames || zTab==0 ) zTab = pTab->zName;
|
if( fullNames || zTab==0 ) zTab = pTab->zName;
|
||||||
sqlite3SetString(&zName, zTab, ".", zCol, (char*)0);
|
sqlite3SetString(&zName, zTab, ".", zCol, (char*)0);
|
||||||
sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC);
|
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, P3_DYNAMIC);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeSetColName(v, i, zCol, strlen(zCol));
|
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, strlen(zCol));
|
||||||
}
|
}
|
||||||
}else if( p->span.z && p->span.z[0] ){
|
}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); */
|
/* sqlite3VdbeCompressSpace(v, addr); */
|
||||||
}else{
|
}else{
|
||||||
char zName[30];
|
char zName[30];
|
||||||
assert( p->op!=TK_COLUMN || pTabList==0 );
|
assert( p->op!=TK_COLUMN || pTabList==0 );
|
||||||
sprintf(zName, "column%d", i+1);
|
sprintf(zName, "column%d", i+1);
|
||||||
sqlite3VdbeSetColName(v, i, zName, 0);
|
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
generateColumnTypes(pParse, pTabList, pEList);
|
generateColumnTypes(pParse, pTabList, pEList);
|
||||||
@@ -1036,7 +1115,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
|
|||||||
*/
|
*/
|
||||||
memset(&sNC, 0, sizeof(sNC));
|
memset(&sNC, 0, sizeof(sNC));
|
||||||
sNC.pSrcList = pSelect->pSrc;
|
sNC.pSrcList = pSelect->pSrc;
|
||||||
zType = sqliteStrDup(columnType(&sNC, p));
|
zType = sqliteStrDup(columnType(&sNC, p, 0, 0, 0));
|
||||||
pCol->zType = zType;
|
pCol->zType = zType;
|
||||||
pCol->affinity = sqlite3ExprAffinity(p);
|
pCol->affinity = sqlite3ExprAffinity(p);
|
||||||
pColl = sqlite3ExprCollSeq(pParse, p);
|
pColl = sqlite3ExprCollSeq(pParse, p);
|
||||||
@@ -2783,13 +2862,6 @@ int sqlite3Select(
|
|||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v==0 ) goto select_end;
|
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
|
/* Generate code for all sub-queries in the FROM clause
|
||||||
*/
|
*/
|
||||||
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
|
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
|
||||||
@@ -3217,6 +3289,14 @@ int sqlite3Select(
|
|||||||
** successful coding of the SELECT.
|
** successful coding of the SELECT.
|
||||||
*/
|
*/
|
||||||
select_end:
|
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.aCol);
|
||||||
sqliteFree(sAggInfo.aFunc);
|
sqliteFree(sAggInfo.aFunc);
|
||||||
return rc;
|
return rc;
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
** This header file defines the interface that the SQLite library
|
** This header file defines the interface that the SQLite library
|
||||||
** presents to client programs.
|
** 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_
|
#ifndef _SQLITE3_H_
|
||||||
#define _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 char *sqlite3_column_name(sqlite3_stmt*,int);
|
||||||
const void *sqlite3_column_name16(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
|
** The first parameter is a compiled SQL statement. If this statement
|
||||||
** is a SELECT statement, the Nth column of the returned result set
|
** 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:
|
** 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
|
** Then this routine would return the string "VARIANT" for the second
|
||||||
** result column (i==1), and a NULL pointer for the first result column
|
** 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:
|
** 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
|
** Then this routine would return the string "INTEGER" for the second
|
||||||
** result column (i==1), and a NULL pointer for the first result column
|
** result column (i==1), and a NULL pointer for the first result column
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** A TCL Interface to SQLite
|
** 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 */
|
#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 ){
|
if( i+1!=nCol ){
|
||||||
char *zErr;
|
char *zErr;
|
||||||
zErr = malloc(200 + strlen(zFile));
|
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);
|
zFile, lineno, nCol, i+1);
|
||||||
Tcl_AppendResult(interp, zErr, 0);
|
Tcl_AppendResult(interp, zErr, 0);
|
||||||
free(zErr);
|
free(zErr);
|
||||||
|
10
src/test1.c
10
src/test1.c
@@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** 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 "sqliteInt.h"
|
||||||
#include "tcl.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_name", test_stmt_utf8, sqlite3_column_name },
|
||||||
{ "sqlite3_column_int", test_stmt_int, sqlite3_column_int },
|
{ "sqlite3_column_int", test_stmt_int, sqlite3_column_int },
|
||||||
{ "sqlite3_column_bytes", test_stmt_int, sqlite3_column_bytes },
|
{ "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
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
{ "sqlite3_column_bytes16", test_stmt_int, sqlite3_column_bytes16 },
|
{ "sqlite3_column_bytes16", test_stmt_int, sqlite3_column_bytes16 },
|
||||||
{ "sqlite3_column_text16", test_stmt_utf16, sqlite3_column_text16 },
|
{ "sqlite3_column_text16", test_stmt_utf16, sqlite3_column_text16 },
|
||||||
{ "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16},
|
{ "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16},
|
||||||
{ "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16 },
|
{ "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
|
#endif
|
||||||
{ "sqlite3_global_recover", test_global_recover, 0 },
|
{ "sqlite3_global_recover", test_global_recover, 0 },
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle UPDATE statements.
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -494,7 +494,7 @@ void sqlite3Update(
|
|||||||
if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
|
if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
|
||||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, "rows updated", P3_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", P3_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
update_cleanup:
|
update_cleanup:
|
||||||
|
15
src/vdbe.h
15
src/vdbe.h
@@ -15,7 +15,7 @@
|
|||||||
** or VDBE. The VDBE implements an abstract machine that runs a
|
** or VDBE. The VDBE implements an abstract machine that runs a
|
||||||
** simple program to access and modify the underlying database.
|
** 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_
|
#ifndef _SQLITE_VDBE_H_
|
||||||
#define _SQLITE_VDBE_H_
|
#define _SQLITE_VDBE_H_
|
||||||
@@ -79,6 +79,17 @@ typedef struct VdbeOpList VdbeOpList;
|
|||||||
*/
|
*/
|
||||||
#define P3_KEYINFO_HANDOFF (-9)
|
#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
|
** The following macro converts a relative address in the p2 field
|
||||||
** of a VdbeOp structure into a negative number so that
|
** of a VdbeOp structure into a negative number so that
|
||||||
@@ -117,7 +128,7 @@ void sqlite3VdbeTrace(Vdbe*,FILE*);
|
|||||||
int sqlite3VdbeReset(Vdbe*);
|
int sqlite3VdbeReset(Vdbe*);
|
||||||
int sqliteVdbeSetVariables(Vdbe*,int,const char**);
|
int sqliteVdbeSetVariables(Vdbe*,int,const char**);
|
||||||
void sqlite3VdbeSetNumCols(Vdbe*,int);
|
void sqlite3VdbeSetNumCols(Vdbe*,int);
|
||||||
int sqlite3VdbeSetColName(Vdbe*, int, const char *, int);
|
int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int);
|
||||||
void sqlite3VdbeCountChanges(Vdbe*);
|
void sqlite3VdbeCountChanges(Vdbe*);
|
||||||
sqlite3 *sqlite3VdbeDb(Vdbe*);
|
sqlite3 *sqlite3VdbeDb(Vdbe*);
|
||||||
|
|
||||||
|
@@ -521,11 +521,13 @@ static const void *columnName(
|
|||||||
** statement pStmt.
|
** statement pStmt.
|
||||||
*/
|
*/
|
||||||
const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
|
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
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
|
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
|
#endif
|
||||||
|
|
||||||
@@ -534,26 +536,30 @@ const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
|
|||||||
** of the result set of SQL statement pStmt.
|
** of the result set of SQL statement pStmt.
|
||||||
*/
|
*/
|
||||||
const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
|
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
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
|
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 */
|
#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.
|
** 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
|
** 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.
|
** anything else which is not an unabiguous reference to a database column.
|
||||||
*/
|
*/
|
||||||
const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
|
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
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
|
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 */
|
#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.
|
** anything else which is not an unabiguous reference to a database column.
|
||||||
*/
|
*/
|
||||||
const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
|
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
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
|
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 */
|
#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.
|
** anything else which is not an unabiguous reference to a database column.
|
||||||
*/
|
*/
|
||||||
const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
|
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
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
|
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_UTF16 */
|
||||||
#endif /* SQLITE_OMIT_ORIGIN_NAMES */
|
#endif /* SQLITE_OMIT_ORIGIN_NAMES */
|
||||||
|
@@ -871,9 +871,9 @@ static void Cleanup(Vdbe *p){
|
|||||||
void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
|
void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
|
||||||
Mem *pColName;
|
Mem *pColName;
|
||||||
int n;
|
int n;
|
||||||
releaseMemArray(p->aColName, p->nResColumn*2);
|
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
|
||||||
sqliteFree(p->aColName);
|
sqliteFree(p->aColName);
|
||||||
n = nResColumn*2;
|
n = nResColumn*COLNAME_N;
|
||||||
p->nResColumn = nResColumn;
|
p->nResColumn = nResColumn;
|
||||||
p->aColName = pColName = (Mem*)sqliteMalloc( sizeof(Mem)*n );
|
p->aColName = pColName = (Mem*)sqliteMalloc( sizeof(Mem)*n );
|
||||||
if( p->aColName==0 ) return;
|
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
|
** the string is freed using sqliteFree() when the vdbe is finished with
|
||||||
** it. Otherwise, N bytes of zName are copied.
|
** 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;
|
int rc;
|
||||||
Mem *pColName;
|
Mem *pColName;
|
||||||
assert( idx<(2*p->nResColumn) );
|
assert( idx<p->nResColumn );
|
||||||
|
assert( var<COLNAME_N );
|
||||||
if( sqlite3MallocFailed() ) return SQLITE_NOMEM;
|
if( sqlite3MallocFailed() ) return SQLITE_NOMEM;
|
||||||
assert( p->aColName!=0 );
|
assert( p->aColName!=0 );
|
||||||
pColName = &(p->aColName[idx]);
|
pColName = &(p->aColName[idx+var*p->nResColumn]);
|
||||||
if( N==P3_DYNAMIC || N==P3_STATIC ){
|
if( N==P3_DYNAMIC || N==P3_STATIC ){
|
||||||
rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
|
rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
|
||||||
}else{
|
}else{
|
||||||
@@ -1481,7 +1482,7 @@ void sqlite3VdbeDelete(Vdbe *p){
|
|||||||
releaseMemArray(p->aVar, p->nVar);
|
releaseMemArray(p->aVar, p->nVar);
|
||||||
sqliteFree(p->aLabel);
|
sqliteFree(p->aLabel);
|
||||||
sqliteFree(p->aStack);
|
sqliteFree(p->aStack);
|
||||||
releaseMemArray(p->aColName, p->nResColumn*2);
|
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
|
||||||
sqliteFree(p->aColName);
|
sqliteFree(p->aColName);
|
||||||
p->magic = VDBE_MAGIC_DEAD;
|
p->magic = VDBE_MAGIC_DEAD;
|
||||||
sqliteFree(p);
|
sqliteFree(p);
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this script testing the callback-free C/C++ API.
|
# 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]
|
set testdir [file dirname $argv0]
|
||||||
@@ -638,6 +638,8 @@ do_test capi2-9.1 {
|
|||||||
sqlite3_finalize $VM1
|
sqlite3_finalize $VM1
|
||||||
} {SQLITE_OK}
|
} {SQLITE_OK}
|
||||||
|
|
||||||
|
# Test that passing a NULL pointer to sqlite3_finalize() or sqlite3_reset
|
||||||
|
# does not cause an error.
|
||||||
do_test capi2-10.1 {
|
do_test capi2-10.1 {
|
||||||
sqlite3_finalize 0
|
sqlite3_finalize 0
|
||||||
} {SQLITE_OK}
|
} {SQLITE_OK}
|
||||||
@@ -645,6 +647,81 @@ do_test capi2-10.2 {
|
|||||||
sqlite3_reset 0
|
sqlite3_reset 0
|
||||||
} {SQLITE_OK}
|
} {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
|
db2 close
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this script testing the callback-free C/C++ API.
|
# 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]
|
set testdir [file dirname $argv0]
|
||||||
@@ -286,7 +286,92 @@ proc check_header {STMT test names decltypes} {
|
|||||||
[sqlite3_column_decltype16 $STMT $numcols]
|
[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:
|
# This proc is used to test the following APIs:
|
||||||
@@ -450,11 +535,13 @@ do_test capi3-5.0 {
|
|||||||
} 3
|
} 3
|
||||||
|
|
||||||
check_header $STMT capi3-5.1 {a b c} {VARINT BLOB VARCHAR(16)}
|
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 {
|
do_test capi3-5.2 {
|
||||||
sqlite3_step $STMT
|
sqlite3_step $STMT
|
||||||
} SQLITE_ROW
|
} SQLITE_ROW
|
||||||
|
|
||||||
check_header $STMT capi3-5.3 {a b c} {VARINT BLOB VARCHAR(16)}
|
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}
|
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 {
|
do_test capi3-5.5 {
|
||||||
@@ -462,6 +549,7 @@ do_test capi3-5.5 {
|
|||||||
} SQLITE_ROW
|
} SQLITE_ROW
|
||||||
|
|
||||||
check_header $STMT capi3-5.6 {a b c} {VARINT BLOB VARCHAR(16)}
|
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 {}}
|
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 {
|
do_test capi3-5.8 {
|
||||||
@@ -469,6 +557,7 @@ do_test capi3-5.8 {
|
|||||||
} SQLITE_ROW
|
} SQLITE_ROW
|
||||||
|
|
||||||
check_header $STMT capi3-5.9 {a b c} {VARINT BLOB VARCHAR(16)}
|
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}
|
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 {
|
do_test capi3-5.11 {
|
||||||
|
Reference in New Issue
Block a user