From 4fdac6c07e1b896cbf6060d61b47669a48a1ebc9 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 16 Mar 2016 19:49:17 +0100 Subject: [PATCH] MDEV-9701: CREATE VIEW with GROUP BY or ORDER BY and constant produces invalid definition Fixed printing integer constant in the ORDER clause (MySQL solution) Removed workaround for double resolving counter in the ORDER. --- mysql-test/r/view.result | 19 +++++++++++++++++++ mysql-test/t/view.test | 17 +++++++++++++++++ sql/sql_lex.cc | 36 ++++++++++++++---------------------- sql/sql_select.cc | 6 +++++- sql/sql_union.cc | 11 +++++++++++ 5 files changed, 66 insertions(+), 23 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 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); - } + char buffer[20]; + size_t length= my_snprintf(buffer, 20, "%d", order->counter); + str->append(buffer, (uint) length); } else - (*order->item)->print(str, query_type); + { + /* replace numeric reference with equivalent for ORDER constant */ + if (order->item[0]->type() == Item::INT_ITEM && + order->item[0]->basic_const_item()) + { + /* make it expression instead of integer constant */ + str->append(STRING_WITH_LEN("''")); + } + 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 *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);