diff options
author | Sergei Golubchik <serg@mariadb.org> | 2016-06-26 20:50:28 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2016-06-30 11:43:02 +0200 |
commit | e8bdb73adee78253424fbb1ff782ad12700939a1 (patch) | |
tree | 2b4db8961bf30957812ef8257fbeb82310eedf4d | |
parent | 3205da712440ccc755281850b9e62d38b6133b33 (diff) | |
download | mariadb-git-e8bdb73adee78253424fbb1ff782ad12700939a1.tar.gz |
function DEFAULT(x) now works for expression defaults
-rw-r--r-- | mysql-test/r/default.result | 11 | ||||
-rw-r--r-- | mysql-test/r/func_default.result | 11 | ||||
-rw-r--r-- | mysql-test/t/default.test | 7 | ||||
-rw-r--r-- | mysql-test/t/func_default.test | 12 | ||||
-rw-r--r-- | sql/item.cc | 54 | ||||
-rw-r--r-- | sql/item.h | 9 |
6 files changed, 92 insertions, 12 deletions
diff --git a/mysql-test/r/default.result b/mysql-test/r/default.result index f2ec5fa4951..ba8093ba025 100644 --- a/mysql-test/r/default.result +++ b/mysql-test/r/default.result @@ -413,11 +413,11 @@ ERROR 01000: Expression for field `a` is refering to uninitialized field `b` create or replace table t1 (a int default 1, b int as (c), c int as (a+1)); ERROR 01000: Expression for field `b` is refering to uninitialized field `c` CREATE TABLE t1 (a INT DEFAULT (DEFAULT(a))); -ERROR HY000: Field 'a' doesn't have a default value +ERROR 01000: Expression for field `a` is refering to uninitialized field `a` CREATE TABLE t1 (a INT DEFAULT(DEFAULT(b)), b INT DEFAULT(DEFAULT(a))); -ERROR HY000: Field 'b' doesn't have a default value +ERROR 01000: Expression for field `a` is refering to uninitialized field `b` CREATE TABLE t1 (a INT DEFAULT(DEFAULT(b)) NOT NULL, b INT DEFAULT(DEFAULT(a)) NOT NULL); -ERROR HY000: Field 'b' doesn't have a default value +ERROR 01000: Expression for field `a` is refering to uninitialized field `b` # # Allow defaults to refer to not default fields # @@ -1193,7 +1193,10 @@ a b 2 2 6 1000 select default(a),b from t1; -ERROR HY000: Field 'a' doesn't have a default value +default(a) b +6 1 +6 2 +6 1000 select a,default(b) from t1; a default(b) 1 1000 diff --git a/mysql-test/r/func_default.result b/mysql-test/r/func_default.result index 8f486d87d47..aac5f4942a7 100644 --- a/mysql-test/r/func_default.result +++ b/mysql-test/r/func_default.result @@ -21,3 +21,14 @@ INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three'); SELECT s, 32 AS mi FROM t1 GROUP BY s HAVING DEFAULT(mi) IS NULL; ERROR HY000: Field 'mi' doesn't have a default value DROP TABLE t1; +set timestamp=unix_timestamp('2001-01-01 10:20:30.123456'); +create table t1 (a int default 1, b int default (a+1), +c varchar(100) default 'foo', d text default 'bar', +e timestamp default now(), f timestamp(6) default now(2)); +insert t1 () values (); +insert t1 (a) values (10); +select default(a),default(b),default(c),default(d),default(e),default(f) from t1; +default(a) default(b) default(c) default(d) default(e) default(f) +1 2 foo bar 2001-01-01 10:20:30 2001-01-01 10:20:30.123456 +1 11 foo bar 2001-01-01 10:20:30 2001-01-01 10:20:30.123456 +drop table t1; diff --git a/mysql-test/t/default.test b/mysql-test/t/default.test index 4219e0fd11a..1d3487abd9c 100644 --- a/mysql-test/t/default.test +++ b/mysql-test/t/default.test @@ -299,11 +299,11 @@ create or replace table t1 (a int default a); create or replace table t1 (a int default b, b int default (1+1)); --error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD create or replace table t1 (a int default 1, b int as (c), c int as (a+1)); ---error ER_NO_DEFAULT_FOR_FIELD +--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD CREATE TABLE t1 (a INT DEFAULT (DEFAULT(a))); ---error ER_NO_DEFAULT_FOR_FIELD +--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD CREATE TABLE t1 (a INT DEFAULT(DEFAULT(b)), b INT DEFAULT(DEFAULT(a))); ---error ER_NO_DEFAULT_FOR_FIELD +--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD CREATE TABLE t1 (a INT DEFAULT(DEFAULT(b)) NOT NULL, b INT DEFAULT(DEFAULT(a)) NOT NULL); --echo # @@ -879,7 +879,6 @@ SHOW CREATE TABLE t1; insert into t1 values (1,1),(2,2); insert into t1 values (default,default); select * from t1; ---error ER_NO_DEFAULT_FOR_FIELD select default(a),b from t1; select a,default(b) from t1; drop table t1; diff --git a/mysql-test/t/func_default.test b/mysql-test/t/func_default.test index 7bebd4b4b72..fbd73990297 100644 --- a/mysql-test/t/func_default.test +++ b/mysql-test/t/func_default.test @@ -29,3 +29,15 @@ INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three'); SELECT s, 32 AS mi FROM t1 GROUP BY s HAVING DEFAULT(mi) IS NULL; DROP TABLE t1; +# +# 10.2 tests +# + +set timestamp=unix_timestamp('2001-01-01 10:20:30.123456'); +create table t1 (a int default 1, b int default (a+1), + c varchar(100) default 'foo', d text default 'bar', + e timestamp default now(), f timestamp(6) default now(2)); +insert t1 () values (); +insert t1 (a) values (10); +select default(a),default(b),default(c),default(d),default(e),default(f) from t1; +drop table t1; diff --git a/sql/item.cc b/sql/item.cc index 7c93c5eed73..c4385b99d39 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -8211,8 +8211,7 @@ bool Item_default_value::fix_fields(THD *thd, Item **items) } field_arg= (Item_field *)real_arg; - if ((field_arg->field->flags & NO_DEFAULT_VALUE_FLAG) || - field_arg->field->default_value) + if ((field_arg->field->flags & NO_DEFAULT_VALUE_FLAG)) { my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), field_arg->field->field_name); goto error; @@ -8225,6 +8224,12 @@ bool Item_default_value::fix_fields(THD *thd, Item **items) (def_field->table->s->default_values - def_field->table->record[0])); set_field(def_field); + if (field->default_value) + { + if (field->default_value->expr_item) // it's NULL during CREATE TABLE + field->default_value->expr_item->walk(&Item::register_field_in_read_map, 1, 0); + IF_DBUG(def_field->is_stat_field=1,); // a hack to fool ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED + } return FALSE; error: @@ -8245,10 +8250,53 @@ void Item_default_value::print(String *str, enum_query_type query_type) str->append(')'); } +void Item_default_value::calculate() +{ + if (field->default_value || field->has_insert_default_function()) + field->set_default(); +} + +String *Item_default_value::val_str(String *str) +{ + calculate(); + return Item_field::val_str(str); +} + +double Item_default_value::val_real() +{ + calculate(); + return Item_field::val_real(); +} + +longlong Item_default_value::val_int() +{ + calculate(); + return Item_field::val_int(); +} + +my_decimal *Item_default_value::val_decimal(my_decimal *decimal_value) +{ + calculate(); + return Item_field::val_decimal(decimal_value); +} + +bool Item_default_value::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) +{ + calculate(); + return Item_field::get_date(ltime, fuzzydate); +} + +bool Item_default_value::send(Protocol *protocol, String *buffer) +{ + calculate(); + return Item_field::send(protocol, buffer); +} int Item_default_value::save_in_field(Field *field_arg, bool no_conversions) { - if (!arg) + if (arg) + calculate(); + else { TABLE *table= field_arg->table; THD *thd= table->in_use; diff --git a/sql/item.h b/sql/item.h index 0a526e09bed..9794d987be1 100644 --- a/sql/item.h +++ b/sql/item.h @@ -4877,6 +4877,7 @@ public: class Item_default_value : public Item_field { + void calculate(); public: Item *arg; Item_default_value(THD *thd, Name_resolution_context *context_arg) @@ -4890,7 +4891,13 @@ public: enum Type type() const { return DEFAULT_VALUE_ITEM; } bool eq(const Item *item, bool binary_cmp) const; bool fix_fields(THD *, Item **); - virtual void print(String *str, enum_query_type query_type); + void print(String *str, enum_query_type query_type); + String *val_str(String *str); + double val_real(); + longlong val_int(); + my_decimal *val_decimal(my_decimal *decimal_value); + bool get_date(MYSQL_TIME *ltime,ulonglong fuzzydate); + bool send(Protocol *protocol, String *buffer); int save_in_field(Field *field_arg, bool no_conversions); table_map used_tables() const { return (table_map)0L; } |