From: dan Date: Sat, 18 Sep 2021 16:15:54 +0000 (+0000) Subject: Further tests for legacy rtree geom callbacks. X-Git-Tag: version-3.37.0~216 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5488e0827a89699e35c0cfc75111f275e003d5df;p=thirdparty%2Fsqlite.git Further tests for legacy rtree geom callbacks. FossilOrigin-Name: 99d6bb22e8735681443bfe67287aa15ce2c57d0d63e304abf8aa01fde50dd021 --- diff --git a/ext/rtree/rtreedoc2.test b/ext/rtree/rtreedoc2.test index f9246a1043..ca0c6b31bd 100644 --- a/ext/rtree/rtreedoc2.test +++ b/ext/rtree/rtreedoc2.test @@ -242,7 +242,104 @@ foreach {tn q vals} { do_test 5.$tn.2 { set ::box_geom } $vals } - +do_execsql_test 5.0 { + CREATE VIRTUAL TABLE myrtree USING rtree(id, x1,x2); + INSERT INTO myrtree VALUES(1, 1, 1); + INSERT INTO myrtree VALUES(2, 2, 2); + INSERT INTO myrtree VALUES(3, 3, 3); +} + +# EVIDENCE-OF: R-44448-00687 The pUser and xDelUser members of the +# sqlite3_rtree_geometry structure are initially set to NULL. +set ::box_geom_calls 0 +proc box_geom {args} { + incr ::box_geom_calls + return user_is_zero +} +do_execsql_test 5.1.1 { + SELECT * FROM myrtree WHERE id MATCH box(4, 5); +} +do_test 5.1.2 { set ::box_geom_calls } 3 + + +# EVIDENCE-OF: R-55837-00155 The pUser variable may be set by the +# callback implementation to any arbitrary value that may be useful to +# subsequent invocations of the callback within the same query (for +# example, a pointer to a complicated data structure used to test for +# region intersection). +# +# EVIDENCE-OF: R-34745-08839 If the xDelUser variable is set to a +# non-NULL value, then after the query has finished running SQLite +# automatically invokes it with the value of the pUser variable as the +# only argument. +# +set ::box_geom_calls 0 +proc box_geom {args} { + incr ::box_geom_calls + switch -- $::box_geom_calls { + 1 { + return user_is_zero + } + 2 { + return [list user box_geom_finalizer] + } + } + return "" +} +proc box_geom_finalizer {} { + set ::box_geom_finalizer "::box_geom_calls is $::box_geom_calls" +} +do_execsql_test 5.1.1 { + SELECT * FROM myrtree WHERE id MATCH box(4, 5); +} +do_test 5.1.2 { set ::box_geom_calls } 3 +do_test 5.1.3 { + set ::box_geom_finalizer +} {::box_geom_calls is 3} + + +# EVIDENCE-OF: R-28176-28813 The xGeom callback always does a +# depth-first search of the r-tree. +# +# For a breadth first search, final test case would return "B L" only. +# +do_execsql_test 6.0 { + CREATE VIRTUAL TABLE xyz USING rtree(x, x1,x2, y1,y2); + WITH s(i) AS ( + VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<15 + ) + INSERT INTO xyz SELECT NULL, one.i,one.i+1, two.i,two.i+1 FROM s one, s two; +} +do_execsql_test 6.1 { + SELECT count(*) FROM xyz_node +} {10} +proc box_geom {args} { + set coords [lindex $args 3] + set area [expr { + ([lindex $coords 1]-[lindex $coords 0]) * + ([lindex $coords 3]-[lindex $coords 2]) + }] + if {$area==1} { + lappend ::box_geom_calls L + } else { + lappend ::box_geom_calls B + } +} +set ::box_geom_calls [list] +do_execsql_test 6.2 { + SELECT count(*) FROM xyz WHERE x MATCH box(0,20,0,20) +} 225 +do_test 6.3 { + set prev "" + set box_calls [list] + foreach c $::box_geom_calls { + if {$c!=$prev} { + lappend ::box_calls $c + set prev $c + } + } + set ::box_calls +} {B L B L B L B L B L B L B L B L B L} finish_test diff --git a/ext/rtree/test_rtreedoc.c b/ext/rtree/test_rtreedoc.c index b19639e025..6eafef806f 100644 --- a/ext/rtree/test_rtreedoc.c +++ b/ext/rtree/test_rtreedoc.c @@ -31,6 +31,13 @@ struct BoxGeomCtx { Tcl_Obj *pScript; }; +static void testDelUser(void *pCtx){ + BoxGeomCtx *p = (BoxGeomCtx*)pCtx; + Tcl_EvalObjEx(p->interp, p->pScript, 0); + Tcl_DecrRefCount(p->pScript); + sqlite3_free(p); +} + static int invokeTclGeomCb( const char *zName, sqlite3_rtree_geometry *p, @@ -48,6 +55,7 @@ static int invokeTclGeomCb( int ii; Tcl_Obj *pRes; + pScript = Tcl_DuplicateObj(pCtx->pScript); Tcl_IncrRefCount(pScript); Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj(zName,-1)); @@ -73,12 +81,41 @@ static int invokeTclGeomCb( Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj(aPtr,-1)); rc = Tcl_EvalObjEx(interp, pScript, 0); - if( rc!=TCL_OK ) rc = SQLITE_ERROR; - - pRes = Tcl_GetObjResult(interp); - if( 0==sqlite3_stricmp(Tcl_GetString(pRes), "zero") ){ - p->aParam[0] = 0.0; - p->nParam = 1; + if( rc!=TCL_OK ){ + rc = SQLITE_ERROR; + }else{ + int nObj = 0; + Tcl_Obj **aObj = 0; + + pRes = Tcl_GetObjResult(interp); + if( Tcl_ListObjGetElements(interp, pRes, &nObj, &aObj) ) return TCL_ERROR; + if( nObj>0 ){ + const char *zCmd = Tcl_GetString(aObj[0]); + if( 0==sqlite3_stricmp(zCmd, "zero") ){ + p->aParam[0] = 0.0; + p->nParam = 1; + } + else if( 0==sqlite3_stricmp(zCmd, "user") ){ + if( p->pUser || p->xDelUser ){ + rc = SQLITE_ERROR; + }else{ + BoxGeomCtx *pCtx = sqlite3_malloc(sizeof(BoxGeomCtx)); + if( pCtx==0 ){ + rc = SQLITE_NOMEM; + }else{ + pCtx->interp = interp; + pCtx->pScript = Tcl_DuplicateObj(pRes); + Tcl_IncrRefCount(pCtx->pScript); + Tcl_ListObjReplace(interp, pCtx->pScript, 0, 1, 0, 0); + p->pUser = (void*)pCtx; + p->xDelUser = testDelUser; + } + } + } + else if( 0==sqlite3_stricmp(zCmd, "user_is_zero") ){ + if( p->pUser || p->xDelUser ) rc = SQLITE_ERROR; + } + } } } return rc; @@ -140,7 +177,6 @@ static int SQLITE_TCLAPI register_box_geom( extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**); extern const char *sqlite3ErrName(int); sqlite3 *db; - int rc; BoxGeomCtx *pCtx; char aPtr[64]; @@ -155,7 +191,7 @@ static int SQLITE_TCLAPI register_box_geom( pCtx->pScript = Tcl_DuplicateObj(objv[2]); Tcl_IncrRefCount(pCtx->pScript); - rc = sqlite3_rtree_geometry_callback(db, "box", box_geom, (void*)pCtx); + sqlite3_rtree_geometry_callback(db, "box", box_geom, (void*)pCtx); sqlite3_snprintf(64, aPtr, "%p", (void*)pCtx); Tcl_SetObjResult(interp, Tcl_NewStringObj(aPtr, -1)); diff --git a/manifest b/manifest index 0fc98d5964..d3509e1aa8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Shell's\s.read\spipe\snow\sworks\sfor\sWindows\stoo. -D 2021-09-17T21:12:47.392 +C Further\stests\sfor\slegacy\srtree\sgeom\scallbacks. +D 2021-09-18T16:15:54.996 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -419,10 +419,10 @@ F ext/rtree/rtreecheck.test d67d5b3e9e45bfa8cd90734e8e9302144ac415b8e9176c6f02d4 F ext/rtree/rtreecirc.test aec664eb21ae943aeb344191407afff5d392d3ae9d12b9a112ced0d9c5de298e F ext/rtree/rtreeconnect.test 225ad3fcb483d36cbee423a25052a6bbae762c9576ae9268332360c68c170d3d F ext/rtree/rtreedoc.test 243cd3fdee1cb89e290e908ddde0cc0cfda0ccb85473c6d1b3c43e6260b14cac -F ext/rtree/rtreedoc2.test ae13849b390f6878434896ecee113cc44bb2bcbcd868f6c47b5d80a73e3e4ab1 +F ext/rtree/rtreedoc2.test 194ebb7d561452dcdc10bf03f44e30c082c2f0c14efeb07f5e02c7daf8284d93 F ext/rtree/rtreefuzz001.test 0fc793f67897c250c5fde96cefee455a5e2fb92f4feeabde5b85ea02040790ee F ext/rtree/sqlite3rtree.h 03c8db3261e435fbddcfc961471795cbf12b24e03001d0015b2636b0f3881373 -F ext/rtree/test_rtreedoc.c 72f78e9930e861ba2a780f36cb6ecbf02ebda350111ecab9594c564c10a30b1c +F ext/rtree/test_rtreedoc.c 216f988e0b56474a3d42905653777772d3bdd413a7fe09a79e466b19296853b0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/util/randomshape.tcl 54ee03d0d4a1c621806f7f44d5b78d2db8fac26e0e8687c36c4bd0203b27dbff F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 @@ -1925,7 +1925,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6ad00e52eda5bc4cb8e6fffbd7538bcd4c6b22f84b837a746eba6bf8c91eb55a -R 4272cac65b9ce52e86aa091f7c699703 -U larrybr -Z f2dab7d439a0b553d4ffc2b434c528dd +P 929bcc4098549692c573779d65c4c28027b0a2f48ebbf5b3f038deee24374b67 +R b53a2568f9f1adf1f421cbce84f79cd1 +U dan +Z 0f8167edfa350ba64179ebda312bfead diff --git a/manifest.uuid b/manifest.uuid index d0c60f0e49..bd0f76d7b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -929bcc4098549692c573779d65c4c28027b0a2f48ebbf5b3f038deee24374b67 \ No newline at end of file +99d6bb22e8735681443bfe67287aa15ce2c57d0d63e304abf8aa01fde50dd021 \ No newline at end of file