engine/sqlite/src/vdbeaux.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
** 2003 September 6
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 code used for creating, destroying, and populating
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    13
** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    14
** to version 2.8.7, all this code was combined into the vdbe.c source file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    15
** But that file was getting too big so this subroutines were split out.
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
#include <ctype.h>
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    19
#include "vdbeInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    20
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    21
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
** When debugging the code generator in a symbolic debugger, one can
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    25
** set the sqlite3_vdbe_addop_trace to 1 and all opcodes will be printed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    26
** as they are added to the instruction stream.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    27
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
#ifdef SQLITE_DEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    29
int sqlite3_vdbe_addop_trace = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    30
#endif
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
** Create a new virtual database engine.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    35
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    36
Vdbe *sqlite3VdbeCreate(sqlite3 *db){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    37
  Vdbe *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    38
  p = (Vdbe*)sqlite3DbMallocZero(db, sizeof(Vdbe) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
  if( p==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    40
  p->db = db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    41
  if( db->pVdbe ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
    db->pVdbe->pPrev = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    43
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    44
  p->pNext = db->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
  p->pPrev = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
  db->pVdbe = p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
  p->magic = VDBE_MAGIC_INIT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
  return p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
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
** Remember the SQL string for a prepared statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    53
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
  if( p==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    56
  assert( p->zSql==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    57
  p->zSql = sqlite3DbStrNDup(p->db, z, n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    60
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    61
** Return the SQL associated with a prepared statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
EXPORT_C const char *sqlite3_sql(sqlite3_stmt *pStmt){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
  return ((Vdbe *)pStmt)->zSql;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
** Swap all content between two VDBE structures.
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
void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    71
  Vdbe tmp, *pTmp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
  char *zTmp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    73
  int nTmp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    74
  tmp = *pA;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
  *pA = *pB;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
  *pB = tmp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
  pTmp = pA->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
  pA->pNext = pB->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
  pB->pNext = pTmp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
  pTmp = pA->pPrev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
  pA->pPrev = pB->pPrev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    82
  pB->pPrev = pTmp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    83
  zTmp = pA->zSql;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    84
  pA->zSql = pB->zSql;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    85
  pB->zSql = zTmp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
  nTmp = pA->nSql;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    87
  pA->nSql = pB->nSql;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    88
  pB->nSql = nTmp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    89
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    90
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    91
#ifdef SQLITE_DEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
** Turn tracing on or off
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    95
void sqlite3VdbeTrace(Vdbe *p, FILE *trace){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    96
  p->trace = trace;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   100
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   101
** Resize the Vdbe.aOp array so that it contains at least N
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
** elements.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   104
** If an out-of-memory error occurs while resizing the array,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   105
** Vdbe.aOp and Vdbe.nOpAlloc remain unchanged (this is so that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   106
** any opcodes already allocated can be correctly deallocated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
** along with the rest of the Vdbe).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
static void resizeOpArray(Vdbe *p, int N){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
  VdbeOp *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   111
  int oldSize = p->nOpAlloc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   112
  pNew = (VdbeOp*)sqlite3DbRealloc(p->db, p->aOp, N*sizeof(Op));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
  if( pNew ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
    p->nOpAlloc = N;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   115
    p->aOp = pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   116
    if( N>oldSize ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
      memset(&p->aOp[oldSize], 0, (N-oldSize)*sizeof(Op));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   119
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   120
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
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
** Add a new instruction to the list of instructions current in the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
** VDBE.  Return the address of the new instruction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
** Parameters:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
**    p               Pointer to the VDBE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
**    op              The opcode for this instruction
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   131
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   132
**    p1, p2          First two of the three possible operands.
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
** Use the sqlite3VdbeResolveLabel() function to fix an address and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
** the sqlite3VdbeChangeP3() function to change the value of the P3
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   136
** operand.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   137
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
int sqlite3VdbeAddOp(Vdbe *p, int op, int p1, int p2){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
  VdbeOp *pOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   142
  i = p->nOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   143
  assert( p->magic==VDBE_MAGIC_INIT );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
  if( p->nOpAlloc<=i ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   145
    resizeOpArray(p, p->nOpAlloc*2 + 100);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   146
    if( p->db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
      return 0;
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   150
  p->nOp++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   151
  pOp = &p->aOp[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   152
  pOp->opcode = op;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   153
  pOp->p1 = p1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
  pOp->p2 = p2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
  pOp->p3 = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   156
  pOp->p3type = P3_NOTUSED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   157
  p->expired = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   158
#ifdef SQLITE_DEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
  if( sqlite3_vdbe_addop_trace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
  return i;
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
** Add an opcode that includes the p3 value.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
int sqlite3VdbeOp3(Vdbe *p, int op, int p1, int p2, const char *zP3,int p3type){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
  int addr = sqlite3VdbeAddOp(p, op, p1, p2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
  sqlite3VdbeChangeP3(p, addr, zP3, p3type);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   170
  return addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   171
}
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
** Create a new symbolic label for an instruction that has yet to be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
** coded.  The symbolic label is really just a negative number.  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
** label can be used as the P2 value of an operation.  Later, when
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
** the label is resolved to a specific address, the VDBE will scan
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
** through its operation list and change all values of P2 which match
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
** the label into the resolved address.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   180
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   181
** The VDBE knows that a P2 value is a label because labels are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   182
** always negative and P2 values are suppose to be non-negative.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   183
** Hence, a negative P2 value is a label that has yet to be resolved.
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
** Zero is returned if a malloc() fails.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
int sqlite3VdbeMakeLabel(Vdbe *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   188
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   189
  i = p->nLabel++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   190
  assert( p->magic==VDBE_MAGIC_INIT );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
  if( i>=p->nLabelAlloc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
    p->nLabelAlloc = p->nLabelAlloc*2 + 10;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
    p->aLabel = (int*)sqlite3DbReallocOrFree(p->db, p->aLabel,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
                                    p->nLabelAlloc*sizeof(p->aLabel[0]));
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
  if( p->aLabel ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
    p->aLabel[i] = -1;
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
  return -1-i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   203
** Resolve label "x" to be the address of the next instruction to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   204
** be inserted.  The parameter "x" must have been obtained from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   205
** a prior call to sqlite3VdbeMakeLabel().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   206
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   207
void sqlite3VdbeResolveLabel(Vdbe *p, int x){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   208
  int j = -1-x;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   209
  assert( p->magic==VDBE_MAGIC_INIT );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
  assert( j>=0 && j<p->nLabel );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
  if( p->aLabel ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
    p->aLabel[j] = p->nOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   216
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   217
** Return non-zero if opcode 'op' is guarenteed not to push more values
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
** onto the VDBE stack than it pops off.
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
static int opcodeNoPush(u8 op){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
  /* The 10 NOPUSH_MASK_n constants are defined in the automatically
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
  ** generated header file opcodes.h. Each is a 16-bit bitmask, one
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
  ** bit corresponding to each opcode implemented by the virtual
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
  ** machine in vdbe.c. The bit is true if the word "no-push" appears
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
  ** in a comment on the same line as the "case OP_XXX:" in 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
  ** sqlite3VdbeExec() in vdbe.c.
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
  ** If the bit is true, then the corresponding opcode is guarenteed not
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
  ** to grow the stack when it is executed. Otherwise, it may grow the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
  ** stack by at most one entry.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   231
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   232
  ** NOPUSH_MASK_0 corresponds to opcodes 0 to 15. NOPUSH_MASK_1 contains
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   233
  ** one bit for opcodes 16 to 31, and so on.
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
  ** 16-bit bitmasks (rather than 32-bit) are specified in opcodes.h 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   236
  ** because the file is generated by an awk program. Awk manipulates
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   237
  ** all numbers as floating-point and we don't want to risk a rounding
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
  ** error if someone builds with an awk that uses (for example) 32-bit 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
  ** IEEE floats.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
  */ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
  static const u32 masks[5] = {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
    NOPUSH_MASK_0 + (((unsigned)NOPUSH_MASK_1)<<16),
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   243
    NOPUSH_MASK_2 + (((unsigned)NOPUSH_MASK_3)<<16),
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   244
    NOPUSH_MASK_4 + (((unsigned)NOPUSH_MASK_5)<<16),
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
    NOPUSH_MASK_6 + (((unsigned)NOPUSH_MASK_7)<<16),
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
    NOPUSH_MASK_8 + (((unsigned)NOPUSH_MASK_9)<<16)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   247
  };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   248
  assert( op<32*5 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
  return (masks[op>>5] & (1<<(op&0x1F)));
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
int sqlite3VdbeOpcodeNoPush(u8 op){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
  return opcodeNoPush(op);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
#endif
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
** Loop through the program looking for P2 values that are negative.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
** Each such value is a label.  Resolve the label by setting the P2
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
** value to its correct non-zero value.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   263
** This routine is called once after all opcodes have been inserted.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   264
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   265
** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   266
** to an OP_Function, OP_AggStep or OP_VFilter opcode. This is used by 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
** The integer *pMaxStack is set to the maximum number of vdbe stack
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   270
** entries that static analysis reveals this program might need.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   271
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
** This routine also does the following optimization:  It scans for
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
** instructions that might cause a statement rollback.  Such instructions
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
** are:
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
**   *  OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   277
**   *  OP_Destroy
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
**   *  OP_VUpdate
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
**   *  OP_VRename
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 no such instruction is found, then every Statement instruction 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   282
** is changed to a Noop.  In this way, we avoid creating the statement 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   283
** journal file unnecessarily.
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
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs, int *pMaxStack){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
  int nMaxArgs = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   288
  int nMaxStack = p->nOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   289
  Op *pOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   290
  int *aLabel = p->aLabel;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
  int doesStatementRollback = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
  int hasStatementBegin = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
  for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
    u8 opcode = pOp->opcode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
    if( opcode==OP_Function || opcode==OP_AggStep 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
#ifndef SQLITE_OMIT_VIRTUALTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
        || opcode==OP_VUpdate
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
#endif
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
      if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
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
    if( opcode==OP_Halt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   304
      if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
        doesStatementRollback = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
    }else if( opcode==OP_Statement ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
      hasStatementBegin = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
    }else if( opcode==OP_Destroy ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
      doesStatementRollback = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
#ifndef SQLITE_OMIT_VIRTUALTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
    }else if( opcode==OP_VUpdate || opcode==OP_VRename ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
      doesStatementRollback = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   314
    }else if( opcode==OP_VFilter ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   315
      int n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   316
      assert( p->nOp - i >= 3 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   317
      assert( pOp[-2].opcode==OP_Integer );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   318
      n = pOp[-2].p1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   319
      if( n>nMaxArgs ) nMaxArgs = n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   320
#endif
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( opcodeNoPush(opcode) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   323
      nMaxStack--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   324
    }
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
    if( pOp->p2>=0 ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   327
    assert( -1-pOp->p2<p->nLabel );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   328
    pOp->p2 = aLabel[-1-pOp->p2];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   329
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   330
  sqlite3_free(p->aLabel);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   331
  p->aLabel = 0;
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
  *pMaxFuncArgs = nMaxArgs;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   334
  *pMaxStack = nMaxStack;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   335
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   336
  /* If we never rollback a statement transaction, then statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   337
  ** transactions are not needed.  So change every OP_Statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   338
  ** opcode into an OP_Noop.  This avoid a call to sqlite3OsOpenExclusive()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   339
  ** which can be expensive on some platforms.
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
  if( hasStatementBegin && !doesStatementRollback ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   342
    for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   343
      if( pOp->opcode==OP_Statement ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   344
        pOp->opcode = OP_Noop;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   345
      }
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
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   348
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   349
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
** Return the address of the next instruction to be inserted.
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
int sqlite3VdbeCurrentAddr(Vdbe *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   354
  assert( p->magic==VDBE_MAGIC_INIT );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   355
  return p->nOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   356
}
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   359
** Add a whole list of operations to the operation stack.  Return the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   360
** address of the first operation added.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   361
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   362
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   363
  int addr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   364
  assert( p->magic==VDBE_MAGIC_INIT );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   365
  if( p->nOp + nOp > p->nOpAlloc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   366
    resizeOpArray(p, p->nOp*2 + nOp);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   367
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   368
  if( p->db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   369
    return 0;
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
  addr = p->nOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   372
  if( nOp>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   373
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   374
    VdbeOpList const *pIn = aOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   375
    for(i=0; i<nOp; i++, pIn++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   376
      int p2 = pIn->p2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   377
      VdbeOp *pOut = &p->aOp[i+addr];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   378
      pOut->opcode = pIn->opcode;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   379
      pOut->p1 = pIn->p1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   380
      pOut->p2 = p2<0 ? addr + ADDR(p2) : p2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   381
      pOut->p3 = pIn->p3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   382
      pOut->p3type = pIn->p3 ? P3_STATIC : P3_NOTUSED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   383
#ifdef SQLITE_DEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   384
      if( sqlite3_vdbe_addop_trace ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   385
        sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
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
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   388
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   389
    p->nOp += nOp;
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
  return addr;
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
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
** Change the value of the P1 operand for a specific instruction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   396
** This routine is useful when a large program is loaded from a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   397
** static array using sqlite3VdbeAddOpList but we want to make a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   398
** few minor changes to the program.
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
void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   401
  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   402
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   403
    p->aOp[addr].p1 = val;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   404
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   405
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   406
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   407
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   408
** Change the value of the P2 operand for a specific instruction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   409
** This routine is useful for setting a jump destination.
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
void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   412
  assert( val>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   413
  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   414
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   415
    p->aOp[addr].p2 = val;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   416
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   417
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   418
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
** Change the P2 operand of instruction addr so that it points to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   421
** the address of the next instruction to be coded.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   422
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   423
void sqlite3VdbeJumpHere(Vdbe *p, int addr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   424
  sqlite3VdbeChangeP2(p, addr, p->nOp);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   425
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   426
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
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   429
** If the input FuncDef structure is ephemeral, then free it.  If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   430
** the FuncDef is not ephermal, then do nothing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   431
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   432
static void freeEphemeralFunction(FuncDef *pDef){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   433
  if( pDef && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   434
    sqlite3_free(pDef);
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
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   437
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   438
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   439
** Delete a P3 value if necessary.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   440
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   441
static void freeP3(int p3type, void *p3){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   442
  if( p3 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   443
    switch( p3type ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   444
      case P3_REAL:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   445
      case P3_INT64:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   446
      case P3_MPRINTF:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   447
      case P3_DYNAMIC:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   448
      case P3_KEYINFO:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   449
      case P3_KEYINFO_HANDOFF: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   450
        sqlite3_free(p3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   451
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   452
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   453
      case P3_VDBEFUNC: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   454
        VdbeFunc *pVdbeFunc = (VdbeFunc *)p3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   455
        freeEphemeralFunction(pVdbeFunc->pFunc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   456
        sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   457
        sqlite3_free(pVdbeFunc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   458
        break;
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
      case P3_FUNCDEF: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   461
        freeEphemeralFunction((FuncDef*)p3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   462
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   463
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   464
      case P3_MEM: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   465
        sqlite3ValueFree((sqlite3_value*)p3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   466
        break;
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
    }
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
}
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   473
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   474
** Change N opcodes starting at addr to No-ops.
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
void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   477
  if( p && p->aOp ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   478
    VdbeOp *pOp = &p->aOp[addr];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   479
    while( N-- ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   480
      freeP3(pOp->p3type, pOp->p3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   481
      memset(pOp, 0, sizeof(pOp[0]));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   482
      pOp->opcode = OP_Noop;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   483
      pOp++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   484
    }
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   488
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   489
** Change the value of the P3 operand for a specific instruction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   490
** This routine is useful when a large program is loaded from a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   491
** static array using sqlite3VdbeAddOpList but we want to make a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   492
** few minor changes to the program.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   493
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   494
** If n>=0 then the P3 operand is dynamic, meaning that a copy of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   495
** the string is made into memory obtained from sqlite3_malloc().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   496
** A value of n==0 means copy bytes of zP3 up to and including the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   497
** first null byte.  If n>0 then copy n+1 bytes of zP3.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   498
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   499
** If n==P3_KEYINFO it means that zP3 is a pointer to a KeyInfo structure.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   500
** A copy is made of the KeyInfo structure into memory obtained from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   501
** sqlite3_malloc, to be freed when the Vdbe is finalized.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   502
** n==P3_KEYINFO_HANDOFF indicates that zP3 points to a KeyInfo structure
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   503
** stored in memory that the caller has obtained from sqlite3_malloc. The 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   504
** caller should not free the allocation, it will be freed when the Vdbe is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   505
** finalized.
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
** Other values of n (P3_STATIC, P3_COLLSEQ etc.) indicate that zP3 points
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   508
** to a string or structure that is guaranteed to exist for the lifetime of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   509
** the Vdbe. In these cases we can just copy the pointer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   510
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   511
** If addr<0 then change P3 on the most recently inserted instruction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   512
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   513
void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   514
  Op *pOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   515
  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   516
  if( p==0 || p->aOp==0 || p->db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   517
    if (n != P3_KEYINFO) {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   518
      freeP3(n, (void*)*(char**)&zP3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   519
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   520
    return;
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
  if( addr<0 || addr>=p->nOp ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   523
    addr = p->nOp - 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   524
    if( addr<0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   525
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   526
  pOp = &p->aOp[addr];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   527
  freeP3(pOp->p3type, pOp->p3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   528
  pOp->p3 = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   529
  if( zP3==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   530
    pOp->p3 = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   531
    pOp->p3type = P3_NOTUSED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   532
  }else if( n==P3_KEYINFO ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   533
    KeyInfo *pKeyInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   534
    int nField, nByte;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   535
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   536
    nField = ((KeyInfo*)zP3)->nField;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   537
    nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   538
    pKeyInfo = (KeyInfo*)sqlite3_malloc( nByte );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   539
    pOp->p3 = (char*)pKeyInfo;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   540
    if( pKeyInfo ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   541
      unsigned char *aSortOrder;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   542
      memcpy(pKeyInfo, zP3, nByte);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   543
      aSortOrder = pKeyInfo->aSortOrder;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   544
      if( aSortOrder ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   545
        pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   546
        memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   547
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   548
      pOp->p3type = P3_KEYINFO;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   549
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   550
      p->db->mallocFailed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   551
      pOp->p3type = P3_NOTUSED;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   552
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   553
  }else if( n==P3_KEYINFO_HANDOFF ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   554
    pOp->p3 = (char*)zP3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   555
    pOp->p3type = P3_KEYINFO;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   556
  }else if( n<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   557
    pOp->p3 = (char*)zP3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   558
    pOp->p3type = n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   559
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   560
    if( n==0 ) n = strlen(zP3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   561
    pOp->p3 = sqlite3DbStrNDup(p->db, zP3, n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   562
    pOp->p3type = P3_DYNAMIC;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   563
  }
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
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   566
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   567
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   568
** Replace the P3 field of the most recently coded instruction with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   569
** comment text.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   570
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   571
void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   572
  va_list ap;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   573
  assert( p->nOp>0 || p->aOp==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   574
  assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 || p->db->mallocFailed );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   575
  va_start(ap, zFormat);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   576
  sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(p->db, zFormat, ap), P3_DYNAMIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   577
  va_end(ap);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   578
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   579
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   580
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   581
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   582
** Return the opcode for a given address.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   583
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   584
VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   585
  assert( p->magic==VDBE_MAGIC_INIT );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   586
  assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   587
  return ((addr>=0 && addr<p->nOp)?(&p->aOp[addr]):0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   588
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   589
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   590
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   591
     || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   592
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   593
** Compute a string that describes the P3 parameter for an opcode.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   594
** Use zTemp for any required temporary buffer space.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   595
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   596
static char *displayP3(Op *pOp, char *zTemp, int nTemp){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   597
  char *zP3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   598
  assert( nTemp>=20 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   599
  switch( pOp->p3type ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   600
    case P3_KEYINFO: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   601
      int i, j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   602
      KeyInfo *pKeyInfo = (KeyInfo*)pOp->p3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   603
      sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   604
      i = strlen(zTemp);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   605
      for(j=0; j<pKeyInfo->nField; j++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   606
        CollSeq *pColl = pKeyInfo->aColl[j];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   607
        if( pColl ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   608
          int n = strlen(pColl->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   609
          if( i+n>nTemp-6 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   610
            memcpy(&zTemp[i],",...",4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   611
            break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   612
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   613
          zTemp[i++] = ',';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   614
          if( pKeyInfo->aSortOrder && pKeyInfo->aSortOrder[j] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   615
            zTemp[i++] = '-';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   616
          }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   617
          memcpy(&zTemp[i], pColl->zName,n+1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   618
          i += n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   619
        }else if( i+4<nTemp-6 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   620
          memcpy(&zTemp[i],",nil",4);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   621
          i += 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   622
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   623
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   624
      zTemp[i++] = ')';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   625
      zTemp[i] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   626
      assert( i<nTemp );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   627
      zP3 = zTemp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   628
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   629
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   630
    case P3_COLLSEQ: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   631
      CollSeq *pColl = (CollSeq*)pOp->p3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   632
      sqlite3_snprintf(nTemp, zTemp, "collseq(%.20s)", pColl->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   633
      zP3 = zTemp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   634
      break;
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
    case P3_FUNCDEF: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   637
      FuncDef *pDef = (FuncDef*)pOp->p3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   638
      sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   639
      zP3 = zTemp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   640
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   641
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   642
    case P3_INT64: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   643
      sqlite3_snprintf(nTemp, zTemp, "%lld", *(sqlite3_int64*)pOp->p3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   644
      zP3 = zTemp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   645
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   646
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   647
    case P3_REAL: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   648
      sqlite3_snprintf(nTemp, zTemp, "%.16g", *(double*)pOp->p3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   649
      zP3 = zTemp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   650
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   651
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   652
#ifndef SQLITE_OMIT_VIRTUALTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   653
    case P3_VTAB: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   654
      sqlite3_vtab *pVtab = (sqlite3_vtab*)pOp->p3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   655
      sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   656
      zP3 = zTemp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   657
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   658
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   659
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   660
    default: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   661
      zP3 = pOp->p3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   662
      if( zP3==0 || pOp->opcode==OP_Noop ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   663
        zP3 = "";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   664
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   665
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   666
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   667
  assert( zP3!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   668
  return zP3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   669
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   670
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   671
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   672
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   673
** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   674
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   675
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   676
void sqlite3VdbeUsesBtree(Vdbe *p, int i){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   677
  int mask;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   678
  assert( i>=0 && i<p->db->nDb );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   679
  assert( i<sizeof(p->btreeMask)*8 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   680
  mask = 1<<i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   681
  if( (p->btreeMask & mask)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   682
    p->btreeMask |= mask;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   683
    sqlite3BtreeMutexArrayInsert(&p->aMutex, p->db->aDb[i].pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   684
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   685
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   686
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   687
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   688
#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   689
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   690
** Print a single opcode.  This routine is used for debugging only.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   691
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   692
void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   693
  char *zP3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   694
  char zPtr[50];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   695
  static const char *zFormat1 = "%4d %-13s %4d %4d %s\n";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   696
  if( pOut==0 ) pOut = stdout;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   697
  zP3 = displayP3(pOp, zPtr, sizeof(zPtr));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   698
  fprintf(pOut, zFormat1,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   699
      pc, sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, zP3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   700
  fflush(pOut);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   701
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   702
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   703
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   704
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   705
** Release an array of N Mem elements
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   706
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   707
static void releaseMemArray(Mem *p, int N){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   708
  if( p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   709
    while( N-->0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   710
      assert( N<2 || p[0].db==p[1].db );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   711
      sqlite3VdbeMemRelease(p++);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   712
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   713
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   714
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   715
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   716
#ifndef SQLITE_OMIT_EXPLAIN
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   717
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   718
** Give a listing of the program in the virtual machine.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   719
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   720
** The interface is the same as sqlite3VdbeExec().  But instead of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   721
** running the code, it invokes the callback once for each instruction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   722
** This feature is used to implement "EXPLAIN".
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   723
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   724
int sqlite3VdbeList(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   725
  Vdbe *p                   /* The VDBE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   726
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   727
  sqlite3 *db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   728
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   729
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   730
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   731
  assert( p->explain );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   732
  if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   733
  assert( db->magic==SQLITE_MAGIC_BUSY );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   734
  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   735
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   736
  /* Even though this opcode does not put dynamic strings onto the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   737
  ** the stack, they may become dynamic if the user calls
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   738
  ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   739
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   740
  if( p->pTos==&p->aStack[4] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   741
    releaseMemArray(p->aStack, 5);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   742
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   743
  p->resOnStack = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   744
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   745
  do{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   746
    i = p->pc++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   747
  }while( i<p->nOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   748
  if( i>=p->nOp ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   749
    p->rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   750
    rc = SQLITE_DONE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   751
  }else if( db->u1.isInterrupted ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   752
    p->rc = SQLITE_INTERRUPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   753
    rc = SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   754
    sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(p->rc), (char*)0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   755
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   756
    Op *pOp = &p->aOp[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   757
    Mem *pMem = p->aStack;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   758
    pMem->flags = MEM_Int;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   759
    pMem->type = SQLITE_INTEGER;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   760
    pMem->u.i = i;                                /* Program counter */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   761
    pMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   762
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   763
    pMem->flags = MEM_Static|MEM_Str|MEM_Term;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   764
    pMem->z = (char*)sqlite3OpcodeName(pOp->opcode);  /* Opcode */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   765
    assert( pMem->z!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   766
    pMem->n = strlen(pMem->z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   767
    pMem->type = SQLITE_TEXT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   768
    pMem->enc = SQLITE_UTF8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   769
    pMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   770
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   771
    pMem->flags = MEM_Int;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   772
    pMem->u.i = pOp->p1;                          /* P1 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   773
    pMem->type = SQLITE_INTEGER;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   774
    pMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   775
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   776
    pMem->flags = MEM_Int;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   777
    pMem->u.i = pOp->p2;                          /* P2 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   778
    pMem->type = SQLITE_INTEGER;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   779
    pMem++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   780
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   781
    pMem->flags = MEM_Ephem|MEM_Str|MEM_Term;   /* P3 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   782
    pMem->z = displayP3(pOp, pMem->zShort, sizeof(pMem->zShort));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   783
    assert( pMem->z!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   784
    pMem->n = strlen(pMem->z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   785
    pMem->type = SQLITE_TEXT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   786
    pMem->enc = SQLITE_UTF8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   787
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   788
    p->nResColumn = 5 - 2*(p->explain-1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   789
    p->pTos = pMem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   790
    p->rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   791
    p->resOnStack = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   792
    rc = SQLITE_ROW;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   793
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   794
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   795
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   796
#endif /* SQLITE_OMIT_EXPLAIN */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   797
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   798
#ifdef SQLITE_DEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   799
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   800
** Print the SQL that was used to generate a VDBE program.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   801
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   802
void sqlite3VdbePrintSql(Vdbe *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   803
  int nOp = p->nOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   804
  VdbeOp *pOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   805
  if( nOp<1 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   806
  pOp = &p->aOp[nOp-1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   807
  if( pOp->opcode==OP_Noop && pOp->p3!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   808
    const char *z = pOp->p3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   809
    while( isspace(*(u8*)z) ) z++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   810
    printf("SQL: [%s]\n", z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   811
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   812
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   813
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   814
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   815
#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   816
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   817
** Print an IOTRACE message showing SQL content.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   818
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   819
void sqlite3VdbeIOTraceSql(Vdbe *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   820
  int nOp = p->nOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   821
  VdbeOp *pOp;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   822
  if( sqlite3_io_trace==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   823
  if( nOp<1 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   824
  pOp = &p->aOp[nOp-1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   825
  if( pOp->opcode==OP_Noop && pOp->p3!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   826
    int i, j;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   827
    char z[1000];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   828
    sqlite3_snprintf(sizeof(z), z, "%s", pOp->p3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   829
    for(i=0; isspace((unsigned char)z[i]); i++){}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   830
    for(j=0; z[i]; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   831
      if( isspace((unsigned char)z[i]) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   832
        if( z[i-1]!=' ' ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   833
          z[j++] = ' ';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   834
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   835
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   836
        z[j++] = z[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   837
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   838
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   839
    z[j] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   840
    sqlite3_io_trace("SQL %s\n", z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   841
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   842
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   843
#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   844
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   845
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   846
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   847
** Prepare a virtual machine for execution.  This involves things such
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   848
** as allocating stack space and initializing the program counter.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   849
** After the VDBE has be prepped, it can be executed by one or more
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   850
** calls to sqlite3VdbeExec().  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   851
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   852
** This is the only way to move a VDBE from VDBE_MAGIC_INIT to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   853
** VDBE_MAGIC_RUN.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   854
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   855
void sqlite3VdbeMakeReady(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   856
  Vdbe *p,                       /* The VDBE */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   857
  int nVar,                      /* Number of '?' see in the SQL statement */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   858
  int nMem,                      /* Number of memory cells to allocate */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   859
  int nCursor,                   /* Number of cursors to allocate */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   860
  int isExplain                  /* True if the EXPLAIN keywords is present */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   861
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   862
  int n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   863
  sqlite3 *db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   864
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   865
  assert( p!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   866
  assert( p->magic==VDBE_MAGIC_INIT );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   867
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   868
  /* There should be at least one opcode.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   869
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   870
  assert( p->nOp>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   871
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   872
  /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. This
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   873
   * is because the call to resizeOpArray() below may shrink the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   874
   * p->aOp[] array to save memory if called when in VDBE_MAGIC_RUN 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   875
   * state.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   876
   */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   877
  p->magic = VDBE_MAGIC_RUN;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   878
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   879
  /* No instruction ever pushes more than a single element onto the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   880
  ** stack.  And the stack never grows on successive executions of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   881
  ** same loop.  So the total number of instructions is an upper bound
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   882
  ** on the maximum stack depth required.  (Added later:)  The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   883
  ** resolveP2Values() call computes a tighter upper bound on the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   884
  ** stack size.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   885
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   886
  ** Allocation all the stack space we will ever need.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   887
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   888
  if( p->aStack==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   889
    int nArg;       /* Maximum number of args passed to a user function. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   890
    int nStack;     /* Maximum number of stack entries required */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   891
    resolveP2Values(p, &nArg, &nStack);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   892
    resizeOpArray(p, p->nOp);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   893
    assert( nVar>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   894
    assert( nStack<p->nOp );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   895
    if( isExplain ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   896
      nStack = 10;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   897
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   898
    p->aStack = (Mem*)sqlite3DbMallocZero(db,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   899
        nStack*sizeof(p->aStack[0])    /* aStack */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   900
      + nArg*sizeof(Mem*)              /* apArg */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   901
      + nVar*sizeof(Mem)               /* aVar */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   902
      + nVar*sizeof(char*)             /* azVar */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   903
      + nMem*sizeof(Mem)               /* aMem */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   904
      + nCursor*sizeof(Cursor*)        /* apCsr */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   905
    );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   906
    if( !db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   907
      p->aMem = &p->aStack[nStack];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   908
      p->nMem = nMem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   909
      p->aVar = &p->aMem[nMem];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   910
      p->nVar = nVar;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   911
      p->okVar = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   912
      p->apArg = (Mem**)&p->aVar[nVar];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   913
      p->azVar = (char**)&p->apArg[nArg];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   914
      p->apCsr = (Cursor**)&p->azVar[nVar];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   915
      p->nCursor = nCursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   916
      for(n=0; n<nVar; n++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   917
        p->aVar[n].flags = MEM_Null;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   918
        p->aVar[n].db = db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   919
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   920
      for(n=0; n<nStack; n++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   921
        p->aStack[n].db = db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   922
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   923
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   924
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   925
  for(n=0; n<p->nMem; n++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   926
    p->aMem[n].flags = MEM_Null;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   927
    p->aMem[n].db = db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   928
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   929
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   930
  p->pTos = &p->aStack[-1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   931
  p->pc = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   932
  p->rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   933
  p->uniqueCnt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   934
  p->returnDepth = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   935
  p->errorAction = OE_Abort;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   936
  p->popStack =  0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   937
  p->explain |= isExplain;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   938
  p->magic = VDBE_MAGIC_RUN;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   939
  p->nChange = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   940
  p->cacheCtr = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   941
  p->minWriteFileFormat = 255;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   942
  p->openedStatement = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   943
#ifdef VDBE_PROFILE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   944
  {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   945
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   946
    for(i=0; i<p->nOp; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   947
      p->aOp[i].cnt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   948
      p->aOp[i].cycles = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   949
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   950
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   951
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   952
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   953
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   954
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   955
** Close a VDBE cursor and release all the resources that cursor happens
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   956
** to hold.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   957
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   958
void sqlite3VdbeFreeCursor(Vdbe *p, Cursor *pCx){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   959
  if( pCx==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   960
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   961
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   962
  if( pCx->pCursor ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   963
    sqlite3BtreeCloseCursor(pCx->pCursor);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   964
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   965
  if( pCx->pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   966
    sqlite3BtreeClose(pCx->pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   967
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   968
#ifndef SQLITE_OMIT_VIRTUALTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   969
  if( pCx->pVtabCursor ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   970
    sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   971
    const sqlite3_module *pModule = pCx->pModule;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   972
    p->inVtabMethod = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   973
    sqlite3SafetyOff(p->db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   974
    pModule->xClose(pVtabCursor);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   975
    sqlite3SafetyOn(p->db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   976
    p->inVtabMethod = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   977
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   978
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   979
  sqlite3_free(pCx->pData);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   980
  sqlite3_free(pCx->aType);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   981
  sqlite3_free(pCx);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   982
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   983
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   984
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   985
** Close all cursors except for VTab cursors that are currently
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   986
** in use.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   987
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   988
static void closeAllCursorsExceptActiveVtabs(Vdbe *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   989
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   990
  if( p->apCsr==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   991
  for(i=0; i<p->nCursor; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   992
    Cursor *pC = p->apCsr[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   993
    if( pC && (!p->inVtabMethod || !pC->pVtabCursor) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   994
      sqlite3VdbeFreeCursor(p, pC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   995
      p->apCsr[i] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   996
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   997
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   998
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   999
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1000
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1001
** Clean up the VM after execution.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1002
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1003
** This routine will automatically close any cursors, lists, and/or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1004
** sorters that were left open.  It also deletes the values of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1005
** variables in the aVar[] array.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1006
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1007
static void Cleanup(Vdbe *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1008
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1009
  if( p->aStack ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1010
    releaseMemArray(p->aStack, 1 + (p->pTos - p->aStack));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1011
    p->pTos = &p->aStack[-1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1012
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1013
  closeAllCursorsExceptActiveVtabs(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1014
  releaseMemArray(p->aMem, p->nMem);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1015
  sqlite3VdbeFifoClear(&p->sFifo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1016
  if( p->contextStack ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1017
    for(i=0; i<p->contextStackTop; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1018
      sqlite3VdbeFifoClear(&p->contextStack[i].sFifo);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1019
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1020
    sqlite3_free(p->contextStack);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1021
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1022
  p->contextStack = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1023
  p->contextStackDepth = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1024
  p->contextStackTop = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1025
  sqlite3_free(p->zErrMsg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1026
  p->zErrMsg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1027
  p->resOnStack = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1028
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1029
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1030
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1031
** Set the number of result columns that will be returned by this SQL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1032
** statement. This is now set at compile time, rather than during
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1033
** execution of the vdbe program so that sqlite3_column_count() can
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1034
** be called on an SQL statement before sqlite3_step().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1035
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1036
void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1037
  Mem *pColName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1038
  int n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1039
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1040
  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1041
  sqlite3_free(p->aColName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1042
  n = nResColumn*COLNAME_N;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1043
  p->nResColumn = nResColumn;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1044
  p->aColName = pColName = (Mem*)sqlite3DbMallocZero(p->db, sizeof(Mem)*n );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1045
  if( p->aColName==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1046
  while( n-- > 0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1047
    pColName->flags = MEM_Null;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1048
    pColName->db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1049
    pColName++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1050
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1051
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1052
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1053
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1054
** Set the name of the idx'th column to be returned by the SQL statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1055
** zName must be a pointer to a nul terminated string.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1056
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1057
** This call must be made after a call to sqlite3VdbeSetNumCols().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1058
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1059
** If N==P3_STATIC  it means that zName is a pointer to a constant static
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1060
** string and we can just copy the pointer. If it is P3_DYNAMIC, then 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1061
** the string is freed using sqlite3_free() when the vdbe is finished with
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1062
** it. Otherwise, N bytes of zName are copied.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1063
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1064
int sqlite3VdbeSetColName(Vdbe *p, int idx, int var, const char *zName, int N){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1065
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1066
  Mem *pColName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1067
  assert( idx<p->nResColumn );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1068
  assert( var<COLNAME_N );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1069
  if( p->db->mallocFailed ) return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1070
  assert( p->aColName!=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1071
  pColName = &(p->aColName[idx+var*p->nResColumn]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1072
  if( N==P3_DYNAMIC || N==P3_STATIC ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1073
    rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1074
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1075
    rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1076
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1077
  if( rc==SQLITE_OK && N==P3_DYNAMIC ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1078
    pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1079
    pColName->xDel = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1080
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1081
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1082
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1083
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1084
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1085
** A read or write transaction may or may not be active on database handle
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1086
** db. If a transaction is active, commit it. If there is a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1087
** write-transaction spanning more than one database file, this routine
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1088
** takes care of the master journal trickery.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1089
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1090
static int vdbeCommit(sqlite3 *db){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1091
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1092
  int nTrans = 0;  /* Number of databases with an active write-transaction */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1093
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1094
  int needXcommit = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1095
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1096
  /* Before doing anything else, call the xSync() callback for any
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1097
  ** virtual module tables written in this transaction. This has to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1098
  ** be done before determining whether a master journal file is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1099
  ** required, as an xSync() callback may add an attached database
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1100
  ** to the transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1101
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1102
  rc = sqlite3VtabSync(db, rc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1103
  if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1104
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1105
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1106
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1107
  /* This loop determines (a) if the commit hook should be invoked and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1108
  ** (b) how many database files have open write transactions, not 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1109
  ** including the temp database. (b) is important because if more than 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1110
  ** one database file has an open write transaction, a master journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1111
  ** file is required for an atomic commit.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1112
  */ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1113
  for(i=0; i<db->nDb; i++){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1114
    Btree *pBt = db->aDb[i].pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1115
    if( sqlite3BtreeIsInTrans(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1116
      needXcommit = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1117
      if( i!=1 ) nTrans++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1118
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1119
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1120
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1121
  /* If there are any write-transactions at all, invoke the commit hook */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1122
  if( needXcommit && db->xCommitCallback ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1123
    sqlite3SafetyOff(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1124
    rc = db->xCommitCallback(db->pCommitArg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1125
    sqlite3SafetyOn(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1126
    if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1127
      return SQLITE_CONSTRAINT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1128
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1129
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1130
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1131
  /* The simple case - no more than one database file (not counting the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1132
  ** TEMP database) has a transaction active.   There is no need for the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1133
  ** master-journal.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1134
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1135
  ** If the return value of sqlite3BtreeGetFilename() is a zero length
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1136
  ** string, it means the main database is :memory:.  In that case we do
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1137
  ** not support atomic multi-file commits, so use the simple case then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1138
  ** too.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1139
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1140
  if( 0==strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt)) || nTrans<=1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1141
    for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1142
      Btree *pBt = db->aDb[i].pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1143
      if( pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1144
        rc = sqlite3BtreeCommitPhaseOne(pBt, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1145
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1146
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1147
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1148
    /* Do the commit only if all databases successfully complete phase 1. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1149
    ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1150
    ** IO error while deleting or truncating a journal file. It is unlikely,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1151
    ** but could happen. In this case abandon processing and return the error.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1152
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1153
    for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1154
      Btree *pBt = db->aDb[i].pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1155
      if( pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1156
        rc = sqlite3BtreeCommitPhaseTwo(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1157
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1158
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1159
    if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1160
      sqlite3VtabCommit(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1161
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1162
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1163
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1164
  /* The complex case - There is a multi-file write-transaction active.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1165
  ** This requires a master journal file to ensure the transaction is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1166
  ** committed atomicly.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1167
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1168
#ifndef SQLITE_OMIT_DISKIO
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1169
  else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1170
    sqlite3_vfs *pVfs = db->pVfs;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1171
    int needSync = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1172
    char *zMaster = 0;   /* File-name for the master journal */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1173
    char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1174
    sqlite3_file *pMaster = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1175
    i64 offset = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1176
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1177
    /* Select a master journal file name */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1178
    do {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1179
      u32 random;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1180
      sqlite3_free(zMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1181
      sqlite3Randomness(sizeof(random), &random);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1182
      zMaster = sqlite3MPrintf(db, "%s-mj%08X", zMainFile, random&0x7fffffff);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1183
      if( !zMaster ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1184
        return SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1185
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1186
    }while( sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1187
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1188
    /* Open the master journal. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1189
    rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1190
        SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1191
        SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1192
    );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1193
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1194
      sqlite3_free(zMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1195
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1196
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1197
 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1198
    /* Write the name of each database file in the transaction into the new
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1199
    ** master journal file. If an error occurs at this point close
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1200
    ** and delete the master journal file. All the individual journal files
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1201
    ** still have 'null' as the master journal pointer, so they will roll
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1202
    ** back independently if a failure occurs.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1203
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1204
    for(i=0; i<db->nDb; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1205
      Btree *pBt = db->aDb[i].pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1206
      if( i==1 ) continue;   /* Ignore the TEMP database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1207
      if( sqlite3BtreeIsInTrans(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1208
        char const *zFile = sqlite3BtreeGetJournalname(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1209
        if( zFile[0]==0 ) continue;  /* Ignore :memory: databases */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1210
        if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1211
          needSync = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1212
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1213
        rc = sqlite3OsWrite(pMaster, zFile, strlen(zFile)+1, offset);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1214
        offset += strlen(zFile)+1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1215
        if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1216
          sqlite3OsCloseFree(pMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1217
          sqlite3OsDelete(pVfs, zMaster, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1218
          sqlite3_free(zMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1219
          return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1220
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1221
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1222
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1223
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1224
    /* Sync the master journal file. If the IOCAP_SEQUENTIAL device
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1225
    ** flag is set this is not required.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1226
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1227
    zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1228
    if( (needSync 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1229
     && (0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1230
     && (rc=sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))!=SQLITE_OK) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1231
      sqlite3OsCloseFree(pMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1232
      sqlite3OsDelete(pVfs, zMaster, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1233
      sqlite3_free(zMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1234
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1235
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1236
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1237
    /* Sync all the db files involved in the transaction. The same call
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1238
    ** sets the master journal pointer in each individual journal. If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1239
    ** an error occurs here, do not delete the master journal file.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1240
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1241
    ** If the error occurs during the first call to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1242
    ** sqlite3BtreeCommitPhaseOne(), then there is a chance that the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1243
    ** master journal file will be orphaned. But we cannot delete it,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1244
    ** in case the master journal file name was written into the journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1245
    ** file before the failure occured.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1246
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1247
    for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1248
      Btree *pBt = db->aDb[i].pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1249
      if( pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1250
        rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1251
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1252
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1253
    sqlite3OsCloseFree(pMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1254
    if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1255
      sqlite3_free(zMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1256
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1257
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1258
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1259
    /* Delete the master journal file. This commits the transaction. After
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1260
    ** doing this the directory is synced again before any individual
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1261
    ** transaction files are deleted.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1262
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1263
    rc = sqlite3OsDelete(pVfs, zMaster, 1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1264
    sqlite3_free(zMaster);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1265
    zMaster = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1266
    if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1267
      return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1268
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1269
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1270
    /* All files and directories have already been synced, so the following
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1271
    ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1272
    ** deleting or truncating journals. If something goes wrong while
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1273
    ** this is happening we don't really care. The integrity of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1274
    ** transaction is already guaranteed, but some stray 'cold' journals
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1275
    ** may be lying around. Returning an error code won't help matters.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1276
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1277
    disable_simulated_io_errors();
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1278
    for(i=0; i<db->nDb; i++){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1279
      Btree *pBt = db->aDb[i].pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1280
      if( pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1281
        sqlite3BtreeCommitPhaseTwo(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1282
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1283
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1284
    enable_simulated_io_errors();
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1285
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1286
    sqlite3VtabCommit(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1287
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1288
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1289
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1290
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1291
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1292
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1293
/* 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1294
** This routine checks that the sqlite3.activeVdbeCnt count variable
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1295
** matches the number of vdbe's in the list sqlite3.pVdbe that are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1296
** currently active. An assertion fails if the two counts do not match.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1297
** This is an internal self-check only - it is not an essential processing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1298
** step.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1299
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1300
** This is a no-op if NDEBUG is defined.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1301
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1302
#ifndef NDEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1303
static void checkActiveVdbeCnt(sqlite3 *db){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1304
  Vdbe *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1305
  int cnt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1306
  p = db->pVdbe;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1307
  while( p ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1308
    if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1309
      cnt++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1310
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1311
    p = p->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1312
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1313
  assert( cnt==db->activeVdbeCnt );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1314
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1315
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1316
#define checkActiveVdbeCnt(x)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1317
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1318
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1319
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1320
** For every Btree that in database connection db which 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1321
** has been modified, "trip" or invalidate each cursor in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1322
** that Btree might have been modified so that the cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1323
** can never be used again.  This happens when a rollback
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1324
*** occurs.  We have to trip all the other cursors, even
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1325
** cursor from other VMs in different database connections,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1326
** so that none of them try to use the data at which they
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1327
** were pointing and which now may have been changed due
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1328
** to the rollback.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1329
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1330
** Remember that a rollback can delete tables complete and
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1331
** reorder rootpages.  So it is not sufficient just to save
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1332
** the state of the cursor.  We have to invalidate the cursor
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1333
** so that it is never used again.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1334
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1335
static void invalidateCursorsOnModifiedBtrees(sqlite3 *db){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1336
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1337
  for(i=0; i<db->nDb; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1338
    Btree *p = db->aDb[i].pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1339
    if( p && sqlite3BtreeIsInTrans(p) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1340
      sqlite3BtreeTripAllCursors(p, SQLITE_ABORT);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1341
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1342
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1343
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1344
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1345
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1346
** This routine is called the when a VDBE tries to halt.  If the VDBE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1347
** has made changes and is in autocommit mode, then commit those
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1348
** changes.  If a rollback is needed, then do the rollback.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1349
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1350
** This routine is the only way to move the state of a VM from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1351
** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT.  It is harmless to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1352
** call this on a VM that is in the SQLITE_MAGIC_HALT state.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1353
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1354
** Return an error code.  If the commit could not complete because of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1355
** lock contention, return SQLITE_BUSY.  If SQLITE_BUSY is returned, it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1356
** means the close did not happen and needs to be repeated.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1357
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1358
int sqlite3VdbeHalt(Vdbe *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1359
  sqlite3 *db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1360
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1361
  int (*xFunc)(Btree *pBt) = 0;  /* Function to call on each btree backend */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1362
  int isSpecialError;            /* Set to true if SQLITE_NOMEM or IOERR */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1363
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1364
  /* This function contains the logic that determines if a statement or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1365
  ** transaction will be committed or rolled back as a result of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1366
  ** execution of this virtual machine. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1367
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1368
  ** If any of the following errors occur:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1369
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1370
  **     SQLITE_NOMEM
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1371
  **     SQLITE_IOERR
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1372
  **     SQLITE_FULL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1373
  **     SQLITE_INTERRUPT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1374
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1375
  ** Then the internal cache might have been left in an inconsistent
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1376
  ** state.  We need to rollback the statement transaction, if there is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1377
  ** one, or the complete transaction if there is no statement transaction.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1378
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1379
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1380
  if( p->db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1381
    p->rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1382
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1383
  closeAllCursorsExceptActiveVtabs(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1384
  if( p->magic!=VDBE_MAGIC_RUN ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1385
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1386
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1387
  checkActiveVdbeCnt(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1388
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1389
  /* No commit or rollback needed if the program never started */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1390
  if( p->pc>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1391
    int mrc;   /* Primary error code from p->rc */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1392
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1393
    /* Lock all btrees used by the statement */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1394
    sqlite3BtreeMutexArrayEnter(&p->aMutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1395
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1396
    /* Check for one of the special errors */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1397
    mrc = p->rc & 0xff;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1398
    isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1399
                     || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1400
    if( isSpecialError ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1401
      /* This loop does static analysis of the query to see which of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1402
      ** following three categories it falls into:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1403
      **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1404
      **     Read-only
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1405
      **     Query with statement journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1406
      **     Query without statement journal
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1407
      **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1408
      ** We could do something more elegant than this static analysis (i.e.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1409
      ** store the type of query as part of the compliation phase), but 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1410
      ** handling malloc() or IO failure is a fairly obscure edge case so 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1411
      ** this is probably easier. Todo: Might be an opportunity to reduce 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1412
      ** code size a very small amount though...
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1413
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1414
      int notReadOnly = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1415
      int isStatement = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1416
      assert(p->aOp || p->nOp==0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1417
      for(i=0; i<p->nOp; i++){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1418
        switch( p->aOp[i].opcode ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1419
          case OP_Transaction:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1420
            notReadOnly |= p->aOp[i].p2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1421
            break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1422
          case OP_Statement:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1423
            isStatement = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1424
            break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1425
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1426
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1427
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1428
   
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1429
      /* If the query was read-only, we need do no rollback at all. Otherwise,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1430
      ** proceed with the special handling.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1431
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1432
      if( notReadOnly || mrc!=SQLITE_INTERRUPT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1433
        if( p->rc==SQLITE_IOERR_BLOCKED && isStatement ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1434
          xFunc = sqlite3BtreeRollbackStmt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1435
          p->rc = SQLITE_BUSY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1436
        } else if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && isStatement ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1437
          xFunc = sqlite3BtreeRollbackStmt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1438
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1439
          /* We are forced to roll back the active transaction. Before doing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1440
          ** so, abort any other statements this handle currently has active.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1441
          */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1442
          invalidateCursorsOnModifiedBtrees(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1443
          sqlite3RollbackAll(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1444
          db->autoCommit = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1445
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1446
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1447
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1448
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1449
    /* If the auto-commit flag is set and this is the only active vdbe, then
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1450
    ** we do either a commit or rollback of the current transaction. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1451
    **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1452
    ** Note: This block also runs if one of the special errors handled 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1453
    ** above has occured. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1454
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1455
    if( db->autoCommit && db->activeVdbeCnt==1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1456
      if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1457
        /* The auto-commit flag is true, and the vdbe program was 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1458
        ** successful or hit an 'OR FAIL' constraint. This means a commit 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1459
        ** is required.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1460
        */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1461
        int rc = vdbeCommit(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1462
        if( rc==SQLITE_BUSY ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1463
          sqlite3BtreeMutexArrayLeave(&p->aMutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1464
          return SQLITE_BUSY;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1465
        }else if( rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1466
          p->rc = rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1467
          sqlite3RollbackAll(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1468
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1469
          sqlite3CommitInternalChanges(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1470
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1471
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1472
        sqlite3RollbackAll(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1473
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1474
    }else if( !xFunc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1475
      if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1476
        if( p->openedStatement ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1477
          xFunc = sqlite3BtreeCommitStmt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1478
        } 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1479
      }else if( p->errorAction==OE_Abort ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1480
        xFunc = sqlite3BtreeRollbackStmt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1481
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1482
        invalidateCursorsOnModifiedBtrees(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1483
        sqlite3RollbackAll(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1484
        db->autoCommit = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1485
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1486
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1487
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1488
    /* If xFunc is not NULL, then it is one of sqlite3BtreeRollbackStmt or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1489
    ** sqlite3BtreeCommitStmt. Call it once on each backend. If an error occurs
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1490
    ** and the return code is still SQLITE_OK, set the return code to the new
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1491
    ** error value.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1492
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1493
    assert(!xFunc ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1494
      xFunc==sqlite3BtreeCommitStmt ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1495
      xFunc==sqlite3BtreeRollbackStmt
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1496
    );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1497
    for(i=0; xFunc && i<db->nDb; i++){ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1498
      int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1499
      Btree *pBt = db->aDb[i].pBt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1500
      if( pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1501
        rc = xFunc(pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1502
        if( rc && (p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1503
          p->rc = rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1504
          sqlite3SetString(&p->zErrMsg, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1505
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1506
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1507
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1508
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1509
    /* If this was an INSERT, UPDATE or DELETE and the statement was committed, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1510
    ** set the change counter. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1511
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1512
    if( p->changeCntOn && p->pc>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1513
      if( !xFunc || xFunc==sqlite3BtreeCommitStmt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1514
        sqlite3VdbeSetChanges(db, p->nChange);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1515
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1516
        sqlite3VdbeSetChanges(db, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1517
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1518
      p->nChange = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1519
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1520
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1521
    /* Rollback or commit any schema changes that occurred. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1522
    if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1523
      sqlite3ResetInternalSchema(db, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1524
      db->flags = (db->flags | SQLITE_InternChanges);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1525
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1526
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1527
    /* Release the locks */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1528
    sqlite3BtreeMutexArrayLeave(&p->aMutex);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1529
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1530
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1531
  /* We have successfully halted and closed the VM.  Record this fact. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1532
  if( p->pc>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1533
    db->activeVdbeCnt--;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1534
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1535
  p->magic = VDBE_MAGIC_HALT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1536
  checkActiveVdbeCnt(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1537
  if( p->db->mallocFailed ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1538
    p->rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1539
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1540
  checkActiveVdbeCnt(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1541
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1542
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1543
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1544
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1545
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1546
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1547
** Each VDBE holds the result of the most recent sqlite3_step() call
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1548
** in p->rc.  This routine sets that result back to SQLITE_OK.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1549
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1550
void sqlite3VdbeResetStepResult(Vdbe *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1551
  p->rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1552
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1553
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1554
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1555
** Clean up a VDBE after execution but do not delete the VDBE just yet.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1556
** Write any error messages into *pzErrMsg.  Return the result code.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1557
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1558
** After this routine is run, the VDBE should be ready to be executed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1559
** again.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1560
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1561
** To look at it another way, this routine resets the state of the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1562
** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1563
** VDBE_MAGIC_INIT.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1564
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1565
int sqlite3VdbeReset(Vdbe *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1566
  sqlite3 *db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1567
  db = p->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1568
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1569
  /* If the VM did not run to completion or if it encountered an
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1570
  ** error, then it might not have been halted properly.  So halt
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1571
  ** it now.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1572
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1573
  sqlite3SafetyOn(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1574
  sqlite3VdbeHalt(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1575
  sqlite3SafetyOff(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1576
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1577
  /* If the VDBE has be run even partially, then transfer the error code
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1578
  ** and error message from the VDBE into the main database structure.  But
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1579
  ** if the VDBE has just been set to run but has not actually executed any
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1580
  ** instructions yet, leave the main database error information unchanged.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1581
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1582
  if( p->pc>=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1583
    if( p->zErrMsg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1584
      sqlite3ValueSetStr(db->pErr,-1,p->zErrMsg,SQLITE_UTF8,sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1585
      db->errCode = p->rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1586
      p->zErrMsg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1587
    }else if( p->rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1588
      sqlite3Error(db, p->rc, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1589
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1590
      sqlite3Error(db, SQLITE_OK, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1591
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1592
  }else if( p->rc && p->expired ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1593
    /* The expired flag was set on the VDBE before the first call
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1594
    ** to sqlite3_step(). For consistency (since sqlite3_step() was
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1595
    ** called), set the database error in this case as well.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1596
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1597
    sqlite3Error(db, p->rc, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1598
    sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1599
    p->zErrMsg = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1600
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1601
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1602
  /* Reclaim all memory used by the VDBE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1603
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1604
  Cleanup(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1605
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1606
  /* Save profiling information from this VDBE run.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1607
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1608
  assert( p->pTos<&p->aStack[p->pc<0?0:p->pc] || !p->aStack );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1609
#ifdef VDBE_PROFILE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1610
  {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1611
    FILE *out = fopen("vdbe_profile.out", "a");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1612
    if( out ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1613
      int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1614
      fprintf(out, "---- ");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1615
      for(i=0; i<p->nOp; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1616
        fprintf(out, "%02x", p->aOp[i].opcode);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1617
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1618
      fprintf(out, "\n");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1619
      for(i=0; i<p->nOp; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1620
        fprintf(out, "%6d %10lld %8lld ",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1621
           p->aOp[i].cnt,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1622
           p->aOp[i].cycles,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1623
           p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1624
        );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1625
        sqlite3VdbePrintOp(out, i, &p->aOp[i]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1626
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1627
      fclose(out);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1628
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1629
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1630
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1631
  p->magic = VDBE_MAGIC_INIT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1632
  p->aborted = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1633
  return p->rc & db->errMask;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1634
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1635
 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1636
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1637
** Clean up and delete a VDBE after execution.  Return an integer which is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1638
** the result code.  Write any error message text into *pzErrMsg.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1639
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1640
int sqlite3VdbeFinalize(Vdbe *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1641
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1642
  if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1643
    rc = sqlite3VdbeReset(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1644
    assert( (rc & p->db->errMask)==rc );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1645
  }else if( p->magic!=VDBE_MAGIC_INIT ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1646
    return SQLITE_MISUSE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1647
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1648
  sqlite3VdbeDelete(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1649
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1650
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1651
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1652
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1653
** Call the destructor for each auxdata entry in pVdbeFunc for which
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1654
** the corresponding bit in mask is clear.  Auxdata entries beyond 31
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1655
** are always destroyed.  To destroy all auxdata entries, call this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1656
** routine with mask==0.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1657
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1658
void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1659
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1660
  for(i=0; i<pVdbeFunc->nAux; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1661
	  VdbeFunc::AuxData *pAux = &pVdbeFunc->apAux[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1662
    if( (i>31 || !(mask&(1<<i))) && pAux->pAux ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1663
      if( pAux->xDelete ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1664
        pAux->xDelete(pAux->pAux);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1665
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1666
      pAux->pAux = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1667
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1668
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1669
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1670
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1671
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1672
** Delete an entire VDBE.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1673
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1674
void sqlite3VdbeDelete(Vdbe *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1675
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1676
  if( p==0 ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1677
  Cleanup(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1678
  if( p->pPrev ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1679
    p->pPrev->pNext = p->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1680
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1681
    assert( p->db->pVdbe==p );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1682
    p->db->pVdbe = p->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1683
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1684
  if( p->pNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1685
    p->pNext->pPrev = p->pPrev;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1686
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1687
  if( p->aOp ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1688
    for(i=0; i<p->nOp; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1689
      Op *pOp = &p->aOp[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1690
      freeP3(pOp->p3type, pOp->p3);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1691
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1692
    sqlite3_free(p->aOp);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1693
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1694
  releaseMemArray(p->aVar, p->nVar);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1695
  sqlite3_free(p->aLabel);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1696
  sqlite3_free(p->aStack);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1697
  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1698
  sqlite3_free(p->aColName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1699
  sqlite3_free(p->zSql);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1700
  p->magic = VDBE_MAGIC_DEAD;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1701
  sqlite3_free(p);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1702
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1703
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1704
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1705
** If a MoveTo operation is pending on the given cursor, then do that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1706
** MoveTo now.  Return an error code.  If no MoveTo is pending, this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1707
** routine does nothing and returns SQLITE_OK.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1708
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1709
int sqlite3VdbeCursorMoveto(Cursor *p){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1710
  if( p->deferredMoveto ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1711
    int res, rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1712
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1713
    extern int sqlite3_search_count;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1714
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1715
    assert( p->isTable );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1716
    rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, 0, &res);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1717
    if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1718
    *p->pIncrKey = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1719
    p->lastRowid = keyToInt(p->movetoTarget);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1720
    p->rowidIsValid = res==0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1721
    if( res<0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1722
      rc = sqlite3BtreeNext(p->pCursor, &res);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1723
      if( rc ) return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1724
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1725
#ifdef SQLITE_TEST
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1726
    sqlite3_search_count++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1727
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1728
    p->deferredMoveto = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1729
    p->cacheStatus = CACHE_STALE;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1730
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1731
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1732
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1733
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1734
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1735
** The following functions:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1736
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1737
** sqlite3VdbeSerialType()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1738
** sqlite3VdbeSerialTypeLen()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1739
** sqlite3VdbeSerialRead()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1740
** sqlite3VdbeSerialLen()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1741
** sqlite3VdbeSerialWrite()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1742
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1743
** encapsulate the code that serializes values for storage in SQLite
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1744
** data and index records. Each serialized value consists of a
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1745
** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1746
** integer, stored as a varint.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1747
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1748
** In an SQLite index record, the serial type is stored directly before
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1749
** the blob of data that it corresponds to. In a table record, all serial
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1750
** types are stored at the start of the record, and the blobs of data at
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1751
** the end. Hence these functions allow the caller to handle the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1752
** serial-type and data blob seperately.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1753
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1754
** The following table describes the various storage classes for data:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1755
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1756
**   serial type        bytes of data      type
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1757
**   --------------     ---------------    ---------------
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1758
**      0                     0            NULL
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1759
**      1                     1            signed integer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1760
**      2                     2            signed integer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1761
**      3                     3            signed integer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1762
**      4                     4            signed integer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1763
**      5                     6            signed integer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1764
**      6                     8            signed integer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1765
**      7                     8            IEEE float
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1766
**      8                     0            Integer constant 0
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1767
**      9                     0            Integer constant 1
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1768
**     10,11                               reserved for expansion
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1769
**    N>=12 and even       (N-12)/2        BLOB
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1770
**    N>=13 and odd        (N-13)/2        text
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1771
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1772
** The 8 and 9 types were added in 3.3.0, file format 4.  Prior versions
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1773
** of SQLite will not understand those serial types.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1774
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1775
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1776
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1777
** Return the serial-type for the value stored in pMem.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1778
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1779
u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1780
  int flags = pMem->flags;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1781
  int n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1782
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1783
  if( flags&MEM_Null ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1784
    return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1785
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1786
  if( flags&MEM_Int ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1787
    /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1788
#   define MAX_6BYTE ((((i64)0x00001000)<<32)-1)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1789
    i64 i = pMem->u.i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1790
    u64 u;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1791
    if( file_format>=4 && (i&1)==i ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1792
      return 8+i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1793
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1794
    u = i<0 ? -i : i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1795
    if( u<=127 ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1796
    if( u<=32767 ) return 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1797
    if( u<=8388607 ) return 3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1798
    if( u<=2147483647 ) return 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1799
    if( u<=MAX_6BYTE ) return 5;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1800
    return 6;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1801
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1802
  if( flags&MEM_Real ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1803
    return 7;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1804
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1805
  assert( flags&(MEM_Str|MEM_Blob) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1806
  n = pMem->n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1807
  if( flags & MEM_Zero ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1808
    n += pMem->u.i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1809
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1810
  assert( n>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1811
  return ((n*2) + 12 + ((flags&MEM_Str)!=0));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1812
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1813
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1814
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1815
** Return the length of the data corresponding to the supplied serial-type.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1816
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1817
int sqlite3VdbeSerialTypeLen(u32 serial_type){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1818
  if( serial_type>=12 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1819
    return (serial_type-12)/2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1820
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1821
    static const u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1822
    return aSize[serial_type];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1823
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1824
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1825
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1826
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1827
** If we are on an architecture with mixed-endian floating 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1828
** points (ex: ARM7) then swap the lower 4 bytes with the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1829
** upper 4 bytes.  Return the result.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1830
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1831
** For most architectures, this is a no-op.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1832
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1833
** (later):  It is reported to me that the mixed-endian problem
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1834
** on ARM7 is an issue with GCC, not with the ARM7 chip.  It seems
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1835
** that early versions of GCC stored the two words of a 64-bit
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1836
** float in the wrong order.  And that error has been propagated
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1837
** ever since.  The blame is not necessarily with GCC, though.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1838
** GCC might have just copying the problem from a prior compiler.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1839
** I am also told that newer versions of GCC that follow a different
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1840
** ABI get the byte order right.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1841
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1842
** Developers using SQLite on an ARM7 should compile and run their
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1843
** application using -DSQLITE_DEBUG=1 at least once.  With DEBUG
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1844
** enabled, some asserts below will ensure that the byte order of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1845
** floating point values is correct.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1846
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1847
** (2007-08-30)  Frank van Vugt has studied this problem closely
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1848
** and has send his findings to the SQLite developers.  Frank
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1849
** writes that some Linux kernels offer floating point hardware
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1850
** emulation that uses only 32-bit mantissas instead of a full 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1851
** 48-bits as required by the IEEE standard.  (This is the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1852
** CONFIG_FPE_FASTFPE option.)  On such systems, floating point
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1853
** byte swapping becomes very complicated.  To avoid problems,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1854
** the necessary byte swapping is carried out using a 64-bit integer
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1855
** rather than a 64-bit float.  Frank assures us that the code here
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1856
** works for him.  We, the developers, have no way to independently
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1857
** verify this, but Frank seems to know what he is talking about
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1858
** so we trust him.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1859
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1860
#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1861
static u64 floatSwap(u64 in){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1862
  union {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1863
    u64 r;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1864
    u32 i[2];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1865
  } u;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1866
  u32 t;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1867
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1868
  u.r = in;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1869
  t = u.i[0];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1870
  u.i[0] = u.i[1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1871
  u.i[1] = t;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1872
  return u.r;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1873
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1874
# define swapMixedEndianFloat(X)  X = floatSwap(X)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1875
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1876
# define swapMixedEndianFloat(X)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1877
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1878
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1879
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1880
** Write the serialized data blob for the value stored in pMem into 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1881
** buf. It is assumed that the caller has allocated sufficient space.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1882
** Return the number of bytes written.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1883
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1884
** nBuf is the amount of space left in buf[].  nBuf must always be
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1885
** large enough to hold the entire field.  Except, if the field is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1886
** a blob with a zero-filled tail, then buf[] might be just the right
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1887
** size to hold everything except for the zero-filled tail.  If buf[]
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1888
** is only big enough to hold the non-zero prefix, then only write that
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1889
** prefix into buf[].  But if buf[] is large enough to hold both the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1890
** prefix and the tail then write the prefix and set the tail to all
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1891
** zeros.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1892
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1893
** Return the number of bytes actually written into buf[].  The number
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1894
** of bytes in the zero-filled tail is included in the return value only
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1895
** if those bytes were zeroed in buf[].
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1896
*/ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1897
int sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1898
  u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1899
  int len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1900
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1901
  /* Integer and Real */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1902
  if( serial_type<=7 && serial_type>0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1903
    u64 v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1904
    int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1905
    if( serial_type==7 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1906
      assert( sizeof(v)==sizeof(pMem->r) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1907
      memcpy(&v, &pMem->r, sizeof(v));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1908
      swapMixedEndianFloat(v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1909
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1910
      v = pMem->u.i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1911
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1912
    len = i = sqlite3VdbeSerialTypeLen(serial_type);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1913
    assert( len<=nBuf );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1914
    while( i-- ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1915
      buf[i] = (v&0xFF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1916
      v >>= 8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1917
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1918
    return len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1919
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1920
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1921
  /* String or blob */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1922
  if( serial_type>=12 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1923
    assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.i:0)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1924
             == sqlite3VdbeSerialTypeLen(serial_type) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1925
    assert( pMem->n<=nBuf );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1926
    len = pMem->n;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1927
    memcpy(buf, pMem->z, len);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1928
    if( pMem->flags & MEM_Zero ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1929
      len += pMem->u.i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1930
      if( len>nBuf ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1931
        len = nBuf;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1932
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1933
      memset(&buf[pMem->n], 0, len-pMem->n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1934
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1935
    return len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1936
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1937
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1938
  /* NULL or constants 0 or 1 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1939
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1940
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1941
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1942
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1943
** Deserialize the data blob pointed to by buf as serial type serial_type
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1944
** and store the result in pMem.  Return the number of bytes read.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1945
*/ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1946
int sqlite3VdbeSerialGet(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1947
  const unsigned char *buf,     /* Buffer to deserialize from */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1948
  u32 serial_type,              /* Serial type to deserialize */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1949
  Mem *pMem                     /* Memory cell to write value into */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1950
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1951
  switch( serial_type ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1952
    case 10:   /* Reserved for future use */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1953
    case 11:   /* Reserved for future use */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1954
    case 0: {  /* NULL */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1955
      pMem->flags = MEM_Null;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1956
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1957
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1958
    case 1: { /* 1-byte signed integer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1959
      pMem->u.i = (signed char)buf[0];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1960
      pMem->flags = MEM_Int;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1961
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1962
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1963
    case 2: { /* 2-byte signed integer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1964
      pMem->u.i = (((signed char)buf[0])<<8) | buf[1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1965
      pMem->flags = MEM_Int;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1966
      return 2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1967
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1968
    case 3: { /* 3-byte signed integer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1969
      pMem->u.i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1970
      pMem->flags = MEM_Int;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1971
      return 3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1972
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1973
    case 4: { /* 4-byte signed integer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1974
      pMem->u.i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1975
      pMem->flags = MEM_Int;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1976
      return 4;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1977
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1978
    case 5: { /* 6-byte signed integer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1979
      u64 x = (((signed char)buf[0])<<8) | buf[1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1980
      u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1981
      x = (x<<32) | y;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1982
      pMem->u.i = *(i64*)&x;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1983
      pMem->flags = MEM_Int;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1984
      return 6;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1985
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1986
    case 6:   /* 8-byte signed integer */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1987
    case 7: { /* IEEE floating point */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1988
      u64 x;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1989
      u32 y;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1990
#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1991
      /* Verify that integers and floating point values use the same
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1992
      ** byte order.  Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1993
      ** defined that 64-bit floating point values really are mixed
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1994
      ** endian.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1995
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1996
      static const u64 t1 = ((u64)0x3ff00000)<<32;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1997
      static const double r1 = 1.0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1998
      u64 t2 = t1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  1999
      swapMixedEndianFloat(t2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2000
      assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2001
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2002
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2003
      x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2004
      y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2005
      x = (x<<32) | y;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2006
      if( serial_type==6 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2007
        pMem->u.i = *(i64*)&x;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2008
        pMem->flags = MEM_Int;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2009
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2010
        assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2011
        swapMixedEndianFloat(x);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2012
        memcpy(&pMem->r, &x, sizeof(x));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2013
        pMem->flags = MEM_Real;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2014
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2015
      return 8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2016
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2017
    case 8:    /* Integer 0 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2018
    case 9: {  /* Integer 1 */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2019
      pMem->u.i = serial_type-8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2020
      pMem->flags = MEM_Int;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2021
      return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2022
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2023
    default: {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2024
      int len = (serial_type-12)/2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2025
      pMem->z = (char *)buf;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2026
      pMem->n = len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2027
      pMem->xDel = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2028
      if( serial_type&0x01 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2029
        pMem->flags = MEM_Str | MEM_Ephem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2030
      }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2031
        pMem->flags = MEM_Blob | MEM_Ephem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2032
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2033
      return len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2034
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2035
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2036
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2037
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2038
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2039
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2040
** The header of a record consists of a sequence variable-length integers.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2041
** These integers are almost always small and are encoded as a single byte.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2042
** The following macro takes advantage this fact to provide a fast decode
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2043
** of the integers in a record header.  It is faster for the common case
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2044
** where the integer is a single byte.  It is a little slower when the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2045
** integer is two or more bytes.  But overall it is faster.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2046
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2047
** The following expressions are equivalent:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2048
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2049
**     x = sqlite3GetVarint32( A, &B );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2050
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2051
**     x = GetVarint( A, B );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2052
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2053
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2054
#define GetVarint(A,B)  ((B = *(A))<=0x7f ? 1 : sqlite3GetVarint32(A, &B))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2055
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2056
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2057
** This function compares the two table rows or index records specified by 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2058
** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2059
** or positive integer if {nKey1, pKey1} is less than, equal to or 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2060
** greater than {nKey2, pKey2}.  Both Key1 and Key2 must be byte strings
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2061
** composed by the OP_MakeRecord opcode of the VDBE.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2062
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2063
int sqlite3VdbeRecordCompare(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2064
  void *userData,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2065
  int nKey1, const void *pKey1, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2066
  int nKey2, const void *pKey2
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2067
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2068
  KeyInfo *pKeyInfo = (KeyInfo*)userData;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2069
  u32 d1, d2;          /* Offset into aKey[] of next data element */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2070
  u32 idx1, idx2;      /* Offset into aKey[] of next header element */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2071
  u32 szHdr1, szHdr2;  /* Number of bytes in header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2072
  int i = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2073
  int nField;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2074
  int rc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2075
  const unsigned char *aKey1 = (const unsigned char *)pKey1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2076
  const unsigned char *aKey2 = (const unsigned char *)pKey2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2077
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2078
  Mem mem1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2079
  Mem mem2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2080
  mem1.enc = pKeyInfo->enc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2081
  mem1.db = pKeyInfo->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2082
  mem2.enc = pKeyInfo->enc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2083
  mem2.db = pKeyInfo->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2084
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2085
  idx1 = GetVarint(aKey1, szHdr1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2086
  d1 = szHdr1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2087
  idx2 = GetVarint(aKey2, szHdr2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2088
  d2 = szHdr2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2089
  nField = pKeyInfo->nField;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2090
  while( idx1<szHdr1 && idx2<szHdr2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2091
    u32 serial_type1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2092
    u32 serial_type2;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2093
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2094
    /* Read the serial types for the next element in each key. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2095
    idx1 += GetVarint( aKey1+idx1, serial_type1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2096
    if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2097
    idx2 += GetVarint( aKey2+idx2, serial_type2 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2098
    if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2099
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2100
    /* Extract the values to be compared.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2101
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2102
    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2103
    d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2104
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2105
    /* Do the comparison
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2106
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2107
    rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2108
    if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2109
    if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2110
    if( rc!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2111
      break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2112
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2113
    i++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2114
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2115
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2116
  /* One of the keys ran out of fields, but all the fields up to that point
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2117
  ** were equal. If the incrKey flag is true, then the second key is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2118
  ** treated as larger.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2119
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2120
  if( rc==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2121
    if( pKeyInfo->incrKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2122
      rc = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2123
    }else if( !pKeyInfo->prefixIsEqual ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2124
      if( d1<nKey1 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2125
        rc = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2126
      }else if( d2<nKey2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2127
        rc = -1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2128
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2129
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2130
  }else if( pKeyInfo->aSortOrder && i<pKeyInfo->nField
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2131
               && pKeyInfo->aSortOrder[i] ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2132
    rc = -rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2133
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2134
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2135
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2136
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2137
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2138
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2139
** The argument is an index entry composed using the OP_MakeRecord opcode.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2140
** The last entry in this record should be an integer (specifically
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2141
** an integer rowid).  This routine returns the number of bytes in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2142
** that integer.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2143
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2144
int sqlite3VdbeIdxRowidLen(const u8 *aKey){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2145
  u32 szHdr;        /* Size of the header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2146
  u32 typeRowid;    /* Serial type of the rowid */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2147
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2148
  sqlite3GetVarint32(aKey, &szHdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2149
  sqlite3GetVarint32(&aKey[szHdr-1], &typeRowid);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2150
  return sqlite3VdbeSerialTypeLen(typeRowid);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2151
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2152
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2153
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2154
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2155
** pCur points at an index entry created using the OP_MakeRecord opcode.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2156
** Read the rowid (the last field in the record) and store it in *rowid.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2157
** Return SQLITE_OK if everything works, or an error code otherwise.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2158
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2159
int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2160
  i64 nCellKey = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2161
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2162
  u32 szHdr;        /* Size of the header */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2163
  u32 typeRowid;    /* Serial type of the rowid */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2164
  u32 lenRowid;     /* Size of the rowid */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2165
  Mem m, v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2166
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2167
  sqlite3BtreeKeySize(pCur, &nCellKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2168
  if( nCellKey<=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2169
    return SQLITE_CORRUPT_BKPT;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2170
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2171
  rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2172
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2173
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2174
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2175
  sqlite3GetVarint32((u8*)m.z, &szHdr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2176
  sqlite3GetVarint32((u8*)&m.z[szHdr-1], &typeRowid);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2177
  lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2178
  sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2179
  *rowid = v.u.i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2180
  sqlite3VdbeMemRelease(&m);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2181
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2182
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2183
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2184
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2185
** Compare the key of the index entry that cursor pC is point to against
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2186
** the key string in pKey (of length nKey).  Write into *pRes a number
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2187
** that is negative, zero, or positive if pC is less than, equal to,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2188
** or greater than pKey.  Return SQLITE_OK on success.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2189
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2190
** pKey is either created without a rowid or is truncated so that it
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2191
** omits the rowid at the end.  The rowid at the end of the index entry
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2192
** is ignored as well.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2193
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2194
int sqlite3VdbeIdxKeyCompare(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2195
  Cursor *pC,                 /* The cursor to compare against */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2196
  int nKey, const u8 *pKey,   /* The key to compare */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2197
  int *res                    /* Write the comparison result here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2198
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2199
  i64 nCellKey = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2200
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2201
  BtCursor *pCur = pC->pCursor;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2202
  int lenRowid;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2203
  Mem m;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2204
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2205
  sqlite3BtreeKeySize(pCur, &nCellKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2206
  if( nCellKey<=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2207
    *res = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2208
    return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2209
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2210
  rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2211
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2212
    return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2213
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2214
  lenRowid = sqlite3VdbeIdxRowidLen((u8*)m.z);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2215
  *res = sqlite3VdbeRecordCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2216
  sqlite3VdbeMemRelease(&m);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2217
  return SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2218
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2219
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2220
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2221
** This routine sets the value to be returned by subsequent calls to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2222
** sqlite3_changes() on the database handle 'db'. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2223
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2224
void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2225
  assert( sqlite3_mutex_held(db->mutex) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2226
  db->nChange = nChange;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2227
  db->nTotalChange += nChange;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2228
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2229
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2230
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2231
** Set a flag in the vdbe to update the change counter when it is finalised
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2232
** or reset.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2233
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2234
void sqlite3VdbeCountChanges(Vdbe *v){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2235
  v->changeCntOn = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2236
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2237
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2238
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2239
** Mark every prepared statement associated with a database connection
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2240
** as expired.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2241
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2242
** An expired statement means that recompilation of the statement is
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2243
** recommend.  Statements expire when things happen that make their
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2244
** programs obsolete.  Removing user-defined functions or collating
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2245
** sequences, or changing an authorization function are the types of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2246
** things that make prepared statements obsolete.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2247
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2248
void sqlite3ExpirePreparedStatements(sqlite3 *db){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2249
  Vdbe *p;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2250
  for(p = db->pVdbe; p; p=p->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2251
    p->expired = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2252
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2253
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2254
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2255
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2256
** Return the database associated with the Vdbe.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2257
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2258
sqlite3 *sqlite3VdbeDb(Vdbe *v){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2259
  return v->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
  2260
}