diff options
author | drh <> | 2024-08-31 22:22:24 +0000 |
---|---|---|
committer | drh <> | 2024-08-31 22:22:24 +0000 |
commit | df2d14b86e8d6d990ed9d5dd5b620fed5ece6adc (patch) | |
tree | 5bc5eda45419c2f81f6b005179c52ee9ad979e85 /src | |
parent | a239ece3781403dd43d0f4db048741a2c8184f37 (diff) | |
download | sqlite-df2d14b86e8d6d990ed9d5dd5b620fed5ece6adc.tar.gz sqlite-df2d14b86e8d6d990ed9d5dd5b620fed5ece6adc.zip |
Add error checking: Do not allow functions other than those in the
percentile extension to use the ordered-set aggregate notation.
FossilOrigin-Name: 317d901429303340290334dbe7680a36339df0a50b586e3f71b6c5e5eba6d411
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 3 | ||||
-rw-r--r-- | src/parse.y | 2 | ||||
-rw-r--r-- | src/resolve.c | 4 | ||||
-rw-r--r-- | src/sqlite.h.in | 8 | ||||
-rw-r--r-- | src/sqliteInt.h | 4 |
5 files changed, 17 insertions, 4 deletions
diff --git a/src/main.c b/src/main.c index 5d6212208..ac08eea04 100644 --- a/src/main.c +++ b/src/main.c @@ -1926,7 +1926,8 @@ int sqlite3CreateFunc( assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| - SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE); + SQLITE_SUBTYPE|SQLITE_INNOCUOUS| + SQLITE_RESULT_SUBTYPE|SQLITE_SELFORDER1); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But diff --git a/src/parse.y b/src/parse.y index efcde10e6..3db20e9ac 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1204,7 +1204,7 @@ expr(A) ::= idj(X) LP STAR RP. { pFuncname); } pExpr = sqlite3ExprFunction(pParse, p, pFuncname, 0); - if( pExpr ) pExpr->iTable = 1; + if( pExpr ) pExpr->iColumn = 1; return pExpr; } } diff --git a/src/resolve.c b/src/resolve.c index b755cc864..f448bc324 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1292,6 +1292,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ else if( ExprHasProperty(pExpr, EP_WinFunc) || pExpr->pLeft ){ is_agg = 1; } + if( pExpr->iColumn && (pDef->funcFlags & SQLITE_SELFORDER1)==0 ){ + sqlite3ErrorMsg(pParse, "%#T() is not a ordered-set aggregate function", + pExpr); + } sqlite3WalkExprList(pWalker, pList); if( is_agg ){ if( pExpr->pLeft ){ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 810ccecc9..8e5e327c9 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5615,6 +5615,13 @@ int sqlite3_create_window_function( ** [sqlite3_result_subtype()] should avoid setting this property, as the ** purpose of this property is to disable certain optimizations that are ** incompatible with subtypes. +** +** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd> +** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate +** that internally orders the values provided to the first argument. The +** ordered-set aggregate SQL notation can be used to invoke this function. +** If the ordered-set aggregate notation is used on a function that lacks +** this flag, then an error is raised. ** </dd> ** </dl> */ @@ -5623,6 +5630,7 @@ int sqlite3_create_window_function( #define SQLITE_SUBTYPE 0x000100000 #define SQLITE_INNOCUOUS 0x000200000 #define SQLITE_RESULT_SUBTYPE 0x001000000 +#define SQLITE_SELFORDER1 0x002000000 /* ** CAPI3REF: Deprecated Functions diff --git a/src/sqliteInt.h b/src/sqliteInt.h index dcadec78d..b77f035e7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3049,10 +3049,10 @@ struct Expr { ** EP_Unlikely: 134217728 times likelihood ** TK_IN: ephemeral table holding RHS ** TK_SELECT_COLUMN: Number of columns on the LHS - ** TK_SELECT: 1st register of result vector - ** TK_FUNCTION: Uses ordered-set aggregate syntax */ + ** TK_SELECT: 1st register of result vector */ ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. ** TK_VARIABLE: variable number (always >= 1). + ** TK_FUNCTION: Uses ordered-set aggregate syntax ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ union { |