From 653bc75992464d02c8f6ec8ff96024265673cb5a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 28 Feb 2002 03:31:10 +0000 Subject: [PATCH] Remove unused opcodes from the VDBE and fix a bug in the substr() function. (CVS 405) FossilOrigin-Name: e8611e0c052ddac477f83df485fa5dc882593de0 --- manifest | 16 +-- manifest.uuid | 2 +- src/func.c | 7 +- src/vdbe.c | 283 +++----------------------------------------------- src/vdbe.h | 122 +++++++++++----------- 5 files changed, 86 insertions(+), 344 deletions(-) diff --git a/manifest b/manifest index d884fbe682..92cd1fe904 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sIFNULL\sand\sNVL\sfunctions\sto\sCOALESCE.\s\sChange\sMIN\sand\sMAX\sso\sthat\nthey\srequire\sat\sleast\sone\sargument.\s(CVS\s404) -D 2002-02-28T03:14:18 +C Remove\sunused\sopcodes\sfrom\sthe\sVDBE\sand\sfix\sa\sbug\sin\sthe\ssubstr()\sfunction.\s(CVS\s405) +D 2002-02-28T03:31:11 F Makefile.in 50f1b3351df109b5774771350d8c1b8d3640130d F Makefile.template 89e373b2dad0321df00400fa968dc14b61a03296 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0 @@ -24,7 +24,7 @@ F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3 F src/build.c 7ada2426caba70cb1072ba268bedb694b5018065 F src/delete.c 950d8f9097361419f1963875f9943344b469cf02 F src/expr.c b70bedaffd27ea24c5c2a197a88b07e82dfa4967 -F src/func.c 7169103d1082c24f0e8a71c66e7ac4062f6acc15 +F src/func.c 089b68c021b82d8f3d0f489143d200ddf1eced39 F src/hash.c cc259475e358baaf299b00a2c7370f2b03dda892 F src/hash.h dca065dda89d4575f3176e75e9a3dc0f4b4fb8b9 F src/insert.c 164d2d5e943268a8ff0594e1947599e04df0ce11 @@ -51,8 +51,8 @@ F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f F src/tokenize.c 4b5d30590a744b9bb5605a92d1f620ab2e7e75af F src/update.c 18971d265b0341574b7e3f73116e7947ddab0997 F src/util.c 1c01f0a54a77ae9fb638d026d18093ee1b61e3b3 -F src/vdbe.c 26a2b62f1d5d0806bd301413327efc85944ae40c -F src/vdbe.h 8ab845e63e196e8eb5e51ce69f43b233e51db07e +F src/vdbe.c 91311e99efe980459a78e8f5b9e5456d772c9e23 +F src/vdbe.h f9be1f6e9a336c3ff4d14ea7489ee976e07460cc F src/where.c 664be01b0ce9ffaecbde609afbd4d8d3e5ed1585 F test/all.test 7a8a8a7a579ed2bb4d8976d55402f21eacd58049 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 @@ -127,7 +127,7 @@ F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279 F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P b00cf110b1cc671b7200a5ce8b9e704f660763c9 -R 700a29215d4083019c40f619d0c95fb2 +P 7d86749d4a78d05930bae2b6491d9428f06fe836 +R f548275963c89789d73119d8b7f277e5 U drh -Z b9fbc42617ff7af7970f2ca4a8912d6a +Z 85324ea3b3c81399d9a571ab6786b2dc diff --git a/manifest.uuid b/manifest.uuid index f5de16f054..8f91e754d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d86749d4a78d05930bae2b6491d9428f06fe836 \ No newline at end of file +e8611e0c052ddac477f83df485fa5dc882593de0 \ No newline at end of file diff --git a/src/func.c b/src/func.c index d87c6f16cc..007a3db95a 100644 --- a/src/func.c +++ b/src/func.c @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.10 2002/02/28 03:14:18 drh Exp $ +** $Id: func.c,v 1.11 2002/02/28 03:31:11 drh Exp $ */ #include #include @@ -108,6 +108,10 @@ static void substrFunc(sqlite_func *context, int argc, const char **argv){ #endif if( p1<0 ){ p1 += len; + if( p1<0 ){ + p2 += p1; + p1 = 0; + } }else if( p1>0 ){ p1--; } @@ -124,6 +128,7 @@ static void substrFunc(sqlite_func *context, int argc, const char **argv){ if( (z[i]&0xc0)!=0x80 ) p2++; } #endif + if( p2<0 ) p2 = 0; sqlite_set_result_string(context, &z[p1], p2); } diff --git a/src/vdbe.c b/src/vdbe.c index ad31ad1d1b..5514df12d4 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -30,7 +30,7 @@ ** But other routines are also provided to help in building up ** a program instruction by instruction. ** -** $Id: vdbe.c,v 1.128 2002/02/28 03:04:48 drh Exp $ +** $Id: vdbe.c,v 1.129 2002/02/28 03:31:11 drh Exp $ */ #include "sqliteInt.h" #include @@ -1047,23 +1047,21 @@ static char *zOpName[] = { 0, "ListRewind", "ListRead", "ListReset", "SortPut", "SortMakeRec", "SortMakeKey", "Sort", "SortNext", "SortCallback", "SortReset", "FileOpen", "FileRead", - "FileColumn", "AggReset", "AggFocus", "AggIncr", - "AggNext", "AggSet", "AggGet", "AggFunc", - "AggInit", "SetInsert", "SetFound", "SetNotFound", - "MakeRecord", "MakeKey", "MakeIdxKey", "IncrKey", - "Goto", "If", "Halt", "ColumnCount", - "ColumnName", "Callback", "NullCallback", "Integer", - "String", "Pop", "Dup", "Pull", - "Push", "MustBeInt", "Add", "AddImm", - "Subtract", "Multiply", "Divide", "Remainder", - "BitAnd", "BitOr", "BitNot", "ShiftLeft", - "ShiftRight", "AbsValue", "Precision", "Min", - "Max", "Like", "Glob", "Eq", + "FileColumn", "AggReset", "AggFocus", "AggNext", + "AggSet", "AggGet", "AggFunc", "AggInit", + "SetInsert", "SetFound", "SetNotFound", "MakeRecord", + "MakeKey", "MakeIdxKey", "IncrKey", "Goto", + "If", "Halt", "ColumnCount", "ColumnName", + "Callback", "NullCallback", "Integer", "String", + "Pop", "Dup", "Pull", "Push", + "MustBeInt", "Add", "AddImm", "Subtract", + "Multiply", "Divide", "Remainder", "BitAnd", + "BitOr", "BitNot", "ShiftLeft", "ShiftRight", + "AbsValue", "Like", "Glob", "Eq", "Ne", "Lt", "Le", "Gt", "Ge", "IsNull", "NotNull", "Negative", "And", "Or", "Not", "Concat", - "Noop", "Strlen", "Substr", "Function", - "Limit", + "Noop", "Function", "Limit", }; /* @@ -1768,104 +1766,6 @@ divide_by_zero: break; } -/* -** Opcode: Precision * * * -** -** The top of stack is a floating-point number and the next on stack is -** an integer. Truncate the floating-point number to a number of digits -** specified by the integer and push the floating-point number back onto -** the stack. -*/ -case OP_Precision: { - int tos = p->tos; - int nos = tos - 1; - int nDigit; - int len; - double v; - char *zNew; - - VERIFY( if( nos<0 ) goto not_enough_stack; ) - Realify(p, tos); - Integerify(p, nos); - nDigit = aStack[nos].i; - if( nDigit<0 ) nDigit = 0; - if( nDigit>30 ) nDigit = 30; - v = aStack[tos].r; - zNew = sqlite_mprintf("%.*f", nDigit, v); - if( zNew==0 ) goto no_mem; - POPSTACK; - Release(p, nos); - aStack[nos].n = len = strlen(zNew) + 1; - if( len<=NBFS ){ - strcpy(aStack[nos].z, zNew); - zStack[nos] = aStack[nos].z; - aStack[nos].flags = STK_Str; - sqliteFree(zNew); - }else{ - zStack[nos] = zNew; - aStack[nos].flags = STK_Str | STK_Dyn; - } - break; -} - -/* Opcode: Max * * * -** -** Pop the top two elements from the stack then push back the -** largest of the two. -*/ -/* Opcode: Min * * * -** -** Pop the top two elements from the stack then push back the -** smaller of the two. -*/ -case OP_Min: -case OP_Max: { - int tos = p->tos; - int nos = tos - 1; - int a,b; - int ft, fn; - int copy = 0; - VERIFY( if( nos<0 ) goto not_enough_stack; ) - ft = aStack[tos].flags; - fn = aStack[nos].flags; - if( pOp->opcode==OP_Max ){ - a = tos; - b = nos; - }else{ - a = nos; - b = tos; - } - if( fn & STK_Null ){ - copy = 1; - }else if( ft & STK_Null ){ - copy = 0; - }else if( (ft & fn & STK_Int)==STK_Int ){ - copy = aStack[a].i>aStack[b].i; - }else if( ( (ft|fn) & (STK_Int|STK_Real) ) !=0 ){ - Realify(p, tos); - Realify(p, nos); - copy = aStack[a].r>aStack[b].r; - }else{ - if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem; - copy = sqliteCompare(zStack[a],zStack[b])>0; - } - if( copy ){ - Release(p, nos); - aStack[nos] = aStack[tos]; - if( aStack[nos].flags & (STK_Dyn|STK_Static) ){ - zStack[nos] = zStack[tos]; - }else{ - zStack[nos] = aStack[nos].z; - } - zStack[tos] = 0; - aStack[tos].flags = 0; - }else{ - Release(p, tos); - } - p->tos = nos; - break; -} - /* Opcode: Function P1 * P3 ** ** Invoke a user function (P3 is a pointer to a Function structure that @@ -4496,36 +4396,6 @@ case OP_AggFocus: { break; } -/* Opcode: AggIncr P1 P2 * -** -** Increase the integer value in the P2-th field of the aggregate -** element current in focus by an amount P1. -*/ -case OP_AggIncr: { - AggElem *pFocus = AggInFocus(p->agg); - int i = pOp->p2; - if( pFocus==0 ) goto no_mem; - if( i>=0 && iagg.nMem ){ - Mem *pMem = &pFocus->aMem[i]; - if( pMem->s.flags!=STK_Int ){ - if( pMem->s.flags & STK_Int ){ - /* Do nothing */ - }else if( pMem->s.flags & STK_Real ){ - pMem->s.i = (int)pMem->s.r; - }else if( pMem->s.flags & STK_Str ){ - pMem->s.i = atoi(pMem->z); - }else{ - pMem->s.i = 0; - } - if( pMem->s.flags & STK_Dyn ) sqliteFree(pMem->z); - pMem->z = 0; - pMem->s.flags = STK_Int; - } - pMem->s.i += pOp->p1; - } - break; -} - /* Opcode: AggSet * P2 * ** ** Move the top of the stack into the P2-th field of the current @@ -4705,133 +4575,6 @@ case OP_SetNotFound: { break; } -/* Opcode: Strlen * * * -** -** Interpret the top of the stack as a string. Replace the top of -** stack with an integer which is the length of the string. -*/ -case OP_Strlen: { - int tos = p->tos; - int len; - VERIFY( if( tos<0 ) goto not_enough_stack; ) - if( Stringify(p, tos) ) goto no_mem; -#ifdef SQLITE_UTF8 - { - char *z = zStack[tos]; - for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; } - } -#else - len = aStack[tos].n-1; -#endif - POPSTACK; - p->tos++; - aStack[tos].i = len; - aStack[tos].flags = STK_Int; - break; -} - -/* Opcode: Substr P1 P2 * -** -** This operation pops between 1 and 3 elements from the stack and -** pushes back a single element. The bottom-most element popped from -** the stack is a string and the element pushed back is also a string. -** The other two elements popped are integers. The integers are taken -** from the stack only if P1 and/or P2 are 0. When P1 or P2 are -** not zero, the value of the operand is used rather than the integer -** from the stack. In the sequel, we will use P1 and P2 to describe -** the two integers, even if those integers are really taken from the -** stack. -** -** The string pushed back onto the stack is a substring of the string -** that was popped. There are P2 characters in the substring. The -** first character of the substring is the P1-th character of the -** original string where the left-most character is 1 (not 0). If P1 -** is negative, then counting begins at the right instead of at the -** left. -*/ -case OP_Substr: { - int cnt; - int start; - int n; - char *z; - - if( pOp->p2==0 ){ - VERIFY( if( p->tos<0 ) goto not_enough_stack; ) - Integerify(p, p->tos); - cnt = aStack[p->tos].i; - POPSTACK; - }else{ - cnt = pOp->p2; - } - if( pOp->p1==0 ){ - VERIFY( if( p->tos<0 ) goto not_enough_stack; ) - Integerify(p, p->tos); - start = aStack[p->tos].i; - POPSTACK; - }else{ - start = pOp->p1; - } - if( start ) start--; - VERIFY( if( p->tos<0 ) goto not_enough_stack; ) - if( Stringify(p, p->tos) ) goto no_mem; - - /* "n" will be the number of characters in the input string. - ** For iso8859, the number of characters is the number of bytes. - ** Buf for UTF-8, some characters can use multiple bytes and the - ** situation is more complex. - */ -#ifdef SQLITE_UTF8 - z = zStack[p->tos]; - for(n=0; *z; z++){ if( (0xc0&*z)!=0x80 ) n++; } -#else - n = aStack[p->tos].n - 1; -#endif - if( start<0 ){ - start += n + 1; - if( start<0 ){ - cnt += start; - start = 0; - } - } - if( start>n ){ - start = n; - } - if( cnt<0 ) cnt = 0; - if( cnt > n ){ - cnt = n; - } - - /* At this point, "start" is the index of the first character to - ** extract and "cnt" is the number of characters to extract. We - ** need to convert units on these variable from characters into - ** bytes. For iso8859, the conversion is a no-op, but for UTF-8 - ** we have to do a little work. - */ -#ifdef SQLITE_UTF8 - { - int c_start = start; - int c_cnt = cnt; - int i; - z = zStack[p->tos]; - for(start=i=0; itos][start], cnt); - z[cnt] = 0; - POPSTACK; - p->tos++; - zStack[p->tos] = z; - aStack[p->tos].n = cnt + 1; - aStack[p->tos].flags = STK_Str|STK_Dyn; - break; -} /* An other opcode is illegal... */ diff --git a/src/vdbe.h b/src/vdbe.h index 8d26764eb8..201cfa051a 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -15,7 +15,7 @@ ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** -** $Id: vdbe.h,v 1.48 2002/02/28 00:41:11 drh Exp $ +** $Id: vdbe.h,v 1.49 2002/02/28 03:31:12 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -136,77 +136,71 @@ typedef struct VdbeOp VdbeOp; #define OP_AggReset 58 #define OP_AggFocus 59 -#define OP_AggIncr 60 -#define OP_AggNext 61 -#define OP_AggSet 62 -#define OP_AggGet 63 -#define OP_AggFunc 64 -#define OP_AggInit 65 +#define OP_AggNext 60 +#define OP_AggSet 61 +#define OP_AggGet 62 +#define OP_AggFunc 63 +#define OP_AggInit 64 -#define OP_SetInsert 66 -#define OP_SetFound 67 -#define OP_SetNotFound 68 +#define OP_SetInsert 65 +#define OP_SetFound 66 +#define OP_SetNotFound 67 -#define OP_MakeRecord 69 -#define OP_MakeKey 70 -#define OP_MakeIdxKey 71 -#define OP_IncrKey 72 +#define OP_MakeRecord 68 +#define OP_MakeKey 69 +#define OP_MakeIdxKey 70 +#define OP_IncrKey 71 -#define OP_Goto 73 -#define OP_If 74 -#define OP_Halt 75 +#define OP_Goto 72 +#define OP_If 73 +#define OP_Halt 74 -#define OP_ColumnCount 76 -#define OP_ColumnName 77 -#define OP_Callback 78 -#define OP_NullCallback 79 +#define OP_ColumnCount 75 +#define OP_ColumnName 76 +#define OP_Callback 77 +#define OP_NullCallback 78 -#define OP_Integer 80 -#define OP_String 81 -#define OP_Pop 82 -#define OP_Dup 83 -#define OP_Pull 84 -#define OP_Push 85 -#define OP_MustBeInt 86 +#define OP_Integer 79 +#define OP_String 80 +#define OP_Pop 81 +#define OP_Dup 82 +#define OP_Pull 83 +#define OP_Push 84 +#define OP_MustBeInt 85 -#define OP_Add 87 -#define OP_AddImm 88 -#define OP_Subtract 89 -#define OP_Multiply 90 -#define OP_Divide 91 -#define OP_Remainder 92 -#define OP_BitAnd 93 -#define OP_BitOr 94 -#define OP_BitNot 95 -#define OP_ShiftLeft 96 -#define OP_ShiftRight 97 -#define OP_AbsValue 98 -#define OP_Precision 99 -#define OP_Min 100 -#define OP_Max 101 -#define OP_Like 102 -#define OP_Glob 103 -#define OP_Eq 104 -#define OP_Ne 105 -#define OP_Lt 106 -#define OP_Le 107 -#define OP_Gt 108 -#define OP_Ge 109 -#define OP_IsNull 110 -#define OP_NotNull 111 -#define OP_Negative 112 -#define OP_And 113 -#define OP_Or 114 -#define OP_Not 115 -#define OP_Concat 116 -#define OP_Noop 117 -#define OP_Strlen 118 -#define OP_Substr 119 -#define OP_Function 120 +#define OP_Add 86 +#define OP_AddImm 87 +#define OP_Subtract 88 +#define OP_Multiply 89 +#define OP_Divide 90 +#define OP_Remainder 91 +#define OP_BitAnd 92 +#define OP_BitOr 93 +#define OP_BitNot 94 +#define OP_ShiftLeft 95 +#define OP_ShiftRight 96 +#define OP_AbsValue 97 +#define OP_Like 98 +#define OP_Glob 99 +#define OP_Eq 100 +#define OP_Ne 101 +#define OP_Lt 102 +#define OP_Le 103 +#define OP_Gt 104 +#define OP_Ge 105 +#define OP_IsNull 106 +#define OP_NotNull 107 +#define OP_Negative 108 +#define OP_And 109 +#define OP_Or 110 +#define OP_Not 111 +#define OP_Concat 112 +#define OP_Noop 113 +#define OP_Function 114 -#define OP_Limit 121 +#define OP_Limit 115 -#define OP_MAX 121 +#define OP_MAX 115 /* ** Prototypes for the VDBE interface. See comments on the implementation