mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-01 06:27:03 +03:00
The new function code passes regression tests. (CVS 403)
FossilOrigin-Name: b00cf110b1cc671b7200a5ce8b9e704f660763c9
This commit is contained in:
15
src/expr.c
15
src/expr.c
@ -12,7 +12,7 @@
|
||||
** This file contains routines used for analyzing expressions and
|
||||
** for generating VDBE code that evaluates expressions in SQLite.
|
||||
**
|
||||
** $Id: expr.c,v 1.50 2002/02/28 01:46:12 drh Exp $
|
||||
** $Id: expr.c,v 1.51 2002/02/28 03:04:48 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -652,7 +652,8 @@ int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){
|
||||
int i;
|
||||
FuncDef *pDef;
|
||||
|
||||
pDef = sqliteFindFunction(pParse->db, pExpr->token.z, pExpr->token.n,n,0);
|
||||
pDef = sqliteFindFunction(pParse->db,
|
||||
pExpr->token.z, pExpr->token.n, n, 0);
|
||||
if( pDef==0 ){
|
||||
pDef = sqliteFindFunction(pParse->db,
|
||||
pExpr->token.z, pExpr->token.n, -1, 0);
|
||||
@ -854,14 +855,15 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
||||
case TK_FUNCTION: {
|
||||
int i;
|
||||
ExprList *pList = pExpr->pList;
|
||||
int nExpr = pList ? pList->nExpr : 0;
|
||||
FuncDef *pDef;
|
||||
pDef = sqliteFindFunction(pParse->db,
|
||||
pExpr->token.z, pExpr->token.n, pList->nExpr, 0);
|
||||
pExpr->token.z, pExpr->token.n, nExpr, 0);
|
||||
assert( pDef!=0 );
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
for(i=0; i<nExpr; i++){
|
||||
sqliteExprCode(pParse, pList->a[i].pExpr);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Function, pList->nExpr, 0);
|
||||
sqliteVdbeAddOp(v, OP_Function, nExpr, 0);
|
||||
sqliteVdbeChangeP3(v, -1, (char*)pDef, P3_POINTER);
|
||||
break;
|
||||
}
|
||||
@ -1246,8 +1248,7 @@ FuncDef *sqliteFindFunction(
|
||||
assert( createFlag==0 );
|
||||
return pMaybe;
|
||||
}
|
||||
if( p==0 && createFlag ){
|
||||
p = sqliteMalloc( sizeof(*p) );
|
||||
if( p==0 && createFlag && (p = sqliteMalloc(sizeof(*p)))!=0 ){
|
||||
p->nArg = nArg;
|
||||
p->pNext = pFirst;
|
||||
sqliteHashInsert(&db->aFunc, zName, nName, (void*)p);
|
||||
|
10
src/func.c
10
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.8 2002/02/28 01:46:13 drh Exp $
|
||||
** $Id: func.c,v 1.9 2002/02/28 03:04:48 drh Exp $
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
@ -31,6 +31,7 @@ static void minFunc(sqlite_func *context, int argc, const char **argv){
|
||||
const char *zBest;
|
||||
int i;
|
||||
|
||||
if( argc==0 ) return;
|
||||
zBest = argv[0];
|
||||
for(i=1; i<argc; i++){
|
||||
if( sqliteCompare(argv[i], zBest)<0 ){
|
||||
@ -43,6 +44,7 @@ static void maxFunc(sqlite_func *context, int argc, const char **argv){
|
||||
const char *zBest;
|
||||
int i;
|
||||
|
||||
if( argc==0 ) return;
|
||||
zBest = argv[0];
|
||||
for(i=1; i<argc; i++){
|
||||
if( sqliteCompare(argv[i], zBest)>0 ){
|
||||
@ -105,7 +107,7 @@ static void substrFunc(sqlite_func *context, int argc, const char **argv){
|
||||
len = strlen(z);
|
||||
#endif
|
||||
if( p1<0 ){
|
||||
p1 = len-p1;
|
||||
p1 += len;
|
||||
}else if( p1>0 ){
|
||||
p1--;
|
||||
}
|
||||
@ -201,9 +203,7 @@ static void sumStep(sqlite_func *context, int argc, const char **argv){
|
||||
static void sumFinalize(sqlite_func *context){
|
||||
SumCtx *p;
|
||||
p = sqlite_aggregate_context(context, sizeof(*p));
|
||||
if( p ){
|
||||
sqlite_set_result_double(context, p->sum);
|
||||
}
|
||||
sqlite_set_result_double(context, p ? p->sum : 0.0);
|
||||
}
|
||||
static void avgFinalize(sqlite_func *context){
|
||||
SumCtx *p;
|
||||
|
@ -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.127 2002/02/28 01:46:13 drh Exp $
|
||||
** $Id: vdbe.c,v 1.128 2002/02/28 03:04:48 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -552,6 +552,7 @@ char *sqlite_set_result_string(sqlite_func *p, const char *zResult, int n){
|
||||
p->s.flags = STK_Null;
|
||||
n = 0;
|
||||
p->z = 0;
|
||||
p->s.n = 0;
|
||||
}else{
|
||||
if( n<0 ) n = strlen(zResult);
|
||||
if( n<NBFS-1 ){
|
||||
@ -567,8 +568,8 @@ char *sqlite_set_result_string(sqlite_func *p, const char *zResult, int n){
|
||||
}
|
||||
p->s.flags = STK_Str | STK_Dyn;
|
||||
}
|
||||
p->s.n = n+1;
|
||||
}
|
||||
p->s.n = n;
|
||||
return p->z;
|
||||
}
|
||||
void sqlite_set_result_int(sqlite_func *p, int iResult){
|
||||
@ -1878,7 +1879,7 @@ case OP_Function: {
|
||||
sqlite_func ctx;
|
||||
|
||||
n = pOp->p1;
|
||||
VERIFY( if( n<=0 ) goto bad_instruction; )
|
||||
VERIFY( if( n<0 ) goto bad_instruction; )
|
||||
VERIFY( if( p->tos+1<n ) goto not_enough_stack; )
|
||||
for(i=p->tos-n+1; i<=p->tos; i++){
|
||||
if( (aStack[i].flags & STK_Null)==0 ){
|
||||
|
Reference in New Issue
Block a user