mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
More test cases with very long priority queues.
FossilOrigin-Name: 71692aa97c78676f0ba80eaeec0ad9ac225f4427
This commit is contained in:
@ -27,46 +27,93 @@ register_circle_geom db
|
|||||||
|
|
||||||
do_execsql_test rtreeE-1.1 {
|
do_execsql_test rtreeE-1.1 {
|
||||||
PRAGMA page_size=512;
|
PRAGMA page_size=512;
|
||||||
CREATE VIRTUAL TABLE rt2 USING rtree(id,x0,x1,y0,y1);
|
CREATE VIRTUAL TABLE rt1 USING rtree(id,x0,x1,y0,y1);
|
||||||
|
|
||||||
/* A tight pattern of small boxes near 0,0 */
|
/* A tight pattern of small boxes near 0,0 */
|
||||||
WITH RECURSIVE
|
WITH RECURSIVE
|
||||||
x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4),
|
x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4),
|
||||||
y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4)
|
y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4)
|
||||||
INSERT INTO rt2 SELECT x+5*y, x, x+2, y, y+2 FROM x, y;
|
INSERT INTO rt1 SELECT x+5*y, x, x+2, y, y+2 FROM x, y;
|
||||||
|
|
||||||
/* A looser pattern of small boxes near 100, 0 */
|
/* A looser pattern of small boxes near 100, 0 */
|
||||||
WITH RECURSIVE
|
WITH RECURSIVE
|
||||||
x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4),
|
x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4),
|
||||||
y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4)
|
y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4)
|
||||||
INSERT INTO rt2 SELECT 100+x+5*y, x*3+100, x*3+102, y*3, y*3+2 FROM x, y;
|
INSERT INTO rt1 SELECT 100+x+5*y, x*3+100, x*3+102, y*3, y*3+2 FROM x, y;
|
||||||
|
|
||||||
/* A looser pattern of larger boxes near 0, 200 */
|
/* A looser pattern of larger boxes near 0, 200 */
|
||||||
WITH RECURSIVE
|
WITH RECURSIVE
|
||||||
x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4),
|
x(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM x WHERE x<4),
|
||||||
y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4)
|
y(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM y WHERE y<4)
|
||||||
INSERT INTO rt2 SELECT 200+x+5*y, x*7, x*7+15, y*7+200, y*7+215 FROM x, y;
|
INSERT INTO rt1 SELECT 200+x+5*y, x*7, x*7+15, y*7+200, y*7+215 FROM x, y;
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
if 0 {
|
|
||||||
# Queries against each of the three clusters */
|
# Queries against each of the three clusters */
|
||||||
do_execsql_test rtreeE-1.1 {
|
do_execsql_test rtreeE-1.1 {
|
||||||
SELECT id FROM rt2 WHERE id MATCH Qcircle(0.0, 0.0, 50.0) ORDER BY id;
|
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}
|
} {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 {
|
do_execsql_test rtreeE-1.2 {
|
||||||
SELECT id FROM rt2 WHERE id MATCH Qcircle(100.0, 0.0, 50.0) ORDER BY id;
|
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}
|
} {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}
|
||||||
do_execsql_test rtreeE-1.3 {
|
do_execsql_test rtreeE-1.3 {
|
||||||
SELECT id FROM rt2 WHERE id MATCH Qcircle(0.0, 200.0, 50.0) ORDER BY id;
|
SELECT id FROM rt1 WHERE id MATCH Qcircle(0.0, 200.0, 50.0, 3) ORDER BY id;
|
||||||
} {200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224}
|
} {200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224}
|
||||||
}
|
|
||||||
|
|
||||||
# The Qcircle geometry function gives a lower score to larger leaf-nodes.
|
# The Qcircle geometry function gives a lower score to larger leaf-nodes.
|
||||||
# This causes the 200s to sort before the 100s and the 0s to sort before
|
# This causes the 200s to sort before the 100s and the 0s to sort before
|
||||||
# last.
|
# last.
|
||||||
#
|
#
|
||||||
do_execsql_test rtreeE-1.4 {
|
do_execsql_test rtreeE-1.4 {
|
||||||
SELECT id FROM rt2 WHERE id MATCH Qcircle(0,0,1000) AND id%100==0
|
SELECT id FROM rt1 WHERE id MATCH Qcircle(0,0,1000,3) AND id%100==0
|
||||||
} {200 100 0}
|
} {200 100 0}
|
||||||
|
|
||||||
|
# Construct a large 2-D RTree with thousands of random entries.
|
||||||
|
#
|
||||||
|
do_test rtreeE-2.1 {
|
||||||
|
db eval {
|
||||||
|
CREATE TABLE t2(id,x0,x1,y0,y1);
|
||||||
|
CREATE VIRTUAL TABLE rt2 USING rtree(id,x0,x1,y0,y1);
|
||||||
|
BEGIN;
|
||||||
|
}
|
||||||
|
expr srand(0)
|
||||||
|
for {set i 1} {$i<=10000} {incr i} {
|
||||||
|
set dx [expr {int(rand()*40)+1}]
|
||||||
|
set dy [expr {int(rand()*40)+1}]
|
||||||
|
set x0 [expr {int(rand()*(10000 - $dx))}]
|
||||||
|
set x1 [expr {$x0+$dx}]
|
||||||
|
set y0 [expr {int(rand()*(10000 - $dy))}]
|
||||||
|
set y1 [expr {$y0+$dy}]
|
||||||
|
set id [expr {$i+10000}]
|
||||||
|
db eval {INSERT INTO t2 VALUES($id,$x0,$x1,$y0,$y1)}
|
||||||
|
}
|
||||||
|
db eval {
|
||||||
|
INSERT INTO rt2 SELECT * FROM t2;
|
||||||
|
COMMIT;
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
for {set i 1} {$i<=200} {incr i} {
|
||||||
|
set dx [expr {int(rand()*100)}]
|
||||||
|
set dy [expr {int(rand()*100)}]
|
||||||
|
set x0 [expr {int(rand()*(10000 - $dx))}]
|
||||||
|
set x1 [expr {$x0+$dx}]
|
||||||
|
set y0 [expr {int(rand()*(10000 - $dy))}]
|
||||||
|
set y1 [expr {$y0+$dy}]
|
||||||
|
set ans [db eval {SELECT id FROM t2 WHERE x1>=$x0 AND x0<=$x1 AND y1>=$y0 AND y0<=$y1 ORDER BY id}]
|
||||||
|
do_execsql_test rtreeE-2.2.$i {
|
||||||
|
SELECT id FROM rt2 WHERE id MATCH breadthfirstsearch($x0,$x1,$y0,$y1) ORDER BY id
|
||||||
|
} $ans
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run query that have very deep priority queues
|
||||||
|
#
|
||||||
|
set ans [db eval {SELECT id FROM t2 WHERE x1>=0 AND x0<=5000 AND y1>=0 AND y0<=5000 ORDER BY id}]
|
||||||
|
do_execsql_test rtreeE-2.3 {
|
||||||
|
SELECT id FROM rt2 WHERE id MATCH breadthfirstsearch(0,5000,0,5000) ORDER BY id
|
||||||
|
} $ans
|
||||||
|
set ans [db eval {SELECT id FROM t2 WHERE x1>=0 AND x0<=10000 AND y1>=0 AND y0<=10000 ORDER BY id}]
|
||||||
|
do_execsql_test rtreeE-2.4 {
|
||||||
|
SELECT id FROM rt2 WHERE id MATCH breadthfirstsearch(0,10000,0,10000) ORDER BY id
|
||||||
|
} $ans
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
|||||||
C Test\scases\sand\sbug\sfixes\sfor\sthe\ssqlite3_rtree_query_callback()\nmechanism.
|
C More\stest\scases\swith\svery\slong\spriority\squeues.
|
||||||
D 2014-04-17T14:52:20.025
|
D 2014-04-17T15:34:58.372
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a
|
F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -135,7 +135,7 @@ F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf
|
|||||||
F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e
|
F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e
|
||||||
F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06
|
F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06
|
||||||
F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca
|
F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca
|
||||||
F ext/rtree/rtreeE.test c8c951df54fd556d30eb621ecc2acd8771970a5e
|
F ext/rtree/rtreeE.test 0878fd6bce3a62ac980e6f67ba14cc86c8f4f2b3
|
||||||
F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
|
F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
|
||||||
F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
|
F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
|
||||||
F ext/rtree/sqlite3rtree.h 488cf8834d2012b913d33683157d3cf5f1327a69
|
F ext/rtree/sqlite3rtree.h 488cf8834d2012b913d33683157d3cf5f1327a69
|
||||||
@ -275,7 +275,7 @@ F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
|
|||||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||||
F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0
|
F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0
|
||||||
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
|
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
|
||||||
F src/test_rtree.c 636d2a5bc9ded2fa1df4e7d4c575eb0d3f13b334
|
F src/test_rtree.c 38cdb28581d07503c9135ef73692ec8192b876b0
|
||||||
F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6
|
F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6
|
||||||
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
|
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
|
||||||
F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e
|
F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e
|
||||||
@ -1176,7 +1176,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
||||||
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
||||||
P 32a13870175a1dd1d33af3572dde09ff607a04b6
|
P 1ccaaed6b516ec2ce953c1b31025a82ba76d00e7
|
||||||
R 1f38906450e19fda5c27a4543b70f18c
|
R 449eb9a5ce303ca34184a4306bd9d328
|
||||||
U drh
|
U drh
|
||||||
Z 26a5b86beaa061e155488cf6e80f8d30
|
Z 39039e877d4cb95ab625ec95bd5cc650
|
||||||
|
@ -1 +1 @@
|
|||||||
1ccaaed6b516ec2ce953c1b31025a82ba76d00e7
|
71692aa97c78676f0ba80eaeec0ad9ac225f4427
|
@ -36,6 +36,7 @@ struct Circle {
|
|||||||
double centery;
|
double centery;
|
||||||
double radius;
|
double radius;
|
||||||
double mxArea;
|
double mxArea;
|
||||||
|
int eScoreType;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -175,10 +176,10 @@ static int circle_query_func(sqlite3_rtree_query_info *p){
|
|||||||
** Return an error if the table does not have exactly 2 dimensions. */
|
** Return an error if the table does not have exactly 2 dimensions. */
|
||||||
if( p->nCoord!=4 ) return SQLITE_ERROR;
|
if( p->nCoord!=4 ) return SQLITE_ERROR;
|
||||||
|
|
||||||
/* Test that the correct number of parameters (3) have been supplied,
|
/* Test that the correct number of parameters (4) have been supplied,
|
||||||
** and that the parameters are in range (that the radius of the circle
|
** and that the parameters are in range (that the radius of the circle
|
||||||
** radius is greater than zero). */
|
** radius is greater than zero). */
|
||||||
if( p->nParam!=3 || p->aParam[2]<0.0 ) return SQLITE_ERROR;
|
if( p->nParam!=4 || p->aParam[2]<0.0 ) return SQLITE_ERROR;
|
||||||
|
|
||||||
/* Allocate a structure to cache parameter data in. Return SQLITE_NOMEM
|
/* Allocate a structure to cache parameter data in. Return SQLITE_NOMEM
|
||||||
** if the allocation fails. */
|
** if the allocation fails. */
|
||||||
@ -193,6 +194,7 @@ static int circle_query_func(sqlite3_rtree_query_info *p){
|
|||||||
pCircle->centerx = p->aParam[0];
|
pCircle->centerx = p->aParam[0];
|
||||||
pCircle->centery = p->aParam[1];
|
pCircle->centery = p->aParam[1];
|
||||||
pCircle->radius = p->aParam[2];
|
pCircle->radius = p->aParam[2];
|
||||||
|
pCircle->eScoreType = (int)p->aParam[3];
|
||||||
|
|
||||||
/* Define two bounding box regions. The first, aBox[0], extends to
|
/* 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
|
** infinity in the X dimension. It covers the same range of the Y dimension
|
||||||
@ -247,12 +249,22 @@ static int circle_query_func(sqlite3_rtree_query_info *p){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( pCircle->eScoreType==1 ){
|
||||||
|
/* Depth first search */
|
||||||
|
p->rScore = p->iLevel;
|
||||||
|
}else if( pCircle->eScoreType==2 ){
|
||||||
|
/* Breadth first search */
|
||||||
|
p->rScore = 100 - p->iLevel;
|
||||||
|
}else{
|
||||||
|
/* Depth-first search, except sort the leaf nodes by area with
|
||||||
|
** the largest area first */
|
||||||
if( p->iLevel==2 ){
|
if( p->iLevel==2 ){
|
||||||
p->rScore = 1.0 - (xmax-xmin)*(ymax-ymin)/pCircle->mxArea;
|
p->rScore = 1.0 - (xmax-xmin)*(ymax-ymin)/pCircle->mxArea;
|
||||||
if( p->rScore<0.01 ) p->rScore = 0.01;
|
if( p->rScore<0.01 ) p->rScore = 0.01;
|
||||||
}else{
|
}else{
|
||||||
p->rScore = 0.0;
|
p->rScore = 0.0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if( nWithin==0 ){
|
if( nWithin==0 ){
|
||||||
p->eWithin = NOT_WITHIN;
|
p->eWithin = NOT_WITHIN;
|
||||||
}else if( nWithin>=4 ){
|
}else if( nWithin>=4 ){
|
||||||
@ -262,6 +274,39 @@ static int circle_query_func(sqlite3_rtree_query_info *p){
|
|||||||
}
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
** Implementation of "breadthfirstsearch" r-tree geometry callback using the
|
||||||
|
** 2nd-generation interface that allows scoring.
|
||||||
|
**
|
||||||
|
** ... WHERE id MATCH breadthfirstsearch($x0,$x1,$y0,$y1) ...
|
||||||
|
**
|
||||||
|
** It returns all entries whose bounding boxes overlap with $x0,$x1,$y0,$y1.
|
||||||
|
*/
|
||||||
|
static int bfs_query_func(sqlite3_rtree_query_info *p){
|
||||||
|
double x0,x1,y0,y1; /* Dimensions of box being tested */
|
||||||
|
double bx0,bx1,by0,by1; /* Boundary of the query function */
|
||||||
|
|
||||||
|
if( p->nParam!=4 ) return SQLITE_ERROR;
|
||||||
|
x0 = p->aCoord[0];
|
||||||
|
x1 = p->aCoord[1];
|
||||||
|
y0 = p->aCoord[2];
|
||||||
|
y1 = p->aCoord[3];
|
||||||
|
bx0 = p->aParam[0];
|
||||||
|
bx1 = p->aParam[1];
|
||||||
|
by0 = p->aParam[2];
|
||||||
|
by1 = p->aParam[3];
|
||||||
|
p->rScore = 100 - p->iLevel;
|
||||||
|
if( p->eParentWithin==FULLY_WITHIN ){
|
||||||
|
p->eWithin = FULLY_WITHIN;
|
||||||
|
}else if( x0>=bx0 && x1<=bx1 && y0>=by0 && y1<=by1 ){
|
||||||
|
p->eWithin = FULLY_WITHIN;
|
||||||
|
}else if( x1>=bx0 && x0<=bx1 && y1>=by0 && y0<=by1 ){
|
||||||
|
p->eWithin = PARTLY_WITHIN;
|
||||||
|
}else{
|
||||||
|
p->eWithin = NOT_WITHIN;
|
||||||
|
}
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* END of implementation of "circle" geometry callback.
|
/* END of implementation of "circle" geometry callback.
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
@ -402,6 +447,10 @@ static int register_circle_geom(
|
|||||||
rc = sqlite3_rtree_query_callback(db, "Qcircle",
|
rc = sqlite3_rtree_query_callback(db, "Qcircle",
|
||||||
circle_query_func, 0, 0);
|
circle_query_func, 0, 0);
|
||||||
}
|
}
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = sqlite3_rtree_query_callback(db, "breadthfirstsearch",
|
||||||
|
bfs_query_func, 0, 0);
|
||||||
|
}
|
||||||
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
|
Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
|
||||||
#endif
|
#endif
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
|
Reference in New Issue
Block a user