I think that the diagrams on http://www.sqlite.org/lang_createtable.html are the generic parsing and construction rules for "expr" everywhere an "expr" can be used. The text description further down the page describes restrictions and usage particular to the CREATE TABLE statement itself.
Under COLUMN DEFINITIONS you have: The DEFAULT clause specifies a default value to use for the column if no value is explicitly provided by the user when doing an INSERT. If there is no explicit DEFAULT clause attached to a column definition, then the default value of the column is NULL. An explicit DEFAULT clause may specify that the default value is NULL, a string constant, a blob constant, a signed-number, or any constant expression enclosed in parentheses. An explicit default value may also be one of the special case-independent keywords CURRENT_TIME, CURRENT_DATE or CURRENT_TIMESTAMP. For the purposes of the DEFAULT clause, an expression is considered constant provided that it does not contain any sub-queries, column or table references, or string literals enclosed in double-quotes instead of single-quotes. note the "constant expression". The type of "constant" is stated, and that it may also be a constant expression (meaning an expression of constants). 45.7 given literally is a constant. sin(45.7) is a constant expression. Since ? is not a constant, then an expression containing ? is not a constant expression. Perhaps it could be more explicit by saying that bound values are not permitted. Under SQL Data Constraints you will also see that: A CHECK constraint may be attached to a column definition or specified as a table constraint. In practice it makes no difference. Each time a new row is inserted into the table or an existing row is updated, the expression associated with each CHECK constraint is evaluated and cast to a NUMERIC value in the same way as a CAST expression. If the result is zero (integer value 0 or real value 0.0), then a constraint violation has occurred. If the CHECK expression evaluates to NULL, or any other non-zero value, it is not a constraint violation. The expression of a CHECK constraint may not contain a subquery. Nothing in the CREATE TABLE (or any CREATE) can contain a bound value (well, I suppose the parser could render it into text and insert that value literally, but at the moment it does not). This is because the schema is stored as the text of the create statements, so the value of that variable must be available each time the constraint parsed when DML is parsed against the definition. >-----Original Message----- >I'm trying to set a default value for a column in my "CREATE TABLE" >statement. I really, really want to bind the default value (using >sqlite3_bind_*) rather than expressing it in SQL text to avoid the >following problems: > > * SQL injection attacks; > * floating point value rounding in conversion to/from text; > * how else can I set a default value for a binary blob column? > > >The SQL syntax tree for the "CREATE TABLE" statement at >http://www.sqlite.org/lang_createtable.html suggests binding a default >value is permitted. In particular"create-table-stmt:column-def:column- >constraint:expr:" can be a bind parameter. > > >The example code, below, highlights the problem I'm having. The code >creates a table with a bound default value for one of the two columns. >The statement is prepared (no syntax error warning), and the value bound >successfully. But upon inserting a row that requires using the default >parameter, it crashes in function sqlite3ExprCodeTarget(). (Inserting a >row with both column values explicitly set works fine.) > > >Tech details: using sqlite-amalgamation-3080600 on Centos 7, compiling >with GCC4.8.2. > > >Am I making a silly mistake? Or, contrary to the documentation, is >binding a default column value in a "CREATE TABLE" statement not >possible? If it's not possible, can anyone suggest another way to achieve >the goal of avoiding conversion ofdefault column values to SQL text? > > >Many thanks, > >Nathaniel > > >Example code: > > > >#include <stdio.h> >#include <stdlib.h> >#include <sqlite3.h> > >int main(int argc, char* argv[]) >{ > sqlite3 *db = NULL; > sqlite3_stmt *pStmt = NULL; > int c; > > /* Open database */ > c = sqlite3_open_v2( > "test.db", &db, (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE), 0); > if (c) { > fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); > exit(0); > } > > /* Table creation SQL */ > const char *sql = > "CREATE TABLE test_table (" > "name TEXT DEFAULT ('joe'), " > "interest TEXT DEFAULT (?1))"; > > /* Prepare SQL statement */ > c = sqlite3_prepare(db, sql, -1, &pStmt, NULL); > if (c != SQLITE_OK) { > fprintf(stderr, "Can't prepare statement: %s\n", sqlite3_errmsg(db)); > exit(0); > } > > /* Bind SQL statement value */ > const char *golf = "golf"; > c = sqlite3_bind_text(pStmt, 1, golf, -1, SQLITE_STATIC); > if (c != SQLITE_OK) { > fprintf(stderr, "Can't bind statement: %s\n", sqlite3_errmsg(db)); > exit(0); > } > > /* Evaluate SQL statement */ > c = sqlite3_step(pStmt); > if (c != SQLITE_DONE) { > fprintf(stderr, "Can't evaluate statement: %s\n", >sqlite3_errmsg(db)); > exit(0); > } > > /* Destroy prepared SQL statement */ > c = sqlite3_finalize(pStmt); > if (c != SQLITE_OK) { > fprintf(stderr, "Can't destroy statement: %s\n", sqlite3_errmsg(db)); > exit(0); > } > > /* Insert row */ > const char *sql2 = "INSERT INTO test_table (name) VALUES ('jack');"; > char *errmsg = NULL; > c = sqlite3_exec(db, sql2, NULL, NULL, &errmsg); > if (c != SQLITE_OK) { > fprintf(stderr, "Can't insert row: %s\n", errmsg); > exit(0); > } > sqlite3_free(errmsg); > > /* Close database */ > c = sqlite3_close(db); > if (c != SQLITE_OK) { > fprintf(stderr, "Can't close database: %s\n", sqlite3_errmsg(db)); > exit(0); > } > > return 0; >} >_______________________________________________ >sqlite-users mailing list >sqlite-users@sqlite.org >http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users