Allow the DEFAULT value of a column to be obtained by calling a
function that has constant arguments, such as julianday('now'). (CVS 2534)
FossilOrigin-Name: d273766ef2442eb87971b07f9ecf5682c88298ee
diff --git a/src/build.c b/src/build.c
index d9d5bb4..f03a40d 100644
--- a/src/build.c
+++ b/src/build.c
@@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.329 2005/06/25 18:42:14 drh Exp $
+** $Id: build.c,v 1.330 2005/06/30 17:04:21 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -977,7 +977,7 @@
Column *pCol;
if( (p = pParse->pNewTable)==0 ) return;
pCol = &(p->aCol[p->nCol-1]);
- if( !sqlite3ExprIsConstant(pExpr) ){
+ if( !sqlite3ExprIsConstantOrFunction(pExpr) ){
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
pCol->zName);
}else{
diff --git a/src/expr.c b/src/expr.c
index efac977..26985fa 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.208 2005/06/25 18:42:14 drh Exp $
+** $Id: expr.c,v 1.209 2005/06/30 17:04:21 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -665,11 +665,15 @@
*/
static int exprNodeIsConstant(void *pArg, Expr *pExpr){
switch( pExpr->op ){
+ /* Consider functions to be constant if all their arguments are constant
+ ** and *pArg==2 */
+ case TK_FUNCTION:
+ if( *((int*)pArg)==2 ) return 0;
+ /* Fall through */
case TK_ID:
case TK_COLUMN:
case TK_DOT:
case TK_AGG_FUNCTION:
- case TK_FUNCTION:
#ifndef SQLITE_OMIT_SUBQUERY
case TK_SELECT:
case TK_EXISTS:
@@ -683,7 +687,7 @@
/*
** Walk an expression tree. Return 1 if the expression is constant
-** and 0 if it involves variables.
+** and 0 if it involves variables or function calls.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
@@ -696,6 +700,21 @@
}
/*
+** Walk an expression tree. Return 1 if the expression is constant
+** or a function call with constant arguments. Return and 0 if there
+** are any variables.
+**
+** For the purposes of this function, a double-quoted string (ex: "abc")
+** is considered a variable but a single-quoted string (ex: 'abc') is
+** a constant.
+*/
+int sqlite3ExprIsConstantOrFunction(Expr *p){
+ int isConst = 2;
+ walkExprTree(p, exprNodeIsConstant, &isConst);
+ return isConst!=0;
+}
+
+/*
** If the expression p codes a constant integer that is small enough
** to fit in a 32-bit integer, return 1 and put the value of the integer
** in *pValue. If the expression is not an integer or if it is too big
diff --git a/src/parse.y b/src/parse.y
index bcb0014..f35e336 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
-** @(#) $Id: parse.y,v 1.173 2005/06/25 18:42:14 drh Exp $
+** @(#) $Id: parse.y,v 1.174 2005/06/30 17:04:21 drh Exp $
*/
// All token codes are small integers with #defines that begin with "TK_"
@@ -248,6 +248,7 @@
carg ::= CONSTRAINT nm ccons.
carg ::= ccons.
carg ::= DEFAULT term(X). {sqlite3AddDefaultValue(pParse,X);}
+carg ::= DEFAULT LP expr(X) RP. {sqlite3AddDefaultValue(pParse,X);}
carg ::= DEFAULT PLUS term(X). {sqlite3AddDefaultValue(pParse,X);}
carg ::= DEFAULT MINUS term(X). {
Expr *p = sqlite3Expr(TK_UMINUS, X, 0, 0);
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index cac864c..5579ca0 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.388 2005/06/25 18:42:14 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.389 2005/06/30 17:04:21 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -1436,6 +1436,7 @@
void sqlite3CommitTransaction(Parse*);
void sqlite3RollbackTransaction(Parse*);
int sqlite3ExprIsConstant(Expr*);
+int sqlite3ExprIsConstantOrFunction(Expr*);
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(sqlite3*, Vdbe*, Table*, int, int);