engine/sqlite/src/update.cpp
author Lars Persson <lars.persson@embeddev.se>
Wed, 31 Mar 2010 18:09:02 +0200
changeset 64 b52f6033af15
parent 2 29cda98b007e
permissions -rw-r--r--
Add so image conversion is done in feedinfo if image already exist. Check in feedengine if image exist from previous database(files might exist, even though the db is corrupt.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     1
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     2
** 2001 September 15
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     3
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     4
** The author disclaims copyright to this source code.  In place of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     5
** a legal notice, here is a blessing:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     6
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     7
**    May you do good and not evil.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     8
**    May you find forgiveness for yourself and forgive others.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     9
**    May you share freely, never taking more than you give.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    10
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    11
*************************************************************************
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    12
** This file contains C code routines that are called by the parser
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    13
** to handle UPDATE statements.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    14
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    15
** $Id: update.cpp 1282 2008-11-13 09:31:33Z LarsPson $
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    16
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    17
#include "sqliteInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    18
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    19
#ifndef SQLITE_OMIT_VIRTUALTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    20
/* Forward declaration */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    21
static void updateVirtualTable(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
  Parse *pParse,       /* The parsing context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
  SrcList *pSrc,       /* The virtual table to be modified */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
  Table *pTab,         /* The virtual table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    25
  ExprList *pChanges,  /* The columns to change in the UPDATE statement */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    26
  Expr *pRowidExpr,    /* Expression used to recompute the rowid */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    27
  int *aXRef,          /* Mapping from columns of pTab to entries in pChanges */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
  Expr *pWhere         /* WHERE clause of the UPDATE statement */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    29
);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    30
#endif /* SQLITE_OMIT_VIRTUALTABLE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    31
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    32
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    33
** The most recently coded instruction was an OP_Column to retrieve the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
** i-th column of table pTab. This routine sets the P3 parameter of the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    35
** OP_Column to the default value, if any.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    36
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    37
** The default value of a column is specified by a DEFAULT clause in the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    38
** column definition. This was either supplied by the user when the table
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
** was created, or added later to the table definition by an ALTER TABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    40
** command. If the latter, then the row-records in the table btree on disk
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    41
** may not contain a value for the column and the default value, taken
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
** from the P3 parameter of the OP_Column instruction, is returned instead.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    43
** If the former, then all row-records are guaranteed to include a value
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    44
** for the column and the P3 value is not required.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
** Column definitions created by an ALTER TABLE command may only have 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
** literal default values specified: a number, null or a string. (If a more
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
** complicated default expression value was provided, it is evaluated 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
** when the ALTER TABLE is executed and one of the literal values written
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
** into the sqlite_master table.)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    51
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    52
** Therefore, the P3 parameter is only required if the default value for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    53
** the column is a literal number, string or null. The sqlite3ValueFromExpr()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
** function is capable of transforming these types of expressions into
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
** sqlite3_value objects.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    56
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    57
void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
  if( pTab && !pTab->pSelect ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
    sqlite3_value *pValue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    60
    u8 enc = ENC(sqlite3VdbeDb(v));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    61
    Column *pCol = &pTab->aCol[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
    assert( i<pTab->nCol );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
    sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, pCol->affinity, &pValue);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
    if( pValue ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
      sqlite3VdbeChangeP3(v, -1, (const char *)pValue, P3_MEM);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
      VdbeComment((v, "# %s.%s", pTab->zName, pCol->zName));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    69
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    70
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    71
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    73
** Process an UPDATE statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    74
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
**          \_______/ \________/     \______/       \________________/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
*            onError   pTabList      pChanges             pWhere
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
void sqlite3Update(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
  Parse *pParse,         /* The parser context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
  SrcList *pTabList,     /* The table in which we should change things */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    82
  ExprList *pChanges,    /* Things to be changed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    83
  Expr *pWhere,          /* The WHERE clause.  May be null */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    84
  int onError            /* How to handle constraint errors */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    85
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
  int i, j;              /* Loop counters */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    87
  Table *pTab;           /* The table to be updated */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    88
  int addr = 0;          /* VDBE instruction address of the start of the loop */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    89
  WhereInfo *pWInfo;     /* Information about the WHERE clause */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    90
  Vdbe *v;               /* The virtual database engine */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    91
  Index *pIdx;           /* For looping over indices */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
  int nIdx;              /* Number of indices that need updating */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
  int nIdxTotal;         /* Total number of indices */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
  int iCur;              /* VDBE Cursor number of pTab */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    95
  sqlite3 *db;           /* The database structure */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    96
  Index **apIdx = 0;     /* An array of indices that need updating too */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
  char *aIdxUsed = 0;    /* aIdxUsed[i]==1 if the i-th index is used */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
  int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
                         ** an expression for the i-th column of the table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   100
                         ** aXRef[i]==-1 if the i-th column is not changed. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   101
  int chngRowid;         /* True if the record number is being changed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
  Expr *pRowidExpr = 0;  /* Expression defining the new record number */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
  int openAll = 0;       /* True if all indices need to be opened */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   104
  AuthContext sContext;  /* The authorization context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   105
  NameContext sNC;       /* The name-context to resolve expressions in */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   106
  int iDb;               /* Database containing the table being updated */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
  int memCnt = 0;        /* Memory cell used for counting rows changed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
  int mem1;      /* Memory address storing the rowid for next row to update */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
#ifndef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   111
  int isView;                  /* Trying to update a view */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   112
  int triggers_exist = 0;      /* True if any row triggers exist */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   115
  int newIdx      = -1;  /* index of trigger "new" temp table       */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   116
  int oldIdx      = -1;  /* index of trigger "old" temp table       */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
  sContext.pParse = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   119
  db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   120
  if( pParse->nErr || db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
    goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   122
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   123
  assert( pTabList->nSrc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
  /* Locate the table which we want to update. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
  pTab = sqlite3SrcListLookup(pParse, pTabList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
  if( pTab==0 ) goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   131
  /* Figure out if we have any triggers and if the table being
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   132
  ** updated is a view
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   133
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   134
#ifndef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
  triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   136
  isView = pTab->pSelect!=0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   137
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
# define triggers_exist 0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
# define isView 0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
#ifdef SQLITE_OMIT_VIEW
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   142
# undef isView
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   143
# define isView 0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   145
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   146
  if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
    goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   148
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   149
  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   150
    goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   151
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   152
  aXRef = (int*)sqlite3DbMallocRaw(db, sizeof(int) * pTab->nCol );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   153
  if( aXRef==0 ) goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
  for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   156
  /* If there are FOR EACH ROW triggers, allocate cursors for the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   157
  ** special OLD and NEW tables
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   158
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
  if( triggers_exist ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
    newIdx = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
    oldIdx = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   162
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   163
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   164
  /* Allocate a cursors for the main database table and for all indices.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
  ** The index cursors might not be used, but if they are used they
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
  ** need to occur right after the database cursor.  So go ahead and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
  ** allocate enough space, just in case.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
  pTabList->a[0].iCursor = iCur = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   170
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   171
    pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   172
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   173
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   174
  /* Initialize the name-context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
  memset(&sNC, 0, sizeof(sNC));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
  sNC.pParse = pParse;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
  sNC.pSrcList = pTabList;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
  /* Resolve the column names in all the expressions of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   180
  ** of the UPDATE statement.  Also find the column index
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   181
  ** for each column to be updated in the pChanges array.  For each
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   182
  ** column to be updated, make sure we have authorization to change
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   183
  ** that column.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   184
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   185
  chngRowid = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
  for(i=0; i<pChanges->nExpr; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
    if( sqlite3ExprResolveNames(&sNC, pChanges->a[i].pExpr) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   188
      goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   189
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   190
    for(j=0; j<pTab->nCol; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
      if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
        if( j==pTab->iPKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
          chngRowid = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
          pRowidExpr = pChanges->a[i].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   195
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   196
        aXRef[j] = i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   198
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   199
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
    if( j>=pTab->nCol ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
      if( sqlite3IsRowid(pChanges->a[i].zName) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
        chngRowid = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   203
        pRowidExpr = pChanges->a[i].pExpr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   204
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   205
        sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   206
        goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   207
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   208
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   209
#ifndef SQLITE_OMIT_AUTHORIZATION
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
    {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
      int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
      rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
                           pTab->aCol[j].zName, db->aDb[iDb].zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
      if( rc==SQLITE_DENY ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
        goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   216
      }else if( rc==SQLITE_IGNORE ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   217
        aXRef[j] = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   219
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   220
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
  /* Allocate memory for the array apIdx[] and fill it with pointers to every
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
  ** index that needs to be updated.  Indices only need updating if their
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
  ** key includes one of the columns named in pChanges or if the record
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
  ** number of the original table entry is changing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   227
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   228
  for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
    if( chngRowid ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
      i = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   231
    }else {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   232
      for(i=0; i<pIdx->nColumn; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   233
        if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   234
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   235
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   236
    if( i<pIdx->nColumn ) nIdx++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   237
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
  if( nIdxTotal>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
    apIdx = (Index**)sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx + nIdxTotal );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
    if( apIdx==0 ) goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
    aIdxUsed = (char*)&apIdx[nIdx];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   243
  for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   244
    if( chngRowid ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
      i = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   247
      for(i=0; i<pIdx->nColumn; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   248
        if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   250
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   251
    if( i<pIdx->nColumn ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
      apIdx[nIdx++] = pIdx;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
      aIdxUsed[j] = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
      aIdxUsed[j] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   257
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   258
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   259
  /* Begin generating code.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
  v = sqlite3GetVdbe(pParse);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
  if( v==0 ) goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   263
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   264
  sqlite3BeginWriteOperation(pParse, 1, iDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   265
  mem1 = pParse->nMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   266
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
#ifndef SQLITE_OMIT_VIRTUALTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
  /* Virtual tables must be handled separately */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
  if( IsVirtual(pTab) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   270
    updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   271
                       pWhere);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
    pWhere = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
    pTabList = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
    goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   275
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   276
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   277
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
  /* Resolve the column names in all the expressions in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
  ** WHERE clause.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   280
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   281
  if( sqlite3ExprResolveNames(&sNC, pWhere) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   282
    goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   283
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   284
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   285
  /* Start the view context
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
  if( isView ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   288
    sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   289
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   290
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
  /* If we are trying to update a view, realize that view into
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
  ** a ephemeral table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
  if( isView ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
    Select *pView;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
    pView = sqlite3SelectDup(db, pTab->pSelect);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
    sqlite3Select(pParse, pView, SRT_EphemTab, iCur, 0, 0, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
    sqlite3SelectDelete(pView);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   300
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   301
  /* Begin the database scan
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   302
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   303
  pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   304
  if( pWInfo==0 ) goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
  /* Remember the rowid of every item to be updated.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
  sqlite3VdbeAddOp(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
  sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
  /* End the database scan loop.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
  sqlite3WhereEnd(pWInfo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   314
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   315
  /* Initialize the count of updated rows
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   316
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   317
  if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   318
    memCnt = pParse->nMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   319
    sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   320
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   321
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   322
  if( triggers_exist ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   323
    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   324
    /* Create pseudo-tables for NEW and OLD
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   325
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   326
    sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   327
    sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   328
    sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   329
    sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   330
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   331
    /* The top of the update loop for when there are triggers.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   332
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   333
    addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   334
    sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   335
    sqlite3VdbeAddOp(v, OP_MemStore, mem1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   336
    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   337
    if( !isView ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   338
      /* Open a cursor and make it point to the record that is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   339
      ** being updated.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   340
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   341
      sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   342
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   343
    sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   344
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   345
    /* Generate the OLD table
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   346
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   347
    sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   348
    sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   349
    sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   350
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   351
    /* Generate the NEW table
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   352
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   353
    if( chngRowid ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   354
      sqlite3ExprCodeAndCache(pParse, pRowidExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   355
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   356
      sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   357
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   358
    for(i=0; i<pTab->nCol; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   359
      if( i==pTab->iPKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   360
        sqlite3VdbeAddOp(v, OP_Null, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   361
        continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   362
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   363
      j = aXRef[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   364
      if( j<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   365
        sqlite3VdbeAddOp(v, OP_Column, iCur, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   366
        sqlite3ColumnDefault(v, pTab, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   367
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   368
        sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   369
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   370
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   371
    sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   372
    if( !isView ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   373
      sqlite3TableAffinityStr(v, pTab);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   374
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   375
    if( pParse->nErr ) goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   376
    sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   377
    if( !isView ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   378
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   379
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   380
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   381
    /* Fire the BEFORE and INSTEAD OF triggers
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   382
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   383
    if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   384
          newIdx, oldIdx, onError, addr) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   385
      goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   386
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   387
    
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   388
    if( !isView ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   389
      sqlite3VdbeAddOp(v, OP_MemLoad, mem1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   390
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   391
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   392
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   393
  if( !isView && !IsVirtual(pTab) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   394
    /* 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   395
    ** Open every index that needs updating.  Note that if any
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   396
    ** index could potentially invoke a REPLACE conflict resolution 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   397
    ** action, then we need to open all indices because we might need
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   398
    ** to be deleting some records.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   399
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   400
    sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   401
    if( onError==OE_Replace ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   402
      openAll = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   403
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   404
      openAll = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   405
      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   406
        if( pIdx->onError==OE_Replace ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   407
          openAll = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   408
          break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   409
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   410
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   411
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   412
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   413
      if( openAll || aIdxUsed[i] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   414
        KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   415
        sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   416
        sqlite3VdbeOp3(v, OP_OpenWrite, iCur+i+1, pIdx->tnum,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   417
                       (char*)pKey, P3_KEYINFO_HANDOFF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   418
        assert( pParse->nTab>iCur+i+1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   419
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   420
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   421
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   422
    /* Loop over every record that needs updating.  We have to load
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   423
    ** the old data for each record to be updated because some columns
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   424
    ** might not change and we will need to copy the old value.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   425
    ** Also, the old data is needed to delete the old index entries.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   426
    ** So make the cursor point at the old record.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   427
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   428
    if( !triggers_exist ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   429
      addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   430
      sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   431
      sqlite3VdbeAddOp(v, OP_MemStore, mem1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   432
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   433
    sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   434
    sqlite3VdbeAddOp(v, OP_MemLoad, mem1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   435
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   436
    /* If the record number will change, push the record number as it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   437
    ** will be after the update. (The old record number is currently
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   438
    ** on top of the stack.)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   439
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   440
    if( chngRowid ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   441
      sqlite3ExprCode(pParse, pRowidExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   442
      sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   443
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   444
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   445
    /* Compute new data for this record.  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   446
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   447
    for(i=0; i<pTab->nCol; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   448
      if( i==pTab->iPKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   449
        sqlite3VdbeAddOp(v, OP_Null, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   450
        continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   451
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   452
      j = aXRef[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   453
      if( j<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   454
        sqlite3VdbeAddOp(v, OP_Column, iCur, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   455
        sqlite3ColumnDefault(v, pTab, i);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   456
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   457
        sqlite3ExprCode(pParse, pChanges->a[j].pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   458
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   459
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   460
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   461
    /* Do constraint checks
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   462
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   463
    sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRowid, 1,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   464
                                   onError, addr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   465
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   466
    /* Delete the old indices for the current record.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   467
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   468
    sqlite3GenerateRowIndexDelete(v, pTab, iCur, aIdxUsed);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   469
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   470
    /* If changing the record number, delete the old record.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   471
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   472
    if( chngRowid ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   473
      sqlite3VdbeAddOp(v, OP_Delete, iCur, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   474
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   475
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   476
    /* Create the new index entries and the new record.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   477
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   478
    sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   479
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   480
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   481
  /* Increment the row counter 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   482
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   483
  if( db->flags & SQLITE_CountRows && !pParse->trigStack){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   484
    sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   485
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   486
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   487
  /* If there are triggers, close all the cursors after each iteration
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   488
  ** through the loop.  The fire the after triggers.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   489
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   490
  if( triggers_exist ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   491
    if( !isView ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   492
      for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   493
        if( openAll || aIdxUsed[i] )
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   494
          sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   495
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   496
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   497
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   498
    if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_AFTER, pTab, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   499
          newIdx, oldIdx, onError, addr) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   500
      goto update_cleanup;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   501
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   502
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   503
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   504
  /* Repeat the above with the next record to be updated, until
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   505
  ** all record selected by the WHERE clause have been updated.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   506
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   507
  sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   508
  sqlite3VdbeJumpHere(v, addr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   509
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   510
  /* Close all tables if there were no FOR EACH ROW triggers */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   511
  if( !triggers_exist ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   512
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   513
      if( openAll || aIdxUsed[i] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   514
        sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   515
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   516
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   517
    sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   518
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   519
    sqlite3VdbeAddOp(v, OP_Close, newIdx, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   520
    sqlite3VdbeAddOp(v, OP_Close, oldIdx, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   521
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   522
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   523
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   524
  ** Return the number of rows that were changed. If this routine is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   525
  ** generating code because of a call to sqlite3NestedParse(), do not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   526
  ** invoke the callback function.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   527
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   528
  if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   529
    sqlite3VdbeAddOp(v, OP_MemLoad, memCnt, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   530
    sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   531
    sqlite3VdbeSetNumCols(v, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   532
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", P3_STATIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   533
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   534
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   535
update_cleanup:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   536
  sqlite3AuthContextPop(&sContext);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   537
  sqlite3_free(apIdx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   538
  sqlite3_free(aXRef);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   539
  sqlite3SrcListDelete(pTabList);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   540
  sqlite3ExprListDelete(pChanges);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   541
  sqlite3ExprDelete(pWhere);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   542
  return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   543
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   544
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   545
#ifndef SQLITE_OMIT_VIRTUALTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   546
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   547
** Generate code for an UPDATE of a virtual table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   548
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   549
** The strategy is that we create an ephemerial table that contains
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   550
** for each row to be changed:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   551
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   552
**   (A)  The original rowid of that row.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   553
**   (B)  The revised rowid for the row. (note1)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   554
**   (C)  The content of every column in the row.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   555
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   556
** Then we loop over this ephemeral table and for each row in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   557
** the ephermeral table call VUpdate.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   558
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   559
** When finished, drop the ephemeral table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   560
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   561
** (note1) Actually, if we know in advance that (A) is always the same
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   562
** as (B) we only store (A), then duplicate (A) when pulling
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   563
** it out of the ephemeral table before calling VUpdate.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   564
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   565
static void updateVirtualTable(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   566
  Parse *pParse,       /* The parsing context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   567
  SrcList *pSrc,       /* The virtual table to be modified */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   568
  Table *pTab,         /* The virtual table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   569
  ExprList *pChanges,  /* The columns to change in the UPDATE statement */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   570
  Expr *pRowid,        /* Expression used to recompute the rowid */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   571
  int *aXRef,          /* Mapping from columns of pTab to entries in pChanges */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   572
  Expr *pWhere         /* WHERE clause of the UPDATE statement */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   573
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   574
  Vdbe *v = pParse->pVdbe;  /* Virtual machine under construction */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   575
  ExprList *pEList = 0;     /* The result set of the SELECT statement */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   576
  Select *pSelect = 0;      /* The SELECT statement */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   577
  Expr *pExpr;              /* Temporary expression */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   578
  int ephemTab;             /* Table holding the result of the SELECT */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   579
  int i;                    /* Loop counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   580
  int addr;                 /* Address of top of loop */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   581
  sqlite3 *db = pParse->db; /* Database connection */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   582
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   583
  /* Construct the SELECT statement that will find the new values for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   584
  ** all updated rows. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   585
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   586
  pEList = sqlite3ExprListAppend(pParse, 0, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   587
                                 sqlite3CreateIdExpr(pParse, "_rowid_"), 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   588
  if( pRowid ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   589
    pEList = sqlite3ExprListAppend(pParse, pEList,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   590
                                   sqlite3ExprDup(db, pRowid), 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   591
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   592
  assert( pTab->iPKey<0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   593
  for(i=0; i<pTab->nCol; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   594
    if( aXRef[i]>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   595
      pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   596
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   597
      pExpr = sqlite3CreateIdExpr(pParse, pTab->aCol[i].zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   598
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   599
    pEList = sqlite3ExprListAppend(pParse, pEList, pExpr, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   600
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   601
  pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   602
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   603
  /* Create the ephemeral table into which the update results will
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   604
  ** be stored.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   605
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   606
  assert( v );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   607
  ephemTab = pParse->nTab++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   608
  sqlite3VdbeAddOp(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   609
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   610
  /* fill the ephemeral table 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   611
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   612
  sqlite3Select(pParse, pSelect, SRT_Table, ephemTab, 0, 0, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   613
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   614
  /*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   615
  ** Generate code to scan the ephemeral table and call VDelete and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   616
  ** VInsert
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   617
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   618
  sqlite3VdbeAddOp(v, OP_Rewind, ephemTab, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   619
  addr = sqlite3VdbeCurrentAddr(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   620
  sqlite3VdbeAddOp(v, OP_Column,  ephemTab, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   621
  if( pRowid ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   622
    sqlite3VdbeAddOp(v, OP_Column, ephemTab, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   623
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   624
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   625
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   626
  for(i=0; i<pTab->nCol; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   627
    sqlite3VdbeAddOp(v, OP_Column, ephemTab, i+1+(pRowid!=0));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   628
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   629
  pParse->pVirtualLock = pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   630
  sqlite3VdbeOp3(v, OP_VUpdate, 0, pTab->nCol+2, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   631
                     (const char*)pTab->pVtab, P3_VTAB);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   632
  sqlite3VdbeAddOp(v, OP_Next, ephemTab, addr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   633
  sqlite3VdbeJumpHere(v, addr-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   634
  sqlite3VdbeAddOp(v, OP_Close, ephemTab, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   635
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   636
  /* Cleanup */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   637
  sqlite3SelectDelete(pSelect);  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   638
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   639
#endif /* SQLITE_OMIT_VIRTUALTABLE */