-C Ensure\sthat\sthe\soptional\s"sz=N"\sparameter\sthat\scan\sbe\smanually\sadded\sto\sthe\nend\sof\san\ssqlite_stat1\sentry\sdoes\snot\shave\san\sN\svalue\sthat\sis\stoo\ssmall.\nTicket\s[e4598ecbdd18bd82]
-D 2019-08-15T14:35:45.987
+C Provide\sthe\sSQLITE_DIRECTONLY\sflag\sfor\sapp-defined\sfunctions\sthat\sprohibits\nthe\suse\sof\sthose\sfunctions\swithin\striggers\sor\sviews.
+D 2019-08-15T20:04:09.316
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 5c3031e45e80f79d7d54c2d32dd3c44926544d4f6a478858bfe4ee3191570190
F src/analyze.c a3f4ea45cdb4e9df78d4ea7beb87ec8a7a46f494173b641cd28512a40a97bff2
-F src/attach.c 78e986baee90cb7b83fb9eafa79c22581a8ada14030fd633b0683c95cf11213c
+F src/attach.c a6f108eb7922fad920e8aba0cda56fb56d89d136d519be5177cd3bd3559f2566
F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/insert.c c2194dd2886337b870226fcb31c13e7df8c4b5e0ea85140e510a6f1daf1ad65b
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c
-F src/main.c 3add6433e077635dac5579edaf7b3942e3ff3dda5588c49c0edd7abea2096482
+F src/main.c ff418603f9435914e8bd2febd1d5dbfcbf2ece3a4e853481a81a50fc27b321ab
F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
F src/prepare.c 132484635a30f873ee7eccd47f93ed1932503863b93b28423b42332d81adffaf
F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
-F src/resolve.c 14ae3326af3d8b94bd64a29e0369986f3125cf4c0dcb8f8dc1b8be2cd1bcdbaa
+F src/resolve.c b2733d39a22f5023ab489b8535ca6854b51ff8667ca975815d004bb7388b0e41
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
F src/select.c 11087458ec2af5c4b377559ea0462c2ab842e02badd35b21a8d67257c4e0b117
F src/shell.c.in 66cd8289adbcd159ca67872c242990ca6bed29fe80be7ebf9c6a1c068249a41e
-F src/sqlite.h.in 1fe019ae55182040e6ea10c89ddbb8d24c1b1015c423da53e55205398a65a906
+F src/sqlite.h.in dfbb64c0b8e4b3de2958d8372208437509acdc523aed8ae90a164f3a5d9a5739
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5
-F src/sqliteInt.h 4875fb443102c9d92ed1cb23b7fb6e2d97714591f02725d595576ef316596b94
+F src/sqliteInt.h 12e8af40a561a3006b6996938c88cce1e24efe690955e193824571d20c3ef352
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
-F src/tclsqlite.c cfe7f93daf9d8787f65e099efb67d7cdfc2c35236dec5d3f6758520bd3519424
+F src/tclsqlite.c a65eb317f8b83f7ae546f88db56600f9a39550688d70501b8eb0cc3a4b4960c9
F src/test1.c 87059457fb90b73a74044b379fe2cb0aefbb53c010c646ecaff23179a423638c
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e
-F src/treeview.c 06e65db6ffa14dd583f90403192190dfe3855c0e3acfcbac0e82109a46e2b16c
+F src/treeview.c fc8c6c0a8a26afb3a97e3f844d65403dd27cf1450baf4415034fa4ccf00c4d7e
F src/trigger.c 2305271878e95addc1c01361e5e8e342e87cba5efefdd7d3032687e5d67e05d1
F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2
F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429
F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
-F test/func.test e4313baba80bf933e58eb89a7c617bec0f0c348c862b096ec4387f36e05ad0a6
+F test/func.test 0889128141b99b38aa9ce78445acfc4c1f9fbe9aa4f51d4c6aff88ae43cf125b
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1e6
F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132
F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
-F test/tclsqlite.test 5a06962d8f18edf4703931f6b7dacd83678d02fa5c8ced9a7958c007ad58626a
+F test/tclsqlite.test 6c7368554f15ea6df3852173c0f1d6353f824afb1896f6fc17fb21b057c0685a
F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08
F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 4f5b2d938194fab7627486e2ced633def2c90d9d3328e3700612feb9dbfa3d9a
-R e211e009e748f2e64e3d39bc31b03be2
+P 98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42
+R ad310bbebd66791c892628fc8eec172c
+T *branch * directonly
+T *sym-directonly *
+T -sym-trunk *
U drh
-Z bec392cb43d1df3c3b62ac4b05f24424
+Z 950f463a47bf34120eda446765855ee2
-98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42
\ No newline at end of file
+fc745845d8d76adc165575e2192f4176e3c28e614c72571d56f4011560499fe1
\ No newline at end of file
Expr *pExpr /* The expression to be fixed to one database */
){
while( pExpr ){
+ ExprSetProperty(pExpr, EP_Indirect);
if( pExpr->op==TK_VARIABLE ){
if( pFix->pParse->db->init.busy ){
pExpr->op = TK_NULL;
}
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
- extraFlags = enc & SQLITE_DETERMINISTIC;
+ assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
+ extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY);
enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
#ifndef SQLITE_OMIT_UTF16
p->u.pDestructor = pDestructor;
p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
testcase( p->funcFlags & SQLITE_DETERMINISTIC );
+ testcase( p->funcFlags & SQLITE_DIRECTONLY );
p->xSFunc = xSFunc ? xSFunc : xStep;
p->xFinalize = xFinal;
p->xValue = xValue;
** SQL is being compiled using sqlite3NestedParse() */
no_such_func = 1;
pDef = 0;
+ }else
+ if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0
+ && ExprHasProperty(pExpr, EP_Indirect)
+ && !IN_RENAME_OBJECT
+ ){
+ /* Functions tagged with SQLITE_DIRECTONLY may not be used
+ ** inside of triggers and views */
+ sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views",
+ pDef->zName);
}
}
** function that is not deterministic. The SQLite query planner is able to
** perform additional optimizations on deterministic functions, so use
** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
+** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY]
+** flag, which if present prevents the function from being invoked from
+** within VIEWs or TRIGGERs.
**
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^
** [SQLITE_UTF8 | preferred text encoding] as the fourth argument
** to [sqlite3_create_function()], [sqlite3_create_function16()], or
** [sqlite3_create_function_v2()].
+**
+** The SQLITE_DETERMINISTIC flag means that the new function will always
+** maps the same inputs into the same output. The abs() function is
+** deterministic, for example, but randomblob() is not.
+**
+** The SQLITE_DIRECTONLY flag means that the function may only be invoked
+** from top-level SQL, and cannot be used in VIEWs or TRIGGERs.
*/
-#define SQLITE_DETERMINISTIC 0x800
+#define SQLITE_DETERMINISTIC 0x000000800
+#define SQLITE_DIRECTONLY 0x000080000
/*
** CAPI3REF: Deprecated Functions
** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG
** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG
** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API
+** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API
** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API
*/
#define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
+#define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
** EP_Agg == NC_HasAgg == SF_HasAgg
** EP_Win == NC_HasWin
*/
-#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
-#define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */
-#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */
-#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */
-#define EP_Agg 0x000010 /* Contains one or more aggregate functions */
-#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
-#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
-#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
-#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */
-#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */
-#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
-#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
-#define EP_Skip 0x001000 /* Operator does not contribute to affinity */
-#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
-#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
-#define EP_Win 0x008000 /* Contains window functions */
-#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
-#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
-#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
-#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
-#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
-#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
-#define EP_Alias 0x400000 /* Is an alias for a result set column */
-#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
-#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
-#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
-#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
-#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
-#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
-#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
+#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
+#define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */
+#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */
+#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */
+#define EP_Agg 0x000010 /* Contains one or more aggregate functions */
+#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
+#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
+#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
+#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */
+#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */
+#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
+#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
+#define EP_Skip 0x001000 /* Operator does not contribute to affinity */
+#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
+#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
+#define EP_Win 0x008000 /* Contains window functions */
+#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
+#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
+#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
+#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
+#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
+#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
+#define EP_Alias 0x400000 /* Is an alias for a result set column */
+#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
+#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
+#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
+#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
+#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
+#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
+#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
+#define EP_Indirect 0x40000000 /* Contained within a TRIGGER or a VIEW */
/*
** The EP_Propagate mask is a set of properties that automatically propagate
}
/*
- ** $db function NAME [-argcount N] [-deterministic] SCRIPT
+ ** $db function NAME [OPTIONS] SCRIPT
**
** Create a new SQL function called NAME. Whenever that function is
** called, invoke SCRIPT to evaluate the function.
+ **
+ ** Options:
+ ** --argcount N Function has exactly N arguments
+ ** --deterministic The function is pure
+ ** --directonly Prohibit use inside triggers and views
+ ** --returntype TYPE Specify the return type of the function
*/
case DB_FUNCTION: {
int flags = SQLITE_UTF8;
if( n>1 && strncmp(z, "-deterministic",n)==0 ){
flags |= SQLITE_DETERMINISTIC;
}else
+ if( n>1 && strncmp(z, "-directonly",n)==0 ){
+ flags |= SQLITE_DIRECTONLY;
+ }else
if( n>1 && strncmp(z, "-returntype", n)==0 ){
const char *azType[] = {"integer", "real", "text", "blob", "any", 0};
assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 );
eType++;
}else{
Tcl_AppendResult(interp, "bad option \"", z,
- "\": must be -argcount, -deterministic or -returntype", (char*)0
+ "\": must be -argcount, -deterministic, -directonly,"
+ " or -returntype", (char*)0
);
return TCL_ERROR;
}
#endif
}
if( pExpr->op==TK_AGG_FUNCTION ){
- sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
- pExpr->op2, pExpr->u.zToken);
+ sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s",
+ pExpr->op2, pExpr->u.zToken, zFlgs);
}else{
- sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
+ sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs);
}
if( pFarg ){
sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0);
SELECT test_frombind(x.a,y.b,x.c,:123,y.e,x.f,$xyz+y.f) FROM t1 x, t1 y;
} {8}
-
+# 2019-08-15
+# Direct-only functions.
+#
+proc testdirectonly {x} {return [expr {$x*2}]}
+do_test func-33.1 {
+ db func testdirectonly -directonly testdirectonly
+ db eval {SELECT testdirectonly(15)}
+} {30}
+do_catchsql_test func-33.2 {
+ CREATE VIEW v33(y) AS SELECT testdirectonly(15);
+ SELECT * FROM v33;
+} {1 {testdirectonly() prohibited in triggers and views}}
+do_execsql_test func-33.3 {
+ SELECT * FROM (SELECT testdirectonly(15)) AS v33;
+} {30}
+do_execsql_test func-33.4 {
+ WITH c(x) AS (SELECT testdirectonly(15))
+ SELECT * FROM c;
+} {30}
+do_catchsql_test func-33.5 {
+ WITH c(x) AS (SELECT * FROM v33)
+ SELECT * FROM c;
+} {1 {testdirectonly() prohibited in triggers and views}}
+do_execsql_test func-33.10 {
+ CREATE TABLE t33a(a,b);
+ CREATE TABLE t33b(x,y);
+ CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN
+ INSERT INTO t33b(x,y) VALUES(testdirectonly(new.a),new.b);
+ END;
+} {}
+do_catchsql_test func-33.11 {
+ INSERT INTO t33a VALUES(1,2);
+} {1 {testdirectonly() prohibited in triggers and views}}
+do_execsql_test func-33.20 {
+ ALTER TABLE t33a RENAME COLUMN a TO aaa;
+ SELECT sql FROM sqlite_master WHERE name='r1';
+} {{CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN
+ INSERT INTO t33b(x,y) VALUES(testdirectonly(new.aaa),new.b);
+ END}}
finish_test
do_test 17.6.3 {
list [catch { db function xyz -n object ret } msg] $msg
-} {1 {bad option "-n": must be -argcount, -deterministic or -returntype}}
+} {1 {bad option "-n": must be -argcount, -deterministic, -directonly, or -returntype}}
# 2019-02-28: The "bind_fallback" command.
#