1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

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:
drh
2018-05-09 13:46:26 +00:00
parent 721e8539c3
commit 0cdbe1aee0
14 changed files with 337 additions and 179 deletions

View File

@@ -1,5 +1,5 @@
C Fix\sa\stypo\sin\sa\scomment\sused\sfor\sdocumentation.\s\sNo\scode\schanges. 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-09T10:11:44.774 D 2018-05-09T13:46:26.086
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da
@@ -434,10 +434,10 @@ F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c abedb349c6624d3efa699b4431d5ef679838236527c694444b38ed48c494b39b F src/btree.c 8270813c8f0ca91b2802e88ded3755d04ee962a923d431c13bcb6cf3e0c18f63
F src/btree.h 448f15b98ea85dcf7e4eb76f731cadb89636c676ad25dfaac6de77cd66556598 F src/btree.h 448f15b98ea85dcf7e4eb76f731cadb89636c676ad25dfaac6de77cd66556598
F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96 F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
F src/build.c 0c2be5839f22aa2938f217c6c6c2120d9fc96872a546a37541a8271541cb355e F src/build.c 50ff3e0fa07646b4d797aae0f773efcdb7602f6a5e2f5da27856503f35200889
F src/callback.c fe677cb5f5abb02f7a772a62a98c2f516426081df68856e8f2d5f950929b966a F src/callback.c fe677cb5f5abb02f7a772a62a98c2f516426081df68856e8f2d5f950929b966a
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 849d4cebe008cfc6e4799b034a172b4eaf8856b100739632a852732ba66eee48 F src/ctime.c 849d4cebe008cfc6e4799b034a172b4eaf8856b100739632a852732ba66eee48
@@ -448,7 +448,7 @@ F src/delete.c b0f90749e22d5e41a12dbf940f4811138cf97da54b46b737089b93eb64a2896f
F src/expr.c af4a81a385277510bfc56df87c25d76fc365f98c33bc8797c4a8d84b88e31013 F src/expr.c af4a81a385277510bfc56df87c25d76fc365f98c33bc8797c4a8d84b88e31013
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331 F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331
F src/func.c 94f42cba2cc1c34aeaa441022ba0170ec3fec4bba54db4e0ded085c6dc0fdc51 F src/func.c e2e3c02621a528a472933fd4733a5da635676f1461be73293f6e9f62f18d4eaa
F src/global.c 9bf034fd560bdd514715170ed8460bb7f823cec113f0569ef3f18a20c7ccd128 F src/global.c 9bf034fd560bdd514715170ed8460bb7f823cec113f0569ef3f18a20c7ccd128
F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
@@ -467,7 +467,7 @@ F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
F src/memdb.c e94c478a757c4307fd170fe0a7650ef4cf722c59e5a95a8a7896ffedc1679139 F src/memdb.c e94c478a757c4307fd170fe0a7650ef4cf722c59e5a95a8a7896ffedc1679139
F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661 F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661
F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81 F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81
F src/mutex.c b021263554c8a3995e9d53193b8194b96d1ed28e06c3b532dd7f7d29cf0c7d53 F src/mutex.c bae36f8af32c22ad80bbf0ccebec63c252b6a2b86e4d3e42672ff287ebf4a604
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
F src/mutex_unix.c aaf9ebc3f89df28483c52208497a99a02cc3650011422fc9d4c57e4392f7fe58 F src/mutex_unix.c aaf9ebc3f89df28483c52208497a99a02cc3650011422fc9d4c57e4392f7fe58
@@ -486,19 +486,19 @@ F src/parse.y 07784439d25f0bc64a656eece4caecc549b147d213f513cdbeb8430345ec2911
F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd
F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170 F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880 F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
F src/pragma.c bea56df3ae0637768c0da4fbbb8f2492f780980d95000034a105ff291bf7ca69 F src/pragma.c c0d13c0e82a9197aef5533d63300c5b0c8a216ae1fd14ada64e1f12f398d7e82
F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324 F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
F src/prepare.c 95a9dba7a5d032039a77775188cb3b6fb17f2fa1a0b7cd915b30b4b823383ffa F src/prepare.c 95a9dba7a5d032039a77775188cb3b6fb17f2fa1a0b7cd915b30b4b823383ffa
F src/printf.c d3b7844ddeb11fbbdd38dd84d09c9c1ac171d21fb038473c3aa97981201cc660 F src/printf.c fb76c433bb01c93a0be63c12794540ce830c93947132ee1446cdc131da81ef42
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 6415381a0e9d22c0e7cba33ca4a53f81474190862f5d4838190f5eb5b0b47bc9 F src/resolve.c 6415381a0e9d22c0e7cba33ca4a53f81474190862f5d4838190f5eb5b0b47bc9
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c a35d462ee7a3c0856ad7a9d9c8921fbf3d91d911a8f39ad9d61302eb43b24a71 F src/select.c a35d462ee7a3c0856ad7a9d9c8921fbf3d91d911a8f39ad9d61302eb43b24a71
F src/shell.c.in df233d5556008e330570da3dc4aa837af1df01d95ca5a15beb67b8515302c36a 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/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 83a3c4ce93d650bedfd1aa558cb85a516bd6d094445ee989740827d0d944368d F src/sqlite3ext.h 83a3c4ce93d650bedfd1aa558cb85a516bd6d094445ee989740827d0d944368d
F src/sqliteInt.h 4b98a37f27033ca887f2027f9a60636625fb2a4a9ef1b96c17f0db8fd951891f F src/sqliteInt.h 5abdade4744cf3bd567afb65bb144bb3c61f6132f86813b995a5ca79c7b584e8
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -556,7 +556,7 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c bbde32eac9eb1280f5292bcdfef66f5a57e43176cbf9347e0efab9f75e133f97 F src/tokenize.c bbde32eac9eb1280f5292bcdfef66f5a57e43176cbf9347e0efab9f75e133f97
F src/treeview.c 06dd506b1dcef01c5882a4189bc79afe2660dd992702f81cd7d003425a99cfbc F src/treeview.c 2c5c4bc0a443401db5fd621542150452ddf5055d38edd4eef868bc2b6bfb0260
F src/trigger.c 4ace6d1d5ba9a89822deb287317f33c810440526eafe185c2d8a48c31df1e995 F src/trigger.c 4ace6d1d5ba9a89822deb287317f33c810440526eafe185c2d8a48c31df1e995
F src/update.c 5be2f501ddc704fc04183bdb28b25eab930bb8553d973429a089ec94fa85cf2b F src/update.c 5be2f501ddc704fc04183bdb28b25eab930bb8553d973429a089ec94fa85cf2b
F src/upsert.c ae4a4823b45c4daf87e8aea8c0f582a8844763271f5ed54ee5956c4c612734f4 F src/upsert.c ae4a4823b45c4daf87e8aea8c0f582a8844763271f5ed54ee5956c4c612734f4
@@ -567,11 +567,11 @@ F src/vdbe.c 066a4e1de2ed83e253adfd2e97a684cf562eaa41d31ee7f3d3e4c8aea4485a55
F src/vdbe.h d970d9738efdd09cb2df73e3a40856e7df13e88a3486789c49fcdd322c9eb8a2 F src/vdbe.h d970d9738efdd09cb2df73e3a40856e7df13e88a3486789c49fcdd322c9eb8a2
F src/vdbeInt.h 95f7adfdc5c8f1353321f55a6c5ec00a90877e3b85af5159e393afb41ff54110 F src/vdbeInt.h 95f7adfdc5c8f1353321f55a6c5ec00a90877e3b85af5159e393afb41ff54110
F src/vdbeapi.c 29d2baf9c1233131ec467d7bed1b7c8a03c27579048d768c4b04acf427838858 F src/vdbeapi.c 29d2baf9c1233131ec467d7bed1b7c8a03c27579048d768c4b04acf427838858
F src/vdbeaux.c 58129ae46be079613df5c2c3714d80a78605415bfa10c9528634c7c2d2147727 F src/vdbeaux.c f1cb5ae6e42c54d4991e2951e5293c1e18bad6847056e9b17622fbf6b17964a9
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
F src/vdbemem.c 0cbe9b9560e42b72983cf9e1bceba48f297e51142bfb6b57f3747cf60106b92d F src/vdbemem.c 0cbe9b9560e42b72983cf9e1bceba48f297e51142bfb6b57f3747cf60106b92d
F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f
F src/vdbetrace.c 48e11ebe040c6b41d146abed2602e3d00d621d7ebe4eb29b0a0f1617fd3c2f6c F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
F src/vtab.c 0e4885495172e1bdf54b12cce23b395ac74ef5729031f15e1bc1e3e6b360ed1a F src/vtab.c 0e4885495172e1bdf54b12cce23b395ac74ef5729031f15e1bc1e3e6b360ed1a
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0 F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0
@@ -579,7 +579,7 @@ F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f
F src/where.c d89b1aa56a75a572cd60ad27ec0fe5958d5f98b0f4391a89c72811287be7c439 F src/where.c d89b1aa56a75a572cd60ad27ec0fe5958d5f98b0f4391a89c72811287be7c439
F src/whereInt.h cbae2bcd37cfebdb7812a8b188cdb19634ced2b9346470d1c270556b0c33ea53 F src/whereInt.h cbae2bcd37cfebdb7812a8b188cdb19634ced2b9346470d1c270556b0c33ea53
F src/wherecode.c 414ec42097b295febcae9c8803cf627580ad9005de1d8bc3afad3d3127f0eb86 F src/wherecode.c 728c7f70731430ccdac807a79969873e1af6968bf1c4745dff3f9dd35f636cc8
F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
@@ -1728,7 +1728,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 0c3f128fd7d5738a8e9da706f5f30aa1985ef5efab70ddaad28ef6b641b04f4a P b866693e6a50b5c41ca54b56bb20753efb94980ad3365c511cccf23ac43a1c23
R 2c62d3beecc0dc62689392fea52a44aa R 68264eb483f86d69689e19bb38cf694a
U drh U drh
Z 9f515593856c1a56e94f7a12690a8e77 Z 4acceaf152c7a58a98e5d6dcf41cb498

View File

@@ -1 +1 @@
b866693e6a50b5c41ca54b56bb20753efb94980ad3365c511cccf23ac43a1c23 87f261f0cb800b06ad786f6df16f2c4dddd0d93dfdcc77b4a4eaa22920b56bf1

View File

@@ -9250,14 +9250,14 @@ static void checkAppendMsg(
pCheck->nErr++; pCheck->nErr++;
va_start(ap, zFormat); va_start(ap, zFormat);
if( pCheck->errMsg.nChar ){ if( pCheck->errMsg.nChar ){
sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1); sqlite3_str_append(&pCheck->errMsg, "\n", 1);
} }
if( pCheck->zPfx ){ 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); va_end(ap);
if( pCheck->errMsg.accError==STRACCUM_NOMEM ){ if( pCheck->errMsg.accError==SQLITE_NOMEM ){
pCheck->mallocFailed = 1; pCheck->mallocFailed = 1;
} }
} }
@@ -9841,11 +9841,11 @@ integrity_ck_cleanup:
sqlite3PageFree(sCheck.heap); sqlite3PageFree(sCheck.heap);
sqlite3_free(sCheck.aPgRef); sqlite3_free(sCheck.aPgRef);
if( sCheck.mallocFailed ){ if( sCheck.mallocFailed ){
sqlite3StrAccumReset(&sCheck.errMsg); sqlite3_str_reset(&sCheck.errMsg);
sCheck.nErr++; sCheck.nErr++;
} }
*pnErr = 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. */ /* Make sure this analysis did not leave any unref() pages. */
assert( nRef==sqlite3PagerRefcount(pBt->pPager) ); assert( nRef==sqlite3PagerRefcount(pBt->pPager) );
sqlite3BtreeLeave(p); sqlite3BtreeLeave(p);

View File

@@ -4207,16 +4207,16 @@ void sqlite3UniqueConstraint(
sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200); sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
if( pIdx->aColExpr ){ if( pIdx->aColExpr ){
sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName); sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName);
}else{ }else{
for(j=0; j<pIdx->nKeyCol; j++){ for(j=0; j<pIdx->nKeyCol; j++){
char *zCol; char *zCol;
assert( pIdx->aiColumn[j]>=0 ); assert( pIdx->aiColumn[j]>=0 );
zCol = pTab->aCol[pIdx->aiColumn[j]].zName; zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2); if( j ) sqlite3_str_append(&errMsg, ", ", 2);
sqlite3StrAccumAppendAll(&errMsg, pTab->zName); sqlite3_str_appendall(&errMsg, pTab->zName);
sqlite3StrAccumAppend(&errMsg, ".", 1); sqlite3_str_append(&errMsg, ".", 1);
sqlite3StrAccumAppendAll(&errMsg, zCol); sqlite3_str_appendall(&errMsg, zCol);
} }
} }
zErr = sqlite3StrAccumFinish(&errMsg); zErr = sqlite3StrAccumFinish(&errMsg);

View File

@@ -251,7 +251,7 @@ static void printfFunc(
x.apArg = argv+1; x.apArg = argv+1;
sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
str.printfFlags = SQLITE_PRINTF_SQLFUNC; str.printfFlags = SQLITE_PRINTF_SQLFUNC;
sqlite3XPrintf(&str, zFormat, &x); sqlite3_str_appendf(&str, zFormat, &x);
n = str.nChar; n = str.nChar;
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
SQLITE_DYNAMIC); SQLITE_DYNAMIC);
@@ -1654,20 +1654,20 @@ static void groupConcatStep(
zSep = ","; zSep = ",";
nSep = 1; nSep = 1;
} }
if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); if( zSep ) sqlite3_str_append(pAccum, zSep, nSep);
} }
zVal = (char*)sqlite3_value_text(argv[0]); zVal = (char*)sqlite3_value_text(argv[0]);
nVal = sqlite3_value_bytes(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){ static void groupConcatFinalize(sqlite3_context *context){
StrAccum *pAccum; StrAccum *pAccum;
pAccum = sqlite3_aggregate_context(context, 0); pAccum = sqlite3_aggregate_context(context, 0);
if( pAccum ){ if( pAccum ){
if( pAccum->accError==STRACCUM_TOOBIG ){ if( pAccum->accError==SQLITE_TOOBIG ){
sqlite3_result_error_toobig(context); sqlite3_result_error_toobig(context);
}else if( pAccum->accError==STRACCUM_NOMEM ){ }else if( pAccum->accError==SQLITE_NOMEM ){
sqlite3_result_error_nomem(context); sqlite3_result_error_nomem(context);
}else{ }else{
sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1,

View File

@@ -358,4 +358,3 @@ int sqlite3_mutex_notheld(sqlite3_mutex *p){
#endif #endif
#endif /* !defined(SQLITE_MUTEX_OMIT) */ #endif /* !defined(SQLITE_MUTEX_OMIT) */

View File

@@ -2216,26 +2216,26 @@ static int pragmaVtabConnect(
UNUSED_PARAMETER(argc); UNUSED_PARAMETER(argc);
UNUSED_PARAMETER(argv); UNUSED_PARAMETER(argv);
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); 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++){ 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 = ','; cSep = ',';
} }
if( i==0 ){ if( i==0 ){
sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName); sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName);
cSep = ','; cSep = ',';
i++; i++;
} }
j = 0; j = 0;
if( pPragma->mPragFlg & PragFlg_Result1 ){ if( pPragma->mPragFlg & PragFlg_Result1 ){
sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN"); sqlite3_str_appendall(&acc, ",arg HIDDEN");
j++; j++;
} }
if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){ if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){
sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN"); sqlite3_str_appendall(&acc, ",schema HIDDEN");
j++; j++;
} }
sqlite3StrAccumAppend(&acc, ")", 1); sqlite3_str_append(&acc, ")", 1);
sqlite3StrAccumFinish(&acc); sqlite3StrAccumFinish(&acc);
assert( strlen(zBuf) < sizeof(zBuf)-1 ); assert( strlen(zBuf) < sizeof(zBuf)-1 );
rc = sqlite3_declare_vtab(db, zBuf); 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]); sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
sqlite3StrAccumAppendAll(&acc, "PRAGMA "); sqlite3_str_appendall(&acc, "PRAGMA ");
if( pCsr->azArg[1] ){ 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] ){ if( pCsr->azArg[0] ){
sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]); sqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]);
} }
zSql = sqlite3StrAccumFinish(&acc); zSql = sqlite3StrAccumFinish(&acc);
if( zSql==0 ) return SQLITE_NOMEM; if( zSql==0 ) return SQLITE_NOMEM;

View File

@@ -134,7 +134,7 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
** Set the StrAccum object to an error mode. ** Set the StrAccum object to an error mode.
*/ */
static void setStrAccumError(StrAccum *p, u8 eError){ 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->accError = eError;
p->nAlloc = 0; p->nAlloc = 0;
} }
@@ -168,8 +168,8 @@ static char *getTextArg(PrintfArguments *p){
/* /*
** Render a string given by "fmt" into the StrAccum object. ** Render a string given by "fmt" into the StrAccum object.
*/ */
void sqlite3VXPrintf( void sqlite3_str_vappendf(
StrAccum *pAccum, /* Accumulate results here */ sqlite3_str *pAccum, /* Accumulate results here */
const char *fmt, /* Format string */ const char *fmt, /* Format string */
va_list ap /* arguments */ va_list ap /* arguments */
){ ){
@@ -226,11 +226,11 @@ void sqlite3VXPrintf(
#else #else
do{ fmt++; }while( *fmt && *fmt != '%' ); do{ fmt++; }while( *fmt && *fmt != '%' );
#endif #endif
sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt)); sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt));
if( *fmt==0 ) break; if( *fmt==0 ) break;
} }
if( (c=(*++fmt))==0 ){ if( (c=(*++fmt))==0 ){
sqlite3StrAccumAppend(pAccum, "%", 1); sqlite3_str_append(pAccum, "%", 1);
break; break;
} }
/* Find out what flags are present */ /* Find out what flags are present */
@@ -408,7 +408,7 @@ void sqlite3VXPrintf(
u64 n = (u64)precision + 10 + precision/3; u64 n = (u64)precision + 10 + precision/3;
zOut = zExtra = sqlite3Malloc( n ); zOut = zExtra = sqlite3Malloc( n );
if( zOut==0 ){ if( zOut==0 ){
setStrAccumError(pAccum, STRACCUM_NOMEM); setStrAccumError(pAccum, SQLITE_NOMEM);
return; return;
} }
nOut = (int)n; nOut = (int)n;
@@ -533,7 +533,7 @@ void sqlite3VXPrintf(
bufpt = zExtra bufpt = zExtra
= sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 ); = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
if( bufpt==0 ){ if( bufpt==0 ){
setStrAccumError(pAccum, STRACCUM_NOMEM); setStrAccumError(pAccum, SQLITE_NOMEM);
return; return;
} }
} }
@@ -665,11 +665,11 @@ void sqlite3VXPrintf(
if( precision>1 ){ if( precision>1 ){
width -= precision-1; width -= precision-1;
if( width>1 && !flag_leftjustify ){ if( width>1 && !flag_leftjustify ){
sqlite3AppendChar(pAccum, width-1, ' '); sqlite3_str_appendchar(pAccum, width-1, ' ');
width = 0; width = 0;
} }
while( precision-- > 1 ){ while( precision-- > 1 ){
sqlite3StrAccumAppend(pAccum, buf, length); sqlite3_str_append(pAccum, buf, length);
} }
} }
bufpt = buf; bufpt = buf;
@@ -755,7 +755,7 @@ void sqlite3VXPrintf(
if( n>etBUFSIZE ){ if( n>etBUFSIZE ){
bufpt = zExtra = sqlite3Malloc( n ); bufpt = zExtra = sqlite3Malloc( n );
if( bufpt==0 ){ if( bufpt==0 ){
setStrAccumError(pAccum, STRACCUM_NOMEM); setStrAccumError(pAccum, SQLITE_NOMEM);
return; return;
} }
}else{ }else{
@@ -779,7 +779,7 @@ void sqlite3VXPrintf(
pToken = va_arg(ap, Token*); pToken = va_arg(ap, Token*);
assert( bArgList==0 ); assert( bArgList==0 );
if( pToken && pToken->n ){ 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; length = width = 0;
break; break;
@@ -795,10 +795,10 @@ void sqlite3VXPrintf(
assert( bArgList==0 ); assert( bArgList==0 );
assert( k>=0 && k<pSrc->nSrc ); assert( k>=0 && k<pSrc->nSrc );
if( pItem->zDatabase ){ if( pItem->zDatabase ){
sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase); sqlite3_str_appendall(pAccum, pItem->zDatabase);
sqlite3StrAccumAppend(pAccum, ".", 1); sqlite3_str_append(pAccum, ".", 1);
} }
sqlite3StrAccumAppendAll(pAccum, pItem->zName); sqlite3_str_appendall(pAccum, pItem->zName);
length = width = 0; length = width = 0;
break; break;
} }
@@ -817,11 +817,11 @@ void sqlite3VXPrintf(
*/ */
width -= length; width -= length;
if( width>0 ){ if( width>0 ){
if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
sqlite3StrAccumAppend(pAccum, bufpt, length); sqlite3_str_append(pAccum, bufpt, length);
if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
}else{ }else{
sqlite3StrAccumAppend(pAccum, bufpt, length); sqlite3_str_append(pAccum, bufpt, length);
} }
if( zExtra ){ if( zExtra ){
@@ -842,13 +842,13 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
char *zNew; char *zNew;
assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
if( p->accError ){ if( p->accError ){
testcase(p->accError==STRACCUM_TOOBIG); testcase(p->accError==SQLITE_TOOBIG);
testcase(p->accError==STRACCUM_NOMEM); testcase(p->accError==SQLITE_NOMEM);
return 0; return 0;
} }
if( p->mxAlloc==0 ){ if( p->mxAlloc==0 ){
N = p->nAlloc - p->nChar - 1; N = p->nAlloc - p->nChar - 1;
setStrAccumError(p, STRACCUM_TOOBIG); setStrAccumError(p, SQLITE_TOOBIG);
return N; return N;
}else{ }else{
char *zOld = isMalloced(p) ? p->zText : 0; char *zOld = isMalloced(p) ? p->zText : 0;
@@ -860,8 +860,8 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
szNew += p->nChar; szNew += p->nChar;
} }
if( szNew > p->mxAlloc ){ if( szNew > p->mxAlloc ){
sqlite3StrAccumReset(p); sqlite3_str_reset(p);
setStrAccumError(p, STRACCUM_TOOBIG); setStrAccumError(p, SQLITE_TOOBIG);
return 0; return 0;
}else{ }else{
p->nAlloc = (int)szNew; p->nAlloc = (int)szNew;
@@ -878,8 +878,8 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
p->nAlloc = sqlite3DbMallocSize(p->db, zNew); p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
p->printfFlags |= SQLITE_PRINTF_MALLOCED; p->printfFlags |= SQLITE_PRINTF_MALLOCED;
}else{ }else{
sqlite3StrAccumReset(p); sqlite3_str_reset(p);
setStrAccumError(p, STRACCUM_NOMEM); setStrAccumError(p, SQLITE_NOMEM);
return 0; return 0;
} }
} }
@@ -889,7 +889,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
/* /*
** Append N copies of character c to the given string buffer. ** 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 ); testcase( p->nChar + (i64)N > 0x7fffffff );
if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
return; 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[]. ** The StrAccum "p" is not large enough to accept N new bytes of z[].
** So enlarge if first, then do the append. ** 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 ** 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){ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
N = sqlite3StrAccumEnlarge(p, 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 ** Append N bytes of text from z to the StrAccum object. Increase the
** size of the memory allocation for StrAccum if necessary. ** 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( z!=0 || N==0 );
assert( p->zText!=0 || p->nChar==0 || p->accError ); assert( p->zText!=0 || p->nChar==0 || p->accError );
assert( N>=0 ); 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. ** Append the complete text of zero-terminated string z[] to the p string.
*/ */
void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ void sqlite3_str_appendall(sqlite3_str *p, const char *z){
sqlite3StrAccumAppend(p, z, sqlite3Strlen30(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); memcpy(zText, p->zText, p->nChar+1);
p->printfFlags |= SQLITE_PRINTF_MALLOCED; p->printfFlags |= SQLITE_PRINTF_MALLOCED;
}else{ }else{
setStrAccumError(p, STRACCUM_NOMEM); setStrAccumError(p, SQLITE_NOMEM);
} }
p->zText = zText; p->zText = zText;
return zText; return zText;
@@ -967,10 +967,38 @@ char *sqlite3StrAccumFinish(StrAccum *p){
return p->zText; 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. ** Reset an StrAccum string. Reclaim all malloced memory.
*/ */
void sqlite3StrAccumReset(StrAccum *p){ void sqlite3_str_reset(StrAccum *p){
if( isMalloced(p) ){ if( isMalloced(p) ){
sqlite3DbFree(p->db, p->zText); sqlite3DbFree(p->db, p->zText);
p->printfFlags &= ~SQLITE_PRINTF_MALLOCED; p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
@@ -1002,6 +1030,15 @@ void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
p->printfFlags = 0; 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 ** Print into memory obtained from sqliteMalloc(). Use the internal
** %-conversion extensions. ** %-conversion extensions.
@@ -1014,9 +1051,9 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase), sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]); db->aLimit[SQLITE_LIMIT_LENGTH]);
acc.printfFlags = SQLITE_PRINTF_INTERNAL; acc.printfFlags = SQLITE_PRINTF_INTERNAL;
sqlite3VXPrintf(&acc, zFormat, ap); sqlite3_str_vappendf(&acc, zFormat, ap);
z = sqlite3StrAccumFinish(&acc); z = sqlite3StrAccumFinish(&acc);
if( acc.accError==STRACCUM_NOMEM ){ if( acc.accError==SQLITE_NOMEM ){
sqlite3OomFault(db); sqlite3OomFault(db);
} }
return z; return z;
@@ -1054,7 +1091,7 @@ char *sqlite3_vmprintf(const char *zFormat, va_list ap){
if( sqlite3_initialize() ) return 0; if( sqlite3_initialize() ) return 0;
#endif #endif
sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
sqlite3VXPrintf(&acc, zFormat, ap); sqlite3_str_vappendf(&acc, zFormat, ap);
z = sqlite3StrAccumFinish(&acc); z = sqlite3StrAccumFinish(&acc);
return z; return z;
} }
@@ -1099,7 +1136,7 @@ char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
} }
#endif #endif
sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
sqlite3VXPrintf(&acc, zFormat, ap); sqlite3_str_vappendf(&acc, zFormat, ap);
zBuf[acc.nChar] = 0; zBuf[acc.nChar] = 0;
return zBuf; 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 ** allocate memory because it might be called while the memory allocator
** mutex is held. ** 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. ** certain format characters (%q) or for very large precisions or widths.
** Care must be taken that any sqlite3_log() calls that occur while the ** Care must be taken that any sqlite3_log() calls that occur while the
** memory mutex is held do not use these mechanisms. ** 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 */ char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
sqlite3VXPrintf(&acc, zFormat, ap); sqlite3_str_vappendf(&acc, zFormat, ap);
sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
sqlite3StrAccumFinish(&acc)); sqlite3StrAccumFinish(&acc));
} }
@@ -1160,7 +1197,7 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
char zBuf[500]; char zBuf[500];
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
va_start(ap,zFormat); va_start(ap,zFormat);
sqlite3VXPrintf(&acc, zFormat, ap); sqlite3_str_vappendf(&acc, zFormat, ap);
va_end(ap); va_end(ap);
sqlite3StrAccumFinish(&acc); sqlite3StrAccumFinish(&acc);
#ifdef SQLITE_OS_TRACE_PROC #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. ** 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_list ap;
va_start(ap,zFormat); va_start(ap,zFormat);
sqlite3VXPrintf(p, zFormat, ap); sqlite3_str_vappendf(p, zFormat, ap);
va_end(ap); va_end(ap);
} }

View File

@@ -7132,6 +7132,133 @@ int sqlite3_keyword_count(void);
int sqlite3_keyword_name(int,const char**,int*); int sqlite3_keyword_name(int,const char**,int*);
int sqlite3_keyword_check(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 ** CAPI3REF: SQLite Runtime Status
** **

View File

@@ -1093,7 +1093,7 @@ typedef struct Select Select;
typedef struct SQLiteThread SQLiteThread; typedef struct SQLiteThread SQLiteThread;
typedef struct SelectDest SelectDest; typedef struct SelectDest SelectDest;
typedef struct SrcList SrcList; typedef struct SrcList SrcList;
typedef struct StrAccum StrAccum; typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
typedef struct Table Table; typedef struct Table Table;
typedef struct TableLock TableLock; typedef struct TableLock TableLock;
typedef struct Token Token; typedef struct Token Token;
@@ -3273,17 +3273,15 @@ struct DbFixer {
** An objected used to accumulate the text of a string where we ** 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. ** 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 */ sqlite3 *db; /* Optional database for lookaside. Can be NULL */
char *zText; /* The string collected so far */ char *zText; /* The string collected so far */
u32 nAlloc; /* Amount of space allocated in zText */ u32 nAlloc; /* Amount of space allocated in zText */
u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
u32 nChar; /* Length of the string so far */ 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 */ 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_INTERNAL 0x01 /* Internal-use-only converters allowed */
#define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */ #define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */
#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */ #define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */
@@ -3652,8 +3650,6 @@ struct PrintfArguments {
sqlite3_value **apArg; /* The argument values */ sqlite3_value **apArg; /* The argument values */
}; };
void sqlite3VXPrintf(StrAccum*, const char*, va_list);
void sqlite3XPrintf(StrAccum*, const char*, ...);
char *sqlite3MPrintf(sqlite3*,const char*, ...); char *sqlite3MPrintf(sqlite3*,const char*, ...);
char *sqlite3VMPrintf(sqlite3*,const char*, va_list); char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
@@ -4176,11 +4172,7 @@ int sqlite3ApiExit(sqlite3 *db, int);
int sqlite3OpenTempDatabase(Parse *); int sqlite3OpenTempDatabase(Parse *);
void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); 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*); char *sqlite3StrAccumFinish(StrAccum*);
void sqlite3StrAccumReset(StrAccum*);
void sqlite3SelectDestInit(SelectDest*,int,int); void sqlite3SelectDestInit(SelectDest*,int,int);
Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);

View File

@@ -58,16 +58,16 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
if( p ){ if( p ){
for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){ 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 ){ if( zFormat!=0 ){
va_start(ap, zFormat); va_start(ap, zFormat);
sqlite3VXPrintf(&acc, zFormat, ap); sqlite3_str_vappendf(&acc, zFormat, ap);
va_end(ap); va_end(ap);
assert( acc.nChar>0 ); assert( acc.nChar>0 );
sqlite3StrAccumAppend(&acc, "\n", 1); sqlite3_str_append(&acc, "\n", 1);
} }
sqlite3StrAccumFinish(&acc); sqlite3StrAccumFinish(&acc);
fprintf(stdout,"%s", zBuf); fprintf(stdout,"%s", zBuf);
@@ -101,17 +101,17 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){
char zLine[1000]; char zLine[1000];
const struct Cte *pCte = &pWith->a[i]; const struct Cte *pCte = &pWith->a[i];
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); 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 ){ if( pCte->pCols && pCte->pCols->nExpr>0 ){
char cSep = '('; char cSep = '(';
int j; int j;
for(j=0; j<pCte->pCols->nExpr; 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 = ','; cSep = ',';
} }
sqlite3XPrintf(&x, ")"); sqlite3_str_appendf(&x, ")");
} }
sqlite3XPrintf(&x, " AS"); sqlite3_str_appendf(&x, " AS");
sqlite3StrAccumFinish(&x); sqlite3StrAccumFinish(&x);
sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1); sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
sqlite3TreeViewSelect(pView, pCte->pSelect, 0); sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
@@ -176,20 +176,20 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
StrAccum x; StrAccum x;
char zLine[100]; char zLine[100];
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor); sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
if( pItem->zDatabase ){ 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 ){ }else if( pItem->zName ){
sqlite3XPrintf(&x, " %s", pItem->zName); sqlite3_str_appendf(&x, " %s", pItem->zName);
} }
if( pItem->pTab ){ if( pItem->pTab ){
sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName); sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
} }
if( pItem->zAlias ){ if( pItem->zAlias ){
sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias); sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
} }
if( pItem->fg.jointype & JT_LEFT ){ if( pItem->fg.jointype & JT_LEFT ){
sqlite3XPrintf(&x, " LEFT-JOIN"); sqlite3_str_appendf(&x, " LEFT-JOIN");
} }
sqlite3StrAccumFinish(&x); sqlite3StrAccumFinish(&x);
sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1); sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1);

View File

@@ -1306,23 +1306,23 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){
const char *zOp = 0; const char *zOp = 0;
switch( pExpr->op ){ switch( pExpr->op ){
case TK_STRING: case TK_STRING:
sqlite3XPrintf(p, "%Q", pExpr->u.zToken); sqlite3_str_appendf(p, "%Q", pExpr->u.zToken);
break; break;
case TK_INTEGER: case TK_INTEGER:
sqlite3XPrintf(p, "%d", pExpr->u.iValue); sqlite3_str_appendf(p, "%d", pExpr->u.iValue);
break; break;
case TK_NULL: case TK_NULL:
sqlite3XPrintf(p, "NULL"); sqlite3_str_appendf(p, "NULL");
break; break;
case TK_REGISTER: { case TK_REGISTER: {
sqlite3XPrintf(p, "r[%d]", pExpr->iTable); sqlite3_str_appendf(p, "r[%d]", pExpr->iTable);
break; break;
} }
case TK_COLUMN: { case TK_COLUMN: {
if( pExpr->iColumn<0 ){ if( pExpr->iColumn<0 ){
sqlite3XPrintf(p, "rowid"); sqlite3_str_appendf(p, "rowid");
}else{ }else{
sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn); sqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn);
} }
break; break;
} }
@@ -1354,18 +1354,18 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){
case TK_NOTNULL: zOp = "NOTNULL"; break; case TK_NOTNULL: zOp = "NOTNULL"; break;
default: default:
sqlite3XPrintf(p, "%s", "expr"); sqlite3_str_appendf(p, "%s", "expr");
break; break;
} }
if( zOp ){ if( zOp ){
sqlite3XPrintf(p, "%s(", zOp); sqlite3_str_appendf(p, "%s(", zOp);
displayP4Expr(p, pExpr->pLeft); displayP4Expr(p, pExpr->pLeft);
if( pExpr->pRight ){ if( pExpr->pRight ){
sqlite3StrAccumAppend(p, ",", 1); sqlite3_str_append(p, ",", 1);
displayP4Expr(p, pExpr->pRight); displayP4Expr(p, pExpr->pRight);
} }
sqlite3StrAccumAppend(p, ")", 1); sqlite3_str_append(p, ")", 1);
} }
} }
#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */ #endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
@@ -1386,14 +1386,15 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
int j; int j;
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
assert( pKeyInfo->aSortOrder!=0 ); 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++){ for(j=0; j<pKeyInfo->nKeyField; j++){
CollSeq *pColl = pKeyInfo->aColl[j]; CollSeq *pColl = pKeyInfo->aColl[j];
const char *zColl = pColl ? pColl->zName : ""; const char *zColl = pColl ? pColl->zName : "";
if( strcmp(zColl, "BINARY")==0 ) zColl = "B"; 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; break;
} }
#ifdef SQLITE_ENABLE_CURSOR_HINTS #ifdef SQLITE_ENABLE_CURSOR_HINTS
@@ -1404,31 +1405,31 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
#endif #endif
case P4_COLLSEQ: { case P4_COLLSEQ: {
CollSeq *pColl = pOp->p4.pColl; CollSeq *pColl = pOp->p4.pColl;
sqlite3XPrintf(&x, "(%.20s)", pColl->zName); sqlite3_str_appendf(&x, "(%.20s)", pColl->zName);
break; break;
} }
case P4_FUNCDEF: { case P4_FUNCDEF: {
FuncDef *pDef = pOp->p4.pFunc; FuncDef *pDef = pOp->p4.pFunc;
sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg); sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
break; break;
} }
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
case P4_FUNCCTX: { case P4_FUNCCTX: {
FuncDef *pDef = pOp->p4.pCtx->pFunc; 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; break;
} }
#endif #endif
case P4_INT64: { case P4_INT64: {
sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64); sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64);
break; break;
} }
case P4_INT32: { case P4_INT32: {
sqlite3XPrintf(&x, "%d", pOp->p4.i); sqlite3_str_appendf(&x, "%d", pOp->p4.i);
break; break;
} }
case P4_REAL: { case P4_REAL: {
sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal); sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal);
break; break;
} }
case P4_MEM: { case P4_MEM: {
@@ -1436,9 +1437,9 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
if( pMem->flags & MEM_Str ){ if( pMem->flags & MEM_Str ){
zP4 = pMem->z; zP4 = pMem->z;
}else if( pMem->flags & MEM_Int ){ }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 ){ }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 ){ }else if( pMem->flags & MEM_Null ){
zP4 = "NULL"; zP4 = "NULL";
}else{ }else{
@@ -1450,7 +1451,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
#ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_OMIT_VIRTUALTABLE
case P4_VTAB: { case P4_VTAB: {
sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab; sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
sqlite3XPrintf(&x, "vtab:%p", pVtab); sqlite3_str_appendf(&x, "vtab:%p", pVtab);
break; break;
} }
#endif #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 int n = ai[0]; /* The first element of an INTARRAY is always the
** count of the number of elements to follow */ ** count of the number of elements to follow */
for(i=1; i<=n; i++){ for(i=1; i<=n; i++){
sqlite3XPrintf(&x, ",%d", ai[i]); sqlite3_str_appendf(&x, ",%d", ai[i]);
} }
zTemp[0] = '['; zTemp[0] = '[';
sqlite3StrAccumAppend(&x, "]", 1); sqlite3_str_append(&x, "]", 1);
break; break;
} }
case P4_SUBPROGRAM: { case P4_SUBPROGRAM: {
sqlite3XPrintf(&x, "program"); sqlite3_str_appendf(&x, "program");
break; break;
} }
case P4_DYNBLOB: case P4_DYNBLOB:
@@ -1476,7 +1477,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
break; break;
} }
case P4_TABLE: { case P4_TABLE: {
sqlite3XPrintf(&x, "%s", pOp->p4.pTab->zName); sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
break; break;
} }
default: { default: {

View File

@@ -93,17 +93,17 @@ char *sqlite3VdbeExpandSql(
while( *zRawSql ){ while( *zRawSql ){
const char *zStart = zRawSql; const char *zStart = zRawSql;
while( *(zRawSql++)!='\n' && *zRawSql ); while( *(zRawSql++)!='\n' && *zRawSql );
sqlite3StrAccumAppend(&out, "-- ", 3); sqlite3_str_append(&out, "-- ", 3);
assert( (zRawSql - zStart) > 0 ); assert( (zRawSql - zStart) > 0 );
sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart));
} }
}else if( p->nVar==0 ){ }else if( p->nVar==0 ){
sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql)); sqlite3_str_append(&out, zRawSql, sqlite3Strlen30(zRawSql));
}else{ }else{
while( zRawSql[0] ){ while( zRawSql[0] ){
n = findNextHostParameter(zRawSql, &nToken); n = findNextHostParameter(zRawSql, &nToken);
assert( n>0 ); assert( n>0 );
sqlite3StrAccumAppend(&out, zRawSql, n); sqlite3_str_append(&out, zRawSql, n);
zRawSql += n; zRawSql += n;
assert( zRawSql[0] || nToken==0 ); assert( zRawSql[0] || nToken==0 );
if( nToken==0 ) break; if( nToken==0 ) break;
@@ -129,11 +129,11 @@ char *sqlite3VdbeExpandSql(
assert( idx>0 && idx<=p->nVar ); assert( idx>0 && idx<=p->nVar );
pVar = &p->aVar[idx-1]; pVar = &p->aVar[idx-1];
if( pVar->flags & MEM_Null ){ if( pVar->flags & MEM_Null ){
sqlite3StrAccumAppend(&out, "NULL", 4); sqlite3_str_append(&out, "NULL", 4);
}else if( pVar->flags & MEM_Int ){ }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 ){ }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 ){ }else if( pVar->flags & MEM_Str ){
int nOut; /* Number of bytes of the string text to include in output */ int nOut; /* Number of bytes of the string text to include in output */
#ifndef SQLITE_OMIT_UTF16 #ifndef SQLITE_OMIT_UTF16
@@ -143,7 +143,7 @@ char *sqlite3VdbeExpandSql(
utf8.db = db; utf8.db = db;
sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){ if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){
out.accError = STRACCUM_NOMEM; out.accError = SQLITE_NOMEM;
out.nAlloc = 0; out.nAlloc = 0;
} }
pVar = &utf8; pVar = &utf8;
@@ -156,38 +156,38 @@ char *sqlite3VdbeExpandSql(
while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
} }
#endif #endif
sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z); sqlite3_str_appendf(&out, "'%.*q'", nOut, pVar->z);
#ifdef SQLITE_TRACE_SIZE_LIMIT #ifdef SQLITE_TRACE_SIZE_LIMIT
if( nOut<pVar->n ){ if( nOut<pVar->n ){
sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
} }
#endif #endif
#ifndef SQLITE_OMIT_UTF16 #ifndef SQLITE_OMIT_UTF16
if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
#endif #endif
}else if( pVar->flags & MEM_Zero ){ }else if( pVar->flags & MEM_Zero ){
sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero); sqlite3_str_appendf(&out, "zeroblob(%d)", pVar->u.nZero);
}else{ }else{
int nOut; /* Number of bytes of the blob to include in output */ int nOut; /* Number of bytes of the blob to include in output */
assert( pVar->flags & MEM_Blob ); assert( pVar->flags & MEM_Blob );
sqlite3StrAccumAppend(&out, "x'", 2); sqlite3_str_append(&out, "x'", 2);
nOut = pVar->n; nOut = pVar->n;
#ifdef SQLITE_TRACE_SIZE_LIMIT #ifdef SQLITE_TRACE_SIZE_LIMIT
if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
#endif #endif
for(i=0; i<nOut; i++){ 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 #ifdef SQLITE_TRACE_SIZE_LIMIT
if( nOut<pVar->n ){ if( nOut<pVar->n ){
sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
} }
#endif #endif
} }
} }
} }
if( out.accError ) sqlite3StrAccumReset(&out); if( out.accError ) sqlite3_str_reset(&out);
return sqlite3StrAccumFinish(&out); return sqlite3StrAccumFinish(&out);
} }

View File

@@ -51,23 +51,23 @@ static void explainAppendTerm(
int i; int i;
assert( nTerm>=1 ); 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++){ for(i=0; i<nTerm; i++){
if( i ) sqlite3StrAccumAppend(pStr, ",", 1); if( i ) sqlite3_str_append(pStr, ",", 1);
sqlite3StrAccumAppendAll(pStr, explainIndexColumnName(pIdx, iTerm+i)); 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++){ for(i=0; i<nTerm; i++){
if( i ) sqlite3StrAccumAppend(pStr, ",", 1); if( i ) sqlite3_str_append(pStr, ",", 1);
sqlite3StrAccumAppend(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; int i, j;
if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return; 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++){ for(i=0; i<nEq; i++){
const char *z = explainIndexColumnName(pIndex, i); const char *z = explainIndexColumnName(pIndex, i);
if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5); if( i ) sqlite3_str_append(pStr, " AND ", 5);
sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z); sqlite3_str_appendf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
} }
j = i; j = i;
@@ -106,7 +106,7 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
if( pLoop->wsFlags&WHERE_TOP_LIMIT ){ if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<"); 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)); || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN"); sqlite3_str_appendall(&str, isSearch ? "SEARCH" : "SCAN");
if( pItem->pSelect ){ if( pItem->pSelect ){
sqlite3XPrintf(&str, " SUBQUERY 0x%p", pItem->pSelect); sqlite3_str_appendf(&str, " SUBQUERY 0x%p", pItem->pSelect);
}else{ }else{
sqlite3XPrintf(&str, " TABLE %s", pItem->zName); sqlite3_str_appendf(&str, " TABLE %s", pItem->zName);
} }
if( pItem->zAlias ){ if( pItem->zAlias ){
sqlite3XPrintf(&str, " AS %s", pItem->zAlias); sqlite3_str_appendf(&str, " AS %s", pItem->zAlias);
} }
if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
const char *zFmt = 0; const char *zFmt = 0;
@@ -179,8 +179,8 @@ int sqlite3WhereExplainOneScan(
zFmt = "INDEX %s"; zFmt = "INDEX %s";
} }
if( zFmt ){ if( zFmt ){
sqlite3StrAccumAppend(&str, " USING ", 7); sqlite3_str_append(&str, " USING ", 7);
sqlite3XPrintf(&str, zFmt, pIdx->zName); sqlite3_str_appendf(&str, zFmt, pIdx->zName);
explainIndexRange(&str, pLoop); explainIndexRange(&str, pLoop);
} }
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
@@ -195,19 +195,21 @@ int sqlite3WhereExplainOneScan(
assert( flags&WHERE_TOP_LIMIT); assert( flags&WHERE_TOP_LIMIT);
zRangeOp = "<"; 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 #ifndef SQLITE_OMIT_VIRTUALTABLE
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ 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); pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
} }
#endif #endif
#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
if( pLoop->nOut>=10 ){ if( pLoop->nOut>=10 ){
sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut)); sqlite3_str_appendf(&str, " (~%llu rows)",
sqlite3LogEstToInt(pLoop->nOut));
}else{ }else{
sqlite3StrAccumAppend(&str, " (~1 row)", 9); sqlite3_str_append(&str, " (~1 row)", 9);
} }
#endif #endif
zMsg = sqlite3StrAccumFinish(&str); zMsg = sqlite3StrAccumFinish(&str);