diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_archive.cc | 43 | ||||
-rw-r--r-- | sql/ha_archive.h | 2 | ||||
-rw-r--r-- | sql/item.cc | 18 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 4 |
5 files changed, 56 insertions, 13 deletions
diff --git a/sql/ha_archive.cc b/sql/ha_archive.cc index cad81926a72..bfb90b607ee 100644 --- a/sql/ha_archive.cc +++ b/sql/ha_archive.cc @@ -396,6 +396,7 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, share->table_name_length= length; share->table_name= tmp_name; share->crashed= FALSE; + share->archive_write_open= FALSE; fn_format(share->data_file_name,table_name,"",ARZ,MY_REPLACE_EXT|MY_UNPACK_FILENAME); fn_format(meta_file_name,table_name,"",ARM,MY_REPLACE_EXT|MY_UNPACK_FILENAME); strmov(share->table_name,table_name); @@ -413,16 +414,7 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, */ if (read_meta_file(share->meta_file, &share->rows_recorded)) share->crashed= TRUE; - else - (void)write_meta_file(share->meta_file, share->rows_recorded, TRUE); - /* - It is expensive to open and close the data files and since you can't have - a gzip file that can be both read and written we keep a writer open - that is shared amoung all open tables. - */ - if ((share->archive_write= gzopen(share->data_file_name, "ab")) == NULL) - share->crashed= TRUE; VOID(my_hash_insert(&archive_open_tables, (byte*) share)); thr_lock_init(&share->lock); } @@ -460,8 +452,9 @@ int ha_archive::free_share(ARCHIVE_SHARE *share) (void)write_meta_file(share->meta_file, share->rows_recorded, TRUE); else (void)write_meta_file(share->meta_file, share->rows_recorded, FALSE); - if (gzclose(share->archive_write) == Z_ERRNO) - rc= 1; + if (share->archive_write_open) + if (gzclose(share->archive_write) == Z_ERRNO) + rc= 1; if (my_close(share->meta_file, MYF(0))) rc= 1; my_free((gptr) share, MYF(0)); @@ -471,6 +464,26 @@ int ha_archive::free_share(ARCHIVE_SHARE *share) DBUG_RETURN(rc); } +int ha_archive::init_archive_writer() +{ + DBUG_ENTER("ha_archive::init_archive_writer"); + (void)write_meta_file(share->meta_file, share->rows_recorded, TRUE); + + /* + It is expensive to open and close the data files and since you can't have + a gzip file that can be both read and written we keep a writer open + that is shared amoung all open tables. + */ + if ((share->archive_write= gzopen(share->data_file_name, "ab")) == NULL) + { + share->crashed= TRUE; + DBUG_RETURN(1); + } + share->archive_write_open= TRUE; + + DBUG_RETURN(0); +} + /* We just implement one additional file extension. @@ -693,6 +706,10 @@ int ha_archive::write_row(byte *buf) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); pthread_mutex_lock(&share->mutex); + if (!share->archive_write_open) + if (init_archive_writer()) + DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); + share->rows_recorded++; rc= real_write_row(buf, share->archive_write); pthread_mutex_unlock(&share->mutex); @@ -893,6 +910,10 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt) gzFile writer; char writer_filename[FN_REFLEN]; + /* Open up the writer if we haven't yet */ + if (!share->archive_write_open) + init_archive_writer(); + /* Flush any waiting data */ gzflush(share->archive_write, Z_SYNC_FLUSH); diff --git a/sql/ha_archive.h b/sql/ha_archive.h index 0fa5cdc56ca..2bac9fa605e 100644 --- a/sql/ha_archive.h +++ b/sql/ha_archive.h @@ -34,6 +34,7 @@ typedef struct st_archive_share { THR_LOCK lock; File meta_file; /* Meta file we use */ gzFile archive_write; /* Archive file we are working with */ + bool archive_write_open; bool dirty; /* Flag for if a flush should occur */ bool crashed; /* Meta file is crashed */ ha_rows rows_recorded; /* Number of rows in tables */ @@ -87,6 +88,7 @@ public: int write_meta_file(File meta_file, ha_rows rows, bool dirty); ARCHIVE_SHARE *get_share(const char *table_name, TABLE *table, int *rc); int free_share(ARCHIVE_SHARE *share); + int init_archive_writer(); bool auto_repair() const { return 1; } // For the moment we just do this int read_data_header(gzFile file_to_read); int write_data_header(gzFile file_to_write); diff --git a/sql/item.cc b/sql/item.cc index 9410fa65408..0afac76f3db 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3147,7 +3147,8 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) both clauses contain different fields with the same names, a warning is issued that name of 'ref' is ambiguous. We extend ANSI SQL in that when no GROUP BY column is found, then a HAVING name is resolved as a possibly - derived SELECT column. + derived SELECT column. This extension is allowed only if the + MODE_ONLY_FULL_GROUP_BY sql mode isn't enabled. NOTES The resolution procedure is: @@ -3157,7 +3158,9 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) in the GROUP BY clause of Q. - If found different columns with the same name in GROUP BY and SELECT - issue a warning and return the GROUP BY column, - - otherwise return the found SELECT column. + - otherwise + - if the MODE_ONLY_FULL_GROUP_BY mode is enabled return error + - else return the found SELECT column. RETURN @@ -3202,6 +3205,17 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) } } + if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && + select_ref != not_found_item && !group_by_ref) + { + /* + Report the error if fields was found only in the SELECT item list and + the strict mode is enabled. + */ + my_error(ER_NON_GROUPING_FIELD_USED, MYF(0), + ref->name, "HAVING"); + return NULL; + } if (select_ref != not_found_item || group_by_ref) { if (select_ref != not_found_item && !ambiguous_fields) diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 1c2e073075f..7665a7425cd 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5615,3 +5615,5 @@ ER_MAX_PREPARED_STMT_COUNT_REACHED 42000 eng "Can't create more than max_prepared_stmt_count statements (current value: %lu)" ER_VIEW_RECURSIVE eng "`%-.64s`.`%-.64s` contains view recursion" +ER_NON_GROUPING_FIELD_USED 42000 + eng "non-grouping field '%-.64s' is used in %-.64s clause" diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 47c5281b258..3a616c28755 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12613,6 +12613,10 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, if (item->type() != Item::SUM_FUNC_ITEM && !item->marker && !item->const_item()) { + /* + TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed + ER_NON_GROUPING_FIELD_USED + */ my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), item->full_name()); return 1; } |