/ Check-in [4871c77f]
Login

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

Overview
Comment:Add comments to unused P3 fields of selected instructions when NDEBUG is not defined. This makes VDBE program dumps more readable during debugging. (CVS 1973)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:4871c77f8fce36ff230e1f026f4e4e49492515e9
User & Date: drh 2004-09-19 02:15:25
Context
2004-09-20
14:57
Pthread is now conditionally included in makefile, see ticket #910 (CVS 1974) check-in: a35e5227 user: dougcurrie tags: trunk
2004-09-19
02:15
Add comments to unused P3 fields of selected instructions when NDEBUG is not defined. This makes VDBE program dumps more readable during debugging. (CVS 1973) check-in: 4871c77f user: drh tags: trunk
00:50
Merge the ListPush and ListPop VDBE opcodes into ContextPush and ContextPop. (CVS 1972) check-in: eb9b501a user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/delete.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
44
45
46
47
48
49
50















51
52
53
54
55
56
57
...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
...
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
** $Id: delete.c,v 1.80 2004/09/06 17:24:13 drh Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
  }
  if( !viewOk && pTab->pSelect ){
    sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
    return 1;
  }
  return 0;
}
















/*
** Process a DELETE FROM statement.
*/
void sqlite3DeleteFrom(
  Parse *pParse,         /* The parser context */
  SrcList *pTabList,     /* The table from which we should delete things */
................................................................................
  if( pWhere==0 && !row_triggers_exist ){
    if( db->flags & SQLITE_CountRows ){
      /* If counting rows deleted, just count the total number of
      ** entries in the table. */
      int endOfLoop = sqlite3VdbeMakeLabel(v);
      int addr;
      if( !isView ){
        sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
        sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
        sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
      }
      sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
      addr = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
      sqlite3VdbeAddOp(v, OP_Next, iCur, addr);
      sqlite3VdbeResolveLabel(v, endOfLoop);
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
    }
................................................................................
    /* This is the beginning of the delete loop when there are
    ** row triggers.
    */
    if( row_triggers_exist ){
      addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      if( !isView ){
        sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
        sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
        sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
      }
      sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
      sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
      sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
      sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
      if( !isView ){
        sqlite3VdbeAddOp(v, OP_Close, iCur, 0);







|







 







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







 







|
<
<







 







|
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
...
177
178
179
180
181
182
183
184


185
186
187
188
189
190
191
...
241
242
243
244
245
246
247
248


249
250
251
252
253
254
255
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
** $Id: delete.c,v 1.81 2004/09/19 02:15:25 drh Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
  }
  if( !viewOk && pTab->pSelect ){
    sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
    return 1;
  }
  return 0;
}

/*
** Generate code that will open a table for reading.
*/
void sqlite3OpenTableForReading(
  Vdbe *v,        /* Generate code into this VDBE */
  int iCur,       /* The cursor number of the table */
  Table *pTab     /* The table to be opened */
){
  sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
  VdbeComment((v, "# %s", pTab->zName));
  sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
}


/*
** Process a DELETE FROM statement.
*/
void sqlite3DeleteFrom(
  Parse *pParse,         /* The parser context */
  SrcList *pTabList,     /* The table from which we should delete things */
................................................................................
  if( pWhere==0 && !row_triggers_exist ){
    if( db->flags & SQLITE_CountRows ){
      /* If counting rows deleted, just count the total number of
      ** entries in the table. */
      int endOfLoop = sqlite3VdbeMakeLabel(v);
      int addr;
      if( !isView ){
        sqlite3OpenTableForReading(v, iCur, pTab);


      }
      sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
      addr = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
      sqlite3VdbeAddOp(v, OP_Next, iCur, addr);
      sqlite3VdbeResolveLabel(v, endOfLoop);
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
    }
................................................................................
    /* This is the beginning of the delete loop when there are
    ** row triggers.
    */
    if( row_triggers_exist ){
      addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      if( !isView ){
        sqlite3OpenTableForReading(v, iCur, pTab);


      }
      sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
      sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
      sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
      sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
      if( !isView ){
        sqlite3VdbeAddOp(v, OP_Close, iCur, 0);

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251
....
1237
1238
1239
1240
1241
1242
1243

1244
1245
1246
1247
1248
1249
1250
....
1366
1367
1368
1369
1370
1371
1372

1373
1374
1375
1376
1377
1378
1379
....
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475

1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.162 2004/09/19 00:50:21 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

char const *sqlite3AffinityString(char affinity){
  switch( affinity ){
    case SQLITE_AFF_INTEGER: return "i";
................................................................................
** Set the Expr.span field of the given expression to span all
** text between the two given tokens.
*/
void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
  assert( pRight!=0 );
  assert( pLeft!=0 );
  if( !sqlite3_malloc_failed && pRight->z && pLeft->z ){

    if( pLeft->dyn==0 && pRight->dyn==0 ){
      pExpr->span.z = pLeft->z;
      pExpr->span.n = pRight->n + Addr(pRight->z) - Addr(pLeft->z);
    }else{
      pExpr->span.z = 0;
    }
  }
}
................................................................................
  }
  switch( pExpr->op ){
    case TK_COLUMN: {
      if( pParse->useAgg ){
        sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
      }else if( pExpr->iColumn>=0 ){
        sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);

      }else{
        sqlite3VdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
      }
      break;
    }
    case TK_INTEGER: {
      codeInteger(v, pExpr->token.z, pExpr->token.n);
................................................................................
        sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
      }
      sqlite3VdbeOp3(v, OP_Function, nExpr, p2, (char*)pDef, P3_FUNCDEF);
      break;
    }
    case TK_SELECT: {
      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);

      break;
    }
    case TK_IN: {
      int addr;
      char const *affStr;

      /* Figure out the affinity to use to create a key from the results
................................................................................
      sqlite3VdbeResolveLabel(v, expr_end_label);
      break;
    }
    case TK_RAISE: {
      if( !pParse->trigStack ){
        sqlite3ErrorMsg(pParse,
                       "RAISE() may only be used within a trigger-program");
        pParse->nErr++;
	return;
      }
      if( pExpr->iColumn == OE_Rollback ||

	  pExpr->iColumn == OE_Abort ||
	  pExpr->iColumn == OE_Fail ){
	  sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn,
                           pExpr->token.z, pExpr->token.n);
	  sqlite3VdbeDequoteP3(v, -1);
      } else {
	  assert( pExpr->iColumn == OE_Ignore );
          sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
	  sqlite3VdbeOp3(v, OP_Goto, 0, pParse->trigStack->ignoreJump,
                           "(IGNORE jump)", 0);
      }
    }
    break;
  }
}

/*







|







 







>
|







 







>







 







>







 







<


|
>
|
|
|
|
|

|
|
|
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
....
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
....
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
....
1468
1469
1470
1471
1472
1473
1474

1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.163 2004/09/19 02:15:25 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

char const *sqlite3AffinityString(char affinity){
  switch( affinity ){
    case SQLITE_AFF_INTEGER: return "i";
................................................................................
** Set the Expr.span field of the given expression to span all
** text between the two given tokens.
*/
void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
  assert( pRight!=0 );
  assert( pLeft!=0 );
  if( !sqlite3_malloc_failed && pRight->z && pLeft->z ){
    assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
    if( pLeft->z[pLeft->n]!=0 && pRight->dyn==0 ){
      pExpr->span.z = pLeft->z;
      pExpr->span.n = pRight->n + Addr(pRight->z) - Addr(pLeft->z);
    }else{
      pExpr->span.z = 0;
    }
  }
}
................................................................................
  }
  switch( pExpr->op ){
    case TK_COLUMN: {
      if( pParse->useAgg ){
        sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
      }else if( pExpr->iColumn>=0 ){
        sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
        VdbeComment((v, "# %T", &pExpr->span));
      }else{
        sqlite3VdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
      }
      break;
    }
    case TK_INTEGER: {
      codeInteger(v, pExpr->token.z, pExpr->token.n);
................................................................................
        sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
      }
      sqlite3VdbeOp3(v, OP_Function, nExpr, p2, (char*)pDef, P3_FUNCDEF);
      break;
    }
    case TK_SELECT: {
      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
      VdbeComment((v, "# load subquery result"));
      break;
    }
    case TK_IN: {
      int addr;
      char const *affStr;

      /* Figure out the affinity to use to create a key from the results
................................................................................
      sqlite3VdbeResolveLabel(v, expr_end_label);
      break;
    }
    case TK_RAISE: {
      if( !pParse->trigStack ){
        sqlite3ErrorMsg(pParse,
                       "RAISE() may only be used within a trigger-program");

	return;
      }
      if( pExpr->iColumn!=OE_Ignore ){
         assert( pExpr->iColumn==OE_Rollback ||
                 pExpr->iColumn == OE_Abort ||
                 pExpr->iColumn == OE_Fail );
         sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn,
                        pExpr->token.z, pExpr->token.n);
         sqlite3VdbeDequoteP3(v, -1);
      } else {
         assert( pExpr->iColumn == OE_Ignore );
         sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
         sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->trigStack->ignoreJump);
         VdbeComment((v, "# raise(IGNORE)"));
      }
    }
    break;
  }
}

/*

Changes to src/insert.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1003
1004
1005
1006
1007
1008
1009

1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.117 2004/09/17 17:23:15 drh Exp $
*/
#include "sqliteInt.h"

/*
** Set P3 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
){
  int i;
  Index *pIdx;
  Vdbe *v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  sqlite3VdbeAddOp(v, op, base, pTab->tnum);

  sqlite3VdbeAddOp(v, OP_SetNumColumns, base, pTab->nCol);
  for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
    sqlite3VdbeOp3(v, op, i+base, pIdx->tnum,
                   (char*)&pIdx->keyInfo, P3_KEYINFO);
  }
  if( pParse->nTab<=base+i ){
    pParse->nTab = base+i;
  }
}







|







 







>










8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.118 2004/09/19 02:15:26 drh Exp $
*/
#include "sqliteInt.h"

/*
** Set P3 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
){
  int i;
  Index *pIdx;
  Vdbe *v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  sqlite3VdbeAddOp(v, op, base, pTab->tnum);
  VdbeComment((v, "# %s", pTab->zName));
  sqlite3VdbeAddOp(v, OP_SetNumColumns, base, pTab->nCol);
  for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
    sqlite3VdbeOp3(v, op, i+base, pIdx->tnum,
                   (char*)&pIdx->keyInfo, P3_KEYINFO);
  }
  if( pParse->nTab<=base+i ){
    pParse->nTab = base+i;
  }
}

Changes to src/printf.c.

582
583
584
585
586
587
588

589

590
591
592
593
594
595
596
          bufpt[j] = 0;
          length = j;
          if( precision>=0 && precision<length ) length = precision;
        }
        break;
      case etTOKEN: {
        Token *pToken = va_arg(ap, Token*);

        (*func)(arg, pToken->z, pToken->n);

        length = width = 0;
        break;
      }
      case etSRCLIST: {
        SrcList *pSrc = va_arg(ap, SrcList*);
        int k = va_arg(ap, int);
        struct SrcList_item *pItem = &pSrc->a[k];







>
|
>







582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
          bufpt[j] = 0;
          length = j;
          if( precision>=0 && precision<length ) length = precision;
        }
        break;
      case etTOKEN: {
        Token *pToken = va_arg(ap, Token*);
        if( pToken && pToken->z ){
          (*func)(arg, pToken->z, pToken->n);
        }
        length = width = 0;
        break;
      }
      case etSRCLIST: {
        SrcList *pSrc = va_arg(ap, SrcList*);
        int k = va_arg(ap, int);
        struct SrcList_item *pItem = &pSrc->a[k];

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
340
341
342
343
344
345
346

347
348
349

350
351
352
353
354
355
356
...
411
412
413
414
415
416
417

418
419
420
421
422
423
424
....
1219
1220
1221
1222
1223
1224
1225

1226
1227
1228
1229
1230
1231
1232
1233

1234
1235
1236
1237
1238
1239
1240
....
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.208 2004/09/08 15:09:41 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
    int addr = sqlite3VdbeCurrentAddr(v) + 2;
    if( nPop>0 ) addr++;
    sqlite3VdbeAddOp(v, OP_MemIncr, p->iOffset, addr);
    if( nPop>0 ){
      sqlite3VdbeAddOp(v, OP_Pop, nPop, 0);
    }
    sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);

  }
  if( p->iLimit>=0 ){
    sqlite3VdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);

  }
}

/*
** This routine generates the code for the inside of the inner loop
** of a SELECT.
**
................................................................................
#endif
    /* Deliberately leave the affinity string off of the following
    ** OP_MakeRecord */
    sqlite3VdbeAddOp(v, OP_MakeRecord, pEList->nExpr * -1, 0);
    sqlite3VdbeAddOp(v, OP_Distinct, distinct, sqlite3VdbeCurrentAddr(v)+3);
    sqlite3VdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
    sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);

    sqlite3VdbeAddOp(v, OP_String8, 0, 0);
    sqlite3VdbeAddOp(v, OP_PutStrKey, distinct, 0);
    if( pOrderBy==0 ){
      codeLimiter(v, p, iContinue, iBreak, nColumn);
    }
  }

................................................................................
  */
  if( p->nLimit>=0 ){
    int iMem = pParse->nMem++;
    Vdbe *v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3VdbeAddOp(v, OP_Integer, -p->nLimit, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);

    p->iLimit = iMem;
  }
  if( p->nOffset>0 ){
    int iMem = pParse->nMem++;
    Vdbe *v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3VdbeAddOp(v, OP_Integer, -p->nOffset, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);

    p->iOffset = iMem;
  }
}

/*
** Generate VDBE instructions that will open a transient table that
** will be used for an index or to store keyed results for a compound
................................................................................
  ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first
  ** or last entry in the main table.
  */
  sqlite3CodeVerifySchema(pParse, pTab->iDb);
  base = pSrc->a[0].iCursor;
  computeLimitRegisters(pParse, p);
  if( pSrc->a[0].pSelect==0 ){
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeAddOp(v, OP_OpenRead, base, pTab->tnum);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, base, pTab->nCol);
  }
  cont = sqlite3VdbeMakeLabel(v);
  if( pIdx==0 ){
    sqlite3VdbeAddOp(v, seekOp, base, 0);
  }else{
    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
    sqlite3VdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum,







|







 







>



>







 







>







 







>








>







 







|
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
...
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
....
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
....
2108
2109
2110
2111
2112
2113
2114
2115


2116
2117
2118
2119
2120
2121
2122
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.209 2004/09/19 02:15:26 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
    int addr = sqlite3VdbeCurrentAddr(v) + 2;
    if( nPop>0 ) addr++;
    sqlite3VdbeAddOp(v, OP_MemIncr, p->iOffset, addr);
    if( nPop>0 ){
      sqlite3VdbeAddOp(v, OP_Pop, nPop, 0);
    }
    sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
    VdbeComment((v, "# skip OFFSET records"));
  }
  if( p->iLimit>=0 ){
    sqlite3VdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
    VdbeComment((v, "# exit when LIMIT reached"));
  }
}

/*
** This routine generates the code for the inside of the inner loop
** of a SELECT.
**
................................................................................
#endif
    /* Deliberately leave the affinity string off of the following
    ** OP_MakeRecord */
    sqlite3VdbeAddOp(v, OP_MakeRecord, pEList->nExpr * -1, 0);
    sqlite3VdbeAddOp(v, OP_Distinct, distinct, sqlite3VdbeCurrentAddr(v)+3);
    sqlite3VdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
    sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
    VdbeComment((v, "# skip indistinct records"));
    sqlite3VdbeAddOp(v, OP_String8, 0, 0);
    sqlite3VdbeAddOp(v, OP_PutStrKey, distinct, 0);
    if( pOrderBy==0 ){
      codeLimiter(v, p, iContinue, iBreak, nColumn);
    }
  }

................................................................................
  */
  if( p->nLimit>=0 ){
    int iMem = pParse->nMem++;
    Vdbe *v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3VdbeAddOp(v, OP_Integer, -p->nLimit, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);
    VdbeComment((v, "# LIMIT counter"));
    p->iLimit = iMem;
  }
  if( p->nOffset>0 ){
    int iMem = pParse->nMem++;
    Vdbe *v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3VdbeAddOp(v, OP_Integer, -p->nOffset, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);
    VdbeComment((v, "# OFFSET counter"));
    p->iOffset = iMem;
  }
}

/*
** Generate VDBE instructions that will open a transient table that
** will be used for an index or to store keyed results for a compound
................................................................................
  ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first
  ** or last entry in the main table.
  */
  sqlite3CodeVerifySchema(pParse, pTab->iDb);
  base = pSrc->a[0].iCursor;
  computeLimitRegisters(pParse, p);
  if( pSrc->a[0].pSelect==0 ){
    sqlite3OpenTableForReading(v, base, pTab);


  }
  cont = sqlite3VdbeMakeLabel(v);
  if( pIdx==0 ){
    sqlite3VdbeAddOp(v, seekOp, base, 0);
  }else{
    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
    sqlite3VdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum,

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1259
1260
1261
1262
1263
1264
1265

1266
1267
1268
1269
1270
1271
1272
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.321 2004/09/08 20:13:05 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

#include "config.h"
#include "sqlite3.h"
#include "hash.h"
................................................................................
int sqlite3Select(Parse*, Select*, int, int, Select*, int, int*, char *aff);
Select *sqlite3SelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
                        int,int,int);
void sqlite3SelectDelete(Select*);
void sqlite3SelectUnbind(Select*);
Table *sqlite3SrcListLookup(Parse*, SrcList*);
int sqlite3IsReadOnly(Parse*, Table*, int);

void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, int, ExprList**);
void sqlite3WhereEnd(WhereInfo*);
void sqlite3ExprCode(Parse*, Expr*);
int sqlite3ExprCodeExprList(Parse*, ExprList*);
void sqlite3ExprIfTrue(Parse*, Expr*, int, int);







|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.322 2004/09/19 02:15:26 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

#include "config.h"
#include "sqlite3.h"
#include "hash.h"
................................................................................
int sqlite3Select(Parse*, Select*, int, int, Select*, int, int*, char *aff);
Select *sqlite3SelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
                        int,int,int);
void sqlite3SelectDelete(Select*);
void sqlite3SelectUnbind(Select*);
Table *sqlite3SrcListLookup(Parse*, SrcList*);
int sqlite3IsReadOnly(Parse*, Table*, int);
void sqlite3OpenTableForReading(Vdbe*, int iCur, Table*);
void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, int, ExprList**);
void sqlite3WhereEnd(WhereInfo*);
void sqlite3ExprCode(Parse*, Expr*);
int sqlite3ExprCodeExprList(Parse*, ExprList*);
void sqlite3ExprIfTrue(Parse*, Expr*, int, int);

Changes to src/trigger.c.

756
757
758
759
760
761
762
763



764
765
766
767
768
769
770
        pTriggerStack = pTriggerStack->pNext;
      }
      if( op == TK_UPDATE && pTrigger->pColumns &&
          !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
        fire_this = 0;
      }
    }




    if( fire_this && (pTriggerStack = sqliteMalloc(sizeof(TriggerStack)))!=0 ){
      int endTrigger;
      SrcList dummyTablist;
      Expr * whenExpr;
      AuthContext sContext;

      dummyTablist.nSrc = 0;







|
>
>
>







756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
        pTriggerStack = pTriggerStack->pNext;
      }
      if( op == TK_UPDATE && pTrigger->pColumns &&
          !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
        fire_this = 0;
      }
    }
 
    /* FIX ME:  Can we not omit the sqliteMalloc() and make pTriggerStack
    ** point to a stack variable?
    */
    if( fire_this && (pTriggerStack = sqliteMalloc(sizeof(TriggerStack)))!=0 ){
      int endTrigger;
      SrcList dummyTablist;
      Expr * whenExpr;
      AuthContext sContext;

      dummyTablist.nSrc = 0;

Changes to src/update.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.88 2004/09/06 17:24:13 drh Exp $
*/
#include "sqliteInt.h"

/*
** Process an UPDATE statement.
**
**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
................................................................................
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);

    /* Open a cursor and make it point to the record that is
    ** being updated.
    */
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    if( !isView ){
      sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
      sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
      sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
    }
    sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);

    /* Generate the OLD table
    */
    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);







|







 







|
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
249
250
251
252
253
254
255
256


257
258
259
260
261
262
263
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.89 2004/09/19 02:15:26 drh Exp $
*/
#include "sqliteInt.h"

/*
** Process an UPDATE statement.
**
**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
................................................................................
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);

    /* Open a cursor and make it point to the record that is
    ** being updated.
    */
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    if( !isView ){
      sqlite3OpenTableForReading(v, iCur, pTab);


    }
    sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);

    /* Generate the OLD table
    */
    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);

Changes to src/vdbeaux.c.

299
300
301
302
303
304
305















306
307
308
309
310
311
312
    pOp->p3 = (char*)zP3;
    pOp->p3type = n;
  }else{
    sqlite3SetNString(&pOp->p3, zP3, n, (char*)0);
    pOp->p3type = P3_DYNAMIC;
  }
}
















/*
** If the P3 operand to the specified instruction appears
** to be a quoted string token, then this procedure removes 
** the quotes.
**
** The quoting operator can be either a grave ascent (ASCII 0x27)







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







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
    pOp->p3 = (char*)zP3;
    pOp->p3type = n;
  }else{
    sqlite3SetNString(&pOp->p3, zP3, n, (char*)0);
    pOp->p3type = P3_DYNAMIC;
  }
}

#ifndef NDEBUG
/*
** Replace the P3 field of the most recently coded instruction with
** comment text.
*/
void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
  va_list ap;
  assert( p->nOp>0 );
  assert( p->aOp[p->nOp-1].p3==0 );
  va_start(ap, zFormat);
  sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(zFormat, ap), P3_DYNAMIC);
  va_end(ap);
}
#endif

/*
** If the P3 operand to the specified instruction appears
** to be a quoted string token, then this procedure removes 
** the quotes.
**
** The quoting operator can be either a grave ascent (ASCII 0x27)

Changes to src/where.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
...
759
760
761
762
763
764
765

766
767
768
769
770
771
772
....
1137
1138
1139
1140
1141
1142
1143

1144
1145
1146
1147
1148
1149
1150
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.
**
** $Id: where.c,v 1.113 2004/09/06 17:24:13 drh Exp $
*/
#include "sqliteInt.h"

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.
................................................................................
  sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
  for(i=0; i<pTabList->nSrc; i++){
    Table *pTab;
    Index *pIx;

    pTab = pTabList->a[i].pTab;
    if( pTab->isTransient || pTab->pSelect ) continue;
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeAddOp(v, OP_OpenRead, pTabList->a[i].iCursor, pTab->tnum);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, pTabList->a[i].iCursor, pTab->nCol);
    sqlite3CodeVerifySchema(pParse, pTab->iDb);
    if( (pIx = pWInfo->a[i].pIdx)!=0 ){
      sqlite3VdbeAddOp(v, OP_Integer, pIx->iDb, 0);
      sqlite3VdbeOp3(v, OP_OpenRead, pWInfo->a[i].iCur, pIx->tnum,
                     (char*)&pIx->keyInfo, P3_KEYINFO);
    }
  }
................................................................................
    ** row of the left table of the join.
    */
    if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){
      if( !pParse->nMem ) pParse->nMem++;
      pLevel->iLeftJoin = pParse->nMem++;
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);

    }

    pIdx = pLevel->pIdx;
    pLevel->inOp = OP_Noop;
    if( i<ARRAYSIZE(iDirectEq) && iDirectEq[i]>=0 ){
      /* Case 1:  We can directly reference a single row using an
      **          equality comparison against the ROWID field.  Or
................................................................................
    /* For a LEFT OUTER JOIN, generate code that will record the fact that
    ** at least one row of the right table has matched the left table.  
    */
    if( pLevel->iLeftJoin ){
      pLevel->top = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);

      for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){
        if( pTerm->p==0 ) continue;
        if( (pTerm->prereqAll & loopMask)!=pTerm->prereqAll ) continue;
        if( haveKey ){
          /* Cannot happen.  "haveKey" can only be true if pushKey is true
          ** an pushKey can only be true for DELETE and UPDATE and there are
          ** no outer joins with DELETE and UPDATE.







|







 







<
|
<







 







>







 







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
730
731
732
733
734
735
736

737

738
739
740
741
742
743
744
...
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
....
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.
**
** $Id: where.c,v 1.114 2004/09/19 02:15:26 drh Exp $
*/
#include "sqliteInt.h"

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.
................................................................................
  sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
  for(i=0; i<pTabList->nSrc; i++){
    Table *pTab;
    Index *pIx;

    pTab = pTabList->a[i].pTab;
    if( pTab->isTransient || pTab->pSelect ) continue;

    sqlite3OpenTableForReading(v, pTabList->a[i].iCursor, pTab);

    sqlite3CodeVerifySchema(pParse, pTab->iDb);
    if( (pIx = pWInfo->a[i].pIdx)!=0 ){
      sqlite3VdbeAddOp(v, OP_Integer, pIx->iDb, 0);
      sqlite3VdbeOp3(v, OP_OpenRead, pWInfo->a[i].iCur, pIx->tnum,
                     (char*)&pIx->keyInfo, P3_KEYINFO);
    }
  }
................................................................................
    ** row of the left table of the join.
    */
    if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){
      if( !pParse->nMem ) pParse->nMem++;
      pLevel->iLeftJoin = pParse->nMem++;
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
      VdbeComment((v, "# init LEFT JOIN no-match flag"));
    }

    pIdx = pLevel->pIdx;
    pLevel->inOp = OP_Noop;
    if( i<ARRAYSIZE(iDirectEq) && iDirectEq[i]>=0 ){
      /* Case 1:  We can directly reference a single row using an
      **          equality comparison against the ROWID field.  Or
................................................................................
    /* For a LEFT OUTER JOIN, generate code that will record the fact that
    ** at least one row of the right table has matched the left table.  
    */
    if( pLevel->iLeftJoin ){
      pLevel->top = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
      VdbeComment((v, "# record LEFT JOIN hit"));
      for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){
        if( pTerm->p==0 ) continue;
        if( (pTerm->prereqAll & loopMask)!=pTerm->prereqAll ) continue;
        if( haveKey ){
          /* Cannot happen.  "haveKey" can only be true if pushKey is true
          ** an pushKey can only be true for DELETE and UPDATE and there are
          ** no outer joins with DELETE and UPDATE.

Changes to test/collate2.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
598
599
600
601
602
603
604
605
606
607
608
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is page cache subsystem.
#
# $Id: collate2.test,v 1.2 2004/06/11 10:51:41 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

#
# Tests are organised as follows:
#
................................................................................
do_test collate2-5.5 {
  execsql {
    SELECT collate2t1.b, collate2t2.b FROM collate2t2 LEFT OUTER JOIN collate2t1 USING (b);
  }
} {aa aa}

finish_test











|







 







<
<
<
<
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
598
599
600
601
602
603
604




#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is page cache subsystem.
#
# $Id: collate2.test,v 1.3 2004/09/19 02:15:26 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

#
# Tests are organised as follows:
#
................................................................................
do_test collate2-5.5 {
  execsql {
    SELECT collate2t1.b, collate2t2.b FROM collate2t2 LEFT OUTER JOIN collate2t1 USING (b);
  }
} {aa aa}

finish_test