mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Change lots of internal symbols from sqliteXXX to sqlite3XXX so that the
library links again. It doesn't work yet, due to changes in the btree layer calling convention. (CVS 1324) FossilOrigin-Name: 8af6474c49263ae26216dff9465b33f76b500cf4
This commit is contained in:
32
main.mk
32
main.mk
@@ -54,14 +54,15 @@ TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src
|
||||
|
||||
# Object files for the SQLite library.
|
||||
#
|
||||
LIBOBJ = btree.o hash.o os.o pager.o random.o \
|
||||
util.o tclsqlite.o utf.o
|
||||
# LIBOBJ = btree.o hash.o os.o pager.o random.o \
|
||||
# util.o tclsqlite.o utf.o
|
||||
|
||||
LIBOBJ_ORIG = attach.o auth.o btree.o btree_rb.o build.o copy.o date.o delete.o \
|
||||
|
||||
LIBOBJ = attach.o auth.o btree.o build.o copy.o date.o delete.o \
|
||||
expr.o func.o hash.o insert.o \
|
||||
main.o opcodes.o os.o pager.o parse.o pragma.o printf.o random.o \
|
||||
select.o table.o tokenize.o trigger.o update.o util.o \
|
||||
vacuum.o vdbe.o vdbeaux.o where.o tclsqlite.o
|
||||
vacuum.o vdbe.o vdbeaux.o where.o tclsqlite.o utf.o
|
||||
|
||||
# All of the source code files.
|
||||
#
|
||||
@@ -120,12 +121,12 @@ SRC_ORIG = \
|
||||
# Source code to the test files.
|
||||
#
|
||||
TESTSRC = \
|
||||
$(TOP)/src/os.c \
|
||||
$(TOP)/src/pager.c \
|
||||
$(TOP)/src/test2.c \
|
||||
$(TOP)/src/test3.c \
|
||||
$(TOP)/src/test5.c \
|
||||
$(TOP)/src/md5.c
|
||||
$(TOP)/src/os.c \
|
||||
$(TOP)/src/pager.c \
|
||||
$(TOP)/src/test2.c \
|
||||
$(TOP)/src/test3.c \
|
||||
$(TOP)/src/test5.c \
|
||||
$(TOP)/src/md5.c
|
||||
|
||||
TESTSRC_ORIG = \
|
||||
$(TOP)/src/btree.c \
|
||||
@@ -136,6 +137,7 @@ TESTSRC_ORIG = \
|
||||
$(TOP)/src/test2.c \
|
||||
$(TOP)/src/test3.c \
|
||||
$(TOP)/src/test4.c \
|
||||
$(TOP)/src/test5.c \
|
||||
$(TOP)/src/vdbe.c \
|
||||
$(TOP)/src/md5.c
|
||||
|
||||
@@ -178,6 +180,8 @@ sqlite$(EXE): $(TOP)/src/shell.c libsqlite.a sqlite.h
|
||||
$(TCCX) $(READLINE_FLAGS) -o sqlite$(EXE) $(TOP)/src/shell.c \
|
||||
libsqlite.a $(LIBREADLINE) $(THREADLIB)
|
||||
|
||||
objects: $(LIBOBJ_ORIG)
|
||||
|
||||
# This target creates a directory named "tsrc" and fills it with
|
||||
# copies of all of the C source code and header files needed to
|
||||
# build on the target system. Some of the C source code and header
|
||||
@@ -217,7 +221,7 @@ opcodes.o: opcodes.c
|
||||
|
||||
opcodes.c: $(TOP)/src/vdbe.c
|
||||
echo '/* Automatically generated file. Do not edit */' >opcodes.c
|
||||
echo 'char *sqliteOpcodeNames[] = { "???", ' >>opcodes.c
|
||||
echo 'char *sqlite3OpcodeNames[] = { "???", ' >>opcodes.c
|
||||
grep '^case OP_' $(TOP)/src/vdbe.c | \
|
||||
sed -e 's/^.*OP_/ "/' -e 's/:.*$$/", /' >>opcodes.c
|
||||
echo '};' >>opcodes.c
|
||||
@@ -234,9 +238,6 @@ os.o: $(TOP)/src/os.c $(HDR)
|
||||
parse.o: parse.c $(HDR)
|
||||
$(TCCX) -c parse.c
|
||||
|
||||
utf.o: $(TOP)/src/utf.c $(HDR)
|
||||
$(TCCX) -c $(TOP)/src/utf.c
|
||||
|
||||
parse.h: parse.c
|
||||
|
||||
parse.c: $(TOP)/src/parse.y lemon
|
||||
@@ -270,6 +271,9 @@ tokenize.o: $(TOP)/src/tokenize.c $(HDR)
|
||||
trigger.o: $(TOP)/src/trigger.c $(HDR)
|
||||
$(TCCX) -c $(TOP)/src/trigger.c
|
||||
|
||||
utf.o: $(TOP)/src/utf.c $(HDR)
|
||||
$(TCCX) -c $(TOP)/src/utf.c
|
||||
|
||||
util.o: $(TOP)/src/util.c $(HDR)
|
||||
$(TCCX) -c $(TOP)/src/util.c
|
||||
|
||||
|
108
manifest
108
manifest
@@ -1,5 +1,5 @@
|
||||
C More\sbug\sfixes\sin\sbtree.c.\s(CVS\s1323)
|
||||
D 2004-05-08T02:03:23
|
||||
C Change\slots\sof\sinternal\ssymbols\sfrom\ssqliteXXX\sto\ssqlite3XXX\sso\sthat\sthe\nlibrary\slinks\sagain.\sIt\sdoesn't\swork\syet,\sdue\sto\schanges\sin\sthe\sbtree\slayer\ncalling\sconvention.\s(CVS\s1324)
|
||||
D 2004-05-08T08:23:20
|
||||
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
|
||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||
@@ -15,59 +15,59 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
|
||||
F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
||||
F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
|
||||
F main.mk 8981b769a3538a8fbd5031786353e8f41bc6a07f
|
||||
F main.mk e351e8ed7c55c2031842adc77c5f9bb2e0d7ea26
|
||||
F publish.sh 1cd5c982388560fa91eedf6a338e210f713b35c8
|
||||
F spec.template a38492f1c1dd349fc24cb0565e08afc53045304b
|
||||
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
|
||||
F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f
|
||||
F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
|
||||
F src/attach.c b01db0d3211f673d8e670abf7eaad04591d40d14
|
||||
F src/auth.c 4fa3b05bd19445d1c474d6751c4a508d6ea0abe1
|
||||
F src/btree.c 1ab8767ab7b2e591b632a6e28e10af97941f4f76
|
||||
F src/btree.h ba5d3bfadc3f46f86df525ac07274dc497af856a
|
||||
F src/btree_rb.c 99feb3ff835106d018a483a1ce403e5cf9c718bc
|
||||
F src/build.c 76fbca30081decd6615dee34b48c927ed5063752
|
||||
F src/copy.c 750e13828c3e4a293123e36aaa7cf0f22466248a
|
||||
F src/date.c f055419d602bde622c70f831350b6b52f2235de0
|
||||
F src/delete.c 82001c74882319f94dab5f6b92a27311b31092ae
|
||||
F src/encode.c fc8c51f0b61bc803ccdec092e130bebe762b0a2f
|
||||
F src/expr.c 8c3f5603c3e98b1c146d18076ba3e82cdbb59c11
|
||||
F src/func.c 34fead7a33e82095f6412d3fafd379d47864b3be
|
||||
F src/hash.c 9b56ef3b291e25168f630d5643a4264ec011c70e
|
||||
F src/hash.h 3247573ab95b9dd90bcca0307a75d9a16da1ccc7
|
||||
F src/insert.c c0485ee2d1b99322894e2d1e0b576fd05ed75616
|
||||
F src/main.c 94dd355768e2a389e184a069b6880f4bac100307
|
||||
F src/md5.c c53e7b50418afbde22d07128baf3cc615530e846
|
||||
F src/os.c 5f11382733805d4529ec2a30800e117f30995ea8
|
||||
F src/os.h 250a3789be609adfee5c5aa20137ce8683276f24
|
||||
F src/pager.c d18d56247c40bf4006ca7761c457b7d76af5c62a
|
||||
F src/pager.h 138ca7f73c47bebf469591939dcefa934cdf8d26
|
||||
F src/parse.y 023720cb8c3bef74e51738bca78335d0dc6d2cfd
|
||||
F src/pragma.c f9c157b0591419d2d3407dac90222020d2a6d822
|
||||
F src/printf.c 8dba7092430549e70c57de2bde6be92a28819eb0
|
||||
F src/random.c 775913e0b7fbd6295d21f12a7bd35b46387c44b2
|
||||
F src/select.c 3833e2b64cc6d249385ee44e13bf49c9ae5b903d
|
||||
F src/shell.c 920af040d3a33ea8919c82cee45b424ad841cee0
|
||||
F src/sqlite.h.in 35bec264dfb4965bbfeb7e75221f8658f210c30d
|
||||
F src/sqliteInt.h 44a17815ec6ffb93151723aa5cde7263162f52f3
|
||||
F src/table.c d845cb101b5afc1f7fea083c99e3d2fa7998d895
|
||||
F src/tclsqlite.c 9fe6fc0c20820e9411dfea407635de9b9d3ae0e3
|
||||
F src/test1.c 9aa62b89d420e6763b5e7ae89a47f6cf87370477
|
||||
F src/test2.c 9d611c45e1b07039a2bd95f5ea73178362b23229
|
||||
F src/test3.c f0539fb9e605f5b3f8fb71e0c897931b8cff8aa3
|
||||
F src/test4.c 6e3e31acfaf21d66420fc35fda5b17dc0000cc8d
|
||||
F src/test5.c 3ff0565057b8d23e20092d5c6c0b7cb0d932c51e
|
||||
F src/tokenize.c 6676b946fd8825b67ab52140af4fdc57a70bda48
|
||||
F src/trigger.c a9927b57c865b6f3df3fb5e40c9824d722660ded
|
||||
F src/update.c 4c50328ebc127852bde8e2950eb8933234802c21
|
||||
F src/utf.c 1f2ac0c4247258196ce97575144e7793a46be2cd
|
||||
F src/util.c b2287b07ddf55ef7aaa8888a9473123995a69f40
|
||||
F src/vacuum.c a4e8464c9f6d60659c5343e9d62c742463227820
|
||||
F src/vdbe.c 7c33f761fdc799633468766fb53eda4301daa6b3
|
||||
F src/vdbe.h ac987945e4dd6f987bca534c6005899f089fc270
|
||||
F src/vdbeInt.h b40ff02ce39fd076e6ff3369e19c1bbfe1986682
|
||||
F src/vdbeaux.c e2cdd1ab63604a390612c73e26bdd2ef910e9438
|
||||
F src/where.c b58764861a96bab3f1d294200f9e53519b92c274
|
||||
F src/attach.c fa9a58234406d84eeb900517d0c0adc4b2da051a
|
||||
F src/auth.c a2a46e3ed7799134cf3d2dd5ae6650115f26b653
|
||||
F src/btree.c 8c50e8f3d1dce11a43342068b3bfc88bcfb104f8
|
||||
F src/btree.h 07a16dbb8c29291d0768b956649350d8f8c3dac3
|
||||
F src/btree_rb.c 47e5b5ec90846af392b5668b34648198ba459561
|
||||
F src/build.c 21b6645c966970dac51bcccfa8650403a3f56210
|
||||
F src/copy.c 3c33157f6b4919d6851602b78008c67d466cdadd
|
||||
F src/date.c ca325e0752a88656ba798bc0666fa41498941732
|
||||
F src/delete.c c6f881904504619ef00c495d535aa0c60a1ddbdc
|
||||
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
|
||||
F src/expr.c efd9daf50407ed27a0a50753e6d6c086320260cd
|
||||
F src/func.c f87eec5cf103f739ba32866660ce22d000c5723f
|
||||
F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
|
||||
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
|
||||
F src/insert.c 954c0ddabc10899526c975b403ca4352d253f2e0
|
||||
F src/main.c eb4b3e74543b137c168a059979039dec681bb0a2
|
||||
F src/md5.c 01d2f55b06316d242749759b6a37186439ef7fe3
|
||||
F src/os.c 4092dcc87e66f49ed660fae1519569a0cee34da0
|
||||
F src/os.h fbb2f6595fc34fa351830d88fe1c6b85118f0383
|
||||
F src/pager.c 97a675f1653ec2dc2907ebc247b1bae5a4d6ed9a
|
||||
F src/pager.h 0c95b18f2785b58bfbb2b6f6a221f23caf378687
|
||||
F src/parse.y d0258aa3cc8b0c5742b07b699d10fa98f3caea7d
|
||||
F src/pragma.c d9f8332a1a87bc4058113ee9686e0c14286d69fd
|
||||
F src/printf.c 43d546542880fde9a3343f285516d74e70e63de1
|
||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
||||
F src/select.c d3868613e70ac09cf2fb4ddd211f088351d1fe51
|
||||
F src/shell.c 9a242ad03c8726823f182bff81c5e12ef2882f93
|
||||
F src/sqlite.h.in 532e08163a8df8b71faf7be4e69ba208938eb312
|
||||
F src/sqliteInt.h 60f087f2d1dae5ece1615a840ddfe797433b06ff
|
||||
F src/table.c 882b0ae9524c67758157540dd6467c9a5de52335
|
||||
F src/tclsqlite.c 21147148e7b57a0bb7409cff5878c60470df9acc
|
||||
F src/test1.c 67a72fa1f5f6d41c838fa97f324f8dbfb4051413
|
||||
F src/test2.c 8dab493c7eccd2c7bb93a8e31f7db60f14e61b7b
|
||||
F src/test3.c c5a25235b6b2ada516550eb17b57f8dd002f6b41
|
||||
F src/test4.c 92d2a10380a65d61e5527a556f604bfde16411e8
|
||||
F src/test5.c eb39aac8fed61bd930b92613cd705c145244074a
|
||||
F src/tokenize.c 256a3cf0ff938cd79774d7f95173d74281912df9
|
||||
F src/trigger.c 8b07ff87b39f24997e5f737340ebbb5ce09ca481
|
||||
F src/update.c 475465fc0582160dadf5455b05235cb13c9e21f9
|
||||
F src/utf.c fc799748d43fe1982d157b871e3e420a19c85d4f
|
||||
F src/util.c 0c31a53b848648271d0910c2604b4d8ae516ebb1
|
||||
F src/vacuum.c 91ba5a23eca2d9a8a11191cef577d417f9318976
|
||||
F src/vdbe.c 500d5140b6f779bfcc60bef74b914e4dc6686439
|
||||
F src/vdbe.h 3cf970b0a64be04d36f4dcece3cecd28312d745c
|
||||
F src/vdbeInt.h 4563dc1c9f05a842cbbc7759e4cc7f3779f53547
|
||||
F src/vdbeaux.c 68c24aa7b7facf7412755f3807d8a3acf4e29963
|
||||
F src/where.c 6db0291280f2c642bae2c69a70750325b53717a4
|
||||
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
|
||||
F test/attach.test ba8261d38da6b6a7d4f78ec543c548c4418582ef
|
||||
F test/attach2.test ce61e6185b3cd891cc0e9a4c868fcc65eb92fc55
|
||||
@@ -190,7 +190,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
|
||||
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
|
||||
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
|
||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||
P a80939ef714ec884950b4a1f4f809ffa37fdfa59
|
||||
R 779830de46b9f26aa95cf36a64b9d819
|
||||
U drh
|
||||
Z a42ee28f0c51193d2a98927224408150
|
||||
P 2d64cba38c0f5fffa18cb30c4c448278837de49d
|
||||
R 03384ffd55df6020603f8282df180679
|
||||
U danielk1977
|
||||
Z bcb34ef43ffabd77f195774597adcbb5
|
||||
|
@@ -1 +1 @@
|
||||
2d64cba38c0f5fffa18cb30c4c448278837de49d
|
||||
8af6474c49263ae26216dff9465b33f76b500cf4
|
115
src/attach.c
115
src/attach.c
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code used to implement the ATTACH and DETACH commands.
|
||||
**
|
||||
** $Id: attach.c,v 1.10 2004/02/12 18:46:39 drh Exp $
|
||||
** $Id: attach.c,v 1.11 2004/05/08 08:23:21 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -23,48 +23,48 @@
|
||||
** The pFilename and pDbname arguments are the tokens that define the
|
||||
** filename and dbname in the ATTACH statement.
|
||||
*/
|
||||
void sqliteAttach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey){
|
||||
void sqlite3Attach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey){
|
||||
Db *aNew;
|
||||
int rc, i;
|
||||
char *zFile, *zName;
|
||||
sqlite *db;
|
||||
Vdbe *v;
|
||||
|
||||
v = sqliteGetVdbe(pParse);
|
||||
sqliteVdbeAddOp(v, OP_Halt, 0, 0);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
|
||||
if( pParse->explain ) return;
|
||||
db = pParse->db;
|
||||
if( db->file_format<4 ){
|
||||
sqliteErrorMsg(pParse, "cannot attach auxiliary databases to an "
|
||||
sqlite3ErrorMsg(pParse, "cannot attach auxiliary databases to an "
|
||||
"older format master database", 0);
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
return;
|
||||
}
|
||||
if( db->nDb>=MAX_ATTACHED+2 ){
|
||||
sqliteErrorMsg(pParse, "too many attached databases - max %d",
|
||||
sqlite3ErrorMsg(pParse, "too many attached databases - max %d",
|
||||
MAX_ATTACHED);
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
zFile = 0;
|
||||
sqliteSetNString(&zFile, pFilename->z, pFilename->n, 0);
|
||||
sqlite3SetNString(&zFile, pFilename->z, pFilename->n, 0);
|
||||
if( zFile==0 ) return;
|
||||
sqliteDequote(zFile);
|
||||
sqlite3Dequote(zFile);
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
if( sqliteAuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
|
||||
sqliteFree(zFile);
|
||||
return;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_AUTHORIZATION */
|
||||
|
||||
zName = 0;
|
||||
sqliteSetNString(&zName, pDbname->z, pDbname->n, 0);
|
||||
sqlite3SetNString(&zName, pDbname->z, pDbname->n, 0);
|
||||
if( zName==0 ) return;
|
||||
sqliteDequote(zName);
|
||||
sqlite3Dequote(zName);
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( db->aDb[i].zName && sqliteStrICmp(db->aDb[i].zName, zName)==0 ){
|
||||
sqliteErrorMsg(pParse, "database %z is already in use", zName);
|
||||
if( db->aDb[i].zName && sqlite3StrICmp(db->aDb[i].zName, zName)==0 ){
|
||||
sqlite3ErrorMsg(pParse, "database %z is already in use", zName);
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
sqliteFree(zFile);
|
||||
return;
|
||||
@@ -82,14 +82,14 @@ void sqliteAttach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey){
|
||||
db->aDb = aNew;
|
||||
aNew = &db->aDb[db->nDb++];
|
||||
memset(aNew, 0, sizeof(*aNew));
|
||||
sqliteHashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
|
||||
sqliteHashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
|
||||
sqliteHashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
|
||||
sqliteHashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
|
||||
sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
|
||||
sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
|
||||
sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
|
||||
sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
|
||||
aNew->zName = zName;
|
||||
rc = sqliteBtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
|
||||
rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
|
||||
if( rc ){
|
||||
sqliteErrorMsg(pParse, "unable to open database: %s", zFile);
|
||||
sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
|
||||
}
|
||||
#if SQLITE_HAS_CODEC
|
||||
{
|
||||
@@ -97,8 +97,8 @@ void sqliteAttach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey){
|
||||
char *zKey = 0;
|
||||
int nKey;
|
||||
if( pKey && pKey->z && pKey->n ){
|
||||
sqliteSetNString(&zKey, pKey->z, pKey->n, 0);
|
||||
sqliteDequote(zKey);
|
||||
sqlite3SetNString(&zKey, pKey->z, pKey->n, 0);
|
||||
sqlite3Dequote(zKey);
|
||||
nKey = strlen(zKey);
|
||||
}else{
|
||||
zKey = 0;
|
||||
@@ -111,16 +111,16 @@ void sqliteAttach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey){
|
||||
db->flags &= ~SQLITE_Initialized;
|
||||
if( pParse->nErr ) return;
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqliteInit(pParse->db, &pParse->zErrMsg);
|
||||
rc = sqlite3Init(pParse->db, &pParse->zErrMsg);
|
||||
}
|
||||
if( rc ){
|
||||
int i = db->nDb - 1;
|
||||
assert( i>=2 );
|
||||
if( db->aDb[i].pBt ){
|
||||
sqliteBtreeClose(db->aDb[i].pBt);
|
||||
sqlite3BtreeClose(db->aDb[i].pBt);
|
||||
db->aDb[i].pBt = 0;
|
||||
}
|
||||
sqliteResetInternalSchema(db, 0);
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
pParse->nErr++;
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
}
|
||||
@@ -133,42 +133,42 @@ void sqliteAttach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey){
|
||||
**
|
||||
** The pDbname argument is the name of the database in the DETACH statement.
|
||||
*/
|
||||
void sqliteDetach(Parse *pParse, Token *pDbname){
|
||||
void sqlite3Detach(Parse *pParse, Token *pDbname){
|
||||
int i;
|
||||
sqlite *db;
|
||||
Vdbe *v;
|
||||
|
||||
v = sqliteGetVdbe(pParse);
|
||||
sqliteVdbeAddOp(v, OP_Halt, 0, 0);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
|
||||
if( pParse->explain ) return;
|
||||
db = pParse->db;
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( db->aDb[i].pBt==0 || db->aDb[i].zName==0 ) continue;
|
||||
if( strlen(db->aDb[i].zName)!=pDbname->n ) continue;
|
||||
if( sqliteStrNICmp(db->aDb[i].zName, pDbname->z, pDbname->n)==0 ) break;
|
||||
if( sqlite3StrNICmp(db->aDb[i].zName, pDbname->z, pDbname->n)==0 ) break;
|
||||
}
|
||||
if( i>=db->nDb ){
|
||||
sqliteErrorMsg(pParse, "no such database: %T", pDbname);
|
||||
sqlite3ErrorMsg(pParse, "no such database: %T", pDbname);
|
||||
return;
|
||||
}
|
||||
if( i<2 ){
|
||||
sqliteErrorMsg(pParse, "cannot detach database %T", pDbname);
|
||||
sqlite3ErrorMsg(pParse, "cannot detach database %T", pDbname);
|
||||
return;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
if( sqliteAuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
|
||||
if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
|
||||
return;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_AUTHORIZATION */
|
||||
sqliteBtreeClose(db->aDb[i].pBt);
|
||||
sqlite3BtreeClose(db->aDb[i].pBt);
|
||||
db->aDb[i].pBt = 0;
|
||||
sqliteFree(db->aDb[i].zName);
|
||||
sqliteResetInternalSchema(db, i);
|
||||
sqlite3ResetInternalSchema(db, i);
|
||||
db->nDb--;
|
||||
if( i<db->nDb ){
|
||||
db->aDb[i] = db->aDb[db->nDb];
|
||||
memset(&db->aDb[db->nDb], 0, sizeof(db->aDb[0]));
|
||||
sqliteResetInternalSchema(db, i);
|
||||
sqlite3ResetInternalSchema(db, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ void sqliteDetach(Parse *pParse, Token *pDbname){
|
||||
** The return value indicates whether or not fixation is required. TRUE
|
||||
** means we do need to fix the database references, FALSE means we do not.
|
||||
*/
|
||||
int sqliteFixInit(
|
||||
int sqlite3FixInit(
|
||||
DbFixer *pFix, /* The fixer to be initialized */
|
||||
Parse *pParse, /* Error messages will be written here */
|
||||
int iDb, /* This is the database that must must be used */
|
||||
@@ -202,7 +202,7 @@ int sqliteFixInit(
|
||||
** The following set of routines walk through the parse tree and assign
|
||||
** a specific database to all table references where the database name
|
||||
** was left unspecified in the original SQL statement. The pFix structure
|
||||
** must have been initialized by a prior call to sqliteFixInit().
|
||||
** must have been initialized by a prior call to sqlite3FixInit().
|
||||
**
|
||||
** These routines are used to make sure that an index, trigger, or
|
||||
** view in one database does not refer to objects in a different database.
|
||||
@@ -212,7 +212,7 @@ int sqliteFixInit(
|
||||
** pParse->zErrMsg and these routines return non-zero. If everything
|
||||
** checks out, these routines return 0.
|
||||
*/
|
||||
int sqliteFixSrcList(
|
||||
int sqlite3FixSrcList(
|
||||
DbFixer *pFix, /* Context of the fixation */
|
||||
SrcList *pList /* The Source list to check and modify */
|
||||
){
|
||||
@@ -224,85 +224,88 @@ int sqliteFixSrcList(
|
||||
for(i=0; i<pList->nSrc; i++){
|
||||
if( pList->a[i].zDatabase==0 ){
|
||||
pList->a[i].zDatabase = sqliteStrDup(zDb);
|
||||
}else if( sqliteStrICmp(pList->a[i].zDatabase,zDb)!=0 ){
|
||||
sqliteErrorMsg(pFix->pParse,
|
||||
}else if( sqlite3StrICmp(pList->a[i].zDatabase,zDb)!=0 ){
|
||||
sqlite3ErrorMsg(pFix->pParse,
|
||||
"%s %z cannot reference objects in database %s",
|
||||
pFix->zType, sqliteStrNDup(pFix->pName->z, pFix->pName->n),
|
||||
pList->a[i].zDatabase);
|
||||
return 1;
|
||||
}
|
||||
if( sqliteFixSelect(pFix, pList->a[i].pSelect) ) return 1;
|
||||
if( sqliteFixExpr(pFix, pList->a[i].pOn) ) return 1;
|
||||
if( sqlite3FixSelect(pFix, pList->a[i].pSelect) ) return 1;
|
||||
if( sqlite3FixExpr(pFix, pList->a[i].pOn) ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int sqliteFixSelect(
|
||||
int sqlite3FixSelect(
|
||||
DbFixer *pFix, /* Context of the fixation */
|
||||
Select *pSelect /* The SELECT statement to be fixed to one database */
|
||||
){
|
||||
while( pSelect ){
|
||||
if( sqliteFixExprList(pFix, pSelect->pEList) ){
|
||||
if( sqlite3FixExprList(pFix, pSelect->pEList) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqliteFixSrcList(pFix, pSelect->pSrc) ){
|
||||
if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqliteFixExpr(pFix, pSelect->pWhere) ){
|
||||
if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqliteFixExpr(pFix, pSelect->pHaving) ){
|
||||
if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
|
||||
return 1;
|
||||
}
|
||||
pSelect = pSelect->pPrior;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int sqliteFixExpr(
|
||||
int sqlite3FixExpr(
|
||||
DbFixer *pFix, /* Context of the fixation */
|
||||
Expr *pExpr /* The expression to be fixed to one database */
|
||||
){
|
||||
while( pExpr ){
|
||||
if( sqliteFixSelect(pFix, pExpr->pSelect) ){
|
||||
if( sqlite3FixSelect(pFix, pExpr->pSelect) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqliteFixExprList(pFix, pExpr->pList) ){
|
||||
if( sqlite3FixExprList(pFix, pExpr->pList) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqliteFixExpr(pFix, pExpr->pRight) ){
|
||||
if( sqlite3FixExpr(pFix, pExpr->pRight) ){
|
||||
return 1;
|
||||
}
|
||||
pExpr = pExpr->pLeft;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int sqliteFixExprList(
|
||||
int sqlite3FixExprList(
|
||||
DbFixer *pFix, /* Context of the fixation */
|
||||
ExprList *pList /* The expression to be fixed to one database */
|
||||
){
|
||||
int i;
|
||||
if( pList==0 ) return 0;
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
if( sqliteFixExpr(pFix, pList->a[i].pExpr) ){
|
||||
if( sqlite3FixExpr(pFix, pList->a[i].pExpr) ){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int sqliteFixTriggerStep(
|
||||
int sqlite3FixTriggerStep(
|
||||
DbFixer *pFix, /* Context of the fixation */
|
||||
TriggerStep *pStep /* The trigger step be fixed to one database */
|
||||
){
|
||||
while( pStep ){
|
||||
if( sqliteFixSelect(pFix, pStep->pSelect) ){
|
||||
if( sqlite3FixSelect(pFix, pStep->pSelect) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqliteFixExpr(pFix, pStep->pWhere) ){
|
||||
if( sqlite3FixExpr(pFix, pStep->pWhere) ){
|
||||
return 1;
|
||||
}
|
||||
if( sqliteFixExprList(pFix, pStep->pExprList) ){
|
||||
if( sqlite3FixExprList(pFix, pStep->pExprList) ){
|
||||
return 1;
|
||||
}
|
||||
pStep = pStep->pNext;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
23
src/auth.c
23
src/auth.c
@@ -14,7 +14,7 @@
|
||||
** systems that do not need this facility may omit it by recompiling
|
||||
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
|
||||
**
|
||||
** $Id: auth.c,v 1.12 2004/02/22 18:40:57 drh Exp $
|
||||
** $Id: auth.c,v 1.13 2004/05/08 08:23:21 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -85,7 +85,7 @@ int sqlite_set_authorizer(
|
||||
** user-supplied authorization function returned an illegal value.
|
||||
*/
|
||||
static void sqliteAuthBadReturnCode(Parse *pParse, int rc){
|
||||
sqliteErrorMsg(pParse, "illegal return value (%d) from the "
|
||||
sqlite3ErrorMsg(pParse, "illegal return value (%d) from the "
|
||||
"authorization function - should be SQLITE_OK, SQLITE_IGNORE, "
|
||||
"or SQLITE_DENY", rc);
|
||||
pParse->rc = SQLITE_MISUSE;
|
||||
@@ -100,7 +100,7 @@ static void sqliteAuthBadReturnCode(Parse *pParse, int rc){
|
||||
** instruction into a TK_NULL. If the auth function returns SQLITE_DENY,
|
||||
** then generate an error.
|
||||
*/
|
||||
void sqliteAuthRead(
|
||||
void sqlite3AuthRead(
|
||||
Parse *pParse, /* The parser context */
|
||||
Expr *pExpr, /* The expression to check authorization on */
|
||||
SrcList *pTabList /* All table that pExpr might refer to */
|
||||
@@ -147,10 +147,10 @@ void sqliteAuthRead(
|
||||
pExpr->op = TK_NULL;
|
||||
}else if( rc==SQLITE_DENY ){
|
||||
if( db->nDb>2 || pExpr->iDb!=0 ){
|
||||
sqliteErrorMsg(pParse, "access to %s.%s.%s is prohibited",
|
||||
sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",
|
||||
zDBase, pTab->zName, zCol);
|
||||
}else{
|
||||
sqliteErrorMsg(pParse, "access to %s.%s is prohibited", pTab->zName,zCol);
|
||||
sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", pTab->zName,zCol);
|
||||
}
|
||||
pParse->rc = SQLITE_AUTH;
|
||||
}else if( rc!=SQLITE_OK ){
|
||||
@@ -164,7 +164,7 @@ void sqliteAuthRead(
|
||||
** is returned, then the error count and error message in pParse are
|
||||
** modified appropriately.
|
||||
*/
|
||||
int sqliteAuthCheck(
|
||||
int sqlite3AuthCheck(
|
||||
Parse *pParse,
|
||||
int code,
|
||||
const char *zArg1,
|
||||
@@ -179,7 +179,7 @@ int sqliteAuthCheck(
|
||||
}
|
||||
rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
|
||||
if( rc==SQLITE_DENY ){
|
||||
sqliteErrorMsg(pParse, "not authorized");
|
||||
sqlite3ErrorMsg(pParse, "not authorized");
|
||||
pParse->rc = SQLITE_AUTH;
|
||||
}else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
|
||||
rc = SQLITE_DENY;
|
||||
@@ -193,7 +193,7 @@ int sqliteAuthCheck(
|
||||
** zArg3 argument to authorization callbacks will be zContext until
|
||||
** popped. Or if pParse==0, this routine is a no-op.
|
||||
*/
|
||||
void sqliteAuthContextPush(
|
||||
void sqlite3AuthContextPush(
|
||||
Parse *pParse,
|
||||
AuthContext *pContext,
|
||||
const char *zContext
|
||||
@@ -207,9 +207,9 @@ void sqliteAuthContextPush(
|
||||
|
||||
/*
|
||||
** Pop an authorization context that was previously pushed
|
||||
** by sqliteAuthContextPush
|
||||
** by sqlite3AuthContextPush
|
||||
*/
|
||||
void sqliteAuthContextPop(AuthContext *pContext){
|
||||
void sqlite3AuthContextPop(AuthContext *pContext){
|
||||
if( pContext->pParse ){
|
||||
pContext->pParse->zAuthContext = pContext->zAuthContext;
|
||||
pContext->pParse = 0;
|
||||
@@ -217,3 +217,6 @@ void sqliteAuthContextPop(AuthContext *pContext){
|
||||
}
|
||||
|
||||
#endif /* SQLITE_OMIT_AUTHORIZATION */
|
||||
|
||||
|
||||
|
||||
|
43
src/btree.c
43
src/btree.c
@@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btree.c,v 1.113 2004/05/08 02:03:23 drh Exp $
|
||||
** $Id: btree.c,v 1.114 2004/05/08 08:23:21 danielk1977 Exp $
|
||||
**
|
||||
** This file implements a external (disk-based) database using BTrees.
|
||||
** For a detailed discussion of BTrees, refer to
|
||||
@@ -3413,10 +3413,10 @@ static void checkAppendMsg(IntegrityCk *pCheck, char *zMsg1, char *zMsg2){
|
||||
if( pCheck->zErrMsg ){
|
||||
char *zOld = pCheck->zErrMsg;
|
||||
pCheck->zErrMsg = 0;
|
||||
sqliteSetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, (char*)0);
|
||||
sqlite3SetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, (char*)0);
|
||||
sqliteFree(zOld);
|
||||
}else{
|
||||
sqliteSetString(&pCheck->zErrMsg, zMsg1, zMsg2, (char*)0);
|
||||
sqlite3SetString(&pCheck->zErrMsg, zMsg1, zMsg2, (char*)0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3764,3 +3764,40 @@ int sqlite3BtreeCopyFile(Btree *pBtTo, Btree *pBtFrom){
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int sqlite3BtreeKeyCompare(
|
||||
BtCursor *pCur, /* Pointer to entry to compare against */
|
||||
const void *pKey, /* Key to compare against entry that pCur points to */
|
||||
int nKey, /* Number of bytes in pKey */
|
||||
int nIgnore, /* Ignore this many bytes at the end of pCur */
|
||||
int *pResult /* Write the result here */
|
||||
){
|
||||
void *pCellKey;
|
||||
u64 nCellKey;
|
||||
int rc;
|
||||
|
||||
sqlite3BtreeKeySize(pCur, &nCellKey);
|
||||
nCellKey = nCellKey - nIgnore;
|
||||
if( nCellKey<=0 ){
|
||||
*pResult = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
pCellKey = sqlite3BtreeKeyFetch(pCur);
|
||||
if( pCellKey ){
|
||||
*pResult = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
pCellKey = sqliteMalloc( nCellKey );
|
||||
if( pCellKey==0 ) return SQLITE_NOMEM;
|
||||
|
||||
rc = sqlite3BtreeKey(pCur, 0, nCellKey, pCellKey);
|
||||
*pResult = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
|
||||
sqliteFree(pCellKey);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
14
src/btree.h
14
src/btree.h
@@ -13,11 +13,16 @@
|
||||
** subsystem. See comments in the source code for a detailed description
|
||||
** of what each interface routine does.
|
||||
**
|
||||
** @(#) $Id: btree.h,v 1.39 2004/05/07 23:50:57 drh Exp $
|
||||
** @(#) $Id: btree.h,v 1.40 2004/05/08 08:23:23 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _BTREE_H_
|
||||
#define _BTREE_H_
|
||||
|
||||
/* TODO: This definition is just included so other modules compile. It
|
||||
** needs to be revisited.
|
||||
*/
|
||||
#define SQLITE_N_BTREE_META 10
|
||||
|
||||
/*
|
||||
** Forward declarations of structure
|
||||
*/
|
||||
@@ -44,6 +49,9 @@ int sqlite3BtreeCommitStmt(Btree*);
|
||||
int sqlite3BtreeRollbackStmt(Btree*);
|
||||
int sqlite3BtreeCreateTable(Btree*, int*, int flags);
|
||||
|
||||
const char *sqlite3BtreeGetFilename(Btree *);
|
||||
int sqlite3BtreeCopyFile(Btree *, Btree *);
|
||||
|
||||
/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
|
||||
** of the following flags:
|
||||
*/
|
||||
@@ -79,6 +87,7 @@ int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
|
||||
void *sqlite3BtreeKeyFetch(BtCursor*);
|
||||
int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
|
||||
int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
|
||||
int sqlite3BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
|
||||
|
||||
char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot);
|
||||
struct Pager *sqlite3BtreePager(Btree*);
|
||||
@@ -91,3 +100,6 @@ int sqlite3BtreePageDump(Btree*, int, int recursive);
|
||||
|
||||
|
||||
#endif /* _BTREE_H_ */
|
||||
|
||||
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btree_rb.c,v 1.24 2004/02/29 00:11:31 drh Exp $
|
||||
** $Id: btree_rb.c,v 1.25 2004/05/08 08:23:23 danielk1977 Exp $
|
||||
**
|
||||
** This file implements an in-core database using Red-Black balanced
|
||||
** binary trees.
|
||||
@@ -265,7 +265,7 @@ static char *append_val(char * orig, char const * val){
|
||||
z = sqliteStrDup( val );
|
||||
} else{
|
||||
z = 0;
|
||||
sqliteSetString(&z, orig, val, (char*)0);
|
||||
sqlite3SetString(&z, orig, val, (char*)0);
|
||||
sqliteFree( orig );
|
||||
}
|
||||
return z;
|
||||
@@ -585,7 +585,7 @@ void do_delete_balancing(BtRbTree *pTree, BtRbNode *pX, BtRbNode *pParent)
|
||||
static void btreeCreateTable(Rbtree* pRbtree, int n)
|
||||
{
|
||||
BtRbTree *pNewTbl = sqliteMalloc(sizeof(BtRbTree));
|
||||
sqliteHashInsert(&pRbtree->tblHash, 0, n, pNewTbl);
|
||||
sqlite3HashInsert(&pRbtree->tblHash, 0, n, pNewTbl);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -618,7 +618,7 @@ int sqliteRbtreeOpen(
|
||||
Rbtree **ppRbtree = (Rbtree**)ppBtree;
|
||||
*ppRbtree = (Rbtree *)sqliteMalloc(sizeof(Rbtree));
|
||||
if( sqlite_malloc_failed ) goto open_no_mem;
|
||||
sqliteHashInit(&(*ppRbtree)->tblHash, SQLITE_HASH_INT, 0);
|
||||
sqlite3HashInit(&(*ppRbtree)->tblHash, SQLITE_HASH_INT, 0);
|
||||
|
||||
/* Create a binary tree for the SQLITE_MASTER table at location 2 */
|
||||
btreeCreateTable(*ppRbtree, 2);
|
||||
@@ -671,7 +671,7 @@ static int memRbtreeDropTable(Rbtree* tree, int n)
|
||||
assert( tree->eTransState != TRANS_NONE );
|
||||
|
||||
memRbtreeClearTable(tree, n);
|
||||
pTree = sqliteHashInsert(&tree->tblHash, 0, n, 0);
|
||||
pTree = sqlite3HashInsert(&tree->tblHash, 0, n, 0);
|
||||
assert(pTree);
|
||||
assert( pTree->pCursors==0 );
|
||||
sqliteFree(pTree);
|
||||
@@ -721,7 +721,7 @@ static int memRbtreeCursor(
|
||||
assert(tree);
|
||||
pCur = *ppCur = sqliteMalloc(sizeof(RbtCursor));
|
||||
if( sqlite_malloc_failed ) return SQLITE_NOMEM;
|
||||
pCur->pTree = sqliteHashFind(&tree->tblHash, 0, iTable);
|
||||
pCur->pTree = sqlite3HashFind(&tree->tblHash, 0, iTable);
|
||||
assert( pCur->pTree );
|
||||
pCur->pRbtree = tree;
|
||||
pCur->iTree = iTable;
|
||||
@@ -1028,7 +1028,7 @@ static int memRbtreeClearTable(Rbtree* tree, int n)
|
||||
BtRbTree *pTree;
|
||||
BtRbNode *pNode;
|
||||
|
||||
pTree = sqliteHashFind(&tree->tblHash, 0, n);
|
||||
pTree = sqlite3HashFind(&tree->tblHash, 0, n);
|
||||
assert(pTree);
|
||||
|
||||
pNode = pTree->pHead;
|
||||
@@ -1306,7 +1306,7 @@ static int memRbtreeClose(Rbtree* tree)
|
||||
tree->eTransState = TRANS_ROLLBACK;
|
||||
memRbtreeDropTable(tree, sqliteHashKeysize(p));
|
||||
}
|
||||
sqliteHashClear(&tree->tblHash);
|
||||
sqlite3HashClear(&tree->tblHash);
|
||||
sqliteFree(tree);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -1325,7 +1325,7 @@ static void execute_rollback_list(Rbtree *pRbtree, BtRollbackOp *pList)
|
||||
while( pList ){
|
||||
switch( pList->eOp ){
|
||||
case ROLLBACK_INSERT:
|
||||
cur.pTree = sqliteHashFind( &pRbtree->tblHash, 0, pList->iTab );
|
||||
cur.pTree = sqlite3HashFind( &pRbtree->tblHash, 0, pList->iTab );
|
||||
assert(cur.pTree);
|
||||
cur.iTree = pList->iTab;
|
||||
cur.eSkip = SKIP_NONE;
|
||||
@@ -1333,7 +1333,7 @@ static void execute_rollback_list(Rbtree *pRbtree, BtRollbackOp *pList)
|
||||
pList->nKey, pList->pData, pList->nData );
|
||||
break;
|
||||
case ROLLBACK_DELETE:
|
||||
cur.pTree = sqliteHashFind( &pRbtree->tblHash, 0, pList->iTab );
|
||||
cur.pTree = sqlite3HashFind( &pRbtree->tblHash, 0, pList->iTab );
|
||||
assert(cur.pTree);
|
||||
cur.iTree = pList->iTab;
|
||||
cur.eSkip = SKIP_NONE;
|
||||
@@ -1486,3 +1486,6 @@ static BtCursorOps sqliteRbtreeCursorOps = {
|
||||
};
|
||||
|
||||
#endif /* SQLITE_OMIT_INMEMORYDB */
|
||||
|
||||
|
||||
|
||||
|
619
src/build.c
619
src/build.c
File diff suppressed because it is too large
Load Diff
71
src/copy.c
71
src/copy.c
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code used to implement the COPY command.
|
||||
**
|
||||
** $Id: copy.c,v 1.9 2004/02/25 13:47:31 drh Exp $
|
||||
** $Id: copy.c,v 1.10 2004/05/08 08:23:24 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
** file to fill this table with data. File might be "stdin". The optional
|
||||
** delimiter string identifies the field separators. The default is a tab.
|
||||
*/
|
||||
void sqliteCopy(
|
||||
void sqlite3Copy(
|
||||
Parse *pParse, /* The parser context */
|
||||
SrcList *pTableName, /* The name of the table into which we will insert */
|
||||
Token *pFilename, /* The file from which to obtain information */
|
||||
@@ -44,67 +44,70 @@ void sqliteCopy(
|
||||
|
||||
if( sqlite_malloc_failed ) goto copy_cleanup;
|
||||
assert( pTableName->nSrc==1 );
|
||||
pTab = sqliteSrcListLookup(pParse, pTableName);
|
||||
if( pTab==0 || sqliteIsReadOnly(pParse, pTab, 0) ) goto copy_cleanup;
|
||||
pTab = sqlite3SrcListLookup(pParse, pTableName);
|
||||
if( pTab==0 || sqlite3IsReadOnly(pParse, pTab, 0) ) goto copy_cleanup;
|
||||
zFile = sqliteStrNDup(pFilename->z, pFilename->n);
|
||||
sqliteDequote(zFile);
|
||||
sqlite3Dequote(zFile);
|
||||
assert( pTab->iDb<db->nDb );
|
||||
zDb = db->aDb[pTab->iDb].zName;
|
||||
if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb)
|
||||
|| sqliteAuthCheck(pParse, SQLITE_COPY, pTab->zName, zFile, zDb) ){
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb)
|
||||
|| sqlite3AuthCheck(pParse, SQLITE_COPY, pTab->zName, zFile, zDb) ){
|
||||
goto copy_cleanup;
|
||||
}
|
||||
v = sqliteGetVdbe(pParse);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v ){
|
||||
sqliteBeginWriteOperation(pParse, 1, pTab->iDb);
|
||||
addr = sqliteVdbeOp3(v, OP_FileOpen, 0, 0, pFilename->z, pFilename->n);
|
||||
sqliteVdbeDequoteP3(v, addr);
|
||||
sqliteOpenTableAndIndices(pParse, pTab, 0);
|
||||
sqlite3BeginWriteOperation(pParse, 1, pTab->iDb);
|
||||
addr = sqlite3VdbeOp3(v, OP_FileOpen, 0, 0, pFilename->z, pFilename->n);
|
||||
sqlite3VdbeDequoteP3(v, addr);
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, 0);
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0); /* Initialize the row count */
|
||||
sqlite3VdbeAddOp(v, OP_Integer, 0, 0); /* Initialize the row count */
|
||||
}
|
||||
end = sqliteVdbeMakeLabel(v);
|
||||
addr = sqliteVdbeAddOp(v, OP_FileRead, pTab->nCol, end);
|
||||
end = sqlite3VdbeMakeLabel(v);
|
||||
addr = sqlite3VdbeAddOp(v, OP_FileRead, pTab->nCol, end);
|
||||
if( pDelimiter ){
|
||||
sqliteVdbeChangeP3(v, addr, pDelimiter->z, pDelimiter->n);
|
||||
sqliteVdbeDequoteP3(v, addr);
|
||||
sqlite3VdbeChangeP3(v, addr, pDelimiter->z, pDelimiter->n);
|
||||
sqlite3VdbeDequoteP3(v, addr);
|
||||
}else{
|
||||
sqliteVdbeChangeP3(v, addr, "\t", 1);
|
||||
sqlite3VdbeChangeP3(v, addr, "\t", 1);
|
||||
}
|
||||
if( pTab->iPKey>=0 ){
|
||||
sqliteVdbeAddOp(v, OP_FileColumn, pTab->iPKey, 0);
|
||||
sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_FileColumn, pTab->iPKey, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0);
|
||||
}
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
if( i==pTab->iPKey ){
|
||||
/* The integer primary key column is filled with NULL since its
|
||||
** value is always pulled from the record number */
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_String, 0, 0);
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_FileColumn, i, 0);
|
||||
sqlite3VdbeAddOp(v, OP_FileColumn, i, 0);
|
||||
}
|
||||
}
|
||||
sqliteGenerateConstraintChecks(pParse, pTab, 0, 0, pTab->iPKey>=0,
|
||||
sqlite3GenerateConstraintChecks(pParse, pTab, 0, 0, pTab->iPKey>=0,
|
||||
0, onError, addr);
|
||||
sqliteCompleteInsertion(pParse, pTab, 0, 0, 0, 0, -1);
|
||||
sqlite3CompleteInsertion(pParse, pTab, 0, 0, 0, 0, -1);
|
||||
if( (db->flags & SQLITE_CountRows)!=0 ){
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 1, 0); /* Increment row count */
|
||||
sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); /* Increment row count */
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
|
||||
sqliteVdbeResolveLabel(v, end);
|
||||
sqliteVdbeAddOp(v, OP_Noop, 0, 0);
|
||||
sqliteEndWriteOperation(pParse);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
|
||||
sqlite3VdbeResolveLabel(v, end);
|
||||
sqlite3VdbeAddOp(v, OP_Noop, 0, 0);
|
||||
sqlite3EndWriteOperation(pParse);
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, 0, 1);
|
||||
sqliteVdbeChangeP3(v, -1, "rows inserted", P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_ColumnName, 0, 1);
|
||||
sqlite3VdbeChangeP3(v, -1, "rows inserted", P3_STATIC);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
copy_cleanup:
|
||||
sqliteSrcListDelete(pTableName);
|
||||
sqlite3SrcListDelete(pTableName);
|
||||
sqliteFree(zFile);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
23
src/date.c
23
src/date.c
@@ -13,10 +13,10 @@
|
||||
** functions for SQLite.
|
||||
**
|
||||
** There is only one exported symbol in this file - the function
|
||||
** sqliteRegisterDateTimeFunctions() found at the bottom of the file.
|
||||
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
|
||||
** All other code has file scope.
|
||||
**
|
||||
** $Id: date.c,v 1.16 2004/02/29 01:08:18 drh Exp $
|
||||
** $Id: date.c,v 1.17 2004/05/08 08:23:24 danielk1977 Exp $
|
||||
**
|
||||
** NOTES:
|
||||
**
|
||||
@@ -126,7 +126,7 @@ static int getDigits(const char *zDate, ...){
|
||||
*/
|
||||
static int getValue(const char *z, double *pR){
|
||||
const char *zEnd;
|
||||
*pR = sqliteAtoF(z, &zEnd);
|
||||
*pR = sqlite3AtoF(z, &zEnd);
|
||||
return zEnd - z;
|
||||
}
|
||||
|
||||
@@ -313,16 +313,16 @@ static int parseDateOrTime(const char *zDate, DateTime *p){
|
||||
return 0;
|
||||
}else if( parseHhMmSs(zDate, p)==0 ){
|
||||
return 0;
|
||||
}else if( sqliteStrICmp(zDate,"now")==0){
|
||||
}else if( sqlite3StrICmp(zDate,"now")==0){
|
||||
double r;
|
||||
if( sqliteOsCurrentTime(&r)==0 ){
|
||||
if( sqlite3OsCurrentTime(&r)==0 ){
|
||||
p->rJD = r;
|
||||
p->validJD = 1;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}else if( sqliteIsNumber(zDate) ){
|
||||
p->rJD = sqliteAtoF(zDate, 0);
|
||||
}else if( sqlite3IsNumber(zDate) ){
|
||||
p->rJD = sqlite3AtoF(zDate, 0);
|
||||
p->validJD = 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -415,7 +415,7 @@ static double localtimeOffset(DateTime *p){
|
||||
x.validJD = 0;
|
||||
computeJD(&x);
|
||||
t = (x.rJD-2440587.5)*86400.0 + 0.5;
|
||||
sqliteOsEnterMutex();
|
||||
sqlite3OsEnterMutex();
|
||||
pTm = localtime(&t);
|
||||
y.Y = pTm->tm_year + 1900;
|
||||
y.M = pTm->tm_mon + 1;
|
||||
@@ -423,7 +423,7 @@ static double localtimeOffset(DateTime *p){
|
||||
y.h = pTm->tm_hour;
|
||||
y.m = pTm->tm_min;
|
||||
y.s = pTm->tm_sec;
|
||||
sqliteOsLeaveMutex();
|
||||
sqlite3OsLeaveMutex();
|
||||
y.validYMD = 1;
|
||||
y.validHMS = 1;
|
||||
y.validJD = 0;
|
||||
@@ -846,7 +846,7 @@ static void strftimeFunc(sqlite_func *context, int argc, const char **argv){
|
||||
** functions. This should be the only routine in this file with
|
||||
** external linkage.
|
||||
*/
|
||||
void sqliteRegisterDateTimeFunctions(sqlite *db){
|
||||
void sqlite3RegisterDateTimeFunctions(sqlite *db){
|
||||
static struct {
|
||||
char *zName;
|
||||
int nArg;
|
||||
@@ -871,3 +871,6 @@ void sqliteRegisterDateTimeFunctions(sqlite *db){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
163
src/delete.c
163
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.61 2004/02/24 01:05:32 drh Exp $
|
||||
** $Id: delete.c,v 1.62 2004/05/08 08:23:24 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -21,13 +21,13 @@
|
||||
** add an error message to pParse->zErrMsg and return NULL. If all tables
|
||||
** are found, return a pointer to the last table.
|
||||
*/
|
||||
Table *sqliteSrcListLookup(Parse *pParse, SrcList *pSrc){
|
||||
Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
|
||||
Table *pTab = 0;
|
||||
int i;
|
||||
for(i=0; i<pSrc->nSrc; i++){
|
||||
const char *zTab = pSrc->a[i].zName;
|
||||
const char *zDb = pSrc->a[i].zDatabase;
|
||||
pTab = sqliteLocateTable(pParse, zTab, zDb);
|
||||
pTab = sqlite3LocateTable(pParse, zTab, zDb);
|
||||
pSrc->a[i].pTab = pTab;
|
||||
}
|
||||
return pTab;
|
||||
@@ -38,13 +38,13 @@ Table *sqliteSrcListLookup(Parse *pParse, SrcList *pSrc){
|
||||
** writable, generate an error message and return 1. If it is
|
||||
** writable return 0;
|
||||
*/
|
||||
int sqliteIsReadOnly(Parse *pParse, Table *pTab, int viewOk){
|
||||
int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
|
||||
if( pTab->readOnly ){
|
||||
sqliteErrorMsg(pParse, "table %s may not be modified", pTab->zName);
|
||||
sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
|
||||
return 1;
|
||||
}
|
||||
if( !viewOk && pTab->pSelect ){
|
||||
sqliteErrorMsg(pParse, "cannot modify %s because it is a view",pTab->zName);
|
||||
sqlite3ErrorMsg(pParse, "cannot modify %s because it is a view",pTab->zName);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -53,7 +53,7 @@ int sqliteIsReadOnly(Parse *pParse, Table *pTab, int viewOk){
|
||||
/*
|
||||
** Process a DELETE FROM statement.
|
||||
*/
|
||||
void sqliteDeleteFrom(
|
||||
void sqlite3DeleteFrom(
|
||||
Parse *pParse, /* The parser context */
|
||||
SrcList *pTabList, /* The table from which we should delete things */
|
||||
Expr *pWhere /* The WHERE clause. May be null */
|
||||
@@ -88,26 +88,26 @@ void sqliteDeleteFrom(
|
||||
** will be calling are designed to work with multiple tables and expect
|
||||
** an SrcList* parameter instead of just a Table* parameter.
|
||||
*/
|
||||
pTab = sqliteSrcListLookup(pParse, pTabList);
|
||||
pTab = sqlite3SrcListLookup(pParse, pTabList);
|
||||
if( pTab==0 ) goto delete_from_cleanup;
|
||||
before_triggers = sqliteTriggersExist(pParse, pTab->pTrigger,
|
||||
before_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger,
|
||||
TK_DELETE, TK_BEFORE, TK_ROW, 0);
|
||||
after_triggers = sqliteTriggersExist(pParse, pTab->pTrigger,
|
||||
after_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger,
|
||||
TK_DELETE, TK_AFTER, TK_ROW, 0);
|
||||
row_triggers_exist = before_triggers || after_triggers;
|
||||
isView = pTab->pSelect!=0;
|
||||
if( sqliteIsReadOnly(pParse, pTab, before_triggers) ){
|
||||
if( sqlite3IsReadOnly(pParse, pTab, before_triggers) ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
assert( pTab->iDb<db->nDb );
|
||||
zDb = db->aDb[pTab->iDb].zName;
|
||||
if( sqliteAuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
|
||||
/* If pTab is really a view, make sure it has been initialized.
|
||||
*/
|
||||
if( isView && sqliteViewGetColumnNames(pParse, pTab) ){
|
||||
if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
|
||||
@@ -122,10 +122,10 @@ void sqliteDeleteFrom(
|
||||
assert( pTabList->nSrc==1 );
|
||||
iCur = pTabList->a[0].iCursor = pParse->nTab++;
|
||||
if( pWhere ){
|
||||
if( sqliteExprResolveIds(pParse, pTabList, 0, pWhere) ){
|
||||
if( sqlite3ExprResolveIds(pParse, pTabList, 0, pWhere) ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
|
||||
if( sqlite3ExprCheck(pParse, pWhere, 0, 0) ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
}
|
||||
@@ -133,31 +133,31 @@ void sqliteDeleteFrom(
|
||||
/* Start the view context
|
||||
*/
|
||||
if( isView ){
|
||||
sqliteAuthContextPush(pParse, &sContext, pTab->zName);
|
||||
sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
|
||||
}
|
||||
|
||||
/* Begin generating code.
|
||||
*/
|
||||
v = sqliteGetVdbe(pParse);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v==0 ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
sqliteBeginWriteOperation(pParse, row_triggers_exist, pTab->iDb);
|
||||
sqlite3BeginWriteOperation(pParse, row_triggers_exist, pTab->iDb);
|
||||
|
||||
/* If we are trying to delete from a view, construct that view into
|
||||
** a temporary table.
|
||||
*/
|
||||
if( isView ){
|
||||
Select *pView = sqliteSelectDup(pTab->pSelect);
|
||||
sqliteSelect(pParse, pView, SRT_TempTable, iCur, 0, 0, 0);
|
||||
sqliteSelectDelete(pView);
|
||||
Select *pView = sqlite3SelectDup(pTab->pSelect);
|
||||
sqlite3Select(pParse, pView, SRT_TempTable, iCur, 0, 0, 0);
|
||||
sqlite3SelectDelete(pView);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
||||
}
|
||||
|
||||
/* Special case: A DELETE without a WHERE clause deletes everything.
|
||||
@@ -168,22 +168,22 @@ void sqliteDeleteFrom(
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
/* If counting rows deleted, just count the total number of
|
||||
** entries in the table. */
|
||||
int endOfLoop = sqliteVdbeMakeLabel(v);
|
||||
int endOfLoop = sqlite3VdbeMakeLabel(v);
|
||||
int addr;
|
||||
if( !isView ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Rewind, iCur, sqliteVdbeCurrentAddr(v)+2);
|
||||
addr = sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_Next, iCur, addr);
|
||||
sqliteVdbeResolveLabel(v, endOfLoop);
|
||||
sqliteVdbeAddOp(v, OP_Close, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
|
||||
addr = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Next, iCur, addr);
|
||||
sqlite3VdbeResolveLabel(v, endOfLoop);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}
|
||||
if( !isView ){
|
||||
sqliteVdbeAddOp(v, OP_Clear, pTab->tnum, pTab->iDb);
|
||||
sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, pTab->iDb);
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
sqliteVdbeAddOp(v, OP_Clear, pIdx->tnum, pIdx->iDb);
|
||||
sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, pIdx->iDb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,53 +194,53 @@ void sqliteDeleteFrom(
|
||||
else{
|
||||
/* Begin the database scan
|
||||
*/
|
||||
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1, 0);
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 1, 0);
|
||||
if( pWInfo==0 ) goto delete_from_cleanup;
|
||||
|
||||
/* Remember the key of every item to be deleted.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
}
|
||||
|
||||
/* End the database scan loop.
|
||||
*/
|
||||
sqliteWhereEnd(pWInfo);
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
|
||||
/* Open the pseudo-table used to store OLD if there are triggers.
|
||||
*/
|
||||
if( row_triggers_exist ){
|
||||
sqliteVdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
|
||||
}
|
||||
|
||||
/* Delete every item whose key was written to the list during the
|
||||
** database scan. We have to delete items after the scan is complete
|
||||
** because deleting an item can change the scan order.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
|
||||
end = sqliteVdbeMakeLabel(v);
|
||||
sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
|
||||
end = sqlite3VdbeMakeLabel(v);
|
||||
|
||||
/* This is the beginning of the delete loop when there are
|
||||
** row triggers.
|
||||
*/
|
||||
if( row_triggers_exist ){
|
||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
||||
if( !isView ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0);
|
||||
|
||||
sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
|
||||
sqliteVdbeAddOp(v, OP_RowData, iCur, 0);
|
||||
sqliteVdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
|
||||
if( !isView ){
|
||||
sqliteVdbeAddOp(v, OP_Close, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}
|
||||
|
||||
sqliteCodeRowTrigger(pParse, TK_DELETE, 0, TK_BEFORE, pTab, -1,
|
||||
sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TK_BEFORE, pTab, -1,
|
||||
oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
|
||||
addr);
|
||||
}
|
||||
@@ -253,16 +253,16 @@ void sqliteDeleteFrom(
|
||||
** cursors are opened only once on the outside the loop.
|
||||
*/
|
||||
pParse->nTab = iCur + 1;
|
||||
sqliteOpenTableAndIndices(pParse, pTab, iCur);
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, iCur);
|
||||
|
||||
/* This is the beginning of the delete loop when there are no
|
||||
** row triggers */
|
||||
if( !row_triggers_exist ){
|
||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end);
|
||||
addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
|
||||
}
|
||||
|
||||
/* Delete the row */
|
||||
sqliteGenerateRowDelete(db, v, pTab, iCur, pParse->trigStack==0);
|
||||
sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->trigStack==0);
|
||||
}
|
||||
|
||||
/* If there are row triggers, close all cursors then invoke
|
||||
@@ -271,45 +271,45 @@ void sqliteDeleteFrom(
|
||||
if( row_triggers_exist ){
|
||||
if( !isView ){
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||
sqliteVdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Close, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}
|
||||
sqliteCodeRowTrigger(pParse, TK_DELETE, 0, TK_AFTER, pTab, -1,
|
||||
sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TK_AFTER, pTab, -1,
|
||||
oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
|
||||
addr);
|
||||
}
|
||||
|
||||
/* End of the delete loop */
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
|
||||
sqliteVdbeResolveLabel(v, end);
|
||||
sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
|
||||
sqlite3VdbeResolveLabel(v, end);
|
||||
sqlite3VdbeAddOp(v, OP_ListReset, 0, 0);
|
||||
|
||||
/* Close the cursors after the loop if there are no row triggers */
|
||||
if( !row_triggers_exist ){
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||
sqliteVdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Close, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
pParse->nTab = iCur;
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_SetCounts, 0, 0);
|
||||
sqliteEndWriteOperation(pParse);
|
||||
sqlite3VdbeAddOp(v, OP_SetCounts, 0, 0);
|
||||
sqlite3EndWriteOperation(pParse);
|
||||
|
||||
/*
|
||||
** Return the number of rows that were deleted.
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqliteVdbeAddOp(v, OP_ColumnName, 0, 1);
|
||||
sqliteVdbeChangeP3(v, -1, "rows deleted", P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_ColumnName, 0, 1);
|
||||
sqlite3VdbeChangeP3(v, -1, "rows deleted", P3_STATIC);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||
}
|
||||
|
||||
delete_from_cleanup:
|
||||
sqliteAuthContextPop(&sContext);
|
||||
sqliteSrcListDelete(pTabList);
|
||||
sqliteExprDelete(pWhere);
|
||||
sqlite3AuthContextPop(&sContext);
|
||||
sqlite3SrcListDelete(pTabList);
|
||||
sqlite3ExprDelete(pWhere);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -333,7 +333,7 @@ delete_from_cleanup:
|
||||
** and then generates code to remove both the table record and all index
|
||||
** entries that point to that record.
|
||||
*/
|
||||
void sqliteGenerateRowDelete(
|
||||
void sqlite3GenerateRowDelete(
|
||||
sqlite *db, /* The database containing the index */
|
||||
Vdbe *v, /* Generate code into this VDBE */
|
||||
Table *pTab, /* Table containing the row to be deleted */
|
||||
@@ -341,11 +341,11 @@ void sqliteGenerateRowDelete(
|
||||
int count /* Increment the row change counter */
|
||||
){
|
||||
int addr;
|
||||
addr = sqliteVdbeAddOp(v, OP_NotExists, iCur, 0);
|
||||
sqliteGenerateRowIndexDelete(db, v, pTab, iCur, 0);
|
||||
sqliteVdbeAddOp(v, OP_Delete, iCur,
|
||||
addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0);
|
||||
sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Delete, iCur,
|
||||
(count?OPFLAG_NCHANGE:0) | OPFLAG_CSCHANGE);
|
||||
sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
|
||||
sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -364,7 +364,7 @@ void sqliteGenerateRowDelete(
|
||||
** 3. The "iCur" cursor must be pointing to the row that is to be
|
||||
** deleted.
|
||||
*/
|
||||
void sqliteGenerateRowIndexDelete(
|
||||
void sqlite3GenerateRowIndexDelete(
|
||||
sqlite *db, /* The database containing the index */
|
||||
Vdbe *v, /* Generate code into this VDBE */
|
||||
Table *pTab, /* Table containing the row to be deleted */
|
||||
@@ -377,17 +377,20 @@ void sqliteGenerateRowIndexDelete(
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||
int j;
|
||||
if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;
|
||||
sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
|
||||
for(j=0; j<pIdx->nColumn; j++){
|
||||
int idx = pIdx->aiColumn[j];
|
||||
if( idx==pTab->iPKey ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, j, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, j, 0);
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_Column, iCur, idx);
|
||||
sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||
if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
|
||||
sqliteVdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||
if( db->file_format>=4 ) sqlite3AddIdxKeyType(v, pIdx);
|
||||
sqlite3VdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
** data in an SQLite database. The code in this file is not used by any other
|
||||
** part of the SQLite library.
|
||||
**
|
||||
** $Id: encode.c,v 1.12 2004/03/17 18:44:46 drh Exp $
|
||||
** $Id: encode.c,v 1.13 2004/05/08 08:23:24 danielk1977 Exp $
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@@ -252,3 +252,6 @@ int main(int argc, char **argv){
|
||||
(nByteOut-nByteIn)*100.0/(double)nByteIn);
|
||||
}
|
||||
#endif /* ENCODER_TEST */
|
||||
|
||||
|
||||
|
||||
|
537
src/expr.c
537
src/expr.c
File diff suppressed because it is too large
Load Diff
35
src/func.c
35
src/func.c
@@ -16,7 +16,7 @@
|
||||
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
|
||||
** All other code has file scope.
|
||||
**
|
||||
** $Id: func.c,v 1.43 2004/02/25 22:51:06 rdc Exp $
|
||||
** $Id: func.c,v 1.44 2004/05/08 08:23:25 danielk1977 Exp $
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
@@ -39,7 +39,7 @@ static void minmaxFunc(sqlite_func *context, int argc, const char **argv){
|
||||
zBest = argv[0];
|
||||
if( zBest==0 ) return;
|
||||
if( argv[1][0]=='n' ){
|
||||
xCompare = sqliteCompare;
|
||||
xCompare = sqlite3Compare;
|
||||
}else{
|
||||
xCompare = strcmp;
|
||||
}
|
||||
@@ -148,7 +148,7 @@ static void roundFunc(sqlite_func *context, int argc, const char **argv){
|
||||
n = argc==2 ? atoi(argv[1]) : 0;
|
||||
if( n>30 ) n = 30;
|
||||
if( n<0 ) n = 0;
|
||||
r = sqliteAtoF(argv[0], 0);
|
||||
r = sqlite3AtoF(argv[0], 0);
|
||||
sprintf(zBuf,"%.*f",n,r);
|
||||
sqlite_set_result_string(context, zBuf, -1);
|
||||
}
|
||||
@@ -197,7 +197,7 @@ static void ifnullFunc(sqlite_func *context, int argc, const char **argv){
|
||||
*/
|
||||
static void randomFunc(sqlite_func *context, int argc, const char **argv){
|
||||
int r;
|
||||
sqliteRandomness(sizeof(r), &r);
|
||||
sqlite3Randomness(sizeof(r), &r);
|
||||
sqlite_set_result_int(context, r);
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ static void last_statement_change_count(sqlite_func *context, int arg,
|
||||
static void likeFunc(sqlite_func *context, int arg, const char **argv){
|
||||
if( argv[0]==0 || argv[1]==0 ) return;
|
||||
sqlite_set_result_int(context,
|
||||
sqliteLikeCompare((const unsigned char*)argv[0],
|
||||
sqlite3LikeCompare((const unsigned char*)argv[0],
|
||||
(const unsigned char*)argv[1]));
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ static void likeFunc(sqlite_func *context, int arg, const char **argv){
|
||||
static void globFunc(sqlite_func *context, int arg, const char **argv){
|
||||
if( argv[0]==0 || argv[1]==0 ) return;
|
||||
sqlite_set_result_int(context,
|
||||
sqliteGlobCompare((const unsigned char*)argv[0],
|
||||
sqlite3GlobCompare((const unsigned char*)argv[0],
|
||||
(const unsigned char*)argv[1]));
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ static void globFunc(sqlite_func *context, int arg, const char **argv){
|
||||
** arguments are equal to each other.
|
||||
*/
|
||||
static void nullifFunc(sqlite_func *context, int argc, const char **argv){
|
||||
if( argv[0]!=0 && sqliteCompare(argv[0],argv[1])!=0 ){
|
||||
if( argv[0]!=0 && sqlite3Compare(argv[0],argv[1])!=0 ){
|
||||
sqlite_set_result_string(context, argv[0], -1);
|
||||
}
|
||||
}
|
||||
@@ -295,7 +295,7 @@ static void quoteFunc(sqlite_func *context, int argc, const char **argv){
|
||||
if( argc<1 ) return;
|
||||
if( argv[0]==0 ){
|
||||
sqlite_set_result_string(context, "NULL", 4);
|
||||
}else if( sqliteIsNumber(argv[0]) ){
|
||||
}else if( sqlite3IsNumber(argv[0]) ){
|
||||
sqlite_set_result_string(context, argv[0], -1);
|
||||
}else{
|
||||
int i,j,n;
|
||||
@@ -386,12 +386,12 @@ static void randStr(sqlite_func *context, int argc, const char **argv){
|
||||
}
|
||||
n = iMin;
|
||||
if( iMax>iMin ){
|
||||
sqliteRandomness(sizeof(r), &r);
|
||||
sqlite3Randomness(sizeof(r), &r);
|
||||
r &= 0x7fffffff;
|
||||
n += r%(iMax + 1 - iMin);
|
||||
}
|
||||
assert( n<sizeof(zBuf) );
|
||||
sqliteRandomness(n, zBuf);
|
||||
sqlite3Randomness(n, zBuf);
|
||||
for(i=0; i<n; i++){
|
||||
zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
|
||||
}
|
||||
@@ -418,7 +418,7 @@ static void sumStep(sqlite_func *context, int argc, const char **argv){
|
||||
if( argc<1 ) return;
|
||||
p = sqlite_aggregate_context(context, sizeof(*p));
|
||||
if( p && argv[0] ){
|
||||
p->sum += sqliteAtoF(argv[0], 0);
|
||||
p->sum += sqlite3AtoF(argv[0], 0);
|
||||
p->cnt++;
|
||||
}
|
||||
}
|
||||
@@ -456,7 +456,7 @@ static void stdDevStep(sqlite_func *context, int argc, const char **argv){
|
||||
if( argc<1 ) return;
|
||||
p = sqlite_aggregate_context(context, sizeof(*p));
|
||||
if( p && argv[0] ){
|
||||
x = sqliteAtoF(argv[0], 0);
|
||||
x = sqlite3AtoF(argv[0], 0);
|
||||
p->sum += x;
|
||||
p->sum2 += x*x;
|
||||
p->cnt++;
|
||||
@@ -518,7 +518,7 @@ static void minmaxStep(sqlite_func *context, int argc, const char **argv){
|
||||
|
||||
assert( argc==2 );
|
||||
if( argv[1][0]=='n' ){
|
||||
xCompare = sqliteCompare;
|
||||
xCompare = sqlite3Compare;
|
||||
}else{
|
||||
xCompare = strcmp;
|
||||
}
|
||||
@@ -558,7 +558,7 @@ static void minMaxFinalize(sqlite_func *context){
|
||||
** functions. This should be the only routine in this file with
|
||||
** external linkage.
|
||||
*/
|
||||
void sqliteRegisterBuiltinFunctions(sqlite *db){
|
||||
void sqlite3RegisterBuiltinFunctions(sqlite *db){
|
||||
static struct {
|
||||
char *zName;
|
||||
signed char nArg;
|
||||
@@ -636,11 +636,14 @@ void sqliteRegisterBuiltinFunctions(sqlite *db){
|
||||
}
|
||||
for(i=0; i<sizeof(azTypeFuncs)/sizeof(azTypeFuncs[0]); i++){
|
||||
int n = strlen(azTypeFuncs[i]);
|
||||
FuncDef *p = sqliteHashFind(&db->aFunc, azTypeFuncs[i], n);
|
||||
FuncDef *p = sqlite3HashFind(&db->aFunc, azTypeFuncs[i], n);
|
||||
while( p ){
|
||||
p->includeTypes = 1;
|
||||
p = p->pNext;
|
||||
}
|
||||
}
|
||||
sqliteRegisterDateTimeFunctions(db);
|
||||
sqlite3RegisterDateTimeFunctions(db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
17
src/hash.c
17
src/hash.c
@@ -12,7 +12,7 @@
|
||||
** This is the implementation of generic hash-tables
|
||||
** used in SQLite.
|
||||
**
|
||||
** $Id: hash.c,v 1.11 2004/01/08 02:17:33 drh Exp $
|
||||
** $Id: hash.c,v 1.12 2004/05/08 08:23:25 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <assert.h>
|
||||
@@ -29,7 +29,7 @@
|
||||
** sense for SQLITE_HASH_STRING and SQLITE_HASH_BINARY and is ignored
|
||||
** for other key classes.
|
||||
*/
|
||||
void sqliteHashInit(Hash *new, int keyClass, int copyKey){
|
||||
void sqlite3HashInit(Hash *new, int keyClass, int copyKey){
|
||||
assert( new!=0 );
|
||||
assert( keyClass>=SQLITE_HASH_INT && keyClass<=SQLITE_HASH_BINARY );
|
||||
new->keyClass = keyClass;
|
||||
@@ -45,7 +45,7 @@ void sqliteHashInit(Hash *new, int keyClass, int copyKey){
|
||||
** Call this routine to delete a hash table or to reset a hash table
|
||||
** to the empty state.
|
||||
*/
|
||||
void sqliteHashClear(Hash *pH){
|
||||
void sqlite3HashClear(Hash *pH){
|
||||
HashElem *elem; /* For looping over all elements of the table */
|
||||
|
||||
assert( pH!=0 );
|
||||
@@ -94,11 +94,11 @@ static int ptrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
|
||||
** Hash and comparison functions when the mode is SQLITE_HASH_STRING
|
||||
*/
|
||||
static int strHash(const void *pKey, int nKey){
|
||||
return sqliteHashNoCase((const char*)pKey, nKey);
|
||||
return sqlite3HashNoCase((const char*)pKey, nKey);
|
||||
}
|
||||
static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){
|
||||
if( n1!=n2 ) return n2-n1;
|
||||
return sqliteStrNICmp((const char*)pKey1,(const char*)pKey2,n1);
|
||||
return sqlite3StrNICmp((const char*)pKey1,(const char*)pKey2,n1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -258,7 +258,7 @@ static void removeElementGivenHash(
|
||||
** that matches pKey,nKey. Return the data for this element if it is
|
||||
** found, or NULL if there is no match.
|
||||
*/
|
||||
void *sqliteHashFind(const Hash *pH, const void *pKey, int nKey){
|
||||
void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){
|
||||
int h; /* A hash on key */
|
||||
HashElem *elem; /* The element that matches key */
|
||||
int (*xHash)(const void*,int); /* The hash function */
|
||||
@@ -287,7 +287,7 @@ void *sqliteHashFind(const Hash *pH, const void *pKey, int nKey){
|
||||
** If the "data" parameter to this function is NULL, then the
|
||||
** element corresponding to "key" is removed from the hash table.
|
||||
*/
|
||||
void *sqliteHashInsert(Hash *pH, const void *pKey, int nKey, void *data){
|
||||
void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){
|
||||
int hraw; /* Raw hash value of the key */
|
||||
int h; /* the hash of the key modulo hash table size */
|
||||
HashElem *elem; /* Used to loop thru the element list */
|
||||
@@ -354,3 +354,6 @@ void *sqliteHashInsert(Hash *pH, const void *pKey, int nKey, void *data){
|
||||
new_elem->data = data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
13
src/hash.h
13
src/hash.h
@@ -12,7 +12,7 @@
|
||||
** This is the header file for the generic hash-table implemenation
|
||||
** used in SQLite.
|
||||
**
|
||||
** $Id: hash.h,v 1.6 2004/01/08 02:17:33 drh Exp $
|
||||
** $Id: hash.h,v 1.7 2004/05/08 08:23:25 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _SQLITE_HASH_H_
|
||||
#define _SQLITE_HASH_H_
|
||||
@@ -78,10 +78,10 @@ struct HashElem {
|
||||
/*
|
||||
** Access routines. To delete, insert a NULL pointer.
|
||||
*/
|
||||
void sqliteHashInit(Hash*, int keytype, int copyKey);
|
||||
void *sqliteHashInsert(Hash*, const void *pKey, int nKey, void *pData);
|
||||
void *sqliteHashFind(const Hash*, const void *pKey, int nKey);
|
||||
void sqliteHashClear(Hash*);
|
||||
void sqlite3HashInit(Hash*, int keytype, int copyKey);
|
||||
void *sqlite3HashInsert(Hash*, const void *pKey, int nKey, void *pData);
|
||||
void *sqlite3HashFind(const Hash*, const void *pKey, int nKey);
|
||||
void sqlite3HashClear(Hash*);
|
||||
|
||||
/*
|
||||
** Macros for looping over all elements of a hash table. The idiom is
|
||||
@@ -107,3 +107,6 @@ void sqliteHashClear(Hash*);
|
||||
#define sqliteHashCount(H) ((H)->count)
|
||||
|
||||
#endif /* _SQLITE_HASH_H_ */
|
||||
|
||||
|
||||
|
||||
|
323
src/insert.c
323
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.94 2004/02/24 01:05:33 drh Exp $
|
||||
** $Id: insert.c,v 1.95 2004/05/08 08:23:25 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
** end the loop
|
||||
** cleanup
|
||||
*/
|
||||
void sqliteInsert(
|
||||
void sqlite3Insert(
|
||||
Parse *pParse, /* Parser context */
|
||||
SrcList *pTabList, /* Name of table into which we are inserting */
|
||||
ExprList *pList, /* List of values to be inserted */
|
||||
@@ -124,13 +124,13 @@ void sqliteInsert(
|
||||
assert( pTabList->nSrc==1 );
|
||||
zTab = pTabList->a[0].zName;
|
||||
if( zTab==0 ) goto insert_cleanup;
|
||||
pTab = sqliteSrcListLookup(pParse, pTabList);
|
||||
pTab = sqlite3SrcListLookup(pParse, pTabList);
|
||||
if( pTab==0 ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
assert( pTab->iDb<db->nDb );
|
||||
zDb = db->aDb[pTab->iDb].zName;
|
||||
if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
|
||||
@@ -138,28 +138,28 @@ void sqliteInsert(
|
||||
* (a) the table is not read-only,
|
||||
* (b) that if it is a view then ON INSERT triggers exist
|
||||
*/
|
||||
before_triggers = sqliteTriggersExist(pParse, pTab->pTrigger, TK_INSERT,
|
||||
before_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, TK_INSERT,
|
||||
TK_BEFORE, TK_ROW, 0);
|
||||
after_triggers = sqliteTriggersExist(pParse, pTab->pTrigger, TK_INSERT,
|
||||
after_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, TK_INSERT,
|
||||
TK_AFTER, TK_ROW, 0);
|
||||
row_triggers_exist = before_triggers || after_triggers;
|
||||
isView = pTab->pSelect!=0;
|
||||
if( sqliteIsReadOnly(pParse, pTab, before_triggers) ){
|
||||
if( sqlite3IsReadOnly(pParse, pTab, before_triggers) ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
if( pTab==0 ) goto insert_cleanup;
|
||||
|
||||
/* If pTab is really a view, make sure it has been initialized.
|
||||
*/
|
||||
if( isView && sqliteViewGetColumnNames(pParse, pTab) ){
|
||||
if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
|
||||
/* Allocate a VDBE
|
||||
*/
|
||||
v = sqliteGetVdbe(pParse);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v==0 ) goto insert_cleanup;
|
||||
sqliteBeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb);
|
||||
sqlite3BeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb);
|
||||
|
||||
/* if there are row triggers, allocate a temp table for new.* references. */
|
||||
if( row_triggers_exist ){
|
||||
@@ -178,13 +178,13 @@ void sqliteInsert(
|
||||
/* Data is coming from a SELECT. Generate code to implement that SELECT
|
||||
*/
|
||||
int rc, iInitCode;
|
||||
iInitCode = sqliteVdbeAddOp(v, OP_Goto, 0, 0);
|
||||
iSelectLoop = sqliteVdbeCurrentAddr(v);
|
||||
iInsertBlock = sqliteVdbeMakeLabel(v);
|
||||
rc = sqliteSelect(pParse, pSelect, SRT_Subroutine, iInsertBlock, 0,0,0);
|
||||
iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
||||
iSelectLoop = sqlite3VdbeCurrentAddr(v);
|
||||
iInsertBlock = sqlite3VdbeMakeLabel(v);
|
||||
rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock, 0,0,0);
|
||||
if( rc || pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
|
||||
iCleanup = sqliteVdbeMakeLabel(v);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, iCleanup);
|
||||
iCleanup = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup);
|
||||
assert( pSelect->pEList );
|
||||
nColumn = pSelect->pEList->nExpr;
|
||||
|
||||
@@ -199,10 +199,10 @@ void sqliteInsert(
|
||||
if( row_triggers_exist ){
|
||||
useTempTable = 1;
|
||||
}else{
|
||||
int addr = sqliteVdbeFindOp(v, OP_OpenRead, pTab->tnum);
|
||||
int addr = sqlite3VdbeFindOp(v, OP_OpenRead, pTab->tnum);
|
||||
useTempTable = 0;
|
||||
if( addr>0 ){
|
||||
VdbeOp *pOp = sqliteVdbeGetOp(v, addr-2);
|
||||
VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-2);
|
||||
if( pOp->opcode==OP_Integer && pOp->p1==pTab->iDb ){
|
||||
useTempTable = 1;
|
||||
}
|
||||
@@ -214,23 +214,23 @@ void sqliteInsert(
|
||||
** the result. Store the result in a temporary table
|
||||
*/
|
||||
srcTab = pParse->nTab++;
|
||||
sqliteVdbeResolveLabel(v, iInsertBlock);
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, srcTab, 0);
|
||||
sqliteVdbeAddOp(v, OP_Pull, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_PutIntKey, srcTab, 0);
|
||||
sqliteVdbeAddOp(v, OP_Return, 0, 0);
|
||||
sqlite3VdbeResolveLabel(v, iInsertBlock);
|
||||
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NewRecno, srcTab, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_PutIntKey, srcTab, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Return, 0, 0);
|
||||
|
||||
/* The following code runs first because the GOTO at the very top
|
||||
** of the program jumps to it. Create the temporary table, then jump
|
||||
** back up and execute the SELECT code above.
|
||||
*/
|
||||
sqliteVdbeChangeP2(v, iInitCode, sqliteVdbeCurrentAddr(v));
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, srcTab, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, iSelectLoop);
|
||||
sqliteVdbeResolveLabel(v, iCleanup);
|
||||
sqlite3VdbeChangeP2(v, iInitCode, sqlite3VdbeCurrentAddr(v));
|
||||
sqlite3VdbeAddOp(v, OP_OpenTemp, srcTab, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
|
||||
sqlite3VdbeResolveLabel(v, iCleanup);
|
||||
}else{
|
||||
sqliteVdbeChangeP2(v, iInitCode, sqliteVdbeCurrentAddr(v));
|
||||
sqlite3VdbeChangeP2(v, iInitCode, sqlite3VdbeCurrentAddr(v));
|
||||
}
|
||||
}else{
|
||||
/* This is the case if the data for the INSERT is coming from a VALUES
|
||||
@@ -244,10 +244,10 @@ void sqliteInsert(
|
||||
nColumn = pList->nExpr;
|
||||
dummy.nSrc = 0;
|
||||
for(i=0; i<nColumn; i++){
|
||||
if( sqliteExprResolveIds(pParse, &dummy, 0, pList->a[i].pExpr) ){
|
||||
if( sqlite3ExprResolveIds(pParse, &dummy, 0, pList->a[i].pExpr) ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
if( sqliteExprCheck(pParse, pList->a[i].pExpr, 0, 0) ){
|
||||
if( sqlite3ExprCheck(pParse, pList->a[i].pExpr, 0, 0) ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
}
|
||||
@@ -257,13 +257,13 @@ void sqliteInsert(
|
||||
** of columns to be inserted into the table.
|
||||
*/
|
||||
if( pColumn==0 && nColumn!=pTab->nCol ){
|
||||
sqliteErrorMsg(pParse,
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"table %S has %d columns but %d values were supplied",
|
||||
pTabList, 0, pTab->nCol, nColumn);
|
||||
goto insert_cleanup;
|
||||
}
|
||||
if( pColumn!=0 && nColumn!=pColumn->nId ){
|
||||
sqliteErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
|
||||
sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
|
||||
goto insert_cleanup;
|
||||
}
|
||||
|
||||
@@ -284,7 +284,7 @@ void sqliteInsert(
|
||||
}
|
||||
for(i=0; i<pColumn->nId; i++){
|
||||
for(j=0; j<pTab->nCol; j++){
|
||||
if( sqliteStrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
|
||||
if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
|
||||
pColumn->a[i].idx = j;
|
||||
if( j==pTab->iPKey ){
|
||||
keyColumn = i;
|
||||
@@ -293,10 +293,10 @@ void sqliteInsert(
|
||||
}
|
||||
}
|
||||
if( j>=pTab->nCol ){
|
||||
if( sqliteIsRowid(pColumn->a[i].zName) ){
|
||||
if( sqlite3IsRowid(pColumn->a[i].zName) ){
|
||||
keyColumn = i;
|
||||
}else{
|
||||
sqliteErrorMsg(pParse, "table %S has no column named %s",
|
||||
sqlite3ErrorMsg(pParse, "table %S has no column named %s",
|
||||
pTabList, 0, pColumn->a[i].zName);
|
||||
pParse->nErr++;
|
||||
goto insert_cleanup;
|
||||
@@ -316,21 +316,21 @@ void sqliteInsert(
|
||||
/* Open the temp table for FOR EACH ROW triggers
|
||||
*/
|
||||
if( row_triggers_exist ){
|
||||
sqliteVdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
|
||||
}
|
||||
|
||||
/* Initialize the count of rows to be inserted
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
iCntMem = pParse->nMem++;
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MemStore, iCntMem, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, iCntMem, 1);
|
||||
}
|
||||
|
||||
/* Open tables and indices if there are no row triggers */
|
||||
if( !row_triggers_exist ){
|
||||
base = pParse->nTab;
|
||||
idx = sqliteOpenTableAndIndices(pParse, pTab, base);
|
||||
idx = sqlite3OpenTableAndIndices(pParse, pTab, base);
|
||||
pParse->nTab += idx;
|
||||
}
|
||||
|
||||
@@ -340,17 +340,17 @@ void sqliteInsert(
|
||||
** to launch the SELECT statement processing.
|
||||
*/
|
||||
if( useTempTable ){
|
||||
iBreak = sqliteVdbeMakeLabel(v);
|
||||
sqliteVdbeAddOp(v, OP_Rewind, srcTab, iBreak);
|
||||
iCont = sqliteVdbeCurrentAddr(v);
|
||||
iBreak = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3VdbeAddOp(v, OP_Rewind, srcTab, iBreak);
|
||||
iCont = sqlite3VdbeCurrentAddr(v);
|
||||
}else if( pSelect ){
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, iSelectLoop);
|
||||
sqliteVdbeResolveLabel(v, iInsertBlock);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
|
||||
sqlite3VdbeResolveLabel(v, iInsertBlock);
|
||||
}
|
||||
|
||||
/* Run the BEFORE and INSTEAD OF triggers, if there are any
|
||||
*/
|
||||
endOfLoop = sqliteVdbeMakeLabel(v);
|
||||
endOfLoop = sqlite3VdbeMakeLabel(v);
|
||||
if( before_triggers ){
|
||||
|
||||
/* build the NEW.* reference row. Note that if there is an INTEGER
|
||||
@@ -360,17 +360,17 @@ void sqliteInsert(
|
||||
** not happened yet) so we substitute a rowid of -1
|
||||
*/
|
||||
if( keyColumn<0 ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, -1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, -1, 0);
|
||||
}else if( useTempTable ){
|
||||
sqliteVdbeAddOp(v, OP_Column, srcTab, keyColumn);
|
||||
sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn);
|
||||
}else if( pSelect ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
|
||||
}else{
|
||||
sqliteExprCode(pParse, pList->a[keyColumn].pExpr);
|
||||
sqliteVdbeAddOp(v, OP_NotNull, -1, sqliteVdbeCurrentAddr(v)+3);
|
||||
sqliteVdbeAddOp(v, OP_Pop, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, -1, 0);
|
||||
sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
|
||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, -1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||
}
|
||||
|
||||
/* Create the new column data
|
||||
@@ -384,20 +384,20 @@ void sqliteInsert(
|
||||
}
|
||||
}
|
||||
if( pColumn && j>=pColumn->nId ){
|
||||
sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
|
||||
}else if( useTempTable ){
|
||||
sqliteVdbeAddOp(v, OP_Column, srcTab, j);
|
||||
sqlite3VdbeAddOp(v, OP_Column, srcTab, j);
|
||||
}else if( pSelect ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, nColumn-j-1, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nColumn-j-1, 1);
|
||||
}else{
|
||||
sqliteExprCode(pParse, pList->a[j].pExpr);
|
||||
sqlite3ExprCode(pParse, pList->a[j].pExpr);
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
|
||||
|
||||
/* Fire BEFORE or INSTEAD OF triggers */
|
||||
if( sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_BEFORE, pTab,
|
||||
if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TK_BEFORE, pTab,
|
||||
newIdx, -1, onError, endOfLoop) ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
@@ -408,7 +408,7 @@ void sqliteInsert(
|
||||
*/
|
||||
if( row_triggers_exist && !isView ){
|
||||
base = pParse->nTab;
|
||||
idx = sqliteOpenTableAndIndices(pParse, pTab, base);
|
||||
idx = sqlite3OpenTableAndIndices(pParse, pTab, base);
|
||||
pParse->nTab += idx;
|
||||
}
|
||||
|
||||
@@ -420,21 +420,21 @@ void sqliteInsert(
|
||||
if( !isView ){
|
||||
if( keyColumn>=0 ){
|
||||
if( useTempTable ){
|
||||
sqliteVdbeAddOp(v, OP_Column, srcTab, keyColumn);
|
||||
sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn);
|
||||
}else if( pSelect ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
|
||||
}else{
|
||||
sqliteExprCode(pParse, pList->a[keyColumn].pExpr);
|
||||
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
|
||||
}
|
||||
/* If the PRIMARY KEY expression is NULL, then use OP_NewRecno
|
||||
** to generate a unique primary key value.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_NotNull, -1, sqliteVdbeCurrentAddr(v)+3);
|
||||
sqliteVdbeAddOp(v, OP_Pop, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, base, 0);
|
||||
sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NewRecno, base, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, base, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NewRecno, base, 0);
|
||||
}
|
||||
|
||||
/* Push onto the stack, data for all columns of the new entry, beginning
|
||||
@@ -446,7 +446,7 @@ void sqliteInsert(
|
||||
** Whenever this column is read, the record number will be substituted
|
||||
** in its place. So will fill this column with a NULL to avoid
|
||||
** taking up data space with information that will never be used. */
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_String, 0, 0);
|
||||
continue;
|
||||
}
|
||||
if( pColumn==0 ){
|
||||
@@ -457,42 +457,42 @@ void sqliteInsert(
|
||||
}
|
||||
}
|
||||
if( pColumn && j>=pColumn->nId ){
|
||||
sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
|
||||
}else if( useTempTable ){
|
||||
sqliteVdbeAddOp(v, OP_Column, srcTab, j);
|
||||
sqlite3VdbeAddOp(v, OP_Column, srcTab, j);
|
||||
}else if( pSelect ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, i+nColumn-j, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, i+nColumn-j, 1);
|
||||
}else{
|
||||
sqliteExprCode(pParse, pList->a[j].pExpr);
|
||||
sqlite3ExprCode(pParse, pList->a[j].pExpr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate code to check constraints and generate index keys and
|
||||
** do the insertion.
|
||||
*/
|
||||
sqliteGenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
|
||||
sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
|
||||
0, onError, endOfLoop);
|
||||
sqliteCompleteInsertion(pParse, pTab, base, 0,0,0,
|
||||
sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0,
|
||||
after_triggers ? newIdx : -1);
|
||||
}
|
||||
|
||||
/* Update the count of rows that are inserted
|
||||
*/
|
||||
if( (db->flags & SQLITE_CountRows)!=0 ){
|
||||
sqliteVdbeAddOp(v, OP_MemIncr, iCntMem, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemIncr, iCntMem, 0);
|
||||
}
|
||||
|
||||
if( row_triggers_exist ){
|
||||
/* Close all tables opened */
|
||||
if( !isView ){
|
||||
sqliteVdbeAddOp(v, OP_Close, base, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, base, 0);
|
||||
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
||||
sqliteVdbeAddOp(v, OP_Close, idx+base, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, idx+base, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Code AFTER triggers */
|
||||
if( sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_AFTER, pTab, newIdx, -1,
|
||||
if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TK_AFTER, pTab, newIdx, -1,
|
||||
onError, endOfLoop) ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
@@ -500,42 +500,42 @@ void sqliteInsert(
|
||||
|
||||
/* The bottom of the loop, if the data source is a SELECT statement
|
||||
*/
|
||||
sqliteVdbeResolveLabel(v, endOfLoop);
|
||||
sqlite3VdbeResolveLabel(v, endOfLoop);
|
||||
if( useTempTable ){
|
||||
sqliteVdbeAddOp(v, OP_Next, srcTab, iCont);
|
||||
sqliteVdbeResolveLabel(v, iBreak);
|
||||
sqliteVdbeAddOp(v, OP_Close, srcTab, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Next, srcTab, iCont);
|
||||
sqlite3VdbeResolveLabel(v, iBreak);
|
||||
sqlite3VdbeAddOp(v, OP_Close, srcTab, 0);
|
||||
}else if( pSelect ){
|
||||
sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_Return, 0, 0);
|
||||
sqliteVdbeResolveLabel(v, iCleanup);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Return, 0, 0);
|
||||
sqlite3VdbeResolveLabel(v, iCleanup);
|
||||
}
|
||||
|
||||
if( !row_triggers_exist ){
|
||||
/* Close all tables opened */
|
||||
sqliteVdbeAddOp(v, OP_Close, base, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, base, 0);
|
||||
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
||||
sqliteVdbeAddOp(v, OP_Close, idx+base, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, idx+base, 0);
|
||||
}
|
||||
}
|
||||
|
||||
sqliteVdbeAddOp(v, OP_SetCounts, 0, 0);
|
||||
sqliteEndWriteOperation(pParse);
|
||||
sqlite3VdbeAddOp(v, OP_SetCounts, 0, 0);
|
||||
sqlite3EndWriteOperation(pParse);
|
||||
|
||||
/*
|
||||
** Return the number of rows inserted.
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
sqliteVdbeOp3(v, OP_ColumnName, 0, 1, "rows inserted", P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_MemLoad, iCntMem, 0);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 1, 0);
|
||||
sqlite3VdbeOp3(v, OP_ColumnName, 0, 1, "rows inserted", P3_STATIC);
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||
}
|
||||
|
||||
insert_cleanup:
|
||||
sqliteSrcListDelete(pTabList);
|
||||
if( pList ) sqliteExprListDelete(pList);
|
||||
if( pSelect ) sqliteSelectDelete(pSelect);
|
||||
sqliteIdListDelete(pColumn);
|
||||
sqlite3SrcListDelete(pTabList);
|
||||
if( pList ) sqlite3ExprListDelete(pList);
|
||||
if( pSelect ) sqlite3SelectDelete(pSelect);
|
||||
sqlite3IdListDelete(pColumn);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -617,7 +617,7 @@ insert_cleanup:
|
||||
** is still pointing at the same entry after the routine returns.
|
||||
** Without the isUpdate flag, the "base" cursor might be moved.
|
||||
*/
|
||||
void sqliteGenerateConstraintChecks(
|
||||
void sqlite3GenerateConstraintChecks(
|
||||
Parse *pParse, /* The parser context */
|
||||
Table *pTab, /* the table into which we are inserting */
|
||||
int base, /* Index of a read/write cursor pointing at pTab */
|
||||
@@ -640,7 +640,7 @@ void sqliteGenerateConstraintChecks(
|
||||
int contAddr;
|
||||
int hasTwoRecnos = (isUpdate && recnoChng);
|
||||
|
||||
v = sqliteGetVdbe(pParse);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
assert( v!=0 );
|
||||
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
|
||||
nCol = pTab->nCol;
|
||||
@@ -663,32 +663,32 @@ void sqliteGenerateConstraintChecks(
|
||||
if( onError==OE_Replace && pTab->aCol[i].zDflt==0 ){
|
||||
onError = OE_Abort;
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Dup, nCol-1-i, 1);
|
||||
addr = sqliteVdbeAddOp(v, OP_NotNull, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol-1-i, 1);
|
||||
addr = sqlite3VdbeAddOp(v, OP_NotNull, 1, 0);
|
||||
switch( onError ){
|
||||
case OE_Rollback:
|
||||
case OE_Abort:
|
||||
case OE_Fail: {
|
||||
char *zMsg = 0;
|
||||
sqliteVdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
|
||||
sqliteSetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName,
|
||||
sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
|
||||
sqlite3SetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName,
|
||||
" may not be NULL", (char*)0);
|
||||
sqliteVdbeChangeP3(v, -1, zMsg, P3_DYNAMIC);
|
||||
sqlite3VdbeChangeP3(v, -1, zMsg, P3_DYNAMIC);
|
||||
break;
|
||||
}
|
||||
case OE_Ignore: {
|
||||
sqliteVdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
||||
break;
|
||||
}
|
||||
case OE_Replace: {
|
||||
sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_Push, nCol-i, 0);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
|
||||
sqlite3VdbeAddOp(v, OP_Push, nCol-i, 0);
|
||||
break;
|
||||
}
|
||||
default: assert(0);
|
||||
}
|
||||
sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
|
||||
sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
|
||||
}
|
||||
|
||||
/* Test all CHECK constraints
|
||||
@@ -710,12 +710,12 @@ void sqliteGenerateConstraintChecks(
|
||||
}
|
||||
|
||||
if( isUpdate ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
|
||||
sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
|
||||
jumpInst1 = sqliteVdbeAddOp(v, OP_Eq, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
|
||||
jumpInst1 = sqlite3VdbeAddOp(v, OP_Eq, 0, 0);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Dup, nCol, 1);
|
||||
jumpInst2 = sqliteVdbeAddOp(v, OP_NotExists, base, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol, 1);
|
||||
jumpInst2 = sqlite3VdbeAddOp(v, OP_NotExists, base, 0);
|
||||
switch( onError ){
|
||||
default: {
|
||||
onError = OE_Abort;
|
||||
@@ -724,32 +724,32 @@ void sqliteGenerateConstraintChecks(
|
||||
case OE_Rollback:
|
||||
case OE_Abort:
|
||||
case OE_Fail: {
|
||||
sqliteVdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError,
|
||||
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError,
|
||||
"PRIMARY KEY must be unique", P3_STATIC);
|
||||
break;
|
||||
}
|
||||
case OE_Replace: {
|
||||
sqliteGenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
|
||||
sqlite3GenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
|
||||
if( isUpdate ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, nCol+hasTwoRecnos, 1);
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRecnos, 1);
|
||||
sqlite3VdbeAddOp(v, OP_MoveTo, base, 0);
|
||||
}
|
||||
seenReplace = 1;
|
||||
break;
|
||||
}
|
||||
case OE_Ignore: {
|
||||
assert( seenReplace==0 );
|
||||
sqliteVdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
contAddr = sqliteVdbeCurrentAddr(v);
|
||||
sqliteVdbeChangeP2(v, jumpInst2, contAddr);
|
||||
contAddr = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3VdbeChangeP2(v, jumpInst2, contAddr);
|
||||
if( isUpdate ){
|
||||
sqliteVdbeChangeP2(v, jumpInst1, contAddr);
|
||||
sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
|
||||
sqlite3VdbeChangeP2(v, jumpInst1, contAddr);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
|
||||
sqlite3VdbeAddOp(v, OP_MoveTo, base, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -763,17 +763,17 @@ void sqliteGenerateConstraintChecks(
|
||||
extra++;
|
||||
|
||||
/* Create a key for accessing the index entry */
|
||||
sqliteVdbeAddOp(v, OP_Dup, nCol+extra, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+extra, 1);
|
||||
for(i=0; i<pIdx->nColumn; i++){
|
||||
int idx = pIdx->aiColumn[i];
|
||||
if( idx==pTab->iPKey ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1);
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1);
|
||||
}
|
||||
}
|
||||
jumpInst1 = sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||
if( pParse->db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
|
||||
jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||
if( pParse->db->file_format>=4 ) sqlite3AddIdxKeyType(v, pIdx);
|
||||
|
||||
/* Find out what action to take in case there is an indexing conflict */
|
||||
onError = pIdx->onError;
|
||||
@@ -792,8 +792,8 @@ void sqliteGenerateConstraintChecks(
|
||||
|
||||
|
||||
/* Check to see if the new index entry will be unique */
|
||||
sqliteVdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1);
|
||||
jumpInst2 = sqliteVdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1);
|
||||
jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);
|
||||
|
||||
/* Generate code that executes if the new index entry is not unique */
|
||||
switch( onError ){
|
||||
@@ -822,45 +822,45 @@ void sqliteGenerateConstraintChecks(
|
||||
}
|
||||
strcpy(&zErrMsg[n1],
|
||||
pIdx->nColumn>1 ? " are not unique" : " is not unique");
|
||||
sqliteVdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, zErrMsg, 0);
|
||||
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, zErrMsg, 0);
|
||||
break;
|
||||
}
|
||||
case OE_Ignore: {
|
||||
assert( seenReplace==0 );
|
||||
sqliteVdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRecnos, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRecnos, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
||||
break;
|
||||
}
|
||||
case OE_Replace: {
|
||||
sqliteGenerateRowDelete(pParse->db, v, pTab, base, 0);
|
||||
sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0);
|
||||
if( isUpdate ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1);
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1);
|
||||
sqlite3VdbeAddOp(v, OP_MoveTo, base, 0);
|
||||
}
|
||||
seenReplace = 1;
|
||||
break;
|
||||
}
|
||||
default: assert(0);
|
||||
}
|
||||
contAddr = sqliteVdbeCurrentAddr(v);
|
||||
contAddr = sqlite3VdbeCurrentAddr(v);
|
||||
#if NULL_DISTINCT_FOR_UNIQUE
|
||||
sqliteVdbeChangeP2(v, jumpInst1, contAddr);
|
||||
sqlite3VdbeChangeP2(v, jumpInst1, contAddr);
|
||||
#endif
|
||||
sqliteVdbeChangeP2(v, jumpInst2, contAddr);
|
||||
sqlite3VdbeChangeP2(v, jumpInst2, contAddr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine generates code to finish the INSERT or UPDATE operation
|
||||
** that was started by a prior call to sqliteGenerateConstraintChecks.
|
||||
** that was started by a prior call to sqlite3GenerateConstraintChecks.
|
||||
** The stack must contain keys for all active indices followed by data
|
||||
** and the recno for the new entry. This routine creates the new
|
||||
** entries in all indices and in the main table.
|
||||
**
|
||||
** The arguments to this routine should be the same as the first six
|
||||
** arguments to sqliteGenerateConstraintChecks.
|
||||
** arguments to sqlite3GenerateConstraintChecks.
|
||||
*/
|
||||
void sqliteCompleteInsertion(
|
||||
void sqlite3CompleteInsertion(
|
||||
Parse *pParse, /* The parser context */
|
||||
Table *pTab, /* the table into which we are inserting */
|
||||
int base, /* Index of a read/write cursor pointing at pTab */
|
||||
@@ -874,25 +874,25 @@ void sqliteCompleteInsertion(
|
||||
int nIdx;
|
||||
Index *pIdx;
|
||||
|
||||
v = sqliteGetVdbe(pParse);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
assert( v!=0 );
|
||||
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
|
||||
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
|
||||
for(i=nIdx-1; i>=0; i--){
|
||||
if( aIdxUsed && aIdxUsed[i]==0 ) continue;
|
||||
sqliteVdbeAddOp(v, OP_IdxPut, base+i+1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_IdxPut, base+i+1, 0);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
if( newIdx>=0 ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_PutIntKey, base,
|
||||
sqlite3VdbeAddOp(v, OP_PutIntKey, base,
|
||||
(pParse->trigStack?0:OPFLAG_NCHANGE) |
|
||||
(isUpdate?0:OPFLAG_LASTROWID) | OPFLAG_CSCHANGE);
|
||||
if( isUpdate && recnoChng ){
|
||||
sqliteVdbeAddOp(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -904,16 +904,19 @@ void sqliteCompleteInsertion(
|
||||
** Return the total number of cursors opened. This is always at least
|
||||
** 1 (for the main table) plus more for each cursor.
|
||||
*/
|
||||
int sqliteOpenTableAndIndices(Parse *pParse, Table *pTab, int base){
|
||||
int sqlite3OpenTableAndIndices(Parse *pParse, Table *pTab, int base){
|
||||
int i;
|
||||
Index *pIdx;
|
||||
Vdbe *v = sqliteGetVdbe(pParse);
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
assert( v!=0 );
|
||||
sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqliteVdbeOp3(v, OP_OpenWrite, base, pTab->tnum, pTab->zName, P3_STATIC);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqlite3VdbeOp3(v, OP_OpenWrite, base, pTab->tnum, pTab->zName, P3_STATIC);
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
|
||||
sqliteVdbeOp3(v, OP_OpenWrite, i+base, pIdx->tnum, pIdx->zName, P3_STATIC);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
|
||||
sqlite3VdbeOp3(v, OP_OpenWrite, i+base, pIdx->tnum, pIdx->zName, P3_STATIC);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
454
src/main.c
454
src/main.c
@@ -14,7 +14,7 @@
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
**
|
||||
** $Id: main.c,v 1.164 2004/04/23 17:04:45 drh Exp $
|
||||
** $Id: main.c,v 1.165 2004/05/08 08:23:26 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
/*
|
||||
** A pointer to this structure is used to communicate information
|
||||
** from sqliteInit into the sqliteInitCallback.
|
||||
** from sqlite3Init into the sqlite3InitCallback.
|
||||
*/
|
||||
typedef struct {
|
||||
sqlite *db; /* The database being initialized */
|
||||
@@ -34,13 +34,13 @@ typedef struct {
|
||||
** that the database is corrupt.
|
||||
*/
|
||||
static void corruptSchema(InitData *pData, const char *zExtra){
|
||||
sqliteSetString(pData->pzErrMsg, "malformed database schema",
|
||||
sqlite3SetString(pData->pzErrMsg, "malformed database schema",
|
||||
zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
|
||||
}
|
||||
|
||||
/*
|
||||
** This is the callback routine for the code that initializes the
|
||||
** database. See sqliteInit() below for additional information.
|
||||
** database. See sqlite3Init() below for additional information.
|
||||
**
|
||||
** Each callback contains the following information:
|
||||
**
|
||||
@@ -53,7 +53,7 @@ static void corruptSchema(InitData *pData, const char *zExtra){
|
||||
**
|
||||
*/
|
||||
static
|
||||
int sqliteInitCallback(void *pInit, int argc, char **argv, char **azColName){
|
||||
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
|
||||
InitData *pData = (InitData*)pInit;
|
||||
int nErr = 0;
|
||||
|
||||
@@ -100,7 +100,7 @@ int sqliteInitCallback(void *pInit, int argc, char **argv, char **azColName){
|
||||
|
||||
iDb = atoi(argv[4]);
|
||||
assert( iDb>=0 && iDb<db->nDb );
|
||||
pIndex = sqliteFindIndex(db, argv[1], db->aDb[iDb].zName);
|
||||
pIndex = sqlite3FindIndex(db, argv[1], db->aDb[iDb].zName);
|
||||
if( pIndex==0 || pIndex->tnum!=0 ){
|
||||
/* This can occur if there exists an index on a TEMP table which
|
||||
** has the same name as another index on a permanent index. Since
|
||||
@@ -143,9 +143,9 @@ int upgrade_3_callback(void *pInit, int argc, char **argv, char **NotUsed){
|
||||
Trigger *pTrig;
|
||||
char *zErr = 0;
|
||||
|
||||
pTab = sqliteFindTable(pData->db, argv[0], 0);
|
||||
pTab = sqlite3FindTable(pData->db, argv[0], 0);
|
||||
assert( pTab!=0 );
|
||||
assert( sqliteStrICmp(pTab->zName, argv[0])==0 );
|
||||
assert( sqlite3StrICmp(pTab->zName, argv[0])==0 );
|
||||
if( pTab ){
|
||||
pTrig = pTab->pTrigger;
|
||||
pTab->pTrigger = 0; /* Disable all triggers before rebuilding the table */
|
||||
@@ -166,9 +166,9 @@ int upgrade_3_callback(void *pInit, int argc, char **argv, char **NotUsed){
|
||||
** cause the structure that pTab points to be deleted. In case that
|
||||
** happened, we need to refetch pTab.
|
||||
*/
|
||||
pTab = sqliteFindTable(pData->db, argv[0], 0);
|
||||
pTab = sqlite3FindTable(pData->db, argv[0], 0);
|
||||
if( pTab ){
|
||||
assert( sqliteStrICmp(pTab->zName, argv[0])==0 );
|
||||
assert( sqlite3StrICmp(pTab->zName, argv[0])==0 );
|
||||
pTab->pTrigger = pTrig; /* Re-enable triggers */
|
||||
}
|
||||
return rc!=SQLITE_OK;
|
||||
@@ -184,7 +184,7 @@ int upgrade_3_callback(void *pInit, int argc, char **argv, char **NotUsed){
|
||||
** auxiliary databases. Return one of the SQLITE_ error codes to
|
||||
** indicate success or failure.
|
||||
*/
|
||||
static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||
static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||
int rc;
|
||||
BtCursor *curMain;
|
||||
int size;
|
||||
@@ -248,7 +248,7 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||
|
||||
/* Construct the schema tables: sqlite_master and sqlite_temp_master
|
||||
*/
|
||||
sqliteSafetyOff(db);
|
||||
sqlite3SafetyOff(db);
|
||||
azArg[0] = "table";
|
||||
azArg[1] = MASTER_NAME;
|
||||
azArg[2] = "2";
|
||||
@@ -258,8 +258,8 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||
azArg[5] = 0;
|
||||
initData.db = db;
|
||||
initData.pzErrMsg = pzErrMsg;
|
||||
sqliteInitCallback(&initData, 5, azArg, 0);
|
||||
pTab = sqliteFindTable(db, MASTER_NAME, "main");
|
||||
sqlite3InitCallback(&initData, 5, azArg, 0);
|
||||
pTab = sqlite3FindTable(db, MASTER_NAME, "main");
|
||||
if( pTab ){
|
||||
pTab->readOnly = 1;
|
||||
}
|
||||
@@ -267,29 +267,34 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||
azArg[1] = TEMP_MASTER_NAME;
|
||||
azArg[3] = temp_master_schema;
|
||||
azArg[4] = "1";
|
||||
sqliteInitCallback(&initData, 5, azArg, 0);
|
||||
pTab = sqliteFindTable(db, TEMP_MASTER_NAME, "temp");
|
||||
sqlite3InitCallback(&initData, 5, azArg, 0);
|
||||
pTab = sqlite3FindTable(db, TEMP_MASTER_NAME, "temp");
|
||||
if( pTab ){
|
||||
pTab->readOnly = 1;
|
||||
}
|
||||
}
|
||||
sqliteSafetyOn(db);
|
||||
sqlite3SafetyOn(db);
|
||||
|
||||
/* Create a cursor to hold the database open
|
||||
*/
|
||||
if( db->aDb[iDb].pBt==0 ) return SQLITE_OK;
|
||||
rc = sqliteBtreeCursor(db->aDb[iDb].pBt, 2, 0, &curMain);
|
||||
rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, 2, 0, 0, 0, &curMain);
|
||||
if( rc ){
|
||||
sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0);
|
||||
sqlite3SetString(pzErrMsg, sqlite_error_string(rc), (char*)0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Get the database meta information
|
||||
*/
|
||||
rc = sqliteBtreeGetMeta(db->aDb[iDb].pBt, meta);
|
||||
{
|
||||
int ii;
|
||||
for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
|
||||
rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, ii+1, &meta[ii]);
|
||||
}
|
||||
}
|
||||
if( rc ){
|
||||
sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0);
|
||||
sqliteBtreeCloseCursor(curMain);
|
||||
sqlite3SetString(pzErrMsg, sqlite_error_string(rc), (char*)0);
|
||||
sqlite3BtreeCloseCursor(curMain);
|
||||
return rc;
|
||||
}
|
||||
db->aDb[iDb].schema_cookie = meta[1];
|
||||
@@ -316,48 +321,48 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||
/* This happens if the database was initially empty */
|
||||
db->file_format = 4;
|
||||
}else if( db->file_format>4 ){
|
||||
sqliteBtreeCloseCursor(curMain);
|
||||
sqliteSetString(pzErrMsg, "unsupported file format", (char*)0);
|
||||
sqlite3BtreeCloseCursor(curMain);
|
||||
sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
}else if( db->file_format!=meta[2] || db->file_format<4 ){
|
||||
assert( db->file_format>=4 );
|
||||
if( meta[2]==0 ){
|
||||
sqliteSetString(pzErrMsg, "cannot attach empty database: ",
|
||||
sqlite3SetString(pzErrMsg, "cannot attach empty database: ",
|
||||
db->aDb[iDb].zName, (char*)0);
|
||||
}else{
|
||||
sqliteSetString(pzErrMsg, "incompatible file format in auxiliary "
|
||||
sqlite3SetString(pzErrMsg, "incompatible file format in auxiliary "
|
||||
"database: ", db->aDb[iDb].zName, (char*)0);
|
||||
}
|
||||
sqliteBtreeClose(db->aDb[iDb].pBt);
|
||||
sqlite3BtreeClose(db->aDb[iDb].pBt);
|
||||
db->aDb[iDb].pBt = 0;
|
||||
return SQLITE_FORMAT;
|
||||
}
|
||||
sqliteBtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size);
|
||||
sqliteBtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]);
|
||||
sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size);
|
||||
sqlite3BtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]);
|
||||
|
||||
/* Read the schema information out of the schema tables
|
||||
*/
|
||||
assert( db->init.busy );
|
||||
sqliteSafetyOff(db);
|
||||
sqlite3SafetyOff(db);
|
||||
if( iDb==0 ){
|
||||
rc = sqlite_exec(db,
|
||||
db->file_format>=2 ? init_script : older_init_script,
|
||||
sqliteInitCallback, &initData, 0);
|
||||
sqlite3InitCallback, &initData, 0);
|
||||
}else{
|
||||
char *zSql = 0;
|
||||
sqliteSetString(&zSql,
|
||||
sqlite3SetString(&zSql,
|
||||
"SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
|
||||
db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
|
||||
rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
|
||||
rc = sqlite_exec(db, zSql, sqlite3InitCallback, &initData, 0);
|
||||
sqliteFree(zSql);
|
||||
}
|
||||
sqliteSafetyOn(db);
|
||||
sqliteBtreeCloseCursor(curMain);
|
||||
sqlite3SafetyOn(db);
|
||||
sqlite3BtreeCloseCursor(curMain);
|
||||
if( sqlite_malloc_failed ){
|
||||
sqliteSetString(pzErrMsg, "out of memory", (char*)0);
|
||||
sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
|
||||
rc = SQLITE_NOMEM;
|
||||
sqliteResetInternalSchema(db, 0);
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
DbSetProperty(db, iDb, DB_SchemaLoaded);
|
||||
@@ -365,7 +370,7 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||
DbSetProperty(db, 1, DB_SchemaLoaded);
|
||||
}
|
||||
}else{
|
||||
sqliteResetInternalSchema(db, iDb);
|
||||
sqlite3ResetInternalSchema(db, iDb);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -383,7 +388,7 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
|
||||
** has the sqlite_master table locked) than another attempt
|
||||
** is made the first time the database is accessed.
|
||||
*/
|
||||
int sqliteInit(sqlite *db, char **pzErrMsg){
|
||||
int sqlite3Init(sqlite *db, char **pzErrMsg){
|
||||
int i, rc;
|
||||
|
||||
if( db->init.busy ) return SQLITE_OK;
|
||||
@@ -393,15 +398,15 @@ int sqliteInit(sqlite *db, char **pzErrMsg){
|
||||
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
|
||||
if( DbHasProperty(db, i, DB_SchemaLoaded) ) continue;
|
||||
assert( i!=1 ); /* Should have been initialized together with 0 */
|
||||
rc = sqliteInitOne(db, i, pzErrMsg);
|
||||
rc = sqlite3InitOne(db, i, pzErrMsg);
|
||||
if( rc ){
|
||||
sqliteResetInternalSchema(db, i);
|
||||
sqlite3ResetInternalSchema(db, i);
|
||||
}
|
||||
}
|
||||
db->init.busy = 0;
|
||||
if( rc==SQLITE_OK ){
|
||||
db->flags |= SQLITE_Initialized;
|
||||
sqliteCommitInternalChanges(db);
|
||||
sqlite3CommitInternalChanges(db);
|
||||
}
|
||||
|
||||
/* If the database is in formats 1 or 2, then upgrade it to
|
||||
@@ -424,13 +429,18 @@ int sqliteInit(sqlite *db, char **pzErrMsg){
|
||||
&initData,
|
||||
&zErr);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqliteBtreeGetMeta(db->aDb[0].pBt, meta);
|
||||
int ii;
|
||||
for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
|
||||
rc = sqlite3BtreeGetMeta(db->aDb[0].pBt, ii+1, &meta[ii]);
|
||||
}
|
||||
meta[2] = 4;
|
||||
sqliteBtreeUpdateMeta(db->aDb[0].pBt, meta);
|
||||
for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
|
||||
rc = sqlite3BtreeUpdateMeta(db->aDb[0].pBt, ii+1, meta[ii]);
|
||||
}
|
||||
sqlite_exec(db, "COMMIT", 0, 0, 0);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqliteSetString(pzErrMsg,
|
||||
sqlite3SetString(pzErrMsg,
|
||||
"unable to upgrade database to the version 2.6 format",
|
||||
zErr ? ": " : 0, zErr, (char*)0);
|
||||
}
|
||||
@@ -482,43 +492,43 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
|
||||
db->nDb = 2;
|
||||
db->aDb = db->aDbStatic;
|
||||
/* db->flags |= SQLITE_ShortColNames; */
|
||||
sqliteHashInit(&db->aFunc, SQLITE_HASH_STRING, 1);
|
||||
sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 1);
|
||||
for(i=0; i<db->nDb; i++){
|
||||
sqliteHashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0);
|
||||
sqliteHashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0);
|
||||
sqliteHashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0);
|
||||
sqliteHashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1);
|
||||
sqlite3HashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0);
|
||||
sqlite3HashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0);
|
||||
sqlite3HashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0);
|
||||
sqlite3HashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1);
|
||||
}
|
||||
|
||||
/* Open the backend database driver */
|
||||
if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
|
||||
db->temp_store = 2;
|
||||
}
|
||||
rc = sqliteBtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
|
||||
rc = sqlite3BtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
|
||||
if( rc!=SQLITE_OK ){
|
||||
switch( rc ){
|
||||
default: {
|
||||
sqliteSetString(pzErrMsg, "unable to open database: ",
|
||||
sqlite3SetString(pzErrMsg, "unable to open database: ",
|
||||
zFilename, (char*)0);
|
||||
}
|
||||
}
|
||||
sqliteFree(db);
|
||||
sqliteStrRealloc(pzErrMsg);
|
||||
sqlite3StrRealloc(pzErrMsg);
|
||||
return 0;
|
||||
}
|
||||
db->aDb[0].zName = "main";
|
||||
db->aDb[1].zName = "temp";
|
||||
|
||||
/* Attempt to read the schema */
|
||||
sqliteRegisterBuiltinFunctions(db);
|
||||
rc = sqliteInit(db, pzErrMsg);
|
||||
sqlite3RegisterBuiltinFunctions(db);
|
||||
rc = sqlite3Init(db, pzErrMsg);
|
||||
db->magic = SQLITE_MAGIC_OPEN;
|
||||
if( sqlite_malloc_failed ){
|
||||
sqlite_close(db);
|
||||
goto no_mem_on_open;
|
||||
}else if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
|
||||
sqlite_close(db);
|
||||
sqliteStrRealloc(pzErrMsg);
|
||||
sqlite3StrRealloc(pzErrMsg);
|
||||
return 0;
|
||||
}else if( pzErrMsg ){
|
||||
sqliteFree(*pzErrMsg);
|
||||
@@ -529,8 +539,8 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
|
||||
return db;
|
||||
|
||||
no_mem_on_open:
|
||||
sqliteSetString(pzErrMsg, "out of memory", (char*)0);
|
||||
sqliteStrRealloc(pzErrMsg);
|
||||
sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
|
||||
sqlite3StrRealloc(pzErrMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -565,7 +575,7 @@ void sqlite_close(sqlite *db){
|
||||
HashElem *i;
|
||||
int j;
|
||||
db->want_to_close = 1;
|
||||
if( sqliteSafetyCheck(db) || sqliteSafetyOn(db) ){
|
||||
if( sqlite3SafetyCheck(db) || sqlite3SafetyOn(db) ){
|
||||
/* printf("DID NOT CLOSE\n"); fflush(stdout); */
|
||||
return;
|
||||
}
|
||||
@@ -573,11 +583,11 @@ void sqlite_close(sqlite *db){
|
||||
for(j=0; j<db->nDb; j++){
|
||||
struct Db *pDb = &db->aDb[j];
|
||||
if( pDb->pBt ){
|
||||
sqliteBtreeClose(pDb->pBt);
|
||||
sqlite3BtreeClose(pDb->pBt);
|
||||
pDb->pBt = 0;
|
||||
}
|
||||
}
|
||||
sqliteResetInternalSchema(db, 0);
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
assert( db->nDb<=2 );
|
||||
assert( db->aDb==db->aDbStatic );
|
||||
for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
|
||||
@@ -587,23 +597,23 @@ void sqlite_close(sqlite *db){
|
||||
sqliteFree(pFunc);
|
||||
}
|
||||
}
|
||||
sqliteHashClear(&db->aFunc);
|
||||
sqlite3HashClear(&db->aFunc);
|
||||
sqliteFree(db);
|
||||
}
|
||||
|
||||
/*
|
||||
** Rollback all database files.
|
||||
*/
|
||||
void sqliteRollbackAll(sqlite *db){
|
||||
void sqlite3RollbackAll(sqlite *db){
|
||||
int i;
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( db->aDb[i].pBt ){
|
||||
sqliteBtreeRollback(db->aDb[i].pBt);
|
||||
sqlite3BtreeRollback(db->aDb[i].pBt);
|
||||
db->aDb[i].inTrans = 0;
|
||||
}
|
||||
}
|
||||
sqliteResetInternalSchema(db, 0);
|
||||
/* sqliteRollbackInternalChanges(db); */
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
/* sqlite3RollbackInternalChanges(db); */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -694,16 +704,16 @@ int sqlite_compile(
|
||||
Parse sParse;
|
||||
|
||||
if( pzErrMsg ) *pzErrMsg = 0;
|
||||
if( sqliteSafetyOn(db) ) goto exec_misuse;
|
||||
if( sqlite3SafetyOn(db) ) goto exec_misuse;
|
||||
if( !db->init.busy ){
|
||||
if( (db->flags & SQLITE_Initialized)==0 ){
|
||||
int rc, cnt = 1;
|
||||
while( (rc = sqliteInit(db, pzErrMsg))==SQLITE_BUSY
|
||||
while( (rc = sqlite3Init(db, pzErrMsg))==SQLITE_BUSY
|
||||
&& db->xBusyCallback
|
||||
&& db->xBusyCallback(db->pBusyArg, "", cnt++)!=0 ){}
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqliteStrRealloc(pzErrMsg);
|
||||
sqliteSafetyOff(db);
|
||||
sqlite3StrRealloc(pzErrMsg);
|
||||
sqlite3SafetyOff(db);
|
||||
return rc;
|
||||
}
|
||||
if( pzErrMsg ){
|
||||
@@ -712,8 +722,8 @@ int sqlite_compile(
|
||||
}
|
||||
}
|
||||
if( db->file_format<3 ){
|
||||
sqliteSafetyOff(db);
|
||||
sqliteSetString(pzErrMsg, "obsolete database file format", (char*)0);
|
||||
sqlite3SafetyOff(db);
|
||||
sqlite3SetString(pzErrMsg, "obsolete database file format", (char*)0);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -721,7 +731,7 @@ int sqlite_compile(
|
||||
if( db->pVdbe==0 ){ db->nChange = 0; }
|
||||
memset(&sParse, 0, sizeof(sParse));
|
||||
sParse.db = db;
|
||||
sqliteRunParser(&sParse, zSql, pzErrMsg);
|
||||
sqlite3RunParser(&sParse, zSql, pzErrMsg);
|
||||
if( db->xTrace && !db->init.busy ){
|
||||
/* Trace only the statment that was compiled.
|
||||
** Make a copy of that part of the SQL string since zSQL is const
|
||||
@@ -746,31 +756,31 @@ int sqlite_compile(
|
||||
}
|
||||
}
|
||||
if( sqlite_malloc_failed ){
|
||||
sqliteSetString(pzErrMsg, "out of memory", (char*)0);
|
||||
sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
|
||||
sParse.rc = SQLITE_NOMEM;
|
||||
sqliteRollbackAll(db);
|
||||
sqliteResetInternalSchema(db, 0);
|
||||
sqlite3RollbackAll(db);
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
db->flags &= ~SQLITE_InTrans;
|
||||
}
|
||||
if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
|
||||
if( sParse.rc!=SQLITE_OK && pzErrMsg && *pzErrMsg==0 ){
|
||||
sqliteSetString(pzErrMsg, sqlite_error_string(sParse.rc), (char*)0);
|
||||
sqlite3SetString(pzErrMsg, sqlite_error_string(sParse.rc), (char*)0);
|
||||
}
|
||||
sqliteStrRealloc(pzErrMsg);
|
||||
sqlite3StrRealloc(pzErrMsg);
|
||||
if( sParse.rc==SQLITE_SCHEMA ){
|
||||
sqliteResetInternalSchema(db, 0);
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
}
|
||||
assert( ppVm );
|
||||
*ppVm = (sqlite_vm*)sParse.pVdbe;
|
||||
if( pzTail ) *pzTail = sParse.zTail;
|
||||
if( sqliteSafetyOff(db) ) goto exec_misuse;
|
||||
if( sqlite3SafetyOff(db) ) goto exec_misuse;
|
||||
return sParse.rc;
|
||||
|
||||
exec_misuse:
|
||||
if( pzErrMsg ){
|
||||
*pzErrMsg = 0;
|
||||
sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0);
|
||||
sqliteStrRealloc(pzErrMsg);
|
||||
sqlite3SetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0);
|
||||
sqlite3StrRealloc(pzErrMsg);
|
||||
}
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
@@ -791,8 +801,8 @@ int sqlite_finalize(
|
||||
sqlite_vm *pVm, /* The virtual machine to be destroyed */
|
||||
char **pzErrMsg /* OUT: Write error messages here */
|
||||
){
|
||||
int rc = sqliteVdbeFinalize((Vdbe*)pVm, pzErrMsg);
|
||||
sqliteStrRealloc(pzErrMsg);
|
||||
int rc = sqlite3VdbeFinalize((Vdbe*)pVm, pzErrMsg);
|
||||
sqlite3StrRealloc(pzErrMsg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -807,9 +817,9 @@ int sqlite_reset(
|
||||
sqlite_vm *pVm, /* The virtual machine to be destroyed */
|
||||
char **pzErrMsg /* OUT: Write error messages here */
|
||||
){
|
||||
int rc = sqliteVdbeReset((Vdbe*)pVm, pzErrMsg);
|
||||
sqliteVdbeMakeReady((Vdbe*)pVm, -1, 0);
|
||||
sqliteStrRealloc(pzErrMsg);
|
||||
int rc = sqlite3VdbeReset((Vdbe*)pVm, pzErrMsg);
|
||||
sqlite3VdbeMakeReady((Vdbe*)pVm, -1, 0);
|
||||
sqlite3StrRealloc(pzErrMsg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -883,14 +893,14 @@ static int sqliteDefaultBusyCallback(
|
||||
delay = timeout - prior;
|
||||
if( delay<=0 ) return 0;
|
||||
}
|
||||
sqliteOsSleep(delay);
|
||||
sqlite3OsSleep(delay);
|
||||
return 1;
|
||||
#else
|
||||
int timeout = (int)Timeout;
|
||||
if( (count+1)*1000 > timeout ){
|
||||
return 0;
|
||||
}
|
||||
sqliteOsSleep(1000);
|
||||
sqlite3OsSleep(1000);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
@@ -960,7 +970,7 @@ void sqlite_interrupt(sqlite *db){
|
||||
**
|
||||
** Note that we need to call free() not sqliteFree() here, since every
|
||||
** string that is exported from SQLite should have already passed through
|
||||
** sqliteStrRealloc().
|
||||
** sqlite3StrRealloc().
|
||||
*/
|
||||
void sqlite_freemem(void *p){ free(p); }
|
||||
|
||||
@@ -995,11 +1005,11 @@ int sqlite_create_function(
|
||||
){
|
||||
FuncDef *p;
|
||||
int nName;
|
||||
if( db==0 || zName==0 || sqliteSafetyCheck(db) ) return 1;
|
||||
if( db==0 || zName==0 || sqlite3SafetyCheck(db) ) return 1;
|
||||
if( nArg<-1 || nArg>127 ) return 1;
|
||||
nName = strlen(zName);
|
||||
if( nName>255 ) return 1;
|
||||
p = sqliteFindFunction(db, zName, nName, nArg, 1);
|
||||
p = sqlite3FindFunction(db, zName, nName, nArg, 1);
|
||||
if( p==0 ) return 1;
|
||||
p->xFunc = xFunc;
|
||||
p->xStep = 0;
|
||||
@@ -1017,11 +1027,11 @@ int sqlite_create_aggregate(
|
||||
){
|
||||
FuncDef *p;
|
||||
int nName;
|
||||
if( db==0 || zName==0 || sqliteSafetyCheck(db) ) return 1;
|
||||
if( db==0 || zName==0 || sqlite3SafetyCheck(db) ) return 1;
|
||||
if( nArg<-1 || nArg>127 ) return 1;
|
||||
nName = strlen(zName);
|
||||
if( nName>255 ) return 1;
|
||||
p = sqliteFindFunction(db, zName, nName, nArg, 1);
|
||||
p = sqlite3FindFunction(db, zName, nName, nArg, 1);
|
||||
if( p==0 ) return 1;
|
||||
p->xFunc = 0;
|
||||
p->xStep = xStep;
|
||||
@@ -1036,7 +1046,7 @@ int sqlite_create_aggregate(
|
||||
** additional information.
|
||||
*/
|
||||
int sqlite_function_type(sqlite *db, const char *zName, int dataType){
|
||||
FuncDef *p = (FuncDef*)sqliteHashFind(&db->aFunc, zName, strlen(zName));
|
||||
FuncDef *p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, strlen(zName));
|
||||
while( p ){
|
||||
p->dataType = dataType;
|
||||
p = p->pNext;
|
||||
@@ -1102,38 +1112,236 @@ void *sqlite_commit_hook(
|
||||
** 2 0 memory
|
||||
** 3 any memory
|
||||
*/
|
||||
int sqliteBtreeFactory(
|
||||
int sqlite3BtreeFactory(
|
||||
const sqlite *db, /* Main database when opening aux otherwise 0 */
|
||||
const char *zFilename, /* Name of the file containing the BTree database */
|
||||
int omitJournal, /* if TRUE then do not journal this file */
|
||||
int nCache, /* How many pages in the page cache */
|
||||
Btree **ppBtree){ /* Pointer to new Btree object written here */
|
||||
|
||||
Btree **ppBtree /* Pointer to new Btree object written here */
|
||||
){
|
||||
assert( ppBtree != 0);
|
||||
|
||||
#ifndef SQLITE_OMIT_INMEMORYDB
|
||||
if( zFilename==0 ){
|
||||
if (TEMP_STORE == 0) {
|
||||
/* Always use file based temporary DB */
|
||||
return sqliteBtreeOpen(0, omitJournal, nCache, ppBtree);
|
||||
} else if (TEMP_STORE == 1 || TEMP_STORE == 2) {
|
||||
/* Switch depending on compile-time and/or runtime settings. */
|
||||
int location = db->temp_store==0 ? TEMP_STORE : db->temp_store;
|
||||
|
||||
if (location == 1) {
|
||||
return sqliteBtreeOpen(zFilename, omitJournal, nCache, ppBtree);
|
||||
} else {
|
||||
return sqliteRbtreeOpen(0, 0, 0, ppBtree);
|
||||
}
|
||||
} else {
|
||||
/* Always use in-core DB */
|
||||
return sqliteRbtreeOpen(0, 0, 0, ppBtree);
|
||||
}
|
||||
}else if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
|
||||
return sqliteRbtreeOpen(0, 0, 0, ppBtree);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
return sqliteBtreeOpen(zFilename, omitJournal, nCache, ppBtree);
|
||||
int btree_flags = 0;
|
||||
|
||||
if( omitJournal ){
|
||||
btree_flags |= BTREE_OMIT_JOURNAL;
|
||||
}
|
||||
if( !zFilename ){
|
||||
btree_flags |= BTREE_MEMORY;
|
||||
}
|
||||
|
||||
return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
** sqlite3_open
|
||||
**
|
||||
*/
|
||||
int sqlite3_open(const char *filename, sqlite3 **pDb, const char **options){
|
||||
*pDb = sqlite_open(filename, 0, &errmsg);
|
||||
return (*pDb?SQLITE_OK:SQLITE_ERROR);
|
||||
}
|
||||
int sqlite3_open16(const void *filename, sqlite3 **pDb, const char **options){
|
||||
int rc;
|
||||
char * filename8;
|
||||
|
||||
filename8 = sqlite3utf16to8(filename, -1);
|
||||
if( !filename8 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
rc = sqlite3_open(filename8, pDb, options);
|
||||
sqliteFree(filename8);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_close
|
||||
**
|
||||
*/
|
||||
int sqlite3_close(sqlite3 *db){
|
||||
return sqlite_close(db);
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_errmsg
|
||||
**
|
||||
** TODO: !
|
||||
*/
|
||||
const char *sqlite3_errmsg(sqlite3 *db){
|
||||
assert(!"TODO");
|
||||
}
|
||||
const void *sqlite3_errmsg16(sqlite3 *db){
|
||||
assert(!"TODO");
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_errcode
|
||||
**
|
||||
** TODO: !
|
||||
*/
|
||||
int sqlite3_errcode(sqlite3 *db){
|
||||
assert(!"TODO");
|
||||
}
|
||||
|
||||
struct sqlite_stmt {
|
||||
};
|
||||
|
||||
/*
|
||||
** sqlite3_prepare
|
||||
**
|
||||
** TODO: error message handling
|
||||
*/
|
||||
int sqlite3_prepare(
|
||||
sqlite3 *db,
|
||||
const char *zSql,
|
||||
sqlite3_stmt **ppStmt,
|
||||
const char** pzTail
|
||||
){
|
||||
int rc;
|
||||
rc = sqlite_compile(db, zSql, pzTail, ppStmt, 0);
|
||||
return rc;
|
||||
}
|
||||
int sqlite3_prepare16(
|
||||
sqlite3 *db,
|
||||
const void *zSql,
|
||||
sqlite3_stmt **ppStmt,
|
||||
const void **pzTail
|
||||
){
|
||||
int rc;
|
||||
char *sql8;
|
||||
|
||||
sql8 = sqlite3utf16to8(zSql, -1);
|
||||
if( !sql8 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
/* TODO: Have to set *pzTail to point into the original UTF-16 string
|
||||
** somehow.
|
||||
*/
|
||||
rc = sqlite3_prepare(db, sql8, ppStmt, 0);
|
||||
sqliteFree(filename8);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_finalize
|
||||
*/
|
||||
int sqlite3_finalize(sqlite3_stmt *stmt){
|
||||
return sqlite_finalize(stmt, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_reset
|
||||
*/
|
||||
int sqlite3_reset(sqlite3_stmt*){
|
||||
return sqlite_reset(stmt, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_step
|
||||
*/
|
||||
int sqlite3_step(sqlite3_stmt *pStmt){
|
||||
return sqlite_step(pStmt);
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_bind_text
|
||||
*/
|
||||
int sqlite3_bind_text(
|
||||
sqlite3_stmt *pStmt,
|
||||
int i,
|
||||
const char *zVal,
|
||||
int n,
|
||||
int eCopy
|
||||
){
|
||||
return sqlite_bind(pStmt, i, zVal, n, eCopy);
|
||||
}
|
||||
|
||||
int sqlite3_bind_text16(
|
||||
sqlite3_stmt *pStmt,
|
||||
int i,
|
||||
void *zVal,
|
||||
int n,
|
||||
int eCopy
|
||||
){
|
||||
int rc;
|
||||
char * zVal8;
|
||||
|
||||
/* convert the first n bytes of the UTF-16 string to UTF-8 */
|
||||
zVal8 = sqlite3utf16to8(zVal, n);
|
||||
if( !zVal8 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
/* Pass -1 as the length of the UTF-8 string. It is guaranteed to be
|
||||
** NULL-terminated by sqlite3utf16to8().
|
||||
*/
|
||||
rc = sqlite3_bind_text(pStmt, i, zVal8, -1, eCopy);
|
||||
sqliteFree(filename8);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_bind_null
|
||||
*/
|
||||
int sqlite3_bind_null(sqlite3_stmt*, int iParm){
|
||||
return sqlite_bind(pStmt, i, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
int sqlite3_bind_int32(sqlite3_stmt*, int iParm, int iValue){
|
||||
assert(!"TODO");
|
||||
}
|
||||
int sqlite3_bind_int64(sqlite3_stmt*, int iParm, long long int iValue){
|
||||
assert(!"TODO");
|
||||
}
|
||||
int sqlite3_bind_double(sqlite3_stmt*, int iParm, double iValue){
|
||||
assert(!"TODO");
|
||||
}
|
||||
int sqlite3_bind_blob(sqlite3_stmt*, int i, const void*, int n, int eCopy){
|
||||
assert(!"TODO");
|
||||
}
|
||||
|
||||
|
||||
int sqlite3_column_count(sqlite3_stmt*){
|
||||
}
|
||||
|
||||
int sqlite3_column_type(sqlite3_stmt*,int){
|
||||
}
|
||||
|
||||
const char *sqlite3_column_decltype(sqlite3_stmt*,int){
|
||||
}
|
||||
|
||||
const void *sqlite3_column_decltype16(sqlite3_stmt*,int){
|
||||
}
|
||||
|
||||
const char *sqlite3_column_name(sqlite3_stmt*,int){
|
||||
}
|
||||
|
||||
const void *sqlite3_column_name16(sqlite3_stmt*,int){
|
||||
}
|
||||
|
||||
const unsigned char *sqlite3_column_data(sqlite3_stmt*,int){
|
||||
}
|
||||
|
||||
const void *sqlite3_column_data16(sqlite3_stmt*,int){
|
||||
}
|
||||
|
||||
int sqlite3_column_bytes(sqlite3_stmt*,int){
|
||||
}
|
||||
|
||||
long long int sqlite3_column_int(sqlite3_stmt*,int){
|
||||
}
|
||||
|
||||
double sqlite3_column_float(sqlite3_stmt*,int){
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@@ -352,7 +352,6 @@ int Md5_Init(Tcl_Interp *interp){
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
** During testing, the special md5sum() aggregate function is available.
|
||||
** inside SQLite. The following routines implement that function.
|
||||
@@ -384,4 +383,6 @@ static void md5finalize(sqlite_func *context){
|
||||
void Md5_Register(sqlite *db){
|
||||
sqlite_create_aggregate(db, "md5sum", -1, md5step, md5finalize, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
129
src/os.c
129
src/os.c
@@ -265,7 +265,7 @@ static Hash openHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
|
||||
static void releaseLockInfo(struct lockInfo *pLock){
|
||||
pLock->nRef--;
|
||||
if( pLock->nRef==0 ){
|
||||
sqliteHashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
|
||||
sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
|
||||
sqliteFree(pLock);
|
||||
}
|
||||
}
|
||||
@@ -276,7 +276,7 @@ static void releaseLockInfo(struct lockInfo *pLock){
|
||||
static void releaseOpenCnt(struct openCnt *pOpen){
|
||||
pOpen->nRef--;
|
||||
if( pOpen->nRef==0 ){
|
||||
sqliteHashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
|
||||
sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
|
||||
sqliteFree(pOpen->aPending);
|
||||
sqliteFree(pOpen);
|
||||
}
|
||||
@@ -309,7 +309,7 @@ int findLockInfo(
|
||||
memset(&key2, 0, sizeof(key2));
|
||||
key2.dev = statbuf.st_dev;
|
||||
key2.ino = statbuf.st_ino;
|
||||
pLock = (struct lockInfo*)sqliteHashFind(&lockHash, &key1, sizeof(key1));
|
||||
pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1));
|
||||
if( pLock==0 ){
|
||||
struct lockInfo *pOld;
|
||||
pLock = sqliteMallocRaw( sizeof(*pLock) );
|
||||
@@ -317,7 +317,7 @@ int findLockInfo(
|
||||
pLock->key = key1;
|
||||
pLock->nRef = 1;
|
||||
pLock->cnt = 0;
|
||||
pOld = sqliteHashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
|
||||
pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
|
||||
if( pOld!=0 ){
|
||||
assert( pOld==pLock );
|
||||
sqliteFree(pLock);
|
||||
@@ -327,7 +327,7 @@ int findLockInfo(
|
||||
pLock->nRef++;
|
||||
}
|
||||
*ppLock = pLock;
|
||||
pOpen = (struct openCnt*)sqliteHashFind(&openHash, &key2, sizeof(key2));
|
||||
pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2));
|
||||
if( pOpen==0 ){
|
||||
struct openCnt *pOld;
|
||||
pOpen = sqliteMallocRaw( sizeof(*pOpen) );
|
||||
@@ -340,7 +340,7 @@ int findLockInfo(
|
||||
pOpen->nLock = 0;
|
||||
pOpen->nPending = 0;
|
||||
pOpen->aPending = 0;
|
||||
pOld = sqliteHashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
|
||||
pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
|
||||
if( pOld!=0 ){
|
||||
assert( pOld==pOpen );
|
||||
sqliteFree(pOpen);
|
||||
@@ -387,7 +387,7 @@ int sqlite_open_file_count = 0;
|
||||
/*
|
||||
** Delete the named file
|
||||
*/
|
||||
int sqliteOsDelete(const char *zFilename){
|
||||
int sqlite3OsDelete(const char *zFilename){
|
||||
#if OS_UNIX
|
||||
unlink(zFilename);
|
||||
#endif
|
||||
@@ -403,7 +403,7 @@ int sqliteOsDelete(const char *zFilename){
|
||||
/*
|
||||
** Return TRUE if the named file exists.
|
||||
*/
|
||||
int sqliteOsFileExists(const char *zFilename){
|
||||
int sqlite3OsFileExists(const char *zFilename){
|
||||
#if OS_UNIX
|
||||
return access(zFilename, 0)==0;
|
||||
#endif
|
||||
@@ -454,7 +454,7 @@ int sqliteOsFileRename(const char *zOldName, const char *zNewName){
|
||||
** On failure, the function returns SQLITE_CANTOPEN and leaves
|
||||
** *id and *pReadonly unchanged.
|
||||
*/
|
||||
int sqliteOsOpenReadWrite(
|
||||
int sqlite3OsOpenReadWrite(
|
||||
const char *zFilename,
|
||||
OsFile *id,
|
||||
int *pReadonly
|
||||
@@ -472,9 +472,9 @@ int sqliteOsOpenReadWrite(
|
||||
}else{
|
||||
*pReadonly = 0;
|
||||
}
|
||||
sqliteOsEnterMutex();
|
||||
sqlite3OsEnterMutex();
|
||||
rc = findLockInfo(id->fd, &id->pLock, &id->pOpen);
|
||||
sqliteOsLeaveMutex();
|
||||
sqlite3OsLeaveMutex();
|
||||
if( rc ){
|
||||
close(id->fd);
|
||||
return SQLITE_NOMEM;
|
||||
@@ -541,7 +541,7 @@ int sqliteOsOpenReadWrite(
|
||||
*pReadonly = 0;
|
||||
# else
|
||||
__path2fss(zFilename, &fsSpec);
|
||||
if( !sqliteOsFileExists(zFilename) ){
|
||||
if( !sqlite3OsFileExists(zFilename) ){
|
||||
if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'SQLI', cDocumentFile) != noErr )
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
@@ -581,7 +581,7 @@ int sqliteOsOpenReadWrite(
|
||||
**
|
||||
** On failure, return SQLITE_CANTOPEN.
|
||||
*/
|
||||
int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
|
||||
int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
|
||||
#if OS_UNIX
|
||||
int rc;
|
||||
if( access(zFilename, 0)==0 ){
|
||||
@@ -593,9 +593,9 @@ int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
|
||||
if( id->fd<0 ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
sqliteOsEnterMutex();
|
||||
sqlite3OsEnterMutex();
|
||||
rc = findLockInfo(id->fd, &id->pLock, &id->pOpen);
|
||||
sqliteOsLeaveMutex();
|
||||
sqlite3OsLeaveMutex();
|
||||
if( rc ){
|
||||
close(id->fd);
|
||||
unlink(zFilename);
|
||||
@@ -659,7 +659,7 @@ int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
|
||||
id->locked = 0;
|
||||
id->delOnClose = delFlag;
|
||||
if (delFlag)
|
||||
id->pathToDel = sqliteOsFullPathname(zFilename);
|
||||
id->pathToDel = sqlite3OsFullPathname(zFilename);
|
||||
OpenCounter(+1);
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
@@ -672,7 +672,7 @@ int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
|
||||
**
|
||||
** On failure, return SQLITE_CANTOPEN.
|
||||
*/
|
||||
int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){
|
||||
int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
|
||||
#if OS_UNIX
|
||||
int rc;
|
||||
id->dirfd = -1;
|
||||
@@ -680,9 +680,9 @@ int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){
|
||||
if( id->fd<0 ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
sqliteOsEnterMutex();
|
||||
sqlite3OsEnterMutex();
|
||||
rc = findLockInfo(id->fd, &id->pLock, &id->pOpen);
|
||||
sqliteOsLeaveMutex();
|
||||
sqlite3OsLeaveMutex();
|
||||
if( rc ){
|
||||
close(id->fd);
|
||||
return SQLITE_NOMEM;
|
||||
@@ -753,7 +753,7 @@ int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){
|
||||
** On failure, the function returns SQLITE_CANTOPEN and leaves
|
||||
** *id unchanged.
|
||||
*/
|
||||
int sqliteOsOpenDirectory(
|
||||
int sqlite3OsOpenDirectory(
|
||||
const char *zDirname,
|
||||
OsFile *id
|
||||
){
|
||||
@@ -777,7 +777,7 @@ int sqliteOsOpenDirectory(
|
||||
** Create a temporary file name in zBuf. zBuf must be big enough to
|
||||
** hold at least SQLITE_TEMPNAME_SIZE characters.
|
||||
*/
|
||||
int sqliteOsTempFileName(char *zBuf){
|
||||
int sqlite3OsTempFileName(char *zBuf){
|
||||
#if OS_UNIX
|
||||
static const char *azDirs[] = {
|
||||
"/var/tmp",
|
||||
@@ -802,7 +802,7 @@ int sqliteOsTempFileName(char *zBuf){
|
||||
do{
|
||||
sprintf(zBuf, "%s/"TEMP_FILE_PREFIX, zDir);
|
||||
j = strlen(zBuf);
|
||||
sqliteRandomness(15, &zBuf[j]);
|
||||
sqlite3Randomness(15, &zBuf[j]);
|
||||
for(i=0; i<15; i++, j++){
|
||||
zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
|
||||
}
|
||||
@@ -822,12 +822,12 @@ int sqliteOsTempFileName(char *zBuf){
|
||||
for(;;){
|
||||
sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
|
||||
j = strlen(zBuf);
|
||||
sqliteRandomness(15, &zBuf[j]);
|
||||
sqlite3Randomness(15, &zBuf[j]);
|
||||
for(i=0; i<15; i++, j++){
|
||||
zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
|
||||
}
|
||||
zBuf[j] = 0;
|
||||
if( !sqliteOsFileExists(zBuf) ) break;
|
||||
if( !sqlite3OsFileExists(zBuf) ) break;
|
||||
}
|
||||
#endif
|
||||
#if OS_MAC
|
||||
@@ -865,12 +865,12 @@ int sqliteOsTempFileName(char *zBuf){
|
||||
for(;;){
|
||||
sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zTempPath);
|
||||
j = strlen(zBuf);
|
||||
sqliteRandomness(15, &zBuf[j]);
|
||||
sqlite3Randomness(15, &zBuf[j]);
|
||||
for(i=0; i<15; i++, j++){
|
||||
zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
|
||||
}
|
||||
zBuf[j] = 0;
|
||||
if( !sqliteOsFileExists(zBuf) ) break;
|
||||
if( !sqlite3OsFileExists(zBuf) ) break;
|
||||
}
|
||||
#endif
|
||||
return SQLITE_OK;
|
||||
@@ -879,12 +879,12 @@ int sqliteOsTempFileName(char *zBuf){
|
||||
/*
|
||||
** Close a file.
|
||||
*/
|
||||
int sqliteOsClose(OsFile *id){
|
||||
int sqlite3OsClose(OsFile *id){
|
||||
#if OS_UNIX
|
||||
sqliteOsUnlock(id);
|
||||
sqlite3OsUnlock(id);
|
||||
if( id->dirfd>=0 ) close(id->dirfd);
|
||||
id->dirfd = -1;
|
||||
sqliteOsEnterMutex();
|
||||
sqlite3OsEnterMutex();
|
||||
if( id->pOpen->nLock ){
|
||||
/* If there are outstanding locks, do not actually close the file just
|
||||
** yet because that would clear those locks. Instead, add the file
|
||||
@@ -907,7 +907,7 @@ int sqliteOsClose(OsFile *id){
|
||||
}
|
||||
releaseLockInfo(id->pLock);
|
||||
releaseOpenCnt(id->pOpen);
|
||||
sqliteOsLeaveMutex();
|
||||
sqlite3OsLeaveMutex();
|
||||
TRACE2("CLOSE %-3d\n", id->fd);
|
||||
OpenCounter(-1);
|
||||
return SQLITE_OK;
|
||||
@@ -939,7 +939,7 @@ int sqliteOsClose(OsFile *id){
|
||||
** bytes were read successfully and SQLITE_IOERR if anything goes
|
||||
** wrong.
|
||||
*/
|
||||
int sqliteOsRead(OsFile *id, void *pBuf, int amt){
|
||||
int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
|
||||
#if OS_UNIX
|
||||
int got;
|
||||
SimulateIOError(SQLITE_IOERR);
|
||||
@@ -990,7 +990,7 @@ int sqliteOsRead(OsFile *id, void *pBuf, int amt){
|
||||
** Write data from a buffer into a file. Return SQLITE_OK on success
|
||||
** or some other error code on failure.
|
||||
*/
|
||||
int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){
|
||||
int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
|
||||
#if OS_UNIX
|
||||
int wrote = 0;
|
||||
SimulateIOError(SQLITE_IOERR);
|
||||
@@ -1049,7 +1049,7 @@ int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){
|
||||
/*
|
||||
** Move the read/write pointer in a file.
|
||||
*/
|
||||
int sqliteOsSeek(OsFile *id, off_t offset){
|
||||
int sqlite3OsSeek(OsFile *id, off_t offset){
|
||||
SEEK(offset/1024 + 1);
|
||||
#if OS_UNIX
|
||||
lseek(id->fd, offset, SEEK_SET);
|
||||
@@ -1068,11 +1068,11 @@ int sqliteOsSeek(OsFile *id, off_t offset){
|
||||
#if OS_MAC
|
||||
{
|
||||
off_t curSize;
|
||||
if( sqliteOsFileSize(id, &curSize) != SQLITE_OK ){
|
||||
if( sqlite3OsFileSize(id, &curSize) != SQLITE_OK ){
|
||||
return SQLITE_IOERR;
|
||||
}
|
||||
if( offset >= curSize ){
|
||||
if( sqliteOsTruncate(id, offset+1) != SQLITE_OK ){
|
||||
if( sqlite3OsTruncate(id, offset+1) != SQLITE_OK ){
|
||||
return SQLITE_IOERR;
|
||||
}
|
||||
}
|
||||
@@ -1100,7 +1100,7 @@ int sqliteOsSeek(OsFile *id, off_t offset){
|
||||
** the directory entry for the journal was never created) and the transaction
|
||||
** will not roll back - possibly leading to database corruption.
|
||||
*/
|
||||
int sqliteOsSync(OsFile *id){
|
||||
int sqlite3OsSync(OsFile *id){
|
||||
#if OS_UNIX
|
||||
SimulateIOError(SQLITE_IOERR);
|
||||
TRACE2("SYNC %-3d\n", id->fd);
|
||||
@@ -1142,7 +1142,7 @@ int sqliteOsSync(OsFile *id){
|
||||
/*
|
||||
** Truncate an open file to a specified size
|
||||
*/
|
||||
int sqliteOsTruncate(OsFile *id, off_t nByte){
|
||||
int sqlite3OsTruncate(OsFile *id, off_t nByte){
|
||||
SimulateIOError(SQLITE_IOERR);
|
||||
#if OS_UNIX
|
||||
return ftruncate(id->fd, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
|
||||
@@ -1171,7 +1171,7 @@ int sqliteOsTruncate(OsFile *id, off_t nByte){
|
||||
/*
|
||||
** Determine the current size of a file in bytes
|
||||
*/
|
||||
int sqliteOsFileSize(OsFile *id, off_t *pSize){
|
||||
int sqlite3OsFileSize(OsFile *id, off_t *pSize){
|
||||
#if OS_UNIX
|
||||
struct stat buf;
|
||||
SimulateIOError(SQLITE_IOERR);
|
||||
@@ -1248,11 +1248,11 @@ int isNT(void){
|
||||
** A lock is obtained on the first byte of the lock range before acquiring
|
||||
** either a read lock or a write lock. This prevents two processes from
|
||||
** attempting to get a lock at a same time. The semantics of
|
||||
** sqliteOsReadLock() require that if there is already a write lock, that
|
||||
** sqlite3OsReadLock() require that if there is already a write lock, that
|
||||
** lock is converted into a read lock atomically. The lock on the first
|
||||
** byte allows us to drop the old write lock and get the read lock without
|
||||
** another process jumping into the middle and messing us up. The same
|
||||
** argument applies to sqliteOsWriteLock().
|
||||
** argument applies to sqlite3OsWriteLock().
|
||||
**
|
||||
** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
|
||||
** which means we can use reader/writer locks. When reader writer locks
|
||||
@@ -1286,10 +1286,10 @@ int isNT(void){
|
||||
** library was compiled with large file support (LFS) but LFS is not
|
||||
** available on the host, then an SQLITE_NOLFS is returned.
|
||||
*/
|
||||
int sqliteOsReadLock(OsFile *id){
|
||||
int sqlite3OsReadLock(OsFile *id){
|
||||
#if OS_UNIX
|
||||
int rc;
|
||||
sqliteOsEnterMutex();
|
||||
sqlite3OsEnterMutex();
|
||||
if( id->pLock->cnt>0 ){
|
||||
if( !id->locked ){
|
||||
id->pLock->cnt++;
|
||||
@@ -1317,7 +1317,7 @@ int sqliteOsReadLock(OsFile *id){
|
||||
}else{
|
||||
rc = SQLITE_BUSY;
|
||||
}
|
||||
sqliteOsLeaveMutex();
|
||||
sqlite3OsLeaveMutex();
|
||||
return rc;
|
||||
#endif
|
||||
#if OS_WIN
|
||||
@@ -1328,7 +1328,7 @@ int sqliteOsReadLock(OsFile *id){
|
||||
int lk;
|
||||
int res;
|
||||
int cnt = 100;
|
||||
sqliteRandomness(sizeof(lk), &lk);
|
||||
sqlite3Randomness(sizeof(lk), &lk);
|
||||
lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
|
||||
while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
|
||||
Sleep(1);
|
||||
@@ -1365,7 +1365,7 @@ int sqliteOsReadLock(OsFile *id){
|
||||
OSErr res;
|
||||
int cnt = 5;
|
||||
ParamBlockRec params;
|
||||
sqliteRandomness(sizeof(lk), &lk);
|
||||
sqlite3Randomness(sizeof(lk), &lk);
|
||||
lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.ioParam.ioRefNum = id->refNumRF;
|
||||
@@ -1404,10 +1404,10 @@ int sqliteOsReadLock(OsFile *id){
|
||||
** library was compiled with large file support (LFS) but LFS is not
|
||||
** available on the host, then an SQLITE_NOLFS is returned.
|
||||
*/
|
||||
int sqliteOsWriteLock(OsFile *id){
|
||||
int sqlite3OsWriteLock(OsFile *id){
|
||||
#if OS_UNIX
|
||||
int rc;
|
||||
sqliteOsEnterMutex();
|
||||
sqlite3OsEnterMutex();
|
||||
if( id->pLock->cnt==0 || (id->pLock->cnt==1 && id->locked==1) ){
|
||||
struct flock lock;
|
||||
int s;
|
||||
@@ -1428,7 +1428,7 @@ int sqliteOsWriteLock(OsFile *id){
|
||||
}else{
|
||||
rc = SQLITE_BUSY;
|
||||
}
|
||||
sqliteOsLeaveMutex();
|
||||
sqlite3OsLeaveMutex();
|
||||
return rc;
|
||||
#endif
|
||||
#if OS_WIN
|
||||
@@ -1514,11 +1514,11 @@ int sqliteOsWriteLock(OsFile *id){
|
||||
** library was compiled with large file support (LFS) but LFS is not
|
||||
** available on the host, then an SQLITE_NOLFS is returned.
|
||||
*/
|
||||
int sqliteOsUnlock(OsFile *id){
|
||||
int sqlite3OsUnlock(OsFile *id){
|
||||
#if OS_UNIX
|
||||
int rc;
|
||||
if( !id->locked ) return SQLITE_OK;
|
||||
sqliteOsEnterMutex();
|
||||
sqlite3OsEnterMutex();
|
||||
assert( id->pLock->cnt!=0 );
|
||||
if( id->pLock->cnt>1 ){
|
||||
id->pLock->cnt--;
|
||||
@@ -1555,7 +1555,7 @@ int sqliteOsUnlock(OsFile *id){
|
||||
pOpen->aPending = 0;
|
||||
}
|
||||
}
|
||||
sqliteOsLeaveMutex();
|
||||
sqlite3OsLeaveMutex();
|
||||
id->locked = 0;
|
||||
return rc;
|
||||
#endif
|
||||
@@ -1604,7 +1604,7 @@ int sqliteOsUnlock(OsFile *id){
|
||||
** is written into the buffer zBuf[256]. The calling function must
|
||||
** supply a sufficiently large buffer.
|
||||
*/
|
||||
int sqliteOsRandomSeed(char *zBuf){
|
||||
int sqlite3OsRandomSeed(char *zBuf){
|
||||
/* We have to initialize zBuf to prevent valgrind from reporting
|
||||
** errors. The reports issued by valgrind are incorrect - we would
|
||||
** prefer that the randomness be increased by making use of the
|
||||
@@ -1643,7 +1643,7 @@ int sqliteOsRandomSeed(char *zBuf){
|
||||
/*
|
||||
** Sleep for a little while. Return the amount of time slept.
|
||||
*/
|
||||
int sqliteOsSleep(int ms){
|
||||
int sqlite3OsSleep(int ms){
|
||||
#if OS_UNIX
|
||||
#if defined(HAVE_USLEEP) && HAVE_USLEEP
|
||||
usleep(ms*1000);
|
||||
@@ -1687,7 +1687,7 @@ static int inMutex = 0;
|
||||
** SQLite uses only a single Mutex. There is not much critical
|
||||
** code and what little there is executes quickly and without blocking.
|
||||
*/
|
||||
void sqliteOsEnterMutex(){
|
||||
void sqlite3OsEnterMutex(){
|
||||
#ifdef SQLITE_UNIX_THREADS
|
||||
pthread_mutex_lock(&mutex);
|
||||
#endif
|
||||
@@ -1720,7 +1720,7 @@ void sqliteOsEnterMutex(){
|
||||
assert( !inMutex );
|
||||
inMutex = 1;
|
||||
}
|
||||
void sqliteOsLeaveMutex(){
|
||||
void sqlite3OsLeaveMutex(){
|
||||
assert( inMutex );
|
||||
inMutex = 0;
|
||||
#ifdef SQLITE_UNIX_THREADS
|
||||
@@ -1740,14 +1740,14 @@ void sqliteOsLeaveMutex(){
|
||||
** The calling function is responsible for freeing this space once it
|
||||
** is no longer needed.
|
||||
*/
|
||||
char *sqliteOsFullPathname(const char *zRelative){
|
||||
char *sqlite3OsFullPathname(const char *zRelative){
|
||||
#if OS_UNIX
|
||||
char *zFull = 0;
|
||||
if( zRelative[0]=='/' ){
|
||||
sqliteSetString(&zFull, zRelative, (char*)0);
|
||||
sqlite3SetString(&zFull, zRelative, (char*)0);
|
||||
}else{
|
||||
char zBuf[5000];
|
||||
sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative,
|
||||
sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative,
|
||||
(char*)0);
|
||||
}
|
||||
return zFull;
|
||||
@@ -1766,14 +1766,14 @@ char *sqliteOsFullPathname(const char *zRelative){
|
||||
char *zFull = 0;
|
||||
if( zRelative[0]==':' ){
|
||||
char zBuf[_MAX_PATH+1];
|
||||
sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), &(zRelative[1]),
|
||||
sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), &(zRelative[1]),
|
||||
(char*)0);
|
||||
}else{
|
||||
if( strchr(zRelative, ':') ){
|
||||
sqliteSetString(&zFull, zRelative, (char*)0);
|
||||
sqlite3SetString(&zFull, zRelative, (char*)0);
|
||||
}else{
|
||||
char zBuf[_MAX_PATH+1];
|
||||
sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), zRelative, (char*)0);
|
||||
sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), zRelative, (char*)0);
|
||||
}
|
||||
}
|
||||
return zFull;
|
||||
@@ -1782,7 +1782,7 @@ char *sqliteOsFullPathname(const char *zRelative){
|
||||
|
||||
/*
|
||||
** The following variable, if set to a non-zero value, becomes the result
|
||||
** returned from sqliteOsCurrentTime(). This is used for testing.
|
||||
** returned from sqlite3OsCurrentTime(). This is used for testing.
|
||||
*/
|
||||
#ifdef SQLITE_TEST
|
||||
int sqlite_current_time = 0;
|
||||
@@ -1793,7 +1793,7 @@ int sqlite_current_time = 0;
|
||||
** current time and date as a Julian Day number into *prNow and
|
||||
** return 0. Return 1 if the time and date cannot be found.
|
||||
*/
|
||||
int sqliteOsCurrentTime(double *prNow){
|
||||
int sqlite3OsCurrentTime(double *prNow){
|
||||
#if OS_UNIX
|
||||
time_t t;
|
||||
time(&t);
|
||||
@@ -1816,3 +1816,6 @@ int sqliteOsCurrentTime(double *prNow){
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
49
src/os.h
49
src/os.h
@@ -161,31 +161,34 @@
|
||||
# define SQLITE_MIN_SLEEP_MS 17
|
||||
#endif
|
||||
|
||||
int sqliteOsDelete(const char*);
|
||||
int sqliteOsFileExists(const char*);
|
||||
int sqlite3OsDelete(const char*);
|
||||
int sqlite3OsFileExists(const char*);
|
||||
int sqliteOsFileRename(const char*, const char*);
|
||||
int sqliteOsOpenReadWrite(const char*, OsFile*, int*);
|
||||
int sqliteOsOpenExclusive(const char*, OsFile*, int);
|
||||
int sqliteOsOpenReadOnly(const char*, OsFile*);
|
||||
int sqliteOsOpenDirectory(const char*, OsFile*);
|
||||
int sqliteOsTempFileName(char*);
|
||||
int sqliteOsClose(OsFile*);
|
||||
int sqliteOsRead(OsFile*, void*, int amt);
|
||||
int sqliteOsWrite(OsFile*, const void*, int amt);
|
||||
int sqliteOsSeek(OsFile*, off_t offset);
|
||||
int sqliteOsSync(OsFile*);
|
||||
int sqliteOsTruncate(OsFile*, off_t size);
|
||||
int sqliteOsFileSize(OsFile*, off_t *pSize);
|
||||
int sqliteOsReadLock(OsFile*);
|
||||
int sqliteOsWriteLock(OsFile*);
|
||||
int sqliteOsUnlock(OsFile*);
|
||||
int sqliteOsRandomSeed(char*);
|
||||
int sqliteOsSleep(int ms);
|
||||
int sqliteOsCurrentTime(double*);
|
||||
void sqliteOsEnterMutex(void);
|
||||
void sqliteOsLeaveMutex(void);
|
||||
char *sqliteOsFullPathname(const char*);
|
||||
int sqlite3OsOpenReadWrite(const char*, OsFile*, int*);
|
||||
int sqlite3OsOpenExclusive(const char*, OsFile*, int);
|
||||
int sqlite3OsOpenReadOnly(const char*, OsFile*);
|
||||
int sqlite3OsOpenDirectory(const char*, OsFile*);
|
||||
int sqlite3OsTempFileName(char*);
|
||||
int sqlite3OsClose(OsFile*);
|
||||
int sqlite3OsRead(OsFile*, void*, int amt);
|
||||
int sqlite3OsWrite(OsFile*, const void*, int amt);
|
||||
int sqlite3OsSeek(OsFile*, off_t offset);
|
||||
int sqlite3OsSync(OsFile*);
|
||||
int sqlite3OsTruncate(OsFile*, off_t size);
|
||||
int sqlite3OsFileSize(OsFile*, off_t *pSize);
|
||||
int sqlite3OsReadLock(OsFile*);
|
||||
int sqlite3OsWriteLock(OsFile*);
|
||||
int sqlite3OsUnlock(OsFile*);
|
||||
int sqlite3OsRandomSeed(char*);
|
||||
int sqlite3OsSleep(int ms);
|
||||
int sqlite3OsCurrentTime(double*);
|
||||
void sqlite3OsEnterMutex(void);
|
||||
void sqlite3OsLeaveMutex(void);
|
||||
char *sqlite3OsFullPathname(const char*);
|
||||
|
||||
|
||||
|
||||
#endif /* _SQLITE_OS_H_ */
|
||||
|
||||
|
||||
|
||||
|
143
src/pager.c
143
src/pager.c
@@ -18,7 +18,7 @@
|
||||
** file simultaneously, or one process from reading the database while
|
||||
** another is writing.
|
||||
**
|
||||
** @(#) $Id: pager.c,v 1.103 2004/05/07 17:57:50 drh Exp $
|
||||
** @(#) $Id: pager.c,v 1.104 2004/05/08 08:23:28 danielk1977 Exp $
|
||||
*/
|
||||
#include "os.h" /* Must be first to enable large file support */
|
||||
#include "sqliteInt.h"
|
||||
@@ -315,7 +315,7 @@ int journal_format = 3;
|
||||
static int read32bits(int format, OsFile *fd, u32 *pRes){
|
||||
u32 res;
|
||||
int rc;
|
||||
rc = sqliteOsRead(fd, &res, sizeof(res));
|
||||
rc = sqlite3OsRead(fd, &res, sizeof(res));
|
||||
if( rc==SQLITE_OK && format>JOURNAL_FORMAT_1 ){
|
||||
unsigned char ac[4];
|
||||
memcpy(ac, &res, 4);
|
||||
@@ -337,13 +337,13 @@ static int read32bits(int format, OsFile *fd, u32 *pRes){
|
||||
static int write32bits(OsFile *fd, u32 val){
|
||||
unsigned char ac[4];
|
||||
if( journal_format<=1 ){
|
||||
return sqliteOsWrite(fd, &val, 4);
|
||||
return sqlite3OsWrite(fd, &val, 4);
|
||||
}
|
||||
ac[0] = (val>>24) & 0xff;
|
||||
ac[1] = (val>>16) & 0xff;
|
||||
ac[2] = (val>>8) & 0xff;
|
||||
ac[3] = val & 0xff;
|
||||
return sqliteOsWrite(fd, ac, 4);
|
||||
return sqlite3OsWrite(fd, ac, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -453,7 +453,7 @@ static void pager_reset(Pager *pPager){
|
||||
if( pPager->state>=SQLITE_WRITELOCK ){
|
||||
sqlite3pager_rollback(pPager);
|
||||
}
|
||||
sqliteOsUnlock(&pPager->fd);
|
||||
sqlite3OsUnlock(&pPager->fd);
|
||||
pPager->state = SQLITE_UNLOCK;
|
||||
pPager->dbSize = -1;
|
||||
pPager->nRef = 0;
|
||||
@@ -476,13 +476,13 @@ static int pager_unwritelock(Pager *pPager){
|
||||
if( pPager->state<SQLITE_WRITELOCK ) return SQLITE_OK;
|
||||
sqlite3pager_stmt_commit(pPager);
|
||||
if( pPager->ckptOpen ){
|
||||
sqliteOsClose(&pPager->cpfd);
|
||||
sqlite3OsClose(&pPager->cpfd);
|
||||
pPager->ckptOpen = 0;
|
||||
}
|
||||
if( pPager->journalOpen ){
|
||||
sqliteOsClose(&pPager->jfd);
|
||||
sqlite3OsClose(&pPager->jfd);
|
||||
pPager->journalOpen = 0;
|
||||
sqliteOsDelete(pPager->zJournal);
|
||||
sqlite3OsDelete(pPager->zJournal);
|
||||
sqliteFree( pPager->aInJournal );
|
||||
pPager->aInJournal = 0;
|
||||
for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
|
||||
@@ -493,7 +493,7 @@ static int pager_unwritelock(Pager *pPager){
|
||||
}else{
|
||||
assert( pPager->dirtyFile==0 || pPager->useJournal==0 );
|
||||
}
|
||||
rc = sqliteOsReadLock(&pPager->fd);
|
||||
rc = sqlite3OsReadLock(&pPager->fd);
|
||||
if( rc==SQLITE_OK ){
|
||||
pPager->state = SQLITE_READLOCK;
|
||||
}else{
|
||||
@@ -533,7 +533,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int format){
|
||||
|
||||
rc = read32bits(format, jfd, &pgRec.pgno);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
rc = sqliteOsRead(jfd, &pgRec.aData, sizeof(pgRec.aData));
|
||||
rc = sqlite3OsRead(jfd, &pgRec.aData, sizeof(pgRec.aData));
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
|
||||
/* Sanity checking on the page. This is more important that I originally
|
||||
@@ -560,8 +560,8 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int format){
|
||||
*/
|
||||
pPg = pager_lookup(pPager, pgRec.pgno);
|
||||
TRACE2("PLAYBACK %d\n", pgRec.pgno);
|
||||
sqliteOsSeek(&pPager->fd, (pgRec.pgno-1)*(off_t)SQLITE_PAGE_SIZE);
|
||||
rc = sqliteOsWrite(&pPager->fd, pgRec.aData, SQLITE_PAGE_SIZE);
|
||||
sqlite3OsSeek(&pPager->fd, (pgRec.pgno-1)*(off_t)SQLITE_PAGE_SIZE);
|
||||
rc = sqlite3OsWrite(&pPager->fd, pgRec.aData, SQLITE_PAGE_SIZE);
|
||||
if( pPg ){
|
||||
/* No page should ever be rolled back that is in use, except for page
|
||||
** 1 which is held in use in order to keep the lock on the database
|
||||
@@ -644,8 +644,8 @@ static int pager_playback(Pager *pPager, int useJournalSize){
|
||||
** the journal is empty.
|
||||
*/
|
||||
assert( pPager->journalOpen );
|
||||
sqliteOsSeek(&pPager->jfd, 0);
|
||||
rc = sqliteOsFileSize(&pPager->jfd, &szJ);
|
||||
sqlite3OsSeek(&pPager->jfd, 0);
|
||||
rc = sqlite3OsFileSize(&pPager->jfd, &szJ);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto end_playback;
|
||||
}
|
||||
@@ -663,7 +663,7 @@ static int pager_playback(Pager *pPager, int useJournalSize){
|
||||
/* Read the beginning of the journal and truncate the
|
||||
** database file back to its original size.
|
||||
*/
|
||||
rc = sqliteOsRead(&pPager->jfd, aMagic, sizeof(aMagic));
|
||||
rc = sqlite3OsRead(&pPager->jfd, aMagic, sizeof(aMagic));
|
||||
if( rc!=SQLITE_OK ){
|
||||
rc = SQLITE_PROTOCOL;
|
||||
goto end_playback;
|
||||
@@ -704,7 +704,7 @@ static int pager_playback(Pager *pPager, int useJournalSize){
|
||||
goto end_playback;
|
||||
}
|
||||
assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg );
|
||||
rc = sqliteOsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)mxPg);
|
||||
rc = sqlite3OsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)mxPg);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto end_playback;
|
||||
}
|
||||
@@ -732,8 +732,8 @@ static int pager_playback(Pager *pPager, int useJournalSize){
|
||||
char zBuf[SQLITE_PAGE_SIZE];
|
||||
if( !pPg->dirty ) continue;
|
||||
if( (int)pPg->pgno <= pPager->origDbSize ){
|
||||
sqliteOsSeek(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)(pPg->pgno-1));
|
||||
rc = sqliteOsRead(&pPager->fd, zBuf, SQLITE_PAGE_SIZE);
|
||||
sqlite3OsSeek(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)(pPg->pgno-1));
|
||||
rc = sqlite3OsRead(&pPager->fd, zBuf, SQLITE_PAGE_SIZE);
|
||||
TRACE2("REFETCH %d\n", pPg->pgno);
|
||||
CODEC(pPager, zBuf, pPg->pgno, 2);
|
||||
if( rc ) break;
|
||||
@@ -782,13 +782,13 @@ static int pager_stmt_playback(Pager *pPager){
|
||||
|
||||
/* Truncate the database back to its original size.
|
||||
*/
|
||||
rc = sqliteOsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)pPager->ckptSize);
|
||||
rc = sqlite3OsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)pPager->ckptSize);
|
||||
pPager->dbSize = pPager->ckptSize;
|
||||
|
||||
/* Figure out how many records are in the checkpoint journal.
|
||||
*/
|
||||
assert( pPager->ckptInUse && pPager->journalOpen );
|
||||
sqliteOsSeek(&pPager->cpfd, 0);
|
||||
sqlite3OsSeek(&pPager->cpfd, 0);
|
||||
nRec = pPager->ckptNRec;
|
||||
|
||||
/* Copy original pages out of the checkpoint journal and back into the
|
||||
@@ -805,11 +805,11 @@ static int pager_stmt_playback(Pager *pPager){
|
||||
/* Figure out how many pages need to be copied out of the transaction
|
||||
** journal.
|
||||
*/
|
||||
rc = sqliteOsSeek(&pPager->jfd, pPager->ckptJSize);
|
||||
rc = sqlite3OsSeek(&pPager->jfd, pPager->ckptJSize);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto end_stmt_playback;
|
||||
}
|
||||
rc = sqliteOsFileSize(&pPager->jfd, &szJ);
|
||||
rc = sqlite3OsFileSize(&pPager->jfd, &szJ);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto end_stmt_playback;
|
||||
}
|
||||
@@ -835,7 +835,7 @@ end_stmt_playback:
|
||||
**
|
||||
** The maximum number is the absolute value of the mxPage parameter.
|
||||
** If mxPage is negative, the noSync flag is also set. noSync bypasses
|
||||
** calls to sqliteOsSync(). The pager runs much faster with noSync on,
|
||||
** calls to sqlite3OsSync(). The pager runs much faster with noSync on,
|
||||
** but if the operating system crashes or there is an abrupt power
|
||||
** failure, the database file might be left in an inconsistent and
|
||||
** unrepairable state.
|
||||
@@ -858,7 +858,7 @@ void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){
|
||||
** or power failures by changing the number of syncs()s when writing
|
||||
** the rollback journal. There are three levels:
|
||||
**
|
||||
** OFF sqliteOsSync() is never called. This is the default
|
||||
** OFF sqlite3OsSync() is never called. This is the default
|
||||
** for temporary and transient files.
|
||||
**
|
||||
** NORMAL The journal is synced once before writes begin on the
|
||||
@@ -899,8 +899,8 @@ static int sqlite3pager_opentemp(char *zFile, OsFile *fd){
|
||||
int rc;
|
||||
do{
|
||||
cnt--;
|
||||
sqliteOsTempFileName(zFile);
|
||||
rc = sqliteOsOpenExclusive(zFile, fd, 1);
|
||||
sqlite3OsTempFileName(zFile);
|
||||
rc = sqlite3OsOpenExclusive(zFile, fd, 1);
|
||||
}while( cnt>0 && rc!=SQLITE_OK );
|
||||
return rc;
|
||||
}
|
||||
@@ -936,13 +936,13 @@ int sqlite3pager_open(
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
if( zFilename && zFilename[0] ){
|
||||
zFullPathname = sqliteOsFullPathname(zFilename);
|
||||
rc = sqliteOsOpenReadWrite(zFullPathname, &fd, &readOnly);
|
||||
zFullPathname = sqlite3OsFullPathname(zFilename);
|
||||
rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly);
|
||||
tempFile = 0;
|
||||
}else{
|
||||
rc = sqlite3pager_opentemp(zTemp, &fd);
|
||||
zFilename = zTemp;
|
||||
zFullPathname = sqliteOsFullPathname(zFilename);
|
||||
zFullPathname = sqlite3OsFullPathname(zFilename);
|
||||
tempFile = 1;
|
||||
}
|
||||
if( sqlite_malloc_failed ){
|
||||
@@ -955,7 +955,7 @@ int sqlite3pager_open(
|
||||
nameLen = strlen(zFullPathname);
|
||||
pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );
|
||||
if( pPager==0 ){
|
||||
sqliteOsClose(&fd);
|
||||
sqlite3OsClose(&fd);
|
||||
sqliteFree(zFullPathname);
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -1018,7 +1018,7 @@ int sqlite3pager_pagecount(Pager *pPager){
|
||||
if( pPager->dbSize>=0 ){
|
||||
return pPager->dbSize;
|
||||
}
|
||||
if( sqliteOsFileSize(&pPager->fd, &n)!=SQLITE_OK ){
|
||||
if( sqlite3OsFileSize(&pPager->fd, &n)!=SQLITE_OK ){
|
||||
pPager->errMask |= PAGER_ERR_DISK;
|
||||
return 0;
|
||||
}
|
||||
@@ -1050,7 +1050,7 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
syncJournal(pPager);
|
||||
rc = sqliteOsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)nPage);
|
||||
rc = sqlite3OsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)nPage);
|
||||
if( rc==SQLITE_OK ){
|
||||
pPager->dbSize = nPage;
|
||||
}
|
||||
@@ -1071,12 +1071,12 @@ int sqlite3pager_close(Pager *pPager){
|
||||
switch( pPager->state ){
|
||||
case SQLITE_WRITELOCK: {
|
||||
sqlite3pager_rollback(pPager);
|
||||
sqliteOsUnlock(&pPager->fd);
|
||||
sqlite3OsUnlock(&pPager->fd);
|
||||
assert( pPager->journalOpen==0 );
|
||||
break;
|
||||
}
|
||||
case SQLITE_READLOCK: {
|
||||
sqliteOsUnlock(&pPager->fd);
|
||||
sqlite3OsUnlock(&pPager->fd);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -1088,11 +1088,11 @@ int sqlite3pager_close(Pager *pPager){
|
||||
pNext = pPg->pNextAll;
|
||||
sqliteFree(pPg);
|
||||
}
|
||||
sqliteOsClose(&pPager->fd);
|
||||
sqlite3OsClose(&pPager->fd);
|
||||
assert( pPager->journalOpen==0 );
|
||||
/* Temp files are automatically deleted by the OS
|
||||
** if( pPager->tempFile ){
|
||||
** sqliteOsDelete(pPager->zFilename);
|
||||
** sqlite3OsDelete(pPager->zFilename);
|
||||
** }
|
||||
*/
|
||||
CLR_PAGER(pPager);
|
||||
@@ -1194,7 +1194,7 @@ static int syncJournal(Pager *pPager){
|
||||
off_t hdrSz, pgSz, jSz;
|
||||
hdrSz = JOURNAL_HDR_SZ(journal_format);
|
||||
pgSz = JOURNAL_PG_SZ(journal_format);
|
||||
rc = sqliteOsFileSize(&pPager->jfd, &jSz);
|
||||
rc = sqlite3OsFileSize(&pPager->jfd, &jSz);
|
||||
if( rc!=0 ) return rc;
|
||||
assert( pPager->nRec*pgSz+hdrSz==jSz );
|
||||
}
|
||||
@@ -1204,18 +1204,18 @@ static int syncJournal(Pager *pPager){
|
||||
off_t szJ;
|
||||
if( pPager->fullSync ){
|
||||
TRACE1("SYNC\n");
|
||||
rc = sqliteOsSync(&pPager->jfd);
|
||||
rc = sqlite3OsSync(&pPager->jfd);
|
||||
if( rc!=0 ) return rc;
|
||||
}
|
||||
sqliteOsSeek(&pPager->jfd, sizeof(aJournalMagic1));
|
||||
sqlite3OsSeek(&pPager->jfd, sizeof(aJournalMagic1));
|
||||
rc = write32bits(&pPager->jfd, pPager->nRec);
|
||||
if( rc ) return rc;
|
||||
szJ = JOURNAL_HDR_SZ(journal_format) +
|
||||
pPager->nRec*JOURNAL_PG_SZ(journal_format);
|
||||
sqliteOsSeek(&pPager->jfd, szJ);
|
||||
sqlite3OsSeek(&pPager->jfd, szJ);
|
||||
}
|
||||
TRACE1("SYNC\n");
|
||||
rc = sqliteOsSync(&pPager->jfd);
|
||||
rc = sqlite3OsSync(&pPager->jfd);
|
||||
if( rc!=0 ) return rc;
|
||||
pPager->journalStarted = 1;
|
||||
}
|
||||
@@ -1258,10 +1258,10 @@ static int pager_write_pagelist(PgHdr *pList){
|
||||
pPager = pList->pPager;
|
||||
while( pList ){
|
||||
assert( pList->dirty );
|
||||
sqliteOsSeek(&pPager->fd, (pList->pgno-1)*(off_t)SQLITE_PAGE_SIZE);
|
||||
sqlite3OsSeek(&pPager->fd, (pList->pgno-1)*(off_t)SQLITE_PAGE_SIZE);
|
||||
CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
|
||||
TRACE2("STORE %d\n", pList->pgno);
|
||||
rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pList), SQLITE_PAGE_SIZE);
|
||||
rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), SQLITE_PAGE_SIZE);
|
||||
CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0);
|
||||
if( rc ) return rc;
|
||||
pList->dirty = 0;
|
||||
@@ -1327,7 +1327,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
||||
** on the database file.
|
||||
*/
|
||||
if( pPager->nRef==0 ){
|
||||
rc = sqliteOsReadLock(&pPager->fd);
|
||||
rc = sqlite3OsReadLock(&pPager->fd);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -1335,14 +1335,14 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
||||
|
||||
/* If a journal file exists, try to play it back.
|
||||
*/
|
||||
if( pPager->useJournal && sqliteOsFileExists(pPager->zJournal) ){
|
||||
if( pPager->useJournal && sqlite3OsFileExists(pPager->zJournal) ){
|
||||
int rc;
|
||||
|
||||
/* Get a write lock on the database
|
||||
*/
|
||||
rc = sqliteOsWriteLock(&pPager->fd);
|
||||
rc = sqlite3OsWriteLock(&pPager->fd);
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( sqliteOsUnlock(&pPager->fd)!=SQLITE_OK ){
|
||||
if( sqlite3OsUnlock(&pPager->fd)!=SQLITE_OK ){
|
||||
/* This should never happen! */
|
||||
rc = SQLITE_INTERNAL;
|
||||
}
|
||||
@@ -1358,9 +1358,9 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
||||
** a write lock, so there is never any chance of two or more
|
||||
** processes opening the journal at the same time.
|
||||
*/
|
||||
rc = sqliteOsOpenReadOnly(pPager->zJournal, &pPager->jfd);
|
||||
rc = sqlite3OsOpenReadOnly(pPager->zJournal, &pPager->jfd);
|
||||
if( rc!=SQLITE_OK ){
|
||||
rc = sqliteOsUnlock(&pPager->fd);
|
||||
rc = sqlite3OsUnlock(&pPager->fd);
|
||||
assert( rc==SQLITE_OK );
|
||||
return SQLITE_BUSY;
|
||||
}
|
||||
@@ -1483,7 +1483,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
||||
}
|
||||
pPg->pgno = pgno;
|
||||
if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
|
||||
sqliteCheckMemory(pPager->aInJournal, pgno/8);
|
||||
sqlite3CheckMemory(pPager->aInJournal, pgno/8);
|
||||
assert( pPager->journalOpen );
|
||||
pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
|
||||
pPg->needSync = 0;
|
||||
@@ -1521,13 +1521,13 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
||||
memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
|
||||
}else{
|
||||
int rc;
|
||||
sqliteOsSeek(&pPager->fd, (pgno-1)*(off_t)SQLITE_PAGE_SIZE);
|
||||
rc = sqliteOsRead(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
|
||||
sqlite3OsSeek(&pPager->fd, (pgno-1)*(off_t)SQLITE_PAGE_SIZE);
|
||||
rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
|
||||
TRACE2("FETCH %d\n", pPg->pgno);
|
||||
CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
|
||||
if( rc!=SQLITE_OK ){
|
||||
off_t fileSize;
|
||||
if( sqliteOsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK
|
||||
if( sqlite3OsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK
|
||||
|| fileSize>=pgno*SQLITE_PAGE_SIZE ){
|
||||
sqlite3pager_unref(PGHDR_TO_DATA(pPg));
|
||||
return rc;
|
||||
@@ -1640,19 +1640,19 @@ static int pager_open_journal(Pager *pPager){
|
||||
sqlite3pager_pagecount(pPager);
|
||||
pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
|
||||
if( pPager->aInJournal==0 ){
|
||||
sqliteOsReadLock(&pPager->fd);
|
||||
sqlite3OsReadLock(&pPager->fd);
|
||||
pPager->state = SQLITE_READLOCK;
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
rc = sqliteOsOpenExclusive(pPager->zJournal, &pPager->jfd,pPager->tempFile);
|
||||
rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd,pPager->tempFile);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqliteFree(pPager->aInJournal);
|
||||
pPager->aInJournal = 0;
|
||||
sqliteOsReadLock(&pPager->fd);
|
||||
sqlite3OsReadLock(&pPager->fd);
|
||||
pPager->state = SQLITE_READLOCK;
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
sqliteOsOpenDirectory(pPager->zDirectory, &pPager->jfd);
|
||||
sqlite3OsOpenDirectory(pPager->zDirectory, &pPager->jfd);
|
||||
pPager->journalOpen = 1;
|
||||
pPager->journalStarted = 0;
|
||||
pPager->needSync = 0;
|
||||
@@ -1664,19 +1664,19 @@ static int pager_open_journal(Pager *pPager){
|
||||
}
|
||||
pPager->origDbSize = pPager->dbSize;
|
||||
if( journal_format==JOURNAL_FORMAT_3 ){
|
||||
rc = sqliteOsWrite(&pPager->jfd, aJournalMagic3, sizeof(aJournalMagic3));
|
||||
rc = sqlite3OsWrite(&pPager->jfd, aJournalMagic3, sizeof(aJournalMagic3));
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = write32bits(&pPager->jfd, pPager->noSync ? 0xffffffff : 0);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
sqliteRandomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
|
||||
sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
|
||||
rc = write32bits(&pPager->jfd, pPager->cksumInit);
|
||||
}
|
||||
}else if( journal_format==JOURNAL_FORMAT_2 ){
|
||||
rc = sqliteOsWrite(&pPager->jfd, aJournalMagic2, sizeof(aJournalMagic2));
|
||||
rc = sqlite3OsWrite(&pPager->jfd, aJournalMagic2, sizeof(aJournalMagic2));
|
||||
}else{
|
||||
assert( journal_format==JOURNAL_FORMAT_1 );
|
||||
rc = sqliteOsWrite(&pPager->jfd, aJournalMagic1, sizeof(aJournalMagic1));
|
||||
rc = sqlite3OsWrite(&pPager->jfd, aJournalMagic1, sizeof(aJournalMagic1));
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = write32bits(&pPager->jfd, pPager->dbSize);
|
||||
@@ -1721,7 +1721,7 @@ int sqlite3pager_begin(void *pData){
|
||||
assert( pPager->state!=SQLITE_UNLOCK );
|
||||
if( pPager->state==SQLITE_READLOCK ){
|
||||
assert( pPager->aInJournal==0 );
|
||||
rc = sqliteOsWriteLock(&pPager->fd);
|
||||
rc = sqlite3OsWriteLock(&pPager->fd);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@@ -1813,7 +1813,7 @@ int sqlite3pager_write(void *pData){
|
||||
}
|
||||
store32bits(pPg->pgno, pPg, -4);
|
||||
CODEC(pPager, pData, pPg->pgno, 7);
|
||||
rc = sqliteOsWrite(&pPager->jfd, &((char*)pData)[-4], szPg);
|
||||
rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg);
|
||||
TRACE3("JOURNAL %d %d\n", pPg->pgno, pPg->needSync);
|
||||
CODEC(pPager, pData, pPg->pgno, 0);
|
||||
if( journal_format>=JOURNAL_FORMAT_3 ){
|
||||
@@ -1851,7 +1851,7 @@ int sqlite3pager_write(void *pData){
|
||||
assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
|
||||
store32bits(pPg->pgno, pPg, -4);
|
||||
CODEC(pPager, pData, pPg->pgno, 7);
|
||||
rc = sqliteOsWrite(&pPager->cpfd, &((char*)pData)[-4], SQLITE_PAGE_SIZE+4);
|
||||
rc = sqlite3OsWrite(&pPager->cpfd, &((char*)pData)[-4], SQLITE_PAGE_SIZE+4);
|
||||
TRACE2("CKPT-JOURNAL %d\n", pPg->pgno);
|
||||
CODEC(pPager, pData, pPg->pgno, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -2005,7 +2005,7 @@ int sqlite3pager_commit(Pager *pPager){
|
||||
}
|
||||
TRACE1("COMMIT\n");
|
||||
if( pPager->dirtyFile==0 ){
|
||||
/* Exit early (without doing the time-consuming sqliteOsSync() calls)
|
||||
/* Exit early (without doing the time-consuming sqlite3OsSync() calls)
|
||||
** if there have been no changes to the database file. */
|
||||
assert( pPager->needSync==0 );
|
||||
rc = pager_unwritelock(pPager);
|
||||
@@ -2020,7 +2020,7 @@ int sqlite3pager_commit(Pager *pPager){
|
||||
pPg = pager_get_all_dirty_pages(pPager);
|
||||
if( pPg ){
|
||||
rc = pager_write_pagelist(pPg);
|
||||
if( rc || (!pPager->noSync && sqliteOsSync(&pPager->fd)!=SQLITE_OK) ){
|
||||
if( rc || (!pPager->noSync && sqlite3OsSync(&pPager->fd)!=SQLITE_OK) ){
|
||||
goto commit_abort;
|
||||
}
|
||||
}
|
||||
@@ -2120,11 +2120,11 @@ int sqlite3pager_stmt_begin(Pager *pPager){
|
||||
assert( !pPager->ckptInUse );
|
||||
pPager->aInCkpt = sqliteMalloc( pPager->dbSize/8 + 1 );
|
||||
if( pPager->aInCkpt==0 ){
|
||||
sqliteOsReadLock(&pPager->fd);
|
||||
sqlite3OsReadLock(&pPager->fd);
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
rc = sqliteOsFileSize(&pPager->jfd, &pPager->ckptJSize);
|
||||
rc = sqlite3OsFileSize(&pPager->jfd, &pPager->ckptJSize);
|
||||
if( rc ) goto ckpt_begin_failed;
|
||||
assert( pPager->ckptJSize ==
|
||||
pPager->nRec*JOURNAL_PG_SZ(journal_format)+JOURNAL_HDR_SZ(journal_format) );
|
||||
@@ -2155,8 +2155,8 @@ ckpt_begin_failed:
|
||||
int sqlite3pager_stmt_commit(Pager *pPager){
|
||||
if( pPager->ckptInUse ){
|
||||
PgHdr *pPg, *pNext;
|
||||
sqliteOsSeek(&pPager->cpfd, 0);
|
||||
/* sqliteOsTruncate(&pPager->cpfd, 0); */
|
||||
sqlite3OsSeek(&pPager->cpfd, 0);
|
||||
/* sqlite3OsTruncate(&pPager->cpfd, 0); */
|
||||
pPager->ckptNRec = 0;
|
||||
pPager->ckptInUse = 0;
|
||||
sqliteFree( pPager->aInCkpt );
|
||||
@@ -2220,3 +2220,6 @@ void sqlite3pager_refdump(Pager *pPager){
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
** subsystem. The page cache subsystem reads and writes a file a page
|
||||
** at a time and provides a journal for rollback.
|
||||
**
|
||||
** @(#) $Id: pager.h,v 1.27 2004/04/26 14:10:22 drh Exp $
|
||||
** @(#) $Id: pager.h,v 1.28 2004/05/08 08:23:30 danielk1977 Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -103,3 +103,6 @@ void sqlite3pager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*);
|
||||
void sqlite3pager_refdump(Pager*);
|
||||
int pager3_refinfo_enable;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
481
src/parse.y
481
src/parse.y
@@ -14,7 +14,7 @@
|
||||
** the parser. Lemon will also generate a header file containing
|
||||
** numeric codes for all of the tokens.
|
||||
**
|
||||
** @(#) $Id: parse.y,v 1.112 2004/02/22 18:40:57 drh Exp $
|
||||
** @(#) $Id: parse.y,v 1.113 2004/05/08 08:23:30 danielk1977 Exp $
|
||||
*/
|
||||
%token_prefix TK_
|
||||
%token_type {Token}
|
||||
@@ -23,13 +23,13 @@
|
||||
%syntax_error {
|
||||
if( pParse->zErrMsg==0 ){
|
||||
if( TOKEN.z[0] ){
|
||||
sqliteErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
|
||||
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
|
||||
}else{
|
||||
sqliteErrorMsg(pParse, "incomplete SQL statement");
|
||||
sqlite3ErrorMsg(pParse, "incomplete SQL statement");
|
||||
}
|
||||
}
|
||||
}
|
||||
%name sqliteParser
|
||||
%name sqlite3Parser
|
||||
%include {
|
||||
#include "sqliteInt.h"
|
||||
#include "parse.h"
|
||||
@@ -69,36 +69,36 @@ cmdlist ::= cmdlist ecmd.
|
||||
cmdlist ::= ecmd.
|
||||
ecmd ::= explain cmdx SEMI.
|
||||
ecmd ::= SEMI.
|
||||
cmdx ::= cmd. { sqliteExec(pParse); }
|
||||
explain ::= EXPLAIN. { sqliteBeginParse(pParse, 1); }
|
||||
explain ::= . { sqliteBeginParse(pParse, 0); }
|
||||
cmdx ::= cmd. { sqlite3Exec(pParse); }
|
||||
explain ::= EXPLAIN. { sqlite3BeginParse(pParse, 1); }
|
||||
explain ::= . { sqlite3BeginParse(pParse, 0); }
|
||||
|
||||
///////////////////// Begin and end transactions. ////////////////////////////
|
||||
//
|
||||
|
||||
cmd ::= BEGIN trans_opt onconf(R). {sqliteBeginTransaction(pParse,R);}
|
||||
cmd ::= BEGIN trans_opt onconf(R). {sqlite3BeginTransaction(pParse,R);}
|
||||
trans_opt ::= .
|
||||
trans_opt ::= TRANSACTION.
|
||||
trans_opt ::= TRANSACTION nm.
|
||||
cmd ::= COMMIT trans_opt. {sqliteCommitTransaction(pParse);}
|
||||
cmd ::= END trans_opt. {sqliteCommitTransaction(pParse);}
|
||||
cmd ::= ROLLBACK trans_opt. {sqliteRollbackTransaction(pParse);}
|
||||
cmd ::= COMMIT trans_opt. {sqlite3CommitTransaction(pParse);}
|
||||
cmd ::= END trans_opt. {sqlite3CommitTransaction(pParse);}
|
||||
cmd ::= ROLLBACK trans_opt. {sqlite3RollbackTransaction(pParse);}
|
||||
|
||||
///////////////////// The CREATE TABLE statement ////////////////////////////
|
||||
//
|
||||
cmd ::= create_table create_table_args.
|
||||
create_table ::= CREATE(X) temp(T) TABLE nm(Y). {
|
||||
sqliteStartTable(pParse,&X,&Y,T,0);
|
||||
sqlite3StartTable(pParse,&X,&Y,T,0);
|
||||
}
|
||||
%type temp {int}
|
||||
temp(A) ::= TEMP. {A = 1;}
|
||||
temp(A) ::= . {A = 0;}
|
||||
create_table_args ::= LP columnlist conslist_opt RP(X). {
|
||||
sqliteEndTable(pParse,&X,0);
|
||||
sqlite3EndTable(pParse,&X,0);
|
||||
}
|
||||
create_table_args ::= AS select(S). {
|
||||
sqliteEndTable(pParse,0,S);
|
||||
sqliteSelectDelete(S);
|
||||
sqlite3EndTable(pParse,0,S);
|
||||
sqlite3SelectDelete(S);
|
||||
}
|
||||
columnlist ::= columnlist COMMA column.
|
||||
columnlist ::= column.
|
||||
@@ -108,7 +108,7 @@ columnlist ::= column.
|
||||
// an elaborate typename. Perhaps someday we'll do something with it.
|
||||
//
|
||||
column ::= columnid type carglist.
|
||||
columnid ::= nm(X). {sqliteAddColumn(pParse,&X);}
|
||||
columnid ::= nm(X). {sqlite3AddColumn(pParse,&X);}
|
||||
|
||||
// An IDENTIFIER can be a generic identifier, or one of several
|
||||
// keywords. Any non-standard keyword can also be an identifier.
|
||||
@@ -157,10 +157,10 @@ nm(A) ::= STRING(X). {A = X;}
|
||||
nm(A) ::= JOIN_KW(X). {A = X;}
|
||||
|
||||
type ::= .
|
||||
type ::= typename(X). {sqliteAddColumnType(pParse,&X,&X);}
|
||||
type ::= typename(X) LP signed RP(Y). {sqliteAddColumnType(pParse,&X,&Y);}
|
||||
type ::= typename(X). {sqlite3AddColumnType(pParse,&X,&X);}
|
||||
type ::= typename(X) LP signed RP(Y). {sqlite3AddColumnType(pParse,&X,&Y);}
|
||||
type ::= typename(X) LP signed COMMA signed RP(Y).
|
||||
{sqliteAddColumnType(pParse,&X,&Y);}
|
||||
{sqlite3AddColumnType(pParse,&X,&Y);}
|
||||
%type typename {Token}
|
||||
typename(A) ::= ids(X). {A = X;}
|
||||
typename(A) ::= typename(X) ids. {A = X;}
|
||||
@@ -172,29 +172,29 @@ carglist ::= carglist carg.
|
||||
carglist ::= .
|
||||
carg ::= CONSTRAINT nm ccons.
|
||||
carg ::= ccons.
|
||||
carg ::= DEFAULT STRING(X). {sqliteAddDefaultValue(pParse,&X,0);}
|
||||
carg ::= DEFAULT ID(X). {sqliteAddDefaultValue(pParse,&X,0);}
|
||||
carg ::= DEFAULT INTEGER(X). {sqliteAddDefaultValue(pParse,&X,0);}
|
||||
carg ::= DEFAULT PLUS INTEGER(X). {sqliteAddDefaultValue(pParse,&X,0);}
|
||||
carg ::= DEFAULT MINUS INTEGER(X). {sqliteAddDefaultValue(pParse,&X,1);}
|
||||
carg ::= DEFAULT FLOAT(X). {sqliteAddDefaultValue(pParse,&X,0);}
|
||||
carg ::= DEFAULT PLUS FLOAT(X). {sqliteAddDefaultValue(pParse,&X,0);}
|
||||
carg ::= DEFAULT MINUS FLOAT(X). {sqliteAddDefaultValue(pParse,&X,1);}
|
||||
carg ::= DEFAULT STRING(X). {sqlite3AddDefaultValue(pParse,&X,0);}
|
||||
carg ::= DEFAULT ID(X). {sqlite3AddDefaultValue(pParse,&X,0);}
|
||||
carg ::= DEFAULT INTEGER(X). {sqlite3AddDefaultValue(pParse,&X,0);}
|
||||
carg ::= DEFAULT PLUS INTEGER(X). {sqlite3AddDefaultValue(pParse,&X,0);}
|
||||
carg ::= DEFAULT MINUS INTEGER(X). {sqlite3AddDefaultValue(pParse,&X,1);}
|
||||
carg ::= DEFAULT FLOAT(X). {sqlite3AddDefaultValue(pParse,&X,0);}
|
||||
carg ::= DEFAULT PLUS FLOAT(X). {sqlite3AddDefaultValue(pParse,&X,0);}
|
||||
carg ::= DEFAULT MINUS FLOAT(X). {sqlite3AddDefaultValue(pParse,&X,1);}
|
||||
carg ::= DEFAULT NULL.
|
||||
|
||||
// In addition to the type name, we also care about the primary key and
|
||||
// UNIQUE constraints.
|
||||
//
|
||||
ccons ::= NULL onconf.
|
||||
ccons ::= NOT NULL onconf(R). {sqliteAddNotNull(pParse, R);}
|
||||
ccons ::= PRIMARY KEY sortorder onconf(R). {sqliteAddPrimaryKey(pParse,0,R);}
|
||||
ccons ::= UNIQUE onconf(R). {sqliteCreateIndex(pParse,0,0,0,R,0,0);}
|
||||
ccons ::= NOT NULL onconf(R). {sqlite3AddNotNull(pParse, R);}
|
||||
ccons ::= PRIMARY KEY sortorder onconf(R). {sqlite3AddPrimaryKey(pParse,0,R);}
|
||||
ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,R,0,0);}
|
||||
ccons ::= CHECK LP expr RP onconf.
|
||||
ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
|
||||
{sqliteCreateForeignKey(pParse,0,&T,TA,R);}
|
||||
ccons ::= defer_subclause(D). {sqliteDeferForeignKey(pParse,D);}
|
||||
{sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
|
||||
ccons ::= defer_subclause(D). {sqlite3DeferForeignKey(pParse,D);}
|
||||
ccons ::= COLLATE id(C). {
|
||||
sqliteAddCollateType(pParse, sqliteCollateType(C.z, C.n));
|
||||
sqlite3AddCollateType(pParse, sqlite3CollateType(C.z, C.n));
|
||||
}
|
||||
|
||||
// The next group of rules parses the arguments to a REFERENCES clause
|
||||
@@ -233,14 +233,14 @@ conslist ::= conslist tcons.
|
||||
conslist ::= tcons.
|
||||
tcons ::= CONSTRAINT nm.
|
||||
tcons ::= PRIMARY KEY LP idxlist(X) RP onconf(R).
|
||||
{sqliteAddPrimaryKey(pParse,X,R);}
|
||||
{sqlite3AddPrimaryKey(pParse,X,R);}
|
||||
tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
|
||||
{sqliteCreateIndex(pParse,0,0,X,R,0,0);}
|
||||
{sqlite3CreateIndex(pParse,0,0,X,R,0,0);}
|
||||
tcons ::= CHECK expr onconf.
|
||||
tcons ::= FOREIGN KEY LP idxlist(FA) RP
|
||||
REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). {
|
||||
sqliteCreateForeignKey(pParse, FA, &T, TA, R);
|
||||
sqliteDeferForeignKey(pParse, D);
|
||||
sqlite3CreateForeignKey(pParse, FA, &T, TA, R);
|
||||
sqlite3DeferForeignKey(pParse, D);
|
||||
}
|
||||
%type defer_subclause_opt {int}
|
||||
defer_subclause_opt(A) ::= . {A = 0;}
|
||||
@@ -264,28 +264,28 @@ resolvetype(A) ::= REPLACE. { A = OE_Replace; }
|
||||
|
||||
////////////////////////// The DROP TABLE /////////////////////////////////////
|
||||
//
|
||||
cmd ::= DROP TABLE nm(X). {sqliteDropTable(pParse,&X,0);}
|
||||
cmd ::= DROP TABLE nm(X). {sqlite3DropTable(pParse,&X,0);}
|
||||
|
||||
///////////////////// The CREATE VIEW statement /////////////////////////////
|
||||
//
|
||||
cmd ::= CREATE(X) temp(T) VIEW nm(Y) AS select(S). {
|
||||
sqliteCreateView(pParse, &X, &Y, S, T);
|
||||
sqlite3CreateView(pParse, &X, &Y, S, T);
|
||||
}
|
||||
cmd ::= DROP VIEW nm(X). {
|
||||
sqliteDropTable(pParse, &X, 1);
|
||||
sqlite3DropTable(pParse, &X, 1);
|
||||
}
|
||||
|
||||
//////////////////////// The SELECT statement /////////////////////////////////
|
||||
//
|
||||
cmd ::= select(X). {
|
||||
sqliteSelect(pParse, X, SRT_Callback, 0, 0, 0, 0);
|
||||
sqliteSelectDelete(X);
|
||||
sqlite3Select(pParse, X, SRT_Callback, 0, 0, 0, 0);
|
||||
sqlite3SelectDelete(X);
|
||||
}
|
||||
|
||||
%type select {Select*}
|
||||
%destructor select {sqliteSelectDelete($$);}
|
||||
%destructor select {sqlite3SelectDelete($$);}
|
||||
%type oneselect {Select*}
|
||||
%destructor oneselect {sqliteSelectDelete($$);}
|
||||
%destructor oneselect {sqlite3SelectDelete($$);}
|
||||
|
||||
select(A) ::= oneselect(X). {A = X;}
|
||||
select(A) ::= select(X) multiselect_op(Y) oneselect(Z). {
|
||||
@@ -302,7 +302,7 @@ multiselect_op(A) ::= INTERSECT. {A = TK_INTERSECT;}
|
||||
multiselect_op(A) ::= EXCEPT. {A = TK_EXCEPT;}
|
||||
oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
|
||||
groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
|
||||
A = sqliteSelectNew(W,X,Y,P,Q,Z,D,L.limit,L.offset);
|
||||
A = sqlite3SelectNew(W,X,Y,P,Q,Z,D,L.limit,L.offset);
|
||||
}
|
||||
|
||||
// The "distinct" nonterminal is true (1) if the DISTINCT keyword is
|
||||
@@ -319,21 +319,21 @@ distinct(A) ::= . {A = 0;}
|
||||
// opcode of TK_ALL.
|
||||
//
|
||||
%type selcollist {ExprList*}
|
||||
%destructor selcollist {sqliteExprListDelete($$);}
|
||||
%destructor selcollist {sqlite3ExprListDelete($$);}
|
||||
%type sclp {ExprList*}
|
||||
%destructor sclp {sqliteExprListDelete($$);}
|
||||
%destructor sclp {sqlite3ExprListDelete($$);}
|
||||
sclp(A) ::= selcollist(X) COMMA. {A = X;}
|
||||
sclp(A) ::= . {A = 0;}
|
||||
selcollist(A) ::= sclp(P) expr(X) as(Y). {
|
||||
A = sqliteExprListAppend(P,X,Y.n?&Y:0);
|
||||
A = sqlite3ExprListAppend(P,X,Y.n?&Y:0);
|
||||
}
|
||||
selcollist(A) ::= sclp(P) STAR. {
|
||||
A = sqliteExprListAppend(P, sqliteExpr(TK_ALL, 0, 0, 0), 0);
|
||||
A = sqlite3ExprListAppend(P, sqlite3Expr(TK_ALL, 0, 0, 0), 0);
|
||||
}
|
||||
selcollist(A) ::= sclp(P) nm(X) DOT STAR. {
|
||||
Expr *pRight = sqliteExpr(TK_ALL, 0, 0, 0);
|
||||
Expr *pLeft = sqliteExpr(TK_ID, 0, 0, &X);
|
||||
A = sqliteExprListAppend(P, sqliteExpr(TK_DOT, pLeft, pRight, 0), 0);
|
||||
Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0);
|
||||
Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &X);
|
||||
A = sqlite3ExprListAppend(P, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0);
|
||||
}
|
||||
|
||||
// An option "AS <id>" phrase that can follow one of the expressions that
|
||||
@@ -346,11 +346,11 @@ as(X) ::= . { X.n = 0; }
|
||||
|
||||
|
||||
%type seltablist {SrcList*}
|
||||
%destructor seltablist {sqliteSrcListDelete($$);}
|
||||
%destructor seltablist {sqlite3SrcListDelete($$);}
|
||||
%type stl_prefix {SrcList*}
|
||||
%destructor stl_prefix {sqliteSrcListDelete($$);}
|
||||
%destructor stl_prefix {sqlite3SrcListDelete($$);}
|
||||
%type from {SrcList*}
|
||||
%destructor from {sqliteSrcListDelete($$);}
|
||||
%destructor from {sqlite3SrcListDelete($$);}
|
||||
|
||||
// A complete FROM clause.
|
||||
//
|
||||
@@ -366,29 +366,29 @@ stl_prefix(A) ::= seltablist(X) joinop(Y). {
|
||||
}
|
||||
stl_prefix(A) ::= . {A = 0;}
|
||||
seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). {
|
||||
A = sqliteSrcListAppend(X,&Y,&D);
|
||||
if( Z.n ) sqliteSrcListAddAlias(A,&Z);
|
||||
A = sqlite3SrcListAppend(X,&Y,&D);
|
||||
if( Z.n ) sqlite3SrcListAddAlias(A,&Z);
|
||||
if( N ){
|
||||
if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; }
|
||||
else { sqliteExprDelete(N); }
|
||||
else { sqlite3ExprDelete(N); }
|
||||
}
|
||||
if( U ){
|
||||
if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
|
||||
else { sqliteIdListDelete(U); }
|
||||
else { sqlite3IdListDelete(U); }
|
||||
}
|
||||
}
|
||||
seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP
|
||||
as(Z) on_opt(N) using_opt(U). {
|
||||
A = sqliteSrcListAppend(X,0,0);
|
||||
A = sqlite3SrcListAppend(X,0,0);
|
||||
A->a[A->nSrc-1].pSelect = S;
|
||||
if( Z.n ) sqliteSrcListAddAlias(A,&Z);
|
||||
if( Z.n ) sqlite3SrcListAddAlias(A,&Z);
|
||||
if( N ){
|
||||
if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; }
|
||||
else { sqliteExprDelete(N); }
|
||||
else { sqlite3ExprDelete(N); }
|
||||
}
|
||||
if( U ){
|
||||
if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
|
||||
else { sqliteIdListDelete(U); }
|
||||
else { sqlite3IdListDelete(U); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,10 +397,10 @@ seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP
|
||||
// a grouping of table and subqueries.
|
||||
//
|
||||
%type seltablist_paren {Select*}
|
||||
%destructor seltablist_paren {sqliteSelectDelete($$);}
|
||||
%destructor seltablist_paren {sqlite3SelectDelete($$);}
|
||||
seltablist_paren(A) ::= select(S). {A = S;}
|
||||
seltablist_paren(A) ::= seltablist(F). {
|
||||
A = sqliteSelectNew(0,F,0,0,0,0,0,-1,0);
|
||||
A = sqlite3SelectNew(0,F,0,0,0,0,0,-1,0);
|
||||
}
|
||||
|
||||
%type dbnm {Token}
|
||||
@@ -411,37 +411,37 @@ dbnm(A) ::= DOT nm(X). {A = X;}
|
||||
%type joinop2 {int}
|
||||
joinop(X) ::= COMMA. { X = JT_INNER; }
|
||||
joinop(X) ::= JOIN. { X = JT_INNER; }
|
||||
joinop(X) ::= JOIN_KW(A) JOIN. { X = sqliteJoinType(pParse,&A,0,0); }
|
||||
joinop(X) ::= JOIN_KW(A) nm(B) JOIN. { X = sqliteJoinType(pParse,&A,&B,0); }
|
||||
joinop(X) ::= JOIN_KW(A) JOIN. { X = sqlite3JoinType(pParse,&A,0,0); }
|
||||
joinop(X) ::= JOIN_KW(A) nm(B) JOIN. { X = sqlite3JoinType(pParse,&A,&B,0); }
|
||||
joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN.
|
||||
{ X = sqliteJoinType(pParse,&A,&B,&C); }
|
||||
{ X = sqlite3JoinType(pParse,&A,&B,&C); }
|
||||
|
||||
%type on_opt {Expr*}
|
||||
%destructor on_opt {sqliteExprDelete($$);}
|
||||
%destructor on_opt {sqlite3ExprDelete($$);}
|
||||
on_opt(N) ::= ON expr(E). {N = E;}
|
||||
on_opt(N) ::= . {N = 0;}
|
||||
|
||||
%type using_opt {IdList*}
|
||||
%destructor using_opt {sqliteIdListDelete($$);}
|
||||
%destructor using_opt {sqlite3IdListDelete($$);}
|
||||
using_opt(U) ::= USING LP idxlist(L) RP. {U = L;}
|
||||
using_opt(U) ::= . {U = 0;}
|
||||
|
||||
|
||||
%type orderby_opt {ExprList*}
|
||||
%destructor orderby_opt {sqliteExprListDelete($$);}
|
||||
%destructor orderby_opt {sqlite3ExprListDelete($$);}
|
||||
%type sortlist {ExprList*}
|
||||
%destructor sortlist {sqliteExprListDelete($$);}
|
||||
%destructor sortlist {sqlite3ExprListDelete($$);}
|
||||
%type sortitem {Expr*}
|
||||
%destructor sortitem {sqliteExprDelete($$);}
|
||||
%destructor sortitem {sqlite3ExprDelete($$);}
|
||||
|
||||
orderby_opt(A) ::= . {A = 0;}
|
||||
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
|
||||
sortlist(A) ::= sortlist(X) COMMA sortitem(Y) collate(C) sortorder(Z). {
|
||||
A = sqliteExprListAppend(X,Y,0);
|
||||
A = sqlite3ExprListAppend(X,Y,0);
|
||||
if( A ) A->a[A->nExpr-1].sortOrder = C+Z;
|
||||
}
|
||||
sortlist(A) ::= sortitem(Y) collate(C) sortorder(Z). {
|
||||
A = sqliteExprListAppend(0,Y,0);
|
||||
A = sqlite3ExprListAppend(0,Y,0);
|
||||
if( A ) A->a[0].sortOrder = C+Z;
|
||||
}
|
||||
sortitem(A) ::= expr(X). {A = X;}
|
||||
@@ -453,15 +453,15 @@ sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;}
|
||||
sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;}
|
||||
sortorder(A) ::= . {A = SQLITE_SO_ASC;}
|
||||
collate(C) ::= . {C = SQLITE_SO_UNK;}
|
||||
collate(C) ::= COLLATE id(X). {C = sqliteCollateType(X.z, X.n);}
|
||||
collate(C) ::= COLLATE id(X). {C = sqlite3CollateType(X.z, X.n);}
|
||||
|
||||
%type groupby_opt {ExprList*}
|
||||
%destructor groupby_opt {sqliteExprListDelete($$);}
|
||||
%destructor groupby_opt {sqlite3ExprListDelete($$);}
|
||||
groupby_opt(A) ::= . {A = 0;}
|
||||
groupby_opt(A) ::= GROUP BY exprlist(X). {A = X;}
|
||||
|
||||
%type having_opt {Expr*}
|
||||
%destructor having_opt {sqliteExprDelete($$);}
|
||||
%destructor having_opt {sqlite3ExprDelete($$);}
|
||||
having_opt(A) ::= . {A = 0;}
|
||||
having_opt(A) ::= HAVING expr(X). {A = X;}
|
||||
|
||||
@@ -476,34 +476,34 @@ limit_opt(A) ::= LIMIT signed(X) COMMA signed(Y).
|
||||
/////////////////////////// The DELETE statement /////////////////////////////
|
||||
//
|
||||
cmd ::= DELETE FROM nm(X) dbnm(D) where_opt(Y). {
|
||||
sqliteDeleteFrom(pParse, sqliteSrcListAppend(0,&X,&D), Y);
|
||||
sqlite3DeleteFrom(pParse, sqlite3SrcListAppend(0,&X,&D), Y);
|
||||
}
|
||||
|
||||
%type where_opt {Expr*}
|
||||
%destructor where_opt {sqliteExprDelete($$);}
|
||||
%destructor where_opt {sqlite3ExprDelete($$);}
|
||||
|
||||
where_opt(A) ::= . {A = 0;}
|
||||
where_opt(A) ::= WHERE expr(X). {A = X;}
|
||||
|
||||
%type setlist {ExprList*}
|
||||
%destructor setlist {sqliteExprListDelete($$);}
|
||||
%destructor setlist {sqlite3ExprListDelete($$);}
|
||||
|
||||
////////////////////////// The UPDATE command ////////////////////////////////
|
||||
//
|
||||
cmd ::= UPDATE orconf(R) nm(X) dbnm(D) SET setlist(Y) where_opt(Z).
|
||||
{sqliteUpdate(pParse,sqliteSrcListAppend(0,&X,&D),Y,Z,R);}
|
||||
{sqlite3Update(pParse,sqlite3SrcListAppend(0,&X,&D),Y,Z,R);}
|
||||
|
||||
setlist(A) ::= setlist(Z) COMMA nm(X) EQ expr(Y).
|
||||
{A = sqliteExprListAppend(Z,Y,&X);}
|
||||
setlist(A) ::= nm(X) EQ expr(Y). {A = sqliteExprListAppend(0,Y,&X);}
|
||||
{A = sqlite3ExprListAppend(Z,Y,&X);}
|
||||
setlist(A) ::= nm(X) EQ expr(Y). {A = sqlite3ExprListAppend(0,Y,&X);}
|
||||
|
||||
////////////////////////// The INSERT command /////////////////////////////////
|
||||
//
|
||||
cmd ::= insert_cmd(R) INTO nm(X) dbnm(D) inscollist_opt(F)
|
||||
VALUES LP itemlist(Y) RP.
|
||||
{sqliteInsert(pParse, sqliteSrcListAppend(0,&X,&D), Y, 0, F, R);}
|
||||
{sqlite3Insert(pParse, sqlite3SrcListAppend(0,&X,&D), Y, 0, F, R);}
|
||||
cmd ::= insert_cmd(R) INTO nm(X) dbnm(D) inscollist_opt(F) select(S).
|
||||
{sqliteInsert(pParse, sqliteSrcListAppend(0,&X,&D), 0, S, F, R);}
|
||||
{sqlite3Insert(pParse, sqlite3SrcListAppend(0,&X,&D), 0, S, F, R);}
|
||||
|
||||
%type insert_cmd {int}
|
||||
insert_cmd(A) ::= INSERT orconf(R). {A = R;}
|
||||
@@ -511,202 +511,202 @@ insert_cmd(A) ::= REPLACE. {A = OE_Replace;}
|
||||
|
||||
|
||||
%type itemlist {ExprList*}
|
||||
%destructor itemlist {sqliteExprListDelete($$);}
|
||||
%destructor itemlist {sqlite3ExprListDelete($$);}
|
||||
|
||||
itemlist(A) ::= itemlist(X) COMMA expr(Y). {A = sqliteExprListAppend(X,Y,0);}
|
||||
itemlist(A) ::= expr(X). {A = sqliteExprListAppend(0,X,0);}
|
||||
itemlist(A) ::= itemlist(X) COMMA expr(Y). {A = sqlite3ExprListAppend(X,Y,0);}
|
||||
itemlist(A) ::= expr(X). {A = sqlite3ExprListAppend(0,X,0);}
|
||||
|
||||
%type inscollist_opt {IdList*}
|
||||
%destructor inscollist_opt {sqliteIdListDelete($$);}
|
||||
%destructor inscollist_opt {sqlite3IdListDelete($$);}
|
||||
%type inscollist {IdList*}
|
||||
%destructor inscollist {sqliteIdListDelete($$);}
|
||||
%destructor inscollist {sqlite3IdListDelete($$);}
|
||||
|
||||
inscollist_opt(A) ::= . {A = 0;}
|
||||
inscollist_opt(A) ::= LP inscollist(X) RP. {A = X;}
|
||||
inscollist(A) ::= inscollist(X) COMMA nm(Y). {A = sqliteIdListAppend(X,&Y);}
|
||||
inscollist(A) ::= nm(Y). {A = sqliteIdListAppend(0,&Y);}
|
||||
inscollist(A) ::= inscollist(X) COMMA nm(Y). {A = sqlite3IdListAppend(X,&Y);}
|
||||
inscollist(A) ::= nm(Y). {A = sqlite3IdListAppend(0,&Y);}
|
||||
|
||||
/////////////////////////// Expression Processing /////////////////////////////
|
||||
//
|
||||
|
||||
%type expr {Expr*}
|
||||
%destructor expr {sqliteExprDelete($$);}
|
||||
%destructor expr {sqlite3ExprDelete($$);}
|
||||
|
||||
expr(A) ::= LP(B) expr(X) RP(E). {A = X; sqliteExprSpan(A,&B,&E); }
|
||||
expr(A) ::= NULL(X). {A = sqliteExpr(TK_NULL, 0, 0, &X);}
|
||||
expr(A) ::= ID(X). {A = sqliteExpr(TK_ID, 0, 0, &X);}
|
||||
expr(A) ::= JOIN_KW(X). {A = sqliteExpr(TK_ID, 0, 0, &X);}
|
||||
expr(A) ::= LP(B) expr(X) RP(E). {A = X; sqlite3ExprSpan(A,&B,&E); }
|
||||
expr(A) ::= NULL(X). {A = sqlite3Expr(TK_NULL, 0, 0, &X);}
|
||||
expr(A) ::= ID(X). {A = sqlite3Expr(TK_ID, 0, 0, &X);}
|
||||
expr(A) ::= JOIN_KW(X). {A = sqlite3Expr(TK_ID, 0, 0, &X);}
|
||||
expr(A) ::= nm(X) DOT nm(Y). {
|
||||
Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &X);
|
||||
Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &Y);
|
||||
A = sqliteExpr(TK_DOT, temp1, temp2, 0);
|
||||
Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &X);
|
||||
Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &Y);
|
||||
A = sqlite3Expr(TK_DOT, temp1, temp2, 0);
|
||||
}
|
||||
expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
|
||||
Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &X);
|
||||
Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &Y);
|
||||
Expr *temp3 = sqliteExpr(TK_ID, 0, 0, &Z);
|
||||
Expr *temp4 = sqliteExpr(TK_DOT, temp2, temp3, 0);
|
||||
A = sqliteExpr(TK_DOT, temp1, temp4, 0);
|
||||
Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &X);
|
||||
Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &Y);
|
||||
Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &Z);
|
||||
Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0);
|
||||
A = sqlite3Expr(TK_DOT, temp1, temp4, 0);
|
||||
}
|
||||
expr(A) ::= INTEGER(X). {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
|
||||
expr(A) ::= FLOAT(X). {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
|
||||
expr(A) ::= STRING(X). {A = sqliteExpr(TK_STRING, 0, 0, &X);}
|
||||
expr(A) ::= INTEGER(X). {A = sqlite3Expr(TK_INTEGER, 0, 0, &X);}
|
||||
expr(A) ::= FLOAT(X). {A = sqlite3Expr(TK_FLOAT, 0, 0, &X);}
|
||||
expr(A) ::= STRING(X). {A = sqlite3Expr(TK_STRING, 0, 0, &X);}
|
||||
expr(A) ::= VARIABLE(X). {
|
||||
A = sqliteExpr(TK_VARIABLE, 0, 0, &X);
|
||||
A = sqlite3Expr(TK_VARIABLE, 0, 0, &X);
|
||||
if( A ) A->iTable = ++pParse->nVar;
|
||||
}
|
||||
expr(A) ::= ID(X) LP exprlist(Y) RP(E). {
|
||||
A = sqliteExprFunction(Y, &X);
|
||||
sqliteExprSpan(A,&X,&E);
|
||||
A = sqlite3ExprFunction(Y, &X);
|
||||
sqlite3ExprSpan(A,&X,&E);
|
||||
}
|
||||
expr(A) ::= ID(X) LP STAR RP(E). {
|
||||
A = sqliteExprFunction(0, &X);
|
||||
sqliteExprSpan(A,&X,&E);
|
||||
A = sqlite3ExprFunction(0, &X);
|
||||
sqlite3ExprSpan(A,&X,&E);
|
||||
}
|
||||
expr(A) ::= expr(X) AND expr(Y). {A = sqliteExpr(TK_AND, X, Y, 0);}
|
||||
expr(A) ::= expr(X) OR expr(Y). {A = sqliteExpr(TK_OR, X, Y, 0);}
|
||||
expr(A) ::= expr(X) LT expr(Y). {A = sqliteExpr(TK_LT, X, Y, 0);}
|
||||
expr(A) ::= expr(X) GT expr(Y). {A = sqliteExpr(TK_GT, X, Y, 0);}
|
||||
expr(A) ::= expr(X) LE expr(Y). {A = sqliteExpr(TK_LE, X, Y, 0);}
|
||||
expr(A) ::= expr(X) GE expr(Y). {A = sqliteExpr(TK_GE, X, Y, 0);}
|
||||
expr(A) ::= expr(X) NE expr(Y). {A = sqliteExpr(TK_NE, X, Y, 0);}
|
||||
expr(A) ::= expr(X) EQ expr(Y). {A = sqliteExpr(TK_EQ, X, Y, 0);}
|
||||
expr(A) ::= expr(X) BITAND expr(Y). {A = sqliteExpr(TK_BITAND, X, Y, 0);}
|
||||
expr(A) ::= expr(X) BITOR expr(Y). {A = sqliteExpr(TK_BITOR, X, Y, 0);}
|
||||
expr(A) ::= expr(X) LSHIFT expr(Y). {A = sqliteExpr(TK_LSHIFT, X, Y, 0);}
|
||||
expr(A) ::= expr(X) RSHIFT expr(Y). {A = sqliteExpr(TK_RSHIFT, X, Y, 0);}
|
||||
expr(A) ::= expr(X) AND expr(Y). {A = sqlite3Expr(TK_AND, X, Y, 0);}
|
||||
expr(A) ::= expr(X) OR expr(Y). {A = sqlite3Expr(TK_OR, X, Y, 0);}
|
||||
expr(A) ::= expr(X) LT expr(Y). {A = sqlite3Expr(TK_LT, X, Y, 0);}
|
||||
expr(A) ::= expr(X) GT expr(Y). {A = sqlite3Expr(TK_GT, X, Y, 0);}
|
||||
expr(A) ::= expr(X) LE expr(Y). {A = sqlite3Expr(TK_LE, X, Y, 0);}
|
||||
expr(A) ::= expr(X) GE expr(Y). {A = sqlite3Expr(TK_GE, X, Y, 0);}
|
||||
expr(A) ::= expr(X) NE expr(Y). {A = sqlite3Expr(TK_NE, X, Y, 0);}
|
||||
expr(A) ::= expr(X) EQ expr(Y). {A = sqlite3Expr(TK_EQ, X, Y, 0);}
|
||||
expr(A) ::= expr(X) BITAND expr(Y). {A = sqlite3Expr(TK_BITAND, X, Y, 0);}
|
||||
expr(A) ::= expr(X) BITOR expr(Y). {A = sqlite3Expr(TK_BITOR, X, Y, 0);}
|
||||
expr(A) ::= expr(X) LSHIFT expr(Y). {A = sqlite3Expr(TK_LSHIFT, X, Y, 0);}
|
||||
expr(A) ::= expr(X) RSHIFT expr(Y). {A = sqlite3Expr(TK_RSHIFT, X, Y, 0);}
|
||||
expr(A) ::= expr(X) likeop(OP) expr(Y). [LIKE] {
|
||||
ExprList *pList = sqliteExprListAppend(0, Y, 0);
|
||||
pList = sqliteExprListAppend(pList, X, 0);
|
||||
A = sqliteExprFunction(pList, 0);
|
||||
ExprList *pList = sqlite3ExprListAppend(0, Y, 0);
|
||||
pList = sqlite3ExprListAppend(pList, X, 0);
|
||||
A = sqlite3ExprFunction(pList, 0);
|
||||
if( A ) A->op = OP;
|
||||
sqliteExprSpan(A, &X->span, &Y->span);
|
||||
sqlite3ExprSpan(A, &X->span, &Y->span);
|
||||
}
|
||||
expr(A) ::= expr(X) NOT likeop(OP) expr(Y). [LIKE] {
|
||||
ExprList *pList = sqliteExprListAppend(0, Y, 0);
|
||||
pList = sqliteExprListAppend(pList, X, 0);
|
||||
A = sqliteExprFunction(pList, 0);
|
||||
ExprList *pList = sqlite3ExprListAppend(0, Y, 0);
|
||||
pList = sqlite3ExprListAppend(pList, X, 0);
|
||||
A = sqlite3ExprFunction(pList, 0);
|
||||
if( A ) A->op = OP;
|
||||
A = sqliteExpr(TK_NOT, A, 0, 0);
|
||||
sqliteExprSpan(A,&X->span,&Y->span);
|
||||
A = sqlite3Expr(TK_NOT, A, 0, 0);
|
||||
sqlite3ExprSpan(A,&X->span,&Y->span);
|
||||
}
|
||||
%type likeop {int}
|
||||
likeop(A) ::= LIKE. {A = TK_LIKE;}
|
||||
likeop(A) ::= GLOB. {A = TK_GLOB;}
|
||||
expr(A) ::= expr(X) PLUS expr(Y). {A = sqliteExpr(TK_PLUS, X, Y, 0);}
|
||||
expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);}
|
||||
expr(A) ::= expr(X) STAR expr(Y). {A = sqliteExpr(TK_STAR, X, Y, 0);}
|
||||
expr(A) ::= expr(X) SLASH expr(Y). {A = sqliteExpr(TK_SLASH, X, Y, 0);}
|
||||
expr(A) ::= expr(X) REM expr(Y). {A = sqliteExpr(TK_REM, X, Y, 0);}
|
||||
expr(A) ::= expr(X) CONCAT expr(Y). {A = sqliteExpr(TK_CONCAT, X, Y, 0);}
|
||||
expr(A) ::= expr(X) PLUS expr(Y). {A = sqlite3Expr(TK_PLUS, X, Y, 0);}
|
||||
expr(A) ::= expr(X) MINUS expr(Y). {A = sqlite3Expr(TK_MINUS, X, Y, 0);}
|
||||
expr(A) ::= expr(X) STAR expr(Y). {A = sqlite3Expr(TK_STAR, X, Y, 0);}
|
||||
expr(A) ::= expr(X) SLASH expr(Y). {A = sqlite3Expr(TK_SLASH, X, Y, 0);}
|
||||
expr(A) ::= expr(X) REM expr(Y). {A = sqlite3Expr(TK_REM, X, Y, 0);}
|
||||
expr(A) ::= expr(X) CONCAT expr(Y). {A = sqlite3Expr(TK_CONCAT, X, Y, 0);}
|
||||
expr(A) ::= expr(X) ISNULL(E). {
|
||||
A = sqliteExpr(TK_ISNULL, X, 0, 0);
|
||||
sqliteExprSpan(A,&X->span,&E);
|
||||
A = sqlite3Expr(TK_ISNULL, X, 0, 0);
|
||||
sqlite3ExprSpan(A,&X->span,&E);
|
||||
}
|
||||
expr(A) ::= expr(X) IS NULL(E). {
|
||||
A = sqliteExpr(TK_ISNULL, X, 0, 0);
|
||||
sqliteExprSpan(A,&X->span,&E);
|
||||
A = sqlite3Expr(TK_ISNULL, X, 0, 0);
|
||||
sqlite3ExprSpan(A,&X->span,&E);
|
||||
}
|
||||
expr(A) ::= expr(X) NOTNULL(E). {
|
||||
A = sqliteExpr(TK_NOTNULL, X, 0, 0);
|
||||
sqliteExprSpan(A,&X->span,&E);
|
||||
A = sqlite3Expr(TK_NOTNULL, X, 0, 0);
|
||||
sqlite3ExprSpan(A,&X->span,&E);
|
||||
}
|
||||
expr(A) ::= expr(X) NOT NULL(E). {
|
||||
A = sqliteExpr(TK_NOTNULL, X, 0, 0);
|
||||
sqliteExprSpan(A,&X->span,&E);
|
||||
A = sqlite3Expr(TK_NOTNULL, X, 0, 0);
|
||||
sqlite3ExprSpan(A,&X->span,&E);
|
||||
}
|
||||
expr(A) ::= expr(X) IS NOT NULL(E). {
|
||||
A = sqliteExpr(TK_NOTNULL, X, 0, 0);
|
||||
sqliteExprSpan(A,&X->span,&E);
|
||||
A = sqlite3Expr(TK_NOTNULL, X, 0, 0);
|
||||
sqlite3ExprSpan(A,&X->span,&E);
|
||||
}
|
||||
expr(A) ::= NOT(B) expr(X). {
|
||||
A = sqliteExpr(TK_NOT, X, 0, 0);
|
||||
sqliteExprSpan(A,&B,&X->span);
|
||||
A = sqlite3Expr(TK_NOT, X, 0, 0);
|
||||
sqlite3ExprSpan(A,&B,&X->span);
|
||||
}
|
||||
expr(A) ::= BITNOT(B) expr(X). {
|
||||
A = sqliteExpr(TK_BITNOT, X, 0, 0);
|
||||
sqliteExprSpan(A,&B,&X->span);
|
||||
A = sqlite3Expr(TK_BITNOT, X, 0, 0);
|
||||
sqlite3ExprSpan(A,&B,&X->span);
|
||||
}
|
||||
expr(A) ::= MINUS(B) expr(X). [UMINUS] {
|
||||
A = sqliteExpr(TK_UMINUS, X, 0, 0);
|
||||
sqliteExprSpan(A,&B,&X->span);
|
||||
A = sqlite3Expr(TK_UMINUS, X, 0, 0);
|
||||
sqlite3ExprSpan(A,&B,&X->span);
|
||||
}
|
||||
expr(A) ::= PLUS(B) expr(X). [UPLUS] {
|
||||
A = sqliteExpr(TK_UPLUS, X, 0, 0);
|
||||
sqliteExprSpan(A,&B,&X->span);
|
||||
A = sqlite3Expr(TK_UPLUS, X, 0, 0);
|
||||
sqlite3ExprSpan(A,&B,&X->span);
|
||||
}
|
||||
expr(A) ::= LP(B) select(X) RP(E). {
|
||||
A = sqliteExpr(TK_SELECT, 0, 0, 0);
|
||||
A = sqlite3Expr(TK_SELECT, 0, 0, 0);
|
||||
if( A ) A->pSelect = X;
|
||||
sqliteExprSpan(A,&B,&E);
|
||||
sqlite3ExprSpan(A,&B,&E);
|
||||
}
|
||||
expr(A) ::= expr(W) BETWEEN expr(X) AND expr(Y). {
|
||||
ExprList *pList = sqliteExprListAppend(0, X, 0);
|
||||
pList = sqliteExprListAppend(pList, Y, 0);
|
||||
A = sqliteExpr(TK_BETWEEN, W, 0, 0);
|
||||
ExprList *pList = sqlite3ExprListAppend(0, X, 0);
|
||||
pList = sqlite3ExprListAppend(pList, Y, 0);
|
||||
A = sqlite3Expr(TK_BETWEEN, W, 0, 0);
|
||||
if( A ) A->pList = pList;
|
||||
sqliteExprSpan(A,&W->span,&Y->span);
|
||||
sqlite3ExprSpan(A,&W->span,&Y->span);
|
||||
}
|
||||
expr(A) ::= expr(W) NOT BETWEEN expr(X) AND expr(Y). {
|
||||
ExprList *pList = sqliteExprListAppend(0, X, 0);
|
||||
pList = sqliteExprListAppend(pList, Y, 0);
|
||||
A = sqliteExpr(TK_BETWEEN, W, 0, 0);
|
||||
ExprList *pList = sqlite3ExprListAppend(0, X, 0);
|
||||
pList = sqlite3ExprListAppend(pList, Y, 0);
|
||||
A = sqlite3Expr(TK_BETWEEN, W, 0, 0);
|
||||
if( A ) A->pList = pList;
|
||||
A = sqliteExpr(TK_NOT, A, 0, 0);
|
||||
sqliteExprSpan(A,&W->span,&Y->span);
|
||||
A = sqlite3Expr(TK_NOT, A, 0, 0);
|
||||
sqlite3ExprSpan(A,&W->span,&Y->span);
|
||||
}
|
||||
expr(A) ::= expr(X) IN LP exprlist(Y) RP(E). {
|
||||
A = sqliteExpr(TK_IN, X, 0, 0);
|
||||
A = sqlite3Expr(TK_IN, X, 0, 0);
|
||||
if( A ) A->pList = Y;
|
||||
sqliteExprSpan(A,&X->span,&E);
|
||||
sqlite3ExprSpan(A,&X->span,&E);
|
||||
}
|
||||
expr(A) ::= expr(X) IN LP select(Y) RP(E). {
|
||||
A = sqliteExpr(TK_IN, X, 0, 0);
|
||||
A = sqlite3Expr(TK_IN, X, 0, 0);
|
||||
if( A ) A->pSelect = Y;
|
||||
sqliteExprSpan(A,&X->span,&E);
|
||||
sqlite3ExprSpan(A,&X->span,&E);
|
||||
}
|
||||
expr(A) ::= expr(X) NOT IN LP exprlist(Y) RP(E). {
|
||||
A = sqliteExpr(TK_IN, X, 0, 0);
|
||||
A = sqlite3Expr(TK_IN, X, 0, 0);
|
||||
if( A ) A->pList = Y;
|
||||
A = sqliteExpr(TK_NOT, A, 0, 0);
|
||||
sqliteExprSpan(A,&X->span,&E);
|
||||
A = sqlite3Expr(TK_NOT, A, 0, 0);
|
||||
sqlite3ExprSpan(A,&X->span,&E);
|
||||
}
|
||||
expr(A) ::= expr(X) NOT IN LP select(Y) RP(E). {
|
||||
A = sqliteExpr(TK_IN, X, 0, 0);
|
||||
A = sqlite3Expr(TK_IN, X, 0, 0);
|
||||
if( A ) A->pSelect = Y;
|
||||
A = sqliteExpr(TK_NOT, A, 0, 0);
|
||||
sqliteExprSpan(A,&X->span,&E);
|
||||
A = sqlite3Expr(TK_NOT, A, 0, 0);
|
||||
sqlite3ExprSpan(A,&X->span,&E);
|
||||
}
|
||||
expr(A) ::= expr(X) IN nm(Y) dbnm(D). {
|
||||
SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
|
||||
A = sqliteExpr(TK_IN, X, 0, 0);
|
||||
if( A ) A->pSelect = sqliteSelectNew(0,pSrc,0,0,0,0,0,-1,0);
|
||||
sqliteExprSpan(A,&X->span,D.z?&D:&Y);
|
||||
SrcList *pSrc = sqlite3SrcListAppend(0, &Y, &D);
|
||||
A = sqlite3Expr(TK_IN, X, 0, 0);
|
||||
if( A ) A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,-1,0);
|
||||
sqlite3ExprSpan(A,&X->span,D.z?&D:&Y);
|
||||
}
|
||||
expr(A) ::= expr(X) NOT IN nm(Y) dbnm(D). {
|
||||
SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
|
||||
A = sqliteExpr(TK_IN, X, 0, 0);
|
||||
if( A ) A->pSelect = sqliteSelectNew(0,pSrc,0,0,0,0,0,-1,0);
|
||||
A = sqliteExpr(TK_NOT, A, 0, 0);
|
||||
sqliteExprSpan(A,&X->span,D.z?&D:&Y);
|
||||
SrcList *pSrc = sqlite3SrcListAppend(0, &Y, &D);
|
||||
A = sqlite3Expr(TK_IN, X, 0, 0);
|
||||
if( A ) A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,-1,0);
|
||||
A = sqlite3Expr(TK_NOT, A, 0, 0);
|
||||
sqlite3ExprSpan(A,&X->span,D.z?&D:&Y);
|
||||
}
|
||||
|
||||
|
||||
/* CASE expressions */
|
||||
expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
|
||||
A = sqliteExpr(TK_CASE, X, Z, 0);
|
||||
A = sqlite3Expr(TK_CASE, X, Z, 0);
|
||||
if( A ) A->pList = Y;
|
||||
sqliteExprSpan(A, &C, &E);
|
||||
sqlite3ExprSpan(A, &C, &E);
|
||||
}
|
||||
%type case_exprlist {ExprList*}
|
||||
%destructor case_exprlist {sqliteExprListDelete($$);}
|
||||
%destructor case_exprlist {sqlite3ExprListDelete($$);}
|
||||
case_exprlist(A) ::= case_exprlist(X) WHEN expr(Y) THEN expr(Z). {
|
||||
A = sqliteExprListAppend(X, Y, 0);
|
||||
A = sqliteExprListAppend(A, Z, 0);
|
||||
A = sqlite3ExprListAppend(X, Y, 0);
|
||||
A = sqlite3ExprListAppend(A, Z, 0);
|
||||
}
|
||||
case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). {
|
||||
A = sqliteExprListAppend(0, Y, 0);
|
||||
A = sqliteExprListAppend(A, Z, 0);
|
||||
A = sqlite3ExprListAppend(0, Y, 0);
|
||||
A = sqlite3ExprListAppend(A, Z, 0);
|
||||
}
|
||||
%type case_else {Expr*}
|
||||
case_else(A) ::= ELSE expr(X). {A = X;}
|
||||
@@ -716,13 +716,13 @@ case_operand(A) ::= expr(X). {A = X;}
|
||||
case_operand(A) ::= . {A = 0;}
|
||||
|
||||
%type exprlist {ExprList*}
|
||||
%destructor exprlist {sqliteExprListDelete($$);}
|
||||
%destructor exprlist {sqlite3ExprListDelete($$);}
|
||||
%type expritem {Expr*}
|
||||
%destructor expritem {sqliteExprDelete($$);}
|
||||
%destructor expritem {sqlite3ExprDelete($$);}
|
||||
|
||||
exprlist(A) ::= exprlist(X) COMMA expritem(Y).
|
||||
{A = sqliteExprListAppend(X,Y,0);}
|
||||
exprlist(A) ::= expritem(X). {A = sqliteExprListAppend(0,X,0);}
|
||||
{A = sqlite3ExprListAppend(X,Y,0);}
|
||||
exprlist(A) ::= expritem(X). {A = sqlite3ExprListAppend(0,X,0);}
|
||||
expritem(A) ::= expr(X). {A = X;}
|
||||
expritem(A) ::= . {A = 0;}
|
||||
|
||||
@@ -730,10 +730,10 @@ expritem(A) ::= . {A = 0;}
|
||||
//
|
||||
cmd ::= CREATE(S) uniqueflag(U) INDEX nm(X)
|
||||
ON nm(Y) dbnm(D) LP idxlist(Z) RP(E) onconf(R). {
|
||||
SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
|
||||
SrcList *pSrc = sqlite3SrcListAppend(0, &Y, &D);
|
||||
if( U!=OE_None ) U = R;
|
||||
if( U==OE_Default) U = OE_Abort;
|
||||
sqliteCreateIndex(pParse, &X, pSrc, Z, U, &S, &E);
|
||||
sqlite3CreateIndex(pParse, &X, pSrc, Z, U, &S, &E);
|
||||
}
|
||||
|
||||
%type uniqueflag {int}
|
||||
@@ -741,45 +741,45 @@ uniqueflag(A) ::= UNIQUE. { A = OE_Abort; }
|
||||
uniqueflag(A) ::= . { A = OE_None; }
|
||||
|
||||
%type idxlist {IdList*}
|
||||
%destructor idxlist {sqliteIdListDelete($$);}
|
||||
%destructor idxlist {sqlite3IdListDelete($$);}
|
||||
%type idxlist_opt {IdList*}
|
||||
%destructor idxlist_opt {sqliteIdListDelete($$);}
|
||||
%destructor idxlist_opt {sqlite3IdListDelete($$);}
|
||||
%type idxitem {Token}
|
||||
|
||||
idxlist_opt(A) ::= . {A = 0;}
|
||||
idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;}
|
||||
idxlist(A) ::= idxlist(X) COMMA idxitem(Y). {A = sqliteIdListAppend(X,&Y);}
|
||||
idxlist(A) ::= idxitem(Y). {A = sqliteIdListAppend(0,&Y);}
|
||||
idxlist(A) ::= idxlist(X) COMMA idxitem(Y). {A = sqlite3IdListAppend(X,&Y);}
|
||||
idxlist(A) ::= idxitem(Y). {A = sqlite3IdListAppend(0,&Y);}
|
||||
idxitem(A) ::= nm(X) sortorder. {A = X;}
|
||||
|
||||
///////////////////////////// The DROP INDEX command /////////////////////////
|
||||
//
|
||||
|
||||
cmd ::= DROP INDEX nm(X) dbnm(Y). {
|
||||
sqliteDropIndex(pParse, sqliteSrcListAppend(0,&X,&Y));
|
||||
sqlite3DropIndex(pParse, sqlite3SrcListAppend(0,&X,&Y));
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////// The COPY command ///////////////////////////////
|
||||
//
|
||||
cmd ::= COPY orconf(R) nm(X) dbnm(D) FROM nm(Y) USING DELIMITERS STRING(Z).
|
||||
{sqliteCopy(pParse,sqliteSrcListAppend(0,&X,&D),&Y,&Z,R);}
|
||||
{sqlite3Copy(pParse,sqlite3SrcListAppend(0,&X,&D),&Y,&Z,R);}
|
||||
cmd ::= COPY orconf(R) nm(X) dbnm(D) FROM nm(Y).
|
||||
{sqliteCopy(pParse,sqliteSrcListAppend(0,&X,&D),&Y,0,R);}
|
||||
{sqlite3Copy(pParse,sqlite3SrcListAppend(0,&X,&D),&Y,0,R);}
|
||||
|
||||
///////////////////////////// The VACUUM command /////////////////////////////
|
||||
//
|
||||
cmd ::= VACUUM. {sqliteVacuum(pParse,0);}
|
||||
cmd ::= VACUUM nm(X). {sqliteVacuum(pParse,&X);}
|
||||
cmd ::= VACUUM. {sqlite3Vacuum(pParse,0);}
|
||||
cmd ::= VACUUM nm(X). {sqlite3Vacuum(pParse,&X);}
|
||||
|
||||
///////////////////////////// The PRAGMA command /////////////////////////////
|
||||
//
|
||||
cmd ::= PRAGMA ids(X) EQ nm(Y). {sqlitePragma(pParse,&X,&Y,0);}
|
||||
cmd ::= PRAGMA ids(X) EQ ON(Y). {sqlitePragma(pParse,&X,&Y,0);}
|
||||
cmd ::= PRAGMA ids(X) EQ plus_num(Y). {sqlitePragma(pParse,&X,&Y,0);}
|
||||
cmd ::= PRAGMA ids(X) EQ minus_num(Y). {sqlitePragma(pParse,&X,&Y,1);}
|
||||
cmd ::= PRAGMA ids(X) LP nm(Y) RP. {sqlitePragma(pParse,&X,&Y,0);}
|
||||
cmd ::= PRAGMA ids(X). {sqlitePragma(pParse,&X,&X,0);}
|
||||
cmd ::= PRAGMA ids(X) EQ nm(Y). {sqlite3Pragma(pParse,&X,&Y,0);}
|
||||
cmd ::= PRAGMA ids(X) EQ ON(Y). {sqlite3Pragma(pParse,&X,&Y,0);}
|
||||
cmd ::= PRAGMA ids(X) EQ plus_num(Y). {sqlite3Pragma(pParse,&X,&Y,0);}
|
||||
cmd ::= PRAGMA ids(X) EQ minus_num(Y). {sqlite3Pragma(pParse,&X,&Y,1);}
|
||||
cmd ::= PRAGMA ids(X) LP nm(Y) RP. {sqlite3Pragma(pParse,&X,&Y,0);}
|
||||
cmd ::= PRAGMA ids(X). {sqlite3Pragma(pParse,&X,&X,0);}
|
||||
plus_num(A) ::= plus_opt number(X). {A = X;}
|
||||
minus_num(A) ::= MINUS number(X). {A = X;}
|
||||
number(A) ::= INTEGER(X). {A = X;}
|
||||
@@ -793,13 +793,13 @@ cmd ::= CREATE(A) trigger_decl BEGIN trigger_cmd_list(S) END(Z). {
|
||||
Token all;
|
||||
all.z = A.z;
|
||||
all.n = (Z.z - A.z) + Z.n;
|
||||
sqliteFinishTrigger(pParse, S, &all);
|
||||
sqlite3FinishTrigger(pParse, S, &all);
|
||||
}
|
||||
|
||||
trigger_decl ::= temp(T) TRIGGER nm(B) trigger_time(C) trigger_event(D)
|
||||
ON nm(E) dbnm(DB) foreach_clause(F) when_clause(G). {
|
||||
SrcList *pTab = sqliteSrcListAppend(0, &E, &DB);
|
||||
sqliteBeginTrigger(pParse, &B, C, D.a, D.b, pTab, F, G, T);
|
||||
SrcList *pTab = sqlite3SrcListAppend(0, &E, &DB);
|
||||
sqlite3BeginTrigger(pParse, &B, C, D.a, D.b, pTab, F, G, T);
|
||||
}
|
||||
|
||||
%type trigger_time {int}
|
||||
@@ -809,7 +809,7 @@ trigger_time(A) ::= INSTEAD OF. { A = TK_INSTEAD;}
|
||||
trigger_time(A) ::= . { A = TK_BEFORE; }
|
||||
|
||||
%type trigger_event {struct TrigEvent}
|
||||
%destructor trigger_event {sqliteIdListDelete($$.b);}
|
||||
%destructor trigger_event {sqlite3IdListDelete($$.b);}
|
||||
trigger_event(A) ::= DELETE. { A.a = TK_DELETE; A.b = 0; }
|
||||
trigger_event(A) ::= INSERT. { A.a = TK_INSERT; A.b = 0; }
|
||||
trigger_event(A) ::= UPDATE. { A.a = TK_UPDATE; A.b = 0;}
|
||||
@@ -825,7 +825,7 @@ when_clause(A) ::= . { A = 0; }
|
||||
when_clause(A) ::= WHEN expr(X). { A = X; }
|
||||
|
||||
%type trigger_cmd_list {TriggerStep *}
|
||||
%destructor trigger_cmd_list {sqliteDeleteTriggerStep($$);}
|
||||
%destructor trigger_cmd_list {sqlite3DeleteTriggerStep($$);}
|
||||
trigger_cmd_list(A) ::= trigger_cmd(X) SEMI trigger_cmd_list(Y). {
|
||||
X->pNext = Y;
|
||||
A = X;
|
||||
@@ -833,56 +833,56 @@ trigger_cmd_list(A) ::= trigger_cmd(X) SEMI trigger_cmd_list(Y). {
|
||||
trigger_cmd_list(A) ::= . { A = 0; }
|
||||
|
||||
%type trigger_cmd {TriggerStep *}
|
||||
%destructor trigger_cmd {sqliteDeleteTriggerStep($$);}
|
||||
%destructor trigger_cmd {sqlite3DeleteTriggerStep($$);}
|
||||
// UPDATE
|
||||
trigger_cmd(A) ::= UPDATE orconf(R) nm(X) SET setlist(Y) where_opt(Z).
|
||||
{ A = sqliteTriggerUpdateStep(&X, Y, Z, R); }
|
||||
{ A = sqlite3TriggerUpdateStep(&X, Y, Z, R); }
|
||||
|
||||
// INSERT
|
||||
trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F)
|
||||
VALUES LP itemlist(Y) RP.
|
||||
{A = sqliteTriggerInsertStep(&X, F, Y, 0, R);}
|
||||
{A = sqlite3TriggerInsertStep(&X, F, Y, 0, R);}
|
||||
|
||||
trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F) select(S).
|
||||
{A = sqliteTriggerInsertStep(&X, F, 0, S, R);}
|
||||
{A = sqlite3TriggerInsertStep(&X, F, 0, S, R);}
|
||||
|
||||
// DELETE
|
||||
trigger_cmd(A) ::= DELETE FROM nm(X) where_opt(Y).
|
||||
{A = sqliteTriggerDeleteStep(&X, Y);}
|
||||
{A = sqlite3TriggerDeleteStep(&X, Y);}
|
||||
|
||||
// SELECT
|
||||
trigger_cmd(A) ::= select(X). {A = sqliteTriggerSelectStep(X); }
|
||||
trigger_cmd(A) ::= select(X). {A = sqlite3TriggerSelectStep(X); }
|
||||
|
||||
// The special RAISE expression that may occur in trigger programs
|
||||
expr(A) ::= RAISE(X) LP IGNORE RP(Y). {
|
||||
A = sqliteExpr(TK_RAISE, 0, 0, 0);
|
||||
A = sqlite3Expr(TK_RAISE, 0, 0, 0);
|
||||
A->iColumn = OE_Ignore;
|
||||
sqliteExprSpan(A, &X, &Y);
|
||||
sqlite3ExprSpan(A, &X, &Y);
|
||||
}
|
||||
expr(A) ::= RAISE(X) LP ROLLBACK COMMA nm(Z) RP(Y). {
|
||||
A = sqliteExpr(TK_RAISE, 0, 0, &Z);
|
||||
A = sqlite3Expr(TK_RAISE, 0, 0, &Z);
|
||||
A->iColumn = OE_Rollback;
|
||||
sqliteExprSpan(A, &X, &Y);
|
||||
sqlite3ExprSpan(A, &X, &Y);
|
||||
}
|
||||
expr(A) ::= RAISE(X) LP ABORT COMMA nm(Z) RP(Y). {
|
||||
A = sqliteExpr(TK_RAISE, 0, 0, &Z);
|
||||
A = sqlite3Expr(TK_RAISE, 0, 0, &Z);
|
||||
A->iColumn = OE_Abort;
|
||||
sqliteExprSpan(A, &X, &Y);
|
||||
sqlite3ExprSpan(A, &X, &Y);
|
||||
}
|
||||
expr(A) ::= RAISE(X) LP FAIL COMMA nm(Z) RP(Y). {
|
||||
A = sqliteExpr(TK_RAISE, 0, 0, &Z);
|
||||
A = sqlite3Expr(TK_RAISE, 0, 0, &Z);
|
||||
A->iColumn = OE_Fail;
|
||||
sqliteExprSpan(A, &X, &Y);
|
||||
sqlite3ExprSpan(A, &X, &Y);
|
||||
}
|
||||
|
||||
//////////////////////// DROP TRIGGER statement //////////////////////////////
|
||||
cmd ::= DROP TRIGGER nm(X) dbnm(D). {
|
||||
sqliteDropTrigger(pParse,sqliteSrcListAppend(0,&X,&D));
|
||||
sqlite3DropTrigger(pParse,sqlite3SrcListAppend(0,&X,&D));
|
||||
}
|
||||
|
||||
//////////////////////// ATTACH DATABASE file AS name /////////////////////////
|
||||
cmd ::= ATTACH database_kw_opt ids(F) AS nm(D) key_opt(K). {
|
||||
sqliteAttach(pParse, &F, &D, &K);
|
||||
sqlite3Attach(pParse, &F, &D, &K);
|
||||
}
|
||||
%type key_opt {Token}
|
||||
key_opt(A) ::= USING ids(X). { A = X; }
|
||||
@@ -893,5 +893,8 @@ database_kw_opt ::= .
|
||||
|
||||
//////////////////////// DETACH DATABASE name /////////////////////////////////
|
||||
cmd ::= DETACH database_kw_opt nm(D). {
|
||||
sqliteDetach(pParse, &D);
|
||||
sqlite3Detach(pParse, &D);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
309
src/pragma.c
309
src/pragma.c
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code used to implement the PRAGMA command.
|
||||
**
|
||||
** $Id: pragma.c,v 1.19 2004/04/23 17:04:45 drh Exp $
|
||||
** $Id: pragma.c,v 1.20 2004/05/08 08:23:31 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@@ -27,7 +27,7 @@ static int getBoolean(const char *z){
|
||||
return atoi(z);
|
||||
}
|
||||
for(i=0; i<sizeof(azTrue)/sizeof(azTrue[0]); i++){
|
||||
if( sqliteStrICmp(z,azTrue[i])==0 ) return 1;
|
||||
if( sqlite3StrICmp(z,azTrue[i])==0 ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ static int getBoolean(const char *z){
|
||||
** unrecognized string argument.
|
||||
**
|
||||
** Note that the values returned are one less that the values that
|
||||
** should be passed into sqliteBtreeSetSafetyLevel(). The is done
|
||||
** should be passed into sqlite3BtreeSetSafetyLevel(). The is done
|
||||
** to support legacy SQL code. The safety level used to be boolean
|
||||
** and older scripts may have used numbers 0 for OFF and 1 for ON.
|
||||
*/
|
||||
@@ -61,7 +61,7 @@ static int getSafetyLevel(char *z){
|
||||
return atoi(z);
|
||||
}
|
||||
for(i=0; i<sizeof(aKey)/sizeof(aKey[0]); i++){
|
||||
if( sqliteStrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;
|
||||
if( sqlite3StrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -74,9 +74,9 @@ static int getSafetyLevel(char *z){
|
||||
static int getTempStore(const char *z){
|
||||
if( z[0]>='0' && z[0]<='2' ){
|
||||
return z[0] - '0';
|
||||
}else if( sqliteStrICmp(z, "file")==0 ){
|
||||
}else if( sqlite3StrICmp(z, "file")==0 ){
|
||||
return 1;
|
||||
}else if( sqliteStrICmp(z, "memory")==0 ){
|
||||
}else if( sqlite3StrICmp(z, "memory")==0 ){
|
||||
return 2;
|
||||
}else{
|
||||
return 0;
|
||||
@@ -94,13 +94,13 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
|
||||
if( db->temp_store==ts ) return SQLITE_OK;
|
||||
if( db->aDb[1].pBt!=0 ){
|
||||
if( db->flags & SQLITE_InTrans ){
|
||||
sqliteErrorMsg(pParse, "temporary storage cannot be changed "
|
||||
sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
|
||||
"from within a transaction");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
sqliteBtreeClose(db->aDb[1].pBt);
|
||||
sqlite3BtreeClose(db->aDb[1].pBt);
|
||||
db->aDb[1].pBt = 0;
|
||||
sqliteResetInternalSchema(db, 0);
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
}
|
||||
db->temp_store = ts;
|
||||
return SQLITE_OK;
|
||||
@@ -125,13 +125,13 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
|
||||
};
|
||||
int i;
|
||||
for(i=0; i<sizeof(aPragma)/sizeof(aPragma[0]); i++){
|
||||
if( sqliteStrICmp(zLeft, aPragma[i].zName)==0 ){
|
||||
if( sqlite3StrICmp(zLeft, aPragma[i].zName)==0 ){
|
||||
sqlite *db = pParse->db;
|
||||
Vdbe *v;
|
||||
if( strcmp(zLeft,zRight)==0 && (v = sqliteGetVdbe(pParse))!=0 ){
|
||||
sqliteVdbeOp3(v, OP_ColumnName, 0, 1, aPragma[i].zName, P3_STATIC);
|
||||
sqliteVdbeOp3(v, OP_ColumnName, 1, 0, "boolean", P3_STATIC);
|
||||
sqliteVdbeCode(v, OP_Integer, (db->flags & aPragma[i].mask)!=0, 0,
|
||||
if( strcmp(zLeft,zRight)==0 && (v = sqlite3GetVdbe(pParse))!=0 ){
|
||||
sqlite3VdbeOp3(v, OP_ColumnName, 0, 1, aPragma[i].zName, P3_STATIC);
|
||||
sqlite3VdbeOp3(v, OP_ColumnName, 1, 0, "boolean", P3_STATIC);
|
||||
sqlite3VdbeCode(v, OP_Integer, (db->flags & aPragma[i].mask)!=0, 0,
|
||||
OP_Callback, 1, 0,
|
||||
0);
|
||||
}else if( getBoolean(zRight) ){
|
||||
@@ -156,23 +156,23 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
|
||||
** identifier, or a number. If minusFlag is true, then the value is
|
||||
** a number that was preceded by a minus sign.
|
||||
*/
|
||||
void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
char *zLeft = 0;
|
||||
char *zRight = 0;
|
||||
sqlite *db = pParse->db;
|
||||
Vdbe *v = sqliteGetVdbe(pParse);
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
if( v==0 ) return;
|
||||
|
||||
zLeft = sqliteStrNDup(pLeft->z, pLeft->n);
|
||||
sqliteDequote(zLeft);
|
||||
sqlite3Dequote(zLeft);
|
||||
if( minusFlag ){
|
||||
zRight = 0;
|
||||
sqliteSetNString(&zRight, "-", 1, pRight->z, pRight->n, 0);
|
||||
sqlite3SetNString(&zRight, "-", 1, pRight->z, pRight->n, 0);
|
||||
}else{
|
||||
zRight = sqliteStrNDup(pRight->z, pRight->n);
|
||||
sqliteDequote(zRight);
|
||||
sqlite3Dequote(zRight);
|
||||
}
|
||||
if( sqliteAuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, 0) ){
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, 0) ){
|
||||
sqliteFree(zLeft);
|
||||
sqliteFree(zRight);
|
||||
return;
|
||||
@@ -194,7 +194,7 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
** synchronous setting. A negative value means synchronous is off
|
||||
** and a positive value means synchronous is on.
|
||||
*/
|
||||
if( sqliteStrICmp(zLeft,"default_cache_size")==0 ){
|
||||
if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
|
||||
static VdbeOpList getCacheSize[] = {
|
||||
{ OP_ReadCookie, 0, 2, 0},
|
||||
{ OP_AbsValue, 0, 0, 0},
|
||||
@@ -207,21 +207,21 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
};
|
||||
int addr;
|
||||
if( pRight->z==pLeft->z ){
|
||||
addr = sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
|
||||
sqliteVdbeChangeP1(v, addr+5, MAX_PAGES);
|
||||
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
|
||||
sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
|
||||
}else{
|
||||
int size = atoi(zRight);
|
||||
if( size<0 ) size = -size;
|
||||
sqliteBeginWriteOperation(pParse, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, size, 0);
|
||||
sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
|
||||
addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Ge, 0, addr+3);
|
||||
sqliteVdbeAddOp(v, OP_Negative, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
|
||||
sqliteEndWriteOperation(pParse);
|
||||
sqlite3BeginWriteOperation(pParse, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, size, 0);
|
||||
sqlite3VdbeAddOp(v, OP_ReadCookie, 0, 2);
|
||||
addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
|
||||
sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_SetCookie, 0, 2);
|
||||
sqlite3EndWriteOperation(pParse);
|
||||
db->cache_size = db->cache_size<0 ? -size : size;
|
||||
sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
|
||||
sqlite3BtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
|
||||
}
|
||||
}else
|
||||
|
||||
@@ -239,7 +239,7 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
** to its default value when the database is closed and reopened.
|
||||
** N should be a positive integer.
|
||||
*/
|
||||
if( sqliteStrICmp(zLeft,"cache_size")==0 ){
|
||||
if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
|
||||
static VdbeOpList getCacheSize[] = {
|
||||
{ OP_ColumnName, 0, 1, "cache_size"},
|
||||
{ OP_Callback, 1, 0, 0},
|
||||
@@ -247,14 +247,14 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
if( pRight->z==pLeft->z ){
|
||||
int size = db->cache_size;;
|
||||
if( size<0 ) size = -size;
|
||||
sqliteVdbeAddOp(v, OP_Integer, size, 0);
|
||||
sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, size, 0);
|
||||
sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
|
||||
}else{
|
||||
int size = atoi(zRight);
|
||||
if( size<0 ) size = -size;
|
||||
if( db->cache_size<0 ) size = -size;
|
||||
db->cache_size = size;
|
||||
sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
|
||||
sqlite3BtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
|
||||
}
|
||||
}else
|
||||
|
||||
@@ -277,7 +277,7 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
** is FULL, extra fsync()s occur to reduce the risk of corruption to near
|
||||
** zero, but with a write performance penalty. The default mode is NORMAL.
|
||||
*/
|
||||
if( sqliteStrICmp(zLeft,"default_synchronous")==0 ){
|
||||
if( sqlite3StrICmp(zLeft,"default_synchronous")==0 ){
|
||||
static VdbeOpList getSync[] = {
|
||||
{ OP_ColumnName, 0, 1, "synchronous"},
|
||||
{ OP_ReadCookie, 0, 3, 0},
|
||||
@@ -293,31 +293,31 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
{ OP_Callback, 1, 0, 0}
|
||||
};
|
||||
if( pRight->z==pLeft->z ){
|
||||
int addr = sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
|
||||
sqliteVdbeChangeP2(v, addr+3, addr+10);
|
||||
int addr = sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync);
|
||||
sqlite3VdbeChangeP2(v, addr+3, addr+10);
|
||||
}else{
|
||||
int addr;
|
||||
int size = db->cache_size;
|
||||
if( size<0 ) size = -size;
|
||||
sqliteBeginWriteOperation(pParse, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Ne, 0, addr+3);
|
||||
sqliteVdbeAddOp(v, OP_AddImm, MAX_PAGES, 0);
|
||||
sqliteVdbeAddOp(v, OP_AbsValue, 0, 0);
|
||||
sqlite3BeginWriteOperation(pParse, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_ReadCookie, 0, 2);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
||||
addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Ne, 0, addr+3);
|
||||
sqlite3VdbeAddOp(v, OP_AddImm, MAX_PAGES, 0);
|
||||
sqlite3VdbeAddOp(v, OP_AbsValue, 0, 0);
|
||||
db->safety_level = getSafetyLevel(zRight)+1;
|
||||
if( db->safety_level==1 ){
|
||||
sqliteVdbeAddOp(v, OP_Negative, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
|
||||
size = -size;
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
|
||||
sqliteVdbeAddOp(v, OP_Integer, db->safety_level, 0);
|
||||
sqliteVdbeAddOp(v, OP_SetCookie, 0, 3);
|
||||
sqliteEndWriteOperation(pParse);
|
||||
sqlite3VdbeAddOp(v, OP_SetCookie, 0, 2);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, db->safety_level, 0);
|
||||
sqlite3VdbeAddOp(v, OP_SetCookie, 0, 3);
|
||||
sqlite3EndWriteOperation(pParse);
|
||||
db->cache_size = size;
|
||||
sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
|
||||
sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
|
||||
sqlite3BtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
|
||||
sqlite3BtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
|
||||
}
|
||||
}else
|
||||
|
||||
@@ -330,27 +330,27 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
** default value will be restored the next time the database is
|
||||
** opened.
|
||||
*/
|
||||
if( sqliteStrICmp(zLeft,"synchronous")==0 ){
|
||||
if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
|
||||
static VdbeOpList getSync[] = {
|
||||
{ OP_ColumnName, 0, 1, "synchronous"},
|
||||
{ OP_Callback, 1, 0, 0},
|
||||
};
|
||||
if( pRight->z==pLeft->z ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, db->safety_level-1, 0);
|
||||
sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, db->safety_level-1, 0);
|
||||
sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync);
|
||||
}else{
|
||||
int size = db->cache_size;
|
||||
if( size<0 ) size = -size;
|
||||
db->safety_level = getSafetyLevel(zRight)+1;
|
||||
if( db->safety_level==1 ) size = -size;
|
||||
db->cache_size = size;
|
||||
sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
|
||||
sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
|
||||
sqlite3BtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
|
||||
sqlite3BtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
|
||||
}
|
||||
}else
|
||||
|
||||
#ifndef NDEBUG
|
||||
if( sqliteStrICmp(zLeft, "trigger_overhead_test")==0 ){
|
||||
if( sqlite3StrICmp(zLeft, "trigger_overhead_test")==0 ){
|
||||
if( getBoolean(zRight) ){
|
||||
always_code_trigger_setup = 1;
|
||||
}else{
|
||||
@@ -363,9 +363,9 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
/* The flagPragma() call also generates any necessary code */
|
||||
}else
|
||||
|
||||
if( sqliteStrICmp(zLeft, "table_info")==0 ){
|
||||
if( sqlite3StrICmp(zLeft, "table_info")==0 ){
|
||||
Table *pTab;
|
||||
pTab = sqliteFindTable(db, zRight, 0);
|
||||
pTab = sqlite3FindTable(db, zRight, 0);
|
||||
if( pTab ){
|
||||
static VdbeOpList tableInfoPreface[] = {
|
||||
{ OP_ColumnName, 0, 0, "cid"},
|
||||
@@ -376,26 +376,26 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
{ OP_ColumnName, 5, 1, "pk"},
|
||||
};
|
||||
int i;
|
||||
sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
|
||||
sqliteViewGetColumnNames(pParse, pTab);
|
||||
sqlite3VdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
|
||||
sqlite3ViewGetColumnNames(pParse, pTab);
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zName, 0);
|
||||
sqliteVdbeOp3(v, OP_String, 0, 0,
|
||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zName, 0);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0,
|
||||
pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
|
||||
sqliteVdbeOp3(v, OP_String, 0, 0,
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0,
|
||||
pTab->aCol[i].zDflt, P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 6, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 6, 0);
|
||||
}
|
||||
}
|
||||
}else
|
||||
|
||||
if( sqliteStrICmp(zLeft, "index_info")==0 ){
|
||||
if( sqlite3StrICmp(zLeft, "index_info")==0 ){
|
||||
Index *pIdx;
|
||||
Table *pTab;
|
||||
pIdx = sqliteFindIndex(db, zRight, 0);
|
||||
pIdx = sqlite3FindIndex(db, zRight, 0);
|
||||
if( pIdx ){
|
||||
static VdbeOpList tableInfoPreface[] = {
|
||||
{ OP_ColumnName, 0, 0, "seqno"},
|
||||
@@ -404,24 +404,24 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
};
|
||||
int i;
|
||||
pTab = pIdx->pTable;
|
||||
sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
|
||||
sqlite3VdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
|
||||
for(i=0; i<pIdx->nColumn; i++){
|
||||
int cnum = pIdx->aiColumn[i];
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, cnum, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, cnum, 0);
|
||||
assert( pTab->nCol>cnum );
|
||||
sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[cnum].zName, 0);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 3, 0);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0, pTab->aCol[cnum].zName, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
|
||||
}
|
||||
}
|
||||
}else
|
||||
|
||||
if( sqliteStrICmp(zLeft, "index_list")==0 ){
|
||||
if( sqlite3StrICmp(zLeft, "index_list")==0 ){
|
||||
Index *pIdx;
|
||||
Table *pTab;
|
||||
pTab = sqliteFindTable(db, zRight, 0);
|
||||
pTab = sqlite3FindTable(db, zRight, 0);
|
||||
if( pTab ){
|
||||
v = sqliteGetVdbe(pParse);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
pIdx = pTab->pIndex;
|
||||
}
|
||||
if( pTab && pIdx ){
|
||||
@@ -432,24 +432,24 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
{ OP_ColumnName, 2, 1, "unique"},
|
||||
};
|
||||
|
||||
sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
|
||||
sqlite3VdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
|
||||
while(pIdx){
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqliteVdbeOp3(v, OP_String, 0, 0, pIdx->zName, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 3, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0, pIdx->zName, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
|
||||
++i;
|
||||
pIdx = pIdx->pNext;
|
||||
}
|
||||
}
|
||||
}else
|
||||
|
||||
if( sqliteStrICmp(zLeft, "foreign_key_list")==0 ){
|
||||
if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 ){
|
||||
FKey *pFK;
|
||||
Table *pTab;
|
||||
pTab = sqliteFindTable(db, zRight, 0);
|
||||
pTab = sqlite3FindTable(db, zRight, 0);
|
||||
if( pTab ){
|
||||
v = sqliteGetVdbe(pParse);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
pFK = pTab->pFKey;
|
||||
}
|
||||
if( pTab && pFK ){
|
||||
@@ -462,17 +462,17 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
{ OP_ColumnName, 4, 1, "to"},
|
||||
};
|
||||
|
||||
sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
|
||||
sqlite3VdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
|
||||
while(pFK){
|
||||
int j;
|
||||
for(j=0; j<pFK->nCol; j++){
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, j, 0);
|
||||
sqliteVdbeOp3(v, OP_String, 0, 0, pFK->zTo, 0);
|
||||
sqliteVdbeOp3(v, OP_String, 0, 0,
|
||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, j, 0);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0, pFK->zTo, 0);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0,
|
||||
pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
|
||||
sqliteVdbeOp3(v, OP_String, 0, 0, pFK->aCol[j].zCol, 0);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 5, 0);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0, pFK->aCol[j].zCol, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 5, 0);
|
||||
}
|
||||
++i;
|
||||
pFK = pFK->pNextFrom;
|
||||
@@ -480,7 +480,7 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
}
|
||||
}else
|
||||
|
||||
if( sqliteStrICmp(zLeft, "database_list")==0 ){
|
||||
if( sqlite3StrICmp(zLeft, "database_list")==0 ){
|
||||
int i;
|
||||
static VdbeOpList indexListPreface[] = {
|
||||
{ OP_ColumnName, 0, 0, "seq"},
|
||||
@@ -488,15 +488,15 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
{ OP_ColumnName, 2, 1, "file"},
|
||||
};
|
||||
|
||||
sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
|
||||
sqlite3VdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( db->aDb[i].pBt==0 ) continue;
|
||||
assert( db->aDb[i].zName!=0 );
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqliteVdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, 0);
|
||||
sqliteVdbeOp3(v, OP_String, 0, 0,
|
||||
sqliteBtreeGetFilename(db->aDb[i].pBt), 0);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 3, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, 0);
|
||||
sqlite3VdbeOp3(v, OP_String, 0, 0,
|
||||
sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
|
||||
}
|
||||
}else
|
||||
|
||||
@@ -512,14 +512,14 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
** Note that it is possible for the library compile-time options to
|
||||
** override this setting
|
||||
*/
|
||||
if( sqliteStrICmp(zLeft, "temp_store")==0 ){
|
||||
if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
|
||||
static VdbeOpList getTmpDbLoc[] = {
|
||||
{ OP_ColumnName, 0, 1, "temp_store"},
|
||||
{ OP_Callback, 1, 0, 0},
|
||||
};
|
||||
if( pRight->z==pLeft->z ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, db->temp_store, 0);
|
||||
sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, db->temp_store, 0);
|
||||
sqlite3VdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
|
||||
}else{
|
||||
changeTempStorage(pParse, zRight);
|
||||
}
|
||||
@@ -536,33 +536,33 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
** Note that it is possible for the library compile-time options to
|
||||
** override this setting
|
||||
*/
|
||||
if( sqliteStrICmp(zLeft, "default_temp_store")==0 ){
|
||||
if( sqlite3StrICmp(zLeft, "default_temp_store")==0 ){
|
||||
static VdbeOpList getTmpDbLoc[] = {
|
||||
{ OP_ColumnName, 0, 1, "temp_store"},
|
||||
{ OP_ReadCookie, 0, 5, 0},
|
||||
{ OP_Callback, 1, 0, 0}};
|
||||
if( pRight->z==pLeft->z ){
|
||||
sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
|
||||
sqlite3VdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
|
||||
}else{
|
||||
sqliteBeginWriteOperation(pParse, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, getTempStore(zRight), 0);
|
||||
sqliteVdbeAddOp(v, OP_SetCookie, 0, 5);
|
||||
sqliteEndWriteOperation(pParse);
|
||||
sqlite3BeginWriteOperation(pParse, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, getTempStore(zRight), 0);
|
||||
sqlite3VdbeAddOp(v, OP_SetCookie, 0, 5);
|
||||
sqlite3EndWriteOperation(pParse);
|
||||
}
|
||||
}else
|
||||
|
||||
#ifndef NDEBUG
|
||||
if( sqliteStrICmp(zLeft, "parser_trace")==0 ){
|
||||
extern void sqliteParserTrace(FILE*, char *);
|
||||
if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
|
||||
extern void sqlite3ParserTrace(FILE*, char *);
|
||||
if( getBoolean(zRight) ){
|
||||
sqliteParserTrace(stdout, "parser: ");
|
||||
sqlite3ParserTrace(stdout, "parser: ");
|
||||
}else{
|
||||
sqliteParserTrace(0, 0);
|
||||
sqlite3ParserTrace(0, 0);
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
|
||||
if( sqliteStrICmp(zLeft, "integrity_check")==0 ){
|
||||
if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){
|
||||
int i, j, addr;
|
||||
|
||||
/* Code that initializes the integrity check program. Set the
|
||||
@@ -610,7 +610,7 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
};
|
||||
|
||||
/* Initialize the VDBE program */
|
||||
sqliteVdbeAddOpList(v, ArraySize(initCode), initCode);
|
||||
sqlite3VdbeAddOpList(v, ArraySize(initCode), initCode);
|
||||
|
||||
/* Do an integrity check on each database file */
|
||||
for(i=0; i<db->nDb; i++){
|
||||
@@ -618,34 +618,34 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
|
||||
/* Do an integrity check of the B-Tree
|
||||
*/
|
||||
addr = sqliteVdbeAddOpList(v, ArraySize(checkDb), checkDb);
|
||||
sqliteVdbeChangeP1(v, addr+1, i);
|
||||
sqliteVdbeChangeP2(v, addr+3, addr+7);
|
||||
sqliteVdbeChangeP2(v, addr+6, addr+4);
|
||||
sqliteVdbeChangeP2(v, addr+7, i);
|
||||
sqliteVdbeChangeP2(v, addr+10, addr+ArraySize(checkDb));
|
||||
sqliteVdbeChangeP3(v, addr+13, db->aDb[i].zName, P3_STATIC);
|
||||
addr = sqlite3VdbeAddOpList(v, ArraySize(checkDb), checkDb);
|
||||
sqlite3VdbeChangeP1(v, addr+1, i);
|
||||
sqlite3VdbeChangeP2(v, addr+3, addr+7);
|
||||
sqlite3VdbeChangeP2(v, addr+6, addr+4);
|
||||
sqlite3VdbeChangeP2(v, addr+7, i);
|
||||
sqlite3VdbeChangeP2(v, addr+10, addr+ArraySize(checkDb));
|
||||
sqlite3VdbeChangeP3(v, addr+13, db->aDb[i].zName, P3_STATIC);
|
||||
|
||||
/* Make sure all the indices are constructed correctly.
|
||||
*/
|
||||
sqliteCodeVerifySchema(pParse, i);
|
||||
sqlite3CodeVerifySchema(pParse, i);
|
||||
for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
|
||||
Table *pTab = sqliteHashData(x);
|
||||
Index *pIdx;
|
||||
int loopTop;
|
||||
|
||||
if( pTab->pIndex==0 ) continue;
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqliteVdbeOp3(v, OP_OpenRead, 1, pTab->tnum, pTab->zName, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqlite3VdbeOp3(v, OP_OpenRead, 1, pTab->tnum, pTab->zName, 0);
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
if( pIdx->tnum==0 ) continue;
|
||||
sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
|
||||
sqliteVdbeOp3(v, OP_OpenRead, j+2, pIdx->tnum, pIdx->zName, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
|
||||
sqlite3VdbeOp3(v, OP_OpenRead, j+2, pIdx->tnum, pIdx->zName, 0);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MemStore, 1, 1);
|
||||
loopTop = sqliteVdbeAddOp(v, OP_Rewind, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_MemIncr, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, 1, 1);
|
||||
loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0);
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
int k, jmp2;
|
||||
static VdbeOpList idxErr[] = {
|
||||
@@ -657,24 +657,24 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
{ OP_Concat, 4, 0, 0},
|
||||
{ OP_Callback, 1, 0, 0},
|
||||
};
|
||||
sqliteVdbeAddOp(v, OP_Recno, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Recno, 1, 0);
|
||||
for(k=0; k<pIdx->nColumn; k++){
|
||||
int idx = pIdx->aiColumn[k];
|
||||
if( idx==pTab->iPKey ){
|
||||
sqliteVdbeAddOp(v, OP_Recno, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Recno, 1, 0);
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_Column, 1, idx);
|
||||
sqlite3VdbeAddOp(v, OP_Column, 1, idx);
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||
if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
|
||||
jmp2 = sqliteVdbeAddOp(v, OP_Found, j+2, 0);
|
||||
addr = sqliteVdbeAddOpList(v, ArraySize(idxErr), idxErr);
|
||||
sqliteVdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
|
||||
sqliteVdbeChangeP2(v, jmp2, sqliteVdbeCurrentAddr(v));
|
||||
sqlite3VdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||
if( db->file_format>=4 ) sqlite3AddIdxKeyType(v, pIdx);
|
||||
jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
|
||||
addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
|
||||
sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
|
||||
sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v));
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Next, 1, loopTop+1);
|
||||
sqliteVdbeChangeP2(v, loopTop, sqliteVdbeCurrentAddr(v));
|
||||
sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1);
|
||||
sqlite3VdbeChangeP2(v, loopTop, sqlite3VdbeCurrentAddr(v));
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
static VdbeOpList cntIdx[] = {
|
||||
{ OP_Integer, 0, 0, 0},
|
||||
@@ -692,21 +692,24 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
{ OP_Callback, 1, 0, 0},
|
||||
};
|
||||
if( pIdx->tnum==0 ) continue;
|
||||
addr = sqliteVdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
|
||||
sqliteVdbeChangeP1(v, addr+2, j+2);
|
||||
sqliteVdbeChangeP2(v, addr+2, addr+5);
|
||||
sqliteVdbeChangeP1(v, addr+4, j+2);
|
||||
sqliteVdbeChangeP2(v, addr+4, addr+3);
|
||||
sqliteVdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
|
||||
sqliteVdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
|
||||
addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
|
||||
sqlite3VdbeChangeP1(v, addr+2, j+2);
|
||||
sqlite3VdbeChangeP2(v, addr+2, addr+5);
|
||||
sqlite3VdbeChangeP1(v, addr+4, j+2);
|
||||
sqlite3VdbeChangeP2(v, addr+4, addr+3);
|
||||
sqlite3VdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
|
||||
sqlite3VdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
addr = sqliteVdbeAddOpList(v, ArraySize(endCode), endCode);
|
||||
sqliteVdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
|
||||
addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
|
||||
sqlite3VdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
|
||||
}else
|
||||
|
||||
{}
|
||||
sqliteFree(zLeft);
|
||||
sqliteFree(zRight);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -346,7 +346,7 @@ static int vxprintf(
|
||||
switch( xtype ){
|
||||
case etRADIX:
|
||||
if( flag_longlong ) longvalue = va_arg(ap,INT64_TYPE);
|
||||
else if( flag_long ) longvalue = va_arg(ap,long ing);
|
||||
else if( flag_long ) longvalue = va_arg(ap,long int);
|
||||
else longvalue = va_arg(ap,int);
|
||||
#if 1
|
||||
/* For the format %#x, the value zero is printed "0" not "0x0".
|
||||
@@ -730,7 +730,7 @@ static void *printf_realloc(void *old, int size){
|
||||
** Print into memory obtained from sqliteMalloc(). Use the internal
|
||||
** %-conversion extensions.
|
||||
*/
|
||||
char *sqliteVMPrintf(const char *zFormat, va_list ap){
|
||||
char *sqlite3VMPrintf(const char *zFormat, va_list ap){
|
||||
char zBase[1000];
|
||||
return base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
|
||||
}
|
||||
@@ -739,7 +739,7 @@ char *sqliteVMPrintf(const char *zFormat, va_list ap){
|
||||
** Print into memory obtained from sqliteMalloc(). Use the internal
|
||||
** %-conversion extensions.
|
||||
*/
|
||||
char *sqliteMPrintf(const char *zFormat, ...){
|
||||
char *sqlite3MPrintf(const char *zFormat, ...){
|
||||
va_list ap;
|
||||
char *z;
|
||||
char zBase[1000];
|
||||
@@ -863,3 +863,6 @@ int sqlite_get_table_vprintf(
|
||||
free(zSql);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
13
src/random.c
13
src/random.c
@@ -15,7 +15,7 @@
|
||||
** Random numbers are used by some of the database backends in order
|
||||
** to generate random integer keys for tables or random filenames.
|
||||
**
|
||||
** $Id: random.c,v 1.11 2004/02/11 09:46:33 drh Exp $
|
||||
** $Id: random.c,v 1.12 2004/05/08 08:23:32 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@@ -60,7 +60,7 @@ static int randomByte(){
|
||||
char k[256];
|
||||
prng.j = 0;
|
||||
prng.i = 0;
|
||||
sqliteOsRandomSeed(k);
|
||||
sqlite3OsRandomSeed(k);
|
||||
for(i=0; i<256; i++){
|
||||
prng.s[i] = i;
|
||||
}
|
||||
@@ -87,11 +87,14 @@ static int randomByte(){
|
||||
/*
|
||||
** Return N random bytes.
|
||||
*/
|
||||
void sqliteRandomness(int N, void *pBuf){
|
||||
void sqlite3Randomness(int N, void *pBuf){
|
||||
unsigned char *zBuf = pBuf;
|
||||
sqliteOsEnterMutex();
|
||||
sqlite3OsEnterMutex();
|
||||
while( N-- ){
|
||||
*(zBuf++) = randomByte();
|
||||
}
|
||||
sqliteOsLeaveMutex();
|
||||
sqlite3OsLeaveMutex();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
577
src/select.c
577
src/select.c
File diff suppressed because it is too large
Load Diff
23
src/shell.c
23
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.93 2004/03/17 23:42:13 drh Exp $
|
||||
** $Id: shell.c,v 1.94 2004/05/08 08:23:32 danielk1977 Exp $
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -80,7 +80,7 @@ static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
|
||||
/*
|
||||
** Determines if a string is a number of not.
|
||||
*/
|
||||
extern int sqliteIsNumber(const char*);
|
||||
extern int sqlite3IsNumber(const char*);
|
||||
|
||||
/*
|
||||
** This routine reads a line of text from standard input, stores
|
||||
@@ -392,7 +392,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
char *zSep = i>0 ? ",": "";
|
||||
if( azArg[i]==0 ){
|
||||
fprintf(p->out,"%sNULL",zSep);
|
||||
}else if( sqliteIsNumber(azArg[i]) ){
|
||||
}else if( sqlite3IsNumber(azArg[i]) ){
|
||||
fprintf(p->out,"%s%s",zSep, azArg[i]);
|
||||
}else{
|
||||
if( zSep[0] ) fprintf(p->out,"%s",zSep);
|
||||
@@ -812,8 +812,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
data.showHeader = 0;
|
||||
data.mode = MODE_Semi;
|
||||
if( nArg>1 ){
|
||||
extern int sqliteStrICmp(const char*,const char*);
|
||||
if( sqliteStrICmp(azArg[1],"sqlite_master")==0 ){
|
||||
extern int sqlite3StrICmp(const char*,const char*);
|
||||
if( sqlite3StrICmp(azArg[1],"sqlite_master")==0 ){
|
||||
char *new_argv[2], *new_colv[2];
|
||||
new_argv[0] = "CREATE TABLE sqlite_master (\n"
|
||||
" type text,\n"
|
||||
@@ -826,7 +826,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
new_colv[0] = "sql";
|
||||
new_colv[1] = 0;
|
||||
callback(&data, 1, new_argv, new_colv);
|
||||
}else if( sqliteStrICmp(azArg[1],"sqlite_temp_master")==0 ){
|
||||
}else if( sqlite3StrICmp(azArg[1],"sqlite_temp_master")==0 ){
|
||||
char *new_argv[2], *new_colv[2];
|
||||
new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
|
||||
" type text,\n"
|
||||
@@ -997,10 +997,10 @@ static int _all_whitespace(const char *z){
|
||||
** as is the Oracle "/".
|
||||
*/
|
||||
static int _is_command_terminator(const char *zLine){
|
||||
extern int sqliteStrNICmp(const char*,const char*,int);
|
||||
extern int sqlite3StrNICmp(const char*,const char*,int);
|
||||
while( isspace(*zLine) ){ zLine++; };
|
||||
if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1; /* Oracle */
|
||||
if( sqliteStrNICmp(zLine,"go",2)==0 && _all_whitespace(&zLine[2]) ){
|
||||
if( sqlite3StrNICmp(zLine,"go",2)==0 && _all_whitespace(&zLine[2]) ){
|
||||
return 1; /* SQL Server */
|
||||
}
|
||||
return 0;
|
||||
@@ -1210,7 +1210,7 @@ int main(int argc, char **argv){
|
||||
const char *zInitFile = 0;
|
||||
char *zFirstCmd = 0;
|
||||
int i;
|
||||
extern int sqliteOsFileExists(const char*);
|
||||
extern int sqlite3OsFileExists(const char*);
|
||||
|
||||
#ifdef __MACOS__
|
||||
argc = ccommand(&argv);
|
||||
@@ -1257,7 +1257,7 @@ int main(int argc, char **argv){
|
||||
** files from being created if a user mistypes the database name argument
|
||||
** to the sqlite command-line tool.
|
||||
*/
|
||||
if( sqliteOsFileExists(data.zDbFilename) ){
|
||||
if( sqlite3OsFileExists(data.zDbFilename) ){
|
||||
open_db(&data);
|
||||
}
|
||||
|
||||
@@ -1352,3 +1352,6 @@ int main(int argc, char **argv){
|
||||
if( db ) sqlite_close(db);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -12,7 +12,7 @@
|
||||
** This header file defines the interface that the SQLite library
|
||||
** presents to client programs.
|
||||
**
|
||||
** @(#) $Id: sqlite.h.in,v 1.60 2004/03/14 22:12:35 drh Exp $
|
||||
** @(#) $Id: sqlite.h.in,v 1.61 2004/05/08 08:23:33 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _SQLITE_H_
|
||||
#define _SQLITE_H_
|
||||
@@ -861,8 +861,66 @@ int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out);
|
||||
*/
|
||||
int sqlite_decode_binary(const unsigned char *in, unsigned char *out);
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
** Below this point are the new sqlite3 APIs. At present these are
|
||||
** implemented in terms of the sqlite2 API above. This is to get the TCL
|
||||
** interface and other testing infrastructure in place for when
|
||||
** functionality starts getting added.
|
||||
*/
|
||||
|
||||
typedef struct sqlite sqlite3;
|
||||
|
||||
int sqlite3_open(const char*, sqlite3**, const char**);
|
||||
int sqlite3_open16(const void*, sqlite3**, const char**);
|
||||
int sqlite3_close(sqlite3*);
|
||||
|
||||
const char *sqlite3_errmsg(sqlite3*);
|
||||
const void *sqlite3_errmsg16(sqlite3*);
|
||||
int sqlite3_errcode(sqlite3*);
|
||||
|
||||
typedef struct sqlite3_vm sqlite3_stmt;
|
||||
|
||||
int sqlite3_prepare(sqlite3*, const char*, sqlite3_stmt**, const char**);
|
||||
int sqlite3_prepare16(sqlite3*, const void*, sqlite3_stmt**, const void**);
|
||||
int sqlite3_finalize(sqlite3_stmt*);
|
||||
int sqlite3_reset(sqlite3_stmt*);
|
||||
|
||||
int sqlite3_bind_int32(sqlite3_stmt*, int iParm, int iValue);
|
||||
int sqlite3_bind_int64(sqlite3_stmt*, int iParm, long long int iValue);
|
||||
int sqlite3_bind_double(sqlite3_stmt*, int iParm, double iValue);
|
||||
int sqlite3_bind_null(sqlite3_stmt*, int iParm);
|
||||
int sqlite3_bind_text(sqlite3_stmt*, int i, const char*, int n, int eCopy);
|
||||
int sqlite3_bind_text16(sqlite3_stmt*, int i, const void*, int, int eCopy);
|
||||
int sqlite3_bind_blob(sqlite3_stmt*, int i, const void*, int n, int eCopy);
|
||||
|
||||
int sqlite3_step(sqlite3_stmt*);
|
||||
|
||||
#define SQLITE3_INTEGER 1
|
||||
#define SQLITE3_FLOAT 2
|
||||
#define SQLITE3_TEXT 3
|
||||
#define SQLITE3_BLOB 4
|
||||
#define SQLITE3_NULL 5
|
||||
|
||||
int sqlite3_column_count(sqlite3_stmt*);
|
||||
int sqlite3_column_type(sqlite3_stmt*,int);
|
||||
const char *sqlite3_column_decltype(sqlite3_stmt*,int);
|
||||
const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
|
||||
const char *sqlite3_column_name(sqlite3_stmt*,int);
|
||||
const void *sqlite3_column_name16(sqlite3_stmt*,int);
|
||||
const unsigned char *sqlite3_column_data(sqlite3_stmt*,int);
|
||||
const void *sqlite3_column_data16(sqlite3_stmt*,int);
|
||||
int sqlite3_column_bytes(sqlite3_stmt*,int);
|
||||
long long int sqlite3_column_int(sqlite3_stmt*,int);
|
||||
double sqlite3_column_float(sqlite3_stmt*,int);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End of the 'extern "C"' block */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* _SQLITE_H_ */
|
||||
|
341
src/sqliteInt.h
341
src/sqliteInt.h
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.223 2004/05/07 13:30:42 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.224 2004/05/08 08:23:36 danielk1977 Exp $
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "sqlite.h"
|
||||
@@ -181,16 +181,16 @@ typedef unsigned INTPTR_TYPE uptr; /* Big enough to hold a pointer */
|
||||
** by an AWK script to determine if there are any leaks.
|
||||
*/
|
||||
#ifdef MEMORY_DEBUG
|
||||
# define sqliteMalloc(X) sqliteMalloc_(X,1,__FILE__,__LINE__)
|
||||
# define sqliteMallocRaw(X) sqliteMalloc_(X,0,__FILE__,__LINE__)
|
||||
# define sqliteFree(X) sqliteFree_(X,__FILE__,__LINE__)
|
||||
# define sqliteRealloc(X,Y) sqliteRealloc_(X,Y,__FILE__,__LINE__)
|
||||
# define sqliteStrDup(X) sqliteStrDup_(X,__FILE__,__LINE__)
|
||||
# define sqliteStrNDup(X,Y) sqliteStrNDup_(X,Y,__FILE__,__LINE__)
|
||||
void sqliteStrRealloc(char**);
|
||||
# define sqliteMalloc(X) sqlite3Malloc_(X,1,__FILE__,__LINE__)
|
||||
# define sqliteMallocRaw(X) sqlite3Malloc_(X,0,__FILE__,__LINE__)
|
||||
# define sqliteFree(X) sqlite3Free_(X,__FILE__,__LINE__)
|
||||
# define sqliteRealloc(X,Y) sqlite3Realloc_(X,Y,__FILE__,__LINE__)
|
||||
# define sqliteStrDup(X) sqlite3StrDup_(X,__FILE__,__LINE__)
|
||||
# define sqliteStrNDup(X,Y) sqlite3StrNDup_(X,Y,__FILE__,__LINE__)
|
||||
void sqlite3StrRealloc(char**);
|
||||
#else
|
||||
# define sqliteRealloc_(X,Y) sqliteRealloc(X,Y)
|
||||
# define sqliteStrRealloc(X)
|
||||
# define sqlite3Realloc_(X,Y) sqliteRealloc(X,Y)
|
||||
# define sqlite3StrRealloc(X)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -368,7 +368,7 @@ struct sqlite {
|
||||
int nChange; /* Number of rows changed (see above) */
|
||||
int lsChange; /* Last statement change count (see above) */
|
||||
int csChange; /* Current statement change count (see above) */
|
||||
struct sqliteInitInfo { /* Information used during initialization */
|
||||
struct sqlite3InitInfo { /* Information used during initialization */
|
||||
int iDb; /* When back is being initialized */
|
||||
int newTnum; /* Rootpage of table being initialized */
|
||||
u8 busy; /* TRUE if currently initializing */
|
||||
@@ -386,6 +386,8 @@ struct sqlite {
|
||||
void *pProgressArg; /* Argument to the progress callback */
|
||||
int nProgressOps; /* Number of opcodes for progress callback */
|
||||
#endif
|
||||
|
||||
char *zErrMsg; /* Most recent error message (UTF-8 encoded) */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -460,7 +462,7 @@ struct Column {
|
||||
*/
|
||||
#define SQLITE_SO_UNK 0 /* Use the default collating type. (SCT_NUM) */
|
||||
#define SQLITE_SO_TEXT 2 /* Sort using memcmp() */
|
||||
#define SQLITE_SO_NUM 4 /* Sort using sqliteCompare() */
|
||||
#define SQLITE_SO_NUM 4 /* Sort using sqlite3Compare() */
|
||||
#define SQLITE_SO_TYPEMASK 6 /* Mask to extract the collating sequence */
|
||||
#define SQLITE_SO_ASC 0 /* Sort in ascending order */
|
||||
#define SQLITE_SO_DESC 1 /* Sort in descending order */
|
||||
@@ -1018,7 +1020,7 @@ struct Trigger {
|
||||
* pWhere -> The WHERE clause of the UPDATE statement if one is specified.
|
||||
* Otherwise NULL.
|
||||
* pExprList -> A list of the columns to update and the expressions to update
|
||||
* them to. See sqliteUpdate() documentation of "pChanges"
|
||||
* them to. See sqlite3Update() documentation of "pChanges"
|
||||
* argument.
|
||||
*
|
||||
*/
|
||||
@@ -1098,20 +1100,20 @@ extern int always_code_trigger_setup;
|
||||
/*
|
||||
** Internal function prototypes
|
||||
*/
|
||||
int sqliteStrICmp(const char *, const char *);
|
||||
int sqliteStrNICmp(const char *, const char *, int);
|
||||
int sqliteHashNoCase(const char *, int);
|
||||
int sqliteIsNumber(const char*);
|
||||
int sqliteCompare(const char *, const char *);
|
||||
int sqliteSortCompare(const char *, const char *);
|
||||
void sqliteRealToSortable(double r, char *);
|
||||
int sqlite3StrICmp(const char *, const char *);
|
||||
int sqlite3StrNICmp(const char *, const char *, int);
|
||||
int sqlite3HashNoCase(const char *, int);
|
||||
int sqlite3IsNumber(const char*);
|
||||
int sqlite3Compare(const char *, const char *);
|
||||
int sqlite3SortCompare(const char *, const char *);
|
||||
void sqlite3RealToSortable(double r, char *);
|
||||
#ifdef MEMORY_DEBUG
|
||||
void *sqliteMalloc_(int,int,char*,int);
|
||||
void sqliteFree_(void*,char*,int);
|
||||
void *sqliteRealloc_(void*,int,char*,int);
|
||||
char *sqliteStrDup_(const char*,char*,int);
|
||||
char *sqliteStrNDup_(const char*, int,char*,int);
|
||||
void sqliteCheckMemory(void*,int);
|
||||
void *sqlite3Malloc_(int,int,char*,int);
|
||||
void sqlite3Free_(void*,char*,int);
|
||||
void *sqlite3Realloc_(void*,int,char*,int);
|
||||
char *sqlite3StrDup_(const char*,char*,int);
|
||||
char *sqlite3StrNDup_(const char*, int,char*,int);
|
||||
void sqlite3CheckMemory(void*,int);
|
||||
#else
|
||||
void *sqliteMalloc(int);
|
||||
void *sqliteMallocRaw(int);
|
||||
@@ -1119,161 +1121,164 @@ void sqliteRealToSortable(double r, char *);
|
||||
void *sqliteRealloc(void*,int);
|
||||
char *sqliteStrDup(const char*);
|
||||
char *sqliteStrNDup(const char*, int);
|
||||
# define sqliteCheckMemory(a,b)
|
||||
# define sqlite3CheckMemory(a,b)
|
||||
#endif
|
||||
char *sqliteMPrintf(const char*, ...);
|
||||
char *sqliteVMPrintf(const char*, va_list);
|
||||
void sqliteSetString(char **, const char *, ...);
|
||||
void sqliteSetNString(char **, ...);
|
||||
void sqliteErrorMsg(Parse*, const char*, ...);
|
||||
void sqliteDequote(char*);
|
||||
int sqliteKeywordCode(const char*, int);
|
||||
int sqliteRunParser(Parse*, const char*, char **);
|
||||
void sqliteExec(Parse*);
|
||||
Expr *sqliteExpr(int, Expr*, Expr*, Token*);
|
||||
void sqliteExprSpan(Expr*,Token*,Token*);
|
||||
Expr *sqliteExprFunction(ExprList*, Token*);
|
||||
void sqliteExprDelete(Expr*);
|
||||
ExprList *sqliteExprListAppend(ExprList*,Expr*,Token*);
|
||||
void sqliteExprListDelete(ExprList*);
|
||||
int sqliteInit(sqlite*, char**);
|
||||
void sqlitePragma(Parse*,Token*,Token*,int);
|
||||
void sqliteResetInternalSchema(sqlite*, int);
|
||||
void sqliteBeginParse(Parse*,int);
|
||||
void sqliteRollbackInternalChanges(sqlite*);
|
||||
void sqliteCommitInternalChanges(sqlite*);
|
||||
Table *sqliteResultSetOfSelect(Parse*,char*,Select*);
|
||||
void sqliteOpenMasterTable(Vdbe *v, int);
|
||||
void sqliteStartTable(Parse*,Token*,Token*,int,int);
|
||||
void sqliteAddColumn(Parse*,Token*);
|
||||
void sqliteAddNotNull(Parse*, int);
|
||||
void sqliteAddPrimaryKey(Parse*, IdList*, int);
|
||||
void sqliteAddColumnType(Parse*,Token*,Token*);
|
||||
void sqliteAddDefaultValue(Parse*,Token*,int);
|
||||
int sqliteCollateType(const char*, int);
|
||||
void sqliteAddCollateType(Parse*, int);
|
||||
void sqliteEndTable(Parse*,Token*,Select*);
|
||||
void sqliteCreateView(Parse*,Token*,Token*,Select*,int);
|
||||
int sqliteViewGetColumnNames(Parse*,Table*);
|
||||
void sqliteDropTable(Parse*, Token*, int);
|
||||
void sqliteDeleteTable(sqlite*, Table*);
|
||||
void sqliteInsert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
|
||||
IdList *sqliteIdListAppend(IdList*, Token*);
|
||||
int sqliteIdListIndex(IdList*,const char*);
|
||||
SrcList *sqliteSrcListAppend(SrcList*, Token*, Token*);
|
||||
void sqliteSrcListAddAlias(SrcList*, Token*);
|
||||
void sqliteSrcListAssignCursors(Parse*, SrcList*);
|
||||
void sqliteIdListDelete(IdList*);
|
||||
void sqliteSrcListDelete(SrcList*);
|
||||
void sqliteCreateIndex(Parse*,Token*,SrcList*,IdList*,int,Token*,Token*);
|
||||
void sqliteDropIndex(Parse*, SrcList*);
|
||||
void sqliteAddKeyType(Vdbe*, ExprList*);
|
||||
void sqliteAddIdxKeyType(Vdbe*, Index*);
|
||||
int sqliteSelect(Parse*, Select*, int, int, Select*, int, int*);
|
||||
Select *sqliteSelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
|
||||
char *sqlite3MPrintf(const char*, ...);
|
||||
char *sqlite3VMPrintf(const char*, va_list);
|
||||
void sqlite3SetString(char **, const char *, ...);
|
||||
void sqlite3SetNString(char **, ...);
|
||||
void sqlite3ErrorMsg(Parse*, const char*, ...);
|
||||
void sqlite3Dequote(char*);
|
||||
int sqlite3KeywordCode(const char*, int);
|
||||
int sqlite3RunParser(Parse*, const char*, char **);
|
||||
void sqlite3Exec(Parse*);
|
||||
Expr *sqlite3Expr(int, Expr*, Expr*, Token*);
|
||||
void sqlite3ExprSpan(Expr*,Token*,Token*);
|
||||
Expr *sqlite3ExprFunction(ExprList*, Token*);
|
||||
void sqlite3ExprDelete(Expr*);
|
||||
ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*);
|
||||
void sqlite3ExprListDelete(ExprList*);
|
||||
int sqlite3Init(sqlite*, char**);
|
||||
void sqlite3Pragma(Parse*,Token*,Token*,int);
|
||||
void sqlite3ResetInternalSchema(sqlite*, int);
|
||||
void sqlite3BeginParse(Parse*,int);
|
||||
void sqlite3RollbackInternalChanges(sqlite*);
|
||||
void sqlite3CommitInternalChanges(sqlite*);
|
||||
Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*);
|
||||
void sqlite3OpenMasterTable(Vdbe *v, int);
|
||||
void sqlite3StartTable(Parse*,Token*,Token*,int,int);
|
||||
void sqlite3AddColumn(Parse*,Token*);
|
||||
void sqlite3AddNotNull(Parse*, int);
|
||||
void sqlite3AddPrimaryKey(Parse*, IdList*, int);
|
||||
void sqlite3AddColumnType(Parse*,Token*,Token*);
|
||||
void sqlite3AddDefaultValue(Parse*,Token*,int);
|
||||
int sqlite3CollateType(const char*, int);
|
||||
void sqlite3AddCollateType(Parse*, int);
|
||||
void sqlite3EndTable(Parse*,Token*,Select*);
|
||||
void sqlite3CreateView(Parse*,Token*,Token*,Select*,int);
|
||||
int sqlite3ViewGetColumnNames(Parse*,Table*);
|
||||
void sqlite3DropTable(Parse*, Token*, int);
|
||||
void sqlite3DeleteTable(sqlite*, Table*);
|
||||
void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
|
||||
IdList *sqlite3IdListAppend(IdList*, Token*);
|
||||
int sqlite3IdListIndex(IdList*,const char*);
|
||||
SrcList *sqlite3SrcListAppend(SrcList*, Token*, Token*);
|
||||
void sqlite3SrcListAddAlias(SrcList*, Token*);
|
||||
void sqlite3SrcListAssignCursors(Parse*, SrcList*);
|
||||
void sqlite3IdListDelete(IdList*);
|
||||
void sqlite3SrcListDelete(SrcList*);
|
||||
void sqlite3CreateIndex(Parse*,Token*,SrcList*,IdList*,int,Token*,Token*);
|
||||
void sqlite3DropIndex(Parse*, SrcList*);
|
||||
void sqlite3AddKeyType(Vdbe*, ExprList*);
|
||||
void sqlite3AddIdxKeyType(Vdbe*, Index*);
|
||||
int sqlite3Select(Parse*, Select*, int, int, Select*, int, int*);
|
||||
Select *sqlite3SelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
|
||||
int,int,int);
|
||||
void sqliteSelectDelete(Select*);
|
||||
void sqliteSelectUnbind(Select*);
|
||||
Table *sqliteSrcListLookup(Parse*, SrcList*);
|
||||
int sqliteIsReadOnly(Parse*, Table*, int);
|
||||
void sqliteDeleteFrom(Parse*, SrcList*, Expr*);
|
||||
void sqliteUpdate(Parse*, SrcList*, ExprList*, Expr*, int);
|
||||
WhereInfo *sqliteWhereBegin(Parse*, SrcList*, Expr*, int, ExprList**);
|
||||
void sqliteWhereEnd(WhereInfo*);
|
||||
void sqliteExprCode(Parse*, Expr*);
|
||||
int sqliteExprCodeExprList(Parse*, ExprList*, int);
|
||||
void sqliteExprIfTrue(Parse*, Expr*, int, int);
|
||||
void sqliteExprIfFalse(Parse*, Expr*, int, int);
|
||||
Table *sqliteFindTable(sqlite*,const char*, const char*);
|
||||
Table *sqliteLocateTable(Parse*,const char*, const char*);
|
||||
Index *sqliteFindIndex(sqlite*,const char*, const char*);
|
||||
void sqliteUnlinkAndDeleteIndex(sqlite*,Index*);
|
||||
void sqliteCopy(Parse*, SrcList*, Token*, Token*, int);
|
||||
void sqliteVacuum(Parse*, Token*);
|
||||
int sqliteRunVacuum(char**, sqlite*);
|
||||
int sqliteGlobCompare(const unsigned char*,const unsigned char*);
|
||||
int sqliteLikeCompare(const unsigned char*,const unsigned char*);
|
||||
char *sqliteTableNameFromToken(Token*);
|
||||
int sqliteExprCheck(Parse*, Expr*, int, int*);
|
||||
int sqliteExprType(Expr*);
|
||||
int sqliteExprCompare(Expr*, Expr*);
|
||||
void sqlite3SelectDelete(Select*);
|
||||
void sqlite3SelectUnbind(Select*);
|
||||
Table *sqlite3SrcListLookup(Parse*, SrcList*);
|
||||
int sqlite3IsReadOnly(Parse*, Table*, int);
|
||||
void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
|
||||
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
|
||||
WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, int, ExprList**);
|
||||
void sqlite3WhereEnd(WhereInfo*);
|
||||
void sqlite3ExprCode(Parse*, Expr*);
|
||||
int sqlite3ExprCodeExprList(Parse*, ExprList*, int);
|
||||
void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
|
||||
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
|
||||
Table *sqlite3FindTable(sqlite*,const char*, const char*);
|
||||
Table *sqlite3LocateTable(Parse*,const char*, const char*);
|
||||
Index *sqlite3FindIndex(sqlite*,const char*, const char*);
|
||||
void sqlite3UnlinkAndDeleteIndex(sqlite*,Index*);
|
||||
void sqlite3Copy(Parse*, SrcList*, Token*, Token*, int);
|
||||
void sqlite3Vacuum(Parse*, Token*);
|
||||
int sqlite3RunVacuum(char**, sqlite*);
|
||||
int sqlite3GlobCompare(const unsigned char*,const unsigned char*);
|
||||
int sqlite3LikeCompare(const unsigned char*,const unsigned char*);
|
||||
char *sqlite3TableNameFromToken(Token*);
|
||||
int sqlite3ExprCheck(Parse*, Expr*, int, int*);
|
||||
int sqlite3ExprType(Expr*);
|
||||
int sqlite3ExprCompare(Expr*, Expr*);
|
||||
int sqliteFuncId(Token*);
|
||||
int sqliteExprResolveIds(Parse*, SrcList*, ExprList*, Expr*);
|
||||
int sqliteExprAnalyzeAggregates(Parse*, Expr*);
|
||||
Vdbe *sqliteGetVdbe(Parse*);
|
||||
void sqliteRandomness(int, void*);
|
||||
void sqliteRollbackAll(sqlite*);
|
||||
void sqliteCodeVerifySchema(Parse*, int);
|
||||
void sqliteBeginTransaction(Parse*, int);
|
||||
void sqliteCommitTransaction(Parse*);
|
||||
void sqliteRollbackTransaction(Parse*);
|
||||
int sqliteExprIsConstant(Expr*);
|
||||
int sqliteExprIsInteger(Expr*, int*);
|
||||
int sqliteIsRowid(const char*);
|
||||
void sqliteGenerateRowDelete(sqlite*, Vdbe*, Table*, int, int);
|
||||
void sqliteGenerateRowIndexDelete(sqlite*, Vdbe*, Table*, int, char*);
|
||||
void sqliteGenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
|
||||
void sqliteCompleteInsertion(Parse*, Table*, int, char*, int, int, int);
|
||||
int sqliteOpenTableAndIndices(Parse*, Table*, int);
|
||||
void sqliteBeginWriteOperation(Parse*, int, int);
|
||||
void sqliteEndWriteOperation(Parse*);
|
||||
Expr *sqliteExprDup(Expr*);
|
||||
void sqliteTokenCopy(Token*, Token*);
|
||||
ExprList *sqliteExprListDup(ExprList*);
|
||||
SrcList *sqliteSrcListDup(SrcList*);
|
||||
IdList *sqliteIdListDup(IdList*);
|
||||
Select *sqliteSelectDup(Select*);
|
||||
FuncDef *sqliteFindFunction(sqlite*,const char*,int,int,int);
|
||||
void sqliteRegisterBuiltinFunctions(sqlite*);
|
||||
void sqliteRegisterDateTimeFunctions(sqlite*);
|
||||
int sqliteSafetyOn(sqlite*);
|
||||
int sqliteSafetyOff(sqlite*);
|
||||
int sqliteSafetyCheck(sqlite*);
|
||||
void sqliteChangeCookie(sqlite*, Vdbe*);
|
||||
void sqliteBeginTrigger(Parse*, Token*,int,int,IdList*,SrcList*,int,Expr*,int);
|
||||
void sqliteFinishTrigger(Parse*, TriggerStep*, Token*);
|
||||
void sqliteDropTrigger(Parse*, SrcList*);
|
||||
void sqliteDropTriggerPtr(Parse*, Trigger*, int);
|
||||
int sqliteTriggersExist(Parse* , Trigger* , int , int , int, ExprList*);
|
||||
int sqliteCodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int,
|
||||
int sqlite3ExprResolveIds(Parse*, SrcList*, ExprList*, Expr*);
|
||||
int sqlite3ExprAnalyzeAggregates(Parse*, Expr*);
|
||||
Vdbe *sqlite3GetVdbe(Parse*);
|
||||
void sqlite3Randomness(int, void*);
|
||||
void sqlite3RollbackAll(sqlite*);
|
||||
void sqlite3CodeVerifySchema(Parse*, int);
|
||||
void sqlite3BeginTransaction(Parse*, int);
|
||||
void sqlite3CommitTransaction(Parse*);
|
||||
void sqlite3RollbackTransaction(Parse*);
|
||||
int sqlite3ExprIsConstant(Expr*);
|
||||
int sqlite3ExprIsInteger(Expr*, int*);
|
||||
int sqlite3IsRowid(const char*);
|
||||
void sqlite3GenerateRowDelete(sqlite*, Vdbe*, Table*, int, int);
|
||||
void sqlite3GenerateRowIndexDelete(sqlite*, Vdbe*, Table*, int, char*);
|
||||
void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
|
||||
void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
|
||||
int sqlite3OpenTableAndIndices(Parse*, Table*, int);
|
||||
void sqlite3BeginWriteOperation(Parse*, int, int);
|
||||
void sqlite3EndWriteOperation(Parse*);
|
||||
Expr *sqlite3ExprDup(Expr*);
|
||||
void sqlite3TokenCopy(Token*, Token*);
|
||||
ExprList *sqlite3ExprListDup(ExprList*);
|
||||
SrcList *sqlite3SrcListDup(SrcList*);
|
||||
IdList *sqlite3IdListDup(IdList*);
|
||||
Select *sqlite3SelectDup(Select*);
|
||||
FuncDef *sqlite3FindFunction(sqlite*,const char*,int,int,int);
|
||||
void sqlite3RegisterBuiltinFunctions(sqlite*);
|
||||
void sqlite3RegisterDateTimeFunctions(sqlite*);
|
||||
int sqlite3SafetyOn(sqlite*);
|
||||
int sqlite3SafetyOff(sqlite*);
|
||||
int sqlite3SafetyCheck(sqlite*);
|
||||
void sqlite3ChangeCookie(sqlite*, Vdbe*);
|
||||
void sqlite3BeginTrigger(Parse*, Token*,int,int,IdList*,SrcList*,int,Expr*,int);
|
||||
void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*);
|
||||
void sqlite3DropTrigger(Parse*, SrcList*);
|
||||
void sqlite3DropTriggerPtr(Parse*, Trigger*, int);
|
||||
int sqlite3TriggersExist(Parse* , Trigger* , int , int , int, ExprList*);
|
||||
int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int,
|
||||
int, int);
|
||||
void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
|
||||
void sqliteDeleteTriggerStep(TriggerStep*);
|
||||
TriggerStep *sqliteTriggerSelectStep(Select*);
|
||||
TriggerStep *sqliteTriggerInsertStep(Token*, IdList*, ExprList*, Select*, int);
|
||||
TriggerStep *sqliteTriggerUpdateStep(Token*, ExprList*, Expr*, int);
|
||||
TriggerStep *sqliteTriggerDeleteStep(Token*, Expr*);
|
||||
void sqliteDeleteTrigger(Trigger*);
|
||||
int sqliteJoinType(Parse*, Token*, Token*, Token*);
|
||||
void sqliteCreateForeignKey(Parse*, IdList*, Token*, IdList*, int);
|
||||
void sqliteDeferForeignKey(Parse*, int);
|
||||
void sqlite3DeleteTriggerStep(TriggerStep*);
|
||||
TriggerStep *sqlite3TriggerSelectStep(Select*);
|
||||
TriggerStep *sqlite3TriggerInsertStep(Token*, IdList*, ExprList*, Select*, int);
|
||||
TriggerStep *sqlite3TriggerUpdateStep(Token*, ExprList*, Expr*, int);
|
||||
TriggerStep *sqlite3TriggerDeleteStep(Token*, Expr*);
|
||||
void sqlite3DeleteTrigger(Trigger*);
|
||||
int sqlite3JoinType(Parse*, Token*, Token*, Token*);
|
||||
void sqlite3CreateForeignKey(Parse*, IdList*, Token*, IdList*, int);
|
||||
void sqlite3DeferForeignKey(Parse*, int);
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
void sqliteAuthRead(Parse*,Expr*,SrcList*);
|
||||
int sqliteAuthCheck(Parse*,int, const char*, const char*, const char*);
|
||||
void sqliteAuthContextPush(Parse*, AuthContext*, const char*);
|
||||
void sqliteAuthContextPop(AuthContext*);
|
||||
void sqlite3AuthRead(Parse*,Expr*,SrcList*);
|
||||
int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*);
|
||||
void sqlite3AuthContextPush(Parse*, AuthContext*, const char*);
|
||||
void sqlite3AuthContextPop(AuthContext*);
|
||||
#else
|
||||
# define sqliteAuthRead(a,b,c)
|
||||
# define sqliteAuthCheck(a,b,c,d,e) SQLITE_OK
|
||||
# define sqliteAuthContextPush(a,b,c)
|
||||
# define sqliteAuthContextPop(a) ((void)(a))
|
||||
# define sqlite3AuthRead(a,b,c)
|
||||
# define sqlite3AuthCheck(a,b,c,d,e) SQLITE_OK
|
||||
# define sqlite3AuthContextPush(a,b,c)
|
||||
# define sqlite3AuthContextPop(a) ((void)(a))
|
||||
#endif
|
||||
void sqliteAttach(Parse*, Token*, Token*, Token*);
|
||||
void sqliteDetach(Parse*, Token*);
|
||||
int sqliteBtreeFactory(const sqlite *db, const char *zFilename,
|
||||
void sqlite3Attach(Parse*, Token*, Token*, Token*);
|
||||
void sqlite3Detach(Parse*, Token*);
|
||||
int sqlite3BtreeFactory(const sqlite *db, const char *zFilename,
|
||||
int mode, int nPg, Btree **ppBtree);
|
||||
int sqliteFixInit(DbFixer*, Parse*, int, const char*, const Token*);
|
||||
int sqliteFixSrcList(DbFixer*, SrcList*);
|
||||
int sqliteFixSelect(DbFixer*, Select*);
|
||||
int sqliteFixExpr(DbFixer*, Expr*);
|
||||
int sqliteFixExprList(DbFixer*, ExprList*);
|
||||
int sqliteFixTriggerStep(DbFixer*, TriggerStep*);
|
||||
double sqliteAtoF(const char *z, const char **);
|
||||
int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
|
||||
int sqlite3FixSrcList(DbFixer*, SrcList*);
|
||||
int sqlite3FixSelect(DbFixer*, Select*);
|
||||
int sqlite3FixExpr(DbFixer*, Expr*);
|
||||
int sqlite3FixExprList(DbFixer*, ExprList*);
|
||||
int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
|
||||
double sqlite3AtoF(const char *z, const char **);
|
||||
char *sqlite_snprintf(int,char*,const char*,...);
|
||||
int sqliteFitsIn32Bits(const char *);
|
||||
int sqlite3FitsIn32Bits(const char *);
|
||||
|
||||
unsigned char *sqlite3utf16to8(const void *pData, int N);
|
||||
void *sqlite3utf8to16be(const unsigned char *pIn, int N);
|
||||
void *sqlite3utf8to16le(const unsigned char *pIn, int N);
|
||||
void sqlite3utf16to16le(void *pData, int N);
|
||||
void sqlite3utf16to16be(void *pData, int N);
|
||||
|
||||
|
||||
|
||||
|
@@ -84,7 +84,7 @@ static int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
|
||||
p->azResult[p->nData++] = z;
|
||||
}
|
||||
}else if( p->nColumn!=nCol ){
|
||||
sqliteSetString(&p->zErrMsg,
|
||||
sqlite3SetString(&p->zErrMsg,
|
||||
"sqlite_get_table() called with two or more incompatible queries",
|
||||
(char*)0);
|
||||
p->rc = SQLITE_ERROR;
|
||||
@@ -158,7 +158,7 @@ int sqlite_get_table(
|
||||
if( pzErrMsg ){
|
||||
free(*pzErrMsg);
|
||||
*pzErrMsg = res.zErrMsg;
|
||||
sqliteStrRealloc(pzErrMsg);
|
||||
sqlite3StrRealloc(pzErrMsg);
|
||||
}else{
|
||||
sqliteFree(res.zErrMsg);
|
||||
}
|
||||
@@ -201,3 +201,6 @@ void sqlite_free_table(
|
||||
free(azResult);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** A TCL Interface to SQLite
|
||||
**
|
||||
** $Id: tclsqlite.c,v 1.62 2004/05/07 17:57:50 drh Exp $
|
||||
** $Id: tclsqlite.c,v 1.63 2004/05/08 08:23:37 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if 0
|
||||
/*
|
||||
** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we
|
||||
** have to do a translation when going between the two. Set the
|
||||
@@ -1156,7 +1155,6 @@ int Sqlite_SafeInit(Tcl_Interp *interp){
|
||||
int Tclsqlite_SafeInit(Tcl_Interp *interp){
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*
|
||||
@@ -1201,7 +1199,7 @@ int TCLSH_MAIN(int argc, char **argv){
|
||||
Tcl_Interp *interp;
|
||||
Tcl_FindExecutable(argv[0]);
|
||||
interp = Tcl_CreateInterp();
|
||||
/* Sqlite_Init(interp); */
|
||||
Sqlite_Init(interp);
|
||||
#ifdef SQLITE_TEST
|
||||
{
|
||||
extern int Sqlitetest1_Init(Tcl_Interp*);
|
||||
@@ -1210,10 +1208,10 @@ int TCLSH_MAIN(int argc, char **argv){
|
||||
extern int Sqlitetest4_Init(Tcl_Interp*);
|
||||
extern int Sqlitetest5_Init(Tcl_Interp*);
|
||||
extern int Md5_Init(Tcl_Interp*);
|
||||
/* Sqlitetest1_Init(interp); */
|
||||
/* Sqlitetest1_Init(interp); */
|
||||
Sqlitetest2_Init(interp);
|
||||
Sqlitetest3_Init(interp);
|
||||
/* Sqlitetest4_Init(interp); */
|
||||
/* Sqlitetest4_Init(interp); */
|
||||
Sqlitetest5_Init(interp);
|
||||
Md5_Init(interp);
|
||||
}
|
||||
@@ -1240,3 +1238,6 @@ int TCLSH_MAIN(int argc, char **argv){
|
||||
#endif /* TCLSH */
|
||||
|
||||
#endif /* !defined(NO_TCL) */
|
||||
|
||||
|
||||
|
||||
|
21
src/test1.c
21
src/test1.c
@@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test1.c,v 1.36 2004/02/22 17:49:34 drh Exp $
|
||||
** $Id: test1.c,v 1.37 2004/05/08 08:23:39 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@@ -180,7 +180,7 @@ static int test_mprintf_z(
|
||||
int i;
|
||||
|
||||
for(i=2; i<argc; i++){
|
||||
zResult = sqliteMPrintf("%z%s%s", zResult, argv[1], argv[i]);
|
||||
zResult = sqlite3MPrintf("%z%s%s", zResult, argv[1], argv[i]);
|
||||
}
|
||||
Tcl_AppendResult(interp, zResult, 0);
|
||||
sqliteFree(zResult);
|
||||
@@ -329,7 +329,7 @@ static void dstrAppend(struct dstr *p, const char *z, int divider){
|
||||
}
|
||||
|
||||
/*
|
||||
** Invoked for each callback from sqliteExecFunc
|
||||
** Invoked for each callback from sqlite3ExecFunc
|
||||
*/
|
||||
static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){
|
||||
struct dstr *p = (struct dstr*)pData;
|
||||
@@ -355,7 +355,7 @@ static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){
|
||||
** This routine simulates the effect of having two threads attempt to
|
||||
** use the same database at the same time.
|
||||
*/
|
||||
static void sqliteExecFunc(sqlite_func *context, int argc, const char **argv){
|
||||
static void sqlite3ExecFunc(sqlite_func *context, int argc, const char **argv){
|
||||
struct dstr x;
|
||||
memset(&x, 0, sizeof(x));
|
||||
sqlite_exec((sqlite*)sqlite_user_data(context), argv[0],
|
||||
@@ -394,7 +394,7 @@ static int test_create_function(
|
||||
}
|
||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
||||
sqlite_create_function(db, "x_coalesce", -1, ifnullFunc, 0);
|
||||
sqlite_create_function(db, "x_sqlite_exec", 1, sqliteExecFunc, db);
|
||||
sqlite_create_function(db, "x_sqlite_exec", 1, sqlite3ExecFunc, db);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -632,15 +632,15 @@ static void testFunc(sqlite_func *context, int argc, const char **argv){
|
||||
if( argv[0]==0 ){
|
||||
sqlite_set_result_error(context, "first argument to test function "
|
||||
"may not be NULL", -1);
|
||||
}else if( sqliteStrICmp(argv[0],"string")==0 ){
|
||||
}else if( sqlite3StrICmp(argv[0],"string")==0 ){
|
||||
sqlite_set_result_string(context, argv[1], -1);
|
||||
}else if( argv[1]==0 ){
|
||||
sqlite_set_result_error(context, "2nd argument may not be NULL if the "
|
||||
"first argument is not \"string\"", -1);
|
||||
}else if( sqliteStrICmp(argv[0],"int")==0 ){
|
||||
}else if( sqlite3StrICmp(argv[0],"int")==0 ){
|
||||
sqlite_set_result_int(context, atoi(argv[1]));
|
||||
}else if( sqliteStrICmp(argv[0],"double")==0 ){
|
||||
sqlite_set_result_double(context, sqliteAtoF(argv[1], 0));
|
||||
}else if( sqlite3StrICmp(argv[0],"double")==0 ){
|
||||
sqlite_set_result_double(context, sqlite3AtoF(argv[1], 0));
|
||||
}else{
|
||||
sqlite_set_result_error(context,"first argument should be one of: "
|
||||
"string int double", -1);
|
||||
@@ -1022,3 +1022,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
(char*)&sqlite_static_bind_value, TCL_LINK_STRING);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
13
src/test2.c
13
src/test2.c
@@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test2.c,v 1.17 2004/04/26 14:10:22 drh Exp $
|
||||
** $Id: test2.c,v 1.18 2004/05/08 08:23:39 danielk1977 Exp $
|
||||
*/
|
||||
#include "os.h"
|
||||
#include "sqliteInt.h"
|
||||
@@ -499,20 +499,20 @@ static int fake_big_file(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
|
||||
rc = sqliteOsOpenReadWrite(argv[2], &fd, &readOnly);
|
||||
rc = sqlite3OsOpenReadWrite(argv[2], &fd, &readOnly);
|
||||
if( rc ){
|
||||
Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
offset = n;
|
||||
offset *= 1024*1024;
|
||||
rc = sqliteOsSeek(&fd, offset);
|
||||
rc = sqlite3OsSeek(&fd, offset);
|
||||
if( rc ){
|
||||
Tcl_AppendResult(interp, "seek failed: ", errorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
rc = sqliteOsWrite(&fd, "Hello, World!", 14);
|
||||
sqliteOsClose(&fd);
|
||||
rc = sqlite3OsWrite(&fd, "Hello, World!", 14);
|
||||
sqlite3OsClose(&fd);
|
||||
if( rc ){
|
||||
Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
@@ -568,3 +568,6 @@ int Sqlitetest2_Init(Tcl_Interp *interp){
|
||||
Tcl_SetVar(interp, "SQLITE_USABLE_SIZE", zBuf, TCL_GLOBAL_ONLY);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test3.c,v 1.29 2004/05/08 02:03:23 drh Exp $
|
||||
** $Id: test3.c,v 1.30 2004/05/08 08:23:39 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "pager.h"
|
||||
@@ -1087,3 +1087,6 @@ int Sqlitetest3_Init(Tcl_Interp *interp){
|
||||
TCL_LINK_INT);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Code for testing the the SQLite library in a multithreaded environment.
|
||||
**
|
||||
** $Id: test4.c,v 1.3 2004/04/23 17:04:45 drh Exp $
|
||||
** $Id: test4.c,v 1.4 2004/05/08 08:23:39 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@@ -632,3 +632,6 @@ int Sqlitetest4_Init(Tcl_Interp *interp){
|
||||
#else
|
||||
int Sqlitetest4_Init(Tcl_Interp *interp){ return TCL_OK; }
|
||||
#endif /* OS_UNIX */
|
||||
|
||||
|
||||
|
||||
|
@@ -194,3 +194,6 @@ int Sqlitetest5_Init(Tcl_Interp *interp){
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
** individual tokens and sends those tokens one-by-one over to the
|
||||
** parser for analysis.
|
||||
**
|
||||
** $Id: tokenize.c,v 1.68 2004/02/14 23:59:58 drh Exp $
|
||||
** $Id: tokenize.c,v 1.69 2004/05/08 08:23:39 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@@ -152,31 +152,31 @@ static u8 aiHashTable[KEY_HASH_SIZE];
|
||||
** keyword. If it is a keyword, the token code of that keyword is
|
||||
** returned. If the input is not a keyword, TK_ID is returned.
|
||||
*/
|
||||
int sqliteKeywordCode(const char *z, int n){
|
||||
int sqlite3KeywordCode(const char *z, int n){
|
||||
int h, i;
|
||||
Keyword *p;
|
||||
static char needInit = 1;
|
||||
if( needInit ){
|
||||
/* Initialize the keyword hash table */
|
||||
sqliteOsEnterMutex();
|
||||
sqlite3OsEnterMutex();
|
||||
if( needInit ){
|
||||
int nk;
|
||||
nk = sizeof(aKeywordTable)/sizeof(aKeywordTable[0]);
|
||||
for(i=0; i<nk; i++){
|
||||
aKeywordTable[i].len = strlen(aKeywordTable[i].zName);
|
||||
h = sqliteHashNoCase(aKeywordTable[i].zName, aKeywordTable[i].len);
|
||||
h = sqlite3HashNoCase(aKeywordTable[i].zName, aKeywordTable[i].len);
|
||||
h %= KEY_HASH_SIZE;
|
||||
aKeywordTable[i].iNext = aiHashTable[h];
|
||||
aiHashTable[h] = i+1;
|
||||
}
|
||||
needInit = 0;
|
||||
}
|
||||
sqliteOsLeaveMutex();
|
||||
sqlite3OsLeaveMutex();
|
||||
}
|
||||
h = sqliteHashNoCase(z, n) % KEY_HASH_SIZE;
|
||||
h = sqlite3HashNoCase(z, n) % KEY_HASH_SIZE;
|
||||
for(i=aiHashTable[h]; i; i=p->iNext){
|
||||
p = &aKeywordTable[i-1];
|
||||
if( p->len==n && sqliteStrNICmp(p->zName, z, n)==0 ){
|
||||
if( p->len==n && sqlite3StrNICmp(p->zName, z, n)==0 ){
|
||||
return p->tokenType;
|
||||
}
|
||||
}
|
||||
@@ -380,7 +380,7 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){
|
||||
break;
|
||||
}
|
||||
for(i=1; (z[i]&0x80)!=0 || isIdChar[z[i]]; i++){}
|
||||
*tokenType = sqliteKeywordCode((char*)z, i);
|
||||
*tokenType = sqlite3KeywordCode((char*)z, i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -395,23 +395,23 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){
|
||||
** memory obtained from malloc() and *pzErrMsg made to point to that
|
||||
** error message. Or maybe not.
|
||||
*/
|
||||
int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
int nErr = 0;
|
||||
int i;
|
||||
void *pEngine;
|
||||
int tokenType;
|
||||
int lastTokenParsed = -1;
|
||||
sqlite *db = pParse->db;
|
||||
extern void *sqliteParserAlloc(void*(*)(int));
|
||||
extern void sqliteParserFree(void*, void(*)(void*));
|
||||
extern int sqliteParser(void*, int, Token, Parse*);
|
||||
extern void *sqlite3ParserAlloc(void*(*)(int));
|
||||
extern void sqlite3ParserFree(void*, void(*)(void*));
|
||||
extern int sqlite3Parser(void*, int, Token, Parse*);
|
||||
|
||||
db->flags &= ~SQLITE_Interrupt;
|
||||
pParse->rc = SQLITE_OK;
|
||||
i = 0;
|
||||
pEngine = sqliteParserAlloc((void*(*)(int))malloc);
|
||||
pEngine = sqlite3ParserAlloc((void*(*)(int))malloc);
|
||||
if( pEngine==0 ){
|
||||
sqliteSetString(pzErrMsg, "out of memory", (char*)0);
|
||||
sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
|
||||
return 1;
|
||||
}
|
||||
pParse->sLastToken.dyn = 0;
|
||||
@@ -427,13 +427,13 @@ int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
case TK_COMMENT: {
|
||||
if( (db->flags & SQLITE_Interrupt)!=0 ){
|
||||
pParse->rc = SQLITE_INTERRUPT;
|
||||
sqliteSetString(pzErrMsg, "interrupt", (char*)0);
|
||||
sqlite3SetString(pzErrMsg, "interrupt", (char*)0);
|
||||
goto abort_parse;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TK_ILLEGAL: {
|
||||
sqliteSetNString(pzErrMsg, "unrecognized token: \"", -1,
|
||||
sqlite3SetNString(pzErrMsg, "unrecognized token: \"", -1,
|
||||
pParse->sLastToken.z, pParse->sLastToken.n, "\"", 1, 0);
|
||||
nErr++;
|
||||
goto abort_parse;
|
||||
@@ -443,7 +443,7 @@ int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
/* Fall thru into the default case */
|
||||
}
|
||||
default: {
|
||||
sqliteParser(pEngine, tokenType, pParse->sLastToken, pParse);
|
||||
sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
|
||||
lastTokenParsed = tokenType;
|
||||
if( pParse->rc!=SQLITE_OK ){
|
||||
goto abort_parse;
|
||||
@@ -455,14 +455,14 @@ int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
abort_parse:
|
||||
if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
|
||||
if( lastTokenParsed!=TK_SEMI ){
|
||||
sqliteParser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
|
||||
sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
|
||||
pParse->zTail = &zSql[i];
|
||||
}
|
||||
sqliteParser(pEngine, 0, pParse->sLastToken, pParse);
|
||||
sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
|
||||
}
|
||||
sqliteParserFree(pEngine, free);
|
||||
sqlite3ParserFree(pEngine, free);
|
||||
if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
|
||||
sqliteSetString(&pParse->zErrMsg, sqlite_error_string(pParse->rc),
|
||||
sqlite3SetString(&pParse->zErrMsg, sqlite_error_string(pParse->rc),
|
||||
(char*)0);
|
||||
}
|
||||
if( pParse->zErrMsg ){
|
||||
@@ -475,15 +475,15 @@ abort_parse:
|
||||
if( !nErr ) nErr++;
|
||||
}
|
||||
if( pParse->pVdbe && pParse->nErr>0 ){
|
||||
sqliteVdbeDelete(pParse->pVdbe);
|
||||
sqlite3VdbeDelete(pParse->pVdbe);
|
||||
pParse->pVdbe = 0;
|
||||
}
|
||||
if( pParse->pNewTable ){
|
||||
sqliteDeleteTable(pParse->db, pParse->pNewTable);
|
||||
sqlite3DeleteTable(pParse->db, pParse->pNewTable);
|
||||
pParse->pNewTable = 0;
|
||||
}
|
||||
if( pParse->pNewTrigger ){
|
||||
sqliteDeleteTrigger(pParse->pNewTrigger);
|
||||
sqlite3DeleteTrigger(pParse->pNewTrigger);
|
||||
pParse->pNewTrigger = 0;
|
||||
}
|
||||
if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
|
||||
@@ -630,7 +630,7 @@ int sqlite_complete(const char *zSql){
|
||||
for(nId=1; isIdChar[(u8)zSql[nId]]; nId++){}
|
||||
switch( *zSql ){
|
||||
case 'c': case 'C': {
|
||||
if( nId==6 && sqliteStrNICmp(zSql, "create", 6)==0 ){
|
||||
if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){
|
||||
token = tkCREATE;
|
||||
}else{
|
||||
token = tkOTHER;
|
||||
@@ -638,11 +638,11 @@ int sqlite_complete(const char *zSql){
|
||||
break;
|
||||
}
|
||||
case 't': case 'T': {
|
||||
if( nId==7 && sqliteStrNICmp(zSql, "trigger", 7)==0 ){
|
||||
if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){
|
||||
token = tkTRIGGER;
|
||||
}else if( nId==4 && sqliteStrNICmp(zSql, "temp", 4)==0 ){
|
||||
}else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){
|
||||
token = tkTEMP;
|
||||
}else if( nId==9 && sqliteStrNICmp(zSql, "temporary", 9)==0 ){
|
||||
}else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){
|
||||
token = tkTEMP;
|
||||
}else{
|
||||
token = tkOTHER;
|
||||
@@ -650,9 +650,9 @@ int sqlite_complete(const char *zSql){
|
||||
break;
|
||||
}
|
||||
case 'e': case 'E': {
|
||||
if( nId==3 && sqliteStrNICmp(zSql, "end", 3)==0 ){
|
||||
if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){
|
||||
token = tkEND;
|
||||
}else if( nId==7 && sqliteStrNICmp(zSql, "explain", 7)==0 ){
|
||||
}else if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){
|
||||
token = tkEXPLAIN;
|
||||
}else{
|
||||
token = tkOTHER;
|
||||
@@ -677,3 +677,6 @@ int sqlite_complete(const char *zSql){
|
||||
}
|
||||
return state==0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
229
src/trigger.c
229
src/trigger.c
@@ -15,16 +15,16 @@
|
||||
/*
|
||||
** Delete a linked list of TriggerStep structures.
|
||||
*/
|
||||
void sqliteDeleteTriggerStep(TriggerStep *pTriggerStep){
|
||||
void sqlite3DeleteTriggerStep(TriggerStep *pTriggerStep){
|
||||
while( pTriggerStep ){
|
||||
TriggerStep * pTmp = pTriggerStep;
|
||||
pTriggerStep = pTriggerStep->pNext;
|
||||
|
||||
if( pTmp->target.dyn ) sqliteFree((char*)pTmp->target.z);
|
||||
sqliteExprDelete(pTmp->pWhere);
|
||||
sqliteExprListDelete(pTmp->pExprList);
|
||||
sqliteSelectDelete(pTmp->pSelect);
|
||||
sqliteIdListDelete(pTmp->pIdList);
|
||||
sqlite3ExprDelete(pTmp->pWhere);
|
||||
sqlite3ExprListDelete(pTmp->pExprList);
|
||||
sqlite3SelectDelete(pTmp->pSelect);
|
||||
sqlite3IdListDelete(pTmp->pIdList);
|
||||
|
||||
sqliteFree(pTmp);
|
||||
}
|
||||
@@ -35,10 +35,10 @@ void sqliteDeleteTriggerStep(TriggerStep *pTriggerStep){
|
||||
** up to the point of the BEGIN before the trigger actions. A Trigger
|
||||
** structure is generated based on the information available and stored
|
||||
** in pParse->pNewTrigger. After the trigger actions have been parsed, the
|
||||
** sqliteFinishTrigger() function is called to complete the trigger
|
||||
** sqlite3FinishTrigger() function is called to complete the trigger
|
||||
** construction process.
|
||||
*/
|
||||
void sqliteBeginTrigger(
|
||||
void sqlite3BeginTrigger(
|
||||
Parse *pParse, /* The parse context of the CREATE TRIGGER statement */
|
||||
Token *pName, /* The name of the trigger */
|
||||
int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
|
||||
@@ -66,40 +66,40 @@ void sqliteBeginTrigger(
|
||||
if( sqlite_malloc_failed ) goto trigger_cleanup;
|
||||
assert( pTableName->nSrc==1 );
|
||||
if( db->init.busy
|
||||
&& sqliteFixInit(&sFix, pParse, db->init.iDb, "trigger", pName)
|
||||
&& sqliteFixSrcList(&sFix, pTableName)
|
||||
&& sqlite3FixInit(&sFix, pParse, db->init.iDb, "trigger", pName)
|
||||
&& sqlite3FixSrcList(&sFix, pTableName)
|
||||
){
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
tab = sqliteSrcListLookup(pParse, pTableName);
|
||||
tab = sqlite3SrcListLookup(pParse, pTableName);
|
||||
if( !tab ){
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
iDb = isTemp ? 1 : tab->iDb;
|
||||
if( iDb>=2 && !db->init.busy ){
|
||||
sqliteErrorMsg(pParse, "triggers may not be added to auxiliary "
|
||||
sqlite3ErrorMsg(pParse, "triggers may not be added to auxiliary "
|
||||
"database %s", db->aDb[tab->iDb].zName);
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
|
||||
zName = sqliteStrNDup(pName->z, pName->n);
|
||||
sqliteDequote(zName);
|
||||
if( sqliteHashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){
|
||||
sqliteErrorMsg(pParse, "trigger %T already exists", pName);
|
||||
sqlite3Dequote(zName);
|
||||
if( sqlite3HashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){
|
||||
sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
if( sqliteStrNICmp(tab->zName, "sqlite_", 7)==0 ){
|
||||
sqliteErrorMsg(pParse, "cannot create trigger on system table");
|
||||
if( sqlite3StrNICmp(tab->zName, "sqlite_", 7)==0 ){
|
||||
sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
|
||||
pParse->nErr++;
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
if( tab->pSelect && tr_tm != TK_INSTEAD ){
|
||||
sqliteErrorMsg(pParse, "cannot create %s trigger on view: %S",
|
||||
sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S",
|
||||
(tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
if( !tab->pSelect && tr_tm == TK_INSTEAD ){
|
||||
sqliteErrorMsg(pParse, "cannot create INSTEAD OF"
|
||||
sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF"
|
||||
" trigger on table: %S", pTableName, 0);
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
@@ -109,10 +109,10 @@ void sqliteBeginTrigger(
|
||||
const char *zDb = db->aDb[tab->iDb].zName;
|
||||
const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
|
||||
if( tab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
|
||||
if( sqliteAuthCheck(pParse, code, zName, tab->zName, zDbTrig) ){
|
||||
if( sqlite3AuthCheck(pParse, code, zName, tab->zName, zDbTrig) ){
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(tab->iDb), 0, zDb)){
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(tab->iDb), 0, zDb)){
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
}
|
||||
@@ -138,25 +138,25 @@ void sqliteBeginTrigger(
|
||||
nt->iTabDb = tab->iDb;
|
||||
nt->op = op;
|
||||
nt->tr_tm = tr_tm;
|
||||
nt->pWhen = sqliteExprDup(pWhen);
|
||||
nt->pColumns = sqliteIdListDup(pColumns);
|
||||
nt->pWhen = sqlite3ExprDup(pWhen);
|
||||
nt->pColumns = sqlite3IdListDup(pColumns);
|
||||
nt->foreach = foreach;
|
||||
sqliteTokenCopy(&nt->nameToken,pName);
|
||||
sqlite3TokenCopy(&nt->nameToken,pName);
|
||||
assert( pParse->pNewTrigger==0 );
|
||||
pParse->pNewTrigger = nt;
|
||||
|
||||
trigger_cleanup:
|
||||
sqliteFree(zName);
|
||||
sqliteSrcListDelete(pTableName);
|
||||
sqliteIdListDelete(pColumns);
|
||||
sqliteExprDelete(pWhen);
|
||||
sqlite3SrcListDelete(pTableName);
|
||||
sqlite3IdListDelete(pColumns);
|
||||
sqlite3ExprDelete(pWhen);
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is called after all of the trigger actions have been parsed
|
||||
** in order to complete the process of building the trigger.
|
||||
*/
|
||||
void sqliteFinishTrigger(
|
||||
void sqlite3FinishTrigger(
|
||||
Parse *pParse, /* Parser context */
|
||||
TriggerStep *pStepList, /* The triggered program */
|
||||
Token *pAll /* Token that describes the complete CREATE TRIGGER */
|
||||
@@ -173,8 +173,8 @@ void sqliteFinishTrigger(
|
||||
pStepList->pTrig = nt;
|
||||
pStepList = pStepList->pNext;
|
||||
}
|
||||
if( sqliteFixInit(&sFix, pParse, nt->iDb, "trigger", &nt->nameToken)
|
||||
&& sqliteFixTriggerStep(&sFix, nt->step_list) ){
|
||||
if( sqlite3FixInit(&sFix, pParse, nt->iDb, "trigger", &nt->nameToken)
|
||||
&& sqlite3FixTriggerStep(&sFix, nt->step_list) ){
|
||||
goto triggerfinish_cleanup;
|
||||
}
|
||||
|
||||
@@ -196,26 +196,26 @@ void sqliteFinishTrigger(
|
||||
Vdbe *v;
|
||||
|
||||
/* Make an entry in the sqlite_master table */
|
||||
v = sqliteGetVdbe(pParse);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v==0 ) goto triggerfinish_cleanup;
|
||||
sqliteBeginWriteOperation(pParse, 0, 0);
|
||||
sqliteOpenMasterTable(v, nt->iDb);
|
||||
addr = sqliteVdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
|
||||
sqliteVdbeChangeP3(v, addr+2, nt->name, 0);
|
||||
sqliteVdbeChangeP3(v, addr+3, nt->table, 0);
|
||||
sqliteVdbeChangeP3(v, addr+5, pAll->z, pAll->n);
|
||||
sqlite3BeginWriteOperation(pParse, 0, 0);
|
||||
sqlite3OpenMasterTable(v, nt->iDb);
|
||||
addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
|
||||
sqlite3VdbeChangeP3(v, addr+2, nt->name, 0);
|
||||
sqlite3VdbeChangeP3(v, addr+3, nt->table, 0);
|
||||
sqlite3VdbeChangeP3(v, addr+5, pAll->z, pAll->n);
|
||||
if( nt->iDb==0 ){
|
||||
sqliteChangeCookie(db, v);
|
||||
sqlite3ChangeCookie(db, v);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Close, 0, 0);
|
||||
sqliteEndWriteOperation(pParse);
|
||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
||||
sqlite3EndWriteOperation(pParse);
|
||||
}
|
||||
|
||||
if( !pParse->explain ){
|
||||
Table *pTab;
|
||||
sqliteHashInsert(&db->aDb[nt->iDb].trigHash,
|
||||
sqlite3HashInsert(&db->aDb[nt->iDb].trigHash,
|
||||
nt->name, strlen(nt->name)+1, nt);
|
||||
pTab = sqliteLocateTable(pParse, nt->table, db->aDb[nt->iTabDb].zName);
|
||||
pTab = sqlite3LocateTable(pParse, nt->table, db->aDb[nt->iTabDb].zName);
|
||||
assert( pTab!=0 );
|
||||
nt->pNext = pTab->pTrigger;
|
||||
pTab->pTrigger = nt;
|
||||
@@ -223,10 +223,10 @@ void sqliteFinishTrigger(
|
||||
}
|
||||
|
||||
triggerfinish_cleanup:
|
||||
sqliteDeleteTrigger(nt);
|
||||
sqliteDeleteTrigger(pParse->pNewTrigger);
|
||||
sqlite3DeleteTrigger(nt);
|
||||
sqlite3DeleteTrigger(pParse->pNewTrigger);
|
||||
pParse->pNewTrigger = 0;
|
||||
sqliteDeleteTriggerStep(pStepList);
|
||||
sqlite3DeleteTriggerStep(pStepList);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -245,23 +245,23 @@ static void sqlitePersistTriggerStep(TriggerStep *p){
|
||||
p->target.dyn = 1;
|
||||
}
|
||||
if( p->pSelect ){
|
||||
Select *pNew = sqliteSelectDup(p->pSelect);
|
||||
sqliteSelectDelete(p->pSelect);
|
||||
Select *pNew = sqlite3SelectDup(p->pSelect);
|
||||
sqlite3SelectDelete(p->pSelect);
|
||||
p->pSelect = pNew;
|
||||
}
|
||||
if( p->pWhere ){
|
||||
Expr *pNew = sqliteExprDup(p->pWhere);
|
||||
sqliteExprDelete(p->pWhere);
|
||||
Expr *pNew = sqlite3ExprDup(p->pWhere);
|
||||
sqlite3ExprDelete(p->pWhere);
|
||||
p->pWhere = pNew;
|
||||
}
|
||||
if( p->pExprList ){
|
||||
ExprList *pNew = sqliteExprListDup(p->pExprList);
|
||||
sqliteExprListDelete(p->pExprList);
|
||||
ExprList *pNew = sqlite3ExprListDup(p->pExprList);
|
||||
sqlite3ExprListDelete(p->pExprList);
|
||||
p->pExprList = pNew;
|
||||
}
|
||||
if( p->pIdList ){
|
||||
IdList *pNew = sqliteIdListDup(p->pIdList);
|
||||
sqliteIdListDelete(p->pIdList);
|
||||
IdList *pNew = sqlite3IdListDup(p->pIdList);
|
||||
sqlite3IdListDelete(p->pIdList);
|
||||
p->pIdList = pNew;
|
||||
}
|
||||
}
|
||||
@@ -273,7 +273,7 @@ static void sqlitePersistTriggerStep(TriggerStep *p){
|
||||
** The parser calls this routine when it finds a SELECT statement in
|
||||
** body of a TRIGGER.
|
||||
*/
|
||||
TriggerStep *sqliteTriggerSelectStep(Select *pSelect){
|
||||
TriggerStep *sqlite3TriggerSelectStep(Select *pSelect){
|
||||
TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
|
||||
if( pTriggerStep==0 ) return 0;
|
||||
|
||||
@@ -292,7 +292,7 @@ TriggerStep *sqliteTriggerSelectStep(Select *pSelect){
|
||||
** The parser calls this routine when it sees an INSERT inside the
|
||||
** body of a trigger.
|
||||
*/
|
||||
TriggerStep *sqliteTriggerInsertStep(
|
||||
TriggerStep *sqlite3TriggerInsertStep(
|
||||
Token *pTableName, /* Name of the table into which we insert */
|
||||
IdList *pColumn, /* List of columns in pTableName to insert into */
|
||||
ExprList *pEList, /* The VALUE clause: a list of values to be inserted */
|
||||
@@ -321,7 +321,7 @@ TriggerStep *sqliteTriggerInsertStep(
|
||||
** a pointer to that trigger step. The parser calls this routine when it
|
||||
** sees an UPDATE statement inside the body of a CREATE TRIGGER.
|
||||
*/
|
||||
TriggerStep *sqliteTriggerUpdateStep(
|
||||
TriggerStep *sqlite3TriggerUpdateStep(
|
||||
Token *pTableName, /* Name of the table to be updated */
|
||||
ExprList *pEList, /* The SET clause: list of column and new values */
|
||||
Expr *pWhere, /* The WHERE clause */
|
||||
@@ -345,7 +345,7 @@ TriggerStep *sqliteTriggerUpdateStep(
|
||||
** a pointer to that trigger step. The parser calls this routine when it
|
||||
** sees a DELETE statement inside the body of a CREATE TRIGGER.
|
||||
*/
|
||||
TriggerStep *sqliteTriggerDeleteStep(Token *pTableName, Expr *pWhere){
|
||||
TriggerStep *sqlite3TriggerDeleteStep(Token *pTableName, Expr *pWhere){
|
||||
TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
|
||||
if( pTriggerStep==0 ) return 0;
|
||||
|
||||
@@ -361,13 +361,13 @@ TriggerStep *sqliteTriggerDeleteStep(Token *pTableName, Expr *pWhere){
|
||||
/*
|
||||
** Recursively delete a Trigger structure
|
||||
*/
|
||||
void sqliteDeleteTrigger(Trigger *pTrigger){
|
||||
void sqlite3DeleteTrigger(Trigger *pTrigger){
|
||||
if( pTrigger==0 ) return;
|
||||
sqliteDeleteTriggerStep(pTrigger->step_list);
|
||||
sqlite3DeleteTriggerStep(pTrigger->step_list);
|
||||
sqliteFree(pTrigger->name);
|
||||
sqliteFree(pTrigger->table);
|
||||
sqliteExprDelete(pTrigger->pWhen);
|
||||
sqliteIdListDelete(pTrigger->pColumns);
|
||||
sqlite3ExprDelete(pTrigger->pWhen);
|
||||
sqlite3IdListDelete(pTrigger->pColumns);
|
||||
if( pTrigger->nameToken.dyn ) sqliteFree((char*)pTrigger->nameToken.z);
|
||||
sqliteFree(pTrigger);
|
||||
}
|
||||
@@ -376,7 +376,7 @@ void sqliteDeleteTrigger(Trigger *pTrigger){
|
||||
* This function is called to drop a trigger from the database schema.
|
||||
*
|
||||
* This may be called directly from the parser and therefore identifies
|
||||
* the trigger by name. The sqliteDropTriggerPtr() routine does the
|
||||
* the trigger by name. The sqlite3DropTriggerPtr() routine does the
|
||||
* same job as this routine except it take a spointer to the trigger
|
||||
* instead of the trigger name.
|
||||
*
|
||||
@@ -385,7 +385,7 @@ void sqliteDeleteTrigger(Trigger *pTrigger){
|
||||
* table. This is so that the trigger can be restored into the database schema
|
||||
* if the transaction is rolled back.
|
||||
*/
|
||||
void sqliteDropTrigger(Parse *pParse, SrcList *pName){
|
||||
void sqlite3DropTrigger(Parse *pParse, SrcList *pName){
|
||||
Trigger *pTrigger;
|
||||
int i;
|
||||
const char *zDb;
|
||||
@@ -400,18 +400,18 @@ void sqliteDropTrigger(Parse *pParse, SrcList *pName){
|
||||
nName = strlen(zName);
|
||||
for(i=0; i<db->nDb; i++){
|
||||
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
|
||||
if( zDb && sqliteStrICmp(db->aDb[j].zName, zDb) ) continue;
|
||||
pTrigger = sqliteHashFind(&(db->aDb[j].trigHash), zName, nName+1);
|
||||
if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
|
||||
pTrigger = sqlite3HashFind(&(db->aDb[j].trigHash), zName, nName+1);
|
||||
if( pTrigger ) break;
|
||||
}
|
||||
if( !pTrigger ){
|
||||
sqliteErrorMsg(pParse, "no such trigger: %S", pName, 0);
|
||||
sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
|
||||
goto drop_trigger_cleanup;
|
||||
}
|
||||
sqliteDropTriggerPtr(pParse, pTrigger, 0);
|
||||
sqlite3DropTriggerPtr(pParse, pTrigger, 0);
|
||||
|
||||
drop_trigger_cleanup:
|
||||
sqliteSrcListDelete(pName);
|
||||
sqlite3SrcListDelete(pName);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -419,18 +419,18 @@ drop_trigger_cleanup:
|
||||
** then also generate code to remove the trigger from the SQLITE_MASTER
|
||||
** table.
|
||||
*/
|
||||
void sqliteDropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
|
||||
void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
|
||||
Table *pTable;
|
||||
Vdbe *v;
|
||||
sqlite *db = pParse->db;
|
||||
|
||||
assert( pTrigger->iDb<db->nDb );
|
||||
if( pTrigger->iDb>=2 ){
|
||||
sqliteErrorMsg(pParse, "triggers may not be removed from "
|
||||
sqlite3ErrorMsg(pParse, "triggers may not be removed from "
|
||||
"auxiliary database %s", db->aDb[pTrigger->iDb].zName);
|
||||
return;
|
||||
}
|
||||
pTable = sqliteFindTable(db, pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
|
||||
pTable = sqlite3FindTable(db, pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
|
||||
assert(pTable);
|
||||
assert( pTable->iDb==pTrigger->iDb || pTrigger->iDb==1 );
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
@@ -439,8 +439,8 @@ void sqliteDropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
|
||||
const char *zDb = db->aDb[pTrigger->iDb].zName;
|
||||
const char *zTab = SCHEMA_TABLE(pTrigger->iDb);
|
||||
if( pTrigger->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
|
||||
if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
|
||||
sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
|
||||
if( sqlite3AuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
|
||||
sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -448,7 +448,7 @@ void sqliteDropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
|
||||
|
||||
/* Generate code to destroy the database record of the trigger.
|
||||
*/
|
||||
if( pTable!=0 && !nested && (v = sqliteGetVdbe(pParse))!=0 ){
|
||||
if( pTable!=0 && !nested && (v = sqlite3GetVdbe(pParse))!=0 ){
|
||||
int base;
|
||||
static VdbeOpList dropTrigger[] = {
|
||||
{ OP_Rewind, 0, ADDR(9), 0},
|
||||
@@ -462,15 +462,15 @@ void sqliteDropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
|
||||
{ OP_Next, 0, ADDR(1), 0}, /* 8 */
|
||||
};
|
||||
|
||||
sqliteBeginWriteOperation(pParse, 0, 0);
|
||||
sqliteOpenMasterTable(v, pTrigger->iDb);
|
||||
base = sqliteVdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
|
||||
sqliteVdbeChangeP3(v, base+1, pTrigger->name, 0);
|
||||
sqlite3BeginWriteOperation(pParse, 0, 0);
|
||||
sqlite3OpenMasterTable(v, pTrigger->iDb);
|
||||
base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
|
||||
sqlite3VdbeChangeP3(v, base+1, pTrigger->name, 0);
|
||||
if( pTrigger->iDb==0 ){
|
||||
sqliteChangeCookie(db, v);
|
||||
sqlite3ChangeCookie(db, v);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Close, 0, 0);
|
||||
sqliteEndWriteOperation(pParse);
|
||||
sqlite3VdbeAddOp(v, OP_Close, 0, 0);
|
||||
sqlite3EndWriteOperation(pParse);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -492,8 +492,8 @@ void sqliteDropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
|
||||
}
|
||||
assert(cc);
|
||||
}
|
||||
sqliteHashInsert(&(db->aDb[pTrigger->iDb].trigHash), zName, nName+1, 0);
|
||||
sqliteDeleteTrigger(pTrigger);
|
||||
sqlite3HashInsert(&(db->aDb[pTrigger->iDb].trigHash), zName, nName+1, 0);
|
||||
sqlite3DeleteTrigger(pTrigger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,7 +510,7 @@ static int checkColumnOverLap(IdList *pIdList, ExprList *pEList){
|
||||
int e;
|
||||
if( !pIdList || !pEList ) return 1;
|
||||
for(e=0; e<pEList->nExpr; e++){
|
||||
if( sqliteIdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
|
||||
if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -530,7 +530,7 @@ int always_code_trigger_setup = 0;
|
||||
* on the Parse objects trigger-stack (to prevent recursive trigger firing) is
|
||||
* found in the list specified as pTrigger.
|
||||
*/
|
||||
int sqliteTriggersExist(
|
||||
int sqlite3TriggersExist(
|
||||
Parse *pParse, /* Used to check for recursive triggers */
|
||||
Trigger *pTrigger, /* A list of triggers associated with a table */
|
||||
int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
|
||||
@@ -586,9 +586,9 @@ static SrcList *targetSrcList(
|
||||
assert( iDb<pParse->db->nDb );
|
||||
sDb.z = pParse->db->aDb[iDb].zName;
|
||||
sDb.n = strlen(sDb.z);
|
||||
pSrc = sqliteSrcListAppend(0, &sDb, &pStep->target);
|
||||
pSrc = sqlite3SrcListAppend(0, &sDb, &pStep->target);
|
||||
} else {
|
||||
pSrc = sqliteSrcListAppend(0, &pStep->target, 0);
|
||||
pSrc = sqlite3SrcListAppend(0, &pStep->target, 0);
|
||||
}
|
||||
return pSrc;
|
||||
}
|
||||
@@ -612,38 +612,38 @@ static int codeTriggerProgram(
|
||||
pParse->trigStack->orconf = orconf;
|
||||
switch( pTriggerStep->op ){
|
||||
case TK_SELECT: {
|
||||
Select * ss = sqliteSelectDup(pTriggerStep->pSelect);
|
||||
Select * ss = sqlite3SelectDup(pTriggerStep->pSelect);
|
||||
assert(ss);
|
||||
assert(ss->pSrc);
|
||||
sqliteSelect(pParse, ss, SRT_Discard, 0, 0, 0, 0);
|
||||
sqliteSelectDelete(ss);
|
||||
sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0);
|
||||
sqlite3SelectDelete(ss);
|
||||
break;
|
||||
}
|
||||
case TK_UPDATE: {
|
||||
SrcList *pSrc;
|
||||
pSrc = targetSrcList(pParse, pTriggerStep);
|
||||
sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
|
||||
sqliteUpdate(pParse, pSrc,
|
||||
sqliteExprListDup(pTriggerStep->pExprList),
|
||||
sqliteExprDup(pTriggerStep->pWhere), orconf);
|
||||
sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
|
||||
sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
|
||||
sqlite3Update(pParse, pSrc,
|
||||
sqlite3ExprListDup(pTriggerStep->pExprList),
|
||||
sqlite3ExprDup(pTriggerStep->pWhere), orconf);
|
||||
sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
|
||||
break;
|
||||
}
|
||||
case TK_INSERT: {
|
||||
SrcList *pSrc;
|
||||
pSrc = targetSrcList(pParse, pTriggerStep);
|
||||
sqliteInsert(pParse, pSrc,
|
||||
sqliteExprListDup(pTriggerStep->pExprList),
|
||||
sqliteSelectDup(pTriggerStep->pSelect),
|
||||
sqliteIdListDup(pTriggerStep->pIdList), orconf);
|
||||
sqlite3Insert(pParse, pSrc,
|
||||
sqlite3ExprListDup(pTriggerStep->pExprList),
|
||||
sqlite3SelectDup(pTriggerStep->pSelect),
|
||||
sqlite3IdListDup(pTriggerStep->pIdList), orconf);
|
||||
break;
|
||||
}
|
||||
case TK_DELETE: {
|
||||
SrcList *pSrc;
|
||||
sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
|
||||
sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
|
||||
pSrc = targetSrcList(pParse, pTriggerStep);
|
||||
sqliteDeleteFrom(pParse, pSrc, sqliteExprDup(pTriggerStep->pWhere));
|
||||
sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
|
||||
sqlite3DeleteFrom(pParse, pSrc, sqlite3ExprDup(pTriggerStep->pWhere));
|
||||
sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -676,7 +676,7 @@ static int codeTriggerProgram(
|
||||
** trigger program(s).
|
||||
**
|
||||
*/
|
||||
int sqliteCodeRowTrigger(
|
||||
int sqlite3CodeRowTrigger(
|
||||
Parse *pParse, /* Parse context */
|
||||
int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
|
||||
ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
|
||||
@@ -732,33 +732,36 @@ int sqliteCodeRowTrigger(
|
||||
pTriggerStack->pNext = pParse->trigStack;
|
||||
pTriggerStack->ignoreJump = ignoreJump;
|
||||
pParse->trigStack = pTriggerStack;
|
||||
sqliteAuthContextPush(pParse, &sContext, pTrigger->name);
|
||||
sqlite3AuthContextPush(pParse, &sContext, pTrigger->name);
|
||||
|
||||
/* code the WHEN clause */
|
||||
endTrigger = sqliteVdbeMakeLabel(pParse->pVdbe);
|
||||
whenExpr = sqliteExprDup(pTrigger->pWhen);
|
||||
if( sqliteExprResolveIds(pParse, &dummyTablist, 0, whenExpr) ){
|
||||
endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe);
|
||||
whenExpr = sqlite3ExprDup(pTrigger->pWhen);
|
||||
if( sqlite3ExprResolveIds(pParse, &dummyTablist, 0, whenExpr) ){
|
||||
pParse->trigStack = pParse->trigStack->pNext;
|
||||
sqliteFree(pTriggerStack);
|
||||
sqliteExprDelete(whenExpr);
|
||||
sqlite3ExprDelete(whenExpr);
|
||||
return 1;
|
||||
}
|
||||
sqliteExprIfFalse(pParse, whenExpr, endTrigger, 1);
|
||||
sqliteExprDelete(whenExpr);
|
||||
sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1);
|
||||
sqlite3ExprDelete(whenExpr);
|
||||
|
||||
sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPush, 0, 0);
|
||||
sqlite3VdbeAddOp(pParse->pVdbe, OP_ContextPush, 0, 0);
|
||||
codeTriggerProgram(pParse, pTrigger->step_list, orconf);
|
||||
sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPop, 0, 0);
|
||||
sqlite3VdbeAddOp(pParse->pVdbe, OP_ContextPop, 0, 0);
|
||||
|
||||
/* Pop the entry off the trigger stack */
|
||||
pParse->trigStack = pParse->trigStack->pNext;
|
||||
sqliteAuthContextPop(&sContext);
|
||||
sqlite3AuthContextPop(&sContext);
|
||||
sqliteFree(pTriggerStack);
|
||||
|
||||
sqliteVdbeResolveLabel(pParse->pVdbe, endTrigger);
|
||||
sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger);
|
||||
}
|
||||
pTrigger = pTrigger->pNext;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
167
src/update.c
167
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.70 2004/02/22 20:05:02 drh Exp $
|
||||
** $Id: update.c,v 1.71 2004/05/08 08:23:40 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
** \_______/ \________/ \______/ \________________/
|
||||
* onError pTabList pChanges pWhere
|
||||
*/
|
||||
void sqliteUpdate(
|
||||
void sqlite3Update(
|
||||
Parse *pParse, /* The parser context */
|
||||
SrcList *pTabList, /* The table in which we should change things */
|
||||
ExprList *pChanges, /* Things to be changed */
|
||||
@@ -65,19 +65,19 @@ void sqliteUpdate(
|
||||
|
||||
/* Locate the table which we want to update.
|
||||
*/
|
||||
pTab = sqliteSrcListLookup(pParse, pTabList);
|
||||
pTab = sqlite3SrcListLookup(pParse, pTabList);
|
||||
if( pTab==0 ) goto update_cleanup;
|
||||
before_triggers = sqliteTriggersExist(pParse, pTab->pTrigger,
|
||||
before_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger,
|
||||
TK_UPDATE, TK_BEFORE, TK_ROW, pChanges);
|
||||
after_triggers = sqliteTriggersExist(pParse, pTab->pTrigger,
|
||||
after_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger,
|
||||
TK_UPDATE, TK_AFTER, TK_ROW, pChanges);
|
||||
row_triggers_exist = before_triggers || after_triggers;
|
||||
isView = pTab->pSelect!=0;
|
||||
if( sqliteIsReadOnly(pParse, pTab, before_triggers) ){
|
||||
if( sqlite3IsReadOnly(pParse, pTab, before_triggers) ){
|
||||
goto update_cleanup;
|
||||
}
|
||||
if( isView ){
|
||||
if( sqliteViewGetColumnNames(pParse, pTab) ){
|
||||
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
|
||||
goto update_cleanup;
|
||||
}
|
||||
}
|
||||
@@ -111,14 +111,14 @@ void sqliteUpdate(
|
||||
*/
|
||||
chngRecno = 0;
|
||||
for(i=0; i<pChanges->nExpr; i++){
|
||||
if( sqliteExprResolveIds(pParse, pTabList, 0, pChanges->a[i].pExpr) ){
|
||||
if( sqlite3ExprResolveIds(pParse, pTabList, 0, pChanges->a[i].pExpr) ){
|
||||
goto update_cleanup;
|
||||
}
|
||||
if( sqliteExprCheck(pParse, pChanges->a[i].pExpr, 0, 0) ){
|
||||
if( sqlite3ExprCheck(pParse, pChanges->a[i].pExpr, 0, 0) ){
|
||||
goto update_cleanup;
|
||||
}
|
||||
for(j=0; j<pTab->nCol; j++){
|
||||
if( sqliteStrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
|
||||
if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
|
||||
if( j==pTab->iPKey ){
|
||||
chngRecno = 1;
|
||||
pRecnoExpr = pChanges->a[i].pExpr;
|
||||
@@ -128,18 +128,18 @@ void sqliteUpdate(
|
||||
}
|
||||
}
|
||||
if( j>=pTab->nCol ){
|
||||
if( sqliteIsRowid(pChanges->a[i].zName) ){
|
||||
if( sqlite3IsRowid(pChanges->a[i].zName) ){
|
||||
chngRecno = 1;
|
||||
pRecnoExpr = pChanges->a[i].pExpr;
|
||||
}else{
|
||||
sqliteErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
|
||||
sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
|
||||
goto update_cleanup;
|
||||
}
|
||||
}
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
{
|
||||
int rc;
|
||||
rc = sqliteAuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
|
||||
rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
|
||||
pTab->aCol[j].zName, db->aDb[pTab->iDb].zName);
|
||||
if( rc==SQLITE_DENY ){
|
||||
goto update_cleanup;
|
||||
@@ -190,10 +190,10 @@ void sqliteUpdate(
|
||||
** WHERE clause.
|
||||
*/
|
||||
if( pWhere ){
|
||||
if( sqliteExprResolveIds(pParse, pTabList, 0, pWhere) ){
|
||||
if( sqlite3ExprResolveIds(pParse, pTabList, 0, pWhere) ){
|
||||
goto update_cleanup;
|
||||
}
|
||||
if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
|
||||
if( sqlite3ExprCheck(pParse, pWhere, 0, 0) ){
|
||||
goto update_cleanup;
|
||||
}
|
||||
}
|
||||
@@ -201,100 +201,100 @@ void sqliteUpdate(
|
||||
/* Start the view context
|
||||
*/
|
||||
if( isView ){
|
||||
sqliteAuthContextPush(pParse, &sContext, pTab->zName);
|
||||
sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
|
||||
}
|
||||
|
||||
/* Begin generating code.
|
||||
*/
|
||||
v = sqliteGetVdbe(pParse);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v==0 ) goto update_cleanup;
|
||||
sqliteBeginWriteOperation(pParse, 1, pTab->iDb);
|
||||
sqlite3BeginWriteOperation(pParse, 1, pTab->iDb);
|
||||
|
||||
/* If we are trying to update a view, construct that view into
|
||||
** a temporary table.
|
||||
*/
|
||||
if( isView ){
|
||||
Select *pView;
|
||||
pView = sqliteSelectDup(pTab->pSelect);
|
||||
sqliteSelect(pParse, pView, SRT_TempTable, iCur, 0, 0, 0);
|
||||
sqliteSelectDelete(pView);
|
||||
pView = sqlite3SelectDup(pTab->pSelect);
|
||||
sqlite3Select(pParse, pView, SRT_TempTable, iCur, 0, 0, 0);
|
||||
sqlite3SelectDelete(pView);
|
||||
}
|
||||
|
||||
/* Begin the database scan
|
||||
*/
|
||||
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1, 0);
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 1, 0);
|
||||
if( pWInfo==0 ) goto update_cleanup;
|
||||
|
||||
/* Remember the index of every item to be updated.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
|
||||
|
||||
/* End the database scan loop.
|
||||
*/
|
||||
sqliteWhereEnd(pWInfo);
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
|
||||
/* Initialize the count of updated rows
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
|
||||
}
|
||||
|
||||
if( row_triggers_exist ){
|
||||
/* Create pseudo-tables for NEW and OLD
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
|
||||
|
||||
/* The top of the update loop for when there are triggers.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
|
||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
|
||||
addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
||||
|
||||
/* Open a cursor and make it point to the record that is
|
||||
** being updated.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
||||
if( !isView ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0);
|
||||
|
||||
/* Generate the OLD table
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
|
||||
sqliteVdbeAddOp(v, OP_RowData, iCur, 0);
|
||||
sqliteVdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
|
||||
|
||||
/* Generate the NEW table
|
||||
*/
|
||||
if( chngRecno ){
|
||||
sqliteExprCode(pParse, pRecnoExpr);
|
||||
sqlite3ExprCode(pParse, pRecnoExpr);
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
|
||||
}
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
if( i==pTab->iPKey ){
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_String, 0, 0);
|
||||
continue;
|
||||
}
|
||||
j = aXRef[i];
|
||||
if( j<0 ){
|
||||
sqliteVdbeAddOp(v, OP_Column, iCur, i);
|
||||
sqlite3VdbeAddOp(v, OP_Column, iCur, i);
|
||||
}else{
|
||||
sqliteExprCode(pParse, pChanges->a[j].pExpr);
|
||||
sqlite3ExprCode(pParse, pChanges->a[j].pExpr);
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
|
||||
if( !isView ){
|
||||
sqliteVdbeAddOp(v, OP_Close, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}
|
||||
|
||||
/* Fire the BEFORE and INSTEAD OF triggers
|
||||
*/
|
||||
if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_BEFORE, pTab,
|
||||
if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_BEFORE, pTab,
|
||||
newIdx, oldIdx, onError, addr) ){
|
||||
goto update_cleanup;
|
||||
}
|
||||
@@ -307,8 +307,8 @@ void sqliteUpdate(
|
||||
** action, then we need to open all indices because we might need
|
||||
** to be deleting some records.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenWrite, iCur, pTab->tnum);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pTab->tnum);
|
||||
if( onError==OE_Replace ){
|
||||
openAll = 1;
|
||||
}else{
|
||||
@@ -322,8 +322,8 @@ void sqliteUpdate(
|
||||
}
|
||||
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
if( openAll || aIdxUsed[i] ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenWrite, iCur+i+1, pIdx->tnum);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
|
||||
sqlite3VdbeAddOp(v, OP_OpenWrite, iCur+i+1, pIdx->tnum);
|
||||
assert( pParse->nTab>iCur+i+1 );
|
||||
}
|
||||
}
|
||||
@@ -335,60 +335,60 @@ void sqliteUpdate(
|
||||
** So make the cursor point at the old record.
|
||||
*/
|
||||
if( !row_triggers_exist ){
|
||||
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
|
||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
|
||||
addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_NotExists, iCur, addr);
|
||||
sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
|
||||
|
||||
/* If the record number will change, push the record number as it
|
||||
** will be after the update. (The old record number is currently
|
||||
** on top of the stack.)
|
||||
*/
|
||||
if( chngRecno ){
|
||||
sqliteExprCode(pParse, pRecnoExpr);
|
||||
sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||
sqlite3ExprCode(pParse, pRecnoExpr);
|
||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||
}
|
||||
|
||||
/* Compute new data for this record.
|
||||
*/
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
if( i==pTab->iPKey ){
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_String, 0, 0);
|
||||
continue;
|
||||
}
|
||||
j = aXRef[i];
|
||||
if( j<0 ){
|
||||
sqliteVdbeAddOp(v, OP_Column, iCur, i);
|
||||
sqlite3VdbeAddOp(v, OP_Column, iCur, i);
|
||||
}else{
|
||||
sqliteExprCode(pParse, pChanges->a[j].pExpr);
|
||||
sqlite3ExprCode(pParse, pChanges->a[j].pExpr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Do constraint checks
|
||||
*/
|
||||
sqliteGenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRecno, 1,
|
||||
sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRecno, 1,
|
||||
onError, addr);
|
||||
|
||||
/* Delete the old indices for the current record.
|
||||
*/
|
||||
sqliteGenerateRowIndexDelete(db, v, pTab, iCur, aIdxUsed);
|
||||
sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, aIdxUsed);
|
||||
|
||||
/* If changing the record number, delete the old record.
|
||||
*/
|
||||
if( chngRecno ){
|
||||
sqliteVdbeAddOp(v, OP_Delete, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Delete, iCur, 0);
|
||||
}
|
||||
|
||||
/* Create the new index entries and the new record.
|
||||
*/
|
||||
sqliteCompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRecno, 1, -1);
|
||||
sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRecno, 1, -1);
|
||||
}
|
||||
|
||||
/* Increment the row counter
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows && !pParse->trigStack){
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
}
|
||||
|
||||
/* If there are triggers, close all the cursors after each iteration
|
||||
@@ -398,12 +398,12 @@ void sqliteUpdate(
|
||||
if( !isView ){
|
||||
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
if( openAll || aIdxUsed[i] )
|
||||
sqliteVdbeAddOp(v, OP_Close, iCur+i+1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Close, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
pParse->nTab = iCur;
|
||||
}
|
||||
if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_AFTER, pTab,
|
||||
if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_AFTER, pTab,
|
||||
newIdx, oldIdx, onError, addr) ){
|
||||
goto update_cleanup;
|
||||
}
|
||||
@@ -412,41 +412,44 @@ void sqliteUpdate(
|
||||
/* Repeat the above with the next record to be updated, until
|
||||
** all record selected by the WHERE clause have been updated.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
|
||||
sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
|
||||
sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
|
||||
sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
|
||||
sqlite3VdbeAddOp(v, OP_ListReset, 0, 0);
|
||||
|
||||
/* Close all tables if there were no FOR EACH ROW triggers */
|
||||
if( !row_triggers_exist ){
|
||||
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
if( openAll || aIdxUsed[i] ){
|
||||
sqliteVdbeAddOp(v, OP_Close, iCur+i+1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Close, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
pParse->nTab = iCur;
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_Close, newIdx, 0);
|
||||
sqliteVdbeAddOp(v, OP_Close, oldIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, newIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, oldIdx, 0);
|
||||
}
|
||||
|
||||
sqliteVdbeAddOp(v, OP_SetCounts, 0, 0);
|
||||
sqliteEndWriteOperation(pParse);
|
||||
sqlite3VdbeAddOp(v, OP_SetCounts, 0, 0);
|
||||
sqlite3EndWriteOperation(pParse);
|
||||
|
||||
/*
|
||||
** Return the number of rows that were changed.
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
|
||||
sqliteVdbeOp3(v, OP_ColumnName, 0, 1, "rows updated", P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 1, 0);
|
||||
sqlite3VdbeOp3(v, OP_ColumnName, 0, 1, "rows updated", P3_STATIC);
|
||||
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
|
||||
}
|
||||
|
||||
update_cleanup:
|
||||
sqliteAuthContextPop(&sContext);
|
||||
sqlite3AuthContextPop(&sContext);
|
||||
sqliteFree(apIdx);
|
||||
sqliteFree(aXRef);
|
||||
sqliteSrcListDelete(pTabList);
|
||||
sqliteExprListDelete(pChanges);
|
||||
sqliteExprDelete(pWhere);
|
||||
sqlite3SrcListDelete(pTabList);
|
||||
sqlite3ExprListDelete(pChanges);
|
||||
sqlite3ExprDelete(pWhere);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -12,7 +12,7 @@
|
||||
** This file contains routines used to translate between UTF-8,
|
||||
** UTF-16, UTF-16BE, and UTF-16LE.
|
||||
**
|
||||
** $Id: utf.c,v 1.2 2004/05/06 23:37:53 danielk1977 Exp $
|
||||
** $Id: utf.c,v 1.3 2004/05/08 08:23:40 danielk1977 Exp $
|
||||
**
|
||||
** Notes on UTF-8:
|
||||
**
|
||||
@@ -491,3 +491,6 @@ void sqlite3utf16to16be(void *pData, int N){
|
||||
utf16to16(pData, N, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
97
src/util.c
97
src/util.c
@@ -14,7 +14,7 @@
|
||||
** This file contains functions for allocating memory, comparing
|
||||
** strings, and stuff like that.
|
||||
**
|
||||
** $Id: util.c,v 1.75 2004/04/26 14:10:22 drh Exp $
|
||||
** $Id: util.c,v 1.76 2004/05/08 08:23:40 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <stdarg.h>
|
||||
@@ -52,7 +52,7 @@ static int memcnt = 0;
|
||||
** Allocate new memory and set it to zero. Return NULL if
|
||||
** no memory is available.
|
||||
*/
|
||||
void *sqliteMalloc_(int n, int bZero, char *zFile, int line){
|
||||
void *sqlite3Malloc_(int n, int bZero, char *zFile, int line){
|
||||
void *p;
|
||||
int *pi;
|
||||
int i, k;
|
||||
@@ -95,7 +95,7 @@ void *sqliteMalloc_(int n, int bZero, char *zFile, int line){
|
||||
**
|
||||
** This routine is used for testing purposes only.
|
||||
*/
|
||||
void sqliteCheckMemory(void *p, int N){
|
||||
void sqlite3CheckMemory(void *p, int N){
|
||||
int *pi = p;
|
||||
int n, i, k;
|
||||
pi -= N_GUARD+1;
|
||||
@@ -113,7 +113,7 @@ void sqliteCheckMemory(void *p, int N){
|
||||
/*
|
||||
** Free memory previously obtained from sqliteMalloc()
|
||||
*/
|
||||
void sqliteFree_(void *p, char *zFile, int line){
|
||||
void sqlite3Free_(void *p, char *zFile, int line){
|
||||
if( p ){
|
||||
int *pi, i, k, n;
|
||||
pi = p;
|
||||
@@ -147,14 +147,14 @@ void sqliteFree_(void *p, char *zFile, int line){
|
||||
** works just like sqliteMalloc(). If n==0, then this routine
|
||||
** works just like sqliteFree().
|
||||
*/
|
||||
void *sqliteRealloc_(void *oldP, int n, char *zFile, int line){
|
||||
void *sqlite3Realloc_(void *oldP, int n, char *zFile, int line){
|
||||
int *oldPi, *pi, i, k, oldN, oldK;
|
||||
void *p;
|
||||
if( oldP==0 ){
|
||||
return sqliteMalloc_(n,1,zFile,line);
|
||||
return sqlite3Malloc_(n,1,zFile,line);
|
||||
}
|
||||
if( n==0 ){
|
||||
sqliteFree_(oldP,zFile,line);
|
||||
sqlite3Free_(oldP,zFile,line);
|
||||
return 0;
|
||||
}
|
||||
oldPi = oldP;
|
||||
@@ -203,7 +203,7 @@ void *sqliteRealloc_(void *oldP, int n, char *zFile, int line){
|
||||
** the SQLite library. That way clients can free the string using free()
|
||||
** rather than having to call sqliteFree().
|
||||
*/
|
||||
void sqliteStrRealloc(char **pz){
|
||||
void sqlite3StrRealloc(char **pz){
|
||||
char *zNew;
|
||||
if( pz==0 || *pz==0 ) return;
|
||||
zNew = malloc( strlen(*pz) + 1 );
|
||||
@@ -220,17 +220,17 @@ void sqliteStrRealloc(char **pz){
|
||||
/*
|
||||
** Make a copy of a string in memory obtained from sqliteMalloc()
|
||||
*/
|
||||
char *sqliteStrDup_(const char *z, char *zFile, int line){
|
||||
char *sqlite3StrDup_(const char *z, char *zFile, int line){
|
||||
char *zNew;
|
||||
if( z==0 ) return 0;
|
||||
zNew = sqliteMalloc_(strlen(z)+1, 0, zFile, line);
|
||||
zNew = sqlite3Malloc_(strlen(z)+1, 0, zFile, line);
|
||||
if( zNew ) strcpy(zNew, z);
|
||||
return zNew;
|
||||
}
|
||||
char *sqliteStrNDup_(const char *z, int n, char *zFile, int line){
|
||||
char *sqlite3StrNDup_(const char *z, int n, char *zFile, int line){
|
||||
char *zNew;
|
||||
if( z==0 ) return 0;
|
||||
zNew = sqliteMalloc_(n+1, 0, zFile, line);
|
||||
zNew = sqlite3Malloc_(n+1, 0, zFile, line);
|
||||
if( zNew ){
|
||||
memcpy(zNew, z, n);
|
||||
zNew[n] = 0;
|
||||
@@ -330,7 +330,7 @@ char *sqliteStrNDup(const char *z, int n){
|
||||
** point to that string. The 1st argument must either be NULL or
|
||||
** point to memory obtained from sqliteMalloc().
|
||||
*/
|
||||
void sqliteSetString(char **pz, const char *zFirst, ...){
|
||||
void sqlite3SetString(char **pz, const char *zFirst, ...){
|
||||
va_list ap;
|
||||
int nByte;
|
||||
const char *z;
|
||||
@@ -364,13 +364,13 @@ void sqliteSetString(char **pz, const char *zFirst, ...){
|
||||
}
|
||||
|
||||
/*
|
||||
** Works like sqliteSetString, but each string is now followed by
|
||||
** Works like sqlite3SetString, but each string is now followed by
|
||||
** a length integer which specifies how much of the source string
|
||||
** to copy (in bytes). -1 means use the whole string. The 1st
|
||||
** argument must either be NULL or point to memory obtained from
|
||||
** sqliteMalloc().
|
||||
*/
|
||||
void sqliteSetNString(char **pz, ...){
|
||||
void sqlite3SetNString(char **pz, ...){
|
||||
va_list ap;
|
||||
int nByte;
|
||||
const char *z;
|
||||
@@ -405,7 +405,6 @@ void sqliteSetNString(char **pz, ...){
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
** Add an error message to pParse->zErrMsg and increment pParse->nErr.
|
||||
** The following formatting characters are allowed:
|
||||
@@ -416,15 +415,14 @@ void sqliteSetNString(char **pz, ...){
|
||||
** %T Insert a token
|
||||
** %S Insert the first element of a SrcList
|
||||
*/
|
||||
void sqliteErrorMsg(Parse *pParse, const char *zFormat, ...){
|
||||
void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
pParse->nErr++;
|
||||
sqliteFree(pParse->zErrMsg);
|
||||
va_start(ap, zFormat);
|
||||
pParse->zErrMsg = sqliteVMPrintf(zFormat, ap);
|
||||
pParse->zErrMsg = sqlite3VMPrintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Convert an SQL-style quoted string into a normal string by removing
|
||||
@@ -436,7 +434,7 @@ void sqliteErrorMsg(Parse *pParse, const char *zFormat, ...){
|
||||
** brackets from around identifers. For example: "[a-b-c]" becomes
|
||||
** "a-b-c".
|
||||
*/
|
||||
void sqliteDequote(char *z){
|
||||
void sqlite3Dequote(char *z){
|
||||
int quote;
|
||||
int i, j;
|
||||
if( z==0 ) return;
|
||||
@@ -487,7 +485,7 @@ static unsigned char UpperToLower[] = {
|
||||
** This function computes a hash on the name of a keyword.
|
||||
** Case is not significant.
|
||||
*/
|
||||
int sqliteHashNoCase(const char *z, int n){
|
||||
int sqlite3HashNoCase(const char *z, int n){
|
||||
int h = 0;
|
||||
if( n<=0 ) n = strlen(z);
|
||||
while( n > 0 ){
|
||||
@@ -501,14 +499,14 @@ int sqliteHashNoCase(const char *z, int n){
|
||||
** Some systems have stricmp(). Others have strcasecmp(). Because
|
||||
** there is no consistency, we will define our own.
|
||||
*/
|
||||
int sqliteStrICmp(const char *zLeft, const char *zRight){
|
||||
int sqlite3StrICmp(const char *zLeft, const char *zRight){
|
||||
register unsigned char *a, *b;
|
||||
a = (unsigned char *)zLeft;
|
||||
b = (unsigned char *)zRight;
|
||||
while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
|
||||
return *a - *b;
|
||||
}
|
||||
int sqliteStrNICmp(const char *zLeft, const char *zRight, int N){
|
||||
int sqlite3StrNICmp(const char *zLeft, const char *zRight, int N){
|
||||
register unsigned char *a, *b;
|
||||
a = (unsigned char *)zLeft;
|
||||
b = (unsigned char *)zRight;
|
||||
@@ -522,7 +520,7 @@ int sqliteStrNICmp(const char *zLeft, const char *zRight, int N){
|
||||
**
|
||||
** Am empty string is considered non-numeric.
|
||||
*/
|
||||
int sqliteIsNumber(const char *z){
|
||||
int sqlite3IsNumber(const char *z){
|
||||
if( *z=='-' || *z=='+' ) z++;
|
||||
if( !isdigit(*z) ){
|
||||
return 0;
|
||||
@@ -555,7 +553,7 @@ int sqliteIsNumber(const char *z){
|
||||
** of "." depending on how locale is set. But that would cause problems
|
||||
** for SQL. So this routine always uses "." regardless of locale.
|
||||
*/
|
||||
double sqliteAtoF(const char *z, const char **pzEnd){
|
||||
double sqlite3AtoF(const char *z, const char **pzEnd){
|
||||
int sign = 1;
|
||||
LONGDOUBLE_TYPE v1 = 0.0;
|
||||
if( *z=='-' ){
|
||||
@@ -618,7 +616,7 @@ double sqliteAtoF(const char *z, const char **pzEnd){
|
||||
** 2147483648 will not fit in 32 bits. So it seems safer to return
|
||||
** false.
|
||||
*/
|
||||
int sqliteFitsIn32Bits(const char *zNum){
|
||||
int sqlite3FitsIn32Bits(const char *zNum){
|
||||
int i, c;
|
||||
if( *zNum=='-' || *zNum=='+' ) zNum++;
|
||||
for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
|
||||
@@ -638,7 +636,7 @@ int sqliteFitsIn32Bits(const char *zNum){
|
||||
** a number is the smaller. Non-numeric strings compare in
|
||||
** lexigraphical order (the same order as strcmp()).
|
||||
*/
|
||||
int sqliteCompare(const char *atext, const char *btext){
|
||||
int sqlite3Compare(const char *atext, const char *btext){
|
||||
int result;
|
||||
int isNumA, isNumB;
|
||||
if( atext==0 ){
|
||||
@@ -646,15 +644,15 @@ int sqliteCompare(const char *atext, const char *btext){
|
||||
}else if( btext==0 ){
|
||||
return 1;
|
||||
}
|
||||
isNumA = sqliteIsNumber(atext);
|
||||
isNumB = sqliteIsNumber(btext);
|
||||
isNumA = sqlite3IsNumber(atext);
|
||||
isNumB = sqlite3IsNumber(btext);
|
||||
if( isNumA ){
|
||||
if( !isNumB ){
|
||||
result = -1;
|
||||
}else{
|
||||
double rA, rB;
|
||||
rA = sqliteAtoF(atext, 0);
|
||||
rB = sqliteAtoF(btext, 0);
|
||||
rA = sqlite3AtoF(atext, 0);
|
||||
rB = sqlite3AtoF(btext, 0);
|
||||
if( rA<rB ){
|
||||
result = -1;
|
||||
}else if( rA>rB ){
|
||||
@@ -697,7 +695,7 @@ int sqliteCompare(const char *atext, const char *btext){
|
||||
** For the "+" and "-" sorting, pure numeric strings (strings for which the
|
||||
** isNum() function above returns TRUE) always compare less than strings
|
||||
** that are not pure numerics. Non-numeric strings compare in memcmp()
|
||||
** order. This is the same sort order as the sqliteCompare() function
|
||||
** order. This is the same sort order as the sqlite3Compare() function
|
||||
** above generates.
|
||||
**
|
||||
** The last point is a change from version 2.6.3 to version 2.7.0. In
|
||||
@@ -712,7 +710,7 @@ int sqliteCompare(const char *atext, const char *btext){
|
||||
** of expressions and for indices. This was not the case for version
|
||||
** 2.6.3 and earlier.
|
||||
*/
|
||||
int sqliteSortCompare(const char *a, const char *b){
|
||||
int sqlite3SortCompare(const char *a, const char *b){
|
||||
int res = 0;
|
||||
int isNumA, isNumB;
|
||||
int dir = 0;
|
||||
@@ -738,16 +736,16 @@ int sqliteSortCompare(const char *a, const char *b){
|
||||
res = strcmp(&a[1],&b[1]);
|
||||
if( res ) break;
|
||||
}else{
|
||||
isNumA = sqliteIsNumber(&a[1]);
|
||||
isNumB = sqliteIsNumber(&b[1]);
|
||||
isNumA = sqlite3IsNumber(&a[1]);
|
||||
isNumB = sqlite3IsNumber(&b[1]);
|
||||
if( isNumA ){
|
||||
double rA, rB;
|
||||
if( !isNumB ){
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
rA = sqliteAtoF(&a[1], 0);
|
||||
rB = sqliteAtoF(&b[1], 0);
|
||||
rA = sqlite3AtoF(&a[1], 0);
|
||||
rB = sqlite3AtoF(&b[1], 0);
|
||||
if( rA<rB ){
|
||||
res = -1;
|
||||
break;
|
||||
@@ -773,7 +771,7 @@ int sqliteSortCompare(const char *a, const char *b){
|
||||
|
||||
/*
|
||||
** Some powers of 64. These constants are needed in the
|
||||
** sqliteRealToSortable() routine below.
|
||||
** sqlite3RealToSortable() routine below.
|
||||
*/
|
||||
#define _64e3 (64.0 * 64.0 * 64.0)
|
||||
#define _64e4 (64.0 * 64.0 * 64.0 * 64.0)
|
||||
@@ -797,7 +795,7 @@ int sqliteSortCompare(const char *a, const char *b){
|
||||
** The calling function should have allocated at least 14 characters
|
||||
** of space for the buffer z[].
|
||||
*/
|
||||
void sqliteRealToSortable(double r, char *z){
|
||||
void sqlite3RealToSortable(double r, char *z){
|
||||
int neg;
|
||||
int exp;
|
||||
int cnt = 0;
|
||||
@@ -942,7 +940,7 @@ static int sqlite_utf8_to_int(const unsigned char *z){
|
||||
** abc[*]xyz Matches "abc*xyz" only
|
||||
*/
|
||||
int
|
||||
sqliteGlobCompare(const unsigned char *zPattern, const unsigned char *zString){
|
||||
sqlite3GlobCompare(const unsigned char *zPattern, const unsigned char *zString){
|
||||
register int c;
|
||||
int invert;
|
||||
int seen;
|
||||
@@ -960,7 +958,7 @@ sqliteGlobCompare(const unsigned char *zPattern, const unsigned char *zString){
|
||||
}
|
||||
if( c==0 ) return 1;
|
||||
if( c=='[' ){
|
||||
while( *zString && sqliteGlobCompare(&zPattern[1],zString)==0 ){
|
||||
while( *zString && sqlite3GlobCompare(&zPattern[1],zString)==0 ){
|
||||
sqliteNextChar(zString);
|
||||
}
|
||||
return *zString!=0;
|
||||
@@ -968,7 +966,7 @@ sqliteGlobCompare(const unsigned char *zPattern, const unsigned char *zString){
|
||||
while( (c2 = *zString)!=0 ){
|
||||
while( c2 != 0 && c2 != c ){ c2 = *++zString; }
|
||||
if( c2==0 ) return 0;
|
||||
if( sqliteGlobCompare(&zPattern[1],zString) ) return 1;
|
||||
if( sqlite3GlobCompare(&zPattern[1],zString) ) return 1;
|
||||
sqliteNextChar(zString);
|
||||
}
|
||||
return 0;
|
||||
@@ -1027,11 +1025,11 @@ sqliteGlobCompare(const unsigned char *zPattern, const unsigned char *zString){
|
||||
** characters and '_' matches any single character. Case is
|
||||
** not significant.
|
||||
**
|
||||
** This routine is just an adaptation of the sqliteGlobCompare()
|
||||
** This routine is just an adaptation of the sqlite3GlobCompare()
|
||||
** routine above.
|
||||
*/
|
||||
int
|
||||
sqliteLikeCompare(const unsigned char *zPattern, const unsigned char *zString){
|
||||
sqlite3LikeCompare(const unsigned char *zPattern, const unsigned char *zString){
|
||||
register int c;
|
||||
int c2;
|
||||
|
||||
@@ -1050,7 +1048,7 @@ sqliteLikeCompare(const unsigned char *zPattern, const unsigned char *zString){
|
||||
while( (c2=UpperToLower[*zString])!=0 ){
|
||||
while( c2 != 0 && c2 != c ){ c2 = UpperToLower[*++zString]; }
|
||||
if( c2==0 ) return 0;
|
||||
if( sqliteLikeCompare(&zPattern[1],zString) ) return 1;
|
||||
if( sqlite3LikeCompare(&zPattern[1],zString) ) return 1;
|
||||
sqliteNextChar(zString);
|
||||
}
|
||||
return 0;
|
||||
@@ -1090,7 +1088,7 @@ sqliteLikeCompare(const unsigned char *zPattern, const unsigned char *zString){
|
||||
** call to sqlite_close(db) and db has been deallocated. And we do
|
||||
** not want to write into deallocated memory.
|
||||
*/
|
||||
int sqliteSafetyOn(sqlite *db){
|
||||
int sqlite3SafetyOn(sqlite *db){
|
||||
if( db->magic==SQLITE_MAGIC_OPEN ){
|
||||
db->magic = SQLITE_MAGIC_BUSY;
|
||||
return 0;
|
||||
@@ -1107,7 +1105,7 @@ int sqliteSafetyOn(sqlite *db){
|
||||
** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY
|
||||
** when this routine is called.
|
||||
*/
|
||||
int sqliteSafetyOff(sqlite *db){
|
||||
int sqlite3SafetyOff(sqlite *db){
|
||||
if( db->magic==SQLITE_MAGIC_BUSY ){
|
||||
db->magic = SQLITE_MAGIC_OPEN;
|
||||
return 0;
|
||||
@@ -1128,10 +1126,13 @@ int sqliteSafetyOff(sqlite *db){
|
||||
** This routine is used to try to detect when API routines are called
|
||||
** at the wrong time or in the wrong sequence.
|
||||
*/
|
||||
int sqliteSafetyCheck(sqlite *db){
|
||||
int sqlite3SafetyCheck(sqlite *db){
|
||||
if( db->pVdbe!=0 ){
|
||||
db->magic = SQLITE_MAGIC_ERROR;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
37
src/vacuum.c
37
src/vacuum.c
@@ -14,7 +14,7 @@
|
||||
** Most of the code in this file may be omitted by defining the
|
||||
** SQLITE_OMIT_VACUUM macro.
|
||||
**
|
||||
** $Id: vacuum.c,v 1.13 2004/03/10 18:57:32 drh Exp $
|
||||
** $Id: vacuum.c,v 1.14 2004/05/08 08:23:40 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@@ -95,7 +95,7 @@ static int execsql(char **pzErrMsg, sqlite *db, const char *zSql){
|
||||
/* printf("***** executing *****\n%s\n", zSql); */
|
||||
rc = sqlite_exec(db, zSql, 0, 0, &zErrMsg);
|
||||
if( zErrMsg ){
|
||||
sqliteSetString(pzErrMsg, zErrMsg, (char*)0);
|
||||
sqlite3SetString(pzErrMsg, zErrMsg, (char*)0);
|
||||
sqlite_freemem(zErrMsg);
|
||||
}
|
||||
return rc;
|
||||
@@ -155,7 +155,7 @@ static int vacuumCallback1(void *pArg, int argc, char **argv, char **NotUsed){
|
||||
p->zTable = argv[1];
|
||||
rc = sqlite_exec(p->dbOld, p->s1.z, vacuumCallback2, p, &zErrMsg);
|
||||
if( zErrMsg ){
|
||||
sqliteSetString(p->pzErrMsg, zErrMsg, (char*)0);
|
||||
sqlite3SetString(p->pzErrMsg, zErrMsg, (char*)0);
|
||||
sqlite_freemem(zErrMsg);
|
||||
}
|
||||
}
|
||||
@@ -189,7 +189,7 @@ static void randomName(unsigned char *zBuf){
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789";
|
||||
int i;
|
||||
sqliteRandomness(20, zBuf);
|
||||
sqlite3Randomness(20, zBuf);
|
||||
for(i=0; i<20; i++){
|
||||
zBuf[i] = zChars[ zBuf[i]%(sizeof(zChars)-1) ];
|
||||
}
|
||||
@@ -206,16 +206,16 @@ static void randomName(unsigned char *zBuf){
|
||||
** with 2.0.0, SQLite no longer uses GDBM so this command has
|
||||
** become a no-op.
|
||||
*/
|
||||
void sqliteVacuum(Parse *pParse, Token *pTableName){
|
||||
Vdbe *v = sqliteGetVdbe(pParse);
|
||||
sqliteVdbeAddOp(v, OP_Vacuum, 0, 0);
|
||||
void sqlite3Vacuum(Parse *pParse, Token *pTableName){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
sqlite3VdbeAddOp(v, OP_Vacuum, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine implements the OP_Vacuum opcode of the VDBE.
|
||||
*/
|
||||
int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
|
||||
int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){
|
||||
#if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM
|
||||
const char *zFilename; /* full pathname of the database file */
|
||||
int nFilename; /* number of characters in zFilename[] */
|
||||
@@ -235,7 +235,7 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
|
||||
};
|
||||
|
||||
if( db->flags & SQLITE_InTrans ){
|
||||
sqliteSetString(pzErrMsg, "cannot VACUUM from within a transaction",
|
||||
sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction",
|
||||
(char*)0);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
@@ -244,7 +244,7 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
|
||||
/* Get the full pathname of the database file and create two
|
||||
** temporary filenames in the same directory as the original file.
|
||||
*/
|
||||
zFilename = sqliteBtreeGetFilename(db->aDb[0].pBt);
|
||||
zFilename = sqlite3BtreeGetFilename(db->aDb[0].pBt);
|
||||
if( zFilename==0 ){
|
||||
/* This only happens with the in-memory database. VACUUM is a no-op
|
||||
** there, so just return */
|
||||
@@ -257,10 +257,10 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
|
||||
for(i=0; i<10; i++){
|
||||
zTemp[nFilename] = '-';
|
||||
randomName((unsigned char*)&zTemp[nFilename+1]);
|
||||
if( !sqliteOsFileExists(zTemp) ) break;
|
||||
if( !sqlite3OsFileExists(zTemp) ) break;
|
||||
}
|
||||
if( i>=10 ){
|
||||
sqliteSetString(pzErrMsg, "unable to create a temporary database file "
|
||||
sqlite3SetString(pzErrMsg, "unable to create a temporary database file "
|
||||
"in the same directory as the original database", (char*)0);
|
||||
goto end_of_vacuum;
|
||||
}
|
||||
@@ -268,7 +268,7 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
|
||||
|
||||
dbNew = sqlite_open(zTemp, 0, &zErrMsg);
|
||||
if( dbNew==0 ){
|
||||
sqliteSetString(pzErrMsg, "unable to open a temporary database at ",
|
||||
sqlite3SetString(pzErrMsg, "unable to open a temporary database at ",
|
||||
zTemp, " - ", zErrMsg, (char*)0);
|
||||
goto end_of_vacuum;
|
||||
}
|
||||
@@ -297,19 +297,19 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
|
||||
vacuumCallback1, &sVac, &zErrMsg);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqliteBtreeCopyFile(db->aDb[0].pBt, dbNew->aDb[0].pBt);
|
||||
rc = sqlite3BtreeCopyFile(db->aDb[0].pBt, dbNew->aDb[0].pBt);
|
||||
sqlite_exec(db, "COMMIT", 0, 0, 0);
|
||||
sqliteResetInternalSchema(db, 0);
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
}
|
||||
|
||||
end_of_vacuum:
|
||||
if( rc && zErrMsg!=0 ){
|
||||
sqliteSetString(pzErrMsg, "unable to vacuum database - ",
|
||||
sqlite3SetString(pzErrMsg, "unable to vacuum database - ",
|
||||
zErrMsg, (char*)0);
|
||||
}
|
||||
sqlite_exec(db, "ROLLBACK", 0, 0, 0);
|
||||
if( dbNew ) sqlite_close(dbNew);
|
||||
sqliteOsDelete(zTemp);
|
||||
sqlite3OsDelete(zTemp);
|
||||
sqliteFree(zTemp);
|
||||
sqliteFree(sVac.s1.z);
|
||||
sqliteFree(sVac.s2.z);
|
||||
@@ -318,3 +318,6 @@ end_of_vacuum:
|
||||
return sVac.rc;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
290
src/vdbe.c
290
src/vdbe.c
@@ -32,7 +32,7 @@
|
||||
** number, or the SQL "NULL" value. An inplicit conversion from one
|
||||
** type to the other occurs as necessary.
|
||||
**
|
||||
** Most of the code in this file is taken up by the sqliteVdbeExec()
|
||||
** Most of the code in this file is taken up by the sqlite3VdbeExec()
|
||||
** function which does the work of interpreting a VDBE program.
|
||||
** But other routines are also provided to help in building up
|
||||
** a program instruction by instruction.
|
||||
@@ -43,7 +43,7 @@
|
||||
** in this file for details. If in doubt, do not deviate from existing
|
||||
** commenting and indentation practices when changing or adding code.
|
||||
**
|
||||
** $Id: vdbe.c,v 1.268 2004/03/03 01:51:25 drh Exp $
|
||||
** $Id: vdbe.c,v 1.269 2004/05/08 08:23:40 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@@ -118,14 +118,14 @@ int sqlite_step(
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
db = p->db;
|
||||
if( sqliteSafetyOn(db) ){
|
||||
if( sqlite3SafetyOn(db) ){
|
||||
p->rc = SQLITE_MISUSE;
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
if( p->explain ){
|
||||
rc = sqliteVdbeList(p);
|
||||
rc = sqlite3VdbeList(p);
|
||||
}else{
|
||||
rc = sqliteVdbeExec(p);
|
||||
rc = sqlite3VdbeExec(p);
|
||||
}
|
||||
if( rc==SQLITE_DONE || rc==SQLITE_ROW ){
|
||||
if( pazColName ) *pazColName = (const char**)p->azColName;
|
||||
@@ -141,7 +141,7 @@ int sqlite_step(
|
||||
*pazValue = 0;
|
||||
}
|
||||
}
|
||||
if( sqliteSafetyOff(db) ){
|
||||
if( sqlite3SafetyOff(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
return rc;
|
||||
@@ -163,7 +163,7 @@ static int AggInsert(Agg *p, char *zKey, int nKey){
|
||||
pElem->zKey = (char*)&pElem->aMem[p->nMem];
|
||||
memcpy(pElem->zKey, zKey, nKey);
|
||||
pElem->nKey = nKey;
|
||||
pOld = sqliteHashInsert(&p->hash, pElem->zKey, pElem->nKey, pElem);
|
||||
pOld = sqlite3HashInsert(&p->hash, pElem->zKey, pElem->nKey, pElem);
|
||||
if( pOld!=0 ){
|
||||
assert( pOld==pElem ); /* Malloc failed on insert */
|
||||
sqliteFree(pOld);
|
||||
@@ -335,7 +335,7 @@ static void hardIntegerify(Mem *pStack){
|
||||
#define Realify(P) if(((P)->flags&MEM_Real)==0){ hardRealify(P); }
|
||||
static void hardRealify(Mem *pStack){
|
||||
if( pStack->flags & MEM_Str ){
|
||||
pStack->r = sqliteAtoF(pStack->z, 0);
|
||||
pStack->r = sqlite3AtoF(pStack->z, 0);
|
||||
}else if( pStack->flags & MEM_Int ){
|
||||
pStack->r = pStack->i;
|
||||
}else{
|
||||
@@ -358,7 +358,7 @@ static Sorter *Merge(Sorter *pLeft, Sorter *pRight){
|
||||
pTail = &sHead;
|
||||
pTail->pNext = 0;
|
||||
while( pLeft && pRight ){
|
||||
int c = sqliteSortCompare(pLeft->zKey, pRight->zKey);
|
||||
int c = sqlite3SortCompare(pLeft->zKey, pRight->zKey);
|
||||
if( c<=0 ){
|
||||
pTail->pNext = pLeft;
|
||||
pLeft = pLeft->pNext;
|
||||
@@ -454,7 +454,7 @@ __inline__ unsigned long long int hwtime(void){
|
||||
/*
|
||||
** Execute as much of a VDBE program as we can then return.
|
||||
**
|
||||
** sqliteVdbeMakeReady() must be called before this routine in order to
|
||||
** sqlite3VdbeMakeReady() must be called before this routine in order to
|
||||
** close the program with a final OP_Halt and to set up the callbacks
|
||||
** and the error message pointer.
|
||||
**
|
||||
@@ -479,10 +479,10 @@ __inline__ unsigned long long int hwtime(void){
|
||||
**
|
||||
** Other fatal errors return SQLITE_ERROR.
|
||||
**
|
||||
** After this routine has finished, sqliteVdbeFinalize() should be
|
||||
** After this routine has finished, sqlite3VdbeFinalize() should be
|
||||
** used to clean up the mess that was left behind.
|
||||
*/
|
||||
int sqliteVdbeExec(
|
||||
int sqlite3VdbeExec(
|
||||
Vdbe *p /* The VDBE */
|
||||
){
|
||||
int pc; /* The program counter */
|
||||
@@ -524,7 +524,7 @@ int sqliteVdbeExec(
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
if( p->trace ){
|
||||
sqliteVdbePrintOp(p->trace, pc, pOp);
|
||||
sqlite3VdbePrintOp(p->trace, pc, pOp);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -543,7 +543,7 @@ int sqliteVdbeExec(
|
||||
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
|
||||
/* Call the progress callback if it is configured and the required number
|
||||
** of VDBE ops have been executed (either since this invocation of
|
||||
** sqliteVdbeExec() or since last time the progress callback was called).
|
||||
** sqlite3VdbeExec() or since last time the progress callback was called).
|
||||
** If the progress callback returns non-zero, exit the virtual machine with
|
||||
** a return code SQLITE_ABORT.
|
||||
*/
|
||||
@@ -614,7 +614,7 @@ case OP_Goto: {
|
||||
*/
|
||||
case OP_Gosub: {
|
||||
if( p->returnDepth>=sizeof(p->returnStack)/sizeof(p->returnStack[0]) ){
|
||||
sqliteSetString(&p->zErrMsg, "return address stack overflow", (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, "return address stack overflow", (char*)0);
|
||||
p->rc = SQLITE_INTERNAL;
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
@@ -631,7 +631,7 @@ case OP_Gosub: {
|
||||
*/
|
||||
case OP_Return: {
|
||||
if( p->returnDepth<=0 ){
|
||||
sqliteSetString(&p->zErrMsg, "return address stack underflow", (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, "return address stack underflow", (char*)0);
|
||||
p->rc = SQLITE_INTERNAL;
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
@@ -664,7 +664,7 @@ case OP_Halt: {
|
||||
p->rc = pOp->p1;
|
||||
p->errorAction = pOp->p2;
|
||||
if( pOp->p3 ){
|
||||
sqliteSetString(&p->zErrMsg, pOp->p3, (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0);
|
||||
}
|
||||
return SQLITE_ERROR;
|
||||
}else{
|
||||
@@ -1106,9 +1106,9 @@ case OP_Function: {
|
||||
ctx.s.z = 0;
|
||||
ctx.isError = 0;
|
||||
ctx.isStep = 0;
|
||||
if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
|
||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||
(*ctx.pFunc->xFunc)(&ctx, n, (const char**)azArgv);
|
||||
if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
|
||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
||||
popStack(&pTos, n);
|
||||
pTos++;
|
||||
*pTos = ctx.s;
|
||||
@@ -1116,7 +1116,7 @@ case OP_Function: {
|
||||
pTos->z = pTos->zShort;
|
||||
}
|
||||
if( ctx.isError ){
|
||||
sqliteSetString(&p->zErrMsg,
|
||||
sqlite3SetString(&p->zErrMsg,
|
||||
(pTos->flags & MEM_Str)!=0 ? pTos->z : "user function error", (char*)0);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
@@ -1213,7 +1213,7 @@ case OP_ForceInt: {
|
||||
int v;
|
||||
assert( pTos>=p->aStack );
|
||||
if( (pTos->flags & (MEM_Int|MEM_Real))==0
|
||||
&& ((pTos->flags & MEM_Str)==0 || sqliteIsNumber(pTos->z)==0) ){
|
||||
&& ((pTos->flags & MEM_Str)==0 || sqlite3IsNumber(pTos->z)==0) ){
|
||||
Release(pTos);
|
||||
pTos--;
|
||||
pc = pOp->p2 - 1;
|
||||
@@ -1259,7 +1259,7 @@ case OP_MustBeInt: {
|
||||
int v;
|
||||
if( !toInt(pTos->z, &v) ){
|
||||
double r;
|
||||
if( !sqliteIsNumber(pTos->z) ){
|
||||
if( !sqlite3IsNumber(pTos->z) ){
|
||||
goto mismatch;
|
||||
}
|
||||
Realify(pTos);
|
||||
@@ -1429,7 +1429,7 @@ case OP_Ge: {
|
||||
}else{
|
||||
Stringify(pTos);
|
||||
Stringify(pNos);
|
||||
c = sqliteCompare(pNos->z, pTos->z);
|
||||
c = sqlite3Compare(pNos->z, pTos->z);
|
||||
}
|
||||
switch( pOp->opcode ){
|
||||
case OP_Eq: c = c==0; break;
|
||||
@@ -1973,7 +1973,7 @@ case OP_MakeRecord: {
|
||||
** of characters that represent the number such that a comparison of
|
||||
** the character string using memcpy() sorts the numbers in numerical
|
||||
** order. The character strings for numbers are generated using the
|
||||
** sqliteRealToSortable() function. A text field is introduced by a
|
||||
** sqlite3RealToSortable() function. A text field is introduced by a
|
||||
** 'c' character and is followed by the exact text of the field. The
|
||||
** use of an 'a', 'b', or 'c' character at the beginning of each field
|
||||
** guarantees that NULLs sort before numbers and that numbers sort
|
||||
@@ -2038,15 +2038,15 @@ case OP_MakeKey: {
|
||||
Stringify(pRec);
|
||||
pRec->flags &= ~(MEM_Int|MEM_Real);
|
||||
nByte += pRec->n+1;
|
||||
}else if( (flags & (MEM_Real|MEM_Int))!=0 || sqliteIsNumber(pRec->z) ){
|
||||
}else if( (flags & (MEM_Real|MEM_Int))!=0 || sqlite3IsNumber(pRec->z) ){
|
||||
if( (flags & (MEM_Real|MEM_Int))==MEM_Int ){
|
||||
pRec->r = pRec->i;
|
||||
}else if( (flags & (MEM_Real|MEM_Int))==0 ){
|
||||
pRec->r = sqliteAtoF(pRec->z, 0);
|
||||
pRec->r = sqlite3AtoF(pRec->z, 0);
|
||||
}
|
||||
Release(pRec);
|
||||
z = pRec->zShort;
|
||||
sqliteRealToSortable(pRec->r, z);
|
||||
sqlite3RealToSortable(pRec->r, z);
|
||||
len = strlen(z);
|
||||
pRec->z = 0;
|
||||
pRec->flags = MEM_Real;
|
||||
@@ -2144,7 +2144,7 @@ case OP_IncrKey: {
|
||||
case OP_Checkpoint: {
|
||||
int i = pOp->p1;
|
||||
if( i>=0 && i<db->nDb && db->aDb[i].pBt && db->aDb[i].inTrans==1 ){
|
||||
rc = sqliteBtreeBeginCkpt(db->aDb[i].pBt);
|
||||
rc = sqlite3BtreeBeginStmt(db->aDb[i].pBt);
|
||||
if( rc==SQLITE_OK ) db->aDb[i].inTrans = 2;
|
||||
}
|
||||
break;
|
||||
@@ -2172,7 +2172,7 @@ case OP_Transaction: {
|
||||
assert( i>=0 && i<db->nDb );
|
||||
if( db->aDb[i].inTrans ) break;
|
||||
while( db->aDb[i].pBt!=0 && busy ){
|
||||
rc = sqliteBtreeBeginTrans(db->aDb[i].pBt);
|
||||
rc = sqlite3BtreeBeginTrans(db->aDb[i].pBt);
|
||||
switch( rc ){
|
||||
case SQLITE_BUSY: {
|
||||
if( db->xBusyCallback==0 ){
|
||||
@@ -2182,7 +2182,7 @@ case OP_Transaction: {
|
||||
p->pTos = pTos;
|
||||
return SQLITE_BUSY;
|
||||
}else if( (*db->xBusyCallback)(db->pBusyArg, "", busy++)==0 ){
|
||||
sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
|
||||
busy = 0;
|
||||
}
|
||||
break;
|
||||
@@ -2217,22 +2217,22 @@ case OP_Transaction: {
|
||||
case OP_Commit: {
|
||||
int i;
|
||||
if( db->xCommitCallback!=0 ){
|
||||
if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
|
||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||
if( db->xCommitCallback(db->pCommitArg)!=0 ){
|
||||
rc = SQLITE_CONSTRAINT;
|
||||
}
|
||||
if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
|
||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
||||
}
|
||||
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
|
||||
if( db->aDb[i].inTrans ){
|
||||
rc = sqliteBtreeCommit(db->aDb[i].pBt);
|
||||
rc = sqlite3BtreeCommit(db->aDb[i].pBt);
|
||||
db->aDb[i].inTrans = 0;
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
sqliteCommitInternalChanges(db);
|
||||
sqlite3CommitInternalChanges(db);
|
||||
}else{
|
||||
sqliteRollbackAll(db);
|
||||
sqlite3RollbackAll(db);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2252,7 +2252,7 @@ case OP_Commit: {
|
||||
** the read and write locks on the indicated database.
|
||||
*/
|
||||
case OP_Rollback: {
|
||||
sqliteRollbackAll(db);
|
||||
sqlite3RollbackAll(db);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2273,7 +2273,12 @@ case OP_ReadCookie: {
|
||||
assert( pOp->p2<SQLITE_N_BTREE_META );
|
||||
assert( pOp->p1>=0 && pOp->p1<db->nDb );
|
||||
assert( db->aDb[pOp->p1].pBt!=0 );
|
||||
rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
|
||||
{
|
||||
int ii;
|
||||
for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
|
||||
rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, ii+1, &aMeta[ii]);
|
||||
}
|
||||
}
|
||||
pTos++;
|
||||
pTos->i = aMeta[1+pOp->p2];
|
||||
pTos->flags = MEM_Int;
|
||||
@@ -2297,10 +2302,20 @@ case OP_SetCookie: {
|
||||
assert( db->aDb[pOp->p1].pBt!=0 );
|
||||
assert( pTos>=p->aStack );
|
||||
Integerify(pTos)
|
||||
rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
|
||||
{
|
||||
int ii;
|
||||
for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
|
||||
rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, ii+1, &aMeta[ii]);
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
aMeta[1+pOp->p2] = pTos->i;
|
||||
rc = sqliteBtreeUpdateMeta(db->aDb[pOp->p1].pBt, aMeta);
|
||||
{
|
||||
int ii;
|
||||
for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
|
||||
rc = sqlite3BtreeUpdateMeta(db->aDb[pOp->p1].pBt, ii+1, aMeta[ii]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Release(pTos);
|
||||
pTos--;
|
||||
@@ -2326,9 +2341,14 @@ case OP_SetCookie: {
|
||||
case OP_VerifyCookie: {
|
||||
int aMeta[SQLITE_N_BTREE_META];
|
||||
assert( pOp->p1>=0 && pOp->p1<db->nDb );
|
||||
rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
|
||||
{
|
||||
int ii;
|
||||
for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
|
||||
rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, ii+1, &aMeta[ii]);
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK && aMeta[1]!=pOp->p2 ){
|
||||
sqliteSetString(&p->zErrMsg, "database schema has changed", (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, "database schema has changed", (char*)0);
|
||||
rc = SQLITE_SCHEMA;
|
||||
}
|
||||
break;
|
||||
@@ -2401,19 +2421,19 @@ case OP_OpenWrite: {
|
||||
p2 = pTos->i;
|
||||
pTos--;
|
||||
if( p2<2 ){
|
||||
sqliteSetString(&p->zErrMsg, "root page number less than 2", (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, "root page number less than 2", (char*)0);
|
||||
rc = SQLITE_INTERNAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert( i>=0 );
|
||||
if( expandCursorArraySize(p, i) ) goto no_mem;
|
||||
sqliteVdbeCleanupCursor(&p->aCsr[i]);
|
||||
sqlite3VdbeCleanupCursor(&p->aCsr[i]);
|
||||
memset(&p->aCsr[i], 0, sizeof(Cursor));
|
||||
p->aCsr[i].nullRow = 1;
|
||||
if( pX==0 ) break;
|
||||
do{
|
||||
rc = sqliteBtreeCursor(pX, p2, wrFlag, &p->aCsr[i].pCursor);
|
||||
rc = sqlite3BtreeCursor(pX, p2, wrFlag, 0, 0, &p->aCsr[i].pCursor);
|
||||
switch( rc ){
|
||||
case SQLITE_BUSY: {
|
||||
if( db->xBusyCallback==0 ){
|
||||
@@ -2422,7 +2442,7 @@ case OP_OpenWrite: {
|
||||
p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
|
||||
return SQLITE_BUSY;
|
||||
}else if( (*db->xBusyCallback)(db->pBusyArg, pOp->p3, ++busy)==0 ){
|
||||
sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
|
||||
busy = 0;
|
||||
}
|
||||
break;
|
||||
@@ -2463,23 +2483,28 @@ case OP_OpenTemp: {
|
||||
assert( i>=0 );
|
||||
if( expandCursorArraySize(p, i) ) goto no_mem;
|
||||
pCx = &p->aCsr[i];
|
||||
sqliteVdbeCleanupCursor(pCx);
|
||||
sqlite3VdbeCleanupCursor(pCx);
|
||||
memset(pCx, 0, sizeof(*pCx));
|
||||
pCx->nullRow = 1;
|
||||
rc = sqliteBtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
|
||||
rc = sqlite3BtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqliteBtreeBeginTrans(pCx->pBt);
|
||||
rc = sqlite3BtreeBeginTrans(pCx->pBt);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
/* If a transient index is required, create it by calling
|
||||
** sqlite3BtreeCreateTable() with the BTREE_ZERODATA flag before
|
||||
** opening it. If a transient table is required, just use the
|
||||
** automatically created table with root-page 2.
|
||||
*/
|
||||
if( pOp->p2 ){
|
||||
int pgno;
|
||||
rc = sqliteBtreeCreateIndex(pCx->pBt, &pgno);
|
||||
rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqliteBtreeCursor(pCx->pBt, pgno, 1, &pCx->pCursor);
|
||||
rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, 0, 0, &pCx->pCursor);
|
||||
}
|
||||
}else{
|
||||
rc = sqliteBtreeCursor(pCx->pBt, 2, 1, &pCx->pCursor);
|
||||
rc = sqlite3BtreeCursor(pCx->pBt, 2, 1, 0, 0, &pCx->pCursor);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2501,7 +2526,7 @@ case OP_OpenPseudo: {
|
||||
assert( i>=0 );
|
||||
if( expandCursorArraySize(p, i) ) goto no_mem;
|
||||
pCx = &p->aCsr[i];
|
||||
sqliteVdbeCleanupCursor(pCx);
|
||||
sqlite3VdbeCleanupCursor(pCx);
|
||||
memset(pCx, 0, sizeof(*pCx));
|
||||
pCx->nullRow = 1;
|
||||
pCx->pseudoTable = 1;
|
||||
@@ -2516,7 +2541,7 @@ case OP_OpenPseudo: {
|
||||
case OP_Close: {
|
||||
int i = pOp->p1;
|
||||
if( i>=0 && i<p->nCursor ){
|
||||
sqliteVdbeCleanupCursor(&p->aCsr[i]);
|
||||
sqlite3VdbeCleanupCursor(&p->aCsr[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2562,33 +2587,33 @@ case OP_MoveTo: {
|
||||
pTos--;
|
||||
break;
|
||||
}
|
||||
sqliteBtreeMoveto(pC->pCursor, (char*)&iKey, sizeof(int), &res);
|
||||
sqlite3BtreeMoveto(pC->pCursor, (char*)&iKey, sizeof(int), &res);
|
||||
pC->lastRecno = pTos->i;
|
||||
pC->recnoIsValid = res==0;
|
||||
}else{
|
||||
Stringify(pTos);
|
||||
sqliteBtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
|
||||
sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
|
||||
pC->recnoIsValid = 0;
|
||||
}
|
||||
pC->deferredMoveto = 0;
|
||||
sqlite_search_count++;
|
||||
oc = pOp->opcode;
|
||||
if( oc==OP_MoveTo && res<0 ){
|
||||
sqliteBtreeNext(pC->pCursor, &res);
|
||||
sqlite3BtreeNext(pC->pCursor, &res);
|
||||
pC->recnoIsValid = 0;
|
||||
if( res && pOp->p2>0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
}else if( oc==OP_MoveLt ){
|
||||
if( res>=0 ){
|
||||
sqliteBtreePrevious(pC->pCursor, &res);
|
||||
sqlite3BtreePrevious(pC->pCursor, &res);
|
||||
pC->recnoIsValid = 0;
|
||||
}else{
|
||||
/* res might be negative because the table is empty. Check to
|
||||
** see if this is the case.
|
||||
*/
|
||||
int keysize;
|
||||
res = sqliteBtreeKeySize(pC->pCursor,&keysize)!=0 || keysize==0;
|
||||
/* TODO: res = sqlite3BtreeKeySize(pC->pCursor,&keysize)!=0 || * keysize==0; */
|
||||
}
|
||||
if( res && pOp->p2>0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
@@ -2644,7 +2669,7 @@ case OP_Found: {
|
||||
if( (pC = &p->aCsr[i])->pCursor!=0 ){
|
||||
int res, rx;
|
||||
Stringify(pTos);
|
||||
rx = sqliteBtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
|
||||
rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
|
||||
alreadyExists = rx==SQLITE_OK && res==0;
|
||||
pC->deferredMoveto = 0;
|
||||
}
|
||||
@@ -2710,16 +2735,16 @@ case OP_IsUnique: {
|
||||
** If there is no such entry, jump immediately to P2.
|
||||
*/
|
||||
assert( p->aCsr[i].deferredMoveto==0 );
|
||||
rc = sqliteBtreeMoveto(pCrsr, zKey, nKey-4, &res);
|
||||
rc = sqlite3BtreeMoveto(pCrsr, zKey, nKey-4, &res);
|
||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
||||
if( res<0 ){
|
||||
rc = sqliteBtreeNext(pCrsr, &res);
|
||||
rc = sqlite3BtreeNext(pCrsr, &res);
|
||||
if( res ){
|
||||
pc = pOp->p2 - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rc = sqliteBtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &res);
|
||||
rc = sqlite3BtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &res);
|
||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
||||
if( res>0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
@@ -2731,7 +2756,7 @@ case OP_IsUnique: {
|
||||
** four bytes of the key are different from R. If the last four
|
||||
** bytes equal R then jump immediately to P2.
|
||||
*/
|
||||
sqliteBtreeKey(pCrsr, nKey - 4, 4, (char*)&v);
|
||||
sqlite3BtreeKey(pCrsr, nKey - 4, 4, (char*)&v);
|
||||
v = keyToInt(v);
|
||||
if( v==R ){
|
||||
pc = pOp->p2 - 1;
|
||||
@@ -2772,7 +2797,7 @@ case OP_NotExists: {
|
||||
int res, rx, iKey;
|
||||
assert( pTos->flags & MEM_Int );
|
||||
iKey = intToKey(pTos->i);
|
||||
rx = sqliteBtreeMoveto(pCrsr, (char*)&iKey, sizeof(int), &res);
|
||||
rx = sqlite3BtreeMoveto(pCrsr, (char*)&iKey, sizeof(int), &res);
|
||||
p->aCsr[i].lastRecno = pTos->i;
|
||||
p->aCsr[i].recnoIsValid = res==0;
|
||||
p->aCsr[i].nullRow = 0;
|
||||
@@ -2838,11 +2863,11 @@ case OP_NewRecno: {
|
||||
if( pC->nextRowidValid ){
|
||||
v = pC->nextRowid;
|
||||
}else{
|
||||
rx = sqliteBtreeLast(pC->pCursor, &res);
|
||||
rx = sqlite3BtreeLast(pC->pCursor, &res);
|
||||
if( res ){
|
||||
v = 1;
|
||||
}else{
|
||||
sqliteBtreeKey(pC->pCursor, 0, sizeof(v), (void*)&v);
|
||||
sqlite3BtreeKey(pC->pCursor, 0, sizeof(v), (void*)&v);
|
||||
v = keyToInt(v);
|
||||
if( v==0x7fffffff ){
|
||||
pC->useRandomRowid = 1;
|
||||
@@ -2863,16 +2888,16 @@ case OP_NewRecno: {
|
||||
cnt = 0;
|
||||
do{
|
||||
if( v==0 || cnt>2 ){
|
||||
sqliteRandomness(sizeof(v), &v);
|
||||
sqlite3Randomness(sizeof(v), &v);
|
||||
if( cnt<5 ) v &= 0xffffff;
|
||||
}else{
|
||||
unsigned char r;
|
||||
sqliteRandomness(1, &r);
|
||||
sqlite3Randomness(1, &r);
|
||||
v += r + 1;
|
||||
}
|
||||
if( v==0 ) continue;
|
||||
x = intToKey(v);
|
||||
rx = sqliteBtreeMoveto(pC->pCursor, &x, sizeof(int), &res);
|
||||
rx = sqlite3BtreeMoveto(pC->pCursor, &x, sizeof(int), &res);
|
||||
cnt++;
|
||||
}while( cnt<1000 && rx==SQLITE_OK && res==0 );
|
||||
db->priorNewRowid = v;
|
||||
@@ -2967,7 +2992,7 @@ case OP_PutStrKey: {
|
||||
}
|
||||
pC->nullRow = 0;
|
||||
}else{
|
||||
rc = sqliteBtreeInsert(pC->pCursor, zKey, nKey, pTos->z, pTos->n);
|
||||
rc = sqlite3BtreeInsert(pC->pCursor, zKey, nKey, pTos->z, pTos->n);
|
||||
}
|
||||
pC->recnoIsValid = 0;
|
||||
pC->deferredMoveto = 0;
|
||||
@@ -2997,8 +3022,8 @@ case OP_Delete: {
|
||||
assert( i>=0 && i<p->nCursor );
|
||||
pC = &p->aCsr[i];
|
||||
if( pC->pCursor!=0 ){
|
||||
sqliteVdbeCursorMoveto(pC);
|
||||
rc = sqliteBtreeDelete(pC->pCursor);
|
||||
sqlite3VdbeCursorMoveto(pC);
|
||||
rc = sqlite3BtreeDelete(pC->pCursor);
|
||||
pC->nextRowidValid = 0;
|
||||
}
|
||||
if( pOp->p2 & OPFLAG_NCHANGE ) db->nChange++;
|
||||
@@ -3062,14 +3087,14 @@ case OP_RowData: {
|
||||
pTos->flags = MEM_Null;
|
||||
}else if( pC->pCursor!=0 ){
|
||||
BtCursor *pCrsr = pC->pCursor;
|
||||
sqliteVdbeCursorMoveto(pC);
|
||||
sqlite3VdbeCursorMoveto(pC);
|
||||
if( pC->nullRow ){
|
||||
pTos->flags = MEM_Null;
|
||||
break;
|
||||
}else if( pC->keyAsData || pOp->opcode==OP_RowKey ){
|
||||
sqliteBtreeKeySize(pCrsr, &n);
|
||||
/* TODO: sqlite3BtreeKeySize(pCrsr, &n); */
|
||||
}else{
|
||||
sqliteBtreeDataSize(pCrsr, &n);
|
||||
sqlite3BtreeDataSize(pCrsr, &n);
|
||||
}
|
||||
pTos->n = n;
|
||||
if( n<=NBFS ){
|
||||
@@ -3082,9 +3107,9 @@ case OP_RowData: {
|
||||
pTos->z = z;
|
||||
}
|
||||
if( pC->keyAsData || pOp->opcode==OP_RowKey ){
|
||||
sqliteBtreeKey(pCrsr, 0, n, pTos->z);
|
||||
sqlite3BtreeKey(pCrsr, 0, n, pTos->z);
|
||||
}else{
|
||||
sqliteBtreeData(pCrsr, 0, n, pTos->z);
|
||||
sqlite3BtreeData(pCrsr, 0, n, pTos->z);
|
||||
}
|
||||
}else if( pC->pseudoTable ){
|
||||
pTos->n = pC->nData;
|
||||
@@ -3133,15 +3158,15 @@ case OP_Column: {
|
||||
zRec = pTos[i].z;
|
||||
payloadSize = pTos[i].n;
|
||||
}else if( (pC = &p->aCsr[i])->pCursor!=0 ){
|
||||
sqliteVdbeCursorMoveto(pC);
|
||||
sqlite3VdbeCursorMoveto(pC);
|
||||
zRec = 0;
|
||||
pCrsr = pC->pCursor;
|
||||
if( pC->nullRow ){
|
||||
payloadSize = 0;
|
||||
}else if( pC->keyAsData ){
|
||||
sqliteBtreeKeySize(pCrsr, &payloadSize);
|
||||
/* TODO: sqlite3BtreeKeySize(pCrsr, &payloadSize); */
|
||||
}else{
|
||||
sqliteBtreeDataSize(pCrsr, &payloadSize);
|
||||
sqlite3BtreeDataSize(pCrsr, &payloadSize);
|
||||
}
|
||||
}else if( pC->pseudoTable ){
|
||||
payloadSize = pC->nData;
|
||||
@@ -3174,9 +3199,9 @@ case OP_Column: {
|
||||
if( zRec ){
|
||||
memcpy(aHdr, &zRec[idxWidth*p2], idxWidth*2);
|
||||
}else if( pC->keyAsData ){
|
||||
sqliteBtreeKey(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
|
||||
sqlite3BtreeKey(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
|
||||
}else{
|
||||
sqliteBtreeData(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
|
||||
sqlite3BtreeData(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
|
||||
}
|
||||
offset = aHdr[0];
|
||||
end = aHdr[idxWidth];
|
||||
@@ -3214,9 +3239,9 @@ case OP_Column: {
|
||||
pTos->z = z;
|
||||
}
|
||||
if( pC->keyAsData ){
|
||||
sqliteBtreeKey(pCrsr, offset, amt, pTos->z);
|
||||
sqlite3BtreeKey(pCrsr, offset, amt, pTos->z);
|
||||
}else{
|
||||
sqliteBtreeData(pCrsr, offset, amt, pTos->z);
|
||||
sqlite3BtreeData(pCrsr, offset, amt, pTos->z);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -3236,7 +3261,7 @@ case OP_Recno: {
|
||||
|
||||
assert( i>=0 && i<p->nCursor );
|
||||
pC = &p->aCsr[i];
|
||||
sqliteVdbeCursorMoveto(pC);
|
||||
sqlite3VdbeCursorMoveto(pC);
|
||||
pTos++;
|
||||
if( pC->recnoIsValid ){
|
||||
v = pC->lastRecno;
|
||||
@@ -3247,7 +3272,7 @@ case OP_Recno: {
|
||||
break;
|
||||
}else{
|
||||
assert( pC->pCursor!=0 );
|
||||
sqliteBtreeKey(pC->pCursor, 0, sizeof(u32), (char*)&v);
|
||||
sqlite3BtreeKey(pC->pCursor, 0, sizeof(u32), (char*)&v);
|
||||
v = keyToInt(v);
|
||||
}
|
||||
pTos->i = v;
|
||||
@@ -3278,8 +3303,8 @@ case OP_FullKey: {
|
||||
int amt;
|
||||
char *z;
|
||||
|
||||
sqliteVdbeCursorMoveto(&p->aCsr[i]);
|
||||
sqliteBtreeKeySize(pCrsr, &amt);
|
||||
sqlite3VdbeCursorMoveto(&p->aCsr[i]);
|
||||
/* TODO: sqlite3BtreeKeySize(pCrsr, &amt); */
|
||||
if( amt<=0 ){
|
||||
rc = SQLITE_CORRUPT;
|
||||
goto abort_due_to_error;
|
||||
@@ -3292,7 +3317,7 @@ case OP_FullKey: {
|
||||
z = pTos->zShort;
|
||||
pTos->flags = MEM_Str | MEM_Short;
|
||||
}
|
||||
sqliteBtreeKey(pCrsr, 0, amt, z);
|
||||
sqlite3BtreeKey(pCrsr, 0, amt, z);
|
||||
pTos->z = z;
|
||||
pTos->n = amt;
|
||||
}
|
||||
@@ -3331,7 +3356,7 @@ case OP_Last: {
|
||||
pC = &p->aCsr[i];
|
||||
if( (pCrsr = pC->pCursor)!=0 ){
|
||||
int res;
|
||||
rc = sqliteBtreeLast(pCrsr, &res);
|
||||
rc = sqlite3BtreeLast(pCrsr, &res);
|
||||
pC->nullRow = res;
|
||||
pC->deferredMoveto = 0;
|
||||
if( res && pOp->p2>0 ){
|
||||
@@ -3360,7 +3385,7 @@ case OP_Rewind: {
|
||||
pC = &p->aCsr[i];
|
||||
if( (pCrsr = pC->pCursor)!=0 ){
|
||||
int res;
|
||||
rc = sqliteBtreeFirst(pCrsr, &res);
|
||||
rc = sqlite3BtreeFirst(pCrsr, &res);
|
||||
pC->atFirst = res==0;
|
||||
pC->nullRow = res;
|
||||
pC->deferredMoveto = 0;
|
||||
@@ -3403,8 +3428,8 @@ case OP_Next: {
|
||||
res = 1;
|
||||
}else{
|
||||
assert( pC->deferredMoveto==0 );
|
||||
rc = pOp->opcode==OP_Next ? sqliteBtreeNext(pCrsr, &res) :
|
||||
sqliteBtreePrevious(pCrsr, &res);
|
||||
rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
|
||||
sqlite3BtreePrevious(pCrsr, &res);
|
||||
pC->nullRow = res;
|
||||
}
|
||||
if( res==0 ){
|
||||
@@ -3441,30 +3466,30 @@ case OP_IdxPut: {
|
||||
if( pOp->p2 ){
|
||||
int res, n;
|
||||
assert( nKey >= 4 );
|
||||
rc = sqliteBtreeMoveto(pCrsr, zKey, nKey-4, &res);
|
||||
rc = sqlite3BtreeMoveto(pCrsr, zKey, nKey-4, &res);
|
||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
||||
while( res!=0 ){
|
||||
int c;
|
||||
sqliteBtreeKeySize(pCrsr, &n);
|
||||
/* TODO: sqlite3BtreeKeySize(pCrsr, &n); */
|
||||
if( n==nKey
|
||||
&& sqliteBtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &c)==SQLITE_OK
|
||||
&& sqlite3BtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &c)==SQLITE_OK
|
||||
&& c==0
|
||||
){
|
||||
rc = SQLITE_CONSTRAINT;
|
||||
if( pOp->p3 && pOp->p3[0] ){
|
||||
sqliteSetString(&p->zErrMsg, pOp->p3, (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0);
|
||||
}
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
if( res<0 ){
|
||||
sqliteBtreeNext(pCrsr, &res);
|
||||
sqlite3BtreeNext(pCrsr, &res);
|
||||
res = +1;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
rc = sqliteBtreeInsert(pCrsr, zKey, nKey, "", 0);
|
||||
rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0);
|
||||
assert( p->aCsr[i].deferredMoveto==0 );
|
||||
}
|
||||
Release(pTos);
|
||||
@@ -3485,9 +3510,9 @@ case OP_IdxDelete: {
|
||||
assert( i>=0 && i<p->nCursor );
|
||||
if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
|
||||
int rx, res;
|
||||
rx = sqliteBtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
|
||||
rx = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
|
||||
if( rx==SQLITE_OK && res==0 ){
|
||||
rc = sqliteBtreeDelete(pCrsr);
|
||||
rc = sqlite3BtreeDelete(pCrsr);
|
||||
}
|
||||
assert( p->aCsr[i].deferredMoveto==0 );
|
||||
}
|
||||
@@ -3515,11 +3540,11 @@ case OP_IdxRecno: {
|
||||
int v;
|
||||
int sz;
|
||||
assert( p->aCsr[i].deferredMoveto==0 );
|
||||
sqliteBtreeKeySize(pCrsr, &sz);
|
||||
/* TODO: sqlite3BtreeKeySize(pCrsr, &sz); */
|
||||
if( sz<sizeof(u32) ){
|
||||
pTos->flags = MEM_Null;
|
||||
}else{
|
||||
sqliteBtreeKey(pCrsr, sz - sizeof(u32), sizeof(u32), (char*)&v);
|
||||
sqlite3BtreeKey(pCrsr, sz - sizeof(u32), sizeof(u32), (char*)&v);
|
||||
v = keyToInt(v);
|
||||
pTos->i = v;
|
||||
pTos->flags = MEM_Int;
|
||||
@@ -3568,7 +3593,7 @@ case OP_IdxGE: {
|
||||
|
||||
Stringify(pTos);
|
||||
assert( p->aCsr[i].deferredMoveto==0 );
|
||||
rc = sqliteBtreeKeyCompare(pCrsr, pTos->z, pTos->n, 4, &res);
|
||||
rc = sqlite3BtreeKeyCompare(pCrsr, pTos->z, pTos->n, 4, &res);
|
||||
if( rc!=SQLITE_OK ){
|
||||
break;
|
||||
}
|
||||
@@ -3629,7 +3654,7 @@ case OP_IdxIsNull: {
|
||||
** See also: Clear
|
||||
*/
|
||||
case OP_Destroy: {
|
||||
rc = sqliteBtreeDropTable(db->aDb[pOp->p2].pBt, pOp->p1);
|
||||
rc = sqlite3BtreeDropTable(db->aDb[pOp->p2].pBt, pOp->p1);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3646,7 +3671,7 @@ case OP_Destroy: {
|
||||
** See also: Destroy
|
||||
*/
|
||||
case OP_Clear: {
|
||||
rc = sqliteBtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1);
|
||||
rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3682,9 +3707,9 @@ case OP_CreateTable: {
|
||||
assert( pOp->p2>=0 && pOp->p2<db->nDb );
|
||||
assert( db->aDb[pOp->p2].pBt!=0 );
|
||||
if( pOp->opcode==OP_CreateTable ){
|
||||
rc = sqliteBtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno);
|
||||
rc = sqlite3BtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno, BTREE_INTKEY);
|
||||
}else{
|
||||
rc = sqliteBtreeCreateIndex(db->aDb[pOp->p2].pBt, &pgno);
|
||||
rc = sqlite3BtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno, BTREE_ZERODATA);
|
||||
}
|
||||
pTos++;
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -3733,9 +3758,9 @@ case OP_IntegrityCk: {
|
||||
toInt((char*)sqliteHashKey(i), &aRoot[j]);
|
||||
}
|
||||
aRoot[j] = 0;
|
||||
sqliteHashClear(&pSet->hash);
|
||||
sqlite3HashClear(&pSet->hash);
|
||||
pSet->prev = 0;
|
||||
z = sqliteBtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot);
|
||||
z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot);
|
||||
if( z==0 || z[0]==0 ){
|
||||
if( z ) sqliteFree(z);
|
||||
pTos->z = "ok";
|
||||
@@ -3828,7 +3853,7 @@ case OP_ListRead: {
|
||||
*/
|
||||
case OP_ListReset: {
|
||||
if( p->pList ){
|
||||
sqliteVdbeKeylistFree(p->pList);
|
||||
sqlite3VdbeKeylistFree(p->pList);
|
||||
p->pList = 0;
|
||||
}
|
||||
break;
|
||||
@@ -3858,7 +3883,7 @@ case OP_ListPush: {
|
||||
case OP_ListPop: {
|
||||
assert(p->keylistStackDepth > 0);
|
||||
p->keylistStackDepth--;
|
||||
sqliteVdbeKeylistFree(p->pList);
|
||||
sqlite3VdbeKeylistFree(p->pList);
|
||||
p->pList = p->keylistStack[p->keylistStackDepth];
|
||||
p->keylistStack[p->keylistStackDepth] = 0;
|
||||
if( p->keylistStackDepth == 0 ){
|
||||
@@ -4119,7 +4144,7 @@ case OP_SortCallback: {
|
||||
** Remove any elements that remain on the sorter.
|
||||
*/
|
||||
case OP_SortReset: {
|
||||
sqliteVdbeSorterReset(p);
|
||||
sqlite3VdbeSorterReset(p);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4134,13 +4159,13 @@ case OP_FileOpen: {
|
||||
if( p->pFile!=stdin ) fclose(p->pFile);
|
||||
p->pFile = 0;
|
||||
}
|
||||
if( sqliteStrICmp(pOp->p3,"stdin")==0 ){
|
||||
if( sqlite3StrICmp(pOp->p3,"stdin")==0 ){
|
||||
p->pFile = stdin;
|
||||
}else{
|
||||
p->pFile = fopen(pOp->p3, "r");
|
||||
}
|
||||
if( p->pFile==0 ){
|
||||
sqliteSetString(&p->zErrMsg,"unable to open file: ", pOp->p3, (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg,"unable to open file: ", pOp->p3, (char*)0);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
break;
|
||||
@@ -4395,7 +4420,7 @@ case OP_MemIncr: {
|
||||
** Future aggregator elements will contain P2 values each.
|
||||
*/
|
||||
case OP_AggReset: {
|
||||
sqliteVdbeAggReset(&p->agg);
|
||||
sqlite3VdbeAggReset(&p->agg);
|
||||
p->agg.nMem = pOp->p2;
|
||||
p->agg.apFunc = sqliteMalloc( p->agg.nMem*sizeof(p->agg.apFunc[0]) );
|
||||
if( p->agg.apFunc==0 ) goto no_mem;
|
||||
@@ -4487,7 +4512,7 @@ case OP_AggFocus: {
|
||||
Stringify(pTos);
|
||||
zKey = pTos->z;
|
||||
nKey = pTos->n;
|
||||
pElem = sqliteHashFind(&p->agg.hash, zKey, nKey);
|
||||
pElem = sqlite3HashFind(&p->agg.hash, zKey, nKey);
|
||||
if( pElem ){
|
||||
p->agg.pCurrent = pElem;
|
||||
pc = pOp->p2 - 1;
|
||||
@@ -4613,16 +4638,16 @@ case OP_SetInsert: {
|
||||
if( aSet==0 ) goto no_mem;
|
||||
p->aSet = aSet;
|
||||
for(k=p->nSet; k<=i; k++){
|
||||
sqliteHashInit(&p->aSet[k].hash, SQLITE_HASH_BINARY, 1);
|
||||
sqlite3HashInit(&p->aSet[k].hash, SQLITE_HASH_BINARY, 1);
|
||||
}
|
||||
p->nSet = i+1;
|
||||
}
|
||||
if( pOp->p3 ){
|
||||
sqliteHashInsert(&p->aSet[i].hash, pOp->p3, strlen(pOp->p3)+1, p);
|
||||
sqlite3HashInsert(&p->aSet[i].hash, pOp->p3, strlen(pOp->p3)+1, p);
|
||||
}else{
|
||||
assert( pTos>=p->aStack );
|
||||
Stringify(pTos);
|
||||
sqliteHashInsert(&p->aSet[i].hash, pTos->z, pTos->n, p);
|
||||
sqlite3HashInsert(&p->aSet[i].hash, pTos->z, pTos->n, p);
|
||||
Release(pTos);
|
||||
pTos--;
|
||||
}
|
||||
@@ -4640,7 +4665,7 @@ case OP_SetFound: {
|
||||
int i = pOp->p1;
|
||||
assert( pTos>=p->aStack );
|
||||
Stringify(pTos);
|
||||
if( i>=0 && i<p->nSet && sqliteHashFind(&p->aSet[i].hash, pTos->z, pTos->n)){
|
||||
if( i>=0 && i<p->nSet && sqlite3HashFind(&p->aSet[i].hash, pTos->z, pTos->n)){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
Release(pTos);
|
||||
@@ -4659,7 +4684,7 @@ case OP_SetNotFound: {
|
||||
assert( pTos>=p->aStack );
|
||||
Stringify(pTos);
|
||||
if( i<0 || i>=p->nSet ||
|
||||
sqliteHashFind(&p->aSet[i].hash, pTos->z, pTos->n)==0 ){
|
||||
sqlite3HashFind(&p->aSet[i].hash, pTos->z, pTos->n)==0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
Release(pTos);
|
||||
@@ -4717,9 +4742,9 @@ case OP_SetNext: {
|
||||
** a transaction.
|
||||
*/
|
||||
case OP_Vacuum: {
|
||||
if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
|
||||
rc = sqliteRunVacuum(&p->zErrMsg, db);
|
||||
if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
|
||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||
rc = sqlite3RunVacuum(&p->zErrMsg, db);
|
||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4727,7 +4752,7 @@ case OP_Vacuum: {
|
||||
*/
|
||||
default: {
|
||||
sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode);
|
||||
sqliteSetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0);
|
||||
rc = SQLITE_INTERNAL;
|
||||
break;
|
||||
}
|
||||
@@ -4747,7 +4772,7 @@ default: {
|
||||
pOp->cnt++;
|
||||
#if 0
|
||||
fprintf(stdout, "%10lld ", elapse);
|
||||
sqliteVdbePrintOp(stdout, origPc, &p->aOp[origPc]);
|
||||
sqlite3VdbePrintOp(stdout, origPc, &p->aOp[origPc]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -4777,7 +4802,7 @@ default: {
|
||||
assert( pTos->flags==MEM_Null || (pTos->flags&MEM_Null)==0 );
|
||||
}
|
||||
if( pc<-1 || pc>=p->nOp ){
|
||||
sqliteSetString(&p->zErrMsg, "jump destination out of range", (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, "jump destination out of range", (char*)0);
|
||||
rc = SQLITE_INTERNAL;
|
||||
}
|
||||
if( p->trace && pTos>=p->aStack ){
|
||||
@@ -4849,7 +4874,7 @@ vdbe_halt:
|
||||
** to fail on a modern VM computer, so this code is untested.
|
||||
*/
|
||||
no_mem:
|
||||
sqliteSetString(&p->zErrMsg, "out of memory", (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, "out of memory", (char*)0);
|
||||
rc = SQLITE_NOMEM;
|
||||
goto vdbe_halt;
|
||||
|
||||
@@ -4865,7 +4890,7 @@ abort_due_to_misuse:
|
||||
abort_due_to_error:
|
||||
if( p->zErrMsg==0 ){
|
||||
if( sqlite_malloc_failed ) rc = SQLITE_NOMEM;
|
||||
sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
|
||||
}
|
||||
goto vdbe_halt;
|
||||
|
||||
@@ -4880,6 +4905,9 @@ abort_due_to_interrupt:
|
||||
}else{
|
||||
rc = SQLITE_INTERRUPT;
|
||||
}
|
||||
sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
|
||||
goto vdbe_halt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
53
src/vdbe.h
53
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.71 2004/02/22 20:05:02 drh Exp $
|
||||
** $Id: vdbe.h,v 1.72 2004/05/08 08:23:45 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _SQLITE_VDBE_H_
|
||||
#define _SQLITE_VDBE_H_
|
||||
@@ -69,7 +69,7 @@ typedef struct VdbeOpList VdbeOpList;
|
||||
/*
|
||||
** The following macro converts a relative address in the p2 field
|
||||
** of a VdbeOp structure into a negative number so that
|
||||
** sqliteVdbeAddOpList() knows that the address is relative. Calling
|
||||
** sqlite3VdbeAddOpList() knows that the address is relative. Calling
|
||||
** the macro again restores the address.
|
||||
*/
|
||||
#define ADDR(X) (-1-(X))
|
||||
@@ -84,29 +84,32 @@ typedef struct VdbeOpList VdbeOpList;
|
||||
** Prototypes for the VDBE interface. See comments on the implementation
|
||||
** for a description of what each of these routines does.
|
||||
*/
|
||||
Vdbe *sqliteVdbeCreate(sqlite*);
|
||||
void sqliteVdbeCreateCallback(Vdbe*, int*);
|
||||
int sqliteVdbeAddOp(Vdbe*,int,int,int);
|
||||
int sqliteVdbeOp3(Vdbe*,int,int,int,const char *zP3,int);
|
||||
int sqliteVdbeCode(Vdbe*,...);
|
||||
int sqliteVdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
|
||||
void sqliteVdbeChangeP1(Vdbe*, int addr, int P1);
|
||||
void sqliteVdbeChangeP2(Vdbe*, int addr, int P2);
|
||||
void sqliteVdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);
|
||||
void sqliteVdbeDequoteP3(Vdbe*, int addr);
|
||||
int sqliteVdbeFindOp(Vdbe*, int, int);
|
||||
VdbeOp *sqliteVdbeGetOp(Vdbe*, int);
|
||||
int sqliteVdbeMakeLabel(Vdbe*);
|
||||
void sqliteVdbeDelete(Vdbe*);
|
||||
void sqliteVdbeMakeReady(Vdbe*,int,int);
|
||||
int sqliteVdbeExec(Vdbe*);
|
||||
int sqliteVdbeList(Vdbe*);
|
||||
int sqliteVdbeFinalize(Vdbe*,char**);
|
||||
void sqliteVdbeResolveLabel(Vdbe*, int);
|
||||
int sqliteVdbeCurrentAddr(Vdbe*);
|
||||
void sqliteVdbeTrace(Vdbe*,FILE*);
|
||||
void sqliteVdbeCompressSpace(Vdbe*,int);
|
||||
int sqliteVdbeReset(Vdbe*,char **);
|
||||
Vdbe *sqlite3VdbeCreate(sqlite*);
|
||||
void sqlite3VdbeCreateCallback(Vdbe*, int*);
|
||||
int sqlite3VdbeAddOp(Vdbe*,int,int,int);
|
||||
int sqlite3VdbeOp3(Vdbe*,int,int,int,const char *zP3,int);
|
||||
int sqlite3VdbeCode(Vdbe*,...);
|
||||
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
|
||||
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
|
||||
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
|
||||
void sqlite3VdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);
|
||||
void sqlite3VdbeDequoteP3(Vdbe*, int addr);
|
||||
int sqlite3VdbeFindOp(Vdbe*, int, int);
|
||||
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
|
||||
int sqlite3VdbeMakeLabel(Vdbe*);
|
||||
void sqlite3VdbeDelete(Vdbe*);
|
||||
void sqlite3VdbeMakeReady(Vdbe*,int,int);
|
||||
int sqlite3VdbeExec(Vdbe*);
|
||||
int sqlite3VdbeList(Vdbe*);
|
||||
int sqlite3VdbeFinalize(Vdbe*,char**);
|
||||
void sqlite3VdbeResolveLabel(Vdbe*, int);
|
||||
int sqlite3VdbeCurrentAddr(Vdbe*);
|
||||
void sqlite3VdbeTrace(Vdbe*,FILE*);
|
||||
void sqlite3VdbeCompressSpace(Vdbe*,int);
|
||||
int sqlite3VdbeReset(Vdbe*,char **);
|
||||
int sqliteVdbeSetVariables(Vdbe*,int,const char**);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@@ -22,8 +22,8 @@
|
||||
** bit of the most significant byte. This causes negative numbers to
|
||||
** sort before positive numbers in the memcmp() function.
|
||||
*/
|
||||
#define keyToInt(X) (sqliteVdbeByteSwap(X) ^ 0x80000000)
|
||||
#define intToKey(X) (sqliteVdbeByteSwap((X) ^ 0x80000000))
|
||||
#define keyToInt(X) (sqlite3VdbeByteSwap(X) ^ 0x80000000)
|
||||
#define intToKey(X) (sqlite3VdbeByteSwap((X) ^ 0x80000000))
|
||||
|
||||
/*
|
||||
** The makefile scans this source file and creates the following
|
||||
@@ -31,7 +31,7 @@
|
||||
** This array is defined in a separate source code file named opcode.c
|
||||
** which is automatically generated by the makefile.
|
||||
*/
|
||||
extern char *sqliteOpcodeNames[];
|
||||
extern char *sqlite3OpcodeNames[];
|
||||
|
||||
/*
|
||||
** SQL is translated into a sequence of instructions to be
|
||||
@@ -71,8 +71,8 @@ struct Cursor {
|
||||
Bool nullRow; /* True if pointing to a row with no data */
|
||||
Bool nextRowidValid; /* True if the nextRowid field is valid */
|
||||
Bool pseudoTable; /* This is a NEW or OLD pseudo-tables of a trigger */
|
||||
Bool deferredMoveto; /* A call to sqliteBtreeMoveto() is needed */
|
||||
int movetoTarget; /* Argument to the deferred sqliteBtreeMoveto() */
|
||||
Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
|
||||
int movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
|
||||
Btree *pBt; /* Separate file holding temporary table */
|
||||
int nData; /* Number of bytes in pData */
|
||||
char *pData; /* Data for a NEW or OLD pseudo-table */
|
||||
@@ -291,13 +291,16 @@ struct Vdbe {
|
||||
/*
|
||||
** Function prototypes
|
||||
*/
|
||||
void sqliteVdbeCleanupCursor(Cursor*);
|
||||
void sqliteVdbeSorterReset(Vdbe*);
|
||||
void sqliteVdbeAggReset(Agg*);
|
||||
void sqliteVdbeKeylistFree(Keylist*);
|
||||
void sqlite3VdbeCleanupCursor(Cursor*);
|
||||
void sqlite3VdbeSorterReset(Vdbe*);
|
||||
void sqlite3VdbeAggReset(Agg*);
|
||||
void sqlite3VdbeKeylistFree(Keylist*);
|
||||
void sqliteVdbePopStack(Vdbe*,int);
|
||||
int sqliteVdbeCursorMoveto(Cursor*);
|
||||
int sqliteVdbeByteSwap(int);
|
||||
int sqlite3VdbeCursorMoveto(Cursor*);
|
||||
int sqlite3VdbeByteSwap(int);
|
||||
#if !defined(NDEBUG) || defined(VDBE_PROFILE)
|
||||
void sqliteVdbePrintOp(FILE*, int, Op*);
|
||||
void sqlite3VdbePrintOp(FILE*, int, Op*);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
145
src/vdbeaux.c
145
src/vdbeaux.c
@@ -33,7 +33,7 @@ int sqlite_vdbe_addop_trace = 0;
|
||||
/*
|
||||
** Create a new virtual database engine.
|
||||
*/
|
||||
Vdbe *sqliteVdbeCreate(sqlite *db){
|
||||
Vdbe *sqlite3VdbeCreate(sqlite *db){
|
||||
Vdbe *p;
|
||||
p = sqliteMalloc( sizeof(Vdbe) );
|
||||
if( p==0 ) return 0;
|
||||
@@ -51,7 +51,7 @@ Vdbe *sqliteVdbeCreate(sqlite *db){
|
||||
/*
|
||||
** Turn tracing on or off
|
||||
*/
|
||||
void sqliteVdbeTrace(Vdbe *p, FILE *trace){
|
||||
void sqlite3VdbeTrace(Vdbe *p, FILE *trace){
|
||||
p->trace = trace;
|
||||
}
|
||||
|
||||
@@ -67,11 +67,11 @@ void sqliteVdbeTrace(Vdbe *p, FILE *trace){
|
||||
**
|
||||
** p1, p2 First two of the three possible operands.
|
||||
**
|
||||
** Use the sqliteVdbeResolveLabel() function to fix an address and
|
||||
** the sqliteVdbeChangeP3() function to change the value of the P3
|
||||
** Use the sqlite3VdbeResolveLabel() function to fix an address and
|
||||
** the sqlite3VdbeChangeP3() function to change the value of the P3
|
||||
** operand.
|
||||
*/
|
||||
int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
|
||||
int sqlite3VdbeAddOp(Vdbe *p, int op, int p1, int p2){
|
||||
int i;
|
||||
VdbeOp *pOp;
|
||||
|
||||
@@ -100,7 +100,7 @@ int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
|
||||
pOp->p3 = 0;
|
||||
pOp->p3type = P3_NOTUSED;
|
||||
#ifndef NDEBUG
|
||||
if( sqlite_vdbe_addop_trace ) sqliteVdbePrintOp(0, i, &p->aOp[i]);
|
||||
if( sqlite_vdbe_addop_trace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
|
||||
#endif
|
||||
return i;
|
||||
}
|
||||
@@ -108,16 +108,16 @@ int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
|
||||
/*
|
||||
** Add an opcode that includes the p3 value.
|
||||
*/
|
||||
int sqliteVdbeOp3(Vdbe *p, int op, int p1, int p2, const char *zP3, int p3type){
|
||||
int addr = sqliteVdbeAddOp(p, op, p1, p2);
|
||||
sqliteVdbeChangeP3(p, addr, zP3, p3type);
|
||||
int sqlite3VdbeOp3(Vdbe *p, int op, int p1, int p2, const char *zP3, int p3type){
|
||||
int addr = sqlite3VdbeAddOp(p, op, p1, p2);
|
||||
sqlite3VdbeChangeP3(p, addr, zP3, p3type);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/*
|
||||
** Add multiple opcodes. The list is terminated by an opcode of 0.
|
||||
*/
|
||||
int sqliteVdbeCode(Vdbe *p, ...){
|
||||
int sqlite3VdbeCode(Vdbe *p, ...){
|
||||
int addr;
|
||||
va_list ap;
|
||||
int opcode, p1, p2;
|
||||
@@ -126,7 +126,7 @@ int sqliteVdbeCode(Vdbe *p, ...){
|
||||
while( (opcode = va_arg(ap,int))!=0 ){
|
||||
p1 = va_arg(ap,int);
|
||||
p2 = va_arg(ap,int);
|
||||
sqliteVdbeAddOp(p, opcode, p1, p2);
|
||||
sqlite3VdbeAddOp(p, opcode, p1, p2);
|
||||
}
|
||||
va_end(ap);
|
||||
return addr;
|
||||
@@ -146,7 +146,7 @@ int sqliteVdbeCode(Vdbe *p, ...){
|
||||
** always negative and P2 values are suppose to be non-negative.
|
||||
** Hence, a negative P2 value is a label that has yet to be resolved.
|
||||
*/
|
||||
int sqliteVdbeMakeLabel(Vdbe *p){
|
||||
int sqlite3VdbeMakeLabel(Vdbe *p){
|
||||
int i;
|
||||
i = p->nLabel++;
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
@@ -171,9 +171,9 @@ int sqliteVdbeMakeLabel(Vdbe *p){
|
||||
/*
|
||||
** Resolve label "x" to be the address of the next instruction to
|
||||
** be inserted. The parameter "x" must have been obtained from
|
||||
** a prior call to sqliteVdbeMakeLabel().
|
||||
** a prior call to sqlite3VdbeMakeLabel().
|
||||
*/
|
||||
void sqliteVdbeResolveLabel(Vdbe *p, int x){
|
||||
void sqlite3VdbeResolveLabel(Vdbe *p, int x){
|
||||
int j;
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
if( x<0 && (-x)<=p->nLabel && p->aOp ){
|
||||
@@ -189,7 +189,7 @@ void sqliteVdbeResolveLabel(Vdbe *p, int x){
|
||||
/*
|
||||
** Return the address of the next instruction to be inserted.
|
||||
*/
|
||||
int sqliteVdbeCurrentAddr(Vdbe *p){
|
||||
int sqlite3VdbeCurrentAddr(Vdbe *p){
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
return p->nOp;
|
||||
}
|
||||
@@ -198,7 +198,7 @@ int sqliteVdbeCurrentAddr(Vdbe *p){
|
||||
** Add a whole list of operations to the operation stack. Return the
|
||||
** address of the first operation added.
|
||||
*/
|
||||
int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
|
||||
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
|
||||
int addr;
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
if( p->nOp + nOp >= p->nOpAlloc ){
|
||||
@@ -227,7 +227,7 @@ int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
|
||||
pOut->p3type = pIn->p3 ? P3_STATIC : P3_NOTUSED;
|
||||
#ifndef NDEBUG
|
||||
if( sqlite_vdbe_addop_trace ){
|
||||
sqliteVdbePrintOp(0, i+addr, &p->aOp[i+addr]);
|
||||
sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -239,10 +239,10 @@ int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
|
||||
/*
|
||||
** Change the value of the P1 operand for a specific instruction.
|
||||
** This routine is useful when a large program is loaded from a
|
||||
** static array using sqliteVdbeAddOpList but we want to make a
|
||||
** static array using sqlite3VdbeAddOpList but we want to make a
|
||||
** few minor changes to the program.
|
||||
*/
|
||||
void sqliteVdbeChangeP1(Vdbe *p, int addr, int val){
|
||||
void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
if( p && addr>=0 && p->nOp>addr && p->aOp ){
|
||||
p->aOp[addr].p1 = val;
|
||||
@@ -253,7 +253,7 @@ void sqliteVdbeChangeP1(Vdbe *p, int addr, int val){
|
||||
** Change the value of the P2 operand for a specific instruction.
|
||||
** This routine is useful for setting a jump destination.
|
||||
*/
|
||||
void sqliteVdbeChangeP2(Vdbe *p, int addr, int val){
|
||||
void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
|
||||
assert( val>=0 );
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
if( p && addr>=0 && p->nOp>addr && p->aOp ){
|
||||
@@ -264,7 +264,7 @@ void sqliteVdbeChangeP2(Vdbe *p, int addr, int val){
|
||||
/*
|
||||
** Change the value of the P3 operand for a specific instruction.
|
||||
** This routine is useful when a large program is loaded from a
|
||||
** static array using sqliteVdbeAddOpList but we want to make a
|
||||
** static array using sqlite3VdbeAddOpList but we want to make a
|
||||
** few minor changes to the program.
|
||||
**
|
||||
** If n>=0 then the P3 operand is dynamic, meaning that a copy of
|
||||
@@ -278,7 +278,7 @@ void sqliteVdbeChangeP2(Vdbe *p, int addr, int val){
|
||||
**
|
||||
** If addr<0 then change P3 on the most recently inserted instruction.
|
||||
*/
|
||||
void sqliteVdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
|
||||
void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
|
||||
Op *pOp;
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
if( p==0 || p->aOp==0 ) return;
|
||||
@@ -298,7 +298,7 @@ void sqliteVdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
|
||||
pOp->p3 = (char*)zP3;
|
||||
pOp->p3type = n;
|
||||
}else{
|
||||
sqliteSetNString(&pOp->p3, zP3, n, 0);
|
||||
sqlite3SetNString(&pOp->p3, zP3, n, 0);
|
||||
pOp->p3type = P3_DYNAMIC;
|
||||
}
|
||||
}
|
||||
@@ -312,7 +312,7 @@ void sqliteVdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
|
||||
** or a double quote character (ASCII 0x22). Two quotes in a row
|
||||
** resolve to be a single actual quote character within the string.
|
||||
*/
|
||||
void sqliteVdbeDequoteP3(Vdbe *p, int addr){
|
||||
void sqlite3VdbeDequoteP3(Vdbe *p, int addr){
|
||||
Op *pOp;
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
if( p->aOp==0 ) return;
|
||||
@@ -327,7 +327,7 @@ void sqliteVdbeDequoteP3(Vdbe *p, int addr){
|
||||
pOp->p3 = sqliteStrDup(pOp->p3);
|
||||
pOp->p3type = P3_DYNAMIC;
|
||||
}
|
||||
sqliteDequote(pOp->p3);
|
||||
sqlite3Dequote(pOp->p3);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -335,7 +335,7 @@ void sqliteVdbeDequoteP3(Vdbe *p, int addr){
|
||||
** strings of whitespace characters into a single space and
|
||||
** delete leading and trailing whitespace.
|
||||
*/
|
||||
void sqliteVdbeCompressSpace(Vdbe *p, int addr){
|
||||
void sqlite3VdbeCompressSpace(Vdbe *p, int addr){
|
||||
unsigned char *z;
|
||||
int i, j;
|
||||
Op *pOp;
|
||||
@@ -369,7 +369,7 @@ void sqliteVdbeCompressSpace(Vdbe *p, int addr){
|
||||
** Search for the current program for the given opcode and P2
|
||||
** value. Return the address plus 1 if found and 0 if not found.
|
||||
*/
|
||||
int sqliteVdbeFindOp(Vdbe *p, int op, int p2){
|
||||
int sqlite3VdbeFindOp(Vdbe *p, int op, int p2){
|
||||
int i;
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
for(i=0; i<p->nOp; i++){
|
||||
@@ -381,7 +381,7 @@ int sqliteVdbeFindOp(Vdbe *p, int op, int p2){
|
||||
/*
|
||||
** Return the opcode for a given address.
|
||||
*/
|
||||
VdbeOp *sqliteVdbeGetOp(Vdbe *p, int addr){
|
||||
VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
assert( addr>=0 && addr<p->nOp );
|
||||
return &p->aOp[addr];
|
||||
@@ -507,7 +507,7 @@ int sqlite_aggregate_count(sqlite_func *p){
|
||||
/*
|
||||
** Print a single opcode. This routine is used for debugging only.
|
||||
*/
|
||||
void sqliteVdbePrintOp(FILE *pOut, int pc, Op *pOp){
|
||||
void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
|
||||
char *zP3;
|
||||
char zPtr[40];
|
||||
if( pOp->p3type==P3_POINTER ){
|
||||
@@ -518,7 +518,7 @@ void sqliteVdbePrintOp(FILE *pOut, int pc, Op *pOp){
|
||||
}
|
||||
if( pOut==0 ) pOut = stdout;
|
||||
fprintf(pOut,"%4d %-12s %4d %4d %s\n",
|
||||
pc, sqliteOpcodeNames[pOp->opcode], pOp->p1, pOp->p2, zP3 ? zP3 : "");
|
||||
pc, sqlite3OpcodeNames[pOp->opcode], pOp->p1, pOp->p2, zP3 ? zP3 : "");
|
||||
fflush(pOut);
|
||||
}
|
||||
#endif
|
||||
@@ -526,11 +526,11 @@ void sqliteVdbePrintOp(FILE *pOut, int pc, Op *pOp){
|
||||
/*
|
||||
** Give a listing of the program in the virtual machine.
|
||||
**
|
||||
** The interface is the same as sqliteVdbeExec(). But instead of
|
||||
** The interface is the same as sqlite3VdbeExec(). But instead of
|
||||
** running the code, it invokes the callback once for each instruction.
|
||||
** This feature is used to implement "EXPLAIN".
|
||||
*/
|
||||
int sqliteVdbeList(
|
||||
int sqlite3VdbeList(
|
||||
Vdbe *p /* The VDBE */
|
||||
){
|
||||
sqlite *db = p->db;
|
||||
@@ -559,7 +559,7 @@ int sqliteVdbeList(
|
||||
p->rc = SQLITE_INTERRUPT;
|
||||
}
|
||||
rc = SQLITE_ERROR;
|
||||
sqliteSetString(&p->zErrMsg, sqlite_error_string(p->rc), (char*)0);
|
||||
sqlite3SetString(&p->zErrMsg, sqlite_error_string(p->rc), (char*)0);
|
||||
}else{
|
||||
sprintf(p->zArgv[0],"%d",i);
|
||||
sprintf(p->zArgv[2],"%d", p->aOp[i].p1);
|
||||
@@ -570,7 +570,7 @@ int sqliteVdbeList(
|
||||
}else{
|
||||
p->zArgv[4] = p->aOp[i].p3;
|
||||
}
|
||||
p->zArgv[1] = sqliteOpcodeNames[p->aOp[i].opcode];
|
||||
p->zArgv[1] = sqlite3OpcodeNames[p->aOp[i].opcode];
|
||||
p->pc = i+1;
|
||||
p->azResColumn = p->zArgv;
|
||||
p->nResColumn = 5;
|
||||
@@ -584,9 +584,9 @@ int sqliteVdbeList(
|
||||
** Prepare a virtual machine for execution. This involves things such
|
||||
** as allocating stack space and initializing the program counter.
|
||||
** After the VDBE has be prepped, it can be executed by one or more
|
||||
** calls to sqliteVdbeExec().
|
||||
** calls to sqlite3VdbeExec().
|
||||
*/
|
||||
void sqliteVdbeMakeReady(
|
||||
void sqlite3VdbeMakeReady(
|
||||
Vdbe *p, /* The VDBE */
|
||||
int nVar, /* Number of '?' see in the SQL statement */
|
||||
int isExplain /* True if the EXPLAIN keywords is present */
|
||||
@@ -599,7 +599,7 @@ void sqliteVdbeMakeReady(
|
||||
/* Add a HALT instruction to the very end of the program.
|
||||
*/
|
||||
if( p->nOp==0 || (p->aOp && p->aOp[p->nOp-1].opcode!=OP_Halt) ){
|
||||
sqliteVdbeAddOp(p, OP_Halt, 0, 0);
|
||||
sqlite3VdbeAddOp(p, OP_Halt, 0, 0);
|
||||
}
|
||||
|
||||
/* No instruction ever pushes more than a single element onto the
|
||||
@@ -624,10 +624,10 @@ void sqliteVdbeMakeReady(
|
||||
p->abVar = (u8*)&p->anVar[p->nVar];
|
||||
}
|
||||
|
||||
sqliteHashInit(&p->agg.hash, SQLITE_HASH_BINARY, 0);
|
||||
sqlite3HashInit(&p->agg.hash, SQLITE_HASH_BINARY, 0);
|
||||
p->agg.pSearch = 0;
|
||||
#ifdef MEMORY_DEBUG
|
||||
if( sqliteOsFileExists("vdbe_trace") ){
|
||||
if( sqlite3OsFileExists("vdbe_trace") ){
|
||||
p->trace = stdout;
|
||||
}
|
||||
#endif
|
||||
@@ -656,7 +656,7 @@ void sqliteVdbeMakeReady(
|
||||
/*
|
||||
** Remove any elements that remain on the sorter for the VDBE given.
|
||||
*/
|
||||
void sqliteVdbeSorterReset(Vdbe *p){
|
||||
void sqlite3VdbeSorterReset(Vdbe *p){
|
||||
while( p->pSort ){
|
||||
Sorter *pSorter = p->pSort;
|
||||
p->pSort = pSorter->pNext;
|
||||
@@ -675,7 +675,7 @@ void sqliteVdbeSorterReset(Vdbe *p){
|
||||
** private context. If the finalizer has not been called yet, call it
|
||||
** now.
|
||||
*/
|
||||
void sqliteVdbeAggReset(Agg *pAgg){
|
||||
void sqlite3VdbeAggReset(Agg *pAgg){
|
||||
int i;
|
||||
HashElem *p;
|
||||
for(p = sqliteHashFirst(&pAgg->hash); p; p = sqliteHashNext(p)){
|
||||
@@ -704,7 +704,7 @@ void sqliteVdbeAggReset(Agg *pAgg){
|
||||
}
|
||||
sqliteFree(pElem);
|
||||
}
|
||||
sqliteHashClear(&pAgg->hash);
|
||||
sqlite3HashClear(&pAgg->hash);
|
||||
sqliteFree(pAgg->apFunc);
|
||||
pAgg->apFunc = 0;
|
||||
pAgg->pCurrent = 0;
|
||||
@@ -715,7 +715,7 @@ void sqliteVdbeAggReset(Agg *pAgg){
|
||||
/*
|
||||
** Delete a keylist
|
||||
*/
|
||||
void sqliteVdbeKeylistFree(Keylist *p){
|
||||
void sqlite3VdbeKeylistFree(Keylist *p){
|
||||
while( p ){
|
||||
Keylist *pNext = p->pNext;
|
||||
sqliteFree(p);
|
||||
@@ -727,12 +727,12 @@ void sqliteVdbeKeylistFree(Keylist *p){
|
||||
** Close a cursor and release all the resources that cursor happens
|
||||
** to hold.
|
||||
*/
|
||||
void sqliteVdbeCleanupCursor(Cursor *pCx){
|
||||
void sqlite3VdbeCleanupCursor(Cursor *pCx){
|
||||
if( pCx->pCursor ){
|
||||
sqliteBtreeCloseCursor(pCx->pCursor);
|
||||
sqlite3BtreeCloseCursor(pCx->pCursor);
|
||||
}
|
||||
if( pCx->pBt ){
|
||||
sqliteBtreeClose(pCx->pBt);
|
||||
sqlite3BtreeClose(pCx->pBt);
|
||||
}
|
||||
sqliteFree(pCx->pData);
|
||||
memset(pCx, 0, sizeof(Cursor));
|
||||
@@ -744,7 +744,7 @@ void sqliteVdbeCleanupCursor(Cursor *pCx){
|
||||
static void closeAllCursors(Vdbe *p){
|
||||
int i;
|
||||
for(i=0; i<p->nCursor; i++){
|
||||
sqliteVdbeCleanupCursor(&p->aCsr[i]);
|
||||
sqlite3VdbeCleanupCursor(&p->aCsr[i]);
|
||||
}
|
||||
sqliteFree(p->aCsr);
|
||||
p->aCsr = 0;
|
||||
@@ -782,10 +782,10 @@ static void Cleanup(Vdbe *p){
|
||||
p->aMem = 0;
|
||||
p->nMem = 0;
|
||||
if( p->pList ){
|
||||
sqliteVdbeKeylistFree(p->pList);
|
||||
sqlite3VdbeKeylistFree(p->pList);
|
||||
p->pList = 0;
|
||||
}
|
||||
sqliteVdbeSorterReset(p);
|
||||
sqlite3VdbeSorterReset(p);
|
||||
if( p->pFile ){
|
||||
if( p->pFile!=stdin ) fclose(p->pFile);
|
||||
p->pFile = 0;
|
||||
@@ -800,10 +800,10 @@ static void Cleanup(Vdbe *p){
|
||||
p->zLine = 0;
|
||||
}
|
||||
p->nLineAlloc = 0;
|
||||
sqliteVdbeAggReset(&p->agg);
|
||||
sqlite3VdbeAggReset(&p->agg);
|
||||
if( p->aSet ){
|
||||
for(i=0; i<p->nSet; i++){
|
||||
sqliteHashClear(&p->aSet[i].hash);
|
||||
sqlite3HashClear(&p->aSet[i].hash);
|
||||
}
|
||||
}
|
||||
sqliteFree(p->aSet);
|
||||
@@ -812,7 +812,7 @@ static void Cleanup(Vdbe *p){
|
||||
if( p->keylistStack ){
|
||||
int ii;
|
||||
for(ii = 0; ii < p->keylistStackDepth; ii++){
|
||||
sqliteVdbeKeylistFree(p->keylistStack[ii]);
|
||||
sqlite3VdbeKeylistFree(p->keylistStack[ii]);
|
||||
}
|
||||
sqliteFree(p->keylistStack);
|
||||
p->keylistStackDepth = 0;
|
||||
@@ -831,12 +831,12 @@ static void Cleanup(Vdbe *p){
|
||||
** After this routine is run, the VDBE should be ready to be executed
|
||||
** again.
|
||||
*/
|
||||
int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){
|
||||
int sqlite3VdbeReset(Vdbe *p, char **pzErrMsg){
|
||||
sqlite *db = p->db;
|
||||
int i;
|
||||
|
||||
if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
|
||||
sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0);
|
||||
sqlite3SetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0);
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
if( p->zErrMsg ){
|
||||
@@ -847,7 +847,7 @@ int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){
|
||||
}
|
||||
p->zErrMsg = 0;
|
||||
}else if( p->rc ){
|
||||
sqliteSetString(pzErrMsg, sqlite_error_string(p->rc), (char*)0);
|
||||
sqlite3SetString(pzErrMsg, sqlite_error_string(p->rc), (char*)0);
|
||||
}
|
||||
Cleanup(p);
|
||||
if( p->rc!=SQLITE_OK ){
|
||||
@@ -856,7 +856,7 @@ int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){
|
||||
if( !p->undoTransOnError ){
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( db->aDb[i].pBt ){
|
||||
sqliteBtreeRollbackCkpt(db->aDb[i].pBt);
|
||||
sqlite3BtreeRollbackStmt(db->aDb[i].pBt);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -864,25 +864,25 @@ int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){
|
||||
/* Fall through to ROLLBACK */
|
||||
}
|
||||
case OE_Rollback: {
|
||||
sqliteRollbackAll(db);
|
||||
sqlite3RollbackAll(db);
|
||||
db->flags &= ~SQLITE_InTrans;
|
||||
db->onError = OE_Default;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if( p->undoTransOnError ){
|
||||
sqliteRollbackAll(db);
|
||||
sqlite3RollbackAll(db);
|
||||
db->flags &= ~SQLITE_InTrans;
|
||||
db->onError = OE_Default;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
sqliteRollbackInternalChanges(db);
|
||||
sqlite3RollbackInternalChanges(db);
|
||||
}
|
||||
for(i=0; i<db->nDb; i++){
|
||||
if( db->aDb[i].pBt && db->aDb[i].inTrans==2 ){
|
||||
sqliteBtreeCommitCkpt(db->aDb[i].pBt);
|
||||
sqlite3BtreeCommitStmt(db->aDb[i].pBt);
|
||||
db->aDb[i].inTrans = 1;
|
||||
}
|
||||
}
|
||||
@@ -903,7 +903,7 @@ int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){
|
||||
p->aOp[i].cycles,
|
||||
p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
|
||||
);
|
||||
sqliteVdbePrintOp(out, i, &p->aOp[i]);
|
||||
sqlite3VdbePrintOp(out, i, &p->aOp[i]);
|
||||
}
|
||||
fclose(out);
|
||||
}
|
||||
@@ -917,22 +917,22 @@ int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){
|
||||
** Clean up and delete a VDBE after execution. Return an integer which is
|
||||
** the result code. Write any error message text into *pzErrMsg.
|
||||
*/
|
||||
int sqliteVdbeFinalize(Vdbe *p, char **pzErrMsg){
|
||||
int sqlite3VdbeFinalize(Vdbe *p, char **pzErrMsg){
|
||||
int rc;
|
||||
sqlite *db;
|
||||
|
||||
if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
|
||||
sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0);
|
||||
sqlite3SetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0);
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
db = p->db;
|
||||
rc = sqliteVdbeReset(p, pzErrMsg);
|
||||
sqliteVdbeDelete(p);
|
||||
rc = sqlite3VdbeReset(p, pzErrMsg);
|
||||
sqlite3VdbeDelete(p);
|
||||
if( db->want_to_close && db->pVdbe==0 ){
|
||||
sqlite_close(db);
|
||||
}
|
||||
if( rc==SQLITE_SCHEMA ){
|
||||
sqliteResetInternalSchema(db, 0);
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -979,7 +979,7 @@ int sqlite_bind(sqlite_vm *pVm, int i, const char *zVal, int len, int copy){
|
||||
/*
|
||||
** Delete an entire VDBE.
|
||||
*/
|
||||
void sqliteVdbeDelete(Vdbe *p){
|
||||
void sqlite3VdbeDelete(Vdbe *p){
|
||||
int i;
|
||||
if( p==0 ) return;
|
||||
Cleanup(p);
|
||||
@@ -1027,7 +1027,7 @@ void sqliteVdbeDelete(Vdbe *p){
|
||||
**
|
||||
** X == byteSwap(byteSwap(X))
|
||||
*/
|
||||
int sqliteVdbeByteSwap(int x){
|
||||
int sqlite3VdbeByteSwap(int x){
|
||||
union {
|
||||
char zBuf[sizeof(int)];
|
||||
int i;
|
||||
@@ -1044,18 +1044,21 @@ int sqliteVdbeByteSwap(int x){
|
||||
** MoveTo now. Return an error code. If no MoveTo is pending, this
|
||||
** routine does nothing and returns SQLITE_OK.
|
||||
*/
|
||||
int sqliteVdbeCursorMoveto(Cursor *p){
|
||||
int sqlite3VdbeCursorMoveto(Cursor *p){
|
||||
if( p->deferredMoveto ){
|
||||
int res;
|
||||
extern int sqlite_search_count;
|
||||
sqliteBtreeMoveto(p->pCursor, (char*)&p->movetoTarget, sizeof(int), &res);
|
||||
sqlite3BtreeMoveto(p->pCursor, (char*)&p->movetoTarget, sizeof(int), &res);
|
||||
p->lastRecno = keyToInt(p->movetoTarget);
|
||||
p->recnoIsValid = res==0;
|
||||
if( res<0 ){
|
||||
sqliteBtreeNext(p->pCursor, &res);
|
||||
sqlite3BtreeNext(p->pCursor, &res);
|
||||
}
|
||||
sqlite_search_count++;
|
||||
p->deferredMoveto = 0;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
271
src/where.c
271
src/where.c
@@ -12,7 +12,7 @@
|
||||
** This module contains C code that generates VDBE code used to process
|
||||
** the WHERE clause of SQL statements.
|
||||
**
|
||||
** $Id: where.c,v 1.89 2004/02/22 20:05:02 drh Exp $
|
||||
** $Id: where.c,v 1.90 2004/05/08 08:23:47 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -113,9 +113,9 @@ static int getMask(ExprMaskSet *pMaskSet, int iCursor){
|
||||
** tree.
|
||||
**
|
||||
** In order for this routine to work, the calling function must have
|
||||
** previously invoked sqliteExprResolveIds() on the expression. See
|
||||
** previously invoked sqlite3ExprResolveIds() on the expression. See
|
||||
** the header comment on that routine for additional information.
|
||||
** The sqliteExprResolveIds() routines looks for column names and
|
||||
** The sqlite3ExprResolveIds() routines looks for column names and
|
||||
** sets their opcodes to TK_COLUMN and their Expr.iTable fields to
|
||||
** the VDBE cursor number of the table.
|
||||
*/
|
||||
@@ -273,7 +273,7 @@ static Index *findSortingIndex(
|
||||
** Generate the beginning of the loop used for WHERE clause processing.
|
||||
** The return value is a pointer to an (opaque) structure that contains
|
||||
** information needed to terminate the loop. Later, the calling routine
|
||||
** should invoke sqliteWhereEnd() with the return value of this function
|
||||
** should invoke sqlite3WhereEnd() with the return value of this function
|
||||
** in order to complete the WHERE clause processing.
|
||||
**
|
||||
** If an error occurs, this routine returns NULL.
|
||||
@@ -288,17 +288,17 @@ static Index *findSortingIndex(
|
||||
** Then the code generated is conceptually like the following:
|
||||
**
|
||||
** foreach row1 in t1 do \ Code generated
|
||||
** foreach row2 in t2 do |-- by sqliteWhereBegin()
|
||||
** foreach row2 in t2 do |-- by sqlite3WhereBegin()
|
||||
** foreach row3 in t3 do /
|
||||
** ...
|
||||
** end \ Code generated
|
||||
** end |-- by sqliteWhereEnd()
|
||||
** end |-- by sqlite3WhereEnd()
|
||||
** end /
|
||||
**
|
||||
** There are Btree cursors associated with each table. t1 uses cursor
|
||||
** number pTabList->a[0].iCursor. t2 uses the cursor pTabList->a[1].iCursor.
|
||||
** And so forth. This routine generates code to open those VDBE cursors
|
||||
** and sqliteWhereEnd() generates the code to close them.
|
||||
** and sqlite3WhereEnd() generates the code to close them.
|
||||
**
|
||||
** If the WHERE clause is empty, the foreach loops must each scan their
|
||||
** entire tables. Thus a three-way join is an O(N^3) operation. But if
|
||||
@@ -346,7 +346,7 @@ static Index *findSortingIndex(
|
||||
** If the where clause loops cannot be arranged to provide the correct
|
||||
** output order, then the *ppOrderBy is unchanged.
|
||||
*/
|
||||
WhereInfo *sqliteWhereBegin(
|
||||
WhereInfo *sqlite3WhereBegin(
|
||||
Parse *pParse, /* The parser context */
|
||||
SrcList *pTabList, /* A list of all tables to be scanned */
|
||||
Expr *pWhere, /* The WHERE clause */
|
||||
@@ -380,7 +380,7 @@ WhereInfo *sqliteWhereBegin(
|
||||
memset(aExpr, 0, sizeof(aExpr));
|
||||
nExpr = exprSplit(ARRAYSIZE(aExpr), aExpr, pWhere);
|
||||
if( nExpr==ARRAYSIZE(aExpr) ){
|
||||
sqliteErrorMsg(pParse, "WHERE clause too complex - no more "
|
||||
sqlite3ErrorMsg(pParse, "WHERE clause too complex - no more "
|
||||
"than %d terms allowed", (int)ARRAYSIZE(aExpr)-1);
|
||||
return 0;
|
||||
}
|
||||
@@ -396,13 +396,13 @@ WhereInfo *sqliteWhereBegin(
|
||||
pWInfo->pParse = pParse;
|
||||
pWInfo->pTabList = pTabList;
|
||||
pWInfo->peakNTab = pWInfo->savedNTab = pParse->nTab;
|
||||
pWInfo->iBreak = sqliteVdbeMakeLabel(v);
|
||||
pWInfo->iBreak = sqlite3VdbeMakeLabel(v);
|
||||
|
||||
/* Special case: a WHERE clause that is constant. Evaluate the
|
||||
** expression and either jump over all of the code or fall thru.
|
||||
*/
|
||||
if( pWhere && (pTabList->nSrc==0 || sqliteExprIsConstant(pWhere)) ){
|
||||
sqliteExprIfFalse(pParse, pWhere, pWInfo->iBreak, 1);
|
||||
if( pWhere && (pTabList->nSrc==0 || sqlite3ExprIsConstant(pWhere)) ){
|
||||
sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, 1);
|
||||
pWhere = 0;
|
||||
}
|
||||
|
||||
@@ -673,13 +673,13 @@ WhereInfo *sqliteWhereBegin(
|
||||
|
||||
pTab = pTabList->a[i].pTab;
|
||||
if( pTab->isTransient || pTab->pSelect ) continue;
|
||||
sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqliteVdbeOp3(v, OP_OpenRead, pTabList->a[i].iCursor, pTab->tnum,
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
|
||||
sqlite3VdbeOp3(v, OP_OpenRead, pTabList->a[i].iCursor, pTab->tnum,
|
||||
pTab->zName, P3_STATIC);
|
||||
sqliteCodeVerifySchema(pParse, pTab->iDb);
|
||||
sqlite3CodeVerifySchema(pParse, pTab->iDb);
|
||||
if( (pIx = pWInfo->a[i].pIdx)!=0 ){
|
||||
sqliteVdbeAddOp(v, OP_Integer, pIx->iDb, 0);
|
||||
sqliteVdbeOp3(v, OP_OpenRead, pWInfo->a[i].iCur, pIx->tnum, pIx->zName,0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, pIx->iDb, 0);
|
||||
sqlite3VdbeOp3(v, OP_OpenRead, pWInfo->a[i].iCur, pIx->tnum, pIx->zName,0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -699,8 +699,8 @@ WhereInfo *sqliteWhereBegin(
|
||||
if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){
|
||||
if( !pParse->nMem ) pParse->nMem++;
|
||||
pLevel->iLeftJoin = pParse->nMem++;
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
|
||||
sqlite3VdbeAddOp(v, OP_String, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
|
||||
}
|
||||
|
||||
pIdx = pLevel->pIdx;
|
||||
@@ -715,32 +715,32 @@ WhereInfo *sqliteWhereBegin(
|
||||
assert( k<nExpr );
|
||||
assert( aExpr[k].p!=0 );
|
||||
assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur );
|
||||
brk = pLevel->brk = sqliteVdbeMakeLabel(v);
|
||||
brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
|
||||
if( aExpr[k].idxLeft==iCur ){
|
||||
Expr *pX = aExpr[k].p;
|
||||
if( pX->op!=TK_IN ){
|
||||
sqliteExprCode(pParse, aExpr[k].p->pRight);
|
||||
sqlite3ExprCode(pParse, aExpr[k].p->pRight);
|
||||
}else if( pX->pList ){
|
||||
sqliteVdbeAddOp(v, OP_SetFirst, pX->iTable, brk);
|
||||
sqlite3VdbeAddOp(v, OP_SetFirst, pX->iTable, brk);
|
||||
pLevel->inOp = OP_SetNext;
|
||||
pLevel->inP1 = pX->iTable;
|
||||
pLevel->inP2 = sqliteVdbeCurrentAddr(v);
|
||||
pLevel->inP2 = sqlite3VdbeCurrentAddr(v);
|
||||
}else{
|
||||
assert( pX->pSelect );
|
||||
sqliteVdbeAddOp(v, OP_Rewind, pX->iTable, brk);
|
||||
sqliteVdbeAddOp(v, OP_KeyAsData, pX->iTable, 1);
|
||||
pLevel->inP2 = sqliteVdbeAddOp(v, OP_FullKey, pX->iTable, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Rewind, pX->iTable, brk);
|
||||
sqlite3VdbeAddOp(v, OP_KeyAsData, pX->iTable, 1);
|
||||
pLevel->inP2 = sqlite3VdbeAddOp(v, OP_FullKey, pX->iTable, 0);
|
||||
pLevel->inOp = OP_Next;
|
||||
pLevel->inP1 = pX->iTable;
|
||||
}
|
||||
}else{
|
||||
sqliteExprCode(pParse, aExpr[k].p->pLeft);
|
||||
sqlite3ExprCode(pParse, aExpr[k].p->pLeft);
|
||||
}
|
||||
aExpr[k].p = 0;
|
||||
cont = pLevel->cont = sqliteVdbeMakeLabel(v);
|
||||
sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk);
|
||||
cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 1, brk);
|
||||
haveKey = 0;
|
||||
sqliteVdbeAddOp(v, OP_NotExists, iCur, brk);
|
||||
sqlite3VdbeAddOp(v, OP_NotExists, iCur, brk);
|
||||
pLevel->op = OP_Noop;
|
||||
}else if( pIdx!=0 && pLevel->score>0 && pLevel->score%4==0 ){
|
||||
/* Case 2: There is an index and all terms of the WHERE clause that
|
||||
@@ -749,7 +749,7 @@ WhereInfo *sqliteWhereBegin(
|
||||
int start;
|
||||
int testOp;
|
||||
int nColumn = (pLevel->score+4)/8;
|
||||
brk = pLevel->brk = sqliteVdbeMakeLabel(v);
|
||||
brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
|
||||
for(j=0; j<nColumn; j++){
|
||||
for(k=0; k<nExpr; k++){
|
||||
Expr *pX = aExpr[k].p;
|
||||
@@ -759,21 +759,21 @@ WhereInfo *sqliteWhereBegin(
|
||||
&& pX->pLeft->iColumn==pIdx->aiColumn[j]
|
||||
){
|
||||
if( pX->op==TK_EQ ){
|
||||
sqliteExprCode(pParse, pX->pRight);
|
||||
sqlite3ExprCode(pParse, pX->pRight);
|
||||
aExpr[k].p = 0;
|
||||
break;
|
||||
}
|
||||
if( pX->op==TK_IN && nColumn==1 ){
|
||||
if( pX->pList ){
|
||||
sqliteVdbeAddOp(v, OP_SetFirst, pX->iTable, brk);
|
||||
sqlite3VdbeAddOp(v, OP_SetFirst, pX->iTable, brk);
|
||||
pLevel->inOp = OP_SetNext;
|
||||
pLevel->inP1 = pX->iTable;
|
||||
pLevel->inP2 = sqliteVdbeCurrentAddr(v);
|
||||
pLevel->inP2 = sqlite3VdbeCurrentAddr(v);
|
||||
}else{
|
||||
assert( pX->pSelect );
|
||||
sqliteVdbeAddOp(v, OP_Rewind, pX->iTable, brk);
|
||||
sqliteVdbeAddOp(v, OP_KeyAsData, pX->iTable, 1);
|
||||
pLevel->inP2 = sqliteVdbeAddOp(v, OP_FullKey, pX->iTable, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Rewind, pX->iTable, brk);
|
||||
sqlite3VdbeAddOp(v, OP_KeyAsData, pX->iTable, 1);
|
||||
pLevel->inP2 = sqlite3VdbeAddOp(v, OP_FullKey, pX->iTable, 0);
|
||||
pLevel->inOp = OP_Next;
|
||||
pLevel->inP1 = pX->iTable;
|
||||
}
|
||||
@@ -786,49 +786,49 @@ WhereInfo *sqliteWhereBegin(
|
||||
&& (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
|
||||
&& aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
|
||||
){
|
||||
sqliteExprCode(pParse, aExpr[k].p->pLeft);
|
||||
sqlite3ExprCode(pParse, aExpr[k].p->pLeft);
|
||||
aExpr[k].p = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pLevel->iMem = pParse->nMem++;
|
||||
cont = pLevel->cont = sqliteVdbeMakeLabel(v);
|
||||
sqliteVdbeAddOp(v, OP_NotNull, -nColumn, sqliteVdbeCurrentAddr(v)+3);
|
||||
sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, brk);
|
||||
sqliteVdbeAddOp(v, OP_MakeKey, nColumn, 0);
|
||||
sqliteAddIdxKeyType(v, pIdx);
|
||||
cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
|
||||
sqlite3VdbeAddOp(v, OP_MakeKey, nColumn, 0);
|
||||
sqlite3AddIdxKeyType(v, pIdx);
|
||||
if( nColumn==pIdx->nColumn || pLevel->bRev ){
|
||||
sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
|
||||
testOp = OP_IdxGT;
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_IncrKey, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
||||
testOp = OP_IdxGE;
|
||||
}
|
||||
if( pLevel->bRev ){
|
||||
/* Scan in reverse order */
|
||||
sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
|
||||
start = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
||||
sqliteVdbeAddOp(v, OP_IdxLT, pLevel->iCur, brk);
|
||||
sqlite3VdbeAddOp(v, OP_IncrKey, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
|
||||
start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
||||
sqlite3VdbeAddOp(v, OP_IdxLT, pLevel->iCur, brk);
|
||||
pLevel->op = OP_Prev;
|
||||
}else{
|
||||
/* Scan in the forward order */
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk);
|
||||
start = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
||||
sqliteVdbeAddOp(v, testOp, pLevel->iCur, brk);
|
||||
sqlite3VdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk);
|
||||
start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
||||
sqlite3VdbeAddOp(v, testOp, pLevel->iCur, brk);
|
||||
pLevel->op = OP_Next;
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
|
||||
sqliteVdbeAddOp(v, OP_IdxIsNull, nColumn, cont);
|
||||
sqliteVdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_IdxIsNull, nColumn, cont);
|
||||
sqlite3VdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
|
||||
if( i==pTabList->nSrc-1 && pushKey ){
|
||||
haveKey = 1;
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0);
|
||||
haveKey = 0;
|
||||
}
|
||||
pLevel->p1 = pLevel->iCur;
|
||||
@@ -839,24 +839,24 @@ WhereInfo *sqliteWhereBegin(
|
||||
int testOp = OP_Noop;
|
||||
int start;
|
||||
|
||||
brk = pLevel->brk = sqliteVdbeMakeLabel(v);
|
||||
cont = pLevel->cont = sqliteVdbeMakeLabel(v);
|
||||
brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
|
||||
cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
|
||||
if( iDirectGt[i]>=0 ){
|
||||
k = iDirectGt[i];
|
||||
assert( k<nExpr );
|
||||
assert( aExpr[k].p!=0 );
|
||||
assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur );
|
||||
if( aExpr[k].idxLeft==iCur ){
|
||||
sqliteExprCode(pParse, aExpr[k].p->pRight);
|
||||
sqlite3ExprCode(pParse, aExpr[k].p->pRight);
|
||||
}else{
|
||||
sqliteExprCode(pParse, aExpr[k].p->pLeft);
|
||||
sqlite3ExprCode(pParse, aExpr[k].p->pLeft);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_ForceInt,
|
||||
sqlite3VdbeAddOp(v, OP_ForceInt,
|
||||
aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT, brk);
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk);
|
||||
sqlite3VdbeAddOp(v, OP_MoveTo, iCur, brk);
|
||||
aExpr[k].p = 0;
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_Rewind, iCur, brk);
|
||||
sqlite3VdbeAddOp(v, OP_Rewind, iCur, brk);
|
||||
}
|
||||
if( iDirectLt[i]>=0 ){
|
||||
k = iDirectLt[i];
|
||||
@@ -864,13 +864,13 @@ WhereInfo *sqliteWhereBegin(
|
||||
assert( aExpr[k].p!=0 );
|
||||
assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur );
|
||||
if( aExpr[k].idxLeft==iCur ){
|
||||
sqliteExprCode(pParse, aExpr[k].p->pRight);
|
||||
sqlite3ExprCode(pParse, aExpr[k].p->pRight);
|
||||
}else{
|
||||
sqliteExprCode(pParse, aExpr[k].p->pLeft);
|
||||
sqlite3ExprCode(pParse, aExpr[k].p->pLeft);
|
||||
}
|
||||
/* sqliteVdbeAddOp(v, OP_MustBeInt, 0, sqliteVdbeCurrentAddr(v)+1); */
|
||||
/* sqlite3VdbeAddOp(v, OP_MustBeInt, 0, sqlite3VdbeCurrentAddr(v)+1); */
|
||||
pLevel->iMem = pParse->nMem++;
|
||||
sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
||||
if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ){
|
||||
testOp = OP_Ge;
|
||||
}else{
|
||||
@@ -878,14 +878,14 @@ WhereInfo *sqliteWhereBegin(
|
||||
}
|
||||
aExpr[k].p = 0;
|
||||
}
|
||||
start = sqliteVdbeCurrentAddr(v);
|
||||
start = sqlite3VdbeCurrentAddr(v);
|
||||
pLevel->op = OP_Next;
|
||||
pLevel->p1 = iCur;
|
||||
pLevel->p2 = start;
|
||||
if( testOp!=OP_Noop ){
|
||||
sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
|
||||
sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
||||
sqliteVdbeAddOp(v, testOp, 0, brk);
|
||||
sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
||||
sqlite3VdbeAddOp(v, testOp, 0, brk);
|
||||
}
|
||||
haveKey = 0;
|
||||
}else if( pIdx==0 ){
|
||||
@@ -894,10 +894,10 @@ WhereInfo *sqliteWhereBegin(
|
||||
*/
|
||||
int start;
|
||||
|
||||
brk = pLevel->brk = sqliteVdbeMakeLabel(v);
|
||||
cont = pLevel->cont = sqliteVdbeMakeLabel(v);
|
||||
sqliteVdbeAddOp(v, OP_Rewind, iCur, brk);
|
||||
start = sqliteVdbeCurrentAddr(v);
|
||||
brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
|
||||
cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3VdbeAddOp(v, OP_Rewind, iCur, brk);
|
||||
start = sqlite3VdbeCurrentAddr(v);
|
||||
pLevel->op = OP_Next;
|
||||
pLevel->p1 = iCur;
|
||||
pLevel->p2 = start;
|
||||
@@ -930,7 +930,7 @@ WhereInfo *sqliteWhereBegin(
|
||||
&& (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight
|
||||
&& aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j]
|
||||
){
|
||||
sqliteExprCode(pParse, aExpr[k].p->pRight);
|
||||
sqlite3ExprCode(pParse, aExpr[k].p->pRight);
|
||||
aExpr[k].p = 0;
|
||||
break;
|
||||
}
|
||||
@@ -939,7 +939,7 @@ WhereInfo *sqliteWhereBegin(
|
||||
&& (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
|
||||
&& aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
|
||||
){
|
||||
sqliteExprCode(pParse, aExpr[k].p->pLeft);
|
||||
sqlite3ExprCode(pParse, aExpr[k].p->pLeft);
|
||||
aExpr[k].p = 0;
|
||||
break;
|
||||
}
|
||||
@@ -951,13 +951,13 @@ WhereInfo *sqliteWhereBegin(
|
||||
** start key.
|
||||
*/
|
||||
for(j=0; j<nEqColumn; j++){
|
||||
sqliteVdbeAddOp(v, OP_Dup, nEqColumn-1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nEqColumn-1, 0);
|
||||
}
|
||||
|
||||
/* Labels for the beginning and end of the loop
|
||||
*/
|
||||
cont = pLevel->cont = sqliteVdbeMakeLabel(v);
|
||||
brk = pLevel->brk = sqliteVdbeMakeLabel(v);
|
||||
cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
|
||||
brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
|
||||
|
||||
/* Generate the termination key. This is the key value that
|
||||
** will end the search. There is no termination key if there
|
||||
@@ -975,7 +975,7 @@ WhereInfo *sqliteWhereBegin(
|
||||
&& (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight
|
||||
&& pExpr->pLeft->iColumn==pIdx->aiColumn[j]
|
||||
){
|
||||
sqliteExprCode(pParse, pExpr->pRight);
|
||||
sqlite3ExprCode(pParse, pExpr->pRight);
|
||||
leFlag = pExpr->op==TK_LE;
|
||||
aExpr[k].p = 0;
|
||||
break;
|
||||
@@ -985,7 +985,7 @@ WhereInfo *sqliteWhereBegin(
|
||||
&& (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
|
||||
&& pExpr->pRight->iColumn==pIdx->aiColumn[j]
|
||||
){
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
sqlite3ExprCode(pParse, pExpr->pLeft);
|
||||
leFlag = pExpr->op==TK_GE;
|
||||
aExpr[k].p = 0;
|
||||
break;
|
||||
@@ -999,21 +999,21 @@ WhereInfo *sqliteWhereBegin(
|
||||
if( testOp!=OP_Noop ){
|
||||
int nCol = nEqColumn + (score & 1);
|
||||
pLevel->iMem = pParse->nMem++;
|
||||
sqliteVdbeAddOp(v, OP_NotNull, -nCol, sqliteVdbeCurrentAddr(v)+3);
|
||||
sqliteVdbeAddOp(v, OP_Pop, nCol, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, brk);
|
||||
sqliteVdbeAddOp(v, OP_MakeKey, nCol, 0);
|
||||
sqliteAddIdxKeyType(v, pIdx);
|
||||
sqlite3VdbeAddOp(v, OP_NotNull, -nCol, sqlite3VdbeCurrentAddr(v)+3);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nCol, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
|
||||
sqlite3VdbeAddOp(v, OP_MakeKey, nCol, 0);
|
||||
sqlite3AddIdxKeyType(v, pIdx);
|
||||
if( leFlag ){
|
||||
sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_IncrKey, 0, 0);
|
||||
}
|
||||
if( pLevel->bRev ){
|
||||
sqliteVdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
|
||||
sqlite3VdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
||||
}
|
||||
}else if( pLevel->bRev ){
|
||||
sqliteVdbeAddOp(v, OP_Last, pLevel->iCur, brk);
|
||||
sqlite3VdbeAddOp(v, OP_Last, pLevel->iCur, brk);
|
||||
}
|
||||
|
||||
/* Generate the start key. This is the key that defines the lower
|
||||
@@ -1034,7 +1034,7 @@ WhereInfo *sqliteWhereBegin(
|
||||
&& (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight
|
||||
&& pExpr->pLeft->iColumn==pIdx->aiColumn[j]
|
||||
){
|
||||
sqliteExprCode(pParse, pExpr->pRight);
|
||||
sqlite3ExprCode(pParse, pExpr->pRight);
|
||||
geFlag = pExpr->op==TK_GE;
|
||||
aExpr[k].p = 0;
|
||||
break;
|
||||
@@ -1044,7 +1044,7 @@ WhereInfo *sqliteWhereBegin(
|
||||
&& (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
|
||||
&& pExpr->pRight->iColumn==pIdx->aiColumn[j]
|
||||
){
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
sqlite3ExprCode(pParse, pExpr->pLeft);
|
||||
geFlag = pExpr->op==TK_LE;
|
||||
aExpr[k].p = 0;
|
||||
break;
|
||||
@@ -1055,43 +1055,43 @@ WhereInfo *sqliteWhereBegin(
|
||||
}
|
||||
if( nEqColumn>0 || (score&2)!=0 ){
|
||||
int nCol = nEqColumn + ((score&2)!=0);
|
||||
sqliteVdbeAddOp(v, OP_NotNull, -nCol, sqliteVdbeCurrentAddr(v)+3);
|
||||
sqliteVdbeAddOp(v, OP_Pop, nCol, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, brk);
|
||||
sqliteVdbeAddOp(v, OP_MakeKey, nCol, 0);
|
||||
sqliteAddIdxKeyType(v, pIdx);
|
||||
sqlite3VdbeAddOp(v, OP_NotNull, -nCol, sqlite3VdbeCurrentAddr(v)+3);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nCol, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
|
||||
sqlite3VdbeAddOp(v, OP_MakeKey, nCol, 0);
|
||||
sqlite3AddIdxKeyType(v, pIdx);
|
||||
if( !geFlag ){
|
||||
sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_IncrKey, 0, 0);
|
||||
}
|
||||
if( pLevel->bRev ){
|
||||
pLevel->iMem = pParse->nMem++;
|
||||
sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
|
||||
testOp = OP_IdxLT;
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk);
|
||||
sqlite3VdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk);
|
||||
}
|
||||
}else if( pLevel->bRev ){
|
||||
testOp = OP_Noop;
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_Rewind, pLevel->iCur, brk);
|
||||
sqlite3VdbeAddOp(v, OP_Rewind, pLevel->iCur, brk);
|
||||
}
|
||||
|
||||
/* Generate the the top of the loop. If there is a termination
|
||||
** key we have to test for that key and abort at the top of the
|
||||
** loop.
|
||||
*/
|
||||
start = sqliteVdbeCurrentAddr(v);
|
||||
start = sqlite3VdbeCurrentAddr(v);
|
||||
if( testOp!=OP_Noop ){
|
||||
sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
||||
sqliteVdbeAddOp(v, testOp, pLevel->iCur, brk);
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
|
||||
sqlite3VdbeAddOp(v, testOp, pLevel->iCur, brk);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
|
||||
sqliteVdbeAddOp(v, OP_IdxIsNull, nEqColumn + (score & 1), cont);
|
||||
sqliteVdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_IdxIsNull, nEqColumn + (score & 1), cont);
|
||||
sqlite3VdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
|
||||
if( i==pTabList->nSrc-1 && pushKey ){
|
||||
haveKey = 1;
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0);
|
||||
haveKey = 0;
|
||||
}
|
||||
|
||||
@@ -1114,9 +1114,9 @@ WhereInfo *sqliteWhereBegin(
|
||||
}
|
||||
if( haveKey ){
|
||||
haveKey = 0;
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0);
|
||||
}
|
||||
sqliteExprIfFalse(pParse, aExpr[j].p, cont, 1);
|
||||
sqlite3ExprIfFalse(pParse, aExpr[j].p, cont, 1);
|
||||
aExpr[j].p = 0;
|
||||
}
|
||||
brk = cont;
|
||||
@@ -1125,9 +1125,9 @@ WhereInfo *sqliteWhereBegin(
|
||||
** at least one row of the right table has matched the left table.
|
||||
*/
|
||||
if( pLevel->iLeftJoin ){
|
||||
pLevel->top = sqliteVdbeCurrentAddr(v);
|
||||
sqliteVdbeAddOp(v, OP_Integer, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
|
||||
pLevel->top = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
|
||||
for(j=0; j<nExpr; j++){
|
||||
if( aExpr[j].p==0 ) continue;
|
||||
if( (aExpr[j].prereqAll & loopMask)!=aExpr[j].prereqAll ) continue;
|
||||
@@ -1137,16 +1137,16 @@ WhereInfo *sqliteWhereBegin(
|
||||
** no outer joins with DELETE and UPDATE.
|
||||
*/
|
||||
haveKey = 0;
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0);
|
||||
}
|
||||
sqliteExprIfFalse(pParse, aExpr[j].p, cont, 1);
|
||||
sqlite3ExprIfFalse(pParse, aExpr[j].p, cont, 1);
|
||||
aExpr[j].p = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
pWInfo->iContinue = cont;
|
||||
if( pushKey && !haveKey ){
|
||||
sqliteVdbeAddOp(v, OP_Recno, pTabList->a[0].iCursor, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Recno, pTabList->a[0].iCursor, 0);
|
||||
}
|
||||
freeMaskSet(&maskSet);
|
||||
return pWInfo;
|
||||
@@ -1154,9 +1154,9 @@ WhereInfo *sqliteWhereBegin(
|
||||
|
||||
/*
|
||||
** Generate the end of the WHERE loop. See comments on
|
||||
** sqliteWhereBegin() for additional information.
|
||||
** sqlite3WhereBegin() for additional information.
|
||||
*/
|
||||
void sqliteWhereEnd(WhereInfo *pWInfo){
|
||||
void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
Vdbe *v = pWInfo->pParse->pVdbe;
|
||||
int i;
|
||||
WhereLevel *pLevel;
|
||||
@@ -1164,34 +1164,34 @@ void sqliteWhereEnd(WhereInfo *pWInfo){
|
||||
|
||||
for(i=pTabList->nSrc-1; i>=0; i--){
|
||||
pLevel = &pWInfo->a[i];
|
||||
sqliteVdbeResolveLabel(v, pLevel->cont);
|
||||
sqlite3VdbeResolveLabel(v, pLevel->cont);
|
||||
if( pLevel->op!=OP_Noop ){
|
||||
sqliteVdbeAddOp(v, pLevel->op, pLevel->p1, pLevel->p2);
|
||||
sqlite3VdbeAddOp(v, pLevel->op, pLevel->p1, pLevel->p2);
|
||||
}
|
||||
sqliteVdbeResolveLabel(v, pLevel->brk);
|
||||
sqlite3VdbeResolveLabel(v, pLevel->brk);
|
||||
if( pLevel->inOp!=OP_Noop ){
|
||||
sqliteVdbeAddOp(v, pLevel->inOp, pLevel->inP1, pLevel->inP2);
|
||||
sqlite3VdbeAddOp(v, pLevel->inOp, pLevel->inP1, pLevel->inP2);
|
||||
}
|
||||
if( pLevel->iLeftJoin ){
|
||||
int addr;
|
||||
addr = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iLeftJoin, 0);
|
||||
sqliteVdbeAddOp(v, OP_NotNull, 1, addr+4 + (pLevel->iCur>=0));
|
||||
sqliteVdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0);
|
||||
addr = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iLeftJoin, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NotNull, 1, addr+4 + (pLevel->iCur>=0));
|
||||
sqlite3VdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0);
|
||||
if( pLevel->iCur>=0 ){
|
||||
sqliteVdbeAddOp(v, OP_NullRow, pLevel->iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NullRow, pLevel->iCur, 0);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, pLevel->top);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, pLevel->top);
|
||||
}
|
||||
}
|
||||
sqliteVdbeResolveLabel(v, pWInfo->iBreak);
|
||||
sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
|
||||
for(i=0; i<pTabList->nSrc; i++){
|
||||
Table *pTab = pTabList->a[i].pTab;
|
||||
assert( pTab!=0 );
|
||||
if( pTab->isTransient || pTab->pSelect ) continue;
|
||||
pLevel = &pWInfo->a[i];
|
||||
sqliteVdbeAddOp(v, OP_Close, pTabList->a[i].iCursor, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, pTabList->a[i].iCursor, 0);
|
||||
if( pLevel->pIdx!=0 ){
|
||||
sqliteVdbeAddOp(v, OP_Close, pLevel->iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, pLevel->iCur, 0);
|
||||
}
|
||||
}
|
||||
#if 0 /* Never reuse a cursor */
|
||||
@@ -1202,3 +1202,6 @@ void sqliteWhereEnd(WhereInfo *pWInfo){
|
||||
sqliteFree(pWInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user