/ Check-in [a06a6392]
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:Merge the table-valued-function rowid fix.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | json
Files: files | file ages | folders
SHA1: a06a6392bd48baa8b9bac2624869c0cc7da7e779
User & Date: drh 2015-08-19 19:26:13
Context
2015-08-19
22:47
Add the json_each(JSON,PATH) table-valued-function. check-in: 3335ac17 user: drh tags: json
19:26
Merge the table-valued-function rowid fix. check-in: a06a6392 user: drh tags: json
19:01
Fix eponymous virtual tables so that they do not automatically make the first column the rowid. Enhance the generate_series virtual table to support rowid. check-in: a325a085 user: drh tags: table-valued-functions
18:31
Merge support for table-valued functions. check-in: 96a5d44d user: drh tags: json
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/misc/series.c.

    80     80   ** serve as the underlying representation of a cursor that scans
    81     81   ** over rows of the result
    82     82   */
    83     83   typedef struct series_cursor series_cursor;
    84     84   struct series_cursor {
    85     85     sqlite3_vtab_cursor base;  /* Base class - must be first */
    86     86     int isDesc;                /* True to count down rather than up */
           87  +  sqlite3_int64 iRowid;      /* The rowid */
    87     88     sqlite3_int64 iValue;      /* Current value ("value") */
    88     89     sqlite3_int64 mnValue;     /* Mimimum value ("start") */
    89     90     sqlite3_int64 mxValue;     /* Maximum value ("stop") */
    90     91     sqlite3_int64 iStep;       /* Increment ("step") */
    91     92   };
    92     93   
    93     94   /*
................................................................................
   161    162   static int seriesNext(sqlite3_vtab_cursor *cur){
   162    163     series_cursor *pCur = (series_cursor*)cur;
   163    164     if( pCur->isDesc ){
   164    165       pCur->iValue -= pCur->iStep;
   165    166     }else{
   166    167       pCur->iValue += pCur->iStep;
   167    168     }
          169  +  pCur->iRowid++;
   168    170     return SQLITE_OK;
   169    171   }
   170    172   
   171    173   /*
   172    174   ** Return values of columns for the row at which the series_cursor
   173    175   ** is currently pointing.
   174    176   */
................................................................................
   191    193   
   192    194   /*
   193    195   ** Return the rowid for the current row.  In this implementation, the
   194    196   ** rowid is the same as the output value.
   195    197   */
   196    198   static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
   197    199     series_cursor *pCur = (series_cursor*)cur;
   198         -  *pRowid = pCur->iValue;
          200  +  *pRowid = pCur->iRowid;
   199    201     return SQLITE_OK;
   200    202   }
   201    203   
   202    204   /*
   203    205   ** Return TRUE if the cursor has been moved off of the last
   204    206   ** row of output.
   205    207   */
................................................................................
   262    264       if( pCur->iStep>0 ){
   263    265         pCur->iValue -= (pCur->mxValue - pCur->mnValue)%pCur->iStep;
   264    266       }
   265    267     }else{
   266    268       pCur->isDesc = 0;
   267    269       pCur->iValue = pCur->mnValue;
   268    270     }
          271  +  pCur->iRowid = 1;
   269    272     return SQLITE_OK;
   270    273   }
   271    274   
   272    275   /*
   273    276   ** SQLite will invoke this method one or more times while planning a query
   274    277   ** that uses the generate_series virtual table.  This routine needs to create
   275    278   ** a query plan for each invocation and compute an estimated cost for that

Changes to src/vtab.c.

  1116   1116     pMod->pEpoTab = pTab;
  1117   1117     pTab->zName = (char*)&pTab[1];
  1118   1118     memcpy(pTab->zName, pMod->zName, nName);
  1119   1119     pTab->nRef = 1;
  1120   1120     pTab->pSchema = db->aDb[0].pSchema;
  1121   1121     pTab->tabFlags |= TF_Virtual;
  1122   1122     pTab->nModuleArg = 0;
         1123  +  pTab->iPKey = -1;
  1123   1124     addModuleArgument(db, pTab, pTab->zName);
  1124   1125     addModuleArgument(db, pTab, 0);
  1125   1126     addModuleArgument(db, pTab, pTab->zName);
  1126   1127     rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
  1127   1128     if( rc ){
  1128   1129       sqlite3ErrorMsg(pParse, "%s", zErr);
  1129   1130       sqlite3DbFree(db, zErr);

Changes to test/tabfunc01.test.

    44     44   do_catchsql_test tabfunc01-1.7 {
    45     45     SELECT * FROM generate_series(1,9,2,11);
    46     46   } {1 {too many arguments on generate_series - max 3}}
    47     47   
    48     48   do_execsql_test tabfunc01-1.8 {
    49     49     SELECT * FROM generate_series(0,32,5) ORDER BY rowid DESC;
    50     50   } {30 25 20 15 10 5 0}
           51  +do_execsql_test tabfunc01-1.9 {
           52  +  SELECT rowid, * FROM generate_series(0,32,5) ORDER BY value DESC;
           53  +} {1 30 2 25 3 20 4 15 5 10 6 5 7 0}
           54  +do_execsql_test tabfunc01-1.10 {
           55  +  SELECT rowid, * FROM generate_series(0,32,5) ORDER BY +value DESC;
           56  +} {7 30 6 25 5 20 4 15 3 10 2 5 1 0}
    51     57   
    52     58   do_execsql_test tabfunc01-2.1 {
    53     59     CREATE TABLE t1(x);
    54     60     INSERT INTO t1(x) VALUES(2),(3);
    55     61     SELECT *, '|' FROM t1, generate_series(1,x) ORDER BY 1, 2
    56     62   } {2 1 | 2 2 | 3 1 | 3 2 | 3 3 |}
    57     63   
    58     64   finish_test