mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Add the new interfaces to rtree, though they do not yet work. Add the
"show_speedtest1_rtree.tcl" script for showing the test data used for the R-Tree tests of speedtest1. Change speedtest1 to generate better R-Tree test data. FossilOrigin-Name: 0b70275972c7a6a533566c1e50bffbf3ac531e95
This commit is contained in:
@ -324,21 +324,24 @@ struct RtreeCell {
|
||||
struct RtreeMatchArg {
|
||||
u32 magic; /* Always RTREE_GEOMETRY_MAGIC */
|
||||
int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue*, int *);
|
||||
int (*xQueryFunc)(sqlite3_rtree_query_info*);
|
||||
void *pContext;
|
||||
int nParam;
|
||||
RtreeDValue aParam[1];
|
||||
};
|
||||
|
||||
/*
|
||||
** When a geometry callback is created (see sqlite3_rtree_geometry_callback),
|
||||
** When a geometry callback is created using either
|
||||
** sqlite3_rtree_geometry_callback() or sqlite3_rtree_query_callback(),
|
||||
** a single instance of the following structure is allocated. It is used
|
||||
** as the context for the user-function created by by s_r_g_c(). The object
|
||||
** is eventually deleted by the destructor mechanism provided by
|
||||
** sqlite3_create_function_v2() (which is called by s_r_g_c() to create
|
||||
** the geometry callback function).
|
||||
** as the context for the user-function created by sqlite3_rtree_*_callback().
|
||||
** The object is eventually deleted by the destructor mechanism provided by
|
||||
** sqlite3_create_function_v2().
|
||||
*/
|
||||
struct RtreeGeomCallback {
|
||||
int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*);
|
||||
int (*xQueryFunc)(sqlite3_rtree_query_info*);
|
||||
void (*xDestructor)(void*);
|
||||
void *pContext;
|
||||
};
|
||||
|
||||
@ -3352,22 +3355,23 @@ int sqlite3RtreeInit(sqlite3 *db){
|
||||
}
|
||||
|
||||
/*
|
||||
** A version of sqlite3_free() that can be used as a callback. This is used
|
||||
** in two places - as the destructor for the blob value returned by the
|
||||
** invocation of a geometry function, and as the destructor for the geometry
|
||||
** functions themselves.
|
||||
** This routine is called when a custom geometry function or custom query
|
||||
** function is cancelled. The pointer is to a RtreeGeomCallback object
|
||||
** that needs to be freed.
|
||||
*/
|
||||
static void doSqlite3Free(void *p){
|
||||
static void rtreeFreeCallback(void *p){
|
||||
RtreeGeomCallback *pGeom = (RtreeGeomCallback*)p;
|
||||
if( pGeom->xDestructor ) pGeom->xDestructor(pGeom->pContext);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
** Each call to sqlite3_rtree_geometry_callback() creates an ordinary SQLite
|
||||
** scalar user function. This C function is the callback used for all such
|
||||
** registered SQL functions.
|
||||
** Each call to sqlite3_rtree_geometry_callback() or
|
||||
** sqlite3_rtree_query_callback() creates an ordinary SQLite
|
||||
** scalar user function that is implemented by this routine.
|
||||
**
|
||||
** The scalar user functions return a blob that is interpreted by r-tree
|
||||
** table MATCH operators.
|
||||
** This function returns a blob that is interpreted by r-tree
|
||||
** table MATCH operator.
|
||||
*/
|
||||
static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
|
||||
RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
|
||||
@ -3391,7 +3395,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
|
||||
pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
|
||||
#endif
|
||||
}
|
||||
sqlite3_result_blob(ctx, pBlob, nBlob, doSqlite3Free);
|
||||
sqlite3_result_blob(ctx, pBlob, nBlob, sqlite3_free);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3410,12 +3414,42 @@ int sqlite3_rtree_geometry_callback(
|
||||
pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback));
|
||||
if( !pGeomCtx ) return SQLITE_NOMEM;
|
||||
pGeomCtx->xGeom = xGeom;
|
||||
pGeomCtx->xQueryFunc = 0;
|
||||
pGeomCtx->xDestructor = 0;
|
||||
pGeomCtx->pContext = pContext;
|
||||
|
||||
/* Create the new user-function. Register a destructor function to delete
|
||||
** the context object when it is no longer required. */
|
||||
return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY,
|
||||
(void *)pGeomCtx, geomCallback, 0, 0, doSqlite3Free
|
||||
(void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
** Register a new 2nd-generation geometry function for use with the
|
||||
** r-tree MATCH operator.
|
||||
*/
|
||||
int sqlite3_rtree_query_callback(
|
||||
sqlite3 *db,
|
||||
const char *zQueryFunc,
|
||||
int (*xQueryFunc)(sqlite3_rtree_query_info*),
|
||||
void *pContext,
|
||||
void (*xDestructor)(void*)
|
||||
){
|
||||
RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */
|
||||
|
||||
/* Allocate and populate the context object. */
|
||||
pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback));
|
||||
if( !pGeomCtx ) return SQLITE_NOMEM;
|
||||
pGeomCtx->xGeom = 0;
|
||||
pGeomCtx->xQueryFunc = xQueryFunc;
|
||||
pGeomCtx->xDestructor = xDestructor;
|
||||
pGeomCtx->pContext = pContext;
|
||||
|
||||
/* Create the new user-function. Register a destructor function to delete
|
||||
** the context object when it is no longer required. */
|
||||
return sqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY,
|
||||
(void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,16 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
|
||||
typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info;
|
||||
|
||||
/* The double-precision datatype used by RTree depends on the
|
||||
** SQLITE_RTREE_INT_ONLY compile-time option.
|
||||
*/
|
||||
#ifdef SQLITE_RTREE_INT_ONLY
|
||||
typedef sqlite3_int64 sqlite3_rtree_dbl;
|
||||
#else
|
||||
typedef double sqlite3_rtree_dbl;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Register a geometry callback named zGeom that can be used as part of an
|
||||
@ -31,11 +41,7 @@ typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
|
||||
int sqlite3_rtree_geometry_callback(
|
||||
sqlite3 *db,
|
||||
const char *zGeom,
|
||||
#ifdef SQLITE_RTREE_INT_ONLY
|
||||
int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes),
|
||||
#else
|
||||
int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes),
|
||||
#endif
|
||||
int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
|
||||
void *pContext
|
||||
);
|
||||
|
||||
@ -47,11 +53,54 @@ int sqlite3_rtree_geometry_callback(
|
||||
struct sqlite3_rtree_geometry {
|
||||
void *pContext; /* Copy of pContext passed to s_r_g_c() */
|
||||
int nParam; /* Size of array aParam[] */
|
||||
double *aParam; /* Parameters passed to SQL geom function */
|
||||
sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */
|
||||
void *pUser; /* Callback implementation user data */
|
||||
void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */
|
||||
};
|
||||
|
||||
/*
|
||||
** Register a 2nd-generation geometry callback named zScore that can be
|
||||
** used as part of an R-Tree geometry query as follows:
|
||||
**
|
||||
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
|
||||
*/
|
||||
int sqlite3_rtree_query_callback(
|
||||
sqlite3 *db,
|
||||
const char *zQueryFunc,
|
||||
int (*xQueryFunc)(sqlite3_rtree_query_info*),
|
||||
void *pContext,
|
||||
void (*xDestructor)(void*)
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
** A pointer to a structure of the following type is passed as the
|
||||
** argument to scored geometry callback registered using
|
||||
** sqlite3_rtree_query_callback().
|
||||
*/
|
||||
struct sqlite3_rtree_query_info {
|
||||
void *pContext; /* pContext from when function registered */
|
||||
int nParam; /* Number of function parameters */
|
||||
sqlite3_rtree_dbl *aParam; /* value of function parameters */
|
||||
void *pUser; /* callback can use this, if desired */
|
||||
void (*xDelUser)(void*); /* function to free pUser */
|
||||
sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */
|
||||
int nCoord; /* Number of coordinates */
|
||||
int iLevel; /* Level of current node or entry */
|
||||
sqlite3_int64 iRowid; /* Rowid for current entry */
|
||||
sqlite3_rtree_dbl rParentScore; /* Score of parent node */
|
||||
int eParentWithin; /* Visibility of parent node */
|
||||
int eWithin; /* OUT: Visiblity */
|
||||
sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
|
||||
};
|
||||
|
||||
/*
|
||||
** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin.
|
||||
*/
|
||||
#define NOT_WITHIN 0 /* Object completely outside of query region */
|
||||
#define PARTLY_WITHIN 1 /* Object partially overlaps query region */
|
||||
#define FULLY_WITHIN 2 /* Object fully contained within query region */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of the 'extern "C"' block */
|
||||
|
Reference in New Issue
Block a user