diff --git a/core/translate/insert.rs b/core/translate/insert.rs index 53368d30b..5fda098e6 100644 --- a/core/translate/insert.rs +++ b/core/translate/insert.rs @@ -297,6 +297,8 @@ struct ColumnMapping<'a> { /// If Some(i), use the i-th value from the VALUES tuple /// If None, use NULL (column was not specified in INSERT statement) value_index: Option, + /// The default value for the column, if defined + default_value: Option<&'a Expr>, } /// Resolves how each column in a table should be populated during an INSERT. @@ -352,6 +354,7 @@ fn resolve_columns_for_insert<'a>( .map(|(i, col)| ColumnMapping { column: col, value_index: if i < num_values { Some(i) } else { None }, + default_value: col.default.as_ref(), }) .collect()); } @@ -362,6 +365,7 @@ fn resolve_columns_for_insert<'a>( .map(|col| ColumnMapping { column: col, value_index: None, + default_value: col.default.as_ref(), }) .collect(); @@ -423,8 +427,10 @@ fn populate_column_registers( if write_directly_to_rowid_reg { program.emit_insn(Insn::SoftNull { reg: target_reg }); } + } else if let Some(default_expr) = mapping.default_value { + translate_expr(program, None, default_expr, target_reg, resolver)?; } else { - // Column was not specified - use NULL if it is nullable, otherwise error + // Column was not specified as has no DEFAULT - use NULL if it is nullable, otherwise error // Rowid alias columns can be NULL because we will autogenerate a rowid in that case. let is_nullable = !mapping.column.primary_key || mapping.column.is_rowid_alias; if is_nullable { diff --git a/testing/all.test b/testing/all.test index 857224ef6..dc12c331a 100755 --- a/testing/all.test +++ b/testing/all.test @@ -28,3 +28,4 @@ source $testdir/scalar-functions-printf.test source $testdir/transactions.test source $testdir/update.test source $testdir/drop_table.test +source $testdir/default_value.test diff --git a/testing/default_value.test b/testing/default_value.test new file mode 100644 index 000000000..32a39144b --- /dev/null +++ b/testing/default_value.test @@ -0,0 +1,43 @@ +#!/usr/bin/env tclsh + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test_on_specific_db {:memory:} default-value-text { + CREATE TABLE t1(x INTEGER PRIMARY KEY, y TEXT DEFAULT 'default_value'); + INSERT INTO t1 (x) VALUES (1); + SELECT y FROM t1 WHERE x = 1; +} {default_value} + +do_execsql_test_on_specific_db {:memory:} default-value-integer { + CREATE TABLE t2(x INTEGER PRIMARY KEY, y INTEGER DEFAULT 42); + INSERT INTO t2 (x) VALUES (1); + SELECT y FROM t2 WHERE x = 1; +} {42} + +do_execsql_test_on_specific_db {:memory:} default-value-real { + CREATE TABLE t3(x INTEGER PRIMARY KEY, y REAL DEFAULT 3.14); + INSERT INTO t3 (x) VALUES (1); + SELECT y FROM t3 WHERE x = 1; +} {3.14} + +do_execsql_test_on_specific_db {:memory:} default-value-null { + CREATE TABLE t5(x INTEGER PRIMARY KEY, y TEXT DEFAULT NULL); + INSERT INTO t5 (x) VALUES (1); + SELECT y FROM t5 WHERE x = 1; +} {} + +do_execsql_test_on_specific_db {:memory:} default-value-boolean { + CREATE TABLE t6(x INTEGER PRIMARY KEY, y BOOLEAN DEFAULT 1); + INSERT INTO t6 (x) VALUES (1); + SELECT y FROM t6 WHERE x = 1; +} {1} + +do_execsql_test_on_specific_db {:memory:} default-value-function { + CREATE TABLE t7(x INTEGER PRIMARY KEY, y INTEGER DEFAULT (ABS(-5))); + INSERT INTO t7 (x) VALUES (1); + SELECT y FROM t7 WHERE x = 1; +} {5} + + +