Do not allow parameters in a DEFAULT clause of a CREATE TABLE statement.

Ticket [78c0c8c3c9f7c1].

FossilOrigin-Name: 1ad2bc1ed4c4ac81ac67a9660761f0eeb47c7fef
This commit is contained in:
drh 2014-09-24 13:20:22 +00:00
parent 9bfdc25062
commit feada2df39
6 changed files with 73 additions and 23 deletions

@ -1,5 +1,5 @@
C Have\sthe\sclearCell()\sroutine\sreturn\sthe\scell\ssize\sto\sthe\scaller,\srather\nthan\shave\sthe\scaller\smake\sa\sseparate\scall\sto\scellSizePtr().
D 2014-09-24T02:05:41.968
C Do\snot\sallow\sparameters\sin\sa\sDEFAULT\sclause\sof\sa\sCREATE\sTABLE\sstatement.\nTicket\s[78c0c8c3c9f7c1].
D 2014-09-24T13:20:22.559
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -175,13 +175,13 @@ F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5
F src/btree.c 183d62b37358f95d2ffac796f8491591a3456362
F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
F src/btreeInt.h 9db0d303b203d18871dc9a1d78a3e1ae4d62c1ef
F src/build.c 8dbca25988045fbf2a33c9631c42706fa6449e60
F src/build.c bde83dd5cf812e310a7e5ad2846790a14745bef4
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14
F src/ctime.c 16cd19215d9fd849ee2b7509b092f2e0bbd6a958
F src/date.c 57a7f9ba9f6b4d5268f5e411739066a611f99036
F src/delete.c fae81cc2eb14b75267d4f47d3cfc9ae02aae726f
F src/expr.c 4f101c8ddc6d5a22303c88278069f5261562a9a8
F src/expr.c f32119248996680aa73c5c37bfdd42820804dc17
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7
F src/func.c 1629ccdd8ef3f19d7accc9d9287190489469ff81
@ -232,7 +232,7 @@ F src/shell.c dad23987c34faddb061a339da3e92e05ccc6935e
F src/sqlite.h.in 8b018219ce988913e5977d5de9ab4beb33be23b6
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
F src/sqliteInt.h 5ecde2191721a94cdce0d5248e26a373e0b17a70
F src/sqliteInt.h ca777ba045b1849d36a44dee1c71c652ae915093
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2e99ef7ef16187e17033d9398dc962ce22dab5cb
@ -438,7 +438,7 @@ F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0
F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204
F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2
F test/default.test 792c3c70836f1901e2a8cb34fa0880ed71e2c1a9
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
@ -1200,7 +1200,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 5dd41cdbfebdd088ebd9a90a394ee296c207ad90
R c3c34442c09fda273806b002932cda25
P f21d217583c205dc17f98bb4877fd4ed98cefcb1
R 0c35c4c692384a20d9dc945800977dcf
U drh
Z 4d0ec3d41d82b7fff44b33f0ea314f2b
Z ea463bda0fe2fcb1086a67d4498e377c

@ -1 +1 @@
f21d217583c205dc17f98bb4877fd4ed98cefcb1
1ad2bc1ed4c4ac81ac67a9660761f0eeb47c7fef

@ -1236,7 +1236,7 @@ void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
p = pParse->pNewTable;
if( p!=0 ){
pCol = &(p->aCol[p->nCol-1]);
if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr) ){
if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
pCol->zName);
}else{

@ -1212,32 +1212,40 @@ void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
/*
** These routines are Walker callbacks. Walker.u.pi is a pointer
** to an integer. These routines are checking an expression to see
** if it is a constant. Set *Walker.u.pi to 0 if the expression is
** if it is a constant. Set *Walker.u.i to 0 if the expression is
** not constant.
**
** These callback routines are used to implement the following:
**
** sqlite3ExprIsConstant()
** sqlite3ExprIsConstantNotJoin()
** sqlite3ExprIsConstantOrFunction()
** sqlite3ExprIsConstant() pWalker->u.i==1
** sqlite3ExprIsConstantNotJoin() pWalker->u.i==2
** sqlite3ExprIsConstantOrFunction() pWalker->u.i==3 or 4
**
** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions
** in a CREATE TABLE statement. The Walker.u.i value is 4 when parsing
** an existing schema and 3 when processing a new statement. A bound
** parameter raises an error for new statements, but is silently converted
** to NULL for existing schemas. This allows sqlite_master tables that
** contain a bound parameter because they were generated by older versions
** of SQLite to be parsed by newer versions of SQLite without raising a
** malformed schema error.
*/
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
/* If pWalker->u.i is 3 then any term of the expression that comes from
/* If pWalker->u.i is 2 then any term of the expression that comes from
** the ON or USING clauses of a join disqualifies the expression
** from being considered constant. */
if( pWalker->u.i==3 && ExprHasProperty(pExpr, EP_FromJoin) ){
if( pWalker->u.i==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
pWalker->u.i = 0;
return WRC_Abort;
}
switch( pExpr->op ){
/* Consider functions to be constant if all their arguments are constant
** and either pWalker->u.i==2 or the function as the SQLITE_FUNC_CONST
** and either pWalker->u.i==3 or 4 or the function as the SQLITE_FUNC_CONST
** flag. */
case TK_FUNCTION:
if( pWalker->u.i==2 || ExprHasProperty(pExpr,EP_Constant) ){
if( pWalker->u.i>=3 || ExprHasProperty(pExpr,EP_Constant) ){
return WRC_Continue;
}
/* Fall through */
@ -1251,6 +1259,19 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_AGG_COLUMN );
pWalker->u.i = 0;
return WRC_Abort;
case TK_VARIABLE:
if( pWalker->u.i==4 ){
/* Silently convert bound parameters that appear inside of CREATE
** statements into a NULL when parsing the CREATE statement text out
** of the sqlite_master table */
pExpr->op = TK_NULL;
}else if( pWalker->u.i==3 ){
/* A bound parameter in a CREATE statement that originates from
** sqlite3_prepare() causes an error */
pWalker->u.i = 0;
return WRC_Abort;
}
/* Fall through */
default:
testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
@ -1291,7 +1312,7 @@ int sqlite3ExprIsConstant(Expr *p){
** an ON or USING clause.
*/
int sqlite3ExprIsConstantNotJoin(Expr *p){
return exprIsConst(p, 3);
return exprIsConst(p, 2);
}
/*
@ -1303,8 +1324,9 @@ int sqlite3ExprIsConstantNotJoin(Expr *p){
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
int sqlite3ExprIsConstantOrFunction(Expr *p){
return exprIsConst(p, 2);
int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
assert( isInit==0 || isInit==1 );
return exprIsConst(p, 3+isInit);
}
/*

@ -3285,7 +3285,7 @@ void sqlite3CloseSavepoints(sqlite3 *);
void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3ExprCanBeNull(const Expr*);
int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);

@ -99,4 +99,32 @@ do_execsql_test default-3.3 {
SELECT * FROM t300;
} {2147483647 2147483648 9223372036854775807 -2147483647 -2147483648 -9223372036854775808 9.22337203685478e+18 9223372036854775807}
# Do now allow bound parameters in new DEFAULT values.
# Silently convert bound parameters to NULL in DEFAULT causes
# in the sqlite_master table, for backwards compatibility.
#
db close
forcedelete test.db
sqlite3 db test.db
do_execsql_test default-4.0 {
CREATE TABLE t1(a TEXT, b TEXT DEFAULT(99));
PRAGMA writable_schema=ON;
UPDATE sqlite_master SET sql='CREATE TABLE t1(a TEXT, b TEXT DEFAULT(:xyz))';
} {}
db close
sqlite3 db test.db
do_execsql_test default-4.1 {
INSERT INTO t1(a) VALUES('xyzzy');
SELECT a, quote(b) FROM t1;
} {xyzzy NULL}
do_catchsql_test default-4.2 {
CREATE TABLE t2(a TEXT, b TEXT DEFAULT(:xyz));
} {1 {default value of column [b] is not constant}}
do_catchsql_test default-4.3 {
CREATE TABLE t2(a TEXT, b TEXT DEFAULT(abs(:xyz)));
} {1 {default value of column [b] is not constant}}
do_catchsql_test default-4.4 {
CREATE TABLE t2(a TEXT, b TEXT DEFAULT(98+coalesce(5,:xyz)));
} {1 {default value of column [b] is not constant}}
finish_test