Compare commits

..

2 Commits

Author SHA1 Message Date
drh 202dd9c2db Make the VdbeCursor object even smaller. But the resulting library is bigger
and slower than trunk.  This branch is a failed experiment.

FossilOrigin-Name: 896a06cc182491d87950c287df45c0656e284d35
2015-12-17 19:17:43 +00:00
drh 65b30ca58a Reduce the size of the VdbeCursor object by a pointer (the pBt pointer used
for ephemeral tables).

FossilOrigin-Name: 98b710c36343fc213c8223f353907934be60b60d
2015-12-17 17:30:53 +00:00
25 changed files with 207 additions and 454 deletions
+1 -1
View File
@@ -544,7 +544,7 @@ int sqlite3Fts5AuxInit(fts5_api *pApi){
int rc = SQLITE_OK; /* Return code */
int i; /* To iterate through builtin functions */
for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aBuiltin); i++){
for(i=0; rc==SQLITE_OK && i<sizeof(aBuiltin)/sizeof(aBuiltin[0]); i++){
rc = pApi->xCreateFunction(pApi,
aBuiltin[i].zFunc,
aBuiltin[i].pUserData,
+3 -3
View File
@@ -407,7 +407,7 @@ static int fts5ExprPhraseIsMatch(
/* If the aStatic[] array is not large enough, allocate a large array
** using sqlite3_malloc(). This approach could be improved upon. */
if( pPhrase->nTerm>(int)ArraySize(aStatic) ){
if( pPhrase->nTerm>(sizeof(aStatic) / sizeof(aStatic[0])) ){
int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
if( !aIter ) return SQLITE_NOMEM;
@@ -543,7 +543,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
/* If the aStatic[] array is not large enough, allocate a large array
** using sqlite3_malloc(). This approach could be improved upon. */
if( pNear->nPhrase>(int)ArraySize(aStatic) ){
if( pNear->nPhrase>(sizeof(aStatic) / sizeof(aStatic[0])) ){
int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
}else{
@@ -2190,7 +2190,7 @@ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
int rc = SQLITE_OK;
void *pCtx = (void*)pGlobal;
for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aFunc); i++){
for(i=0; rc==SQLITE_OK && i<(sizeof(aFunc) / sizeof(aFunc[0])); i++){
struct Fts5ExprFunc *p = &aFunc[i];
rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
}
+2 -2
View File
@@ -537,7 +537,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
for(i=0; i<pInfo->nConstraint; i++){
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
int j;
for(j=0; j<(int)ArraySize(aConstraint); j++){
for(j=0; j<sizeof(aConstraint)/sizeof(aConstraint[0]); j++){
struct Constraint *pC = &aConstraint[j];
if( p->iColumn==aColMap[pC->iCol] && p->op & pC->op ){
if( p->usable ){
@@ -584,7 +584,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
/* Assign argvIndex values to each constraint in use. */
iNext = 1;
for(i=0; i<(int)ArraySize(aConstraint); i++){
for(i=0; i<sizeof(aConstraint)/sizeof(aConstraint[0]); i++){
struct Constraint *pC = &aConstraint[i];
if( pC->iConsIndex>=0 ){
pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++;
+1 -1
View File
@@ -338,7 +338,7 @@ int sqlite3Fts5StorageClose(Fts5Storage *p){
int i;
/* Finalize all SQL statements */
for(i=0; i<(int)ArraySize(p->aStmt); i++){
for(i=0; i<ArraySize(p->aStmt); i++){
sqlite3_finalize(p->aStmt[i]);
}
+1 -1
View File
@@ -1220,7 +1220,7 @@ int sqlite3Fts5TokenizerInit(fts5_api *pApi){
int rc = SQLITE_OK; /* Return code */
int i; /* To iterate through builtin functions */
for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aBuiltin); i++){
for(i=0; rc==SQLITE_OK && i<sizeof(aBuiltin)/sizeof(aBuiltin[0]); i++){
rc = pApi->xCreateTokenizer(pApi,
aBuiltin[i].zName,
(void*)pApi,
+1 -111
View File
@@ -1181,7 +1181,7 @@ static void jsonTest1Func(
#endif /* SQLITE_DEBUG */
/****************************************************************************
** Scalar SQL function implementations
** SQL function implementations
****************************************************************************/
/*
@@ -1514,102 +1514,6 @@ static void jsonValidFunc(
sqlite3_result_int(ctx, rc);
}
/****************************************************************************
** Aggregate SQL function implementations
****************************************************************************/
/*
** json_group_array(VALUE)
**
** Return a JSON array composed of all values in the aggregate.
*/
static void jsonArrayStep(
sqlite3_context *ctx,
int argc,
sqlite3_value **argv
){
JsonString *pStr;
pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
if( pStr ){
if( pStr->zBuf==0 ){
jsonInit(pStr, ctx);
jsonAppendChar(pStr, '[');
}else{
jsonAppendChar(pStr, ',');
pStr->pCtx = ctx;
}
jsonAppendValue(pStr, argv[0]);
}
}
static void jsonArrayFinal(sqlite3_context *ctx){
JsonString *pStr;
pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
if( pStr ){
pStr->pCtx = ctx;
jsonAppendChar(pStr, ']');
if( pStr->bErr ){
sqlite3_result_error_nomem(ctx);
if( !pStr->bStatic ) sqlite3_free(pStr->zBuf);
}else{
sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
pStr->bStatic = 1;
}
}else{
sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
}
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
}
/*
** json_group_obj(NAME,VALUE)
**
** Return a JSON object composed of all names and values in the aggregate.
*/
static void jsonObjectStep(
sqlite3_context *ctx,
int argc,
sqlite3_value **argv
){
JsonString *pStr;
const char *z;
u32 n;
pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
if( pStr ){
if( pStr->zBuf==0 ){
jsonInit(pStr, ctx);
jsonAppendChar(pStr, '{');
}else{
jsonAppendChar(pStr, ',');
pStr->pCtx = ctx;
}
z = (const char*)sqlite3_value_text(argv[0]);
n = (u32)sqlite3_value_bytes(argv[0]);
jsonAppendString(pStr, z, n);
jsonAppendChar(pStr, ':');
jsonAppendValue(pStr, argv[1]);
}
}
static void jsonObjectFinal(sqlite3_context *ctx){
JsonString *pStr;
pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
if( pStr ){
jsonAppendChar(pStr, '}');
if( pStr->bErr ){
sqlite3_result_error_nomem(ctx);
if( !pStr->bStatic ) sqlite3_free(pStr->zBuf);
}else{
sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
pStr->bStatic = 1;
}
}else{
sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
}
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
/****************************************************************************
** The json_each virtual table
@@ -2108,15 +2012,6 @@ int sqlite3Json1Init(sqlite3 *db){
{ "json_test1", 1, 0, jsonTest1Func },
#endif
};
static const struct {
const char *zName;
int nArg;
void (*xStep)(sqlite3_context*,int,sqlite3_value**);
void (*xFinal)(sqlite3_context*);
} aAgg[] = {
{ "json_group_array", 1, jsonArrayStep, jsonArrayFinal },
{ "json_group_object", 2, jsonObjectStep, jsonObjectFinal },
};
#ifndef SQLITE_OMIT_VIRTUALTABLE
static const struct {
const char *zName;
@@ -2132,11 +2027,6 @@ int sqlite3Json1Init(sqlite3 *db){
(void*)&aFunc[i].flag,
aFunc[i].xFunc, 0, 0);
}
for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
rc = sqlite3_create_function(db, aAgg[i].zName, aAgg[i].nArg,
SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
0, aAgg[i].xStep, aAgg[i].xFinal);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
+27 -31
View File
@@ -1,5 +1,5 @@
C Enhance\sthe\scommand-line\sshell\sto\shandle\sMBCS\scharacters\son\sinput\sand\soutput.
D 2015-12-30T13:36:57.561
C Make\sthe\sVdbeCursor\sobject\seven\ssmaller.\s\sBut\sthe\sresulting\slibrary\sis\sbigger\nand\sslower\sthan\strunk.\s\sThis\sbranch\sis\sa\sfailed\sexperiment.
D 2015-12-17T19:17:43.940
F Makefile.in 28bcd6149e050dff35d4dcfd97e890cd387a499d
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 5fff077fcc46de7714ed6eebb6159a4c00eab751
@@ -98,17 +98,17 @@ F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
F ext/fts5/fts5.h 8b9a13b309b180e9fb88ea5666c0d8d73c6102d9
F ext/fts5/fts5Int.h acf968e43d57b6b1caf7554d34ec35d6ed3b4fe8
F ext/fts5/fts5_aux.c 2dafc3aee0c70d643140c77d8d70daffa51a9e9e
F ext/fts5/fts5_aux.c 1f384972d606375b8fa078319f25ab4b5feb1b35
F ext/fts5/fts5_buffer.c 1e49512a535045e621246dc7f4f65f3593fa0fc2
F ext/fts5/fts5_config.c 0ee66188609a62342e9f9aeefa3c3e44518a4dd6
F ext/fts5/fts5_expr.c 8228aca3e9af626a1ca9b093d4d24b4f2488ad23
F ext/fts5/fts5_expr.c 80075fa45091bad42100c4a5c4f2efc83e43e3af
F ext/fts5/fts5_hash.c 25838d525e97f8662ff3504be94d0bad24f9a37e
F ext/fts5/fts5_index.c 578f46697080f11a1e26cd45a1c039c043a3111d
F ext/fts5/fts5_main.c e11b525778e6fce416d916bfa96926bd1ce4616d
F ext/fts5/fts5_storage.c 57c636d87cbb829d6147c8c8bf78fa53b9ebb526
F ext/fts5/fts5_main.c ef04699949ab8e42d590ae30188afef7ad58776e
F ext/fts5/fts5_storage.c 9ea3d92178743758b6c54d9fe8836bbbdcc92e3b
F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd
F ext/fts5/fts5_test_mi.c e96be827aa8f571031e65e481251dc1981d608bf
F ext/fts5/fts5_tokenize.c 504984ac6993323247221eebe3cd55bead01b5f8
F ext/fts5/fts5_tokenize.c 618efe033bceb80c521b1e9ddfd9fee85fb5946e
F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c
F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1
F ext/fts5/fts5_vocab.c 3742d0abfe8aa8c3cb4a7df56aa38f2e3c3fb1c2
@@ -191,7 +191,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
F ext/misc/json1.c b7ed42db00f7429c0f0b5068209c95c41b531596
F ext/misc/json1.c 4f45afd9dbcd6feca8c528251efbb7fc09299a09
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
@@ -276,17 +276,17 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc
F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
F src/btree.c 84ede51e371a11c3dbb3e24ccc5e3e99594a6c00
F src/btree.h 2d76dee44704c47eed323356a758662724b674a0
F src/btree.c cb0ed74a8212a7b31fb967a162658f490a302a18
F src/btree.h 778f36cd143dae941e8b8d0cbc7b0f43ba35dfef
F src/btreeInt.h 3ab435ed27adea54d040584b0bcc488ee7db1e38
F src/build.c e83da4d004a4e050c01acbb821ff7a7b1019c29b
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
F src/date.c e4655393bb403fa310eef66cc4583d75d4d7fd93
F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78
F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da
F src/expr.c 38790e65d1219f2b7dc26458f39a5252fe7c60cd
F src/expr.c ccb93d7b7e1ac5d187c9b153bae145933f93ee5c
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0
F src/func.c fe50a9ab977acc0bb0fcd46741e0071fa388888e
@@ -294,7 +294,7 @@ F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 4622e544a6f054b8f36bb06ae85f4aa09fcd6b5b
F src/insert.c e1d20ae8979e25519c2670233718676bedcfedc9
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b
@@ -304,13 +304,13 @@ F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
F src/mem5.c 262055c242fa7db59c5f07ad77fdc4e97888c054
F src/mem5.c 5c267678ba9f745a2ee58102a9f482d64a58577a
F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23
F src/mutex_unix.c fc54f25b2a750d53b32512a4a728cec28039ae2a
F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
@@ -334,11 +334,11 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c a83b41104e6ff69855d03cd0aaa09e93927ec39f
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c f8fded11fc443a9f5a73cc5db069d06b34460e2f
F src/shell.c ace08b69cd9702143cf87b5bd20b744a56f832fd
F src/shell.c abbc74ea43dbf2f306ea18282d666683fb5efab2
F src/sqlite.h.in 7d87d71b9a4689c51fa092f48f16590ff71558e3
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
F src/sqliteInt.h 6e0c1082268e99aa337de1547df32b220e812fb3
F src/sqliteInt.h beb4a63b94428f52a3d7c7af2ba8bdc7d4682a03
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
@@ -395,17 +395,17 @@ F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785
F src/treeview.c 78842e90c1f71269e7a73a1d4221b6fe360bab66
F src/trigger.c de3ed31ad3218a20d7d7e18bf1b3b734e78bda66
F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3
F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c 984c2be6691d3f67deb2e6747c2132150d776f32
F src/vdbe.c 3bedca4adcf7dc42224a20049883c89819c459b0
F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637
F src/vdbeInt.h 75c2e82ee3357e9210c06474f8d9bdf12c81105d
F src/vdbeInt.h 06caadd917765d7b981686b1dd33845023ccfbdc
F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca
F src/vdbeaux.c 68082d9991fc1b8625d34c8b5db1775c9dee426e
F src/vdbeaux.c b0d427a5070bae99f137368356674457d018c168
F src/vdbeblob.c fdc4a81605ae7a35ae94a55bd768b66d6be16f15
F src/vdbemem.c fdd1578e47bea61390d472de53c565781d81e045
F src/vdbesort.c a7ec02da4494c59dfd071126dd3726be5a11459d
F src/vdbesort.c 90a3545ed856e1007c77ca3ac4f9c1975a64ed23
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
@@ -563,7 +563,7 @@ F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
F test/cursorhint.test 432811b62bd5ffb812729f49bba3b9ad687550bb
F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65
F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0
F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204
F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
@@ -787,7 +787,7 @@ F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7
F test/index6.test 7102ec371414c42dfb1d5ca37eb4519aa9edc23a
F test/index7.test 9c6765a74fc3fcde7aebc5b3bd40d98df14a527c
F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985
F test/indexexpr1.test cb71b6586177b840e28110dd952178bb2bdfedc2
F test/indexexpr1.test bbb52b5d5717d9f23853826963b0af5110009366
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371
@@ -820,7 +820,6 @@ F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/json101.test f0178422b3a2418f423fd0d3caf3571c8d1b9863
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
F test/json103.test 923b288a0610ec86c0951778f7db19cbcca36ad1
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
@@ -1406,10 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 7f386a9332237100a345035ca213327e21d95855
R 5acb3019b0f92c56ad605906cb883a23
T *branch * mbcs-shell
T *sym-mbcs-shell *
T -sym-trunk *
P 98b710c36343fc213c8223f353907934be60b60d
R 10fdd2deb8319d6498b358eb4665321f
U drh
Z 2dbfb8e7ec032a3367036522c7c27bf6
Z dceb428fbc78dc00f293c1c742052765
+1 -1
View File
@@ -1 +1 @@
a0a08b8c0bbd4d71955261f6b7e997701ca68e18
896a06cc182491d87950c287df45c0656e284d35
+8
View File
@@ -4182,6 +4182,14 @@ void sqlite3BtreeCursorZero(BtCursor *p){
memset(p, 0, offsetof(BtCursor, iPage));
}
/*
** Return the Btree object associated with a BtCursor.
*/
Btree *sqlite3BtreeOfCursor(BtCursor *p){
assert( p!=0 );
return p->pBtree;
}
/*
** Close a cursor. The read lock on the database file is released
** when the last cursor is closed.
+1
View File
@@ -221,6 +221,7 @@ int sqlite3BtreeCursor(
int sqlite3BtreeCursorSize(void);
void sqlite3BtreeCursorZero(BtCursor*);
void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
Btree *sqlite3BtreeOfCursor(BtCursor*);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
void sqlite3BtreeCursorHint(BtCursor*, int, ...);
#endif
+7 -14
View File
@@ -65,7 +65,6 @@ struct DateTime {
char validHMS; /* True (1) if h,m,s are valid */
char validJD; /* True (1) if iJD is valid */
char validTZ; /* True (1) if tz is valid */
char tzSet; /* Timezone was set explicitly */
};
@@ -159,7 +158,6 @@ static int parseTimezone(const char *zDate, DateTime *p){
p->tz = sgn*(nMn + nHr*60);
zulu_time:
while( sqlite3Isspace(*zDate) ){ zDate++; }
p->tzSet = 1;
return *zDate!=0;
}
@@ -592,18 +590,13 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
}
#ifndef SQLITE_OMIT_LOCALTIME
else if( strcmp(z, "utc")==0 ){
if( p->tzSet==0 ){
sqlite3_int64 c1;
computeJD(p);
c1 = localtimeOffset(p, pCtx, &rc);
if( rc==SQLITE_OK ){
p->iJD -= c1;
clearYMD_HMS_TZ(p);
p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
}
p->tzSet = 1;
}else{
rc = SQLITE_OK;
sqlite3_int64 c1;
computeJD(p);
c1 = localtimeOffset(p, pCtx, &rc);
if( rc==SQLITE_OK ){
p->iJD -= c1;
clearYMD_HMS_TZ(p);
p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
}
}
#endif
+3 -15
View File
@@ -888,7 +888,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
assert( ExprHasProperty(p, EP_Reduced)==0 );
memcpy(zAlloc, p, nNewSize);
}else{
u32 nSize = (u32)exprStructSize(p);
int nSize = exprStructSize(p);
memcpy(zAlloc, p, nSize);
if( nSize<EXPR_FULLSIZE ){
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
@@ -2468,7 +2468,7 @@ void sqlite3ExprCodeLoadIndexColumn(
assert( pIdx->aColExpr );
assert( pIdx->aColExpr->nExpr>iIdxCol );
pParse->iSelfTab = iTabCur;
sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
sqlite3ExprCode(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
}else{
sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
iTabCol, regOut);
@@ -3321,25 +3321,13 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target);
}else{
inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
assert( pParse->pVdbe || pParse->db->mallocFailed );
if( inReg!=target && pParse->pVdbe ){
sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
}
}
}
/*
** Make a transient copy of expression pExpr and then code it using
** sqlite3ExprCode(). This routine works just like sqlite3ExprCode()
** except that the input expression is guaranteed to be unchanged.
*/
void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
sqlite3 *db = pParse->db;
pExpr = sqlite3ExprDup(db, pExpr, 0);
if( !db->mallocFailed ) sqlite3ExprCode(pParse, pExpr, target);
sqlite3ExprDelete(db, pExpr);
}
/*
** Generate code that will evaluate expression pExpr and store the
** results in register target. The results are guaranteed to appear
+1 -1
View File
@@ -1408,7 +1408,7 @@ void sqlite3GenerateConstraintChecks(
int x;
if( iField==XN_EXPR ){
pParse->ckBase = regNewData+1;
sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
sqlite3ExprCode(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
pParse->ckBase = 0;
VdbeComment((v, "%s column %d", pIdx->zName, i));
}else{
+19 -10
View File
@@ -25,7 +25,7 @@
**
** This memory allocator uses the following algorithm:
**
** 1. All memory allocation sizes are rounded up to a power of 2.
** 1. All memory allocations sizes are rounded up to a power of 2.
**
** 2. If two adjacent free blocks are the halves of a larger block,
** then the two blocks are coalesced into the single larger block.
@@ -117,7 +117,7 @@ static SQLITE_WSD struct Mem5Global {
/*
** Lists of free blocks. aiFreelist[0] is a list of free blocks of
** size mem5.szAtom. aiFreelist[1] holds blocks of size szAtom*2.
** aiFreelist[2] holds free blocks of size szAtom*4. And so forth.
** and so forth.
*/
int aiFreelist[LOGMAX+1];
@@ -183,7 +183,9 @@ static void memsys5Link(int i, int iLogsize){
}
/*
** Obtain or release the mutex needed to access global data structures.
** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
** will already be held (obtained by code in malloc.c) if
** sqlite3GlobalConfig.bMemStat is true.
*/
static void memsys5Enter(void){
sqlite3_mutex_enter(mem5.mutex);
@@ -193,8 +195,9 @@ static void memsys5Leave(void){
}
/*
** Return the size of an outstanding allocation, in bytes.
** This only works for chunks that are currently checked out.
** Return the size of an outstanding allocation, in bytes. The
** size returned omits the 8-byte header overhead. This only
** works for chunks that are currently checked out.
*/
static int memsys5Size(void *p){
int iSize, i;
@@ -227,12 +230,16 @@ static void *memsys5MallocUnsafe(int nByte){
/* Keep track of the maximum allocation request. Even unfulfilled
** requests are counted */
if( (u32)nByte>mem5.maxRequest ){
/* Abort if the requested allocation size is larger than the largest
** power of two that we can represent using 32-bit signed integers. */
if( nByte > 0x40000000 ) return 0;
mem5.maxRequest = nByte;
}
/* Abort if the requested allocation size is larger than the largest
** power of two that we can represent using 32-bit signed integers.
*/
if( nByte > 0x40000000 ){
return 0;
}
/* Round nByte up to the next valid power of two */
for(iFullSz=mem5.szAtom,iLogsize=0; iFullSz<nByte; iFullSz*=2,iLogsize++){}
@@ -391,11 +398,13 @@ static void *memsys5Realloc(void *pPrior, int nBytes){
if( nBytes<=nOld ){
return pPrior;
}
p = memsys5Malloc(nBytes);
memsys5Enter();
p = memsys5MallocUnsafe(nBytes);
if( p ){
memcpy(p, pPrior, nOld);
memsys5Free(pPrior);
memsys5FreeUnsafe(pPrior);
}
memsys5Leave();
return p;
}
-2
View File
@@ -51,8 +51,6 @@ struct sqlite3_mutex {
};
#if SQLITE_MUTEX_NREF
#define SQLITE3_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,0,0,(pthread_t)0,0}
#elif defined(SQLITE_ENABLE_API_ARMOR)
#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0 }
#else
#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
#endif
+59 -114
View File
@@ -329,13 +329,6 @@ static int bail_on_error = 0;
*/
static int stdin_is_interactive = 1;
/*
** On Windows systems we have to know if standard output is a console
** in order to translate UTF-8 into MBCS. The following variable is
** true if translation is required.
*/
static int stdout_is_console = 1;
/*
** The following is the open SQLite database. We make a pointer
** to this database a static variable so that it can be accessed
@@ -437,16 +430,6 @@ static void shellstaticFunc(
}
/*
** Compute a string length that is limited to what can be stored in
** lower 30 bits of a 32-bit signed integer.
*/
static int strlen30(const char *z){
const char *z2 = z;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
@@ -482,26 +465,6 @@ static char *local_getline(char *zLine, FILE *in){
break;
}
}
#if defined(_WIN32) || defined(WIN32)
/* For interactive input on Windows systems, translate the
** multi-byte characterset characters into UTF-8. */
if( stdin_is_interactive ){
extern char *sqlite3_win32_mbcs_to_utf8(const char*);
char *zTrans = sqlite3_win32_mbcs_to_utf8(zLine);
if( zTrans ){
int nTrans = strlen30(zTrans)+1;
if( nTrans>nLine ){
zLine = realloc(zLine, nTrans);
if( zLine==0 ){
sqlite3_free(zTrans);
return 0;
}
}
memcpy(zLine, zTrans, nTrans);
sqlite3_free(zTrans);
}
}
#endif /* defined(_WIN32) || defined(WIN32) */
return zLine;
}
@@ -539,31 +502,6 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
return zResult;
}
/*
** Render output like fprintf(). Except, if the output is going to the
** console and if this is running on a Windows machine, translate the
** output from UTF-8 into MBCS.
*/
#if defined(_WIN32) || defined(WIN32)
void utf8_printf(FILE *out, const char *zFormat, ...){
va_list ap;
va_start(ap, zFormat);
if( stdout_is_console && out==stdout ){
extern char *sqlite3_win32_utf8_to_mbcs(const char*);
char *z1 = sqlite3_vmprintf(zFormat, ap);
char *z2 = sqlite3_win32_utf8_to_mbcs(z1);
sqlite3_free(z1);
fputs(z2, out);
sqlite3_free(z2);
}else{
vfprintf(out, zFormat, ap);
}
va_end(ap);
}
#else
# define utf8_printf fprintf
#endif
/*
** Shell output mode information from before ".explain on",
** saved so that it can be restored by ".explain off"
@@ -669,6 +607,16 @@ static const char *modeDescr[] = {
*/
#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
/*
** Compute a string length that is limited to what can be stored in
** lower 30 bits of a 32-bit signed integer.
*/
static int strlen30(const char *z){
const char *z2 = z;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
/*
** A callback for the sqlite3_log() interface.
*/
@@ -701,7 +649,7 @@ static void output_quoted_string(FILE *out, const char *z){
if( z[i]=='\'' ) nSingle++;
}
if( nSingle==0 ){
utf8_printf(out,"'%s'",z);
fprintf(out,"'%s'",z);
}else{
fprintf(out,"'");
while( *z ){
@@ -710,10 +658,10 @@ static void output_quoted_string(FILE *out, const char *z){
fprintf(out,"''");
z++;
}else if( z[i]=='\'' ){
utf8_printf(out,"%.*s''",i,z);
fprintf(out,"%.*s''",i,z);
z += i+1;
}else{
utf8_printf(out,"%s",z);
fprintf(out,"%s",z);
break;
}
}
@@ -769,7 +717,7 @@ static void output_html_string(FILE *out, const char *z){
&& z[i]!='\'';
i++){}
if( i>0 ){
utf8_printf(out,"%.*s",i,z);
fprintf(out,"%.*s",i,z);
}
if( z[i]=='<' ){
fprintf(out,"&lt;");
@@ -820,7 +768,7 @@ static const char needCsvQuote[] = {
static void output_csv(ShellState *p, const char *z, int bSep){
FILE *out = p->out;
if( z==0 ){
utf8_printf(out,"%s",p->nullValue);
fprintf(out,"%s",p->nullValue);
}else{
int i;
int nSep = strlen30(p->colSeparator);
@@ -840,11 +788,11 @@ static void output_csv(ShellState *p, const char *z, int bSep){
}
putc('"', out);
}else{
utf8_printf(out, "%s", z);
fprintf(out, "%s", z);
}
}
if( bSep ){
utf8_printf(p->out, "%s", p->colSeparator);
fprintf(p->out, "%s", p->colSeparator);
}
}
@@ -882,9 +830,9 @@ static int shell_callback(
int len = strlen30(azCol[i] ? azCol[i] : "");
if( len>w ) w = len;
}
if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
for(i=0; i<nArg; i++){
utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
fprintf(p->out,"%*s = %s%s", w, azCol[i],
azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
}
break;
@@ -910,10 +858,10 @@ static int shell_callback(
}
if( p->showHeader ){
if( w<0 ){
utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
i==nArg-1 ? p->rowSeparator : " ");
}else{
utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
i==nArg-1 ? p->rowSeparator : " ");
}
}
@@ -927,8 +875,7 @@ static int shell_callback(
}else{
w = 10;
}
fprintf(p->out,"%-*.*s%s",w,w,
"----------------------------------------------------------"
fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
"----------------------------------------------------------",
i==nArg-1 ? p->rowSeparator : " ");
}
@@ -952,11 +899,11 @@ static int shell_callback(
p->iIndent++;
}
if( w<0 ){
utf8_printf(p->out,"%*.*s%s",-w,-w,
fprintf(p->out,"%*.*s%s",-w,-w,
azArg[i] ? azArg[i] : p->nullValue,
i==nArg-1 ? p->rowSeparator : " ");
}else{
utf8_printf(p->out,"%-*.*s%s",w,w,
fprintf(p->out,"%-*.*s%s",w,w,
azArg[i] ? azArg[i] : p->nullValue,
i==nArg-1 ? p->rowSeparator : " ");
}
@@ -967,7 +914,7 @@ static int shell_callback(
case MODE_List: {
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
utf8_printf(p->out,"%s%s",azCol[i],
fprintf(p->out,"%s%s",azCol[i],
i==nArg-1 ? p->rowSeparator : p->colSeparator);
}
}
@@ -975,13 +922,13 @@ static int shell_callback(
for(i=0; i<nArg; i++){
char *z = azArg[i];
if( z==0 ) z = p->nullValue;
utf8_printf(p->out, "%s", z);
fprintf(p->out, "%s", z);
if( i<nArg-1 ){
utf8_printf(p->out, "%s", p->colSeparator);
fprintf(p->out, "%s", p->colSeparator);
}else if( p->mode==MODE_Semi ){
utf8_printf(p->out, ";%s", p->rowSeparator);
fprintf(p->out, ";%s", p->rowSeparator);
}else{
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
}
}
break;
@@ -1010,16 +957,16 @@ static int shell_callback(
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
output_c_string(p->out,azCol[i] ? azCol[i] : "");
if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
}
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
}
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
}
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
break;
}
case MODE_Csv: {
@@ -1028,13 +975,13 @@ static int shell_callback(
for(i=0; i<nArg; i++){
output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
}
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
}
if( nArg>0 ){
for(i=0; i<nArg; i++){
output_csv(p, azArg[i], i<nArg-1);
}
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
}
setTextMode(p->out);
break;
@@ -1042,12 +989,12 @@ static int shell_callback(
case MODE_Insert: {
p->cnt++;
if( azArg==0 ) break;
utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
fprintf(p->out,"INSERT INTO %s",p->zDestTable);
if( p->showHeader ){
fprintf(p->out,"(");
for(i=0; i<nArg; i++){
char *zSep = i>0 ? ",": "";
utf8_printf(p->out, "%s%s", zSep, azCol[i]);
fprintf(p->out, "%s%s", zSep, azCol[i]);
}
fprintf(p->out,")");
}
@@ -1061,14 +1008,14 @@ static int shell_callback(
output_quoted_string(p->out, azArg[i]);
}else if( aiType && (aiType[i]==SQLITE_INTEGER
|| aiType[i]==SQLITE_FLOAT) ){
utf8_printf(p->out,"%s%s",zSep, azArg[i]);
fprintf(p->out,"%s%s",zSep, azArg[i]);
}else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
const void *pBlob = sqlite3_column_blob(p->pStmt, i);
int nBlob = sqlite3_column_bytes(p->pStmt, i);
if( zSep[0] ) fprintf(p->out,"%s",zSep);
output_hex_blob(p->out, pBlob, nBlob);
}else if( isNumber(azArg[i], 0) ){
utf8_printf(p->out,"%s%s",zSep, azArg[i]);
fprintf(p->out,"%s%s",zSep, azArg[i]);
}else{
if( zSep[0] ) fprintf(p->out,"%s",zSep);
output_quoted_string(p->out, azArg[i]);
@@ -1080,17 +1027,17 @@ static int shell_callback(
case MODE_Ascii: {
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
}
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
}
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
}
utf8_printf(p->out, "%s", p->rowSeparator);
fprintf(p->out, "%s", p->rowSeparator);
break;
}
}
@@ -1220,13 +1167,13 @@ static int run_table_dump_query(
nResult = sqlite3_column_count(pSelect);
while( rc==SQLITE_ROW ){
if( zFirstRow ){
utf8_printf(p->out, "%s", zFirstRow);
fprintf(p->out, "%s", zFirstRow);
zFirstRow = 0;
}
z = (const char*)sqlite3_column_text(pSelect, 0);
utf8_printf(p->out, "%s", z);
fprintf(p->out, "%s", z);
for(i=1; i<nResult; i++){
utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
}
if( z==0 ) z = "";
while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
@@ -1414,7 +1361,7 @@ static void display_scanstats(
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
rEstLoop *= rEst;
fprintf(pArg->out,
" nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
@@ -1575,7 +1522,7 @@ static int shell_exec(
/* echo the sql statement if echo on */
if( pArg && pArg->echoOn ){
const char *zStmtSql = sqlite3_sql(pStmt);
utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
}
/* Show the EXPLAIN QUERY PLAN if .eqp is on */
@@ -1589,7 +1536,7 @@ static int shell_exec(
fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
}
}
sqlite3_finalize(pExplain);
@@ -1730,11 +1677,11 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
"INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
"VALUES('table','%q','%q',0,'%q');",
zTable, zTable, zSql);
utf8_printf(p->out, "%s\n", zIns);
fprintf(p->out, "%s\n", zIns);
sqlite3_free(zIns);
return 0;
}else{
utf8_printf(p->out, "%s;\n", zSql);
fprintf(p->out, "%s;\n", zSql);
}
if( strcmp(zType, "table")==0 ){
@@ -2179,7 +2126,7 @@ static void sql_trace_callback(void *pArg, const char *z){
if( f ){
int i = (int)strlen(z);
while( i>0 && z[i-1]==';' ){ i--; }
utf8_printf(f, "%.*s;\n", i, z);
fprintf(f, "%.*s;\n", i, z);
}
}
@@ -2662,7 +2609,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
int val = db_int(p, zSql);
sqlite3_free(zSql);
utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
}
sqlite3_free(zSchemaTab);
return 0;
@@ -3502,7 +3449,7 @@ static int do_meta_command(char *zLine, ShellState *p){
int i;
for(i=1; i<nArg; i++){
if( i>1 ) fprintf(p->out, " ");
utf8_printf(p->out, "%s", azArg[i]);
fprintf(p->out, "%s", azArg[i]);
}
fprintf(p->out, "\n");
}else
@@ -3696,7 +3643,7 @@ static int do_meta_command(char *zLine, ShellState *p){
int i, v;
for(i=1; i<nArg; i++){
v = booleanValue(azArg[i]);
utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
}
}
if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
@@ -3705,7 +3652,7 @@ static int do_meta_command(char *zLine, ShellState *p){
char zBuf[200];
v = integerValue(azArg[i]);
sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
utf8_printf(p->out, "%s", zBuf);
fprintf(p->out, "%s", zBuf);
}
}
}else
@@ -3879,8 +3826,7 @@ static int do_meta_command(char *zLine, ShellState *p){
for(i=0; i<nPrintRow; i++){
for(j=i; j<nRow; j+=nPrintRow){
char *zSp = j<nPrintRow ? "" : " ";
utf8_printf(p->out, "%s%-*s", zSp, maxlen,
azResult[j] ? azResult[j]:"");
fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
}
fprintf(p->out, "\n");
}
@@ -4601,7 +4547,6 @@ int SQLITE_CDECL main(int argc, char **argv){
Argv0 = argv[0];
main_init(&data);
stdin_is_interactive = isatty(0);
stdout_is_console = isatty(1);
/* Make sure we have a valid signal handler early, before anything
** else is done.
+5 -6
View File
@@ -692,6 +692,11 @@ typedef INT16_TYPE LogEst;
** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
** at run-time.
*/
#ifdef SQLITE_AMALGAMATION
const int sqlite3one = 1;
#else
extern const int sqlite3one;
#endif
#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
@@ -709,11 +714,6 @@ typedef INT16_TYPE LogEst;
# define SQLITE_UTF16NATIVE SQLITE_UTF16BE
#endif
#if !defined(SQLITE_BYTEORDER)
# ifdef SQLITE_AMALGAMATION
const int sqlite3one = 1;
# else
extern const int sqlite3one;
# endif
# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0)
# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
@@ -3461,7 +3461,6 @@ void sqlite3ExprCacheRemove(Parse*, int, int);
void sqlite3ExprCacheClear(Parse*);
void sqlite3ExprCacheAffinityChange(Parse*, int, int);
void sqlite3ExprCode(Parse*, Expr*, int);
void sqlite3ExprCodeCopy(Parse*, Expr*, int);
void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8);
int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
+2 -2
View File
@@ -37,13 +37,13 @@
#include <assert.h>
#include "vdbeInt.h"
#if !defined(SQLITE_AMALGAMATION) && SQLITE_BYTEORDER==0
#ifndef SQLITE_AMALGAMATION
/*
** The following constant value is used by the SQLITE_BIGENDIAN and
** SQLITE_LITTLEENDIAN macros.
*/
const int sqlite3one = 1;
#endif /* SQLITE_AMALGAMATION && SQLITE_BYTEORDER==0 */
#endif /* SQLITE_AMALGAMATION */
/*
** This lookup table is used to help decode the first byte of
+48 -36
View File
@@ -3441,6 +3441,7 @@ case OP_OpenAutoindex:
case OP_OpenEphemeral: {
VdbeCursor *pCx;
KeyInfo *pKeyInfo;
Btree *pBt;
static const int vfsFlags =
SQLITE_OPEN_READWRITE |
@@ -3453,35 +3454,39 @@ case OP_OpenEphemeral: {
pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
if( pCx==0 ) goto no_mem;
pCx->nullRow = 1;
pCx->isEphemeral = 1;
rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt,
rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt,
BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
if( rc==SQLITE_OK ){
rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
}
if( rc==SQLITE_OK ){
/* If a transient index is required, create it by calling
** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
** opening it. If a transient table is required, just use the
** automatically created table with root-page 1 (an BLOB_INTKEY table).
*/
if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
int pgno;
assert( pOp->p4type==P4_KEYINFO );
rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
if( rc==SQLITE_OK ){
assert( pgno==MASTER_ROOT+1 );
assert( pKeyInfo->db==db );
assert( pKeyInfo->enc==ENC(db) );
pCx->pKeyInfo = pKeyInfo;
rc = sqlite3BtreeCursor(pCx->pBt, pgno, BTREE_WRCSR,
pKeyInfo, pCx->uc.pCursor);
rc = sqlite3BtreeBeginTrans(pBt, 1);
if( rc==SQLITE_OK ){
/* If a transient index is required, create it by calling
** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
** opening it. If a transient table is required, just use the
** automatically created table with root-page 1 (an BLOB_INTKEY table).
*/
if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
int pgno;
assert( pOp->p4type==P4_KEYINFO );
rc = sqlite3BtreeCreateTable(pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
if( rc==SQLITE_OK ){
assert( pgno==MASTER_ROOT+1 );
assert( pKeyInfo->db==db );
assert( pKeyInfo->enc==ENC(db) );
pCx->pKeyInfo = pKeyInfo;
rc = sqlite3BtreeCursor(pBt, pgno, BTREE_WRCSR,
pKeyInfo, pCx->uc.pCursor);
}
pCx->isTable = 0;
}else{
rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, BTREE_WRCSR,
0, pCx->uc.pCursor);
pCx->isTable = 1;
}
pCx->isTable = 0;
}
if( rc==SQLITE_OK ){
pCx->isEphemeral = 1;
}else{
rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, BTREE_WRCSR,
0, pCx->uc.pCursor);
pCx->isTable = 1;
sqlite3BtreeClose(pBt);
}
}
pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
@@ -3524,7 +3529,8 @@ case OP_SequenceTest: {
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( isSorter(pC) );
if( (pC->seqCount++)==0 ){
assert( !pC->movetoUsed );
if( (pC->ux.seqCount++)==0 ){
goto jump_to_p2;
}
break;
@@ -3754,7 +3760,8 @@ case OP_SeekGT: { /* jump, in3 */
}
}
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res);
pC->movetoTarget = iKey; /* Used by OP_Delete */
VVA_ONLY( pC->movetoUsed = 1; )
pC->ux.movetoTarget = iKey; /* Used by OP_Delete */
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
@@ -3862,11 +3869,13 @@ case OP_Seek: { /* in2 */
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->eCurType==CURTYPE_BTREE );
assert( !pC->isEphemeral );
assert( pC->uc.pCursor!=0 );
assert( pC->isTable );
pC->nullRow = 0;
pIn2 = &aMem[pOp->p2];
pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
VVA_ONLY( pC->movetoUsed = 1; )
pC->ux.movetoTarget = sqlite3VdbeIntValue(pIn2);
pC->deferredMoveto = 1;
break;
}
@@ -4055,7 +4064,8 @@ case OP_NotExists: { /* jump, in3 */
iKey = pIn3->u.i;
rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
assert( rc==SQLITE_OK || res==0 );
pC->movetoTarget = iKey; /* Used by OP_Delete */
VVA_ONLY( pC->movetoUsed = 1; )
pC->ux.movetoTarget = iKey; /* Used by OP_Delete */
pC->nullRow = 0;
pC->cacheStatus = CACHE_STALE;
pC->deferredMoveto = 0;
@@ -4083,9 +4093,11 @@ case OP_NotExists: { /* jump, in3 */
case OP_Sequence: { /* out2 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( p->apCsr[pOp->p1]!=0 );
assert( p->apCsr[pOp->p1]->eCurType!=CURTYPE_VTAB );
assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
assert( p->apCsr[pOp->p1]->isEphemeral );
assert( !p->apCsr[pOp->p1]->movetoUsed );
pOut = out2Prerelease(p, pOp);
pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
pOut->u.i = p->apCsr[pOp->p1]->ux.seqCount++;
break;
}
@@ -4370,17 +4382,17 @@ case OP_Delete: {
hasUpdateCallback = db->xUpdateCallback && pOp->p4.z && pC->isTable;
if( pOp->p5 && hasUpdateCallback ){
sqlite3BtreeKeySize(pC->uc.pCursor, &pC->movetoTarget);
sqlite3BtreeKeySize(pC->uc.pCursor, &pC->ux.movetoTarget);
}
#ifdef SQLITE_DEBUG
/* The seek operation that positioned the cursor prior to OP_Delete will
** have also set the pC->movetoTarget field to the rowid of the row that
** have also set the pC->ux.movetoTarget field to the rowid of the row that
** is being deleted */
if( pOp->p4.z && pC->isTable && pOp->p5==0 ){
i64 iKey = 0;
sqlite3BtreeKeySize(pC->uc.pCursor, &iKey);
assert( pC->movetoTarget==iKey );
assert( pC->ux.movetoTarget==iKey );
}
#endif
@@ -4390,7 +4402,7 @@ case OP_Delete: {
/* Invoke the update-hook if required. */
if( rc==SQLITE_OK && hasUpdateCallback ){
db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget);
db->aDb[pC->iDb].zName, pOp->p4.z, pC->ux.movetoTarget);
assert( pC->iDb>=0 );
}
if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
@@ -4581,7 +4593,7 @@ case OP_Rowid: { /* out2 */
pOut->flags = MEM_Null;
break;
}else if( pC->deferredMoveto ){
v = pC->movetoTarget;
v = pC->ux.movetoTarget;
#ifndef SQLITE_OMIT_VIRTUALTABLE
}else if( pC->eCurType==CURTYPE_VTAB ){
assert( pC->uc.pVCur!=0 );
+9 -7
View File
@@ -77,16 +77,18 @@ typedef struct AuxData AuxData;
struct VdbeCursor {
u8 eCurType; /* One of the CURTYPE_* values above */
i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
u8 nullRow; /* True if pointing to a row with no data */
u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
u8 isTable; /* True for rowid tables. False for indexes */
#ifdef SQLITE_DEBUG
u8 seekOp; /* Most recent seek operation on this cursor */
Bool movetoUsed:1; /* True if ux.movetoTarget has been used */
#endif
Bool nullRow:1; /* True if pointing to a row with no data */
Bool deferredMoveto:1; /* A call to sqlite3BtreeMoveto() is needed */
Bool isTable:1; /* True for rowid tables. False for indexes */
Bool isEphemeral:1; /* True for an ephemeral table */
Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */
Pgno pgnoRoot; /* Root page of the open btree cursor */
int seekResult; /* Result of previous sqlite3BtreeMoveto() */
i16 nField; /* Number of fields in the header */
u16 nHdrParsed; /* Number of header fields parsed so far */
union {
@@ -95,11 +97,11 @@ struct VdbeCursor {
int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */
VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */
} uc;
Btree *pBt; /* Separate file holding temporary table */
KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
int seekResult; /* Result of previous sqlite3BtreeMoveto() */
i64 seqCount; /* Sequence counter */
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
union {
i64 seqCount; /* Sequence counter. Only valid if movetoUsed==0 */
i64 movetoTarget; /* Rowid moved to. */
} ux;
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
u64 maskUsed; /* Mask of columns used by this cursor */
#endif
+7 -5
View File
@@ -1925,19 +1925,19 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
if( pCx==0 ){
return;
}
assert( pCx->pBt==0 || pCx->eCurType==CURTYPE_BTREE );
assert( pCx->isEphemeral==0 || pCx->eCurType==CURTYPE_BTREE );
switch( pCx->eCurType ){
case CURTYPE_SORTER: {
sqlite3VdbeSorterClose(p->db, pCx);
break;
}
case CURTYPE_BTREE: {
if( pCx->pBt ){
sqlite3BtreeClose(pCx->pBt);
assert( pCx->uc.pCursor!=0 );
if( pCx->isEphemeral ){
sqlite3BtreeClose(sqlite3BtreeOfCursor(pCx->uc.pCursor));
/* The pCx->pCursor will be close automatically, if it exists, by
** the call above. */
}else{
assert( pCx->uc.pCursor!=0 );
sqlite3BtreeCloseCursor(pCx->uc.pCursor);
}
break;
@@ -2940,7 +2940,9 @@ static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){
assert( p->deferredMoveto );
assert( p->isTable );
assert( p->eCurType==CURTYPE_BTREE );
rc = sqlite3BtreeMovetoUnpacked(p->uc.pCursor, 0, p->movetoTarget, 0, &res);
assert( !p->isEphemeral );
assert( p->movetoUsed );
rc = sqlite3BtreeMovetoUnpacked(p->uc.pCursor, 0, p->ux.movetoTarget, 0,&res);
if( rc ) return rc;
if( res!=0 ) return SQLITE_CORRUPT_BKPT;
#ifdef SQLITE_TEST
+1 -1
View File
@@ -960,7 +960,7 @@ int sqlite3VdbeSorterInit(
}
#endif
assert( pCsr->pKeyInfo && pCsr->pBt==0 );
assert( pCsr->pKeyInfo && !pCsr->isEphemeral );
assert( pCsr->eCurType==CURTYPE_SORTER );
szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*);
sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);
-9
View File
@@ -336,15 +336,6 @@ if {$tzoffset_new==4} {
datetest 6.8.1 {datetime('2006-04-02 02:00:00','utc')} {2006-04-02 06:00:00}
datetest 6.8.2 {datetime('2007-03-11 02:00:00','utc')} {2007-03-11 06:00:00}
# The 'utc' modifier is a no-op if the LHS is known to already be in UTC
datetest 6.9.1 {datetime('2015-12-23 12:00:00','utc')} {2015-12-23 17:00:00}
datetest 6.9.2 {datetime('2015-12-23 12:00:00z','utc')} {2015-12-23 12:00:00}
datetest 6.9.3 {datetime('2015-12-23 12:00:00-03:00','utc')} \
{2015-12-23 15:00:00}
datetest 6.9.4 {datetime('2015-12-23 12:00:00','utc','utc','utc')} \
{2015-12-23 17:00:00}
datetest 6.10 {datetime('2000-01-01 12:00:00','localtime')} \
{2000-01-01 07:00:00}
datetest 6.11 {datetime('1969-01-01 12:00:00','localtime')} \
-16
View File
@@ -307,21 +307,5 @@ do_catchsql_test indexexpr1-910 {
INSERT INTO t9(a,b,c,d) VALUES(5,6,7,-8);
} {1 {UNIQUE constraint failed: index 't9x1'}}
# Test cases derived from a NEVER() maro failure discovered by
# Jonathan Metzman using AFL
#
do_execsql_test indexexpr1-1000 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0(a,b,t);
CREATE INDEX i ON t0(a in(0,1));
INSERT INTO t0 VALUES(0,1,2),(2,3,4),(5,6,7);
UPDATE t0 SET b=99 WHERE (a in(0,1))=0;
SELECT *, '|' FROM t0 ORDER BY +a;
} {0 1 2 | 2 99 4 | 5 99 7 |}
do_execsql_test indexexpr1-1010 {
UPDATE t0 SET b=88 WHERE (a in(0,1))=1;
SELECT *, '|' FROM t0 ORDER BY +a;
} {0 88 2 | 2 99 4 | 5 99 7 |}
finish_test
-65
View File
@@ -1,65 +0,0 @@
# 2015-12-30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements tests for JSON aggregate SQL functions
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !json1 {
finish_test
return
}
do_execsql_test json103-100 {
CREATE TABLE t1(a,b,c);
WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<100)
INSERT INTO t1(a,b,c) SELECT x, x%3, printf('n%d',x) FROM c;
UPDATE t1 SET a='orange' WHERE rowid=39;
UPDATE t1 SET a=32.5 WHERE rowid=31;
UPDATE t1 SET a=x'303132' WHERE rowid=29;
UPDATE t1 SET a=NULL WHERE rowid=37;
SELECT json_group_array(a) FROM t1 WHERE a<0 AND typeof(a)!='blob';
} {{[]}}
do_catchsql_test json103-101 {
SELECT json_group_array(a) FROM t1;
} {1 {JSON cannot hold BLOB values}}
do_execsql_test json103-110 {
SELECT json_group_array(a) FROM t1
WHERE rowid BETWEEN 31 AND 39;
} {{[32.5,32,33,34,35,36,null,38,"orange"]}}
do_execsql_test json103-111 {
SELECT json_array_length(json_group_array(a)) FROM t1
WHERE rowid BETWEEN 31 AND 39;
} {9}
do_execsql_test json103-120 {
SELECT b, json_group_array(a) FROM t1 WHERE rowid<10 GROUP BY b ORDER BY b;
} {0 {[3,6,9]} 1 {[1,4,7]} 2 {[2,5,8]}}
do_execsql_test json103-200 {
SELECT json_group_object(c,a) FROM t1 WHERE a<0 AND typeof(a)!='blob';
} {{{}}}
do_catchsql_test json103-201 {
SELECT json_group_object(c,a) FROM t1;
} {1 {JSON cannot hold BLOB values}}
do_execsql_test json103-210 {
SELECT json_group_object(c,a) FROM t1
WHERE rowid BETWEEN 31 AND 39 AND rowid%2==1;
} {{{"n31":32.5,"n33":33,"n35":35,"n37":null,"n39":"orange"}}}
do_execsql_test json103-220 {
SELECT b, json_group_object(c,a) FROM t1
WHERE rowid<7 GROUP BY b ORDER BY b;
} {0 {{"n3":3,"n6":6}} 1 {{"n1":1,"n4":4}} 2 {{"n2":2,"n5":5}}}
finish_test