SQLite

Check-in [8fd65e7048]
Login

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

Overview
Comment:Simplifications and optimizations. Also: disable the corrupt.test for now. (CVS 1924)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8fd65e704888a8e2f4a712a94fd0e3f866c10ef3
User & Date: drh 2004-08-31 13:45:11.000
Context
2004-08-31
23:41
Changes to support compiling under windows. (CVS 1925) (check-in: 68a712f372 user: drh tags: trunk)
13:45
Simplifications and optimizations. Also: disable the corrupt.test for now. (CVS 1924) (check-in: 8fd65e7048 user: drh tags: trunk)
00:52
Combine the implementation of LIKE and GLOB into a single parameterized function. (CVS 1923) (check-in: 0a47c8f86d user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/btree.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    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.
**
*************************************************************************
** $Id: btree.c,v 1.183 2004/08/30 16:52:18 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    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.
**
*************************************************************************
** $Id: btree.c,v 1.184 2004/08/31 13:45:11 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
    if( sqlite3pager_get(pCheck->pPager, (Pgno)iPage, (void**)&pOvfl) ){
      sprintf(zMsg, "failed to get page %d", iPage);
      checkAppendMsg(pCheck, zContext, zMsg);
      break;
    }
    if( isFreeList ){
      int n = get4byte(&pOvfl[4]);
      if( n>=pCheck->pBt->usableSize/4-8 ){
        sprintf(zMsg, "freelist leaf count too big on page %d", iPage);
        checkAppendMsg(pCheck, zContext, zMsg);
        N--;
      }else{
        for(i=0; i<n; i++){
          checkRef(pCheck, get4byte(&pOvfl[8+i*4]), zContext);
        }







|







4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
    if( sqlite3pager_get(pCheck->pPager, (Pgno)iPage, (void**)&pOvfl) ){
      sprintf(zMsg, "failed to get page %d", iPage);
      checkAppendMsg(pCheck, zContext, zMsg);
      break;
    }
    if( isFreeList ){
      int n = get4byte(&pOvfl[4]);
      if( n>pCheck->pBt->usableSize/4-8 ){
        sprintf(zMsg, "freelist leaf count too big on page %d", iPage);
        checkAppendMsg(pCheck, zContext, zMsg);
        N--;
      }else{
        for(i=0; i<n; i++){
          checkRef(pCheck, get4byte(&pOvfl[8+i*4]), zContext);
        }
Changes to src/build.c.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.249 2004/08/21 17:54:45 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.250 2004/08/31 13:45:11 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
      }else{
        sqlite3VdbeOp3(v, OP_String8, 0, 0, "CREATE TABLE ", P3_STATIC);
      }
      assert( pEnd!=0 );
      n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1;
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeChangeP3(v, -1, pParse->sNameToken.z, n);
      sqlite3VdbeAddOp(v, OP_Concat8, 2, 0);
    }
    sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC);
    sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
    sqlite3ChangeCookie(db, v, p->iDb);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0,
        sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC);







|







1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
      }else{
        sqlite3VdbeOp3(v, OP_String8, 0, 0, "CREATE TABLE ", P3_STATIC);
      }
      assert( pEnd!=0 );
      n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1;
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeChangeP3(v, -1, pParse->sNameToken.z, n);
      sqlite3VdbeAddOp(v, OP_Concat, 0, 0);
    }
    sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC);
    sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
    sqlite3ChangeCookie(db, v, p->iDb);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0,
        sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC);
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
        sqlite3VdbeChangeP3(v, -1, "CREATE INDEX ", P3_STATIC);
      }else{
        sqlite3VdbeChangeP3(v, -1, "CREATE UNIQUE INDEX ", P3_STATIC);
      }
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      n = Addr(pEnd->z) - Addr(pName->z) + 1;
      sqlite3VdbeChangeP3(v, -1, pName->z, n);
      sqlite3VdbeAddOp(v, OP_Concat8, 2, 0);
    }
    sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC);
    sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
    if( pTblName ){
      sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
      sqlite3VdbeAddOp(v, OP_OpenRead, 2, pTab->tnum);
      /* VdbeComment((v, "%s", pTab->zName)); */







|







2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
        sqlite3VdbeChangeP3(v, -1, "CREATE INDEX ", P3_STATIC);
      }else{
        sqlite3VdbeChangeP3(v, -1, "CREATE UNIQUE INDEX ", P3_STATIC);
      }
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      n = Addr(pEnd->z) - Addr(pName->z) + 1;
      sqlite3VdbeChangeP3(v, -1, pName->z, n);
      sqlite3VdbeAddOp(v, OP_Concat, 0, 0);
    }
    sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC);
    sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
    if( pTblName ){
      sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
      sqlite3VdbeAddOp(v, OP_OpenRead, 2, pTab->tnum);
      /* VdbeComment((v, "%s", pTab->zName)); */
Changes to src/delete.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
**    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.78 2004/08/21 17:54:45 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.
*/
Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
  Table *pTab = 0;
  int i;

  for(i=0; i<pSrc->nSrc; i++){
    const char *zTab = pSrc->a[i].zName;
    const char *zDb = pSrc->a[i].zDatabase;
    pTab = sqlite3LocateTable(pParse, zTab, zDb);
    pSrc->a[i].pTab = pTab;
  }
  return pTab;
}

/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is







|











>
|
<
<
|
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28


29
30
31
32
33
34
35
36
37
**    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.79 2004/08/31 13:45:12 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.
*/
Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
  Table *pTab = 0;
  int i;
  struct SrcList_item *pItem;
  for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){


    pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase);
    pItem->pTab = pTab;
  }
  return pTab;
}

/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is
Changes to src/expr.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    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.157 2004/08/21 17:54:45 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

char const *sqlite3AffinityString(char affinity){
  switch( affinity ){
    case SQLITE_AFF_INTEGER: return "i";







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    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.158 2004/08/31 13:45:12 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

char const *sqlite3AffinityString(char affinity){
  switch( affinity ){
    case SQLITE_AFF_INTEGER: return "i";
1143
1144
1145
1146
1147
1148
1149
1150
1151

1152
1153
1154
1155
1156
1157
1158
    case TK_BITAND:   op = OP_BitAnd;   break;
    case TK_BITOR:    op = OP_BitOr;    break;
    case TK_BITNOT:   op = OP_BitNot;   break;
    case TK_LSHIFT:   op = OP_ShiftLeft;  break;
    case TK_RSHIFT:   op = OP_ShiftRight; break;
    case TK_REM:      op = OP_Remainder;  break;
    case TK_FLOAT:    op = OP_Real;       break;
    case TK_STRING:   op = OP_String8;     break;
    case TK_BLOB:     op = OP_HexBlob;    break;

    default: op = 0; break;
  }
  switch( pExpr->op ){
    case TK_COLUMN: {
      if( pParse->useAgg ){
        sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
      }else if( pExpr->iColumn>=0 ){







|

>







1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
    case TK_BITAND:   op = OP_BitAnd;   break;
    case TK_BITOR:    op = OP_BitOr;    break;
    case TK_BITNOT:   op = OP_BitNot;   break;
    case TK_LSHIFT:   op = OP_ShiftLeft;  break;
    case TK_RSHIFT:   op = OP_ShiftRight; break;
    case TK_REM:      op = OP_Remainder;  break;
    case TK_FLOAT:    op = OP_Real;       break;
    case TK_STRING:   op = OP_String8;    break;
    case TK_BLOB:     op = OP_HexBlob;    break;
    case TK_CONCAT:   op = OP_Concat;     break;
    default: op = 0; break;
  }
  switch( pExpr->op ){
    case TK_COLUMN: {
      if( pParse->useAgg ){
        sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
      }else if( pExpr->iColumn>=0 ){
1205
1206
1207
1208
1209
1210
1211
1212

1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
    case TK_STAR:
    case TK_MINUS:
    case TK_REM:
    case TK_BITAND:
    case TK_BITOR:
    case TK_SLASH:
    case TK_LSHIFT:
    case TK_RSHIFT: {

      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3ExprCode(pParse, pExpr->pRight);
      sqlite3VdbeAddOp(v, op, 0, 0);
      break;
    }
    case TK_CONCAT: {
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3ExprCode(pParse, pExpr->pRight);
      sqlite3VdbeAddOp(v, OP_Concat8, 2, 0);
      break;
    }
    case TK_UMINUS: {
      Expr *pLeft = pExpr->pLeft;
      assert( pLeft );
      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
        Token *p = &pLeft->token;
        char *z = sqliteMalloc( p->n + 2 );
        sprintf(z, "-%.*s", p->n, p->z);







|
>





<
<
<
<
<
<







1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219






1220
1221
1222
1223
1224
1225
1226
    case TK_STAR:
    case TK_MINUS:
    case TK_REM:
    case TK_BITAND:
    case TK_BITOR:
    case TK_SLASH:
    case TK_LSHIFT:
    case TK_RSHIFT: 
    case TK_CONCAT: {
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3ExprCode(pParse, pExpr->pRight);
      sqlite3VdbeAddOp(v, op, 0, 0);
      break;
    }






    case TK_UMINUS: {
      Expr *pLeft = pExpr->pLeft;
      assert( pLeft );
      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
        Token *p = &pLeft->token;
        char *z = sqliteMalloc( p->n + 2 );
        sprintf(z, "-%.*s", p->n, p->z);
Changes to src/pragma.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2003 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    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.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.60 2004/08/21 17:54:45 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# include "pager.h"
# include "btree.h"













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2003 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    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.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.61 2004/08/31 13:45:12 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# include "pager.h"
# include "btree.h"
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
      sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
      addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6);
      sqlite3VdbeOp3(v, OP_String8, 0, 0,
         sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
         P3_DYNAMIC);
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
      sqlite3VdbeAddOp(v, OP_Concat8, 2, 1);
      sqlite3VdbeAddOp(v, OP_Callback, 1, 0);

      /* Make sure all the indices are constructed correctly.
      */
      sqlite3CodeVerifySchema(pParse, i);
      for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);







|







573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
      sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
      addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6);
      sqlite3VdbeOp3(v, OP_String8, 0, 0,
         sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
         P3_DYNAMIC);
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
      sqlite3VdbeAddOp(v, OP_Concat, 0, 1);
      sqlite3VdbeAddOp(v, OP_Callback, 1, 0);

      /* Make sure all the indices are constructed correctly.
      */
      sqlite3CodeVerifySchema(pParse, i);
      for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
          int jmp2;
          static VdbeOpList idxErr[] = {
            { OP_MemIncr,     0,  0,  0},
            { OP_String8,     0,  0,  "rowid "},
            { OP_Recno,       1,  0,  0},
            { OP_String8,     0,  0,  " missing from index "},
            { OP_String8,     0,  0,  0},    /* 4 */
            { OP_Concat8,     4,  0,  0},
            { OP_Callback,    1,  0,  0},
          };
          sqlite3GenerateIndexKey(v, pIdx, 1);
          jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
          addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
          sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
          sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v));







|







598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
          int jmp2;
          static VdbeOpList idxErr[] = {
            { OP_MemIncr,     0,  0,  0},
            { OP_String8,     0,  0,  "rowid "},
            { OP_Recno,       1,  0,  0},
            { OP_String8,     0,  0,  " missing from index "},
            { OP_String8,     0,  0,  0},    /* 4 */
            { OP_Concat,      2,  0,  0},
            { OP_Callback,    1,  0,  0},
          };
          sqlite3GenerateIndexKey(v, pIdx, 1);
          jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
          addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
          sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
          sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v));
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
             { OP_Next,         0,  0,  0},  /* 4 */
             { OP_MemLoad,      1,  0,  0},
             { OP_MemLoad,      2,  0,  0},
             { OP_Eq,           0,  0,  0},  /* 7 */
             { OP_MemIncr,      0,  0,  0},
             { OP_String8,      0,  0,  "wrong # of entries in index "},
             { OP_String8,      0,  0,  0},  /* 10 */
             { OP_Concat8,      2,  0,  0},
             { OP_Callback,     1,  0,  0},
          };
          if( pIdx->tnum==0 ) continue;
          addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
          sqlite3VdbeChangeP1(v, addr+2, j+2);
          sqlite3VdbeChangeP2(v, addr+2, addr+5);
          sqlite3VdbeChangeP1(v, addr+4, j+2);







|







622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
             { OP_Next,         0,  0,  0},  /* 4 */
             { OP_MemLoad,      1,  0,  0},
             { OP_MemLoad,      2,  0,  0},
             { OP_Eq,           0,  0,  0},  /* 7 */
             { OP_MemIncr,      0,  0,  0},
             { OP_String8,      0,  0,  "wrong # of entries in index "},
             { OP_String8,      0,  0,  0},  /* 10 */
             { OP_Concat,       0,  0,  0},
             { OP_Callback,     1,  0,  0},
          };
          if( pIdx->tnum==0 ) continue;
          addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
          sqlite3VdbeChangeP1(v, addr+2, j+2);
          sqlite3VdbeChangeP2(v, addr+2, addr+5);
          sqlite3VdbeChangeP1(v, addr+4, j+2);
Changes to src/trigger.c.
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
      { OP_NewRecno,   0, 0,  0          },
      { OP_String8,    0, 0,  "trigger"  },
      { OP_String8,    0, 0,  0          },  /* 2: trigger name */
      { OP_String8,    0, 0,  0          },  /* 3: table name */
      { OP_Integer,    0, 0,  0          },
      { OP_String8,    0, 0,  "CREATE TRIGGER "},
      { OP_String8,    0, 0,  0          },  /* 6: SQL */
      { OP_Concat8,    2, 0,  0          }, 
      { OP_MakeRecord, 5, 0,  "tttit"    },
      { OP_PutIntKey,  0, 0,  0          },
    };
    int addr;
    Vdbe *v;

    /* Make an entry in the sqlite_master table */







|







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
      { OP_NewRecno,   0, 0,  0          },
      { OP_String8,    0, 0,  "trigger"  },
      { OP_String8,    0, 0,  0          },  /* 2: trigger name */
      { OP_String8,    0, 0,  0          },  /* 3: table name */
      { OP_Integer,    0, 0,  0          },
      { OP_String8,    0, 0,  "CREATE TRIGGER "},
      { OP_String8,    0, 0,  0          },  /* 6: SQL */
      { OP_Concat,     0, 0,  0          }, 
      { OP_MakeRecord, 5, 0,  "tttit"    },
      { OP_PutIntKey,  0, 0,  0          },
    };
    int addr;
    Vdbe *v;

    /* Make an entry in the sqlite_master table */
Changes to src/update.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    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.86 2004/08/21 17:54:45 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;







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    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.87 2004/08/31 13:45:12 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;
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
    /* Generate the NEW table
    */
    if( chngRecno ){
      sqlite3ExprCode(pParse, pRecnoExpr);
    }else{
      sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    }
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
        continue;
      }
      j = aXRef[i];
      if( j<0 ){
        sqlite3VdbeAddOp(v, OP_Column, iCur, i);







|







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
    /* Generate the NEW table
    */
    if( chngRecno ){
      sqlite3ExprCode(pParse, pRecnoExpr);
    }else{
      sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    }
    for(i=0; i<pTab->nCol; i++){ /* TODO: Factor out this loop as common code */
      if( i==pTab->iPKey ){
        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
        continue;
      }
      j = aXRef[i];
      if( j<0 ){
        sqlite3VdbeAddOp(v, OP_Column, iCur, i);
Changes to src/vdbe.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.411 2004/08/29 17:30:50 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.412 2004/08/31 13:45:12 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
  p->nCallback++;
  p->popStack = pOp->p1;
  p->pc = pc + 1;
  p->pTos = pTos;
  return SQLITE_ROW;
}

/* Opcode: Concat8 P1 P2 P3
**
** P3 points to a nul terminated UTF-8 string. When it is executed for
** the first time, P3 is converted to the native database encoding and
** the opcode replaced with Concat (see Concat for details of processing).
*/
case OP_Concat8: {
  pOp->opcode = OP_Concat;

  if( db->enc!=SQLITE_UTF8 && pOp->p3 ){
    Mem tmp;
    tmp.flags = MEM_Null;
    sqlite3VdbeMemSetStr(&tmp, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC);
    if( SQLITE_OK!=sqlite3VdbeChangeEncoding(&tmp, db->enc) ||
        SQLITE_OK!=sqlite3VdbeMemDynamicify(&tmp) 
    ){
      goto no_mem;
    }
    assert( tmp.flags|MEM_Dyn );
    assert( !tmp.xDel );
    pOp->p3type = P3_DYNAMIC;
    pOp->p3 = tmp.z;
    /* Don't call sqlite3VdbeMemRelease() on &tmp, the dynamic allocation
    ** is cleaned up when the vdbe is deleted. 
    */
  }

  /* If it wasn't already, P3 has been converted to the database text
  ** encoding. Fall through to OP_Concat to process this instruction.
  */
}

/* Opcode: Concat P1 P2 *
**
** Look at the first P1 elements of the stack.  Append them all 
** together with the lowest element first.  The original P1 elements
** are popped from the stack if P2==0 and retained if P2==1.  If
** any element of the stack is NULL, then the result is NULL.
**
** When P1==1, this routine makes a copy of the top stack element
** into memory obtained from sqliteMalloc().
*/
case OP_Concat: {
  char *zNew;
  int nByte;
  int nField;
  int i, j;
  Mem *pTerm;

  /* Loop through the stack elements to see how long the result will be. */
  nField = pOp->p1;
  pTerm = &pTos[1-nField];
  nByte = 0;
  for(i=0; i<nField; i++, pTerm++){
    assert( pOp->p2==0 || (pTerm->flags&MEM_Str) );
    if( pTerm->flags&MEM_Null ){
      nByte = -1;
      break;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|
|














|







904
905
906
907
908
909
910
































911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
  p->nCallback++;
  p->popStack = pOp->p1;
  p->pc = pc + 1;
  p->pTos = pTos;
  return SQLITE_ROW;
}

































/* Opcode: Concat P1 P2 *
**
** Look at the first P1+2 elements of the stack.  Append them all 
** together with the lowest element first.  The original P1+2 elements
** are popped from the stack if P2==0 and retained if P2==1.  If
** any element of the stack is NULL, then the result is NULL.
**
** When P1==1, this routine makes a copy of the top stack element
** into memory obtained from sqliteMalloc().
*/
case OP_Concat: {
  char *zNew;
  int nByte;
  int nField;
  int i, j;
  Mem *pTerm;

  /* Loop through the stack elements to see how long the result will be. */
  nField = pOp->p1 + 2;
  pTerm = &pTos[1-nField];
  nByte = 0;
  for(i=0; i<nField; i++, pTerm++){
    assert( pOp->p2==0 || (pTerm->flags&MEM_Str) );
    if( pTerm->flags&MEM_Null ){
      nByte = -1;
      break;
Changes to test/all.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    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.
#
#***********************************************************************
# This file runs all tests.
#
# $Id: all.test,v 1.21 2004/06/30 08:20:16 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {memleak_check}

if {[file exists ./sqlite_test_count]} {












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    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.
#
#***********************************************************************
# This file runs all tests.
#
# $Id: all.test,v 1.22 2004/08/31 13:45:12 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {memleak_check}

if {[file exists ./sqlite_test_count]} {
50
51
52
53
54
55
56

57
58
59
60
61
62
63
set EXCLUDE {
  all.test
  crash.test
  quick.test
  malloc.test
  misuse.test
  memleak.test

}
#  btree2.test

for {set Counter 0} {$Counter<$COUNT && $nErr==0} {incr Counter} {
  if {$Counter%2} {
    set ::SETUP_SQL {PRAGMA default_synchronous=off;}
  } else {







>







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
set EXCLUDE {
  all.test
  crash.test
  quick.test
  malloc.test
  misuse.test
  memleak.test
  corrupt.test
}
#  btree2.test

for {set Counter 0} {$Counter<$COUNT && $nErr==0} {incr Counter} {
  if {$Counter%2} {
    set ::SETUP_SQL {PRAGMA default_synchronous=off;}
  } else {