diff options
-rw-r--r-- | mysql-test/r/view.result | 19 | ||||
-rw-r--r-- | mysql-test/t/view.test | 17 | ||||
-rw-r--r-- | sql/sql_lex.cc | 32 | ||||
-rw-r--r-- | sql/sql_select.cc | 6 | ||||
-rw-r--r-- | sql/sql_union.cc | 11 |
5 files changed, 64 insertions, 21 deletions
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 8ee72c35d0b..d4a2a9b1b79 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -826,6 +826,9 @@ drop table t2; create table t1 (a int); insert into t1 values (1), (2); create view v1 as select 5 from t1 order by 1; +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 5 AS `5` from `t1` order by 1 latin1 latin1_swedish_ci select * from v1; 5 5 @@ -5884,5 +5887,21 @@ a DROP VIEW v1; DROP TABLE t1; # +# MDEV-9701: CREATE VIEW with GROUP BY or ORDER BY and constant +# produces invalid definition +# +CREATE TABLE t1 ( i INT ); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS +SELECT 3 AS three, COUNT(*) FROM t1 GROUP BY three; +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 3 AS `three`,count(0) AS `COUNT(*)` from `t1` group by '' latin1 latin1_swedish_ci +SELECT * FROM v1; +three COUNT(*) +3 2 +drop view v1; +drop table t1; +# # End of 10.1 tests # diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 3132b99b2b7..f1288e6a63d 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -731,6 +731,7 @@ drop table t2; create table t1 (a int); insert into t1 values (1), (2); create view v1 as select 5 from t1 order by 1; +show create view v1; select * from v1; drop view v1; drop table t1; @@ -5747,6 +5748,22 @@ SELECT * FROM v1 WHERE a=_latin1'a' COLLATE latin1_bin; DROP VIEW v1; DROP TABLE t1; +--echo # +--echo # MDEV-9701: CREATE VIEW with GROUP BY or ORDER BY and constant +--echo # produces invalid definition +--echo # +CREATE TABLE t1 ( i INT ); +INSERT INTO t1 VALUES (1),(2); + +CREATE VIEW v1 AS +SELECT 3 AS three, COUNT(*) FROM t1 GROUP BY three; + +show create view v1; + +SELECT * FROM v1; + +drop view v1; +drop table t1; --echo # --echo # End of 10.1 tests diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index fd841094e68..31fc5f9712c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2689,30 +2689,22 @@ void st_select_lex::print_order(String *str, { if (order->counter_used) { - if (!(query_type & QT_VIEW_INTERNAL)) + char buffer[20]; + size_t length= my_snprintf(buffer, 20, "%d", order->counter); + str->append(buffer, (uint) length); + } + else + { + /* replace numeric reference with equivalent for ORDER constant */ + if (order->item[0]->type() == Item::INT_ITEM && + order->item[0]->basic_const_item()) { - char buffer[20]; - size_t length= my_snprintf(buffer, 20, "%d", order->counter); - str->append(buffer, (uint) length); + /* make it expression instead of integer constant */ + str->append(STRING_WITH_LEN("''")); } else - { - /* replace numeric reference with expression */ - if (order->item[0]->type() == Item::INT_ITEM && - order->item[0]->basic_const_item()) - { - char buffer[20]; - size_t length= my_snprintf(buffer, 20, "%d", order->counter); - str->append(buffer, (uint) length); - /* make it expression instead of integer constant */ - str->append(STRING_WITH_LEN("+0")); - } - else - (*order->item)->print(str, query_type); - } + (*order->item)->print(str, query_type); } - else - (*order->item)->print(str, query_type); if (!order->asc) str->append(STRING_WITH_LEN(" desc")); if (order->next) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fff24b97e6a..f14e8b1a5f8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -21874,7 +21874,11 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, */ if (order_item->type() == Item::INT_ITEM && order_item->basic_const_item()) { /* Order by position */ - uint count= (uint) order_item->val_int(); + uint count; + if (order->counter_used) + count= order->counter; // counter was once resolved + else + count= (uint) order_item->val_int(); if (!count || count > fields.elements) { my_error(ER_BAD_FIELD_ERROR, MYF(0), diff --git a/sql/sql_union.cc b/sql/sql_union.cc index c8350838ee8..8145cec5f25 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -1161,11 +1161,22 @@ List<Item> *st_select_lex_unit::get_unit_column_types() return &sl->item_list; } + +static void cleanup_order(ORDER *order) +{ + for (; order; order= order->next) + order->counter_used= 0; +} + + bool st_select_lex::cleanup() { bool error= FALSE; DBUG_ENTER("st_select_lex::cleanup()"); + cleanup_order(order_list.first); + cleanup_order(group_list.first); + if (join) { DBUG_ASSERT((st_select_lex*)join->select_lex == this); |