=== modified file 'mysql-test/r/group_by.result'
--- mysql-test/r/group_by.result	2012-11-22 18:30:39 +0000
+++ mysql-test/r/group_by.result	2013-01-24 14:35:26 +0000
@@ -2056,6 +2056,251 @@ col2
 
 DROP TABLE t1,t2;
 #
+# MDEV-641 LP:1002108 - Wrong result (or crash) from a query with duplicated field in the group list and a limit clause
+# Bug#11761078: 53534: INCORRECT 'SELECT SQL_BIG_RESULT...' 
+#               WITH GROUP BY ON DUPLICATED FIELDS
+#
+CREATE TABLE t1(
+col1 int, 
+UNIQUE INDEX idx (col1)
+);
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),
+(11),(12),(13),(14),(15),(16),(17),(18),(19),(20);
+EXPLAIN SELECT col1 AS field1, col1 AS field2
+FROM t1 GROUP BY field1, field2;;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	NULL	idx	5	NULL	7	Using index for group-by
+FLUSH STATUS;
+SELECT col1 AS field1, col1 AS field2
+FROM t1 GROUP BY field1, field2;;
+field1	field2
+1	1
+2	2
+3	3
+4	4
+5	5
+6	6
+7	7
+8	8
+9	9
+10	10
+11	11
+12	12
+13	13
+14	14
+15	15
+16	16
+17	17
+18	18
+19	19
+20	20
+SHOW SESSION STATUS LIKE 'Sort_scan%';
+Variable_name	Value
+Sort_scan	0
+EXPLAIN SELECT SQL_BIG_RESULT col1 AS field1, col1 AS field2
+FROM t1 GROUP BY field1, field2;;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	NULL	idx	5	NULL	7	Using index for group-by
+FLUSH STATUS;
+SELECT SQL_BIG_RESULT col1 AS field1, col1 AS field2
+FROM t1 GROUP BY field1, field2;;
+field1	field2
+1	1
+2	2
+3	3
+4	4
+5	5
+6	6
+7	7
+8	8
+9	9
+10	10
+11	11
+12	12
+13	13
+14	14
+15	15
+16	16
+17	17
+18	18
+19	19
+20	20
+SHOW SESSION STATUS LIKE 'Sort_scan%';
+Variable_name	Value
+Sort_scan	0
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT SQL_BIG_RESULT col1 AS field1, col1 AS field2
+FROM v1 
+GROUP BY field1, field2;
+field1	field2
+1	1
+2	2
+3	3
+4	4
+5	5
+6	6
+7	7
+8	8
+9	9
+10	10
+11	11
+12	12
+13	13
+14	14
+15	15
+16	16
+17	17
+18	18
+19	19
+20	20
+SELECT SQL_BIG_RESULT tbl1.col1 AS field1, tbl2.col1 AS field2
+FROM t1 as tbl1, t1 as tbl2 
+GROUP BY field1, field2 
+LIMIT 3;
+field1	field2
+1	1
+1	2
+1	3
+explain
+select col1 f1, col1 f2 from t1 order by f2, f1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	idx	5	NULL	20	Using index
+select col1 f1, col1 f2 from t1 order by f2, f1;
+f1	f2
+1	1
+2	2
+3	3
+4	4
+5	5
+6	6
+7	7
+8	8
+9	9
+10	10
+11	11
+12	12
+13	13
+14	14
+15	15
+16	16
+17	17
+18	18
+19	19
+20	20
+explain
+select col1 f1, col1 f2 from t1 group by f2 order by f2, f1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	NULL	idx	5	NULL	7	Using index for group-by
+select col1 f1, col1 f2 from t1 group by f2 order by f2, f1;
+f1	f2
+1	1
+2	2
+3	3
+4	4
+5	5
+6	6
+7	7
+8	8
+9	9
+10	10
+11	11
+12	12
+13	13
+14	14
+15	15
+16	16
+17	17
+18	18
+19	19
+20	20
+explain
+select col1 f1, col1 f2 from t1 group by f1, f2 order by f2, f1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	NULL	idx	5	NULL	7	Using index for group-by
+select col1 f1, col1 f2 from t1 group by f1, f2 order by f2, f1;
+f1	f2
+1	1
+2	2
+3	3
+4	4
+5	5
+6	6
+7	7
+8	8
+9	9
+10	10
+11	11
+12	12
+13	13
+14	14
+15	15
+16	16
+17	17
+18	18
+19	19
+20	20
+CREATE TABLE t2(
+col1 int, 
+col2 int, 
+UNIQUE INDEX idx (col1, col2));
+INSERT INTO t2(col1, col2) VALUES
+(1,20),(2,19),(3,18),(4,17),(5,16),(6,15),(7,14),(8,13),(9,12),(10,11),
+(11,10),(12,9),(13,8),(14,7),(15,6),(16,5),(17,4),(18,3),(19,2),(20,1);
+explain
+select col1 f1, col2 f2, col1 f3 from t2 group by f1, f2, f3;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	range	NULL	idx	10	NULL	7	Using index for group-by
+select col1 f1, col2 f2, col1 f3 from t2 group by f1, f2, f3;
+f1	f2	f3
+1	20	1
+2	19	2
+3	18	3
+4	17	4
+5	16	5
+6	15	6
+7	14	7
+8	13	8
+9	12	9
+10	11	10
+11	10	11
+12	9	12
+13	8	13
+14	7	14
+15	6	15
+16	5	16
+17	4	17
+18	3	18
+19	2	19
+20	1	20
+explain
+select col1 f1, col2 f2, col1 f3 from t2 order by f1, f2, f3;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	index	NULL	idx	10	NULL	20	Using index
+select col1 f1, col2 f2, col1 f3 from t2 order by f1, f2, f3;
+f1	f2	f3
+1	20	1
+2	19	2
+3	18	3
+4	17	4
+5	16	5
+6	15	6
+7	14	7
+8	13	8
+9	12	9
+10	11	10
+11	10	11
+12	9	12
+13	8	13
+14	7	14
+15	6	15
+16	5	16
+17	4	17
+18	3	18
+19	2	19
+20	1	20
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
 # BUG#12640437: USING SQL_BUFFER_RESULT RESULTS IN A
 #               DIFFERENT QUERY OUTPUT
 #

=== modified file 'mysql-test/t/group_by.test'
--- mysql-test/t/group_by.test	2012-11-22 18:30:39 +0000
+++ mysql-test/t/group_by.test	2013-01-24 14:35:26 +0000
@@ -1415,6 +1415,81 @@ let $q_body=t2.col2 FROM t2 JOIN t1 ON t
 DROP TABLE t1,t2;
 
 --echo #
+--echo # MDEV-641 LP:1002108 - Wrong result (or crash) from a query with duplicated field in the group list and a limit clause
+--echo # Bug#11761078: 53534: INCORRECT 'SELECT SQL_BIG_RESULT...' 
+--echo #               WITH GROUP BY ON DUPLICATED FIELDS
+--echo #
+
+CREATE TABLE t1(
+ col1 int, 
+ UNIQUE INDEX idx (col1)
+);
+
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),
+   (11),(12),(13),(14),(15),(16),(17),(18),(19),(20);
+
+let $query0=SELECT col1 AS field1, col1 AS field2
+            FROM t1 GROUP BY field1, field2;
+
+# Needs to be range to exercise bug
+--eval EXPLAIN $query0;
+FLUSH STATUS;
+--eval $query0;
+SHOW SESSION STATUS LIKE 'Sort_scan%';
+
+let $query=SELECT SQL_BIG_RESULT col1 AS field1, col1 AS field2
+           FROM t1 GROUP BY field1, field2;
+
+# Needs to be range to exercise bug
+--eval EXPLAIN $query;
+FLUSH STATUS;
+--eval $query;
+SHOW SESSION STATUS LIKE 'Sort_scan%';
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT SQL_BIG_RESULT col1 AS field1, col1 AS field2
+FROM v1 
+GROUP BY field1, field2; 
+
+SELECT SQL_BIG_RESULT tbl1.col1 AS field1, tbl2.col1 AS field2
+FROM t1 as tbl1, t1 as tbl2 
+GROUP BY field1, field2 
+LIMIT 3;
+
+explain
+select col1 f1, col1 f2 from t1 order by f2, f1;
+select col1 f1, col1 f2 from t1 order by f2, f1;
+
+explain
+select col1 f1, col1 f2 from t1 group by f2 order by f2, f1;
+select col1 f1, col1 f2 from t1 group by f2 order by f2, f1;
+
+explain
+select col1 f1, col1 f2 from t1 group by f1, f2 order by f2, f1;
+select col1 f1, col1 f2 from t1 group by f1, f2 order by f2, f1;
+
+CREATE TABLE t2(
+ col1 int, 
+ col2 int, 
+ UNIQUE INDEX idx (col1, col2));
+
+INSERT INTO t2(col1, col2) VALUES
+   (1,20),(2,19),(3,18),(4,17),(5,16),(6,15),(7,14),(8,13),(9,12),(10,11),
+   (11,10),(12,9),(13,8),(14,7),(15,6),(16,5),(17,4),(18,3),(19,2),(20,1);
+
+explain
+select col1 f1, col2 f2, col1 f3 from t2 group by f1, f2, f3;
+select col1 f1, col2 f2, col1 f3 from t2 group by f1, f2, f3;
+
+explain
+select col1 f1, col2 f2, col1 f3 from t2 order by f1, f2, f3;
+select col1 f1, col2 f2, col1 f3 from t2 order by f1, f2, f3;
+
+DROP VIEW v1;
+DROP TABLE t1, t2;
+
+--echo #
 --echo # BUG#12640437: USING SQL_BUFFER_RESULT RESULTS IN A
 --echo #               DIFFERENT QUERY OUTPUT
 --echo #

=== modified file 'sql/sql_select.cc'
--- sql/sql_select.cc	2013-01-16 13:11:13 +0000
+++ sql/sql_select.cc	2013-01-24 14:35:26 +0000
@@ -1643,14 +1643,6 @@ JOIN::optimize()
     }
   }
 
-  tmp_having= having;
-  if (select_options & SELECT_DESCRIBE)
-  {
-    error= 0;
-    goto derived_exit;
-  }
-  having= 0;
-
   /*
     The loose index scan access method guarantees that all grouping or
     duplicate row elimination (for distinct) is already performed
@@ -1663,10 +1655,19 @@ JOIN::optimize()
     join_tab element of the plan for its access method.
   */
   if (join_tab->is_using_loose_index_scan())
+  {
     tmp_table_param.precomputed_group_by= TRUE;
+    select_options&= ~SELECT_BIG_RESULT;
+  }
 
+  tmp_having= having;
+  if (select_options & SELECT_DESCRIBE)
+  {
+    error= 0;
+    goto derived_exit;
+  }
+  having= 0;
   error= 0;
-
   DBUG_RETURN(0);
 
 setup_subq_exit:
@@ -2423,8 +2424,10 @@ JOIN::exec()
           functions. See extended comment in JOIN::exec.
         */
         if (curr_join->join_tab->is_using_loose_index_scan())
+        {
           curr_join->tmp_table_param.precomputed_group_by= TRUE;
-
+          curr_join->select_options&= ~SELECT_BIG_RESULT;
+        }
 	if (!(curr_tmp_table=
 	      exec_tmp_table2= create_tmp_table(thd,
 						&curr_join->tmp_table_param,
@@ -10603,6 +10606,33 @@ static void update_depend_map_for_order(
 
 
 /**
+  Test if any element in a list of ORDER elements references the same column.
+
+  @param ord_list    a list of ORDER elements
+  @param find_order  the order element to look for
+
+  @retval TRUE if found
+  @retval FALSE if not found
+*/
+
+static bool find_order_in_order_list(ORDER *ord_list, ORDER *find_order)
+{
+  ORDER *cur_ord;
+  Item *it1= find_order->item[0]->real_item();
+
+  for (cur_ord= ord_list; (cur_ord != find_order && cur_ord);
+       cur_ord= cur_ord->next)
+  {
+    Item *it2= cur_ord->item[0]->real_item();
+    if (it1->type() == Item::FIELD_ITEM && it2->type() == Item::FIELD_ITEM &&
+        ((Item_field*)it1)->field->eq(((Item_field*)it2)->field))
+      return true;
+  }
+  return false;
+}
+
+
+/**
   Remove all constants and check if ORDER only contains simple
   expressions.
 
@@ -10661,7 +10691,13 @@ remove_const(JOIN *join,ORDER *first_ord
   for (order=first_order; order ; order=order->next)
   {
     table_map order_tables=order->item[0]->used_tables();
-    if (order->item[0]->with_sum_func ||
+    if (find_order_in_order_list(first_order, order))
+    {
+      /* Remove duplicate ORDER elements. */
+      DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
+      continue;
+    }
+    else if (order->item[0]->with_sum_func ||
         /*
           If the outer table of an outer join is const (either by itself or
           after applying WHERE condition), grouping on a field from such a
@@ -18567,8 +18603,10 @@ check_reverse_order:
         tab->ref.key_parts=0;		// Don't use ref key.
         tab->read_first_record= join_init_read_record;
         if (tab->is_using_loose_index_scan())
+        {
           tab->join->tmp_table_param.precomputed_group_by= TRUE;
-
+          tab->join->select_options&= ~SELECT_BIG_RESULT;
+        }
         /*
           Restore the original condition as changes done by pushdown
           condition are not relevant anymore

