-C Version\s1.0.3\s(CVS\s497)
-D 2000-08-22T18:30:00
+C Added\slength()\sand\ssubstr()\sfunctions\s(CVS\s143)
+D 2000-08-28T15:51:44
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
F Makefile.in 036bce328b963f48dbaadbec8cc4144a1fd9e50a
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
F src/dbbe.c 226daaf8c095ceb4aff48cad188dad90643f9867
F src/dbbe.h 6337132f904e72ecb28b07390021c241397e4cbf
F src/delete.c 4d491eaf61b515516749c7ed68fa3b2ee8a09065
-F src/expr.c 2fa63f086707176d09092e71832f9bbdc6a8ac85
+F src/expr.c e8e350d7baa33bd9ed8701c159eaba5e912e0adb
F src/insert.c f146f149ad2422a1dc3bfa7a1651a25940f98958
F src/main.c 9a89579b40e498920f86e89878f52185457b9c2c
F src/parse.y 5d199034de5d29ebedb42c1c51f34db4df40cbe5
F src/shell.c 061186b1a4f0884037d067f0f102ec5d382119b5
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in d341439fc1432c7d7014bcff5f7b6e914571232c
-F src/sqliteInt.h f6d1e139b3bfa4ceff2136684e19d76b53178ec0
+F src/sqliteInt.h b65fdecac7281aafb4c9ff3e79ea1b5546478385
F src/tclsqlite.c 89dc4ba2b521f3e919d6d7aaa4cc1c2aba8e16f3
F src/tokenize.c 097bec5843d4a0fb4509e036fee93bac080c5e73
F src/update.c 51b9ef7434b15e31096155da920302e9db0d27fc
F src/util.c b75b33e6bd5d47898bb7ed9fdd0dea4fe7c19b00
-F src/vdbe.c bdedf21230581f0cf73a2dcd8fe23f30cf30ebe6
-F src/vdbe.h 6c5653241633c583549c2d8097394ab52550eb63
+F src/vdbe.c a2372aebfcf2a5ed4530cd956a8cdbb595c67991
+F src/vdbe.h 6413cd0165ac62b0839fe3e077cb7c9f0b736295
F src/where.c 3dfad2ffd0aa994d5eceac88852f7189c8d1d3c8
F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7
F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb
F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
F www/vdbe.tcl bcbfc33bcdd0ebad95eab31286adb9e1bc289520
-P f255ea6d4bb085a869485c14b4c96af13ca826fa
-R d941b15d38d95642a66b6ff4bba2c454
+P d35a1f8b37333e2df86c22c2dbd766132b4931b2
+R 33478b7323acb1d67e1ce4b66b8bba30
U drh
-Z cbdf4324aa4508ca2f8e72c3acf62235
+Z a1f7d622d82864a914f4580098647f78
-d35a1f8b37333e2df86c22c2dbd766132b4931b2
\ No newline at end of file
+0eef538f3de66fede7c88f8be8c3458d84107c3f
\ No newline at end of file
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions.
**
-** $Id: expr.c,v 1.18 2000/06/21 13:59:11 drh Exp $
+** $Id: expr.c,v 1.19 2000/08/28 15:51:44 drh Exp $
*/
#include "sqliteInt.h"
{ "sum", 3, FN_Sum },
{ "avg", 3, FN_Avg },
{ "fcnt", 4, FN_Fcnt }, /* Used for testing only */
+ { "length", 6, FN_Length},
+ { "substr", 6, FN_Substr},
};
int i;
for(i=0; i<ArraySize(aFunc); i++){
is_agg = 1;
break;
}
+ case FN_Length: {
+ too_few_args = n<1;
+ too_many_args = n>1;
+ break;
+ }
+ case FN_Substr: {
+ too_few_args = n<3;
+ too_many_args = n>3;
+ break;
+ }
/* The "fcnt(*)" function always returns the number of fetch
** operations that have occurred so far while processing the
** SQL statement. This information can be used by test procedures
n = 0;
break;
}
+
default: break;
}
if( no_such_func ){
int op;
int i;
ExprList *pList = pExpr->pList;
- if( id==FN_Fcnt ){
- sqliteVdbeAddOp(v, OP_Fcnt, 0, 0, 0, 0);
- break;
- }
- op = id==FN_Min ? OP_Min : OP_Max;
- for(i=0; i<pList->nExpr; i++){
- sqliteExprCode(pParse, pList->a[i].pExpr);
- if( i>0 ){
- sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
+ switch( id ){
+ case FN_Fcnt: {
+ sqliteVdbeAddOp(v, OP_Fcnt, 0, 0, 0, 0);
+ break;
+ }
+ case FN_Min:
+ case FN_Max: {
+ op = id==FN_Min ? OP_Min : OP_Max;
+ for(i=0; i<pList->nExpr; i++){
+ sqliteExprCode(pParse, pList->a[i].pExpr);
+ if( i>0 ){
+ sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
+ }
+ }
+ break;
+ }
+ case FN_Length: {
+ sqliteExprCode(pParse, pList->a[0].pExpr);
+ sqliteVdbeAddOp(v, OP_Strlen, 0, 0, 0, 0);
+ break;
+ }
+ case FN_Substr: {
+ for(i=0; i<pList->nExpr; i++){
+ sqliteExprCode(pParse, pList->a[i].pExpr);
+ }
+ sqliteVdbeAddOp(v, OP_Substr, 0, 0, 0, 0);
+ break;
+ }
+ default: {
+ /* Can't happen! */
+ break;
}
}
break;
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.29 2000/08/02 13:47:42 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.30 2000/08/28 15:51:44 drh Exp $
*/
#include "sqlite.h"
#include "dbbe.h"
#define FN_Sum 4
#define FN_Avg 5
#define FN_Fcnt 6
+#define FN_Length 7
+#define FN_Substr 8
/*
** Forward references to structures
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
-** $Id: vdbe.c,v 1.38 2000/08/02 12:26:29 drh Exp $
+** $Id: vdbe.c,v 1.39 2000/08/28 15:51:44 drh Exp $
*/
#include "sqliteInt.h"
#include <unistd.h>
"Lt", "Le", "Gt", "Ge",
"IsNull", "NotNull", "Negative", "And",
"Or", "Not", "Concat", "Noop",
+ "Strlen", "Substr",
};
/*
break;
}
+ /* Opcode: Length * * *
+ **
+ ** 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;
+ if( tos<0 ) goto not_enough_stack;
+ Stringify(p, tos);
+ len = p->aStack[tos].n-1;
+ PopStack(p, 1);
+ p->tos++;
+ p->aStack[tos].i = len;
+ p->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 ){
+ if( p->tos<0 ) goto not_enough_stack;
+ Integerify(p, p->tos);
+ cnt = p->aStack[p->tos].i;
+ PopStack(p, 1);
+ }else{
+ cnt = pOp->p2;
+ }
+ if( pOp->p1==0 ){
+ if( p->tos<0 ) goto not_enough_stack;
+ Integerify(p, p->tos);
+ start = p->aStack[p->tos].i;
+ PopStack(p, 1);
+ }else{
+ start = pOp->p1;
+ }
+ if( p->tos<0 ) goto not_enough_stack;
+ Stringify(p, p->tos);
+ n = p->aStack[p->tos].n - 1;
+ if( start<0 ){
+ start += n;
+ if( start<0 ){
+ cnt += start;
+ start = 0;
+ }
+ }
+ if( cnt<0 ) cnt = 0;
+ if( cnt > n ){
+ cnt = n;
+ }
+ z = sqliteMalloc( cnt+1 );
+ if( z==0 ) goto no_mem;
+ strncpy(z, p->zStack[p->tos], cnt);
+ z[cnt] = 0;
+ PopStack(p, 1);
+ p->tos++;
+ p->zStack[p->tos] = z;
+ p->aStack[p->tos].n = cnt + 1;
+ p->aStack[p->tos].flags = STK_Str|STK_Dyn;
+ break;
+ }
+
/* An other opcode is illegal...
*/
default: {
** 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.11 2000/07/28 14:32:50 drh Exp $
+** $Id: vdbe.h,v 1.12 2000/08/28 15:51:45 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#define OP_Concat 87
#define OP_Noop 88
-#define OP_MAX 88
+#define OP_Strlen 89
+#define OP_Substr 90
+
+#define OP_MAX 90
/*
** Prototypes for the VDBE interface. See comments on the implementation