-C Modify\sthe\sbuild\sprocess\sso\sthat\sthe\sVDBE\sopcode\snumbers\sand\sthe\stable\nthat\scontains\sthe\sopcode\snames\sare\sboth\sautomatically\sgenerated.\sThis\smakes\nit\smuch\seasier\sto\screate\snew\sVDBE\sopcodes.\s(CVS\s1727)
-D 2002-09-08T00:04:54
+C Fix\sfor\sticket\s#147:\sHonor\sthe\sORDER\sBY\sand\sLIMIT\sclauses\sin\sa\sSELECT\seven\nif\sthe\sdestination\sof\sthat\sSELECT\sis\sa\ssubroutine\scall.\s(CVS\s747)
+D 2002-09-08T17:23:42
F Makefile.in d6c9a85c2a5e696843201d090dcf8bf2f8716f2a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
F libtool c56e618713c9510a103bda6b95f3ea3900dcacd6
F ltmain.sh e9ed72eb1d690f447c13945eaf69e28af531eda1
-F main.mk e9c6f552f230b8befc25346c515c494fecd2e823
+F main.mk d7a9dfc003ab1eeb4fdb46dfcee8af0ab0e38a99
F publish.sh a7a8d23e6525bd25d4f5ba9b0fc6edc107d94050
F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
F src/parse.y 818b03a73f6b3b8b284b515c5b1d9998d4663dc3
F src/printf.c 5c50fc1da75c8f5bf432b1ad17d91d6653acd167
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
-F src/select.c 6cd3673edbb36a8f8027341093085e01c04dd3d4
+F src/select.c 74a025cd6887b636fc06a79ff6246c4eb6826ec4
F src/shell.c 9e9a6eb6bca07f01e6472a603f908a0127ea50ff
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in d3999a9c6374675779058d6cfe5431131618e92b
F src/trigger.c c90a292a4bef25e478fd5deda6d300319be6a023
F src/update.c f07e6ed2c517c92871e54d3f5886d1cf56121b11
F src/util.c c70d5da5357e01b58392faebae3c3620c1d71f14
-F src/vdbe.c 8637ddb9072df676f50dce3f7894cdaec714fe4a
+F src/vdbe.c 7e7392f2a92187ba1d2351fed0524c2dd607cffb
F src/vdbe.h b7584044223104ba7896a7f87b66daebdd6022ba
F src/where.c 53959c9d94adaf93b409271815e26eafa6ddd515
F test/all.test efd958d048c70a3247997c482f0b33561f7759f0
F test/intpkey.test f3620158fd7963af1306b01047277f10ae91a30b
F test/ioerr.test 57d9bffaca18b34f9e976f786eadc2591d6efc6a
F test/join.test 90a620f2a2d015e5139d5a4cde0eeb4cf62523bf
-F test/limit.test dd932f7572fe78e82ef621ef62f0cc480c7e541e
+F test/limit.test 9f26f874bc765df5b3f5c92d26d1b12eac6d4cf9
F test/lock.test 5079615ba0ef0899c4cbade42ffec291620a2819
F test/main.test c66b564554b770ee7fdbf6a66c0cd90329bc2c85
F test/malloc.test 7ba32a9ebd3aeed52ae4aaa6d42ca37e444536fd
F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P eb54d455b0325d3be96daf6c220c4ee3e0da1a85
-R ec4eceb930ae5f7d03668e5150997da1
+P c4f0bb02387a6e6f254320e1e5eef3d5d8a3c538
+R d53bc433eee4d832716a49a9ea35550f
U drh
-Z ef4086cb3b45d72139e3d7498833a607
+Z fdf23733e2dbe5e105dfffa0429ea82b
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
-** $Id: vdbe.c,v 1.176 2002/09/08 00:04:52 drh Exp $
+** Various scripts scan this source file in order to generate HTML
+** documentation, headers files, or other derived files. The formatting
+** of the code in this file is, therefore, important. See other comments
+** in this file for details. If in doubt, do not deviate from existing
+** commenting and indentation practices when changing or adding code.
+**
+** $Id: vdbe.c,v 1.177 2002/09/08 17:23:43 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
** The following global variable is incremented every time a cursor
** moves, either by the OP_MoveTo or the OP_Next opcode. The test
** procedures use this information to make sure that indices are
-** working correctly.
+** working correctly. This variable has no function other than to
+** help verify the correct operation of the library.
*/
int sqlite_search_count = 0;
};
/*
-** When debugging the code generator in a symbolic debugger, on can
+** When debugging the code generator in a symbolic debugger, one can
** set the sqlite_vdbe_addop_trace to 1 and all opcodes will be printed
** as they are added to the instruction stream.
*/
/*
** Resolve label "x" to be the address of the next instruction to
-** be inserted.
+** be inserted. The parameter "x" must have been obtained from
+** a prior call to sqliteVdbeMakeLabel().
*/
void sqliteVdbeResolveLabel(Vdbe *p, int x){
int j;
** The sqlite_set_result_string() routine can be used to return a string
** value or to return a NULL. To return a NULL, pass in NULL for zResult.
** A copy is made of the string before this routine returns so it is safe
-** to pass in a ephemeral string.
+** to pass in an ephemeral string.
**
** sqlite_set_result_error() works like sqlite_set_result_string() except
** that it signals a fatal error. The string argument, if any, is the
** value of the user function to an integer or a double.
**
** These routines are defined here in vdbe.c because they depend on knowing
-** the internals of the sqlite_func structure which is only defined in that
-** one source file.
+** the internals of the sqlite_func structure which is only defined in
+** this source file.
*/
char *sqlite_set_result_string(sqlite_func *p, const char *zResult, int n){
assert( !p->isStep );
** pointer to it.
**
** This routine is defined here in vdbe.c because it depends on knowing
-** the internals of the sqlite_func structure which is only defined in that
-** one source file.
+** the internals of the sqlite_func structure which is only defined in
+** this source file.
*/
void *sqlite_user_data(sqlite_func *p){
assert( p && p->pFunc );
** same context that was returned on prior calls.
**
** This routine is defined here in vdbe.c because it depends on knowing
-** the internals of the sqlite_func structure which is only defined in that
-** one source file.
+** the internals of the sqlite_func structure which is only defined in
+** this source file.
*/
void *sqlite_aggregate_context(sqlite_func *p, int nByte){
assert( p && p->pFunc && p->pFunc->xStep );
** called.
**
** This routine is defined here in vdbe.c because it depends on knowing
-** the internals of the sqlite_func structure which is only defined in that
-** one source file.
+** the internals of the sqlite_func structure which is only defined in
+** this source file.
*/
int sqlite_aggregate_count(sqlite_func *p){
assert( p && p->pFunc && p->pFunc->xStep );
}
/*
-** Insert a new element and make it the current element.
+** Insert a new aggregate element and make it the element that
+** has focus.
**
** Return 0 on success and 1 if memory is exhausted.
*/
** the switch statement will break with convention and be flush-left. Another
** big comment (similar to this one) will mark the point in the code where
** we transition back to normal indentation.
+**
+** The formatting of each case is important. The makefile for SQLite
+** generates two C files "opcodes.h" and "opcodes.c" by scanning this
+** file looking for lines that begin with "case OP_". The opcodes.h files
+** will be filled with #defines that give unique integer values to each
+** opcode and the opcodes.c file is filled with an array of strings where
+** each string is the symbolic name for the corresponding opcode.
+**
+** Documentation about VDBE opcodes is generated by scanning this file
+** for lines of that contain "Opcode:". That line and all subsequent
+** comment lines are used in the generation of the opcode.html documentation
+** file.
+**
+** SUMMARY:
+**
+** Formatting is important to scripts that scan this file.
+** Do not deviate from the formatting style currently in use.
+**
*****************************************************************************/
/* Opcode: Goto * P2 *
**
** Overwrite the value of the P1-th element down on the
** stack (P1==0 is the top of the stack) with the value
-** of the top of the stack. The pop the top of the stack.
+** of the top of the stack. Then pop the top of the stack.
*/
case OP_Push: {
int from = p->tos;
** If the KeyAsData opcode has previously executed on this cursor,
** then the field might be extracted from the key rather than the
** data.
+**
+** If P1 is negative, then the record is stored on the stack rather
+** than in a table. For P1==-1, the top of the stack is used.
+** For P1==-2, the next on the stack is used. And so forth. The
+** value pushed is always just a pointer into the record which is
+** stored further down on the stack. The column value is not copied.
*/
case OP_Column: {
int amt, offset, end, payloadSize;
int p2 = pOp->p2;
int tos = p->tos+1;
Cursor *pC;
+ char *zRec;
BtCursor *pCrsr;
int idxWidth;
unsigned char aHdr[10];
- int (*xRead)(BtCursor*, int, int, char*);
VERIFY( if( NeedStack(p, tos+1) ) goto no_mem; )
- if( VERIFY( i>=0 && i<p->nCursor && ) (pC = &p->aCsr[i])->pCursor!=0 ){
-
- /* Use different access functions depending on whether the information
- ** is coming from the key or the data of the record.
- */
+ if( i<0 ){
+ VERIFY( if( tos+i<0 ) goto bad_instruction; )
+ VERIFY( if( (aStack[tos+i].flags & STK_Str)==0 ) goto bad_instruction; )
+ zRec = zStack[tos+i];
+ payloadSize = aStack[tos+i].n;
+ }else if( VERIFY( i>=0 && i<p->nCursor && ) (pC = &p->aCsr[i])->pCursor!=0 ){
+ zRec = 0;
pCrsr = pC->pCursor;
if( pC->nullRow ){
payloadSize = 0;
}else if( pC->keyAsData ){
sqliteBtreeKeySize(pCrsr, &payloadSize);
- xRead = sqliteBtreeKey;
}else{
sqliteBtreeDataSize(pCrsr, &payloadSize);
- xRead = sqliteBtreeData;
}
+ }else{
+ payloadSize = 0;
+ }
- /* Figure out how many bytes in the column data and where the column
- ** data begins.
- */
- if( payloadSize==0 ){
- aStack[tos].flags = STK_Null;
- p->tos = tos;
- break;
- }else if( payloadSize<256 ){
- idxWidth = 1;
- }else if( payloadSize<65536 ){
- idxWidth = 2;
- }else{
- idxWidth = 3;
- }
+ /* Figure out how many bytes in the column data and where the column
+ ** data begins.
+ */
+ if( payloadSize==0 ){
+ aStack[tos].flags = STK_Null;
+ p->tos = tos;
+ break;
+ }else if( payloadSize<256 ){
+ idxWidth = 1;
+ }else if( payloadSize<65536 ){
+ idxWidth = 2;
+ }else{
+ idxWidth = 3;
+ }
- /* Figure out where the requested column is stored and how big it is.
- */
- if( payloadSize < idxWidth*(p2+1) ){
- rc = SQLITE_CORRUPT;
- goto abort_due_to_error;
- }
- (*xRead)(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
- offset = aHdr[0];
- end = aHdr[idxWidth];
- if( idxWidth>1 ){
- offset |= aHdr[1]<<8;
- end |= aHdr[idxWidth+1]<<8;
- if( idxWidth>2 ){
- offset |= aHdr[2]<<16;
- end |= aHdr[idxWidth+2]<<16;
- }
- }
- amt = end - offset;
- if( amt<0 || offset<0 || end>payloadSize ){
- rc = SQLITE_CORRUPT;
- goto abort_due_to_error;
+ /* Figure out where the requested column is stored and how big it is.
+ */
+ if( payloadSize < idxWidth*(p2+1) ){
+ rc = SQLITE_CORRUPT;
+ goto abort_due_to_error;
+ }
+ if( zRec ){
+ memcpy(aHdr, &zRec[idxWidth*p2], idxWidth*2);
+ }else if( pC->keyAsData ){
+ sqliteBtreeKey(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
+ }else{
+ sqliteBtreeData(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
+ }
+ offset = aHdr[0];
+ end = aHdr[idxWidth];
+ if( idxWidth>1 ){
+ offset |= aHdr[1]<<8;
+ end |= aHdr[idxWidth+1]<<8;
+ if( idxWidth>2 ){
+ offset |= aHdr[2]<<16;
+ end |= aHdr[idxWidth+2]<<16;
}
+ }
+ amt = end - offset;
+ if( amt<0 || offset<0 || end>payloadSize ){
+ rc = SQLITE_CORRUPT;
+ goto abort_due_to_error;
+ }
- /* amt and offset now hold the offset to the start of data and the
- ** amount of data. Go get the data and put it on the stack.
- */
- if( amt==0 ){
- aStack[tos].flags = STK_Null;
- }else if( amt<=NBFS ){
- (*xRead)(pCrsr, offset, amt, aStack[tos].z);
+ /* amt and offset now hold the offset to the start of data and the
+ ** amount of data. Go get the data and put it on the stack.
+ */
+ if( amt==0 ){
+ aStack[tos].flags = STK_Null;
+ }else if( zRec ){
+ aStack[tos].flags = STK_Str | STK_Static;
+ aStack[tos].n = amt;
+ zStack[tos] = &zRec[offset];
+ }else{
+ if( amt<=NBFS ){
aStack[tos].flags = STK_Str;
zStack[tos] = aStack[tos].z;
aStack[tos].n = amt;
}else{
char *z = sqliteMalloc( amt );
if( z==0 ) goto no_mem;
- (*xRead)(pCrsr, offset, amt, z);
aStack[tos].flags = STK_Str | STK_Dyn;
zStack[tos] = z;
aStack[tos].n = amt;
}
- p->tos = tos;
+ if( pC->keyAsData ){
+ sqliteBtreeKey(pCrsr, offset, amt, zStack[tos]);
+ }else{
+ sqliteBtreeData(pCrsr, offset, amt, zStack[tos]);
+ }
}
+ p->tos = tos;
break;
}
-/* Opcode: Extract * * *
-*/
-
/* Opcode: Recno P1 * *
**
** Push onto the stack an integer which is the first 4 bytes of the