/ Check-in [fc4d7537]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:When generating sqlite3.h, append the contents of sqlite3rtree.h.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fc4d75370bad9021d01b76dbb1b8dde9ff223d2c
User & Date: dan 2010-08-30 18:39:50
Context
2010-08-30
22:15
Provide hints to the btree layer during the creation of transient tables for when it is possible for those tables to use a hash rather than a binary tree. No use is currently made of those hints, though assert() statement verify their accuracy. check-in: 4fead8e7 user: drh tags: trunk
18:39
When generating sqlite3.h, append the contents of sqlite3rtree.h. check-in: fc4d7537 user: dan tags: trunk
16:15
Fix a problem in pagerfault.test uncovered by the previous change. check-in: b6719ce3 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/rtree/rtree.c.

   181    181   /*
   182    182   ** A search constraint.
   183    183   */
   184    184   struct RtreeConstraint {
   185    185     int iCoord;                     /* Index of constrained coordinate */
   186    186     int op;                         /* Constraining operation */
   187    187     double rValue;                  /* Constraint value. */
   188         -  int (*xGeom)(RtreeGeometry *, int, double *, int *);
   189         -  RtreeGeometry *pGeom;           /* Constraint callback argument for a MATCH */
          188  +  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *);
          189  +  sqlite3_rtree_geometry *pGeom;  /* Constraint callback argument for a MATCH */
   190    190   };
   191    191   
   192    192   /* Possible values for RtreeConstraint.op */
   193    193   #define RTREE_EQ    0x41
   194    194   #define RTREE_LE    0x42
   195    195   #define RTREE_LT    0x43
   196    196   #define RTREE_GE    0x44
................................................................................
   230    230   */
   231    231   struct RtreeCell {
   232    232     i64 iRowid;
   233    233     RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2];
   234    234   };
   235    235   
   236    236   
          237  +/*
          238  +** Value for the first field of every RtreeGeomBlob object. The MATCH
          239  +** operator tests that the first field of a blob operand matches this
          240  +** value to avoid operating on invalid blobs (which could cause a segfault).
          241  +*/
   237    242   #define RTREE_GEOMETRY_MAGIC 0x891245AB
   238    243   
   239    244   /*
   240    245   ** An instance of this structure must be supplied as a blob argument to
   241    246   ** the right-hand-side of an SQL MATCH operator used to constrain an
   242    247   ** r-tree query.
   243    248   */
   244    249   struct RtreeGeomBlob {
   245    250     u32 magic;                      /* Always RTREE_GEOMETRY_MAGIC */
   246         -  int (*xGeom)(RtreeGeometry *, int, double *, int *);
          251  +  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *);
   247    252     void *pContext;
   248    253     int nParam;
   249    254     double aParam[1];
   250    255   };
   251    256   
   252    257   #ifndef MAX
   253    258   # define MAX(x,y) ((x) < (y) ? (y) : (x))
................................................................................
   741    746   /*
   742    747   ** Free the RtreeCursor.aConstraint[] array and its contents.
   743    748   */
   744    749   static void freeCursorConstraints(RtreeCursor *pCsr){
   745    750     if( pCsr->aConstraint ){
   746    751       int i;                        /* Used to iterate through constraint array */
   747    752       for(i=0; i<pCsr->nConstraint; i++){
   748         -      RtreeGeometry *pGeom = pCsr->aConstraint[i].pGeom;
          753  +      sqlite3_rtree_geometry *pGeom = pCsr->aConstraint[i].pGeom;
   749    754         if( pGeom ){
   750    755           if( pGeom->xDelUser ) pGeom->xDelUser(pGeom->pUser);
   751    756           sqlite3_free(pGeom);
   752    757         }
   753    758       }
   754    759       sqlite3_free(pCsr->aConstraint);
   755    760       pCsr->aConstraint = 0;
................................................................................
  1098   1103   ** This function is called to configure the RtreeConstraint object passed
  1099   1104   ** as the second argument for a MATCH constraint. The value passed as the
  1100   1105   ** first argument to this function is the right-hand operand to the MATCH
  1101   1106   ** operator.
  1102   1107   */
  1103   1108   static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
  1104   1109     RtreeGeomBlob *p;
  1105         -  RtreeGeometry *pGeom;
         1110  +  sqlite3_rtree_geometry *pGeom;
  1106   1111     int nBlob;
  1107   1112   
  1108   1113     /* Check that value is actually a blob. */
  1109   1114     if( !sqlite3_value_type(pValue)==SQLITE_BLOB ) return SQLITE_ERROR;
  1110   1115   
  1111   1116     /* Check that the blob is roughly the right size. */
  1112   1117     nBlob = sqlite3_value_bytes(pValue);
  1113   1118     if( nBlob<sizeof(RtreeGeomBlob) 
  1114   1119      || ((nBlob-sizeof(RtreeGeomBlob))%sizeof(double))!=0
  1115   1120     ){
  1116   1121       return SQLITE_ERROR;
  1117   1122     }
  1118   1123   
  1119         -  pGeom = (RtreeGeometry *)sqlite3_malloc(sizeof(RtreeGeometry) + nBlob);
         1124  +  pGeom = (sqlite3_rtree_geometry *)sqlite3_malloc(
         1125  +      sizeof(sqlite3_rtree_geometry) + nBlob
         1126  +  );
  1120   1127     if( !pGeom ) return SQLITE_NOMEM;
  1121         -  memset(pGeom, 0, sizeof(RtreeGeometry));
         1128  +  memset(pGeom, 0, sizeof(sqlite3_rtree_geometry));
  1122   1129     p = (RtreeGeomBlob *)&pGeom[1];
  1123   1130   
  1124   1131     memcpy(p, sqlite3_value_blob(pValue), nBlob);
  1125   1132     if( p->magic!=RTREE_GEOMETRY_MAGIC 
  1126   1133      || nBlob!=(sizeof(RtreeGeomBlob) + (p->nParam-1)*sizeof(double))
  1127   1134     ){
  1128   1135       sqlite3_free(pGeom);
................................................................................
  3072   3079       void *c = (void *)RTREE_COORD_INT32;
  3073   3080       rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0);
  3074   3081     }
  3075   3082   
  3076   3083     return rc;
  3077   3084   }
  3078   3085   
  3079         -typedef struct GeomCallbackCtx GeomCallbackCtx;
  3080         -struct GeomCallbackCtx {
  3081         -  int (*xGeom)(RtreeGeometry *, int, double *, int *);
  3082         -  void *pContext;
  3083         -};
  3084         -
         3086  +/*
         3087  +** A version of sqlite3_free() that can be used as a callback. This is used
         3088  +** in two places - as the destructor for the blob value returned by the
         3089  +** invocation of a geometry function, and as the destructor for the geometry
         3090  +** functions themselves.
         3091  +*/
  3085   3092   static void doSqlite3Free(void *p){
  3086   3093     sqlite3_free(p);
  3087   3094   }
  3088   3095   
         3096  +typedef struct GeomCallbackCtx GeomCallbackCtx;
         3097  +struct GeomCallbackCtx {
         3098  +  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *);
         3099  +  void *pContext;
         3100  +};
         3101  +
         3102  +/*
         3103  +** Each call to sqlite3_rtree_geometry_callback() creates an ordinary SQLite
         3104  +** scalar user function. This C function is the callback used for all such
         3105  +** registered SQL functions.
         3106  +**
         3107  +** The scalar user functions return a blob that is interpreted by r-tree
         3108  +** table MATCH operators.
         3109  +*/
  3089   3110   static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
  3090   3111     GeomCallbackCtx *pGeomCtx = (GeomCallbackCtx *)sqlite3_user_data(ctx);
  3091   3112     RtreeGeomBlob *pBlob;
  3092   3113     int nBlob;
  3093   3114   
  3094   3115     nBlob = sizeof(RtreeGeomBlob) + (nArg-1)*sizeof(double);
  3095   3116     pBlob = (RtreeGeomBlob *)sqlite3_malloc(nBlob);
................................................................................
  3104   3125       for(i=0; i<nArg; i++){
  3105   3126         pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
  3106   3127       }
  3107   3128       sqlite3_result_blob(ctx, pBlob, nBlob, doSqlite3Free);
  3108   3129     }
  3109   3130   }
  3110   3131   
         3132  +/*
         3133  +** Register a new geometry function for use with the r-tree MATCH operator.
         3134  +*/
  3111   3135   int sqlite3_rtree_geometry_callback(
  3112   3136     sqlite3 *db,
  3113   3137     const char *zGeom,
  3114         -  int (*xGeom)(RtreeGeometry *, int nCoord, double *aCoord, int *piResOut),
         3138  +  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *),
  3115   3139     void *pContext
  3116   3140   ){
  3117   3141     GeomCallbackCtx *pGeomCtx;      /* Context object for new user-function */
  3118   3142   
  3119   3143     /* Allocate and populate the context object. */
  3120   3144     pGeomCtx = (GeomCallbackCtx *)sqlite3_malloc(sizeof(GeomCallbackCtx));
  3121   3145     if( !pGeomCtx ) return SQLITE_NOMEM;

Changes to ext/rtree/sqlite3rtree.h.

            1  +/*
            2  +** 2010 August 30
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +*/
           13  +
           14  +#ifndef _SQLITE3RTREE_H_
           15  +#define _SQLITE3RTREE_H_
     1     16   
     2     17   #include <sqlite3.h>
     3     18   
     4         -typedef struct RtreeGeometry RtreeGeometry;
           19  +#ifdef __cplusplus
           20  +extern "C" {
           21  +#endif
           22  +
           23  +typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
           24  +
           25  +/*
           26  +** Register a geometry callback named zGeom that can be used as part of an
           27  +** R-Tree geometry query as follows:
           28  +**
           29  +**   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
           30  +*/
           31  +int sqlite3_rtree_geometry_callback(
           32  +  sqlite3 *db,
           33  +  const char *zGeom,
           34  +  int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes),
           35  +  void *pContext
           36  +);
           37  +
     5     38   
     6         -struct RtreeGeometry {
           39  +/*
           40  +** A pointer to a structure of the following type is passed as the first
           41  +** argument to callbacks registered using rtree_geometry_callback().
           42  +*/
           43  +struct sqlite3_rtree_geometry {
     7     44     void *pContext;                 /* Copy of pContext passed to s_r_g_c() */
     8     45     int nParam;                     /* Size of array aParam[] */
     9     46     double *aParam;                 /* Parameters passed to SQL geom function */
    10     47     void *pUser;                    /* Callback implementation user data */
    11     48     void (*xDelUser)(void *);       /* Called by SQLite to clean up pUser */
    12     49   };
    13     50   
    14         -/*
    15         -** Register a geometry callback named zGeom that can be used as part of an
    16         -** R-Tree geometry query as follows:
    17         -**
    18         -**   SELECT ... FROM <rtree> WHERE <rtree> MATCH $zGeom(... params ...)
    19         -*/
    20         -int sqlite3_rtree_geometry_callback(
    21         -  sqlite3 *db,
    22         -  const char *zGeom,
    23         -  int (*xGeom)(RtreeGeometry *, int nCoord, double *aCoord, int *piResOut),
    24         -  void *pContext
    25         -);
           51  +
           52  +#ifdef __cplusplus
           53  +}  /* end of the 'extern "C"' block */
           54  +#endif
    26     55   
           56  +#endif  /* ifndef _SQLITE3RTREE_H_ */

Changes to src/test_rtree.c.

    44     44   ** coordinates as follows:
    45     45   **
    46     46   **   cube(x, y, z, width, height, depth)
    47     47   **
    48     48   ** The width, height and depth parameters must all be greater than zero.
    49     49   */
    50     50   static int cube_geom(
    51         -  RtreeGeometry *p,
           51  +  sqlite3_rtree_geometry *p,
    52     52     int nCoord, 
    53     53     double *aCoord, 
    54     54     int *piRes
    55     55   ){
    56     56     Cube *pCube = (Cube *)p->pUser;
    57     57   
    58     58     assert( p->pContext==(void *)&gHere );

Changes to tool/mksqlite3h.tcl.

    61     61   close $in
    62     62   
    63     63   # Set up patterns for recognizing API declarations.
    64     64   #
    65     65   set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+sqlite3_[_a-zA-Z0-9]+(\[|;| =)}
    66     66   set declpattern {^ *[a-zA-Z][a-zA-Z_0-9 ]+ \**sqlite3_[_a-zA-Z0-9]+\(}
    67     67   
    68         -# Process the  src/sqlite.h.in  file.
           68  +# Process the src/sqlite.h.in ext/rtree/sqlite3rtree.h files.
    69     69   #
    70         -set in [open $TOP/src/sqlite.h.in]
    71         -while {![eof $in]} {
    72         -
    73         -  set line [gets $in]
    74         -
    75         -  regsub -- --VERS--           $line $zVersion line
    76         -  regsub -- --VERSION-NUMBER-- $line $nVersion line
    77         -  regsub -- --SOURCE-ID--      $line "$zDate $zUuid" line
           70  +foreach file [list $TOP/src/sqlite.h.in $TOP/ext/rtree/sqlite3rtree.h] {
           71  +  set in [open $file]
           72  +  while {![eof $in]} {
           73  +  
           74  +    set line [gets $in]
    78     75   
    79         -  if {[regexp {define SQLITE_EXTERN extern} $line]} {
           76  +    # File sqlite3rtree.h contains a line "#include <sqlite3.h>". Omit this
           77  +    # line when copying sqlite3rtree.h into sqlite3.h.
           78  +    #
           79  +    if {[string match {*#include*<sqlite3.h>*} $line]} continue
           80  +  
           81  +    regsub -- --VERS--           $line $zVersion line
           82  +    regsub -- --VERSION-NUMBER-- $line $nVersion line
           83  +    regsub -- --SOURCE-ID--      $line "$zDate $zUuid" line
           84  +  
           85  +    if {[regexp {define SQLITE_EXTERN extern} $line]} {
           86  +      puts $line
           87  +      puts [gets $in]
           88  +      puts ""
           89  +      puts "#ifndef SQLITE_API"
           90  +      puts "# define SQLITE_API"
           91  +      puts "#endif"
           92  +      set line ""
           93  +    }
           94  +  
           95  +    if {([regexp $varpattern $line] && ![regexp {^ *typedef} $line])
           96  +     || ([regexp $declpattern $line])
           97  +    } {
           98  +      set line "SQLITE_API $line"
           99  +    }
    80    100       puts $line
    81         -    puts [gets $in]
    82         -    puts ""
    83         -    puts "#ifndef SQLITE_API"
    84         -    puts "# define SQLITE_API"
    85         -    puts "#endif"
    86         -    set line ""
    87         -  }
    88         -
    89         -  if {([regexp $varpattern $line] && ![regexp {^ *typedef} $line])
    90         -   || ([regexp $declpattern $line])
    91         -  } {
    92         -    set line "SQLITE_API $line"
    93    101     }
    94         -  puts $line
          102  +  close $in
    95    103   }
    96         -close $in