/ Check-in [20ea7375]
Login

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

Overview
Comment:Fix a serious bug in INSERT when the source is a SELECT. (CVS 366)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:20ea737536700b016385c70105a2af8b2bffce2b
User & Date: drh 2002-02-03 19:06:03
Context
2002-02-03
19:15
Reenable testing code even if NDEBUG is defined. (CVS 367) check-in: 0090c279 user: drh tags: trunk
19:06
Fix a serious bug in INSERT when the source is a SELECT. (CVS 366) check-in: 20ea7375 user: drh tags: trunk
17:37
Put in PRAGMA SANITY_CHECK in place of VACUUM. (CVS 365) check-in: 7c65029e user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
** 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.50 2002/02/03 17:37:36 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.
................................................................................
/******************************************************************************
** The complete implementation of the BTree subsystem is above this line.
** All the code the follows is for testing and troubleshooting the BTree
** subsystem.  None of the code that follows is used during normal operation.
** All of the following code is omitted if the library is compiled with
** the -DNDEBUG=1 compiler option.
******************************************************************************/
#ifndef NDEEBUG

/*
** Print a disassembly of the given page on standard output.  This routine
** is used for debugging and testing only.
*/
int sqliteBtreePageDump(Btree *pBt, int pgno, int recursive){
  int rc;







|







 







|







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
** 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.51 2002/02/03 19:06:03 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.
................................................................................
/******************************************************************************
** The complete implementation of the BTree subsystem is above this line.
** All the code the follows is for testing and troubleshooting the BTree
** subsystem.  None of the code that follows is used during normal operation.
** All of the following code is omitted if the library is compiled with
** the -DNDEBUG=1 compiler option.
******************************************************************************/
#ifndef NDEBUG

/*
** Print a disassembly of the given page on standard output.  This routine
** is used for debugging and testing only.
*/
int sqliteBtreePageDump(Btree *pBt, int pgno, int recursive){
  int rc;

Changes to src/insert.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
**    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.41 2002/02/03 00:56:10 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is call to handle SQL of the following forms:
**
**    insert into TABLE (IDLIST) values(EXPRLIST)
................................................................................
        if( pColumn->a[j].idx==i ) break;
      }
    }
    if( pColumn && j>=pColumn->nId ){
      sqliteVdbeAddOp(v, OP_String, 0, 0);
      sqliteVdbeChangeP3(v, -1, pTab->aCol[i].zDflt, P3_STATIC);
    }else if( srcTab>=0 ){
      sqliteVdbeAddOp(v, OP_Column, srcTab, i); 
    }else{
      sqliteExprCode(pParse, pList->a[j].pExpr);
    }
  }

  /* Generate code to check constraints and generate index keys and
  ** do the insertion.







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
**    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.42 2002/02/03 19:06:03 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is call to handle SQL of the following forms:
**
**    insert into TABLE (IDLIST) values(EXPRLIST)
................................................................................
        if( pColumn->a[j].idx==i ) break;
      }
    }
    if( pColumn && j>=pColumn->nId ){
      sqliteVdbeAddOp(v, OP_String, 0, 0);
      sqliteVdbeChangeP3(v, -1, pTab->aCol[i].zDflt, P3_STATIC);
    }else if( srcTab>=0 ){
      sqliteVdbeAddOp(v, OP_Column, srcTab, j); 
    }else{
      sqliteExprCode(pParse, pList->a[j].pExpr);
    }
  }

  /* Generate code to check constraints and generate index keys and
  ** do the insertion.

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
**    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.56 2002/01/28 15:53:05 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
................................................................................
    if( pTabList->a[i].pTab ){
      /* This routine has run before!  No need to continue */
      return 0;
    }
    if( pTabList->a[i].zName==0 ){
      /* No table name is given.  Instead, there is a (SELECT ...) statement
      ** the results of which should be used in place of the table.  The
      ** was this is implemented is that the (SELECT ...) writes its results
      ** into a temporary table which is then scanned like any other table.
      */
      sqliteSetString(&pParse->zErrMsg, 
          "(SELECT...) in a FROM clause is not yet implemented.", 0);
      pParse->nErr++;
      return 1;
    }







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
**    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.57 2002/02/03 19:06:03 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
................................................................................
    if( pTabList->a[i].pTab ){
      /* This routine has run before!  No need to continue */
      return 0;
    }
    if( pTabList->a[i].zName==0 ){
      /* No table name is given.  Instead, there is a (SELECT ...) statement
      ** the results of which should be used in place of the table.  The
      ** way this is implemented is that the (SELECT ...) writes its results
      ** into a temporary table which is then scanned like any other table.
      */
      sqliteSetString(&pParse->zErrMsg, 
          "(SELECT...) in a FROM clause is not yet implemented.", 0);
      pParse->nErr++;
      return 1;
    }

Changes to src/vdbe.c.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
....
3521
3522
3523
3524
3525
3526
3527

3528
3529
3530
3531
3532
3533
3534
3535
** type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqliteVdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.116 2002/02/03 03:34:09 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The following global variable is incremented every time a cursor
** moves, either by the OP_MoveTo or the OP_Next opcode.  The test
................................................................................
**
** P1 is the index of a set that contains the root page numbers
** for all tables and indices in this database.
**
** This opcode is used for testing purposes only.
*/
case OP_SanityCheck: {
#if 1  /* This opcode used for testing only */
  int nRoot;
  int *aRoot;
  int tos = ++p->tos;
  int iSet = pOp->p1;
  Set *pSet;
  int j;
  HashElem *i;
  char *z;

  if( iSet<0 || iSet>=p->nSet ){
    goto bad_instruction;
  }
  VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
  pSet = &p->aSet[iSet];
  nRoot = sqliteHashCount(&pSet->hash);
  aRoot = sqliteMalloc( sizeof(int)*(nRoot+1) );
  for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){
    aRoot[j] = atoi((char*)sqliteHashKey(i));
  }
  aRoot[j] = 0;
................................................................................
    aStack[tos].flags = STK_Str | STK_Static;
    if( z ) sqliteFree(z);
  }else{
    zStack[tos] = z;
    aStack[tos].n = strlen(z) + 1;
    aStack[tos].flags = STK_Str | STK_Dyn;
  }

#endif /* SQLITE_TEST */
  break;
}

/* Opcode:  Limit P1 P2 *
**
** Set a limit and offset on callbacks.  P1 is the limit and P2 is
** the offset.  If the offset counter is positive, no callbacks are







|







 







|









|
<
<
|







 







>
|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506


3507
3508
3509
3510
3511
3512
3513
3514
....
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
** type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqliteVdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.117 2002/02/03 19:06:03 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The following global variable is incremented every time a cursor
** moves, either by the OP_MoveTo or the OP_Next opcode.  The test
................................................................................
**
** P1 is the index of a set that contains the root page numbers
** for all tables and indices in this database.
**
** This opcode is used for testing purposes only.
*/
case OP_SanityCheck: {
#ifndef NDEBUG  /* This opcode used for testing only */
  int nRoot;
  int *aRoot;
  int tos = ++p->tos;
  int iSet = pOp->p1;
  Set *pSet;
  int j;
  HashElem *i;
  char *z;

  if( iSet<0 || iSet>=p->nSet ) goto bad_instruction;


  if( NeedStack(p, p->tos) ) goto no_mem;
  pSet = &p->aSet[iSet];
  nRoot = sqliteHashCount(&pSet->hash);
  aRoot = sqliteMalloc( sizeof(int)*(nRoot+1) );
  for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){
    aRoot[j] = atoi((char*)sqliteHashKey(i));
  }
  aRoot[j] = 0;
................................................................................
    aStack[tos].flags = STK_Str | STK_Static;
    if( z ) sqliteFree(z);
  }else{
    zStack[tos] = z;
    aStack[tos].n = strlen(z) + 1;
    aStack[tos].flags = STK_Str | STK_Dyn;
  }
  sqliteFree(aRoot);
#endif /* !define(NDEBUG) */
  break;
}

/* Opcode:  Limit P1 P2 *
**
** Set a limit and offset on callbacks.  P1 is the limit and P2 is
** the offset.  If the offset counter is positive, no callbacks are

Changes to test/conflict.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
373
374
375
376
377
378
379





380
381
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the conflict resolution extension
# to SQLite.
#
# $Id: conflict.test,v 1.6 2002/02/03 03:34:09 drh Exp $

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

# Create tables for the first group of tests.
#
do_test conflict-1.0 {
................................................................................
    execsql {COMMIT}
    if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]}
    set r2 [execsql {SELECT x FROM t3}]
    list $r0 $r1 $r2
  } [list $t0 $t1 $t2]
}







finish_test







|







 







>
>
>
>
>


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
373
374
375
376
377
378
379
380
381
382
383
384
385
386
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the conflict resolution extension
# to SQLite.
#
# $Id: conflict.test,v 1.7 2002/02/03 19:06:03 drh Exp $

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

# Create tables for the first group of tests.
#
do_test conflict-1.0 {
................................................................................
    execsql {COMMIT}
    if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]}
    set r2 [execsql {SELECT x FROM t3}]
    list $r0 $r1 $r2
  } [list $t0 $t1 $t2]
}

do_test insert-99.1 {
  set x [execsql {PRAGMA sanity_check}]
  if {$x==""} {set x ok}
  set x
} {ok}

finish_test

Changes to test/copy.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
203
204
205
206
207
208
209
























210
211
212
213
214
215
216
#    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 file is testing the COPY statement.
#
# $Id: copy.test,v 1.8 2002/01/31 15:54:23 drh Exp $

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

# Create a file of data from which to copy.
#
set f [open data1.txt w]
................................................................................
  puts $fd "33|22|44"
  close $fd
  catchsql {
    COPY OR REPLACE t1 FROM 'data6.txt' USING DELIMITERS '|';
    SELECT * FROM t1;
  }
} {0 {22 33 11 33 22 44}}
























 

# Cleanup 
#
file delete -force data1.txt data2.txt data3.txt data4.txt data5.txt data6.txt

finish_test







|







 







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







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#    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 file is testing the COPY statement.
#
# $Id: copy.test,v 1.9 2002/02/03 19:06:03 drh Exp $

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

# Create a file of data from which to copy.
#
set f [open data1.txt w]
................................................................................
  puts $fd "33|22|44"
  close $fd
  catchsql {
    COPY OR REPLACE t1 FROM 'data6.txt' USING DELIMITERS '|';
    SELECT * FROM t1;
  }
} {0 {22 33 11 33 22 44}}

do_test copy-5.5 {
  execsql {
    DELETE FROM t1;
    PRAGMA count_changes=on;
    COPY t1 FROM 'data5.txt' USING DELIMITERS '|';
  }
} {2}
do_test copy-5.6 {
  execsql {
    COPY OR REPLACE t1 FROM 'data5.txt' USING DELIMITERS '|';
  }
} {2}
do_test copy-5.7 {
  execsql {
    COPY OR IGNORE t1 FROM 'data5.txt' USING DELIMITERS '|';
  }
} {0}

do_test copy-6.0 {
  set x [execsql {PRAGMA sanity_check}]
  if {$x==""} {set x ok}
  set x
} {ok}
 

# Cleanup 
#
file delete -force data1.txt data2.txt data3.txt data4.txt data5.txt data6.txt

finish_test

Changes to test/insert.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
152
153
154
155
156
157
158





159

160
#    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 file is testing the INSERT statement.
#
# $Id: insert.test,v 1.6 2001/09/16 00:13:28 drh Exp $

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

# Try to insert into a non-existant table.
#
do_test insert-1.1 {
................................................................................
do_test insert-3.3 {
  execsql {INSERT INTO test2(f1,f2,f5) VALUES(22,-4.44,'wham')}
  execsql {SELECT * FROM test2 WHERE f1=111 AND f2=-3.33}
} {111 -3.33 hi hum {}}
do_test insert-3.4 {
  execsql {SELECT * FROM test2 WHERE f1=22 AND f2=-4.44}
} {22 -4.44 hi abc-123 wham}







finish_test







|







 







>
>
>
>
>

>

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#    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 file is testing the INSERT statement.
#
# $Id: insert.test,v 1.7 2002/02/03 19:06:03 drh Exp $

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

# Try to insert into a non-existant table.
#
do_test insert-1.1 {
................................................................................
do_test insert-3.3 {
  execsql {INSERT INTO test2(f1,f2,f5) VALUES(22,-4.44,'wham')}
  execsql {SELECT * FROM test2 WHERE f1=111 AND f2=-3.33}
} {111 -3.33 hi hum {}}
do_test insert-3.4 {
  execsql {SELECT * FROM test2 WHERE f1=22 AND f2=-4.44}
} {22 -4.44 hi abc-123 wham}
do_test insert-3.5 {
  set x [execsql {PRAGMA sanity_check}]
  if {$x==""} {set x ok}
  set x
} {ok}


finish_test

Changes to test/insert2.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
78
79
80
81
82
83
84
85



































86
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the INSERT statement that takes is
# result from a SELECT.
#
# $Id: insert2.test,v 1.5 2001/10/15 00:44:36 drh Exp $

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

# Create some tables with data that we can select against
#
do_test insert2-1.0 {
................................................................................
    CREATE INDEX i2 ON t1(cnt);
    INSERT INTO t1 SELECT log, count() FROM d1 GROUP BY log;
    SELECT * FROM t1 ORDER BY log;
  }]
  lappend r [execsql {SELECT cnt FROM t1 WHERE log=3}]
  lappend r [execsql {SELECT log FROM t1 WHERE cnt=4 ORDER BY log}]
} {0 1 1 1 2 2 3 4 4 8 5 4 4 {3 5}}




































finish_test







|







 








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

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
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
117
118
119
120
121
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the INSERT statement that takes is
# result from a SELECT.
#
# $Id: insert2.test,v 1.6 2002/02/03 19:06:03 drh Exp $

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

# Create some tables with data that we can select against
#
do_test insert2-1.0 {
................................................................................
    CREATE INDEX i2 ON t1(cnt);
    INSERT INTO t1 SELECT log, count() FROM d1 GROUP BY log;
    SELECT * FROM t1 ORDER BY log;
  }]
  lappend r [execsql {SELECT cnt FROM t1 WHERE log=3}]
  lappend r [execsql {SELECT log FROM t1 WHERE cnt=4 ORDER BY log}]
} {0 1 1 1 2 2 3 4 4 8 5 4 4 {3 5}}

do_test insert2-2.0 {
  execsql {
    CREATE TABLE t3(a,b,c);
    CREATE TABLE t4(x,y);
    INSERT INTO t4 VALUES(1,2);
    SELECT * FROM t4;
  }
} {1 2}
do_test insert2-2.1 {
  execsql {
    INSERT INTO t3(a,c) SELECT * FROM t4;
    SELECT * FROM t3;
  }
} {1 {} 2}
do_test insert2-2.2 {
  execsql {
    DELETE FROM t3;
    INSERT INTO t3(c,b) SELECT * FROM t4;
    SELECT * FROM t3;
  }
} {{} 2 1}
do_test insert2-2.3 {
  execsql {
    DELETE FROM t3;
    INSERT INTO t3(c,a,b) SELECT x, 'hi', y FROM t4;
    SELECT * FROM t3;
  }
} {hi 2 1}

do_test insert2-4.0 {
  set x [execsql {PRAGMA sanity_check}]
  if {$x==""} {set x ok}
  set x
} {ok}

finish_test

Changes to www/changes.tcl.

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


proc chng {date desc} {
  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}

chng {2002 Jan 30 (2.3.0 beta)} {



<li>Added the ability to resolve constraint conflicts is ways other than
    an abort and rollback.  See the documentation on the "ON CONFLICT"
    clause for details.</li>
<li>Temporary files are now automatically deleted by the operating system
    when closed.  There are no more dangling temporary files on a program
    crash.  (If the OS crashes, fsck will delete the file after reboot 
    under Unix.  I do not know what happens under Windows.)</li>
<li>NOT NULL constraints are honored.</li>
<li>The COPY command puts NULLs in columns whose data is '\N'.</li>
<li>In the COPY command, backslash can now be used to escape a newline.</li>

}

chng {2002 Jan 28 (2.2.5)} {
<li>Important bug fix: the IN operator was not working if either the
    left-hand or right-hand side was derived from an INTEGER PRIMARY KEY.</li>
<li>Do not escape the backslash '\' character in the output of the
    <b>sqlite</b> command-line access program.</li>







|
>
>
>










>







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
39
40
41


proc chng {date desc} {
  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}

chng {2002 Jan 30 (2.3.0)} {
<li>Fix a serious bug in the INSERT command which was causing data to go
    into the wrong columns if the data source was a SELECT and the INSERT
    clauses specified its columns in some order other than the default.</li>
<li>Added the ability to resolve constraint conflicts is ways other than
    an abort and rollback.  See the documentation on the "ON CONFLICT"
    clause for details.</li>
<li>Temporary files are now automatically deleted by the operating system
    when closed.  There are no more dangling temporary files on a program
    crash.  (If the OS crashes, fsck will delete the file after reboot 
    under Unix.  I do not know what happens under Windows.)</li>
<li>NOT NULL constraints are honored.</li>
<li>The COPY command puts NULLs in columns whose data is '\N'.</li>
<li>In the COPY command, backslash can now be used to escape a newline.</li>
<li>Added the SANITY_CHECK pragma.</li>
}

chng {2002 Jan 28 (2.2.5)} {
<li>Important bug fix: the IN operator was not working if either the
    left-hand or right-hand side was derived from an INTEGER PRIMARY KEY.</li>
<li>Do not escape the backslash '\' character in the output of the
    <b>sqlite</b> command-line access program.</li>

Changes to www/index.tcl.

1
2
3
4
5
6
7
8
9
10
11
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#
# Run this TCL script to generate HTML for the index.html file.
#
set rcsid {$Id: index.tcl,v 1.52 2002/01/29 18:41:26 drh Exp $}

puts {<html>
<head><title>SQLite: An SQL Database Engine In A C Library</title></head>
<body bgcolor=white>
<h1 align=center>SQLite: An SQL Database Engine In A C Library</h1>
<p align=center>}
puts "This page was last modified on [lrange $rcsid 3 4] UTC<br>"
................................................................................
}

puts {<h2>Current Status</h2>

<p>A <a href="changes.html">change history</a> is available online.
The latest source code is
<a href="download.html">available for download</a>.
There are currently no known memory leaks or bugs
in version 2.2.5 of the library.
</p>

<p>
Whenever either of the first two digits in the version number
for SQLite change, it means that the underlying file format
has changed.  See <a href="formatchng.html">formatchng.html</a>
for additional information.



|







 







|
<







1
2
3
4
5
6
7
8
9
10
11
..
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
#
# Run this TCL script to generate HTML for the index.html file.
#
set rcsid {$Id: index.tcl,v 1.53 2002/02/03 19:06:04 drh Exp $}

puts {<html>
<head><title>SQLite: An SQL Database Engine In A C Library</title></head>
<body bgcolor=white>
<h1 align=center>SQLite: An SQL Database Engine In A C Library</h1>
<p align=center>}
puts "This page was last modified on [lrange $rcsid 3 4] UTC<br>"
................................................................................
}

puts {<h2>Current Status</h2>

<p>A <a href="changes.html">change history</a> is available online.
The latest source code is
<a href="download.html">available for download</a>.
For a list of recently discovered bugs, refer to the change history.

</p>

<p>
Whenever either of the first two digits in the version number
for SQLite change, it means that the underlying file format
has changed.  See <a href="formatchng.html">formatchng.html</a>
for additional information.

Changes to www/lang.tcl.

1
2
3
4
5
6
7
8
9
10
11
...
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640




641
642
643
644
645
646
647
...
732
733
734
735
736
737
738









739
740
741
742
743
744
745
#
# Run this Tcl script to generate the sqlite.html file.
#
set rcsid {$Id: lang.tcl,v 1.21 2002/02/03 00:56:11 drh Exp $}

puts {<html>
<head>
  <title>Query Language Understood By SQLite</title>
</head>
<body bgcolor=white>
<h1 align=center>
................................................................................
<dt><b>FAIL</b></dt>
<dd><p>When a constraint violation occurs, the command aborts with a
return code SQLITE_CONSTRAINT.  But any changes to the database that
the command made prior to encountering the constraint violation
are preserved and are not backed out.  For example, if an UPDATE
statement encountered a constraint violation on the 100th row that
it attempts to update, then the first 99 row changes are preserved
by change to rows 100 and beyond never occur.</p></dd>

<dt><b>IGNORE</b></dt>
<dd><p>When a constraint violation occurs, the one row that contains
the constraint violation is not inserted or changed.  But the command
continues executing normally.  Other rows before and after the row that
contained the constraint violation continue to be inserted or updated
normally.  No error is returned.</p></dd>

<dt><b>REPLACE</b></dt>
<dd><p>When a UNIQUE constraint violation occurs, the pre-existing row
that is causing the constraint violation is removed prior to inserting
or updating the current row.  Thus the insert or update always occurs.
The command continues executing normally.  No error is returned.</p></dd>




</dl>

<p>
The conflict resolution algorithm can be specified in three places,
in order from lowest to highest precedence:
</p>

................................................................................

<li><p><b>PRAGMA parser_trace = ON;<br>PRAGMA parser_trace = OFF;</b></p>
    <p>Turn tracing of the SQL parser inside of the
    SQLite library on and off.  This is used for debugging.
    This only works if the library is compiled without the NDEBUG macro.
    </p></li>










<li><p><b>PRAGMA table_info(</b><i>table-name</i><b>);</b></p>
    <p>For each column in the named table, invoke the callback function
    once with information about that column, including the column name,
    data type, whether or not the column can be NULL, and the default
    value for the column.</p>

<li><p><b>PRAGMA vdbe_trace = ON;<br>PRAGMA vdbe_trace = OFF;</b></p>



|







 







|












|
>
>
>
>







 







>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
...
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
...
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
#
# Run this Tcl script to generate the sqlite.html file.
#
set rcsid {$Id: lang.tcl,v 1.22 2002/02/03 19:06:04 drh Exp $}

puts {<html>
<head>
  <title>Query Language Understood By SQLite</title>
</head>
<body bgcolor=white>
<h1 align=center>
................................................................................
<dt><b>FAIL</b></dt>
<dd><p>When a constraint violation occurs, the command aborts with a
return code SQLITE_CONSTRAINT.  But any changes to the database that
the command made prior to encountering the constraint violation
are preserved and are not backed out.  For example, if an UPDATE
statement encountered a constraint violation on the 100th row that
it attempts to update, then the first 99 row changes are preserved
but changes to rows 100 and beyond never occur.</p></dd>

<dt><b>IGNORE</b></dt>
<dd><p>When a constraint violation occurs, the one row that contains
the constraint violation is not inserted or changed.  But the command
continues executing normally.  Other rows before and after the row that
contained the constraint violation continue to be inserted or updated
normally.  No error is returned.</p></dd>

<dt><b>REPLACE</b></dt>
<dd><p>When a UNIQUE constraint violation occurs, the pre-existing row
that is causing the constraint violation is removed prior to inserting
or updating the current row.  Thus the insert or update always occurs.
The command continues executing normally.  No error is returned.</p>
<p>If a NOT NULL constraint violation occurs, the NULL value is replaced
by the default value for that column.  If the column has no default
value, then the ABORT algorithm is used.</p>
</dd>
</dl>

<p>
The conflict resolution algorithm can be specified in three places,
in order from lowest to highest precedence:
</p>

................................................................................

<li><p><b>PRAGMA parser_trace = ON;<br>PRAGMA parser_trace = OFF;</b></p>
    <p>Turn tracing of the SQL parser inside of the
    SQLite library on and off.  This is used for debugging.
    This only works if the library is compiled without the NDEBUG macro.
    </p></li>

<li><p><b>PRAGMA sanity_check;</b></p>
    <p>The command does an integrity check of the entire database.  It
    looks for out-of-order records, missing pages, and malformed records.
    If any problems are found, then a single string is returned which is
    a description of all problems.  If everything is in order, "ok" is
    returned.  This command is used for testing and debugging only and
    is not available if the library is compiled 
    with the -DNDEBUG=1 compiler option.</p>

<li><p><b>PRAGMA table_info(</b><i>table-name</i><b>);</b></p>
    <p>For each column in the named table, invoke the callback function
    once with information about that column, including the column name,
    data type, whether or not the column can be NULL, and the default
    value for the column.</p>

<li><p><b>PRAGMA vdbe_trace = ON;<br>PRAGMA vdbe_trace = OFF;</b></p>