summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2016-06-26 20:50:28 +0200
committerSergei Golubchik <serg@mariadb.org>2016-06-30 11:43:02 +0200
commite8bdb73adee78253424fbb1ff782ad12700939a1 (patch)
tree2b4db8961bf30957812ef8257fbeb82310eedf4d
parent3205da712440ccc755281850b9e62d38b6133b33 (diff)
downloadmariadb-git-e8bdb73adee78253424fbb1ff782ad12700939a1.tar.gz
function DEFAULT(x) now works for expression defaults
-rw-r--r--mysql-test/r/default.result11
-rw-r--r--mysql-test/r/func_default.result11
-rw-r--r--mysql-test/t/default.test7
-rw-r--r--mysql-test/t/func_default.test12
-rw-r--r--sql/item.cc54
-rw-r--r--sql/item.h9
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; }