Version 2.0.6 (CVS 291)
FossilOrigin-Name: 8467d84fc6e67bd93051f54338a8f6c9b1711ee1
This commit is contained in:
parent
98808babd3
commit
6a535340bc
38
manifest
38
manifest
@ -1,9 +1,9 @@
|
||||
C Support\sfor\sUTF-8\sand\sISO8859\scharacters\sin\sidentifiers.\s\sBug\sfix\sin\nthe\scolumn\sname\sgenerator\sfor\sselects\s(was\scoreing).\s(CVS\s290)
|
||||
D 2001-10-18T12:34:47
|
||||
C Version\s2.0.6\s(CVS\s291)
|
||||
D 2001-10-19T16:44:56
|
||||
F Makefile.in 6801df952cb1df64aa32e4de85fed24511d28efd
|
||||
F Makefile.template 1fdb891f14083ee0b63cf7282f91529634438e7a
|
||||
F README 93d2977cc5c6595c448de16bdefc312b9d401533
|
||||
F VERSION e14d2010c343ae28a0dd038c3850eae3a88a9307
|
||||
F VERSION be4a9c5c382f200a4575c3dc5133f6359a33606a
|
||||
F aclocal.m4 11faa843caa38fd451bc6aeb43e248d1723a269d
|
||||
F config.guess f38b1e93d1e0fa6f5a6913e9e7b12774b9232588
|
||||
F config.log 6a73d03433669b10a3f0c221198c3f26b9413914
|
||||
@ -21,7 +21,7 @@ F publish.sh badcd69b8e3a8bc69b162c4c9d7c209b2a0b119e
|
||||
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
||||
F src/btree.c 97653e88bc4b7396226b93c878b153c77f1d3d03
|
||||
F src/btree.h 57d653ef5137b91f2a068aaf71a2905468dd2cb7
|
||||
F src/build.c fe71d516148226bd6249403e82f8d07129206489
|
||||
F src/build.c d18081e69b23390cb6baaaf6f6c804b93775a0be
|
||||
F src/delete.c 6fe2191c49c4a31336e2fac11b3ad665ddcd4246
|
||||
F src/expr.c c1381b8229a5573b0928ede962e45c1c49d067af
|
||||
F src/hash.c b7ced0735287c142a3b2db46c3cae3e6826afb75
|
||||
@ -36,21 +36,21 @@ F src/pager.h a0d4c5ae271914aa07b62aee0707997d6932b6ca
|
||||
F src/parse.y 148e4cd134d3cbd816dcb0df50e49e498faa6ba4
|
||||
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
|
||||
F src/random.c 2a9cc2c9716d14815fd4c2accf89d87a1143e46b
|
||||
F src/select.c 0e8089c5ae84fa3eb7e64b40350832983918e7a4
|
||||
F src/shell.c cb8c41f1b2173efd212dab3f35f1fc6bf32ead76
|
||||
F src/select.c 10957c2fd52ee36fbb40171c36377c9f94dd36ea
|
||||
F src/shell.c 71597951753b56a97fea1c7a30908f31e635c00c
|
||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||
F src/sqlite.h.in b95c161abf1d58bceb05290fa3f657d8f388fc11
|
||||
F src/sqliteInt.h acfd52eb2949abb847b1be93687e93e3663231b2
|
||||
F src/table.c abd0adbe0fee39d995287b3bcccd908d174dfcac
|
||||
F src/tclsqlite.c 0b947866c89fe5b683fc86e8419b7f8da3cebf7d
|
||||
F src/sqliteInt.h 52577abf2805ba148972f69788ed49c64064fa31
|
||||
F src/table.c 4e8cbabfbc6018fdd0615f7c5d06fb431cd56505
|
||||
F src/tclsqlite.c 7d205aeda449047f86b39a6c55731a1ded7a7ab5
|
||||
F src/test1.c e4b31f62ea71963cbae44338acf477a04fc8fc49
|
||||
F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321
|
||||
F src/test3.c 4a0d7b882fdae731dbb759f512ad867122452f96
|
||||
F src/tokenize.c 2b95e67bcb5f68e7fe4a5a426fcbe0891d7aaa54
|
||||
F src/tokenize.c 59ddae1501de472e9a6274a1cbf451170c52488c
|
||||
F src/update.c c916182c6bfbc8a6f20c24920c4560fece6c9569
|
||||
F src/util.c 4da3be37d0fd3c640d2d3033503768afdc8e5387
|
||||
F src/vdbe.c 01617df84381c3ace10feb370b8d1f72f275c1ab
|
||||
F src/vdbe.h 86fc2ef42f48024c9a2e1b7fb01eda22b65a5295
|
||||
F src/vdbe.c e326ff611c9d2c273fdcb86b4661b464f2af128b
|
||||
F src/vdbe.h f8407fd6b644bc001b1e7c65460c9962f6a15f6b
|
||||
F src/where.c 22fe910c7c8e2736eb37e9861343e90c0b513c86
|
||||
F test/all.test a2320eb40b462f25bd3e33115b1cabf3791450dd
|
||||
F test/bigrow.test a35f2de9948b24e427fb292c35947795efe182d0
|
||||
@ -74,7 +74,7 @@ F test/printf.test 3cb415073754cb8ff076f26173143c3cd293a9da
|
||||
F test/quick.test b6ec50f808efc06595fd324bf4f3fabadb9c7e9c
|
||||
F test/quote.test 286db944717afa9a9bf829dd85e59185c65d5435
|
||||
F test/rowid.test 427bfbbe9684fe7a2f851aa05badaae6d4972ce8
|
||||
F test/select1.test 129c0188565383c3d22858161b96fefd3f7fa09f
|
||||
F test/select1.test 75af194669ff9f4fe42c6fd070d9ec3b268354bb
|
||||
F test/select2.test f91c903e2bab0e9d45274855a981eebf846d5e32
|
||||
F test/select3.test 5e1fe8e5a4e63fb2827ab3b89527e0fd4ae35259
|
||||
F test/select4.test 29a2ffb187f3d8b6ca42a0a6b619e9cabe12e228
|
||||
@ -101,20 +101,20 @@ F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816
|
||||
F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
|
||||
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
|
||||
F www/arch.tcl 03b521d252575f93b9c52f7c8b0007011512fcfb
|
||||
F www/c_interface.tcl a59ee0835d1b33fcddab7d4fd65cf9e50f7d2dc7
|
||||
F www/changes.tcl 5ff43653f6387ce7b6e0a8aa384855b3f3b76550
|
||||
F www/c_interface.tcl 6c5989670e014de44dce6580cbde0eea965dadbb
|
||||
F www/changes.tcl 7f249321a6ccb4abb79e56b801dede791a44c237
|
||||
F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e
|
||||
F www/download.tcl 3e51c9ff1326b0a182846134987301310dff7d60
|
||||
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
|
||||
F www/index.tcl 68c815d64b35b2dcc4d4f6845827df71c6869f9f
|
||||
F www/lang.tcl 37d4a44bdafe42a270b9e28554651278086ce806
|
||||
F www/lang.tcl 1899ec4fb77cd69de335ebd998253de869f34d8e
|
||||
F www/mingw.tcl fc5f4ba9d336b6e8c97347cc6496d6162461ef60
|
||||
F www/opcode.tcl 4365ad9798872491dbd7d3071510ebe461785ac3
|
||||
F www/speed.tcl ab7d6d3bc898472bd94320a5d3c63de928d4804b
|
||||
F www/sqlite.tcl 6a21242a272e9c0939a04419a51c3d50cae33e3e
|
||||
F www/tclsqlite.tcl 13d50723f583888fc80ae1a38247c0ab415066fa
|
||||
F www/vdbe.tcl bb7d620995f0a987293e9d4fb6185a3b077e9b44
|
||||
P e2d84f71ed39cbb75884205521aa9e316ab3b56c
|
||||
R 3132f2509f739a21413aa9b99beee504
|
||||
P 22948fc685299ca888907eea68edb8a6e87c3f49
|
||||
R 517debf090e30b01a34d90ad2b9ba498
|
||||
U drh
|
||||
Z 7eb9951a3a4ed42d9ed165321f9fc396
|
||||
Z 0b94093f141bb1ed6e93360cffc751d6
|
||||
|
@ -1 +1 @@
|
||||
22948fc685299ca888907eea68edb8a6e87c3f49
|
||||
8467d84fc6e67bd93051f54338a8f6c9b1711ee1
|
10
src/build.c
10
src/build.c
@ -25,7 +25,7 @@
|
||||
** ROLLBACK
|
||||
** PRAGMA
|
||||
**
|
||||
** $Id: build.c,v 1.50 2001/10/15 00:44:36 drh Exp $
|
||||
** $Id: build.c,v 1.51 2001/10/19 16:44:57 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -1449,6 +1449,14 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
}
|
||||
}else
|
||||
|
||||
if( sqliteStrICmp(zLeft, "empty_result_callbacks")==0 ){
|
||||
if( getBoolean(zRight) ){
|
||||
db->flags |= SQLITE_NullCallback;
|
||||
}else{
|
||||
db->flags &= ~SQLITE_NullCallback;
|
||||
}
|
||||
}else
|
||||
|
||||
if( sqliteStrICmp(zLeft, "table_info")==0 ){
|
||||
Table *pTab;
|
||||
Vdbe *v;
|
||||
|
10
src/select.c
10
src/select.c
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle SELECT statements in SQLite.
|
||||
**
|
||||
** $Id: select.c,v 1.41 2001/10/18 12:34:47 drh Exp $
|
||||
** $Id: select.c,v 1.42 2001/10/19 16:44:57 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -994,5 +994,13 @@ int sqliteSelect(
|
||||
generateSortTail(v, pEList->nExpr);
|
||||
}
|
||||
pParse->nTab = base;
|
||||
|
||||
|
||||
/* Issue a null callback if that is what the user wants.
|
||||
*/
|
||||
if( (pParse->db->flags & SQLITE_NullCallback)!=0 && eDest==SRT_Callback ){
|
||||
sqliteVdbeAddOp(v, OP_NullCallback, pEList->nExpr, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
10
src/shell.c
10
src/shell.c
@ -12,7 +12,7 @@
|
||||
** This file contains code to implement the "sqlite" command line
|
||||
** utility for accessing SQLite databases.
|
||||
**
|
||||
** $Id: shell.c,v 1.36 2001/10/06 16:33:03 drh Exp $
|
||||
** $Id: shell.c,v 1.37 2001/10/19 16:44:57 drh Exp $
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -244,6 +244,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
switch( p->mode ){
|
||||
case MODE_Line: {
|
||||
int w = 5;
|
||||
if( azArg==0 ) break;
|
||||
for(i=0; i<nArg; i++){
|
||||
int len = strlen(azCol[i]);
|
||||
if( len>w ) w = len;
|
||||
@ -266,7 +267,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
if( w<=0 ){
|
||||
w = strlen(azCol[i] ? azCol[i] : "");
|
||||
if( w<10 ) w = 10;
|
||||
n = strlen(azArg[i] ? azArg[i] : "");
|
||||
n = strlen(azArg && azArg[i] ? azArg[i] : "");
|
||||
if( w<n ) w = n;
|
||||
}
|
||||
if( i<ArraySize(p->actualWidth) ){
|
||||
@ -290,6 +291,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
}
|
||||
}
|
||||
}
|
||||
if( azArg==0 ) break;
|
||||
for(i=0; i<nArg; i++){
|
||||
int w;
|
||||
if( i<ArraySize(p->actualWidth) ){
|
||||
@ -309,6 +311,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
|
||||
}
|
||||
}
|
||||
if( azArg==0 ) break;
|
||||
for(i=0; i<nArg; i++){
|
||||
char *z = azArg[i];
|
||||
if( z==0 ) z = "";
|
||||
@ -342,6 +345,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
}
|
||||
fprintf(p->out,"</TR>\n");
|
||||
}
|
||||
if( azArg==0 ) break;
|
||||
fprintf(p->out,"<TR>");
|
||||
for(i=0; i<nArg; i++){
|
||||
fprintf(p->out,"<TD>");
|
||||
@ -352,6 +356,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
break;
|
||||
}
|
||||
case MODE_Insert: {
|
||||
if( azArg==0 ) break;
|
||||
fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
|
||||
for(i=0; i<nArg; i++){
|
||||
char *zSep = i>0 ? ",": "";
|
||||
@ -365,6 +370,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
}
|
||||
}
|
||||
fprintf(p->out,");\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.63 2001/10/18 12:34:47 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.64 2001/10/19 16:44:57 drh Exp $
|
||||
*/
|
||||
#include "sqlite.h"
|
||||
#include "hash.h"
|
||||
@ -166,6 +166,8 @@ struct sqlite {
|
||||
#define SQLITE_CountRows 0x00000040 /* Count rows changed by INSERT, */
|
||||
/* DELETE, or UPDATE and return */
|
||||
/* the count using a callback. */
|
||||
#define SQLITE_NullCallback 0x00000080 /* Invoke the callback once if the */
|
||||
/* result set is empty */
|
||||
|
||||
/*
|
||||
** Current file format version
|
||||
|
26
src/table.c
26
src/table.c
@ -47,7 +47,7 @@ static int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
|
||||
/* Make sure there is enough space in p->azResult to hold everything
|
||||
** we need to remember from this invocation of the callback.
|
||||
*/
|
||||
if( p->nRow==0 ){
|
||||
if( p->nRow==0 && argv!=0 ){
|
||||
p->nColumn = nCol;
|
||||
need = nCol*2;
|
||||
}else{
|
||||
@ -83,20 +83,22 @@ static int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
|
||||
|
||||
/* Copy over the row data
|
||||
*/
|
||||
for(i=0; i<nCol; i++){
|
||||
if( argv[i]==0 ){
|
||||
z = 0;
|
||||
}else{
|
||||
z = malloc( strlen(argv[i])+1 );
|
||||
if( z==0 ){
|
||||
p->rc = SQLITE_NOMEM;
|
||||
return 1;
|
||||
if( argv!=0 ){
|
||||
for(i=0; i<nCol; i++){
|
||||
if( argv[i]==0 ){
|
||||
z = 0;
|
||||
}else{
|
||||
z = malloc( strlen(argv[i])+1 );
|
||||
if( z==0 ){
|
||||
p->rc = SQLITE_NOMEM;
|
||||
return 1;
|
||||
}
|
||||
strcpy(z, argv[i]);
|
||||
}
|
||||
strcpy(z, argv[i]);
|
||||
p->azResult[p->nData++] = z;
|
||||
}
|
||||
p->azResult[p->nData++] = z;
|
||||
p->nRow++;
|
||||
}
|
||||
p->nRow++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** A TCL Interface to SQLite
|
||||
**
|
||||
** $Id: tclsqlite.c,v 1.25 2001/10/18 12:34:47 drh Exp $
|
||||
** $Id: tclsqlite.c,v 1.26 2001/10/19 16:44:57 drh Exp $
|
||||
*/
|
||||
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
|
||||
|
||||
@ -72,42 +72,44 @@ static int DbEvalCallback(
|
||||
#ifdef UTF_TRANSLATION_NEEDED
|
||||
Tcl_DString dCol;
|
||||
#endif
|
||||
if( cbData->zArray[0] ){
|
||||
if( cbData->once ){
|
||||
Tcl_SetVar2(cbData->interp, cbData->zArray, "*", "", 0);
|
||||
if( azCol==0 || (cbData->once && cbData->zArray[0]) ){
|
||||
Tcl_SetVar2(cbData->interp, cbData->zArray, "*", "", 0);
|
||||
for(i=0; i<nCol; i++){
|
||||
Tcl_SetVar2(cbData->interp, cbData->zArray, "*", azN[i],
|
||||
TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
|
||||
}
|
||||
cbData->once = 0;
|
||||
}
|
||||
if( azCol!=0 ){
|
||||
if( cbData->zArray[0] ){
|
||||
for(i=0; i<nCol; i++){
|
||||
Tcl_SetVar2(cbData->interp, cbData->zArray, "*", azN[i],
|
||||
TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
|
||||
char *z = azCol[i];
|
||||
if( z==0 ) z = "";
|
||||
#ifdef UTF_TRANSLATION_NEEDED
|
||||
Tcl_DStringInit(&dCol);
|
||||
Tcl_ExternalToUtfDString(NULL, z, -1, &dCol);
|
||||
Tcl_SetVar2(cbData->interp, cbData->zArray, azN[i],
|
||||
Tcl_DStringValue(&dCol), 0);
|
||||
Tcl_DStringFree(&dCol);
|
||||
#else
|
||||
Tcl_SetVar2(cbData->interp, cbData->zArray, azN[i], z, 0);
|
||||
#endif
|
||||
}
|
||||
}else{
|
||||
for(i=0; i<nCol; i++){
|
||||
char *z = azCol[i];
|
||||
if( z==0 ) z = "";
|
||||
#ifdef UTF_TRANSLATION_NEEDED
|
||||
Tcl_DStringInit(&dCol);
|
||||
Tcl_ExternalToUtfDString(NULL, z, -1, &dCol);
|
||||
Tcl_SetVar(cbData->interp, azN[i], Tcl_DStringValue(&dCol), 0);
|
||||
Tcl_DStringFree(&dCol);
|
||||
#else
|
||||
Tcl_SetVar(cbData->interp, azN[i], z, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
for(i=0; i<nCol; i++){
|
||||
char *z = azCol[i];
|
||||
if( z==0 ) z = "";
|
||||
#ifdef UTF_TRANSLATION_NEEDED
|
||||
Tcl_DStringInit(&dCol);
|
||||
Tcl_ExternalToUtfDString(NULL, z, -1, &dCol);
|
||||
Tcl_SetVar2(cbData->interp, cbData->zArray, azN[i],
|
||||
Tcl_DStringValue(&dCol), 0);
|
||||
Tcl_DStringFree(&dCol);
|
||||
#else
|
||||
Tcl_SetVar2(cbData->interp, cbData->zArray, azN[i], z, 0);
|
||||
#endif
|
||||
}
|
||||
}else{
|
||||
for(i=0; i<nCol; i++){
|
||||
char *z = azCol[i];
|
||||
if( z==0 ) z = "";
|
||||
#ifdef UTF_TRANSLATION_NEEDED
|
||||
Tcl_DStringInit(&dCol);
|
||||
Tcl_ExternalToUtfDString(NULL, z, -1, &dCol);
|
||||
Tcl_SetVar(cbData->interp, azN[i], Tcl_DStringValue(&dCol), 0);
|
||||
Tcl_DStringFree(&dCol);
|
||||
#else
|
||||
Tcl_SetVar(cbData->interp, azN[i], z, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
cbData->once = 0;
|
||||
rc = Tcl_EvalObj(cbData->interp, cbData->pCode);
|
||||
if( rc==TCL_CONTINUE ) rc = TCL_OK;
|
||||
cbData->tcl_rc = rc;
|
||||
@ -128,6 +130,7 @@ static int DbEvalCallback2(
|
||||
){
|
||||
Tcl_Obj *pList = (Tcl_Obj*)clientData;
|
||||
int i;
|
||||
if( azCol==0 ) return 0;
|
||||
for(i=0; i<nCol; i++){
|
||||
Tcl_Obj *pElem;
|
||||
if( azCol[i] && *azCol[i] ){
|
||||
|
@ -15,7 +15,7 @@
|
||||
** individual tokens and sends those tokens one-by-one over to the
|
||||
** parser for analysis.
|
||||
**
|
||||
** $Id: tokenize.c,v 1.28 2001/10/18 12:34:48 drh Exp $
|
||||
** $Id: tokenize.c,v 1.29 2001/10/19 16:44:57 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -331,7 +331,7 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){
|
||||
break;
|
||||
}
|
||||
for(i=1; isIdChar[z[i]]; i++){}
|
||||
*tokenType = sqliteKeywordCode(z, i);
|
||||
*tokenType = sqliteKeywordCode((char*)z, i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
55
src/vdbe.c
55
src/vdbe.c
@ -30,7 +30,7 @@
|
||||
** But other routines are also provided to help in building up
|
||||
** a program instruction by instruction.
|
||||
**
|
||||
** $Id: vdbe.c,v 1.86 2001/10/18 12:34:48 drh Exp $
|
||||
** $Id: vdbe.c,v 1.87 2001/10/19 16:44:57 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -202,6 +202,7 @@ struct Vdbe {
|
||||
int nSet; /* Number of sets allocated */
|
||||
Set *aSet; /* An array of sets */
|
||||
int nFetch; /* Number of OP_Fetch instructions executed */
|
||||
int nCallback; /* Number of callbacks invoked so far */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -811,17 +812,17 @@ static char *zOpName[] = { 0,
|
||||
"AggGet", "SetInsert", "SetFound", "SetNotFound",
|
||||
"SetClear", "MakeRecord", "MakeKey", "MakeIdxKey",
|
||||
"Goto", "If", "Halt", "ColumnCount",
|
||||
"ColumnName", "Callback", "Integer", "String",
|
||||
"Null", "Pop", "Dup", "Pull",
|
||||
"Add", "AddImm", "Subtract", "Multiply",
|
||||
"Divide", "Remainder", "BitAnd", "BitOr",
|
||||
"BitNot", "ShiftLeft", "ShiftRight", "AbsValue",
|
||||
"Precision", "Min", "Max", "Like",
|
||||
"Glob", "Eq", "Ne", "Lt",
|
||||
"Le", "Gt", "Ge", "IsNull",
|
||||
"NotNull", "Negative", "And", "Or",
|
||||
"Not", "Concat", "Noop", "Strlen",
|
||||
"Substr",
|
||||
"ColumnName", "Callback", "NullCallback", "Integer",
|
||||
"String", "Null", "Pop", "Dup",
|
||||
"Pull", "Add", "AddImm", "Subtract",
|
||||
"Multiply", "Divide", "Remainder", "BitAnd",
|
||||
"BitOr", "BitNot", "ShiftLeft", "ShiftRight",
|
||||
"AbsValue", "Precision", "Min", "Max",
|
||||
"Like", "Glob", "Eq", "Ne",
|
||||
"Lt", "Le", "Gt", "Ge",
|
||||
"IsNull", "NotNull", "Negative", "And",
|
||||
"Or", "Not", "Concat", "Noop",
|
||||
"Strlen", "Substr",
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1194,6 +1195,7 @@ case OP_ColumnCount: {
|
||||
p->azColName = sqliteRealloc(p->azColName, (pOp->p1+1)*sizeof(char*));
|
||||
if( p->azColName==0 ) goto no_mem;
|
||||
p->azColName[pOp->p1] = 0;
|
||||
p->nCallback = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1207,6 +1209,7 @@ case OP_ColumnCount: {
|
||||
*/
|
||||
case OP_ColumnName: {
|
||||
p->azColName[pOp->p1] = pOp->p3 ? pOp->p3 : "";
|
||||
p->nCallback = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1231,11 +1234,38 @@ case OP_Callback: {
|
||||
if( xCallback(pArg, pOp->p1, &zStack[i], p->azColName)!=0 ){
|
||||
rc = SQLITE_ABORT;
|
||||
}
|
||||
p->nCallback++;
|
||||
}
|
||||
PopStack(p, pOp->p1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: NullCallback P1 * *
|
||||
**
|
||||
** Invoke the callback function once with the 2nd argument (the
|
||||
** number of columns) equal to P1 and with the 4th argument (the
|
||||
** names of the columns) set according to prior OP_ColumnName and
|
||||
** OP_ColumnCount instructions. This is all like the regular
|
||||
** OP_Callback or OP_SortCallback opcodes. But the 3rd argument
|
||||
** which normally contains a pointer to an array of pointers to
|
||||
** data is NULL.
|
||||
**
|
||||
** The callback is only invoked if there have been no prior calls
|
||||
** to OP_Callback or OP_SortCallback.
|
||||
**
|
||||
** This opcode is used to report the number and names of columns
|
||||
** in cases where the result set is empty.
|
||||
*/
|
||||
case OP_NullCallback: {
|
||||
if( xCallback!=0 && p->nCallback==0 ){
|
||||
if( xCallback(pArg, pOp->p1, 0, p->azColName)!=0 ){
|
||||
rc = SQLITE_ABORT;
|
||||
}
|
||||
p->nCallback++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Concat P1 P2 P3
|
||||
**
|
||||
** Look at the first P1 elements of the stack. Append them all
|
||||
@ -3376,6 +3406,7 @@ case OP_SortCallback: {
|
||||
if( xCallback(pArg, pOp->p1, (char**)zStack[i], p->azColName) ){
|
||||
rc = SQLITE_ABORT;
|
||||
}
|
||||
p->nCallback++;
|
||||
}
|
||||
POPSTACK;
|
||||
break;
|
||||
|
83
src/vdbe.h
83
src/vdbe.h
@ -15,7 +15,7 @@
|
||||
** or VDBE. The VDBE implements an abstract machine that runs a
|
||||
** simple program to access and modify the underlying database.
|
||||
**
|
||||
** $Id: vdbe.h,v 1.29 2001/10/13 02:59:09 drh Exp $
|
||||
** $Id: vdbe.h,v 1.30 2001/10/19 16:44:57 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITE_VDBE_H_
|
||||
#define _SQLITE_VDBE_H_
|
||||
@ -155,50 +155,51 @@ typedef struct VdbeOp VdbeOp;
|
||||
#define OP_ColumnCount 72
|
||||
#define OP_ColumnName 73
|
||||
#define OP_Callback 74
|
||||
#define OP_NullCallback 75
|
||||
|
||||
#define OP_Integer 75
|
||||
#define OP_String 76
|
||||
#define OP_Null 77
|
||||
#define OP_Pop 78
|
||||
#define OP_Dup 79
|
||||
#define OP_Pull 80
|
||||
#define OP_Integer 76
|
||||
#define OP_String 77
|
||||
#define OP_Null 78
|
||||
#define OP_Pop 79
|
||||
#define OP_Dup 80
|
||||
#define OP_Pull 81
|
||||
|
||||
#define OP_Add 81
|
||||
#define OP_AddImm 82
|
||||
#define OP_Subtract 83
|
||||
#define OP_Multiply 84
|
||||
#define OP_Divide 85
|
||||
#define OP_Remainder 86
|
||||
#define OP_BitAnd 87
|
||||
#define OP_BitOr 88
|
||||
#define OP_BitNot 89
|
||||
#define OP_ShiftLeft 90
|
||||
#define OP_ShiftRight 91
|
||||
#define OP_AbsValue 92
|
||||
#define OP_Precision 93
|
||||
#define OP_Min 94
|
||||
#define OP_Max 95
|
||||
#define OP_Like 96
|
||||
#define OP_Glob 97
|
||||
#define OP_Eq 98
|
||||
#define OP_Ne 99
|
||||
#define OP_Lt 100
|
||||
#define OP_Le 101
|
||||
#define OP_Gt 102
|
||||
#define OP_Ge 103
|
||||
#define OP_IsNull 104
|
||||
#define OP_NotNull 105
|
||||
#define OP_Negative 106
|
||||
#define OP_And 107
|
||||
#define OP_Or 108
|
||||
#define OP_Not 109
|
||||
#define OP_Concat 110
|
||||
#define OP_Noop 111
|
||||
#define OP_Add 82
|
||||
#define OP_AddImm 83
|
||||
#define OP_Subtract 84
|
||||
#define OP_Multiply 85
|
||||
#define OP_Divide 86
|
||||
#define OP_Remainder 87
|
||||
#define OP_BitAnd 88
|
||||
#define OP_BitOr 89
|
||||
#define OP_BitNot 90
|
||||
#define OP_ShiftLeft 91
|
||||
#define OP_ShiftRight 92
|
||||
#define OP_AbsValue 93
|
||||
#define OP_Precision 94
|
||||
#define OP_Min 95
|
||||
#define OP_Max 96
|
||||
#define OP_Like 97
|
||||
#define OP_Glob 98
|
||||
#define OP_Eq 99
|
||||
#define OP_Ne 100
|
||||
#define OP_Lt 101
|
||||
#define OP_Le 102
|
||||
#define OP_Gt 103
|
||||
#define OP_Ge 104
|
||||
#define OP_IsNull 105
|
||||
#define OP_NotNull 106
|
||||
#define OP_Negative 107
|
||||
#define OP_And 108
|
||||
#define OP_Or 109
|
||||
#define OP_Not 110
|
||||
#define OP_Concat 111
|
||||
#define OP_Noop 112
|
||||
|
||||
#define OP_Strlen 112
|
||||
#define OP_Substr 113
|
||||
#define OP_Strlen 113
|
||||
#define OP_Substr 114
|
||||
|
||||
#define OP_MAX 113
|
||||
#define OP_MAX 114
|
||||
|
||||
/*
|
||||
** Prototypes for the VDBE interface. See comments on the implementation
|
||||
|
@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the SELECT statement.
|
||||
#
|
||||
# $Id: select1.test,v 1.13 2001/10/18 12:34:48 drh Exp $
|
||||
# $Id: select1.test,v 1.14 2001/10/19 16:44:58 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -414,4 +414,36 @@ do_test select1-8.5 {
|
||||
}
|
||||
} {1 -3 1 -3}
|
||||
|
||||
|
||||
# Check the behavior when the result set is empty
|
||||
#
|
||||
do_test select1-9.1 {
|
||||
catch {unset r}
|
||||
set r(*) {}
|
||||
db eval {SELECT * FROM test1 WHERE f1<0} r {}
|
||||
set r(*)
|
||||
} {}
|
||||
do_test select1-9.2 {
|
||||
execsql {PRAGMA empty_result_callbacks=on}
|
||||
set r(*) {}
|
||||
db eval {SELECT * FROM test1 WHERE f1<0} r {}
|
||||
set r(*)
|
||||
} {f1 f2}
|
||||
do_test select1-9.3 {
|
||||
set r(*) {}
|
||||
db eval {SELECT * FROM test1 WHERE f1<(select count(*) from test2)} r {}
|
||||
set r(*)
|
||||
} {f1 f2}
|
||||
do_test select1-9.4 {
|
||||
set r(*) {}
|
||||
db eval {SELECT * FROM test1 ORDER BY f1} r {}
|
||||
set r(*)
|
||||
} {f1 f2}
|
||||
do_test select1-9.5 {
|
||||
set r(*) {}
|
||||
db eval {SELECT * FROM test1 WHERE f1<0 ORDER BY f1} r {}
|
||||
set r(*)
|
||||
} {f1 f2}
|
||||
unset r
|
||||
|
||||
finish_test
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this Tcl script to generate the sqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: c_interface.tcl,v 1.17 2001/10/12 17:30:05 drh Exp $}
|
||||
set rcsid {$Id: c_interface.tcl,v 1.18 2001/10/19 16:44:58 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@ -20,7 +20,7 @@ puts {
|
||||
a C or C++ program. This document gives an overview of the C/C++
|
||||
programming interface.</p>
|
||||
|
||||
<h2>The API</h2>
|
||||
<h2>The Core API</h2>
|
||||
|
||||
<p>The interface to the SQLite library consists of three core functions,
|
||||
one opaque data structure, and some constants used as return values.
|
||||
@ -28,6 +28,7 @@ The core interface is as follows:</p>
|
||||
|
||||
<blockquote><pre>
|
||||
typedef struct sqlite sqlite;
|
||||
#define SQLITE_OK 0 /* Successful result */
|
||||
|
||||
sqlite *sqlite_open(const char *dbname, int mode, char **errmsg);
|
||||
|
||||
@ -40,101 +41,14 @@ int sqlite_exec(
|
||||
void*,
|
||||
char **errmsg
|
||||
);
|
||||
|
||||
#define SQLITE_OK 0 /* Successful result */
|
||||
#define SQLITE_ERROR 1 /* SQL error or missing database */
|
||||
#define SQLITE_INTERNAL 2 /* An internal logic error in SQLite */
|
||||
#define SQLITE_PERM 3 /* Access permission denied */
|
||||
#define SQLITE_ABORT 4 /* Callback routine requested an abort */
|
||||
#define SQLITE_BUSY 5 /* The database file is locked */
|
||||
#define SQLITE_LOCKED 6 /* A table in the database is locked */
|
||||
#define SQLITE_NOMEM 7 /* A malloc() failed */
|
||||
#define SQLITE_READONLY 8 /* Attempt to write a readonly database */
|
||||
#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite_interrupt() */
|
||||
#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
|
||||
#define SQLITE_CORRUPT 11 /* The database disk image is malformed */
|
||||
#define SQLITE_NOTFOUND 12 /* (Internal Only) Table or record not found */
|
||||
#define SQLITE_FULL 13 /* Insertion failed because database is full */
|
||||
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
|
||||
#define SQLITE_PROTOCOL 15 /* Database lock protocol error */
|
||||
#define SQLITE_EMPTY 16 /* (Internal Only) Database table is empty */
|
||||
#define SQLITE_SCHEMA 17 /* The database schema changed */
|
||||
#define SQLITE_TOOBIG 18 /* Too much data for one row of a table */
|
||||
#define SQLITE_CONSTRAINT 19 /* Abort due to contraint violation */
|
||||
</pre></blockquote>
|
||||
|
||||
<p>Only the three core routines shown above are required to use
|
||||
SQLite. But there are many other functions that provide
|
||||
useful interfaces. These extended routines are as follows:
|
||||
<p>
|
||||
The above is all you really need to know in order to use SQLite
|
||||
in your C or C++ programs. There are other convenience functions
|
||||
available (and described below) but we will begin by describing
|
||||
the core functions shown above.
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
int sqlite_get_table(
|
||||
sqlite*,
|
||||
char *sql,
|
||||
char ***result,
|
||||
int *nrow,
|
||||
int *ncolumn,
|
||||
char **errmsg
|
||||
);
|
||||
|
||||
void sqlite_free_table(char**);
|
||||
|
||||
void sqlite_interrupt(sqlite*);
|
||||
|
||||
int sqlite_complete(const char *sql);
|
||||
|
||||
void sqlite_busy_handler(sqlite*, int (*)(void*,const char*,int), void*);
|
||||
|
||||
void sqlite_busy_timeout(sqlite*, int ms);
|
||||
|
||||
const char sqlite_version[];
|
||||
|
||||
const char sqlite_encoding[];
|
||||
|
||||
int sqlite_exec_printf(
|
||||
sqlite*,
|
||||
char *sql,
|
||||
int (*)(void*,int,char**,char**),
|
||||
void*,
|
||||
char **errmsg,
|
||||
...
|
||||
);
|
||||
|
||||
int sqlite_exec_vprintf(
|
||||
sqlite*,
|
||||
char *sql,
|
||||
int (*)(void*,int,char**,char**),
|
||||
void*,
|
||||
char **errmsg,
|
||||
va_list
|
||||
);
|
||||
|
||||
int sqlite_get_table_printf(
|
||||
sqlite*,
|
||||
char *sql,
|
||||
char ***result,
|
||||
int *nrow,
|
||||
int *ncolumn,
|
||||
char **errmsg,
|
||||
...
|
||||
);
|
||||
|
||||
int sqlite_get_table_vprintf(
|
||||
sqlite*,
|
||||
char *sql,
|
||||
char ***result,
|
||||
int *nrow,
|
||||
int *ncolumn,
|
||||
char **errmsg,
|
||||
va_list
|
||||
);
|
||||
|
||||
</pre></blockquote>
|
||||
|
||||
<p>All of the above definitions are included in the "sqlite.h"
|
||||
header file that comes in the source tree.</p>
|
||||
|
||||
<h2>Opening a database</h2>
|
||||
|
||||
<p>Use the <b>sqlite_open()</b> function to open an existing SQLite
|
||||
@ -225,13 +139,57 @@ argv[i] == 0
|
||||
</pre></blockquote>
|
||||
<p>The names of the columns are contained in the fourth argument.</p>
|
||||
|
||||
<p>If the EMPTY_RESULT_CALLBACKS pragma is set to ON and the result of
|
||||
a query is an empty set, then the callback is invoked once with the
|
||||
third parameter (argv) set to 0. In other words
|
||||
<blockquote><pre>
|
||||
argv == 0
|
||||
</pre></blockquote>
|
||||
The second parameter (argc)
|
||||
and the fourth parameter (columnNames) are still valid
|
||||
and can be used to determine the number and names of the result
|
||||
columns if there had been a result.
|
||||
The default behavior is not to invoke the callback at all if the
|
||||
result set is empty.</p>
|
||||
|
||||
<p>The callback function should normally return 0. If the callback
|
||||
function returns non-zero, the query is immediately aborted and
|
||||
<b>sqlite_exec()</b> will return SQLITE_ABORT.</p>
|
||||
|
||||
<p>The <b>sqlite_exec()</b> function returns an integer to indicate
|
||||
success or failure of the operation. The following are possible
|
||||
return values:</p>
|
||||
<h2>Error Codes</h2>
|
||||
|
||||
<p>
|
||||
The <b>sqlite_exec()</b> function normally returns SQLITE_OK. But
|
||||
if something goes wrong it can return a different value to indicate
|
||||
the type of error. Here is a complete list of the return codes:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
#define SQLITE_OK 0 /* Successful result */
|
||||
#define SQLITE_ERROR 1 /* SQL error or missing database */
|
||||
#define SQLITE_INTERNAL 2 /* An internal logic error in SQLite */
|
||||
#define SQLITE_PERM 3 /* Access permission denied */
|
||||
#define SQLITE_ABORT 4 /* Callback routine requested an abort */
|
||||
#define SQLITE_BUSY 5 /* The database file is locked */
|
||||
#define SQLITE_LOCKED 6 /* A table in the database is locked */
|
||||
#define SQLITE_NOMEM 7 /* A malloc() failed */
|
||||
#define SQLITE_READONLY 8 /* Attempt to write a readonly database */
|
||||
#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite_interrupt() */
|
||||
#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
|
||||
#define SQLITE_CORRUPT 11 /* The database disk image is malformed */
|
||||
#define SQLITE_NOTFOUND 12 /* (Internal Only) Table or record not found */
|
||||
#define SQLITE_FULL 13 /* Insertion failed because database is full */
|
||||
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
|
||||
#define SQLITE_PROTOCOL 15 /* Database lock protocol error */
|
||||
#define SQLITE_EMPTY 16 /* (Internal Only) Database table is empty */
|
||||
#define SQLITE_SCHEMA 17 /* The database schema changed */
|
||||
#define SQLITE_TOOBIG 18 /* Too much data for one row of a table */
|
||||
#define SQLITE_CONSTRAINT 19 /* Abort due to contraint violation */
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The meanings of these various return values are as follows:
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<dl>
|
||||
@ -332,6 +290,80 @@ a database constraint.
|
||||
</dl>
|
||||
</blockquote>
|
||||
|
||||
<h2>The Extended API</h2>
|
||||
|
||||
<p>Only the three core routines shown above are required to use
|
||||
SQLite. But there are many other functions that provide
|
||||
useful interfaces. These extended routines are as follows:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
int sqlite_get_table(
|
||||
sqlite*,
|
||||
char *sql,
|
||||
char ***result,
|
||||
int *nrow,
|
||||
int *ncolumn,
|
||||
char **errmsg
|
||||
);
|
||||
|
||||
void sqlite_free_table(char**);
|
||||
|
||||
void sqlite_interrupt(sqlite*);
|
||||
|
||||
int sqlite_complete(const char *sql);
|
||||
|
||||
void sqlite_busy_handler(sqlite*, int (*)(void*,const char*,int), void*);
|
||||
|
||||
void sqlite_busy_timeout(sqlite*, int ms);
|
||||
|
||||
const char sqlite_version[];
|
||||
|
||||
const char sqlite_encoding[];
|
||||
|
||||
int sqlite_exec_printf(
|
||||
sqlite*,
|
||||
char *sql,
|
||||
int (*)(void*,int,char**,char**),
|
||||
void*,
|
||||
char **errmsg,
|
||||
...
|
||||
);
|
||||
|
||||
int sqlite_exec_vprintf(
|
||||
sqlite*,
|
||||
char *sql,
|
||||
int (*)(void*,int,char**,char**),
|
||||
void*,
|
||||
char **errmsg,
|
||||
va_list
|
||||
);
|
||||
|
||||
int sqlite_get_table_printf(
|
||||
sqlite*,
|
||||
char *sql,
|
||||
char ***result,
|
||||
int *nrow,
|
||||
int *ncolumn,
|
||||
char **errmsg,
|
||||
...
|
||||
);
|
||||
|
||||
int sqlite_get_table_vprintf(
|
||||
sqlite*,
|
||||
char *sql,
|
||||
char ***result,
|
||||
int *nrow,
|
||||
int *ncolumn,
|
||||
char **errmsg,
|
||||
va_list
|
||||
);
|
||||
|
||||
</pre></blockquote>
|
||||
|
||||
<p>All of the above definitions are included in the "sqlite.h"
|
||||
header file that comes in the source tree.</p>
|
||||
|
||||
<h2>Querying without using a callback function</h2>
|
||||
|
||||
<p>The <b>sqlite_get_table()</b> function is a wrapper around
|
||||
@ -375,10 +407,46 @@ result[8] = "zadok"
|
||||
<p>Notice that the "host" value for the "dummy" record is NULL so
|
||||
the result[] array contains a NULL pointer at that slot.</p>
|
||||
|
||||
<p>If the result set of a query is empty, then by default
|
||||
<b>sqlite_get_table()</b> will set nrow to 0 and leave its
|
||||
result parameter is set to NULL. But if the EMPTY_RESULT_CALLBACKS
|
||||
pragma is ON then the result parameter is initialized to the names
|
||||
of the columns only. For example, consider this query which has
|
||||
an empty result set:</p>
|
||||
|
||||
<blockquote>
|
||||
SELECT employee_name, login, host FROM users WHERE employee_name IS NULL;
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
The default behavior gives this results:
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
nrow = 0<br>
|
||||
ncolumn = 0<br>
|
||||
result = 0<br>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
But if the EMPTY_RESULT_CALLBACKS pragma is ON, then the following
|
||||
is returned:
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
nrow = 0<br>
|
||||
ncolumn = 3<br>
|
||||
result[0] = "employee_name"<br>
|
||||
result[1] = "login"<br>
|
||||
result[2] = "host"<br>
|
||||
</blockquote>
|
||||
|
||||
<p>Memory to hold the information returned by <b>sqlite_get_table()</b>
|
||||
is obtained from malloc(). But the calling function should not try
|
||||
to free this information directly. Instead, pass the complete table
|
||||
to <b>sqlite_free_table()</b> when the table is no longer needed.</p>
|
||||
to <b>sqlite_free_table()</b> when the table is no longer needed.
|
||||
It is safe to call <b>sqlite_free_table()</b> will a NULL pointer such
|
||||
as would be returned if the result set is empty.</p>
|
||||
|
||||
<p>The <b>sqlite_get_table()</b> routine returns the same integer
|
||||
result code as <b>sqlite_exec()</b>.</p>
|
||||
|
@ -17,7 +17,8 @@ proc chng {date desc} {
|
||||
puts "<DD><P><UL>$desc</UL></P></DD>"
|
||||
}
|
||||
|
||||
chng {2001 Oct ?? (2.0.6)} {
|
||||
chng {2001 Oct 19 (2.0.6)} {
|
||||
<li>Added the EMPTY_RESULT_CALLBACKS pragma</li>
|
||||
<li>Support for UTF-8 and ISO8859 characters in column and table names.</li>
|
||||
<li>Bug fix: Compute correct table names with the FULL_COLUMN_NAMES pragma
|
||||
is turned on.</li>
|
||||
|
12
www/lang.tcl
12
www/lang.tcl
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this Tcl script to generate the sqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: lang.tcl,v 1.13 2001/10/15 00:44:36 drh Exp $}
|
||||
set rcsid {$Id: lang.tcl,v 1.14 2001/10/19 16:44:58 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@ -637,6 +637,16 @@ with caution.</p>
|
||||
be invoked once for each DELETE, INSERT, or UPDATE operation. The
|
||||
argument is the number of rows that were changed.</p>
|
||||
|
||||
<li><p><b>PRAGMA empty_result_callbacks = ON;
|
||||
<br>PRAGMA empty_result_callbacks = OFF;</b></p>
|
||||
<p>When on, the EMPTY_RESULT_CALLBACKS pragma causes the callback
|
||||
function to be invoked once for each query that has an empty result
|
||||
set. The third "<b>argv</b>" parameter to the callback is set to NULL
|
||||
because there is no data to report. But the second "<b>argc</b>" and
|
||||
fourth "<b>columnNames</b>" parameters are valid and can be used to
|
||||
determine the number and names of the columns that would have been in
|
||||
the result set had the set not been empty.</p>
|
||||
|
||||
<li><p><b>PRAGMA full_column_names = ON;
|
||||
<br>PRAGMA full_column_names = OFF;</b></p>
|
||||
<p>The column names reported in an SQLite callback are normally just
|
||||
|
Loading…
x
Reference in New Issue
Block a user