Merge enhancements from trunk, including the new sqlite3_value_dup() API and
the addition of the apSqlParam field in the sqlite3_rtree_query_info object of R-Tree. FossilOrigin-Name: cdc0ca6fb36e787b981fb544a27c6df838f85704
This commit is contained in:
commit
893ca50d0f
@ -351,6 +351,7 @@ struct RtreeMatchArg {
|
||||
u32 magic; /* Always RTREE_GEOMETRY_MAGIC */
|
||||
RtreeGeomCallback cb; /* Info about the callback functions */
|
||||
int nParam; /* Number of parameters to the SQL function */
|
||||
sqlite3_value **apSqlParam; /* Original SQL parameter values */
|
||||
RtreeDValue aParam[1]; /* Values for parameters to the SQL function */
|
||||
};
|
||||
|
||||
@ -1482,9 +1483,7 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
|
||||
|
||||
/* Check that the blob is roughly the right size. */
|
||||
nBlob = sqlite3_value_bytes(pValue);
|
||||
if( nBlob<(int)sizeof(RtreeMatchArg)
|
||||
|| ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0
|
||||
){
|
||||
if( nBlob<(int)sizeof(RtreeMatchArg) ){
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
@ -1495,6 +1494,7 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
|
||||
|
||||
memcpy(pBlob, sqlite3_value_blob(pValue), nBlob);
|
||||
nExpected = (int)(sizeof(RtreeMatchArg) +
|
||||
pBlob->nParam*sizeof(sqlite3_value*) +
|
||||
(pBlob->nParam-1)*sizeof(RtreeDValue));
|
||||
if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){
|
||||
sqlite3_free(pInfo);
|
||||
@ -1503,6 +1503,7 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
|
||||
pInfo->pContext = pBlob->cb.pContext;
|
||||
pInfo->nParam = pBlob->nParam;
|
||||
pInfo->aParam = pBlob->aParam;
|
||||
pInfo->apSqlParam = pBlob->apSqlParam;
|
||||
|
||||
if( pBlob->cb.xGeom ){
|
||||
pCons->u.xGeom = pBlob->cb.xGeom;
|
||||
@ -1669,17 +1670,30 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
Rtree *pRtree = (Rtree*)tab;
|
||||
int rc = SQLITE_OK;
|
||||
int ii;
|
||||
int bMatch = 0; /* True if there exists a MATCH constraint */
|
||||
i64 nRow; /* Estimated rows returned by this scan */
|
||||
|
||||
int iIdx = 0;
|
||||
char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
|
||||
memset(zIdxStr, 0, sizeof(zIdxStr));
|
||||
|
||||
/* Check if there exists a MATCH constraint - even an unusable one. If there
|
||||
** is, do not consider the lookup-by-rowid plan as using such a plan would
|
||||
** require the VDBE to evaluate the MATCH constraint, which is not currently
|
||||
** possible. */
|
||||
for(ii=0; ii<pIdxInfo->nConstraint; ii++){
|
||||
if( pIdxInfo->aConstraint[ii].op==SQLITE_INDEX_CONSTRAINT_MATCH ){
|
||||
bMatch = 1;
|
||||
}
|
||||
}
|
||||
|
||||
assert( pIdxInfo->idxStr==0 );
|
||||
for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
|
||||
struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
|
||||
|
||||
if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
|
||||
if( bMatch==0 && p->usable
|
||||
&& p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ
|
||||
){
|
||||
/* We have an equality constraint on the rowid. Use strategy 1. */
|
||||
int jj;
|
||||
for(jj=0; jj<ii; jj++){
|
||||
@ -3372,6 +3386,18 @@ static void rtreeFreeCallback(void *p){
|
||||
sqlite3_free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine frees the BLOB that is returned by geomCallback().
|
||||
*/
|
||||
static void rtreeMatchArgFree(void *pArg){
|
||||
int i;
|
||||
RtreeMatchArg *p = (RtreeMatchArg*)pArg;
|
||||
for(i=0; i<p->nParam; i++){
|
||||
sqlite3_value_free(p->apSqlParam[i]);
|
||||
}
|
||||
sqlite3_free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
** Each call to sqlite3_rtree_geometry_callback() or
|
||||
** sqlite3_rtree_query_callback() creates an ordinary SQLite
|
||||
@ -3390,8 +3416,10 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
|
||||
RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
|
||||
RtreeMatchArg *pBlob;
|
||||
int nBlob;
|
||||
int memErr = 0;
|
||||
|
||||
nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue);
|
||||
nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue)
|
||||
+ nArg*sizeof(sqlite3_value*);
|
||||
pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
|
||||
if( !pBlob ){
|
||||
sqlite3_result_error_nomem(ctx);
|
||||
@ -3399,22 +3427,23 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
|
||||
int i;
|
||||
pBlob->magic = RTREE_GEOMETRY_MAGIC;
|
||||
pBlob->cb = pGeomCtx[0];
|
||||
pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg];
|
||||
pBlob->nParam = nArg;
|
||||
for(i=0; i<nArg; i++){
|
||||
if( sqlite3_value_type(aArg[i])==SQLITE_BLOB
|
||||
&& sqlite3_value_bytes(aArg[i])==sizeof(sqlite3_rtree_dbl)
|
||||
){
|
||||
memcpy(&pBlob->aParam[i], sqlite3_value_blob(aArg[i]),
|
||||
sizeof(sqlite3_rtree_dbl));
|
||||
}else{
|
||||
pBlob->apSqlParam[i] = sqlite3_value_dup(aArg[i]);
|
||||
if( pBlob->apSqlParam[i]==0 ) memErr = 1;
|
||||
#ifdef SQLITE_RTREE_INT_ONLY
|
||||
pBlob->aParam[i] = sqlite3_value_int64(aArg[i]);
|
||||
pBlob->aParam[i] = sqlite3_value_int64(aArg[i]);
|
||||
#else
|
||||
pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
|
||||
pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
sqlite3_result_blob(ctx, pBlob, nBlob, sqlite3_free);
|
||||
if( memErr ){
|
||||
sqlite3_result_error_nomem(ctx);
|
||||
rtreeMatchArgFree(pBlob);
|
||||
}else{
|
||||
sqlite3_result_blob(ctx, pBlob, nBlob, rtreeMatchArgFree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,9 @@ do_execsql_test rtreeE-1.1 {
|
||||
do_execsql_test rtreeE-1.1 {
|
||||
SELECT id FROM rt1 WHERE id MATCH Qcircle(0.0, 0.0, 50.0, 3) ORDER BY id;
|
||||
} {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24}
|
||||
do_execsql_test rtreeE-1.1x {
|
||||
SELECT id FROM rt1 WHERE id MATCH Qcircle('x:0 y:0 r:50.0 e:3') ORDER BY id;
|
||||
} {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24}
|
||||
do_execsql_test rtreeE-1.2 {
|
||||
SELECT id FROM rt1 WHERE id MATCH Qcircle(100.0, 0.0, 50.0, 3) ORDER BY id;
|
||||
} {100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124}
|
||||
@ -64,12 +67,12 @@ do_execsql_test rtreeE-1.3 {
|
||||
# last.
|
||||
#
|
||||
do_execsql_test rtreeE-1.4 {
|
||||
SELECT id FROM rt1 WHERE id MATCH Qcircle(0,0,1000,3) AND id%100==0
|
||||
SELECT id FROM rt1 WHERE id MATCH Qcircle('r:1000 e:3') AND id%100==0
|
||||
} {200 100 0}
|
||||
|
||||
# Exclude odd rowids on a depth-first search
|
||||
do_execsql_test rtreeE-1.5 {
|
||||
SELECT id FROM rt1 WHERE id MATCH Qcircle(0,0,1000,4) ORDER BY +id
|
||||
SELECT id FROM rt1 WHERE id MATCH Qcircle('r:1000 e:4') ORDER BY +id
|
||||
} {0 2 4 6 8 10 12 14 16 18 20 22 24 100 102 104 106 108 110 112 114 116 118 120 122 124 200 202 204 206 208 210 212 214 216 218 220 222 224}
|
||||
|
||||
# Exclude odd rowids on a breadth-first search.
|
||||
@ -77,6 +80,13 @@ do_execsql_test rtreeE-1.6 {
|
||||
SELECT id FROM rt1 WHERE id MATCH Qcircle(0,0,1000,5) ORDER BY +id
|
||||
} {0 2 4 6 8 10 12 14 16 18 20 22 24 100 102 104 106 108 110 112 114 116 118 120 122 124 200 202 204 206 208 210 212 214 216 218 220 222 224}
|
||||
|
||||
# Test that rtree prefers MATCH to lookup-by-rowid.
|
||||
#
|
||||
do_execsql_test rtreeE-1.7 {
|
||||
SELECT id FROM rt1 WHERE id=18 AND id MATCH Qcircle(0,0,1000,5)
|
||||
} {18}
|
||||
|
||||
|
||||
# Construct a large 2-D RTree with thousands of random entries.
|
||||
#
|
||||
do_test rtreeE-2.1 {
|
||||
@ -126,4 +136,5 @@ do_execsql_test rtreeE-2.4 {
|
||||
SELECT id FROM rt2 WHERE id MATCH breadthfirstsearch(0,10000,0,10000) ORDER BY id
|
||||
} $ans
|
||||
|
||||
|
||||
finish_test
|
||||
|
@ -98,6 +98,8 @@ struct sqlite3_rtree_query_info {
|
||||
int eParentWithin; /* Visibility of parent node */
|
||||
int eWithin; /* OUT: Visiblity */
|
||||
sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
|
||||
/* The following fields are only available in 3.8.11 and later */
|
||||
sqlite3_value **apSqlParam; /* Original SQL values of parameters */
|
||||
};
|
||||
|
||||
/*
|
||||
|
46
manifest
46
manifest
@ -1,5 +1,5 @@
|
||||
C Merge\sthe\sMakefile.msc\sfix\sand\sthe\scompiler\swarning\sfix\sfrom\strunk.\s\sAlso\nfix\sanother\scompiler\swarning\sin\ssqlite3session_diff().
|
||||
D 2015-05-19T23:04:26.372
|
||||
C Merge\senhancements\sfrom\strunk,\sincluding\sthe\snew\ssqlite3_value_dup()\sAPI\sand\nthe\saddition\sof\sthe\sapSqlParam\sfield\sin\sthe\ssqlite3_rtree_query_info\sobject\nof\sR-Tree.
|
||||
D 2015-05-22T23:26:18.963
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 66db4ec2c6cd63d0f3e29d366aaaab769aba175b
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -143,7 +143,7 @@ F ext/ota/sqlite3ota.c 2246b779f46ab20d5e7876f5b96c378c601d20f4
|
||||
F ext/ota/sqlite3ota.h 00028de37eede471ff1947d455cc3f33d3a911c6
|
||||
F ext/ota/test_ota.c a876f88550d7d59a3ef62d4c1a5c04c4c2f1ebe1
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 60ec0a71d4d213665a706c795c887e7c4d148635
|
||||
F ext/rtree/rtree.c 0f9b595bd0debcbedf1d7a63d0e0678d619e6c9c
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
F ext/rtree/rtree1.test 541bbcab74613907fea08b2ecdcdd5b7aa724cc9
|
||||
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
|
||||
@ -158,11 +158,11 @@ F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf
|
||||
F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e
|
||||
F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06
|
||||
F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca
|
||||
F ext/rtree/rtreeE.test 388c1c8602c3ce55c15f03b509e9cf545fb7c41f
|
||||
F ext/rtree/rtreeE.test 45a147a64a76306172819562309681d8e90f94bb
|
||||
F ext/rtree/rtreeF.test 66deb9fd1611c7ca2e374adba63debdc2dbb12b4
|
||||
F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
|
||||
F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
|
||||
F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd
|
||||
F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28
|
||||
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
||||
F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a
|
||||
@ -210,10 +210,10 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
||||
F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d
|
||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||
F src/btree.c 30a80340481098d699398cba3536c895373b2e2c
|
||||
F src/btree.c 0eb4eb39e75be6170f1e59f7d6aabedaefb19938
|
||||
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
||||
F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4
|
||||
F src/build.c 61b47073f79f31e80a05db9ce13c5ca81bf8f74e
|
||||
F src/build.c d5d9090788118178190c5724c19f93953b8c7a4e
|
||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
|
||||
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
|
||||
@ -228,7 +228,7 @@ F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e
|
||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c 533e0f08a2e695cbd67c6a3d1067e106905f11f3
|
||||
F src/insert.c 6d9cde1aafe23b157fcc4a6567bf1fb1a1cb8ce3
|
||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
|
||||
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
|
||||
@ -257,7 +257,7 @@ F src/os_win.c 97f7828a9554d753665b6fcf7540e31c2b3d6a6e
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c 97110085b1321298412f1e5c37bddb95b36d9208
|
||||
F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77
|
||||
F src/parse.y c4e0387bc88c8e21e5ba653e2578959a1f3cdbc7
|
||||
F src/parse.y af55d4fb5e588705112e9788364ca3af09651fcf
|
||||
F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4
|
||||
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
|
||||
F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9
|
||||
@ -268,11 +268,11 @@ F src/printf.c 13ce37e5574f9b0682fa86dbcf9faf76b9d82a15
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c 99eabf7eff0bfa65b75939b46caa82e2b2133f28
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c 6d9d6ae899acb9bf148862e8cccdf16085514b26
|
||||
F src/select.c 6adad8d698a382f83009eed7b73080273fa993ca
|
||||
F src/shell.c f26cca96f7dadab5efb5e655edf548f4b91695c5
|
||||
F src/sqlite.h.in 6805658a16c77dc153131c2dd7e39cc766bd9454
|
||||
F src/sqlite.h.in 5808551a21911fb58584316ccf878c4cd74d3258
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
F src/sqlite3ext.h 2ebeb634e751a61a6f0eebfa0f4669f46a42f6cd
|
||||
F src/sqliteInt.h 88f58e88856dcfed5b03ae020335e3a562c91f29
|
||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
|
||||
@ -312,7 +312,7 @@ F src/test_osinst.c 5423dc1d355f594371f27dd292ca54bd320b8196
|
||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||
F src/test_quota.c 180813f43683be5725458fc1ff13ac455d8e722d
|
||||
F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d
|
||||
F src/test_rtree.c bfe6f4386517f70054311109f3528adffec34485
|
||||
F src/test_rtree.c 43fff4c5a01576d6d213f27472598801a247890c
|
||||
F src/test_schema.c 2bdba21b82f601da69793e1f1d11bf481a79b091
|
||||
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
|
||||
F src/test_sqllog.c b690c12933f50ff46491e0d56a251f84ae16e914
|
||||
@ -326,17 +326,17 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
|
||||
F src/tokenize.c af8cbbca6db6b664ffecafa236b06629ef6d35c4
|
||||
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
|
||||
F src/update.c d207deb7a031f698104bee879de0632b611e72dd
|
||||
F src/update.c 24dd6a45b8b3470e62702128ebf11be1f2693145
|
||||
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
|
||||
F src/util.c a6431c92803b975b7322724a7b433e538d243539
|
||||
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
||||
F src/vdbe.c e4b07daec26aaeb3700308f82770485f0a28a988
|
||||
F src/vdbe.h 01d8c35cb877faca74331bb690f0327493c2cb50
|
||||
F src/vdbeInt.h 0c025e70881b42896c0a7575f4b1191a2f3ea5f9
|
||||
F src/vdbeapi.c d95f2bb43d01a91d93231cde181811b38182202e
|
||||
F src/vdbeInt.h 50e298245b66b320c8930219c8aeab492c9a4cce
|
||||
F src/vdbeapi.c a5d2e8afd53b4f81934f5ca59c04465cd1a6d50d
|
||||
F src/vdbeaux.c 38233cc7faa4ad1dfbc1a9bc5a54ecf996d6840b
|
||||
F src/vdbeblob.c ab33f9b57cfce7dddb23853090186da614be4846
|
||||
F src/vdbemem.c eda55a13cfaa797f89ef243a129f3f5a457719e7
|
||||
F src/vdbemem.c c704f0f2515a658d8d1566a5f2f3dc9870622427
|
||||
F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b
|
||||
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
|
||||
F src/vtab.c c535e80259ebe616467181a83a4263555b97c694
|
||||
@ -784,7 +784,7 @@ F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
|
||||
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
|
||||
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
|
||||
F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f
|
||||
F test/misc1.test 783ba75743b2cf71e0f646bf540a6cef57264811
|
||||
F test/misc1.test 2bb46a3656e97f80c82880a94ea10d76a3b60cb0
|
||||
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
|
||||
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
|
||||
F test/misc4.test 0d8be3466adf123a7791a66ba2bc8e8d229e87f3
|
||||
@ -882,7 +882,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
|
||||
F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686
|
||||
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
|
||||
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
|
||||
F test/select4.test 824342f382f16b4afe42d0887ef82b3d6abb6075
|
||||
F test/select4.test 6d5bc6d178a367e8b48fa1c1d3ea12cae9c2d650
|
||||
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
|
||||
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
|
||||
F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d
|
||||
@ -1249,7 +1249,7 @@ F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
|
||||
F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
|
||||
F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1
|
||||
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
|
||||
F tool/fuzzershell.c e8be9a8bd8e0e7814592c5e3e38de99ad7beee83
|
||||
F tool/fuzzershell.c e35a3e0918349f2a9e0498c17c6fe5a6c7d61d86
|
||||
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
|
||||
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
|
||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
@ -1297,7 +1297,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 0a0de8b72ca24f287f9c84766a14e12ea4564b59 c7b16645307d6e46c4153693d6806269de64955f
|
||||
R 4c94d0a5b34d5dffef0e5fc7fa5c812a
|
||||
P 7530e1bf557083ef91447a02f05b019dbe60fa70 10cc44f5a63e6cadf6940bb7310a177ee7fa6ee2
|
||||
R a152f3a145c4384cb72a92d8f9b69eb6
|
||||
U drh
|
||||
Z 5fb8b92e45ad4729c65ff31de37671dd
|
||||
Z 209f039a515a9e78b61cf9368c3a92c3
|
||||
|
@ -1 +1 @@
|
||||
7530e1bf557083ef91447a02f05b019dbe60fa70
|
||||
cdc0ca6fb36e787b981fb544a27c6df838f85704
|
@ -7860,7 +7860,8 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
|
||||
pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
|
||||
pgnoRoot++;
|
||||
}
|
||||
assert( pgnoRoot>=3 );
|
||||
assert( pgnoRoot>=3 || CORRUPT_DB );
|
||||
testcase( pgnoRoot<3 );
|
||||
|
||||
/* Allocate a page. The page that currently resides at pgnoRoot will
|
||||
** be moved to the allocated page (unless the allocated page happens
|
||||
@ -8010,7 +8011,8 @@ static int clearDatabasePage(
|
||||
rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
|
||||
if( rc ) goto cleardatabasepage_out;
|
||||
}else if( pnChange ){
|
||||
assert( pPage->intKey );
|
||||
assert( pPage->intKey || CORRUPT_DB );
|
||||
testcase( !pPage->intKey );
|
||||
*pnChange += pPage->nCell;
|
||||
}
|
||||
if( freePageFlag ){
|
||||
|
45
src/build.c
45
src/build.c
@ -1913,26 +1913,45 @@ void sqlite3EndTable(
|
||||
** be redundant.
|
||||
*/
|
||||
if( pSelect ){
|
||||
SelectDest dest;
|
||||
Table *pSelTab;
|
||||
SelectDest dest; /* Where the SELECT should store results */
|
||||
int regYield; /* Register holding co-routine entry-point */
|
||||
int addrTop; /* Top of the co-routine */
|
||||
int regRec; /* A record to be insert into the new table */
|
||||
int regRowid; /* Rowid of the next row to insert */
|
||||
int addrInsLoop; /* Top of the loop for inserting rows */
|
||||
Table *pSelTab; /* A table that describes the SELECT results */
|
||||
|
||||
regYield = ++pParse->nMem;
|
||||
regRec = ++pParse->nMem;
|
||||
regRowid = ++pParse->nMem;
|
||||
assert(pParse->nTab==1);
|
||||
sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
|
||||
pParse->nTab = 2;
|
||||
sqlite3SelectDestInit(&dest, SRT_Table, 1);
|
||||
addrTop = sqlite3VdbeCurrentAddr(v) + 1;
|
||||
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
|
||||
sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
|
||||
sqlite3Select(pParse, pSelect, &dest);
|
||||
sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
|
||||
sqlite3VdbeJumpHere(v, addrTop - 1);
|
||||
if( pParse->nErr ) return;
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
|
||||
if( pSelTab==0 ) return;
|
||||
assert( p->aCol==0 );
|
||||
p->nCol = pSelTab->nCol;
|
||||
p->aCol = pSelTab->aCol;
|
||||
pSelTab->nCol = 0;
|
||||
pSelTab->aCol = 0;
|
||||
sqlite3DeleteTable(db, pSelTab);
|
||||
addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec);
|
||||
sqlite3TableAffinity(v, p, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid);
|
||||
sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrInsLoop);
|
||||
sqlite3VdbeJumpHere(v, addrInsLoop);
|
||||
sqlite3VdbeAddOp1(v, OP_Close, 1);
|
||||
if( pParse->nErr==0 ){
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
|
||||
if( pSelTab==0 ) return;
|
||||
assert( p->aCol==0 );
|
||||
p->nCol = pSelTab->nCol;
|
||||
p->aCol = pSelTab->aCol;
|
||||
pSelTab->nCol = 0;
|
||||
pSelTab->aCol = 0;
|
||||
sqlite3DeleteTable(db, pSelTab);
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute the complete text of the CREATE statement */
|
||||
|
@ -42,7 +42,7 @@ void sqlite3OpenTable(
|
||||
}else{
|
||||
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
|
||||
assert( pPk!=0 );
|
||||
assert( pPk->tnum=pTab->tnum );
|
||||
assert( pPk->tnum==pTab->tnum );
|
||||
sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb);
|
||||
sqlite3VdbeSetP4KeyInfo(pParse, pPk);
|
||||
VdbeComment((v, "%s", pTab->zName));
|
||||
|
@ -448,6 +448,7 @@ selectnowith(A) ::= oneselect(X). {A = X;}
|
||||
%ifndef SQLITE_OMIT_COMPOUND_SELECT
|
||||
selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). {
|
||||
Select *pRhs = Z;
|
||||
Select *pLhs = X;
|
||||
if( pRhs && pRhs->pPrior ){
|
||||
SrcList *pFrom;
|
||||
Token x;
|
||||
@ -458,11 +459,12 @@ selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). {
|
||||
}
|
||||
if( pRhs ){
|
||||
pRhs->op = (u8)Y;
|
||||
pRhs->pPrior = X;
|
||||
pRhs->pPrior = pLhs;
|
||||
if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
|
||||
pRhs->selFlags &= ~SF_MultiValue;
|
||||
if( Y!=TK_ALL ) pParse->hasCompound = 1;
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, X);
|
||||
sqlite3SelectDelete(pParse->db, pLhs);
|
||||
}
|
||||
A = pRhs;
|
||||
}
|
||||
|
24
src/select.c
24
src/select.c
@ -816,6 +816,8 @@ static void selectInnerLoop(
|
||||
int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1);
|
||||
testcase( eDest==SRT_Table );
|
||||
testcase( eDest==SRT_EphemTab );
|
||||
testcase( eDest==SRT_Fifo );
|
||||
testcase( eDest==SRT_DistFifo );
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg);
|
||||
#ifndef SQLITE_OMIT_CTE
|
||||
if( eDest==SRT_DistFifo ){
|
||||
@ -1231,10 +1233,7 @@ static void generateSortTail(
|
||||
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
|
||||
}
|
||||
switch( eDest ){
|
||||
case SRT_Table:
|
||||
case SRT_EphemTab: {
|
||||
testcase( eDest==SRT_Table );
|
||||
testcase( eDest==SRT_EphemTab );
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
|
||||
sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
|
||||
@ -2583,15 +2582,14 @@ static int generateOutputSubroutine(
|
||||
*/
|
||||
codeOffset(v, p->iOffset, iContinue);
|
||||
|
||||
assert( pDest->eDest!=SRT_Exists );
|
||||
assert( pDest->eDest!=SRT_Table );
|
||||
switch( pDest->eDest ){
|
||||
/* Store the result as data using a unique key.
|
||||
*/
|
||||
case SRT_Table:
|
||||
case SRT_EphemTab: {
|
||||
int r1 = sqlite3GetTempReg(pParse);
|
||||
int r2 = sqlite3GetTempReg(pParse);
|
||||
testcase( pDest->eDest==SRT_Table );
|
||||
testcase( pDest->eDest==SRT_EphemTab );
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2);
|
||||
sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2);
|
||||
@ -2619,16 +2617,6 @@ static int generateOutputSubroutine(
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0 /* Never occurs on an ORDER BY query */
|
||||
/* If any row exist in the result set, record that fact and abort.
|
||||
*/
|
||||
case SRT_Exists: {
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm);
|
||||
/* The LIMIT clause will terminate the loop for us */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If this is a scalar select that is part of an expression, then
|
||||
** store the results in the appropriate memory cell and break out
|
||||
** of the scan loop.
|
||||
@ -5523,9 +5511,9 @@ select_end:
|
||||
void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
int n = 0;
|
||||
pView = sqlite3TreeViewPush(pView, moreToFollow);
|
||||
sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p)",
|
||||
sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x",
|
||||
((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
|
||||
((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p
|
||||
((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags
|
||||
);
|
||||
if( p->pSrc && p->pSrc->nSrc ) n++;
|
||||
if( p->pWhere ) n++;
|
||||
|
@ -4294,12 +4294,12 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
|
||||
#endif
|
||||
|
||||
/*
|
||||
** CAPI3REF: Obtaining SQL Function Parameter Values
|
||||
** CAPI3REF: Obtaining SQL Values
|
||||
** METHOD: sqlite3_value
|
||||
**
|
||||
** The C-language implementation of SQL functions and aggregates uses
|
||||
** this set of interface routines to access the parameter values on
|
||||
** the function or aggregate.
|
||||
** the function or aggregate.
|
||||
**
|
||||
** The xFunc (for scalar functions) or xStep (for aggregates) parameters
|
||||
** to [sqlite3_create_function()] and [sqlite3_create_function16()]
|
||||
@ -4352,6 +4352,23 @@ const void *sqlite3_value_text16be(sqlite3_value*);
|
||||
int sqlite3_value_type(sqlite3_value*);
|
||||
int sqlite3_value_numeric_type(sqlite3_value*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Copy And Free SQL Values
|
||||
** METHOD: sqlite3_value
|
||||
**
|
||||
** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
|
||||
** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
|
||||
** is a [protected sqlite3_value] object even if the input is not.
|
||||
** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
|
||||
** memory allocation fails.
|
||||
**
|
||||
** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
|
||||
** previously obtained from [sqlite_value_dup()]. ^If V is a NULL pointer
|
||||
** then sqlite3_value_free(V) is a harmless no-op.
|
||||
*/
|
||||
SQLITE_EXPERIMENTAL sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
|
||||
SQLITE_EXPERIMENTAL void sqlite3_value_free(sqlite3_value*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Obtain Aggregate Function Context
|
||||
** METHOD: sqlite3_context
|
||||
@ -5875,7 +5892,7 @@ int sqlite3_blob_open(
|
||||
**
|
||||
** ^This function sets the database handle error code and message.
|
||||
*/
|
||||
SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
|
||||
int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Close A BLOB Handle
|
||||
@ -7685,7 +7702,7 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
|
||||
**
|
||||
** See also: [sqlite3_stmt_scanstatus_reset()]
|
||||
*/
|
||||
SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus(
|
||||
int sqlite3_stmt_scanstatus(
|
||||
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
|
||||
int idx, /* Index of loop to report on */
|
||||
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
|
||||
@ -7701,7 +7718,7 @@ SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus(
|
||||
** This API is only available if the library is built with pre-processor
|
||||
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
|
||||
*/
|
||||
SQLITE_EXPERIMENTAL void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
|
||||
void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -267,6 +267,8 @@ struct sqlite3_api_routines {
|
||||
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
|
||||
void(*)(void*), unsigned char);
|
||||
int (*strglob)(const char*,const char*);
|
||||
sqlite3_value (*value_dup)(const sqlite3_value*);
|
||||
void (*value_free)(sqlite3_value*);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -497,6 +499,9 @@ struct sqlite3_api_routines {
|
||||
#define sqlite3_result_blob64 sqlite3_api->result_blob64
|
||||
#define sqlite3_result_text64 sqlite3_api->result_text64
|
||||
#define sqlite3_strglob sqlite3_api->strglob
|
||||
/* Version 3.8.11 and later */
|
||||
#define sqlite3_value_dup sqlite3_api->value_dup
|
||||
#define sqlite3_value_free sqlite3_api->value_free
|
||||
#endif /* SQLITE_CORE */
|
||||
|
||||
#ifndef SQLITE_CORE
|
||||
|
@ -155,6 +155,11 @@ static int circle_geom(
|
||||
/*
|
||||
** Implementation of "circle" r-tree geometry callback using the
|
||||
** 2nd-generation interface that allows scoring.
|
||||
**
|
||||
** Two calling forms:
|
||||
**
|
||||
** Qcircle(X,Y,Radius,eType) -- All values are doubles
|
||||
** Qcircle('x:X y:Y r:R e:ETYPE') -- Single string parameter
|
||||
*/
|
||||
static int circle_query_func(sqlite3_rtree_query_info *p){
|
||||
int i; /* Iterator variable */
|
||||
@ -176,10 +181,9 @@ static int circle_query_func(sqlite3_rtree_query_info *p){
|
||||
** Return an error if the table does not have exactly 2 dimensions. */
|
||||
if( p->nCoord!=4 ) return SQLITE_ERROR;
|
||||
|
||||
/* Test that the correct number of parameters (4) have been supplied,
|
||||
** and that the parameters are in range (that the radius of the circle
|
||||
** radius is greater than zero). */
|
||||
if( p->nParam!=4 || p->aParam[2]<0.0 ) return SQLITE_ERROR;
|
||||
/* Test that the correct number of parameters (1 or 4) have been supplied.
|
||||
*/
|
||||
if( p->nParam!=4 && p->nParam!=1 ) return SQLITE_ERROR;
|
||||
|
||||
/* Allocate a structure to cache parameter data in. Return SQLITE_NOMEM
|
||||
** if the allocation fails. */
|
||||
@ -191,10 +195,38 @@ static int circle_query_func(sqlite3_rtree_query_info *p){
|
||||
** tested bounding boxes that intersect the circular region are detected
|
||||
** is by testing if each corner of the bounding box lies within radius
|
||||
** units of the center of the circle. */
|
||||
pCircle->centerx = p->aParam[0];
|
||||
pCircle->centery = p->aParam[1];
|
||||
pCircle->radius = p->aParam[2];
|
||||
pCircle->eScoreType = (int)p->aParam[3];
|
||||
if( p->nParam==4 ){
|
||||
pCircle->centerx = p->aParam[0];
|
||||
pCircle->centery = p->aParam[1];
|
||||
pCircle->radius = p->aParam[2];
|
||||
pCircle->eScoreType = (int)p->aParam[3];
|
||||
}else{
|
||||
const char *z = (const char*)sqlite3_value_text(p->apSqlParam[0]);
|
||||
pCircle->centerx = 0.0;
|
||||
pCircle->centery = 0.0;
|
||||
pCircle->radius = 0.0;
|
||||
pCircle->eScoreType = 0;
|
||||
while( z && z[0] ){
|
||||
if( z[0]=='r' && z[1]==':' ){
|
||||
pCircle->radius = atof(&z[2]);
|
||||
}else if( z[0]=='x' && z[1]==':' ){
|
||||
pCircle->centerx = atof(&z[2]);
|
||||
}else if( z[0]=='y' && z[1]==':' ){
|
||||
pCircle->centery = atof(&z[2]);
|
||||
}else if( z[0]=='e' && z[1]==':' ){
|
||||
pCircle->eScoreType = (int)atof(&z[2]);
|
||||
}else if( z[0]==' ' ){
|
||||
z++;
|
||||
continue;
|
||||
}
|
||||
while( z[0]!=0 && z[0]!=' ' ) z++;
|
||||
while( z[0]==' ' ) z++;
|
||||
}
|
||||
}
|
||||
if( pCircle->radius<0.0 ){
|
||||
sqlite3_free(pCircle);
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
/* Define two bounding box regions. The first, aBox[0], extends to
|
||||
** infinity in the X dimension. It covers the same range of the Y dimension
|
||||
|
@ -756,12 +756,10 @@ static void updateVirtualTable(
|
||||
*/
|
||||
assert( v );
|
||||
ephemTab = pParse->nTab++;
|
||||
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
|
||||
sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
|
||||
|
||||
/* fill the ephemeral table
|
||||
*/
|
||||
sqlite3SelectDestInit(&dest, SRT_Table, ephemTab);
|
||||
sqlite3SelectDestInit(&dest, SRT_EphemTab, ephemTab);
|
||||
sqlite3Select(pParse, pSelect, &dest);
|
||||
|
||||
/* Generate code to scan the ephemeral table and call VUpdate. */
|
||||
|
@ -186,6 +186,12 @@ struct Mem {
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
** Size of struct Mem not including the Mem.zMalloc member or anything that
|
||||
** follows.
|
||||
*/
|
||||
#define MEMCELLSIZE offsetof(Mem,zMalloc)
|
||||
|
||||
/* One or more of the following flags are set to indicate the validOK
|
||||
** representations of the value stored in the Mem struct.
|
||||
**
|
||||
|
@ -212,6 +212,36 @@ int sqlite3_value_type(sqlite3_value* pVal){
|
||||
return aType[pVal->flags&MEM_AffMask];
|
||||
}
|
||||
|
||||
/* Make a copy of an sqlite3_value object
|
||||
*/
|
||||
sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
|
||||
sqlite3_value *pNew;
|
||||
if( pOrig==0 ) return 0;
|
||||
pNew = sqlite3_malloc( sizeof(*pNew) );
|
||||
if( pNew==0 ) return 0;
|
||||
memset(pNew, 0, sizeof(*pNew));
|
||||
memcpy(pNew, pOrig, MEMCELLSIZE);
|
||||
pNew->flags &= ~MEM_Dyn;
|
||||
pNew->db = 0;
|
||||
if( pNew->flags&(MEM_Str|MEM_Blob) ){
|
||||
pNew->flags &= ~(MEM_Static|MEM_Dyn);
|
||||
pNew->flags |= MEM_Ephem;
|
||||
if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){
|
||||
sqlite3ValueFree(pNew);
|
||||
pNew = 0;
|
||||
}
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/* Destroy an sqlite3_value object previously obtained from
|
||||
** sqlite3_value_dup().
|
||||
*/
|
||||
void sqlite3_value_free(sqlite3_value *pOld){
|
||||
sqlite3ValueFree(pOld);
|
||||
}
|
||||
|
||||
|
||||
/**************************** sqlite3_result_ *******************************
|
||||
** The following routines are used by user-defined functions to specify
|
||||
** the function result.
|
||||
|
@ -770,10 +770,6 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
|
||||
}
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
/*
|
||||
** Size of struct Mem not including the Mem.zMalloc member.
|
||||
*/
|
||||
#define MEMCELLSIZE offsetof(Mem,zMalloc)
|
||||
|
||||
/*
|
||||
** Make an shallow copy of pFrom into pTo. Prior contents of
|
||||
|
@ -603,6 +603,15 @@ do_execsql_test misc1-19.2 {
|
||||
SELECT * FROM t19b;
|
||||
} {4 5 6}
|
||||
|
||||
# 2015-05-20: CREATE TABLE AS should not store INT value is a TEXT
|
||||
# column.
|
||||
#
|
||||
do_execsql_test misc1-19.3 {
|
||||
CREATE TABLE t19c(x TEXT);
|
||||
CREATE TABLE t19d AS SELECT * FROM t19c UNION ALL SELECT 1234;
|
||||
SELECT x, typeof(x) FROM t19d;
|
||||
} {1234 text}
|
||||
|
||||
# 2014-05-16: Tests for the SQLITE_TESTCTRL_FAULT_INSTALL feature.
|
||||
#
|
||||
unset -nocomplain fault_callbacks
|
||||
|
@ -909,5 +909,11 @@ do_execsql_test select4-14.14 {
|
||||
do_execsql_test select4-14.15 {
|
||||
SELECT * FROM (SELECT 123), (SELECT 456) ON likely(0 OR 1) OR 0;
|
||||
} {123 456}
|
||||
do_execsql_test select4-14.16 {
|
||||
VALUES(1),(2),(3),(4) UNION ALL SELECT 5 LIMIT 99;
|
||||
} {1 2 3 4 5}
|
||||
do_execsql_test select4-14.17 {
|
||||
VALUES(1),(2),(3),(4) UNION ALL SELECT 5 LIMIT 3;
|
||||
} {1 2 3}
|
||||
|
||||
finish_test
|
||||
|
@ -321,6 +321,7 @@ static void showHelp(void){
|
||||
"and then evaluate each block of SQL contained therein.\n"
|
||||
"Options:\n"
|
||||
" --autovacuum Enable AUTOVACUUM mode\n"
|
||||
" --database FILE Use database FILE instead of an in-memory database\n"
|
||||
" --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n"
|
||||
" --help Show this help text\n"
|
||||
" --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n"
|
||||
@ -453,6 +454,7 @@ int main(int argc, char **argv){
|
||||
int jj; /* Loop counter for azInFile[] */
|
||||
sqlite3_int64 iBegin; /* Start time for the whole program */
|
||||
sqlite3_int64 iStart, iEnd; /* Start and end-times for a test case */
|
||||
const char *zDbName; /* Name of an on-disk database file to open */
|
||||
|
||||
iBegin = timeOfDay();
|
||||
zFailCode = getenv("TEST_FAILURE");
|
||||
@ -466,6 +468,11 @@ int main(int argc, char **argv){
|
||||
if( strcmp(z,"autovacuum")==0 ){
|
||||
doAutovac = 1;
|
||||
}else
|
||||
if( strcmp(z,"database")==0 ){
|
||||
if( i>=argc-1 ) abendError("missing argument on %s\n", argv[i]);
|
||||
zDbName = argv[i+1];
|
||||
i += 1;
|
||||
}else
|
||||
if( strcmp(z, "f")==0 && i+1<argc ){
|
||||
i++;
|
||||
goto addNewInFile;
|
||||
@ -692,10 +699,14 @@ int main(int argc, char **argv){
|
||||
oomCnt = 0;
|
||||
}
|
||||
do{
|
||||
rc = sqlite3_open_v2(
|
||||
"main.db", &db,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY,
|
||||
0);
|
||||
if( zDbName ){
|
||||
rc = sqlite3_open_v2(zDbName, &db, SQLITE_OPEN_READWRITE, 0);
|
||||
}else{
|
||||
rc = sqlite3_open_v2(
|
||||
"main.db", &db,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY,
|
||||
0);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
abendError("Unable to open the in-memory database");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user