Make the internal dynamic string interface available to extensions using
the new sqlite3_str object and its associated methods. This is mostly just a renaming of internal objects and methods to use external names, through there are a few small wrapper functions. FossilOrigin-Name: 87f261f0cb800b06ad786f6df16f2c4dddd0d93dfdcc77b4a4eaa22920b56bf1
This commit is contained in:
parent
721e8539c3
commit
0cdbe1aee0
34
manifest
34
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sa\stypo\sin\sa\scomment\sused\sfor\sdocumentation.\s\sNo\scode\schanges.
|
||||
D 2018-05-09T10:11:44.774
|
||||
C Make\sthe\sinternal\sdynamic\sstring\sinterface\savailable\sto\sextensions\susing\nthe\snew\ssqlite3_str\sobject\sand\sits\sassociated\smethods.\s\sThis\sis\smostly\sjust\na\srenaming\sof\sinternal\sobjects\sand\smethods\sto\suse\sexternal\snames,\sthrough\nthere\sare\sa\sfew\ssmall\swrapper\sfunctions.
|
||||
D 2018-05-09T13:46:26.086
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da
|
||||
@ -434,10 +434,10 @@ F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73
|
||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c abedb349c6624d3efa699b4431d5ef679838236527c694444b38ed48c494b39b
|
||||
F src/btree.c 8270813c8f0ca91b2802e88ded3755d04ee962a923d431c13bcb6cf3e0c18f63
|
||||
F src/btree.h 448f15b98ea85dcf7e4eb76f731cadb89636c676ad25dfaac6de77cd66556598
|
||||
F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
|
||||
F src/build.c 0c2be5839f22aa2938f217c6c6c2120d9fc96872a546a37541a8271541cb355e
|
||||
F src/build.c 50ff3e0fa07646b4d797aae0f773efcdb7602f6a5e2f5da27856503f35200889
|
||||
F src/callback.c fe677cb5f5abb02f7a772a62a98c2f516426081df68856e8f2d5f950929b966a
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 849d4cebe008cfc6e4799b034a172b4eaf8856b100739632a852732ba66eee48
|
||||
@ -448,7 +448,7 @@ F src/delete.c b0f90749e22d5e41a12dbf940f4811138cf97da54b46b737089b93eb64a2896f
|
||||
F src/expr.c af4a81a385277510bfc56df87c25d76fc365f98c33bc8797c4a8d84b88e31013
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331
|
||||
F src/func.c 94f42cba2cc1c34aeaa441022ba0170ec3fec4bba54db4e0ded085c6dc0fdc51
|
||||
F src/func.c e2e3c02621a528a472933fd4733a5da635676f1461be73293f6e9f62f18d4eaa
|
||||
F src/global.c 9bf034fd560bdd514715170ed8460bb7f823cec113f0569ef3f18a20c7ccd128
|
||||
F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
|
||||
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
||||
@ -467,7 +467,7 @@ F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
F src/memdb.c e94c478a757c4307fd170fe0a7650ef4cf722c59e5a95a8a7896ffedc1679139
|
||||
F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661
|
||||
F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81
|
||||
F src/mutex.c b021263554c8a3995e9d53193b8194b96d1ed28e06c3b532dd7f7d29cf0c7d53
|
||||
F src/mutex.c bae36f8af32c22ad80bbf0ccebec63c252b6a2b86e4d3e42672ff287ebf4a604
|
||||
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
|
||||
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
|
||||
F src/mutex_unix.c aaf9ebc3f89df28483c52208497a99a02cc3650011422fc9d4c57e4392f7fe58
|
||||
@ -486,19 +486,19 @@ F src/parse.y 07784439d25f0bc64a656eece4caecc549b147d213f513cdbeb8430345ec2911
|
||||
F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd
|
||||
F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
|
||||
F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
|
||||
F src/pragma.c bea56df3ae0637768c0da4fbbb8f2492f780980d95000034a105ff291bf7ca69
|
||||
F src/pragma.c c0d13c0e82a9197aef5533d63300c5b0c8a216ae1fd14ada64e1f12f398d7e82
|
||||
F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
|
||||
F src/prepare.c 95a9dba7a5d032039a77775188cb3b6fb17f2fa1a0b7cd915b30b4b823383ffa
|
||||
F src/printf.c d3b7844ddeb11fbbdd38dd84d09c9c1ac171d21fb038473c3aa97981201cc660
|
||||
F src/printf.c fb76c433bb01c93a0be63c12794540ce830c93947132ee1446cdc131da81ef42
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c 6415381a0e9d22c0e7cba33ca4a53f81474190862f5d4838190f5eb5b0b47bc9
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c a35d462ee7a3c0856ad7a9d9c8921fbf3d91d911a8f39ad9d61302eb43b24a71
|
||||
F src/shell.c.in df233d5556008e330570da3dc4aa837af1df01d95ca5a15beb67b8515302c36a
|
||||
F src/sqlite.h.in 90953956babca76c5462487d9f08df6f3d5cc61c12f5f21a668e4fcc069ac03c
|
||||
F src/sqlite.h.in 934a3e0e1e581efcd3b7c463c89fd8658ebd25bf38f6c7e700ba2e8d1c4cb632
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 83a3c4ce93d650bedfd1aa558cb85a516bd6d094445ee989740827d0d944368d
|
||||
F src/sqliteInt.h 4b98a37f27033ca887f2027f9a60636625fb2a4a9ef1b96c17f0db8fd951891f
|
||||
F src/sqliteInt.h 5abdade4744cf3bd567afb65bb144bb3c61f6132f86813b995a5ca79c7b584e8
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
@ -556,7 +556,7 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c bbde32eac9eb1280f5292bcdfef66f5a57e43176cbf9347e0efab9f75e133f97
|
||||
F src/treeview.c 06dd506b1dcef01c5882a4189bc79afe2660dd992702f81cd7d003425a99cfbc
|
||||
F src/treeview.c 2c5c4bc0a443401db5fd621542150452ddf5055d38edd4eef868bc2b6bfb0260
|
||||
F src/trigger.c 4ace6d1d5ba9a89822deb287317f33c810440526eafe185c2d8a48c31df1e995
|
||||
F src/update.c 5be2f501ddc704fc04183bdb28b25eab930bb8553d973429a089ec94fa85cf2b
|
||||
F src/upsert.c ae4a4823b45c4daf87e8aea8c0f582a8844763271f5ed54ee5956c4c612734f4
|
||||
@ -567,11 +567,11 @@ F src/vdbe.c 066a4e1de2ed83e253adfd2e97a684cf562eaa41d31ee7f3d3e4c8aea4485a55
|
||||
F src/vdbe.h d970d9738efdd09cb2df73e3a40856e7df13e88a3486789c49fcdd322c9eb8a2
|
||||
F src/vdbeInt.h 95f7adfdc5c8f1353321f55a6c5ec00a90877e3b85af5159e393afb41ff54110
|
||||
F src/vdbeapi.c 29d2baf9c1233131ec467d7bed1b7c8a03c27579048d768c4b04acf427838858
|
||||
F src/vdbeaux.c 58129ae46be079613df5c2c3714d80a78605415bfa10c9528634c7c2d2147727
|
||||
F src/vdbeaux.c f1cb5ae6e42c54d4991e2951e5293c1e18bad6847056e9b17622fbf6b17964a9
|
||||
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
||||
F src/vdbemem.c 0cbe9b9560e42b72983cf9e1bceba48f297e51142bfb6b57f3747cf60106b92d
|
||||
F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f
|
||||
F src/vdbetrace.c 48e11ebe040c6b41d146abed2602e3d00d621d7ebe4eb29b0a0f1617fd3c2f6c
|
||||
F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
|
||||
F src/vtab.c 0e4885495172e1bdf54b12cce23b395ac74ef5729031f15e1bc1e3e6b360ed1a
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0
|
||||
@ -579,7 +579,7 @@ F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
|
||||
F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f
|
||||
F src/where.c d89b1aa56a75a572cd60ad27ec0fe5958d5f98b0f4391a89c72811287be7c439
|
||||
F src/whereInt.h cbae2bcd37cfebdb7812a8b188cdb19634ced2b9346470d1c270556b0c33ea53
|
||||
F src/wherecode.c 414ec42097b295febcae9c8803cf627580ad9005de1d8bc3afad3d3127f0eb86
|
||||
F src/wherecode.c 728c7f70731430ccdac807a79969873e1af6968bf1c4745dff3f9dd35f636cc8
|
||||
F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
@ -1728,7 +1728,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 0c3f128fd7d5738a8e9da706f5f30aa1985ef5efab70ddaad28ef6b641b04f4a
|
||||
R 2c62d3beecc0dc62689392fea52a44aa
|
||||
P b866693e6a50b5c41ca54b56bb20753efb94980ad3365c511cccf23ac43a1c23
|
||||
R 68264eb483f86d69689e19bb38cf694a
|
||||
U drh
|
||||
Z 9f515593856c1a56e94f7a12690a8e77
|
||||
Z 4acceaf152c7a58a98e5d6dcf41cb498
|
||||
|
@ -1 +1 @@
|
||||
b866693e6a50b5c41ca54b56bb20753efb94980ad3365c511cccf23ac43a1c23
|
||||
87f261f0cb800b06ad786f6df16f2c4dddd0d93dfdcc77b4a4eaa22920b56bf1
|
12
src/btree.c
12
src/btree.c
@ -9250,14 +9250,14 @@ static void checkAppendMsg(
|
||||
pCheck->nErr++;
|
||||
va_start(ap, zFormat);
|
||||
if( pCheck->errMsg.nChar ){
|
||||
sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
|
||||
sqlite3_str_append(&pCheck->errMsg, "\n", 1);
|
||||
}
|
||||
if( pCheck->zPfx ){
|
||||
sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
|
||||
sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
|
||||
}
|
||||
sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap);
|
||||
sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap);
|
||||
va_end(ap);
|
||||
if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
|
||||
if( pCheck->errMsg.accError==SQLITE_NOMEM ){
|
||||
pCheck->mallocFailed = 1;
|
||||
}
|
||||
}
|
||||
@ -9841,11 +9841,11 @@ integrity_ck_cleanup:
|
||||
sqlite3PageFree(sCheck.heap);
|
||||
sqlite3_free(sCheck.aPgRef);
|
||||
if( sCheck.mallocFailed ){
|
||||
sqlite3StrAccumReset(&sCheck.errMsg);
|
||||
sqlite3_str_reset(&sCheck.errMsg);
|
||||
sCheck.nErr++;
|
||||
}
|
||||
*pnErr = sCheck.nErr;
|
||||
if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
|
||||
if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg);
|
||||
/* Make sure this analysis did not leave any unref() pages. */
|
||||
assert( nRef==sqlite3PagerRefcount(pBt->pPager) );
|
||||
sqlite3BtreeLeave(p);
|
||||
|
10
src/build.c
10
src/build.c
@ -4207,16 +4207,16 @@ void sqlite3UniqueConstraint(
|
||||
|
||||
sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
|
||||
if( pIdx->aColExpr ){
|
||||
sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName);
|
||||
sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName);
|
||||
}else{
|
||||
for(j=0; j<pIdx->nKeyCol; j++){
|
||||
char *zCol;
|
||||
assert( pIdx->aiColumn[j]>=0 );
|
||||
zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
|
||||
if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
|
||||
sqlite3StrAccumAppendAll(&errMsg, pTab->zName);
|
||||
sqlite3StrAccumAppend(&errMsg, ".", 1);
|
||||
sqlite3StrAccumAppendAll(&errMsg, zCol);
|
||||
if( j ) sqlite3_str_append(&errMsg, ", ", 2);
|
||||
sqlite3_str_appendall(&errMsg, pTab->zName);
|
||||
sqlite3_str_append(&errMsg, ".", 1);
|
||||
sqlite3_str_appendall(&errMsg, zCol);
|
||||
}
|
||||
}
|
||||
zErr = sqlite3StrAccumFinish(&errMsg);
|
||||
|
10
src/func.c
10
src/func.c
@ -251,7 +251,7 @@ static void printfFunc(
|
||||
x.apArg = argv+1;
|
||||
sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
|
||||
str.printfFlags = SQLITE_PRINTF_SQLFUNC;
|
||||
sqlite3XPrintf(&str, zFormat, &x);
|
||||
sqlite3_str_appendf(&str, zFormat, &x);
|
||||
n = str.nChar;
|
||||
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
|
||||
SQLITE_DYNAMIC);
|
||||
@ -1654,20 +1654,20 @@ static void groupConcatStep(
|
||||
zSep = ",";
|
||||
nSep = 1;
|
||||
}
|
||||
if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
|
||||
if( zSep ) sqlite3_str_append(pAccum, zSep, nSep);
|
||||
}
|
||||
zVal = (char*)sqlite3_value_text(argv[0]);
|
||||
nVal = sqlite3_value_bytes(argv[0]);
|
||||
if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal);
|
||||
if( zVal ) sqlite3_str_append(pAccum, zVal, nVal);
|
||||
}
|
||||
}
|
||||
static void groupConcatFinalize(sqlite3_context *context){
|
||||
StrAccum *pAccum;
|
||||
pAccum = sqlite3_aggregate_context(context, 0);
|
||||
if( pAccum ){
|
||||
if( pAccum->accError==STRACCUM_TOOBIG ){
|
||||
if( pAccum->accError==SQLITE_TOOBIG ){
|
||||
sqlite3_result_error_toobig(context);
|
||||
}else if( pAccum->accError==STRACCUM_NOMEM ){
|
||||
}else if( pAccum->accError==SQLITE_NOMEM ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
}else{
|
||||
sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1,
|
||||
|
@ -358,4 +358,3 @@ int sqlite3_mutex_notheld(sqlite3_mutex *p){
|
||||
#endif
|
||||
|
||||
#endif /* !defined(SQLITE_MUTEX_OMIT) */
|
||||
|
||||
|
20
src/pragma.c
20
src/pragma.c
@ -2216,26 +2216,26 @@ static int pragmaVtabConnect(
|
||||
UNUSED_PARAMETER(argc);
|
||||
UNUSED_PARAMETER(argv);
|
||||
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
|
||||
sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x");
|
||||
sqlite3_str_appendall(&acc, "CREATE TABLE x");
|
||||
for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
|
||||
sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]);
|
||||
sqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]);
|
||||
cSep = ',';
|
||||
}
|
||||
if( i==0 ){
|
||||
sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName);
|
||||
sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName);
|
||||
cSep = ',';
|
||||
i++;
|
||||
}
|
||||
j = 0;
|
||||
if( pPragma->mPragFlg & PragFlg_Result1 ){
|
||||
sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN");
|
||||
sqlite3_str_appendall(&acc, ",arg HIDDEN");
|
||||
j++;
|
||||
}
|
||||
if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){
|
||||
sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN");
|
||||
sqlite3_str_appendall(&acc, ",schema HIDDEN");
|
||||
j++;
|
||||
}
|
||||
sqlite3StrAccumAppend(&acc, ")", 1);
|
||||
sqlite3_str_append(&acc, ")", 1);
|
||||
sqlite3StrAccumFinish(&acc);
|
||||
assert( strlen(zBuf) < sizeof(zBuf)-1 );
|
||||
rc = sqlite3_declare_vtab(db, zBuf);
|
||||
@ -2387,13 +2387,13 @@ static int pragmaVtabFilter(
|
||||
}
|
||||
}
|
||||
sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
|
||||
sqlite3StrAccumAppendAll(&acc, "PRAGMA ");
|
||||
sqlite3_str_appendall(&acc, "PRAGMA ");
|
||||
if( pCsr->azArg[1] ){
|
||||
sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]);
|
||||
sqlite3_str_appendf(&acc, "%Q.", pCsr->azArg[1]);
|
||||
}
|
||||
sqlite3StrAccumAppendAll(&acc, pTab->pName->zName);
|
||||
sqlite3_str_appendall(&acc, pTab->pName->zName);
|
||||
if( pCsr->azArg[0] ){
|
||||
sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]);
|
||||
sqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]);
|
||||
}
|
||||
zSql = sqlite3StrAccumFinish(&acc);
|
||||
if( zSql==0 ) return SQLITE_NOMEM;
|
||||
|
123
src/printf.c
123
src/printf.c
@ -134,7 +134,7 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
|
||||
** Set the StrAccum object to an error mode.
|
||||
*/
|
||||
static void setStrAccumError(StrAccum *p, u8 eError){
|
||||
assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG );
|
||||
assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG );
|
||||
p->accError = eError;
|
||||
p->nAlloc = 0;
|
||||
}
|
||||
@ -168,8 +168,8 @@ static char *getTextArg(PrintfArguments *p){
|
||||
/*
|
||||
** Render a string given by "fmt" into the StrAccum object.
|
||||
*/
|
||||
void sqlite3VXPrintf(
|
||||
StrAccum *pAccum, /* Accumulate results here */
|
||||
void sqlite3_str_vappendf(
|
||||
sqlite3_str *pAccum, /* Accumulate results here */
|
||||
const char *fmt, /* Format string */
|
||||
va_list ap /* arguments */
|
||||
){
|
||||
@ -226,11 +226,11 @@ void sqlite3VXPrintf(
|
||||
#else
|
||||
do{ fmt++; }while( *fmt && *fmt != '%' );
|
||||
#endif
|
||||
sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt));
|
||||
sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt));
|
||||
if( *fmt==0 ) break;
|
||||
}
|
||||
if( (c=(*++fmt))==0 ){
|
||||
sqlite3StrAccumAppend(pAccum, "%", 1);
|
||||
sqlite3_str_append(pAccum, "%", 1);
|
||||
break;
|
||||
}
|
||||
/* Find out what flags are present */
|
||||
@ -408,7 +408,7 @@ void sqlite3VXPrintf(
|
||||
u64 n = (u64)precision + 10 + precision/3;
|
||||
zOut = zExtra = sqlite3Malloc( n );
|
||||
if( zOut==0 ){
|
||||
setStrAccumError(pAccum, STRACCUM_NOMEM);
|
||||
setStrAccumError(pAccum, SQLITE_NOMEM);
|
||||
return;
|
||||
}
|
||||
nOut = (int)n;
|
||||
@ -533,7 +533,7 @@ void sqlite3VXPrintf(
|
||||
bufpt = zExtra
|
||||
= sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
|
||||
if( bufpt==0 ){
|
||||
setStrAccumError(pAccum, STRACCUM_NOMEM);
|
||||
setStrAccumError(pAccum, SQLITE_NOMEM);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -665,11 +665,11 @@ void sqlite3VXPrintf(
|
||||
if( precision>1 ){
|
||||
width -= precision-1;
|
||||
if( width>1 && !flag_leftjustify ){
|
||||
sqlite3AppendChar(pAccum, width-1, ' ');
|
||||
sqlite3_str_appendchar(pAccum, width-1, ' ');
|
||||
width = 0;
|
||||
}
|
||||
while( precision-- > 1 ){
|
||||
sqlite3StrAccumAppend(pAccum, buf, length);
|
||||
sqlite3_str_append(pAccum, buf, length);
|
||||
}
|
||||
}
|
||||
bufpt = buf;
|
||||
@ -755,7 +755,7 @@ void sqlite3VXPrintf(
|
||||
if( n>etBUFSIZE ){
|
||||
bufpt = zExtra = sqlite3Malloc( n );
|
||||
if( bufpt==0 ){
|
||||
setStrAccumError(pAccum, STRACCUM_NOMEM);
|
||||
setStrAccumError(pAccum, SQLITE_NOMEM);
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
@ -779,7 +779,7 @@ void sqlite3VXPrintf(
|
||||
pToken = va_arg(ap, Token*);
|
||||
assert( bArgList==0 );
|
||||
if( pToken && pToken->n ){
|
||||
sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
|
||||
sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
|
||||
}
|
||||
length = width = 0;
|
||||
break;
|
||||
@ -795,10 +795,10 @@ void sqlite3VXPrintf(
|
||||
assert( bArgList==0 );
|
||||
assert( k>=0 && k<pSrc->nSrc );
|
||||
if( pItem->zDatabase ){
|
||||
sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase);
|
||||
sqlite3StrAccumAppend(pAccum, ".", 1);
|
||||
sqlite3_str_appendall(pAccum, pItem->zDatabase);
|
||||
sqlite3_str_append(pAccum, ".", 1);
|
||||
}
|
||||
sqlite3StrAccumAppendAll(pAccum, pItem->zName);
|
||||
sqlite3_str_appendall(pAccum, pItem->zName);
|
||||
length = width = 0;
|
||||
break;
|
||||
}
|
||||
@ -817,11 +817,11 @@ void sqlite3VXPrintf(
|
||||
*/
|
||||
width -= length;
|
||||
if( width>0 ){
|
||||
if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
|
||||
sqlite3StrAccumAppend(pAccum, bufpt, length);
|
||||
if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
|
||||
if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
|
||||
sqlite3_str_append(pAccum, bufpt, length);
|
||||
if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
|
||||
}else{
|
||||
sqlite3StrAccumAppend(pAccum, bufpt, length);
|
||||
sqlite3_str_append(pAccum, bufpt, length);
|
||||
}
|
||||
|
||||
if( zExtra ){
|
||||
@ -842,13 +842,13 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
||||
char *zNew;
|
||||
assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
|
||||
if( p->accError ){
|
||||
testcase(p->accError==STRACCUM_TOOBIG);
|
||||
testcase(p->accError==STRACCUM_NOMEM);
|
||||
testcase(p->accError==SQLITE_TOOBIG);
|
||||
testcase(p->accError==SQLITE_NOMEM);
|
||||
return 0;
|
||||
}
|
||||
if( p->mxAlloc==0 ){
|
||||
N = p->nAlloc - p->nChar - 1;
|
||||
setStrAccumError(p, STRACCUM_TOOBIG);
|
||||
setStrAccumError(p, SQLITE_TOOBIG);
|
||||
return N;
|
||||
}else{
|
||||
char *zOld = isMalloced(p) ? p->zText : 0;
|
||||
@ -860,8 +860,8 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
||||
szNew += p->nChar;
|
||||
}
|
||||
if( szNew > p->mxAlloc ){
|
||||
sqlite3StrAccumReset(p);
|
||||
setStrAccumError(p, STRACCUM_TOOBIG);
|
||||
sqlite3_str_reset(p);
|
||||
setStrAccumError(p, SQLITE_TOOBIG);
|
||||
return 0;
|
||||
}else{
|
||||
p->nAlloc = (int)szNew;
|
||||
@ -878,8 +878,8 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
||||
p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
|
||||
p->printfFlags |= SQLITE_PRINTF_MALLOCED;
|
||||
}else{
|
||||
sqlite3StrAccumReset(p);
|
||||
setStrAccumError(p, STRACCUM_NOMEM);
|
||||
sqlite3_str_reset(p);
|
||||
setStrAccumError(p, SQLITE_NOMEM);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -889,7 +889,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
||||
/*
|
||||
** Append N copies of character c to the given string buffer.
|
||||
*/
|
||||
void sqlite3AppendChar(StrAccum *p, int N, char c){
|
||||
void sqlite3_str_appendchar(sqlite3_str *p, int N, char c){
|
||||
testcase( p->nChar + (i64)N > 0x7fffffff );
|
||||
if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
|
||||
return;
|
||||
@ -901,9 +901,9 @@ void sqlite3AppendChar(StrAccum *p, int N, char c){
|
||||
** The StrAccum "p" is not large enough to accept N new bytes of z[].
|
||||
** So enlarge if first, then do the append.
|
||||
**
|
||||
** This is a helper routine to sqlite3StrAccumAppend() that does special-case
|
||||
** This is a helper routine to sqlite3_str_append() that does special-case
|
||||
** work (enlarging the buffer) using tail recursion, so that the
|
||||
** sqlite3StrAccumAppend() routine can use fast calling semantics.
|
||||
** sqlite3_str_append() routine can use fast calling semantics.
|
||||
*/
|
||||
static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
|
||||
N = sqlite3StrAccumEnlarge(p, N);
|
||||
@ -917,7 +917,7 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
|
||||
** Append N bytes of text from z to the StrAccum object. Increase the
|
||||
** size of the memory allocation for StrAccum if necessary.
|
||||
*/
|
||||
void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
|
||||
void sqlite3_str_append(sqlite3_str *p, const char *z, int N){
|
||||
assert( z!=0 || N==0 );
|
||||
assert( p->zText!=0 || p->nChar==0 || p->accError );
|
||||
assert( N>=0 );
|
||||
@ -934,8 +934,8 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
|
||||
/*
|
||||
** Append the complete text of zero-terminated string z[] to the p string.
|
||||
*/
|
||||
void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
|
||||
sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z));
|
||||
void sqlite3_str_appendall(sqlite3_str *p, const char *z){
|
||||
sqlite3_str_append(p, z, sqlite3Strlen30(z));
|
||||
}
|
||||
|
||||
|
||||
@ -952,7 +952,7 @@ static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){
|
||||
memcpy(zText, p->zText, p->nChar+1);
|
||||
p->printfFlags |= SQLITE_PRINTF_MALLOCED;
|
||||
}else{
|
||||
setStrAccumError(p, STRACCUM_NOMEM);
|
||||
setStrAccumError(p, SQLITE_NOMEM);
|
||||
}
|
||||
p->zText = zText;
|
||||
return zText;
|
||||
@ -967,10 +967,38 @@ char *sqlite3StrAccumFinish(StrAccum *p){
|
||||
return p->zText;
|
||||
}
|
||||
|
||||
/* Finalize a string created using sqlite3_str_new().
|
||||
*/
|
||||
char *sqlite3_str_finish(sqlite3_str *p){
|
||||
char *z;
|
||||
if( p ){
|
||||
z = sqlite3StrAccumFinish(p);
|
||||
sqlite3DbFree(p->db, p);
|
||||
}else{
|
||||
z = 0;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
/* Return any error code associated with p */
|
||||
int sqlite3_str_errcode(sqlite3_str *p){
|
||||
return p ? p->accError : SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
/* Return the current length of p in bytes */
|
||||
int sqlite3_str_length(sqlite3_str *p){
|
||||
return p ? p->nChar : 0;
|
||||
}
|
||||
|
||||
/* Return the current value for p */
|
||||
char *sqlite3_str_value(sqlite3_str *p){
|
||||
return p ? p->zText : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Reset an StrAccum string. Reclaim all malloced memory.
|
||||
*/
|
||||
void sqlite3StrAccumReset(StrAccum *p){
|
||||
void sqlite3_str_reset(StrAccum *p){
|
||||
if( isMalloced(p) ){
|
||||
sqlite3DbFree(p->db, p->zText);
|
||||
p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
|
||||
@ -1002,6 +1030,15 @@ void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
|
||||
p->printfFlags = 0;
|
||||
}
|
||||
|
||||
/* Allocate and initialize a new dynamic string object */
|
||||
sqlite3_str *sqlite3_str_new(sqlite3 *db){
|
||||
sqlite3_str *p = sqlite3DbMallocRaw(db, sizeof(*p));
|
||||
if( p ){
|
||||
sqlite3StrAccumInit(p, db, 0, 0, SQLITE_MAX_LENGTH);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Print into memory obtained from sqliteMalloc(). Use the internal
|
||||
** %-conversion extensions.
|
||||
@ -1014,9 +1051,9 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
|
||||
sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
|
||||
db->aLimit[SQLITE_LIMIT_LENGTH]);
|
||||
acc.printfFlags = SQLITE_PRINTF_INTERNAL;
|
||||
sqlite3VXPrintf(&acc, zFormat, ap);
|
||||
sqlite3_str_vappendf(&acc, zFormat, ap);
|
||||
z = sqlite3StrAccumFinish(&acc);
|
||||
if( acc.accError==STRACCUM_NOMEM ){
|
||||
if( acc.accError==SQLITE_NOMEM ){
|
||||
sqlite3OomFault(db);
|
||||
}
|
||||
return z;
|
||||
@ -1054,7 +1091,7 @@ char *sqlite3_vmprintf(const char *zFormat, va_list ap){
|
||||
if( sqlite3_initialize() ) return 0;
|
||||
#endif
|
||||
sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
|
||||
sqlite3VXPrintf(&acc, zFormat, ap);
|
||||
sqlite3_str_vappendf(&acc, zFormat, ap);
|
||||
z = sqlite3StrAccumFinish(&acc);
|
||||
return z;
|
||||
}
|
||||
@ -1099,7 +1136,7 @@ char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
|
||||
}
|
||||
#endif
|
||||
sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
|
||||
sqlite3VXPrintf(&acc, zFormat, ap);
|
||||
sqlite3_str_vappendf(&acc, zFormat, ap);
|
||||
zBuf[acc.nChar] = 0;
|
||||
return zBuf;
|
||||
}
|
||||
@ -1121,7 +1158,7 @@ char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
|
||||
** allocate memory because it might be called while the memory allocator
|
||||
** mutex is held.
|
||||
**
|
||||
** sqlite3VXPrintf() might ask for *temporary* memory allocations for
|
||||
** sqlite3_str_vappendf() might ask for *temporary* memory allocations for
|
||||
** certain format characters (%q) or for very large precisions or widths.
|
||||
** Care must be taken that any sqlite3_log() calls that occur while the
|
||||
** memory mutex is held do not use these mechanisms.
|
||||
@ -1131,7 +1168,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
|
||||
char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
|
||||
|
||||
sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
|
||||
sqlite3VXPrintf(&acc, zFormat, ap);
|
||||
sqlite3_str_vappendf(&acc, zFormat, ap);
|
||||
sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
|
||||
sqlite3StrAccumFinish(&acc));
|
||||
}
|
||||
@ -1160,7 +1197,7 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
|
||||
char zBuf[500];
|
||||
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
|
||||
va_start(ap,zFormat);
|
||||
sqlite3VXPrintf(&acc, zFormat, ap);
|
||||
sqlite3_str_vappendf(&acc, zFormat, ap);
|
||||
va_end(ap);
|
||||
sqlite3StrAccumFinish(&acc);
|
||||
#ifdef SQLITE_OS_TRACE_PROC
|
||||
@ -1177,12 +1214,12 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
|
||||
|
||||
|
||||
/*
|
||||
** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument
|
||||
** variable-argument wrapper around sqlite3_str_vappendf(). The bFlags argument
|
||||
** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
|
||||
*/
|
||||
void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
|
||||
void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
va_start(ap,zFormat);
|
||||
sqlite3VXPrintf(p, zFormat, ap);
|
||||
sqlite3_str_vappendf(p, zFormat, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
127
src/sqlite.h.in
127
src/sqlite.h.in
@ -7132,6 +7132,133 @@ int sqlite3_keyword_count(void);
|
||||
int sqlite3_keyword_name(int,const char**,int*);
|
||||
int sqlite3_keyword_check(const char*,int);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Dynamic String Object
|
||||
** KEYWORDS: {dynamic string}
|
||||
**
|
||||
** An instance of the sqlite3_str object contains a dynamically-sized
|
||||
** string under construction.
|
||||
**
|
||||
** The lifecycle of an sqlite3_str object is as follows:
|
||||
** <ol>
|
||||
** <li> The sqlite3_str object is created using [sqlite3_str_new()].
|
||||
** <li> Text is appended to the sqlite3_str object using various
|
||||
** methods, such as [sqlite3_str_appendf()].
|
||||
** <li> The sqlite3_str object is destroyed and the string it created
|
||||
** is returned using the [sqlite3_str_finish()] interface.
|
||||
** </ol>
|
||||
*/
|
||||
typedef struct sqlite3_str sqlite3_str;
|
||||
|
||||
/*
|
||||
** CAPI3REF: Create A New Dynamic String Object
|
||||
** CONSTRUCTOR: sqlite3_str
|
||||
**
|
||||
** The [sqlite3_str_new(D)] allocates and initializes a new [sqlite3_str]
|
||||
** object. The [sqlite3_str_new(D)] interface returns NULL on an out-of-memory
|
||||
** condition. To avoid memory leaks, the object returned by
|
||||
** [sqlite3_str_new(D)] must be freed by a subsequent call to
|
||||
** [sqlite3_str_finish(S)].
|
||||
**
|
||||
** If the D argument to [sqlite3_str_new(D)] is NULL then memory used to
|
||||
** construct the string is always taken from the global memory pool used
|
||||
** by [sqlite3_malloc64()]. If D is not NULL, then a private memory pool
|
||||
** used by connection D might also be used. This private memory pool is
|
||||
** faster, but is limited in space, and should only be used for transient
|
||||
** allocations. The final string returned by [sqlite3_str_finish(X)] is
|
||||
** always stored in space obtained from [sqlite3_malloc64()] regardless
|
||||
** of whether or not the private per-connection memory pool is used during
|
||||
** its construction.
|
||||
*/
|
||||
sqlite3_str *sqlite3_str_new(sqlite3*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Finalize A Dynamic String
|
||||
** DESTRUCTOR: sqlite3_str
|
||||
**
|
||||
** The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X
|
||||
** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()]
|
||||
** that contains the constructed string. The calling application should
|
||||
** pass the returned value to [sqlite3_free()] to avoid a memory leak.
|
||||
** The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
|
||||
** errors were encountered during construction of the string. The
|
||||
** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
|
||||
** string in [sqlite3_str] object X is zero bytes long.
|
||||
*/
|
||||
char *sqlite3_str_finish(sqlite3_str*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Add Content To A Dynamic String
|
||||
** METHOD: sqlite3_str
|
||||
**
|
||||
** These interfaces add content to an sqlite3_str object previously obtained
|
||||
** from [sqlite3_str_new()].
|
||||
**
|
||||
** The [sqlite3_str_appendf(X,F,...)] and
|
||||
** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
|
||||
** functionality of SQLite to append formatted text onto the end of
|
||||
** [sqlite3_str] object X.
|
||||
**
|
||||
** The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S
|
||||
** onto the end of the [sqlite3_str] object X. N must be non-negative.
|
||||
** S must contain at least N non-zero bytes of content. To append a
|
||||
** zero-terminated string in its entirety, use the [sqlite3_str_appendall()]
|
||||
** method instead.
|
||||
**
|
||||
** The [sqlite3_str_appendall(X,S)] method the complete content of
|
||||
** zero-terminated string S onto the end of [sqlite3_str] object X.
|
||||
**
|
||||
** The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the
|
||||
** single-byte character C onto the end of [sqlite3_str] object X.
|
||||
** This method can be used, for example, to add whitespace indentation.
|
||||
**
|
||||
** The [sqlite3_str_reset(X)] method resets the string under construction
|
||||
** inside [sqlite3_str] object X back to zero bytes in length.
|
||||
**
|
||||
** These methods do not return a result code. If an error occurs, that fact
|
||||
** is recorded in the [sqlite3_str] object and can be recovered by a
|
||||
** subsequent call to [sqlite3_str_errcode(X)].
|
||||
*/
|
||||
void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);
|
||||
void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
|
||||
void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
|
||||
void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
|
||||
void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
|
||||
void sqlite3_str_reset(sqlite3_str*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Status Of A Dynamic String
|
||||
** METHOD: sqlite3_str
|
||||
**
|
||||
** These interfaces return the current status of an [sqlite3_str] object.
|
||||
**
|
||||
** If any prior errors have occurred while constructing the dynamic string
|
||||
** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return
|
||||
** an appropriate error code. The [sqlite3_str_errcode(X)] method returns
|
||||
** [SQLITE_NOMEM] following any out-of-memory error, or
|
||||
** [SQLITE_TOOBIG] if the size of the dynamic string exceeds
|
||||
** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors.
|
||||
**
|
||||
** The [sqlite3_str_length(X)] method returns the current length, in bytes,
|
||||
** of the dynamic string under construction in [sqlite3_str] object X.
|
||||
** The length returned by [sqlite3_str_length(X)] does not include the
|
||||
** zero-termination byte.
|
||||
**
|
||||
** The [sqlite3_str_value(X)] method returns a pointer to the current
|
||||
** content of the dynamic string under construction in X. The value
|
||||
** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
|
||||
** and might be freed or altered by any subsequent method on the same
|
||||
** [sqlite3_str] object. Applications must not used the pointer returned
|
||||
** [sqlite3_str_value(X)] after any subsequent method call on the same
|
||||
** object. Applications may change the content of the string returned
|
||||
** by [sqlite3_str_value(X)] as long as they do not write into any bytes
|
||||
** outside the range of 0 to [sqlite3_str_length(X)] and do not read or
|
||||
** write any byte after any subsequent sqlite3_str method call.
|
||||
*/
|
||||
int sqlite3_str_errcode(sqlite3_str*);
|
||||
int sqlite3_str_length(sqlite3_str*);
|
||||
char *sqlite3_str_value(sqlite3_str*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: SQLite Runtime Status
|
||||
**
|
||||
|
@ -1093,7 +1093,7 @@ typedef struct Select Select;
|
||||
typedef struct SQLiteThread SQLiteThread;
|
||||
typedef struct SelectDest SelectDest;
|
||||
typedef struct SrcList SrcList;
|
||||
typedef struct StrAccum StrAccum;
|
||||
typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
|
||||
typedef struct Table Table;
|
||||
typedef struct TableLock TableLock;
|
||||
typedef struct Token Token;
|
||||
@ -3273,17 +3273,15 @@ struct DbFixer {
|
||||
** An objected used to accumulate the text of a string where we
|
||||
** do not necessarily know how big the string will be in the end.
|
||||
*/
|
||||
struct StrAccum {
|
||||
struct sqlite3_str {
|
||||
sqlite3 *db; /* Optional database for lookaside. Can be NULL */
|
||||
char *zText; /* The string collected so far */
|
||||
u32 nAlloc; /* Amount of space allocated in zText */
|
||||
u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
|
||||
u32 nChar; /* Length of the string so far */
|
||||
u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
|
||||
u8 accError; /* SQLITE_NOMEM or SQLITE_TOOBIG */
|
||||
u8 printfFlags; /* SQLITE_PRINTF flags below */
|
||||
};
|
||||
#define STRACCUM_NOMEM 1
|
||||
#define STRACCUM_TOOBIG 2
|
||||
#define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */
|
||||
#define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */
|
||||
#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */
|
||||
@ -3652,8 +3650,6 @@ struct PrintfArguments {
|
||||
sqlite3_value **apArg; /* The argument values */
|
||||
};
|
||||
|
||||
void sqlite3VXPrintf(StrAccum*, const char*, va_list);
|
||||
void sqlite3XPrintf(StrAccum*, const char*, ...);
|
||||
char *sqlite3MPrintf(sqlite3*,const char*, ...);
|
||||
char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
|
||||
@ -4176,11 +4172,7 @@ int sqlite3ApiExit(sqlite3 *db, int);
|
||||
int sqlite3OpenTempDatabase(Parse *);
|
||||
|
||||
void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
|
||||
void sqlite3StrAccumAppend(StrAccum*,const char*,int);
|
||||
void sqlite3StrAccumAppendAll(StrAccum*,const char*);
|
||||
void sqlite3AppendChar(StrAccum*,int,char);
|
||||
char *sqlite3StrAccumFinish(StrAccum*);
|
||||
void sqlite3StrAccumReset(StrAccum*);
|
||||
void sqlite3SelectDestInit(SelectDest*,int,int);
|
||||
Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
|
||||
|
||||
|
@ -58,16 +58,16 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
|
||||
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
|
||||
if( p ){
|
||||
for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
|
||||
sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4);
|
||||
sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4);
|
||||
}
|
||||
sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
|
||||
sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
|
||||
}
|
||||
if( zFormat!=0 ){
|
||||
va_start(ap, zFormat);
|
||||
sqlite3VXPrintf(&acc, zFormat, ap);
|
||||
sqlite3_str_vappendf(&acc, zFormat, ap);
|
||||
va_end(ap);
|
||||
assert( acc.nChar>0 );
|
||||
sqlite3StrAccumAppend(&acc, "\n", 1);
|
||||
sqlite3_str_append(&acc, "\n", 1);
|
||||
}
|
||||
sqlite3StrAccumFinish(&acc);
|
||||
fprintf(stdout,"%s", zBuf);
|
||||
@ -101,17 +101,17 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){
|
||||
char zLine[1000];
|
||||
const struct Cte *pCte = &pWith->a[i];
|
||||
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
|
||||
sqlite3XPrintf(&x, "%s", pCte->zName);
|
||||
sqlite3_str_appendf(&x, "%s", pCte->zName);
|
||||
if( pCte->pCols && pCte->pCols->nExpr>0 ){
|
||||
char cSep = '(';
|
||||
int j;
|
||||
for(j=0; j<pCte->pCols->nExpr; j++){
|
||||
sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
|
||||
sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
|
||||
cSep = ',';
|
||||
}
|
||||
sqlite3XPrintf(&x, ")");
|
||||
sqlite3_str_appendf(&x, ")");
|
||||
}
|
||||
sqlite3XPrintf(&x, " AS");
|
||||
sqlite3_str_appendf(&x, " AS");
|
||||
sqlite3StrAccumFinish(&x);
|
||||
sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
|
||||
sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
|
||||
@ -176,20 +176,20 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
StrAccum x;
|
||||
char zLine[100];
|
||||
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
|
||||
sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor);
|
||||
sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
|
||||
if( pItem->zDatabase ){
|
||||
sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
|
||||
sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
|
||||
}else if( pItem->zName ){
|
||||
sqlite3XPrintf(&x, " %s", pItem->zName);
|
||||
sqlite3_str_appendf(&x, " %s", pItem->zName);
|
||||
}
|
||||
if( pItem->pTab ){
|
||||
sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName);
|
||||
sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
|
||||
}
|
||||
if( pItem->zAlias ){
|
||||
sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias);
|
||||
sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
|
||||
}
|
||||
if( pItem->fg.jointype & JT_LEFT ){
|
||||
sqlite3XPrintf(&x, " LEFT-JOIN");
|
||||
sqlite3_str_appendf(&x, " LEFT-JOIN");
|
||||
}
|
||||
sqlite3StrAccumFinish(&x);
|
||||
sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1);
|
||||
|
@ -1306,23 +1306,23 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){
|
||||
const char *zOp = 0;
|
||||
switch( pExpr->op ){
|
||||
case TK_STRING:
|
||||
sqlite3XPrintf(p, "%Q", pExpr->u.zToken);
|
||||
sqlite3_str_appendf(p, "%Q", pExpr->u.zToken);
|
||||
break;
|
||||
case TK_INTEGER:
|
||||
sqlite3XPrintf(p, "%d", pExpr->u.iValue);
|
||||
sqlite3_str_appendf(p, "%d", pExpr->u.iValue);
|
||||
break;
|
||||
case TK_NULL:
|
||||
sqlite3XPrintf(p, "NULL");
|
||||
sqlite3_str_appendf(p, "NULL");
|
||||
break;
|
||||
case TK_REGISTER: {
|
||||
sqlite3XPrintf(p, "r[%d]", pExpr->iTable);
|
||||
sqlite3_str_appendf(p, "r[%d]", pExpr->iTable);
|
||||
break;
|
||||
}
|
||||
case TK_COLUMN: {
|
||||
if( pExpr->iColumn<0 ){
|
||||
sqlite3XPrintf(p, "rowid");
|
||||
sqlite3_str_appendf(p, "rowid");
|
||||
}else{
|
||||
sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn);
|
||||
sqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1354,18 +1354,18 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){
|
||||
case TK_NOTNULL: zOp = "NOTNULL"; break;
|
||||
|
||||
default:
|
||||
sqlite3XPrintf(p, "%s", "expr");
|
||||
sqlite3_str_appendf(p, "%s", "expr");
|
||||
break;
|
||||
}
|
||||
|
||||
if( zOp ){
|
||||
sqlite3XPrintf(p, "%s(", zOp);
|
||||
sqlite3_str_appendf(p, "%s(", zOp);
|
||||
displayP4Expr(p, pExpr->pLeft);
|
||||
if( pExpr->pRight ){
|
||||
sqlite3StrAccumAppend(p, ",", 1);
|
||||
sqlite3_str_append(p, ",", 1);
|
||||
displayP4Expr(p, pExpr->pRight);
|
||||
}
|
||||
sqlite3StrAccumAppend(p, ")", 1);
|
||||
sqlite3_str_append(p, ")", 1);
|
||||
}
|
||||
}
|
||||
#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
|
||||
@ -1386,14 +1386,15 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
int j;
|
||||
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
|
||||
assert( pKeyInfo->aSortOrder!=0 );
|
||||
sqlite3XPrintf(&x, "k(%d", pKeyInfo->nKeyField);
|
||||
sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField);
|
||||
for(j=0; j<pKeyInfo->nKeyField; j++){
|
||||
CollSeq *pColl = pKeyInfo->aColl[j];
|
||||
const char *zColl = pColl ? pColl->zName : "";
|
||||
if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
|
||||
sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
|
||||
sqlite3_str_appendf(&x, ",%s%s",
|
||||
pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
|
||||
}
|
||||
sqlite3StrAccumAppend(&x, ")", 1);
|
||||
sqlite3_str_append(&x, ")", 1);
|
||||
break;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
@ -1404,31 +1405,31 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
#endif
|
||||
case P4_COLLSEQ: {
|
||||
CollSeq *pColl = pOp->p4.pColl;
|
||||
sqlite3XPrintf(&x, "(%.20s)", pColl->zName);
|
||||
sqlite3_str_appendf(&x, "(%.20s)", pColl->zName);
|
||||
break;
|
||||
}
|
||||
case P4_FUNCDEF: {
|
||||
FuncDef *pDef = pOp->p4.pFunc;
|
||||
sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
|
||||
sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
|
||||
break;
|
||||
}
|
||||
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
|
||||
case P4_FUNCCTX: {
|
||||
FuncDef *pDef = pOp->p4.pCtx->pFunc;
|
||||
sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
|
||||
sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case P4_INT64: {
|
||||
sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64);
|
||||
sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64);
|
||||
break;
|
||||
}
|
||||
case P4_INT32: {
|
||||
sqlite3XPrintf(&x, "%d", pOp->p4.i);
|
||||
sqlite3_str_appendf(&x, "%d", pOp->p4.i);
|
||||
break;
|
||||
}
|
||||
case P4_REAL: {
|
||||
sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal);
|
||||
sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal);
|
||||
break;
|
||||
}
|
||||
case P4_MEM: {
|
||||
@ -1436,9 +1437,9 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
if( pMem->flags & MEM_Str ){
|
||||
zP4 = pMem->z;
|
||||
}else if( pMem->flags & MEM_Int ){
|
||||
sqlite3XPrintf(&x, "%lld", pMem->u.i);
|
||||
sqlite3_str_appendf(&x, "%lld", pMem->u.i);
|
||||
}else if( pMem->flags & MEM_Real ){
|
||||
sqlite3XPrintf(&x, "%.16g", pMem->u.r);
|
||||
sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
|
||||
}else if( pMem->flags & MEM_Null ){
|
||||
zP4 = "NULL";
|
||||
}else{
|
||||
@ -1450,7 +1451,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
case P4_VTAB: {
|
||||
sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
|
||||
sqlite3XPrintf(&x, "vtab:%p", pVtab);
|
||||
sqlite3_str_appendf(&x, "vtab:%p", pVtab);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -1460,14 +1461,14 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
int n = ai[0]; /* The first element of an INTARRAY is always the
|
||||
** count of the number of elements to follow */
|
||||
for(i=1; i<=n; i++){
|
||||
sqlite3XPrintf(&x, ",%d", ai[i]);
|
||||
sqlite3_str_appendf(&x, ",%d", ai[i]);
|
||||
}
|
||||
zTemp[0] = '[';
|
||||
sqlite3StrAccumAppend(&x, "]", 1);
|
||||
sqlite3_str_append(&x, "]", 1);
|
||||
break;
|
||||
}
|
||||
case P4_SUBPROGRAM: {
|
||||
sqlite3XPrintf(&x, "program");
|
||||
sqlite3_str_appendf(&x, "program");
|
||||
break;
|
||||
}
|
||||
case P4_DYNBLOB:
|
||||
@ -1476,7 +1477,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
break;
|
||||
}
|
||||
case P4_TABLE: {
|
||||
sqlite3XPrintf(&x, "%s", pOp->p4.pTab->zName);
|
||||
sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
@ -93,17 +93,17 @@ char *sqlite3VdbeExpandSql(
|
||||
while( *zRawSql ){
|
||||
const char *zStart = zRawSql;
|
||||
while( *(zRawSql++)!='\n' && *zRawSql );
|
||||
sqlite3StrAccumAppend(&out, "-- ", 3);
|
||||
sqlite3_str_append(&out, "-- ", 3);
|
||||
assert( (zRawSql - zStart) > 0 );
|
||||
sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
|
||||
sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart));
|
||||
}
|
||||
}else if( p->nVar==0 ){
|
||||
sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql));
|
||||
sqlite3_str_append(&out, zRawSql, sqlite3Strlen30(zRawSql));
|
||||
}else{
|
||||
while( zRawSql[0] ){
|
||||
n = findNextHostParameter(zRawSql, &nToken);
|
||||
assert( n>0 );
|
||||
sqlite3StrAccumAppend(&out, zRawSql, n);
|
||||
sqlite3_str_append(&out, zRawSql, n);
|
||||
zRawSql += n;
|
||||
assert( zRawSql[0] || nToken==0 );
|
||||
if( nToken==0 ) break;
|
||||
@ -129,11 +129,11 @@ char *sqlite3VdbeExpandSql(
|
||||
assert( idx>0 && idx<=p->nVar );
|
||||
pVar = &p->aVar[idx-1];
|
||||
if( pVar->flags & MEM_Null ){
|
||||
sqlite3StrAccumAppend(&out, "NULL", 4);
|
||||
sqlite3_str_append(&out, "NULL", 4);
|
||||
}else if( pVar->flags & MEM_Int ){
|
||||
sqlite3XPrintf(&out, "%lld", pVar->u.i);
|
||||
sqlite3_str_appendf(&out, "%lld", pVar->u.i);
|
||||
}else if( pVar->flags & MEM_Real ){
|
||||
sqlite3XPrintf(&out, "%!.15g", pVar->u.r);
|
||||
sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
|
||||
}else if( pVar->flags & MEM_Str ){
|
||||
int nOut; /* Number of bytes of the string text to include in output */
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
@ -143,7 +143,7 @@ char *sqlite3VdbeExpandSql(
|
||||
utf8.db = db;
|
||||
sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
|
||||
if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){
|
||||
out.accError = STRACCUM_NOMEM;
|
||||
out.accError = SQLITE_NOMEM;
|
||||
out.nAlloc = 0;
|
||||
}
|
||||
pVar = &utf8;
|
||||
@ -156,38 +156,38 @@ char *sqlite3VdbeExpandSql(
|
||||
while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
|
||||
}
|
||||
#endif
|
||||
sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z);
|
||||
sqlite3_str_appendf(&out, "'%.*q'", nOut, pVar->z);
|
||||
#ifdef SQLITE_TRACE_SIZE_LIMIT
|
||||
if( nOut<pVar->n ){
|
||||
sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
|
||||
sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
|
||||
}
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
|
||||
#endif
|
||||
}else if( pVar->flags & MEM_Zero ){
|
||||
sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
|
||||
sqlite3_str_appendf(&out, "zeroblob(%d)", pVar->u.nZero);
|
||||
}else{
|
||||
int nOut; /* Number of bytes of the blob to include in output */
|
||||
assert( pVar->flags & MEM_Blob );
|
||||
sqlite3StrAccumAppend(&out, "x'", 2);
|
||||
sqlite3_str_append(&out, "x'", 2);
|
||||
nOut = pVar->n;
|
||||
#ifdef SQLITE_TRACE_SIZE_LIMIT
|
||||
if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
|
||||
#endif
|
||||
for(i=0; i<nOut; i++){
|
||||
sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
|
||||
sqlite3_str_appendf(&out, "%02x", pVar->z[i]&0xff);
|
||||
}
|
||||
sqlite3StrAccumAppend(&out, "'", 1);
|
||||
sqlite3_str_append(&out, "'", 1);
|
||||
#ifdef SQLITE_TRACE_SIZE_LIMIT
|
||||
if( nOut<pVar->n ){
|
||||
sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
|
||||
sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
if( out.accError ) sqlite3StrAccumReset(&out);
|
||||
if( out.accError ) sqlite3_str_reset(&out);
|
||||
return sqlite3StrAccumFinish(&out);
|
||||
}
|
||||
|
||||
|
@ -51,23 +51,23 @@ static void explainAppendTerm(
|
||||
int i;
|
||||
|
||||
assert( nTerm>=1 );
|
||||
if( bAnd ) sqlite3StrAccumAppend(pStr, " AND ", 5);
|
||||
if( bAnd ) sqlite3_str_append(pStr, " AND ", 5);
|
||||
|
||||
if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
|
||||
if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
|
||||
for(i=0; i<nTerm; i++){
|
||||
if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
|
||||
sqlite3StrAccumAppendAll(pStr, explainIndexColumnName(pIdx, iTerm+i));
|
||||
if( i ) sqlite3_str_append(pStr, ",", 1);
|
||||
sqlite3_str_appendall(pStr, explainIndexColumnName(pIdx, iTerm+i));
|
||||
}
|
||||
if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
|
||||
if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
|
||||
|
||||
sqlite3StrAccumAppend(pStr, zOp, 1);
|
||||
sqlite3_str_append(pStr, zOp, 1);
|
||||
|
||||
if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
|
||||
if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
|
||||
for(i=0; i<nTerm; i++){
|
||||
if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
|
||||
sqlite3StrAccumAppend(pStr, "?", 1);
|
||||
if( i ) sqlite3_str_append(pStr, ",", 1);
|
||||
sqlite3_str_append(pStr, "?", 1);
|
||||
}
|
||||
if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
|
||||
if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -91,11 +91,11 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
|
||||
int i, j;
|
||||
|
||||
if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
|
||||
sqlite3StrAccumAppend(pStr, " (", 2);
|
||||
sqlite3_str_append(pStr, " (", 2);
|
||||
for(i=0; i<nEq; i++){
|
||||
const char *z = explainIndexColumnName(pIndex, i);
|
||||
if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
|
||||
sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
|
||||
if( i ) sqlite3_str_append(pStr, " AND ", 5);
|
||||
sqlite3_str_appendf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
|
||||
}
|
||||
|
||||
j = i;
|
||||
@ -106,7 +106,7 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
|
||||
if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
|
||||
explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<");
|
||||
}
|
||||
sqlite3StrAccumAppend(pStr, ")", 1);
|
||||
sqlite3_str_append(pStr, ")", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -148,15 +148,15 @@ int sqlite3WhereExplainOneScan(
|
||||
|| (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
|
||||
|
||||
sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
|
||||
sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
|
||||
sqlite3_str_appendall(&str, isSearch ? "SEARCH" : "SCAN");
|
||||
if( pItem->pSelect ){
|
||||
sqlite3XPrintf(&str, " SUBQUERY 0x%p", pItem->pSelect);
|
||||
sqlite3_str_appendf(&str, " SUBQUERY 0x%p", pItem->pSelect);
|
||||
}else{
|
||||
sqlite3XPrintf(&str, " TABLE %s", pItem->zName);
|
||||
sqlite3_str_appendf(&str, " TABLE %s", pItem->zName);
|
||||
}
|
||||
|
||||
if( pItem->zAlias ){
|
||||
sqlite3XPrintf(&str, " AS %s", pItem->zAlias);
|
||||
sqlite3_str_appendf(&str, " AS %s", pItem->zAlias);
|
||||
}
|
||||
if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
|
||||
const char *zFmt = 0;
|
||||
@ -179,8 +179,8 @@ int sqlite3WhereExplainOneScan(
|
||||
zFmt = "INDEX %s";
|
||||
}
|
||||
if( zFmt ){
|
||||
sqlite3StrAccumAppend(&str, " USING ", 7);
|
||||
sqlite3XPrintf(&str, zFmt, pIdx->zName);
|
||||
sqlite3_str_append(&str, " USING ", 7);
|
||||
sqlite3_str_appendf(&str, zFmt, pIdx->zName);
|
||||
explainIndexRange(&str, pLoop);
|
||||
}
|
||||
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
|
||||
@ -195,19 +195,21 @@ int sqlite3WhereExplainOneScan(
|
||||
assert( flags&WHERE_TOP_LIMIT);
|
||||
zRangeOp = "<";
|
||||
}
|
||||
sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
|
||||
sqlite3_str_appendf(&str,
|
||||
" USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
|
||||
sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s",
|
||||
sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
|
||||
pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
|
||||
}
|
||||
#endif
|
||||
#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
|
||||
if( pLoop->nOut>=10 ){
|
||||
sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
|
||||
sqlite3_str_appendf(&str, " (~%llu rows)",
|
||||
sqlite3LogEstToInt(pLoop->nOut));
|
||||
}else{
|
||||
sqlite3StrAccumAppend(&str, " (~1 row)", 9);
|
||||
sqlite3_str_append(&str, " (~1 row)", 9);
|
||||
}
|
||||
#endif
|
||||
zMsg = sqlite3StrAccumFinish(&str);
|
||||
|
Loading…
Reference in New Issue
Block a user