msi: Always use WHEREVIEW for sorting.
diff --git a/dlls/msi/distinct.c b/dlls/msi/distinct.c
index 3737d28..04f09fa 100644
--- a/dlls/msi/distinct.c
+++ b/dlls/msi/distinct.c
@@ -268,15 +268,6 @@
     return r;
 }
 
-static UINT DISTINCT_sort(struct tagMSIVIEW *view, column_info *columns)
-{
-    MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW *)view;
-
-    TRACE("%p %p\n", view, columns);
-
-    return dv->table->ops->sort( dv->table, columns );
-}
-
 static const MSIVIEWOPS distinct_ops =
 {
     DISTINCT_fetch_int,
@@ -296,7 +287,7 @@
     NULL,
     NULL,
     NULL,
-    DISTINCT_sort,
+    NULL,
     NULL,
 };
 
diff --git a/dlls/msi/select.c b/dlls/msi/select.c
index 696c3b9..a0184cb 100644
--- a/dlls/msi/select.c
+++ b/dlls/msi/select.c
@@ -333,14 +333,6 @@
     return sv->table->ops->find_matching_rows( sv->table, col, val, row, handle );
 }
 
-static UINT SELECT_sort(struct tagMSIVIEW *view, column_info *columns)
-{
-    MSISELECTVIEW *sv = (MSISELECTVIEW *)view;
-
-    TRACE("%p %p\n", view, columns);
-
-    return sv->table->ops->sort( sv->table, columns );
-}
 
 static const MSIVIEWOPS select_ops =
 {
@@ -361,7 +353,7 @@
     NULL,
     NULL,
     NULL,
-    SELECT_sort,
+    NULL,
     NULL,
 };
 
diff --git a/dlls/msi/sql.y b/dlls/msi/sql.y
index 645e3b3..8de696d 100644
--- a/dlls/msi/sql.y
+++ b/dlls/msi/sql.y
@@ -114,7 +114,7 @@
 %type <string> table tablelist id
 %type <column_list> selcollist column column_and_type column_def table_def
 %type <column_list> column_assignment update_assign_list constlist
-%type <query> query from fromtable selectfrom unorderedsel
+%type <query> query from selectfrom unorderdfrom
 %type <query> oneupdate onedelete oneselect onequery onecreate oneinsert onealter onedrop
 %type <expr> expr val column_val const_val
 %type <column_type> column_type data_type data_type_l data_count
@@ -409,23 +409,6 @@
     ;
 
 oneselect:
-    unorderedsel TK_ORDER TK_BY selcollist
-        {
-            UINT r;
-
-            if( $4 )
-            {
-                r = $1->ops->sort( $1, $4 );
-                if ( r != ERROR_SUCCESS)
-                    YYABORT;
-            }
-
-            $$ = $1;
-        }
-  | unorderedsel
-    ;
-
-unorderedsel:
     TK_SELECT selectfrom
         {
             $$ = $2;
@@ -477,34 +460,6 @@
     ;
 
 from:
-    fromtable
-  | TK_FROM tablelist TK_WHERE expr
-        {
-            SQL_input* sql = (SQL_input*) info;
-            MSIVIEW* where = NULL;
-            UINT r;
-
-            r = WHERE_CreateView( sql->db, &where, $2, $4 );
-            if( r != ERROR_SUCCESS )
-                YYABORT;
-
-            PARSER_BUBBLE_UP_VIEW( sql, $$, where );
-        }
-  | TK_FROM tablelist
-        {
-            SQL_input* sql = (SQL_input*) info;
-            MSIVIEW* where = NULL;
-            UINT r;
-
-            r = WHERE_CreateView( sql->db, &where, $2, NULL );
-            if( r != ERROR_SUCCESS )
-                YYABORT;
-
-            PARSER_BUBBLE_UP_VIEW( sql, $$, where );
-        }
-    ;
-
-fromtable:
     TK_FROM table
         {
             SQL_input* sql = (SQL_input*) info;
@@ -517,6 +472,47 @@
 
             PARSER_BUBBLE_UP_VIEW( sql, $$, table );
         }
+  | unorderdfrom TK_ORDER TK_BY selcollist
+        {
+            UINT r;
+
+            if( $4 )
+            {
+                r = $1->ops->sort( $1, $4 );
+                if ( r != ERROR_SUCCESS)
+                    YYABORT;
+            }
+
+            $$ = $1;
+        }
+  | unorderdfrom
+  ;
+
+unorderdfrom:
+    TK_FROM tablelist
+        {
+            SQL_input* sql = (SQL_input*) info;
+            MSIVIEW* where = NULL;
+            UINT r;
+
+            r = WHERE_CreateView( sql->db, &where, $2, NULL );
+            if( r != ERROR_SUCCESS )
+                YYABORT;
+
+            PARSER_BUBBLE_UP_VIEW( sql, $$, where );
+        }
+  | TK_FROM tablelist TK_WHERE expr
+        {
+            SQL_input* sql = (SQL_input*) info;
+            MSIVIEW* where = NULL;
+            UINT r;
+
+            r = WHERE_CreateView( sql->db, &where, $2, $4 );
+            if( r != ERROR_SUCCESS )
+                YYABORT;
+
+            PARSER_BUBBLE_UP_VIEW( sql, $$, where );
+        }
     ;
 
 tablelist:
diff --git a/dlls/msi/table.c b/dlls/msi/table.c
index c35a95d..d3c6714 100644
--- a/dlls/msi/table.c
+++ b/dlls/msi/table.c
@@ -62,13 +62,6 @@
     MSICOLUMNHASHENTRY **hash_table;
 } MSICOLUMNINFO;
 
-typedef struct tagMSIORDERINFO
-{
-    UINT *reorder;
-    UINT num_cols;
-    UINT cols[1];
-} MSIORDERINFO;
-
 struct tagMSITABLE
 {
     BYTE **data;
@@ -1019,7 +1012,6 @@
     MSIDATABASE   *db;
     MSITABLE      *table;
     MSICOLUMNINFO *columns;
-    MSIORDERINFO  *order;
     UINT           num_cols;
     UINT           row_size;
     WCHAR          name[1];
@@ -1047,9 +1039,6 @@
         return ERROR_FUNCTION_FAILED;
     }
 
-    if (tv->order)
-        row = tv->order->reorder[row];
-
     n = bytes_per_column( tv->db, &tv->columns[col - 1], LONG_STR_BYTES );
     if (n != 2 && n != 3 && n != 4)
     {
@@ -1226,9 +1215,6 @@
     if (!tv->table)
         return ERROR_INVALID_PARAMETER;
 
-    if (tv->order)
-        row = tv->order->reorder[row];
-
     return msi_view_get_row(tv->db, view, row, rec);
 }
 
@@ -1726,9 +1712,6 @@
     if (row != new_row + 1)
         return ERROR_FUNCTION_FAILED;
 
-    if(tv->order)
-        new_row = tv->order->reorder[new_row];
-
     return TABLE_set_row(view, new_row, rec, (1 << tv->num_cols) - 1);
 }
 
@@ -1853,13 +1836,6 @@
     tv->table = NULL;
     tv->columns = NULL;
 
-    if (tv->order)
-    {
-        msi_free( tv->order->reorder );
-        msi_free( tv->order );
-        tv->order = NULL;
-    }
-
     msi_free( tv );
 
     return ERROR_SUCCESS;
@@ -2072,161 +2048,6 @@
     return r;
 }
 
-static UINT order_add_column(struct tagMSIVIEW *view, MSIORDERINFO *order, LPCWSTR name)
-{
-    UINT n, r, count;
-    MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
-
-    r = TABLE_get_dimensions(view, NULL, &count);
-    if (r != ERROR_SUCCESS)
-        return r;
-
-    if (order->num_cols >= count)
-        return ERROR_FUNCTION_FAILED;
-
-    r = VIEW_find_column(view, name, tv->name, &n);
-    if (r != ERROR_SUCCESS)
-        return r;
-
-    order->cols[order->num_cols] = n;
-    TRACE("Ordering by column %s (%d)\n", debugstr_w(name), n);
-
-    order->num_cols++;
-
-    return ERROR_SUCCESS;
-}
-
-static UINT order_compare(struct tagMSIVIEW *view, MSIORDERINFO *order,
-                          UINT a, UINT b, UINT *swap)
-{
-    UINT r, i, a_val = 0, b_val = 0;
-
-    *swap = 0;
-    for (i = 0; i < order->num_cols; i++)
-    {
-        r = TABLE_fetch_int(view, a, order->cols[i], &a_val);
-        if (r != ERROR_SUCCESS)
-            return r;
-
-        r = TABLE_fetch_int(view, b, order->cols[i], &b_val);
-        if (r != ERROR_SUCCESS)
-            return r;
-
-        if (a_val != b_val)
-        {
-            if (a_val > b_val)
-                *swap = 1;
-            break;
-        }
-    }
-
-    return ERROR_SUCCESS;
-}
-
-static UINT order_mergesort(struct tagMSIVIEW *view, MSIORDERINFO *order,
-                            UINT left, UINT right)
-{
-    UINT r, i, j, temp;
-    UINT swap = 0, center = (left + right) / 2;
-    UINT *array = order->reorder;
-
-    if (left == right)
-        return ERROR_SUCCESS;
-
-    /* sort the left half */
-    r = order_mergesort(view, order, left, center);
-    if (r != ERROR_SUCCESS)
-        return r;
-
-    /* sort the right half */
-    r = order_mergesort(view, order, center + 1, right);
-    if (r != ERROR_SUCCESS)
-        return r;
-
-    for (i = left, j = center + 1; (i <= center) && (j <= right); i++)
-    {
-        r = order_compare(view, order, array[i], array[j], &swap);
-        if (r != ERROR_SUCCESS)
-            return r;
-
-        if (swap)
-        {
-            temp = array[j];
-            memmove(&array[i + 1], &array[i], (j - i) * sizeof(UINT));
-            array[i] = temp;
-            j++;
-            center++;
-        }
-    }
-
-    return ERROR_SUCCESS;
-}
-
-static UINT order_verify(struct tagMSIVIEW *view, MSIORDERINFO *order, UINT num_rows)
-{
-    UINT i, swap, r;
-
-    for (i = 1; i < num_rows; i++)
-    {
-        r = order_compare(view, order, order->reorder[i - 1],
-                          order->reorder[i], &swap);
-        if (r != ERROR_SUCCESS)
-            return r;
-
-        if (!swap)
-            continue;
-
-        ERR("Bad order! %d\n", i);
-        return ERROR_FUNCTION_FAILED;
-    }
-
-    return ERROR_SUCCESS;
-}
-
-static UINT TABLE_sort(struct tagMSIVIEW *view, column_info *columns)
-{
-    MSITABLEVIEW *tv = (MSITABLEVIEW *)view;
-    MSIORDERINFO *order;
-    column_info *ptr;
-    UINT r, i;
-    UINT rows, cols;
-
-    TRACE("sorting table %s\n", debugstr_w(tv->name));
-
-    r = TABLE_get_dimensions(view, &rows, &cols);
-    if (r != ERROR_SUCCESS)
-        return r;
-
-    if (rows == 0)
-        return ERROR_SUCCESS;
-
-    order = msi_alloc_zero(sizeof(MSIORDERINFO) + sizeof(UINT) * cols);
-    if (!order)
-        return ERROR_OUTOFMEMORY;
-
-    for (ptr = columns; ptr; ptr = ptr->next)
-        order_add_column(view, order, ptr->column);
-
-    order->reorder = msi_alloc(rows * sizeof(UINT));
-    if (!order->reorder)
-        return ERROR_OUTOFMEMORY;
-
-    for (i = 0; i < rows; i++)
-        order->reorder[i] = i;
-
-    r = order_mergesort(view, order, 0, rows - 1);
-    if (r != ERROR_SUCCESS)
-        return r;
-
-    r = order_verify(view, order, rows);
-    if (r != ERROR_SUCCESS)
-        return r;
-
-    tv->order = order;
-
-    return ERROR_SUCCESS;
-}
-
 static UINT TABLE_drop(struct tagMSIVIEW *view)
 {
     MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
@@ -2292,7 +2113,7 @@
     TABLE_release,
     TABLE_add_column,
     TABLE_remove_column,
-    TABLE_sort,
+    NULL,
     TABLE_drop,
 };