mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Added support for the COUNT_CHANGES pragma in order to help out the
ODBC driver. Fixed a but on count(*) when applied to empty tables. (CVS 289) FossilOrigin-Name: 747bf1b30b74cfd0e9c27e7c0bc5172637f35520
This commit is contained in:
@@ -58,6 +58,7 @@ EXE =
|
||||
#
|
||||
TCC = gcc -O6
|
||||
#TCC = gcc -g -O0 -Wall
|
||||
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
|
||||
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
|
||||
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
|
||||
|
||||
|
44
manifest
44
manifest
@@ -1,9 +1,9 @@
|
||||
C Version\s2.0.4\s(CVS\s466)
|
||||
D 2001-10-13T22:00:00
|
||||
C Added\ssupport\sfor\sthe\sCOUNT_CHANGES\spragma\sin\sorder\sto\shelp\sout\sthe\nODBC\sdriver.\s\sFixed\sa\sbut\son\scount(*)\swhen\sapplied\sto\sempty\stables.\s(CVS\s289)
|
||||
D 2001-10-15T00:44:35
|
||||
F Makefile.in 6801df952cb1df64aa32e4de85fed24511d28efd
|
||||
F Makefile.template 582916b263aa40a70521dfb3d99d574028abd47b
|
||||
F Makefile.template 1fdb891f14083ee0b63cf7282f91529634438e7a
|
||||
F README 93d2977cc5c6595c448de16bdefc312b9d401533
|
||||
F VERSION 930f436b9878b6b1a49f546e86a54c17df3e0ca9
|
||||
F VERSION e14d2010c343ae28a0dd038c3850eae3a88a9307
|
||||
F aclocal.m4 11faa843caa38fd451bc6aeb43e248d1723a269d
|
||||
F config.guess f38b1e93d1e0fa6f5a6913e9e7b12774b9232588
|
||||
F config.log 6a73d03433669b10a3f0c221198c3f26b9413914
|
||||
@@ -19,35 +19,35 @@ F libtool c56e618713c9510a103bda6b95f3ea3900dcacd6
|
||||
F ltmain.sh e9ed72eb1d690f447c13945eaf69e28af531eda1
|
||||
F publish.sh badcd69b8e3a8bc69b162c4c9d7c209b2a0b119e
|
||||
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
||||
F src/btree.c 7e9c33a714ed1630562f89ad19847f5f28bd6d4d
|
||||
F src/btree.c 97653e88bc4b7396226b93c878b153c77f1d3d03
|
||||
F src/btree.h 57d653ef5137b91f2a068aaf71a2905468dd2cb7
|
||||
F src/build.c 9c3e3634b20c358e538f33f5ae125667e65447b2
|
||||
F src/delete.c bed54503368e0976aa2e8487d8914e7b7fb63aae
|
||||
F src/build.c fe71d516148226bd6249403e82f8d07129206489
|
||||
F src/delete.c 6fe2191c49c4a31336e2fac11b3ad665ddcd4246
|
||||
F src/expr.c c1381b8229a5573b0928ede962e45c1c49d067af
|
||||
F src/hash.c b7ced0735287c142a3b2db46c3cae3e6826afb75
|
||||
F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac
|
||||
F src/insert.c ae283e85a301bb3cd6af955f62bde1ca4ba4b56d
|
||||
F src/insert.c b65c1d4b848e45d41e9dcccd2b226ca335de67b6
|
||||
F src/main.c 9a18e97290d41844e8c12e021fb7c42948a19dc9
|
||||
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
||||
F src/os.c cece4ac6cabc9d377ef0a4ab4c16f6f0f6c84377
|
||||
F src/os.c 886bdd6c1dff71116f688e8b736d82e43e7ac9ed
|
||||
F src/os.h bed702c9e3b768bc3cb1b12c90b83d099c1546be
|
||||
F src/pager.c e2e189a15e230c60e811f5e2ab25e68ae41c90be
|
||||
F src/pager.h a0d4c5ae271914aa07b62aee0707997d6932b6ca
|
||||
F src/parse.y 148e4cd134d3cbd816dcb0df50e49e498faa6ba4
|
||||
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
|
||||
F src/random.c 2a9cc2c9716d14815fd4c2accf89d87a1143e46b
|
||||
F src/select.c ff4dc2271bb6de7a94f22e651be4d29b4f24ff3f
|
||||
F src/select.c 75bb3ca7fd42f7c6d86fc565688e7834587a9f0d
|
||||
F src/shell.c cb8c41f1b2173efd212dab3f35f1fc6bf32ead76
|
||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||
F src/sqlite.h.in b95c161abf1d58bceb05290fa3f657d8f388fc11
|
||||
F src/sqliteInt.h 5d6a79c70bdd9f993958c9c4a7970079fda495dd
|
||||
F src/sqliteInt.h 04bfa79fcf6ade1961f6e3b9dc679a63be25cbd7
|
||||
F src/table.c abd0adbe0fee39d995287b3bcccd908d174dfcac
|
||||
F src/tclsqlite.c 765599686c19ed777ac379928d732c8bfc63ebac
|
||||
F src/test1.c e4b31f62ea71963cbae44338acf477a04fc8fc49
|
||||
F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321
|
||||
F src/test3.c 4a0d7b882fdae731dbb759f512ad867122452f96
|
||||
F src/tokenize.c c3fcb76a41a22803b6060bddb5fbadc80bbe309c
|
||||
F src/update.c 0b287faf0cc1d2bfa437f8a54061dd12ae6df91d
|
||||
F src/update.c c916182c6bfbc8a6f20c24920c4560fece6c9569
|
||||
F src/util.c 4da3be37d0fd3c640d2d3033503768afdc8e5387
|
||||
F src/vdbe.c 0f8ea6ca59f0899e9e0d71a81c0bf46110447cf6
|
||||
F src/vdbe.h 86fc2ef42f48024c9a2e1b7fb01eda22b65a5295
|
||||
@@ -57,13 +57,13 @@ F test/bigrow.test a35f2de9948b24e427fb292c35947795efe182d0
|
||||
F test/btree.test 47952c7a0c22660566264c68c0664592b7da85ce
|
||||
F test/btree2.test 20ce47ab804f15b6563736528bdd38aabe5193dc
|
||||
F test/copy.test 768e6f1701a07d08090e1ca7f7dcce0a7a72b43e
|
||||
F test/delete.test 5ebb114582457428b3e0e30b21b477fedcb85609
|
||||
F test/delete.test c904a62129fe102b314a96111a8417f10249e4d8
|
||||
F test/expr.test b4171c84b767f7b7e94dbce4824ba8e981a1c72f
|
||||
F test/func.test fb0f44de6d8487359a4455accbae120bde267772
|
||||
F test/in.test 9323681388be301dc73f370b4cd62c5a33f79d1e
|
||||
F test/index.test 6076f29d09a4f26a2efa38b03b8cc338b8662f0e
|
||||
F test/insert.test a5c122aa726f1cef6f07d6767e8fd6f220994c11
|
||||
F test/insert2.test 252d7130d8cc20f649b31a4f503cd87e660abda8
|
||||
F test/insert2.test d6901ca931e308fea7fca8c95ebe7dc957cc9fc2
|
||||
F test/ioerr.test 57d9bffaca18b34f9e976f786eadc2591d6efc6a
|
||||
F test/lock.test 19593689260c419efe7ced55b1418653a4b7bcd1
|
||||
F test/main.test 1626345b5f630c5398eede500d9354813b76b0fd
|
||||
@@ -74,11 +74,11 @@ F test/printf.test 3cb415073754cb8ff076f26173143c3cd293a9da
|
||||
F test/quick.test b6ec50f808efc06595fd324bf4f3fabadb9c7e9c
|
||||
F test/quote.test 286db944717afa9a9bf829dd85e59185c65d5435
|
||||
F test/rowid.test 427bfbbe9684fe7a2f851aa05badaae6d4972ce8
|
||||
F test/select1.test b59e8c713277d7545f5b6e782e6223e51fea45a5
|
||||
F test/select1.test 5f47445fa3a033e02e1b07e4fcd4f142e5a46403
|
||||
F test/select2.test f91c903e2bab0e9d45274855a981eebf846d5e32
|
||||
F test/select3.test 5e1fe8e5a4e63fb2827ab3b89527e0fd4ae35259
|
||||
F test/select4.test 29a2ffb187f3d8b6ca42a0a6b619e9cabe12e228
|
||||
F test/select5.test 00a240e3311b6c4ff0f27a252ad33811211fa8d8
|
||||
F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
|
||||
F test/sort.test 462c1161eee1abaa7cc93990e0b34d5fdb70ce19
|
||||
F test/subselect.test 335d3dad8d585726c447dfee8d9c4f7383c76b78
|
||||
F test/table.test 3ef4254d62ece31a3872ab11cdaec846f6fa8fd1
|
||||
@@ -88,7 +88,7 @@ F test/temptable.test 37acd9e39781c2ff7cff2ba741b6b27ce020a44a
|
||||
F test/tester.tcl c7ddeebc14cc841abb37134cd5d40c1e3ad367c1
|
||||
F test/trans.test 855337b8a178c73c433fcf8ee88e4b2f5efff0d9
|
||||
F test/unique.test ef1f67607a7109e9c0842cd8557550fb121d7ec6
|
||||
F test/update.test b320ea22899e80b32b4d21c54591eb7a6ba4d6bd
|
||||
F test/update.test 8cf76467d46b1650539763c95d5208340c61d561
|
||||
F test/vacuum.test 8acf8669f3b627e54149b25165b034aa06c2432e
|
||||
F test/where.test 43d5ac94da3f3722375307f948884dc79b326a91
|
||||
F tool/lemon.c 5533b63e5cdbb1efc939abac3c2f4f37ac839488
|
||||
@@ -102,19 +102,19 @@ 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 5407ebb20a046f1f12dd4b8acd23c135f8e45f91
|
||||
F www/changes.tcl 00cfa817042f33097616ff0de388e6503aab3968
|
||||
F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e
|
||||
F www/download.tcl 3e51c9ff1326b0a182846134987301310dff7d60
|
||||
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
|
||||
F www/index.tcl 68c815d64b35b2dcc4d4f6845827df71c6869f9f
|
||||
F www/lang.tcl 8cf5de0e7b5d038506cd0b8fd26567ba43777b16
|
||||
F www/lang.tcl 37d4a44bdafe42a270b9e28554651278086ce806
|
||||
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 26972afd645e21e0d16de9a0bb0d03754e909044
|
||||
R 4a79f4243a1c67e525408e6bb2f97ed5
|
||||
P 444447007a32f9ebd9e0714c6cbe0d9a63e193b1
|
||||
R 27dbd8ccaf5ffe5bb0031ee011cf1c46
|
||||
U drh
|
||||
Z bda58aec2ebf892c3a56d60499b5a93d
|
||||
Z 7a6d7f82de1493c63c9271f60dfef892
|
||||
|
@@ -1 +1 @@
|
||||
444447007a32f9ebd9e0714c6cbe0d9a63e193b1
|
||||
747bf1b30b74cfd0e9c27e7c0bc5172637f35520
|
14
src/btree.c
14
src/btree.c
@@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btree.c,v 1.33 2001/10/06 16:33:02 drh Exp $
|
||||
** $Id: btree.c,v 1.34 2001/10/15 00:44:35 drh Exp $
|
||||
**
|
||||
** This file implements a external (disk-based) database using BTrees.
|
||||
** For a detailed discussion of BTrees, refer to
|
||||
@@ -597,8 +597,8 @@ static void pageDestructor(void *pData){
|
||||
** until the first page is loaded.
|
||||
**
|
||||
** zFilename is the name of the database file. If zFilename is NULL
|
||||
** a new database with a random name is created. The database will be
|
||||
** destroyed when sqliteBtreeClose() is called.
|
||||
** a new database with a random name is created. This randomly named
|
||||
** database file will be deleted when sqliteBtreeClose() is called.
|
||||
*/
|
||||
int sqliteBtreeOpen(
|
||||
const char *zFilename, /* Name of the file containing the BTree database */
|
||||
@@ -807,6 +807,13 @@ int sqliteBtreeRollback(Btree *pBt){
|
||||
** Create a new cursor for the BTree whose root is on the page
|
||||
** iTable. The act of acquiring a cursor gets a read lock on
|
||||
** the database file.
|
||||
**
|
||||
** If wrFlag==0, then the cursor can only be used for reading.
|
||||
** If wrFlag==1, then the cursor can be used for reading or writing.
|
||||
** A read/write cursor requires exclusive access to its table. There
|
||||
** cannot be two or more cursors open on the same table is any one of
|
||||
** cursors is a read/write cursor. But there can be two or more
|
||||
** read-only cursors open on the same table.
|
||||
*/
|
||||
int sqliteBtreeCursor(Btree *pBt, int iTable, int wrFlag, BtCursor **ppCur){
|
||||
int rc;
|
||||
@@ -1357,6 +1364,7 @@ int sqliteBtreeMoveto(BtCursor *pCur, const void *pKey, int nKey, int *pRes){
|
||||
int sqliteBtreeNext(BtCursor *pCur, int *pRes){
|
||||
int rc;
|
||||
if( pCur->pPage==0 ){
|
||||
if( pRes ) *pRes = 1;
|
||||
return SQLITE_ABORT;
|
||||
}
|
||||
if( pCur->bSkipNext ){
|
||||
|
10
src/build.c
10
src/build.c
@@ -25,7 +25,7 @@
|
||||
** ROLLBACK
|
||||
** PRAGMA
|
||||
**
|
||||
** $Id: build.c,v 1.49 2001/10/13 02:59:09 drh Exp $
|
||||
** $Id: build.c,v 1.50 2001/10/15 00:44:36 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@@ -1441,6 +1441,14 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
}
|
||||
}else
|
||||
|
||||
if( sqliteStrICmp(zLeft, "count_changes")==0 ){
|
||||
if( getBoolean(zRight) ){
|
||||
db->flags |= SQLITE_CountRows;
|
||||
}else{
|
||||
db->flags &= ~SQLITE_CountRows;
|
||||
}
|
||||
}else
|
||||
|
||||
if( sqliteStrICmp(zLeft, "table_info")==0 ){
|
||||
Table *pTab;
|
||||
Vdbe *v;
|
||||
|
38
src/delete.c
38
src/delete.c
@@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle DELETE FROM statements.
|
||||
**
|
||||
** $Id: delete.c,v 1.17 2001/10/13 01:06:48 drh Exp $
|
||||
** $Id: delete.c,v 1.18 2001/10/15 00:44:36 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -33,6 +33,8 @@ void sqliteDeleteFrom(
|
||||
Index *pIdx; /* For looping over indices of the table */
|
||||
int base; /* Index of the first available table cursor */
|
||||
sqlite *db; /* Main database structure */
|
||||
int openOp; /* Opcode used to open a cursor to the table */
|
||||
|
||||
|
||||
if( pParse->nErr || sqlite_malloc_failed ){
|
||||
pTabList = 0;
|
||||
@@ -86,11 +88,31 @@ void sqliteDeleteFrom(
|
||||
pParse->schemaVerified = 1;
|
||||
}
|
||||
|
||||
/* Initialize the counter of the number of rows deleted, if
|
||||
** we are counting rows.
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0);
|
||||
}
|
||||
|
||||
/* Special case: A DELETE without a WHERE clause deletes everything.
|
||||
** It is easier just to erase the whole table.
|
||||
*/
|
||||
if( pWhere==0 ){
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
/* If counting rows deleted, just count the total number of
|
||||
** entries in the table. */
|
||||
int endOfLoop = sqliteVdbeMakeLabel(v);
|
||||
int addr;
|
||||
openOp = pTab->isTemp ? OP_OpenAux : OP_Open;
|
||||
sqliteVdbeAddOp(v, openOp, 0, pTab->tnum);
|
||||
sqliteVdbeAddOp(v, OP_Rewind, 0, 0);
|
||||
addr = sqliteVdbeAddOp(v, OP_Next, 0, endOfLoop);
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
|
||||
sqliteVdbeResolveLabel(v, endOfLoop);
|
||||
sqliteVdbeAddOp(v, OP_Close, 0, 0);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Clear, pTab->tnum, pTab->isTemp);
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
sqliteVdbeAddOp(v, OP_Clear, pIdx->tnum, pTab->isTemp);
|
||||
@@ -101,8 +123,6 @@ void sqliteDeleteFrom(
|
||||
** the table an pick which records to delete.
|
||||
*/
|
||||
else{
|
||||
int openOp;
|
||||
|
||||
/* Begin the database scan
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_ListOpen, 0, 0);
|
||||
@@ -112,6 +132,9 @@ void sqliteDeleteFrom(
|
||||
/* Remember the key of every item to be deleted.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
}
|
||||
|
||||
/* End the database scan loop.
|
||||
*/
|
||||
@@ -151,6 +174,15 @@ void sqliteDeleteFrom(
|
||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the number of rows that were deleted.
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqliteVdbeAddOp(v, OP_ColumnCount, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, "rows deleted", P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 1, 0);
|
||||
}
|
||||
|
||||
delete_from_cleanup:
|
||||
sqliteIdListDelete(pTabList);
|
||||
|
26
src/insert.c
26
src/insert.c
@@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle INSERT statements in SQLite.
|
||||
**
|
||||
** $Id: insert.c,v 1.23 2001/10/13 01:06:48 drh Exp $
|
||||
** $Id: insert.c,v 1.24 2001/10/15 00:44:36 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -170,6 +170,9 @@ void sqliteInsert(
|
||||
** and the loop is not used.
|
||||
*/
|
||||
if( srcTab>=0 ){
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0); /* Initialize the row count */
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Rewind, srcTab, 0);
|
||||
iBreak = sqliteVdbeMakeLabel(v);
|
||||
iCont = sqliteVdbeAddOp(v, OP_Next, srcTab, iBreak);
|
||||
@@ -201,6 +204,7 @@ void sqliteInsert(
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, base, 0);
|
||||
|
||||
|
||||
/* Create appropriate entries for the new data row in all indices
|
||||
** of the table.
|
||||
*/
|
||||
@@ -230,6 +234,14 @@ void sqliteInsert(
|
||||
sqliteVdbeAddOp(v, OP_PutIdx, idx+base, pIdx->isUnique);
|
||||
}
|
||||
|
||||
|
||||
/* If inserting from a SELECT, keep a count of the number of
|
||||
** rows inserted.
|
||||
*/
|
||||
if( srcTab>=0 && (db->flags & SQLITE_CountRows)!=0 ){
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
}
|
||||
|
||||
/* The bottom of the loop, if the data source is a SELECT statement
|
||||
*/
|
||||
if( srcTab>=0 ){
|
||||
@@ -241,6 +253,18 @@ void sqliteInsert(
|
||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the number of rows inserted.
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqliteVdbeAddOp(v, OP_ColumnCount, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, "rows inserted", P3_STATIC);
|
||||
if( srcTab<0 ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, 1, 0);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Callback, 1, 0);
|
||||
}
|
||||
|
||||
insert_cleanup:
|
||||
if( pList ) sqliteExprListDelete(pList);
|
||||
|
2
src/os.c
2
src/os.c
@@ -68,7 +68,7 @@
|
||||
** To work around the problem, SQLite has to manage file locks internally
|
||||
** on its own. Whenever a new database is opened, we have to find the
|
||||
** specific inode of the database file (the inode is determined by the
|
||||
** st_dev and st_ino fields of the stat structure the stat() fills in)
|
||||
** st_dev and st_ino fields of the stat structure that fstat() fills in)
|
||||
** and check for locks already existing on that inode. When locks are
|
||||
** created or removed, we have to look at our own internal record of the
|
||||
** locks to see if another thread has previously set a lock on that same
|
||||
|
61
src/select.c
61
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.39 2001/10/13 01:06:48 drh Exp $
|
||||
** $Id: select.c,v 1.40 2001/10/15 00:44:36 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -239,6 +239,7 @@ void generateColumnNames(Parse *pParse, IdList *pTabList, ExprList *pEList){
|
||||
sqliteVdbeAddOp(v, OP_ColumnCount, pEList->nExpr, 0);
|
||||
for(i=0; i<pEList->nExpr; i++){
|
||||
Expr *p;
|
||||
int showFullNames;
|
||||
if( pEList->a[i].zName ){
|
||||
char *zName = pEList->a[i].zName;
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
|
||||
@@ -247,17 +248,13 @@ void generateColumnNames(Parse *pParse, IdList *pTabList, ExprList *pEList){
|
||||
}
|
||||
p = pEList->a[i].pExpr;
|
||||
if( p==0 ) continue;
|
||||
if( p->span.z && p->span.z[0] ){
|
||||
showFullNames = (pParse->db->flags & SQLITE_FullColNames)!=0;
|
||||
if( p->span.z && p->span.z[0] && !showFullNames ){
|
||||
int addr = sqliteVdbeAddOp(v,OP_ColumnName, i, 0);
|
||||
sqliteVdbeChangeP3(v, -1, p->span.z, p->span.n);
|
||||
sqliteVdbeCompressSpace(v, addr);
|
||||
}else if( p->op!=TK_COLUMN || pTabList==0 ){
|
||||
char zName[30];
|
||||
sprintf(zName, "column%d", i+1);
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
|
||||
sqliteVdbeChangeP3(v, -1, zName, strlen(zName));
|
||||
}else{
|
||||
if( pTabList->nId>1 || (pParse->db->flags & SQLITE_FullColNames)!=0 ){
|
||||
}else if( p->op==TK_COLUMN && pTabList ){
|
||||
if( pTabList->nId>1 || showFullNames ){
|
||||
char *zName = 0;
|
||||
Table *pTab = pTabList->a[p->iTable].pTab;
|
||||
char *zTab;
|
||||
@@ -274,6 +271,16 @@ void generateColumnNames(Parse *pParse, IdList *pTabList, ExprList *pEList){
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
|
||||
sqliteVdbeChangeP3(v, -1, zName, P3_STATIC);
|
||||
}
|
||||
}else if( p->span.z && p->span.z[0] ){
|
||||
int addr = sqliteVdbeAddOp(v,OP_ColumnName, i, 0);
|
||||
sqliteVdbeChangeP3(v, -1, p->span.z, p->span.n);
|
||||
sqliteVdbeCompressSpace(v, addr);
|
||||
}else{
|
||||
char zName[30];
|
||||
assert( p->op!=TK_COLUMN || pTabList==0 );
|
||||
sprintf(zName, "column%d", i+1);
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
|
||||
sqliteVdbeChangeP3(v, -1, zName, strlen(zName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -867,6 +874,23 @@ int sqliteSelect(
|
||||
*/
|
||||
if( isAgg ){
|
||||
sqliteVdbeAddOp(v, OP_AggReset, 0, pParse->nAgg);
|
||||
if( pGroupBy==0 ){
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, "", P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_AggFocus, 0, 0);
|
||||
for(i=0; i<pParse->nAgg; i++){
|
||||
Expr *pE;
|
||||
if( !pParse->aAgg[i].isAgg ) continue;
|
||||
pE = pParse->aAgg[i].pExpr;
|
||||
assert( pE==0 || pE->op==TK_AGG_FUNCTION );
|
||||
assert( pE==0 || (pE->pList!=0 && pE->pList->nExpr==1) );
|
||||
if( pE==0 || pE->iColumn==FN_Sum ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AggSet, 0, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the memory cell to NULL
|
||||
@@ -898,28 +922,13 @@ int sqliteSelect(
|
||||
** processing.
|
||||
*/
|
||||
else{
|
||||
int doFocus;
|
||||
if( pGroupBy ){
|
||||
int lbl1;
|
||||
for(i=0; i<pGroupBy->nExpr; i++){
|
||||
sqliteExprCode(pParse, pGroupBy->a[i].pExpr);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MakeKey, pGroupBy->nExpr, 0);
|
||||
doFocus = 1;
|
||||
}else{
|
||||
doFocus = 0;
|
||||
for(i=0; i<pParse->nAgg; i++){
|
||||
if( !pParse->aAgg[i].isAgg ){
|
||||
doFocus = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( doFocus ){
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, "", P3_STATIC);
|
||||
}
|
||||
}
|
||||
if( doFocus ){
|
||||
int lbl1 = sqliteVdbeMakeLabel(v);
|
||||
lbl1 = sqliteVdbeMakeLabel(v);
|
||||
sqliteVdbeAddOp(v, OP_AggFocus, 0, lbl1);
|
||||
for(i=0; i<pParse->nAgg; i++){
|
||||
if( pParse->aAgg[i].isAgg ) continue;
|
||||
|
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.61 2001/10/13 02:59:09 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.62 2001/10/15 00:44:36 drh Exp $
|
||||
*/
|
||||
#include "sqlite.h"
|
||||
#include "hash.h"
|
||||
@@ -163,6 +163,9 @@ struct sqlite {
|
||||
#define SQLITE_InTrans 0x00000008 /* True if in a transaction */
|
||||
#define SQLITE_InternChanges 0x00000010 /* Uncommitted Hash table changes */
|
||||
#define SQLITE_FullColNames 0x00000020 /* Show full column names on SELECT */
|
||||
#define SQLITE_CountRows 0x00000040 /* Count rows changed by INSERT, */
|
||||
/* DELETE, or UPDATE and return */
|
||||
/* the count using a callback. */
|
||||
|
||||
/*
|
||||
** Current file format version
|
||||
|
24
src/update.c
24
src/update.c
@@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle UPDATE statements.
|
||||
**
|
||||
** $Id: update.c,v 1.18 2001/10/13 01:06:48 drh Exp $
|
||||
** $Id: update.c,v 1.19 2001/10/15 00:44:36 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -155,6 +155,12 @@ void sqliteUpdate(
|
||||
*/
|
||||
sqliteWhereEnd(pWInfo);
|
||||
|
||||
/* Initialize the count of updated rows
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0);
|
||||
}
|
||||
|
||||
/* Rewind the list of records that need to be updated and
|
||||
** open every index that needs updating.
|
||||
*/
|
||||
@@ -216,6 +222,12 @@ void sqliteUpdate(
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, base, 0);
|
||||
|
||||
/* Increment the count of rows affected by the update
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
}
|
||||
|
||||
/* Repeat the above with the next record to be updated, until
|
||||
** all record selected by the WHERE clause have been updated.
|
||||
*/
|
||||
@@ -226,6 +238,16 @@ void sqliteUpdate(
|
||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the number of rows that were changed.
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqliteVdbeAddOp(v, OP_ColumnCount, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, "rows updated", P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 1, 0);
|
||||
}
|
||||
|
||||
update_cleanup:
|
||||
sqliteFree(apIdx);
|
||||
sqliteFree(aXRef);
|
||||
|
@@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the DELETE FROM statement.
|
||||
#
|
||||
# $Id: delete.test,v 1.9 2001/09/16 00:13:28 drh Exp $
|
||||
# $Id: delete.test,v 1.10 2001/10/15 00:44:36 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -32,7 +32,7 @@ do_test delete-2.1 {
|
||||
|
||||
# Delete selected entries from a table with and without an index.
|
||||
#
|
||||
do_test delete-3.1a {
|
||||
do_test delete-3.1.1 {
|
||||
execsql {CREATE TABLE table1(f1 int, f2 int)}
|
||||
execsql {INSERT INTO table1 VALUES(1,2)}
|
||||
execsql {INSERT INTO table1 VALUES(2,4)}
|
||||
@@ -40,17 +40,24 @@ do_test delete-3.1a {
|
||||
execsql {INSERT INTO table1 VALUES(4,16)}
|
||||
execsql {SELECT * FROM table1 ORDER BY f1}
|
||||
} {1 2 2 4 3 8 4 16}
|
||||
do_test delete-3.1b {
|
||||
do_test delete-3.1.2 {
|
||||
execsql {DELETE FROM table1 WHERE f1=3}
|
||||
} {}
|
||||
do_test delete-3.1.3 {
|
||||
execsql {SELECT * FROM table1 ORDER BY f1}
|
||||
} {1 2 2 4 4 16}
|
||||
do_test delete-3.1c {
|
||||
do_test delete-3.1.4 {
|
||||
execsql {CREATE INDEX index1 ON table1(f1)}
|
||||
execsql {PRAGMA count_changes=on}
|
||||
execsql {DELETE FROM 'table1' WHERE f1=3}
|
||||
} {0}
|
||||
do_test delete-3.1.5 {
|
||||
execsql {SELECT * FROM table1 ORDER BY f1}
|
||||
} {1 2 2 4 4 16}
|
||||
do_test delete-3.1d {
|
||||
do_test delete-3.1.6 {
|
||||
execsql {DELETE FROM table1 WHERE f1=2}
|
||||
} {1}
|
||||
do_test delete-3.1.7 {
|
||||
execsql {SELECT * FROM table1 ORDER BY f1}
|
||||
} {1 2 4 16}
|
||||
|
||||
@@ -69,14 +76,44 @@ do_test delete-4.2 {
|
||||
|
||||
# Lots of deletes
|
||||
#
|
||||
do_test delete-5.1 {
|
||||
do_test delete-5.1.1 {
|
||||
execsql {DELETE FROM table1}
|
||||
} {2}
|
||||
do_test delete-5.1.2 {
|
||||
execsql {SELECT count(*) FROM table1}
|
||||
} {}
|
||||
do_test delete-5.2 {
|
||||
} {0}
|
||||
do_test delete-5.2.1 {
|
||||
execsql {BEGIN TRANSACTION}
|
||||
for {set i 1} {$i<=200} {incr i} {
|
||||
execsql "INSERT INTO table1 VALUES($i,[expr {$i*$i}])"
|
||||
}
|
||||
execsql {COMMIT}
|
||||
execsql {SELECT count(*) FROM table1}
|
||||
} {200}
|
||||
do_test delete-5.2.2 {
|
||||
execsql {DELETE FROM table1}
|
||||
} {200}
|
||||
do_test delete-5.2.3 {
|
||||
execsql {BEGIN TRANSACTION}
|
||||
for {set i 1} {$i<=200} {incr i} {
|
||||
execsql "INSERT INTO table1 VALUES($i,[expr {$i*$i}])"
|
||||
}
|
||||
execsql {COMMIT}
|
||||
execsql {SELECT count(*) FROM table1}
|
||||
} {200}
|
||||
do_test delete-5.2.4 {
|
||||
execsql {PRAGMA count_changes=off}
|
||||
execsql {DELETE FROM table1}
|
||||
} {}
|
||||
do_test delete-5.2.5 {
|
||||
execsql {SELECT count(*) FROM table1}
|
||||
} {0}
|
||||
do_test delete-5.2.6 {
|
||||
execsql {BEGIN TRANSACTION}
|
||||
for {set i 1} {$i<=200} {incr i} {
|
||||
execsql "INSERT INTO table1 VALUES($i,[expr {$i*$i}])"
|
||||
}
|
||||
execsql {COMMIT}
|
||||
execsql {SELECT count(*) FROM table1}
|
||||
} {200}
|
||||
do_test delete-5.3 {
|
||||
|
@@ -12,7 +12,7 @@
|
||||
# focus of this file is testing the INSERT statement that takes is
|
||||
# result from a SELECT.
|
||||
#
|
||||
# $Id: insert2.test,v 1.4 2001/09/16 00:13:28 drh Exp $
|
||||
# $Id: insert2.test,v 1.5 2001/10/15 00:44:36 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -30,32 +30,43 @@ do_test insert2-1.0 {
|
||||
|
||||
# Insert into a new table from the old one.
|
||||
#
|
||||
do_test insert2-1.1 {
|
||||
do_test insert2-1.1.1 {
|
||||
execsql {
|
||||
CREATE TABLE t1(log int, cnt int);
|
||||
---vdbe-trace-on--
|
||||
PRAGMA count_changes=on;
|
||||
INSERT INTO t1 SELECT log, count(*) FROM d1 GROUP BY log;
|
||||
}
|
||||
} {6}
|
||||
do_test insert2-1.1.2 {
|
||||
execsql {SELECT * FROM t1 ORDER BY log}
|
||||
} {0 1 1 1 2 2 3 4 4 8 5 4}
|
||||
|
||||
do_test insert2-1.2 {
|
||||
do_test insert2-1.2.1 {
|
||||
catch {execsql {DROP TABLE t1}}
|
||||
execsql {
|
||||
CREATE TABLE t1(log int, cnt int);
|
||||
INSERT INTO t1
|
||||
SELECT log, count(*) FROM d1 GROUP BY log
|
||||
EXCEPT SELECT n-1,log FROM d1;
|
||||
}
|
||||
} {4}
|
||||
do_test insert2-1.2.2 {
|
||||
execsql {
|
||||
SELECT * FROM t1 ORDER BY log;
|
||||
}
|
||||
} {0 1 3 4 4 8 5 4}
|
||||
do_test insert2-1.3 {
|
||||
do_test insert2-1.3.1 {
|
||||
catch {execsql {DROP TABLE t1}}
|
||||
execsql {
|
||||
CREATE TABLE t1(log int, cnt int);
|
||||
PRAGMA count_changes=off;
|
||||
INSERT INTO t1
|
||||
SELECT log, count(*) FROM d1 GROUP BY log
|
||||
INTERSECT SELECT n-1,log FROM d1;
|
||||
}
|
||||
} {}
|
||||
do_test insert2-1.3.2 {
|
||||
execsql {
|
||||
SELECT * FROM t1 ORDER BY log;
|
||||
}
|
||||
} {1 1 2 2}
|
||||
|
@@ -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.11 2001/10/06 16:33:03 drh Exp $
|
||||
# $Id: select1.test,v 1.12 2001/10/15 00:44:36 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -242,13 +242,17 @@ do_test select1-6.1.1 {
|
||||
execsql {PRAGMA full_column_names=on}
|
||||
set v [catch {execsql2 {SELECT f1 FROM test1 ORDER BY f2}} msg]
|
||||
lappend v $msg
|
||||
} {0 {f1 11 f1 33}}
|
||||
} {0 {test1.f1 11 test1.f1 33}}
|
||||
do_test select1-6.1.2 {
|
||||
set v [catch {execsql2 {SELECT f1 as 'f1' FROM test1 ORDER BY f2}} msg]
|
||||
lappend v $msg
|
||||
} {0 {f1 11 f1 33}}
|
||||
do_test select1-6.1.3 {
|
||||
set v [catch {execsql2 {SELECT * FROM test1 WHERE f1==11}} msg]
|
||||
execsql {PRAGMA full_column_names=off}
|
||||
lappend v $msg
|
||||
} {0 {test1.f1 11 test1.f2 22}}
|
||||
do_test select1-6.1.2 {
|
||||
do_test select1-6.1.4 {
|
||||
set v [catch {execsql2 {SELECT * FROM test1 WHERE f1==11}} msg]
|
||||
lappend v $msg
|
||||
} {0 {f1 11 f2 22}}
|
||||
@@ -276,6 +280,12 @@ do_test select1-6.5 {
|
||||
set v [catch {execsql2 {SELECT test1.f1+F2 FROM test1 ORDER BY f2}} msg]
|
||||
lappend v $msg
|
||||
} {0 {test1.f1+F2 33 test1.f1+F2 77}}
|
||||
do_test select1-6.5.1 {
|
||||
execsql2 {PRAGMA full_column_names=on}
|
||||
set v [catch {execsql2 {SELECT test1.f1+F2 FROM test1 ORDER BY f2}} msg]
|
||||
execsql2 {PRAGMA full_column_names=off}
|
||||
lappend v $msg
|
||||
} {0 {test1.f1+F2 33 test1.f1+F2 77}}
|
||||
do_test select1-6.6 {
|
||||
set v [catch {execsql2 {SELECT test1.f1+F2, t1 FROM test1, test2
|
||||
ORDER BY f2}} msg]
|
||||
|
@@ -12,7 +12,7 @@
|
||||
# focus of this file is testing aggregate functions and the
|
||||
# GROUP BY and HAVING clauses of SELECT statements.
|
||||
#
|
||||
# $Id: select5.test,v 1.5 2001/09/16 00:13:28 drh Exp $
|
||||
# $Id: select5.test,v 1.6 2001/10/15 00:44:36 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -88,12 +88,32 @@ do_test select5-3.1 {
|
||||
}
|
||||
} {1 1 5 2 1 5 3 1 5}
|
||||
|
||||
# Run the AVG() function when the count is zero.
|
||||
# Run various aggregate functions when the count is zero.
|
||||
#
|
||||
do_test select5-4.1 {
|
||||
execsql {
|
||||
SELECT avg(x) FROM t1 WHERE x>100
|
||||
}
|
||||
} {}
|
||||
} {{}}
|
||||
do_test select5-4.2 {
|
||||
execsql {
|
||||
SELECT count(x) FROM t1 WHERE x>100
|
||||
}
|
||||
} {0}
|
||||
do_test select5-4.3 {
|
||||
execsql {
|
||||
SELECT min(x) FROM t1 WHERE x>100
|
||||
}
|
||||
} {{}}
|
||||
do_test select5-4.4 {
|
||||
execsql {
|
||||
SELECT max(x) FROM t1 WHERE x>100
|
||||
}
|
||||
} {{}}
|
||||
do_test select5-4.5 {
|
||||
execsql {
|
||||
SELECT sum(x) FROM t1 WHERE x>100
|
||||
}
|
||||
} {0}
|
||||
|
||||
finish_test
|
||||
|
@@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the UPDATE statement.
|
||||
#
|
||||
# $Id: update.test,v 1.6 2001/09/16 00:13:28 drh Exp $
|
||||
# $Id: update.test,v 1.7 2001/10/15 00:44:36 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -61,25 +61,37 @@ do_test update-3.4 {
|
||||
#
|
||||
do_test update-3.5 {
|
||||
execsql {UPDATE test1 SET f2=f2*3}
|
||||
} {}
|
||||
do_test update-3.6 {
|
||||
execsql {SELECT * FROM test1 ORDER BY f1}
|
||||
} {1 6 2 12 3 24 4 48 5 96 6 192 7 384 8 768 9 1536 10 3072}
|
||||
do_test update-3.6 {
|
||||
do_test update-3.7 {
|
||||
execsql {PRAGMA count_changes=on}
|
||||
execsql {UPDATE test1 SET f2=f2/3 WHERE f1<=5}
|
||||
} {5}
|
||||
do_test update-3.8 {
|
||||
execsql {SELECT * FROM test1 ORDER BY f1}
|
||||
} {1 2 2 4 3 8 4 16 5 32 6 192 7 384 8 768 9 1536 10 3072}
|
||||
do_test update-3.7 {
|
||||
do_test update-3.9 {
|
||||
execsql {UPDATE test1 SET f2=f2/3 WHERE f1>5}
|
||||
} {5}
|
||||
do_test update-3.10 {
|
||||
execsql {SELECT * FROM test1 ORDER BY f1}
|
||||
} {1 2 2 4 3 8 4 16 5 32 6 64 7 128 8 256 9 512 10 1024}
|
||||
|
||||
# Swap the values of f1 and f2 for all elements
|
||||
#
|
||||
do_test update-3.8 {
|
||||
do_test update-3.11 {
|
||||
execsql {UPDATE test1 SET F2=f1, F1=f2}
|
||||
} {10}
|
||||
do_test update-3.12 {
|
||||
execsql {SELECT * FROM test1 ORDER BY F1}
|
||||
} {2 1 4 2 8 3 16 4 32 5 64 6 128 7 256 8 512 9 1024 10}
|
||||
do_test update-3.9 {
|
||||
do_test update-3.13 {
|
||||
execsql {PRAGMA count_changes=off}
|
||||
execsql {UPDATE test1 SET F2=f1, F1=f2}
|
||||
} {}
|
||||
do_test update-3.14 {
|
||||
execsql {SELECT * FROM test1 ORDER BY F1}
|
||||
} {1 2 2 4 3 8 4 16 5 32 6 64 7 128 8 256 9 512 10 1024}
|
||||
|
||||
@@ -117,8 +129,16 @@ do_test update-4.5 {
|
||||
execsql {SELECT * FROM test1 ORDER BY f1,f2}
|
||||
} {6 64 8 88 8 128 8 256 8 888 9 512 10 1024 78 128 777 128}
|
||||
do_test update-4.6 {
|
||||
execsql {UPDATE test1 SET f1=f1-1 WHERE f1<=100 and f2==128}
|
||||
execsql {SELECT * FROM test1 ORDER BY f1,f2}
|
||||
execsql {
|
||||
PRAGMA count_changes=on;
|
||||
UPDATE test1 SET f1=f1-1 WHERE f1<=100 and f2==128;
|
||||
}
|
||||
} {2}
|
||||
do_test update-4.7 {
|
||||
execsql {
|
||||
PRAGMA count_changes=off;
|
||||
SELECT * FROM test1 ORDER BY f1,f2
|
||||
}
|
||||
} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128}
|
||||
|
||||
# Repeat the previous sequence of tests with an index.
|
||||
@@ -154,34 +174,44 @@ do_test update-5.4.3 {
|
||||
} {8 88 8 128 8 256 8 888}
|
||||
do_test update-5.5 {
|
||||
execsql {UPDATE test1 SET f1=f1-1 WHERE f1>100 and f2==128}
|
||||
} {}
|
||||
do_test update-5.5.1 {
|
||||
execsql {SELECT * FROM test1 ORDER BY f1,f2}
|
||||
} {6 64 8 88 8 128 8 256 8 888 9 512 10 1024 78 128 777 128}
|
||||
do_test update-5.5.1 {
|
||||
do_test update-5.5.2 {
|
||||
execsql {SELECT * FROM test1 WHERE f1==78 ORDER BY f1,f2}
|
||||
} {78 128}
|
||||
do_test update-5.5.2 {
|
||||
do_test update-5.5.3 {
|
||||
execsql {SELECT * FROM test1 WHERE f1==778 ORDER BY f1,f2}
|
||||
} {}
|
||||
do_test update-5.5.3 {
|
||||
do_test update-5.5.4 {
|
||||
execsql {SELECT * FROM test1 WHERE f1==777 ORDER BY f1,f2}
|
||||
} {777 128}
|
||||
do_test update-5.5.4 {
|
||||
do_test update-5.5.5 {
|
||||
execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2}
|
||||
} {8 88 8 128 8 256 8 888}
|
||||
do_test update-5.6 {
|
||||
execsql {UPDATE test1 SET f1=f1-1 WHERE f1<=100 and f2==128}
|
||||
execsql {SELECT * FROM test1 ORDER BY f1,f2}
|
||||
} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128}
|
||||
execsql {
|
||||
PRAGMA count_changes=on;
|
||||
UPDATE test1 SET f1=f1-1 WHERE f1<=100 and f2==128;
|
||||
}
|
||||
} {2}
|
||||
do_test update-5.6.1 {
|
||||
execsql {
|
||||
PRAGMA count_changes=off;
|
||||
SELECT * FROM test1 ORDER BY f1,f2
|
||||
}
|
||||
} {6 64 7 128 8 88 8 256 8 888 9 512 10 1024 77 128 777 128}
|
||||
do_test update-5.6.2 {
|
||||
execsql {SELECT * FROM test1 WHERE f1==77 ORDER BY f1,f2}
|
||||
} {77 128}
|
||||
do_test update-5.6.2 {
|
||||
do_test update-5.6.3 {
|
||||
execsql {SELECT * FROM test1 WHERE f1==778 ORDER BY f1,f2}
|
||||
} {}
|
||||
do_test update-5.6.3 {
|
||||
do_test update-5.6.4 {
|
||||
execsql {SELECT * FROM test1 WHERE f1==777 ORDER BY f1,f2}
|
||||
} {777 128}
|
||||
do_test update-5.6.4 {
|
||||
do_test update-5.6.5 {
|
||||
execsql {SELECT * FROM test1 WHERE f1==8 ORDER BY f1,f2}
|
||||
} {8 88 8 256 8 888}
|
||||
|
||||
|
@@ -17,6 +17,13 @@ proc chng {date desc} {
|
||||
puts "<DD><P><UL>$desc</UL></P></DD>"
|
||||
}
|
||||
|
||||
chng {2001 Oct 14 (2.0.5)} {
|
||||
<li>Added the COUNT_CHANGES pragma.</li>
|
||||
<li>Changes to the FULL_COLUMN_NAMES pragma to help out the ODBC driver.</li>
|
||||
<li>Bug fix: "SELECT count(*)" was returning NULL for empty tables.
|
||||
Now it returns 0.</li>
|
||||
}
|
||||
|
||||
chng {2001 Oct 13 (2.0.4)} {
|
||||
<li>Bug fix: an abscure and relatively harmless bug was causing one of
|
||||
the tests to fail when gcc optimizations are turned on. This release
|
||||
|
34
www/lang.tcl
34
www/lang.tcl
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Run this Tcl script to generate the sqlite.html file.
|
||||
#
|
||||
set rcsid {$Id: lang.tcl,v 1.12 2001/10/13 02:59:10 drh Exp $}
|
||||
set rcsid {$Id: lang.tcl,v 1.13 2001/10/15 00:44:36 drh Exp $}
|
||||
|
||||
puts {<html>
|
||||
<head>
|
||||
@@ -631,6 +631,12 @@ with caution.</p>
|
||||
uses more memory, you can increase the cache size for a possible speed
|
||||
improvement.</p></li>
|
||||
|
||||
<li><p><b>PRAGMA count_changes = ON;
|
||||
<br>PRAGMA count_changes = OFF;</b></p>
|
||||
<p>When on, the COUNT_CHANGES pragma causes the callback function to
|
||||
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 full_column_names = ON;
|
||||
<br>PRAGMA full_column_names = OFF;</b></p>
|
||||
<p>The column names reported in an SQLite callback are normally just
|
||||
@@ -638,12 +644,32 @@ with caution.</p>
|
||||
is used. But when full_column_names is turned on, column names are
|
||||
always reported as "TABLE.COLUMN" even for simple queries.</p></li>
|
||||
|
||||
<li><p><b>PRAGMA vdbe_trace = ON;<br>PRAGMA vdbe_trace = OFF;</b></p>
|
||||
<p>Turn tracing of the virtual database engine inside of the
|
||||
SQLite library on and off. This is used for debugging.</p></li>
|
||||
<li><p><b>PRAGMA index_info(</b><i>index-name</i><b>);</b></p>
|
||||
<p>For each column that the named index references, invoke the
|
||||
callback function
|
||||
once with information about that column, including the column name,
|
||||
and the column number.</p>
|
||||
|
||||
<li><p><b>PRAGMA index_list(</b><i>table-name</i><b>);</b></p>
|
||||
<p>For each index on the named table, invoke the callback function
|
||||
once with information about that index. Arguments include the
|
||||
index name and a flag to indicate whether or not the index must be
|
||||
unique.</p>
|
||||
|
||||
<li><p><b>PRAGMA parser_trace = ON;<br>PRAGMA parser_trace = OFF;</b></p>
|
||||
<p>Turn tracing of the SQL parser inside of the
|
||||
SQLite library on and off. This is used for debugging.
|
||||
This only works if the library is compiled without the NDEBUG macro.
|
||||
</p></li>
|
||||
|
||||
<li><p><b>PRAGMA table_info(</b><i>table-name</i><b>);</b></p>
|
||||
<p>For each column in the named table, invoke the callback function
|
||||
once with information about that column, including the column name,
|
||||
data type, whether or not the column can be NULL, and the default
|
||||
value for the column.</p>
|
||||
|
||||
<li><p><b>PRAGMA vdbe_trace = ON;<br>PRAGMA vdbe_trace = OFF;</b></p>
|
||||
<p>Turn tracing of the virtual database engine inside of the
|
||||
SQLite library on and off. This is used for debugging.</p></li>
|
||||
</ul>
|
||||
|
||||
|
Reference in New Issue
Block a user