1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Added length() and substr() functions (CVS 143)

FossilOrigin-Name: 0eef538f3de66fede7c88f8be8c3458d84107c3f
This commit is contained in:
drh
2000-08-28 15:51:43 +00:00
parent 3d441f8082
commit 6ec2733b44
6 changed files with 150 additions and 24 deletions

View File

@@ -1,5 +1,5 @@
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
@@ -11,7 +11,7 @@ F src/build.c 4d90e9e94750ca80249fc7958c617021d8bb7a50
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
@@ -19,13 +19,13 @@ F src/select.c d382e96c2221d08367cc87976f2b574537c9de97
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
@@ -70,7 +70,7 @@ F www/mingw.tcl fc5f4ba9d336b6e8c97347cc6496d6162461ef60
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

View File

@@ -1 +1 @@
d35a1f8b37333e2df86c22c2dbd766132b4931b2
0eef538f3de66fede7c88f8be8c3458d84107c3f

View File

@@ -24,7 +24,7 @@
** 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"
@@ -323,6 +323,8 @@ int sqliteFuncId(Token *pToken){
{ "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++){
@@ -381,6 +383,16 @@ int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){
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
@@ -392,6 +404,7 @@ int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){
n = 0;
break;
}
default: break;
}
if( no_such_func ){
@@ -574,10 +587,13 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
int op;
int i;
ExprList *pList = pExpr->pList;
if( id==FN_Fcnt ){
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);
@@ -587,6 +603,25 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
}
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;
}
case TK_SELECT: {
sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0, 0, 0);
break;

View File

@@ -23,7 +23,7 @@
*************************************************************************
** 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"
@@ -99,6 +99,8 @@ int sqlite_iMallocFail; /* Fail sqliteMalloc() after this many calls */
#define FN_Sum 4
#define FN_Avg 5
#define FN_Fcnt 6
#define FN_Length 7
#define FN_Substr 8
/*
** Forward references to structures

View File

@@ -41,7 +41,7 @@
** 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>
@@ -788,6 +788,7 @@ static char *zOpName[] = { 0,
"Lt", "Le", "Gt", "Ge",
"IsNull", "NotNull", "Negative", "And",
"Or", "Not", "Concat", "Noop",
"Strlen", "Substr",
};
/*
@@ -3130,6 +3131,91 @@ int sqliteVdbeExec(
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: {

View File

@@ -27,7 +27,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.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_
@@ -173,7 +173,10 @@ typedef struct VdbeOp VdbeOp;
#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