summaryrefslogtreecommitdiff
path: root/ext/pdo_sqlite/sqlite/src/func.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/func.c')
-rw-r--r--ext/pdo_sqlite/sqlite/src/func.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/func.c b/ext/pdo_sqlite/sqlite/src/func.c
index 326d98eef6..cdb674fa28 100644
--- a/ext/pdo_sqlite/sqlite/src/func.c
+++ b/ext/pdo_sqlite/sqlite/src/func.c
@@ -819,6 +819,7 @@ typedef struct SumCtx SumCtx;
struct SumCtx {
double sum; /* Sum of terms */
int cnt; /* Number of elements summed */
+ u8 seenFloat; /* True if there has been any floating point value */
};
/*
@@ -826,21 +827,32 @@ struct SumCtx {
*/
static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
SumCtx *p;
- if( argc<1 ) return;
+ int type;
+ assert( argc==1 );
p = sqlite3_aggregate_context(context, sizeof(*p));
- if( p && SQLITE_NULL!=sqlite3_value_type(argv[0]) ){
+ type = sqlite3_value_type(argv[0]);
+ if( p && type!=SQLITE_NULL ){
p->sum += sqlite3_value_double(argv[0]);
p->cnt++;
+ if( type==SQLITE_FLOAT ){
+ p->seenFloat = 1;
+ }
}
}
static void sumFinalize(sqlite3_context *context){
SumCtx *p;
- p = sqlite3_aggregate_context(context, sizeof(*p));
- sqlite3_result_double(context, p ? p->sum : 0.0);
+ p = sqlite3_aggregate_context(context, 0);
+ if( p && p->cnt>0 ){
+ if( p->seenFloat ){
+ sqlite3_result_double(context, p->sum);
+ }else{
+ sqlite3_result_int64(context, (i64)p->sum);
+ }
+ }
}
static void avgFinalize(sqlite3_context *context){
SumCtx *p;
- p = sqlite3_aggregate_context(context, sizeof(*p));
+ p = sqlite3_aggregate_context(context, 0);
if( p && p->cnt>0 ){
sqlite3_result_double(context, p->sum/(double)p->cnt);
}
@@ -878,7 +890,7 @@ static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
}
static void countFinalize(sqlite3_context *context){
CountCtx *p;
- p = sqlite3_aggregate_context(context, sizeof(*p));
+ p = sqlite3_aggregate_context(context, 0);
sqlite3_result_int(context, p ? p->n : 0);
}
@@ -916,11 +928,13 @@ static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv)
}
static void minMaxFinalize(sqlite3_context *context){
sqlite3_value *pRes;
- pRes = (sqlite3_value *)sqlite3_aggregate_context(context, sizeof(Mem));
- if( pRes->flags ){
- sqlite3_result_value(context, pRes);
+ pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
+ if( pRes ){
+ if( pRes->flags ){
+ sqlite3_result_value(context, pRes);
+ }
+ sqlite3VdbeMemRelease(pRes);
}
- sqlite3VdbeMemRelease(pRes);
}
@@ -1041,11 +1055,11 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
/*
** Set the LIKEOPT flag on the 2-argument function with the given name.
*/
-static void setLikeOptFlag(sqlite3 *db, const char *zName){
+static void setLikeOptFlag(sqlite3 *db, const char *zName, int flagVal){
FuncDef *pDef;
pDef = sqlite3FindFunction(db, zName, strlen(zName), 2, SQLITE_UTF8, 0);
if( pDef ){
- pDef->flags = SQLITE_FUNC_LIKEOPT;
+ pDef->flags = flagVal;
}
}
@@ -1065,10 +1079,9 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
sqlite3_create_function(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
sqlite3_create_function(db, "glob", 2, SQLITE_UTF8,
(struct compareInfo*)&globInfo, likeFunc, 0,0);
- setLikeOptFlag(db, "glob");
- if( caseSensitive ){
- setLikeOptFlag(db, "like");
- }
+ setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
+ setLikeOptFlag(db, "like",
+ caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
}
/*
@@ -1078,7 +1091,7 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
** return TRUE. If the function is not a LIKE-style function then
** return FALSE.
*/
-int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, char *aWc){
+int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
FuncDef *pDef;
if( pExpr->op!=TK_FUNCTION ){
return 0;
@@ -1088,7 +1101,7 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, char *aWc){
}
pDef = sqlite3FindFunction(db, pExpr->token.z, pExpr->token.n, 2,
SQLITE_UTF8, 0);
- if( pDef==0 || (pDef->flags & SQLITE_FUNC_LIKEOPT)==0 ){
+ if( pDef==0 || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
return 0;
}
@@ -1100,6 +1113,6 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, char *aWc){
assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
-
+ *pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0;
return 1;
}