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
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,
int ii;
Tcl_Obj *pRes;
+
pScript = Tcl_DuplicateObj(pCtx->pScript);
Tcl_IncrRefCount(pScript);
Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj(zName,-1));
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;
extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
extern const char *sqlite3ErrName(int);
sqlite3 *db;
- int rc;
BoxGeomCtx *pCtx;
char aPtr[64];
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));
-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
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
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
-929bcc4098549692c573779d65c4c28027b0a2f48ebbf5b3f038deee24374b67
\ No newline at end of file
+99d6bb22e8735681443bfe67287aa15ce2c57d0d63e304abf8aa01fde50dd021
\ No newline at end of file