xref: /illumos-gate/usr/src/lib/libsqlite/src/vdbe.c (revision 55fea89d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate ** 2001 September 15
87c478bd9Sstevel@tonic-gate **
97c478bd9Sstevel@tonic-gate ** The author disclaims copyright to this source code.  In place of
107c478bd9Sstevel@tonic-gate ** a legal notice, here is a blessing:
117c478bd9Sstevel@tonic-gate **
127c478bd9Sstevel@tonic-gate **    May you do good and not evil.
137c478bd9Sstevel@tonic-gate **    May you find forgiveness for yourself and forgive others.
147c478bd9Sstevel@tonic-gate **    May you share freely, never taking more than you give.
157c478bd9Sstevel@tonic-gate **
167c478bd9Sstevel@tonic-gate *************************************************************************
17*55fea89dSDan Cross ** The code in this file implements execution method of the
187c478bd9Sstevel@tonic-gate ** Virtual Database Engine (VDBE).  A separate file ("vdbeaux.c")
197c478bd9Sstevel@tonic-gate ** handles housekeeping details such as creating and deleting
207c478bd9Sstevel@tonic-gate ** VDBE instances.  This file is solely interested in executing
217c478bd9Sstevel@tonic-gate ** the VDBE program.
227c478bd9Sstevel@tonic-gate **
237c478bd9Sstevel@tonic-gate ** In the external interface, an "sqlite_vm*" is an opaque pointer
247c478bd9Sstevel@tonic-gate ** to a VDBE.
257c478bd9Sstevel@tonic-gate **
267c478bd9Sstevel@tonic-gate ** The SQL parser generates a program which is then executed by
27*55fea89dSDan Cross ** the VDBE to do the work of the SQL statement.  VDBE programs are
287c478bd9Sstevel@tonic-gate ** similar in form to assembly language.  The program consists of
29*55fea89dSDan Cross ** a linear sequence of operations.  Each operation has an opcode
30*55fea89dSDan Cross ** and 3 operands.  Operands P1 and P2 are integers.  Operand P3
317c478bd9Sstevel@tonic-gate ** is a null-terminated string.   The P2 operand must be non-negative.
327c478bd9Sstevel@tonic-gate ** Opcodes will typically ignore one or more operands.  Many opcodes
337c478bd9Sstevel@tonic-gate ** ignore all three operands.
347c478bd9Sstevel@tonic-gate **
357c478bd9Sstevel@tonic-gate ** Computation results are stored on a stack.  Each entry on the
367c478bd9Sstevel@tonic-gate ** stack is either an integer, a null-terminated string, a floating point
377c478bd9Sstevel@tonic-gate ** number, or the SQL "NULL" value.  An inplicit conversion from one
387c478bd9Sstevel@tonic-gate ** type to the other occurs as necessary.
39*55fea89dSDan Cross **
407c478bd9Sstevel@tonic-gate ** Most of the code in this file is taken up by the sqliteVdbeExec()
417c478bd9Sstevel@tonic-gate ** function which does the work of interpreting a VDBE program.
427c478bd9Sstevel@tonic-gate ** But other routines are also provided to help in building up
437c478bd9Sstevel@tonic-gate ** a program instruction by instruction.
447c478bd9Sstevel@tonic-gate **
457c478bd9Sstevel@tonic-gate ** Various scripts scan this source file in order to generate HTML
467c478bd9Sstevel@tonic-gate ** documentation, headers files, or other derived files.  The formatting
477c478bd9Sstevel@tonic-gate ** of the code in this file is, therefore, important.  See other comments
487c478bd9Sstevel@tonic-gate ** in this file for details.  If in doubt, do not deviate from existing
497c478bd9Sstevel@tonic-gate ** commenting and indentation practices when changing or adding code.
507c478bd9Sstevel@tonic-gate **
517c478bd9Sstevel@tonic-gate ** $Id: vdbe.c,v 1.268.2.3 2004/07/19 19:30:50 drh Exp $
527c478bd9Sstevel@tonic-gate */
537c478bd9Sstevel@tonic-gate #include "sqliteInt.h"
547c478bd9Sstevel@tonic-gate #include "os.h"
557c478bd9Sstevel@tonic-gate #include <ctype.h>
567c478bd9Sstevel@tonic-gate #include "vdbeInt.h"
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate /*
597c478bd9Sstevel@tonic-gate ** The following global variable is incremented every time a cursor
607c478bd9Sstevel@tonic-gate ** moves, either by the OP_MoveTo or the OP_Next opcode.  The test
617c478bd9Sstevel@tonic-gate ** procedures use this information to make sure that indices are
627c478bd9Sstevel@tonic-gate ** working correctly.  This variable has no function other than to
637c478bd9Sstevel@tonic-gate ** help verify the correct operation of the library.
647c478bd9Sstevel@tonic-gate */
657c478bd9Sstevel@tonic-gate int sqlite_search_count = 0;
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate /*
687c478bd9Sstevel@tonic-gate ** When this global variable is positive, it gets decremented once before
697c478bd9Sstevel@tonic-gate ** each instruction in the VDBE.  When reaches zero, the SQLITE_Interrupt
707c478bd9Sstevel@tonic-gate ** of the db.flags field is set in order to simulate an interrupt.
717c478bd9Sstevel@tonic-gate **
727c478bd9Sstevel@tonic-gate ** This facility is used for testing purposes only.  It does not function
737c478bd9Sstevel@tonic-gate ** in an ordinary build.
747c478bd9Sstevel@tonic-gate */
757c478bd9Sstevel@tonic-gate int sqlite_interrupt_count = 0;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate /*
787c478bd9Sstevel@tonic-gate ** Advance the virtual machine to the next output row.
797c478bd9Sstevel@tonic-gate **
80*55fea89dSDan Cross ** The return vale will be either SQLITE_BUSY, SQLITE_DONE,
817c478bd9Sstevel@tonic-gate ** SQLITE_ROW, SQLITE_ERROR, or SQLITE_MISUSE.
827c478bd9Sstevel@tonic-gate **
837c478bd9Sstevel@tonic-gate ** SQLITE_BUSY means that the virtual machine attempted to open
847c478bd9Sstevel@tonic-gate ** a locked database and there is no busy callback registered.
857c478bd9Sstevel@tonic-gate ** Call sqlite_step() again to retry the open.  *pN is set to 0
867c478bd9Sstevel@tonic-gate ** and *pazColName and *pazValue are both set to NULL.
877c478bd9Sstevel@tonic-gate **
887c478bd9Sstevel@tonic-gate ** SQLITE_DONE means that the virtual machine has finished
897c478bd9Sstevel@tonic-gate ** executing.  sqlite_step() should not be called again on this
907c478bd9Sstevel@tonic-gate ** virtual machine.  *pN and *pazColName are set appropriately
917c478bd9Sstevel@tonic-gate ** but *pazValue is set to NULL.
927c478bd9Sstevel@tonic-gate **
937c478bd9Sstevel@tonic-gate ** SQLITE_ROW means that the virtual machine has generated another
947c478bd9Sstevel@tonic-gate ** row of the result set.  *pN is set to the number of columns in
957c478bd9Sstevel@tonic-gate ** the row.  *pazColName is set to the names of the columns followed
967c478bd9Sstevel@tonic-gate ** by the column datatypes.  *pazValue is set to the values of each
977c478bd9Sstevel@tonic-gate ** column in the row.  The value of the i-th column is (*pazValue)[i].
987c478bd9Sstevel@tonic-gate ** The name of the i-th column is (*pazColName)[i] and the datatype
997c478bd9Sstevel@tonic-gate ** of the i-th column is (*pazColName)[i+*pN].
1007c478bd9Sstevel@tonic-gate **
1017c478bd9Sstevel@tonic-gate ** SQLITE_ERROR means that a run-time error (such as a constraint
1027c478bd9Sstevel@tonic-gate ** violation) has occurred.  The details of the error will be returned
1037c478bd9Sstevel@tonic-gate ** by the next call to sqlite_finalize().  sqlite_step() should not
1047c478bd9Sstevel@tonic-gate ** be called again on the VM.
1057c478bd9Sstevel@tonic-gate **
1067c478bd9Sstevel@tonic-gate ** SQLITE_MISUSE means that the this routine was called inappropriately.
1077c478bd9Sstevel@tonic-gate ** Perhaps it was called on a virtual machine that had already been
1087c478bd9Sstevel@tonic-gate ** finalized or on one that had previously returned SQLITE_ERROR or
1097c478bd9Sstevel@tonic-gate ** SQLITE_DONE.  Or it could be the case the the same database connection
1107c478bd9Sstevel@tonic-gate ** is being used simulataneously by two or more threads.
1117c478bd9Sstevel@tonic-gate */
sqlite_step(sqlite_vm * pVm,int * pN,const char *** pazValue,const char *** pazColName)1127c478bd9Sstevel@tonic-gate int sqlite_step(
1137c478bd9Sstevel@tonic-gate   sqlite_vm *pVm,              /* The virtual machine to execute */
1147c478bd9Sstevel@tonic-gate   int *pN,                     /* OUT: Number of columns in result */
1157c478bd9Sstevel@tonic-gate   const char ***pazValue,      /* OUT: Column data */
1167c478bd9Sstevel@tonic-gate   const char ***pazColName     /* OUT: Column names and datatypes */
1177c478bd9Sstevel@tonic-gate ){
1187c478bd9Sstevel@tonic-gate   Vdbe *p = (Vdbe*)pVm;
1197c478bd9Sstevel@tonic-gate   sqlite *db;
1207c478bd9Sstevel@tonic-gate   int rc;
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate   if( p->magic!=VDBE_MAGIC_RUN ){
1237c478bd9Sstevel@tonic-gate     return SQLITE_MISUSE;
1247c478bd9Sstevel@tonic-gate   }
1257c478bd9Sstevel@tonic-gate   db = p->db;
1267c478bd9Sstevel@tonic-gate   if( sqliteSafetyOn(db) ){
1277c478bd9Sstevel@tonic-gate     p->rc = SQLITE_MISUSE;
1287c478bd9Sstevel@tonic-gate     return SQLITE_MISUSE;
1297c478bd9Sstevel@tonic-gate   }
1307c478bd9Sstevel@tonic-gate   if( p->explain ){
1317c478bd9Sstevel@tonic-gate     rc = sqliteVdbeList(p);
1327c478bd9Sstevel@tonic-gate   }else{
1337c478bd9Sstevel@tonic-gate     rc = sqliteVdbeExec(p);
1347c478bd9Sstevel@tonic-gate   }
1357c478bd9Sstevel@tonic-gate   if( rc==SQLITE_DONE || rc==SQLITE_ROW ){
1367c478bd9Sstevel@tonic-gate     if( pazColName ) *pazColName = (const char**)p->azColName;
1377c478bd9Sstevel@tonic-gate     if( pN ) *pN = p->nResColumn;
1387c478bd9Sstevel@tonic-gate   }else{
1397c478bd9Sstevel@tonic-gate     if( pazColName) *pazColName = 0;
1407c478bd9Sstevel@tonic-gate     if( pN ) *pN = 0;
1417c478bd9Sstevel@tonic-gate   }
1427c478bd9Sstevel@tonic-gate   if( pazValue ){
1437c478bd9Sstevel@tonic-gate     if( rc==SQLITE_ROW ){
1447c478bd9Sstevel@tonic-gate       *pazValue = (const char**)p->azResColumn;
1457c478bd9Sstevel@tonic-gate     }else{
1467c478bd9Sstevel@tonic-gate       *pazValue = 0;
1477c478bd9Sstevel@tonic-gate     }
1487c478bd9Sstevel@tonic-gate   }
1497c478bd9Sstevel@tonic-gate   if( sqliteSafetyOff(db) ){
1507c478bd9Sstevel@tonic-gate     return SQLITE_MISUSE;
1517c478bd9Sstevel@tonic-gate   }
1527c478bd9Sstevel@tonic-gate   return rc;
1537c478bd9Sstevel@tonic-gate }
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate /*
1567c478bd9Sstevel@tonic-gate ** Insert a new aggregate element and make it the element that
1577c478bd9Sstevel@tonic-gate ** has focus.
1587c478bd9Sstevel@tonic-gate **
1597c478bd9Sstevel@tonic-gate ** Return 0 on success and 1 if memory is exhausted.
1607c478bd9Sstevel@tonic-gate */
AggInsert(Agg * p,char * zKey,int nKey)1617c478bd9Sstevel@tonic-gate static int AggInsert(Agg *p, char *zKey, int nKey){
1627c478bd9Sstevel@tonic-gate   AggElem *pElem, *pOld;
1637c478bd9Sstevel@tonic-gate   int i;
1647c478bd9Sstevel@tonic-gate   Mem *pMem;
1657c478bd9Sstevel@tonic-gate   pElem = sqliteMalloc( sizeof(AggElem) + nKey +
1667c478bd9Sstevel@tonic-gate                         (p->nMem-1)*sizeof(pElem->aMem[0]) );
1677c478bd9Sstevel@tonic-gate   if( pElem==0 ) return 1;
1687c478bd9Sstevel@tonic-gate   pElem->zKey = (char*)&pElem->aMem[p->nMem];
1697c478bd9Sstevel@tonic-gate   memcpy(pElem->zKey, zKey, nKey);
1707c478bd9Sstevel@tonic-gate   pElem->nKey = nKey;
1717c478bd9Sstevel@tonic-gate   pOld = sqliteHashInsert(&p->hash, pElem->zKey, pElem->nKey, pElem);
1727c478bd9Sstevel@tonic-gate   if( pOld!=0 ){
1737c478bd9Sstevel@tonic-gate     assert( pOld==pElem );  /* Malloc failed on insert */
1747c478bd9Sstevel@tonic-gate     sqliteFree(pOld);
1757c478bd9Sstevel@tonic-gate     return 0;
1767c478bd9Sstevel@tonic-gate   }
1777c478bd9Sstevel@tonic-gate   for(i=0, pMem=pElem->aMem; i<p->nMem; i++, pMem++){
1787c478bd9Sstevel@tonic-gate     pMem->flags = MEM_Null;
1797c478bd9Sstevel@tonic-gate   }
1807c478bd9Sstevel@tonic-gate   p->pCurrent = pElem;
1817c478bd9Sstevel@tonic-gate   return 0;
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate /*
1857c478bd9Sstevel@tonic-gate ** Get the AggElem currently in focus
1867c478bd9Sstevel@tonic-gate */
1877c478bd9Sstevel@tonic-gate #define AggInFocus(P)   ((P).pCurrent ? (P).pCurrent : _AggInFocus(&(P)))
_AggInFocus(Agg * p)1887c478bd9Sstevel@tonic-gate static AggElem *_AggInFocus(Agg *p){
1897c478bd9Sstevel@tonic-gate   HashElem *pElem = sqliteHashFirst(&p->hash);
1907c478bd9Sstevel@tonic-gate   if( pElem==0 ){
1917c478bd9Sstevel@tonic-gate     AggInsert(p,"",1);
1927c478bd9Sstevel@tonic-gate     pElem = sqliteHashFirst(&p->hash);
1937c478bd9Sstevel@tonic-gate   }
1947c478bd9Sstevel@tonic-gate   return pElem ? sqliteHashData(pElem) : 0;
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate /*
1987c478bd9Sstevel@tonic-gate ** Convert the given stack entity into a string if it isn't one
1997c478bd9Sstevel@tonic-gate ** already.
2007c478bd9Sstevel@tonic-gate */
2017c478bd9Sstevel@tonic-gate #define Stringify(P) if(((P)->flags & MEM_Str)==0){hardStringify(P);}
hardStringify(Mem * pStack)2027c478bd9Sstevel@tonic-gate static int hardStringify(Mem *pStack){
2037c478bd9Sstevel@tonic-gate   int fg = pStack->flags;
2047c478bd9Sstevel@tonic-gate   if( fg & MEM_Real ){
2057c478bd9Sstevel@tonic-gate     sqlite_snprintf(sizeof(pStack->zShort),pStack->zShort,"%.15g",pStack->r);
2067c478bd9Sstevel@tonic-gate   }else if( fg & MEM_Int ){
2077c478bd9Sstevel@tonic-gate     sqlite_snprintf(sizeof(pStack->zShort),pStack->zShort,"%d",pStack->i);
2087c478bd9Sstevel@tonic-gate   }else{
2097c478bd9Sstevel@tonic-gate     pStack->zShort[0] = 0;
2107c478bd9Sstevel@tonic-gate   }
2117c478bd9Sstevel@tonic-gate   pStack->z = pStack->zShort;
2127c478bd9Sstevel@tonic-gate   pStack->n = strlen(pStack->zShort)+1;
2137c478bd9Sstevel@tonic-gate   pStack->flags = MEM_Str | MEM_Short;
2147c478bd9Sstevel@tonic-gate   return 0;
2157c478bd9Sstevel@tonic-gate }
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate /*
2187c478bd9Sstevel@tonic-gate ** Convert the given stack entity into a string that has been obtained
2197c478bd9Sstevel@tonic-gate ** from sqliteMalloc().  This is different from Stringify() above in that
2207c478bd9Sstevel@tonic-gate ** Stringify() will use the NBFS bytes of static string space if the string
2217c478bd9Sstevel@tonic-gate ** will fit but this routine always mallocs for space.
2227c478bd9Sstevel@tonic-gate ** Return non-zero if we run out of memory.
2237c478bd9Sstevel@tonic-gate */
2247c478bd9Sstevel@tonic-gate #define Dynamicify(P) (((P)->flags & MEM_Dyn)==0 ? hardDynamicify(P):0)
hardDynamicify(Mem * pStack)2257c478bd9Sstevel@tonic-gate static int hardDynamicify(Mem *pStack){
2267c478bd9Sstevel@tonic-gate   int fg = pStack->flags;
2277c478bd9Sstevel@tonic-gate   char *z;
2287c478bd9Sstevel@tonic-gate   if( (fg & MEM_Str)==0 ){
2297c478bd9Sstevel@tonic-gate     hardStringify(pStack);
2307c478bd9Sstevel@tonic-gate   }
2317c478bd9Sstevel@tonic-gate   assert( (fg & MEM_Dyn)==0 );
2327c478bd9Sstevel@tonic-gate   z = sqliteMallocRaw( pStack->n );
2337c478bd9Sstevel@tonic-gate   if( z==0 ) return 1;
2347c478bd9Sstevel@tonic-gate   memcpy(z, pStack->z, pStack->n);
2357c478bd9Sstevel@tonic-gate   pStack->z = z;
2367c478bd9Sstevel@tonic-gate   pStack->flags |= MEM_Dyn;
2377c478bd9Sstevel@tonic-gate   return 0;
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate /*
2417c478bd9Sstevel@tonic-gate ** An ephemeral string value (signified by the MEM_Ephem flag) contains
2427c478bd9Sstevel@tonic-gate ** a pointer to a dynamically allocated string where some other entity
2437c478bd9Sstevel@tonic-gate ** is responsible for deallocating that string.  Because the stack entry
2447c478bd9Sstevel@tonic-gate ** does not control the string, it might be deleted without the stack
2457c478bd9Sstevel@tonic-gate ** entry knowing it.
2467c478bd9Sstevel@tonic-gate **
2477c478bd9Sstevel@tonic-gate ** This routine converts an ephemeral string into a dynamically allocated
2487c478bd9Sstevel@tonic-gate ** string that the stack entry itself controls.  In other words, it
2497c478bd9Sstevel@tonic-gate ** converts an MEM_Ephem string into an MEM_Dyn string.
2507c478bd9Sstevel@tonic-gate */
2517c478bd9Sstevel@tonic-gate #define Deephemeralize(P) \
2527c478bd9Sstevel@tonic-gate    if( ((P)->flags&MEM_Ephem)!=0 && hardDeephem(P) ){ goto no_mem;}
hardDeephem(Mem * pStack)2537c478bd9Sstevel@tonic-gate static int hardDeephem(Mem *pStack){
2547c478bd9Sstevel@tonic-gate   char *z;
2557c478bd9Sstevel@tonic-gate   assert( (pStack->flags & MEM_Ephem)!=0 );
2567c478bd9Sstevel@tonic-gate   z = sqliteMallocRaw( pStack->n );
2577c478bd9Sstevel@tonic-gate   if( z==0 ) return 1;
2587c478bd9Sstevel@tonic-gate   memcpy(z, pStack->z, pStack->n);
2597c478bd9Sstevel@tonic-gate   pStack->z = z;
2607c478bd9Sstevel@tonic-gate   pStack->flags &= ~MEM_Ephem;
2617c478bd9Sstevel@tonic-gate   pStack->flags |= MEM_Dyn;
2627c478bd9Sstevel@tonic-gate   return 0;
2637c478bd9Sstevel@tonic-gate }
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate /*
2667c478bd9Sstevel@tonic-gate ** Release the memory associated with the given stack level.  This
2677c478bd9Sstevel@tonic-gate ** leaves the Mem.flags field in an inconsistent state.
2687c478bd9Sstevel@tonic-gate */
2697c478bd9Sstevel@tonic-gate #define	Release(P) \
2707c478bd9Sstevel@tonic-gate 	if ((P)->flags & MEM_Dyn) { \
2717c478bd9Sstevel@tonic-gate 		sqliteFree((P)->z); \
2727c478bd9Sstevel@tonic-gate 		(P)->z = NULL; \
2737c478bd9Sstevel@tonic-gate 	}
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate /*
2767c478bd9Sstevel@tonic-gate ** Pop the stack N times.
2777c478bd9Sstevel@tonic-gate */
popStack(Mem ** ppTos,int N)2787c478bd9Sstevel@tonic-gate static void popStack(Mem **ppTos, int N){
2797c478bd9Sstevel@tonic-gate   Mem *pTos = *ppTos;
2807c478bd9Sstevel@tonic-gate   while( N>0 ){
2817c478bd9Sstevel@tonic-gate     N--;
2827c478bd9Sstevel@tonic-gate     Release(pTos);
2837c478bd9Sstevel@tonic-gate     pTos--;
2847c478bd9Sstevel@tonic-gate   }
2857c478bd9Sstevel@tonic-gate   *ppTos = pTos;
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate /*
2897c478bd9Sstevel@tonic-gate ** Return TRUE if zNum is a 32-bit signed integer and write
2907c478bd9Sstevel@tonic-gate ** the value of the integer into *pNum.  If zNum is not an integer
2917c478bd9Sstevel@tonic-gate ** or is an integer that is too large to be expressed with just 32
2927c478bd9Sstevel@tonic-gate ** bits, then return false.
2937c478bd9Sstevel@tonic-gate **
2947c478bd9Sstevel@tonic-gate ** Under Linux (RedHat 7.2) this routine is much faster than atoi()
2957c478bd9Sstevel@tonic-gate ** for converting strings into integers.
2967c478bd9Sstevel@tonic-gate */
toInt(const char * zNum,int * pNum)2977c478bd9Sstevel@tonic-gate static int toInt(const char *zNum, int *pNum){
2987c478bd9Sstevel@tonic-gate   int v = 0;
2997c478bd9Sstevel@tonic-gate   int neg;
3007c478bd9Sstevel@tonic-gate   int i, c;
3017c478bd9Sstevel@tonic-gate   if( *zNum=='-' ){
3027c478bd9Sstevel@tonic-gate     neg = 1;
3037c478bd9Sstevel@tonic-gate     zNum++;
3047c478bd9Sstevel@tonic-gate   }else if( *zNum=='+' ){
3057c478bd9Sstevel@tonic-gate     neg = 0;
3067c478bd9Sstevel@tonic-gate     zNum++;
3077c478bd9Sstevel@tonic-gate   }else{
3087c478bd9Sstevel@tonic-gate     neg = 0;
3097c478bd9Sstevel@tonic-gate   }
3107c478bd9Sstevel@tonic-gate   for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
3117c478bd9Sstevel@tonic-gate     v = v*10 + c - '0';
3127c478bd9Sstevel@tonic-gate   }
3137c478bd9Sstevel@tonic-gate   *pNum = neg ? -v : v;
3147c478bd9Sstevel@tonic-gate   return c==0 && i>0 && (i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0));
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate /*
3187c478bd9Sstevel@tonic-gate ** Convert the given stack entity into a integer if it isn't one
3197c478bd9Sstevel@tonic-gate ** already.
3207c478bd9Sstevel@tonic-gate **
321*55fea89dSDan Cross ** Any prior string or real representation is invalidated.
3227c478bd9Sstevel@tonic-gate ** NULLs are converted into 0.
3237c478bd9Sstevel@tonic-gate */
3247c478bd9Sstevel@tonic-gate #define Integerify(P) if(((P)->flags&MEM_Int)==0){ hardIntegerify(P); }
hardIntegerify(Mem * pStack)3257c478bd9Sstevel@tonic-gate static void hardIntegerify(Mem *pStack){
3267c478bd9Sstevel@tonic-gate   if( pStack->flags & MEM_Real ){
3277c478bd9Sstevel@tonic-gate     pStack->i = (int)pStack->r;
3287c478bd9Sstevel@tonic-gate     Release(pStack);
3297c478bd9Sstevel@tonic-gate   }else if( pStack->flags & MEM_Str ){
3307c478bd9Sstevel@tonic-gate     toInt(pStack->z, &pStack->i);
3317c478bd9Sstevel@tonic-gate     Release(pStack);
3327c478bd9Sstevel@tonic-gate   }else{
3337c478bd9Sstevel@tonic-gate     pStack->i = 0;
3347c478bd9Sstevel@tonic-gate   }
3357c478bd9Sstevel@tonic-gate   pStack->flags = MEM_Int;
3367c478bd9Sstevel@tonic-gate }
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate /*
3397c478bd9Sstevel@tonic-gate ** Get a valid Real representation for the given stack element.
3407c478bd9Sstevel@tonic-gate **
3417c478bd9Sstevel@tonic-gate ** Any prior string or integer representation is retained.
3427c478bd9Sstevel@tonic-gate ** NULLs are converted into 0.0.
3437c478bd9Sstevel@tonic-gate */
3447c478bd9Sstevel@tonic-gate #define Realify(P) if(((P)->flags&MEM_Real)==0){ hardRealify(P); }
hardRealify(Mem * pStack)3457c478bd9Sstevel@tonic-gate static void hardRealify(Mem *pStack){
3467c478bd9Sstevel@tonic-gate   if( pStack->flags & MEM_Str ){
3477c478bd9Sstevel@tonic-gate     pStack->r = sqliteAtoF(pStack->z, 0);
3487c478bd9Sstevel@tonic-gate   }else if( pStack->flags & MEM_Int ){
3497c478bd9Sstevel@tonic-gate     pStack->r = pStack->i;
3507c478bd9Sstevel@tonic-gate   }else{
3517c478bd9Sstevel@tonic-gate     pStack->r = 0.0;
3527c478bd9Sstevel@tonic-gate   }
3537c478bd9Sstevel@tonic-gate   pStack->flags |= MEM_Real;
3547c478bd9Sstevel@tonic-gate }
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate /*
3577c478bd9Sstevel@tonic-gate ** The parameters are pointers to the head of two sorted lists
3587c478bd9Sstevel@tonic-gate ** of Sorter structures.  Merge these two lists together and return
3597c478bd9Sstevel@tonic-gate ** a single sorted list.  This routine forms the core of the merge-sort
3607c478bd9Sstevel@tonic-gate ** algorithm.
3617c478bd9Sstevel@tonic-gate **
3627c478bd9Sstevel@tonic-gate ** In the case of a tie, left sorts in front of right.
3637c478bd9Sstevel@tonic-gate */
Merge(Sorter * pLeft,Sorter * pRight)3647c478bd9Sstevel@tonic-gate static Sorter *Merge(Sorter *pLeft, Sorter *pRight){
3657c478bd9Sstevel@tonic-gate   Sorter sHead;
3667c478bd9Sstevel@tonic-gate   Sorter *pTail;
3677c478bd9Sstevel@tonic-gate   pTail = &sHead;
3687c478bd9Sstevel@tonic-gate   pTail->pNext = 0;
3697c478bd9Sstevel@tonic-gate   while( pLeft && pRight ){
3707c478bd9Sstevel@tonic-gate     int c = sqliteSortCompare(pLeft->zKey, pRight->zKey);
3717c478bd9Sstevel@tonic-gate     if( c<=0 ){
3727c478bd9Sstevel@tonic-gate       pTail->pNext = pLeft;
3737c478bd9Sstevel@tonic-gate       pLeft = pLeft->pNext;
3747c478bd9Sstevel@tonic-gate     }else{
3757c478bd9Sstevel@tonic-gate       pTail->pNext = pRight;
3767c478bd9Sstevel@tonic-gate       pRight = pRight->pNext;
3777c478bd9Sstevel@tonic-gate     }
3787c478bd9Sstevel@tonic-gate     pTail = pTail->pNext;
3797c478bd9Sstevel@tonic-gate   }
3807c478bd9Sstevel@tonic-gate   if( pLeft ){
3817c478bd9Sstevel@tonic-gate     pTail->pNext = pLeft;
3827c478bd9Sstevel@tonic-gate   }else if( pRight ){
3837c478bd9Sstevel@tonic-gate     pTail->pNext = pRight;
3847c478bd9Sstevel@tonic-gate   }
3857c478bd9Sstevel@tonic-gate   return sHead.pNext;
3867c478bd9Sstevel@tonic-gate }
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate /*
3897c478bd9Sstevel@tonic-gate ** The following routine works like a replacement for the standard
3907c478bd9Sstevel@tonic-gate ** library routine fgets().  The difference is in how end-of-line (EOL)
3917c478bd9Sstevel@tonic-gate ** is handled.  Standard fgets() uses LF for EOL under unix, CRLF
3927c478bd9Sstevel@tonic-gate ** under windows, and CR under mac.  This routine accepts any of these
3937c478bd9Sstevel@tonic-gate ** character sequences as an EOL mark.  The EOL mark is replaced by
3947c478bd9Sstevel@tonic-gate ** a single LF character in zBuf.
3957c478bd9Sstevel@tonic-gate */
vdbe_fgets(char * zBuf,int nBuf,FILE * in)3967c478bd9Sstevel@tonic-gate static char *vdbe_fgets(char *zBuf, int nBuf, FILE *in){
3977c478bd9Sstevel@tonic-gate   int i, c;
3987c478bd9Sstevel@tonic-gate   for(i=0; i<nBuf-1 && (c=getc(in))!=EOF; i++){
3997c478bd9Sstevel@tonic-gate     zBuf[i] = c;
4007c478bd9Sstevel@tonic-gate     if( c=='\r' || c=='\n' ){
4017c478bd9Sstevel@tonic-gate       if( c=='\r' ){
4027c478bd9Sstevel@tonic-gate         zBuf[i] = '\n';
4037c478bd9Sstevel@tonic-gate         c = getc(in);
4047c478bd9Sstevel@tonic-gate         if( c!=EOF && c!='\n' ) ungetc(c, in);
4057c478bd9Sstevel@tonic-gate       }
4067c478bd9Sstevel@tonic-gate       i++;
4077c478bd9Sstevel@tonic-gate       break;
4087c478bd9Sstevel@tonic-gate     }
4097c478bd9Sstevel@tonic-gate   }
4107c478bd9Sstevel@tonic-gate   zBuf[i]  = 0;
4117c478bd9Sstevel@tonic-gate   return i>0 ? zBuf : 0;
4127c478bd9Sstevel@tonic-gate }
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate /*
4157c478bd9Sstevel@tonic-gate ** Make sure there is space in the Vdbe structure to hold at least
4167c478bd9Sstevel@tonic-gate ** mxCursor cursors.  If there is not currently enough space, then
4177c478bd9Sstevel@tonic-gate ** allocate more.
4187c478bd9Sstevel@tonic-gate **
4197c478bd9Sstevel@tonic-gate ** If a memory allocation error occurs, return 1.  Return 0 if
4207c478bd9Sstevel@tonic-gate ** everything works.
4217c478bd9Sstevel@tonic-gate */
expandCursorArraySize(Vdbe * p,int mxCursor)4227c478bd9Sstevel@tonic-gate static int expandCursorArraySize(Vdbe *p, int mxCursor){
4237c478bd9Sstevel@tonic-gate   if( mxCursor>=p->nCursor ){
4247c478bd9Sstevel@tonic-gate     Cursor *aCsr = sqliteRealloc( p->aCsr, (mxCursor+1)*sizeof(Cursor) );
4257c478bd9Sstevel@tonic-gate     if( aCsr==0 ) return 1;
4267c478bd9Sstevel@tonic-gate     p->aCsr = aCsr;
4277c478bd9Sstevel@tonic-gate     memset(&p->aCsr[p->nCursor], 0, sizeof(Cursor)*(mxCursor+1-p->nCursor));
4287c478bd9Sstevel@tonic-gate     p->nCursor = mxCursor+1;
4297c478bd9Sstevel@tonic-gate   }
4307c478bd9Sstevel@tonic-gate   return 0;
4317c478bd9Sstevel@tonic-gate }
4327c478bd9Sstevel@tonic-gate 
4337c478bd9Sstevel@tonic-gate #ifdef VDBE_PROFILE
4347c478bd9Sstevel@tonic-gate /*
4357c478bd9Sstevel@tonic-gate ** The following routine only works on pentium-class processors.
4367c478bd9Sstevel@tonic-gate ** It uses the RDTSC opcode to read cycle count value out of the
4377c478bd9Sstevel@tonic-gate ** processor and returns that value.  This can be used for high-res
4387c478bd9Sstevel@tonic-gate ** profiling.
4397c478bd9Sstevel@tonic-gate */
hwtime(void)4407c478bd9Sstevel@tonic-gate __inline__ unsigned long long int hwtime(void){
4417c478bd9Sstevel@tonic-gate   unsigned long long int x;
4427c478bd9Sstevel@tonic-gate   __asm__("rdtsc\n\t"
4437c478bd9Sstevel@tonic-gate           "mov %%edx, %%ecx\n\t"
4447c478bd9Sstevel@tonic-gate           :"=A" (x));
4457c478bd9Sstevel@tonic-gate   return x;
4467c478bd9Sstevel@tonic-gate }
4477c478bd9Sstevel@tonic-gate #endif
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate /*
4507c478bd9Sstevel@tonic-gate ** The CHECK_FOR_INTERRUPT macro defined here looks to see if the
4517c478bd9Sstevel@tonic-gate ** sqlite_interrupt() routine has been called.  If it has been, then
4527c478bd9Sstevel@tonic-gate ** processing of the VDBE program is interrupted.
4537c478bd9Sstevel@tonic-gate **
4547c478bd9Sstevel@tonic-gate ** This macro added to every instruction that does a jump in order to
4557c478bd9Sstevel@tonic-gate ** implement a loop.  This test used to be on every single instruction,
4567c478bd9Sstevel@tonic-gate ** but that meant we more testing that we needed.  By only testing the
4577c478bd9Sstevel@tonic-gate ** flag on jump instructions, we get a (small) speed improvement.
4587c478bd9Sstevel@tonic-gate */
4597c478bd9Sstevel@tonic-gate #define CHECK_FOR_INTERRUPT \
4607c478bd9Sstevel@tonic-gate    if( db->flags & SQLITE_Interrupt ) goto abort_due_to_interrupt;
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate /*
4647c478bd9Sstevel@tonic-gate ** Execute as much of a VDBE program as we can then return.
4657c478bd9Sstevel@tonic-gate **
4667c478bd9Sstevel@tonic-gate ** sqliteVdbeMakeReady() must be called before this routine in order to
4677c478bd9Sstevel@tonic-gate ** close the program with a final OP_Halt and to set up the callbacks
4687c478bd9Sstevel@tonic-gate ** and the error message pointer.
4697c478bd9Sstevel@tonic-gate **
4707c478bd9Sstevel@tonic-gate ** Whenever a row or result data is available, this routine will either
4717c478bd9Sstevel@tonic-gate ** invoke the result callback (if there is one) or return with
4727c478bd9Sstevel@tonic-gate ** SQLITE_ROW.
4737c478bd9Sstevel@tonic-gate **
4747c478bd9Sstevel@tonic-gate ** If an attempt is made to open a locked database, then this routine
4757c478bd9Sstevel@tonic-gate ** will either invoke the busy callback (if there is one) or it will
4767c478bd9Sstevel@tonic-gate ** return SQLITE_BUSY.
4777c478bd9Sstevel@tonic-gate **
4787c478bd9Sstevel@tonic-gate ** If an error occurs, an error message is written to memory obtained
4797c478bd9Sstevel@tonic-gate ** from sqliteMalloc() and p->zErrMsg is made to point to that memory.
4807c478bd9Sstevel@tonic-gate ** The error code is stored in p->rc and this routine returns SQLITE_ERROR.
4817c478bd9Sstevel@tonic-gate **
4827c478bd9Sstevel@tonic-gate ** If the callback ever returns non-zero, then the program exits
4837c478bd9Sstevel@tonic-gate ** immediately.  There will be no error message but the p->rc field is
4847c478bd9Sstevel@tonic-gate ** set to SQLITE_ABORT and this routine will return SQLITE_ERROR.
4857c478bd9Sstevel@tonic-gate **
4867c478bd9Sstevel@tonic-gate ** A memory allocation error causes p->rc to be set to SQLITE_NOMEM and this
4877c478bd9Sstevel@tonic-gate ** routine to return SQLITE_ERROR.
4887c478bd9Sstevel@tonic-gate **
4897c478bd9Sstevel@tonic-gate ** Other fatal errors return SQLITE_ERROR.
4907c478bd9Sstevel@tonic-gate **
4917c478bd9Sstevel@tonic-gate ** After this routine has finished, sqliteVdbeFinalize() should be
4927c478bd9Sstevel@tonic-gate ** used to clean up the mess that was left behind.
4937c478bd9Sstevel@tonic-gate */
sqliteVdbeExec(Vdbe * p)4947c478bd9Sstevel@tonic-gate int sqliteVdbeExec(
4957c478bd9Sstevel@tonic-gate   Vdbe *p                    /* The VDBE */
4967c478bd9Sstevel@tonic-gate ){
4977c478bd9Sstevel@tonic-gate   int pc;                    /* The program counter */
4987c478bd9Sstevel@tonic-gate   Op *pOp;                   /* Current operation */
4997c478bd9Sstevel@tonic-gate   int rc = SQLITE_OK;        /* Value to return */
5007c478bd9Sstevel@tonic-gate   sqlite *db = p->db;        /* The database */
5017c478bd9Sstevel@tonic-gate   Mem *pTos;                 /* Top entry in the operand stack */
5027c478bd9Sstevel@tonic-gate   char zBuf[100];            /* Space to sprintf() an integer */
5037c478bd9Sstevel@tonic-gate #ifdef VDBE_PROFILE
5047c478bd9Sstevel@tonic-gate   unsigned long long start;  /* CPU clock count at start of opcode */
5057c478bd9Sstevel@tonic-gate   int origPc;                /* Program counter at start of opcode */
5067c478bd9Sstevel@tonic-gate #endif
5077c478bd9Sstevel@tonic-gate #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
5087c478bd9Sstevel@tonic-gate   int nProgressOps = 0;      /* Opcodes executed since progress callback. */
5097c478bd9Sstevel@tonic-gate #endif
5107c478bd9Sstevel@tonic-gate 
5117c478bd9Sstevel@tonic-gate   if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
5127c478bd9Sstevel@tonic-gate   assert( db->magic==SQLITE_MAGIC_BUSY );
5137c478bd9Sstevel@tonic-gate   assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
5147c478bd9Sstevel@tonic-gate   p->rc = SQLITE_OK;
5157c478bd9Sstevel@tonic-gate   assert( p->explain==0 );
5167c478bd9Sstevel@tonic-gate   if( sqlite_malloc_failed ) goto no_mem;
5177c478bd9Sstevel@tonic-gate   pTos = p->pTos;
5187c478bd9Sstevel@tonic-gate   if( p->popStack ){
5197c478bd9Sstevel@tonic-gate     popStack(&pTos, p->popStack);
5207c478bd9Sstevel@tonic-gate     p->popStack = 0;
5217c478bd9Sstevel@tonic-gate   }
5227c478bd9Sstevel@tonic-gate   CHECK_FOR_INTERRUPT;
5237c478bd9Sstevel@tonic-gate   for(pc=p->pc; rc==SQLITE_OK; pc++){
5247c478bd9Sstevel@tonic-gate     assert( pc>=0 && pc<p->nOp );
5257c478bd9Sstevel@tonic-gate     assert( pTos<=&p->aStack[pc] );
5267c478bd9Sstevel@tonic-gate #ifdef VDBE_PROFILE
5277c478bd9Sstevel@tonic-gate     origPc = pc;
5287c478bd9Sstevel@tonic-gate     start = hwtime();
5297c478bd9Sstevel@tonic-gate #endif
5307c478bd9Sstevel@tonic-gate     pOp = &p->aOp[pc];
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate     /* Only allow tracing if NDEBUG is not defined.
5337c478bd9Sstevel@tonic-gate     */
5347c478bd9Sstevel@tonic-gate #ifndef NDEBUG
5357c478bd9Sstevel@tonic-gate     if( p->trace ){
5367c478bd9Sstevel@tonic-gate       sqliteVdbePrintOp(p->trace, pc, pOp);
5377c478bd9Sstevel@tonic-gate     }
5387c478bd9Sstevel@tonic-gate #endif
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate     /* Check to see if we need to simulate an interrupt.  This only happens
5417c478bd9Sstevel@tonic-gate     ** if we have a special test build.
5427c478bd9Sstevel@tonic-gate     */
5437c478bd9Sstevel@tonic-gate #ifdef SQLITE_TEST
5447c478bd9Sstevel@tonic-gate     if( sqlite_interrupt_count>0 ){
5457c478bd9Sstevel@tonic-gate       sqlite_interrupt_count--;
5467c478bd9Sstevel@tonic-gate       if( sqlite_interrupt_count==0 ){
5477c478bd9Sstevel@tonic-gate         sqlite_interrupt(db);
5487c478bd9Sstevel@tonic-gate       }
5497c478bd9Sstevel@tonic-gate     }
5507c478bd9Sstevel@tonic-gate #endif
5517c478bd9Sstevel@tonic-gate 
5527c478bd9Sstevel@tonic-gate #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
5537c478bd9Sstevel@tonic-gate     /* Call the progress callback if it is configured and the required number
5547c478bd9Sstevel@tonic-gate     ** of VDBE ops have been executed (either since this invocation of
5557c478bd9Sstevel@tonic-gate     ** sqliteVdbeExec() or since last time the progress callback was called).
5567c478bd9Sstevel@tonic-gate     ** If the progress callback returns non-zero, exit the virtual machine with
5577c478bd9Sstevel@tonic-gate     ** a return code SQLITE_ABORT.
5587c478bd9Sstevel@tonic-gate     */
5597c478bd9Sstevel@tonic-gate     if( db->xProgress ){
5607c478bd9Sstevel@tonic-gate       if( db->nProgressOps==nProgressOps ){
5617c478bd9Sstevel@tonic-gate         if( db->xProgress(db->pProgressArg)!=0 ){
5627c478bd9Sstevel@tonic-gate           rc = SQLITE_ABORT;
5637c478bd9Sstevel@tonic-gate           continue; /* skip to the next iteration of the for loop */
5647c478bd9Sstevel@tonic-gate         }
5657c478bd9Sstevel@tonic-gate         nProgressOps = 0;
5667c478bd9Sstevel@tonic-gate       }
5677c478bd9Sstevel@tonic-gate       nProgressOps++;
5687c478bd9Sstevel@tonic-gate     }
5697c478bd9Sstevel@tonic-gate #endif
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate     switch( pOp->opcode ){
5727c478bd9Sstevel@tonic-gate 
5737c478bd9Sstevel@tonic-gate /*****************************************************************************
5747c478bd9Sstevel@tonic-gate ** What follows is a massive switch statement where each case implements a
5757c478bd9Sstevel@tonic-gate ** separate instruction in the virtual machine.  If we follow the usual
5767c478bd9Sstevel@tonic-gate ** indentation conventions, each case should be indented by 6 spaces.  But
5777c478bd9Sstevel@tonic-gate ** that is a lot of wasted space on the left margin.  So the code within
5787c478bd9Sstevel@tonic-gate ** the switch statement will break with convention and be flush-left. Another
5797c478bd9Sstevel@tonic-gate ** big comment (similar to this one) will mark the point in the code where
5807c478bd9Sstevel@tonic-gate ** we transition back to normal indentation.
5817c478bd9Sstevel@tonic-gate **
5827c478bd9Sstevel@tonic-gate ** The formatting of each case is important.  The makefile for SQLite
5837c478bd9Sstevel@tonic-gate ** generates two C files "opcodes.h" and "opcodes.c" by scanning this
5847c478bd9Sstevel@tonic-gate ** file looking for lines that begin with "case OP_".  The opcodes.h files
5857c478bd9Sstevel@tonic-gate ** will be filled with #defines that give unique integer values to each
5867c478bd9Sstevel@tonic-gate ** opcode and the opcodes.c file is filled with an array of strings where
5877c478bd9Sstevel@tonic-gate ** each string is the symbolic name for the corresponding opcode.
5887c478bd9Sstevel@tonic-gate **
5897c478bd9Sstevel@tonic-gate ** Documentation about VDBE opcodes is generated by scanning this file
5907c478bd9Sstevel@tonic-gate ** for lines of that contain "Opcode:".  That line and all subsequent
5917c478bd9Sstevel@tonic-gate ** comment lines are used in the generation of the opcode.html documentation
5927c478bd9Sstevel@tonic-gate ** file.
5937c478bd9Sstevel@tonic-gate **
5947c478bd9Sstevel@tonic-gate ** SUMMARY:
5957c478bd9Sstevel@tonic-gate **
5967c478bd9Sstevel@tonic-gate **     Formatting is important to scripts that scan this file.
5977c478bd9Sstevel@tonic-gate **     Do not deviate from the formatting style currently in use.
5987c478bd9Sstevel@tonic-gate **
5997c478bd9Sstevel@tonic-gate *****************************************************************************/
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate /* Opcode:  Goto * P2 *
6027c478bd9Sstevel@tonic-gate **
6037c478bd9Sstevel@tonic-gate ** An unconditional jump to address P2.
604*55fea89dSDan Cross ** The next instruction executed will be
6057c478bd9Sstevel@tonic-gate ** the one at index P2 from the beginning of
6067c478bd9Sstevel@tonic-gate ** the program.
6077c478bd9Sstevel@tonic-gate */
6087c478bd9Sstevel@tonic-gate case OP_Goto: {
6097c478bd9Sstevel@tonic-gate   CHECK_FOR_INTERRUPT;
6107c478bd9Sstevel@tonic-gate   pc = pOp->p2 - 1;
6117c478bd9Sstevel@tonic-gate   break;
6127c478bd9Sstevel@tonic-gate }
6137c478bd9Sstevel@tonic-gate 
6147c478bd9Sstevel@tonic-gate /* Opcode:  Gosub * P2 *
6157c478bd9Sstevel@tonic-gate **
6167c478bd9Sstevel@tonic-gate ** Push the current address plus 1 onto the return address stack
6177c478bd9Sstevel@tonic-gate ** and then jump to address P2.
6187c478bd9Sstevel@tonic-gate **
6197c478bd9Sstevel@tonic-gate ** The return address stack is of limited depth.  If too many
6207c478bd9Sstevel@tonic-gate ** OP_Gosub operations occur without intervening OP_Returns, then
6217c478bd9Sstevel@tonic-gate ** the return address stack will fill up and processing will abort
6227c478bd9Sstevel@tonic-gate ** with a fatal error.
6237c478bd9Sstevel@tonic-gate */
6247c478bd9Sstevel@tonic-gate case OP_Gosub: {
6257c478bd9Sstevel@tonic-gate   if( p->returnDepth>=sizeof(p->returnStack)/sizeof(p->returnStack[0]) ){
6267c478bd9Sstevel@tonic-gate     sqliteSetString(&p->zErrMsg, "return address stack overflow", (char*)0);
6277c478bd9Sstevel@tonic-gate     p->rc = SQLITE_INTERNAL;
6287c478bd9Sstevel@tonic-gate     return SQLITE_ERROR;
6297c478bd9Sstevel@tonic-gate   }
6307c478bd9Sstevel@tonic-gate   p->returnStack[p->returnDepth++] = pc+1;
6317c478bd9Sstevel@tonic-gate   pc = pOp->p2 - 1;
6327c478bd9Sstevel@tonic-gate   break;
6337c478bd9Sstevel@tonic-gate }
6347c478bd9Sstevel@tonic-gate 
6357c478bd9Sstevel@tonic-gate /* Opcode:  Return * * *
6367c478bd9Sstevel@tonic-gate **
6377c478bd9Sstevel@tonic-gate ** Jump immediately to the next instruction after the last unreturned
6387c478bd9Sstevel@tonic-gate ** OP_Gosub.  If an OP_Return has occurred for all OP_Gosubs, then
6397c478bd9Sstevel@tonic-gate ** processing aborts with a fatal error.
6407c478bd9Sstevel@tonic-gate */
6417c478bd9Sstevel@tonic-gate case OP_Return: {
6427c478bd9Sstevel@tonic-gate   if( p->returnDepth<=0 ){
6437c478bd9Sstevel@tonic-gate     sqliteSetString(&p->zErrMsg, "return address stack underflow", (char*)0);
6447c478bd9Sstevel@tonic-gate     p->rc = SQLITE_INTERNAL;
6457c478bd9Sstevel@tonic-gate     return SQLITE_ERROR;
6467c478bd9Sstevel@tonic-gate   }
6477c478bd9Sstevel@tonic-gate   p->returnDepth--;
6487c478bd9Sstevel@tonic-gate   pc = p->returnStack[p->returnDepth] - 1;
6497c478bd9Sstevel@tonic-gate   break;
6507c478bd9Sstevel@tonic-gate }
6517c478bd9Sstevel@tonic-gate 
6527c478bd9Sstevel@tonic-gate /* Opcode:  Halt P1 P2 *
6537c478bd9Sstevel@tonic-gate **
6547c478bd9Sstevel@tonic-gate ** Exit immediately.  All open cursors, Lists, Sorts, etc are closed
6557c478bd9Sstevel@tonic-gate ** automatically.
6567c478bd9Sstevel@tonic-gate **
6577c478bd9Sstevel@tonic-gate ** P1 is the result code returned by sqlite_exec().  For a normal
6587c478bd9Sstevel@tonic-gate ** halt, this should be SQLITE_OK (0).  For errors, it can be some
6597c478bd9Sstevel@tonic-gate ** other value.  If P1!=0 then P2 will determine whether or not to
6607c478bd9Sstevel@tonic-gate ** rollback the current transaction.  Do not rollback if P2==OE_Fail.
6617c478bd9Sstevel@tonic-gate ** Do the rollback if P2==OE_Rollback.  If P2==OE_Abort, then back
6627c478bd9Sstevel@tonic-gate ** out all changes that have occurred during this execution of the
663*55fea89dSDan Cross ** VDBE, but do not rollback the transaction.
6647c478bd9Sstevel@tonic-gate **
6657c478bd9Sstevel@tonic-gate ** There is an implied "Halt 0 0 0" instruction inserted at the very end of
6667c478bd9Sstevel@tonic-gate ** every program.  So a jump past the last instruction of the program
6677c478bd9Sstevel@tonic-gate ** is the same as executing Halt.
6687c478bd9Sstevel@tonic-gate */
6697c478bd9Sstevel@tonic-gate case OP_Halt: {
6707c478bd9Sstevel@tonic-gate   p->magic = VDBE_MAGIC_HALT;
6717c478bd9Sstevel@tonic-gate   p->pTos = pTos;
6727c478bd9Sstevel@tonic-gate   if( pOp->p1!=SQLITE_OK ){
6737c478bd9Sstevel@tonic-gate     p->rc = pOp->p1;
6747c478bd9Sstevel@tonic-gate     p->errorAction = pOp->p2;
6757c478bd9Sstevel@tonic-gate     if( pOp->p3 ){
6767c478bd9Sstevel@tonic-gate       sqliteSetString(&p->zErrMsg, pOp->p3, (char*)0);
6777c478bd9Sstevel@tonic-gate     }
6787c478bd9Sstevel@tonic-gate     return SQLITE_ERROR;
6797c478bd9Sstevel@tonic-gate   }else{
6807c478bd9Sstevel@tonic-gate     p->rc = SQLITE_OK;
6817c478bd9Sstevel@tonic-gate     return SQLITE_DONE;
6827c478bd9Sstevel@tonic-gate   }
6837c478bd9Sstevel@tonic-gate }
6847c478bd9Sstevel@tonic-gate 
6857c478bd9Sstevel@tonic-gate /* Opcode: Integer P1 * P3
6867c478bd9Sstevel@tonic-gate **
6877c478bd9Sstevel@tonic-gate ** The integer value P1 is pushed onto the stack.  If P3 is not zero
6887c478bd9Sstevel@tonic-gate ** then it is assumed to be a string representation of the same integer.
6897c478bd9Sstevel@tonic-gate */
6907c478bd9Sstevel@tonic-gate case OP_Integer: {
6917c478bd9Sstevel@tonic-gate   pTos++;
6927c478bd9Sstevel@tonic-gate   pTos->i = pOp->p1;
6937c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Int;
6947c478bd9Sstevel@tonic-gate   if( pOp->p3 ){
6957c478bd9Sstevel@tonic-gate     pTos->z = pOp->p3;
6967c478bd9Sstevel@tonic-gate     pTos->flags |= MEM_Str | MEM_Static;
6977c478bd9Sstevel@tonic-gate     pTos->n = strlen(pOp->p3)+1;
6987c478bd9Sstevel@tonic-gate   }
6997c478bd9Sstevel@tonic-gate   break;
7007c478bd9Sstevel@tonic-gate }
7017c478bd9Sstevel@tonic-gate 
7027c478bd9Sstevel@tonic-gate /* Opcode: String * * P3
7037c478bd9Sstevel@tonic-gate **
7047c478bd9Sstevel@tonic-gate ** The string value P3 is pushed onto the stack.  If P3==0 then a
7057c478bd9Sstevel@tonic-gate ** NULL is pushed onto the stack.
7067c478bd9Sstevel@tonic-gate */
7077c478bd9Sstevel@tonic-gate case OP_String: {
7087c478bd9Sstevel@tonic-gate   char *z = pOp->p3;
7097c478bd9Sstevel@tonic-gate   pTos++;
7107c478bd9Sstevel@tonic-gate   if( z==0 ){
7117c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
7127c478bd9Sstevel@tonic-gate   }else{
7137c478bd9Sstevel@tonic-gate     pTos->z = z;
7147c478bd9Sstevel@tonic-gate     pTos->n = strlen(z) + 1;
7157c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Str | MEM_Static;
7167c478bd9Sstevel@tonic-gate   }
7177c478bd9Sstevel@tonic-gate   break;
7187c478bd9Sstevel@tonic-gate }
7197c478bd9Sstevel@tonic-gate 
7207c478bd9Sstevel@tonic-gate /* Opcode: Variable P1 * *
7217c478bd9Sstevel@tonic-gate **
7227c478bd9Sstevel@tonic-gate ** Push the value of variable P1 onto the stack.  A variable is
7237c478bd9Sstevel@tonic-gate ** an unknown in the original SQL string as handed to sqlite_compile().
7247c478bd9Sstevel@tonic-gate ** Any occurance of the '?' character in the original SQL is considered
7257c478bd9Sstevel@tonic-gate ** a variable.  Variables in the SQL string are number from left to
7267c478bd9Sstevel@tonic-gate ** right beginning with 1.  The values of variables are set using the
7277c478bd9Sstevel@tonic-gate ** sqlite_bind() API.
7287c478bd9Sstevel@tonic-gate */
7297c478bd9Sstevel@tonic-gate case OP_Variable: {
7307c478bd9Sstevel@tonic-gate   int j = pOp->p1 - 1;
7317c478bd9Sstevel@tonic-gate   pTos++;
7327c478bd9Sstevel@tonic-gate   if( j>=0 && j<p->nVar && p->azVar[j]!=0 ){
7337c478bd9Sstevel@tonic-gate     pTos->z = p->azVar[j];
7347c478bd9Sstevel@tonic-gate     pTos->n = p->anVar[j];
7357c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Str | MEM_Static;
7367c478bd9Sstevel@tonic-gate   }else{
7377c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
7387c478bd9Sstevel@tonic-gate   }
7397c478bd9Sstevel@tonic-gate   break;
7407c478bd9Sstevel@tonic-gate }
7417c478bd9Sstevel@tonic-gate 
7427c478bd9Sstevel@tonic-gate /* Opcode: Pop P1 * *
7437c478bd9Sstevel@tonic-gate **
7447c478bd9Sstevel@tonic-gate ** P1 elements are popped off of the top of stack and discarded.
7457c478bd9Sstevel@tonic-gate */
7467c478bd9Sstevel@tonic-gate case OP_Pop: {
7477c478bd9Sstevel@tonic-gate   assert( pOp->p1>=0 );
7487c478bd9Sstevel@tonic-gate   popStack(&pTos, pOp->p1);
7497c478bd9Sstevel@tonic-gate   assert( pTos>=&p->aStack[-1] );
7507c478bd9Sstevel@tonic-gate   break;
7517c478bd9Sstevel@tonic-gate }
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate /* Opcode: Dup P1 P2 *
7547c478bd9Sstevel@tonic-gate **
755*55fea89dSDan Cross ** A copy of the P1-th element of the stack
7567c478bd9Sstevel@tonic-gate ** is made and pushed onto the top of the stack.
7577c478bd9Sstevel@tonic-gate ** The top of the stack is element 0.  So the
7587c478bd9Sstevel@tonic-gate ** instruction "Dup 0 0 0" will make a copy of the
7597c478bd9Sstevel@tonic-gate ** top of the stack.
7607c478bd9Sstevel@tonic-gate **
7617c478bd9Sstevel@tonic-gate ** If the content of the P1-th element is a dynamically
7627c478bd9Sstevel@tonic-gate ** allocated string, then a new copy of that string
7637c478bd9Sstevel@tonic-gate ** is made if P2==0.  If P2!=0, then just a pointer
7647c478bd9Sstevel@tonic-gate ** to the string is copied.
7657c478bd9Sstevel@tonic-gate **
7667c478bd9Sstevel@tonic-gate ** Also see the Pull instruction.
7677c478bd9Sstevel@tonic-gate */
7687c478bd9Sstevel@tonic-gate case OP_Dup: {
7697c478bd9Sstevel@tonic-gate   Mem *pFrom = &pTos[-pOp->p1];
7707c478bd9Sstevel@tonic-gate   assert( pFrom<=pTos && pFrom>=p->aStack );
7717c478bd9Sstevel@tonic-gate   pTos++;
7727c478bd9Sstevel@tonic-gate   memcpy(pTos, pFrom, sizeof(*pFrom)-NBFS);
7737c478bd9Sstevel@tonic-gate   if( pTos->flags & MEM_Str ){
7747c478bd9Sstevel@tonic-gate     if( pOp->p2 && (pTos->flags & (MEM_Dyn|MEM_Ephem)) ){
7757c478bd9Sstevel@tonic-gate       pTos->flags &= ~MEM_Dyn;
7767c478bd9Sstevel@tonic-gate       pTos->flags |= MEM_Ephem;
7777c478bd9Sstevel@tonic-gate     }else if( pTos->flags & MEM_Short ){
7787c478bd9Sstevel@tonic-gate       memcpy(pTos->zShort, pFrom->zShort, pTos->n);
7797c478bd9Sstevel@tonic-gate       pTos->z = pTos->zShort;
7807c478bd9Sstevel@tonic-gate     }else if( (pTos->flags & MEM_Static)==0 ){
7817c478bd9Sstevel@tonic-gate       pTos->z = sqliteMallocRaw(pFrom->n);
7827c478bd9Sstevel@tonic-gate       if( sqlite_malloc_failed ) goto no_mem;
7837c478bd9Sstevel@tonic-gate       memcpy(pTos->z, pFrom->z, pFrom->n);
7847c478bd9Sstevel@tonic-gate       pTos->flags &= ~(MEM_Static|MEM_Ephem|MEM_Short);
7857c478bd9Sstevel@tonic-gate       pTos->flags |= MEM_Dyn;
7867c478bd9Sstevel@tonic-gate     }
7877c478bd9Sstevel@tonic-gate   }
7887c478bd9Sstevel@tonic-gate   break;
7897c478bd9Sstevel@tonic-gate }
7907c478bd9Sstevel@tonic-gate 
7917c478bd9Sstevel@tonic-gate /* Opcode: Pull P1 * *
7927c478bd9Sstevel@tonic-gate **
793*55fea89dSDan Cross ** The P1-th element is removed from its current location on
7947c478bd9Sstevel@tonic-gate ** the stack and pushed back on top of the stack.  The
7957c478bd9Sstevel@tonic-gate ** top of the stack is element 0, so "Pull 0 0 0" is
7967c478bd9Sstevel@tonic-gate ** a no-op.  "Pull 1 0 0" swaps the top two elements of
7977c478bd9Sstevel@tonic-gate ** the stack.
7987c478bd9Sstevel@tonic-gate **
7997c478bd9Sstevel@tonic-gate ** See also the Dup instruction.
8007c478bd9Sstevel@tonic-gate */
8017c478bd9Sstevel@tonic-gate case OP_Pull: {
8027c478bd9Sstevel@tonic-gate   Mem *pFrom = &pTos[-pOp->p1];
8037c478bd9Sstevel@tonic-gate   int i;
8047c478bd9Sstevel@tonic-gate   Mem ts;
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate   ts = *pFrom;
8077c478bd9Sstevel@tonic-gate   Deephemeralize(pTos);
8087c478bd9Sstevel@tonic-gate   for(i=0; i<pOp->p1; i++, pFrom++){
8097c478bd9Sstevel@tonic-gate     Deephemeralize(&pFrom[1]);
8107c478bd9Sstevel@tonic-gate     *pFrom = pFrom[1];
8117c478bd9Sstevel@tonic-gate     assert( (pFrom->flags & MEM_Ephem)==0 );
8127c478bd9Sstevel@tonic-gate     if( pFrom->flags & MEM_Short ){
8137c478bd9Sstevel@tonic-gate       assert( pFrom->flags & MEM_Str );
8147c478bd9Sstevel@tonic-gate       assert( pFrom->z==pFrom[1].zShort );
8157c478bd9Sstevel@tonic-gate       pFrom->z = pFrom->zShort;
8167c478bd9Sstevel@tonic-gate     }
8177c478bd9Sstevel@tonic-gate   }
8187c478bd9Sstevel@tonic-gate   *pTos = ts;
8197c478bd9Sstevel@tonic-gate   if( pTos->flags & MEM_Short ){
8207c478bd9Sstevel@tonic-gate     assert( pTos->flags & MEM_Str );
8217c478bd9Sstevel@tonic-gate     assert( pTos->z==pTos[-pOp->p1].zShort );
8227c478bd9Sstevel@tonic-gate     pTos->z = pTos->zShort;
8237c478bd9Sstevel@tonic-gate   }
8247c478bd9Sstevel@tonic-gate   break;
8257c478bd9Sstevel@tonic-gate }
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate /* Opcode: Push P1 * *
8287c478bd9Sstevel@tonic-gate **
8297c478bd9Sstevel@tonic-gate ** Overwrite the value of the P1-th element down on the
8307c478bd9Sstevel@tonic-gate ** stack (P1==0 is the top of the stack) with the value
8317c478bd9Sstevel@tonic-gate ** of the top of the stack.  Then pop the top of the stack.
8327c478bd9Sstevel@tonic-gate */
8337c478bd9Sstevel@tonic-gate case OP_Push: {
8347c478bd9Sstevel@tonic-gate   Mem *pTo = &pTos[-pOp->p1];
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate   assert( pTo>=p->aStack );
8377c478bd9Sstevel@tonic-gate   Deephemeralize(pTos);
8387c478bd9Sstevel@tonic-gate   Release(pTo);
8397c478bd9Sstevel@tonic-gate   *pTo = *pTos;
8407c478bd9Sstevel@tonic-gate   if( pTo->flags & MEM_Short ){
8417c478bd9Sstevel@tonic-gate     assert( pTo->z==pTos->zShort );
8427c478bd9Sstevel@tonic-gate     pTo->z = pTo->zShort;
8437c478bd9Sstevel@tonic-gate   }
8447c478bd9Sstevel@tonic-gate   pTos--;
8457c478bd9Sstevel@tonic-gate   break;
8467c478bd9Sstevel@tonic-gate }
8477c478bd9Sstevel@tonic-gate 
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate /* Opcode: ColumnName P1 P2 P3
8507c478bd9Sstevel@tonic-gate **
8517c478bd9Sstevel@tonic-gate ** P3 becomes the P1-th column name (first is 0).  An array of pointers
8527c478bd9Sstevel@tonic-gate ** to all column names is passed as the 4th parameter to the callback.
8537c478bd9Sstevel@tonic-gate ** If P2==1 then this is the last column in the result set and thus the
8547c478bd9Sstevel@tonic-gate ** number of columns in the result set will be P1.  There must be at least
8557c478bd9Sstevel@tonic-gate ** one OP_ColumnName with a P2==1 before invoking OP_Callback and the
8567c478bd9Sstevel@tonic-gate ** number of columns specified in OP_Callback must one more than the P1
8577c478bd9Sstevel@tonic-gate ** value of the OP_ColumnName that has P2==1.
8587c478bd9Sstevel@tonic-gate */
8597c478bd9Sstevel@tonic-gate case OP_ColumnName: {
8607c478bd9Sstevel@tonic-gate   assert( pOp->p1>=0 && pOp->p1<p->nOp );
8617c478bd9Sstevel@tonic-gate   p->azColName[pOp->p1] = pOp->p3;
8627c478bd9Sstevel@tonic-gate   p->nCallback = 0;
8637c478bd9Sstevel@tonic-gate   if( pOp->p2 ) p->nResColumn = pOp->p1+1;
8647c478bd9Sstevel@tonic-gate   break;
8657c478bd9Sstevel@tonic-gate }
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate /* Opcode: Callback P1 * *
8687c478bd9Sstevel@tonic-gate **
8697c478bd9Sstevel@tonic-gate ** Pop P1 values off the stack and form them into an array.  Then
8707c478bd9Sstevel@tonic-gate ** invoke the callback function using the newly formed array as the
8717c478bd9Sstevel@tonic-gate ** 3rd parameter.
8727c478bd9Sstevel@tonic-gate */
8737c478bd9Sstevel@tonic-gate case OP_Callback: {
8747c478bd9Sstevel@tonic-gate   int i;
8757c478bd9Sstevel@tonic-gate   char **azArgv = p->zArgv;
8767c478bd9Sstevel@tonic-gate   Mem *pCol;
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate   pCol = &pTos[1-pOp->p1];
8797c478bd9Sstevel@tonic-gate   assert( pCol>=p->aStack );
8807c478bd9Sstevel@tonic-gate   for(i=0; i<pOp->p1; i++, pCol++){
8817c478bd9Sstevel@tonic-gate     if( pCol->flags & MEM_Null ){
8827c478bd9Sstevel@tonic-gate       azArgv[i] = 0;
8837c478bd9Sstevel@tonic-gate     }else{
8847c478bd9Sstevel@tonic-gate       Stringify(pCol);
8857c478bd9Sstevel@tonic-gate       azArgv[i] = pCol->z;
8867c478bd9Sstevel@tonic-gate     }
8877c478bd9Sstevel@tonic-gate   }
8887c478bd9Sstevel@tonic-gate   azArgv[i] = 0;
8897c478bd9Sstevel@tonic-gate   p->nCallback++;
8907c478bd9Sstevel@tonic-gate   p->azResColumn = azArgv;
8917c478bd9Sstevel@tonic-gate   assert( p->nResColumn==pOp->p1 );
8927c478bd9Sstevel@tonic-gate   p->popStack = pOp->p1;
8937c478bd9Sstevel@tonic-gate   p->pc = pc + 1;
8947c478bd9Sstevel@tonic-gate   p->pTos = pTos;
8957c478bd9Sstevel@tonic-gate   return SQLITE_ROW;
8967c478bd9Sstevel@tonic-gate }
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate /* Opcode: Concat P1 P2 P3
8997c478bd9Sstevel@tonic-gate **
900*55fea89dSDan Cross ** Look at the first P1 elements of the stack.  Append them all
901*55fea89dSDan Cross ** together with the lowest element first.  Use P3 as a separator.
9027c478bd9Sstevel@tonic-gate ** Put the result on the top of the stack.  The original P1 elements
9037c478bd9Sstevel@tonic-gate ** are popped from the stack if P2==0 and retained if P2==1.  If
9047c478bd9Sstevel@tonic-gate ** any element of the stack is NULL, then the result is NULL.
9057c478bd9Sstevel@tonic-gate **
9067c478bd9Sstevel@tonic-gate ** If P3 is NULL, then use no separator.  When P1==1, this routine
9077c478bd9Sstevel@tonic-gate ** makes a copy of the top stack element into memory obtained
9087c478bd9Sstevel@tonic-gate ** from sqliteMalloc().
9097c478bd9Sstevel@tonic-gate */
9107c478bd9Sstevel@tonic-gate case OP_Concat: {
9117c478bd9Sstevel@tonic-gate   char *zNew;
9127c478bd9Sstevel@tonic-gate   int nByte;
9137c478bd9Sstevel@tonic-gate   int nField;
9147c478bd9Sstevel@tonic-gate   int i, j;
9157c478bd9Sstevel@tonic-gate   char *zSep;
9167c478bd9Sstevel@tonic-gate   int nSep;
9177c478bd9Sstevel@tonic-gate   Mem *pTerm;
9187c478bd9Sstevel@tonic-gate 
9197c478bd9Sstevel@tonic-gate   nField = pOp->p1;
9207c478bd9Sstevel@tonic-gate   zSep = pOp->p3;
9217c478bd9Sstevel@tonic-gate   if( zSep==0 ) zSep = "";
9227c478bd9Sstevel@tonic-gate   nSep = strlen(zSep);
9237c478bd9Sstevel@tonic-gate   assert( &pTos[1-nField] >= p->aStack );
9247c478bd9Sstevel@tonic-gate   nByte = 1 - nSep;
9257c478bd9Sstevel@tonic-gate   pTerm = &pTos[1-nField];
9267c478bd9Sstevel@tonic-gate   for(i=0; i<nField; i++, pTerm++){
9277c478bd9Sstevel@tonic-gate     if( pTerm->flags & MEM_Null ){
9287c478bd9Sstevel@tonic-gate       nByte = -1;
9297c478bd9Sstevel@tonic-gate       break;
9307c478bd9Sstevel@tonic-gate     }else{
9317c478bd9Sstevel@tonic-gate       Stringify(pTerm);
9327c478bd9Sstevel@tonic-gate       nByte += pTerm->n - 1 + nSep;
9337c478bd9Sstevel@tonic-gate     }
9347c478bd9Sstevel@tonic-gate   }
9357c478bd9Sstevel@tonic-gate   if( nByte<0 ){
9367c478bd9Sstevel@tonic-gate     if( pOp->p2==0 ){
9377c478bd9Sstevel@tonic-gate       popStack(&pTos, nField);
9387c478bd9Sstevel@tonic-gate     }
9397c478bd9Sstevel@tonic-gate     pTos++;
9407c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
9417c478bd9Sstevel@tonic-gate     break;
9427c478bd9Sstevel@tonic-gate   }
9437c478bd9Sstevel@tonic-gate   zNew = sqliteMallocRaw( nByte );
9447c478bd9Sstevel@tonic-gate   if( zNew==0 ) goto no_mem;
9457c478bd9Sstevel@tonic-gate   j = 0;
9467c478bd9Sstevel@tonic-gate   pTerm = &pTos[1-nField];
9477c478bd9Sstevel@tonic-gate   for(i=j=0; i<nField; i++, pTerm++){
9487c478bd9Sstevel@tonic-gate     assert( pTerm->flags & MEM_Str );
9497c478bd9Sstevel@tonic-gate     memcpy(&zNew[j], pTerm->z, pTerm->n-1);
9507c478bd9Sstevel@tonic-gate     j += pTerm->n-1;
9517c478bd9Sstevel@tonic-gate     if( nSep>0 && i<nField-1 ){
9527c478bd9Sstevel@tonic-gate       memcpy(&zNew[j], zSep, nSep);
9537c478bd9Sstevel@tonic-gate       j += nSep;
9547c478bd9Sstevel@tonic-gate     }
9557c478bd9Sstevel@tonic-gate   }
9567c478bd9Sstevel@tonic-gate   zNew[j] = 0;
9577c478bd9Sstevel@tonic-gate   if( pOp->p2==0 ){
9587c478bd9Sstevel@tonic-gate     popStack(&pTos, nField);
9597c478bd9Sstevel@tonic-gate   }
9607c478bd9Sstevel@tonic-gate   pTos++;
9617c478bd9Sstevel@tonic-gate   pTos->n = nByte;
9627c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Str|MEM_Dyn;
9637c478bd9Sstevel@tonic-gate   pTos->z = zNew;
9647c478bd9Sstevel@tonic-gate   break;
9657c478bd9Sstevel@tonic-gate }
9667c478bd9Sstevel@tonic-gate 
9677c478bd9Sstevel@tonic-gate /* Opcode: Add * * *
9687c478bd9Sstevel@tonic-gate **
9697c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack, add them together,
9707c478bd9Sstevel@tonic-gate ** and push the result back onto the stack.  If either element
9717c478bd9Sstevel@tonic-gate ** is a string then it is converted to a double using the atof()
9727c478bd9Sstevel@tonic-gate ** function before the addition.
9737c478bd9Sstevel@tonic-gate ** If either operand is NULL, the result is NULL.
9747c478bd9Sstevel@tonic-gate */
9757c478bd9Sstevel@tonic-gate /* Opcode: Multiply * * *
9767c478bd9Sstevel@tonic-gate **
9777c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack, multiply them together,
9787c478bd9Sstevel@tonic-gate ** and push the result back onto the stack.  If either element
9797c478bd9Sstevel@tonic-gate ** is a string then it is converted to a double using the atof()
9807c478bd9Sstevel@tonic-gate ** function before the multiplication.
9817c478bd9Sstevel@tonic-gate ** If either operand is NULL, the result is NULL.
9827c478bd9Sstevel@tonic-gate */
9837c478bd9Sstevel@tonic-gate /* Opcode: Subtract * * *
9847c478bd9Sstevel@tonic-gate **
9857c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack, subtract the
9867c478bd9Sstevel@tonic-gate ** first (what was on top of the stack) from the second (the
9877c478bd9Sstevel@tonic-gate ** next on stack)
9887c478bd9Sstevel@tonic-gate ** and push the result back onto the stack.  If either element
9897c478bd9Sstevel@tonic-gate ** is a string then it is converted to a double using the atof()
9907c478bd9Sstevel@tonic-gate ** function before the subtraction.
9917c478bd9Sstevel@tonic-gate ** If either operand is NULL, the result is NULL.
9927c478bd9Sstevel@tonic-gate */
9937c478bd9Sstevel@tonic-gate /* Opcode: Divide * * *
9947c478bd9Sstevel@tonic-gate **
9957c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack, divide the
9967c478bd9Sstevel@tonic-gate ** first (what was on top of the stack) from the second (the
9977c478bd9Sstevel@tonic-gate ** next on stack)
9987c478bd9Sstevel@tonic-gate ** and push the result back onto the stack.  If either element
9997c478bd9Sstevel@tonic-gate ** is a string then it is converted to a double using the atof()
10007c478bd9Sstevel@tonic-gate ** function before the division.  Division by zero returns NULL.
10017c478bd9Sstevel@tonic-gate ** If either operand is NULL, the result is NULL.
10027c478bd9Sstevel@tonic-gate */
10037c478bd9Sstevel@tonic-gate /* Opcode: Remainder * * *
10047c478bd9Sstevel@tonic-gate **
10057c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack, divide the
10067c478bd9Sstevel@tonic-gate ** first (what was on top of the stack) from the second (the
10077c478bd9Sstevel@tonic-gate ** next on stack)
10087c478bd9Sstevel@tonic-gate ** and push the remainder after division onto the stack.  If either element
10097c478bd9Sstevel@tonic-gate ** is a string then it is converted to a double using the atof()
10107c478bd9Sstevel@tonic-gate ** function before the division.  Division by zero returns NULL.
10117c478bd9Sstevel@tonic-gate ** If either operand is NULL, the result is NULL.
10127c478bd9Sstevel@tonic-gate */
10137c478bd9Sstevel@tonic-gate case OP_Add:
10147c478bd9Sstevel@tonic-gate case OP_Subtract:
10157c478bd9Sstevel@tonic-gate case OP_Multiply:
10167c478bd9Sstevel@tonic-gate case OP_Divide:
10177c478bd9Sstevel@tonic-gate case OP_Remainder: {
10187c478bd9Sstevel@tonic-gate   Mem *pNos = &pTos[-1];
10197c478bd9Sstevel@tonic-gate   assert( pNos>=p->aStack );
10207c478bd9Sstevel@tonic-gate   if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){
10217c478bd9Sstevel@tonic-gate     Release(pTos);
10227c478bd9Sstevel@tonic-gate     pTos--;
10237c478bd9Sstevel@tonic-gate     Release(pTos);
10247c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
10257c478bd9Sstevel@tonic-gate   }else if( (pTos->flags & pNos->flags & MEM_Int)==MEM_Int ){
10267c478bd9Sstevel@tonic-gate     int a, b;
10277c478bd9Sstevel@tonic-gate     a = pTos->i;
10287c478bd9Sstevel@tonic-gate     b = pNos->i;
10297c478bd9Sstevel@tonic-gate     switch( pOp->opcode ){
10307c478bd9Sstevel@tonic-gate       case OP_Add:         b += a;       break;
10317c478bd9Sstevel@tonic-gate       case OP_Subtract:    b -= a;       break;
10327c478bd9Sstevel@tonic-gate       case OP_Multiply:    b *= a;       break;
10337c478bd9Sstevel@tonic-gate       case OP_Divide: {
10347c478bd9Sstevel@tonic-gate         if( a==0 ) goto divide_by_zero;
10357c478bd9Sstevel@tonic-gate         b /= a;
10367c478bd9Sstevel@tonic-gate         break;
10377c478bd9Sstevel@tonic-gate       }
10387c478bd9Sstevel@tonic-gate       default: {
10397c478bd9Sstevel@tonic-gate         if( a==0 ) goto divide_by_zero;
10407c478bd9Sstevel@tonic-gate         b %= a;
10417c478bd9Sstevel@tonic-gate         break;
10427c478bd9Sstevel@tonic-gate       }
10437c478bd9Sstevel@tonic-gate     }
10447c478bd9Sstevel@tonic-gate     Release(pTos);
10457c478bd9Sstevel@tonic-gate     pTos--;
10467c478bd9Sstevel@tonic-gate     Release(pTos);
10477c478bd9Sstevel@tonic-gate     pTos->i = b;
10487c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Int;
10497c478bd9Sstevel@tonic-gate   }else{
10507c478bd9Sstevel@tonic-gate     double a, b;
10517c478bd9Sstevel@tonic-gate     Realify(pTos);
10527c478bd9Sstevel@tonic-gate     Realify(pNos);
10537c478bd9Sstevel@tonic-gate     a = pTos->r;
10547c478bd9Sstevel@tonic-gate     b = pNos->r;
10557c478bd9Sstevel@tonic-gate     switch( pOp->opcode ){
10567c478bd9Sstevel@tonic-gate       case OP_Add:         b += a;       break;
10577c478bd9Sstevel@tonic-gate       case OP_Subtract:    b -= a;       break;
10587c478bd9Sstevel@tonic-gate       case OP_Multiply:    b *= a;       break;
10597c478bd9Sstevel@tonic-gate       case OP_Divide: {
10607c478bd9Sstevel@tonic-gate         if( a==0.0 ) goto divide_by_zero;
10617c478bd9Sstevel@tonic-gate         b /= a;
10627c478bd9Sstevel@tonic-gate         break;
10637c478bd9Sstevel@tonic-gate       }
10647c478bd9Sstevel@tonic-gate       default: {
10657c478bd9Sstevel@tonic-gate         int ia = (int)a;
10667c478bd9Sstevel@tonic-gate         int ib = (int)b;
10677c478bd9Sstevel@tonic-gate         if( ia==0.0 ) goto divide_by_zero;
10687c478bd9Sstevel@tonic-gate         b = ib % ia;
10697c478bd9Sstevel@tonic-gate         break;
10707c478bd9Sstevel@tonic-gate       }
10717c478bd9Sstevel@tonic-gate     }
10727c478bd9Sstevel@tonic-gate     Release(pTos);
10737c478bd9Sstevel@tonic-gate     pTos--;
10747c478bd9Sstevel@tonic-gate     Release(pTos);
10757c478bd9Sstevel@tonic-gate     pTos->r = b;
10767c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Real;
10777c478bd9Sstevel@tonic-gate   }
10787c478bd9Sstevel@tonic-gate   break;
10797c478bd9Sstevel@tonic-gate 
10807c478bd9Sstevel@tonic-gate divide_by_zero:
10817c478bd9Sstevel@tonic-gate   Release(pTos);
10827c478bd9Sstevel@tonic-gate   pTos--;
10837c478bd9Sstevel@tonic-gate   Release(pTos);
10847c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Null;
10857c478bd9Sstevel@tonic-gate   break;
10867c478bd9Sstevel@tonic-gate }
10877c478bd9Sstevel@tonic-gate 
10887c478bd9Sstevel@tonic-gate /* Opcode: Function P1 * P3
10897c478bd9Sstevel@tonic-gate **
10907c478bd9Sstevel@tonic-gate ** Invoke a user function (P3 is a pointer to a Function structure that
10917c478bd9Sstevel@tonic-gate ** defines the function) with P1 string arguments taken from the stack.
10927c478bd9Sstevel@tonic-gate ** Pop all arguments from the stack and push back the result.
10937c478bd9Sstevel@tonic-gate **
10947c478bd9Sstevel@tonic-gate ** See also: AggFunc
10957c478bd9Sstevel@tonic-gate */
10967c478bd9Sstevel@tonic-gate case OP_Function: {
10977c478bd9Sstevel@tonic-gate   int n, i;
10987c478bd9Sstevel@tonic-gate   Mem *pArg;
10997c478bd9Sstevel@tonic-gate   char **azArgv;
11007c478bd9Sstevel@tonic-gate   sqlite_func ctx;
11017c478bd9Sstevel@tonic-gate 
11027c478bd9Sstevel@tonic-gate   n = pOp->p1;
11037c478bd9Sstevel@tonic-gate   pArg = &pTos[1-n];
11047c478bd9Sstevel@tonic-gate   azArgv = p->zArgv;
11057c478bd9Sstevel@tonic-gate   for(i=0; i<n; i++, pArg++){
11067c478bd9Sstevel@tonic-gate     if( pArg->flags & MEM_Null ){
11077c478bd9Sstevel@tonic-gate       azArgv[i] = 0;
11087c478bd9Sstevel@tonic-gate     }else{
11097c478bd9Sstevel@tonic-gate       Stringify(pArg);
11107c478bd9Sstevel@tonic-gate       azArgv[i] = pArg->z;
11117c478bd9Sstevel@tonic-gate     }
11127c478bd9Sstevel@tonic-gate   }
11137c478bd9Sstevel@tonic-gate   ctx.pFunc = (FuncDef*)pOp->p3;
11147c478bd9Sstevel@tonic-gate   ctx.s.flags = MEM_Null;
11157c478bd9Sstevel@tonic-gate   ctx.s.z = 0;
11167c478bd9Sstevel@tonic-gate   ctx.isError = 0;
11177c478bd9Sstevel@tonic-gate   ctx.isStep = 0;
11187c478bd9Sstevel@tonic-gate   if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
11197c478bd9Sstevel@tonic-gate   (*ctx.pFunc->xFunc)(&ctx, n, (const char**)azArgv);
11207c478bd9Sstevel@tonic-gate   if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
11217c478bd9Sstevel@tonic-gate   popStack(&pTos, n);
11227c478bd9Sstevel@tonic-gate   pTos++;
11237c478bd9Sstevel@tonic-gate   *pTos = ctx.s;
11247c478bd9Sstevel@tonic-gate   if( pTos->flags & MEM_Short ){
11257c478bd9Sstevel@tonic-gate     pTos->z = pTos->zShort;
11267c478bd9Sstevel@tonic-gate   }
11277c478bd9Sstevel@tonic-gate   if( ctx.isError ){
1128*55fea89dSDan Cross     sqliteSetString(&p->zErrMsg,
11297c478bd9Sstevel@tonic-gate        (pTos->flags & MEM_Str)!=0 ? pTos->z : "user function error", (char*)0);
11307c478bd9Sstevel@tonic-gate     rc = SQLITE_ERROR;
11317c478bd9Sstevel@tonic-gate   }
11327c478bd9Sstevel@tonic-gate   break;
11337c478bd9Sstevel@tonic-gate }
11347c478bd9Sstevel@tonic-gate 
11357c478bd9Sstevel@tonic-gate /* Opcode: BitAnd * * *
11367c478bd9Sstevel@tonic-gate **
11377c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  Convert both elements
11387c478bd9Sstevel@tonic-gate ** to integers.  Push back onto the stack the bit-wise AND of the
11397c478bd9Sstevel@tonic-gate ** two elements.
11407c478bd9Sstevel@tonic-gate ** If either operand is NULL, the result is NULL.
11417c478bd9Sstevel@tonic-gate */
11427c478bd9Sstevel@tonic-gate /* Opcode: BitOr * * *
11437c478bd9Sstevel@tonic-gate **
11447c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  Convert both elements
11457c478bd9Sstevel@tonic-gate ** to integers.  Push back onto the stack the bit-wise OR of the
11467c478bd9Sstevel@tonic-gate ** two elements.
11477c478bd9Sstevel@tonic-gate ** If either operand is NULL, the result is NULL.
11487c478bd9Sstevel@tonic-gate */
11497c478bd9Sstevel@tonic-gate /* Opcode: ShiftLeft * * *
11507c478bd9Sstevel@tonic-gate **
11517c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  Convert both elements
11527c478bd9Sstevel@tonic-gate ** to integers.  Push back onto the stack the top element shifted
11537c478bd9Sstevel@tonic-gate ** left by N bits where N is the second element on the stack.
11547c478bd9Sstevel@tonic-gate ** If either operand is NULL, the result is NULL.
11557c478bd9Sstevel@tonic-gate */
11567c478bd9Sstevel@tonic-gate /* Opcode: ShiftRight * * *
11577c478bd9Sstevel@tonic-gate **
11587c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  Convert both elements
11597c478bd9Sstevel@tonic-gate ** to integers.  Push back onto the stack the top element shifted
11607c478bd9Sstevel@tonic-gate ** right by N bits where N is the second element on the stack.
11617c478bd9Sstevel@tonic-gate ** If either operand is NULL, the result is NULL.
11627c478bd9Sstevel@tonic-gate */
11637c478bd9Sstevel@tonic-gate case OP_BitAnd:
11647c478bd9Sstevel@tonic-gate case OP_BitOr:
11657c478bd9Sstevel@tonic-gate case OP_ShiftLeft:
11667c478bd9Sstevel@tonic-gate case OP_ShiftRight: {
11677c478bd9Sstevel@tonic-gate   Mem *pNos = &pTos[-1];
11687c478bd9Sstevel@tonic-gate   int a, b;
11697c478bd9Sstevel@tonic-gate 
11707c478bd9Sstevel@tonic-gate   assert( pNos>=p->aStack );
11717c478bd9Sstevel@tonic-gate   if( (pTos->flags | pNos->flags) & MEM_Null ){
11727c478bd9Sstevel@tonic-gate     popStack(&pTos, 2);
11737c478bd9Sstevel@tonic-gate     pTos++;
11747c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
11757c478bd9Sstevel@tonic-gate     break;
11767c478bd9Sstevel@tonic-gate   }
11777c478bd9Sstevel@tonic-gate   Integerify(pTos);
11787c478bd9Sstevel@tonic-gate   Integerify(pNos);
11797c478bd9Sstevel@tonic-gate   a = pTos->i;
11807c478bd9Sstevel@tonic-gate   b = pNos->i;
11817c478bd9Sstevel@tonic-gate   switch( pOp->opcode ){
11827c478bd9Sstevel@tonic-gate     case OP_BitAnd:      a &= b;     break;
11837c478bd9Sstevel@tonic-gate     case OP_BitOr:       a |= b;     break;
11847c478bd9Sstevel@tonic-gate     case OP_ShiftLeft:   a <<= b;    break;
11857c478bd9Sstevel@tonic-gate     case OP_ShiftRight:  a >>= b;    break;
11867c478bd9Sstevel@tonic-gate     default:   /* CANT HAPPEN */     break;
11877c478bd9Sstevel@tonic-gate   }
11887c478bd9Sstevel@tonic-gate   assert( (pTos->flags & MEM_Dyn)==0 );
11897c478bd9Sstevel@tonic-gate   assert( (pNos->flags & MEM_Dyn)==0 );
11907c478bd9Sstevel@tonic-gate   pTos--;
11917c478bd9Sstevel@tonic-gate   Release(pTos);
11927c478bd9Sstevel@tonic-gate   pTos->i = a;
11937c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Int;
11947c478bd9Sstevel@tonic-gate   break;
11957c478bd9Sstevel@tonic-gate }
11967c478bd9Sstevel@tonic-gate 
11977c478bd9Sstevel@tonic-gate /* Opcode: AddImm  P1 * *
1198*55fea89dSDan Cross **
11997c478bd9Sstevel@tonic-gate ** Add the value P1 to whatever is on top of the stack.  The result
12007c478bd9Sstevel@tonic-gate ** is always an integer.
12017c478bd9Sstevel@tonic-gate **
12027c478bd9Sstevel@tonic-gate ** To force the top of the stack to be an integer, just add 0.
12037c478bd9Sstevel@tonic-gate */
12047c478bd9Sstevel@tonic-gate case OP_AddImm: {
12057c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
12067c478bd9Sstevel@tonic-gate   Integerify(pTos);
12077c478bd9Sstevel@tonic-gate   pTos->i += pOp->p1;
12087c478bd9Sstevel@tonic-gate   break;
12097c478bd9Sstevel@tonic-gate }
12107c478bd9Sstevel@tonic-gate 
12117c478bd9Sstevel@tonic-gate /* Opcode: ForceInt P1 P2 *
12127c478bd9Sstevel@tonic-gate **
12137c478bd9Sstevel@tonic-gate ** Convert the top of the stack into an integer.  If the current top of
12147c478bd9Sstevel@tonic-gate ** the stack is not numeric (meaning that is is a NULL or a string that
12157c478bd9Sstevel@tonic-gate ** does not look like an integer or floating point number) then pop the
12167c478bd9Sstevel@tonic-gate ** stack and jump to P2.  If the top of the stack is numeric then
12177c478bd9Sstevel@tonic-gate ** convert it into the least integer that is greater than or equal to its
12187c478bd9Sstevel@tonic-gate ** current value if P1==0, or to the least integer that is strictly
12197c478bd9Sstevel@tonic-gate ** greater than its current value if P1==1.
12207c478bd9Sstevel@tonic-gate */
12217c478bd9Sstevel@tonic-gate case OP_ForceInt: {
12227c478bd9Sstevel@tonic-gate   int v;
12237c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
12247c478bd9Sstevel@tonic-gate   if( (pTos->flags & (MEM_Int|MEM_Real))==0
12257c478bd9Sstevel@tonic-gate          && ((pTos->flags & MEM_Str)==0 || sqliteIsNumber(pTos->z)==0) ){
12267c478bd9Sstevel@tonic-gate     Release(pTos);
12277c478bd9Sstevel@tonic-gate     pTos--;
12287c478bd9Sstevel@tonic-gate     pc = pOp->p2 - 1;
12297c478bd9Sstevel@tonic-gate     break;
12307c478bd9Sstevel@tonic-gate   }
12317c478bd9Sstevel@tonic-gate   if( pTos->flags & MEM_Int ){
12327c478bd9Sstevel@tonic-gate     v = pTos->i + (pOp->p1!=0);
12337c478bd9Sstevel@tonic-gate   }else{
12347c478bd9Sstevel@tonic-gate     Realify(pTos);
12357c478bd9Sstevel@tonic-gate     v = (int)pTos->r;
12367c478bd9Sstevel@tonic-gate     if( pTos->r>(double)v ) v++;
12377c478bd9Sstevel@tonic-gate     if( pOp->p1 && pTos->r==(double)v ) v++;
12387c478bd9Sstevel@tonic-gate   }
12397c478bd9Sstevel@tonic-gate   Release(pTos);
12407c478bd9Sstevel@tonic-gate   pTos->i = v;
12417c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Int;
12427c478bd9Sstevel@tonic-gate   break;
12437c478bd9Sstevel@tonic-gate }
12447c478bd9Sstevel@tonic-gate 
12457c478bd9Sstevel@tonic-gate /* Opcode: MustBeInt P1 P2 *
1246*55fea89dSDan Cross **
12477c478bd9Sstevel@tonic-gate ** Force the top of the stack to be an integer.  If the top of the
12487c478bd9Sstevel@tonic-gate ** stack is not an integer and cannot be converted into an integer
12497c478bd9Sstevel@tonic-gate ** with out data loss, then jump immediately to P2, or if P2==0
12507c478bd9Sstevel@tonic-gate ** raise an SQLITE_MISMATCH exception.
12517c478bd9Sstevel@tonic-gate **
12527c478bd9Sstevel@tonic-gate ** If the top of the stack is not an integer and P2 is not zero and
12537c478bd9Sstevel@tonic-gate ** P1 is 1, then the stack is popped.  In all other cases, the depth
12547c478bd9Sstevel@tonic-gate ** of the stack is unchanged.
12557c478bd9Sstevel@tonic-gate */
12567c478bd9Sstevel@tonic-gate case OP_MustBeInt: {
12577c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
12587c478bd9Sstevel@tonic-gate   if( pTos->flags & MEM_Int ){
12597c478bd9Sstevel@tonic-gate     /* Do nothing */
12607c478bd9Sstevel@tonic-gate   }else if( pTos->flags & MEM_Real ){
12617c478bd9Sstevel@tonic-gate     int i = (int)pTos->r;
12627c478bd9Sstevel@tonic-gate     double r = (double)i;
12637c478bd9Sstevel@tonic-gate     if( r!=pTos->r ){
12647c478bd9Sstevel@tonic-gate       goto mismatch;
12657c478bd9Sstevel@tonic-gate     }
12667c478bd9Sstevel@tonic-gate     pTos->i = i;
12677c478bd9Sstevel@tonic-gate   }else if( pTos->flags & MEM_Str ){
12687c478bd9Sstevel@tonic-gate     int v;
12697c478bd9Sstevel@tonic-gate     if( !toInt(pTos->z, &v) ){
12707c478bd9Sstevel@tonic-gate       double r;
12717c478bd9Sstevel@tonic-gate       if( !sqliteIsNumber(pTos->z) ){
12727c478bd9Sstevel@tonic-gate         goto mismatch;
12737c478bd9Sstevel@tonic-gate       }
12747c478bd9Sstevel@tonic-gate       Realify(pTos);
12757c478bd9Sstevel@tonic-gate       v = (int)pTos->r;
12767c478bd9Sstevel@tonic-gate       r = (double)v;
12777c478bd9Sstevel@tonic-gate       if( r!=pTos->r ){
12787c478bd9Sstevel@tonic-gate         goto mismatch;
12797c478bd9Sstevel@tonic-gate       }
12807c478bd9Sstevel@tonic-gate     }
12817c478bd9Sstevel@tonic-gate     pTos->i = v;
12827c478bd9Sstevel@tonic-gate   }else{
12837c478bd9Sstevel@tonic-gate     goto mismatch;
12847c478bd9Sstevel@tonic-gate   }
12857c478bd9Sstevel@tonic-gate   Release(pTos);
12867c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Int;
12877c478bd9Sstevel@tonic-gate   break;
12887c478bd9Sstevel@tonic-gate 
12897c478bd9Sstevel@tonic-gate mismatch:
12907c478bd9Sstevel@tonic-gate   if( pOp->p2==0 ){
12917c478bd9Sstevel@tonic-gate     rc = SQLITE_MISMATCH;
12927c478bd9Sstevel@tonic-gate     goto abort_due_to_error;
12937c478bd9Sstevel@tonic-gate   }else{
12947c478bd9Sstevel@tonic-gate     if( pOp->p1 ) popStack(&pTos, 1);
12957c478bd9Sstevel@tonic-gate     pc = pOp->p2 - 1;
12967c478bd9Sstevel@tonic-gate   }
12977c478bd9Sstevel@tonic-gate   break;
12987c478bd9Sstevel@tonic-gate }
12997c478bd9Sstevel@tonic-gate 
13007c478bd9Sstevel@tonic-gate /* Opcode: Eq P1 P2 *
13017c478bd9Sstevel@tonic-gate **
13027c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  If they are equal, then
13037c478bd9Sstevel@tonic-gate ** jump to instruction P2.  Otherwise, continue to the next instruction.
13047c478bd9Sstevel@tonic-gate **
13057c478bd9Sstevel@tonic-gate ** If either operand is NULL (and thus if the result is unknown) then
13067c478bd9Sstevel@tonic-gate ** take the jump if P1 is true.
13077c478bd9Sstevel@tonic-gate **
13087c478bd9Sstevel@tonic-gate ** If both values are numeric, they are converted to doubles using atof()
13097c478bd9Sstevel@tonic-gate ** and compared for equality that way.  Otherwise the strcmp() library
13107c478bd9Sstevel@tonic-gate ** routine is used for the comparison.  For a pure text comparison
13117c478bd9Sstevel@tonic-gate ** use OP_StrEq.
13127c478bd9Sstevel@tonic-gate **
13137c478bd9Sstevel@tonic-gate ** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
13147c478bd9Sstevel@tonic-gate ** stack if the jump would have been taken, or a 0 if not.  Push a
13157c478bd9Sstevel@tonic-gate ** NULL if either operand was NULL.
13167c478bd9Sstevel@tonic-gate */
13177c478bd9Sstevel@tonic-gate /* Opcode: Ne P1 P2 *
13187c478bd9Sstevel@tonic-gate **
13197c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  If they are not equal, then
13207c478bd9Sstevel@tonic-gate ** jump to instruction P2.  Otherwise, continue to the next instruction.
13217c478bd9Sstevel@tonic-gate **
13227c478bd9Sstevel@tonic-gate ** If either operand is NULL (and thus if the result is unknown) then
13237c478bd9Sstevel@tonic-gate ** take the jump if P1 is true.
13247c478bd9Sstevel@tonic-gate **
13257c478bd9Sstevel@tonic-gate ** If both values are numeric, they are converted to doubles using atof()
13267c478bd9Sstevel@tonic-gate ** and compared in that format.  Otherwise the strcmp() library
13277c478bd9Sstevel@tonic-gate ** routine is used for the comparison.  For a pure text comparison
13287c478bd9Sstevel@tonic-gate ** use OP_StrNe.
13297c478bd9Sstevel@tonic-gate **
13307c478bd9Sstevel@tonic-gate ** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
13317c478bd9Sstevel@tonic-gate ** stack if the jump would have been taken, or a 0 if not.  Push a
13327c478bd9Sstevel@tonic-gate ** NULL if either operand was NULL.
13337c478bd9Sstevel@tonic-gate */
13347c478bd9Sstevel@tonic-gate /* Opcode: Lt P1 P2 *
13357c478bd9Sstevel@tonic-gate **
13367c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  If second element (the
13377c478bd9Sstevel@tonic-gate ** next on stack) is less than the first (the top of stack), then
13387c478bd9Sstevel@tonic-gate ** jump to instruction P2.  Otherwise, continue to the next instruction.
13397c478bd9Sstevel@tonic-gate ** In other words, jump if NOS<TOS.
13407c478bd9Sstevel@tonic-gate **
13417c478bd9Sstevel@tonic-gate ** If either operand is NULL (and thus if the result is unknown) then
13427c478bd9Sstevel@tonic-gate ** take the jump if P1 is true.
13437c478bd9Sstevel@tonic-gate **
13447c478bd9Sstevel@tonic-gate ** If both values are numeric, they are converted to doubles using atof()
13457c478bd9Sstevel@tonic-gate ** and compared in that format.  Numeric values are always less than
13467c478bd9Sstevel@tonic-gate ** non-numeric values.  If both operands are non-numeric, the strcmp() library
13477c478bd9Sstevel@tonic-gate ** routine is used for the comparison.  For a pure text comparison
13487c478bd9Sstevel@tonic-gate ** use OP_StrLt.
13497c478bd9Sstevel@tonic-gate **
13507c478bd9Sstevel@tonic-gate ** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
13517c478bd9Sstevel@tonic-gate ** stack if the jump would have been taken, or a 0 if not.  Push a
13527c478bd9Sstevel@tonic-gate ** NULL if either operand was NULL.
13537c478bd9Sstevel@tonic-gate */
13547c478bd9Sstevel@tonic-gate /* Opcode: Le P1 P2 *
13557c478bd9Sstevel@tonic-gate **
13567c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  If second element (the
13577c478bd9Sstevel@tonic-gate ** next on stack) is less than or equal to the first (the top of stack),
13587c478bd9Sstevel@tonic-gate ** then jump to instruction P2. In other words, jump if NOS<=TOS.
13597c478bd9Sstevel@tonic-gate **
13607c478bd9Sstevel@tonic-gate ** If either operand is NULL (and thus if the result is unknown) then
13617c478bd9Sstevel@tonic-gate ** take the jump if P1 is true.
13627c478bd9Sstevel@tonic-gate **
13637c478bd9Sstevel@tonic-gate ** If both values are numeric, they are converted to doubles using atof()
13647c478bd9Sstevel@tonic-gate ** and compared in that format.  Numeric values are always less than
13657c478bd9Sstevel@tonic-gate ** non-numeric values.  If both operands are non-numeric, the strcmp() library
13667c478bd9Sstevel@tonic-gate ** routine is used for the comparison.  For a pure text comparison
13677c478bd9Sstevel@tonic-gate ** use OP_StrLe.
13687c478bd9Sstevel@tonic-gate **
13697c478bd9Sstevel@tonic-gate ** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
13707c478bd9Sstevel@tonic-gate ** stack if the jump would have been taken, or a 0 if not.  Push a
13717c478bd9Sstevel@tonic-gate ** NULL if either operand was NULL.
13727c478bd9Sstevel@tonic-gate */
13737c478bd9Sstevel@tonic-gate /* Opcode: Gt P1 P2 *
13747c478bd9Sstevel@tonic-gate **
13757c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  If second element (the
13767c478bd9Sstevel@tonic-gate ** next on stack) is greater than the first (the top of stack),
13777c478bd9Sstevel@tonic-gate ** then jump to instruction P2. In other words, jump if NOS>TOS.
13787c478bd9Sstevel@tonic-gate **
13797c478bd9Sstevel@tonic-gate ** If either operand is NULL (and thus if the result is unknown) then
13807c478bd9Sstevel@tonic-gate ** take the jump if P1 is true.
13817c478bd9Sstevel@tonic-gate **
13827c478bd9Sstevel@tonic-gate ** If both values are numeric, they are converted to doubles using atof()
13837c478bd9Sstevel@tonic-gate ** and compared in that format.  Numeric values are always less than
13847c478bd9Sstevel@tonic-gate ** non-numeric values.  If both operands are non-numeric, the strcmp() library
13857c478bd9Sstevel@tonic-gate ** routine is used for the comparison.  For a pure text comparison
13867c478bd9Sstevel@tonic-gate ** use OP_StrGt.
13877c478bd9Sstevel@tonic-gate **
13887c478bd9Sstevel@tonic-gate ** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
13897c478bd9Sstevel@tonic-gate ** stack if the jump would have been taken, or a 0 if not.  Push a
13907c478bd9Sstevel@tonic-gate ** NULL if either operand was NULL.
13917c478bd9Sstevel@tonic-gate */
13927c478bd9Sstevel@tonic-gate /* Opcode: Ge P1 P2 *
13937c478bd9Sstevel@tonic-gate **
13947c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  If second element (the next
13957c478bd9Sstevel@tonic-gate ** on stack) is greater than or equal to the first (the top of stack),
13967c478bd9Sstevel@tonic-gate ** then jump to instruction P2. In other words, jump if NOS>=TOS.
13977c478bd9Sstevel@tonic-gate **
13987c478bd9Sstevel@tonic-gate ** If either operand is NULL (and thus if the result is unknown) then
13997c478bd9Sstevel@tonic-gate ** take the jump if P1 is true.
14007c478bd9Sstevel@tonic-gate **
14017c478bd9Sstevel@tonic-gate ** If both values are numeric, they are converted to doubles using atof()
14027c478bd9Sstevel@tonic-gate ** and compared in that format.  Numeric values are always less than
14037c478bd9Sstevel@tonic-gate ** non-numeric values.  If both operands are non-numeric, the strcmp() library
14047c478bd9Sstevel@tonic-gate ** routine is used for the comparison.  For a pure text comparison
14057c478bd9Sstevel@tonic-gate ** use OP_StrGe.
14067c478bd9Sstevel@tonic-gate **
14077c478bd9Sstevel@tonic-gate ** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
14087c478bd9Sstevel@tonic-gate ** stack if the jump would have been taken, or a 0 if not.  Push a
14097c478bd9Sstevel@tonic-gate ** NULL if either operand was NULL.
14107c478bd9Sstevel@tonic-gate */
14117c478bd9Sstevel@tonic-gate case OP_Eq:
14127c478bd9Sstevel@tonic-gate case OP_Ne:
14137c478bd9Sstevel@tonic-gate case OP_Lt:
14147c478bd9Sstevel@tonic-gate case OP_Le:
14157c478bd9Sstevel@tonic-gate case OP_Gt:
14167c478bd9Sstevel@tonic-gate case OP_Ge: {
14177c478bd9Sstevel@tonic-gate   Mem *pNos = &pTos[-1];
14187c478bd9Sstevel@tonic-gate   int c, v;
14197c478bd9Sstevel@tonic-gate   int ft, fn;
14207c478bd9Sstevel@tonic-gate   assert( pNos>=p->aStack );
14217c478bd9Sstevel@tonic-gate   ft = pTos->flags;
14227c478bd9Sstevel@tonic-gate   fn = pNos->flags;
14237c478bd9Sstevel@tonic-gate   if( (ft | fn) & MEM_Null ){
14247c478bd9Sstevel@tonic-gate     popStack(&pTos, 2);
14257c478bd9Sstevel@tonic-gate     if( pOp->p2 ){
14267c478bd9Sstevel@tonic-gate       if( pOp->p1 ) pc = pOp->p2-1;
14277c478bd9Sstevel@tonic-gate     }else{
14287c478bd9Sstevel@tonic-gate       pTos++;
14297c478bd9Sstevel@tonic-gate       pTos->flags = MEM_Null;
14307c478bd9Sstevel@tonic-gate     }
14317c478bd9Sstevel@tonic-gate     break;
14327c478bd9Sstevel@tonic-gate   }else if( (ft & fn & MEM_Int)==MEM_Int ){
14337c478bd9Sstevel@tonic-gate     c = pNos->i - pTos->i;
14347c478bd9Sstevel@tonic-gate   }else if( (ft & MEM_Int)!=0 && (fn & MEM_Str)!=0 && toInt(pNos->z,&v) ){
14357c478bd9Sstevel@tonic-gate     c = v - pTos->i;
14367c478bd9Sstevel@tonic-gate   }else if( (fn & MEM_Int)!=0 && (ft & MEM_Str)!=0 && toInt(pTos->z,&v) ){
14377c478bd9Sstevel@tonic-gate     c = pNos->i - v;
14387c478bd9Sstevel@tonic-gate   }else{
14397c478bd9Sstevel@tonic-gate     Stringify(pTos);
14407c478bd9Sstevel@tonic-gate     Stringify(pNos);
14417c478bd9Sstevel@tonic-gate     c = sqliteCompare(pNos->z, pTos->z);
14427c478bd9Sstevel@tonic-gate   }
14437c478bd9Sstevel@tonic-gate   switch( pOp->opcode ){
14447c478bd9Sstevel@tonic-gate     case OP_Eq:    c = c==0;     break;
14457c478bd9Sstevel@tonic-gate     case OP_Ne:    c = c!=0;     break;
14467c478bd9Sstevel@tonic-gate     case OP_Lt:    c = c<0;      break;
14477c478bd9Sstevel@tonic-gate     case OP_Le:    c = c<=0;     break;
14487c478bd9Sstevel@tonic-gate     case OP_Gt:    c = c>0;      break;
14497c478bd9Sstevel@tonic-gate     default:       c = c>=0;     break;
14507c478bd9Sstevel@tonic-gate   }
14517c478bd9Sstevel@tonic-gate   popStack(&pTos, 2);
14527c478bd9Sstevel@tonic-gate   if( pOp->p2 ){
14537c478bd9Sstevel@tonic-gate     if( c ) pc = pOp->p2-1;
14547c478bd9Sstevel@tonic-gate   }else{
14557c478bd9Sstevel@tonic-gate     pTos++;
14567c478bd9Sstevel@tonic-gate     pTos->i = c;
14577c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Int;
14587c478bd9Sstevel@tonic-gate   }
14597c478bd9Sstevel@tonic-gate   break;
14607c478bd9Sstevel@tonic-gate }
14617c478bd9Sstevel@tonic-gate /* INSERT NO CODE HERE!
14627c478bd9Sstevel@tonic-gate **
14637c478bd9Sstevel@tonic-gate ** The opcode numbers are extracted from this source file by doing
14647c478bd9Sstevel@tonic-gate **
14657c478bd9Sstevel@tonic-gate **    grep '^case OP_' vdbe.c | ... >opcodes.h
14667c478bd9Sstevel@tonic-gate **
14677c478bd9Sstevel@tonic-gate ** The opcodes are numbered in the order that they appear in this file.
14687c478bd9Sstevel@tonic-gate ** But in order for the expression generating code to work right, the
14697c478bd9Sstevel@tonic-gate ** string comparison operators that follow must be numbered exactly 6
14707c478bd9Sstevel@tonic-gate ** greater than the numeric comparison opcodes above.  So no other
14717c478bd9Sstevel@tonic-gate ** cases can appear between the two.
14727c478bd9Sstevel@tonic-gate */
14737c478bd9Sstevel@tonic-gate /* Opcode: StrEq P1 P2 *
14747c478bd9Sstevel@tonic-gate **
14757c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  If they are equal, then
14767c478bd9Sstevel@tonic-gate ** jump to instruction P2.  Otherwise, continue to the next instruction.
14777c478bd9Sstevel@tonic-gate **
14787c478bd9Sstevel@tonic-gate ** If either operand is NULL (and thus if the result is unknown) then
14797c478bd9Sstevel@tonic-gate ** take the jump if P1 is true.
14807c478bd9Sstevel@tonic-gate **
14817c478bd9Sstevel@tonic-gate ** The strcmp() library routine is used for the comparison.  For a
14827c478bd9Sstevel@tonic-gate ** numeric comparison, use OP_Eq.
14837c478bd9Sstevel@tonic-gate **
14847c478bd9Sstevel@tonic-gate ** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
14857c478bd9Sstevel@tonic-gate ** stack if the jump would have been taken, or a 0 if not.  Push a
14867c478bd9Sstevel@tonic-gate ** NULL if either operand was NULL.
14877c478bd9Sstevel@tonic-gate */
14887c478bd9Sstevel@tonic-gate /* Opcode: StrNe P1 P2 *
14897c478bd9Sstevel@tonic-gate **
14907c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  If they are not equal, then
14917c478bd9Sstevel@tonic-gate ** jump to instruction P2.  Otherwise, continue to the next instruction.
14927c478bd9Sstevel@tonic-gate **
14937c478bd9Sstevel@tonic-gate ** If either operand is NULL (and thus if the result is unknown) then
14947c478bd9Sstevel@tonic-gate ** take the jump if P1 is true.
14957c478bd9Sstevel@tonic-gate **
14967c478bd9Sstevel@tonic-gate ** The strcmp() library routine is used for the comparison.  For a
14977c478bd9Sstevel@tonic-gate ** numeric comparison, use OP_Ne.
14987c478bd9Sstevel@tonic-gate **
14997c478bd9Sstevel@tonic-gate ** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
15007c478bd9Sstevel@tonic-gate ** stack if the jump would have been taken, or a 0 if not.  Push a
15017c478bd9Sstevel@tonic-gate ** NULL if either operand was NULL.
15027c478bd9Sstevel@tonic-gate */
15037c478bd9Sstevel@tonic-gate /* Opcode: StrLt P1 P2 *
15047c478bd9Sstevel@tonic-gate **
15057c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  If second element (the
15067c478bd9Sstevel@tonic-gate ** next on stack) is less than the first (the top of stack), then
15077c478bd9Sstevel@tonic-gate ** jump to instruction P2.  Otherwise, continue to the next instruction.
15087c478bd9Sstevel@tonic-gate ** In other words, jump if NOS<TOS.
15097c478bd9Sstevel@tonic-gate **
15107c478bd9Sstevel@tonic-gate ** If either operand is NULL (and thus if the result is unknown) then
15117c478bd9Sstevel@tonic-gate ** take the jump if P1 is true.
15127c478bd9Sstevel@tonic-gate **
15137c478bd9Sstevel@tonic-gate ** The strcmp() library routine is used for the comparison.  For a
15147c478bd9Sstevel@tonic-gate ** numeric comparison, use OP_Lt.
15157c478bd9Sstevel@tonic-gate **
15167c478bd9Sstevel@tonic-gate ** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
15177c478bd9Sstevel@tonic-gate ** stack if the jump would have been taken, or a 0 if not.  Push a
15187c478bd9Sstevel@tonic-gate ** NULL if either operand was NULL.
15197c478bd9Sstevel@tonic-gate */
15207c478bd9Sstevel@tonic-gate /* Opcode: StrLe P1 P2 *
15217c478bd9Sstevel@tonic-gate **
15227c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  If second element (the
15237c478bd9Sstevel@tonic-gate ** next on stack) is less than or equal to the first (the top of stack),
15247c478bd9Sstevel@tonic-gate ** then jump to instruction P2. In other words, jump if NOS<=TOS.
15257c478bd9Sstevel@tonic-gate **
15267c478bd9Sstevel@tonic-gate ** If either operand is NULL (and thus if the result is unknown) then
15277c478bd9Sstevel@tonic-gate ** take the jump if P1 is true.
15287c478bd9Sstevel@tonic-gate **
15297c478bd9Sstevel@tonic-gate ** The strcmp() library routine is used for the comparison.  For a
15307c478bd9Sstevel@tonic-gate ** numeric comparison, use OP_Le.
15317c478bd9Sstevel@tonic-gate **
15327c478bd9Sstevel@tonic-gate ** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
15337c478bd9Sstevel@tonic-gate ** stack if the jump would have been taken, or a 0 if not.  Push a
15347c478bd9Sstevel@tonic-gate ** NULL if either operand was NULL.
15357c478bd9Sstevel@tonic-gate */
15367c478bd9Sstevel@tonic-gate /* Opcode: StrGt P1 P2 *
15377c478bd9Sstevel@tonic-gate **
15387c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  If second element (the
15397c478bd9Sstevel@tonic-gate ** next on stack) is greater than the first (the top of stack),
15407c478bd9Sstevel@tonic-gate ** then jump to instruction P2. In other words, jump if NOS>TOS.
15417c478bd9Sstevel@tonic-gate **
15427c478bd9Sstevel@tonic-gate ** If either operand is NULL (and thus if the result is unknown) then
15437c478bd9Sstevel@tonic-gate ** take the jump if P1 is true.
15447c478bd9Sstevel@tonic-gate **
15457c478bd9Sstevel@tonic-gate ** The strcmp() library routine is used for the comparison.  For a
15467c478bd9Sstevel@tonic-gate ** numeric comparison, use OP_Gt.
15477c478bd9Sstevel@tonic-gate **
15487c478bd9Sstevel@tonic-gate ** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
15497c478bd9Sstevel@tonic-gate ** stack if the jump would have been taken, or a 0 if not.  Push a
15507c478bd9Sstevel@tonic-gate ** NULL if either operand was NULL.
15517c478bd9Sstevel@tonic-gate */
15527c478bd9Sstevel@tonic-gate /* Opcode: StrGe P1 P2 *
15537c478bd9Sstevel@tonic-gate **
15547c478bd9Sstevel@tonic-gate ** Pop the top two elements from the stack.  If second element (the next
15557c478bd9Sstevel@tonic-gate ** on stack) is greater than or equal to the first (the top of stack),
15567c478bd9Sstevel@tonic-gate ** then jump to instruction P2. In other words, jump if NOS>=TOS.
15577c478bd9Sstevel@tonic-gate **
15587c478bd9Sstevel@tonic-gate ** If either operand is NULL (and thus if the result is unknown) then
15597c478bd9Sstevel@tonic-gate ** take the jump if P1 is true.
15607c478bd9Sstevel@tonic-gate **
15617c478bd9Sstevel@tonic-gate ** The strcmp() library routine is used for the comparison.  For a
15627c478bd9Sstevel@tonic-gate ** numeric comparison, use OP_Ge.
15637c478bd9Sstevel@tonic-gate **
15647c478bd9Sstevel@tonic-gate ** If P2 is zero, do not jump.  Instead, push an integer 1 onto the
15657c478bd9Sstevel@tonic-gate ** stack if the jump would have been taken, or a 0 if not.  Push a
15667c478bd9Sstevel@tonic-gate ** NULL if either operand was NULL.
15677c478bd9Sstevel@tonic-gate */
15687c478bd9Sstevel@tonic-gate case OP_StrEq:
15697c478bd9Sstevel@tonic-gate case OP_StrNe:
15707c478bd9Sstevel@tonic-gate case OP_StrLt:
15717c478bd9Sstevel@tonic-gate case OP_StrLe:
15727c478bd9Sstevel@tonic-gate case OP_StrGt:
15737c478bd9Sstevel@tonic-gate case OP_StrGe: {
15747c478bd9Sstevel@tonic-gate   Mem *pNos = &pTos[-1];
15757c478bd9Sstevel@tonic-gate   int c;
15767c478bd9Sstevel@tonic-gate   assert( pNos>=p->aStack );
15777c478bd9Sstevel@tonic-gate   if( (pNos->flags | pTos->flags) & MEM_Null ){
15787c478bd9Sstevel@tonic-gate     popStack(&pTos, 2);
15797c478bd9Sstevel@tonic-gate     if( pOp->p2 ){
15807c478bd9Sstevel@tonic-gate       if( pOp->p1 ) pc = pOp->p2-1;
15817c478bd9Sstevel@tonic-gate     }else{
15827c478bd9Sstevel@tonic-gate       pTos++;
15837c478bd9Sstevel@tonic-gate       pTos->flags = MEM_Null;
15847c478bd9Sstevel@tonic-gate     }
15857c478bd9Sstevel@tonic-gate     break;
15867c478bd9Sstevel@tonic-gate   }else{
15877c478bd9Sstevel@tonic-gate     Stringify(pTos);
15887c478bd9Sstevel@tonic-gate     Stringify(pNos);
15897c478bd9Sstevel@tonic-gate     c = strcmp(pNos->z, pTos->z);
15907c478bd9Sstevel@tonic-gate   }
15917c478bd9Sstevel@tonic-gate   /* The asserts on each case of the following switch are there to verify
15927c478bd9Sstevel@tonic-gate   ** that string comparison opcodes are always exactly 6 greater than the
15937c478bd9Sstevel@tonic-gate   ** corresponding numeric comparison opcodes.  The code generator depends
15947c478bd9Sstevel@tonic-gate   ** on this fact.
15957c478bd9Sstevel@tonic-gate   */
15967c478bd9Sstevel@tonic-gate   switch( pOp->opcode ){
15977c478bd9Sstevel@tonic-gate     case OP_StrEq:    c = c==0;    assert( pOp->opcode-6==OP_Eq );   break;
15987c478bd9Sstevel@tonic-gate     case OP_StrNe:    c = c!=0;    assert( pOp->opcode-6==OP_Ne );   break;
15997c478bd9Sstevel@tonic-gate     case OP_StrLt:    c = c<0;     assert( pOp->opcode-6==OP_Lt );   break;
16007c478bd9Sstevel@tonic-gate     case OP_StrLe:    c = c<=0;    assert( pOp->opcode-6==OP_Le );   break;
16017c478bd9Sstevel@tonic-gate     case OP_StrGt:    c = c>0;     assert( pOp->opcode-6==OP_Gt );   break;
16027c478bd9Sstevel@tonic-gate     default:          c = c>=0;    assert( pOp->opcode-6==OP_Ge );   break;
16037c478bd9Sstevel@tonic-gate   }
16047c478bd9Sstevel@tonic-gate   popStack(&pTos, 2);
16057c478bd9Sstevel@tonic-gate   if( pOp->p2 ){
16067c478bd9Sstevel@tonic-gate     if( c ) pc = pOp->p2-1;
16077c478bd9Sstevel@tonic-gate   }else{
16087c478bd9Sstevel@tonic-gate     pTos++;
16097c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Int;
16107c478bd9Sstevel@tonic-gate     pTos->i = c;
16117c478bd9Sstevel@tonic-gate   }
16127c478bd9Sstevel@tonic-gate   break;
16137c478bd9Sstevel@tonic-gate }
16147c478bd9Sstevel@tonic-gate 
16157c478bd9Sstevel@tonic-gate /* Opcode: And * * *
16167c478bd9Sstevel@tonic-gate **
16177c478bd9Sstevel@tonic-gate ** Pop two values off the stack.  Take the logical AND of the
16187c478bd9Sstevel@tonic-gate ** two values and push the resulting boolean value back onto the
1619*55fea89dSDan Cross ** stack.
16207c478bd9Sstevel@tonic-gate */
16217c478bd9Sstevel@tonic-gate /* Opcode: Or * * *
16227c478bd9Sstevel@tonic-gate **
16237c478bd9Sstevel@tonic-gate ** Pop two values off the stack.  Take the logical OR of the
16247c478bd9Sstevel@tonic-gate ** two values and push the resulting boolean value back onto the
1625*55fea89dSDan Cross ** stack.
16267c478bd9Sstevel@tonic-gate */
16277c478bd9Sstevel@tonic-gate case OP_And:
16287c478bd9Sstevel@tonic-gate case OP_Or: {
16297c478bd9Sstevel@tonic-gate   Mem *pNos = &pTos[-1];
16307c478bd9Sstevel@tonic-gate   int v1, v2;    /* 0==TRUE, 1==FALSE, 2==UNKNOWN or NULL */
16317c478bd9Sstevel@tonic-gate 
16327c478bd9Sstevel@tonic-gate   assert( pNos>=p->aStack );
16337c478bd9Sstevel@tonic-gate   if( pTos->flags & MEM_Null ){
16347c478bd9Sstevel@tonic-gate     v1 = 2;
16357c478bd9Sstevel@tonic-gate   }else{
16367c478bd9Sstevel@tonic-gate     Integerify(pTos);
16377c478bd9Sstevel@tonic-gate     v1 = pTos->i==0;
16387c478bd9Sstevel@tonic-gate   }
16397c478bd9Sstevel@tonic-gate   if( pNos->flags & MEM_Null ){
16407c478bd9Sstevel@tonic-gate     v2 = 2;
16417c478bd9Sstevel@tonic-gate   }else{
16427c478bd9Sstevel@tonic-gate     Integerify(pNos);
16437c478bd9Sstevel@tonic-gate     v2 = pNos->i==0;
16447c478bd9Sstevel@tonic-gate   }
16457c478bd9Sstevel@tonic-gate   if( pOp->opcode==OP_And ){
16467c478bd9Sstevel@tonic-gate     static const unsigned char and_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
16477c478bd9Sstevel@tonic-gate     v1 = and_logic[v1*3+v2];
16487c478bd9Sstevel@tonic-gate   }else{
16497c478bd9Sstevel@tonic-gate     static const unsigned char or_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
16507c478bd9Sstevel@tonic-gate     v1 = or_logic[v1*3+v2];
16517c478bd9Sstevel@tonic-gate   }
16527c478bd9Sstevel@tonic-gate   popStack(&pTos, 2);
16537c478bd9Sstevel@tonic-gate   pTos++;
16547c478bd9Sstevel@tonic-gate   if( v1==2 ){
16557c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
16567c478bd9Sstevel@tonic-gate   }else{
16577c478bd9Sstevel@tonic-gate     pTos->i = v1==0;
16587c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Int;
16597c478bd9Sstevel@tonic-gate   }
16607c478bd9Sstevel@tonic-gate   break;
16617c478bd9Sstevel@tonic-gate }
16627c478bd9Sstevel@tonic-gate 
16637c478bd9Sstevel@tonic-gate /* Opcode: Negative * * *
16647c478bd9Sstevel@tonic-gate **
16657c478bd9Sstevel@tonic-gate ** Treat the top of the stack as a numeric quantity.  Replace it
16667c478bd9Sstevel@tonic-gate ** with its additive inverse.  If the top of the stack is NULL
16677c478bd9Sstevel@tonic-gate ** its value is unchanged.
16687c478bd9Sstevel@tonic-gate */
16697c478bd9Sstevel@tonic-gate /* Opcode: AbsValue * * *
16707c478bd9Sstevel@tonic-gate **
16717c478bd9Sstevel@tonic-gate ** Treat the top of the stack as a numeric quantity.  Replace it
16727c478bd9Sstevel@tonic-gate ** with its absolute value. If the top of the stack is NULL
16737c478bd9Sstevel@tonic-gate ** its value is unchanged.
16747c478bd9Sstevel@tonic-gate */
16757c478bd9Sstevel@tonic-gate case OP_Negative:
16767c478bd9Sstevel@tonic-gate case OP_AbsValue: {
16777c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
16787c478bd9Sstevel@tonic-gate   if( pTos->flags & MEM_Real ){
16797c478bd9Sstevel@tonic-gate     Release(pTos);
16807c478bd9Sstevel@tonic-gate     if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
16817c478bd9Sstevel@tonic-gate       pTos->r = -pTos->r;
16827c478bd9Sstevel@tonic-gate     }
16837c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Real;
16847c478bd9Sstevel@tonic-gate   }else if( pTos->flags & MEM_Int ){
16857c478bd9Sstevel@tonic-gate     Release(pTos);
16867c478bd9Sstevel@tonic-gate     if( pOp->opcode==OP_Negative || pTos->i<0 ){
16877c478bd9Sstevel@tonic-gate       pTos->i = -pTos->i;
16887c478bd9Sstevel@tonic-gate     }
16897c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Int;
16907c478bd9Sstevel@tonic-gate   }else if( pTos->flags & MEM_Null ){
16917c478bd9Sstevel@tonic-gate     /* Do nothing */
16927c478bd9Sstevel@tonic-gate   }else{
16937c478bd9Sstevel@tonic-gate     Realify(pTos);
16947c478bd9Sstevel@tonic-gate     Release(pTos);
16957c478bd9Sstevel@tonic-gate     if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
16967c478bd9Sstevel@tonic-gate       pTos->r = -pTos->r;
16977c478bd9Sstevel@tonic-gate     }
16987c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Real;
16997c478bd9Sstevel@tonic-gate   }
17007c478bd9Sstevel@tonic-gate   break;
17017c478bd9Sstevel@tonic-gate }
17027c478bd9Sstevel@tonic-gate 
17037c478bd9Sstevel@tonic-gate /* Opcode: Not * * *
17047c478bd9Sstevel@tonic-gate **
17057c478bd9Sstevel@tonic-gate ** Interpret the top of the stack as a boolean value.  Replace it
17067c478bd9Sstevel@tonic-gate ** with its complement.  If the top of the stack is NULL its value
17077c478bd9Sstevel@tonic-gate ** is unchanged.
17087c478bd9Sstevel@tonic-gate */
17097c478bd9Sstevel@tonic-gate case OP_Not: {
17107c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
17117c478bd9Sstevel@tonic-gate   if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
17127c478bd9Sstevel@tonic-gate   Integerify(pTos);
17137c478bd9Sstevel@tonic-gate   Release(pTos);
17147c478bd9Sstevel@tonic-gate   pTos->i = !pTos->i;
17157c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Int;
17167c478bd9Sstevel@tonic-gate   break;
17177c478bd9Sstevel@tonic-gate }
17187c478bd9Sstevel@tonic-gate 
17197c478bd9Sstevel@tonic-gate /* Opcode: BitNot * * *
17207c478bd9Sstevel@tonic-gate **
17217c478bd9Sstevel@tonic-gate ** Interpret the top of the stack as an value.  Replace it
17227c478bd9Sstevel@tonic-gate ** with its ones-complement.  If the top of the stack is NULL its
17237c478bd9Sstevel@tonic-gate ** value is unchanged.
17247c478bd9Sstevel@tonic-gate */
17257c478bd9Sstevel@tonic-gate case OP_BitNot: {
17267c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
17277c478bd9Sstevel@tonic-gate   if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
17287c478bd9Sstevel@tonic-gate   Integerify(pTos);
17297c478bd9Sstevel@tonic-gate   Release(pTos);
17307c478bd9Sstevel@tonic-gate   pTos->i = ~pTos->i;
17317c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Int;
17327c478bd9Sstevel@tonic-gate   break;
17337c478bd9Sstevel@tonic-gate }
17347c478bd9Sstevel@tonic-gate 
17357c478bd9Sstevel@tonic-gate /* Opcode: Noop * * *
17367c478bd9Sstevel@tonic-gate **
17377c478bd9Sstevel@tonic-gate ** Do nothing.  This instruction is often useful as a jump
17387c478bd9Sstevel@tonic-gate ** destination.
17397c478bd9Sstevel@tonic-gate */
17407c478bd9Sstevel@tonic-gate case OP_Noop: {
17417c478bd9Sstevel@tonic-gate   break;
17427c478bd9Sstevel@tonic-gate }
17437c478bd9Sstevel@tonic-gate 
17447c478bd9Sstevel@tonic-gate /* Opcode: If P1 P2 *
17457c478bd9Sstevel@tonic-gate **
17467c478bd9Sstevel@tonic-gate ** Pop a single boolean from the stack.  If the boolean popped is
17477c478bd9Sstevel@tonic-gate ** true, then jump to p2.  Otherwise continue to the next instruction.
17487c478bd9Sstevel@tonic-gate ** An integer is false if zero and true otherwise.  A string is
17497c478bd9Sstevel@tonic-gate ** false if it has zero length and true otherwise.
17507c478bd9Sstevel@tonic-gate **
17517c478bd9Sstevel@tonic-gate ** If the value popped of the stack is NULL, then take the jump if P1
17527c478bd9Sstevel@tonic-gate ** is true and fall through if P1 is false.
17537c478bd9Sstevel@tonic-gate */
17547c478bd9Sstevel@tonic-gate /* Opcode: IfNot P1 P2 *
17557c478bd9Sstevel@tonic-gate **
17567c478bd9Sstevel@tonic-gate ** Pop a single boolean from the stack.  If the boolean popped is
17577c478bd9Sstevel@tonic-gate ** false, then jump to p2.  Otherwise continue to the next instruction.
17587c478bd9Sstevel@tonic-gate ** An integer is false if zero and true otherwise.  A string is
17597c478bd9Sstevel@tonic-gate ** false if it has zero length and true otherwise.
17607c478bd9Sstevel@tonic-gate **
17617c478bd9Sstevel@tonic-gate ** If the value popped of the stack is NULL, then take the jump if P1
17627c478bd9Sstevel@tonic-gate ** is true and fall through if P1 is false.
17637c478bd9Sstevel@tonic-gate */
17647c478bd9Sstevel@tonic-gate case OP_If:
17657c478bd9Sstevel@tonic-gate case OP_IfNot: {
17667c478bd9Sstevel@tonic-gate   int c;
17677c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
17687c478bd9Sstevel@tonic-gate   if( pTos->flags & MEM_Null ){
17697c478bd9Sstevel@tonic-gate     c = pOp->p1;
17707c478bd9Sstevel@tonic-gate   }else{
17717c478bd9Sstevel@tonic-gate     Integerify(pTos);
17727c478bd9Sstevel@tonic-gate     c = pTos->i;
17737c478bd9Sstevel@tonic-gate     if( pOp->opcode==OP_IfNot ) c = !c;
17747c478bd9Sstevel@tonic-gate   }
17757c478bd9Sstevel@tonic-gate   assert( (pTos->flags & MEM_Dyn)==0 );
17767c478bd9Sstevel@tonic-gate   pTos--;
17777c478bd9Sstevel@tonic-gate   if( c ) pc = pOp->p2-1;
17787c478bd9Sstevel@tonic-gate   break;
17797c478bd9Sstevel@tonic-gate }
17807c478bd9Sstevel@tonic-gate 
17817c478bd9Sstevel@tonic-gate /* Opcode: IsNull P1 P2 *
17827c478bd9Sstevel@tonic-gate **
17837c478bd9Sstevel@tonic-gate ** If any of the top abs(P1) values on the stack are NULL, then jump
17847c478bd9Sstevel@tonic-gate ** to P2.  Pop the stack P1 times if P1>0.   If P1<0 leave the stack
17857c478bd9Sstevel@tonic-gate ** unchanged.
17867c478bd9Sstevel@tonic-gate */
17877c478bd9Sstevel@tonic-gate case OP_IsNull: {
17887c478bd9Sstevel@tonic-gate   int i, cnt;
17897c478bd9Sstevel@tonic-gate   Mem *pTerm;
17907c478bd9Sstevel@tonic-gate   cnt = pOp->p1;
17917c478bd9Sstevel@tonic-gate   if( cnt<0 ) cnt = -cnt;
17927c478bd9Sstevel@tonic-gate   pTerm = &pTos[1-cnt];
17937c478bd9Sstevel@tonic-gate   assert( pTerm>=p->aStack );
17947c478bd9Sstevel@tonic-gate   for(i=0; i<cnt; i++, pTerm++){
17957c478bd9Sstevel@tonic-gate     if( pTerm->flags & MEM_Null ){
17967c478bd9Sstevel@tonic-gate       pc = pOp->p2-1;
17977c478bd9Sstevel@tonic-gate       break;
17987c478bd9Sstevel@tonic-gate     }
17997c478bd9Sstevel@tonic-gate   }
18007c478bd9Sstevel@tonic-gate   if( pOp->p1>0 ) popStack(&pTos, cnt);
18017c478bd9Sstevel@tonic-gate   break;
18027c478bd9Sstevel@tonic-gate }
18037c478bd9Sstevel@tonic-gate 
18047c478bd9Sstevel@tonic-gate /* Opcode: NotNull P1 P2 *
18057c478bd9Sstevel@tonic-gate **
18067c478bd9Sstevel@tonic-gate ** Jump to P2 if the top P1 values on the stack are all not NULL.  Pop the
18077c478bd9Sstevel@tonic-gate ** stack if P1 times if P1 is greater than zero.  If P1 is less than
18087c478bd9Sstevel@tonic-gate ** zero then leave the stack unchanged.
18097c478bd9Sstevel@tonic-gate */
18107c478bd9Sstevel@tonic-gate case OP_NotNull: {
18117c478bd9Sstevel@tonic-gate   int i, cnt;
18127c478bd9Sstevel@tonic-gate   cnt = pOp->p1;
18137c478bd9Sstevel@tonic-gate   if( cnt<0 ) cnt = -cnt;
18147c478bd9Sstevel@tonic-gate   assert( &pTos[1-cnt] >= p->aStack );
18157c478bd9Sstevel@tonic-gate   for(i=0; i<cnt && (pTos[1+i-cnt].flags & MEM_Null)==0; i++){}
18167c478bd9Sstevel@tonic-gate   if( i>=cnt ) pc = pOp->p2-1;
18177c478bd9Sstevel@tonic-gate   if( pOp->p1>0 ) popStack(&pTos, cnt);
18187c478bd9Sstevel@tonic-gate   break;
18197c478bd9Sstevel@tonic-gate }
18207c478bd9Sstevel@tonic-gate 
18217c478bd9Sstevel@tonic-gate /* Opcode: MakeRecord P1 P2 *
18227c478bd9Sstevel@tonic-gate **
18237c478bd9Sstevel@tonic-gate ** Convert the top P1 entries of the stack into a single entry
18247c478bd9Sstevel@tonic-gate ** suitable for use as a data record in a database table.  The
182563360950Smp ** details of the format are irrelevant as long as the OP_Column
18267c478bd9Sstevel@tonic-gate ** opcode can decode the record later.  Refer to source code
18277c478bd9Sstevel@tonic-gate ** comments for the details of the record format.
18287c478bd9Sstevel@tonic-gate **
18297c478bd9Sstevel@tonic-gate ** If P2 is true (non-zero) and one or more of the P1 entries
18307c478bd9Sstevel@tonic-gate ** that go into building the record is NULL, then add some extra
18317c478bd9Sstevel@tonic-gate ** bytes to the record to make it distinct for other entries created
18327c478bd9Sstevel@tonic-gate ** during the same run of the VDBE.  The extra bytes added are a
18337c478bd9Sstevel@tonic-gate ** counter that is reset with each run of the VDBE, so records
18347c478bd9Sstevel@tonic-gate ** created this way will not necessarily be distinct across runs.
18357c478bd9Sstevel@tonic-gate ** But they should be distinct for transient tables (created using
18367c478bd9Sstevel@tonic-gate ** OP_OpenTemp) which is what they are intended for.
18377c478bd9Sstevel@tonic-gate **
18387c478bd9Sstevel@tonic-gate ** (Later:) The P2==1 option was intended to make NULLs distinct
18397c478bd9Sstevel@tonic-gate ** for the UNION operator.  But I have since discovered that NULLs
18407c478bd9Sstevel@tonic-gate ** are indistinct for UNION.  So this option is never used.
18417c478bd9Sstevel@tonic-gate */
18427c478bd9Sstevel@tonic-gate case OP_MakeRecord: {
18437c478bd9Sstevel@tonic-gate   char *zNewRecord;
18447c478bd9Sstevel@tonic-gate   int nByte;
18457c478bd9Sstevel@tonic-gate   int nField;
18467c478bd9Sstevel@tonic-gate   int i, j;
18477c478bd9Sstevel@tonic-gate   int idxWidth;
18487c478bd9Sstevel@tonic-gate   u32 addr;
18497c478bd9Sstevel@tonic-gate   Mem *pRec;
18507c478bd9Sstevel@tonic-gate   int addUnique = 0;   /* True to cause bytes to be added to make the
18517c478bd9Sstevel@tonic-gate                        ** generated record distinct */
18527c478bd9Sstevel@tonic-gate   char zTemp[NBFS];    /* Temp space for small records */
18537c478bd9Sstevel@tonic-gate 
18547c478bd9Sstevel@tonic-gate   /* Assuming the record contains N fields, the record format looks
18557c478bd9Sstevel@tonic-gate   ** like this:
18567c478bd9Sstevel@tonic-gate   **
18577c478bd9Sstevel@tonic-gate   **   -------------------------------------------------------------------
18587c478bd9Sstevel@tonic-gate   **   | idx0 | idx1 | ... | idx(N-1) | idx(N) | data0 | ... | data(N-1) |
18597c478bd9Sstevel@tonic-gate   **   -------------------------------------------------------------------
18607c478bd9Sstevel@tonic-gate   **
18617c478bd9Sstevel@tonic-gate   ** All data fields are converted to strings before being stored and
18627c478bd9Sstevel@tonic-gate   ** are stored with their null terminators.  NULL entries omit the
18637c478bd9Sstevel@tonic-gate   ** null terminator.  Thus an empty string uses 1 byte and a NULL uses
18647c478bd9Sstevel@tonic-gate   ** zero bytes.  Data(0) is taken from the lowest element of the stack
18657c478bd9Sstevel@tonic-gate   ** and data(N-1) is the top of the stack.
18667c478bd9Sstevel@tonic-gate   **
18677c478bd9Sstevel@tonic-gate   ** Each of the idx() entries is either 1, 2, or 3 bytes depending on
18687c478bd9Sstevel@tonic-gate   ** how big the total record is.  Idx(0) contains the offset to the start
18697c478bd9Sstevel@tonic-gate   ** of data(0).  Idx(k) contains the offset to the start of data(k).
18707c478bd9Sstevel@tonic-gate   ** Idx(N) contains the total number of bytes in the record.
18717c478bd9Sstevel@tonic-gate   */
18727c478bd9Sstevel@tonic-gate   nField = pOp->p1;
18737c478bd9Sstevel@tonic-gate   pRec = &pTos[1-nField];
18747c478bd9Sstevel@tonic-gate   assert( pRec>=p->aStack );
18757c478bd9Sstevel@tonic-gate   nByte = 0;
18767c478bd9Sstevel@tonic-gate   for(i=0; i<nField; i++, pRec++){
18777c478bd9Sstevel@tonic-gate     if( pRec->flags & MEM_Null ){
18787c478bd9Sstevel@tonic-gate       addUnique = pOp->p2;
18797c478bd9Sstevel@tonic-gate     }else{
18807c478bd9Sstevel@tonic-gate       Stringify(pRec);
18817c478bd9Sstevel@tonic-gate       nByte += pRec->n;
18827c478bd9Sstevel@tonic-gate     }
18837c478bd9Sstevel@tonic-gate   }
18847c478bd9Sstevel@tonic-gate   if( addUnique ) nByte += sizeof(p->uniqueCnt);
18857c478bd9Sstevel@tonic-gate   if( nByte + nField + 1 < 256 ){
18867c478bd9Sstevel@tonic-gate     idxWidth = 1;
18877c478bd9Sstevel@tonic-gate   }else if( nByte + 2*nField + 2 < 65536 ){
18887c478bd9Sstevel@tonic-gate     idxWidth = 2;
18897c478bd9Sstevel@tonic-gate   }else{
18907c478bd9Sstevel@tonic-gate     idxWidth = 3;
18917c478bd9Sstevel@tonic-gate   }
18927c478bd9Sstevel@tonic-gate   nByte += idxWidth*(nField + 1);
18937c478bd9Sstevel@tonic-gate   if( nByte>MAX_BYTES_PER_ROW ){
18947c478bd9Sstevel@tonic-gate     rc = SQLITE_TOOBIG;
18957c478bd9Sstevel@tonic-gate     goto abort_due_to_error;
18967c478bd9Sstevel@tonic-gate   }
18977c478bd9Sstevel@tonic-gate   if( nByte<=NBFS ){
18987c478bd9Sstevel@tonic-gate     zNewRecord = zTemp;
18997c478bd9Sstevel@tonic-gate   }else{
19007c478bd9Sstevel@tonic-gate     zNewRecord = sqliteMallocRaw( nByte );
19017c478bd9Sstevel@tonic-gate     if( zNewRecord==0 ) goto no_mem;
19027c478bd9Sstevel@tonic-gate   }
19037c478bd9Sstevel@tonic-gate   j = 0;
19047c478bd9Sstevel@tonic-gate   addr = idxWidth*(nField+1) + addUnique*sizeof(p->uniqueCnt);
19057c478bd9Sstevel@tonic-gate   for(i=0, pRec=&pTos[1-nField]; i<nField; i++, pRec++){
19067c478bd9Sstevel@tonic-gate     zNewRecord[j++] = addr & 0xff;
19077c478bd9Sstevel@tonic-gate     if( idxWidth>1 ){
19087c478bd9Sstevel@tonic-gate       zNewRecord[j++] = (addr>>8)&0xff;
19097c478bd9Sstevel@tonic-gate       if( idxWidth>2 ){
19107c478bd9Sstevel@tonic-gate         zNewRecord[j++] = (addr>>16)&0xff;
19117c478bd9Sstevel@tonic-gate       }
19127c478bd9Sstevel@tonic-gate     }
19137c478bd9Sstevel@tonic-gate     if( (pRec->flags & MEM_Null)==0 ){
19147c478bd9Sstevel@tonic-gate       addr += pRec->n;
19157c478bd9Sstevel@tonic-gate     }
19167c478bd9Sstevel@tonic-gate   }
19177c478bd9Sstevel@tonic-gate   zNewRecord[j++] = addr & 0xff;
19187c478bd9Sstevel@tonic-gate   if( idxWidth>1 ){
19197c478bd9Sstevel@tonic-gate     zNewRecord[j++] = (addr>>8)&0xff;
19207c478bd9Sstevel@tonic-gate     if( idxWidth>2 ){
19217c478bd9Sstevel@tonic-gate       zNewRecord[j++] = (addr>>16)&0xff;
19227c478bd9Sstevel@tonic-gate     }
19237c478bd9Sstevel@tonic-gate   }
19247c478bd9Sstevel@tonic-gate   if( addUnique ){
19257c478bd9Sstevel@tonic-gate     memcpy(&zNewRecord[j], &p->uniqueCnt, sizeof(p->uniqueCnt));
19267c478bd9Sstevel@tonic-gate     p->uniqueCnt++;
19277c478bd9Sstevel@tonic-gate     j += sizeof(p->uniqueCnt);
19287c478bd9Sstevel@tonic-gate   }
19297c478bd9Sstevel@tonic-gate   for(i=0, pRec=&pTos[1-nField]; i<nField; i++, pRec++){
19307c478bd9Sstevel@tonic-gate     if( (pRec->flags & MEM_Null)==0 ){
19317c478bd9Sstevel@tonic-gate       memcpy(&zNewRecord[j], pRec->z, pRec->n);
19327c478bd9Sstevel@tonic-gate       j += pRec->n;
19337c478bd9Sstevel@tonic-gate     }
19347c478bd9Sstevel@tonic-gate   }
19357c478bd9Sstevel@tonic-gate   popStack(&pTos, nField);
19367c478bd9Sstevel@tonic-gate   pTos++;
19377c478bd9Sstevel@tonic-gate   pTos->n = nByte;
19387c478bd9Sstevel@tonic-gate   if( nByte<=NBFS ){
19397c478bd9Sstevel@tonic-gate     assert( zNewRecord==zTemp );
19407c478bd9Sstevel@tonic-gate     memcpy(pTos->zShort, zTemp, nByte);
19417c478bd9Sstevel@tonic-gate     pTos->z = pTos->zShort;
19427c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Str | MEM_Short;
19437c478bd9Sstevel@tonic-gate   }else{
19447c478bd9Sstevel@tonic-gate     assert( zNewRecord!=zTemp );
19457c478bd9Sstevel@tonic-gate     pTos->z = zNewRecord;
19467c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Str | MEM_Dyn;
19477c478bd9Sstevel@tonic-gate   }
19487c478bd9Sstevel@tonic-gate   break;
19497c478bd9Sstevel@tonic-gate }
19507c478bd9Sstevel@tonic-gate 
19517c478bd9Sstevel@tonic-gate /* Opcode: MakeKey P1 P2 P3
19527c478bd9Sstevel@tonic-gate **
19537c478bd9Sstevel@tonic-gate ** Convert the top P1 entries of the stack into a single entry suitable
19547c478bd9Sstevel@tonic-gate ** for use as the key in an index.  The top P1 records are
1955*55fea89dSDan Cross ** converted to strings and merged.  The null-terminators
19567c478bd9Sstevel@tonic-gate ** are retained and used as separators.
19577c478bd9Sstevel@tonic-gate ** The lowest entry in the stack is the first field and the top of the
19587c478bd9Sstevel@tonic-gate ** stack becomes the last.
19597c478bd9Sstevel@tonic-gate **
19607c478bd9Sstevel@tonic-gate ** If P2 is not zero, then the original entries remain on the stack
19617c478bd9Sstevel@tonic-gate ** and the new key is pushed on top.  If P2 is zero, the original
19627c478bd9Sstevel@tonic-gate ** data is popped off the stack first then the new key is pushed
19637c478bd9Sstevel@tonic-gate ** back in its place.
19647c478bd9Sstevel@tonic-gate **
19657c478bd9Sstevel@tonic-gate ** P3 is a string that is P1 characters long.  Each character is either
19667c478bd9Sstevel@tonic-gate ** an 'n' or a 't' to indicates if the argument should be intepreted as
19677c478bd9Sstevel@tonic-gate ** numeric or text type.  The first character of P3 corresponds to the
19687c478bd9Sstevel@tonic-gate ** lowest element on the stack.  If P3 is NULL then all arguments are
19697c478bd9Sstevel@tonic-gate ** assumed to be of the numeric type.
19707c478bd9Sstevel@tonic-gate **
1971*55fea89dSDan Cross ** The type makes a difference in that text-type fields may not be
19727c478bd9Sstevel@tonic-gate ** introduced by 'b' (as described in the next paragraph).  The
19737c478bd9Sstevel@tonic-gate ** first character of a text-type field must be either 'a' (if it is NULL)
19747c478bd9Sstevel@tonic-gate ** or 'c'.  Numeric fields will be introduced by 'b' if their content
19757c478bd9Sstevel@tonic-gate ** looks like a well-formed number.  Otherwise the 'a' or 'c' will be
19767c478bd9Sstevel@tonic-gate ** used.
19777c478bd9Sstevel@tonic-gate **
19787c478bd9Sstevel@tonic-gate ** The key is a concatenation of fields.  Each field is terminated by
19797c478bd9Sstevel@tonic-gate ** a single 0x00 character.  A NULL field is introduced by an 'a' and
19807c478bd9Sstevel@tonic-gate ** is followed immediately by its 0x00 terminator.  A numeric field is
19817c478bd9Sstevel@tonic-gate ** introduced by a single character 'b' and is followed by a sequence
19827c478bd9Sstevel@tonic-gate ** of characters that represent the number such that a comparison of
19837c478bd9Sstevel@tonic-gate ** the character string using memcpy() sorts the numbers in numerical
19847c478bd9Sstevel@tonic-gate ** order.  The character strings for numbers are generated using the
19857c478bd9Sstevel@tonic-gate ** sqliteRealToSortable() function.  A text field is introduced by a
19867c478bd9Sstevel@tonic-gate ** 'c' character and is followed by the exact text of the field.  The
19877c478bd9Sstevel@tonic-gate ** use of an 'a', 'b', or 'c' character at the beginning of each field
19887c478bd9Sstevel@tonic-gate ** guarantees that NULLs sort before numbers and that numbers sort
19897c478bd9Sstevel@tonic-gate ** before text.  0x00 characters do not occur except as separators
19907c478bd9Sstevel@tonic-gate ** between fields.
19917c478bd9Sstevel@tonic-gate **
19927c478bd9Sstevel@tonic-gate ** See also: MakeIdxKey, SortMakeKey
19937c478bd9Sstevel@tonic-gate */
19947c478bd9Sstevel@tonic-gate /* Opcode: MakeIdxKey P1 P2 P3
19957c478bd9Sstevel@tonic-gate **
19967c478bd9Sstevel@tonic-gate ** Convert the top P1 entries of the stack into a single entry suitable
19977c478bd9Sstevel@tonic-gate ** for use as the key in an index.  In addition, take one additional integer
19987c478bd9Sstevel@tonic-gate ** off of the stack, treat that integer as a four-byte record number, and
19997c478bd9Sstevel@tonic-gate ** append the four bytes to the key.  Thus a total of P1+1 entries are
20007c478bd9Sstevel@tonic-gate ** popped from the stack for this instruction and a single entry is pushed
20017c478bd9Sstevel@tonic-gate ** back.  The first P1 entries that are popped are strings and the last
20027c478bd9Sstevel@tonic-gate ** entry (the lowest on the stack) is an integer record number.
20037c478bd9Sstevel@tonic-gate **
20047c478bd9Sstevel@tonic-gate ** The converstion of the first P1 string entries occurs just like in
20057c478bd9Sstevel@tonic-gate ** MakeKey.  Each entry is separated from the others by a null.
20067c478bd9Sstevel@tonic-gate ** The entire concatenation is null-terminated.  The lowest entry
20077c478bd9Sstevel@tonic-gate ** in the stack is the first field and the top of the stack becomes the
20087c478bd9Sstevel@tonic-gate ** last.
20097c478bd9Sstevel@tonic-gate **
20107c478bd9Sstevel@tonic-gate ** If P2 is not zero and one or more of the P1 entries that go into the
20117c478bd9Sstevel@tonic-gate ** generated key is NULL, then jump to P2 after the new key has been
20127c478bd9Sstevel@tonic-gate ** pushed on the stack.  In other words, jump to P2 if the key is
20137c478bd9Sstevel@tonic-gate ** guaranteed to be unique.  This jump can be used to skip a subsequent
20147c478bd9Sstevel@tonic-gate ** uniqueness test.
20157c478bd9Sstevel@tonic-gate **
20167c478bd9Sstevel@tonic-gate ** P3 is a string that is P1 characters long.  Each character is either
20177c478bd9Sstevel@tonic-gate ** an 'n' or a 't' to indicates if the argument should be numeric or
20187c478bd9Sstevel@tonic-gate ** text.  The first character corresponds to the lowest element on the
20197c478bd9Sstevel@tonic-gate ** stack.  If P3 is null then all arguments are assumed to be numeric.
20207c478bd9Sstevel@tonic-gate **
20217c478bd9Sstevel@tonic-gate ** See also:  MakeKey, SortMakeKey
20227c478bd9Sstevel@tonic-gate */
20237c478bd9Sstevel@tonic-gate case OP_MakeIdxKey:
20247c478bd9Sstevel@tonic-gate case OP_MakeKey: {
20257c478bd9Sstevel@tonic-gate   char *zNewKey;
20267c478bd9Sstevel@tonic-gate   int nByte;
20277c478bd9Sstevel@tonic-gate   int nField;
20287c478bd9Sstevel@tonic-gate   int addRowid;
20297c478bd9Sstevel@tonic-gate   int i, j;
20307c478bd9Sstevel@tonic-gate   int containsNull = 0;
20317c478bd9Sstevel@tonic-gate   Mem *pRec;
20327c478bd9Sstevel@tonic-gate   char zTemp[NBFS];
20337c478bd9Sstevel@tonic-gate 
20347c478bd9Sstevel@tonic-gate   addRowid = pOp->opcode==OP_MakeIdxKey;
20357c478bd9Sstevel@tonic-gate   nField = pOp->p1;
20367c478bd9Sstevel@tonic-gate   pRec = &pTos[1-nField];
20377c478bd9Sstevel@tonic-gate   assert( pRec>=p->aStack );
20387c478bd9Sstevel@tonic-gate   nByte = 0;
20397c478bd9Sstevel@tonic-gate   for(j=0, i=0; i<nField; i++, j++, pRec++){
20407c478bd9Sstevel@tonic-gate     int flags = pRec->flags;
20417c478bd9Sstevel@tonic-gate     int len;
20427c478bd9Sstevel@tonic-gate     char *z;
20437c478bd9Sstevel@tonic-gate     if( flags & MEM_Null ){
20447c478bd9Sstevel@tonic-gate       nByte += 2;
20457c478bd9Sstevel@tonic-gate       containsNull = 1;
20467c478bd9Sstevel@tonic-gate     }else if( pOp->p3 && pOp->p3[j]=='t' ){
20477c478bd9Sstevel@tonic-gate       Stringify(pRec);
20487c478bd9Sstevel@tonic-gate       pRec->flags &= ~(MEM_Int|MEM_Real);
20497c478bd9Sstevel@tonic-gate       nByte += pRec->n+1;
20507c478bd9Sstevel@tonic-gate     }else if( (flags & (MEM_Real|MEM_Int))!=0 || sqliteIsNumber(pRec->z) ){
20517c478bd9Sstevel@tonic-gate       if( (flags & (MEM_Real|MEM_Int))==MEM_Int ){
20527c478bd9Sstevel@tonic-gate         pRec->r = pRec->i;
20537c478bd9Sstevel@tonic-gate       }else if( (flags & (MEM_Real|MEM_Int))==0 ){
20547c478bd9Sstevel@tonic-gate         pRec->r = sqliteAtoF(pRec->z, 0);
20557c478bd9Sstevel@tonic-gate       }
20567c478bd9Sstevel@tonic-gate       Release(pRec);
20577c478bd9Sstevel@tonic-gate       z = pRec->zShort;
20587c478bd9Sstevel@tonic-gate       sqliteRealToSortable(pRec->r, z);
20597c478bd9Sstevel@tonic-gate       len = strlen(z);
20607c478bd9Sstevel@tonic-gate       pRec->z = 0;
20617c478bd9Sstevel@tonic-gate       pRec->flags = MEM_Real;
20627c478bd9Sstevel@tonic-gate       pRec->n = len+1;
20637c478bd9Sstevel@tonic-gate       nByte += pRec->n+1;
20647c478bd9Sstevel@tonic-gate     }else{
20657c478bd9Sstevel@tonic-gate       nByte += pRec->n+1;
20667c478bd9Sstevel@tonic-gate     }
20677c478bd9Sstevel@tonic-gate   }
20687c478bd9Sstevel@tonic-gate   if( nByte+sizeof(u32)>MAX_BYTES_PER_ROW ){
20697c478bd9Sstevel@tonic-gate     rc = SQLITE_TOOBIG;
20707c478bd9Sstevel@tonic-gate     goto abort_due_to_error;
20717c478bd9Sstevel@tonic-gate   }
20727c478bd9Sstevel@tonic-gate   if( addRowid ) nByte += sizeof(u32);
20737c478bd9Sstevel@tonic-gate   if( nByte<=NBFS ){
20747c478bd9Sstevel@tonic-gate     zNewKey = zTemp;
20757c478bd9Sstevel@tonic-gate   }else{
20767c478bd9Sstevel@tonic-gate     zNewKey = sqliteMallocRaw( nByte );
20777c478bd9Sstevel@tonic-gate     if( zNewKey==0 ) goto no_mem;
20787c478bd9Sstevel@tonic-gate   }
20797c478bd9Sstevel@tonic-gate   j = 0;
20807c478bd9Sstevel@tonic-gate   pRec = &pTos[1-nField];
20817c478bd9Sstevel@tonic-gate   for(i=0; i<nField; i++, pRec++){
20827c478bd9Sstevel@tonic-gate     if( pRec->flags & MEM_Null ){
20837c478bd9Sstevel@tonic-gate       zNewKey[j++] = 'a';
20847c478bd9Sstevel@tonic-gate       zNewKey[j++] = 0;
20857c478bd9Sstevel@tonic-gate     }else if( pRec->flags==MEM_Real ){
20867c478bd9Sstevel@tonic-gate       zNewKey[j++] = 'b';
20877c478bd9Sstevel@tonic-gate       memcpy(&zNewKey[j], pRec->zShort, pRec->n);
20887c478bd9Sstevel@tonic-gate       j += pRec->n;
20897c478bd9Sstevel@tonic-gate     }else{
20907c478bd9Sstevel@tonic-gate       assert( pRec->flags & MEM_Str );
20917c478bd9Sstevel@tonic-gate       zNewKey[j++] = 'c';
20927c478bd9Sstevel@tonic-gate       memcpy(&zNewKey[j], pRec->z, pRec->n);
20937c478bd9Sstevel@tonic-gate       j += pRec->n;
20947c478bd9Sstevel@tonic-gate     }
20957c478bd9Sstevel@tonic-gate   }
20967c478bd9Sstevel@tonic-gate   if( addRowid ){
20977c478bd9Sstevel@tonic-gate     u32 iKey;
20987c478bd9Sstevel@tonic-gate     pRec = &pTos[-nField];
20997c478bd9Sstevel@tonic-gate     assert( pRec>=p->aStack );
21007c478bd9Sstevel@tonic-gate     Integerify(pRec);
21017c478bd9Sstevel@tonic-gate     iKey = intToKey(pRec->i);
21027c478bd9Sstevel@tonic-gate     memcpy(&zNewKey[j], &iKey, sizeof(u32));
21037c478bd9Sstevel@tonic-gate     popStack(&pTos, nField+1);
21047c478bd9Sstevel@tonic-gate     if( pOp->p2 && containsNull ) pc = pOp->p2 - 1;
21057c478bd9Sstevel@tonic-gate   }else{
21067c478bd9Sstevel@tonic-gate     if( pOp->p2==0 ) popStack(&pTos, nField);
21077c478bd9Sstevel@tonic-gate   }
21087c478bd9Sstevel@tonic-gate   pTos++;
21097c478bd9Sstevel@tonic-gate   pTos->n = nByte;
21107c478bd9Sstevel@tonic-gate   if( nByte<=NBFS ){
21117c478bd9Sstevel@tonic-gate     assert( zNewKey==zTemp );
21127c478bd9Sstevel@tonic-gate     pTos->z = pTos->zShort;
21137c478bd9Sstevel@tonic-gate     memcpy(pTos->zShort, zTemp, nByte);
21147c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Str | MEM_Short;
21157c478bd9Sstevel@tonic-gate   }else{
21167c478bd9Sstevel@tonic-gate     pTos->z = zNewKey;
21177c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Str | MEM_Dyn;
21187c478bd9Sstevel@tonic-gate   }
21197c478bd9Sstevel@tonic-gate   break;
21207c478bd9Sstevel@tonic-gate }
21217c478bd9Sstevel@tonic-gate 
21227c478bd9Sstevel@tonic-gate /* Opcode: IncrKey * * *
21237c478bd9Sstevel@tonic-gate **
21247c478bd9Sstevel@tonic-gate ** The top of the stack should contain an index key generated by
21257c478bd9Sstevel@tonic-gate ** The MakeKey opcode.  This routine increases the least significant
21267c478bd9Sstevel@tonic-gate ** byte of that key by one.  This is used so that the MoveTo opcode
21277c478bd9Sstevel@tonic-gate ** will move to the first entry greater than the key rather than to
21287c478bd9Sstevel@tonic-gate ** the key itself.
21297c478bd9Sstevel@tonic-gate */
21307c478bd9Sstevel@tonic-gate case OP_IncrKey: {
21317c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
21327c478bd9Sstevel@tonic-gate   /* The IncrKey opcode is only applied to keys generated by
21337c478bd9Sstevel@tonic-gate   ** MakeKey or MakeIdxKey and the results of those operands
21347c478bd9Sstevel@tonic-gate   ** are always dynamic strings or zShort[] strings.  So we
21357c478bd9Sstevel@tonic-gate   ** are always free to modify the string in place.
21367c478bd9Sstevel@tonic-gate   */
21377c478bd9Sstevel@tonic-gate   assert( pTos->flags & (MEM_Dyn|MEM_Short) );
21387c478bd9Sstevel@tonic-gate   pTos->z[pTos->n-1]++;
21397c478bd9Sstevel@tonic-gate   break;
21407c478bd9Sstevel@tonic-gate }
21417c478bd9Sstevel@tonic-gate 
21427c478bd9Sstevel@tonic-gate /* Opcode: Checkpoint P1 * *
21437c478bd9Sstevel@tonic-gate **
21447c478bd9Sstevel@tonic-gate ** Begin a checkpoint.  A checkpoint is the beginning of a operation that
21457c478bd9Sstevel@tonic-gate ** is part of a larger transaction but which might need to be rolled back
21467c478bd9Sstevel@tonic-gate ** itself without effecting the containing transaction.  A checkpoint will
21477c478bd9Sstevel@tonic-gate ** be automatically committed or rollback when the VDBE halts.
21487c478bd9Sstevel@tonic-gate **
21497c478bd9Sstevel@tonic-gate ** The checkpoint is begun on the database file with index P1.  The main
21507c478bd9Sstevel@tonic-gate ** database file has an index of 0 and the file used for temporary tables
21517c478bd9Sstevel@tonic-gate ** has an index of 1.
21527c478bd9Sstevel@tonic-gate */
21537c478bd9Sstevel@tonic-gate case OP_Checkpoint: {
21547c478bd9Sstevel@tonic-gate   int i = pOp->p1;
21557c478bd9Sstevel@tonic-gate   if( i>=0 && i<db->nDb && db->aDb[i].pBt && db->aDb[i].inTrans==1 ){
21567c478bd9Sstevel@tonic-gate     rc = sqliteBtreeBeginCkpt(db->aDb[i].pBt);
21577c478bd9Sstevel@tonic-gate     if( rc==SQLITE_OK ) db->aDb[i].inTrans = 2;
21587c478bd9Sstevel@tonic-gate   }
21597c478bd9Sstevel@tonic-gate   break;
21607c478bd9Sstevel@tonic-gate }
21617c478bd9Sstevel@tonic-gate 
21627c478bd9Sstevel@tonic-gate /* Opcode: Transaction P1 * *
21637c478bd9Sstevel@tonic-gate **
21647c478bd9Sstevel@tonic-gate ** Begin a transaction.  The transaction ends when a Commit or Rollback
21657c478bd9Sstevel@tonic-gate ** opcode is encountered.  Depending on the ON CONFLICT setting, the
21667c478bd9Sstevel@tonic-gate ** transaction might also be rolled back if an error is encountered.
21677c478bd9Sstevel@tonic-gate **
21687c478bd9Sstevel@tonic-gate ** P1 is the index of the database file on which the transaction is
21697c478bd9Sstevel@tonic-gate ** started.  Index 0 is the main database file and index 1 is the
21707c478bd9Sstevel@tonic-gate ** file used for temporary tables.
21717c478bd9Sstevel@tonic-gate **
21727c478bd9Sstevel@tonic-gate ** A write lock is obtained on the database file when a transaction is
21737c478bd9Sstevel@tonic-gate ** started.  No other process can read or write the file while the
21747c478bd9Sstevel@tonic-gate ** transaction is underway.  Starting a transaction also creates a
21757c478bd9Sstevel@tonic-gate ** rollback journal.  A transaction must be started before any changes
21767c478bd9Sstevel@tonic-gate ** can be made to the database.
21777c478bd9Sstevel@tonic-gate */
21787c478bd9Sstevel@tonic-gate case OP_Transaction: {
21797c478bd9Sstevel@tonic-gate   int busy = 1;
21807c478bd9Sstevel@tonic-gate   int i = pOp->p1;
21817c478bd9Sstevel@tonic-gate   assert( i>=0 && i<db->nDb );
21827c478bd9Sstevel@tonic-gate   if( db->aDb[i].inTrans ) break;
21837c478bd9Sstevel@tonic-gate   while( db->aDb[i].pBt!=0 && busy ){
21847c478bd9Sstevel@tonic-gate     rc = sqliteBtreeBeginTrans(db->aDb[i].pBt);
21857c478bd9Sstevel@tonic-gate     switch( rc ){
21867c478bd9Sstevel@tonic-gate       case SQLITE_BUSY: {
21877c478bd9Sstevel@tonic-gate         if( db->xBusyCallback==0 ){
21887c478bd9Sstevel@tonic-gate           p->pc = pc;
21897c478bd9Sstevel@tonic-gate           p->undoTransOnError = 1;
21907c478bd9Sstevel@tonic-gate           p->rc = SQLITE_BUSY;
21917c478bd9Sstevel@tonic-gate           p->pTos = pTos;
21927c478bd9Sstevel@tonic-gate           return SQLITE_BUSY;
21937c478bd9Sstevel@tonic-gate         }else if( (*db->xBusyCallback)(db->pBusyArg, "", busy++)==0 ){
21947c478bd9Sstevel@tonic-gate           sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
21957c478bd9Sstevel@tonic-gate           busy = 0;
21967c478bd9Sstevel@tonic-gate         }
21977c478bd9Sstevel@tonic-gate         break;
21987c478bd9Sstevel@tonic-gate       }
21997c478bd9Sstevel@tonic-gate       case SQLITE_READONLY: {
22007c478bd9Sstevel@tonic-gate         rc = SQLITE_OK;
22017c478bd9Sstevel@tonic-gate       }
220288e1588bSToomas Soome       /* FALLTHROUGH */
22037c478bd9Sstevel@tonic-gate       case SQLITE_OK: {
22047c478bd9Sstevel@tonic-gate         p->inTempTrans = 0;
22057c478bd9Sstevel@tonic-gate         busy = 0;
22067c478bd9Sstevel@tonic-gate         break;
22077c478bd9Sstevel@tonic-gate       }
22087c478bd9Sstevel@tonic-gate       default: {
22097c478bd9Sstevel@tonic-gate         goto abort_due_to_error;
22107c478bd9Sstevel@tonic-gate       }
22117c478bd9Sstevel@tonic-gate     }
22127c478bd9Sstevel@tonic-gate   }
22137c478bd9Sstevel@tonic-gate   db->aDb[i].inTrans = 1;
22147c478bd9Sstevel@tonic-gate   p->undoTransOnError = 1;
22157c478bd9Sstevel@tonic-gate   break;
22167c478bd9Sstevel@tonic-gate }
22177c478bd9Sstevel@tonic-gate 
22187c478bd9Sstevel@tonic-gate /* Opcode: Commit * * *
22197c478bd9Sstevel@tonic-gate **
22207c478bd9Sstevel@tonic-gate ** Cause all modifications to the database that have been made since the
22217c478bd9Sstevel@tonic-gate ** last Transaction to actually take effect.  No additional modifications
22227c478bd9Sstevel@tonic-gate ** are allowed until another transaction is started.  The Commit instruction
22237c478bd9Sstevel@tonic-gate ** deletes the journal file and releases the write lock on the database.
22247c478bd9Sstevel@tonic-gate ** A read lock continues to be held if there are still cursors open.
22257c478bd9Sstevel@tonic-gate */
22267c478bd9Sstevel@tonic-gate case OP_Commit: {
22277c478bd9Sstevel@tonic-gate   int i;
22287c478bd9Sstevel@tonic-gate   if( db->xCommitCallback!=0 ){
2229*55fea89dSDan Cross     if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
22307c478bd9Sstevel@tonic-gate     if( db->xCommitCallback(db->pCommitArg)!=0 ){
22317c478bd9Sstevel@tonic-gate       rc = SQLITE_CONSTRAINT;
22327c478bd9Sstevel@tonic-gate     }
22337c478bd9Sstevel@tonic-gate     if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
22347c478bd9Sstevel@tonic-gate   }
22357c478bd9Sstevel@tonic-gate   for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
22367c478bd9Sstevel@tonic-gate     if( db->aDb[i].inTrans ){
22377c478bd9Sstevel@tonic-gate       rc = sqliteBtreeCommit(db->aDb[i].pBt);
22387c478bd9Sstevel@tonic-gate       db->aDb[i].inTrans = 0;
22397c478bd9Sstevel@tonic-gate     }
22407c478bd9Sstevel@tonic-gate   }
22417c478bd9Sstevel@tonic-gate   if( rc==SQLITE_OK ){
22427c478bd9Sstevel@tonic-gate     sqliteCommitInternalChanges(db);
22437c478bd9Sstevel@tonic-gate   }else{
22447c478bd9Sstevel@tonic-gate     sqliteRollbackAll(db);
22457c478bd9Sstevel@tonic-gate   }
22467c478bd9Sstevel@tonic-gate   break;
22477c478bd9Sstevel@tonic-gate }
22487c478bd9Sstevel@tonic-gate 
22497c478bd9Sstevel@tonic-gate /* Opcode: Rollback P1 * *
22507c478bd9Sstevel@tonic-gate **
22517c478bd9Sstevel@tonic-gate ** Cause all modifications to the database that have been made since the
22527c478bd9Sstevel@tonic-gate ** last Transaction to be undone. The database is restored to its state
22537c478bd9Sstevel@tonic-gate ** before the Transaction opcode was executed.  No additional modifications
22547c478bd9Sstevel@tonic-gate ** are allowed until another transaction is started.
22557c478bd9Sstevel@tonic-gate **
22567c478bd9Sstevel@tonic-gate ** P1 is the index of the database file that is committed.  An index of 0
22577c478bd9Sstevel@tonic-gate ** is used for the main database and an index of 1 is used for the file used
22587c478bd9Sstevel@tonic-gate ** to hold temporary tables.
22597c478bd9Sstevel@tonic-gate **
22607c478bd9Sstevel@tonic-gate ** This instruction automatically closes all cursors and releases both
22617c478bd9Sstevel@tonic-gate ** the read and write locks on the indicated database.
22627c478bd9Sstevel@tonic-gate */
22637c478bd9Sstevel@tonic-gate case OP_Rollback: {
22647c478bd9Sstevel@tonic-gate   sqliteRollbackAll(db);
22657c478bd9Sstevel@tonic-gate   break;
22667c478bd9Sstevel@tonic-gate }
22677c478bd9Sstevel@tonic-gate 
22687c478bd9Sstevel@tonic-gate /* Opcode: ReadCookie P1 P2 *
22697c478bd9Sstevel@tonic-gate **
22707c478bd9Sstevel@tonic-gate ** Read cookie number P2 from database P1 and push it onto the stack.
22717c478bd9Sstevel@tonic-gate ** P2==0 is the schema version.  P2==1 is the database format.
22727c478bd9Sstevel@tonic-gate ** P2==2 is the recommended pager cache size, and so forth.  P1==0 is
22737c478bd9Sstevel@tonic-gate ** the main database file and P1==1 is the database file used to store
22747c478bd9Sstevel@tonic-gate ** temporary tables.
22757c478bd9Sstevel@tonic-gate **
22767c478bd9Sstevel@tonic-gate ** There must be a read-lock on the database (either a transaction
22777c478bd9Sstevel@tonic-gate ** must be started or there must be an open cursor) before
22787c478bd9Sstevel@tonic-gate ** executing this instruction.
22797c478bd9Sstevel@tonic-gate */
22807c478bd9Sstevel@tonic-gate case OP_ReadCookie: {
22817c478bd9Sstevel@tonic-gate   int aMeta[SQLITE_N_BTREE_META];
22827c478bd9Sstevel@tonic-gate   assert( pOp->p2<SQLITE_N_BTREE_META );
22837c478bd9Sstevel@tonic-gate   assert( pOp->p1>=0 && pOp->p1<db->nDb );
22847c478bd9Sstevel@tonic-gate   assert( db->aDb[pOp->p1].pBt!=0 );
22857c478bd9Sstevel@tonic-gate   rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
22867c478bd9Sstevel@tonic-gate   pTos++;
22877c478bd9Sstevel@tonic-gate   pTos->i = aMeta[1+pOp->p2];
22887c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Int;
22897c478bd9Sstevel@tonic-gate   break;
22907c478bd9Sstevel@tonic-gate }
22917c478bd9Sstevel@tonic-gate 
22927c478bd9Sstevel@tonic-gate /* Opcode: SetCookie P1 P2 *
22937c478bd9Sstevel@tonic-gate **
22947c478bd9Sstevel@tonic-gate ** Write the top of the stack into cookie number P2 of database P1.
22957c478bd9Sstevel@tonic-gate ** P2==0 is the schema version.  P2==1 is the database format.
22967c478bd9Sstevel@tonic-gate ** P2==2 is the recommended pager cache size, and so forth.  P1==0 is
22977c478bd9Sstevel@tonic-gate ** the main database file and P1==1 is the database file used to store
22987c478bd9Sstevel@tonic-gate ** temporary tables.
22997c478bd9Sstevel@tonic-gate **
23007c478bd9Sstevel@tonic-gate ** A transaction must be started before executing this opcode.
23017c478bd9Sstevel@tonic-gate */
23027c478bd9Sstevel@tonic-gate case OP_SetCookie: {
23037c478bd9Sstevel@tonic-gate   int aMeta[SQLITE_N_BTREE_META];
23047c478bd9Sstevel@tonic-gate   assert( pOp->p2<SQLITE_N_BTREE_META );
23057c478bd9Sstevel@tonic-gate   assert( pOp->p1>=0 && pOp->p1<db->nDb );
23067c478bd9Sstevel@tonic-gate   assert( db->aDb[pOp->p1].pBt!=0 );
23077c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
23087c478bd9Sstevel@tonic-gate   Integerify(pTos)
23097c478bd9Sstevel@tonic-gate   rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
23107c478bd9Sstevel@tonic-gate   if( rc==SQLITE_OK ){
23117c478bd9Sstevel@tonic-gate     aMeta[1+pOp->p2] = pTos->i;
23127c478bd9Sstevel@tonic-gate     rc = sqliteBtreeUpdateMeta(db->aDb[pOp->p1].pBt, aMeta);
23137c478bd9Sstevel@tonic-gate   }
23147c478bd9Sstevel@tonic-gate   Release(pTos);
23157c478bd9Sstevel@tonic-gate   pTos--;
23167c478bd9Sstevel@tonic-gate   break;
23177c478bd9Sstevel@tonic-gate }
23187c478bd9Sstevel@tonic-gate 
23197c478bd9Sstevel@tonic-gate /* Opcode: VerifyCookie P1 P2 *
23207c478bd9Sstevel@tonic-gate **
23217c478bd9Sstevel@tonic-gate ** Check the value of global database parameter number 0 (the
2322*55fea89dSDan Cross ** schema version) and make sure it is equal to P2.
23237c478bd9Sstevel@tonic-gate ** P1 is the database number which is 0 for the main database file
23247c478bd9Sstevel@tonic-gate ** and 1 for the file holding temporary tables and some higher number
23257c478bd9Sstevel@tonic-gate ** for auxiliary databases.
23267c478bd9Sstevel@tonic-gate **
23277c478bd9Sstevel@tonic-gate ** The cookie changes its value whenever the database schema changes.
23287c478bd9Sstevel@tonic-gate ** This operation is used to detect when that the cookie has changed
23297c478bd9Sstevel@tonic-gate ** and that the current process needs to reread the schema.
23307c478bd9Sstevel@tonic-gate **
23317c478bd9Sstevel@tonic-gate ** Either a transaction needs to have been started or an OP_Open needs
23327c478bd9Sstevel@tonic-gate ** to be executed (to establish a read lock) before this opcode is
23337c478bd9Sstevel@tonic-gate ** invoked.
23347c478bd9Sstevel@tonic-gate */
23357c478bd9Sstevel@tonic-gate case OP_VerifyCookie: {
23367c478bd9Sstevel@tonic-gate   int aMeta[SQLITE_N_BTREE_META];
23377c478bd9Sstevel@tonic-gate   assert( pOp->p1>=0 && pOp->p1<db->nDb );
23387c478bd9Sstevel@tonic-gate   rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
23397c478bd9Sstevel@tonic-gate   if( rc==SQLITE_OK && aMeta[1]!=pOp->p2 ){
23407c478bd9Sstevel@tonic-gate     sqliteSetString(&p->zErrMsg, "database schema has changed", (char*)0);
23417c478bd9Sstevel@tonic-gate     rc = SQLITE_SCHEMA;
23427c478bd9Sstevel@tonic-gate   }
23437c478bd9Sstevel@tonic-gate   break;
23447c478bd9Sstevel@tonic-gate }
23457c478bd9Sstevel@tonic-gate 
23467c478bd9Sstevel@tonic-gate /* Opcode: OpenRead P1 P2 P3
23477c478bd9Sstevel@tonic-gate **
23487c478bd9Sstevel@tonic-gate ** Open a read-only cursor for the database table whose root page is
2349*55fea89dSDan Cross ** P2 in a database file.  The database file is determined by an
23507c478bd9Sstevel@tonic-gate ** integer from the top of the stack.  0 means the main database and
2351*55fea89dSDan Cross ** 1 means the database used for temporary tables.  Give the new
23527c478bd9Sstevel@tonic-gate ** cursor an identifier of P1.  The P1 values need not be contiguous
23537c478bd9Sstevel@tonic-gate ** but all P1 values should be small integers.  It is an error for
23547c478bd9Sstevel@tonic-gate ** P1 to be negative.
23557c478bd9Sstevel@tonic-gate **
23567c478bd9Sstevel@tonic-gate ** If P2==0 then take the root page number from the next of the stack.
23577c478bd9Sstevel@tonic-gate **
23587c478bd9Sstevel@tonic-gate ** There will be a read lock on the database whenever there is an
23597c478bd9Sstevel@tonic-gate ** open cursor.  If the database was unlocked prior to this instruction
23607c478bd9Sstevel@tonic-gate ** then a read lock is acquired as part of this instruction.  A read
23617c478bd9Sstevel@tonic-gate ** lock allows other processes to read the database but prohibits
23627c478bd9Sstevel@tonic-gate ** any other process from modifying the database.  The read lock is
23637c478bd9Sstevel@tonic-gate ** released when all cursors are closed.  If this instruction attempts
23647c478bd9Sstevel@tonic-gate ** to get a read lock but fails, the script terminates with an
23657c478bd9Sstevel@tonic-gate ** SQLITE_BUSY error code.
23667c478bd9Sstevel@tonic-gate **
23677c478bd9Sstevel@tonic-gate ** The P3 value is the name of the table or index being opened.
23687c478bd9Sstevel@tonic-gate ** The P3 value is not actually used by this opcode and may be
23697c478bd9Sstevel@tonic-gate ** omitted.  But the code generator usually inserts the index or
23707c478bd9Sstevel@tonic-gate ** table name into P3 to make the code easier to read.
23717c478bd9Sstevel@tonic-gate **
23727c478bd9Sstevel@tonic-gate ** See also OpenWrite.
23737c478bd9Sstevel@tonic-gate */
23747c478bd9Sstevel@tonic-gate /* Opcode: OpenWrite P1 P2 P3
23757c478bd9Sstevel@tonic-gate **
23767c478bd9Sstevel@tonic-gate ** Open a read/write cursor named P1 on the table or index whose root
23777c478bd9Sstevel@tonic-gate ** page is P2.  If P2==0 then take the root page number from the stack.
23787c478bd9Sstevel@tonic-gate **
23797c478bd9Sstevel@tonic-gate ** The P3 value is the name of the table or index being opened.
23807c478bd9Sstevel@tonic-gate ** The P3 value is not actually used by this opcode and may be
23817c478bd9Sstevel@tonic-gate ** omitted.  But the code generator usually inserts the index or
23827c478bd9Sstevel@tonic-gate ** table name into P3 to make the code easier to read.
23837c478bd9Sstevel@tonic-gate **
23847c478bd9Sstevel@tonic-gate ** This instruction works just like OpenRead except that it opens the cursor
23857c478bd9Sstevel@tonic-gate ** in read/write mode.  For a given table, there can be one or more read-only
23867c478bd9Sstevel@tonic-gate ** cursors or a single read/write cursor but not both.
23877c478bd9Sstevel@tonic-gate **
23887c478bd9Sstevel@tonic-gate ** See also OpenRead.
23897c478bd9Sstevel@tonic-gate */
23907c478bd9Sstevel@tonic-gate case OP_OpenRead:
23917c478bd9Sstevel@tonic-gate case OP_OpenWrite: {
23927c478bd9Sstevel@tonic-gate   int busy = 0;
23937c478bd9Sstevel@tonic-gate   int i = pOp->p1;
23947c478bd9Sstevel@tonic-gate   int p2 = pOp->p2;
23957c478bd9Sstevel@tonic-gate   int wrFlag;
23967c478bd9Sstevel@tonic-gate   Btree *pX;
23977c478bd9Sstevel@tonic-gate   int iDb;
2398*55fea89dSDan Cross 
23997c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
24007c478bd9Sstevel@tonic-gate   Integerify(pTos);
24017c478bd9Sstevel@tonic-gate   iDb = pTos->i;
24027c478bd9Sstevel@tonic-gate   pTos--;
24037c478bd9Sstevel@tonic-gate   assert( iDb>=0 && iDb<db->nDb );
24047c478bd9Sstevel@tonic-gate   pX = db->aDb[iDb].pBt;
24057c478bd9Sstevel@tonic-gate   assert( pX!=0 );
24067c478bd9Sstevel@tonic-gate   wrFlag = pOp->opcode==OP_OpenWrite;
24077c478bd9Sstevel@tonic-gate   if( p2<=0 ){
24087c478bd9Sstevel@tonic-gate     assert( pTos>=p->aStack );
24097c478bd9Sstevel@tonic-gate     Integerify(pTos);
24107c478bd9Sstevel@tonic-gate     p2 = pTos->i;
24117c478bd9Sstevel@tonic-gate     pTos--;
24127c478bd9Sstevel@tonic-gate     if( p2<2 ){
24137c478bd9Sstevel@tonic-gate       sqliteSetString(&p->zErrMsg, "root page number less than 2", (char*)0);
24147c478bd9Sstevel@tonic-gate       rc = SQLITE_INTERNAL;
24157c478bd9Sstevel@tonic-gate       break;
24167c478bd9Sstevel@tonic-gate     }
24177c478bd9Sstevel@tonic-gate   }
24187c478bd9Sstevel@tonic-gate   assert( i>=0 );
24197c478bd9Sstevel@tonic-gate   if( expandCursorArraySize(p, i) ) goto no_mem;
24207c478bd9Sstevel@tonic-gate   sqliteVdbeCleanupCursor(&p->aCsr[i]);
24217c478bd9Sstevel@tonic-gate   memset(&p->aCsr[i], 0, sizeof(Cursor));
24227c478bd9Sstevel@tonic-gate   p->aCsr[i].nullRow = 1;
24237c478bd9Sstevel@tonic-gate   if( pX==0 ) break;
24247c478bd9Sstevel@tonic-gate   do{
24257c478bd9Sstevel@tonic-gate     rc = sqliteBtreeCursor(pX, p2, wrFlag, &p->aCsr[i].pCursor);
24267c478bd9Sstevel@tonic-gate     switch( rc ){
24277c478bd9Sstevel@tonic-gate       case SQLITE_BUSY: {
24287c478bd9Sstevel@tonic-gate         if( db->xBusyCallback==0 ){
24297c478bd9Sstevel@tonic-gate           p->pc = pc;
24307c478bd9Sstevel@tonic-gate           p->rc = SQLITE_BUSY;
24317c478bd9Sstevel@tonic-gate           p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
24327c478bd9Sstevel@tonic-gate           return SQLITE_BUSY;
24337c478bd9Sstevel@tonic-gate         }else if( (*db->xBusyCallback)(db->pBusyArg, pOp->p3, ++busy)==0 ){
24347c478bd9Sstevel@tonic-gate           sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
24357c478bd9Sstevel@tonic-gate           busy = 0;
24367c478bd9Sstevel@tonic-gate         }
24377c478bd9Sstevel@tonic-gate         break;
24387c478bd9Sstevel@tonic-gate       }
24397c478bd9Sstevel@tonic-gate       case SQLITE_OK: {
24407c478bd9Sstevel@tonic-gate         busy = 0;
24417c478bd9Sstevel@tonic-gate         break;
24427c478bd9Sstevel@tonic-gate       }
24437c478bd9Sstevel@tonic-gate       default: {
24447c478bd9Sstevel@tonic-gate         goto abort_due_to_error;
24457c478bd9Sstevel@tonic-gate       }
24467c478bd9Sstevel@tonic-gate     }
24477c478bd9Sstevel@tonic-gate   }while( busy );
24487c478bd9Sstevel@tonic-gate   break;
24497c478bd9Sstevel@tonic-gate }
24507c478bd9Sstevel@tonic-gate 
24517c478bd9Sstevel@tonic-gate /* Opcode: OpenTemp P1 P2 *
24527c478bd9Sstevel@tonic-gate **
24537c478bd9Sstevel@tonic-gate ** Open a new cursor to a transient table.
2454*55fea89dSDan Cross ** The transient cursor is always opened read/write even if
24557c478bd9Sstevel@tonic-gate ** the main database is read-only.  The transient table is deleted
24567c478bd9Sstevel@tonic-gate ** automatically when the cursor is closed.
24577c478bd9Sstevel@tonic-gate **
24587c478bd9Sstevel@tonic-gate ** The cursor points to a BTree table if P2==0 and to a BTree index
24597c478bd9Sstevel@tonic-gate ** if P2==1.  A BTree table must have an integer key and can have arbitrary
24607c478bd9Sstevel@tonic-gate ** data.  A BTree index has no data but can have an arbitrary key.
24617c478bd9Sstevel@tonic-gate **
24627c478bd9Sstevel@tonic-gate ** This opcode is used for tables that exist for the duration of a single
24637c478bd9Sstevel@tonic-gate ** SQL statement only.  Tables created using CREATE TEMPORARY TABLE
24647c478bd9Sstevel@tonic-gate ** are opened using OP_OpenRead or OP_OpenWrite.  "Temporary" in the
24657c478bd9Sstevel@tonic-gate ** context of this opcode means for the duration of a single SQL statement
24667c478bd9Sstevel@tonic-gate ** whereas "Temporary" in the context of CREATE TABLE means for the duration
24677c478bd9Sstevel@tonic-gate ** of the connection to the database.  Same word; different meanings.
24687c478bd9Sstevel@tonic-gate */
24697c478bd9Sstevel@tonic-gate case OP_OpenTemp: {
24707c478bd9Sstevel@tonic-gate   int i = pOp->p1;
24717c478bd9Sstevel@tonic-gate   Cursor *pCx;
24727c478bd9Sstevel@tonic-gate   assert( i>=0 );
24737c478bd9Sstevel@tonic-gate   if( expandCursorArraySize(p, i) ) goto no_mem;
24747c478bd9Sstevel@tonic-gate   pCx = &p->aCsr[i];
24757c478bd9Sstevel@tonic-gate   sqliteVdbeCleanupCursor(pCx);
24767c478bd9Sstevel@tonic-gate   memset(pCx, 0, sizeof(*pCx));
24777c478bd9Sstevel@tonic-gate   pCx->nullRow = 1;
24787c478bd9Sstevel@tonic-gate   rc = sqliteBtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
24797c478bd9Sstevel@tonic-gate 
24807c478bd9Sstevel@tonic-gate   if( rc==SQLITE_OK ){
24817c478bd9Sstevel@tonic-gate     rc = sqliteBtreeBeginTrans(pCx->pBt);
24827c478bd9Sstevel@tonic-gate   }
24837c478bd9Sstevel@tonic-gate   if( rc==SQLITE_OK ){
24847c478bd9Sstevel@tonic-gate     if( pOp->p2 ){
24857c478bd9Sstevel@tonic-gate       int pgno;
24867c478bd9Sstevel@tonic-gate       rc = sqliteBtreeCreateIndex(pCx->pBt, &pgno);
24877c478bd9Sstevel@tonic-gate       if( rc==SQLITE_OK ){
24887c478bd9Sstevel@tonic-gate         rc = sqliteBtreeCursor(pCx->pBt, pgno, 1, &pCx->pCursor);
24897c478bd9Sstevel@tonic-gate       }
24907c478bd9Sstevel@tonic-gate     }else{
24917c478bd9Sstevel@tonic-gate       rc = sqliteBtreeCursor(pCx->pBt, 2, 1, &pCx->pCursor);
24927c478bd9Sstevel@tonic-gate     }
24937c478bd9Sstevel@tonic-gate   }
24947c478bd9Sstevel@tonic-gate   break;
24957c478bd9Sstevel@tonic-gate }
24967c478bd9Sstevel@tonic-gate 
24977c478bd9Sstevel@tonic-gate /* Opcode: OpenPseudo P1 * *
24987c478bd9Sstevel@tonic-gate **
24997c478bd9Sstevel@tonic-gate ** Open a new cursor that points to a fake table that contains a single
25007c478bd9Sstevel@tonic-gate ** row of data.  Any attempt to write a second row of data causes the
25017c478bd9Sstevel@tonic-gate ** first row to be deleted.  All data is deleted when the cursor is
25027c478bd9Sstevel@tonic-gate ** closed.
25037c478bd9Sstevel@tonic-gate **
25047c478bd9Sstevel@tonic-gate ** A pseudo-table created by this opcode is useful for holding the
25057c478bd9Sstevel@tonic-gate ** NEW or OLD tables in a trigger.
25067c478bd9Sstevel@tonic-gate */
25077c478bd9Sstevel@tonic-gate case OP_OpenPseudo: {
25087c478bd9Sstevel@tonic-gate   int i = pOp->p1;
25097c478bd9Sstevel@tonic-gate   Cursor *pCx;
25107c478bd9Sstevel@tonic-gate   assert( i>=0 );
25117c478bd9Sstevel@tonic-gate   if( expandCursorArraySize(p, i) ) goto no_mem;
25127c478bd9Sstevel@tonic-gate   pCx = &p->aCsr[i];
25137c478bd9Sstevel@tonic-gate   sqliteVdbeCleanupCursor(pCx);
25147c478bd9Sstevel@tonic-gate   memset(pCx, 0, sizeof(*pCx));
25157c478bd9Sstevel@tonic-gate   pCx->nullRow = 1;
25167c478bd9Sstevel@tonic-gate   pCx->pseudoTable = 1;
25177c478bd9Sstevel@tonic-gate   break;
25187c478bd9Sstevel@tonic-gate }
25197c478bd9Sstevel@tonic-gate 
25207c478bd9Sstevel@tonic-gate /* Opcode: Close P1 * *
25217c478bd9Sstevel@tonic-gate **
25227c478bd9Sstevel@tonic-gate ** Close a cursor previously opened as P1.  If P1 is not
25237c478bd9Sstevel@tonic-gate ** currently open, this instruction is a no-op.
25247c478bd9Sstevel@tonic-gate */
25257c478bd9Sstevel@tonic-gate case OP_Close: {
25267c478bd9Sstevel@tonic-gate   int i = pOp->p1;
25277c478bd9Sstevel@tonic-gate   if( i>=0 && i<p->nCursor ){
25287c478bd9Sstevel@tonic-gate     sqliteVdbeCleanupCursor(&p->aCsr[i]);
25297c478bd9Sstevel@tonic-gate   }
25307c478bd9Sstevel@tonic-gate   break;
25317c478bd9Sstevel@tonic-gate }
25327c478bd9Sstevel@tonic-gate 
25337c478bd9Sstevel@tonic-gate /* Opcode: MoveTo P1 P2 *
25347c478bd9Sstevel@tonic-gate **
25357c478bd9Sstevel@tonic-gate ** Pop the top of the stack and use its value as a key.  Reposition
25367c478bd9Sstevel@tonic-gate ** cursor P1 so that it points to an entry with a matching key.  If
25377c478bd9Sstevel@tonic-gate ** the table contains no record with a matching key, then the cursor
25387c478bd9Sstevel@tonic-gate ** is left pointing at the first record that is greater than the key.
25397c478bd9Sstevel@tonic-gate ** If there are no records greater than the key and P2 is not zero,
25407c478bd9Sstevel@tonic-gate ** then an immediate jump to P2 is made.
25417c478bd9Sstevel@tonic-gate **
25427c478bd9Sstevel@tonic-gate ** See also: Found, NotFound, Distinct, MoveLt
25437c478bd9Sstevel@tonic-gate */
25447c478bd9Sstevel@tonic-gate /* Opcode: MoveLt P1 P2 *
25457c478bd9Sstevel@tonic-gate **
25467c478bd9Sstevel@tonic-gate ** Pop the top of the stack and use its value as a key.  Reposition
25477c478bd9Sstevel@tonic-gate ** cursor P1 so that it points to the entry with the largest key that is
25487c478bd9Sstevel@tonic-gate ** less than the key popped from the stack.
25497c478bd9Sstevel@tonic-gate ** If there are no records less than than the key and P2
25507c478bd9Sstevel@tonic-gate ** is not zero then an immediate jump to P2 is made.
25517c478bd9Sstevel@tonic-gate **
25527c478bd9Sstevel@tonic-gate ** See also: MoveTo
25537c478bd9Sstevel@tonic-gate */
25547c478bd9Sstevel@tonic-gate case OP_MoveLt:
25557c478bd9Sstevel@tonic-gate case OP_MoveTo: {
25567c478bd9Sstevel@tonic-gate   int i = pOp->p1;
25577c478bd9Sstevel@tonic-gate   Cursor *pC;
25587c478bd9Sstevel@tonic-gate 
25597c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
25607c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
25617c478bd9Sstevel@tonic-gate   pC = &p->aCsr[i];
25627c478bd9Sstevel@tonic-gate   if( pC->pCursor!=0 ){
25637c478bd9Sstevel@tonic-gate     int res, oc;
25647c478bd9Sstevel@tonic-gate     pC->nullRow = 0;
25657c478bd9Sstevel@tonic-gate     if( pTos->flags & MEM_Int ){
25667c478bd9Sstevel@tonic-gate       int iKey = intToKey(pTos->i);
25677c478bd9Sstevel@tonic-gate       if( pOp->p2==0 && pOp->opcode==OP_MoveTo ){
25687c478bd9Sstevel@tonic-gate         pC->movetoTarget = iKey;
25697c478bd9Sstevel@tonic-gate         pC->deferredMoveto = 1;
25707c478bd9Sstevel@tonic-gate         Release(pTos);
25717c478bd9Sstevel@tonic-gate         pTos--;
25727c478bd9Sstevel@tonic-gate         break;
25737c478bd9Sstevel@tonic-gate       }
25747c478bd9Sstevel@tonic-gate       sqliteBtreeMoveto(pC->pCursor, (char*)&iKey, sizeof(int), &res);
25757c478bd9Sstevel@tonic-gate       pC->lastRecno = pTos->i;
25767c478bd9Sstevel@tonic-gate       pC->recnoIsValid = res==0;
25777c478bd9Sstevel@tonic-gate     }else{
25787c478bd9Sstevel@tonic-gate       Stringify(pTos);
25797c478bd9Sstevel@tonic-gate       sqliteBtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
25807c478bd9Sstevel@tonic-gate       pC->recnoIsValid = 0;
25817c478bd9Sstevel@tonic-gate     }
25827c478bd9Sstevel@tonic-gate     pC->deferredMoveto = 0;
25837c478bd9Sstevel@tonic-gate     sqlite_search_count++;
25847c478bd9Sstevel@tonic-gate     oc = pOp->opcode;
25857c478bd9Sstevel@tonic-gate     if( oc==OP_MoveTo && res<0 ){
25867c478bd9Sstevel@tonic-gate       sqliteBtreeNext(pC->pCursor, &res);
25877c478bd9Sstevel@tonic-gate       pC->recnoIsValid = 0;
25887c478bd9Sstevel@tonic-gate       if( res && pOp->p2>0 ){
25897c478bd9Sstevel@tonic-gate         pc = pOp->p2 - 1;
25907c478bd9Sstevel@tonic-gate       }
25917c478bd9Sstevel@tonic-gate     }else if( oc==OP_MoveLt ){
25927c478bd9Sstevel@tonic-gate       if( res>=0 ){
25937c478bd9Sstevel@tonic-gate         sqliteBtreePrevious(pC->pCursor, &res);
25947c478bd9Sstevel@tonic-gate         pC->recnoIsValid = 0;
25957c478bd9Sstevel@tonic-gate       }else{
25967c478bd9Sstevel@tonic-gate         /* res might be negative because the table is empty.  Check to
25977c478bd9Sstevel@tonic-gate         ** see if this is the case.
25987c478bd9Sstevel@tonic-gate         */
25997c478bd9Sstevel@tonic-gate         int keysize;
26007c478bd9Sstevel@tonic-gate         res = sqliteBtreeKeySize(pC->pCursor,&keysize)!=0 || keysize==0;
26017c478bd9Sstevel@tonic-gate       }
26027c478bd9Sstevel@tonic-gate       if( res && pOp->p2>0 ){
26037c478bd9Sstevel@tonic-gate         pc = pOp->p2 - 1;
26047c478bd9Sstevel@tonic-gate       }
26057c478bd9Sstevel@tonic-gate     }
26067c478bd9Sstevel@tonic-gate   }
26077c478bd9Sstevel@tonic-gate   Release(pTos);
26087c478bd9Sstevel@tonic-gate   pTos--;
26097c478bd9Sstevel@tonic-gate   break;
26107c478bd9Sstevel@tonic-gate }
26117c478bd9Sstevel@tonic-gate 
26127c478bd9Sstevel@tonic-gate /* Opcode: Distinct P1 P2 *
26137c478bd9Sstevel@tonic-gate **
26147c478bd9Sstevel@tonic-gate ** Use the top of the stack as a string key.  If a record with that key does
26157c478bd9Sstevel@tonic-gate ** not exist in the table of cursor P1, then jump to P2.  If the record
26167c478bd9Sstevel@tonic-gate ** does already exist, then fall thru.  The cursor is left pointing
26177c478bd9Sstevel@tonic-gate ** at the record if it exists. The key is not popped from the stack.
26187c478bd9Sstevel@tonic-gate **
26197c478bd9Sstevel@tonic-gate ** This operation is similar to NotFound except that this operation
26207c478bd9Sstevel@tonic-gate ** does not pop the key from the stack.
26217c478bd9Sstevel@tonic-gate **
26227c478bd9Sstevel@tonic-gate ** See also: Found, NotFound, MoveTo, IsUnique, NotExists
26237c478bd9Sstevel@tonic-gate */
26247c478bd9Sstevel@tonic-gate /* Opcode: Found P1 P2 *
26257c478bd9Sstevel@tonic-gate **
26267c478bd9Sstevel@tonic-gate ** Use the top of the stack as a string key.  If a record with that key
26277c478bd9Sstevel@tonic-gate ** does exist in table of P1, then jump to P2.  If the record
26287c478bd9Sstevel@tonic-gate ** does not exist, then fall thru.  The cursor is left pointing
26297c478bd9Sstevel@tonic-gate ** to the record if it exists.  The key is popped from the stack.
26307c478bd9Sstevel@tonic-gate **
26317c478bd9Sstevel@tonic-gate ** See also: Distinct, NotFound, MoveTo, IsUnique, NotExists
26327c478bd9Sstevel@tonic-gate */
26337c478bd9Sstevel@tonic-gate /* Opcode: NotFound P1 P2 *
26347c478bd9Sstevel@tonic-gate **
26357c478bd9Sstevel@tonic-gate ** Use the top of the stack as a string key.  If a record with that key
26367c478bd9Sstevel@tonic-gate ** does not exist in table of P1, then jump to P2.  If the record
26377c478bd9Sstevel@tonic-gate ** does exist, then fall thru.  The cursor is left pointing to the
26387c478bd9Sstevel@tonic-gate ** record if it exists.  The key is popped from the stack.
26397c478bd9Sstevel@tonic-gate **
26407c478bd9Sstevel@tonic-gate ** The difference between this operation and Distinct is that
26417c478bd9Sstevel@tonic-gate ** Distinct does not pop the key from the stack.
26427c478bd9Sstevel@tonic-gate **
26437c478bd9Sstevel@tonic-gate ** See also: Distinct, Found, MoveTo, NotExists, IsUnique
26447c478bd9Sstevel@tonic-gate */
26457c478bd9Sstevel@tonic-gate case OP_Distinct:
26467c478bd9Sstevel@tonic-gate case OP_NotFound:
26477c478bd9Sstevel@tonic-gate case OP_Found: {
26487c478bd9Sstevel@tonic-gate   int i = pOp->p1;
26497c478bd9Sstevel@tonic-gate   int alreadyExists = 0;
26507c478bd9Sstevel@tonic-gate   Cursor *pC;
26517c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
26527c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
26537c478bd9Sstevel@tonic-gate   if( (pC = &p->aCsr[i])->pCursor!=0 ){
26547c478bd9Sstevel@tonic-gate     int res, rx;
26557c478bd9Sstevel@tonic-gate     Stringify(pTos);
26567c478bd9Sstevel@tonic-gate     rx = sqliteBtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
26577c478bd9Sstevel@tonic-gate     alreadyExists = rx==SQLITE_OK && res==0;
26587c478bd9Sstevel@tonic-gate     pC->deferredMoveto = 0;
26597c478bd9Sstevel@tonic-gate   }
26607c478bd9Sstevel@tonic-gate   if( pOp->opcode==OP_Found ){
26617c478bd9Sstevel@tonic-gate     if( alreadyExists ) pc = pOp->p2 - 1;
26627c478bd9Sstevel@tonic-gate   }else{
26637c478bd9Sstevel@tonic-gate     if( !alreadyExists ) pc = pOp->p2 - 1;
26647c478bd9Sstevel@tonic-gate   }
26657c478bd9Sstevel@tonic-gate   if( pOp->opcode!=OP_Distinct ){
26667c478bd9Sstevel@tonic-gate     Release(pTos);
26677c478bd9Sstevel@tonic-gate     pTos--;
26687c478bd9Sstevel@tonic-gate   }
26697c478bd9Sstevel@tonic-gate   break;
26707c478bd9Sstevel@tonic-gate }
26717c478bd9Sstevel@tonic-gate 
26727c478bd9Sstevel@tonic-gate /* Opcode: IsUnique P1 P2 *
26737c478bd9Sstevel@tonic-gate **
26747c478bd9Sstevel@tonic-gate ** The top of the stack is an integer record number.  Call this
26757c478bd9Sstevel@tonic-gate ** record number R.  The next on the stack is an index key created
26767c478bd9Sstevel@tonic-gate ** using MakeIdxKey.  Call it K.  This instruction pops R from the
26777c478bd9Sstevel@tonic-gate ** stack but it leaves K unchanged.
26787c478bd9Sstevel@tonic-gate **
26797c478bd9Sstevel@tonic-gate ** P1 is an index.  So all but the last four bytes of K are an
26807c478bd9Sstevel@tonic-gate ** index string.  The last four bytes of K are a record number.
26817c478bd9Sstevel@tonic-gate **
26827c478bd9Sstevel@tonic-gate ** This instruction asks if there is an entry in P1 where the
26837c478bd9Sstevel@tonic-gate ** index string matches K but the record number is different
26847c478bd9Sstevel@tonic-gate ** from R.  If there is no such entry, then there is an immediate
26857c478bd9Sstevel@tonic-gate ** jump to P2.  If any entry does exist where the index string
26867c478bd9Sstevel@tonic-gate ** matches K but the record number is not R, then the record
26877c478bd9Sstevel@tonic-gate ** number for that entry is pushed onto the stack and control
26887c478bd9Sstevel@tonic-gate ** falls through to the next instruction.
26897c478bd9Sstevel@tonic-gate **
26907c478bd9Sstevel@tonic-gate ** See also: Distinct, NotFound, NotExists, Found
26917c478bd9Sstevel@tonic-gate */
26927c478bd9Sstevel@tonic-gate case OP_IsUnique: {
26937c478bd9Sstevel@tonic-gate   int i = pOp->p1;
26947c478bd9Sstevel@tonic-gate   Mem *pNos = &pTos[-1];
26957c478bd9Sstevel@tonic-gate   BtCursor *pCrsr;
26967c478bd9Sstevel@tonic-gate   int R;
26977c478bd9Sstevel@tonic-gate 
26987c478bd9Sstevel@tonic-gate   /* Pop the value R off the top of the stack
26997c478bd9Sstevel@tonic-gate   */
27007c478bd9Sstevel@tonic-gate   assert( pNos>=p->aStack );
27017c478bd9Sstevel@tonic-gate   Integerify(pTos);
27027c478bd9Sstevel@tonic-gate   R = pTos->i;
27037c478bd9Sstevel@tonic-gate   pTos--;
27047c478bd9Sstevel@tonic-gate   assert( i>=0 && i<=p->nCursor );
27057c478bd9Sstevel@tonic-gate   if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
27067c478bd9Sstevel@tonic-gate     int res, rc;
27077c478bd9Sstevel@tonic-gate     int v;         /* The record number on the P1 entry that matches K */
27087c478bd9Sstevel@tonic-gate     char *zKey;    /* The value of K */
27097c478bd9Sstevel@tonic-gate     int nKey;      /* Number of bytes in K */
27107c478bd9Sstevel@tonic-gate 
27117c478bd9Sstevel@tonic-gate     /* Make sure K is a string and make zKey point to K
27127c478bd9Sstevel@tonic-gate     */
27137c478bd9Sstevel@tonic-gate     Stringify(pNos);
27147c478bd9Sstevel@tonic-gate     zKey = pNos->z;
27157c478bd9Sstevel@tonic-gate     nKey = pNos->n;
27167c478bd9Sstevel@tonic-gate     assert( nKey >= 4 );
27177c478bd9Sstevel@tonic-gate 
27187c478bd9Sstevel@tonic-gate     /* Search for an entry in P1 where all but the last four bytes match K.
27197c478bd9Sstevel@tonic-gate     ** If there is no such entry, jump immediately to P2.
27207c478bd9Sstevel@tonic-gate     */
27217c478bd9Sstevel@tonic-gate     assert( p->aCsr[i].deferredMoveto==0 );
27227c478bd9Sstevel@tonic-gate     rc = sqliteBtreeMoveto(pCrsr, zKey, nKey-4, &res);
27237c478bd9Sstevel@tonic-gate     if( rc!=SQLITE_OK ) goto abort_due_to_error;
27247c478bd9Sstevel@tonic-gate     if( res<0 ){
27257c478bd9Sstevel@tonic-gate       rc = sqliteBtreeNext(pCrsr, &res);
27267c478bd9Sstevel@tonic-gate       if( res ){
27277c478bd9Sstevel@tonic-gate         pc = pOp->p2 - 1;
27287c478bd9Sstevel@tonic-gate         break;
27297c478bd9Sstevel@tonic-gate       }
27307c478bd9Sstevel@tonic-gate     }
27317c478bd9Sstevel@tonic-gate     rc = sqliteBtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &res);
27327c478bd9Sstevel@tonic-gate     if( rc!=SQLITE_OK ) goto abort_due_to_error;
27337c478bd9Sstevel@tonic-gate     if( res>0 ){
27347c478bd9Sstevel@tonic-gate       pc = pOp->p2 - 1;
27357c478bd9Sstevel@tonic-gate       break;
27367c478bd9Sstevel@tonic-gate     }
27377c478bd9Sstevel@tonic-gate 
27387c478bd9Sstevel@tonic-gate     /* At this point, pCrsr is pointing to an entry in P1 where all but
27397c478bd9Sstevel@tonic-gate     ** the last for bytes of the key match K.  Check to see if the last
27407c478bd9Sstevel@tonic-gate     ** four bytes of the key are different from R.  If the last four
27417c478bd9Sstevel@tonic-gate     ** bytes equal R then jump immediately to P2.
27427c478bd9Sstevel@tonic-gate     */
27437c478bd9Sstevel@tonic-gate     sqliteBtreeKey(pCrsr, nKey - 4, 4, (char*)&v);
27447c478bd9Sstevel@tonic-gate     v = keyToInt(v);
27457c478bd9Sstevel@tonic-gate     if( v==R ){
27467c478bd9Sstevel@tonic-gate       pc = pOp->p2 - 1;
27477c478bd9Sstevel@tonic-gate       break;
27487c478bd9Sstevel@tonic-gate     }
27497c478bd9Sstevel@tonic-gate 
27507c478bd9Sstevel@tonic-gate     /* The last four bytes of the key are different from R.  Convert the
27517c478bd9Sstevel@tonic-gate     ** last four bytes of the key into an integer and push it onto the
27527c478bd9Sstevel@tonic-gate     ** stack.  (These bytes are the record number of an entry that
27537c478bd9Sstevel@tonic-gate     ** violates a UNIQUE constraint.)
27547c478bd9Sstevel@tonic-gate     */
27557c478bd9Sstevel@tonic-gate     pTos++;
27567c478bd9Sstevel@tonic-gate     pTos->i = v;
27577c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Int;
27587c478bd9Sstevel@tonic-gate   }
27597c478bd9Sstevel@tonic-gate   break;
27607c478bd9Sstevel@tonic-gate }
27617c478bd9Sstevel@tonic-gate 
27627c478bd9Sstevel@tonic-gate /* Opcode: NotExists P1 P2 *
27637c478bd9Sstevel@tonic-gate **
27647c478bd9Sstevel@tonic-gate ** Use the top of the stack as a integer key.  If a record with that key
27657c478bd9Sstevel@tonic-gate ** does not exist in table of P1, then jump to P2.  If the record
27667c478bd9Sstevel@tonic-gate ** does exist, then fall thru.  The cursor is left pointing to the
27677c478bd9Sstevel@tonic-gate ** record if it exists.  The integer key is popped from the stack.
27687c478bd9Sstevel@tonic-gate **
27697c478bd9Sstevel@tonic-gate ** The difference between this operation and NotFound is that this
27707c478bd9Sstevel@tonic-gate ** operation assumes the key is an integer and NotFound assumes it
27717c478bd9Sstevel@tonic-gate ** is a string.
27727c478bd9Sstevel@tonic-gate **
27737c478bd9Sstevel@tonic-gate ** See also: Distinct, Found, MoveTo, NotFound, IsUnique
27747c478bd9Sstevel@tonic-gate */
27757c478bd9Sstevel@tonic-gate case OP_NotExists: {
27767c478bd9Sstevel@tonic-gate   int i = pOp->p1;
27777c478bd9Sstevel@tonic-gate   BtCursor *pCrsr;
27787c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
27797c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
27807c478bd9Sstevel@tonic-gate   if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
27817c478bd9Sstevel@tonic-gate     int res, rx, iKey;
27827c478bd9Sstevel@tonic-gate     assert( pTos->flags & MEM_Int );
27837c478bd9Sstevel@tonic-gate     iKey = intToKey(pTos->i);
27847c478bd9Sstevel@tonic-gate     rx = sqliteBtreeMoveto(pCrsr, (char*)&iKey, sizeof(int), &res);
27857c478bd9Sstevel@tonic-gate     p->aCsr[i].lastRecno = pTos->i;
27867c478bd9Sstevel@tonic-gate     p->aCsr[i].recnoIsValid = res==0;
27877c478bd9Sstevel@tonic-gate     p->aCsr[i].nullRow = 0;
27887c478bd9Sstevel@tonic-gate     if( rx!=SQLITE_OK || res!=0 ){
27897c478bd9Sstevel@tonic-gate       pc = pOp->p2 - 1;
27907c478bd9Sstevel@tonic-gate       p->aCsr[i].recnoIsValid = 0;
27917c478bd9Sstevel@tonic-gate     }
27927c478bd9Sstevel@tonic-gate   }
27937c478bd9Sstevel@tonic-gate   Release(pTos);
27947c478bd9Sstevel@tonic-gate   pTos--;
27957c478bd9Sstevel@tonic-gate   break;
27967c478bd9Sstevel@tonic-gate }
27977c478bd9Sstevel@tonic-gate 
27987c478bd9Sstevel@tonic-gate /* Opcode: NewRecno P1 * *
27997c478bd9Sstevel@tonic-gate **
28007c478bd9Sstevel@tonic-gate ** Get a new integer record number used as the key to a table.
28017c478bd9Sstevel@tonic-gate ** The record number is not previously used as a key in the database
2802*55fea89dSDan Cross ** table that cursor P1 points to.  The new record number is pushed
28037c478bd9Sstevel@tonic-gate ** onto the stack.
28047c478bd9Sstevel@tonic-gate */
28057c478bd9Sstevel@tonic-gate case OP_NewRecno: {
28067c478bd9Sstevel@tonic-gate   int i = pOp->p1;
28077c478bd9Sstevel@tonic-gate   int v = 0;
28087c478bd9Sstevel@tonic-gate   Cursor *pC;
28097c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
28107c478bd9Sstevel@tonic-gate   if( (pC = &p->aCsr[i])->pCursor==0 ){
28117c478bd9Sstevel@tonic-gate     v = 0;
28127c478bd9Sstevel@tonic-gate   }else{
28137c478bd9Sstevel@tonic-gate     /* The next rowid or record number (different terms for the same
28147c478bd9Sstevel@tonic-gate     ** thing) is obtained in a two-step algorithm.
28157c478bd9Sstevel@tonic-gate     **
28167c478bd9Sstevel@tonic-gate     ** First we attempt to find the largest existing rowid and add one
28177c478bd9Sstevel@tonic-gate     ** to that.  But if the largest existing rowid is already the maximum
28187c478bd9Sstevel@tonic-gate     ** positive integer, we have to fall through to the second
28197c478bd9Sstevel@tonic-gate     ** probabilistic algorithm
28207c478bd9Sstevel@tonic-gate     **
28217c478bd9Sstevel@tonic-gate     ** The second algorithm is to select a rowid at random and see if
28227c478bd9Sstevel@tonic-gate     ** it already exists in the table.  If it does not exist, we have
28237c478bd9Sstevel@tonic-gate     ** succeeded.  If the random rowid does exist, we select a new one
28247c478bd9Sstevel@tonic-gate     ** and try again, up to 1000 times.
28257c478bd9Sstevel@tonic-gate     **
28267c478bd9Sstevel@tonic-gate     ** For a table with less than 2 billion entries, the probability
2827*55fea89dSDan Cross     ** of not finding a unused rowid is about 1.0e-300.  This is a
28287c478bd9Sstevel@tonic-gate     ** non-zero probability, but it is still vanishingly small and should
28297c478bd9Sstevel@tonic-gate     ** never cause a problem.  You are much, much more likely to have a
28307c478bd9Sstevel@tonic-gate     ** hardware failure than for this algorithm to fail.
28317c478bd9Sstevel@tonic-gate     **
28327c478bd9Sstevel@tonic-gate     ** The analysis in the previous paragraph assumes that you have a good
28337c478bd9Sstevel@tonic-gate     ** source of random numbers.  Is a library function like lrand48()
28347c478bd9Sstevel@tonic-gate     ** good enough?  Maybe. Maybe not. It's hard to know whether there
28357c478bd9Sstevel@tonic-gate     ** might be subtle bugs is some implementations of lrand48() that
2836*55fea89dSDan Cross     ** could cause problems. To avoid uncertainty, SQLite uses its own
28377c478bd9Sstevel@tonic-gate     ** random number generator based on the RC4 algorithm.
28387c478bd9Sstevel@tonic-gate     **
28397c478bd9Sstevel@tonic-gate     ** To promote locality of reference for repetitive inserts, the
28407c478bd9Sstevel@tonic-gate     ** first few attempts at chosing a random rowid pick values just a little
28417c478bd9Sstevel@tonic-gate     ** larger than the previous rowid.  This has been shown experimentally
28427c478bd9Sstevel@tonic-gate     ** to double the speed of the COPY operation.
28437c478bd9Sstevel@tonic-gate     */
28447c478bd9Sstevel@tonic-gate     int res, rx, cnt, x;
28457c478bd9Sstevel@tonic-gate     cnt = 0;
28467c478bd9Sstevel@tonic-gate     if( !pC->useRandomRowid ){
28477c478bd9Sstevel@tonic-gate       if( pC->nextRowidValid ){
28487c478bd9Sstevel@tonic-gate         v = pC->nextRowid;
28497c478bd9Sstevel@tonic-gate       }else{
28507c478bd9Sstevel@tonic-gate         rx = sqliteBtreeLast(pC->pCursor, &res);
28517c478bd9Sstevel@tonic-gate         if( res ){
28527c478bd9Sstevel@tonic-gate           v = 1;
28537c478bd9Sstevel@tonic-gate         }else{
28547c478bd9Sstevel@tonic-gate           sqliteBtreeKey(pC->pCursor, 0, sizeof(v), (void*)&v);
28557c478bd9Sstevel@tonic-gate           v = keyToInt(v);
28567c478bd9Sstevel@tonic-gate           if( v==0x7fffffff ){
28577c478bd9Sstevel@tonic-gate             pC->useRandomRowid = 1;
28587c478bd9Sstevel@tonic-gate           }else{
28597c478bd9Sstevel@tonic-gate             v++;
28607c478bd9Sstevel@tonic-gate           }
28617c478bd9Sstevel@tonic-gate         }
28627c478bd9Sstevel@tonic-gate       }
28637c478bd9Sstevel@tonic-gate       if( v<0x7fffffff ){
28647c478bd9Sstevel@tonic-gate         pC->nextRowidValid = 1;
28657c478bd9Sstevel@tonic-gate         pC->nextRowid = v+1;
28667c478bd9Sstevel@tonic-gate       }else{
28677c478bd9Sstevel@tonic-gate         pC->nextRowidValid = 0;
28687c478bd9Sstevel@tonic-gate       }
28697c478bd9Sstevel@tonic-gate     }
28707c478bd9Sstevel@tonic-gate     if( pC->useRandomRowid ){
28717c478bd9Sstevel@tonic-gate       v = db->priorNewRowid;
28727c478bd9Sstevel@tonic-gate       cnt = 0;
28737c478bd9Sstevel@tonic-gate       do{
28747c478bd9Sstevel@tonic-gate         if( v==0 || cnt>2 ){
28757c478bd9Sstevel@tonic-gate           sqliteRandomness(sizeof(v), &v);
28767c478bd9Sstevel@tonic-gate           if( cnt<5 ) v &= 0xffffff;
28777c478bd9Sstevel@tonic-gate         }else{
28787c478bd9Sstevel@tonic-gate           unsigned char r;
28797c478bd9Sstevel@tonic-gate           sqliteRandomness(1, &r);
28807c478bd9Sstevel@tonic-gate           v += r + 1;
28817c478bd9Sstevel@tonic-gate         }
28827c478bd9Sstevel@tonic-gate         if( v==0 ) continue;
28837c478bd9Sstevel@tonic-gate         x = intToKey(v);
28847c478bd9Sstevel@tonic-gate         rx = sqliteBtreeMoveto(pC->pCursor, &x, sizeof(int), &res);
28857c478bd9Sstevel@tonic-gate         cnt++;
28867c478bd9Sstevel@tonic-gate       }while( cnt<1000 && rx==SQLITE_OK && res==0 );
28877c478bd9Sstevel@tonic-gate       db->priorNewRowid = v;
28887c478bd9Sstevel@tonic-gate       if( rx==SQLITE_OK && res==0 ){
28897c478bd9Sstevel@tonic-gate         rc = SQLITE_FULL;
28907c478bd9Sstevel@tonic-gate         goto abort_due_to_error;
28917c478bd9Sstevel@tonic-gate       }
28927c478bd9Sstevel@tonic-gate     }
28937c478bd9Sstevel@tonic-gate     pC->recnoIsValid = 0;
28947c478bd9Sstevel@tonic-gate     pC->deferredMoveto = 0;
28957c478bd9Sstevel@tonic-gate   }
28967c478bd9Sstevel@tonic-gate   pTos++;
28977c478bd9Sstevel@tonic-gate   pTos->i = v;
28987c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Int;
28997c478bd9Sstevel@tonic-gate   break;
29007c478bd9Sstevel@tonic-gate }
29017c478bd9Sstevel@tonic-gate 
29027c478bd9Sstevel@tonic-gate /* Opcode: PutIntKey P1 P2 *
29037c478bd9Sstevel@tonic-gate **
29047c478bd9Sstevel@tonic-gate ** Write an entry into the table of cursor P1.  A new entry is
29057c478bd9Sstevel@tonic-gate ** created if it doesn't already exist or the data for an existing
29067c478bd9Sstevel@tonic-gate ** entry is overwritten.  The data is the value on the top of the
29077c478bd9Sstevel@tonic-gate ** stack.  The key is the next value down on the stack.  The key must
29087c478bd9Sstevel@tonic-gate ** be an integer.  The stack is popped twice by this instruction.
29097c478bd9Sstevel@tonic-gate **
29107c478bd9Sstevel@tonic-gate ** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
29117c478bd9Sstevel@tonic-gate ** incremented (otherwise not).  If the OPFLAG_CSCHANGE flag is set,
29127c478bd9Sstevel@tonic-gate ** then the current statement change count is incremented (otherwise not).
29137c478bd9Sstevel@tonic-gate ** If the OPFLAG_LASTROWID flag of P2 is set, then rowid is
29147c478bd9Sstevel@tonic-gate ** stored for subsequent return by the sqlite_last_insert_rowid() function
29157c478bd9Sstevel@tonic-gate ** (otherwise it's unmodified).
29167c478bd9Sstevel@tonic-gate */
29177c478bd9Sstevel@tonic-gate /* Opcode: PutStrKey P1 * *
29187c478bd9Sstevel@tonic-gate **
29197c478bd9Sstevel@tonic-gate ** Write an entry into the table of cursor P1.  A new entry is
29207c478bd9Sstevel@tonic-gate ** created if it doesn't already exist or the data for an existing
29217c478bd9Sstevel@tonic-gate ** entry is overwritten.  The data is the value on the top of the
29227c478bd9Sstevel@tonic-gate ** stack.  The key is the next value down on the stack.  The key must
29237c478bd9Sstevel@tonic-gate ** be a string.  The stack is popped twice by this instruction.
29247c478bd9Sstevel@tonic-gate **
29257c478bd9Sstevel@tonic-gate ** P1 may not be a pseudo-table opened using the OpenPseudo opcode.
29267c478bd9Sstevel@tonic-gate */
29277c478bd9Sstevel@tonic-gate case OP_PutIntKey:
29287c478bd9Sstevel@tonic-gate case OP_PutStrKey: {
29297c478bd9Sstevel@tonic-gate   Mem *pNos = &pTos[-1];
29307c478bd9Sstevel@tonic-gate   int i = pOp->p1;
29317c478bd9Sstevel@tonic-gate   Cursor *pC;
29327c478bd9Sstevel@tonic-gate   assert( pNos>=p->aStack );
29337c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
29347c478bd9Sstevel@tonic-gate   if( ((pC = &p->aCsr[i])->pCursor!=0 || pC->pseudoTable) ){
29357c478bd9Sstevel@tonic-gate     char *zKey;
29367c478bd9Sstevel@tonic-gate     int nKey, iKey;
29377c478bd9Sstevel@tonic-gate     if( pOp->opcode==OP_PutStrKey ){
29387c478bd9Sstevel@tonic-gate       Stringify(pNos);
29397c478bd9Sstevel@tonic-gate       nKey = pNos->n;
29407c478bd9Sstevel@tonic-gate       zKey = pNos->z;
29417c478bd9Sstevel@tonic-gate     }else{
29427c478bd9Sstevel@tonic-gate       assert( pNos->flags & MEM_Int );
29437c478bd9Sstevel@tonic-gate       nKey = sizeof(int);
29447c478bd9Sstevel@tonic-gate       iKey = intToKey(pNos->i);
29457c478bd9Sstevel@tonic-gate       zKey = (char*)&iKey;
29467c478bd9Sstevel@tonic-gate       if( pOp->p2 & OPFLAG_NCHANGE ) db->nChange++;
29477c478bd9Sstevel@tonic-gate       if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
29487c478bd9Sstevel@tonic-gate       if( pOp->p2 & OPFLAG_CSCHANGE ) db->csChange++;
29497c478bd9Sstevel@tonic-gate       if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
29507c478bd9Sstevel@tonic-gate         pC->nextRowidValid = 0;
29517c478bd9Sstevel@tonic-gate       }
29527c478bd9Sstevel@tonic-gate     }
29537c478bd9Sstevel@tonic-gate     if( pTos->flags & MEM_Null ){
29547c478bd9Sstevel@tonic-gate       pTos->z = 0;
29557c478bd9Sstevel@tonic-gate       pTos->n = 0;
29567c478bd9Sstevel@tonic-gate     }else{
29577c478bd9Sstevel@tonic-gate       assert( pTos->flags & MEM_Str );
29587c478bd9Sstevel@tonic-gate     }
29597c478bd9Sstevel@tonic-gate     if( pC->pseudoTable ){
29607c478bd9Sstevel@tonic-gate       /* PutStrKey does not work for pseudo-tables.
29617c478bd9Sstevel@tonic-gate       ** The following assert makes sure we are not trying to use
29627c478bd9Sstevel@tonic-gate       ** PutStrKey on a pseudo-table
29637c478bd9Sstevel@tonic-gate       */
29647c478bd9Sstevel@tonic-gate       assert( pOp->opcode==OP_PutIntKey );
29657c478bd9Sstevel@tonic-gate       sqliteFree(pC->pData);
29667c478bd9Sstevel@tonic-gate       pC->iKey = iKey;
29677c478bd9Sstevel@tonic-gate       pC->nData = pTos->n;
29687c478bd9Sstevel@tonic-gate       if( pTos->flags & MEM_Dyn ){
29697c478bd9Sstevel@tonic-gate         pC->pData = pTos->z;
29707c478bd9Sstevel@tonic-gate         pTos->flags = MEM_Null;
29717c478bd9Sstevel@tonic-gate       }else{
29727c478bd9Sstevel@tonic-gate         pC->pData = sqliteMallocRaw( pC->nData );
29737c478bd9Sstevel@tonic-gate         if( pC->pData ){
29747c478bd9Sstevel@tonic-gate           memcpy(pC->pData, pTos->z, pC->nData);
29757c478bd9Sstevel@tonic-gate         }
29767c478bd9Sstevel@tonic-gate       }
29777c478bd9Sstevel@tonic-gate       pC->nullRow = 0;
29787c478bd9Sstevel@tonic-gate     }else{
29797c478bd9Sstevel@tonic-gate       rc = sqliteBtreeInsert(pC->pCursor, zKey, nKey, pTos->z, pTos->n);
29807c478bd9Sstevel@tonic-gate     }
29817c478bd9Sstevel@tonic-gate     pC->recnoIsValid = 0;
29827c478bd9Sstevel@tonic-gate     pC->deferredMoveto = 0;
29837c478bd9Sstevel@tonic-gate   }
29847c478bd9Sstevel@tonic-gate   popStack(&pTos, 2);
29857c478bd9Sstevel@tonic-gate   break;
29867c478bd9Sstevel@tonic-gate }
29877c478bd9Sstevel@tonic-gate 
29887c478bd9Sstevel@tonic-gate /* Opcode: Delete P1 P2 *
29897c478bd9Sstevel@tonic-gate **
29907c478bd9Sstevel@tonic-gate ** Delete the record at which the P1 cursor is currently pointing.
29917c478bd9Sstevel@tonic-gate **
29927c478bd9Sstevel@tonic-gate ** The cursor will be left pointing at either the next or the previous
29937c478bd9Sstevel@tonic-gate ** record in the table. If it is left pointing at the next record, then
29947c478bd9Sstevel@tonic-gate ** the next Next instruction will be a no-op.  Hence it is OK to delete
29957c478bd9Sstevel@tonic-gate ** a record from within an Next loop.
29967c478bd9Sstevel@tonic-gate **
29977c478bd9Sstevel@tonic-gate ** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
29987c478bd9Sstevel@tonic-gate ** incremented (otherwise not).  If OPFLAG_CSCHANGE flag is set,
29997c478bd9Sstevel@tonic-gate ** then the current statement change count is incremented (otherwise not).
30007c478bd9Sstevel@tonic-gate **
30017c478bd9Sstevel@tonic-gate ** If P1 is a pseudo-table, then this instruction is a no-op.
30027c478bd9Sstevel@tonic-gate */
30037c478bd9Sstevel@tonic-gate case OP_Delete: {
30047c478bd9Sstevel@tonic-gate   int i = pOp->p1;
30057c478bd9Sstevel@tonic-gate   Cursor *pC;
30067c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
30077c478bd9Sstevel@tonic-gate   pC = &p->aCsr[i];
30087c478bd9Sstevel@tonic-gate   if( pC->pCursor!=0 ){
30097c478bd9Sstevel@tonic-gate     sqliteVdbeCursorMoveto(pC);
30107c478bd9Sstevel@tonic-gate     rc = sqliteBtreeDelete(pC->pCursor);
30117c478bd9Sstevel@tonic-gate     pC->nextRowidValid = 0;
30127c478bd9Sstevel@tonic-gate   }
30137c478bd9Sstevel@tonic-gate   if( pOp->p2 & OPFLAG_NCHANGE ) db->nChange++;
30147c478bd9Sstevel@tonic-gate   if( pOp->p2 & OPFLAG_CSCHANGE ) db->csChange++;
30157c478bd9Sstevel@tonic-gate   break;
30167c478bd9Sstevel@tonic-gate }
30177c478bd9Sstevel@tonic-gate 
30187c478bd9Sstevel@tonic-gate /* Opcode: SetCounts * * *
30197c478bd9Sstevel@tonic-gate **
30207c478bd9Sstevel@tonic-gate ** Called at end of statement.  Updates lsChange (last statement change count)
30217c478bd9Sstevel@tonic-gate ** and resets csChange (current statement change count) to 0.
30227c478bd9Sstevel@tonic-gate */
30237c478bd9Sstevel@tonic-gate case OP_SetCounts: {
30247c478bd9Sstevel@tonic-gate   db->lsChange=db->csChange;
30257c478bd9Sstevel@tonic-gate   db->csChange=0;
30267c478bd9Sstevel@tonic-gate   break;
30277c478bd9Sstevel@tonic-gate }
30287c478bd9Sstevel@tonic-gate 
30297c478bd9Sstevel@tonic-gate /* Opcode: KeyAsData P1 P2 *
30307c478bd9Sstevel@tonic-gate **
30317c478bd9Sstevel@tonic-gate ** Turn the key-as-data mode for cursor P1 either on (if P2==1) or
30327c478bd9Sstevel@tonic-gate ** off (if P2==0).  In key-as-data mode, the OP_Column opcode pulls
30337c478bd9Sstevel@tonic-gate ** data off of the key rather than the data.  This is used for
30347c478bd9Sstevel@tonic-gate ** processing compound selects.
30357c478bd9Sstevel@tonic-gate */
30367c478bd9Sstevel@tonic-gate case OP_KeyAsData: {
30377c478bd9Sstevel@tonic-gate   int i = pOp->p1;
30387c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
30397c478bd9Sstevel@tonic-gate   p->aCsr[i].keyAsData = pOp->p2;
30407c478bd9Sstevel@tonic-gate   break;
30417c478bd9Sstevel@tonic-gate }
30427c478bd9Sstevel@tonic-gate 
30437c478bd9Sstevel@tonic-gate /* Opcode: RowData P1 * *
30447c478bd9Sstevel@tonic-gate **
30457c478bd9Sstevel@tonic-gate ** Push onto the stack the complete row data for cursor P1.
30467c478bd9Sstevel@tonic-gate ** There is no interpretation of the data.  It is just copied
30477c478bd9Sstevel@tonic-gate ** onto the stack exactly as it is found in the database file.
30487c478bd9Sstevel@tonic-gate **
30497c478bd9Sstevel@tonic-gate ** If the cursor is not pointing to a valid row, a NULL is pushed
30507c478bd9Sstevel@tonic-gate ** onto the stack.
30517c478bd9Sstevel@tonic-gate */
30527c478bd9Sstevel@tonic-gate /* Opcode: RowKey P1 * *
30537c478bd9Sstevel@tonic-gate **
30547c478bd9Sstevel@tonic-gate ** Push onto the stack the complete row key for cursor P1.
30557c478bd9Sstevel@tonic-gate ** There is no interpretation of the key.  It is just copied
30567c478bd9Sstevel@tonic-gate ** onto the stack exactly as it is found in the database file.
30577c478bd9Sstevel@tonic-gate **
30587c478bd9Sstevel@tonic-gate ** If the cursor is not pointing to a valid row, a NULL is pushed
30597c478bd9Sstevel@tonic-gate ** onto the stack.
30607c478bd9Sstevel@tonic-gate */
30617c478bd9Sstevel@tonic-gate case OP_RowKey:
30627c478bd9Sstevel@tonic-gate case OP_RowData: {
30637c478bd9Sstevel@tonic-gate   int i = pOp->p1;
30647c478bd9Sstevel@tonic-gate   Cursor *pC;
30657c478bd9Sstevel@tonic-gate   int n;
30667c478bd9Sstevel@tonic-gate 
30677c478bd9Sstevel@tonic-gate   pTos++;
30687c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
30697c478bd9Sstevel@tonic-gate   pC = &p->aCsr[i];
30707c478bd9Sstevel@tonic-gate   if( pC->nullRow ){
30717c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
30727c478bd9Sstevel@tonic-gate   }else if( pC->pCursor!=0 ){
30737c478bd9Sstevel@tonic-gate     BtCursor *pCrsr = pC->pCursor;
30747c478bd9Sstevel@tonic-gate     sqliteVdbeCursorMoveto(pC);
30757c478bd9Sstevel@tonic-gate     if( pC->nullRow ){
30767c478bd9Sstevel@tonic-gate       pTos->flags = MEM_Null;
30777c478bd9Sstevel@tonic-gate       break;
30787c478bd9Sstevel@tonic-gate     }else if( pC->keyAsData || pOp->opcode==OP_RowKey ){
30797c478bd9Sstevel@tonic-gate       sqliteBtreeKeySize(pCrsr, &n);
30807c478bd9Sstevel@tonic-gate     }else{
30817c478bd9Sstevel@tonic-gate       sqliteBtreeDataSize(pCrsr, &n);
30827c478bd9Sstevel@tonic-gate     }
30837c478bd9Sstevel@tonic-gate     pTos->n = n;
30847c478bd9Sstevel@tonic-gate     if( n<=NBFS ){
30857c478bd9Sstevel@tonic-gate       pTos->flags = MEM_Str | MEM_Short;
30867c478bd9Sstevel@tonic-gate       pTos->z = pTos->zShort;
30877c478bd9Sstevel@tonic-gate     }else{
30887c478bd9Sstevel@tonic-gate       char *z = sqliteMallocRaw( n );
30897c478bd9Sstevel@tonic-gate       if( z==0 ) goto no_mem;
30907c478bd9Sstevel@tonic-gate       pTos->flags = MEM_Str | MEM_Dyn;
30917c478bd9Sstevel@tonic-gate       pTos->z = z;
30927c478bd9Sstevel@tonic-gate     }
30937c478bd9Sstevel@tonic-gate     if( pC->keyAsData || pOp->opcode==OP_RowKey ){
30947c478bd9Sstevel@tonic-gate       sqliteBtreeKey(pCrsr, 0, n, pTos->z);
30957c478bd9Sstevel@tonic-gate     }else{
30967c478bd9Sstevel@tonic-gate       sqliteBtreeData(pCrsr, 0, n, pTos->z);
30977c478bd9Sstevel@tonic-gate     }
30987c478bd9Sstevel@tonic-gate   }else if( pC->pseudoTable ){
30997c478bd9Sstevel@tonic-gate     pTos->n = pC->nData;
31007c478bd9Sstevel@tonic-gate     pTos->z = pC->pData;
31017c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Str|MEM_Ephem;
31027c478bd9Sstevel@tonic-gate   }else{
31037c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
31047c478bd9Sstevel@tonic-gate   }
31057c478bd9Sstevel@tonic-gate   break;
31067c478bd9Sstevel@tonic-gate }
31077c478bd9Sstevel@tonic-gate 
31087c478bd9Sstevel@tonic-gate /* Opcode: Column P1 P2 *
31097c478bd9Sstevel@tonic-gate **
31107c478bd9Sstevel@tonic-gate ** Interpret the data that cursor P1 points to as
31117c478bd9Sstevel@tonic-gate ** a structure built using the MakeRecord instruction.
31127c478bd9Sstevel@tonic-gate ** (See the MakeRecord opcode for additional information about
31137c478bd9Sstevel@tonic-gate ** the format of the data.)
31147c478bd9Sstevel@tonic-gate ** Push onto the stack the value of the P2-th column contained
31157c478bd9Sstevel@tonic-gate ** in the data.
31167c478bd9Sstevel@tonic-gate **
31177c478bd9Sstevel@tonic-gate ** If the KeyAsData opcode has previously executed on this cursor,
31187c478bd9Sstevel@tonic-gate ** then the field might be extracted from the key rather than the
31197c478bd9Sstevel@tonic-gate ** data.
31207c478bd9Sstevel@tonic-gate **
31217c478bd9Sstevel@tonic-gate ** If P1 is negative, then the record is stored on the stack rather
31227c478bd9Sstevel@tonic-gate ** than in a table.  For P1==-1, the top of the stack is used.
31237c478bd9Sstevel@tonic-gate ** For P1==-2, the next on the stack is used.  And so forth.  The
31247c478bd9Sstevel@tonic-gate ** value pushed is always just a pointer into the record which is
31257c478bd9Sstevel@tonic-gate ** stored further down on the stack.  The column value is not copied.
31267c478bd9Sstevel@tonic-gate */
31277c478bd9Sstevel@tonic-gate case OP_Column: {
31287c478bd9Sstevel@tonic-gate   int amt, offset, end, payloadSize;
31297c478bd9Sstevel@tonic-gate   int i = pOp->p1;
31307c478bd9Sstevel@tonic-gate   int p2 = pOp->p2;
31317c478bd9Sstevel@tonic-gate   Cursor *pC;
31327c478bd9Sstevel@tonic-gate   char *zRec;
31337c478bd9Sstevel@tonic-gate   BtCursor *pCrsr;
31347c478bd9Sstevel@tonic-gate   int idxWidth;
31357c478bd9Sstevel@tonic-gate   unsigned char aHdr[10];
31367c478bd9Sstevel@tonic-gate 
31377c478bd9Sstevel@tonic-gate   assert( i<p->nCursor );
31387c478bd9Sstevel@tonic-gate   pTos++;
31397c478bd9Sstevel@tonic-gate   if( i<0 ){
31407c478bd9Sstevel@tonic-gate     assert( &pTos[i]>=p->aStack );
31417c478bd9Sstevel@tonic-gate     assert( pTos[i].flags & MEM_Str );
31427c478bd9Sstevel@tonic-gate     zRec = pTos[i].z;
31437c478bd9Sstevel@tonic-gate     payloadSize = pTos[i].n;
31447c478bd9Sstevel@tonic-gate   }else if( (pC = &p->aCsr[i])->pCursor!=0 ){
31457c478bd9Sstevel@tonic-gate     sqliteVdbeCursorMoveto(pC);
31467c478bd9Sstevel@tonic-gate     zRec = 0;
31477c478bd9Sstevel@tonic-gate     pCrsr = pC->pCursor;
31487c478bd9Sstevel@tonic-gate     if( pC->nullRow ){
31497c478bd9Sstevel@tonic-gate       payloadSize = 0;
31507c478bd9Sstevel@tonic-gate     }else if( pC->keyAsData ){
31517c478bd9Sstevel@tonic-gate       sqliteBtreeKeySize(pCrsr, &payloadSize);
31527c478bd9Sstevel@tonic-gate     }else{
31537c478bd9Sstevel@tonic-gate       sqliteBtreeDataSize(pCrsr, &payloadSize);
31547c478bd9Sstevel@tonic-gate     }
31557c478bd9Sstevel@tonic-gate   }else if( pC->pseudoTable ){
31567c478bd9Sstevel@tonic-gate     payloadSize = pC->nData;
31577c478bd9Sstevel@tonic-gate     zRec = pC->pData;
31587c478bd9Sstevel@tonic-gate     assert( payloadSize==0 || zRec!=0 );
31597c478bd9Sstevel@tonic-gate   }else{
31607c478bd9Sstevel@tonic-gate     payloadSize = 0;
31617c478bd9Sstevel@tonic-gate   }
31627c478bd9Sstevel@tonic-gate 
31637c478bd9Sstevel@tonic-gate   /* Figure out how many bytes in the column data and where the column
31647c478bd9Sstevel@tonic-gate   ** data begins.
31657c478bd9Sstevel@tonic-gate   */
31667c478bd9Sstevel@tonic-gate   if( payloadSize==0 ){
31677c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
31687c478bd9Sstevel@tonic-gate     break;
31697c478bd9Sstevel@tonic-gate   }else if( payloadSize<256 ){
31707c478bd9Sstevel@tonic-gate     idxWidth = 1;
31717c478bd9Sstevel@tonic-gate   }else if( payloadSize<65536 ){
31727c478bd9Sstevel@tonic-gate     idxWidth = 2;
31737c478bd9Sstevel@tonic-gate   }else{
31747c478bd9Sstevel@tonic-gate     idxWidth = 3;
31757c478bd9Sstevel@tonic-gate   }
31767c478bd9Sstevel@tonic-gate 
31777c478bd9Sstevel@tonic-gate   /* Figure out where the requested column is stored and how big it is.
31787c478bd9Sstevel@tonic-gate   */
31797c478bd9Sstevel@tonic-gate   if( payloadSize < idxWidth*(p2+1) ){
31807c478bd9Sstevel@tonic-gate     rc = SQLITE_CORRUPT;
31817c478bd9Sstevel@tonic-gate     goto abort_due_to_error;
31827c478bd9Sstevel@tonic-gate   }
31837c478bd9Sstevel@tonic-gate   if( zRec ){
31847c478bd9Sstevel@tonic-gate     memcpy(aHdr, &zRec[idxWidth*p2], idxWidth*2);
31857c478bd9Sstevel@tonic-gate   }else if( pC->keyAsData ){
31867c478bd9Sstevel@tonic-gate     sqliteBtreeKey(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
31877c478bd9Sstevel@tonic-gate   }else{
31887c478bd9Sstevel@tonic-gate     sqliteBtreeData(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
31897c478bd9Sstevel@tonic-gate   }
31907c478bd9Sstevel@tonic-gate   offset = aHdr[0];
31917c478bd9Sstevel@tonic-gate   end = aHdr[idxWidth];
31927c478bd9Sstevel@tonic-gate   if( idxWidth>1 ){
31937c478bd9Sstevel@tonic-gate     offset |= aHdr[1]<<8;
31947c478bd9Sstevel@tonic-gate     end |= aHdr[idxWidth+1]<<8;
31957c478bd9Sstevel@tonic-gate     if( idxWidth>2 ){
31967c478bd9Sstevel@tonic-gate       offset |= aHdr[2]<<16;
31977c478bd9Sstevel@tonic-gate       end |= aHdr[idxWidth+2]<<16;
31987c478bd9Sstevel@tonic-gate     }
31997c478bd9Sstevel@tonic-gate   }
32007c478bd9Sstevel@tonic-gate   amt = end - offset;
32017c478bd9Sstevel@tonic-gate   if( amt<0 || offset<0 || end>payloadSize ){
32027c478bd9Sstevel@tonic-gate     rc = SQLITE_CORRUPT;
32037c478bd9Sstevel@tonic-gate     goto abort_due_to_error;
32047c478bd9Sstevel@tonic-gate   }
32057c478bd9Sstevel@tonic-gate 
32067c478bd9Sstevel@tonic-gate   /* amt and offset now hold the offset to the start of data and the
32077c478bd9Sstevel@tonic-gate   ** amount of data.  Go get the data and put it on the stack.
32087c478bd9Sstevel@tonic-gate   */
32097c478bd9Sstevel@tonic-gate   pTos->n = amt;
32107c478bd9Sstevel@tonic-gate   if( amt==0 ){
32117c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
32127c478bd9Sstevel@tonic-gate   }else if( zRec ){
32137c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Str | MEM_Ephem;
32147c478bd9Sstevel@tonic-gate     pTos->z = &zRec[offset];
32157c478bd9Sstevel@tonic-gate   }else{
32167c478bd9Sstevel@tonic-gate     if( amt<=NBFS ){
32177c478bd9Sstevel@tonic-gate       pTos->flags = MEM_Str | MEM_Short;
32187c478bd9Sstevel@tonic-gate       pTos->z = pTos->zShort;
32197c478bd9Sstevel@tonic-gate     }else{
32207c478bd9Sstevel@tonic-gate       char *z = sqliteMallocRaw( amt );
32217c478bd9Sstevel@tonic-gate       if( z==0 ) goto no_mem;
32227c478bd9Sstevel@tonic-gate       pTos->flags = MEM_Str | MEM_Dyn;
32237c478bd9Sstevel@tonic-gate       pTos->z = z;
32247c478bd9Sstevel@tonic-gate     }
32257c478bd9Sstevel@tonic-gate     if( pC->keyAsData ){
32267c478bd9Sstevel@tonic-gate       sqliteBtreeKey(pCrsr, offset, amt, pTos->z);
32277c478bd9Sstevel@tonic-gate     }else{
32287c478bd9Sstevel@tonic-gate       sqliteBtreeData(pCrsr, offset, amt, pTos->z);
32297c478bd9Sstevel@tonic-gate     }
32307c478bd9Sstevel@tonic-gate   }
32317c478bd9Sstevel@tonic-gate   break;
32327c478bd9Sstevel@tonic-gate }
32337c478bd9Sstevel@tonic-gate 
32347c478bd9Sstevel@tonic-gate /* Opcode: Recno P1 * *
32357c478bd9Sstevel@tonic-gate **
32367c478bd9Sstevel@tonic-gate ** Push onto the stack an integer which is the first 4 bytes of the
32377c478bd9Sstevel@tonic-gate ** the key to the current entry in a sequential scan of the database
3238*55fea89dSDan Cross ** file P1.  The sequential scan should have been started using the
32397c478bd9Sstevel@tonic-gate ** Next opcode.
32407c478bd9Sstevel@tonic-gate */
32417c478bd9Sstevel@tonic-gate case OP_Recno: {
32427c478bd9Sstevel@tonic-gate   int i = pOp->p1;
32437c478bd9Sstevel@tonic-gate   Cursor *pC;
32447c478bd9Sstevel@tonic-gate   int v;
32457c478bd9Sstevel@tonic-gate 
32467c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
32477c478bd9Sstevel@tonic-gate   pC = &p->aCsr[i];
32487c478bd9Sstevel@tonic-gate   sqliteVdbeCursorMoveto(pC);
32497c478bd9Sstevel@tonic-gate   pTos++;
32507c478bd9Sstevel@tonic-gate   if( pC->recnoIsValid ){
32517c478bd9Sstevel@tonic-gate     v = pC->lastRecno;
32527c478bd9Sstevel@tonic-gate   }else if( pC->pseudoTable ){
32537c478bd9Sstevel@tonic-gate     v = keyToInt(pC->iKey);
32547c478bd9Sstevel@tonic-gate   }else if( pC->nullRow || pC->pCursor==0 ){
32557c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
32567c478bd9Sstevel@tonic-gate     break;
32577c478bd9Sstevel@tonic-gate   }else{
32587c478bd9Sstevel@tonic-gate     assert( pC->pCursor!=0 );
32597c478bd9Sstevel@tonic-gate     sqliteBtreeKey(pC->pCursor, 0, sizeof(u32), (char*)&v);
32607c478bd9Sstevel@tonic-gate     v = keyToInt(v);
32617c478bd9Sstevel@tonic-gate   }
32627c478bd9Sstevel@tonic-gate   pTos->i = v;
32637c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Int;
32647c478bd9Sstevel@tonic-gate   break;
32657c478bd9Sstevel@tonic-gate }
32667c478bd9Sstevel@tonic-gate 
32677c478bd9Sstevel@tonic-gate /* Opcode: FullKey P1 * *
32687c478bd9Sstevel@tonic-gate **
32697c478bd9Sstevel@tonic-gate ** Extract the complete key from the record that cursor P1 is currently
32707c478bd9Sstevel@tonic-gate ** pointing to and push the key onto the stack as a string.
32717c478bd9Sstevel@tonic-gate **
32727c478bd9Sstevel@tonic-gate ** Compare this opcode to Recno.  The Recno opcode extracts the first
32737c478bd9Sstevel@tonic-gate ** 4 bytes of the key and pushes those bytes onto the stack as an
32747c478bd9Sstevel@tonic-gate ** integer.  This instruction pushes the entire key as a string.
32757c478bd9Sstevel@tonic-gate **
32767c478bd9Sstevel@tonic-gate ** This opcode may not be used on a pseudo-table.
32777c478bd9Sstevel@tonic-gate */
32787c478bd9Sstevel@tonic-gate case OP_FullKey: {
32797c478bd9Sstevel@tonic-gate   int i = pOp->p1;
32807c478bd9Sstevel@tonic-gate   BtCursor *pCrsr;
32817c478bd9Sstevel@tonic-gate 
32827c478bd9Sstevel@tonic-gate   assert( p->aCsr[i].keyAsData );
32837c478bd9Sstevel@tonic-gate   assert( !p->aCsr[i].pseudoTable );
32847c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
32857c478bd9Sstevel@tonic-gate   pTos++;
32867c478bd9Sstevel@tonic-gate   if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
32877c478bd9Sstevel@tonic-gate     int amt;
32887c478bd9Sstevel@tonic-gate     char *z;
32897c478bd9Sstevel@tonic-gate 
32907c478bd9Sstevel@tonic-gate     sqliteVdbeCursorMoveto(&p->aCsr[i]);
32917c478bd9Sstevel@tonic-gate     sqliteBtreeKeySize(pCrsr, &amt);
32927c478bd9Sstevel@tonic-gate     if( amt<=0 ){
32937c478bd9Sstevel@tonic-gate       rc = SQLITE_CORRUPT;
32947c478bd9Sstevel@tonic-gate       goto abort_due_to_error;
32957c478bd9Sstevel@tonic-gate     }
32967c478bd9Sstevel@tonic-gate     if( amt>NBFS ){
32977c478bd9Sstevel@tonic-gate       z = sqliteMallocRaw( amt );
32987c478bd9Sstevel@tonic-gate       if( z==0 ) goto no_mem;
32997c478bd9Sstevel@tonic-gate       pTos->flags = MEM_Str | MEM_Dyn;
33007c478bd9Sstevel@tonic-gate     }else{
33017c478bd9Sstevel@tonic-gate       z = pTos->zShort;
33027c478bd9Sstevel@tonic-gate       pTos->flags = MEM_Str | MEM_Short;
33037c478bd9Sstevel@tonic-gate     }
33047c478bd9Sstevel@tonic-gate     sqliteBtreeKey(pCrsr, 0, amt, z);
33057c478bd9Sstevel@tonic-gate     pTos->z = z;
33067c478bd9Sstevel@tonic-gate     pTos->n = amt;
33077c478bd9Sstevel@tonic-gate   }
33087c478bd9Sstevel@tonic-gate   break;
33097c478bd9Sstevel@tonic-gate }
33107c478bd9Sstevel@tonic-gate 
33117c478bd9Sstevel@tonic-gate /* Opcode: NullRow P1 * *
33127c478bd9Sstevel@tonic-gate **
33137c478bd9Sstevel@tonic-gate ** Move the cursor P1 to a null row.  Any OP_Column operations
3314*55fea89dSDan Cross ** that occur while the cursor is on the null row will always push
33157c478bd9Sstevel@tonic-gate ** a NULL onto the stack.
33167c478bd9Sstevel@tonic-gate */
33177c478bd9Sstevel@tonic-gate case OP_NullRow: {
33187c478bd9Sstevel@tonic-gate   int i = pOp->p1;
33197c478bd9Sstevel@tonic-gate 
33207c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
33217c478bd9Sstevel@tonic-gate   p->aCsr[i].nullRow = 1;
33227c478bd9Sstevel@tonic-gate   p->aCsr[i].recnoIsValid = 0;
33237c478bd9Sstevel@tonic-gate   break;
33247c478bd9Sstevel@tonic-gate }
33257c478bd9Sstevel@tonic-gate 
33267c478bd9Sstevel@tonic-gate /* Opcode: Last P1 P2 *
33277c478bd9Sstevel@tonic-gate **
3328*55fea89dSDan Cross ** The next use of the Recno or Column or Next instruction for P1
33297c478bd9Sstevel@tonic-gate ** will refer to the last entry in the database table or index.
33307c478bd9Sstevel@tonic-gate ** If the table or index is empty and P2>0, then jump immediately to P2.
33317c478bd9Sstevel@tonic-gate ** If P2 is 0 or if the table or index is not empty, fall through
33327c478bd9Sstevel@tonic-gate ** to the following instruction.
33337c478bd9Sstevel@tonic-gate */
33347c478bd9Sstevel@tonic-gate case OP_Last: {
33357c478bd9Sstevel@tonic-gate   int i = pOp->p1;
33367c478bd9Sstevel@tonic-gate   Cursor *pC;
33377c478bd9Sstevel@tonic-gate   BtCursor *pCrsr;
33387c478bd9Sstevel@tonic-gate 
33397c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
33407c478bd9Sstevel@tonic-gate   pC = &p->aCsr[i];
33417c478bd9Sstevel@tonic-gate   if( (pCrsr = pC->pCursor)!=0 ){
33427c478bd9Sstevel@tonic-gate     int res;
33437c478bd9Sstevel@tonic-gate     rc = sqliteBtreeLast(pCrsr, &res);
33447c478bd9Sstevel@tonic-gate     pC->nullRow = res;
33457c478bd9Sstevel@tonic-gate     pC->deferredMoveto = 0;
33467c478bd9Sstevel@tonic-gate     if( res && pOp->p2>0 ){
33477c478bd9Sstevel@tonic-gate       pc = pOp->p2 - 1;
33487c478bd9Sstevel@tonic-gate     }
33497c478bd9Sstevel@tonic-gate   }else{
33507c478bd9Sstevel@tonic-gate     pC->nullRow = 0;
33517c478bd9Sstevel@tonic-gate   }
33527c478bd9Sstevel@tonic-gate   break;
33537c478bd9Sstevel@tonic-gate }
33547c478bd9Sstevel@tonic-gate 
33557c478bd9Sstevel@tonic-gate /* Opcode: Rewind P1 P2 *
33567c478bd9Sstevel@tonic-gate **
3357*55fea89dSDan Cross ** The next use of the Recno or Column or Next instruction for P1
33587c478bd9Sstevel@tonic-gate ** will refer to the first entry in the database table or index.
33597c478bd9Sstevel@tonic-gate ** If the table or index is empty and P2>0, then jump immediately to P2.
33607c478bd9Sstevel@tonic-gate ** If P2 is 0 or if the table or index is not empty, fall through
33617c478bd9Sstevel@tonic-gate ** to the following instruction.
33627c478bd9Sstevel@tonic-gate */
33637c478bd9Sstevel@tonic-gate case OP_Rewind: {
33647c478bd9Sstevel@tonic-gate   int i = pOp->p1;
33657c478bd9Sstevel@tonic-gate   Cursor *pC;
33667c478bd9Sstevel@tonic-gate   BtCursor *pCrsr;
33677c478bd9Sstevel@tonic-gate 
33687c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
33697c478bd9Sstevel@tonic-gate   pC = &p->aCsr[i];
33707c478bd9Sstevel@tonic-gate   if( (pCrsr = pC->pCursor)!=0 ){
33717c478bd9Sstevel@tonic-gate     int res;
33727c478bd9Sstevel@tonic-gate     rc = sqliteBtreeFirst(pCrsr, &res);
33737c478bd9Sstevel@tonic-gate     pC->atFirst = res==0;
33747c478bd9Sstevel@tonic-gate     pC->nullRow = res;
33757c478bd9Sstevel@tonic-gate     pC->deferredMoveto = 0;
33767c478bd9Sstevel@tonic-gate     if( res && pOp->p2>0 ){
33777c478bd9Sstevel@tonic-gate       pc = pOp->p2 - 1;
33787c478bd9Sstevel@tonic-gate     }
33797c478bd9Sstevel@tonic-gate   }else{
33807c478bd9Sstevel@tonic-gate     pC->nullRow = 0;
33817c478bd9Sstevel@tonic-gate   }
33827c478bd9Sstevel@tonic-gate   break;
33837c478bd9Sstevel@tonic-gate }
33847c478bd9Sstevel@tonic-gate 
33857c478bd9Sstevel@tonic-gate /* Opcode: Next P1 P2 *
33867c478bd9Sstevel@tonic-gate **
33877c478bd9Sstevel@tonic-gate ** Advance cursor P1 so that it points to the next key/data pair in its
33887c478bd9Sstevel@tonic-gate ** table or index.  If there are no more key/value pairs then fall through
33897c478bd9Sstevel@tonic-gate ** to the following instruction.  But if the cursor advance was successful,
33907c478bd9Sstevel@tonic-gate ** jump immediately to P2.
33917c478bd9Sstevel@tonic-gate **
33927c478bd9Sstevel@tonic-gate ** See also: Prev
33937c478bd9Sstevel@tonic-gate */
33947c478bd9Sstevel@tonic-gate /* Opcode: Prev P1 P2 *
33957c478bd9Sstevel@tonic-gate **
33967c478bd9Sstevel@tonic-gate ** Back up cursor P1 so that it points to the previous key/data pair in its
33977c478bd9Sstevel@tonic-gate ** table or index.  If there is no previous key/value pairs then fall through
33987c478bd9Sstevel@tonic-gate ** to the following instruction.  But if the cursor backup was successful,
33997c478bd9Sstevel@tonic-gate ** jump immediately to P2.
34007c478bd9Sstevel@tonic-gate */
34017c478bd9Sstevel@tonic-gate case OP_Prev:
34027c478bd9Sstevel@tonic-gate case OP_Next: {
34037c478bd9Sstevel@tonic-gate   Cursor *pC;
34047c478bd9Sstevel@tonic-gate   BtCursor *pCrsr;
34057c478bd9Sstevel@tonic-gate 
34067c478bd9Sstevel@tonic-gate   CHECK_FOR_INTERRUPT;
34077c478bd9Sstevel@tonic-gate   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
34087c478bd9Sstevel@tonic-gate   pC = &p->aCsr[pOp->p1];
34097c478bd9Sstevel@tonic-gate   if( (pCrsr = pC->pCursor)!=0 ){
34107c478bd9Sstevel@tonic-gate     int res;
34117c478bd9Sstevel@tonic-gate     if( pC->nullRow ){
34127c478bd9Sstevel@tonic-gate       res = 1;
34137c478bd9Sstevel@tonic-gate     }else{
34147c478bd9Sstevel@tonic-gate       assert( pC->deferredMoveto==0 );
34157c478bd9Sstevel@tonic-gate       rc = pOp->opcode==OP_Next ? sqliteBtreeNext(pCrsr, &res) :
34167c478bd9Sstevel@tonic-gate                                   sqliteBtreePrevious(pCrsr, &res);
34177c478bd9Sstevel@tonic-gate       pC->nullRow = res;
34187c478bd9Sstevel@tonic-gate     }
34197c478bd9Sstevel@tonic-gate     if( res==0 ){
34207c478bd9Sstevel@tonic-gate       pc = pOp->p2 - 1;
34217c478bd9Sstevel@tonic-gate       sqlite_search_count++;
34227c478bd9Sstevel@tonic-gate     }
34237c478bd9Sstevel@tonic-gate   }else{
34247c478bd9Sstevel@tonic-gate     pC->nullRow = 1;
34257c478bd9Sstevel@tonic-gate   }
34267c478bd9Sstevel@tonic-gate   pC->recnoIsValid = 0;
34277c478bd9Sstevel@tonic-gate   break;
34287c478bd9Sstevel@tonic-gate }
34297c478bd9Sstevel@tonic-gate 
34307c478bd9Sstevel@tonic-gate /* Opcode: IdxPut P1 P2 P3
34317c478bd9Sstevel@tonic-gate **
34327c478bd9Sstevel@tonic-gate ** The top of the stack holds a SQL index key made using the
34337c478bd9Sstevel@tonic-gate ** MakeIdxKey instruction.  This opcode writes that key into the
34347c478bd9Sstevel@tonic-gate ** index P1.  Data for the entry is nil.
34357c478bd9Sstevel@tonic-gate **
34367c478bd9Sstevel@tonic-gate ** If P2==1, then the key must be unique.  If the key is not unique,
34377c478bd9Sstevel@tonic-gate ** the program aborts with a SQLITE_CONSTRAINT error and the database
34387c478bd9Sstevel@tonic-gate ** is rolled back.  If P3 is not null, then it becomes part of the
34397c478bd9Sstevel@tonic-gate ** error message returned with the SQLITE_CONSTRAINT.
34407c478bd9Sstevel@tonic-gate */
34417c478bd9Sstevel@tonic-gate case OP_IdxPut: {
34427c478bd9Sstevel@tonic-gate   int i = pOp->p1;
34437c478bd9Sstevel@tonic-gate   BtCursor *pCrsr;
34447c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
34457c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
34467c478bd9Sstevel@tonic-gate   assert( pTos->flags & MEM_Str );
34477c478bd9Sstevel@tonic-gate   if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
34487c478bd9Sstevel@tonic-gate     int nKey = pTos->n;
34497c478bd9Sstevel@tonic-gate     const char *zKey = pTos->z;
34507c478bd9Sstevel@tonic-gate     if( pOp->p2 ){
34517c478bd9Sstevel@tonic-gate       int res, n;
34527c478bd9Sstevel@tonic-gate       assert( nKey >= 4 );
34537c478bd9Sstevel@tonic-gate       rc = sqliteBtreeMoveto(pCrsr, zKey, nKey-4, &res);
34547c478bd9Sstevel@tonic-gate       if( rc!=SQLITE_OK ) goto abort_due_to_error;
34557c478bd9Sstevel@tonic-gate       while( res!=0 ){
34567c478bd9Sstevel@tonic-gate         int c;
34577c478bd9Sstevel@tonic-gate         sqliteBtreeKeySize(pCrsr, &n);
34587c478bd9Sstevel@tonic-gate         if( n==nKey
34597c478bd9Sstevel@tonic-gate            && sqliteBtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &c)==SQLITE_OK
34607c478bd9Sstevel@tonic-gate            && c==0
34617c478bd9Sstevel@tonic-gate         ){
34627c478bd9Sstevel@tonic-gate           rc = SQLITE_CONSTRAINT;
34637c478bd9Sstevel@tonic-gate           if( pOp->p3 && pOp->p3[0] ){
34647c478bd9Sstevel@tonic-gate             sqliteSetString(&p->zErrMsg, pOp->p3, (char*)0);
34657c478bd9Sstevel@tonic-gate           }
34667c478bd9Sstevel@tonic-gate           goto abort_due_to_error;
34677c478bd9Sstevel@tonic-gate         }
34687c478bd9Sstevel@tonic-gate         if( res<0 ){
34697c478bd9Sstevel@tonic-gate           sqliteBtreeNext(pCrsr, &res);
34707c478bd9Sstevel@tonic-gate           res = +1;
34717c478bd9Sstevel@tonic-gate         }else{
34727c478bd9Sstevel@tonic-gate           break;
34737c478bd9Sstevel@tonic-gate         }
34747c478bd9Sstevel@tonic-gate       }
34757c478bd9Sstevel@tonic-gate     }
34767c478bd9Sstevel@tonic-gate     rc = sqliteBtreeInsert(pCrsr, zKey, nKey, "", 0);
34777c478bd9Sstevel@tonic-gate     assert( p->aCsr[i].deferredMoveto==0 );
34787c478bd9Sstevel@tonic-gate   }
34797c478bd9Sstevel@tonic-gate   Release(pTos);
34807c478bd9Sstevel@tonic-gate   pTos--;
34817c478bd9Sstevel@tonic-gate   break;
34827c478bd9Sstevel@tonic-gate }
34837c478bd9Sstevel@tonic-gate 
34847c478bd9Sstevel@tonic-gate /* Opcode: IdxDelete P1 * *
34857c478bd9Sstevel@tonic-gate **
34867c478bd9Sstevel@tonic-gate ** The top of the stack is an index key built using the MakeIdxKey opcode.
34877c478bd9Sstevel@tonic-gate ** This opcode removes that entry from the index.
34887c478bd9Sstevel@tonic-gate */
34897c478bd9Sstevel@tonic-gate case OP_IdxDelete: {
34907c478bd9Sstevel@tonic-gate   int i = pOp->p1;
34917c478bd9Sstevel@tonic-gate   BtCursor *pCrsr;
34927c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
34937c478bd9Sstevel@tonic-gate   assert( pTos->flags & MEM_Str );
34947c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
34957c478bd9Sstevel@tonic-gate   if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
34967c478bd9Sstevel@tonic-gate     int rx, res;
34977c478bd9Sstevel@tonic-gate     rx = sqliteBtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
34987c478bd9Sstevel@tonic-gate     if( rx==SQLITE_OK && res==0 ){
34997c478bd9Sstevel@tonic-gate       rc = sqliteBtreeDelete(pCrsr);
35007c478bd9Sstevel@tonic-gate     }
35017c478bd9Sstevel@tonic-gate     assert( p->aCsr[i].deferredMoveto==0 );
35027c478bd9Sstevel@tonic-gate   }
35037c478bd9Sstevel@tonic-gate   Release(pTos);
35047c478bd9Sstevel@tonic-gate   pTos--;
35057c478bd9Sstevel@tonic-gate   break;
35067c478bd9Sstevel@tonic-gate }
35077c478bd9Sstevel@tonic-gate 
35087c478bd9Sstevel@tonic-gate /* Opcode: IdxRecno P1 * *
35097c478bd9Sstevel@tonic-gate **
35107c478bd9Sstevel@tonic-gate ** Push onto the stack an integer which is the last 4 bytes of the
35117c478bd9Sstevel@tonic-gate ** the key to the current entry in index P1.  These 4 bytes should
35127c478bd9Sstevel@tonic-gate ** be the record number of the table entry to which this index entry
35137c478bd9Sstevel@tonic-gate ** points.
35147c478bd9Sstevel@tonic-gate **
35157c478bd9Sstevel@tonic-gate ** See also: Recno, MakeIdxKey.
35167c478bd9Sstevel@tonic-gate */
35177c478bd9Sstevel@tonic-gate case OP_IdxRecno: {
35187c478bd9Sstevel@tonic-gate   int i = pOp->p1;
35197c478bd9Sstevel@tonic-gate   BtCursor *pCrsr;
35207c478bd9Sstevel@tonic-gate 
35217c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
35227c478bd9Sstevel@tonic-gate   pTos++;
35237c478bd9Sstevel@tonic-gate   if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
35247c478bd9Sstevel@tonic-gate     int v;
35257c478bd9Sstevel@tonic-gate     int sz;
35267c478bd9Sstevel@tonic-gate     assert( p->aCsr[i].deferredMoveto==0 );
35277c478bd9Sstevel@tonic-gate     sqliteBtreeKeySize(pCrsr, &sz);
35287c478bd9Sstevel@tonic-gate     if( sz<sizeof(u32) ){
35297c478bd9Sstevel@tonic-gate       pTos->flags = MEM_Null;
35307c478bd9Sstevel@tonic-gate     }else{
35317c478bd9Sstevel@tonic-gate       sqliteBtreeKey(pCrsr, sz - sizeof(u32), sizeof(u32), (char*)&v);
35327c478bd9Sstevel@tonic-gate       v = keyToInt(v);
35337c478bd9Sstevel@tonic-gate       pTos->i = v;
35347c478bd9Sstevel@tonic-gate       pTos->flags = MEM_Int;
35357c478bd9Sstevel@tonic-gate     }
35367c478bd9Sstevel@tonic-gate   }else{
35377c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
35387c478bd9Sstevel@tonic-gate   }
35397c478bd9Sstevel@tonic-gate   break;
35407c478bd9Sstevel@tonic-gate }
35417c478bd9Sstevel@tonic-gate 
35427c478bd9Sstevel@tonic-gate /* Opcode: IdxGT P1 P2 *
35437c478bd9Sstevel@tonic-gate **
35447c478bd9Sstevel@tonic-gate ** Compare the top of the stack against the key on the index entry that
35457c478bd9Sstevel@tonic-gate ** cursor P1 is currently pointing to.  Ignore the last 4 bytes of the
35467c478bd9Sstevel@tonic-gate ** index entry.  If the index entry is greater than the top of the stack
35477c478bd9Sstevel@tonic-gate ** then jump to P2.  Otherwise fall through to the next instruction.
35487c478bd9Sstevel@tonic-gate ** In either case, the stack is popped once.
35497c478bd9Sstevel@tonic-gate */
35507c478bd9Sstevel@tonic-gate /* Opcode: IdxGE P1 P2 *
35517c478bd9Sstevel@tonic-gate **
35527c478bd9Sstevel@tonic-gate ** Compare the top of the stack against the key on the index entry that
35537c478bd9Sstevel@tonic-gate ** cursor P1 is currently pointing to.  Ignore the last 4 bytes of the
3554*55fea89dSDan Cross ** index entry.  If the index entry is greater than or equal to
35557c478bd9Sstevel@tonic-gate ** the top of the stack
35567c478bd9Sstevel@tonic-gate ** then jump to P2.  Otherwise fall through to the next instruction.
35577c478bd9Sstevel@tonic-gate ** In either case, the stack is popped once.
35587c478bd9Sstevel@tonic-gate */
35597c478bd9Sstevel@tonic-gate /* Opcode: IdxLT P1 P2 *
35607c478bd9Sstevel@tonic-gate **
35617c478bd9Sstevel@tonic-gate ** Compare the top of the stack against the key on the index entry that
35627c478bd9Sstevel@tonic-gate ** cursor P1 is currently pointing to.  Ignore the last 4 bytes of the
35637c478bd9Sstevel@tonic-gate ** index entry.  If the index entry is less than the top of the stack
35647c478bd9Sstevel@tonic-gate ** then jump to P2.  Otherwise fall through to the next instruction.
35657c478bd9Sstevel@tonic-gate ** In either case, the stack is popped once.
35667c478bd9Sstevel@tonic-gate */
35677c478bd9Sstevel@tonic-gate case OP_IdxLT:
35687c478bd9Sstevel@tonic-gate case OP_IdxGT:
35697c478bd9Sstevel@tonic-gate case OP_IdxGE: {
35707c478bd9Sstevel@tonic-gate   int i= pOp->p1;
35717c478bd9Sstevel@tonic-gate   BtCursor *pCrsr;
35727c478bd9Sstevel@tonic-gate 
35737c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nCursor );
35747c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
35757c478bd9Sstevel@tonic-gate   if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
35767c478bd9Sstevel@tonic-gate     int res, rc;
3577*55fea89dSDan Cross 
35787c478bd9Sstevel@tonic-gate     Stringify(pTos);
35797c478bd9Sstevel@tonic-gate     assert( p->aCsr[i].deferredMoveto==0 );
35807c478bd9Sstevel@tonic-gate     rc = sqliteBtreeKeyCompare(pCrsr, pTos->z, pTos->n, 4, &res);
35817c478bd9Sstevel@tonic-gate     if( rc!=SQLITE_OK ){
35827c478bd9Sstevel@tonic-gate       break;
35837c478bd9Sstevel@tonic-gate     }
35847c478bd9Sstevel@tonic-gate     if( pOp->opcode==OP_IdxLT ){
35857c478bd9Sstevel@tonic-gate       res = -res;
35867c478bd9Sstevel@tonic-gate     }else if( pOp->opcode==OP_IdxGE ){
35877c478bd9Sstevel@tonic-gate       res++;
35887c478bd9Sstevel@tonic-gate     }
35897c478bd9Sstevel@tonic-gate     if( res>0 ){
35907c478bd9Sstevel@tonic-gate       pc = pOp->p2 - 1 ;
35917c478bd9Sstevel@tonic-gate     }
35927c478bd9Sstevel@tonic-gate   }
35937c478bd9Sstevel@tonic-gate   Release(pTos);
35947c478bd9Sstevel@tonic-gate   pTos--;
35957c478bd9Sstevel@tonic-gate   break;
35967c478bd9Sstevel@tonic-gate }
35977c478bd9Sstevel@tonic-gate 
35987c478bd9Sstevel@tonic-gate /* Opcode: IdxIsNull P1 P2 *
35997c478bd9Sstevel@tonic-gate **
36007c478bd9Sstevel@tonic-gate ** The top of the stack contains an index entry such as might be generated
36017c478bd9Sstevel@tonic-gate ** by the MakeIdxKey opcode.  This routine looks at the first P1 fields of
36027c478bd9Sstevel@tonic-gate ** that key.  If any of the first P1 fields are NULL, then a jump is made
36037c478bd9Sstevel@tonic-gate ** to address P2.  Otherwise we fall straight through.
36047c478bd9Sstevel@tonic-gate **
36057c478bd9Sstevel@tonic-gate ** The index entry is always popped from the stack.
36067c478bd9Sstevel@tonic-gate */
36077c478bd9Sstevel@tonic-gate case OP_IdxIsNull: {
36087c478bd9Sstevel@tonic-gate   int i = pOp->p1;
36097c478bd9Sstevel@tonic-gate   int k, n;
36107c478bd9Sstevel@tonic-gate   const char *z;
36117c478bd9Sstevel@tonic-gate 
36127c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
36137c478bd9Sstevel@tonic-gate   assert( pTos->flags & MEM_Str );
36147c478bd9Sstevel@tonic-gate   z = pTos->z;
36157c478bd9Sstevel@tonic-gate   n = pTos->n;
36167c478bd9Sstevel@tonic-gate   for(k=0; k<n && i>0; i--){
36177c478bd9Sstevel@tonic-gate     if( z[k]=='a' ){
36187c478bd9Sstevel@tonic-gate       pc = pOp->p2-1;
36197c478bd9Sstevel@tonic-gate       break;
36207c478bd9Sstevel@tonic-gate     }
36217c478bd9Sstevel@tonic-gate     while( k<n && z[k] ){ k++; }
36227c478bd9Sstevel@tonic-gate     k++;
36237c478bd9Sstevel@tonic-gate   }
36247c478bd9Sstevel@tonic-gate   Release(pTos);
36257c478bd9Sstevel@tonic-gate   pTos--;
36267c478bd9Sstevel@tonic-gate   break;
36277c478bd9Sstevel@tonic-gate }
36287c478bd9Sstevel@tonic-gate 
36297c478bd9Sstevel@tonic-gate /* Opcode: Destroy P1 P2 *
36307c478bd9Sstevel@tonic-gate **
36317c478bd9Sstevel@tonic-gate ** Delete an entire database table or index whose root page in the database
36327c478bd9Sstevel@tonic-gate ** file is given by P1.
36337c478bd9Sstevel@tonic-gate **
36347c478bd9Sstevel@tonic-gate ** The table being destroyed is in the main database file if P2==0.  If
36357c478bd9Sstevel@tonic-gate ** P2==1 then the table to be clear is in the auxiliary database file
36367c478bd9Sstevel@tonic-gate ** that is used to store tables create using CREATE TEMPORARY TABLE.
36377c478bd9Sstevel@tonic-gate **
36387c478bd9Sstevel@tonic-gate ** See also: Clear
36397c478bd9Sstevel@tonic-gate */
36407c478bd9Sstevel@tonic-gate case OP_Destroy: {
36417c478bd9Sstevel@tonic-gate   rc = sqliteBtreeDropTable(db->aDb[pOp->p2].pBt, pOp->p1);
36427c478bd9Sstevel@tonic-gate   break;
36437c478bd9Sstevel@tonic-gate }
36447c478bd9Sstevel@tonic-gate 
36457c478bd9Sstevel@tonic-gate /* Opcode: Clear P1 P2 *
36467c478bd9Sstevel@tonic-gate **
36477c478bd9Sstevel@tonic-gate ** Delete all contents of the database table or index whose root page
36487c478bd9Sstevel@tonic-gate ** in the database file is given by P1.  But, unlike Destroy, do not
36497c478bd9Sstevel@tonic-gate ** remove the table or index from the database file.
36507c478bd9Sstevel@tonic-gate **
36517c478bd9Sstevel@tonic-gate ** The table being clear is in the main database file if P2==0.  If
36527c478bd9Sstevel@tonic-gate ** P2==1 then the table to be clear is in the auxiliary database file
36537c478bd9Sstevel@tonic-gate ** that is used to store tables create using CREATE TEMPORARY TABLE.
36547c478bd9Sstevel@tonic-gate **
36557c478bd9Sstevel@tonic-gate ** See also: Destroy
36567c478bd9Sstevel@tonic-gate */
36577c478bd9Sstevel@tonic-gate case OP_Clear: {
36587c478bd9Sstevel@tonic-gate   rc = sqliteBtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1);
36597c478bd9Sstevel@tonic-gate   break;
36607c478bd9Sstevel@tonic-gate }
36617c478bd9Sstevel@tonic-gate 
36627c478bd9Sstevel@tonic-gate /* Opcode: CreateTable * P2 P3
36637c478bd9Sstevel@tonic-gate **
36647c478bd9Sstevel@tonic-gate ** Allocate a new table in the main database file if P2==0 or in the
36657c478bd9Sstevel@tonic-gate ** auxiliary database file if P2==1.  Push the page number
36667c478bd9Sstevel@tonic-gate ** for the root page of the new table onto the stack.
36677c478bd9Sstevel@tonic-gate **
36687c478bd9Sstevel@tonic-gate ** The root page number is also written to a memory location that P3
36697c478bd9Sstevel@tonic-gate ** points to.  This is the mechanism is used to write the root page
36707c478bd9Sstevel@tonic-gate ** number into the parser's internal data structures that describe the
36717c478bd9Sstevel@tonic-gate ** new table.
36727c478bd9Sstevel@tonic-gate **
36737c478bd9Sstevel@tonic-gate ** The difference between a table and an index is this:  A table must
36747c478bd9Sstevel@tonic-gate ** have a 4-byte integer key and can have arbitrary data.  An index
36757c478bd9Sstevel@tonic-gate ** has an arbitrary key but no data.
36767c478bd9Sstevel@tonic-gate **
36777c478bd9Sstevel@tonic-gate ** See also: CreateIndex
36787c478bd9Sstevel@tonic-gate */
36797c478bd9Sstevel@tonic-gate /* Opcode: CreateIndex * P2 P3
36807c478bd9Sstevel@tonic-gate **
36817c478bd9Sstevel@tonic-gate ** Allocate a new index in the main database file if P2==0 or in the
36827c478bd9Sstevel@tonic-gate ** auxiliary database file if P2==1.  Push the page number of the
36837c478bd9Sstevel@tonic-gate ** root page of the new index onto the stack.
36847c478bd9Sstevel@tonic-gate **
36857c478bd9Sstevel@tonic-gate ** See documentation on OP_CreateTable for additional information.
36867c478bd9Sstevel@tonic-gate */
36877c478bd9Sstevel@tonic-gate case OP_CreateIndex:
36887c478bd9Sstevel@tonic-gate case OP_CreateTable: {
36897c478bd9Sstevel@tonic-gate   int pgno;
36907c478bd9Sstevel@tonic-gate   assert( pOp->p3!=0 && pOp->p3type==P3_POINTER );
36917c478bd9Sstevel@tonic-gate   assert( pOp->p2>=0 && pOp->p2<db->nDb );
36927c478bd9Sstevel@tonic-gate   assert( db->aDb[pOp->p2].pBt!=0 );
36937c478bd9Sstevel@tonic-gate   if( pOp->opcode==OP_CreateTable ){
36947c478bd9Sstevel@tonic-gate     rc = sqliteBtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno);
36957c478bd9Sstevel@tonic-gate   }else{
36967c478bd9Sstevel@tonic-gate     rc = sqliteBtreeCreateIndex(db->aDb[pOp->p2].pBt, &pgno);
36977c478bd9Sstevel@tonic-gate   }
36987c478bd9Sstevel@tonic-gate   pTos++;
36997c478bd9Sstevel@tonic-gate   if( rc==SQLITE_OK ){
37007c478bd9Sstevel@tonic-gate     pTos->i = pgno;
37017c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Int;
37027c478bd9Sstevel@tonic-gate     *(u32*)pOp->p3 = pgno;
37037c478bd9Sstevel@tonic-gate     pOp->p3 = 0;
37047c478bd9Sstevel@tonic-gate   }else{
37057c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
37067c478bd9Sstevel@tonic-gate   }
37077c478bd9Sstevel@tonic-gate   break;
37087c478bd9Sstevel@tonic-gate }
37097c478bd9Sstevel@tonic-gate 
37107c478bd9Sstevel@tonic-gate /* Opcode: IntegrityCk P1 P2 *
37117c478bd9Sstevel@tonic-gate **
37127c478bd9Sstevel@tonic-gate ** Do an analysis of the currently open database.  Push onto the
37137c478bd9Sstevel@tonic-gate ** stack the text of an error message describing any problems.
37147c478bd9Sstevel@tonic-gate ** If there are no errors, push a "ok" onto the stack.
37157c478bd9Sstevel@tonic-gate **
37167c478bd9Sstevel@tonic-gate ** P1 is the index of a set that contains the root page numbers
37177c478bd9Sstevel@tonic-gate ** for all tables and indices in the main database file.  The set
37187c478bd9Sstevel@tonic-gate ** is cleared by this opcode.  In other words, after this opcode
37197c478bd9Sstevel@tonic-gate ** has executed, the set will be empty.
37207c478bd9Sstevel@tonic-gate **
37217c478bd9Sstevel@tonic-gate ** If P2 is not zero, the check is done on the auxiliary database
37227c478bd9Sstevel@tonic-gate ** file, not the main database file.
37237c478bd9Sstevel@tonic-gate **
37247c478bd9Sstevel@tonic-gate ** This opcode is used for testing purposes only.
37257c478bd9Sstevel@tonic-gate */
37267c478bd9Sstevel@tonic-gate case OP_IntegrityCk: {
37277c478bd9Sstevel@tonic-gate   int nRoot;
37287c478bd9Sstevel@tonic-gate   int *aRoot;
37297c478bd9Sstevel@tonic-gate   int iSet = pOp->p1;
37307c478bd9Sstevel@tonic-gate   Set *pSet;
37317c478bd9Sstevel@tonic-gate   int j;
37327c478bd9Sstevel@tonic-gate   HashElem *i;
37337c478bd9Sstevel@tonic-gate   char *z;
37347c478bd9Sstevel@tonic-gate 
37357c478bd9Sstevel@tonic-gate   assert( iSet>=0 && iSet<p->nSet );
37367c478bd9Sstevel@tonic-gate   pTos++;
37377c478bd9Sstevel@tonic-gate   pSet = &p->aSet[iSet];
37387c478bd9Sstevel@tonic-gate   nRoot = sqliteHashCount(&pSet->hash);
37397c478bd9Sstevel@tonic-gate   aRoot = sqliteMallocRaw( sizeof(int)*(nRoot+1) );
37407c478bd9Sstevel@tonic-gate   if( aRoot==0 ) goto no_mem;
37417c478bd9Sstevel@tonic-gate   for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){
37427c478bd9Sstevel@tonic-gate     toInt((char*)sqliteHashKey(i), &aRoot[j]);
37437c478bd9Sstevel@tonic-gate   }
37447c478bd9Sstevel@tonic-gate   aRoot[j] = 0;
37457c478bd9Sstevel@tonic-gate   sqliteHashClear(&pSet->hash);
37467c478bd9Sstevel@tonic-gate   pSet->prev = 0;
37477c478bd9Sstevel@tonic-gate   z = sqliteBtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot);
37487c478bd9Sstevel@tonic-gate   if( z==0 || z[0]==0 ){
37497c478bd9Sstevel@tonic-gate     if( z ) sqliteFree(z);
37507c478bd9Sstevel@tonic-gate     pTos->z = "ok";
37517c478bd9Sstevel@tonic-gate     pTos->n = 3;
37527c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Str | MEM_Static;
37537c478bd9Sstevel@tonic-gate   }else{
37547c478bd9Sstevel@tonic-gate     pTos->z = z;
37557c478bd9Sstevel@tonic-gate     pTos->n = strlen(z) + 1;
37567c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Str | MEM_Dyn;
37577c478bd9Sstevel@tonic-gate   }
37587c478bd9Sstevel@tonic-gate   sqliteFree(aRoot);
37597c478bd9Sstevel@tonic-gate   break;
37607c478bd9Sstevel@tonic-gate }
37617c478bd9Sstevel@tonic-gate 
37627c478bd9Sstevel@tonic-gate /* Opcode: ListWrite * * *
37637c478bd9Sstevel@tonic-gate **
37647c478bd9Sstevel@tonic-gate ** Write the integer on the top of the stack
37657c478bd9Sstevel@tonic-gate ** into the temporary storage list.
37667c478bd9Sstevel@tonic-gate */
37677c478bd9Sstevel@tonic-gate case OP_ListWrite: {
37687c478bd9Sstevel@tonic-gate   Keylist *pKeylist;
37697c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
37707c478bd9Sstevel@tonic-gate   pKeylist = p->pList;
37717c478bd9Sstevel@tonic-gate   if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){
37727c478bd9Sstevel@tonic-gate     pKeylist = sqliteMallocRaw( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) );
37737c478bd9Sstevel@tonic-gate     if( pKeylist==0 ) goto no_mem;
37747c478bd9Sstevel@tonic-gate     pKeylist->nKey = 1000;
37757c478bd9Sstevel@tonic-gate     pKeylist->nRead = 0;
37767c478bd9Sstevel@tonic-gate     pKeylist->nUsed = 0;
37777c478bd9Sstevel@tonic-gate     pKeylist->pNext = p->pList;
37787c478bd9Sstevel@tonic-gate     p->pList = pKeylist;
37797c478bd9Sstevel@tonic-gate   }
37807c478bd9Sstevel@tonic-gate   Integerify(pTos);
37817c478bd9Sstevel@tonic-gate   pKeylist->aKey[pKeylist->nUsed++] = pTos->i;
37827c478bd9Sstevel@tonic-gate   Release(pTos);
37837c478bd9Sstevel@tonic-gate   pTos--;
37847c478bd9Sstevel@tonic-gate   break;
37857c478bd9Sstevel@tonic-gate }
37867c478bd9Sstevel@tonic-gate 
37877c478bd9Sstevel@tonic-gate /* Opcode: ListRewind * * *
37887c478bd9Sstevel@tonic-gate **
37897c478bd9Sstevel@tonic-gate ** Rewind the temporary buffer back to the beginning.
37907c478bd9Sstevel@tonic-gate */
37917c478bd9Sstevel@tonic-gate case OP_ListRewind: {
37927c478bd9Sstevel@tonic-gate   /* What this opcode codes, really, is reverse the order of the
37937c478bd9Sstevel@tonic-gate   ** linked list of Keylist structures so that they are read out
37947c478bd9Sstevel@tonic-gate   ** in the same order that they were read in. */
37957c478bd9Sstevel@tonic-gate   Keylist *pRev, *pTop;
37967c478bd9Sstevel@tonic-gate   pRev = 0;
37977c478bd9Sstevel@tonic-gate   while( p->pList ){
37987c478bd9Sstevel@tonic-gate     pTop = p->pList;
37997c478bd9Sstevel@tonic-gate     p->pList = pTop->pNext;
38007c478bd9Sstevel@tonic-gate     pTop->pNext = pRev;
38017c478bd9Sstevel@tonic-gate     pRev = pTop;
38027c478bd9Sstevel@tonic-gate   }
38037c478bd9Sstevel@tonic-gate   p->pList = pRev;
38047c478bd9Sstevel@tonic-gate   break;
38057c478bd9Sstevel@tonic-gate }
38067c478bd9Sstevel@tonic-gate 
38077c478bd9Sstevel@tonic-gate /* Opcode: ListRead * P2 *
38087c478bd9Sstevel@tonic-gate **
38097c478bd9Sstevel@tonic-gate ** Attempt to read an integer from the temporary storage buffer
3810*55fea89dSDan Cross ** and push it onto the stack.  If the storage buffer is empty,
38117c478bd9Sstevel@tonic-gate ** push nothing but instead jump to P2.
38127c478bd9Sstevel@tonic-gate */
38137c478bd9Sstevel@tonic-gate case OP_ListRead: {
38147c478bd9Sstevel@tonic-gate   Keylist *pKeylist;
38157c478bd9Sstevel@tonic-gate   CHECK_FOR_INTERRUPT;
38167c478bd9Sstevel@tonic-gate   pKeylist = p->pList;
38177c478bd9Sstevel@tonic-gate   if( pKeylist!=0 ){
38187c478bd9Sstevel@tonic-gate     assert( pKeylist->nRead>=0 );
38197c478bd9Sstevel@tonic-gate     assert( pKeylist->nRead<pKeylist->nUsed );
38207c478bd9Sstevel@tonic-gate     assert( pKeylist->nRead<pKeylist->nKey );
38217c478bd9Sstevel@tonic-gate     pTos++;
38227c478bd9Sstevel@tonic-gate     pTos->i = pKeylist->aKey[pKeylist->nRead++];
38237c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Int;
38247c478bd9Sstevel@tonic-gate     if( pKeylist->nRead>=pKeylist->nUsed ){
38257c478bd9Sstevel@tonic-gate       p->pList = pKeylist->pNext;
38267c478bd9Sstevel@tonic-gate       sqliteFree(pKeylist);
38277c478bd9Sstevel@tonic-gate     }
38287c478bd9Sstevel@tonic-gate   }else{
38297c478bd9Sstevel@tonic-gate     pc = pOp->p2 - 1;
38307c478bd9Sstevel@tonic-gate   }
38317c478bd9Sstevel@tonic-gate   break;
38327c478bd9Sstevel@tonic-gate }
38337c478bd9Sstevel@tonic-gate 
38347c478bd9Sstevel@tonic-gate /* Opcode: ListReset * * *
38357c478bd9Sstevel@tonic-gate **
38367c478bd9Sstevel@tonic-gate ** Reset the temporary storage buffer so that it holds nothing.
38377c478bd9Sstevel@tonic-gate */
38387c478bd9Sstevel@tonic-gate case OP_ListReset: {
38397c478bd9Sstevel@tonic-gate   if( p->pList ){
38407c478bd9Sstevel@tonic-gate     sqliteVdbeKeylistFree(p->pList);
38417c478bd9Sstevel@tonic-gate     p->pList = 0;
38427c478bd9Sstevel@tonic-gate   }
38437c478bd9Sstevel@tonic-gate   break;
38447c478bd9Sstevel@tonic-gate }
38457c478bd9Sstevel@tonic-gate 
3846*55fea89dSDan Cross /* Opcode: ListPush * * *
38477c478bd9Sstevel@tonic-gate **
38487c478bd9Sstevel@tonic-gate ** Save the current Vdbe list such that it can be restored by a ListPop
38497c478bd9Sstevel@tonic-gate ** opcode. The list is empty after this is executed.
38507c478bd9Sstevel@tonic-gate */
38517c478bd9Sstevel@tonic-gate case OP_ListPush: {
38527c478bd9Sstevel@tonic-gate   p->keylistStackDepth++;
38537c478bd9Sstevel@tonic-gate   assert(p->keylistStackDepth > 0);
3854*55fea89dSDan Cross   p->keylistStack = sqliteRealloc(p->keylistStack,
38557c478bd9Sstevel@tonic-gate           sizeof(Keylist *) * p->keylistStackDepth);
38567c478bd9Sstevel@tonic-gate   if( p->keylistStack==0 ) goto no_mem;
38577c478bd9Sstevel@tonic-gate   p->keylistStack[p->keylistStackDepth - 1] = p->pList;
38587c478bd9Sstevel@tonic-gate   p->pList = 0;
38597c478bd9Sstevel@tonic-gate   break;
38607c478bd9Sstevel@tonic-gate }
38617c478bd9Sstevel@tonic-gate 
3862*55fea89dSDan Cross /* Opcode: ListPop * * *
38637c478bd9Sstevel@tonic-gate **
38647c478bd9Sstevel@tonic-gate ** Restore the Vdbe list to the state it was in when ListPush was last
38657c478bd9Sstevel@tonic-gate ** executed.
38667c478bd9Sstevel@tonic-gate */
38677c478bd9Sstevel@tonic-gate case OP_ListPop: {
38687c478bd9Sstevel@tonic-gate   assert(p->keylistStackDepth > 0);
38697c478bd9Sstevel@tonic-gate   p->keylistStackDepth--;
38707c478bd9Sstevel@tonic-gate   sqliteVdbeKeylistFree(p->pList);
38717c478bd9Sstevel@tonic-gate   p->pList = p->keylistStack[p->keylistStackDepth];
38727c478bd9Sstevel@tonic-gate   p->keylistStack[p->keylistStackDepth] = 0;
38737c478bd9Sstevel@tonic-gate   if( p->keylistStackDepth == 0 ){
38747c478bd9Sstevel@tonic-gate     sqliteFree(p->keylistStack);
38757c478bd9Sstevel@tonic-gate     p->keylistStack = 0;
38767c478bd9Sstevel@tonic-gate   }
38777c478bd9Sstevel@tonic-gate   break;
38787c478bd9Sstevel@tonic-gate }
38797c478bd9Sstevel@tonic-gate 
3880*55fea89dSDan Cross /* Opcode: ContextPush * * *
38817c478bd9Sstevel@tonic-gate **
38827c478bd9Sstevel@tonic-gate ** Save the current Vdbe context such that it can be restored by a ContextPop
38837c478bd9Sstevel@tonic-gate ** opcode. The context stores the last insert row id, the last statement change
38847c478bd9Sstevel@tonic-gate ** count, and the current statement change count.
38857c478bd9Sstevel@tonic-gate */
38867c478bd9Sstevel@tonic-gate case OP_ContextPush: {
38877c478bd9Sstevel@tonic-gate   p->contextStackDepth++;
38887c478bd9Sstevel@tonic-gate   assert(p->contextStackDepth > 0);
3889*55fea89dSDan Cross   p->contextStack = sqliteRealloc(p->contextStack,
38907c478bd9Sstevel@tonic-gate           sizeof(Context) * p->contextStackDepth);
38917c478bd9Sstevel@tonic-gate   if( p->contextStack==0 ) goto no_mem;
38927c478bd9Sstevel@tonic-gate   p->contextStack[p->contextStackDepth - 1].lastRowid = p->db->lastRowid;
38937c478bd9Sstevel@tonic-gate   p->contextStack[p->contextStackDepth - 1].lsChange = p->db->lsChange;
38947c478bd9Sstevel@tonic-gate   p->contextStack[p->contextStackDepth - 1].csChange = p->db->csChange;
38957c478bd9Sstevel@tonic-gate   break;
38967c478bd9Sstevel@tonic-gate }
38977c478bd9Sstevel@tonic-gate 
3898*55fea89dSDan Cross /* Opcode: ContextPop * * *
38997c478bd9Sstevel@tonic-gate **
39007c478bd9Sstevel@tonic-gate ** Restore the Vdbe context to the state it was in when contextPush was last
39017c478bd9Sstevel@tonic-gate ** executed. The context stores the last insert row id, the last statement
39027c478bd9Sstevel@tonic-gate ** change count, and the current statement change count.
39037c478bd9Sstevel@tonic-gate */
39047c478bd9Sstevel@tonic-gate case OP_ContextPop: {
39057c478bd9Sstevel@tonic-gate   assert(p->contextStackDepth > 0);
39067c478bd9Sstevel@tonic-gate   p->contextStackDepth--;
39077c478bd9Sstevel@tonic-gate   p->db->lastRowid = p->contextStack[p->contextStackDepth].lastRowid;
39087c478bd9Sstevel@tonic-gate   p->db->lsChange = p->contextStack[p->contextStackDepth].lsChange;
39097c478bd9Sstevel@tonic-gate   p->db->csChange = p->contextStack[p->contextStackDepth].csChange;
39107c478bd9Sstevel@tonic-gate   if( p->contextStackDepth == 0 ){
39117c478bd9Sstevel@tonic-gate     sqliteFree(p->contextStack);
39127c478bd9Sstevel@tonic-gate     p->contextStack = 0;
39137c478bd9Sstevel@tonic-gate   }
39147c478bd9Sstevel@tonic-gate   break;
39157c478bd9Sstevel@tonic-gate }
39167c478bd9Sstevel@tonic-gate 
39177c478bd9Sstevel@tonic-gate /* Opcode: SortPut * * *
39187c478bd9Sstevel@tonic-gate **
39197c478bd9Sstevel@tonic-gate ** The TOS is the key and the NOS is the data.  Pop both from the stack
39207c478bd9Sstevel@tonic-gate ** and put them on the sorter.  The key and data should have been
39217c478bd9Sstevel@tonic-gate ** made using SortMakeKey and SortMakeRec, respectively.
39227c478bd9Sstevel@tonic-gate */
39237c478bd9Sstevel@tonic-gate case OP_SortPut: {
39247c478bd9Sstevel@tonic-gate   Mem *pNos = &pTos[-1];
39257c478bd9Sstevel@tonic-gate   Sorter *pSorter;
39267c478bd9Sstevel@tonic-gate   assert( pNos>=p->aStack );
39277c478bd9Sstevel@tonic-gate   if( Dynamicify(pTos) || Dynamicify(pNos) ) goto no_mem;
39287c478bd9Sstevel@tonic-gate   pSorter = sqliteMallocRaw( sizeof(Sorter) );
39297c478bd9Sstevel@tonic-gate   if( pSorter==0 ) goto no_mem;
39307c478bd9Sstevel@tonic-gate   pSorter->pNext = p->pSort;
39317c478bd9Sstevel@tonic-gate   p->pSort = pSorter;
39327c478bd9Sstevel@tonic-gate   assert( pTos->flags & MEM_Dyn );
39337c478bd9Sstevel@tonic-gate   pSorter->nKey = pTos->n;
39347c478bd9Sstevel@tonic-gate   pSorter->zKey = pTos->z;
39357c478bd9Sstevel@tonic-gate   assert( pNos->flags & MEM_Dyn );
39367c478bd9Sstevel@tonic-gate   pSorter->nData = pNos->n;
39377c478bd9Sstevel@tonic-gate   pSorter->pData = pNos->z;
39387c478bd9Sstevel@tonic-gate   pTos -= 2;
39397c478bd9Sstevel@tonic-gate   break;
39407c478bd9Sstevel@tonic-gate }
39417c478bd9Sstevel@tonic-gate 
39427c478bd9Sstevel@tonic-gate /* Opcode: SortMakeRec P1 * *
39437c478bd9Sstevel@tonic-gate **
39447c478bd9Sstevel@tonic-gate ** The top P1 elements are the arguments to a callback.  Form these
39457c478bd9Sstevel@tonic-gate ** elements into a single data entry that can be stored on a sorter
39467c478bd9Sstevel@tonic-gate ** using SortPut and later fed to a callback using SortCallback.
39477c478bd9Sstevel@tonic-gate */
39487c478bd9Sstevel@tonic-gate case OP_SortMakeRec: {
39497c478bd9Sstevel@tonic-gate   char *z;
39507c478bd9Sstevel@tonic-gate   char **azArg;
39517c478bd9Sstevel@tonic-gate   int nByte;
39527c478bd9Sstevel@tonic-gate   int nField;
39537c478bd9Sstevel@tonic-gate   int i;
39547c478bd9Sstevel@tonic-gate   Mem *pRec;
39557c478bd9Sstevel@tonic-gate 
39567c478bd9Sstevel@tonic-gate   nField = pOp->p1;
39577c478bd9Sstevel@tonic-gate   pRec = &pTos[1-nField];
39587c478bd9Sstevel@tonic-gate   assert( pRec>=p->aStack );
39597c478bd9Sstevel@tonic-gate   nByte = 0;
39607c478bd9Sstevel@tonic-gate   for(i=0; i<nField; i++, pRec++){
39617c478bd9Sstevel@tonic-gate     if( (pRec->flags & MEM_Null)==0 ){
39627c478bd9Sstevel@tonic-gate       Stringify(pRec);
39637c478bd9Sstevel@tonic-gate       nByte += pRec->n;
39647c478bd9Sstevel@tonic-gate     }
39657c478bd9Sstevel@tonic-gate   }
39667c478bd9Sstevel@tonic-gate   nByte += sizeof(char*)*(nField+1);
39677c478bd9Sstevel@tonic-gate   azArg = sqliteMallocRaw( nByte );
39687c478bd9Sstevel@tonic-gate   if( azArg==0 ) goto no_mem;
39697c478bd9Sstevel@tonic-gate   z = (char*)&azArg[nField+1];
39707c478bd9Sstevel@tonic-gate   for(pRec=&pTos[1-nField], i=0; i<nField; i++, pRec++){
39717c478bd9Sstevel@tonic-gate     if( pRec->flags & MEM_Null ){
39727c478bd9Sstevel@tonic-gate       azArg[i] = 0;
39737c478bd9Sstevel@tonic-gate     }else{
39747c478bd9Sstevel@tonic-gate       azArg[i] = z;
39757c478bd9Sstevel@tonic-gate       memcpy(z, pRec->z, pRec->n);
39767c478bd9Sstevel@tonic-gate       z += pRec->n;
39777c478bd9Sstevel@tonic-gate     }
39787c478bd9Sstevel@tonic-gate   }
39797c478bd9Sstevel@tonic-gate   popStack(&pTos, nField);
39807c478bd9Sstevel@tonic-gate   pTos++;
39817c478bd9Sstevel@tonic-gate   pTos->n = nByte;
39827c478bd9Sstevel@tonic-gate   pTos->z = (char*)azArg;
39837c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Str | MEM_Dyn;
39847c478bd9Sstevel@tonic-gate   break;
39857c478bd9Sstevel@tonic-gate }
39867c478bd9Sstevel@tonic-gate 
39877c478bd9Sstevel@tonic-gate /* Opcode: SortMakeKey * * P3
39887c478bd9Sstevel@tonic-gate **
39897c478bd9Sstevel@tonic-gate ** Convert the top few entries of the stack into a sort key.  The
3990*55fea89dSDan Cross ** number of stack entries consumed is the number of characters in
39917c478bd9Sstevel@tonic-gate ** the string P3.  One character from P3 is prepended to each entry.
39927c478bd9Sstevel@tonic-gate ** The first character of P3 is prepended to the element lowest in
39937c478bd9Sstevel@tonic-gate ** the stack and the last character of P3 is prepended to the top of
39947c478bd9Sstevel@tonic-gate ** the stack.  All stack entries are separated by a \000 character
39957c478bd9Sstevel@tonic-gate ** in the result.  The whole key is terminated by two \000 characters
39967c478bd9Sstevel@tonic-gate ** in a row.
39977c478bd9Sstevel@tonic-gate **
39987c478bd9Sstevel@tonic-gate ** "N" is substituted in place of the P3 character for NULL values.
39997c478bd9Sstevel@tonic-gate **
40007c478bd9Sstevel@tonic-gate ** See also the MakeKey and MakeIdxKey opcodes.
40017c478bd9Sstevel@tonic-gate */
40027c478bd9Sstevel@tonic-gate case OP_SortMakeKey: {
40037c478bd9Sstevel@tonic-gate   char *zNewKey;
40047c478bd9Sstevel@tonic-gate   int nByte;
40057c478bd9Sstevel@tonic-gate   int nField;
40067c478bd9Sstevel@tonic-gate   int i, j, k;
40077c478bd9Sstevel@tonic-gate   Mem *pRec;
40087c478bd9Sstevel@tonic-gate 
40097c478bd9Sstevel@tonic-gate   nField = strlen(pOp->p3);
40107c478bd9Sstevel@tonic-gate   pRec = &pTos[1-nField];
40117c478bd9Sstevel@tonic-gate   nByte = 1;
40127c478bd9Sstevel@tonic-gate   for(i=0; i<nField; i++, pRec++){
40137c478bd9Sstevel@tonic-gate     if( pRec->flags & MEM_Null ){
40147c478bd9Sstevel@tonic-gate       nByte += 2;
40157c478bd9Sstevel@tonic-gate     }else{
40167c478bd9Sstevel@tonic-gate       Stringify(pRec);
40177c478bd9Sstevel@tonic-gate       nByte += pRec->n+2;
40187c478bd9Sstevel@tonic-gate     }
40197c478bd9Sstevel@tonic-gate   }
40207c478bd9Sstevel@tonic-gate   zNewKey = sqliteMallocRaw( nByte );
40217c478bd9Sstevel@tonic-gate   if( zNewKey==0 ) goto no_mem;
40227c478bd9Sstevel@tonic-gate   j = 0;
40237c478bd9Sstevel@tonic-gate   k = 0;
40247c478bd9Sstevel@tonic-gate   for(pRec=&pTos[1-nField], i=0; i<nField; i++, pRec++){
40257c478bd9Sstevel@tonic-gate     if( pRec->flags & MEM_Null ){
40267c478bd9Sstevel@tonic-gate       zNewKey[j++] = 'N';
40277c478bd9Sstevel@tonic-gate       zNewKey[j++] = 0;
40287c478bd9Sstevel@tonic-gate       k++;
40297c478bd9Sstevel@tonic-gate     }else{
40307c478bd9Sstevel@tonic-gate       zNewKey[j++] = pOp->p3[k++];
40317c478bd9Sstevel@tonic-gate       memcpy(&zNewKey[j], pRec->z, pRec->n-1);
40327c478bd9Sstevel@tonic-gate       j += pRec->n-1;
40337c478bd9Sstevel@tonic-gate       zNewKey[j++] = 0;
40347c478bd9Sstevel@tonic-gate     }
40357c478bd9Sstevel@tonic-gate   }
40367c478bd9Sstevel@tonic-gate   zNewKey[j] = 0;
40377c478bd9Sstevel@tonic-gate   assert( j<nByte );
40387c478bd9Sstevel@tonic-gate   popStack(&pTos, nField);
40397c478bd9Sstevel@tonic-gate   pTos++;
40407c478bd9Sstevel@tonic-gate   pTos->n = nByte;
40417c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Str|MEM_Dyn;
40427c478bd9Sstevel@tonic-gate   pTos->z = zNewKey;
40437c478bd9Sstevel@tonic-gate   break;
40447c478bd9Sstevel@tonic-gate }
40457c478bd9Sstevel@tonic-gate 
40467c478bd9Sstevel@tonic-gate /* Opcode: Sort * * *
40477c478bd9Sstevel@tonic-gate **
40487c478bd9Sstevel@tonic-gate ** Sort all elements on the sorter.  The algorithm is a
40497c478bd9Sstevel@tonic-gate ** mergesort.
40507c478bd9Sstevel@tonic-gate */
40517c478bd9Sstevel@tonic-gate case OP_Sort: {
40527c478bd9Sstevel@tonic-gate   int i;
40537c478bd9Sstevel@tonic-gate   Sorter *pElem;
40547c478bd9Sstevel@tonic-gate   Sorter *apSorter[NSORT];
40557c478bd9Sstevel@tonic-gate   for(i=0; i<NSORT; i++){
40567c478bd9Sstevel@tonic-gate     apSorter[i] = 0;
40577c478bd9Sstevel@tonic-gate   }
40587c478bd9Sstevel@tonic-gate   while( p->pSort ){
40597c478bd9Sstevel@tonic-gate     pElem = p->pSort;
40607c478bd9Sstevel@tonic-gate     p->pSort = pElem->pNext;
40617c478bd9Sstevel@tonic-gate     pElem->pNext = 0;
40627c478bd9Sstevel@tonic-gate     for(i=0; i<NSORT-1; i++){
40637c478bd9Sstevel@tonic-gate     if( apSorter[i]==0 ){
40647c478bd9Sstevel@tonic-gate         apSorter[i] = pElem;
40657c478bd9Sstevel@tonic-gate         break;
40667c478bd9Sstevel@tonic-gate       }else{
40677c478bd9Sstevel@tonic-gate         pElem = Merge(apSorter[i], pElem);
40687c478bd9Sstevel@tonic-gate         apSorter[i] = 0;
40697c478bd9Sstevel@tonic-gate       }
40707c478bd9Sstevel@tonic-gate     }
40717c478bd9Sstevel@tonic-gate     if( i>=NSORT-1 ){
40727c478bd9Sstevel@tonic-gate       apSorter[NSORT-1] = Merge(apSorter[NSORT-1],pElem);
40737c478bd9Sstevel@tonic-gate     }
40747c478bd9Sstevel@tonic-gate   }
40757c478bd9Sstevel@tonic-gate   pElem = 0;
40767c478bd9Sstevel@tonic-gate   for(i=0; i<NSORT; i++){
40777c478bd9Sstevel@tonic-gate     pElem = Merge(apSorter[i], pElem);
40787c478bd9Sstevel@tonic-gate   }
40797c478bd9Sstevel@tonic-gate   p->pSort = pElem;
40807c478bd9Sstevel@tonic-gate   break;
40817c478bd9Sstevel@tonic-gate }
40827c478bd9Sstevel@tonic-gate 
40837c478bd9Sstevel@tonic-gate /* Opcode: SortNext * P2 *
40847c478bd9Sstevel@tonic-gate **
40857c478bd9Sstevel@tonic-gate ** Push the data for the topmost element in the sorter onto the
40867c478bd9Sstevel@tonic-gate ** stack, then remove the element from the sorter.  If the sorter
4087*55fea89dSDan Cross ** is empty, push nothing on the stack and instead jump immediately
40887c478bd9Sstevel@tonic-gate ** to instruction P2.
40897c478bd9Sstevel@tonic-gate */
40907c478bd9Sstevel@tonic-gate case OP_SortNext: {
40917c478bd9Sstevel@tonic-gate   Sorter *pSorter = p->pSort;
40927c478bd9Sstevel@tonic-gate   CHECK_FOR_INTERRUPT;
40937c478bd9Sstevel@tonic-gate   if( pSorter!=0 ){
40947c478bd9Sstevel@tonic-gate     p->pSort = pSorter->pNext;
40957c478bd9Sstevel@tonic-gate     pTos++;
40967c478bd9Sstevel@tonic-gate     pTos->z = pSorter->pData;
40977c478bd9Sstevel@tonic-gate     pTos->n = pSorter->nData;
40987c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Str|MEM_Dyn;
40997c478bd9Sstevel@tonic-gate     sqliteFree(pSorter->zKey);
41007c478bd9Sstevel@tonic-gate     sqliteFree(pSorter);
41017c478bd9Sstevel@tonic-gate   }else{
41027c478bd9Sstevel@tonic-gate     pc = pOp->p2 - 1;
41037c478bd9Sstevel@tonic-gate   }
41047c478bd9Sstevel@tonic-gate   break;
41057c478bd9Sstevel@tonic-gate }
41067c478bd9Sstevel@tonic-gate 
41077c478bd9Sstevel@tonic-gate /* Opcode: SortCallback P1 * *
41087c478bd9Sstevel@tonic-gate **
41097c478bd9Sstevel@tonic-gate ** The top of the stack contains a callback record built using
41107c478bd9Sstevel@tonic-gate ** the SortMakeRec operation with the same P1 value as this
41117c478bd9Sstevel@tonic-gate ** instruction.  Pop this record from the stack and invoke the
41127c478bd9Sstevel@tonic-gate ** callback on it.
41137c478bd9Sstevel@tonic-gate */
41147c478bd9Sstevel@tonic-gate case OP_SortCallback: {
41157c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
41167c478bd9Sstevel@tonic-gate   assert( pTos->flags & MEM_Str );
41177c478bd9Sstevel@tonic-gate   p->nCallback++;
41187c478bd9Sstevel@tonic-gate   p->pc = pc+1;
41197c478bd9Sstevel@tonic-gate   p->azResColumn = (char**)pTos->z;
41207c478bd9Sstevel@tonic-gate   assert( p->nResColumn==pOp->p1 );
41217c478bd9Sstevel@tonic-gate   p->popStack = 1;
41227c478bd9Sstevel@tonic-gate   p->pTos = pTos;
41237c478bd9Sstevel@tonic-gate   return SQLITE_ROW;
41247c478bd9Sstevel@tonic-gate }
41257c478bd9Sstevel@tonic-gate 
41267c478bd9Sstevel@tonic-gate /* Opcode: SortReset * * *
41277c478bd9Sstevel@tonic-gate **
41287c478bd9Sstevel@tonic-gate ** Remove any elements that remain on the sorter.
41297c478bd9Sstevel@tonic-gate */
41307c478bd9Sstevel@tonic-gate case OP_SortReset: {
41317c478bd9Sstevel@tonic-gate   sqliteVdbeSorterReset(p);
41327c478bd9Sstevel@tonic-gate   break;
41337c478bd9Sstevel@tonic-gate }
41347c478bd9Sstevel@tonic-gate 
41357c478bd9Sstevel@tonic-gate /* Opcode: FileOpen * * P3
41367c478bd9Sstevel@tonic-gate **
41377c478bd9Sstevel@tonic-gate ** Open the file named by P3 for reading using the FileRead opcode.
41387c478bd9Sstevel@tonic-gate ** If P3 is "stdin" then open standard input for reading.
41397c478bd9Sstevel@tonic-gate */
41407c478bd9Sstevel@tonic-gate case OP_FileOpen: {
41417c478bd9Sstevel@tonic-gate   assert( pOp->p3!=0 );
41427c478bd9Sstevel@tonic-gate   if( p->pFile ){
41437c478bd9Sstevel@tonic-gate     if( p->pFile!=stdin ) fclose(p->pFile);
41447c478bd9Sstevel@tonic-gate     p->pFile = 0;
41457c478bd9Sstevel@tonic-gate   }
41467c478bd9Sstevel@tonic-gate   if( sqliteStrICmp(pOp->p3,"stdin")==0 ){
41477c478bd9Sstevel@tonic-gate     p->pFile = stdin;
41487c478bd9Sstevel@tonic-gate   }else{
41497c478bd9Sstevel@tonic-gate     p->pFile = fopen(pOp->p3, "r");
41507c478bd9Sstevel@tonic-gate   }
41517c478bd9Sstevel@tonic-gate   if( p->pFile==0 ){
41527c478bd9Sstevel@tonic-gate     sqliteSetString(&p->zErrMsg,"unable to open file: ", pOp->p3, (char*)0);
41537c478bd9Sstevel@tonic-gate     rc = SQLITE_ERROR;
41547c478bd9Sstevel@tonic-gate   }
41557c478bd9Sstevel@tonic-gate   break;
41567c478bd9Sstevel@tonic-gate }
41577c478bd9Sstevel@tonic-gate 
41587c478bd9Sstevel@tonic-gate /* Opcode: FileRead P1 P2 P3
41597c478bd9Sstevel@tonic-gate **
41607c478bd9Sstevel@tonic-gate ** Read a single line of input from the open file (the file opened using
41617c478bd9Sstevel@tonic-gate ** FileOpen).  If we reach end-of-file, jump immediately to P2.  If
41627c478bd9Sstevel@tonic-gate ** we are able to get another line, split the line apart using P3 as
41637c478bd9Sstevel@tonic-gate ** a delimiter.  There should be P1 fields.  If the input line contains
41647c478bd9Sstevel@tonic-gate ** more than P1 fields, ignore the excess.  If the input line contains
41657c478bd9Sstevel@tonic-gate ** fewer than P1 fields, assume the remaining fields contain NULLs.
41667c478bd9Sstevel@tonic-gate **
41677c478bd9Sstevel@tonic-gate ** Input ends if a line consists of just "\.".  A field containing only
41687c478bd9Sstevel@tonic-gate ** "\N" is a null field.  The backslash \ character can be used be used
41697c478bd9Sstevel@tonic-gate ** to escape newlines or the delimiter.
41707c478bd9Sstevel@tonic-gate */
41717c478bd9Sstevel@tonic-gate case OP_FileRead: {
41727c478bd9Sstevel@tonic-gate   int n, eol, nField, i, c, nDelim;
41737c478bd9Sstevel@tonic-gate   char *zDelim, *z;
41747c478bd9Sstevel@tonic-gate   CHECK_FOR_INTERRUPT;
41757c478bd9Sstevel@tonic-gate   if( p->pFile==0 ) goto fileread_jump;
41767c478bd9Sstevel@tonic-gate   nField = pOp->p1;
41777c478bd9Sstevel@tonic-gate   if( nField<=0 ) goto fileread_jump;
41787c478bd9Sstevel@tonic-gate   if( nField!=p->nField || p->azField==0 ){
41797c478bd9Sstevel@tonic-gate     char **azField = sqliteRealloc(p->azField, sizeof(char*)*nField+1);
41807c478bd9Sstevel@tonic-gate     if( azField==0 ){ goto no_mem; }
41817c478bd9Sstevel@tonic-gate     p->azField = azField;
41827c478bd9Sstevel@tonic-gate     p->nField = nField;
41837c478bd9Sstevel@tonic-gate   }
41847c478bd9Sstevel@tonic-gate   n = 0;
41857c478bd9Sstevel@tonic-gate   eol = 0;
41867c478bd9Sstevel@tonic-gate   while( eol==0 ){
41877c478bd9Sstevel@tonic-gate     if( p->zLine==0 || n+200>p->nLineAlloc ){
41887c478bd9Sstevel@tonic-gate       char *zLine;
41897c478bd9Sstevel@tonic-gate       p->nLineAlloc = p->nLineAlloc*2 + 300;
41907c478bd9Sstevel@tonic-gate       zLine = sqliteRealloc(p->zLine, p->nLineAlloc);
41917c478bd9Sstevel@tonic-gate       if( zLine==0 ){
41927c478bd9Sstevel@tonic-gate         p->nLineAlloc = 0;
41937c478bd9Sstevel@tonic-gate         sqliteFree(p->zLine);
41947c478bd9Sstevel@tonic-gate         p->zLine = 0;
41957c478bd9Sstevel@tonic-gate         goto no_mem;
41967c478bd9Sstevel@tonic-gate       }
41977c478bd9Sstevel@tonic-gate       p->zLine = zLine;
41987c478bd9Sstevel@tonic-gate     }
41997c478bd9Sstevel@tonic-gate     if( vdbe_fgets(&p->zLine[n], p->nLineAlloc-n, p->pFile)==0 ){
42007c478bd9Sstevel@tonic-gate       eol = 1;
42017c478bd9Sstevel@tonic-gate       p->zLine[n] = 0;
42027c478bd9Sstevel@tonic-gate     }else{
42037c478bd9Sstevel@tonic-gate       int c;
42047c478bd9Sstevel@tonic-gate       while( (c = p->zLine[n])!=0 ){
42057c478bd9Sstevel@tonic-gate         if( c=='\\' ){
42067c478bd9Sstevel@tonic-gate           if( p->zLine[n+1]==0 ) break;
42077c478bd9Sstevel@tonic-gate           n += 2;
42087c478bd9Sstevel@tonic-gate         }else if( c=='\n' ){
42097c478bd9Sstevel@tonic-gate           p->zLine[n] = 0;
42107c478bd9Sstevel@tonic-gate           eol = 1;
42117c478bd9Sstevel@tonic-gate           break;
42127c478bd9Sstevel@tonic-gate         }else{
42137c478bd9Sstevel@tonic-gate           n++;
42147c478bd9Sstevel@tonic-gate         }
42157c478bd9Sstevel@tonic-gate       }
42167c478bd9Sstevel@tonic-gate     }
42177c478bd9Sstevel@tonic-gate   }
42187c478bd9Sstevel@tonic-gate   if( n==0 ) goto fileread_jump;
42197c478bd9Sstevel@tonic-gate   z = p->zLine;
42207c478bd9Sstevel@tonic-gate   if( z[0]=='\\' && z[1]=='.' && z[2]==0 ){
42217c478bd9Sstevel@tonic-gate     goto fileread_jump;
42227c478bd9Sstevel@tonic-gate   }
42237c478bd9Sstevel@tonic-gate   zDelim = pOp->p3;
42247c478bd9Sstevel@tonic-gate   if( zDelim==0 ) zDelim = "\t";
42257c478bd9Sstevel@tonic-gate   c = zDelim[0];
42267c478bd9Sstevel@tonic-gate   nDelim = strlen(zDelim);
42277c478bd9Sstevel@tonic-gate   p->azField[0] = z;
42287c478bd9Sstevel@tonic-gate   for(i=1; *z!=0 && i<=nField; i++){
42297c478bd9Sstevel@tonic-gate     int from, to;
42307c478bd9Sstevel@tonic-gate     from = to = 0;
4231*55fea89dSDan Cross     if( z[0]=='\\' && z[1]=='N'
42327c478bd9Sstevel@tonic-gate        && (z[2]==0 || strncmp(&z[2],zDelim,nDelim)==0) ){
42337c478bd9Sstevel@tonic-gate       if( i<=nField ) p->azField[i-1] = 0;
42347c478bd9Sstevel@tonic-gate       z += 2 + nDelim;
42357c478bd9Sstevel@tonic-gate       if( i<nField ) p->azField[i] = z;
42367c478bd9Sstevel@tonic-gate       continue;
42377c478bd9Sstevel@tonic-gate     }
42387c478bd9Sstevel@tonic-gate     while( z[from] ){
42397c478bd9Sstevel@tonic-gate       if( z[from]=='\\' && z[from+1]!=0 ){
42407c478bd9Sstevel@tonic-gate         int tx = z[from+1];
42417c478bd9Sstevel@tonic-gate         switch( tx ){
42427c478bd9Sstevel@tonic-gate           case 'b':  tx = '\b'; break;
42437c478bd9Sstevel@tonic-gate           case 'f':  tx = '\f'; break;
42447c478bd9Sstevel@tonic-gate           case 'n':  tx = '\n'; break;
42457c478bd9Sstevel@tonic-gate           case 'r':  tx = '\r'; break;
42467c478bd9Sstevel@tonic-gate           case 't':  tx = '\t'; break;
42477c478bd9Sstevel@tonic-gate           case 'v':  tx = '\v'; break;
42487c478bd9Sstevel@tonic-gate           default:   break;
42497c478bd9Sstevel@tonic-gate         }
42507c478bd9Sstevel@tonic-gate         z[to++] = tx;
42517c478bd9Sstevel@tonic-gate         from += 2;
42527c478bd9Sstevel@tonic-gate         continue;
42537c478bd9Sstevel@tonic-gate       }
42547c478bd9Sstevel@tonic-gate       if( z[from]==c && strncmp(&z[from],zDelim,nDelim)==0 ) break;
42557c478bd9Sstevel@tonic-gate       z[to++] = z[from++];
42567c478bd9Sstevel@tonic-gate     }
42577c478bd9Sstevel@tonic-gate     if( z[from] ){
42587c478bd9Sstevel@tonic-gate       z[to] = 0;
42597c478bd9Sstevel@tonic-gate       z += from + nDelim;
42607c478bd9Sstevel@tonic-gate       if( i<nField ) p->azField[i] = z;
42617c478bd9Sstevel@tonic-gate     }else{
42627c478bd9Sstevel@tonic-gate       z[to] = 0;
42637c478bd9Sstevel@tonic-gate       z = "";
42647c478bd9Sstevel@tonic-gate     }
42657c478bd9Sstevel@tonic-gate   }
42667c478bd9Sstevel@tonic-gate   while( i<nField ){
42677c478bd9Sstevel@tonic-gate     p->azField[i++] = 0;
42687c478bd9Sstevel@tonic-gate   }
42697c478bd9Sstevel@tonic-gate   break;
42707c478bd9Sstevel@tonic-gate 
42717c478bd9Sstevel@tonic-gate   /* If we reach end-of-file, or if anything goes wrong, jump here.
42727c478bd9Sstevel@tonic-gate   ** This code will cause a jump to P2 */
42737c478bd9Sstevel@tonic-gate fileread_jump:
42747c478bd9Sstevel@tonic-gate   pc = pOp->p2 - 1;
42757c478bd9Sstevel@tonic-gate   break;
42767c478bd9Sstevel@tonic-gate }
42777c478bd9Sstevel@tonic-gate 
42787c478bd9Sstevel@tonic-gate /* Opcode: FileColumn P1 * *
42797c478bd9Sstevel@tonic-gate **
42807c478bd9Sstevel@tonic-gate ** Push onto the stack the P1-th column of the most recently read line
42817c478bd9Sstevel@tonic-gate ** from the input file.
42827c478bd9Sstevel@tonic-gate */
42837c478bd9Sstevel@tonic-gate case OP_FileColumn: {
42847c478bd9Sstevel@tonic-gate   int i = pOp->p1;
42857c478bd9Sstevel@tonic-gate   char *z;
42867c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nField );
42877c478bd9Sstevel@tonic-gate   if( p->azField ){
42887c478bd9Sstevel@tonic-gate     z = p->azField[i];
42897c478bd9Sstevel@tonic-gate   }else{
42907c478bd9Sstevel@tonic-gate     z = 0;
42917c478bd9Sstevel@tonic-gate   }
42927c478bd9Sstevel@tonic-gate   pTos++;
42937c478bd9Sstevel@tonic-gate   if( z ){
42947c478bd9Sstevel@tonic-gate     pTos->n = strlen(z) + 1;
42957c478bd9Sstevel@tonic-gate     pTos->z = z;
42967c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Str | MEM_Ephem;
42977c478bd9Sstevel@tonic-gate   }else{
42987c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
42997c478bd9Sstevel@tonic-gate   }
43007c478bd9Sstevel@tonic-gate   break;
43017c478bd9Sstevel@tonic-gate }
43027c478bd9Sstevel@tonic-gate 
43037c478bd9Sstevel@tonic-gate /* Opcode: MemStore P1 P2 *
43047c478bd9Sstevel@tonic-gate **
43057c478bd9Sstevel@tonic-gate ** Write the top of the stack into memory location P1.
43067c478bd9Sstevel@tonic-gate ** P1 should be a small integer since space is allocated
43077c478bd9Sstevel@tonic-gate ** for all memory locations between 0 and P1 inclusive.
43087c478bd9Sstevel@tonic-gate **
43097c478bd9Sstevel@tonic-gate ** After the data is stored in the memory location, the
43107c478bd9Sstevel@tonic-gate ** stack is popped once if P2 is 1.  If P2 is zero, then
43117c478bd9Sstevel@tonic-gate ** the original data remains on the stack.
43127c478bd9Sstevel@tonic-gate */
43137c478bd9Sstevel@tonic-gate case OP_MemStore: {
43147c478bd9Sstevel@tonic-gate   int i = pOp->p1;
43157c478bd9Sstevel@tonic-gate   Mem *pMem;
43167c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
43177c478bd9Sstevel@tonic-gate   if( i>=p->nMem ){
43187c478bd9Sstevel@tonic-gate     int nOld = p->nMem;
43197c478bd9Sstevel@tonic-gate     Mem *aMem;
43207c478bd9Sstevel@tonic-gate     p->nMem = i + 5;
43217c478bd9Sstevel@tonic-gate     aMem = sqliteRealloc(p->aMem, p->nMem*sizeof(p->aMem[0]));
43227c478bd9Sstevel@tonic-gate     if( aMem==0 ) goto no_mem;
43237c478bd9Sstevel@tonic-gate     if( aMem!=p->aMem ){
43247c478bd9Sstevel@tonic-gate       int j;
43257c478bd9Sstevel@tonic-gate       for(j=0; j<nOld; j++){
43267c478bd9Sstevel@tonic-gate         if( aMem[j].flags & MEM_Short ){
43277c478bd9Sstevel@tonic-gate           aMem[j].z = aMem[j].zShort;
43287c478bd9Sstevel@tonic-gate         }
43297c478bd9Sstevel@tonic-gate       }
43307c478bd9Sstevel@tonic-gate     }
43317c478bd9Sstevel@tonic-gate     p->aMem = aMem;
43327c478bd9Sstevel@tonic-gate     if( nOld<p->nMem ){
43337c478bd9Sstevel@tonic-gate       memset(&p->aMem[nOld], 0, sizeof(p->aMem[0])*(p->nMem-nOld));
43347c478bd9Sstevel@tonic-gate     }
43357c478bd9Sstevel@tonic-gate   }
43367c478bd9Sstevel@tonic-gate   Deephemeralize(pTos);
43377c478bd9Sstevel@tonic-gate   pMem = &p->aMem[i];
43387c478bd9Sstevel@tonic-gate   Release(pMem);
43397c478bd9Sstevel@tonic-gate   *pMem = *pTos;
43407c478bd9Sstevel@tonic-gate   if( pMem->flags & MEM_Dyn ){
43417c478bd9Sstevel@tonic-gate     if( pOp->p2 ){
43427c478bd9Sstevel@tonic-gate       pTos->flags = MEM_Null;
43437c478bd9Sstevel@tonic-gate     }else{
43447c478bd9Sstevel@tonic-gate       pMem->z = sqliteMallocRaw( pMem->n );
43457c478bd9Sstevel@tonic-gate       if( pMem->z==0 ) goto no_mem;
43467c478bd9Sstevel@tonic-gate       memcpy(pMem->z, pTos->z, pMem->n);
43477c478bd9Sstevel@tonic-gate     }
43487c478bd9Sstevel@tonic-gate   }else if( pMem->flags & MEM_Short ){
43497c478bd9Sstevel@tonic-gate     pMem->z = pMem->zShort;
43507c478bd9Sstevel@tonic-gate   }
43517c478bd9Sstevel@tonic-gate   if( pOp->p2 ){
43527c478bd9Sstevel@tonic-gate     Release(pTos);
43537c478bd9Sstevel@tonic-gate     pTos--;
43547c478bd9Sstevel@tonic-gate   }
43557c478bd9Sstevel@tonic-gate   break;
43567c478bd9Sstevel@tonic-gate }
43577c478bd9Sstevel@tonic-gate 
43587c478bd9Sstevel@tonic-gate /* Opcode: MemLoad P1 * *
43597c478bd9Sstevel@tonic-gate **
43607c478bd9Sstevel@tonic-gate ** Push a copy of the value in memory location P1 onto the stack.
43617c478bd9Sstevel@tonic-gate **
43627c478bd9Sstevel@tonic-gate ** If the value is a string, then the value pushed is a pointer to
43637c478bd9Sstevel@tonic-gate ** the string that is stored in the memory location.  If the memory
43647c478bd9Sstevel@tonic-gate ** location is subsequently changed (using OP_MemStore) then the
43657c478bd9Sstevel@tonic-gate ** value pushed onto the stack will change too.
43667c478bd9Sstevel@tonic-gate */
43677c478bd9Sstevel@tonic-gate case OP_MemLoad: {
43687c478bd9Sstevel@tonic-gate   int i = pOp->p1;
43697c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nMem );
43707c478bd9Sstevel@tonic-gate   pTos++;
43717c478bd9Sstevel@tonic-gate   memcpy(pTos, &p->aMem[i], sizeof(pTos[0])-NBFS);;
43727c478bd9Sstevel@tonic-gate   if( pTos->flags & MEM_Str ){
43737c478bd9Sstevel@tonic-gate     pTos->flags |= MEM_Ephem;
43747c478bd9Sstevel@tonic-gate     pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
43757c478bd9Sstevel@tonic-gate   }
43767c478bd9Sstevel@tonic-gate   break;
43777c478bd9Sstevel@tonic-gate }
43787c478bd9Sstevel@tonic-gate 
43797c478bd9Sstevel@tonic-gate /* Opcode: MemIncr P1 P2 *
43807c478bd9Sstevel@tonic-gate **
43817c478bd9Sstevel@tonic-gate ** Increment the integer valued memory cell P1 by 1.  If P2 is not zero
43827c478bd9Sstevel@tonic-gate ** and the result after the increment is greater than zero, then jump
43837c478bd9Sstevel@tonic-gate ** to P2.
43847c478bd9Sstevel@tonic-gate **
43857c478bd9Sstevel@tonic-gate ** This instruction throws an error if the memory cell is not initially
43867c478bd9Sstevel@tonic-gate ** an integer.
43877c478bd9Sstevel@tonic-gate */
43887c478bd9Sstevel@tonic-gate case OP_MemIncr: {
43897c478bd9Sstevel@tonic-gate   int i = pOp->p1;
43907c478bd9Sstevel@tonic-gate   Mem *pMem;
43917c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->nMem );
43927c478bd9Sstevel@tonic-gate   pMem = &p->aMem[i];
43937c478bd9Sstevel@tonic-gate   assert( pMem->flags==MEM_Int );
43947c478bd9Sstevel@tonic-gate   pMem->i++;
43957c478bd9Sstevel@tonic-gate   if( pOp->p2>0 && pMem->i>0 ){
43967c478bd9Sstevel@tonic-gate      pc = pOp->p2 - 1;
43977c478bd9Sstevel@tonic-gate   }
43987c478bd9Sstevel@tonic-gate   break;
43997c478bd9Sstevel@tonic-gate }
44007c478bd9Sstevel@tonic-gate 
44017c478bd9Sstevel@tonic-gate /* Opcode: AggReset * P2 *
44027c478bd9Sstevel@tonic-gate **
44037c478bd9Sstevel@tonic-gate ** Reset the aggregator so that it no longer contains any data.
44047c478bd9Sstevel@tonic-gate ** Future aggregator elements will contain P2 values each.
44057c478bd9Sstevel@tonic-gate */
44067c478bd9Sstevel@tonic-gate case OP_AggReset: {
44077c478bd9Sstevel@tonic-gate   sqliteVdbeAggReset(&p->agg);
44087c478bd9Sstevel@tonic-gate   p->agg.nMem = pOp->p2;
44097c478bd9Sstevel@tonic-gate   p->agg.apFunc = sqliteMalloc( p->agg.nMem*sizeof(p->agg.apFunc[0]) );
44107c478bd9Sstevel@tonic-gate   if( p->agg.apFunc==0 ) goto no_mem;
44117c478bd9Sstevel@tonic-gate   break;
44127c478bd9Sstevel@tonic-gate }
44137c478bd9Sstevel@tonic-gate 
44147c478bd9Sstevel@tonic-gate /* Opcode: AggInit * P2 P3
44157c478bd9Sstevel@tonic-gate **
44167c478bd9Sstevel@tonic-gate ** Initialize the function parameters for an aggregate function.
44177c478bd9Sstevel@tonic-gate ** The aggregate will operate out of aggregate column P2.
44187c478bd9Sstevel@tonic-gate ** P3 is a pointer to the FuncDef structure for the function.
44197c478bd9Sstevel@tonic-gate */
44207c478bd9Sstevel@tonic-gate case OP_AggInit: {
44217c478bd9Sstevel@tonic-gate   int i = pOp->p2;
44227c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->agg.nMem );
44237c478bd9Sstevel@tonic-gate   p->agg.apFunc[i] = (FuncDef*)pOp->p3;
44247c478bd9Sstevel@tonic-gate   break;
44257c478bd9Sstevel@tonic-gate }
44267c478bd9Sstevel@tonic-gate 
44277c478bd9Sstevel@tonic-gate /* Opcode: AggFunc * P2 P3
44287c478bd9Sstevel@tonic-gate **
44297c478bd9Sstevel@tonic-gate ** Execute the step function for an aggregate.  The
44307c478bd9Sstevel@tonic-gate ** function has P2 arguments.  P3 is a pointer to the FuncDef
44317c478bd9Sstevel@tonic-gate ** structure that specifies the function.
44327c478bd9Sstevel@tonic-gate **
44337c478bd9Sstevel@tonic-gate ** The top of the stack must be an integer which is the index of
44347c478bd9Sstevel@tonic-gate ** the aggregate column that corresponds to this aggregate function.
44357c478bd9Sstevel@tonic-gate ** Ideally, this index would be another parameter, but there are
44367c478bd9Sstevel@tonic-gate ** no free parameters left.  The integer is popped from the stack.
44377c478bd9Sstevel@tonic-gate */
44387c478bd9Sstevel@tonic-gate case OP_AggFunc: {
44397c478bd9Sstevel@tonic-gate   int n = pOp->p2;
44407c478bd9Sstevel@tonic-gate   int i;
44417c478bd9Sstevel@tonic-gate   Mem *pMem, *pRec;
44427c478bd9Sstevel@tonic-gate   char **azArgv = p->zArgv;
44437c478bd9Sstevel@tonic-gate   sqlite_func ctx;
44447c478bd9Sstevel@tonic-gate 
44457c478bd9Sstevel@tonic-gate   assert( n>=0 );
44467c478bd9Sstevel@tonic-gate   assert( pTos->flags==MEM_Int );
44477c478bd9Sstevel@tonic-gate   pRec = &pTos[-n];
44487c478bd9Sstevel@tonic-gate   assert( pRec>=p->aStack );
44497c478bd9Sstevel@tonic-gate   for(i=0; i<n; i++, pRec++){
44507c478bd9Sstevel@tonic-gate     if( pRec->flags & MEM_Null ){
44517c478bd9Sstevel@tonic-gate       azArgv[i] = 0;
44527c478bd9Sstevel@tonic-gate     }else{
44537c478bd9Sstevel@tonic-gate       Stringify(pRec);
44547c478bd9Sstevel@tonic-gate       azArgv[i] = pRec->z;
44557c478bd9Sstevel@tonic-gate     }
44567c478bd9Sstevel@tonic-gate   }
44577c478bd9Sstevel@tonic-gate   i = pTos->i;
44587c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->agg.nMem );
44597c478bd9Sstevel@tonic-gate   ctx.pFunc = (FuncDef*)pOp->p3;
44607c478bd9Sstevel@tonic-gate   pMem = &p->agg.pCurrent->aMem[i];
44617c478bd9Sstevel@tonic-gate   ctx.s.z = pMem->zShort;  /* Space used for small aggregate contexts */
44627c478bd9Sstevel@tonic-gate   ctx.pAgg = pMem->z;
44637c478bd9Sstevel@tonic-gate   ctx.cnt = ++pMem->i;
44647c478bd9Sstevel@tonic-gate   ctx.isError = 0;
44657c478bd9Sstevel@tonic-gate   ctx.isStep = 1;
44667c478bd9Sstevel@tonic-gate   (ctx.pFunc->xStep)(&ctx, n, (const char**)azArgv);
44677c478bd9Sstevel@tonic-gate   pMem->z = ctx.pAgg;
44687c478bd9Sstevel@tonic-gate   pMem->flags = MEM_AggCtx;
44697c478bd9Sstevel@tonic-gate   popStack(&pTos, n+1);
44707c478bd9Sstevel@tonic-gate   if( ctx.isError ){
44717c478bd9Sstevel@tonic-gate     rc = SQLITE_ERROR;
44727c478bd9Sstevel@tonic-gate   }
44737c478bd9Sstevel@tonic-gate   break;
44747c478bd9Sstevel@tonic-gate }
44757c478bd9Sstevel@tonic-gate 
44767c478bd9Sstevel@tonic-gate /* Opcode: AggFocus * P2 *
44777c478bd9Sstevel@tonic-gate **
44787c478bd9Sstevel@tonic-gate ** Pop the top of the stack and use that as an aggregator key.  If
44797c478bd9Sstevel@tonic-gate ** an aggregator with that same key already exists, then make the
44807c478bd9Sstevel@tonic-gate ** aggregator the current aggregator and jump to P2.  If no aggregator
44817c478bd9Sstevel@tonic-gate ** with the given key exists, create one and make it current but
44827c478bd9Sstevel@tonic-gate ** do not jump.
44837c478bd9Sstevel@tonic-gate **
44847c478bd9Sstevel@tonic-gate ** The order of aggregator opcodes is important.  The order is:
44857c478bd9Sstevel@tonic-gate ** AggReset AggFocus AggNext.  In other words, you must execute
44867c478bd9Sstevel@tonic-gate ** AggReset first, then zero or more AggFocus operations, then
44877c478bd9Sstevel@tonic-gate ** zero or more AggNext operations.  You must not execute an AggFocus
44887c478bd9Sstevel@tonic-gate ** in between an AggNext and an AggReset.
44897c478bd9Sstevel@tonic-gate */
44907c478bd9Sstevel@tonic-gate case OP_AggFocus: {
44917c478bd9Sstevel@tonic-gate   AggElem *pElem;
44927c478bd9Sstevel@tonic-gate   char *zKey;
44937c478bd9Sstevel@tonic-gate   int nKey;
44947c478bd9Sstevel@tonic-gate 
44957c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
44967c478bd9Sstevel@tonic-gate   Stringify(pTos);
44977c478bd9Sstevel@tonic-gate   zKey = pTos->z;
44987c478bd9Sstevel@tonic-gate   nKey = pTos->n;
44997c478bd9Sstevel@tonic-gate   pElem = sqliteHashFind(&p->agg.hash, zKey, nKey);
45007c478bd9Sstevel@tonic-gate   if( pElem ){
45017c478bd9Sstevel@tonic-gate     p->agg.pCurrent = pElem;
45027c478bd9Sstevel@tonic-gate     pc = pOp->p2 - 1;
45037c478bd9Sstevel@tonic-gate   }else{
45047c478bd9Sstevel@tonic-gate     AggInsert(&p->agg, zKey, nKey);
45057c478bd9Sstevel@tonic-gate     if( sqlite_malloc_failed ) goto no_mem;
45067c478bd9Sstevel@tonic-gate   }
45077c478bd9Sstevel@tonic-gate   Release(pTos);
45087c478bd9Sstevel@tonic-gate   pTos--;
4509*55fea89dSDan Cross   break;
45107c478bd9Sstevel@tonic-gate }
45117c478bd9Sstevel@tonic-gate 
45127c478bd9Sstevel@tonic-gate /* Opcode: AggSet * P2 *
45137c478bd9Sstevel@tonic-gate **
45147c478bd9Sstevel@tonic-gate ** Move the top of the stack into the P2-th field of the current
45157c478bd9Sstevel@tonic-gate ** aggregate.  String values are duplicated into new memory.
45167c478bd9Sstevel@tonic-gate */
45177c478bd9Sstevel@tonic-gate case OP_AggSet: {
45187c478bd9Sstevel@tonic-gate   AggElem *pFocus = AggInFocus(p->agg);
45197c478bd9Sstevel@tonic-gate   Mem *pMem;
45207c478bd9Sstevel@tonic-gate   int i = pOp->p2;
45217c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
45227c478bd9Sstevel@tonic-gate   if( pFocus==0 ) goto no_mem;
45237c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->agg.nMem );
45247c478bd9Sstevel@tonic-gate   Deephemeralize(pTos);
45257c478bd9Sstevel@tonic-gate   pMem = &pFocus->aMem[i];
45267c478bd9Sstevel@tonic-gate   Release(pMem);
45277c478bd9Sstevel@tonic-gate   *pMem = *pTos;
45287c478bd9Sstevel@tonic-gate   if( pMem->flags & MEM_Dyn ){
45297c478bd9Sstevel@tonic-gate     pTos->flags = MEM_Null;
45307c478bd9Sstevel@tonic-gate   }else if( pMem->flags & MEM_Short ){
45317c478bd9Sstevel@tonic-gate     pMem->z = pMem->zShort;
45327c478bd9Sstevel@tonic-gate   }
45337c478bd9Sstevel@tonic-gate   Release(pTos);
45347c478bd9Sstevel@tonic-gate   pTos--;
45357c478bd9Sstevel@tonic-gate   break;
45367c478bd9Sstevel@tonic-gate }
45377c478bd9Sstevel@tonic-gate 
45387c478bd9Sstevel@tonic-gate /* Opcode: AggGet * P2 *
45397c478bd9Sstevel@tonic-gate **
45407c478bd9Sstevel@tonic-gate ** Push a new entry onto the stack which is a copy of the P2-th field
45417c478bd9Sstevel@tonic-gate ** of the current aggregate.  Strings are not duplicated so
45427c478bd9Sstevel@tonic-gate ** string values will be ephemeral.
45437c478bd9Sstevel@tonic-gate */
45447c478bd9Sstevel@tonic-gate case OP_AggGet: {
45457c478bd9Sstevel@tonic-gate   AggElem *pFocus = AggInFocus(p->agg);
45467c478bd9Sstevel@tonic-gate   Mem *pMem;
45477c478bd9Sstevel@tonic-gate   int i = pOp->p2;
45487c478bd9Sstevel@tonic-gate   if( pFocus==0 ) goto no_mem;
45497c478bd9Sstevel@tonic-gate   assert( i>=0 && i<p->agg.nMem );
45507c478bd9Sstevel@tonic-gate   pTos++;
45517c478bd9Sstevel@tonic-gate   pMem = &pFocus->aMem[i];
45527c478bd9Sstevel@tonic-gate   *pTos = *pMem;
45537c478bd9Sstevel@tonic-gate   if( pTos->flags & MEM_Str ){
45547c478bd9Sstevel@tonic-gate     pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
45557c478bd9Sstevel@tonic-gate     pTos->flags |= MEM_Ephem;
45567c478bd9Sstevel@tonic-gate   }
45577c478bd9Sstevel@tonic-gate   break;
45587c478bd9Sstevel@tonic-gate }
45597c478bd9Sstevel@tonic-gate 
45607c478bd9Sstevel@tonic-gate /* Opcode: AggNext * P2 *
45617c478bd9Sstevel@tonic-gate **
45627c478bd9Sstevel@tonic-gate ** Make the next aggregate value the current aggregate.  The prior
45637c478bd9Sstevel@tonic-gate ** aggregate is deleted.  If all aggregate values have been consumed,
45647c478bd9Sstevel@tonic-gate ** jump to P2.
45657c478bd9Sstevel@tonic-gate **
45667c478bd9Sstevel@tonic-gate ** The order of aggregator opcodes is important.  The order is:
45677c478bd9Sstevel@tonic-gate ** AggReset AggFocus AggNext.  In other words, you must execute
45687c478bd9Sstevel@tonic-gate ** AggReset first, then zero or more AggFocus operations, then
45697c478bd9Sstevel@tonic-gate ** zero or more AggNext operations.  You must not execute an AggFocus
45707c478bd9Sstevel@tonic-gate ** in between an AggNext and an AggReset.
45717c478bd9Sstevel@tonic-gate */
45727c478bd9Sstevel@tonic-gate case OP_AggNext: {
45737c478bd9Sstevel@tonic-gate   CHECK_FOR_INTERRUPT;
45747c478bd9Sstevel@tonic-gate   if( p->agg.pSearch==0 ){
45757c478bd9Sstevel@tonic-gate     p->agg.pSearch = sqliteHashFirst(&p->agg.hash);
45767c478bd9Sstevel@tonic-gate   }else{
45777c478bd9Sstevel@tonic-gate     p->agg.pSearch = sqliteHashNext(p->agg.pSearch);
45787c478bd9Sstevel@tonic-gate   }
45797c478bd9Sstevel@tonic-gate   if( p->agg.pSearch==0 ){
45807c478bd9Sstevel@tonic-gate     pc = pOp->p2 - 1;
45817c478bd9Sstevel@tonic-gate   } else {
45827c478bd9Sstevel@tonic-gate     int i;
45837c478bd9Sstevel@tonic-gate     sqlite_func ctx;
45847c478bd9Sstevel@tonic-gate     Mem *aMem;
45857c478bd9Sstevel@tonic-gate     p->agg.pCurrent = sqliteHashData(p->agg.pSearch);
45867c478bd9Sstevel@tonic-gate     aMem = p->agg.pCurrent->aMem;
45877c478bd9Sstevel@tonic-gate     for(i=0; i<p->agg.nMem; i++){
45887c478bd9Sstevel@tonic-gate       int freeCtx;
45897c478bd9Sstevel@tonic-gate       if( p->agg.apFunc[i]==0 ) continue;
45907c478bd9Sstevel@tonic-gate       if( p->agg.apFunc[i]->xFinalize==0 ) continue;
45917c478bd9Sstevel@tonic-gate       ctx.s.flags = MEM_Null;
45927c478bd9Sstevel@tonic-gate       ctx.s.z = aMem[i].zShort;
45937c478bd9Sstevel@tonic-gate       ctx.pAgg = (void*)aMem[i].z;
45947c478bd9Sstevel@tonic-gate       freeCtx = aMem[i].z && aMem[i].z!=aMem[i].zShort;
45957c478bd9Sstevel@tonic-gate       ctx.cnt = aMem[i].i;
45967c478bd9Sstevel@tonic-gate       ctx.isStep = 0;
45977c478bd9Sstevel@tonic-gate       ctx.pFunc = p->agg.apFunc[i];
45987c478bd9Sstevel@tonic-gate       (*p->agg.apFunc[i]->xFinalize)(&ctx);
45997c478bd9Sstevel@tonic-gate       if( freeCtx ){
46007c478bd9Sstevel@tonic-gate         sqliteFree( aMem[i].z );
46017c478bd9Sstevel@tonic-gate       }
46027c478bd9Sstevel@tonic-gate       aMem[i] = ctx.s;
46037c478bd9Sstevel@tonic-gate       if( aMem[i].flags & MEM_Short ){
46047c478bd9Sstevel@tonic-gate         aMem[i].z = aMem[i].zShort;
46057c478bd9Sstevel@tonic-gate       }
46067c478bd9Sstevel@tonic-gate     }
46077c478bd9Sstevel@tonic-gate   }
46087c478bd9Sstevel@tonic-gate   break;
46097c478bd9Sstevel@tonic-gate }
46107c478bd9Sstevel@tonic-gate 
46117c478bd9Sstevel@tonic-gate /* Opcode: SetInsert P1 * P3
46127c478bd9Sstevel@tonic-gate **
46137c478bd9Sstevel@tonic-gate ** If Set P1 does not exist then create it.  Then insert value
46147c478bd9Sstevel@tonic-gate ** P3 into that set.  If P3 is NULL, then insert the top of the
46157c478bd9Sstevel@tonic-gate ** stack into the set.
46167c478bd9Sstevel@tonic-gate */
46177c478bd9Sstevel@tonic-gate case OP_SetInsert: {
46187c478bd9Sstevel@tonic-gate   int i = pOp->p1;
46197c478bd9Sstevel@tonic-gate   if( p->nSet<=i ){
46207c478bd9Sstevel@tonic-gate     int k;
46217c478bd9Sstevel@tonic-gate     Set *aSet = sqliteRealloc(p->aSet, (i+1)*sizeof(p->aSet[0]) );
46227c478bd9Sstevel@tonic-gate     if( aSet==0 ) goto no_mem;
46237c478bd9Sstevel@tonic-gate     p->aSet = aSet;
46247c478bd9Sstevel@tonic-gate     for(k=p->nSet; k<=i; k++){
46257c478bd9Sstevel@tonic-gate       sqliteHashInit(&p->aSet[k].hash, SQLITE_HASH_BINARY, 1);
46267c478bd9Sstevel@tonic-gate     }
46277c478bd9Sstevel@tonic-gate     p->nSet = i+1;
46287c478bd9Sstevel@tonic-gate   }
46297c478bd9Sstevel@tonic-gate   if( pOp->p3 ){
46307c478bd9Sstevel@tonic-gate     sqliteHashInsert(&p->aSet[i].hash, pOp->p3, strlen(pOp->p3)+1, p);
46317c478bd9Sstevel@tonic-gate   }else{
46327c478bd9Sstevel@tonic-gate     assert( pTos>=p->aStack );
46337c478bd9Sstevel@tonic-gate     Stringify(pTos);
46347c478bd9Sstevel@tonic-gate     sqliteHashInsert(&p->aSet[i].hash, pTos->z, pTos->n, p);
46357c478bd9Sstevel@tonic-gate     Release(pTos);
46367c478bd9Sstevel@tonic-gate     pTos--;
46377c478bd9Sstevel@tonic-gate   }
46387c478bd9Sstevel@tonic-gate   if( sqlite_malloc_failed ) goto no_mem;
46397c478bd9Sstevel@tonic-gate   break;
46407c478bd9Sstevel@tonic-gate }
46417c478bd9Sstevel@tonic-gate 
46427c478bd9Sstevel@tonic-gate /* Opcode: SetFound P1 P2 *
46437c478bd9Sstevel@tonic-gate **
46447c478bd9Sstevel@tonic-gate ** Pop the stack once and compare the value popped off with the
46457c478bd9Sstevel@tonic-gate ** contents of set P1.  If the element popped exists in set P1,
46467c478bd9Sstevel@tonic-gate ** then jump to P2.  Otherwise fall through.
46477c478bd9Sstevel@tonic-gate */
46487c478bd9Sstevel@tonic-gate case OP_SetFound: {
46497c478bd9Sstevel@tonic-gate   int i = pOp->p1;
46507c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
46517c478bd9Sstevel@tonic-gate   Stringify(pTos);
46527c478bd9Sstevel@tonic-gate   if( i>=0 && i<p->nSet && sqliteHashFind(&p->aSet[i].hash, pTos->z, pTos->n)){
46537c478bd9Sstevel@tonic-gate     pc = pOp->p2 - 1;
46547c478bd9Sstevel@tonic-gate   }
46557c478bd9Sstevel@tonic-gate   Release(pTos);
46567c478bd9Sstevel@tonic-gate   pTos--;
46577c478bd9Sstevel@tonic-gate   break;
46587c478bd9Sstevel@tonic-gate }
46597c478bd9Sstevel@tonic-gate 
46607c478bd9Sstevel@tonic-gate /* Opcode: SetNotFound P1 P2 *
46617c478bd9Sstevel@tonic-gate **
46627c478bd9Sstevel@tonic-gate ** Pop the stack once and compare the value popped off with the
4663*55fea89dSDan Cross ** contents of set P1.  If the element popped does not exists in
46647c478bd9Sstevel@tonic-gate ** set P1, then jump to P2.  Otherwise fall through.
46657c478bd9Sstevel@tonic-gate */
46667c478bd9Sstevel@tonic-gate case OP_SetNotFound: {
46677c478bd9Sstevel@tonic-gate   int i = pOp->p1;
46687c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
46697c478bd9Sstevel@tonic-gate   Stringify(pTos);
46707c478bd9Sstevel@tonic-gate   if( i<0 || i>=p->nSet ||
46717c478bd9Sstevel@tonic-gate        sqliteHashFind(&p->aSet[i].hash, pTos->z, pTos->n)==0 ){
46727c478bd9Sstevel@tonic-gate     pc = pOp->p2 - 1;
46737c478bd9Sstevel@tonic-gate   }
46747c478bd9Sstevel@tonic-gate   Release(pTos);
46757c478bd9Sstevel@tonic-gate   pTos--;
46767c478bd9Sstevel@tonic-gate   break;
46777c478bd9Sstevel@tonic-gate }
46787c478bd9Sstevel@tonic-gate 
46797c478bd9Sstevel@tonic-gate /* Opcode: SetFirst P1 P2 *
46807c478bd9Sstevel@tonic-gate **
46817c478bd9Sstevel@tonic-gate ** Read the first element from set P1 and push it onto the stack.  If the
46827c478bd9Sstevel@tonic-gate ** set is empty, push nothing and jump immediately to P2.  This opcode is
46837c478bd9Sstevel@tonic-gate ** used in combination with OP_SetNext to loop over all elements of a set.
46847c478bd9Sstevel@tonic-gate */
46857c478bd9Sstevel@tonic-gate /* Opcode: SetNext P1 P2 *
46867c478bd9Sstevel@tonic-gate **
46877c478bd9Sstevel@tonic-gate ** Read the next element from set P1 and push it onto the stack.  If there
46887c478bd9Sstevel@tonic-gate ** are no more elements in the set, do not do the push and fall through.
46897c478bd9Sstevel@tonic-gate ** Otherwise, jump to P2 after pushing the next set element.
46907c478bd9Sstevel@tonic-gate */
4691*55fea89dSDan Cross case OP_SetFirst:
46927c478bd9Sstevel@tonic-gate case OP_SetNext: {
46937c478bd9Sstevel@tonic-gate   Set *pSet;
46947c478bd9Sstevel@tonic-gate   CHECK_FOR_INTERRUPT;
46957c478bd9Sstevel@tonic-gate   if( pOp->p1<0 || pOp->p1>=p->nSet ){
46967c478bd9Sstevel@tonic-gate     if( pOp->opcode==OP_SetFirst ) pc = pOp->p2 - 1;
46977c478bd9Sstevel@tonic-gate     break;
46987c478bd9Sstevel@tonic-gate   }
46997c478bd9Sstevel@tonic-gate   pSet = &p->aSet[pOp->p1];
47007c478bd9Sstevel@tonic-gate   if( pOp->opcode==OP_SetFirst ){
47017c478bd9Sstevel@tonic-gate     pSet->prev = sqliteHashFirst(&pSet->hash);
47027c478bd9Sstevel@tonic-gate     if( pSet->prev==0 ){
47037c478bd9Sstevel@tonic-gate       pc = pOp->p2 - 1;
47047c478bd9Sstevel@tonic-gate       break;
47057c478bd9Sstevel@tonic-gate     }
47067c478bd9Sstevel@tonic-gate   }else{
47077c478bd9Sstevel@tonic-gate     if( pSet->prev ){
47087c478bd9Sstevel@tonic-gate       pSet->prev = sqliteHashNext(pSet->prev);
47097c478bd9Sstevel@tonic-gate     }
47107c478bd9Sstevel@tonic-gate     if( pSet->prev==0 ){
47117c478bd9Sstevel@tonic-gate       break;
47127c478bd9Sstevel@tonic-gate     }else{
47137c478bd9Sstevel@tonic-gate       pc = pOp->p2 - 1;
47147c478bd9Sstevel@tonic-gate     }
47157c478bd9Sstevel@tonic-gate   }
47167c478bd9Sstevel@tonic-gate   pTos++;
47177c478bd9Sstevel@tonic-gate   pTos->z = sqliteHashKey(pSet->prev);
47187c478bd9Sstevel@tonic-gate   pTos->n = sqliteHashKeysize(pSet->prev);
47197c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Str | MEM_Ephem;
47207c478bd9Sstevel@tonic-gate   break;
47217c478bd9Sstevel@tonic-gate }
47227c478bd9Sstevel@tonic-gate 
47237c478bd9Sstevel@tonic-gate /* Opcode: Vacuum * * *
47247c478bd9Sstevel@tonic-gate **
47257c478bd9Sstevel@tonic-gate ** Vacuum the entire database.  This opcode will cause other virtual
47267c478bd9Sstevel@tonic-gate ** machines to be created and run.  It may not be called from within
47277c478bd9Sstevel@tonic-gate ** a transaction.
47287c478bd9Sstevel@tonic-gate */
47297c478bd9Sstevel@tonic-gate case OP_Vacuum: {
4730*55fea89dSDan Cross   if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
47317c478bd9Sstevel@tonic-gate   rc = sqliteRunVacuum(&p->zErrMsg, db);
47327c478bd9Sstevel@tonic-gate   if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
47337c478bd9Sstevel@tonic-gate   break;
47347c478bd9Sstevel@tonic-gate }
47357c478bd9Sstevel@tonic-gate 
47367c478bd9Sstevel@tonic-gate /* Opcode: StackDepth * * *
47377c478bd9Sstevel@tonic-gate **
47387c478bd9Sstevel@tonic-gate ** Push an integer onto the stack which is the depth of the stack prior
47397c478bd9Sstevel@tonic-gate ** to that integer being pushed.
47407c478bd9Sstevel@tonic-gate */
47417c478bd9Sstevel@tonic-gate case OP_StackDepth: {
47427c478bd9Sstevel@tonic-gate   int depth = (&pTos[1]) - p->aStack;
47437c478bd9Sstevel@tonic-gate   pTos++;
47447c478bd9Sstevel@tonic-gate   pTos->i = depth;
47457c478bd9Sstevel@tonic-gate   pTos->flags = MEM_Int;
47467c478bd9Sstevel@tonic-gate   break;
47477c478bd9Sstevel@tonic-gate }
47487c478bd9Sstevel@tonic-gate 
47497c478bd9Sstevel@tonic-gate /* Opcode: StackReset * * *
47507c478bd9Sstevel@tonic-gate **
47517c478bd9Sstevel@tonic-gate ** Pop a single integer off of the stack.  Then pop the stack
47527c478bd9Sstevel@tonic-gate ** as many times as necessary to get the depth of the stack down
47537c478bd9Sstevel@tonic-gate ** to the value of the integer that was popped.
47547c478bd9Sstevel@tonic-gate */
47557c478bd9Sstevel@tonic-gate case OP_StackReset: {
47567c478bd9Sstevel@tonic-gate   int depth, goal;
47577c478bd9Sstevel@tonic-gate   assert( pTos>=p->aStack );
47587c478bd9Sstevel@tonic-gate   Integerify(pTos);
47597c478bd9Sstevel@tonic-gate   goal = pTos->i;
47607c478bd9Sstevel@tonic-gate   depth = (&pTos[1]) - p->aStack;
47617c478bd9Sstevel@tonic-gate   assert( goal<depth );
47627c478bd9Sstevel@tonic-gate   popStack(&pTos, depth-goal);
47637c478bd9Sstevel@tonic-gate   break;
47647c478bd9Sstevel@tonic-gate }
47657c478bd9Sstevel@tonic-gate 
47667c478bd9Sstevel@tonic-gate /* An other opcode is illegal...
47677c478bd9Sstevel@tonic-gate */
47687c478bd9Sstevel@tonic-gate default: {
47697c478bd9Sstevel@tonic-gate   sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode);
47707c478bd9Sstevel@tonic-gate   sqliteSetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0);
47717c478bd9Sstevel@tonic-gate   rc = SQLITE_INTERNAL;
47727c478bd9Sstevel@tonic-gate   break;
47737c478bd9Sstevel@tonic-gate }
47747c478bd9Sstevel@tonic-gate 
47757c478bd9Sstevel@tonic-gate /*****************************************************************************
47767c478bd9Sstevel@tonic-gate ** The cases of the switch statement above this line should all be indented
47777c478bd9Sstevel@tonic-gate ** by 6 spaces.  But the left-most 6 spaces have been removed to improve the
47787c478bd9Sstevel@tonic-gate ** readability.  From this point on down, the normal indentation rules are
47797c478bd9Sstevel@tonic-gate ** restored.
47807c478bd9Sstevel@tonic-gate *****************************************************************************/
47817c478bd9Sstevel@tonic-gate     }
47827c478bd9Sstevel@tonic-gate 
47837c478bd9Sstevel@tonic-gate #ifdef VDBE_PROFILE
47847c478bd9Sstevel@tonic-gate     {
47857c478bd9Sstevel@tonic-gate       long long elapse = hwtime() - start;
47867c478bd9Sstevel@tonic-gate       pOp->cycles += elapse;
47877c478bd9Sstevel@tonic-gate       pOp->cnt++;
47887c478bd9Sstevel@tonic-gate #if 0
47897c478bd9Sstevel@tonic-gate         fprintf(stdout, "%10lld ", elapse);
47907c478bd9Sstevel@tonic-gate         sqliteVdbePrintOp(stdout, origPc, &p->aOp[origPc]);
47917c478bd9Sstevel@tonic-gate #endif
47927c478bd9Sstevel@tonic-gate     }
47937c478bd9Sstevel@tonic-gate #endif
47947c478bd9Sstevel@tonic-gate 
47957c478bd9Sstevel@tonic-gate     /* The following code adds nothing to the actual functionality
47967c478bd9Sstevel@tonic-gate     ** of the program.  It is only here for testing and debugging.
47977c478bd9Sstevel@tonic-gate     ** On the other hand, it does burn CPU cycles every time through
47987c478bd9Sstevel@tonic-gate     ** the evaluator loop.  So we can leave it out when NDEBUG is defined.
47997c478bd9Sstevel@tonic-gate     */
48007c478bd9Sstevel@tonic-gate #ifndef NDEBUG
48017c478bd9Sstevel@tonic-gate     /* Sanity checking on the top element of the stack */
48027c478bd9Sstevel@tonic-gate     if( pTos>=p->aStack ){
48037c478bd9Sstevel@tonic-gate       assert( pTos->flags!=0 );  /* Must define some type */
48047c478bd9Sstevel@tonic-gate       if( pTos->flags & MEM_Str ){
48057c478bd9Sstevel@tonic-gate         int x = pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
48067c478bd9Sstevel@tonic-gate         assert( x!=0 );            /* Strings must define a string subtype */
48077c478bd9Sstevel@tonic-gate         assert( (x & (x-1))==0 );  /* Only one string subtype can be defined */
48087c478bd9Sstevel@tonic-gate         assert( pTos->z!=0 );      /* Strings must have a value */
48097c478bd9Sstevel@tonic-gate         /* Mem.z points to Mem.zShort iff the subtype is MEM_Short */
48107c478bd9Sstevel@tonic-gate         assert( (pTos->flags & MEM_Short)==0 || pTos->z==pTos->zShort );
48117c478bd9Sstevel@tonic-gate         assert( (pTos->flags & MEM_Short)!=0 || pTos->z!=pTos->zShort );
48127c478bd9Sstevel@tonic-gate       }else{
48137c478bd9Sstevel@tonic-gate         /* Cannot define a string subtype for non-string objects */
48147c478bd9Sstevel@tonic-gate         assert( (pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );
48157c478bd9Sstevel@tonic-gate       }
48167c478bd9Sstevel@tonic-gate       /* MEM_Null excludes all other types */
48177c478bd9Sstevel@tonic-gate       assert( pTos->flags==MEM_Null || (pTos->flags&MEM_Null)==0 );
48187c478bd9Sstevel@tonic-gate     }
48197c478bd9Sstevel@tonic-gate     if( pc<-1 || pc>=p->nOp ){
48207c478bd9Sstevel@tonic-gate       sqliteSetString(&p->zErrMsg, "jump destination out of range", (char*)0);
48217c478bd9Sstevel@tonic-gate       rc = SQLITE_INTERNAL;
48227c478bd9Sstevel@tonic-gate     }
48237c478bd9Sstevel@tonic-gate     if( p->trace && pTos>=p->aStack ){
48247c478bd9Sstevel@tonic-gate       int i;
48257c478bd9Sstevel@tonic-gate       fprintf(p->trace, "Stack:");
48267c478bd9Sstevel@tonic-gate       for(i=0; i>-5 && &pTos[i]>=p->aStack; i--){
48277c478bd9Sstevel@tonic-gate         if( pTos[i].flags & MEM_Null ){
48287c478bd9Sstevel@tonic-gate           fprintf(p->trace, " NULL");
48297c478bd9Sstevel@tonic-gate         }else if( (pTos[i].flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
48307c478bd9Sstevel@tonic-gate           fprintf(p->trace, " si:%d", pTos[i].i);
48317c478bd9Sstevel@tonic-gate         }else if( pTos[i].flags & MEM_Int ){
48327c478bd9Sstevel@tonic-gate           fprintf(p->trace, " i:%d", pTos[i].i);
48337c478bd9Sstevel@tonic-gate         }else if( pTos[i].flags & MEM_Real ){
48347c478bd9Sstevel@tonic-gate           fprintf(p->trace, " r:%g", pTos[i].r);
48357c478bd9Sstevel@tonic-gate         }else if( pTos[i].flags & MEM_Str ){
48367c478bd9Sstevel@tonic-gate           int j, k;
48377c478bd9Sstevel@tonic-gate           char zBuf[100];
48387c478bd9Sstevel@tonic-gate           zBuf[0] = ' ';
48397c478bd9Sstevel@tonic-gate           if( pTos[i].flags & MEM_Dyn ){
48407c478bd9Sstevel@tonic-gate             zBuf[1] = 'z';
48417c478bd9Sstevel@tonic-gate             assert( (pTos[i].flags & (MEM_Static|MEM_Ephem))==0 );
48427c478bd9Sstevel@tonic-gate           }else if( pTos[i].flags & MEM_Static ){
48437c478bd9Sstevel@tonic-gate             zBuf[1] = 't';
48447c478bd9Sstevel@tonic-gate             assert( (pTos[i].flags & (MEM_Dyn|MEM_Ephem))==0 );
48457c478bd9Sstevel@tonic-gate           }else if( pTos[i].flags & MEM_Ephem ){
48467c478bd9Sstevel@tonic-gate             zBuf[1] = 'e';
48477c478bd9Sstevel@tonic-gate             assert( (pTos[i].flags & (MEM_Static|MEM_Dyn))==0 );
48487c478bd9Sstevel@tonic-gate           }else{
48497c478bd9Sstevel@tonic-gate             zBuf[1] = 's';
48507c478bd9Sstevel@tonic-gate           }
48517c478bd9Sstevel@tonic-gate           zBuf[2] = '[';
48527c478bd9Sstevel@tonic-gate           k = 3;
48537c478bd9Sstevel@tonic-gate           for(j=0; j<20 && j<pTos[i].n; j++){
48547c478bd9Sstevel@tonic-gate             int c = pTos[i].z[j];
48557c478bd9Sstevel@tonic-gate             if( c==0 && j==pTos[i].n-1 ) break;
48567c478bd9Sstevel@tonic-gate             if( isprint(c) && !isspace(c) ){
48577c478bd9Sstevel@tonic-gate               zBuf[k++] = c;
48587c478bd9Sstevel@tonic-gate             }else{
48597c478bd9Sstevel@tonic-gate               zBuf[k++] = '.';
48607c478bd9Sstevel@tonic-gate             }
48617c478bd9Sstevel@tonic-gate           }
48627c478bd9Sstevel@tonic-gate           zBuf[k++] = ']';
48637c478bd9Sstevel@tonic-gate           zBuf[k++] = 0;
48647c478bd9Sstevel@tonic-gate           fprintf(p->trace, "%s", zBuf);
48657c478bd9Sstevel@tonic-gate         }else{
48667c478bd9Sstevel@tonic-gate           fprintf(p->trace, " ???");
48677c478bd9Sstevel@tonic-gate         }
48687c478bd9Sstevel@tonic-gate       }
48697c478bd9Sstevel@tonic-gate       if( rc!=0 ) fprintf(p->trace," rc=%d",rc);
48707c478bd9Sstevel@tonic-gate       fprintf(p->trace,"\n");
48717c478bd9Sstevel@tonic-gate     }
48727c478bd9Sstevel@tonic-gate #endif
48737c478bd9Sstevel@tonic-gate   }  /* The end of the for(;;) loop the loops through opcodes */
48747c478bd9Sstevel@tonic-gate 
48757c478bd9Sstevel@tonic-gate   /* If we reach this point, it means that execution is finished.
48767c478bd9Sstevel@tonic-gate   */
48777c478bd9Sstevel@tonic-gate vdbe_halt:
48787c478bd9Sstevel@tonic-gate   CHECK_FOR_INTERRUPT
48797c478bd9Sstevel@tonic-gate   if( rc ){
48807c478bd9Sstevel@tonic-gate     p->rc = rc;
48817c478bd9Sstevel@tonic-gate     rc = SQLITE_ERROR;
48827c478bd9Sstevel@tonic-gate   }else{
48837c478bd9Sstevel@tonic-gate     rc = SQLITE_DONE;
48847c478bd9Sstevel@tonic-gate   }
48857c478bd9Sstevel@tonic-gate   p->magic = VDBE_MAGIC_HALT;
48867c478bd9Sstevel@tonic-gate   p->pTos = pTos;
48877c478bd9Sstevel@tonic-gate   return rc;
48887c478bd9Sstevel@tonic-gate 
48897c478bd9Sstevel@tonic-gate   /* Jump to here if a malloc() fails.  It's hard to get a malloc()
48907c478bd9Sstevel@tonic-gate   ** to fail on a modern VM computer, so this code is untested.
48917c478bd9Sstevel@tonic-gate   */
48927c478bd9Sstevel@tonic-gate no_mem:
48937c478bd9Sstevel@tonic-gate   sqliteSetString(&p->zErrMsg, "out of memory", (char*)0);
48947c478bd9Sstevel@tonic-gate   rc = SQLITE_NOMEM;
48957c478bd9Sstevel@tonic-gate   goto vdbe_halt;
48967c478bd9Sstevel@tonic-gate 
48977c478bd9Sstevel@tonic-gate   /* Jump to here for an SQLITE_MISUSE error.
48987c478bd9Sstevel@tonic-gate   */
48997c478bd9Sstevel@tonic-gate abort_due_to_misuse:
49007c478bd9Sstevel@tonic-gate   rc = SQLITE_MISUSE;
49017c478bd9Sstevel@tonic-gate   /* Fall thru into abort_due_to_error */
49027c478bd9Sstevel@tonic-gate 
49037c478bd9Sstevel@tonic-gate   /* Jump to here for any other kind of fatal error.  The "rc" variable
49047c478bd9Sstevel@tonic-gate   ** should hold the error number.
49057c478bd9Sstevel@tonic-gate   */
49067c478bd9Sstevel@tonic-gate abort_due_to_error:
49077c478bd9Sstevel@tonic-gate   if( p->zErrMsg==0 ){
49087c478bd9Sstevel@tonic-gate     if( sqlite_malloc_failed ) rc = SQLITE_NOMEM;
49097c478bd9Sstevel@tonic-gate     sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
49107c478bd9Sstevel@tonic-gate   }
49117c478bd9Sstevel@tonic-gate   goto vdbe_halt;
49127c478bd9Sstevel@tonic-gate 
49137c478bd9Sstevel@tonic-gate   /* Jump to here if the sqlite_interrupt() API sets the interrupt
49147c478bd9Sstevel@tonic-gate   ** flag.
49157c478bd9Sstevel@tonic-gate   */
49167c478bd9Sstevel@tonic-gate abort_due_to_interrupt:
49177c478bd9Sstevel@tonic-gate   assert( db->flags & SQLITE_Interrupt );
49187c478bd9Sstevel@tonic-gate   db->flags &= ~SQLITE_Interrupt;
49197c478bd9Sstevel@tonic-gate   if( db->magic!=SQLITE_MAGIC_BUSY ){
49207c478bd9Sstevel@tonic-gate     rc = SQLITE_MISUSE;
49217c478bd9Sstevel@tonic-gate   }else{
49227c478bd9Sstevel@tonic-gate     rc = SQLITE_INTERRUPT;
49237c478bd9Sstevel@tonic-gate   }
49247c478bd9Sstevel@tonic-gate   sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
49257c478bd9Sstevel@tonic-gate   goto vdbe_halt;
49267c478bd9Sstevel@tonic-gate }
4927