SQLite

Check-in [43bf797842]
Login

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

Overview
Comment:Fix for an UPDATE on a virtual table when the WHERE clause matches zero rows. Ticket #2244. (CVS 3652)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 43bf797842f00a104f5c5619ad3215edddfc641b
User & Date: danielk1977 2007-02-21 16:52:12.000
Context
2007-02-21
17:04
Modify the fix for #2244 to avoid using a vdbe label. (CVS 3653) (check-in: f7ce74b22a user: danielk1977 tags: trunk)
16:52
Fix for an UPDATE on a virtual table when the WHERE clause matches zero rows. Ticket #2244. (CVS 3652) (check-in: 43bf797842 user: danielk1977 tags: trunk)
16:44
Add comments to the top of keywordhash.h. (CVS 3651) (check-in: 0aa9ed5bbf user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
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.134 2007/02/07 01:06:53 drh Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
  Parse *pParse,       /* The parsing context */







|







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.135 2007/02/21 16:52:12 danielk1977 Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
  Parse *pParse,       /* The parsing context */
564
565
566
567
568
569
570

571
572
573
574
575
576
577
  Vdbe *v = pParse->pVdbe;  /* Virtual machine under construction */
  ExprList *pEList = 0;     /* The result set of the SELECT statement */
  Select *pSelect = 0;      /* The SELECT statement */
  Expr *pExpr;              /* Temporary expression */
  int ephemTab;             /* Table holding the result of the SELECT */
  int i;                    /* Loop counter */
  int addr;                 /* Address of top of loop */


  /* Construct the SELECT statement that will find the new values for
  ** all updated rows. 
  */
  pEList = sqlite3ExprListAppend(0, sqlite3CreateIdExpr("_rowid_"), 0);
  if( pRowid ){
    pEList = sqlite3ExprListAppend(pEList, sqlite3ExprDup(pRowid), 0);







>







564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
  Vdbe *v = pParse->pVdbe;  /* Virtual machine under construction */
  ExprList *pEList = 0;     /* The result set of the SELECT statement */
  Select *pSelect = 0;      /* The SELECT statement */
  Expr *pExpr;              /* Temporary expression */
  int ephemTab;             /* Table holding the result of the SELECT */
  int i;                    /* Loop counter */
  int addr;                 /* Address of top of loop */
  int iLabel;               /* Vdbe label used by the OP_Rewind op */

  /* Construct the SELECT statement that will find the new values for
  ** all updated rows. 
  */
  pEList = sqlite3ExprListAppend(0, sqlite3CreateIdExpr("_rowid_"), 0);
  if( pRowid ){
    pEList = sqlite3ExprListAppend(pEList, sqlite3ExprDup(pRowid), 0);
598
599
600
601
602
603
604

605
606
607
608
609
610
611
612
613
614
615
616
617
618
619

620
621
622
623
624
625
  */
  sqlite3Select(pParse, pSelect, SRT_Table, ephemTab, 0, 0, 0, 0);

  /*
  ** Generate code to scan the ephemeral table and call VDelete and
  ** VInsert
  */

  sqlite3VdbeAddOp(v, OP_Rewind, ephemTab, 0);
  addr = sqlite3VdbeCurrentAddr(v);
  sqlite3VdbeAddOp(v, OP_Column,  ephemTab, 0);
  if( pRowid ){
    sqlite3VdbeAddOp(v, OP_Column, ephemTab, 1);
  }else{
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
  }
  for(i=0; i<pTab->nCol; i++){
    sqlite3VdbeAddOp(v, OP_Column, ephemTab, i+1+(pRowid!=0));
  }
  pParse->pVirtualLock = pTab;
  sqlite3VdbeOp3(v, OP_VUpdate, 0, pTab->nCol+2, 
                     (const char*)pTab->pVtab, P3_VTAB);
  sqlite3VdbeAddOp(v, OP_Next, ephemTab, addr);

  sqlite3VdbeAddOp(v, OP_Close, ephemTab, 0);

  /* Cleanup */
  sqlite3SelectDelete(pSelect);  
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */







>
|














>






599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
  */
  sqlite3Select(pParse, pSelect, SRT_Table, ephemTab, 0, 0, 0, 0);

  /*
  ** Generate code to scan the ephemeral table and call VDelete and
  ** VInsert
  */
  iLabel = sqlite3VdbeMakeLabel(v);
  sqlite3VdbeAddOp(v, OP_Rewind, ephemTab, iLabel);
  addr = sqlite3VdbeCurrentAddr(v);
  sqlite3VdbeAddOp(v, OP_Column,  ephemTab, 0);
  if( pRowid ){
    sqlite3VdbeAddOp(v, OP_Column, ephemTab, 1);
  }else{
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
  }
  for(i=0; i<pTab->nCol; i++){
    sqlite3VdbeAddOp(v, OP_Column, ephemTab, i+1+(pRowid!=0));
  }
  pParse->pVirtualLock = pTab;
  sqlite3VdbeOp3(v, OP_VUpdate, 0, pTab->nCol+2, 
                     (const char*)pTab->pVtab, P3_VTAB);
  sqlite3VdbeAddOp(v, OP_Next, ephemTab, addr);
  sqlite3VdbeResolveLabel(v, iLabel);
  sqlite3VdbeAddOp(v, OP_Close, ephemTab, 0);

  /* Cleanup */
  sqlite3SelectDelete(pSelect);  
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
Changes to test/vtab1.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2006 June 10
#
# 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 implements regression tests for SQLite library.  The
# focus of this file is creating and dropping virtual tables.
#
# $Id: vtab1.test,v 1.39 2007/01/09 14:01:14 drh Exp $

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

ifcapable !vtab||!schema_pragmas {
  finish_test
  return













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2006 June 10
#
# 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 implements regression tests for SQLite library.  The
# focus of this file is creating and dropping virtual tables.
#
# $Id: vtab1.test,v 1.40 2007/02/21 16:52:12 danielk1977 Exp $

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

ifcapable !vtab||!schema_pragmas {
  finish_test
  return
885
886
887
888
889
890
891























892
893
894
  }
} {0 1}
do_test vtab1.11-5 {
  execsql {
    SELECT  glob(a,'2') FROM e
  }
} {{2 1} {2 2}}
























unset -nocomplain echo_module_begin_fail
finish_test







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



885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
  }
} {0 1}
do_test vtab1.11-5 {
  execsql {
    SELECT  glob(a,'2') FROM e
  }
} {{2 1} {2 2}}
 
# See ticket #2244
#
do_test vtab1.2244-1 {
  execsql {
    CREATE TABLE t2244(a, b);
    CREATE VIRTUAL TABLE t2244e USING echo(t2244);
    INSERT INTO t2244 VALUES('AA', 'BB');
    INSERT INTO t2244 VALUES('CC', 'DD');
    SELECT rowid, * FROM t2244e;
  }
} {1 AA BB 2 CC DD}
do_test vtab1.2244-2 {
  execsql {
    SELECT * FROM t2244e WHERE rowid = 10;
  }
} {}
do_test vtab1.2244-3 {
  execsql {
    UPDATE t2244e SET a = 'hello world' WHERE 0;
    SELECT rowid, * FROM t2244e;
  }
} {1 AA BB 2 CC DD}

unset -nocomplain echo_module_begin_fail
finish_test