SQLite

Check-in [7c3d441f2a]
Login

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

Overview
Comment:Fix an off-by-one comparison in the intarray() virtual table. Get the intarray() virtual table tests working using the legacy makefile.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | prototype-int-array
Files: files | file ages | folders
SHA1: 7c3d441f2a9f642f3d91dcee854a4d16d298bc34
User & Date: drh 2016-07-02 20:57:06.871
Context
2016-07-03
02:35
Change the name of the intarray() extension to carray() and give it an optional third parameter that specifies the datatype as one of 'int32', 'int64', 'double', or 'char*'. 'int32' is the default. (Closed-Leaf check-in: a204ba99db user: drh tags: prototype-int-array)
2016-07-02
20:57
Fix an off-by-one comparison in the intarray() virtual table. Get the intarray() virtual table tests working using the legacy makefile. (check-in: 7c3d441f2a user: drh tags: prototype-int-array)
20:51
Merge the alternative table-valued function RHS of IN operator implementation from trunk. (check-in: 507fdbfb54 user: drh tags: prototype-int-array)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/misc/array.c.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
** has been cast to an integer.
**
** HOW IT WORKS
**
** The intarray "function" is really a virtual table with the
** following schema:
**
**     CREATE FUNCTION intarray(
**       value,
**       pointer HIDDEN,
**       count HIDDEN
**     );
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1







|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
** has been cast to an integer.
**
** HOW IT WORKS
**
** The intarray "function" is really a virtual table with the
** following schema:
**
**     CREATE TABLE intarray(
**       value,
**       pointer HIDDEN,
**       count HIDDEN
**     );
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int intarrayEof(sqlite3_vtab_cursor *cur){
  intarray_cursor *pCur = (intarray_cursor*)cur;
  return pCur->iRowid>=pCur->iCnt;
}

/*
** This method is called to "rewind" the intarray_cursor object back
** to the first row of output.
*/
static int intarrayFilter(
  sqlite3_vtab_cursor *pVtabCursor, 
  int idxNum, const char *idxStr,
  int argc, sqlite3_value **argv
){
  intarray_cursor *pCur = (intarray_cursor *)pVtabCursor;
  int i = 0;
  if( idxNum ){
    pCur->iPtr = sqlite3_value_int64(argv[0]);
    pCur->iCnt = sqlite3_value_int64(argv[1]);
  }else{
    pCur->iPtr = 0;
    pCur->iCnt = 0;
  }







|












<







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190

/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int intarrayEof(sqlite3_vtab_cursor *cur){
  intarray_cursor *pCur = (intarray_cursor*)cur;
  return pCur->iRowid>pCur->iCnt;
}

/*
** This method is called to "rewind" the intarray_cursor object back
** to the first row of output.
*/
static int intarrayFilter(
  sqlite3_vtab_cursor *pVtabCursor, 
  int idxNum, const char *idxStr,
  int argc, sqlite3_value **argv
){
  intarray_cursor *pCur = (intarray_cursor *)pVtabCursor;

  if( idxNum ){
    pCur->iPtr = sqlite3_value_int64(argv[0]);
    pCur->iCnt = sqlite3_value_int64(argv[1]);
  }else{
    pCur->iPtr = 0;
    pCur->iCnt = 0;
  }
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
** If idxNum is 0, then intarray becomes an empty table.
*/
static int intarrayBestIndex(
  sqlite3_vtab *tab,
  sqlite3_index_info *pIdxInfo
){
  int i;                 /* Loop over constraints */
  int idxNum = 0;        /* The query plan bitmask */
  int ptrIdx = -1;       /* Index of the pointer= constraint, or -1 if none */
  int cntIdx = -1;       /* Index of the count= constraint, or -1 if none */
  int nArg = 0;          /* Number of arguments that intarrayFilter() expects */

  const struct sqlite3_index_constraint *pConstraint;
  pConstraint = pIdxInfo->aConstraint;
  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
    if( pConstraint->usable==0 ) continue;
    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
    switch( pConstraint->iColumn ){







<


<







205
206
207
208
209
210
211

212
213

214
215
216
217
218
219
220
** If idxNum is 0, then intarray becomes an empty table.
*/
static int intarrayBestIndex(
  sqlite3_vtab *tab,
  sqlite3_index_info *pIdxInfo
){
  int i;                 /* Loop over constraints */

  int ptrIdx = -1;       /* Index of the pointer= constraint, or -1 if none */
  int cntIdx = -1;       /* Index of the count= constraint, or -1 if none */


  const struct sqlite3_index_constraint *pConstraint;
  pConstraint = pIdxInfo->aConstraint;
  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
    if( pConstraint->usable==0 ) continue;
    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
    switch( pConstraint->iColumn ){
Changes to main.mk.
320
321
322
323
324
325
326

327
328
329
330
331
332
333
  $(TOP)/src/test_windirent.c \
  $(TOP)/src/test_wsd.c

# Extensions to be statically loaded.
#
TESTSRC += \
  $(TOP)/ext/misc/amatch.c \

  $(TOP)/ext/misc/closure.c \
  $(TOP)/ext/misc/csv.c \
  $(TOP)/ext/misc/eval.c \
  $(TOP)/ext/misc/fileio.c \
  $(TOP)/ext/misc/fuzzer.c \
  $(TOP)/ext/misc/ieee754.c \
  $(TOP)/ext/misc/nextchar.c \







>







320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
  $(TOP)/src/test_windirent.c \
  $(TOP)/src/test_wsd.c

# Extensions to be statically loaded.
#
TESTSRC += \
  $(TOP)/ext/misc/amatch.c \
  $(TOP)/ext/misc/array.c \
  $(TOP)/ext/misc/closure.c \
  $(TOP)/ext/misc/csv.c \
  $(TOP)/ext/misc/eval.c \
  $(TOP)/ext/misc/fileio.c \
  $(TOP)/ext/misc/fuzzer.c \
  $(TOP)/ext/misc/ieee754.c \
  $(TOP)/ext/misc/nextchar.c \
Changes to test/tabfunc01.test.
197
198
199
200
201
202
203











204
205
206
207
208
do_test tabfunc01-671 {
  sqlite3_bind_intarray $VM 1 11 22 33 44 55
  sqlite3_step $VM
} SQLITE_ROW
do_test tabfunc01-672 {
  sqlite3_column_int $VM 0
} 11











sqlite3_finalize $VM

catch {sqlite3_bind_intarray}

finish_test







>
>
>
>
>
>
>
>
>
>
>





197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
do_test tabfunc01-671 {
  sqlite3_bind_intarray $VM 1 11 22 33 44 55
  sqlite3_step $VM
} SQLITE_ROW
do_test tabfunc01-672 {
  sqlite3_column_int $VM 0
} 11
do_test tabfunc01-673 {
  sqlite3_step $VM
  sqlite3_column_int $VM 0
} 22
do_test tabfunc01-674 {
  sqlite3_step $VM
  sqlite3_column_int $VM 0
} 33
do_test tabfunc01-675 {
  sqlite3_step $VM
} {SQLITE_DONE}
sqlite3_finalize $VM

catch {sqlite3_bind_intarray}

finish_test