/ Check-in [9c3a6e47]
Login

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

Overview
Comment:Merge in all the latest changes from the trunk, and especially the interface changes to the SystemCall methods of the VFS.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1:9c3a6e479988e96086bef00c79dbce508a14da0d
User & Date: drh 2011-03-23 22:48:46
Context
2011-03-24
11:22
Store primary key definitions for modified tables in changesets. Add the sqlite3changeset_pk() API to extract this data from a changeset iterator. check-in: 54298ee5 user: dan tags: sessions
2011-03-23
22:48
Merge in all the latest changes from the trunk, and especially the interface changes to the SystemCall methods of the VFS. check-in: 9c3a6e47 user: drh tags: sessions
22:02
Change the xSetSyscall methods of the VFS so that they do not cast object pointers into function pointers. Fix other unrelated compiler warnings. check-in: e059152a user: drh tags: trunk
16:03
Add the "indirect flag" to the changeset blob format. Also the sqlite3session_indirect() API. check-in: 1feaf2d3 user: dan tags: sessions
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/fts3/fts3_snippet.c.

876
877
878
879
880
881
882




883
884
885
886
887
888
889
890
891
892
893
894
895
896
*/
static int fts3ExprLocalHitsCb(
  Fts3Expr *pExpr,                /* Phrase expression node */
  int iPhrase,                    /* Phrase number */
  void *pCtx                      /* Pointer to MatchInfo structure */
){
  MatchInfo *p = (MatchInfo *)pCtx;





  if( pExpr->aDoclist ){
    char *pCsr;
    int iStart = iPhrase * p->nCol * 3;
    int i;

    for(i=0; i<p->nCol; i++) p->aMatchinfo[iStart+i*3] = 0;

    pCsr = sqlite3Fts3FindPositions(pExpr, p->pCursor->iPrevId, -1);
    if( pCsr ){
      fts3LoadColumnlistCounts(&pCsr, &p->aMatchinfo[iStart], 0);
    }
  }








>
>
>
>



<
<
<
<







876
877
878
879
880
881
882
883
884
885
886
887
888
889




890
891
892
893
894
895
896
*/
static int fts3ExprLocalHitsCb(
  Fts3Expr *pExpr,                /* Phrase expression node */
  int iPhrase,                    /* Phrase number */
  void *pCtx                      /* Pointer to MatchInfo structure */
){
  MatchInfo *p = (MatchInfo *)pCtx;
  int iStart = iPhrase * p->nCol * 3;
  int i;

  for(i=0; i<p->nCol; i++) p->aMatchinfo[iStart+i*3] = 0;

  if( pExpr->aDoclist ){
    char *pCsr;





    pCsr = sqlite3Fts3FindPositions(pExpr, p->pCursor->iPrevId, -1);
    if( pCsr ){
      fts3LoadColumnlistCounts(&pCsr, &p->aMatchinfo[iStart], 0);
    }
  }

Changes to ext/rtree/rtree.c.

1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
....
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
**
** The second of each pair of bytes identifies the coordinate column
** to which the constraint applies. The leftmost coordinate column
** is 'a', the second from the left 'b' etc.
*/
static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
  int rc = SQLITE_OK;
  int ii, cCol;

  int iIdx = 0;
  char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
  memset(zIdxStr, 0, sizeof(zIdxStr));
  UNUSED_PARAMETER(tab);

  assert( pIdxInfo->idxStr==0 );
  for(ii=0; ii<pIdxInfo->nConstraint; ii++){
    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];

    if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
      /* We have an equality constraint on the rowid. Use strategy 1. */
      int jj;
      for(jj=0; jj<ii; jj++){
        pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
................................................................................
      ** sqlite uses an internal cost of 0.0).
      */ 
      pIdxInfo->estimatedCost = 10.0;
      return SQLITE_OK;
    }

    if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){
      int j, opmsk;
      static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 };
      u8 op = 0;
      switch( p->op ){
        case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
        case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break;
        case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
        case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
        case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
        default:
          assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH );
          op = RTREE_MATCH; 
          break;
      }
      assert( op!=0 );

      /* Make sure this particular constraint has not been used before.
      ** If it has been used before, ignore it.
      **
      ** A <= or < can be used if there is a prior >= or >.
      ** A >= or > can be used if there is a prior < or <=.
      ** A <= or < is disqualified if there is a prior <=, <, or ==.
      ** A >= or > is disqualified if there is a prior >=, >, or ==.
      ** A == is disqualifed if there is any prior constraint.
      */
      assert( compatible[RTREE_EQ & 7]==0 );
      assert( compatible[RTREE_LT & 7]==1 );
      assert( compatible[RTREE_LE & 7]==1 );
      assert( compatible[RTREE_GT & 7]==2 );
      assert( compatible[RTREE_GE & 7]==2 );
      cCol = p->iColumn - 1 + 'a';
      opmsk = compatible[op & 7];
      for(j=0; j<iIdx; j+=2){
        if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){
          op = 0;
          break;
        }
      }
      if( op ){
        assert( iIdx<sizeof(zIdxStr)-1 );
        zIdxStr[iIdx++] = op;
        zIdxStr[iIdx++] = cCol;
        pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
        pIdxInfo->aConstraintUsage[ii].omit = 1;
      }
    }
  }

  pIdxInfo->idxNum = 2;
  pIdxInfo->needToFreeIdxStr = 1;
  if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
    return SQLITE_NOMEM;







|







|







 







<
<
|











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
<







1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
....
1381
1382
1383
1384
1385
1386
1387


1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399


























1400
1401
1402
1403

1404
1405
1406
1407
1408
1409
1410
**
** The second of each pair of bytes identifies the coordinate column
** to which the constraint applies. The leftmost coordinate column
** is 'a', the second from the left 'b' etc.
*/
static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
  int rc = SQLITE_OK;
  int ii;

  int iIdx = 0;
  char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
  memset(zIdxStr, 0, sizeof(zIdxStr));
  UNUSED_PARAMETER(tab);

  assert( pIdxInfo->idxStr==0 );
  for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(sizeof(zIdxStr)-1); ii++){
    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];

    if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
      /* We have an equality constraint on the rowid. Use strategy 1. */
      int jj;
      for(jj=0; jj<ii; jj++){
        pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
................................................................................
      ** sqlite uses an internal cost of 0.0).
      */ 
      pIdxInfo->estimatedCost = 10.0;
      return SQLITE_OK;
    }

    if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){


      u8 op;
      switch( p->op ){
        case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
        case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break;
        case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
        case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
        case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
        default:
          assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH );
          op = RTREE_MATCH; 
          break;
      }


























      zIdxStr[iIdx++] = op;
      zIdxStr[iIdx++] = p->iColumn - 1 + 'a';
      pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
      pIdxInfo->aConstraintUsage[ii].omit = 1;

    }
  }

  pIdxInfo->idxNum = 2;
  pIdxInfo->needToFreeIdxStr = 1;
  if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
    return SQLITE_NOMEM;

Changes to ext/rtree/rtree6.test.

101
102
103
104
105
106
107
108















































109

do_eqp_test rtree6.2.5 {
  SELECT * FROM t1,t2 WHERE k=ii AND x1<v
} {
  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2: (~0 rows)} 
  0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}
}
















































finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

do_eqp_test rtree6.2.5 {
  SELECT * FROM t1,t2 WHERE k=ii AND x1<v
} {
  0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2: (~0 rows)} 
  0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}
}

do_execsql_test rtree6-3.1 {
  CREATE VIRTUAL TABLE t3 USING rtree(id, x1, x2, y1, y2);
  INSERT INTO t3 VALUES(NULL, 1, 1, 2, 2);
  SELECT * FROM t3 WHERE 
    x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
    x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
    x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
    x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
    x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
    x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5;
} {1 1.0 1.0 2.0 2.0}

do_test rtree6.3.2 {
  rtree_strategy {
    SELECT * FROM t3 WHERE 
      x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
      x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
      x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
      x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 
  }
} {EaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEa}
do_test rtree6.3.3 {
  rtree_strategy {
    SELECT * FROM t3 WHERE 
      x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
      x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
      x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
      x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
      x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
      x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5
  }
} {EaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEa}

do_execsql_test rtree6-3.4 {
  SELECT * FROM t3 WHERE x1>0.5 AND x1>0.8 AND x1>1.1
} {}
do_execsql_test rtree6-3.5 {
  SELECT * FROM t3 WHERE 
    x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
    x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
    x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
    x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
    x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND 
    x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>1.1
} {}


finish_test

Changes to src/build.c.

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
....
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
....
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
    /* The cookie mask contains one bit for each database file open.
    ** (Bit 0 is for main, bit 1 is for temp, and so forth.)  Bits are
    ** set for each database that is used.  Generate code to start a
    ** transaction on each used database and to verify the schema cookie
    ** on each used database.
    */
    if( pParse->cookieGoto>0 ){
      u32 mask;
      int iDb;
      sqlite3VdbeJumpHere(v, pParse->cookieGoto-1);
      for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
        if( (mask & pParse->cookieMask)==0 ) continue;
        sqlite3VdbeUsesBtree(v, iDb);
        sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
        if( db->init.busy==0 ){
................................................................................
  if( pToplevel->cookieGoto==0 ){
    Vdbe *v = sqlite3GetVdbe(pToplevel);
    if( v==0 ) return;  /* This only happens if there was a prior error */
    pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1;
  }
  if( iDb>=0 ){
    sqlite3 *db = pToplevel->db;
    int mask;

    assert( iDb<db->nDb );
    assert( db->aDb[iDb].pBt!=0 || iDb==1 );
    assert( iDb<SQLITE_MAX_ATTACHED+2 );
    mask = 1<<iDb;
    if( (pToplevel->cookieMask & mask)==0 ){
      pToplevel->cookieMask |= mask;
      pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
      if( !OMIT_TEMPDB && iDb==1 ){
        sqlite3OpenTempDatabase(pToplevel);
      }
    }
................................................................................
** rollback the whole transaction.  For operations where all constraints
** can be checked before any changes are made to the database, it is never
** necessary to undo a write and the checkpoint should not be set.
*/
void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
  Parse *pToplevel = sqlite3ParseToplevel(pParse);
  sqlite3CodeVerifySchema(pParse, iDb);
  pToplevel->writeMask |= 1<<iDb;
  pToplevel->isMultiWrite |= setStatement;
}

/*
** Indicate that the statement currently under construction might write
** more than one entry (example: deleting one row then inserting another,
** inserting multiple rows in a table, or inserting a row and index entries.)







|







 







|




|







 







|







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
....
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
....
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
    /* The cookie mask contains one bit for each database file open.
    ** (Bit 0 is for main, bit 1 is for temp, and so forth.)  Bits are
    ** set for each database that is used.  Generate code to start a
    ** transaction on each used database and to verify the schema cookie
    ** on each used database.
    */
    if( pParse->cookieGoto>0 ){
      tAttachMask mask;
      int iDb;
      sqlite3VdbeJumpHere(v, pParse->cookieGoto-1);
      for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
        if( (mask & pParse->cookieMask)==0 ) continue;
        sqlite3VdbeUsesBtree(v, iDb);
        sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
        if( db->init.busy==0 ){
................................................................................
  if( pToplevel->cookieGoto==0 ){
    Vdbe *v = sqlite3GetVdbe(pToplevel);
    if( v==0 ) return;  /* This only happens if there was a prior error */
    pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1;
  }
  if( iDb>=0 ){
    sqlite3 *db = pToplevel->db;
    tAttachMask mask;

    assert( iDb<db->nDb );
    assert( db->aDb[iDb].pBt!=0 || iDb==1 );
    assert( iDb<SQLITE_MAX_ATTACHED+2 );
    mask = ((tAttachMask)1)<<iDb;
    if( (pToplevel->cookieMask & mask)==0 ){
      pToplevel->cookieMask |= mask;
      pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
      if( !OMIT_TEMPDB && iDb==1 ){
        sqlite3OpenTempDatabase(pToplevel);
      }
    }
................................................................................
** rollback the whole transaction.  For operations where all constraints
** can be checked before any changes are made to the database, it is never
** necessary to undo a write and the checkpoint should not be set.
*/
void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
  Parse *pToplevel = sqlite3ParseToplevel(pParse);
  sqlite3CodeVerifySchema(pParse, iDb);
  pToplevel->writeMask |= ((tAttachMask)1)<<iDb;
  pToplevel->isMultiWrite |= setStatement;
}

/*
** Indicate that the statement currently under construction might write
** more than one entry (example: deleting one row then inserting another,
** inserting multiple rows in a table, or inserting a row and index entries.)

Changes to src/delete.c.

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
...
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
    addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid);

    /* Delete the row */
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( IsVirtual(pTab) ){
      const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
      sqlite3VtabMakeWritable(pParse, pTab);
      sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB);
      sqlite3MayAbort(pParse);
    }else
#endif
    {
      int count = (pParse->nested==0);    /* True to count changes */
      sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default);
    }
................................................................................
  ** be invoked unless table pTab is a system table. The difference is that
  ** the update-hook is not invoked for rows removed by REPLACE, but the 
  ** pre-update-hook is.
  */ 
  if( pTab->pSelect==0 ){
    sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0);
    sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
    sqlite3VdbeChangeP4(v, -1, pTab, P4_TABLE);
  }

  /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
  ** handle rows (possibly in other tables) that refer via a foreign key
  ** to the row just deleted. */ 
  sqlite3FkActions(pParse, pTab, 0, iOld);








|







 







|







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
...
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
    addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid);

    /* Delete the row */
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( IsVirtual(pTab) ){
      const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
      sqlite3VtabMakeWritable(pParse, pTab);
      sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, (char*)pVTab, P4_VTAB);
      sqlite3MayAbort(pParse);
    }else
#endif
    {
      int count = (pParse->nested==0);    /* True to count changes */
      sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default);
    }
................................................................................
  ** be invoked unless table pTab is a system table. The difference is that
  ** the update-hook is not invoked for rows removed by REPLACE, but the 
  ** pre-update-hook is.
  */ 
  if( pTab->pSelect==0 ){
    sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0);
    sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
    sqlite3VdbeChangeP4(v, -1, (char*)pTab, P4_TABLE);
  }

  /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
  ** handle rows (possibly in other tables) that refer via a foreign key
  ** to the row just deleted. */ 
  sqlite3FkActions(pParse, pTab, 0, iOld);

Changes to src/main.c.

525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
....
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
      static const struct {
        int op;      /* The opcode */
        u32 mask;    /* Mask of the bit in sqlite3.flags to set/clear */
      } aFlagOp[] = {
        { SQLITE_DBCONFIG_ENABLE_FKEY,    SQLITE_ForeignKeys    },
        { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger  },
      };
      int i;
      rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
      for(i=0; i<ArraySize(aFlagOp); i++){
        if( aFlagOp[i].op==op ){
          int onoff = va_arg(ap, int);
          int *pRes = va_arg(ap, int*);
          u32 oldFlags = db->flags;
          if( onoff>0 ){
            db->flags |= aFlagOp[i].mask;
          }else if( onoff==0 ){
            db->flags &= ~aFlagOp[i].mask;
          }
          if( oldFlags!=db->flags ){
            sqlite3ExpirePreparedStatements(db);
................................................................................
#endif
#if SQLITE_MAX_VDBE_OP<40
# error SQLITE_MAX_VDBE_OP must be at least 40
#endif
#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
#endif
#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>30
# error SQLITE_MAX_ATTACHED must be between 0 and 30
#endif
#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1
# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1
#endif
#if SQLITE_MAX_COLUMN>32767
# error SQLITE_MAX_COLUMN must not exceed 32767
#endif







|





|







 







|
|







525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
....
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
      static const struct {
        int op;      /* The opcode */
        u32 mask;    /* Mask of the bit in sqlite3.flags to set/clear */
      } aFlagOp[] = {
        { SQLITE_DBCONFIG_ENABLE_FKEY,    SQLITE_ForeignKeys    },
        { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger  },
      };
      unsigned int i;
      rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
      for(i=0; i<ArraySize(aFlagOp); i++){
        if( aFlagOp[i].op==op ){
          int onoff = va_arg(ap, int);
          int *pRes = va_arg(ap, int*);
          int oldFlags = db->flags;
          if( onoff>0 ){
            db->flags |= aFlagOp[i].mask;
          }else if( onoff==0 ){
            db->flags &= ~aFlagOp[i].mask;
          }
          if( oldFlags!=db->flags ){
            sqlite3ExpirePreparedStatements(db);
................................................................................
#endif
#if SQLITE_MAX_VDBE_OP<40
# error SQLITE_MAX_VDBE_OP must be at least 40
#endif
#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
#endif
#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62
# error SQLITE_MAX_ATTACHED must be between 0 and 62
#endif
#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1
# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1
#endif
#if SQLITE_MAX_COLUMN>32767
# error SQLITE_MAX_COLUMN must not exceed 32767
#endif

Changes to src/os_unix.c.

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390


391
392
393
394
395
396
397
...
418
419
420
421
422
423
424

425


426


427
428
429
430
431
432
433
434
435
436
437
438
439
440


441
442
443
444
445
446
447
/*
** Many system calls are accessed through pointer-to-functions so that
** they may be overridden at runtime to facilitate fault injection during
** testing and sandboxing.  The following array holds the names and pointers
** to all overrideable system calls.
*/
static struct unix_syscall {
  const char *zName;      /* Name of the sytem call */
  void *pCurrent;         /* Current value of the system call */
  void *pDefault;         /* Default value */
} aSyscall[] = {
  { "open",         (void*)open,       0  },
#define osOpen      ((int(*)(const char*,int,int))aSyscall[0].pCurrent)

  { "close",        (void*)close,      0  },
#define osClose     ((int(*)(int))aSyscall[1].pCurrent)

  { "access",       (void*)access,     0  },
#define osAccess    ((int(*)(const char*,int))aSyscall[2].pCurrent)

  { "getcwd",       (void*)getcwd,     0  },
#define osGetcwd    ((char*(*)(char*,size_t))aSyscall[3].pCurrent)

  { "stat",         (void*)stat,       0  },
#define osStat      ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent)

/*
** The DJGPP compiler environment looks mostly like Unix, but it
** lacks the fcntl() system call.  So redefine fcntl() to be something
** that always succeeds.  This means that locking does not occur under
** DJGPP.  But it is DOS - what did you expect?
*/
#ifdef __DJGPP__
  { "fstat",        0,                 0  },
#define osFstat(a,b,c)    0
#else     
  { "fstat",        (void*)fstat,      0  },
#define osFstat     ((int(*)(int,struct stat*))aSyscall[5].pCurrent)
#endif

  { "ftruncate",    (void*)ftruncate,  0  },
#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent)

  { "fcntl",        (void*)fcntl,      0  },
#define osFcntl     ((int(*)(int,int,...))aSyscall[7].pCurrent)

  { "read",         (void*)read,       0  },
#define osRead      ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent)

#if defined(USE_PREAD) || defined(SQLITE_ENABLE_LOCKING_STYLE)
  { "pread",        (void*)pread,      0  },
#else
  { "pread",        (void*)0,          0  },
#endif
#define osPread     ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent)

#if defined(USE_PREAD64)
  { "pread64",      (void*)pread64,    0  },
#else
  { "pread64",      (void*)0,          0  },
#endif
#define osPread64   ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent)

  { "write",        (void*)write,      0  },
#define osWrite     ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)

#if defined(USE_PREAD) || defined(SQLITE_ENABLE_LOCKING_STYLE)
  { "pwrite",       (void*)pwrite,     0  },
#else
  { "pwrite",       (void*)0,          0  },
#endif
#define osPwrite    ((ssize_t(*)(int,const void*,size_t,off_t))\
                    aSyscall[12].pCurrent)

#if defined(USE_PREAD64)
  { "pwrite64",     (void*)pwrite64,   0  },
#else
  { "pwrite64",     (void*)0,          0  },
#endif
#define osPwrite64  ((ssize_t(*)(int,const void*,size_t,off_t))\
                    aSyscall[13].pCurrent)

  { "fchmod",       (void*)fchmod,     0  },
#define osFchmod    ((int(*)(int,mode_t))aSyscall[14].pCurrent)

#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
  { "fallocate",    (void*)posix_fallocate,  0 },
#else
  { "fallocate",    (void*)0,                0 },
#endif
#define osFallocate ((int(*)(int,off_t,off_t)aSyscall[15].pCurrent)

}; /* End of the overrideable system calls */

/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "unix" VFSes.  Return SQLITE_OK opon successfully updating the
** system call pointer, or SQLITE_NOTFOUND if there is no configurable
** system call named zName.
*/
static int unixSetSystemCall(
  sqlite3_vfs *pNotUsed,     /* The VFS pointer.  Not used */
  const char *zName,         /* Name of system call to override */
  void *pNewFunc             /* Pointer to new system call value */
){
  int i;
  int rc = SQLITE_NOTFOUND;


  if( zName==0 ){
    /* If no zName is given, restore all system calls to their default
    ** settings and return NULL
    */
    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
      if( aSyscall[i].pDefault ){
        aSyscall[i].pCurrent = aSyscall[i].pDefault;
................................................................................
}

/*
** Return the value of a system call.  Return NULL if zName is not a
** recognized system call name.  NULL is also returned if the system call
** is currently undefined.
*/

static void *unixGetSystemCall(sqlite3_vfs *pNotUsed, const char *zName){


  int i;


  for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
    if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
  }
  return 0;
}

/*
** Return the name of the first system call after zName.  If zName==NULL
** then return the name of the first system call.  Return NULL if zName
** is the last system call or if zName is not the name of a valid
** system call.
*/
static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){
  int i;


  if( zName==0 ){
    i = -1;
  }else{
    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0])-1; i++){
      if( strcmp(zName, aSyscall[0].zName)==0 ) break;
    }
  }







|
|
|

|


|


|


|


|












|



|


|


|



|

|




|

|



|



|

|





|

|




|



|

|












|
|
|

|

>
>







 







>
|
>
>
|
>
>













|
>
>







284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
...
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
/*
** Many system calls are accessed through pointer-to-functions so that
** they may be overridden at runtime to facilitate fault injection during
** testing and sandboxing.  The following array holds the names and pointers
** to all overrideable system calls.
*/
static struct unix_syscall {
  const char *zName;            /* Name of the sytem call */
  sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
  sqlite3_syscall_ptr pDefault; /* Default value */
} aSyscall[] = {
  { "open",         (sqlite3_syscall_ptr)open,       0  },
#define osOpen      ((int(*)(const char*,int,int))aSyscall[0].pCurrent)

  { "close",        (sqlite3_syscall_ptr)close,      0  },
#define osClose     ((int(*)(int))aSyscall[1].pCurrent)

  { "access",       (sqlite3_syscall_ptr)access,     0  },
#define osAccess    ((int(*)(const char*,int))aSyscall[2].pCurrent)

  { "getcwd",       (sqlite3_syscall_ptr)getcwd,     0  },
#define osGetcwd    ((char*(*)(char*,size_t))aSyscall[3].pCurrent)

  { "stat",         (sqlite3_syscall_ptr)stat,       0  },
#define osStat      ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent)

/*
** The DJGPP compiler environment looks mostly like Unix, but it
** lacks the fcntl() system call.  So redefine fcntl() to be something
** that always succeeds.  This means that locking does not occur under
** DJGPP.  But it is DOS - what did you expect?
*/
#ifdef __DJGPP__
  { "fstat",        0,                 0  },
#define osFstat(a,b,c)    0
#else     
  { "fstat",        (sqlite3_syscall_ptr)fstat,      0  },
#define osFstat     ((int(*)(int,struct stat*))aSyscall[5].pCurrent)
#endif

  { "ftruncate",    (sqlite3_syscall_ptr)ftruncate,  0  },
#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent)

  { "fcntl",        (sqlite3_syscall_ptr)fcntl,      0  },
#define osFcntl     ((int(*)(int,int,...))aSyscall[7].pCurrent)

  { "read",         (sqlite3_syscall_ptr)read,       0  },
#define osRead      ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent)

#if defined(USE_PREAD) || defined(SQLITE_ENABLE_LOCKING_STYLE)
  { "pread",        (sqlite3_syscall_ptr)pread,      0  },
#else
  { "pread",        (sqlite3_syscall_ptr)0,          0  },
#endif
#define osPread     ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent)

#if defined(USE_PREAD64)
  { "pread64",      (sqlite3_syscall_ptr)pread64,    0  },
#else
  { "pread64",      (sqlite3_syscall_ptr)0,          0  },
#endif
#define osPread64   ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent)

  { "write",        (sqlite3_syscall_ptr)write,      0  },
#define osWrite     ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)

#if defined(USE_PREAD) || defined(SQLITE_ENABLE_LOCKING_STYLE)
  { "pwrite",       (sqlite3_syscall_ptr)pwrite,     0  },
#else
  { "pwrite",       (sqlite3_syscall_ptr)0,          0  },
#endif
#define osPwrite    ((ssize_t(*)(int,const void*,size_t,off_t))\
                    aSyscall[12].pCurrent)

#if defined(USE_PREAD64)
  { "pwrite64",     (sqlite3_syscall_ptr)pwrite64,   0  },
#else
  { "pwrite64",     (sqlite3_syscall_ptr)0,          0  },
#endif
#define osPwrite64  ((ssize_t(*)(int,const void*,size_t,off_t))\
                    aSyscall[13].pCurrent)

  { "fchmod",       (sqlite3_syscall_ptr)fchmod,     0  },
#define osFchmod    ((int(*)(int,mode_t))aSyscall[14].pCurrent)

#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
  { "fallocate",    (sqlite3_syscall_ptr)posix_fallocate,  0 },
#else
  { "fallocate",    (sqlite3_syscall_ptr)0,                0 },
#endif
#define osFallocate ((int(*)(int,off_t,off_t)aSyscall[15].pCurrent)

}; /* End of the overrideable system calls */

/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "unix" VFSes.  Return SQLITE_OK opon successfully updating the
** system call pointer, or SQLITE_NOTFOUND if there is no configurable
** system call named zName.
*/
static int unixSetSystemCall(
  sqlite3_vfs *pNotUsed,        /* The VFS pointer.  Not used */
  const char *zName,            /* Name of system call to override */
  sqlite3_syscall_ptr pNewFunc  /* Pointer to new system call value */
){
  unsigned int i;
  int rc = SQLITE_NOTFOUND;

  UNUSED_PARAMETER(pNotUsed);
  if( zName==0 ){
    /* If no zName is given, restore all system calls to their default
    ** settings and return NULL
    */
    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
      if( aSyscall[i].pDefault ){
        aSyscall[i].pCurrent = aSyscall[i].pDefault;
................................................................................
}

/*
** Return the value of a system call.  Return NULL if zName is not a
** recognized system call name.  NULL is also returned if the system call
** is currently undefined.
*/
static sqlite3_syscall_ptr unixGetSystemCall(
  sqlite3_vfs *pNotUsed,
  const char *zName
){
  unsigned int i;

  UNUSED_PARAMETER(pNotUsed);
  for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
    if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
  }
  return 0;
}

/*
** Return the name of the first system call after zName.  If zName==NULL
** then return the name of the first system call.  Return NULL if zName
** is the last system call or if zName is not the name of a valid
** system call.
*/
static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){
  unsigned int i;

  UNUSED_PARAMETER(p);
  if( zName==0 ){
    i = -1;
  }else{
    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0])-1; i++){
      if( strcmp(zName, aSyscall[0].zName)==0 ) break;
    }
  }

Changes to src/shell.c.

1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
      fprintf(stderr, "Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
      rc = 1;
    }
  }else
#endif

  if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=1 ){
    const char *zFile = azArg[1];
    if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
      fclose(p->pLog);
      p->pLog = 0;
    }
    if( strcmp(zFile,"stdout")==0 ){
      p->pLog = stdout;







|







1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
      fprintf(stderr, "Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
      rc = 1;
    }
  }else
#endif

  if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
    const char *zFile = azArg[1];
    if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){
      fclose(p->pLog);
      p->pLog = 0;
    }
    if( strcmp(zFile,"stdout")==0 ){
      p->pLog = stdout;

Changes to src/sqlite.h.in.

903
904
905
906
907
908
909

910
911
912
913
914
915
916
...
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
** varies from one VFS to another, and from one version of the same VFS to the
** next.  Applications that use these interfaces must be prepared for any
** or all of these interfaces to be NULL or for their behavior to change
** from one release to the next.  Applications must not attempt to access
** any of these methods if the iVersion of the VFS is less than 3.
*/
typedef struct sqlite3_vfs sqlite3_vfs;

struct sqlite3_vfs {
  int iVersion;            /* Structure version number (currently 3) */
  int szOsFile;            /* Size of subclassed sqlite3_file */
  int mxPathname;          /* Maximum file pathname length */
  sqlite3_vfs *pNext;      /* Next registered VFS */
  const char *zName;       /* Name of this virtual file system */
  void *pAppData;          /* Pointer to application-specific data */
................................................................................
  ** definition.  Those that follow are added in version 2 or later
  */
  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
  /*
  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
  ** Those below are for version 3 and greater.
  */
  int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, void *pFunc);
  void *(*xGetSystemCall)(sqlite3_vfs*, const char *zName);
  const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
  /*
  ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
  ** New fields may be appended in figure versions.  The iVersion
  ** value will increment whenever this happens. 
  */
};







>







 







|
|







903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
...
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
** varies from one VFS to another, and from one version of the same VFS to the
** next.  Applications that use these interfaces must be prepared for any
** or all of these interfaces to be NULL or for their behavior to change
** from one release to the next.  Applications must not attempt to access
** any of these methods if the iVersion of the VFS is less than 3.
*/
typedef struct sqlite3_vfs sqlite3_vfs;
typedef void (*sqlite3_syscall_ptr)(void);
struct sqlite3_vfs {
  int iVersion;            /* Structure version number (currently 3) */
  int szOsFile;            /* Size of subclassed sqlite3_file */
  int mxPathname;          /* Maximum file pathname length */
  sqlite3_vfs *pNext;      /* Next registered VFS */
  const char *zName;       /* Name of this virtual file system */
  void *pAppData;          /* Pointer to application-specific data */
................................................................................
  ** definition.  Those that follow are added in version 2 or later
  */
  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
  /*
  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
  ** Those below are for version 3 and greater.
  */
  int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr);
  sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName);
  const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
  /*
  ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
  ** New fields may be appended in figure versions.  The iVersion
  ** value will increment whenever this happens. 
  */
};

Changes to src/sqliteInt.h.

2127
2128
2129
2130
2131
2132
2133







2134
2135
2136
2137
2138
2139
2140
....
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
  Trigger *pTrigger;      /* Trigger this program was coded from */
  int orconf;             /* Default ON CONFLICT policy */
  SubProgram *pProgram;   /* Program implementing pTrigger/orconf */
  u32 aColmask[2];        /* Masks of old.*, new.* columns accessed */
  TriggerPrg *pNext;      /* Next entry in Parse.pTriggerPrg list */
};








/*
** An SQL parser context.  A copy of this structure is passed through
** the parser and down into all the parser action routine in order to
** carry around information that is global to the entire parse.
**
** The structure is divided into two parts.  When the parser and code
** generate call themselves recursively, the first part of the structure
................................................................................
    int iTable;           /* Table cursor number */
    int iColumn;          /* Table column number */
    u8 tempReg;           /* iReg is a temp register that needs to be freed */
    int iLevel;           /* Nesting level */
    int iReg;             /* Reg with value of this column. 0 means none. */
    int lru;              /* Least recently used entry has the smallest value */
  } aColCache[SQLITE_N_COLCACHE];  /* One for each column cache entry */
  u32 writeMask;       /* Start a write transaction on these databases */
  u32 cookieMask;      /* Bitmask of schema verified databases */
  u8 isMultiWrite;     /* True if statement may affect/insert multiple rows */
  u8 mayAbort;         /* True if statement may throw an ABORT exception */
  int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
  int cookieValue[SQLITE_MAX_ATTACHED+2];  /* Values of cookies to verify */
#ifndef SQLITE_OMIT_SHARED_CACHE
  int nTableLock;        /* Number of locks in aTableLock */
  TableLock *aTableLock; /* Required table locks for shared-cache mode */







>
>
>
>
>
>
>







 







|
|







2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
....
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
  Trigger *pTrigger;      /* Trigger this program was coded from */
  int orconf;             /* Default ON CONFLICT policy */
  SubProgram *pProgram;   /* Program implementing pTrigger/orconf */
  u32 aColmask[2];        /* Masks of old.*, new.* columns accessed */
  TriggerPrg *pNext;      /* Next entry in Parse.pTriggerPrg list */
};

/* Datatype for the bitmask of all attached databases */
#if SQLITE_MAX_ATTACHED>30
  typedef sqlite3_uint64 tAttachMask;
#else
  typedef unsigned int tAttachMask;
#endif

/*
** An SQL parser context.  A copy of this structure is passed through
** the parser and down into all the parser action routine in order to
** carry around information that is global to the entire parse.
**
** The structure is divided into two parts.  When the parser and code
** generate call themselves recursively, the first part of the structure
................................................................................
    int iTable;           /* Table cursor number */
    int iColumn;          /* Table column number */
    u8 tempReg;           /* iReg is a temp register that needs to be freed */
    int iLevel;           /* Nesting level */
    int iReg;             /* Reg with value of this column. 0 means none. */
    int lru;              /* Least recently used entry has the smallest value */
  } aColCache[SQLITE_N_COLCACHE];  /* One for each column cache entry */
  tAttachMask writeMask;  /* Start a write transaction on these databases */
  tAttachMask cookieMask; /* Bitmask of schema verified databases */
  u8 isMultiWrite;     /* True if statement may affect/insert multiple rows */
  u8 mayAbort;         /* True if statement may throw an ABORT exception */
  int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
  int cookieValue[SQLITE_MAX_ATTACHED+2];  /* Values of cookies to verify */
#ifndef SQLITE_OMIT_SHARED_CACHE
  int nTableLock;        /* Number of locks in aTableLock */
  TableLock *aTableLock; /* Required table locks for shared-cache mode */

Changes to src/update.c.

499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
    */
    assert( regNew==regNewRowid+1 );
    sqlite3VdbeAddOp3(v, OP_Delete, iCur,
        OPFLAG_ISUPDATE | ((hasFK || chngRowid) ? 0 : OPFLAG_ISNOOP),
        regNewRowid
    );
    if( !pParse->nested ){
      sqlite3VdbeChangeP4(v, -1, pTab, P4_TABLE);
    }
    sqlite3VdbeJumpHere(v, j1);

    if( hasFK ){
      sqlite3FkCheck(pParse, pTab, 0, regNewRowid);
    }
  







|







499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
    */
    assert( regNew==regNewRowid+1 );
    sqlite3VdbeAddOp3(v, OP_Delete, iCur,
        OPFLAG_ISUPDATE | ((hasFK || chngRowid) ? 0 : OPFLAG_ISNOOP),
        regNewRowid
    );
    if( !pParse->nested ){
      sqlite3VdbeChangeP4(v, -1, (char*)pTab, P4_TABLE);
    }
    sqlite3VdbeJumpHere(v, j1);

    if( hasFK ){
      sqlite3FkCheck(pParse, pTab, 0, regNewRowid);
    }
  

Changes to src/vdbeInt.h.

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
  u8 runOnlyOnce;         /* Automatically expire on reset */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
  u8 inVtabMethod;        /* See comments above */
  u8 usesStmtJournal;     /* True if uses a statement journal */
  u8 readOnly;            /* True for read-only statements */
  u8 isPrepareV2;         /* True if prepared with prepare_v2() */
  int nChange;            /* Number of db changes made since last reset */
  int btreeMask;          /* Bitmask of db->aDb[] entries referenced */
  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
  int aCounter[3];        /* Counters used by sqlite3_stmt_status() */
  BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
#ifndef SQLITE_OMIT_TRACE
  i64 startTime;          /* Time when query started - used for profiling */
#endif
  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */







|







298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
  u8 runOnlyOnce;         /* Automatically expire on reset */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
  u8 inVtabMethod;        /* See comments above */
  u8 usesStmtJournal;     /* True if uses a statement journal */
  u8 readOnly;            /* True for read-only statements */
  u8 isPrepareV2;         /* True if prepared with prepare_v2() */
  int nChange;            /* Number of db changes made since last reset */
  tAttachMask btreeMask;  /* Bitmask of db->aDb[] entries referenced */
  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
  int aCounter[3];        /* Counters used by sqlite3_stmt_status() */
  BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
#ifndef SQLITE_OMIT_TRACE
  i64 startTime;          /* Time when query started - used for profiling */
#endif
  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */

Changes to src/vdbeaux.c.

947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
**
** The prepared statement has to know in advance which Btree objects
** will be used so that it can acquire mutexes on them all in sorted
** order (via sqlite3VdbeMutexArrayEnter().  Mutexes are acquired
** in order (and released in reverse order) to avoid deadlocks.
*/
void sqlite3VdbeUsesBtree(Vdbe *p, int i){
  int mask;
  assert( i>=0 && i<p->db->nDb && i<sizeof(u32)*8 );
  assert( i<(int)sizeof(p->btreeMask)*8 );
  mask = ((u32)1)<<i;
  if( (p->btreeMask & mask)==0 ){
    p->btreeMask |= mask;
    sqlite3BtreeMutexArrayInsert(&p->aMutex, p->db->aDb[i].pBt);
  }
}







|
|







947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
**
** The prepared statement has to know in advance which Btree objects
** will be used so that it can acquire mutexes on them all in sorted
** order (via sqlite3VdbeMutexArrayEnter().  Mutexes are acquired
** in order (and released in reverse order) to avoid deadlocks.
*/
void sqlite3VdbeUsesBtree(Vdbe *p, int i){
  tAttachMask mask;
  assert( i>=0 && i<p->db->nDb && i<sizeof(tAttachMask)*8 );
  assert( i<(int)sizeof(p->btreeMask)*8 );
  mask = ((u32)1)<<i;
  if( (p->btreeMask & mask)==0 ){
    p->btreeMask |= mask;
    sqlite3BtreeMutexArrayInsert(&p->aMutex, p->db->aDb[i].pBt);
  }
}

Changes to test/attach.test.

148
149
150
151
152
153
154

155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
...
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
} {1 {database MAIN is already in use}}
do_test attach-1.18 {
  catchsql {
    ATTACH 'test.db' as db10;
    ATTACH 'test.db' as db11;
  }
} {0 {}}

do_test attach-1.19 {
  catchsql {
    ATTACH 'test.db' as db12;
  }
} {1 {too many attached databases - max 10}}
do_test attach-1.19.1 {
  db errorcode
} {1}

do_test attach-1.20.1 {
  execsql {
    DETACH db5;
  }
} {}
ifcapable schema_pragmas {
do_test attach-1.20.2 {
................................................................................
  execsql {select * from sqlite_temp_master}
}
do_test attach-1.21 {
  catchsql {
    ATTACH 'test.db' as db12;
  }
} {0 {}}

do_test attach-1.22 {
  catchsql {
    ATTACH 'test.db' as db13;
  }
} {1 {too many attached databases - max 10}}
do_test attach-1.22.1 {
  db errorcode
} {1}

do_test attach-1.23 {
  catchsql {
    DETACH "db14";
  }
} {1 {no such database: db14}}
do_test attach-1.24 {
  catchsql {







>
|
|
|
|
|
|
|
|
>







 







>
|
|
|
|
|
|
|
|
>







148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
...
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
} {1 {database MAIN is already in use}}
do_test attach-1.18 {
  catchsql {
    ATTACH 'test.db' as db10;
    ATTACH 'test.db' as db11;
  }
} {0 {}}
if {$SQLITE_MAX_ATTACHED==10} {
  do_test attach-1.19 {
    catchsql {
      ATTACH 'test.db' as db12;
    }
  } {1 {too many attached databases - max 10}}
  do_test attach-1.19.1 {
    db errorcode
  } {1}
}
do_test attach-1.20.1 {
  execsql {
    DETACH db5;
  }
} {}
ifcapable schema_pragmas {
do_test attach-1.20.2 {
................................................................................
  execsql {select * from sqlite_temp_master}
}
do_test attach-1.21 {
  catchsql {
    ATTACH 'test.db' as db12;
  }
} {0 {}}
if {$SQLITE_MAX_ATTACHED==10} {
  do_test attach-1.22 {
    catchsql {
      ATTACH 'test.db' as db13;
    }
  } {1 {too many attached databases - max 10}}
  do_test attach-1.22.1 {
    db errorcode
  } {1}
}
do_test attach-1.23 {
  catchsql {
    DETACH "db14";
  }
} {1 {no such database: db14}}
do_test attach-1.24 {
  catchsql {

Changes to test/fts3defer2.test.

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100









101
102
103
104
105
106
107
# Test cases fts3defer2-2.* focus specifically on the matchinfo function.
# 
do_execsql_test 2.1.1 "CREATE VIRTUAL TABLE t2 USING fts4"
do_execsql_test 2.1.2 "INSERT INTO t2 VALUES('[string repeat {a } 10000]')"
do_execsql_test 2.1.3 "INSERT INTO t2 VALUES('b [string repeat {z } 10000]')"
do_execsql_test 2.1.4 [string repeat "INSERT INTO t2 VALUES('x');" 50]
do_execsql_test 2.1.5 {
  INSERT INTO t2 VALUES('a b c d e f g');
  INSERT INTO t2 VALUES('a b c d e f g');
}
foreach {tn sql} {
  1 {}
  2 { INSERT INTO t2(t2) VALUES('optimize') }
  3 { UPDATE t2_segments SET block = zeroblob(length(block)) 
      WHERE length(block)>10000;
  }
} {
  execsql $sql

  do_execsql_test 2.2.$tn {
    SELECT mit(matchinfo(t2, 'pcxnal')) FROM t2 WHERE t2 MATCH 'a b';
  } [list                                          \
    [list 2 1  1 54 54  1 3 3  54 372 7]        \
    [list 2 1  1 54 54  1 3 3  54 372 7]        \
  ]









}

do_execsql_test 2.3.1 {
  CREATE VIRTUAL TABLE t3 USING fts4;
  INSERT INTO t3 VALUES('a b c d e f');
  INSERT INTO t3 VALUES('x b c d e f');
  INSERT INTO t3 VALUES('d e f a b c');







|











|


|


>
>
>
>
>
>
>
>
>







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# Test cases fts3defer2-2.* focus specifically on the matchinfo function.
# 
do_execsql_test 2.1.1 "CREATE VIRTUAL TABLE t2 USING fts4"
do_execsql_test 2.1.2 "INSERT INTO t2 VALUES('[string repeat {a } 10000]')"
do_execsql_test 2.1.3 "INSERT INTO t2 VALUES('b [string repeat {z } 10000]')"
do_execsql_test 2.1.4 [string repeat "INSERT INTO t2 VALUES('x');" 50]
do_execsql_test 2.1.5 {
  INSERT INTO t2 VALUES('a b c d e f g z');
  INSERT INTO t2 VALUES('a b c d e f g');
}
foreach {tn sql} {
  1 {}
  2 { INSERT INTO t2(t2) VALUES('optimize') }
  3 { UPDATE t2_segments SET block = zeroblob(length(block)) 
      WHERE length(block)>10000;
  }
} {
  execsql $sql

  do_execsql_test 2.2.$tn.1 {
    SELECT mit(matchinfo(t2, 'pcxnal')) FROM t2 WHERE t2 MATCH 'a b';
  } [list                                          \
    [list 2 1  1 54 54  1 3 3  54 372 8]        \
    [list 2 1  1 54 54  1 3 3  54 372 7]        \
  ]

  set sqlite_fts3_enable_parentheses 1
  do_execsql_test 2.2.$tn.2 {
    SELECT mit(matchinfo(t2, 'x')) FROM t2 WHERE t2 MATCH 'g OR (g z)';
  } [list                                       \
    [list 1 2 2  1 2 2   1 54 54]               \
    [list 1 2 2  1 2 2   0 54 54]               \
  ]
  set sqlite_fts3_enable_parentheses 0
}

do_execsql_test 2.3.1 {
  CREATE VIRTUAL TABLE t3 USING fts4;
  INSERT INTO t3 VALUES('a b c d e f');
  INSERT INTO t3 VALUES('x b c d e f');
  INSERT INTO t3 VALUES('d e f a b c');