From 4ac1e8e034a30afd4428653754e4e7878eaf0ace Mon Sep 17 00:00:00 2001 From: Bernhard Loos Date: Thu, 20 Oct 2011 14:22:25 +0200 Subject: [PATCH] msi: Always use WHEREVIEW for sorting. --- dlls/msi/distinct.c | 11 +-- dlls/msi/select.c | 10 +-- dlls/msi/sql.y | 88 ++++++++++----------- dlls/msi/table.c | 181 +------------------------------------------- 4 files changed, 45 insertions(+), 245 deletions(-) diff --git a/dlls/msi/distinct.c b/dlls/msi/distinct.c index 3737d287902..04f09fa4913 100644 --- a/dlls/msi/distinct.c +++ b/dlls/msi/distinct.c @@ -268,15 +268,6 @@ static UINT DISTINCT_find_matching_rows( struct tagMSIVIEW *view, UINT col, 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 @@ static const MSIVIEWOPS distinct_ops = NULL, NULL, NULL, - DISTINCT_sort, + NULL, NULL, }; diff --git a/dlls/msi/select.c b/dlls/msi/select.c index 696c3b97e77..a0184cb6f91 100644 --- a/dlls/msi/select.c +++ b/dlls/msi/select.c @@ -333,14 +333,6 @@ static UINT SELECT_find_matching_rows( struct tagMSIVIEW *view, UINT col, 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 @@ static const MSIVIEWOPS select_ops = NULL, NULL, NULL, - SELECT_sort, + NULL, NULL, }; diff --git a/dlls/msi/sql.y b/dlls/msi/sql.y index 645e3b3fad2..8de696d3ae8 100644 --- a/dlls/msi/sql.y +++ b/dlls/msi/sql.y @@ -114,7 +114,7 @@ static struct expr * EXPR_wildcard( void *info ); %type table tablelist id %type selcollist column column_and_type column_def table_def %type column_assignment update_assign_list constlist -%type query from fromtable selectfrom unorderedsel +%type query from selectfrom unorderdfrom %type oneupdate onedelete oneselect onequery onecreate oneinsert onealter onedrop %type expr val column_val const_val %type column_type data_type data_type_l data_count @@ -409,23 +409,6 @@ data_count: ; 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 @@ selcollist: ; 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 @@ fromtable: 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 c35a95ddb81..d3c6714717f 100644 --- a/dlls/msi/table.c +++ b/dlls/msi/table.c @@ -62,13 +62,6 @@ typedef struct tagMSICOLUMNINFO MSICOLUMNHASHENTRY **hash_table; } MSICOLUMNINFO; -typedef struct tagMSIORDERINFO -{ - UINT *reorder; - UINT num_cols; - UINT cols[1]; -} MSIORDERINFO; - struct tagMSITABLE { BYTE **data; @@ -1019,7 +1012,6 @@ typedef struct tagMSITABLEVIEW MSIDATABASE *db; MSITABLE *table; MSICOLUMNINFO *columns; - MSIORDERINFO *order; UINT num_cols; UINT row_size; WCHAR name[1]; @@ -1047,9 +1039,6 @@ static UINT TABLE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT * 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 @@ static UINT TABLE_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec ) 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 @@ static UINT msi_table_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row) 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 @@ static UINT TABLE_delete( struct tagMSIVIEW *view ) 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 @@ done: 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 @@ static const MSIVIEWOPS table_ops = TABLE_release, TABLE_add_column, TABLE_remove_column, - TABLE_sort, + NULL, TABLE_drop, };