summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/view.result19
-rw-r--r--mysql-test/t/view.test17
-rw-r--r--sql/sql_lex.cc32
-rw-r--r--sql/sql_select.cc6
-rw-r--r--sql/sql_union.cc11
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);