summaryrefslogtreecommitdiff
path: root/sql/sql_union.cc
diff options
context:
space:
mode:
authorunknown <monty@narttu.mysql.fi>2003-08-20 16:25:44 +0300
committerunknown <monty@narttu.mysql.fi>2003-08-20 16:25:44 +0300
commitde5d47c35d426a84cb0fd453dfdc17012dc8ba55 (patch)
tree4d61f552796b268be72317d81fd6051dd59c7966 /sql/sql_union.cc
parent9c5c6dafa16fe5c6e77b72a0dafa310417600901 (diff)
downloadmariadb-git-de5d47c35d426a84cb0fd453dfdc17012dc8ba55.tar.gz
Fixed some varnings from valgrind
Set min value of max_allowed_packet to 1024 Fixed problem with UNION's without braces and SQL_CALC_FOUND_ROWS, LIMIT #,# and ORDER BY...LIMIT include/m_string.h: Added memcpy_overlap() to avoid warnings when using valgrind on memcpy(A,A,...) myisam/mi_create.c: Fixed comment myisam/mi_search.c: Fix warning from valgrind myisam/mi_write.c: Indentation fix mysql-test/mysql-test-run.sh: Add options handled by general skip- option mysql-test/r/packet.result: Update results after change to mysqld (min max_allowed_packet length is now 1024) mysql-test/r/union.result: Added testing of UNION with SQL_CALC_FOUND_ROWS mysql-test/t/packet.test: Update results after change to mysqld (min max_allowed_packet length is now 1024) mysql-test/t/union.test: Added testing of UNION with SQL_CALC_FOUND_ROWS sql/field.cc: Fix to remove waarning from valgrind sql/ha_innodb.cc: Remove wrong include file sql/item_cmpfunc.cc: Safety fix to handle EOM conditions in IN sql/item_sum.cc: Fixed prototype for update_field() (argument was alwys 0) sql/item_sum.h: Fixed prototype for update_field() (argument was alwys 0) sql/item_uniq.h: Fixed prototype for update_field() (argument was alwys 0) sql/log.cc: Indentation fix sql/mysqld.cc: Set min value of max_allowed_packet to 1024 (to avoid it getting set to 0) sql/net_serv.cc: Indentation changes + trivial optimization sql/sql_select.cc: Fixed prototype for update_field() (argument was alwys 0) sql/sql_union.cc: Fixed problem with UNION's without braces and - SQL_CALC_FOUND_ROWS - LIMIT #,# - ORDER BY ... LIMIT
Diffstat (limited to 'sql/sql_union.cc')
-rw-r--r--sql/sql_union.cc65
1 files changed, 52 insertions, 13 deletions
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index bd7bc7027d3..34acd79f18b 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -31,9 +31,10 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
ORDER *order;
List<Item> item_list;
TABLE *table;
- int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0;
int res;
- bool found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS;
+ ulonglong add_rows= 0;
+ ulong found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS;
+ ulong describe= lex->select_lex.options & SELECT_DESCRIBE;
TABLE_LIST result_table_list;
TABLE_LIST *first_table=(TABLE_LIST *)lex->select_lex.table_list.first;
TMP_TABLE_PARAM tmp_table_param;
@@ -135,14 +136,44 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
union_result->tmp_table_param=&tmp_table_param;
for (sl= &lex->select_lex; sl; sl=sl->next)
{
+ ha_rows records_at_start;
lex->select=sl;
- thd->offset_limit=sl->offset_limit;
- thd->select_limit=sl->select_limit+sl->offset_limit;
+ /* Don't use offset for the last union if there is no braces */
+ if (sl != lex_sl)
+ {
+ thd->offset_limit= sl->offset_limit;
+ thd->select_limit=sl->select_limit+sl->offset_limit;
+ }
+ else
+ {
+ thd->offset_limit= 0;
+ /*
+ We can't use LIMIT at this stage if we are using ORDER BY for the
+ whole query
+ */
+ thd->select_limit= HA_POS_ERROR;
+ if (! sl->order_list.first)
+ thd->select_limit= sl->select_limit+sl->offset_limit;
+ }
if (thd->select_limit < sl->select_limit)
thd->select_limit= HA_POS_ERROR; // no limit
+
+ /*
+ When using braces, SQL_CALC_FOUND_ROWS affects the whole query.
+ We don't calculate found_rows() per union part
+ */
if (thd->select_limit == HA_POS_ERROR || sl->braces)
sl->options&= ~OPTION_FOUND_ROWS;
+ else
+ {
+ /*
+ We are doing an union without braces. In this case
+ SQL_CALC_FOUND_ROWS should be done on all sub parts
+ */
+ sl->options|= found_rows_for_union;
+ }
+ records_at_start= table->file->records;
res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ?
first_table : (TABLE_LIST*) sl->table_list.first,
sl->item_list,
@@ -153,10 +184,23 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
sl->having,
(ORDER*) NULL,
sl->options | thd->options | SELECT_NO_UNLOCK |
- ((describe) ? SELECT_DESCRIBE : 0),
+ describe,
union_result);
if (res)
goto exit;
+ /* Needed for the following test and for records_at_start in next loop */
+ table->file->info(HA_STATUS_VARIABLE);
+ if (found_rows_for_union & sl->options)
+ {
+ /*
+ This is a union without braces. Remember the number of rows that could
+ also have been part of the result set.
+ We get this from the difference of between total number of possible
+ rows and actual rows added to the temporary table.
+ */
+ add_rows+= (ulonglong) (thd->limit_found_rows - (table->file->records -
+ records_at_start));
+ }
}
if (union_result->flush())
{
@@ -172,19 +216,14 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
/* Create a list of fields in the temporary table */
List_iterator<Item> it(item_list);
Field **field;
-#if 0
- List<Item_func_match> ftfunc_list;
- ftfunc_list.empty();
-#else
thd->lex.select_lex.ftfunc_list.empty();
-#endif
for (field=table->field ; *field ; field++)
{
(void) it++;
(void) it.replace(new Item_field(*field));
}
- if (!thd->fatal_error) // Check if EOM
+ if (!thd->fatal_error) // Check if EOM
{
if (lex_sl)
{
@@ -209,8 +248,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
item_list, NULL, (describe) ? 0 : order,
(ORDER*) NULL, NULL, (ORDER*) NULL,
thd->options, result);
- if (found_rows_for_union && !res)
- thd->limit_found_rows = (ulonglong)table->file->records;
+ if (!res)
+ thd->limit_found_rows = (ulonglong)table->file->records + add_rows;
}
}