aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2024-08-31 22:22:24 +0000
committerdrh <>2024-08-31 22:22:24 +0000
commitdf2d14b86e8d6d990ed9d5dd5b620fed5ece6adc (patch)
tree5bc5eda45419c2f81f6b005179c52ee9ad979e85 /src
parenta239ece3781403dd43d0f4db048741a2c8184f37 (diff)
downloadsqlite-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.c3
-rw-r--r--src/parse.y2
-rw-r--r--src/resolve.c4
-rw-r--r--src/sqlite.h.in8
-rw-r--r--src/sqliteInt.h4
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 {