Diff
Not logged in

Differences From Artifact [6828a2deef]:

To Artifact [8896d1d455]:


6000
6001
6002
6003
6004
6005
6006
6007
6008
6009



6010
6011
6012
6013




6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027

6028
6029
6030
6031
6032

6033
6034
6035
6036
6037

6038
6039
6040
6041
6042

6043
6044
6045


















6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057

6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080







6081
6082
6083
6084
6085
6086
6087

6088

6089
6090
6091

6092
6093
6094
6095
6096
6097
6098
6099

6100
6101
6102
6103
















6104
6105
6106
6107


6108



6109
6110
6111
6112

6113
6114
6115
6116





6117

6118
6119
6120


6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141

6142
6143
6144
6145
6146
6147
6148

6149
6150

6151
6152
6153



6154
6155
6156
6157
6158
6159
6160
6000
6001
6002
6003
6004
6005
6006



6007
6008
6009




6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026

6027
6028
6029
6030
6031

6032
6033
6034
6035
6036

6037
6038
6039
6040
6041

6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074

6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094




6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113

6114
6115
6116
6117
6118
6119
6120
6121

6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148

6149
6150
6151
6152
6153
6154

6155
6156
6157
6158
6159
6160
6161
6162
6163
6164

6165
6166
6167

6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189

6190
6191
6192
6193
6194
6195
6196

6197
6198

6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212







-
-
-
+
+
+
-
-
-
-
+
+
+
+













-
+




-
+




-
+




-
+



+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+











-
+



















-
-
-
-
+
+
+
+
+
+
+







+

+


-
+







-
+




+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




+
+
-
+
+
+



-
+




+
+
+
+
+
-
+


-
+
+




















-
+






-
+

-
+



+
+
+







** once prior to any call to seriesColumn() or seriesRowid() or
** seriesEof().
**
** The query plan selected by seriesBestIndex is passed in the idxNum
** parameter.  (idxStr is not used in this implementation.)  idxNum
** is a bitmask showing which constraints are available:
**
**    1:    start=VALUE
**    2:    stop=VALUE
**    4:    step=VALUE
**   0x01:    start=VALUE
**   0x02:    stop=VALUE
**   0x04:    step=VALUE
**
** Also, if bit 8 is set, that means that the series should be output
** in descending order rather than in ascending order.  If bit 16 is
** set, then output must appear in ascending order.
**   0x08:    descending order
**   0x10:    ascending order
**   0x20:    LIMIT  VALUE
**   0x40:    OFFSET  VALUE
**
** This routine should initialize the cursor and position it so that it
** is pointing at the first row, or pointing off the end of the table
** (so that seriesEof() will return true) if the table is empty.
*/
static int seriesFilter(
  sqlite3_vtab_cursor *pVtabCursor,
  int idxNum, const char *idxStrUnused,
  int argc, sqlite3_value **argv
){
  series_cursor *pCur = (series_cursor *)pVtabCursor;
  int i = 0;
  (void)idxStrUnused;
  if( idxNum & 1 ){
  if( idxNum & 0x01 ){
    pCur->ss.iBase = sqlite3_value_int64(argv[i++]);
  }else{
    pCur->ss.iBase = 0;
  }
  if( idxNum & 2 ){
  if( idxNum & 0x02 ){
    pCur->ss.iTerm = sqlite3_value_int64(argv[i++]);
  }else{
    pCur->ss.iTerm = 0xffffffff;
  }
  if( idxNum & 4 ){
  if( idxNum & 0x04 ){
    pCur->ss.iStep = sqlite3_value_int64(argv[i++]);
    if( pCur->ss.iStep==0 ){
      pCur->ss.iStep = 1;
    }else if( pCur->ss.iStep<0 ){
      if( (idxNum & 16)==0 ) idxNum |= 8;
      if( (idxNum & 0x10)==0 ) idxNum |= 0x08;
    }
  }else{
    pCur->ss.iStep = 1;
  }
  if( idxNum & 0x20 ){
    sqlite3_int64 iLimit = sqlite3_value_int64(argv[i++]);
    sqlite3_int64 iTerm;
    if( idxNum & 0x40 ){
      sqlite3_int64 iOffset = sqlite3_value_int64(argv[i++]);
      if( iOffset>0 ){
        pCur->ss.iBase += pCur->ss.iStep*iOffset;
      }
    }
    if( iLimit>=0 ){
      iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep;
      if( pCur->ss.iStep<0 ){
        if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
      }else{
        if( iTerm<pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
      }
    }
  }
  for(i=0; i<argc; i++){
    if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
      /* If any of the constraints have a NULL value, then return no rows.
      ** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */
      pCur->ss.iBase = 1;
      pCur->ss.iTerm = 0;
      pCur->ss.iStep = 1;
      break;
    }
  }
  if( idxNum & 8 ){
  if( idxNum & 0x08 ){
    pCur->ss.isReversing = pCur->ss.iStep > 0;
  }else{
    pCur->ss.isReversing = pCur->ss.iStep < 0;
  }
  setupSequence( &pCur->ss );
  return SQLITE_OK;
}

/*
** SQLite will invoke this method one or more times while planning a query
** that uses the generate_series virtual table.  This routine needs to create
** a query plan for each invocation and compute an estimated cost for that
** plan.
**
** In this implementation idxNum is used to represent the
** query plan.  idxStr is unused.
**
** The query plan is represented by bits in idxNum:
**
**  (1)  start = $value  -- constraint exists
**  (2)  stop = $value   -- constraint exists
**  (4)  step = $value   -- constraint exists
**  (8)  output in descending order
**   0x01  start = $value  -- constraint exists
**   0x02  stop = $value   -- constraint exists
**   0x04  step = $value   -- constraint exists
**   0x08  output is in descending order
**   0x10  output is in ascending order
**   0x20  LIMIT $value    -- constraint exists
**   0x40  OFFSET $value   -- constraint exists
*/
static int seriesBestIndex(
  sqlite3_vtab *pVTab,
  sqlite3_index_info *pIdxInfo
){
  int i, j;              /* Loop over constraints */
  int idxNum = 0;        /* The query plan bitmask */
#ifndef ZERO_ARGUMENT_GENERATE_SERIES
  int bStartSeen = 0;    /* EQ constraint seen on the START column */
#endif
  int unusableMask = 0;  /* Mask of unusable constraints */
  int nArg = 0;          /* Number of arguments that seriesFilter() expects */
  int aIdx[3];           /* Constraints on start, stop, and step */
  int aIdx[5];           /* Constraints on start, stop, step, LIMIT, OFFSET */
  const struct sqlite3_index_constraint *pConstraint;

  /* This implementation assumes that the start, stop, and step columns
  ** are the last three columns in the virtual table. */
  assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 );
  assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 );

  aIdx[0] = aIdx[1] = aIdx[2] = -1;
  aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = -1;
  pConstraint = pIdxInfo->aConstraint;
  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
    int iCol;    /* 0 for start, 1 for stop, 2 for step */
    int iMask;   /* bitmask for those column */
    int op = pConstraint->op;
    if( op>=SQLITE_INDEX_CONSTRAINT_LIMIT
     && op<=SQLITE_INDEX_CONSTRAINT_OFFSET
    ){
      if( pConstraint->usable==0 ){
        /* do nothing */
      }else if( op==SQLITE_INDEX_CONSTRAINT_LIMIT ){
        aIdx[3] = i;
        idxNum |= 0x20;
      }else{
        assert( op==SQLITE_INDEX_CONSTRAINT_OFFSET );
        aIdx[4] = i;
        idxNum |= 0x40;
      }
      continue;
    }
    if( pConstraint->iColumn<SERIES_COLUMN_START ) continue;
    iCol = pConstraint->iColumn - SERIES_COLUMN_START;
    assert( iCol>=0 && iCol<=2 );
    iMask = 1 << iCol;
#ifndef ZERO_ARGUMENT_GENERATE_SERIES
    if( iCol==0 && op==SQLITE_INDEX_CONSTRAINT_EQ ){
    if( iCol==0 ) bStartSeen = 1;
      bStartSeen = 1;
    }
#endif
    if( pConstraint->usable==0 ){
      unusableMask |=  iMask;
      continue;
    }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
    }else if( op==SQLITE_INDEX_CONSTRAINT_EQ ){
      idxNum |= iMask;
      aIdx[iCol] = i;
    }
  }
  if( aIdx[3]==0 ){
    /* Ignore OFFSET if LIMIT is omitted */
    idxNum &= ~0x60;
    aIdx[4] = 0;
  }
  for(i=0; i<3; i++){
  for(i=0; i<5; i++){
    if( (j = aIdx[i])>=0 ){
      pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg;
      pIdxInfo->aConstraintUsage[j].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY;
      pIdxInfo->aConstraintUsage[j].omit =
         !SQLITE_SERIES_CONSTRAINT_VERIFY || i>=3;
    }
  }
  /* The current generate_column() implementation requires at least one
  ** argument (the START value).  Legacy versions assumed START=0 if the
  ** first argument was omitted.  Compile with -DZERO_ARGUMENT_GENERATE_SERIES
  ** to obtain the legacy behavior */
#ifndef ZERO_ARGUMENT_GENERATE_SERIES
  if( !bStartSeen ){
    sqlite3_free(pVTab->zErrMsg);
    pVTab->zErrMsg = sqlite3_mprintf(
        "first argument to \"generate_series()\" missing or unusable");
    return SQLITE_ERROR;
  }
#endif
  if( (unusableMask & ~idxNum)!=0 ){
    /* The start, stop, and step columns are inputs.  Therefore if there
    ** are unusable constraints on any of start, stop, or step then
    ** this plan is unusable */
    return SQLITE_CONSTRAINT;
  }
  if( (idxNum & 3)==3 ){
  if( (idxNum & 0x03)==0x03 ){
    /* Both start= and stop= boundaries are available.  This is the 
    ** the preferred case */
    pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0));
    pIdxInfo->estimatedRows = 1000;
    if( pIdxInfo->nOrderBy>=1 && pIdxInfo->aOrderBy[0].iColumn==0 ){
      if( pIdxInfo->aOrderBy[0].desc ){
        idxNum |= 8;
        idxNum |= 0x08;
      }else{
        idxNum |= 16;
        idxNum |= 0x10;
      }
      pIdxInfo->orderByConsumed = 1;
    }
  }else if( (idxNum & 0x21)==0x21 ){
    /* We have start= and LIMIT */
    pIdxInfo->estimatedRows = 2500;
  }else{
    /* If either boundary is missing, we have to generate a huge span
    ** of numbers.  Make this case very expensive so that the query
    ** planner will work hard to avoid it. */
    pIdxInfo->estimatedRows = 2147483647;
  }
  pIdxInfo->idxNum = idxNum;
7473
7474
7475
7476
7477
7478
7479


7480

7481
7482
7483
7484
7485
7486
7487
7525
7526
7527
7528
7529
7530
7531
7532
7533

7534
7535
7536
7537
7538
7539
7540
7541







+
+
-
+







  mode_t mode,                    /* MODE parameter passed to writefile() */
  sqlite3_int64 mtime             /* MTIME parameter (or -1 to not set time) */
){
  if( zFile==0 ) return 1;
#if !defined(_WIN32) && !defined(WIN32)
  if( S_ISLNK(mode) ){
    const char *zTo = (const char*)sqlite3_value_text(pData);
    if( zTo==0 ) return 1;
    unlink(zFile);
    if( zTo==0 || symlink(zTo, zFile)<0 ) return 1;
    if( symlink(zTo, zFile)<0 ) return 1;
  }else
#endif
  {
    if( S_ISDIR(mode) ){
      if( mkdir(zFile, mode) ){
        /* The mkdir() call to create the directory failed. This might not
        ** be an error though - if there is already a directory at the same
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572













7573
7574
7575
7576
7577
7578
7579
7613
7614
7615
7616
7617
7618
7619







7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639







-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+







    times[0].tv_nsec = times[1].tv_nsec = 0;
    times[0].tv_sec = time(0);
    times[1].tv_sec = mtime;
    if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
      return 1;
    }
#else
    /* Legacy unix */
    struct timeval times[2];
    times[0].tv_usec = times[1].tv_usec = 0;
    times[0].tv_sec = time(0);
    times[1].tv_sec = mtime;
    if( utimes(zFile, times) ){
      return 1;
    /* Legacy unix. 
    **
    ** Do not use utimes() on a symbolic link - it sees through the link and
    ** modifies the timestamps on the target. Or fails if the target does 
    ** not exist.  */
    if( 0==S_ISLNK(mode) ){
      struct timeval times[2];
      times[0].tv_usec = times[1].tv_usec = 0;
      times[0].tv_sec = time(0);
      times[1].tv_sec = mtime;
      if( utimes(zFile, times) ){
        return 1;
      }
    }
#endif
  }

  return 0;
}

11637
11638
11639
11640
11641
11642
11643
11644

11645
11646
11647
11648
11649
11650
11651

11652
11653
11654
11655
11656

11657
11658
11659

11660
11661
11662
11663
11664
11665
11666
11697
11698
11699
11700
11701
11702
11703

11704
11705
11706
11707
11708
11709
11710
11711
11712
11713
11714
11715
11716

11717
11718
11719

11720
11721
11722
11723
11724
11725
11726
11727







-
+







+




-
+


-
+







*/
static void sqlarUncompressFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  uLong nData;
  uLongf sz;
  sqlite3_int64 sz;

  assert( argc==2 );
  sz = sqlite3_value_int(argv[1]);

  if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){
    sqlite3_result_value(context, argv[0]);
  }else{
    uLongf szf = sz;
    const Bytef *pData= sqlite3_value_blob(argv[0]);
    Bytef *pOut = sqlite3_malloc(sz);
    if( pOut==0 ){
      sqlite3_result_error_nomem(context);
    }else if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){
    }else if( Z_OK!=uncompress(pOut, &szf, pData, nData) ){
      sqlite3_result_error(context, "error in uncompress()", -1);
    }else{
      sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT);
      sqlite3_result_blob(context, pOut, szf, SQLITE_TRANSIENT);
    }
    sqlite3_free(pOut);
  }
}

#ifdef _WIN32

15474
15475
15476
15477
15478
15479
15480









15481
15482
15483
15484
15485
15486
15487
15488
15489
15490
15491
15492
15493
15494
15495
15496
15497

15498
15499
15500
15501
15502
15503
15504
15535
15536
15537
15538
15539
15540
15541
15542
15543
15544
15545
15546
15547
15548
15549
15550
15551
15552
15553
15554
15555
15556
15557
15558
15559
15560
15561
15562
15563
15564
15565
15566

15567
15568
15569
15570
15571
15572
15573
15574







+
+
+
+
+
+
+
+
+
















-
+








#ifndef SQLITE_OMIT_VIRTUALTABLE

#define DBDATA_PADDING_BYTES 100 

typedef struct DbdataTable DbdataTable;
typedef struct DbdataCursor DbdataCursor;
typedef struct DbdataBuffer DbdataBuffer;

/*
** Buffer type.
*/
struct DbdataBuffer {
  u8 *aBuf;
  sqlite3_int64 nBuf;
};

/* Cursor object */
struct DbdataCursor {
  sqlite3_vtab_cursor base;       /* Base class.  Must be first */
  sqlite3_stmt *pStmt;            /* For fetching database pages */

  int iPgno;                      /* Current page number */
  u8 *aPage;                      /* Buffer containing page */
  int nPage;                      /* Size of aPage[] in bytes */
  int nCell;                      /* Number of cells on aPage[] */
  int iCell;                      /* Current cell number */
  int bOnePage;                   /* True to stop after one page */
  int szDb;
  sqlite3_int64 iRowid;

  /* Only for the sqlite_dbdata table */
  u8 *pRec;                       /* Buffer containing current record */
  DbdataBuffer rec;
  sqlite3_int64 nRec;             /* Size of pRec[] in bytes */
  sqlite3_int64 nHdr;             /* Size of header in bytes */
  int iField;                     /* Current field number */
  u8 *pHdrPtr;
  u8 *pPtr;
  u32 enc;                        /* Text encoding */
  
15534
15535
15536
15537
15538
15539
15540

























15541
15542
15543
15544
15545
15546
15547
15604
15605
15606
15607
15608
15609
15610
15611
15612
15613
15614
15615
15616
15617
15618
15619
15620
15621
15622
15623
15624
15625
15626
15627
15628
15629
15630
15631
15632
15633
15634
15635
15636
15637
15638
15639
15640
15641
15642







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#define DBPTR_COLUMN_SCHEMA       2
#define DBPTR_SCHEMA              \
      "CREATE TABLE x("           \
      "  pgno INTEGER,"           \
      "  child INTEGER,"          \
      "  schema TEXT HIDDEN"      \
      ")"

/*
** Ensure the buffer passed as the first argument is at least nMin bytes
** in size. If an error occurs while attempting to resize the buffer,
** SQLITE_NOMEM is returned. Otherwise, SQLITE_OK.
*/
static int dbdataBufferSize(DbdataBuffer *pBuf, sqlite3_int64 nMin){
  if( nMin>pBuf->nBuf ){
    sqlite3_int64 nNew = nMin+16384;
    u8 *aNew = (u8*)sqlite3_realloc64(pBuf->aBuf, nNew);

    if( aNew==0 ) return SQLITE_NOMEM;
    pBuf->aBuf = aNew;
    pBuf->nBuf = nNew;
  }
  return SQLITE_OK;
}

/*
** Release the allocation managed by buffer pBuf.
*/
static void dbdataBufferFree(DbdataBuffer *pBuf){
  sqlite3_free(pBuf->aBuf);
  memset(pBuf, 0, sizeof(*pBuf));
}

/*
** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual 
** table.
*/
static int dbdataConnect(
  sqlite3 *db,
15675
15676
15677
15678
15679
15680
15681
15682
15683

15684
15685
15686
15687
15688
15689
15690
15770
15771
15772
15773
15774
15775
15776


15777
15778
15779
15780
15781
15782
15783
15784







-
-
+







  }
  pCsr->pStmt = 0;
  pCsr->iPgno = 1;
  pCsr->iCell = 0;
  pCsr->iField = 0;
  pCsr->bOnePage = 0;
  sqlite3_free(pCsr->aPage);
  sqlite3_free(pCsr->pRec);
  pCsr->pRec = 0;
  dbdataBufferFree(&pCsr->rec);
  pCsr->aPage = 0;
}

/*
** Close an sqlite_dbdata or sqlite_dbptr cursor.
*/
static int dbdataClose(sqlite3_vtab_cursor *pCursor){
15937
15938
15939
15940
15941
15942
15943
15944

15945
15946
15947
15948
15949
15950
15951
16031
16032
16033
16034
16035
16036
16037

16038
16039
16040
16041
16042
16043
16044
16045







-
+







        if( pCsr->bOnePage ) return SQLITE_OK;
        pCsr->iPgno++;
      }else{
        return SQLITE_OK;
      }
    }else{
      /* If there is no record loaded, load it now. */
      if( pCsr->pRec==0 ){
      if( pCsr->nRec==0 ){
        int bHasRowid = 0;
        int nPointer = 0;
        sqlite3_int64 nPayload = 0;
        sqlite3_int64 nHdr = 0;
        int iHdr;
        int U, X;
        int nLocal;
15981
15982
15983
15984
15985
15986
15987

15988
15989
15990
15991
15992
15993
15994
16075
16076
16077
16078
16079
16080
16081
16082
16083
16084
16085
16086
16087
16088
16089







+







    
          /* Load the "byte of payload including overflow" field */
          if( bNextPage || iOff>pCsr->nPage || iOff<=iCellPtr ){
            bNextPage = 1;
          }else{
            iOff += dbdataGetVarintU32(&pCsr->aPage[iOff], &nPayload);
            if( nPayload>0x7fffff00 ) nPayload &= 0x3fff;
            if( nPayload==0 ) nPayload = 1;
          }
    
          /* If this is a leaf intkey cell, load the rowid */
          if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){
            iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey);
          }
    
16015
16016
16017
16018
16019
16020
16021
16022
16023


16024
16025

16026
16027
16028

16029
16030
16031
16032
16033
16034
16035
16036
16037
16038
16039
16040
16041
16042
16043
16044
16045
16046

16047
16048
16049
16050
16051

16052


16053
16054

16055
16056
16057
16058


16059
16060
16061
16062
16063
16064
16065
16066

16067
16068
16069
16070
16071
16072
16073
16074
16075


16076
16077
16078
16079
16080
16081
16082
16083
16084
16085
16086
16087

16088
16089
16090
16091

16092
16093
16094
16095
16096
16097
16098

16099
16100
16101
16102
16103
16104
16105
16110
16111
16112
16113
16114
16115
16116


16117
16118


16119
16120
16121

16122
16123
16124
16125
16126
16127
16128
16129
16130
16131
16132
16133
16134
16135
16136
16137
16138
16139

16140
16141
16142
16143
16144
16145
16146
16147
16148
16149
16150

16151
16152
16153


16154
16155
16156
16157
16158
16159
16160
16161
16162

16163
16164
16165
16166
16167
16168
16169
16170


16171
16172
16173
16174
16175
16176
16177
16178
16179
16180
16181

16182

16183
16184
16185
16186

16187
16188
16189
16190
16191
16192


16193
16194
16195
16196
16197
16198
16199
16200







-
-
+
+
-
-
+


-
+

















-
+





+

+
+

-
+


-
-
+
+







-
+







-
-
+
+









-

-
+



-
+





-
-
+







          if( bNextPage || nLocal+iOff>pCsr->nPage ){
            bNextPage = 1;
          }else{

            /* Allocate space for payload. And a bit more to catch small buffer
            ** overruns caused by attempting to read a varint or similar from 
            ** near the end of a corrupt record.  */
            pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES);
            if( pCsr->pRec==0 ) return SQLITE_NOMEM;
            rc = dbdataBufferSize(&pCsr->rec, nPayload+DBDATA_PADDING_BYTES);
            if( rc!=SQLITE_OK ) return rc;
            memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES);
            pCsr->nRec = nPayload;
            assert( nPayload!=0 );

            /* Load the nLocal bytes of payload */
            memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal);
            memcpy(pCsr->rec.aBuf, &pCsr->aPage[iOff], nLocal);
            iOff += nLocal;

            /* Load content from overflow pages */
            if( nPayload>nLocal ){
              sqlite3_int64 nRem = nPayload - nLocal;
              u32 pgnoOvfl = get_uint32(&pCsr->aPage[iOff]);
              while( nRem>0 ){
                u8 *aOvfl = 0;
                int nOvfl = 0;
                int nCopy;
                rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl);
                assert( rc!=SQLITE_OK || aOvfl==0 || nOvfl==pCsr->nPage );
                if( rc!=SQLITE_OK ) return rc;
                if( aOvfl==0 ) break;

                nCopy = U-4;
                if( nCopy>nRem ) nCopy = nRem;
                memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy);
                memcpy(&pCsr->rec.aBuf[nPayload-nRem], &aOvfl[4], nCopy);
                nRem -= nCopy;

                pgnoOvfl = get_uint32(aOvfl);
                sqlite3_free(aOvfl);
              }
              nPayload -= nRem;
            }
            memset(&pCsr->rec.aBuf[nPayload], 0, DBDATA_PADDING_BYTES);
            pCsr->nRec = nPayload;
    
            iHdr = dbdataGetVarintU32(pCsr->pRec, &nHdr);
            iHdr = dbdataGetVarintU32(pCsr->rec.aBuf, &nHdr);
            if( nHdr>nPayload ) nHdr = 0;
            pCsr->nHdr = nHdr;
            pCsr->pHdrPtr = &pCsr->pRec[iHdr];
            pCsr->pPtr = &pCsr->pRec[pCsr->nHdr];
            pCsr->pHdrPtr = &pCsr->rec.aBuf[iHdr];
            pCsr->pPtr = &pCsr->rec.aBuf[pCsr->nHdr];
            pCsr->iField = (bHasRowid ? -1 : 0);
          }
        }
      }else{
        pCsr->iField++;
        if( pCsr->iField>0 ){
          sqlite3_int64 iType;
          if( pCsr->pHdrPtr>=&pCsr->pRec[pCsr->nRec] 
          if( pCsr->pHdrPtr>=&pCsr->rec.aBuf[pCsr->nRec] 
           || pCsr->iField>=DBDATA_MX_FIELD
          ){
            bNextPage = 1;
          }else{
            int szField = 0;
            pCsr->pHdrPtr += dbdataGetVarintU32(pCsr->pHdrPtr, &iType);
            szField = dbdataValueBytes(iType);
            if( (pCsr->nRec - (pCsr->pPtr - pCsr->pRec))<szField ){
              pCsr->pPtr = &pCsr->pRec[pCsr->nRec];
            if( (pCsr->nRec - (pCsr->pPtr - pCsr->rec.aBuf))<szField ){
              pCsr->pPtr = &pCsr->rec.aBuf[pCsr->nRec];
            }else{
              pCsr->pPtr += szField;
            }
          }
        }
      }

      if( bNextPage ){
        sqlite3_free(pCsr->aPage);
        sqlite3_free(pCsr->pRec);
        pCsr->aPage = 0;
        pCsr->pRec = 0;
        pCsr->nRec = 0;
        if( pCsr->bOnePage ) return SQLITE_OK;
        pCsr->iPgno++;
      }else{
        if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){
        if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->rec.aBuf[pCsr->nHdr] ){
          return SQLITE_OK;
        }

        /* Advance to the next cell. The next iteration of the loop will load
        ** the record and so on. */
        sqlite3_free(pCsr->pRec);
        pCsr->pRec = 0;
        pCsr->nRec = 0;
        pCsr->iCell++;
      }
    }
  }

  assert( !"can't get here" );
  return SQLITE_OK;
16281
16282
16283
16284
16285
16286
16287
16288

16289
16290
16291
16292
16293

16294
16295
16296
16297
16298
16299
16300
16376
16377
16378
16379
16380
16381
16382

16383
16384
16385
16386
16387

16388
16389
16390
16391
16392
16393
16394
16395







-
+




-
+







        break;
      case DBDATA_COLUMN_FIELD:
        sqlite3_result_int(ctx, pCsr->iField);
        break;
      case DBDATA_COLUMN_VALUE: {
        if( pCsr->iField<0 ){
          sqlite3_result_int64(ctx, pCsr->iIntkey);
        }else if( &pCsr->pRec[pCsr->nRec] >= pCsr->pPtr ){
        }else if( &pCsr->rec.aBuf[pCsr->nRec] >= pCsr->pPtr ){
          sqlite3_int64 iType;
          dbdataGetVarintU32(pCsr->pHdrPtr, &iType);
          dbdataValue(
              ctx, pCsr->enc, iType, pCsr->pPtr, 
              &pCsr->pRec[pCsr->nRec] - pCsr->pPtr
              &pCsr->rec.aBuf[pCsr->nRec] - pCsr->pPtr
          );
        }
        break;
      }
    }
  }
  return SQLITE_OK;