summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_archive.cc43
-rw-r--r--sql/ha_archive.h2
-rw-r--r--sql/item.cc18
-rw-r--r--sql/share/errmsg.txt2
-rw-r--r--sql/sql_select.cc4
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;
}