summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_archive.cc1
-rw-r--r--sql/ha_archive.h2
-rw-r--r--sql/ha_berkeley.cc1
-rw-r--r--sql/ha_innodb.cc3
-rw-r--r--sql/ha_myisam.cc11
-rw-r--r--sql/ha_ndbcluster.cc6
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item_func.cc38
-rw-r--r--sql/item_timefunc.cc63
-rw-r--r--sql/log_event.cc246
-rw-r--r--sql/log_event.h115
-rw-r--r--sql/mysqld.cc3
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_cache.cc1
-rw-r--r--sql/sql_class.cc6
-rw-r--r--sql/sql_class.h8
-rw-r--r--sql/sql_lex.h1
-rw-r--r--sql/sql_load.cc19
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_select.cc3
-rw-r--r--sql/sql_show.cc9
-rw-r--r--sql/sql_table.cc6
-rw-r--r--sql/sql_view.cc3
-rw-r--r--sql/sql_yacc.yy56
25 files changed, 390 insertions, 219 deletions
diff --git a/sql/ha_archive.cc b/sql/ha_archive.cc
index b4bcf162ff0..c4801de5fb2 100644
--- a/sql/ha_archive.cc
+++ b/sql/ha_archive.cc
@@ -453,7 +453,6 @@ int ha_archive::free_share(ARCHIVE_SHARE *share)
*/
static const char *ha_archive_exts[] = {
ARZ,
- ARN,
ARM,
NullS
};
diff --git a/sql/ha_archive.h b/sql/ha_archive.h
index 6ba6d95685e..56a4b9d1e27 100644
--- a/sql/ha_archive.h
+++ b/sql/ha_archive.h
@@ -68,7 +68,7 @@ public:
ulong table_flags() const
{
return (HA_REC_NOT_IN_SEQ | HA_NOT_EXACT_COUNT | HA_NO_AUTO_INCREMENT |
- HA_FILE_BASED | HA_CAN_INSERT_DELAYED);
+ HA_FILE_BASED | HA_CAN_INSERT_DELAYED | HA_CAN_GEOMETRY);
}
ulong index_flags(uint idx, uint part, bool all_parts) const
{
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 7cbb4e90452..3a2bdf3ef9a 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -392,6 +392,7 @@ ha_berkeley::ha_berkeley(TABLE *table_arg)
int_table_flags(HA_REC_NOT_IN_SEQ | HA_FAST_KEY_READ |
HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS | HA_NOT_EXACT_COUNT |
HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED |
+ HA_CAN_GEOMETRY |
HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX),
changed_rows(0), last_dup_key((uint) -1), version(0), using_ignore(0)
{}
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index a7957ee3cbf..61af1afb2be 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -812,6 +812,7 @@ ha_innobase::ha_innobase(TABLE *table_arg)
HA_CAN_SQL_HANDLER |
HA_NOT_EXACT_COUNT |
HA_PRIMARY_KEY_IN_READ_INDEX |
+ HA_CAN_GEOMETRY |
HA_TABLE_SCAN_ON_INDEX),
last_dup_key((uint) -1),
start_of_scan(0),
@@ -2757,6 +2758,7 @@ get_innobase_type_from_mysql_type(
return(DATA_DOUBLE);
case FIELD_TYPE_DECIMAL:
return(DATA_DECIMAL);
+ case FIELD_TYPE_GEOMETRY:
case FIELD_TYPE_TINY_BLOB:
case FIELD_TYPE_MEDIUM_BLOB:
case FIELD_TYPE_BLOB:
@@ -6811,6 +6813,7 @@ ha_innobase::store_lock(
|| thd->lex->sql_command == SQLCOM_CALL)
&& !thd->tablespace_op
&& thd->lex->sql_command != SQLCOM_TRUNCATE
+ && thd->lex->sql_command != SQLCOM_OPTIMIZE
&& thd->lex->sql_command != SQLCOM_CREATE_TABLE) {
lock_type = TL_WRITE_ALLOW_WRITE;
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 70137ff2b16..ced00c94e73 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -985,11 +985,16 @@ int ha_myisam::enable_indexes(uint mode)
{
sql_print_warning("Warning: Enabling keys got errno %d, retrying",
my_errno);
- thd->clear_error();
+ /* Repairing by sort failed. Now try standard repair method. */
param.testflag&= ~(T_REP_BY_SORT | T_QUICK);
error= (repair(thd,param,0) != HA_ADMIN_OK);
- if (!error && thd->net.report_error)
- error= HA_ERR_CRASHED;
+ /*
+ If the standard repair succeeded, clear all error messages which
+ might have been set by the first repair. They can still be seen
+ with SHOW WARNINGS then.
+ */
+ if (! error)
+ thd->clear_error();
}
info(HA_STATUS_CONST);
thd->proc_info=save_proc_info;
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index a0efcd2c4f9..4248230abbe 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -588,9 +588,9 @@ static bool ndb_supported_type(enum_field_types type)
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_BIT:
+ case MYSQL_TYPE_GEOMETRY:
return TRUE;
case MYSQL_TYPE_NULL:
- case MYSQL_TYPE_GEOMETRY:
break;
}
return FALSE;
@@ -3714,6 +3714,7 @@ static int create_ndb_column(NDBCOL &col,
col.setStripeSize(0);
break;
//mysql_type_blob:
+ case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_BLOB:
if ((field->flags & BINARY_FLAG) && cs == &my_charset_bin)
col.setType(NDBCOL::Blob);
@@ -3779,7 +3780,6 @@ static int create_ndb_column(NDBCOL &col,
break;
}
case MYSQL_TYPE_NULL:
- case MYSQL_TYPE_GEOMETRY:
goto mysql_type_unsupported;
mysql_type_unsupported:
default:
@@ -3931,6 +3931,7 @@ int ha_ndbcluster::create(const char *name,
* 5 - from extra words added by tup/dict??
*/
switch (form->field[i]->real_type()) {
+ case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
@@ -4206,6 +4207,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
HA_AUTO_PART_KEY |
HA_NO_PREFIX_CHAR_KEYS |
HA_NEED_READ_RANGE_BUFFER |
+ HA_CAN_GEOMETRY |
HA_CAN_BIT_FIELD),
m_share(0),
m_use_write(FALSE),
diff --git a/sql/item.cc b/sql/item.cc
index b2aca750475..fed3ffcc080 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -3248,7 +3248,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
Item** res= find_item_in_list(this, thd->lex->current_select->item_list,
&counter, REPORT_EXCEPT_NOT_FOUND,
&not_used);
- if (res != not_found_item && (*res)->type() == Item::FIELD_ITEM)
+ if (res != (Item **)not_found_item && (*res)->type() == Item::FIELD_ITEM)
{
set_field((*((Item_field**)res))->field);
return 0;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 35ed9b615f2..92d57d826a5 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1386,8 +1386,13 @@ double Item_func_ln::val_real()
{
DBUG_ASSERT(fixed == 1);
double value= args[0]->val_real();
- if ((null_value=(args[0]->null_value || value <= 0.0)))
+ if ((null_value=args[0]->null_value))
+ return 0.0;
+ if ((null_value= value <=0.0))
+ {
+ signal_divide_by_null();
return 0.0;
+ }
return log(value);
}
@@ -1400,13 +1405,23 @@ double Item_func_log::val_real()
{
DBUG_ASSERT(fixed == 1);
double value= args[0]->val_real();
- if ((null_value=(args[0]->null_value || value <= 0.0)))
+ if ((null_value=args[0]->null_value))
+ return 0.0;
+ if ((null_value= value <=0.0))
+ {
+ signal_divide_by_null();
return 0.0;
+ }
if (arg_count == 2)
{
double value2= args[1]->val_real();
- if ((null_value=(args[1]->null_value || value2 <= 0.0 || value == 1.0)))
+ if ((null_value=args[1]->null_value))
return 0.0;
+ if ((null_value= value2 <=0.0) || (value == 1.0))
+ {
+ signal_divide_by_null();
+ return 0.0;
+ }
return log(value2) / log(value);
}
return log(value);
@@ -1416,8 +1431,14 @@ double Item_func_log2::val_real()
{
DBUG_ASSERT(fixed == 1);
double value= args[0]->val_real();
- if ((null_value=(args[0]->null_value || value <= 0.0)))
+
+ if ((null_value=args[0]->null_value))
return 0.0;
+ if ((null_value= value <=0.0))
+ {
+ signal_divide_by_null();
+ return 0.0;
+ }
return log(value) / M_LN2;
}
@@ -1425,8 +1446,13 @@ double Item_func_log10::val_real()
{
DBUG_ASSERT(fixed == 1);
double value= args[0]->val_real();
- if ((null_value=(args[0]->null_value || value <= 0.0)))
- return 0.0; /* purecov: inspected */
+ if ((null_value=args[0]->null_value))
+ return 0.0;
+ if ((null_value= value <=0.0))
+ {
+ signal_divide_by_null();
+ return 0.0;
+ }
return log10(value);
}
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 7f94c19647e..459b5a22cb1 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -2723,16 +2723,16 @@ longlong Item_func_timestamp_diff::val_int()
int_type == INTERVAL_QUARTER ||
int_type == INTERVAL_MONTH)
{
- uint year;
- uint year_beg, year_end, month_beg, month_end;
- uint diff_days= (uint) (seconds/86400L);
- uint diff_years= 0;
+ uint year_beg, year_end, month_beg, month_end, day_beg, day_end;
+ uint years= 0;
if (neg == -1)
{
year_beg= ltime2.year;
year_end= ltime1.year;
month_beg= ltime2.month;
month_end= ltime1.month;
+ day_beg= ltime2.day;
+ day_end= ltime1.day;
}
else
{
@@ -2740,53 +2740,32 @@ longlong Item_func_timestamp_diff::val_int()
year_end= ltime2.year;
month_beg= ltime1.month;
month_end= ltime2.month;
- }
- /* calc years*/
- for (year= year_beg;year < year_end; year++)
- {
- uint days=calc_days_in_year(year);
- if (days > diff_days)
- break;
- diff_days-= days;
- diff_years++;
+ day_beg= ltime1.day;
+ day_end= ltime2.day;
}
- /* calc months; Current year is in the 'year' variable */
- month_beg--; /* Change months to be 0-11 for easier calculation */
- month_end--;
+ /* calc years */
+ years= year_end - year_beg;
+ if (month_end < month_beg || (month_end == month_beg && day_end < day_beg))
+ years-= 1;
- months= 12*diff_years;
- while (month_beg != month_end)
- {
- uint m_days= (uint) days_in_month[month_beg];
- if (month_beg == 1)
- {
- /* This is only calculated once so there is no reason to cache it*/
- uint leap= (uint) ((year & 3) == 0 && (year%100 ||
- (year%400 == 0 && year)));
- m_days+= leap;
- }
- if (m_days > diff_days)
- break;
- diff_days-= m_days;
- months++;
- if (month_beg++ == 11) /* if we wrap to next year */
- {
- month_beg= 0;
- year++;
- }
- }
- if (neg == -1)
- months= -months;
+ /* calc months */
+ months= 12*years;
+ if (month_end < month_beg || (month_end == month_beg && day_end < day_beg))
+ months+= 12 - (month_beg - month_end);
+ else
+ months+= (month_end - month_beg);
+ if (day_end < day_beg)
+ months-= 1;
}
switch (int_type) {
case INTERVAL_YEAR:
- return months/12;
+ return months/12*neg;
case INTERVAL_QUARTER:
- return months/3;
+ return months/3*neg;
case INTERVAL_MONTH:
- return months;
+ return months*neg;
case INTERVAL_WEEK:
return seconds/86400L/7L*neg;
case INTERVAL_DAY:
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 2ec63febca4..2390ebd4214 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -696,7 +696,6 @@ failed my_b_read"));
*/
DBUG_RETURN(0);
}
-
uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
char *buf= 0;
const char *error= 0;
@@ -876,15 +875,76 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
Log_event::print_header()
*/
-void Log_event::print_header(FILE* file)
+void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
char llbuff[22];
+ my_off_t hexdump_from= print_event_info->hexdump_from;
+
fputc('#', file);
print_timestamp(file);
fprintf(file, " server id %d end_log_pos %s ", server_id,
- llstr(log_pos,llbuff));
+ llstr(log_pos,llbuff));
+
+ /* mysqlbinlog --hexdump */
+ if (print_event_info->hexdump_from)
+ {
+ fprintf(file, "\n");
+ uchar *ptr= (uchar*)temp_buf;
+ my_off_t size=
+ uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
+ my_off_t i;
+
+ /* Header len * 4 >= header len * (2 chars + space + extra space) */
+ char *h, hex_string[LOG_EVENT_MINIMAL_HEADER_LEN*4]= {0};
+ char *c, char_string[16+1]= {0};
+
+ /* Pretty-print event common header if header is exactly 19 bytes */
+ if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
+ {
+ fprintf(file, "# Position Timestamp Type Master ID "
+ "Size Master Pos Flags \n");
+ fprintf(file, "# %8.8lx %02x %02x %02x %02x %02x "
+ "%02x %02x %02x %02x %02x %02x %02x %02x "
+ "%02x %02x %02x %02x %02x %02x\n",
+ hexdump_from, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4],
+ ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11],
+ ptr[12], ptr[13], ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
+ ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
+ hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
+ }
+
+ /* Rest of event (without common header) */
+ for (i= 0, c= char_string, h=hex_string;
+ i < size;
+ i++, ptr++)
+ {
+ my_snprintf(h, 4, "%02x ", *ptr);
+ h += 3;
+
+ *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
+
+ if (i % 16 == 15)
+ {
+ fprintf(file, "# %8.8lx %-48.48s |%16s|\n",
+ hexdump_from + (i & 0xfffffff0), hex_string, char_string);
+ hex_string[0]= 0;
+ char_string[0]= 0;
+ c= char_string;
+ h= hex_string;
+ }
+ else if (i % 8 == 7) *h++ = ' ';
+ }
+ *c= '\0';
+
+ /* Non-full last line */
+ if (hex_string[0]) {
+ printf("# %8.8lx %-48.48s |%s|\n# ",
+ hexdump_from + (i & 0xfffffff0), hex_string, char_string);
+ }
+ }
}
+
/*
Log_event::print_timestamp()
*/
@@ -1367,25 +1427,25 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
*/
#ifdef MYSQL_CLIENT
-void Query_log_event::print_query_header(FILE* file, bool short_form,
- LAST_EVENT_INFO* last_event_info)
+void Query_log_event::print_query_header(FILE* file,
+ PRINT_EVENT_INFO* print_event_info)
{
// TODO: print the catalog ??
char buff[40],*end; // Enough for SET TIMESTAMP
bool different_db= 1;
uint32 tmp;
- if (!short_form)
+ if (!print_event_info->short_form)
{
- print_header(file);
+ print_header(file, print_event_info);
fprintf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
get_type_str(), (ulong) thread_id, (ulong) exec_time, error_code);
}
if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db)
{
- if (different_db= memcmp(last_event_info->db, db, db_len + 1))
- memcpy(last_event_info->db, db, db_len + 1);
+ if (different_db= memcmp(print_event_info->db, db, db_len + 1))
+ memcpy(print_event_info->db, db, db_len + 1);
if (db[0] && different_db)
fprintf(file, "use %s;\n", db);
}
@@ -1405,12 +1465,12 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
{
/* tmp is a bitmask of bits which have changed. */
- if (likely(last_event_info->flags2_inited))
+ if (likely(print_event_info->flags2_inited))
/* All bits which have changed */
- tmp= (last_event_info->flags2) ^ flags2;
+ tmp= (print_event_info->flags2) ^ flags2;
else /* that's the first Query event we read */
{
- last_event_info->flags2_inited= 1;
+ print_event_info->flags2_inited= 1;
tmp= ~((uint32)0); /* all bits have changed */
}
@@ -1425,7 +1485,7 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
"@@session.unique_checks", &need_comma);
fprintf(file,";\n");
- last_event_info->flags2= flags2;
+ print_event_info->flags2= flags2;
}
}
@@ -1444,37 +1504,37 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
if (likely(sql_mode_inited))
{
- if (unlikely(!last_event_info->sql_mode_inited)) /* first Query event */
+ if (unlikely(!print_event_info->sql_mode_inited)) /* first Query event */
{
- last_event_info->sql_mode_inited= 1;
+ print_event_info->sql_mode_inited= 1;
/* force a difference to force write */
- last_event_info->sql_mode= ~sql_mode;
+ print_event_info->sql_mode= ~sql_mode;
}
- if (unlikely(last_event_info->sql_mode != sql_mode))
+ if (unlikely(print_event_info->sql_mode != sql_mode))
{
fprintf(file,"SET @@session.sql_mode=%lu;\n",(ulong)sql_mode);
- last_event_info->sql_mode= sql_mode;
+ print_event_info->sql_mode= sql_mode;
}
}
- if (last_event_info->auto_increment_increment != auto_increment_increment ||
- last_event_info->auto_increment_offset != auto_increment_offset)
+ if (print_event_info->auto_increment_increment != auto_increment_increment ||
+ print_event_info->auto_increment_offset != auto_increment_offset)
{
fprintf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu;\n",
auto_increment_increment,auto_increment_offset);
- last_event_info->auto_increment_increment= auto_increment_increment;
- last_event_info->auto_increment_offset= auto_increment_offset;
+ print_event_info->auto_increment_increment= auto_increment_increment;
+ print_event_info->auto_increment_offset= auto_increment_offset;
}
/* TODO: print the catalog when we feature SET CATALOG */
if (likely(charset_inited))
{
- if (unlikely(!last_event_info->charset_inited)) /* first Query event */
+ if (unlikely(!print_event_info->charset_inited)) /* first Query event */
{
- last_event_info->charset_inited= 1;
- last_event_info->charset[0]= ~charset[0]; // force a difference to force write
+ print_event_info->charset_inited= 1;
+ print_event_info->charset[0]= ~charset[0]; // force a difference to force write
}
- if (unlikely(bcmp(last_event_info->charset, charset, 6)))
+ if (unlikely(bcmp(print_event_info->charset, charset, 6)))
{
fprintf(file,"SET "
"@@session.character_set_client=%d,"
@@ -1484,24 +1544,23 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
uint2korr(charset),
uint2korr(charset+2),
uint2korr(charset+4));
- memcpy(last_event_info->charset, charset, 6);
+ memcpy(print_event_info->charset, charset, 6);
}
}
if (time_zone_len)
{
- if (bcmp(last_event_info->time_zone_str, time_zone_str, time_zone_len+1))
+ if (bcmp(print_event_info->time_zone_str, time_zone_str, time_zone_len+1))
{
fprintf(file,"SET @@session.time_zone='%s';\n", time_zone_str);
- memcpy(last_event_info->time_zone_str, time_zone_str, time_zone_len+1);
+ memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
}
}
}
-void Query_log_event::print(FILE* file, bool short_form,
- LAST_EVENT_INFO* last_event_info)
+void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
- print_query_header(file, short_form, last_event_info);
+ print_query_header(file, print_event_info);
my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME));
fputs(";\n", file);
}
@@ -1799,11 +1858,11 @@ void Start_log_event_v3::pack_info(Protocol *protocol)
*/
#ifdef MYSQL_CLIENT
-void Start_log_event_v3::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
- if (!short_form)
+ if (!print_event_info->short_form)
{
- print_header(file);
+ print_header(file, print_event_info);
fprintf(file, "\tStart: binlog v %d, server v %s created ", binlog_version,
server_version);
print_timestamp(file);
@@ -2527,19 +2586,19 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
*/
#ifdef MYSQL_CLIENT
-void Load_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
- print(file, short_form, last_event_info, 0);
+ print(file, print_event_info, 0);
}
-void Load_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info,
+void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
bool commented)
{
DBUG_ENTER("Load_log_event::print");
- if (!short_form)
+ if (!print_event_info->short_form)
{
- print_header(file);
+ print_header(file, print_event_info);
fprintf(file, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
thread_id, exec_time);
}
@@ -2553,9 +2612,9 @@ void Load_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_ev
But if commented, the "use" is going to be commented so we should not
update the last_db.
*/
- if ((different_db= memcmp(last_event_info->db, db, db_len + 1)) &&
+ if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
!commented)
- memcpy(last_event_info->db, db, db_len + 1);
+ memcpy(print_event_info->db, db, db_len + 1);
}
if (db && db[0] && different_db)
@@ -2944,13 +3003,13 @@ void Rotate_log_event::pack_info(Protocol *protocol)
*/
#ifdef MYSQL_CLIENT
-void Rotate_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
char buf[22];
- if (short_form)
+ if (print_event_info->short_form)
return;
- print_header(file);
+ print_header(file, print_event_info);
fprintf(file, "\tRotate to ");
if (new_log_ident)
my_fwrite(file, (byte*) new_log_ident, (uint)ident_len,
@@ -3168,16 +3227,15 @@ bool Intvar_log_event::write(IO_CACHE* file)
*/
#ifdef MYSQL_CLIENT
-void Intvar_log_event::print(FILE* file, bool short_form,
- LAST_EVENT_INFO* last_event_info)
+void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
char llbuff[22];
const char *msg;
LINT_INIT(msg);
- if (!short_form)
+ if (!print_event_info->short_form)
{
- print_header(file);
+ print_header(file, print_event_info);
fprintf(file, "\tIntvar\n");
}
@@ -3258,12 +3316,12 @@ bool Rand_log_event::write(IO_CACHE* file)
#ifdef MYSQL_CLIENT
-void Rand_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
char llbuff[22],llbuff2[22];
- if (!short_form)
+ if (!print_event_info->short_form)
{
- print_header(file);
+ print_header(file, print_event_info);
fprintf(file, "\tRand\n");
}
fprintf(file, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s;\n",
@@ -3328,14 +3386,14 @@ bool Xid_log_event::write(IO_CACHE* file)
#ifdef MYSQL_CLIENT
-void Xid_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
- if (!short_form)
+ if (!print_event_info->short_form)
{
char buf[64];
longlong10_to_str(xid, buf, 10);
- print_header(file);
+ print_header(file, print_event_info);
fprintf(file, "\tXid = %s\n", buf);
fflush(file);
}
@@ -3526,11 +3584,11 @@ bool User_var_log_event::write(IO_CACHE* file)
*/
#ifdef MYSQL_CLIENT
-void User_var_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
- if (!short_form)
+ if (!print_event_info->short_form)
{
- print_header(file);
+ print_header(file, print_event_info);
fprintf(file, "\tUser_var\n");
}
@@ -3701,11 +3759,11 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli)
#ifdef HAVE_REPLICATION
#ifdef MYSQL_CLIENT
-void Unknown_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+void Unknown_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
- if (short_form)
+ if (print_event_info->short_form)
return;
- print_header(file);
+ print_header(file, print_event_info);
fputc('\n', file);
fprintf(file, "# %s", "Unknown event\n");
}
@@ -3772,12 +3830,12 @@ Slave_log_event::~Slave_log_event()
#ifdef MYSQL_CLIENT
-void Slave_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+void Slave_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
char llbuff[22];
- if (short_form)
+ if (print_event_info->short_form)
return;
- print_header(file);
+ print_header(file, print_event_info);
fputc('\n', file);
fprintf(file, "\
Slave: master_host: '%s' master_port: %d master_log: '%s' master_pos: %s\n",
@@ -3857,12 +3915,12 @@ int Slave_log_event::exec_event(struct st_relay_log_info* rli)
*/
#ifdef MYSQL_CLIENT
-void Stop_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
- if (short_form)
+ if (print_event_info->short_form)
return;
- print_header(file);
+ print_header(file, print_event_info);
fprintf(file, "\tStop\n");
fflush(file);
}
@@ -4036,19 +4094,20 @@ Create_file_log_event::Create_file_log_event(const char* buf, uint len,
*/
#ifdef MYSQL_CLIENT
-void Create_file_log_event::print(FILE* file, bool short_form,
- LAST_EVENT_INFO* last_event_info, bool enable_local)
+void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
+ bool enable_local)
{
- if (short_form)
+ if (print_event_info->short_form)
{
if (enable_local && check_fname_outside_temp_buf())
- Load_log_event::print(file, 1, last_event_info);
+ Load_log_event::print(file, print_event_info);
return;
}
if (enable_local)
{
- Load_log_event::print(file, short_form, last_event_info, !check_fname_outside_temp_buf());
+ Load_log_event::print(file, print_event_info,
+ !check_fname_outside_temp_buf());
/*
That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
SHOW BINLOG EVENTS we don't.
@@ -4060,10 +4119,9 @@ void Create_file_log_event::print(FILE* file, bool short_form,
}
-void Create_file_log_event::print(FILE* file, bool short_form,
- LAST_EVENT_INFO* last_event_info)
+void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
- print(file,short_form,last_event_info,0);
+ print(file, print_event_info, 0);
}
#endif /* MYSQL_CLIENT */
@@ -4223,12 +4281,12 @@ bool Append_block_log_event::write(IO_CACHE* file)
*/
#ifdef MYSQL_CLIENT
-void Append_block_log_event::print(FILE* file, bool short_form,
- LAST_EVENT_INFO* last_event_info)
+void Append_block_log_event::print(FILE* file,
+ PRINT_EVENT_INFO* print_event_info)
{
- if (short_form)
+ if (print_event_info->short_form)
return;
- print_header(file);
+ print_header(file, print_event_info);
fputc('\n', file);
fprintf(file, "#%s: file_id: %d block_len: %d\n",
get_type_str(), file_id, block_len);
@@ -4367,12 +4425,12 @@ bool Delete_file_log_event::write(IO_CACHE* file)
*/
#ifdef MYSQL_CLIENT
-void Delete_file_log_event::print(FILE* file, bool short_form,
- LAST_EVENT_INFO* last_event_info)
+void Delete_file_log_event::print(FILE* file,
+ PRINT_EVENT_INFO* print_event_info)
{
- if (short_form)
+ if (print_event_info->short_form)
return;
- print_header(file);
+ print_header(file, print_event_info);
fputc('\n', file);
fprintf(file, "#Delete_file: file_id=%u\n", file_id);
}
@@ -4463,12 +4521,12 @@ bool Execute_load_log_event::write(IO_CACHE* file)
*/
#ifdef MYSQL_CLIENT
-void Execute_load_log_event::print(FILE* file, bool short_form,
- LAST_EVENT_INFO* last_event_info)
+void Execute_load_log_event::print(FILE* file,
+ PRINT_EVENT_INFO* print_event_info)
{
- if (short_form)
+ if (print_event_info->short_form)
return;
- print_header(file);
+ print_header(file, print_event_info);
fputc('\n', file);
fprintf(file, "#Exec_load: file_id=%d\n",
file_id);
@@ -4675,18 +4733,18 @@ Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
#ifdef MYSQL_CLIENT
-void Execute_load_query_log_event::print(FILE* file, bool short_form,
- LAST_EVENT_INFO* last_event_info)
+void Execute_load_query_log_event::print(FILE* file,
+ PRINT_EVENT_INFO* print_event_info)
{
- print(file, short_form, last_event_info, 0);
+ print(file, print_event_info, 0);
}
-void Execute_load_query_log_event::print(FILE* file, bool short_form,
- LAST_EVENT_INFO* last_event_info,
+void Execute_load_query_log_event::print(FILE* file,
+ PRINT_EVENT_INFO* print_event_info,
const char *local_fname)
{
- print_query_header(file, short_form, last_event_info);
+ print_query_header(file, print_event_info);
if (local_fname)
{
@@ -4707,7 +4765,7 @@ void Execute_load_query_log_event::print(FILE* file, bool short_form,
fprintf(file, ";\n");
}
- if (!short_form)
+ if (!print_event_info->short_form)
fprintf(file, "# file_id: %d \n", file_id);
}
#endif
diff --git a/sql/log_event.h b/sql/log_event.h
index b0f76aa1034..8acdf015464 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -403,27 +403,38 @@ enum Log_event_type
Every time you update this enum (when you add a type), you have to
fix Format_description_log_event::Format_description_log_event().
*/
- UNKNOWN_EVENT= 0, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
- INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
- APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT,
+ UNKNOWN_EVENT= 0,
+ START_EVENT_V3= 1,
+ QUERY_EVENT= 2,
+ STOP_EVENT= 3,
+ ROTATE_EVENT= 4,
+ INTVAR_EVENT= 5,
+ LOAD_EVENT= 6,
+ SLAVE_EVENT= 7,
+ CREATE_FILE_EVENT= 8,
+ APPEND_BLOCK_EVENT= 9,
+ EXEC_LOAD_EVENT= 10,
+ DELETE_FILE_EVENT= 11,
/*
NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer
sql_ex, allowing multibyte TERMINATED BY etc; both types share the
same class (Load_log_event)
*/
- NEW_LOAD_EVENT,
- RAND_EVENT, USER_VAR_EVENT,
- FORMAT_DESCRIPTION_EVENT,
- XID_EVENT,
- BEGIN_LOAD_QUERY_EVENT,
- EXECUTE_LOAD_QUERY_EVENT,
+ NEW_LOAD_EVENT= 12,
+ RAND_EVENT= 13,
+ USER_VAR_EVENT= 14,
+ FORMAT_DESCRIPTION_EVENT= 15,
+ XID_EVENT= 16,
+ BEGIN_LOAD_QUERY_EVENT= 17,
+ EXECUTE_LOAD_QUERY_EVENT= 18,
/*
- add new events here - right above this comment!
- existing events should never change their numbers
+ Add new events here - right above this comment!
+ And change the ENUM_END_EVENT_MARKER below.
+ Existing events should never change their numbers
*/
- ENUM_END_EVENT /* end marker */
+ ENUM_END_EVENT= 19 /* end marker */
};
/*
@@ -451,12 +462,23 @@ struct st_relay_log_info;
#ifdef MYSQL_CLIENT
/*
- A structure for mysqlbinlog to remember the last db, flags2, sql_mode etc; it
- is passed to events' print() methods, so that they print only the necessary
- USE and SET commands.
+ A structure for mysqlbinlog to know how to print events
+
+ This structure is passed to the event's print() methods,
+
+ There are two types of settings stored here:
+ 1. Last db, flags2, sql_mode etc comes from the last printed event.
+ They are stored so that only the necessary USE and SET commands
+ are printed.
+ 2. Other information on how to print the events, e.g. short_form,
+ hexdump_from. These are not dependent on the last event.
*/
-typedef struct st_last_event_info
+typedef struct st_print_event_info
{
+ /*
+ Settings for database, sql_mode etc that comes from the last event
+ that was printed.
+ */
// TODO: have the last catalog here ??
char db[FN_REFLEN+1]; // TODO: make this a LEX_STRING when thd->db is
bool flags2_inited;
@@ -467,12 +489,12 @@ typedef struct st_last_event_info
bool charset_inited;
char charset[6]; // 3 variables, each of them storable in 2 bytes
char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
- st_last_event_info()
+ st_print_event_info()
:flags2_inited(0), sql_mode_inited(0),
auto_increment_increment(1),auto_increment_offset(1), charset_inited(0)
{
/*
- Currently we only use static LAST_EVENT_INFO objects, so zeroed at
+ Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
program's startup, but these explicit bzero() is for the day someone
creates dynamic instances.
*/
@@ -480,7 +502,13 @@ typedef struct st_last_event_info
bzero(charset, sizeof(charset));
bzero(time_zone_str, sizeof(time_zone_str));
}
-} LAST_EVENT_INFO;
+
+ /* Settings on how to print the events */
+ bool short_form;
+ my_off_t hexdump_from;
+ uint8 common_header_len;
+
+} PRINT_EVENT_INFO;
#endif
@@ -589,9 +617,9 @@ public:
static Log_event* read_log_event(IO_CACHE* file,
const Format_description_log_event *description_event);
/* print*() functions are used by mysqlbinlog */
- virtual void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0) = 0;
+ virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0) = 0;
void print_timestamp(FILE* file, time_t *ts = 0);
- void print_header(FILE* file);
+ void print_header(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif
static void *operator new(size_t size)
@@ -751,8 +779,8 @@ public:
uint32 q_len_arg);
#endif /* HAVE_REPLICATION */
#else
- void print_query_header(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+ void print_query_header(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif
Query_log_event(const char* buf, uint event_len,
@@ -806,7 +834,7 @@ public:
void pack_info(Protocol* protocol);
int exec_event(struct st_relay_log_info* rli);
#else
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif
Slave_log_event(const char* buf, uint event_len);
@@ -894,8 +922,8 @@ public:
bool use_rli_only_for_errors);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info = 0);
- void print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info, bool commented);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info = 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool commented);
#endif
/*
@@ -984,7 +1012,7 @@ public:
#endif /* HAVE_REPLICATION */
#else
Start_log_event_v3() {}
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif
Start_log_event_v3(const char* buf,
@@ -1079,7 +1107,7 @@ public:
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif
Intvar_log_event(const char* buf, const Format_description_log_event* description_event);
@@ -1120,7 +1148,7 @@ class Rand_log_event: public Log_event
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif
Rand_log_event(const char* buf, const Format_description_log_event* description_event);
@@ -1157,7 +1185,7 @@ class Xid_log_event: public Log_event
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif
Xid_log_event(const char* buf, const Format_description_log_event* description_event);
@@ -1199,7 +1227,7 @@ public:
void pack_info(Protocol* protocol);
int exec_event(struct st_relay_log_info* rli);
#else
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif
User_var_log_event(const char* buf, const Format_description_log_event* description_event);
@@ -1225,7 +1253,7 @@ public:
{}
int exec_event(struct st_relay_log_info* rli);
#else
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif
Stop_log_event(const char* buf, const Format_description_log_event* description_event):
@@ -1263,7 +1291,7 @@ public:
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif
Rotate_log_event(const char* buf, uint event_len,
@@ -1316,8 +1344,8 @@ public:
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
- void print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info, bool enable_local);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool enable_local);
#endif
Create_file_log_event(const char* buf, uint event_len,
@@ -1384,7 +1412,7 @@ public:
virtual int get_create_or_append() const;
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif
Append_block_log_event(const char* buf, uint event_len,
@@ -1419,8 +1447,8 @@ public:
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
- void print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info, bool enable_local);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool enable_local);
#endif
Delete_file_log_event(const char* buf, uint event_len,
@@ -1455,7 +1483,7 @@ public:
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
#endif
Execute_load_log_event(const char* buf, uint event_len,
@@ -1540,11 +1568,10 @@ public:
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, bool short_form = 0,
- LAST_EVENT_INFO* last_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
/* Prints the query as LOAD DATA LOCAL and with rewritten filename */
- void print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info,
- const char *local_fname);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
+ const char *local_fname);
#endif
Execute_load_query_log_event(const char* buf, uint event_len,
const Format_description_log_event *description_event);
@@ -1573,7 +1600,7 @@ public:
Log_event(buf, description_event)
{}
~Unknown_log_event() {}
- void print(FILE* file, bool short_form= 0, LAST_EVENT_INFO* last_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
Log_event_type get_type_code() { return UNKNOWN_EVENT;}
bool is_valid() const { return 1; }
};
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index e51eb481767..252fb9c8467 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -5212,7 +5212,7 @@ replicating a LOAD DATA INFILE command.",
{"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME,
"The update log is deprecated since version 5.0, is replaced by the binary \
log and this option does nothing anymore.",
- 0, 0, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ 0, 0, 0, GET_DISABLED, NO_ARG, 0, 0, 0, 0, 0, 0},
{"sql-mode", OPT_SQL_MODE,
"Syntax: sql-mode=option[,option[,option...]] where option can be one of: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, ONLY_FULL_GROUP_BY, NO_UNSIGNED_SUBTRACTION.",
(gptr*) &sql_mode_str, (gptr*) &sql_mode_str, 0, GET_STR, REQUIRED_ARG, 0,
@@ -7155,6 +7155,7 @@ static void fix_paths(void)
CHARSET_DIR, NullS);
}
(void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff);
+ convert_dirname(mysql_charsets_dir, mysql_charsets_dir, NullS);
charsets_dir=mysql_charsets_dir;
if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index d4376a65594..973fbca12f5 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -4272,7 +4272,7 @@ bool setup_fields(THD *thd, Item **ref_pointer_array,
thd->set_query_id=set_query_id;
thd->allow_sum_func= allow_sum_func;
- thd->where="field list";
+ thd->where= THD::DEFAULT_WHERE;
/*
To prevent fail on forward lookup we fill it with zerows,
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 49b0554f3a2..ed781e9bba3 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1204,6 +1204,7 @@ sql mode: 0x%lx, sort len: %lu, conncat len: %lu",
#endif /*!EMBEDDED_LIBRARY*/
thd->limit_found_rows = query->found_rows();
+ thd->status_var.last_query_cost= 0.0;
BLOCK_UNLOCK_RD(query_block);
DBUG_RETURN(1); // Result sent to client
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 609156ef5a8..fc9df020b6c 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -44,6 +44,8 @@
*/
char internal_table_name[2]= "*";
+const char * const THD::DEFAULT_WHERE= "field list";
+
/*****************************************************************************
** Instansiate templates
@@ -234,7 +236,7 @@ THD::THD()
/* Variables with default values */
proc_info="login";
- where="field list";
+ where= THD::DEFAULT_WHERE;
server_id = ::server_id;
slave_net = 0;
command=COM_CONNECT;
@@ -545,6 +547,8 @@ void THD::cleanup_after_query()
}
/* Free Items that were created during this execution */
free_items();
+ /* Reset where. */
+ where= THD::DEFAULT_WHERE;
}
/*
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 2679143e9a5..7ca168ec518 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1109,6 +1109,14 @@ class THD :public Statement,
public Open_tables_state
{
public:
+ /*
+ Constant for THD::where initialization in the beginning of every query.
+
+ It's needed because we do not save/restore THD::where normally during
+ primary (non subselect) query execution.
+ */
+ static const char * const DEFAULT_WHERE;
+
#ifdef EMBEDDED_LIBRARY
struct st_mysql *mysql;
struct st_mysql_data *data;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 1e935c6dc2a..1bf346eafb1 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -738,6 +738,7 @@ typedef struct st_lex
/* store original leaf_tables for INSERT SELECT and PS/SP */
TABLE_LIST *leaf_tables_insert;
st_lex_user *create_view_definer;
+ char *create_view_start;
char *create_view_select_start;
List<key_part_spec> col_list;
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index ff2be0ae6fb..37342d47d78 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1014,8 +1014,23 @@ int READ_INFO::read_field()
*to++= (byte) escape_char;
goto found_eof;
}
- *to++ = (byte) unescape((char) chr);
- continue;
+ /*
+ When escape_char == enclosed_char, we treat it like we do for
+ handling quotes in SQL parsing -- you can double-up the
+ escape_char to include it literally, but it doesn't do escapes
+ like \n. This allows: LOAD DATA ... ENCLOSED BY '"' ESCAPED BY '"'
+ with data like: "fie""ld1", "field2"
+ */
+ if (escape_char != enclosed_char || chr == escape_char)
+ {
+ *to++ = (byte) unescape((char) chr);
+ continue;
+ }
+ else
+ {
+ PUSH(chr);
+ chr= escape_char;
+ }
}
#ifdef ALLOW_LINESEPARATOR_IN_STRINGS
if (chr == line_term_char)
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d0585dd1a65..33020fccd8e 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5791,7 +5791,7 @@ new_create_field(THD *thd, char *field_name, enum_field_types type,
case FIELD_TYPE_NULL:
break;
case FIELD_TYPE_NEWDECIMAL:
- if (!length)
+ if (!length && !new_field->decimals)
new_field->length= 10;
if (new_field->length > DECIMAL_MAX_PRECISION)
{
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 5f3539ca1e9..865c597e00d 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1742,6 +1742,8 @@ static bool check_prepared_statement(Prepared_statement *stmt,
case SQLCOM_ROLLBACK:
case SQLCOM_TRUNCATE:
case SQLCOM_CALL:
+ case SQLCOM_CREATE_VIEW:
+ case SQLCOM_DROP_VIEW:
break;
default:
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 806a6d3ea32..97d5bf4e1d5 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -537,6 +537,9 @@ JOIN::optimize()
DBUG_RETURN(0);
optimized= 1;
+ if (thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS)
+ thd->status_var.last_query_cost= 0.0;
+
row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
unit->select_limit_cnt);
/* select_limit is used to decide if we are likely to scan the whole table */
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index e1d3c7d6d33..72bb8cdb4cf 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2559,11 +2559,12 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables,
is_blob= (field->type() == FIELD_TYPE_BLOB);
if (field->has_charset() || is_blob)
{
- longlong c_octet_len= is_blob ? (longlong) field->max_length() :
- (longlong) field->max_length()/field->charset()->mbmaxlen;
- table->field[8]->store((longlong) field->max_length(), TRUE);
+ longlong char_max_len= is_blob ?
+ (longlong) field->max_length() / field->charset()->mbminlen :
+ (longlong) field->max_length() / field->charset()->mbmaxlen;
+ table->field[8]->store(char_max_len, TRUE);
table->field[8]->set_notnull();
- table->field[9]->store(c_octet_len, TRUE);
+ table->field[9]->store((longlong) field->max_length(), TRUE);
table->field[9]->set_notnull();
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 1e96891113b..56a55d9fbc0 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1149,13 +1149,17 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{
column->length*= sql_field->charset->mbmaxlen;
- if (f_is_blob(sql_field->pack_flag))
+ if (f_is_blob(sql_field->pack_flag) ||
+ (f_is_geom(sql_field->pack_flag) && key->type != Key::SPATIAL))
{
if (!(file->table_flags() & HA_CAN_INDEX_BLOBS))
{
my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name);
DBUG_RETURN(-1);
}
+ if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type ==
+ Field::GEOM_POINT)
+ column->length= 21;
if (!column->length)
{
my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name);
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 5db08275735..858f0c2520e 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -643,7 +643,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
view->query.length= str.length()-1; // we do not need last \0
view->source.str= thd->lex->create_view_select_start;
view->source.length= (thd->query_length -
- (thd->lex->create_view_select_start - thd->query));
+ (thd->lex->create_view_select_start -
+ thd->lex->create_view_start));
view->file_version= 1;
view->calc_md5(md5);
view->md5.str= md5;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 94ce04fb5b1..fb77f01d38c 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -660,7 +660,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token YEAR_SYM
%token ZEROFILL
-%left JOIN_SYM
+%left JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT
/* A dummy token to force the priority of table_ref production in a join. */
%left TABLE_REF_PRIORITY
%left SET_VAR
@@ -1263,6 +1263,7 @@ create:
THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_CREATE_VIEW;
+ lex->create_view_start= thd->query;
/* first table in list is target VIEW name */
if (!lex->select_lex.add_table_to_list(thd, $7, NULL, 0))
YYABORT;
@@ -2669,9 +2670,21 @@ create_table_option:
| CHECKSUM_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; }
| DELAY_KEY_WRITE_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE; }
| ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT; }
- | RAID_TYPE opt_equal raid_types { Lex->create_info.raid_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
- | RAID_CHUNKS opt_equal ulong_num { Lex->create_info.raid_chunks= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
- | RAID_CHUNKSIZE opt_equal ulong_num { Lex->create_info.raid_chunksize= $3*RAID_BLOCK_SIZE; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
+ | RAID_TYPE opt_equal raid_types
+ {
+ my_error(ER_WARN_DEPRECATED_SYNTAX, MYF(0), "RAID_TYPE", "PARTITION");
+ YYABORT;
+ }
+ | RAID_CHUNKS opt_equal ulong_num
+ {
+ my_error(ER_WARN_DEPRECATED_SYNTAX, MYF(0), "RAID_CHUNKS", "PARTITION");
+ YYABORT;
+ }
+ | RAID_CHUNKSIZE opt_equal ulong_num
+ {
+ my_error(ER_WARN_DEPRECATED_SYNTAX, MYF(0), "RAID_CHUNKSIZE", "PARTITION");
+ YYABORT;
+ }
| UNION_SYM opt_equal '(' table_list ')'
{
/* Move the union list to the merge_list */
@@ -2969,7 +2982,9 @@ type:
spatial_type:
GEOMETRY_SYM { $$= Field::GEOM_GEOMETRY; }
| GEOMETRYCOLLECTION { $$= Field::GEOM_GEOMETRYCOLLECTION; }
- | POINT_SYM { $$= Field::GEOM_POINT; }
+ | POINT_SYM { Lex->length= (char*)"21";
+ $$= Field::GEOM_POINT;
+ }
| MULTIPOINT { $$= Field::GEOM_MULTIPOINT; }
| LINESTRING { $$= Field::GEOM_LINESTRING; }
| MULTILINESTRING { $$= Field::GEOM_MULTILINESTRING; }
@@ -3425,6 +3440,7 @@ alter:
THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_CREATE_VIEW;
+ lex->create_view_start= thd->query;
lex->create_view_mode= VIEW_ALTER;
/* first table in list is target VIEW name */
lex->select_lex.add_table_to_list(thd, $6, NULL, 0);
@@ -5225,14 +5241,22 @@ derived_table_list:
}
;
+/*
+ Notice that JOIN is a left-associative operation, and it must be parsed
+ as such, that is, the parser must process first the left join operand
+ then the right one. Such order of processing ensures that the parser
+ produces correct join trees which is essential for semantic analysis
+ and subsequent optimization phases.
+*/
join_table:
+/* INNER JOIN variants */
/*
- Evaluate production 'table_ref' before 'normal_join' so that
- [INNER | CROSS] JOIN is properly nested as other left-associative
- joins.
+ Use %prec to evaluate production 'table_ref' before 'normal_join'
+ so that [INNER | CROSS] JOIN is properly nested as other
+ left-associative joins.
*/
table_ref %prec TABLE_REF_PRIORITY normal_join table_ref
- { YYERROR_UNLESS($1 && ($$=$3)); }
+ { YYERROR_UNLESS($1 && ($$=$3)); }
| table_ref STRAIGHT_JOIN table_factor
{ YYERROR_UNLESS($1 && ($$=$3)); $3->straight=1; }
| table_ref normal_join table_ref
@@ -5274,6 +5298,13 @@ join_table:
}
'(' using_list ')'
{ add_join_natural($1,$3,$7); $$=$3; }
+ | table_ref NATURAL JOIN_SYM table_factor
+ {
+ YYERROR_UNLESS($1 && ($$=$4));
+ add_join_natural($1,$4,NULL);
+ }
+
+/* LEFT JOIN variants */
| table_ref LEFT opt_outer JOIN_SYM table_ref
ON
{
@@ -5305,6 +5336,8 @@ join_table:
$6->outer_join|=JOIN_TYPE_LEFT;
$$=$6;
}
+
+/* RIGHT JOIN variants */
| table_ref RIGHT opt_outer JOIN_SYM table_ref
ON
{
@@ -5342,10 +5375,7 @@ join_table:
LEX *lex= Lex;
if (!($$= lex->current_select->convert_right_join()))
YYABORT;
- }
- | table_ref NATURAL JOIN_SYM table_factor
- { YYERROR_UNLESS($1 && ($$=$4)); add_join_natural($1,$4,NULL); };
-
+ };
normal_join:
JOIN_SYM {}