summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authormsvensson@shellback.(none) <>2006-11-29 15:44:09 +0100
committermsvensson@shellback.(none) <>2006-11-29 15:44:09 +0100
commit7ddc43e30596246effffa5944c23d019120f8dda (patch)
tree9a20c4415bb69ebb31576302a0e46beb9863997e /sql
parentebee55f48a09c3971192beeb122d3fff17794ba6 (diff)
parent40684173ad1c4a0a64c8c5bccc0ac9ff1009d8bf (diff)
downloadmariadb-git-7ddc43e30596246effffa5944c23d019120f8dda.tar.gz
Merge shellback.(none):/home/msvensson/mysql/mysql-5.1
into shellback.(none):/home/msvensson/mysql/mysql-5.1-maint
Diffstat (limited to 'sql')
-rw-r--r--sql/event_data_objects.cc83
-rw-r--r--sql/event_data_objects.h4
-rw-r--r--sql/event_db_repository.cc2
-rw-r--r--sql/event_queue.cc46
-rw-r--r--sql/event_scheduler.cc23
-rw-r--r--sql/events.cc2
-rw-r--r--sql/field.cc47
-rw-r--r--sql/field.h8
-rw-r--r--sql/field_conv.cc12
-rw-r--r--sql/filesort.cc45
-rw-r--r--sql/ha_ndbcluster.cc62
-rw-r--r--sql/ha_ndbcluster_binlog.cc122
-rw-r--r--sql/ha_ndbcluster_tables.h2
-rw-r--r--sql/ha_partition.cc10
-rw-r--r--sql/handler.cc20
-rw-r--r--sql/item.cc111
-rw-r--r--sql/item.h15
-rw-r--r--sql/item_cmpfunc.cc38
-rw-r--r--sql/item_cmpfunc.h48
-rw-r--r--sql/item_func.cc25
-rw-r--r--sql/item_func.h1
-rw-r--r--sql/item_strfunc.cc6
-rw-r--r--sql/item_subselect.cc486
-rw-r--r--sql/item_subselect.h84
-rw-r--r--sql/item_sum.cc58
-rw-r--r--sql/item_sum.h34
-rw-r--r--sql/item_timefunc.cc27
-rw-r--r--sql/item_timefunc.h150
-rw-r--r--sql/key.cc51
-rw-r--r--sql/log.cc41
-rw-r--r--sql/log_event.cc54
-rw-r--r--sql/my_decimal.cc19
-rw-r--r--sql/my_decimal.h7
-rw-r--r--sql/mysql_priv.h7
-rw-r--r--sql/mysqld.cc13
-rw-r--r--sql/mysqld.cc.rej17
-rw-r--r--sql/net_serv.cc2
-rw-r--r--sql/opt_range.cc22
-rw-r--r--sql/parse_file.h17
-rw-r--r--sql/protocol.cc16
-rw-r--r--sql/protocol.h1
-rw-r--r--sql/records.cc7
-rw-r--r--sql/repl_failsafe.cc4
-rw-r--r--sql/rpl_rli.cc4
-rw-r--r--sql/rpl_tblmap.cc16
-rw-r--r--sql/rpl_utility.cc11
-rw-r--r--sql/set_var.cc2
-rw-r--r--sql/slave.cc27
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sql_acl.cc2
-rw-r--r--sql/sql_base.cc27
-rw-r--r--sql/sql_binlog.cc20
-rw-r--r--sql/sql_cache.cc89
-rw-r--r--sql/sql_class.cc16
-rw-r--r--sql/sql_class.h17
-rw-r--r--sql/sql_db.cc46
-rw-r--r--sql/sql_delete.cc2
-rw-r--r--sql/sql_handler.cc7
-rw-r--r--sql/sql_lex.cc11
-rw-r--r--sql/sql_lex.h9
-rw-r--r--sql/sql_parse.cc345
-rw-r--r--sql/sql_parse.cc.rej166
-rw-r--r--sql/sql_partition.cc2
-rw-r--r--sql/sql_prepare.cc22
-rw-r--r--sql/sql_repl.cc4
-rw-r--r--sql/sql_select.cc144
-rw-r--r--sql/sql_select.h11
-rw-r--r--sql/sql_show.cc2
-rw-r--r--sql/sql_table.cc7
-rw-r--r--sql/sql_test.cc9
-rw-r--r--sql/sql_trigger.cc4
-rw-r--r--sql/sql_update.cc4
-rw-r--r--sql/sql_yacc.yy83
-rw-r--r--sql/strfunc.cc2
-rw-r--r--sql/table.cc85
-rw-r--r--sql/table.cc.rej17
-rw-r--r--sql/table.h5
-rw-r--r--sql/tztime.cc15
-rw-r--r--sql/unireg.cc8
79 files changed, 2159 insertions, 933 deletions
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index afd10350bb5..0de90e4145b 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -124,8 +124,8 @@ void
Event_parse_data::init_body(THD *thd)
{
DBUG_ENTER("Event_parse_data::init_body");
- DBUG_PRINT("info", ("body=[%s] body_begin=0x%lx end=0x%lx", body_begin,
- body_begin, thd->lex->ptr));
+ DBUG_PRINT("info", ("body: '%s' body_begin: 0x%lx end: 0x%lx", body_begin,
+ (long) body_begin, (long) thd->lex->ptr));
body.length= thd->lex->ptr - body_begin;
const uchar *body_end= body_begin + body.length - 1;
@@ -399,8 +399,9 @@ Event_parse_data::init_starts(THD *thd)
thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp,
(my_time_t) thd->query_start());
- DBUG_PRINT("info",("now =%lld", TIME_to_ulonglong_datetime(&time_tmp)));
- DBUG_PRINT("info",("starts=%lld", TIME_to_ulonglong_datetime(&ltime)));
+ DBUG_PRINT("info",("now: %ld starts: %ld",
+ (long) TIME_to_ulonglong_datetime(&time_tmp),
+ (long) TIME_to_ulonglong_datetime(&ltime)));
if (TIME_to_ulonglong_datetime(&ltime) <
TIME_to_ulonglong_datetime(&time_tmp))
goto wrong_value;
@@ -536,8 +537,9 @@ Event_parse_data::check_parse_data(THD *thd)
{
bool ret;
DBUG_ENTER("Event_parse_data::check_parse_data");
- DBUG_PRINT("info", ("execute_at=0x%lx expr=0x%lx starts=0x%lx ends=0x%lx",
- item_execute_at, item_expression, item_starts, item_ends));
+ DBUG_PRINT("info", ("execute_at: 0x%lx expr=0x%lx starts=0x%lx ends=0x%lx",
+ (long) item_execute_at, (long) item_expression,
+ (long) item_starts, (long) item_ends));
init_name(thd, identifier);
@@ -564,9 +566,9 @@ Event_parse_data::init_definer(THD *thd)
int definer_host_len;
DBUG_ENTER("Event_parse_data::init_definer");
- DBUG_PRINT("info",("init definer_user thd->mem_root=0x%lx "
- "thd->sec_ctx->priv_user=0x%lx", thd->mem_root,
- thd->security_ctx->priv_user));
+ DBUG_PRINT("info",("init definer_user thd->mem_root: 0x%lx "
+ "thd->sec_ctx->priv_user: 0x%lx", (long) thd->mem_root,
+ (long) thd->security_ctx->priv_user));
definer_user_len= strlen(thd->security_ctx->priv_user);
definer_host_len= strlen(thd->security_ctx->priv_host);
@@ -1032,8 +1034,9 @@ bool get_next_time(TIME *next, TIME *start, TIME *time_now, TIME *last_exec,
TIME tmp;
longlong months=0, seconds=0;
DBUG_ENTER("get_next_time");
- DBUG_PRINT("enter", ("start=%llu now=%llu", TIME_to_ulonglong_datetime(start),
- TIME_to_ulonglong_datetime(time_now)));
+ DBUG_PRINT("enter", ("start: %lu now: %lu",
+ (long) TIME_to_ulonglong_datetime(start),
+ (long) TIME_to_ulonglong_datetime(time_now)));
bzero(&interval, sizeof(interval));
@@ -1081,7 +1084,7 @@ bool get_next_time(TIME *next, TIME *start, TIME *time_now, TIME *last_exec,
case INTERVAL_LAST:
DBUG_ASSERT(0);
}
- DBUG_PRINT("info", ("seconds=%ld months=%ld", seconds, months));
+ DBUG_PRINT("info", ("seconds: %ld months: %ld", (long) seconds, (long) months));
if (seconds)
{
longlong seconds_diff;
@@ -1099,14 +1102,14 @@ bool get_next_time(TIME *next, TIME *start, TIME *time_now, TIME *last_exec,
event two times for the same time
get the next exec if the modulus is not
*/
- DBUG_PRINT("info", ("multiplier=%d", multiplier));
+ DBUG_PRINT("info", ("multiplier: %d", multiplier));
if (seconds_diff % seconds || (!seconds_diff && last_exec->year) ||
TIME_to_ulonglong_datetime(time_now) ==
TIME_to_ulonglong_datetime(last_exec))
++multiplier;
interval.second= seconds * multiplier;
- DBUG_PRINT("info", ("multiplier=%u interval.second=%u", multiplier,
- interval.second));
+ DBUG_PRINT("info", ("multiplier: %lu interval.second: %lu", (ulong) multiplier,
+ (ulong) interval.second));
tmp= *start;
if (!(ret= date_add_interval(&tmp, INTERVAL_SECOND, interval)))
*next= tmp;
@@ -1158,7 +1161,7 @@ bool get_next_time(TIME *next, TIME *start, TIME *time_now, TIME *last_exec,
}
done:
- DBUG_PRINT("info", ("next=%llu", TIME_to_ulonglong_datetime(next)));
+ DBUG_PRINT("info", ("next: %lu", (long) TIME_to_ulonglong_datetime(next)));
DBUG_RETURN(ret);
}
@@ -1183,17 +1186,17 @@ Event_queue_element::compute_next_execution_time()
{
TIME time_now;
int tmp;
-
DBUG_ENTER("Event_queue_element::compute_next_execution_time");
- DBUG_PRINT("enter", ("starts=%llu ends=%llu last_executed=%llu this=0x%lx",
- TIME_to_ulonglong_datetime(&starts),
- TIME_to_ulonglong_datetime(&ends),
- TIME_to_ulonglong_datetime(&last_executed), this));
+ DBUG_PRINT("enter", ("starts: %lu ends: %lu last_executed: %lu this: 0x%lx",
+ (long) TIME_to_ulonglong_datetime(&starts),
+ (long) TIME_to_ulonglong_datetime(&ends),
+ (long) TIME_to_ulonglong_datetime(&last_executed),
+ (long) this));
if (status == Event_queue_element::DISABLED)
{
DBUG_PRINT("compute_next_execution_time",
- ("Event %s is DISABLED", name.str));
+ ("Event %s is DISABLED", name.str));
goto ret;
}
/* If one-time, no need to do computation */
@@ -1203,9 +1206,9 @@ Event_queue_element::compute_next_execution_time()
if (last_executed.year)
{
DBUG_PRINT("info",("One-time event %s.%s of was already executed",
- dbname.str, name.str, definer.str));
+ dbname.str, name.str));
dropped= (on_completion == Event_queue_element::ON_COMPLETION_DROP);
- DBUG_PRINT("info",("One-time event will be dropped=%d.", dropped));
+ DBUG_PRINT("info",("One-time event will be dropped: %d.", dropped));
status= Event_queue_element::DISABLED;
status_changed= TRUE;
@@ -1215,7 +1218,8 @@ Event_queue_element::compute_next_execution_time()
my_tz_UTC->gmt_sec_to_TIME(&time_now, current_thd->query_start());
- DBUG_PRINT("info",("NOW=[%llu]", TIME_to_ulonglong_datetime(&time_now)));
+ DBUG_PRINT("info",("NOW: [%lu]",
+ (ulong) TIME_to_ulonglong_datetime(&time_now)));
/* if time_now is after ends don't execute anymore */
if (!ends_null && (tmp= my_time_compare(&ends, &time_now)) == -1)
@@ -1226,7 +1230,7 @@ Event_queue_element::compute_next_execution_time()
execute_at_null= TRUE;
if (on_completion == Event_queue_element::ON_COMPLETION_DROP)
dropped= TRUE;
- DBUG_PRINT("info", ("Dropped=%d", dropped));
+ DBUG_PRINT("info", ("Dropped: %d", dropped));
status= Event_queue_element::DISABLED;
status_changed= TRUE;
@@ -1297,7 +1301,8 @@ Event_queue_element::compute_next_execution_time()
}
else
{
- DBUG_PRINT("info",("Next[%llu]",TIME_to_ulonglong_datetime(&next_exec)));
+ DBUG_PRINT("info",("Next[%lu]",
+ (ulong) TIME_to_ulonglong_datetime(&next_exec)));
execute_at= next_exec;
execute_at_null= FALSE;
}
@@ -1319,7 +1324,8 @@ Event_queue_element::compute_next_execution_time()
expression, interval))
goto err;
execute_at= next_exec;
- DBUG_PRINT("info",("Next[%llu]",TIME_to_ulonglong_datetime(&next_exec)));
+ DBUG_PRINT("info",("Next[%lu]",
+ (ulong) TIME_to_ulonglong_datetime(&next_exec)));
}
else
{
@@ -1353,7 +1359,8 @@ Event_queue_element::compute_next_execution_time()
expression, interval))
goto err;
execute_at= next_exec;
- DBUG_PRINT("info",("Next[%llu]",TIME_to_ulonglong_datetime(&next_exec)));
+ DBUG_PRINT("info",("Next[%lu]",
+ (ulong) TIME_to_ulonglong_datetime(&next_exec)));
}
execute_at_null= FALSE;
}
@@ -1390,8 +1397,8 @@ Event_queue_element::compute_next_execution_time()
}
else
{
- DBUG_PRINT("info", ("Next[%llu]",
- TIME_to_ulonglong_datetime(&next_exec)));
+ DBUG_PRINT("info", ("Next[%lu]",
+ (ulong) TIME_to_ulonglong_datetime(&next_exec)));
execute_at= next_exec;
execute_at_null= FALSE;
}
@@ -1400,8 +1407,8 @@ Event_queue_element::compute_next_execution_time()
goto ret;
}
ret:
- DBUG_PRINT("info", ("ret=0 execute_at=%llu",
- TIME_to_ulonglong_datetime(&execute_at)));
+ DBUG_PRINT("info", ("ret: 0 execute_at: %lu",
+ (long) TIME_to_ulonglong_datetime(&execute_at)));
DBUG_RETURN(FALSE);
err:
DBUG_PRINT("info", ("ret=1"));
@@ -1688,7 +1695,7 @@ done:
thd->end_statement();
thd->cleanup_after_query();
- DBUG_PRINT("info", ("EXECUTED %s.%s ret=%d", dbname.str, name.str, ret));
+ DBUG_PRINT("info", ("EXECUTED %s.%s ret: %d", dbname.str, name.str, ret));
DBUG_RETURN(ret);
}
@@ -1752,7 +1759,7 @@ Event_job_data::compile(THD *thd, MEM_ROOT *mem_root)
thd->update_charset();
- DBUG_PRINT("info",("old_sql_mode=%d new_sql_mode=%d",old_sql_mode, sql_mode));
+ DBUG_PRINT("info",("old_sql_mode: %lu new_sql_mode: %lu",old_sql_mode, sql_mode));
thd->variables.sql_mode= this->sql_mode;
/* Change the memory root for the execution time */
if (mem_root)
@@ -1769,7 +1776,7 @@ Event_job_data::compile(THD *thd, MEM_ROOT *mem_root)
thd->query= show_create.c_ptr_safe();
thd->query_length= show_create.length();
- DBUG_PRINT("info", ("query:%s",thd->query));
+ DBUG_PRINT("info", ("query: %s",thd->query));
event_change_security_context(thd, definer_user, definer_host, dbname,
&save_ctx);
@@ -1777,14 +1784,14 @@ Event_job_data::compile(THD *thd, MEM_ROOT *mem_root)
mysql_init_query(thd, (uchar*) thd->query, thd->query_length);
if (MYSQLparse((void *)thd) || thd->is_fatal_error)
{
- DBUG_PRINT("error", ("error during compile or thd->is_fatal_error=%d",
+ DBUG_PRINT("error", ("error during compile or thd->is_fatal_error: %d",
thd->is_fatal_error));
/*
Free lex associated resources
QQ: Do we really need all this stuff here?
*/
sql_print_error("SCHEDULER: Error during compilation of %s.%s or "
- "thd->is_fatal_error=%d",
+ "thd->is_fatal_error: %d",
dbname.str, name.str, thd->is_fatal_error);
lex.unit.cleanup();
diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h
index e7e96d299fb..2da39c2158b 100644
--- a/sql/event_data_objects.h
+++ b/sql/event_data_objects.h
@@ -111,14 +111,14 @@ public:
void *p;
DBUG_ENTER("Event_queue_element::new(size)");
p= my_malloc(size, MYF(0));
- DBUG_PRINT("info", ("alloc_ptr=0x%lx", p));
+ DBUG_PRINT("info", ("alloc_ptr: 0x%lx", (long) p));
DBUG_RETURN(p);
}
static void operator delete(void *ptr, size_t size)
{
DBUG_ENTER("Event_queue_element::delete(ptr,size)");
- DBUG_PRINT("enter", ("free_ptr=0x%lx", ptr));
+ DBUG_PRINT("enter", ("free_ptr: 0x%lx", (long) ptr));
TRASH(ptr, size);
my_free((gptr) ptr, MYF(0));
DBUG_VOID_RETURN;
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 3d30aff669b..367c5bae579 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -958,7 +958,7 @@ Event_db_repository::load_named_event(THD *thd, LEX_STRING dbname,
Open_tables_state backup;
DBUG_ENTER("Event_db_repository::load_named_event");
- DBUG_PRINT("enter",("thd=0x%lx name:%*s",thd, name.length, name.str));
+ DBUG_PRINT("enter",("thd: 0x%lx name: %*s", (long) thd, name.length, name.str));
thd->reset_n_backup_open_tables_state(&backup);
diff --git a/sql/event_queue.cc b/sql/event_queue.cc
index 527a59018a8..7ec665fcd5f 100644
--- a/sql/event_queue.cc
+++ b/sql/event_queue.cc
@@ -143,7 +143,7 @@ Event_queue::init_queue(THD *thd, Event_db_repository *db_repo)
struct event_queue_param *event_queue_param_value= NULL;
DBUG_ENTER("Event_queue::init_queue");
- DBUG_PRINT("enter", ("this=0x%lx", this));
+ DBUG_PRINT("enter", ("this: 0x%lx", (long) this));
LOCK_QUEUE_DATA();
db_repository= db_repo;
@@ -218,7 +218,7 @@ Event_queue::create_event(THD *thd, LEX_STRING dbname, LEX_STRING name)
int res;
Event_queue_element *new_element;
DBUG_ENTER("Event_queue::create_event");
- DBUG_PRINT("enter", ("thd=0x%lx et=%s.%s",thd, dbname.str, name.str));
+ DBUG_PRINT("enter", ("thd: 0x%lx et=%s.%s", (long) thd, dbname.str, name.str));
new_element= new Event_queue_element();
res= db_repository->load_named_event(thd, dbname, name, new_element);
@@ -229,7 +229,7 @@ Event_queue::create_event(THD *thd, LEX_STRING dbname, LEX_STRING name)
new_element->compute_next_execution_time();
LOCK_QUEUE_DATA();
- DBUG_PRINT("info", ("new event in the queue 0x%lx", new_element));
+ DBUG_PRINT("info", ("new event in the queue: 0x%lx", (long) new_element));
queue_insert_safe(&queue, (byte *) new_element);
dbug_dump_queue(thd->query_start());
pthread_cond_broadcast(&COND_queue_state);
@@ -264,7 +264,7 @@ Event_queue::update_event(THD *thd, LEX_STRING dbname, LEX_STRING name,
Event_queue_element *new_element;
DBUG_ENTER("Event_queue::update_event");
- DBUG_PRINT("enter", ("thd=0x%lx et=[%s.%s]", thd, dbname.str, name.str));
+ DBUG_PRINT("enter", ("thd: 0x%lx et=[%s.%s]", (long) thd, dbname.str, name.str));
new_element= new Event_queue_element();
@@ -294,7 +294,7 @@ Event_queue::update_event(THD *thd, LEX_STRING dbname, LEX_STRING name,
/* If not disabled event */
if (new_element)
{
- DBUG_PRINT("info", ("new event in the Q 0x%lx", new_element));
+ DBUG_PRINT("info", ("new event in the queue: 0x%lx", (long) new_element));
queue_insert_safe(&queue, (byte *) new_element);
pthread_cond_broadcast(&COND_queue_state);
}
@@ -322,7 +322,8 @@ void
Event_queue::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name)
{
DBUG_ENTER("Event_queue::drop_event");
- DBUG_PRINT("enter", ("thd=0x%lx db=%s name=%s", thd, dbname.str, name.str));
+ DBUG_PRINT("enter", ("thd: 0x%lx db :%s name: %s", (long) thd,
+ dbname.str, name.str));
LOCK_QUEUE_DATA();
find_n_remove_event(dbname, name);
@@ -484,7 +485,7 @@ Event_queue::load_events_from_db(THD *thd)
bool clean_the_queue= TRUE;
DBUG_ENTER("Event_queue::load_events_from_db");
- DBUG_PRINT("enter", ("thd=0x%lx", thd));
+ DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
if ((ret= db_repository->open_event_table(thd, TL_READ, &table)))
{
@@ -555,7 +556,6 @@ Event_queue::load_events_from_db(THD *thd)
goto end;
}
- DBUG_PRINT("load_events_from_db", ("Adding 0x%lx to the exec list."));
queue_insert_safe(&queue, (byte *) et);
count++;
}
@@ -663,16 +663,20 @@ Event_queue::dbug_dump_queue(time_t now)
for (i = 0; i < queue.elements; i++)
{
et= ((Event_queue_element*)queue_element(&queue, i));
- DBUG_PRINT("info",("et=0x%lx db=%s name=%s",et, et->dbname.str, et->name.str));
- DBUG_PRINT("info", ("exec_at=%llu starts=%llu ends=%llu execs_so_far=%u"
- " expr=%lld et.exec_at=%d now=%d (et.exec_at - now)=%d if=%d",
- TIME_to_ulonglong_datetime(&et->execute_at),
- TIME_to_ulonglong_datetime(&et->starts),
- TIME_to_ulonglong_datetime(&et->ends),
- et->execution_count,
- et->expression, sec_since_epoch_TIME(&et->execute_at), now,
- (int)(sec_since_epoch_TIME(&et->execute_at) - now),
- sec_since_epoch_TIME(&et->execute_at) <= now));
+ DBUG_PRINT("info", ("et: 0x%lx name: %s.%s", (long) et,
+ et->dbname.str, et->name.str));
+ DBUG_PRINT("info", ("exec_at: %lu starts: %lu ends: %lu execs_so_far: %u "
+ "expr: %ld et.exec_at: %ld now: %ld "
+ "(et.exec_at - now): %d if: %d",
+ (long) TIME_to_ulonglong_datetime(&et->execute_at),
+ (long) TIME_to_ulonglong_datetime(&et->starts),
+ (long) TIME_to_ulonglong_datetime(&et->ends),
+ et->execution_count,
+ (long) et->expression,
+ (long) (sec_since_epoch_TIME(&et->execute_at)),
+ (long) now,
+ (int) (sec_since_epoch_TIME(&et->execute_at) - now),
+ sec_since_epoch_TIME(&et->execute_at) <= now));
}
DBUG_VOID_RETURN;
#endif
@@ -812,11 +816,11 @@ end:
if (to_free)
delete top;
- DBUG_PRINT("info", ("returning %d. et_new=0x%lx abstime.tv_sec=%d ",
- ret, *job_data, abstime? abstime->tv_sec:0));
+ DBUG_PRINT("info", ("returning %d et_new: 0x%lx abstime.tv_sec: %ld ",
+ ret, (long) *job_data, abstime ? abstime->tv_sec : 0));
if (*job_data)
- DBUG_PRINT("info", ("db=%s name=%s definer=%s", (*job_data)->dbname.str,
+ DBUG_PRINT("info", ("db: %s name: %s definer=%s", (*job_data)->dbname.str,
(*job_data)->name.str, (*job_data)->definer.str));
DBUG_RETURN(ret);
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index 6f9f6887c12..9be2f2d1125 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -264,8 +264,9 @@ event_worker_thread(void *arg)
if (!post_init_event_thread(thd))
{
- DBUG_PRINT("info", ("Baikonur, time is %d, BURAN reporting and operational."
- "THD=0x%lx", time(NULL), thd));
+ DBUG_PRINT("info", ("Baikonur, time is %ld, BURAN reporting and operational."
+ "THD: 0x%lx",
+ (long) time(NULL), (long) thd));
sql_print_information("SCHEDULER: [%s.%s of %s] executing in thread %lu. "
"Execution %u",
@@ -378,7 +379,7 @@ Event_scheduler::start()
DBUG_ENTER("Event_scheduler::start");
LOCK_DATA();
- DBUG_PRINT("info", ("state before action %s", scheduler_states_names[state]));
+ DBUG_PRINT("info", ("state before action %s", scheduler_states_names[state].str));
if (state > INITIALIZED)
goto end;
@@ -400,7 +401,7 @@ Event_scheduler::start()
scheduler_thd= new_thd;
DBUG_PRINT("info", ("Setting state go RUNNING"));
state= RUNNING;
- DBUG_PRINT("info", ("Forking new thread for scheduduler. THD=0x%lx", new_thd));
+ DBUG_PRINT("info", ("Forking new thread for scheduduler. THD: 0x%lx", (long) new_thd));
if (pthread_create(&th, &connection_attrib, event_scheduler_thread,
(void*)scheduler_param_value))
{
@@ -463,7 +464,7 @@ Event_scheduler::run(THD *thd)
break;
}
- DBUG_PRINT("info", ("get_top returned job_data=0x%lx", job_data));
+ DBUG_PRINT("info", ("get_top returned job_data: 0x%lx", (long) job_data));
if (job_data)
{
if ((res= execute_top(thd, job_data)))
@@ -522,11 +523,11 @@ Event_scheduler::execute_top(THD *thd, Event_job_data *job_data)
++started_events;
- DBUG_PRINT("info", ("Launch succeeded. BURAN is in THD=0x%lx", new_thd));
+ DBUG_PRINT("info", ("Launch succeeded. BURAN is in THD: 0x%lx", (long) new_thd));
DBUG_RETURN(FALSE);
error:
- DBUG_PRINT("error", ("Baikonur, we have a problem! res=%d", res));
+ DBUG_PRINT("error", ("Baikonur, we have a problem! res: %d", res));
if (new_thd)
{
new_thd->proc_info= "Clearing";
@@ -581,10 +582,10 @@ Event_scheduler::stop()
{
THD *thd= current_thd;
DBUG_ENTER("Event_scheduler::stop");
- DBUG_PRINT("enter", ("thd=0x%lx", current_thd));
+ DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
LOCK_DATA();
- DBUG_PRINT("info", ("state before action %s", scheduler_states_names[state]));
+ DBUG_PRINT("info", ("state before action %s", scheduler_states_names[state].str));
if (state != RUNNING)
goto end;
@@ -605,7 +606,7 @@ Event_scheduler::stop()
*/
state= STOPPING;
- DBUG_PRINT("info", ("Manager thread has id %d", scheduler_thd->thread_id));
+ DBUG_PRINT("info", ("Manager thread has id %lu", scheduler_thd->thread_id));
/* Lock from delete */
pthread_mutex_lock(&scheduler_thd->LOCK_delete);
/* This will wake up the thread if it waits on Queue's conditional */
@@ -775,7 +776,7 @@ Event_scheduler::dump_internal_status()
mutex_last_unlocked_at_line);
printf("WOC : %s\n", waiting_on_cond? "YES":"NO");
printf("Workers : %u\n", workers_count());
- printf("Executed : %llu\n", started_events);
+ printf("Executed : %lu\n", (ulong) started_events);
printf("Data locked: %s\n", mutex_scheduler_data_locked ? "YES":"NO");
DBUG_VOID_RETURN;
diff --git a/sql/events.cc b/sql/events.cc
index 10a8be948ef..3dbc6fd27e1 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -858,7 +858,7 @@ Events::check_system_tables(THD *thd)
bool ret= FALSE;
DBUG_ENTER("Events::check_system_tables");
- DBUG_PRINT("enter", ("thd=0x%lx", thd));
+ DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
thd->reset_n_backup_open_tables_state(&backup);
diff --git a/sql/field.cc b/sql/field.cc
index 1e42a53e45a..b83bb9a194d 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1237,12 +1237,6 @@ Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
}
-uint Field::offset()
-{
- return (uint) (ptr - (char*) table->record[0]);
-}
-
-
void Field::hash(ulong *nr, ulong *nr2)
{
if (is_null())
@@ -2478,6 +2472,13 @@ int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
}
+int Field_new_decimal::store_time(TIME *ltime, timestamp_type t_type)
+{
+ my_decimal decimal_value;
+ return store_value(date2my_decimal(ltime, &decimal_value));
+}
+
+
double Field_new_decimal::val_real(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
@@ -4919,7 +4920,7 @@ int Field_time::store_time(TIME *ltime, timestamp_type type)
(ltime->minute * 100 + ltime->second);
if (ltime->neg)
tmp= -tmp;
- return Field_time::store((longlong) tmp, TRUE);
+ return Field_time::store((longlong) tmp, FALSE);
}
@@ -5530,7 +5531,21 @@ int Field_newdate::store_time(TIME *ltime,timestamp_type type)
long tmp;
int error= 0;
if (type == MYSQL_TIMESTAMP_DATE || type == MYSQL_TIMESTAMP_DATETIME)
+ {
tmp=ltime->year*16*32+ltime->month*32+ltime->day;
+ if ((my_bool)check_date(ltime, tmp,
+ (TIME_FUZZY_DATE |
+ (current_thd->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
+ MODE_INVALID_DATES))), &error))
+ {
+ char buff[12];
+ String str(buff, sizeof(buff), &my_charset_latin1);
+ make_date((DATE_TIME_FORMAT *) 0, ltime, &str);
+ set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
+ str.ptr(), str.length(), MYSQL_TIMESTAMP_DATE, 1);
+ }
+ }
else
{
tmp=0;
@@ -5745,8 +5760,22 @@ int Field_datetime::store_time(TIME *ltime,timestamp_type type)
structure always fit into DATETIME range.
*/
if (type == MYSQL_TIMESTAMP_DATE || type == MYSQL_TIMESTAMP_DATETIME)
+ {
tmp=((ltime->year*10000L+ltime->month*100+ltime->day)*LL(1000000)+
(ltime->hour*10000L+ltime->minute*100+ltime->second));
+ if ((my_bool)check_date(ltime, tmp,
+ (TIME_FUZZY_DATE |
+ (current_thd->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
+ MODE_INVALID_DATES))), &error))
+ {
+ char buff[19];
+ String str(buff, sizeof(buff), &my_charset_latin1);
+ make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str);
+ set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED,
+ str.ptr(), str.length(), MYSQL_TIMESTAMP_DATETIME,1);
+ }
+ }
else
{
tmp=0;
@@ -8186,8 +8215,8 @@ Field_bit::do_last_null_byte() const
bits. On systems with CHAR_BIT > 8 (not very common), the storage
will lose the extra bits.
*/
- DBUG_PRINT("debug", ("bit_ofs=%d, bit_len=%d, bit_ptr=%p",
- bit_ofs, bit_len, bit_ptr));
+ DBUG_PRINT("test", ("bit_ofs: %d, bit_len: %d bit_ptr: 0x%lx",
+ bit_ofs, bit_len, (long) bit_ptr));
uchar *result;
if (bit_len == 0)
result= null_ptr;
diff --git a/sql/field.h b/sql/field.h
index f0cd9cc6f03..ff0c759ca71 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -239,7 +239,7 @@ public:
*/
my_size_t last_null_byte() const {
my_size_t bytes= do_last_null_byte();
- DBUG_PRINT("debug", ("last_null_byte() ==> %d", bytes));
+ DBUG_PRINT("debug", ("last_null_byte() ==> %ld", (long) bytes));
DBUG_ASSERT(bytes <= table->s->null_bytes);
return bytes;
}
@@ -342,7 +342,10 @@ public:
virtual int pack_cmp(const char *b, uint key_length_arg,
my_bool insert_or_update)
{ return cmp(ptr,b); }
- uint offset(); // Should be inline ...
+ uint offset(byte *record)
+ {
+ return (uint) (ptr - (char*) record);
+ }
void copy_from_tmp(int offset);
uint fill_cache_field(struct st_cache_field *copy);
virtual bool get_date(TIME *ltime,uint fuzzydate);
@@ -562,6 +565,7 @@ public:
int store(const char *to, uint length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
+ int store_time(TIME *ltime, timestamp_type t_type);
int store_decimal(const my_decimal *);
double val_real(void);
longlong val_int(void);
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 7bc6c432d1c..01b5306f5a4 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -119,12 +119,12 @@ set_field_to_null(Field *field)
return 0;
}
field->reset();
- if (current_thd->count_cuted_fields == CHECK_FIELD_WARN)
+ if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
{
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
return 0;
}
- if (!current_thd->no_errors)
+ if (!field->table->in_use->no_errors)
my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
return -1;
}
@@ -176,12 +176,12 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions)
field->table->auto_increment_field_not_null= FALSE;
return 0; // field is set in handler.cc
}
- if (current_thd->count_cuted_fields == CHECK_FIELD_WARN)
+ if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
{
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1);
return 0;
}
- if (!current_thd->no_errors)
+ if (!field->table->in_use->no_errors)
my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
return -1;
}
@@ -403,7 +403,7 @@ static void do_varstring1(Copy_field *copy)
if (length > copy->to_length- 1)
{
length=copy->to_length - 1;
- if (current_thd->count_cuted_fields)
+ if (copy->from_field->table->in_use->count_cuted_fields)
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1);
}
@@ -418,7 +418,7 @@ static void do_varstring2(Copy_field *copy)
if (length > copy->to_length- HA_KEY_BLOB_LENGTH)
{
length=copy->to_length-HA_KEY_BLOB_LENGTH;
- if (current_thd->count_cuted_fields)
+ if (copy->from_field->table->in_use->count_cuted_fields)
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1);
}
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 01f3bb97557..5f8153e64e7 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -115,6 +115,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
DBUG_PUSH(""); /* No DBUG here */
#endif
FILESORT_INFO table_sort;
+ TABLE_LIST *tab= table->pos_in_table_list;
+ Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
/*
Don't use table->sort in filesort as it is also used by
QUICK_INDEX_MERGE_SELECT. Work with a copy and put it back at the end
@@ -127,7 +129,6 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
my_b_clear(&tempfile);
my_b_clear(&buffpek_pointers);
buffpek=0;
- sort_keys= (uchar **) NULL;
error= 1;
bzero((char*) &param,sizeof(param));
param.sort_length= sortlength(thd, sortorder, s_length, &multi_byte_charset);
@@ -208,13 +209,15 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
ulong old_memavl;
ulong keys= memavl/(param.rec_length+sizeof(char*));
param.keys=(uint) min(records+1, keys);
- if ((sort_keys= (uchar **) make_char_array(param.keys, param.rec_length,
- MYF(0))))
+ if (table_sort.sort_keys ||
+ (table_sort.sort_keys= (uchar **) make_char_array(param.keys, param.rec_length,
+ MYF(0))))
break;
old_memavl=memavl;
if ((memavl=memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
memavl= min_sort_memory;
}
+ sort_keys= table_sort.sort_keys;
if (memavl < min_sort_memory)
{
my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),
@@ -241,8 +244,12 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
}
else
{
- if (!(buffpek=read_buffpek_from_file(&buffpek_pointers, maxbuffer)))
+ if (!table_sort.buffpek && table_sort.buffpek_len < maxbuffer &&
+ !(table_sort.buffpek=
+ (byte *) read_buffpek_from_file(&buffpek_pointers, maxbuffer)))
goto err;
+ buffpek= (BUFFPEK *) table_sort.buffpek;
+ table_sort.buffpek_len= maxbuffer;
close_cached_file(&buffpek_pointers);
/* Open cached file if it isn't open */
if (! my_b_inited(outfile) &&
@@ -275,8 +282,14 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
err:
if (param.tmp_buffer)
x_free(param.tmp_buffer);
- x_free((gptr) sort_keys);
- x_free((gptr) buffpek);
+ if (!subselect || !subselect->is_uncacheable())
+ {
+ x_free((gptr) sort_keys);
+ table_sort.sort_keys= 0;
+ x_free((gptr) buffpek);
+ table_sort.buffpek= 0;
+ table_sort.buffpek_len= 0;
+ }
close_cached_file(&tempfile);
close_cached_file(&buffpek_pointers);
if (my_b_inited(outfile))
@@ -302,18 +315,32 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
DBUG_POP(); /* Ok to DBUG */
#endif
memcpy(&table->sort, &table_sort, sizeof(FILESORT_INFO));
- DBUG_PRINT("exit",("records: %ld",records));
+ DBUG_PRINT("exit",("records: %ld", (long) records));
DBUG_RETURN(error ? HA_POS_ERROR : records);
} /* filesort */
-void filesort_free_buffers(TABLE *table)
+void filesort_free_buffers(TABLE *table, bool full)
{
if (table->sort.record_pointers)
{
my_free((gptr) table->sort.record_pointers,MYF(0));
table->sort.record_pointers=0;
}
+ if (full)
+ {
+ if (table->sort.sort_keys )
+ {
+ x_free((gptr) table->sort.sort_keys);
+ table->sort.sort_keys= 0;
+ }
+ if (table->sort.buffpek)
+ {
+ x_free((gptr) table->sort.buffpek);
+ table->sort.buffpek= 0;
+ table->sort.buffpek_len= 0;
+ }
+ }
if (table->sort.addon_buf)
{
my_free((char *) table->sort.addon_buf, MYF(0));
@@ -1023,7 +1050,7 @@ uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
Put all room used by freed buffer to use in adjacent buffer. Note, that
we can't simply distribute memory evenly between all buffers, because
new areas must not overlap with old ones.
- SYNOPSYS
+ SYNOPSIS
reuse_freed_buff()
queue IN list of non-empty buffers, without freed buffer
reuse IN empty buffer
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 331f6cf016c..093d7cdbcd6 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -413,7 +413,8 @@ Thd_ndb::get_open_table(THD *thd, const void *key)
thd_ndb_share->stat.no_uncommitted_rows_count= 0;
thd_ndb_share->stat.records= ~(ha_rows)0;
}
- DBUG_PRINT("exit", ("thd_ndb_share: %p key: %p", thd_ndb_share, key));
+ DBUG_PRINT("exit", ("thd_ndb_share: 0x%lx key: 0x%lx",
+ (long) thd_ndb_share, (long) key));
DBUG_RETURN(thd_ndb_share);
}
@@ -761,8 +762,8 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field,
blob_ptr= (char*)"";
}
- DBUG_PRINT("value", ("set blob ptr=%p len=%u",
- blob_ptr, blob_len));
+ DBUG_PRINT("value", ("set blob ptr: 0x%lx len: %u",
+ (long) blob_ptr, blob_len));
DBUG_DUMP("value", (char*)blob_ptr, min(blob_len, 26));
if (set_blob_value)
@@ -847,8 +848,8 @@ int get_ndb_blobs_value(TABLE* table, NdbValue* value_array,
uint32 len= 0xffffffff; // Max uint32
if (ndb_blob->readData(buf, len) != 0)
ERR_RETURN(ndb_blob->getNdbError());
- DBUG_PRINT("info", ("[%u] offset=%u buf=%p len=%u [ptrdiff=%d]",
- i, offset, buf, len, (int)ptrdiff));
+ DBUG_PRINT("info", ("[%u] offset: %u buf: 0x%lx len=%u [ptrdiff=%d]",
+ i, offset, (long) buf, len, (int)ptrdiff));
DBUG_ASSERT(len == len64);
// Ugly hack assumes only ptr needs to be changed
field_blob->ptr+= ptrdiff;
@@ -1171,8 +1172,8 @@ int ha_ndbcluster::add_index_handle(THD *thd, NDBDICT *dict, KEY *key_info,
index= dict->getIndexGlobal(index_name, *m_table);
if (!index)
ERR_RETURN(dict->getNdbError());
- DBUG_PRINT("info", ("index: %p id: %d version: %d.%d status: %d",
- index,
+ DBUG_PRINT("info", ("index: 0x%lx id: %d version: %d.%d status: %d",
+ (long) index,
index->getObjectId(),
index->getObjectVersion() & 0xFFFFFF,
index->getObjectVersion() >> 24,
@@ -1215,8 +1216,8 @@ int ha_ndbcluster::add_index_handle(THD *thd, NDBDICT *dict, KEY *key_info,
index= dict->getIndexGlobal(unique_index_name, *m_table);
if (!index)
ERR_RETURN(dict->getNdbError());
- DBUG_PRINT("info", ("index: %p id: %d version: %d.%d status: %d",
- index,
+ DBUG_PRINT("info", ("index: 0x%lx id: %d version: %d.%d status: %d",
+ (long) index,
index->getObjectId(),
index->getObjectVersion() & 0xFFFFFF,
index->getObjectVersion() >> 24,
@@ -2072,7 +2073,7 @@ inline int ha_ndbcluster::fetch_next(NdbScanOperation* cursor)
all pending update or delete operations should
be sent to NDB
*/
- DBUG_PRINT("info", ("ops_pending: %llu", m_ops_pending));
+ DBUG_PRINT("info", ("ops_pending: %ld", (long) m_ops_pending));
if (m_ops_pending)
{
if (m_transaction_on)
@@ -2305,7 +2306,7 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op,
// Set bound if not done with this key
if (p.key != NULL)
{
- DBUG_PRINT("info", ("key %d:%d offset=%d length=%d last=%d bound=%d",
+ DBUG_PRINT("info", ("key %d:%d offset: %d length: %d last: %d bound: %d",
j, i, tot_len, part_len, p.part_last, p.bound_type));
DBUG_DUMP("info", (const char*)p.part_ptr, part_store_len);
@@ -2462,7 +2463,7 @@ int ha_ndbcluster::full_table_scan(byte *buf)
part_spec.start_part= 0;
part_spec.end_part= m_part_info->get_tot_partitions() - 1;
prune_partition_set(table, &part_spec);
- DBUG_PRINT("info", ("part_spec.start_part = %u, part_spec.end_part = %u",
+ DBUG_PRINT("info", ("part_spec.start_part: %u part_spec.end_part: %u",
part_spec.start_part, part_spec.end_part));
/*
If partition pruning has found no partition in set
@@ -2658,7 +2659,7 @@ int ha_ndbcluster::write_row(byte *record)
{
// Send rows to NDB
DBUG_PRINT("info", ("Sending inserts to NDB, "\
- "rows_inserted:%d, bulk_insert_rows: %d",
+ "rows_inserted: %d bulk_insert_rows: %d",
(int)m_rows_inserted, (int)m_bulk_insert_rows));
m_bulk_insert_not_flushed= FALSE;
@@ -3108,7 +3109,8 @@ void ndb_unpack_record(TABLE *table, NdbValue *value,
char* ptr;
field_blob->get_ptr(&ptr, row_offset);
uint32 len= field_blob->get_length(row_offset);
- DBUG_PRINT("info",("[%u] SET ptr=%p len=%u", col_no, ptr, len));
+ DBUG_PRINT("info",("[%u] SET ptr: 0x%lx len: %u",
+ col_no, (long) ptr, len));
#endif
}
}
@@ -3350,7 +3352,7 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key,
if (m_use_partition_function)
{
get_partition_set(table, buf, active_index, start_key, &part_spec);
- DBUG_PRINT("info", ("part_spec.start_part = %u, part_spec.end_part = %u",
+ DBUG_PRINT("info", ("part_spec.start_part: %u part_spec.end_part: %u",
part_spec.start_part, part_spec.end_part));
/*
If partition pruning has found no partition in set
@@ -3480,7 +3482,7 @@ int ha_ndbcluster::close_scan()
Take over any pending transactions to the
deleteing/updating transaction before closing the scan
*/
- DBUG_PRINT("info", ("ops_pending: %llu", m_ops_pending));
+ DBUG_PRINT("info", ("ops_pending: %ld", (long) m_ops_pending));
if (execute_no_commit(this,trans,false) != 0) {
no_uncommitted_rows_execute_failure();
DBUG_RETURN(ndb_err(trans));
@@ -3876,7 +3878,7 @@ int ha_ndbcluster::end_bulk_insert()
NdbTransaction *trans= m_active_trans;
// Send rows to NDB
DBUG_PRINT("info", ("Sending inserts to NDB, "\
- "rows_inserted:%d, bulk_insert_rows: %d",
+ "rows_inserted: %d bulk_insert_rows: %d",
(int) m_rows_inserted, (int) m_bulk_insert_rows));
m_bulk_insert_not_flushed= FALSE;
if (m_transaction_on)
@@ -4286,8 +4288,8 @@ static int ndbcluster_commit(handlerton *hton, THD *thd, bool all)
while ((share= it++))
{
pthread_mutex_lock(&share->mutex);
- DBUG_PRINT("info", ("Invalidate commit_count for %s, commit_count: %llu ",
- share->key, share->commit_count));
+ DBUG_PRINT("info", ("Invalidate commit_count for %s, share->commit_count: %lu",
+ share->table_name, (ulong) share->commit_count));
share->commit_count= 0;
share->commit_count_lock++;
pthread_mutex_unlock(&share->mutex);
@@ -4690,8 +4692,7 @@ int ha_ndbcluster::create(const char *name,
my_free((char*)data, MYF(0));
DBUG_RETURN(2);
}
-
- DBUG_PRINT("info", ("setFrm data=%p len=%d", pack_data, pack_length));
+ DBUG_PRINT("info", ("setFrm data: 0x%lx len: %d", (long) pack_data, pack_length));
tab.setFrm(pack_data, pack_length);
my_free((char*)data, MYF(0));
my_free((char*)pack_data, MYF(0));
@@ -5102,13 +5103,12 @@ void ha_ndbcluster::prepare_for_alter()
int ha_ndbcluster::add_index(TABLE *table_arg,
KEY *key_info, uint num_of_keys)
{
- DBUG_ENTER("ha_ndbcluster::add_index");
- DBUG_PRINT("info", ("ha_ndbcluster::add_index to table %s",
- table_arg->s->table_name.str));
int error= 0;
uint idx;
-
+ DBUG_ENTER("ha_ndbcluster::add_index");
+ DBUG_PRINT("enter", ("table %s", table_arg->s->table_name.str));
DBUG_ASSERT(m_share->state == NSS_ALTERED);
+
for (idx= 0; idx < num_of_keys; idx++)
{
KEY *key= key_info + idx;
@@ -6664,7 +6664,7 @@ static int ndbcluster_end(handlerton *hton, ha_panic_function type)
void ha_ndbcluster::print_error(int error, myf errflag)
{
DBUG_ENTER("ha_ndbcluster::print_error");
- DBUG_PRINT("enter", ("error = %d", error));
+ DBUG_PRINT("enter", ("error: %d", error));
if (error == HA_ERR_NO_PARTITION_FOUND)
m_part_info->print_no_partition_found(table);
@@ -7797,7 +7797,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
get_partition_set(table, curr, active_index,
&multi_range_curr->start_key,
&part_spec);
- DBUG_PRINT("info", ("part_spec.start_part = %u, part_spec.end_part = %u",
+ DBUG_PRINT("info", ("part_spec.start_part: %u part_spec.end_part: %u",
part_spec.start_part, part_spec.end_part));
/*
If partition pruning has found no partition in set
@@ -8247,7 +8247,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
&abstime);
pthread_mutex_unlock(&LOCK_ndb_util_thread);
#ifdef NDB_EXTRA_DEBUG_UTIL_THREAD
- DBUG_PRINT("ndb_util_thread", ("Started, ndb_cache_check_time: %d",
+ DBUG_PRINT("ndb_util_thread", ("Started, ndb_cache_check_time: %lu",
ndb_cache_check_time));
#endif
if (abort_loop)
@@ -8325,8 +8325,8 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
ndbtab_g.get_table(), &stat) == 0)
{
char buff[22], buff2[22];
- DBUG_PRINT("ndb_util_thread",
- ("Table: %s, commit_count: %s, rows: %s",
+ DBUG_PRINT("info",
+ ("Table: %s commit_count: %s rows: %s",
share->key,
llstr(stat.commit_count, buff),
llstr(stat.row_count, buff2)));
@@ -9167,7 +9167,7 @@ void ndb_serialize_cond(const Item *item, void *arg)
if (context->expecting(Item::INT_ITEM))
{
Item_int *int_item= (Item_int *) item;
- DBUG_PRINT("info", ("value %llu", int_item->value));
+ DBUG_PRINT("info", ("value %ld", (long) int_item->value));
NDB_ITEM_QUALIFICATION q;
q.value_type= Item::INT_ITEM;
curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index e0b7502a40a..865fa0bde94 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -161,16 +161,16 @@ static void dbug_print_table(const char *info, TABLE *table)
}
DBUG_PRINT("info",
("%s: %s.%s s->fields: %d "
- "reclength: %d rec_buff_length: %d record[0]: %lx "
- "record[1]: %lx",
+ "reclength: %lu rec_buff_length: %u record[0]: 0x%lx "
+ "record[1]: 0x%lx",
info,
table->s->db.str,
table->s->table_name.str,
table->s->fields,
table->s->reclength,
table->s->rec_buff_length,
- table->record[0],
- table->record[1]));
+ (long) table->record[0],
+ (long) table->record[1]));
for (unsigned int i= 0; i < table->s->fields; i++)
{
@@ -180,7 +180,7 @@ static void dbug_print_table(const char *info, TABLE *table)
"ptr: 0x%lx[+%d] null_bit: %u null_ptr: 0x%lx[+%d]",
i,
f->field_name,
- f->flags,
+ (long) f->flags,
(f->flags & PRI_KEY_FLAG) ? "pri" : "attr",
(f->flags & NOT_NULL_FLAG) ? "" : ",nullable",
(f->flags & UNSIGNED_FLAG) ? ",unsigned" : ",signed",
@@ -189,16 +189,18 @@ static void dbug_print_table(const char *info, TABLE *table)
(f->flags & BINARY_FLAG) ? ",binary" : "",
f->real_type(),
f->pack_length(),
- f->ptr, f->ptr - table->record[0],
+ (long) f->ptr, (int) (f->ptr - table->record[0]),
f->null_bit,
- f->null_ptr, (byte*) f->null_ptr - table->record[0]));
+ (long) f->null_ptr,
+ (int) ((byte*) f->null_ptr - table->record[0])));
if (f->type() == MYSQL_TYPE_BIT)
{
Field_bit *g= (Field_bit*) f;
DBUG_PRINT("MYSQL_TYPE_BIT",("field_length: %d bit_ptr: 0x%lx[+%d] "
- "bit_ofs: %u bit_len: %u",
- g->field_length, g->bit_ptr,
- (byte*) g->bit_ptr-table->record[0],
+ "bit_ofs: %d bit_len: %u",
+ g->field_length, (long) g->bit_ptr,
+ (int) ((byte*) g->bit_ptr -
+ table->record[0]),
g->bit_ofs, g->bit_len));
}
}
@@ -605,11 +607,11 @@ static int ndbcluster_binlog_end(THD *thd)
{
DBUG_PRINT("share",
("[%d] 0x%lx key: %s key_length: %d",
- i, share, share->key, share->key_length));
+ i, (long) share, share->key, share->key_length));
DBUG_PRINT("share",
- ("db.tablename: %s.%s use_count: %d commit_count: %d",
+ ("db.tablename: %s.%s use_count: %d commit_count: %lu",
share->db, share->table_name,
- share->use_count, share->commit_count));
+ share->use_count, (long) share->commit_count));
}
}
pthread_mutex_unlock(&ndbcluster_mutex);
@@ -685,8 +687,8 @@ static NDB_SHARE *ndbcluster_check_apply_status_share()
void *share= hash_search(&ndbcluster_open_tables,
NDB_APPLY_TABLE_FILE,
sizeof(NDB_APPLY_TABLE_FILE) - 1);
- DBUG_PRINT("info",("ndbcluster_check_apply_status_share %s %p",
- NDB_APPLY_TABLE_FILE, share));
+ DBUG_PRINT("info",("ndbcluster_check_apply_status_share %s 0x%lx",
+ NDB_APPLY_TABLE_FILE, (long) share));
pthread_mutex_unlock(&ndbcluster_mutex);
return (NDB_SHARE*) share;
}
@@ -703,8 +705,8 @@ static NDB_SHARE *ndbcluster_check_schema_share()
void *share= hash_search(&ndbcluster_open_tables,
NDB_SCHEMA_TABLE_FILE,
sizeof(NDB_SCHEMA_TABLE_FILE) - 1);
- DBUG_PRINT("info",("ndbcluster_check_schema_share %s %p",
- NDB_SCHEMA_TABLE_FILE, share));
+ DBUG_PRINT("info",("ndbcluster_check_schema_share %s 0x%lx",
+ NDB_SCHEMA_TABLE_FILE, (long) share));
pthread_mutex_unlock(&ndbcluster_mutex);
return (NDB_SHARE*) share;
}
@@ -2721,10 +2723,9 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab,
if (share->flags & NSF_BLOB_FLAG)
op->mergeEvents(TRUE); // currently not inherited from event
- DBUG_PRINT("info", ("share->ndb_value[0]: 0x%x",
- share->ndb_value[0]));
- DBUG_PRINT("info", ("share->ndb_value[1]: 0x%x",
- share->ndb_value[1]));
+ DBUG_PRINT("info", ("share->ndb_value[0]: 0x%lx share->ndb_value[1]: 0x%lx",
+ (long) share->ndb_value[0],
+ (long) share->ndb_value[1]));
int n_columns= ndbtab->getNoOfColumns();
int n_fields= table ? table->s->fields : 0; // XXX ???
for (int j= 0; j < n_columns; j++)
@@ -2778,12 +2779,14 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab,
}
share->ndb_value[0][j].ptr= attr0.ptr;
share->ndb_value[1][j].ptr= attr1.ptr;
- DBUG_PRINT("info", ("&share->ndb_value[0][%d]: 0x%x "
- "share->ndb_value[0][%d]: 0x%x",
- j, &share->ndb_value[0][j], j, attr0.ptr));
- DBUG_PRINT("info", ("&share->ndb_value[1][%d]: 0x%x "
- "share->ndb_value[1][%d]: 0x%x",
- j, &share->ndb_value[0][j], j, attr1.ptr));
+ DBUG_PRINT("info", ("&share->ndb_value[0][%d]: 0x%lx "
+ "share->ndb_value[0][%d]: 0x%lx",
+ j, (long) &share->ndb_value[0][j],
+ j, (long) attr0.ptr));
+ DBUG_PRINT("info", ("&share->ndb_value[1][%d]: 0x%lx "
+ "share->ndb_value[1][%d]: 0x%lx",
+ j, (long) &share->ndb_value[0][j],
+ j, (long) attr1.ptr));
}
op->setCustomData((void *) share); // set before execute
share->op= op; // assign op in NDB_SHARE
@@ -2826,8 +2829,8 @@ ndbcluster_create_event_ops(NDB_SHARE *share, const NDBTAB *ndbtab,
(void) pthread_cond_signal(&injector_cond);
}
- DBUG_PRINT("info",("%s share->op: 0x%lx, share->use_count: %u",
- share->key, share->op, share->use_count));
+ DBUG_PRINT("info",("%s share->op: 0x%lx share->use_count: %u",
+ share->key, (long) share->op, share->use_count));
if (ndb_extra_logging)
sql_print_information("NDB Binlog: logging %s", share->key);
@@ -3012,10 +3015,11 @@ ndb_binlog_thread_handle_non_data_event(THD *thd, Ndb *ndb,
free_share(&apply_status_share);
apply_status_share= 0;
}
- DBUG_PRINT("info", ("CLUSTER FAILURE EVENT: "
- "%s received share: 0x%lx op: %lx share op: %lx "
- "op_old: %lx",
- share->key, share, pOp, share->op, share->op_old));
+ DBUG_PRINT("error", ("CLUSTER FAILURE EVENT: "
+ "%s received share: 0x%lx op: 0x%lx share op: 0x%lx "
+ "op_old: 0x%lx",
+ share->key, (long) share, (long) pOp,
+ (long) share->op, (long) share->op_old));
break;
case NDBEVENT::TE_DROP:
if (apply_status_share == share)
@@ -3033,10 +3037,11 @@ ndb_binlog_thread_handle_non_data_event(THD *thd, Ndb *ndb,
// fall through
case NDBEVENT::TE_ALTER:
row.n_schemaops++;
- DBUG_PRINT("info", ("TABLE %s EVENT: %s received share: 0x%lx op: %lx "
- "share op: %lx op_old: %lx",
- type == NDBEVENT::TE_DROP ? "DROP" : "ALTER",
- share->key, share, pOp, share->op, share->op_old));
+ DBUG_PRINT("info", ("TABLE %s EVENT: %s received share: 0x%lx op: 0x%lx "
+ "share op: 0x%lx op_old: 0x%lx",
+ type == NDBEVENT::TE_DROP ? "DROP" : "ALTER",
+ share->key, (long) share, (long) pOp,
+ (long) share->op, (long) share->op_old));
break;
case NDBEVENT::TE_NODE_FAILURE:
/* fall through */
@@ -3513,7 +3518,8 @@ restart:
}
}
// now check that we have epochs consistant with what we had before the restart
- DBUG_PRINT("info", ("schema_res: %d schema_gci: %d", schema_res, schema_gci));
+ DBUG_PRINT("info", ("schema_res: %d schema_gci: %lu", schema_res,
+ (long) schema_gci));
{
i_ndb->flushIncompleteEvents(schema_gci);
s_ndb->flushIncompleteEvents(schema_gci);
@@ -3557,9 +3563,11 @@ restart:
if (do_ndbcluster_binlog_close_connection)
{
DBUG_PRINT("info", ("do_ndbcluster_binlog_close_connection: %d, "
- "ndb_latest_handled_binlog_epoch: %llu, "
- "*p_latest_trans_gci: %llu", do_ndbcluster_binlog_close_connection,
- ndb_latest_handled_binlog_epoch, *p_latest_trans_gci));
+ "ndb_latest_handled_binlog_epoch: %lu, "
+ "*p_latest_trans_gci: %lu",
+ do_ndbcluster_binlog_close_connection,
+ (ulong) ndb_latest_handled_binlog_epoch,
+ (ulong) *p_latest_trans_gci));
}
#endif
#ifdef RUN_NDB_BINLOG_TIMER
@@ -3647,9 +3655,10 @@ restart:
do_ndbcluster_binlog_close_connection= BCCC_restart;
if (ndb_latest_received_binlog_epoch < *p_latest_trans_gci && ndb_binlog_running)
{
- sql_print_error("NDB Binlog: latest transaction in epoch %lld not in binlog "
- "as latest received epoch is %lld",
- *p_latest_trans_gci, ndb_latest_received_binlog_epoch);
+ sql_print_error("NDB Binlog: latest transaction in epoch %lu not in binlog "
+ "as latest received epoch is %lu",
+ (ulong) *p_latest_trans_gci,
+ (ulong) ndb_latest_received_binlog_epoch);
}
}
}
@@ -3697,8 +3706,8 @@ restart:
!= NULL)
{
NDB_SHARE *share= (NDB_SHARE*)gci_op->getCustomData();
- DBUG_PRINT("info", ("per gci_op: %p share: %p event_types: 0x%x",
- gci_op, share, event_types));
+ DBUG_PRINT("info", ("per gci_op: 0x%lx share: 0x%lx event_types: 0x%x",
+ (long) gci_op, (long) share, event_types));
// workaround for interface returning TE_STOP events
// which are normally filtered out below in the nextEvent loop
if ((event_types & ~NdbDictionary::Event::TE_STOP) == 0)
@@ -3784,11 +3793,13 @@ restart:
{
NDB_SHARE *share= (NDB_SHARE*) pOp->getCustomData();
DBUG_PRINT("info",
- ("EVENT TYPE: %d GCI: %lld last applied: %lld "
- "share: 0x%lx (%s.%s)", pOp->getEventType(), gci,
- ndb_latest_applied_binlog_epoch, share,
- share ? share->db : "share == NULL",
- share ? share->table_name : ""));
+ ("EVENT TYPE: %d GCI: %ld last applied: %ld "
+ "share: 0x%lx (%s.%s)", pOp->getEventType(),
+ (long) gci,
+ (long) ndb_latest_applied_binlog_epoch,
+ (long) share,
+ share ? share->db : "'NULL'",
+ share ? share->table_name : "'NULL'"));
DBUG_ASSERT(share != 0);
}
// assert that there is consistancy between gci op list
@@ -3833,9 +3844,10 @@ restart:
do_ndbcluster_binlog_close_connection= BCCC_restart;
if (ndb_latest_received_binlog_epoch < *p_latest_trans_gci && ndb_binlog_running)
{
- sql_print_error("NDB Binlog: latest transaction in epoch %lld not in binlog "
- "as latest received epoch is %lld",
- *p_latest_trans_gci, ndb_latest_received_binlog_epoch);
+ sql_print_error("NDB Binlog: latest transaction in epoch %lu not in binlog "
+ "as latest received epoch is %lu",
+ (ulong) *p_latest_trans_gci,
+ (ulong) ndb_latest_received_binlog_epoch);
}
}
}
@@ -3867,7 +3879,7 @@ restart:
row.master_log_file= start.file_name();
row.master_log_pos= start.file_pos();
- DBUG_PRINT("info", ("COMMIT gci: %lld", gci));
+ DBUG_PRINT("info", ("COMMIT gci: %lu", (ulong) gci));
if (ndb_update_binlog_index)
ndb_add_binlog_index(thd, &row);
ndb_latest_applied_binlog_epoch= gci;
diff --git a/sql/ha_ndbcluster_tables.h b/sql/ha_ndbcluster_tables.h
index 12124cd8820..9d7fda33102 100644
--- a/sql/ha_ndbcluster_tables.h
+++ b/sql/ha_ndbcluster_tables.h
@@ -15,7 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define NDB_REP_DB "cluster"
+#define NDB_REP_DB "mysql"
#define NDB_REP_TABLE "binlog_index"
#define NDB_APPLY_TABLE "apply_status"
#define NDB_SCHEMA_TABLE "schema"
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 3edd3923779..7cd33dd5726 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -2027,7 +2027,7 @@ bool ha_partition::create_handlers(MEM_ROOT *mem_root)
if (!(m_file[i]= get_new_handler(table_share, mem_root,
m_engine_array[i])))
DBUG_RETURN(TRUE);
- DBUG_PRINT("info", ("engine_type: %u", m_engine_array[i]));
+ DBUG_PRINT("info", ("engine_type: %u", m_engine_array[i]->db_type));
}
/* For the moment we only support partition over the same table engine */
if (m_engine_array[0] == myisam_hton)
@@ -2427,7 +2427,7 @@ repeat:
do
{
DBUG_PRINT("info", ("external_lock(thd, %d) iteration %d",
- lock_type, (file - m_file)));
+ lock_type, (int) (file - m_file)));
if ((error= (*file)->external_lock(thd, lock_type)))
{
if (F_UNLCK != lock_type)
@@ -2508,7 +2508,7 @@ THR_LOCK_DATA **ha_partition::store_lock(THD *thd,
file= m_file;
do
{
- DBUG_PRINT("info", ("store lock %d iteration", (file - m_file)));
+ DBUG_PRINT("info", ("store lock %d iteration", (int) (file - m_file)));
to= (*file)->store_lock(thd, to, lock_type);
} while (*(++file));
DBUG_RETURN(to);
@@ -2939,8 +2939,8 @@ int ha_partition::rnd_init(bool scan)
include_partition_fields_in_used_fields();
/* Now we see what the index of our first important partition is */
- DBUG_PRINT("info", ("m_part_info->used_partitions 0x%x",
- m_part_info->used_partitions.bitmap));
+ DBUG_PRINT("info", ("m_part_info->used_partitions: 0x%lx",
+ (long) m_part_info->used_partitions.bitmap));
part_id= bitmap_get_first_set(&(m_part_info->used_partitions));
DBUG_PRINT("info", ("m_part_spec.start_part %d", part_id));
diff --git a/sql/handler.cc b/sql/handler.cc
index f16876f2ffd..85345c70e36 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1513,7 +1513,7 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode,
DBUG_ENTER("handler::ha_open");
DBUG_PRINT("enter",
("name: %s db_type: %d db_stat: %d mode: %d lock_test: %d",
- name, table_share->db_type, table_arg->db_stat, mode,
+ name, ht->db_type, table_arg->db_stat, mode,
test_if_locked));
table= table_arg;
@@ -1654,7 +1654,7 @@ prev_insert_id(ulonglong nr, struct system_variables *variables)
*/
DBUG_PRINT("info",("auto_increment: nr: %lu cannot honour "
"auto_increment_offset: %lu",
- nr, variables->auto_increment_offset));
+ (ulong) nr, variables->auto_increment_offset));
return nr;
}
if (variables->auto_increment_increment == 1)
@@ -1927,8 +1927,8 @@ int handler::update_auto_increment()
void handler::column_bitmaps_signal()
{
DBUG_ENTER("column_bitmaps_signal");
- DBUG_PRINT("info", ("read_set: 0x%lx write_set: 0x%lx", table->read_set,
- table->write_set));
+ DBUG_PRINT("info", ("read_set: 0x%lx write_set: 0x%lx", (long) table->read_set,
+ (long) table->write_set));
DBUG_VOID_RETURN;
}
@@ -2119,8 +2119,8 @@ void handler::print_error(int error, myf errflag)
break;
}
case HA_ERR_NULL_IN_SPATIAL:
- textno= ER_UNKNOWN_ERROR;
- break;
+ my_error(ER_CANT_CREATE_GEOMETRY_OBJECT, MYF(0));
+ DBUG_VOID_RETURN;
case HA_ERR_FOUND_DUPP_UNIQUE:
textno=ER_DUP_UNIQUE;
break;
@@ -3507,8 +3507,10 @@ namespace
int write_locked_table_maps(THD *thd)
{
DBUG_ENTER("write_locked_table_maps");
- DBUG_PRINT("enter", ("thd=%p, thd->lock=%p, thd->locked_tables=%p, thd->extra_lock",
- thd, thd->lock, thd->locked_tables, thd->extra_lock));
+ DBUG_PRINT("enter", ("thd: 0x%lx thd->lock: 0x%lx thd->locked_tables: 0x%lx "
+ "thd->extra_lock: 0x%lx",
+ (long) thd, (long) thd->lock,
+ (long) thd->locked_tables, (long) thd->extra_lock));
if (thd->get_binlog_table_maps() == 0)
{
@@ -3528,7 +3530,7 @@ namespace
++table_ptr)
{
TABLE *const table= *table_ptr;
- DBUG_PRINT("info", ("Checking table %s", table->s->table_name));
+ DBUG_PRINT("info", ("Checking table %s", table->s->table_name.str));
if (table->current_lock == F_WRLCK &&
check_table_binlog_row_based(thd, table))
{
diff --git a/sql/item.cc b/sql/item.cc
index 0662ddefbb4..eff7defda0c 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -269,6 +269,34 @@ my_decimal *Item::val_decimal_from_string(my_decimal *decimal_value)
}
+my_decimal *Item::val_decimal_from_date(my_decimal *decimal_value)
+{
+ DBUG_ASSERT(fixed == 1);
+ TIME ltime;
+ longlong date;
+ if (get_date(&ltime, TIME_FUZZY_DATE))
+ {
+ my_decimal_set_zero(decimal_value);
+ return 0;
+ }
+ return date2my_decimal(&ltime, decimal_value);
+}
+
+
+my_decimal *Item::val_decimal_from_time(my_decimal *decimal_value)
+{
+ DBUG_ASSERT(fixed == 1);
+ TIME ltime;
+ longlong date;
+ if (get_time(&ltime))
+ {
+ my_decimal_set_zero(decimal_value);
+ return 0;
+ }
+ return date2my_decimal(&ltime, decimal_value);
+}
+
+
double Item::val_real_from_decimal()
{
/* Note that fix_fields may not be called for Item_avg_field items */
@@ -292,6 +320,25 @@ longlong Item::val_int_from_decimal()
return result;
}
+int Item::save_time_in_field(Field *field)
+{
+ TIME ltime;
+ if (get_time(&ltime))
+ return set_field_to_null(field);
+ field->set_notnull();
+ return field->store_time(&ltime, MYSQL_TIMESTAMP_TIME);
+}
+
+
+int Item::save_date_in_field(Field *field)
+{
+ TIME ltime;
+ if (get_date(&ltime, TIME_FUZZY_DATE))
+ return set_field_to_null(field);
+ field->set_notnull();
+ return field->store_time(&ltime, MYSQL_TIMESTAMP_DATETIME);
+}
+
Item::Item():
rsize(0), name(0), orig_name(0), name_length(0), fixed(0),
@@ -1176,6 +1223,28 @@ void Item_name_const::print(String *str)
/*
+ need a special class to adjust printing : references to aggregate functions
+ must not be printed as refs because the aggregate functions that are added to
+ the front of select list are not printed as well.
+*/
+class Item_aggregate_ref : public Item_ref
+{
+public:
+ Item_aggregate_ref(Name_resolution_context *context_arg, Item **item,
+ const char *table_name_arg, const char *field_name_arg)
+ :Item_ref(context_arg, item, table_name_arg, field_name_arg) {}
+
+ void print (String *str)
+ {
+ if (ref)
+ (*ref)->print(str);
+ else
+ Item_ident::print(str);
+ }
+};
+
+
+/*
Move SUM items out from item tree and replace with reference
SYNOPSIS
@@ -1228,8 +1297,8 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
Item *new_item, *real_itm= real_item();
ref_pointer_array[el]= real_itm;
- if (!(new_item= new Item_ref(&thd->lex->current_select->context,
- ref_pointer_array + el, 0, name)))
+ if (!(new_item= new Item_aggregate_ref(&thd->lex->current_select->context,
+ ref_pointer_array + el, 0, name)))
return; // fatal_error is set
fields.push_front(real_itm);
thd->change_item_tree(ref, new_item);
@@ -3672,11 +3741,37 @@ 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 != (Item **)not_found_item &&
- (*res)->type() == Item::FIELD_ITEM)
+ if (res != (Item **)not_found_item)
{
- set_field((*((Item_field**)res))->field);
- return 0;
+ if ((*res)->type() == Item::FIELD_ITEM)
+ {
+ /*
+ It's an Item_field referencing another Item_field in the select
+ list.
+ use the field from the Item_field in the select list and leave
+ the Item_field instance in place.
+ */
+ set_field((*((Item_field**)res))->field);
+ return 0;
+ }
+ else
+ {
+ /*
+ It's not an Item_field in the select list so we must make a new
+ Item_ref to point to the Item in the select list and replace the
+ Item_field created by the parser with the new Item_ref.
+ */
+ Item_ref *rf= new Item_ref(context, db_name,table_name,field_name);
+ if (!rf)
+ return 1;
+ thd->change_item_tree(reference, rf);
+ /*
+ Because Item_ref never substitutes itself with other items
+ in Item_ref::fix_fields(), we can safely use the original
+ pointer to it even after fix_fields()
+ */
+ return rf->fix_fields(thd, reference) || rf->check_cols(1);
+ }
}
}
if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
@@ -4193,6 +4288,10 @@ void Item_field::make_field(Send_field *tmp_field)
DBUG_ASSERT(tmp_field->table_name != 0);
if (name)
tmp_field->col_name=name; // Use user supplied name
+ if (table_name)
+ tmp_field->table_name= table_name;
+ if (db_name)
+ tmp_field->db_name= db_name;
}
diff --git a/sql/item.h b/sql/item.h
index 2c26e1c4a07..126e106330d 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -646,9 +646,14 @@ public:
my_decimal *val_decimal_from_real(my_decimal *decimal_value);
my_decimal *val_decimal_from_int(my_decimal *decimal_value);
my_decimal *val_decimal_from_string(my_decimal *decimal_value);
+ my_decimal *val_decimal_from_date(my_decimal *decimal_value);
+ my_decimal *val_decimal_from_time(my_decimal *decimal_value);
longlong val_int_from_decimal();
double val_real_from_decimal();
+ int save_time_in_field(Field *field);
+ int save_date_in_field(Field *field);
+
virtual Field *get_tmp_table_field() { return 0; }
/* This is also used to create fields in CREATE ... SELECT: */
virtual Field *tmp_table_field(TABLE *t_arg) { return 0; }
@@ -2049,6 +2054,16 @@ public:
class Item_in_subselect;
+
+/*
+ An object of this class:
+ - Converts val_XXX() calls to ref->val_XXX_result() calls, like Item_ref.
+ - Sets owner->was_null=TRUE if it has returned a NULL value from any
+ val_XXX() function. This allows to inject an Item_ref_null_helper
+ object into subquery and then check if the subquery has produced a row
+ with NULL value.
+*/
+
class Item_ref_null_helper: public Item_ref
{
protected:
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 691715c3bff..39c63e9a46a 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -833,9 +833,41 @@ longlong Item_in_optimizer::val_int()
{
DBUG_ASSERT(fixed == 1);
cache->store(args[0]);
+
if (cache->null_value)
{
- null_value= 1;
+ if (((Item_in_subselect*)args[1])->is_top_level_item())
+ {
+ /*
+ We're evaluating "NULL IN (SELECT ...)". The result can be NULL or
+ FALSE, and we can return one instead of another. Just return NULL.
+ */
+ null_value= 1;
+ }
+ else
+ {
+ if (!((Item_in_subselect*)args[1])->is_correlated &&
+ result_for_null_param != UNKNOWN)
+ {
+ /* Use cached value from previous execution */
+ null_value= result_for_null_param;
+ }
+ else
+ {
+ /*
+ We're evaluating "NULL IN (SELECT ...)". The result is:
+ FALSE if SELECT produces an empty set, or
+ NULL otherwise.
+ We disable the predicates we've pushed down into subselect, run the
+ subselect and see if it has produced any rows.
+ */
+ ((Item_in_subselect*)args[1])->enable_pushed_conds= FALSE;
+ longlong tmp= args[1]->val_bool_result();
+ result_for_null_param= null_value=
+ !((Item_in_subselect*)args[1])->engine->no_rows();
+ ((Item_in_subselect*)args[1])->enable_pushed_conds= TRUE;
+ }
+ }
return 0;
}
bool tmp= args[1]->val_bool_result();
@@ -2229,7 +2261,7 @@ cmp_item* cmp_item_row::make_same()
cmp_item_row::~cmp_item_row()
{
DBUG_ENTER("~cmp_item_row");
- DBUG_PRINT("enter",("this: 0x%lx", this));
+ DBUG_PRINT("enter",("this: 0x%lx", (long) this));
if (comparators)
{
for (uint i= 0; i < n; i++)
@@ -3061,7 +3093,7 @@ longlong Item_is_not_null_test::val_int()
if (!used_tables_cache)
{
owner->was_null|= (!cached_value);
- DBUG_PRINT("info", ("cached :%d", cached_value));
+ DBUG_PRINT("info", ("cached: %ld", (long) cached_value));
DBUG_RETURN(cached_value);
}
if (args[0]->is_null())
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index c2d93fdd5ef..51cf5667c95 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -100,25 +100,44 @@ public:
};
class Item_cache;
+#define UNKNOWN ((my_bool)-1)
+
+
+/*
+ Item_in_optimizer(left_expr, Item_in_subselect(...))
+
+ Item_in_optimizer is used to wrap an instance of Item_in_subselect. This
+ class does the following:
+ - Evaluate the left expression and store it in Item_cache_* object (to
+ avoid re-evaluating it many times during subquery execution)
+ - Shortcut the evaluation of "NULL IN (...)" to NULL in the cases where we
+ don't care if the result is NULL or FALSE.
+
+ NOTE
+ It is not quite clear why the above listed functionality should be
+ placed into a separate class called 'Item_in_optimizer'.
+*/
+
class Item_in_optimizer: public Item_bool_func
{
protected:
Item_cache *cache;
bool save_cache;
+ /*
+ Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
+ UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
+ FALSE - result is FALSE
+ TRUE - result is NULL
+ */
+ my_bool result_for_null_param;
public:
Item_in_optimizer(Item *a, Item_in_subselect *b):
- Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0), save_cache(0)
+ Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0),
+ save_cache(0), result_for_null_param(UNKNOWN)
{}
bool fix_fields(THD *, Item **);
bool fix_left(THD *thd, Item **ref);
bool is_null();
- /*
- Item_in_optimizer item is special boolean function. On value request
- (one of val, val_int or val_str methods) it evaluate left expression
- of IN by storing it value in cache item (one of Item_cache* items),
- then it test cache is it NULL. If left expression (cache) is NULL then
- Item_in_optimizer return NULL, else it evaluate Item_in_subselect.
- */
longlong val_int();
void cleanup();
const char *func_name() const { return "<in_optimizer>"; }
@@ -258,9 +277,11 @@ public:
class Item_maxmin_subselect;
/*
+ trigcond<param>(arg) ::= param? arg : TRUE
+
The class Item_func_trig_cond is used for guarded predicates
which are employed only for internal purposes.
- A guarded predicates is an object consisting of an a regular or
+ A guarded predicate is an object consisting of an a regular or
a guarded predicate P and a pointer to a boolean guard variable g.
A guarded predicate P/g is evaluated to true if the value of the
guard g is false, otherwise it is evaluated to the same value that
@@ -278,6 +299,10 @@ class Item_maxmin_subselect;
Objects of this class are built only for query execution after
the execution plan has been already selected. That's why this
class needs only val_int out of generic methods.
+
+ Current uses of Item_func_trig_cond objects:
+ - To wrap selection conditions when executing outer joins
+ - To wrap condition that is pushed down into subquery
*/
class Item_func_trig_cond: public Item_bool_func
@@ -1095,6 +1120,11 @@ public:
/* Functions used by HAVING for rewriting IN subquery */
class Item_in_subselect;
+
+/*
+ This is like IS NOT NULL but it also remembers if it ever has
+ encountered a NULL.
+*/
class Item_is_not_null_test :public Item_func_isnull
{
Item_in_subselect* owner;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index e8d3b539142..a0ecf9f30dd 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -961,7 +961,14 @@ longlong Item_func_unsigned::val_int()
longlong value;
int error;
- if (args[0]->cast_to_int_type() != STRING_RESULT)
+ if (args[0]->cast_to_int_type() == DECIMAL_RESULT)
+ {
+ my_decimal tmp, *dec= args[0]->val_decimal(&tmp);
+ if (!(null_value= args[0]->null_value))
+ my_decimal2int(E_DEC_FATAL_ERROR, dec, 1, &value);
+ return value;
+ }
+ else if (args[0]->cast_to_int_type() != STRING_RESULT)
{
value= args[0]->val_int();
null_value= args[0]->null_value;
@@ -2911,6 +2918,20 @@ void Item_udf_func::cleanup()
}
+void Item_udf_func::print(String *str)
+{
+ str->append(func_name());
+ str->append('(');
+ for (uint i=0 ; i < arg_count ; i++)
+ {
+ if (i != 0)
+ str->append(',');
+ args[i]->print_item_w_name(str);
+ }
+ str->append(')');
+}
+
+
double Item_func_udf_float::val_real()
{
DBUG_ASSERT(fixed == 1);
@@ -5068,7 +5089,7 @@ Item_func_sp::result_type() const
{
Field *field;
DBUG_ENTER("Item_func_sp::result_type");
- DBUG_PRINT("info", ("m_sp = %p", m_sp));
+ DBUG_PRINT("info", ("m_sp: 0x%lx", (long) m_sp));
if (result_field)
DBUG_RETURN(result_field->result_type());
diff --git a/sql/item_func.h b/sql/item_func.h
index e86f601fc2b..3b8aef1589c 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -980,6 +980,7 @@ public:
Item_result result_type () const { return udf.result_type(); }
table_map not_null_tables() const { return 0; }
bool is_expensive() { return 1; }
+ void print(String *str);
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 7237b4e37ae..2a022d4af71 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -978,8 +978,8 @@ String *Item_func_insert::val_str(String *str)
if (length > res->length() - start)
length= res->length() - start;
- if (res->length() - length + res2->length() >
- current_thd->variables.max_allowed_packet)
+ if ((ulonglong) (res->length() - length + res2->length()) >
+ (ulonglong) current_thd->variables.max_allowed_packet)
{
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
@@ -2426,7 +2426,7 @@ String *Item_func_lpad::val_str(String *str)
pad_char_length= pad->numchars();
byte_count= count * collation.collation->mbmaxlen;
- if (byte_count > current_thd->variables.max_allowed_packet)
+ if ((ulonglong) byte_count > current_thd->variables.max_allowed_packet)
{
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 4e6c67cba60..da491b91143 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -37,7 +37,7 @@ inline Item * and_items(Item* cond, Item *item)
Item_subselect::Item_subselect():
Item_result_field(), value_assigned(0), thd(0), substitution(0),
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
- const_item_cache(1), engine_changed(0), changed(0)
+ const_item_cache(1), engine_changed(0), changed(0), is_correlated(FALSE)
{
with_subselect= 1;
reset();
@@ -54,7 +54,7 @@ void Item_subselect::init(st_select_lex *select_lex,
{
DBUG_ENTER("Item_subselect::init");
- DBUG_PRINT("enter", ("select_lex: 0x%x", (ulong) select_lex));
+ DBUG_PRINT("enter", ("select_lex: 0x%lx", (long) select_lex));
unit= select_lex->master_unit();
if (unit->item)
@@ -235,16 +235,16 @@ bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
}
-bool Item_subselect::exec()
+bool Item_subselect::exec(bool full_scan)
{
int res;
- res= engine->exec();
+ res= engine->exec(full_scan);
if (engine_changed)
{
engine_changed= 0;
- return exec();
+ return exec(full_scan);
}
return (res);
}
@@ -434,6 +434,15 @@ enum Item_result Item_singlerow_subselect::result_type() const
return engine->type();
}
+/*
+ Don't rely on the result type to calculate field type.
+ Ask the engine instead.
+*/
+enum_field_types Item_singlerow_subselect::field_type() const
+{
+ return engine->field_type();
+}
+
void Item_singlerow_subselect::fix_length_and_dec()
{
if ((max_columns= engine->cols()) == 1)
@@ -484,13 +493,13 @@ bool Item_singlerow_subselect::null_inside()
void Item_singlerow_subselect::bring_value()
{
- exec();
+ exec(FALSE);
}
double Item_singlerow_subselect::val_real()
{
DBUG_ASSERT(fixed == 1);
- if (!exec() && !value->null_value)
+ if (!exec(FALSE) && !value->null_value)
{
null_value= 0;
return value->val_real();
@@ -505,7 +514,7 @@ double Item_singlerow_subselect::val_real()
longlong Item_singlerow_subselect::val_int()
{
DBUG_ASSERT(fixed == 1);
- if (!exec() && !value->null_value)
+ if (!exec(FALSE) && !value->null_value)
{
null_value= 0;
return value->val_int();
@@ -519,7 +528,7 @@ longlong Item_singlerow_subselect::val_int()
String *Item_singlerow_subselect::val_str(String *str)
{
- if (!exec() && !value->null_value)
+ if (!exec(FALSE) && !value->null_value)
{
null_value= 0;
return value->val_str(str);
@@ -534,7 +543,7 @@ String *Item_singlerow_subselect::val_str(String *str)
my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
{
- if (!exec() && !value->null_value)
+ if (!exec(FALSE) && !value->null_value)
{
null_value= 0;
return value->val_decimal(decimal_value);
@@ -549,7 +558,7 @@ my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
bool Item_singlerow_subselect::val_bool()
{
- if (!exec() && !value->null_value)
+ if (!exec(FALSE) && !value->null_value)
{
null_value= 0;
return value->val_bool();
@@ -600,7 +609,8 @@ bool Item_in_subselect::test_limit(SELECT_LEX_UNIT *unit)
Item_in_subselect::Item_in_subselect(Item * left_exp,
st_select_lex *select_lex):
- Item_exists_subselect(), optimizer(0), transformed(0), upper_item(0)
+ Item_exists_subselect(), optimizer(0), transformed(0),
+ enable_pushed_conds(TRUE), upper_item(0)
{
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
left_expr= left_exp;
@@ -645,7 +655,7 @@ void Item_exists_subselect::fix_length_and_dec()
double Item_exists_subselect::val_real()
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (exec(FALSE))
{
reset();
return 0;
@@ -656,7 +666,7 @@ double Item_exists_subselect::val_real()
longlong Item_exists_subselect::val_int()
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (exec(FALSE))
{
reset();
return 0;
@@ -667,7 +677,7 @@ longlong Item_exists_subselect::val_int()
String *Item_exists_subselect::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (exec(FALSE))
{
reset();
return 0;
@@ -680,7 +690,7 @@ String *Item_exists_subselect::val_str(String *str)
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (exec(FALSE))
{
reset();
return 0;
@@ -693,7 +703,7 @@ my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
bool Item_exists_subselect::val_bool()
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (exec(FALSE))
{
reset();
return 0;
@@ -710,7 +720,8 @@ double Item_in_subselect::val_real()
*/
DBUG_ASSERT(0);
DBUG_ASSERT(fixed == 1);
- if (exec())
+ null_value= 0;
+ if (exec(!enable_pushed_conds))
{
reset();
null_value= 1;
@@ -730,7 +741,8 @@ longlong Item_in_subselect::val_int()
*/
DBUG_ASSERT(0);
DBUG_ASSERT(fixed == 1);
- if (exec())
+ null_value= 0;
+ if (exec(!enable_pushed_conds))
{
reset();
null_value= 1;
@@ -750,7 +762,8 @@ String *Item_in_subselect::val_str(String *str)
*/
DBUG_ASSERT(0);
DBUG_ASSERT(fixed == 1);
- if (exec())
+ null_value= 0;
+ if (exec(!enable_pushed_conds))
{
reset();
null_value= 1;
@@ -769,7 +782,8 @@ String *Item_in_subselect::val_str(String *str)
bool Item_in_subselect::val_bool()
{
DBUG_ASSERT(fixed == 1);
- if (exec())
+ null_value= 0;
+ if (exec(!enable_pushed_conds))
{
reset();
null_value= 1;
@@ -787,8 +801,9 @@ my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
method should not be used
*/
DBUG_ASSERT(0);
+ null_value= 0;
DBUG_ASSERT(fixed == 1);
- if (exec())
+ if (exec(!enable_pushed_conds))
{
reset();
null_value= 1;
@@ -801,7 +816,55 @@ my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
}
-/* Rewrite a single-column IN/ALL/ANY subselect. */
+/*
+ Rewrite a single-column IN/ALL/ANY subselect
+
+ SYNOPSIS
+ Item_in_subselect::single_value_transformer()
+ join Join object of the subquery (i.e. 'child' join).
+ func Subquery comparison creator
+
+ DESCRIPTION
+ Rewrite a single-column subquery using rule-based approach. The subquery
+
+ oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
+
+ First, try to convert the subquery to scalar-result subquery in one of
+ the forms:
+
+ - oe $cmp$ (SELECT MAX(...) ) // handled by Item_singlerow_subselect
+ - oe $cmp$ <max>(SELECT ...) // handled by Item_maxmin_subselect
+
+ If that fails, the subquery will be handled with class Item_in_optimizer,
+ Inject the predicates into subquery, i.e. convert it to:
+
+ - If the subquery has aggregates, GROUP BY, or HAVING, convert to
+
+ SELECT ie FROM ... HAVING subq_having AND
+ trigcond(oe $cmp$ ref_or_null_helper<ie>)
+
+ the addition is wrapped into trigger only when we want to distinguish
+ between NULL and FALSE results.
+
+ - Otherwise (no aggregates/GROUP BY/HAVING) convert it to one of the
+ following:
+
+ = If we don't need to distinguish between NULL and FALSE subquery:
+
+ SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
+
+ = If we need to distinguish between those:
+
+ SELECT 1 FROM ...
+ WHERE subq_where AND trigcond((oe $cmp$ ie) OR (ie IS NULL))
+ HAVING trigcond(<is_not_null_test>(ie))
+
+ RETURN
+ RES_OK - OK, either subquery was transformed, or appopriate
+ predicates where injected into it.
+ RES_REDUCE - The subquery was reduced to non-subquery
+ RES_ERROR - Error
+*/
Item_subselect::trans_res
Item_in_subselect::single_value_transformer(JOIN *join,
@@ -934,8 +997,12 @@ Item_in_subselect::single_value_transformer(JOIN *join,
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
/*
Add the left part of a subselect to a WHERE or HAVING clause of
- the right part, e.g. SELECT 1 IN (SELECT a FROM t1) =>
- SELECT Item_in_optimizer(1, SELECT a FROM t1 WHERE a=1)
+ the right part, e.g.
+
+ SELECT 1 IN (SELECT a FROM t1) =>
+
+ SELECT Item_in_optimizer(1, SELECT a FROM t1 WHERE a=1)
+
HAVING is used only if the right part contains a SUM function, a GROUP
BY or a HAVING clause.
*/
@@ -950,10 +1017,15 @@ Item_in_subselect::single_value_transformer(JOIN *join,
ref_pointer_array,
(char *)"<ref>",
this->full_name()));
-#ifdef CORRECT_BUT_TOO_SLOW_TO_BE_USABLE
- if (!abort_on_null && left_expr->maybe_null)
- item= new Item_cond_or(new Item_func_isnull(left_expr), item);
-#endif
+ if (!abort_on_null && ((Item*)select_lex->item_list.head())->maybe_null)
+ {
+ /*
+ We can encounter "NULL IN (SELECT ...)". Wrap the added condition
+ within a trigger.
+ */
+ item= new Item_func_trig_cond(item, &enable_pushed_conds);
+ }
+
/*
AND and comparison functions can't be changed during fix_fields()
we can assign select_lex->having here, and pass 0 as last
@@ -982,19 +1054,19 @@ Item_in_subselect::single_value_transformer(JOIN *join,
select_lex->item_list.push_back(new Item_int("Not_used",
(longlong) 1, 21));
select_lex->ref_pointer_array[0]= select_lex->item_list.head();
+
item= func->create(expr, item);
if (!abort_on_null && orig_item->maybe_null)
{
- having= new Item_is_not_null_test(this, having);
+ having=
+ new Item_func_trig_cond(new Item_is_not_null_test(this, having),
+ &enable_pushed_conds);
/*
Item_is_not_null_test can't be changed during fix_fields()
we can assign select_lex->having here, and pass 0 as last
argument (reference) to fix_fields()
*/
- select_lex->having=
- join->having= (join->having ?
- new Item_cond_and(having, join->having) :
- having);
+ select_lex->having= join->having= having;
select_lex->having_fix_field= 1;
/*
we do not check join->having->fixed, because Item_and (from
@@ -1005,12 +1077,15 @@ Item_in_subselect::single_value_transformer(JOIN *join,
select_lex->having_fix_field= 0;
if (tmp)
DBUG_RETURN(RES_ERROR);
+ /*
+ NOTE: It is important that we add this "IS NULL" here, even when
+ orig_item can't be NULL. This is needed so that this predicate is
+ only used by ref[_or_null] analyzer (and, e.g. is not used by const
+ propagation).
+ */
item= new Item_cond_or(item,
new Item_func_isnull(orig_item));
-#ifdef CORRECT_BUT_TOO_SLOW_TO_BE_USABLE
- if (left_expr->maybe_null)
- item= new Item_cond_or(new Item_func_isnull(left_expr), item);
-#endif
+ item= new Item_func_trig_cond(item, &enable_pushed_conds);
}
item->name= (char *)in_additional_cond;
/*
@@ -1037,13 +1112,14 @@ Item_in_subselect::single_value_transformer(JOIN *join,
we can assign select_lex->having here, and pass 0 as last
argument (reference) to fix_fields()
*/
- select_lex->having=
- join->having=
- func->create(expr,
+ Item *new_having=
+ func->create(expr,
new Item_ref_null_helper(&select_lex->context, this,
select_lex->ref_pointer_array,
(char *)"<no matter>",
(char *)"<result>"));
+ new_having= new Item_func_trig_cond(new_having, &enable_pushed_conds);
+ select_lex->having= join->having= new_having;
select_lex->having_fix_field= 1;
/*
@@ -1248,6 +1324,8 @@ Item_in_subselect::row_value_transformer(JOIN *join)
where_item= and_items(where_item, item);
}
+ if (where_item)
+ where_item= new Item_func_trig_cond(where_item, &enable_pushed_conds);
/*
AND can't be changed during fix_fields()
we can assign select_lex->where here, and pass 0 as last
@@ -1261,6 +1339,8 @@ Item_in_subselect::row_value_transformer(JOIN *join)
if (having_item)
{
bool res;
+ having_item= new Item_func_trig_cond(having_item, &enable_pushed_conds);
+
select_lex->having= join->having= and_items(join->having, having_item);
select_lex->having->top_level_item();
/*
@@ -1477,6 +1557,27 @@ bool subselect_union_engine::is_executed() const
}
+/*
+ Check if last execution of the subquery engine produced any rows
+
+ SYNOPSIS
+ subselect_union_engine::no_rows()
+
+ DESCRIPTION
+ Check if last execution of the subquery engine produced any rows. The
+ return value is undefined if last execution ended in an error.
+
+ RETURN
+ TRUE - Last subselect execution has produced no rows
+ FALSE - Otherwise
+*/
+
+bool subselect_union_engine::no_rows()
+{
+ /* Check if we got any rows when reading UNION result from temp. table: */
+ return test(!unit->fake_select_lex->join->send_records);
+}
+
void subselect_uniquesubquery_engine::cleanup()
{
DBUG_ENTER("subselect_uniquesubquery_engine::cleanup");
@@ -1542,32 +1643,58 @@ int subselect_uniquesubquery_engine::prepare()
return 1;
}
-static Item_result set_row(List<Item> &item_list, Item *item,
- Item_cache **row, bool *maybe_null)
+
+/*
+ Check if last execution of the subquery engine produced any rows
+
+ SYNOPSIS
+ subselect_single_select_engine::no_rows()
+
+ DESCRIPTION
+ Check if last execution of the subquery engine produced any rows. The
+ return value is undefined if last execution ended in an error.
+
+ RETURN
+ TRUE - Last subselect execution has produced no rows
+ FALSE - Otherwise
+*/
+
+bool subselect_single_select_engine::no_rows()
+{
+ return !item->assigned();
+}
+
+
+/*
+ makes storage for the output values for the subquery and calcuates
+ their data and column types and their nullability.
+*/
+void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
{
- Item_result res_type= STRING_RESULT;
Item *sel_item;
List_iterator_fast<Item> li(item_list);
+ res_type= STRING_RESULT;
+ res_field_type= FIELD_TYPE_VAR_STRING;
for (uint i= 0; (sel_item= li++); i++)
{
item->max_length= sel_item->max_length;
res_type= sel_item->result_type();
+ res_field_type= sel_item->field_type();
item->decimals= sel_item->decimals;
item->unsigned_flag= sel_item->unsigned_flag;
- *maybe_null= sel_item->maybe_null;
+ maybe_null= sel_item->maybe_null;
if (!(row[i]= Item_cache::get_cache(res_type)))
- return STRING_RESULT; // we should return something
+ return;
row[i]->setup(sel_item);
}
if (item_list.elements > 1)
res_type= ROW_RESULT;
- return res_type;
}
void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
{
DBUG_ASSERT(row || select_lex->item_list.elements==1);
- res_type= set_row(select_lex->item_list, item, row, &maybe_null);
+ set_row(select_lex->item_list, row);
item->collation.set(row[0]->collation);
if (cols() != 1)
maybe_null= 0;
@@ -1579,13 +1706,14 @@ void subselect_union_engine::fix_length_and_dec(Item_cache **row)
if (unit->first_select()->item_list.elements == 1)
{
- res_type= set_row(unit->types, item, row, &maybe_null);
+ set_row(unit->types, row);
item->collation.set(row[0]->collation);
}
else
{
- bool fake= 0;
- res_type= set_row(unit->types, item, row, &fake);
+ bool maybe_null_saved= maybe_null;
+ set_row(unit->types, row);
+ maybe_null= maybe_null_saved;
}
}
@@ -1595,7 +1723,11 @@ void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row)
DBUG_ASSERT(0);
}
-int subselect_single_select_engine::exec()
+int init_read_record_seq(JOIN_TAB *tab);
+int join_read_always_key_or_null(JOIN_TAB *tab);
+int join_read_next_same_or_null(READ_RECORD *info);
+
+int subselect_single_select_engine::exec(bool full_scan)
{
DBUG_ENTER("subselect_single_select_engine::exec");
char const *save_where= thd->where;
@@ -1633,7 +1765,43 @@ int subselect_single_select_engine::exec()
if (!executed)
{
item->reset_value_registration();
+ if (full_scan)
+ {
+ /*
+ We should not apply optimizations based on the condition that was
+ pushed down into the subquery. Those optimizations are ref[_or_null]
+ acceses. Change them to be full table scans.
+ */
+ for (uint i=join->const_tables ; i < join->tables ; i++)
+ {
+ JOIN_TAB *tab=join->join_tab+i;
+ if (tab->keyuse && tab->keyuse->outer_ref)
+ {
+ tab->read_first_record= init_read_record_seq;
+ tab->read_record.record= tab->table->record[0];
+ tab->read_record.thd= join->thd;
+ tab->read_record.ref_length= tab->table->file->ref_length;
+ }
+ }
+ }
+
join->exec();
+
+ if (full_scan)
+ {
+ /* Enable the optimizations back */
+ for (uint i=join->const_tables ; i < join->tables ; i++)
+ {
+ JOIN_TAB *tab=join->join_tab+i;
+ if (tab->keyuse && tab->keyuse->outer_ref)
+ {
+ tab->read_record.record= 0;
+ tab->read_record.ref_length= 0;
+ tab->read_first_record= join_read_always_key_or_null;
+ tab->read_record.read_record= join_read_next_same_or_null;
+ }
+ }
+ }
executed= 1;
thd->where= save_where;
thd->lex->current_select= save_select;
@@ -1644,29 +1812,159 @@ int subselect_single_select_engine::exec()
DBUG_RETURN(0);
}
-int subselect_union_engine::exec()
+int subselect_union_engine::exec(bool full_scan)
{
char const *save_where= thd->where;
+ /*
+ Ignore the full_scan parameter: the pushed down predicates are only used
+ for filtering, and the caller has disabled them if necessary.
+ */
int res= unit->exec();
thd->where= save_where;
return res;
}
-int subselect_uniquesubquery_engine::exec()
+/*
+ Search for at least on row satisfying select condition
+
+ SYNOPSIS
+ subselect_uniquesubquery_engine::scan_table()
+
+ DESCRIPTION
+ Scan the table using sequential access until we find at least one row
+ satisfying select condition.
+
+ The result of this function (info about whether a row was found) is
+ stored in this->empty_result_set.
+
+ RETURN
+ FALSE - OK
+ TRUE - Error
+*/
+
+int subselect_uniquesubquery_engine::scan_table()
{
- DBUG_ENTER("subselect_uniquesubquery_engine::exec");
int error;
TABLE *table= tab->table;
- for (store_key **copy=tab->ref.key_copy ; *copy ; copy++)
+ DBUG_ENTER("subselect_uniquesubquery_engine::scan_table");
+ empty_result_set= TRUE;
+
+ if (table->file->inited)
+ table->file->ha_index_end();
+
+ table->file->ha_rnd_init(1);
+ table->file->extra_opt(HA_EXTRA_CACHE,
+ current_thd->variables.read_buff_size);
+ table->null_row= 0;
+ for (;;)
+ {
+ error=table->file->rnd_next(table->record[0]);
+ if (error && error != HA_ERR_END_OF_FILE)
+ {
+ error= report_error(table, error);
+ break;
+ }
+ /* No more rows */
+ if (table->status)
+ break;
+
+ if (!cond || cond->val_int())
+ {
+ empty_result_set= FALSE;
+ break;
+ }
+ }
+
+ table->file->ha_rnd_end();
+ DBUG_RETURN(error != 0);
+}
+
+
+/*
+ Copy ref key and check for null parts in it
+
+ SYNOPSIS
+ subselect_uniquesubquery_engine::copy_ref_key()
+
+ DESCRIPTION
+ Copy ref key and check for null parts in it.
+
+ RETURN
+ FALSE - ok, index lookup key without keys copied.
+ TRUE - an error occured while copying the key
+*/
+
+bool subselect_uniquesubquery_engine::copy_ref_key()
+{
+ DBUG_ENTER("subselect_uniquesubquery_engine::copy_ref_key");
+
+ for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
{
- if ((tab->ref.key_err= (*copy)->copy()) & 1)
+ tab->ref.key_err= (*copy)->copy();
+
+ /*
+ When there is a NULL part in the key we don't need to make index
+ lookup for such key thus we don't need to copy whole key.
+ If we later should do a sequential scan return OK. Fail otherwise.
+
+ See also the comment for the subselect_uniquesubquery_engine::exec()
+ function.
+ */
+ null_keypart= (*copy)->null_key;
+ bool top_level= ((Item_in_subselect *) item)->is_top_level_item();
+ if (null_keypart && !top_level)
+ break;
+ if ((tab->ref.key_err) & 1 || (null_keypart && top_level))
{
- table->status= STATUS_NOT_FOUND;
+ tab->table->status= STATUS_NOT_FOUND;
DBUG_RETURN(1);
}
}
+ DBUG_RETURN(0);
+}
+
+
+/*
+ Execute subselect
+
+ SYNOPSIS
+ subselect_uniquesubquery_engine::exec()
+ DESCRIPTION
+ Find rows corresponding to the ref key using index access.
+ If some part of the lookup key is NULL, then we're evaluating
+ NULL IN (SELECT ... )
+ This is a special case, we don't need to search for NULL in the table,
+ instead, the result value is
+ - NULL if select produces empty row set
+ - FALSE otherwise.
+
+ In some cases (IN subselect is a top level item, i.e. abort_on_null==TRUE)
+ the caller doesn't distinguish between NULL and FALSE result and we just
+ return FALSE.
+ Otherwise we make a full table scan to see if there is at least one matching row.
+
+ NOTE
+
+ RETURN
+ FALSE - ok
+ TRUE - an error occured while scanning
+*/
+
+int subselect_uniquesubquery_engine::exec(bool full_scan)
+{
+ DBUG_ENTER("subselect_uniquesubquery_engine::exec");
+ int error;
+ TABLE *table= tab->table;
+
+ /* TODO: change to use of 'full_scan' here? */
+ if (copy_ref_key())
+ DBUG_RETURN(1);
+
+ if (null_keypart)
+ DBUG_RETURN(scan_table());
+
if (!table->file->inited)
table->file->ha_index_init(tab->ref.key, 0);
error= table->file->index_read(table->record[0],
@@ -1695,14 +1993,68 @@ subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine()
}
-int subselect_indexsubquery_engine::exec()
+/*
+ Index-lookup subselect 'engine' - run the subquery
+
+ SYNOPSIS
+ subselect_uniquesubquery_engine:exec()
+ full_scan
+
+ DESCRIPTION
+ The engine is used to resolve subqueries in form
+
+ oe IN (SELECT key FROM tbl WHERE subq_where)
+
+ The value of the predicate is calculated as follows:
+ 1. If oe IS NULL, this is a special case, do a full table scan on
+ table tbl and search for row that satisfies subq_where. If such
+ row is found, return NULL, otherwise return FALSE.
+ 2. Make an index lookup via key=oe, search for a row that satisfies
+ subq_where. If found, return TRUE.
+ 3. If check_null==TRUE, make another lookup via key=NULL, search for a
+ row that satisfies subq_where. If found, return NULL, otherwise
+ return FALSE.
+
+ TODO
+ The step #1 can be optimized further when the index has several key
+ parts. Consider a subquery:
+
+ (oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where)
+
+ and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}.
+ Current code will do a full table scan and obtain correct result. There
+ is a better option: instead of evaluating
+
+ SELECT keypart1, keypart2 FROM tbl WHERE subq_where (1)
+
+ and checking if it has produced any matching rows, evaluate
+
+ SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1 (2)
+
+ If this query produces a row, the result is NULL (as we're evaluating
+ "(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
+ i.e. NULL). If the query produces no rows, the result is FALSE.
+
+ We currently evaluate (1) by doing a full table scan. (2) can be
+ evaluated by doing a "ref" scan on "keypart1=const1", which can be much
+ cheaper. We can use index statistics to quickly check whether "ref" scan
+ will be cheaper than full table scan.
+
+ RETURN
+ 0
+ 1
+*/
+
+int subselect_indexsubquery_engine::exec(bool full_scan)
{
- DBUG_ENTER("subselect_indexsubselect_engine::exec");
+ DBUG_ENTER("subselect_indexsubquery_engine::exec");
int error;
bool null_finding= 0;
TABLE *table= tab->table;
((Item_in_subselect *) item)->value= 0;
+ empty_result_set= TRUE;
+ null_keypart= 0;
if (check_null)
{
@@ -1711,14 +2063,12 @@ int subselect_indexsubquery_engine::exec()
((Item_in_subselect *) item)->was_null= 0;
}
- for (store_key **copy=tab->ref.key_copy ; *copy ; copy++)
- {
- if ((tab->ref.key_err= (*copy)->copy()) & 1)
- {
- table->status= STATUS_NOT_FOUND;
- DBUG_RETURN(1);
- }
- }
+ /* Copy the ref key and check for nulls... */
+ if (copy_ref_key())
+ DBUG_RETURN(1);
+
+ if (null_keypart)
+ DBUG_RETURN(scan_table());
if (!table->file->inited)
table->file->ha_index_init(tab->ref.key, 1);
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index a72c6e85739..77199365710 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -60,6 +60,9 @@ public:
/* subquery is transformed */
bool changed;
+ /* TRUE <=> The underlying SELECT is correlated w.r.t some ancestor select */
+ bool is_correlated;
+
enum trans_res {RES_OK, RES_REDUCE, RES_ERROR};
enum subs_type {UNKNOWN_SUBS, SINGLEROW_SUBS,
EXISTS_SUBS, IN_SUBS, ALL_SUBS, ANY_SUBS};
@@ -92,7 +95,7 @@ public:
return null_value;
}
bool fix_fields(THD *thd, Item **ref);
- virtual bool exec();
+ virtual bool exec(bool full_scan);
virtual void fix_length_and_dec();
table_map used_tables() const;
table_map not_null_tables() const { return 0; }
@@ -114,6 +117,7 @@ public:
single select and union subqueries only.
*/
bool is_evaluated() const;
+ bool is_uncacheable() const;
/*
Used by max/min subquery to initialize value presence registration
@@ -156,6 +160,7 @@ public:
my_decimal *val_decimal(my_decimal *);
bool val_bool();
enum Item_result result_type() const;
+ enum_field_types field_type() const;
void fix_length_and_dec();
uint cols();
@@ -216,7 +221,20 @@ public:
friend class subselect_indexsubquery_engine;
};
-/* IN subselect */
+
+/*
+ IN subselect: this represents "left_exr IN (SELECT ...)"
+
+ This class has:
+ - (as a descendant of Item_subselect) a "subquery execution engine" which
+ allows it to evaluate subqueries. (and this class participates in
+ execution by having was_null variable where part of execution result
+ is stored.
+ - Transformation methods (todo: more on this).
+
+ This class is not used directly, it is "wrapped" into Item_in_optimizer
+ which provides some small bits of subquery evaluation.
+*/
class Item_in_subselect :public Item_exists_subselect
{
@@ -232,12 +250,14 @@ protected:
bool abort_on_null;
bool transformed;
public:
+ /* Used to trigger on/off conditions that were pushed down to subselect */
+ bool enable_pushed_conds;
Item_func_not_all *upper_item; // point on NOT/NOP before ALL/SOME subquery
Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
Item_in_subselect()
:Item_exists_subselect(), optimizer(0), abort_on_null(0), transformed(0),
- upper_item(0)
+ enable_pushed_conds(TRUE), upper_item(0)
{}
subs_type substype() { return IN_SUBS; }
@@ -257,6 +277,7 @@ public:
my_decimal *val_decimal(my_decimal *);
bool val_bool();
void top_level_item() { abort_on_null=1; }
+ inline bool is_top_level_item() { return abort_on_null; }
bool test_limit(st_select_lex_unit *unit);
void print(String *str);
bool fix_fields(THD *thd, Item **ref);
@@ -292,6 +313,7 @@ protected:
THD *thd; /* pointer to current THD */
Item_subselect *item; /* item, that use this engine */
enum Item_result res_type; /* type of results */
+ enum_field_types res_field_type; /* column type of the results */
bool maybe_null; /* may be null (first item in select) */
public:
@@ -301,6 +323,7 @@ public:
result= res;
item= si;
res_type= STRING_RESULT;
+ res_field_type= FIELD_TYPE_VAR_STRING;
maybe_null= 0;
}
virtual ~subselect_engine() {}; // to satisfy compiler
@@ -314,10 +337,32 @@ public:
THD * get_thd() { return thd; }
virtual int prepare()= 0;
virtual void fix_length_and_dec(Item_cache** row)= 0;
- virtual int exec()= 0;
+ /*
+ Execute the engine
+
+ SYNOPSIS
+ exec()
+ full_scan TRUE - Pushed-down predicates are disabled, the engine
+ must disable made based on those predicates.
+ FALSE - Pushed-down predicates are in effect.
+ DESCRIPTION
+ Execute the engine. The result of execution is subquery value that is
+ either captured by previously set up select_result-based 'sink' or
+ stored somewhere by the exec() method itself.
+
+ A required side effect: if full_scan==TRUE, subselect_engine->no_rows()
+ should return correct result.
+
+ RETURN
+ 0 - OK
+ 1 - Either an execution error, or the engine was be "changed", and
+ caller should call exec() again for the new engine.
+ */
+ virtual int exec(bool full_scan)= 0;
virtual uint cols()= 0; /* return number of columns in select */
virtual uint8 uncacheable()= 0; /* query is uncacheable */
enum Item_result type() { return res_type; }
+ enum_field_types field_type() { return res_field_type; }
virtual void exclude()= 0;
bool may_be_null() { return maybe_null; };
virtual table_map upper_select_const_tables()= 0;
@@ -326,6 +371,11 @@ public:
virtual bool change_result(Item_subselect *si, select_subselect *result)= 0;
virtual bool no_tables()= 0;
virtual bool is_executed() const { return FALSE; }
+ /* Check if subquery produced any rows during last query execution */
+ virtual bool no_rows() = 0;
+
+protected:
+ void set_row(List<Item> &item_list, Item_cache **row);
};
@@ -343,7 +393,7 @@ public:
void cleanup();
int prepare();
void fix_length_and_dec(Item_cache** row);
- int exec();
+ int exec(bool full_scan);
uint cols();
uint8 uncacheable();
void exclude();
@@ -352,6 +402,7 @@ public:
bool change_result(Item_subselect *si, select_subselect *result);
bool no_tables();
bool is_executed() const { return executed; }
+ bool no_rows();
};
@@ -365,7 +416,7 @@ public:
void cleanup();
int prepare();
void fix_length_and_dec(Item_cache** row);
- int exec();
+ int exec(bool full_scan);
uint cols();
uint8 uncacheable();
void exclude();
@@ -374,6 +425,7 @@ public:
bool change_result(Item_subselect *si, select_subselect *result);
bool no_tables();
bool is_executed() const;
+ bool no_rows();
};
@@ -383,6 +435,12 @@ class subselect_uniquesubquery_engine: public subselect_engine
protected:
st_join_table *tab;
Item *cond;
+ /*
+ TRUE<=> last execution produced empty set. Valid only when left
+ expression is NULL.
+ */
+ bool empty_result_set;
+ bool null_keypart; /* TRUE <=> constructed search tuple has a NULL */
public:
// constructor can assign THD because it will be called after JOIN::prepare
@@ -396,7 +454,7 @@ public:
void cleanup();
int prepare();
void fix_length_and_dec(Item_cache** row);
- int exec();
+ int exec(bool full_scan);
uint cols() { return 1; }
uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; }
void exclude();
@@ -404,11 +462,15 @@ public:
void print (String *str);
bool change_result(Item_subselect *si, select_subselect *result);
bool no_tables();
+ int scan_table();
+ bool copy_ref_key();
+ bool no_rows() { return empty_result_set; }
};
class subselect_indexsubquery_engine: public subselect_uniquesubquery_engine
{
+ /* FALSE for 'ref', TRUE for 'ref-or-null'. */
bool check_null;
public:
@@ -419,7 +481,7 @@ public:
:subselect_uniquesubquery_engine(thd, tab_arg, subs, where),
check_null(chk_null)
{}
- int exec();
+ int exec(bool full_scan);
void print (String *str);
};
@@ -429,3 +491,9 @@ inline bool Item_subselect::is_evaluated() const
return engine->is_executed();
}
+inline bool Item_subselect::is_uncacheable() const
+{
+ return engine->uncacheable();
+}
+
+
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 1cb943e45c2..ea6a950f07c 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -903,6 +903,7 @@ bool Item_sum_distinct::setup(THD *thd)
tree= new Unique(simple_raw_key_cmp, &tree_key_length, tree_key_length,
thd->variables.max_heap_table_size);
+ is_evaluated= FALSE;
DBUG_RETURN(tree == 0);
}
@@ -910,6 +911,7 @@ bool Item_sum_distinct::setup(THD *thd)
bool Item_sum_distinct::add()
{
args[0]->save_in_field(table->field[0], FALSE);
+ is_evaluated= FALSE;
if (!table->field[0]->is_null())
{
DBUG_ASSERT(tree);
@@ -939,6 +941,7 @@ void Item_sum_distinct::clear()
DBUG_ASSERT(tree != 0); /* we always have a tree */
null_value= 1;
tree->reset();
+ is_evaluated= FALSE;
DBUG_VOID_RETURN;
}
@@ -948,6 +951,7 @@ void Item_sum_distinct::cleanup()
delete tree;
tree= 0;
table= 0;
+ is_evaluated= FALSE;
}
Item_sum_distinct::~Item_sum_distinct()
@@ -959,16 +963,20 @@ Item_sum_distinct::~Item_sum_distinct()
void Item_sum_distinct::calculate_val_and_count()
{
- count= 0;
- val.traits->set_zero(&val);
- /*
- We don't have a tree only if 'setup()' hasn't been called;
- this is the case of sql_select.cc:return_zero_rows.
- */
- if (tree)
+ if (!is_evaluated)
{
- table->field[0]->set_notnull();
- tree->walk(item_sum_distinct_walk, (void*) this);
+ count= 0;
+ val.traits->set_zero(&val);
+ /*
+ We don't have a tree only if 'setup()' hasn't been called;
+ this is the case of sql_select.cc:return_zero_rows.
+ */
+ if (tree)
+ {
+ table->field[0]->set_notnull();
+ tree->walk(item_sum_distinct_walk, (void*) this);
+ }
+ is_evaluated= TRUE;
}
}
@@ -1024,9 +1032,13 @@ Item_sum_avg_distinct::fix_length_and_dec()
void
Item_sum_avg_distinct::calculate_val_and_count()
{
- Item_sum_distinct::calculate_val_and_count();
- if (count)
- val.traits->div(&val, count);
+ if (!is_evaluated)
+ {
+ Item_sum_distinct::calculate_val_and_count();
+ if (count)
+ val.traits->div(&val, count);
+ is_evaluated= TRUE;
+ }
}
@@ -2497,6 +2509,7 @@ void Item_sum_count_distinct::cleanup()
*/
delete tree;
tree= 0;
+ is_evaluated= FALSE;
if (table)
{
free_tmp_table(table->in_use, table);
@@ -2518,6 +2531,7 @@ void Item_sum_count_distinct::make_unique()
original= 0;
force_copy_fields= 1;
tree= 0;
+ is_evaluated= FALSE;
tmp_table_param= 0;
always_null= FALSE;
}
@@ -2637,6 +2651,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
but this has to be handled - otherwise someone can crash
the server with a DoS attack
*/
+ is_evaluated= FALSE;
if (! tree)
return TRUE;
}
@@ -2653,8 +2668,11 @@ Item *Item_sum_count_distinct::copy_or_same(THD* thd)
void Item_sum_count_distinct::clear()
{
/* tree and table can be both null only if always_null */
+ is_evaluated= FALSE;
if (tree)
+ {
tree->reset();
+ }
else if (table)
{
table->file->extra(HA_EXTRA_NO_CACHE);
@@ -2675,6 +2693,7 @@ bool Item_sum_count_distinct::add()
if ((*field)->is_real_null(0))
return 0; // Don't count NULL
+ is_evaluated= FALSE;
if (tree)
{
/*
@@ -2700,12 +2719,14 @@ longlong Item_sum_count_distinct::val_int()
return LL(0);
if (tree)
{
- ulonglong count;
+ if (is_evaluated)
+ return count;
if (tree->elements == 0)
return (longlong) tree->elements_in_tree(); // everything fits in memory
count= 0;
tree->walk(count_distinct_walk, (void*) &count);
+ is_evaluated= TRUE;
return (longlong) count;
}
@@ -2929,13 +2950,14 @@ int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
*/
Field *field= (*field_item)->get_tmp_table_field();
/*
- If field_item is a const item then either get_tp_table_field returns 0
+ If field_item is a const item then either get_tmp_table_field returns 0
or it is an item over a const table.
*/
if (field && !(*field_item)->const_item())
{
int res;
- uint offset= field->offset() - table->s->null_bytes;
+ uint offset= (field->offset(field->table->record[0]) -
+ table->s->null_bytes);
if ((res= field->cmp((char *) key1 + offset, (char *) key2 + offset)))
return res;
}
@@ -2973,7 +2995,8 @@ int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
if (field && !item->const_item())
{
int res;
- uint offset= field->offset() - table->s->null_bytes;
+ uint offset= (field->offset(field->table->record[0]) -
+ table->s->null_bytes);
if ((res= field->cmp((char *) key1 + offset, (char *) key2 + offset)))
return (*order_item)->asc ? res : -res;
}
@@ -3041,7 +3064,8 @@ int dump_leaf_key(byte* key, element_count count __attribute__((unused)),
because it contains both order and arg list fields.
*/
Field *field= (*arg)->get_tmp_table_field();
- uint offset= field->offset() - table->s->null_bytes;
+ uint offset= (field->offset(field->table->record[0]) -
+ table->s->null_bytes);
DBUG_ASSERT(offset < table->s->reclength);
res= field->val_str(&tmp, (char *) key + offset);
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index eb4c21bbe06..a4cd078b98b 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -352,12 +352,23 @@ public:
class Item_sum_num :public Item_sum
{
+protected:
+ /*
+ val_xxx() functions may be called several times during the execution of a
+ query. Derived classes that require extensive calculation in val_xxx()
+ maintain cache of aggregate value. This variable governs the validity of
+ that cache.
+ */
+ bool is_evaluated;
public:
- Item_sum_num() :Item_sum() {}
- Item_sum_num(Item *item_par) :Item_sum(item_par) {}
- Item_sum_num(Item *a, Item* b) :Item_sum(a,b) {}
- Item_sum_num(List<Item> &list) :Item_sum(list) {}
- Item_sum_num(THD *thd, Item_sum_num *item) :Item_sum(thd, item) {}
+ Item_sum_num() :Item_sum(),is_evaluated(FALSE) {}
+ Item_sum_num(Item *item_par)
+ :Item_sum(item_par), is_evaluated(FALSE) {}
+ Item_sum_num(Item *a, Item* b) :Item_sum(a,b),is_evaluated(FALSE) {}
+ Item_sum_num(List<Item> &list)
+ :Item_sum(list), is_evaluated(FALSE) {}
+ Item_sum_num(THD *thd, Item_sum_num *item)
+ :Item_sum(thd, item),is_evaluated(item->is_evaluated) {}
bool fix_fields(THD *, Item **);
longlong val_int()
{
@@ -540,6 +551,12 @@ class Item_sum_count_distinct :public Item_sum_int
*/
Unique *tree;
/*
+ Storage for the value of count between calls to val_int() so val_int()
+ will not recalculate on each call. Validitiy of the value is stored in
+ is_evaluated.
+ */
+ longlong count;
+ /*
Following is 0 normal object and pointer to original one for copy
(to correctly free resources)
*/
@@ -556,14 +573,15 @@ class Item_sum_count_distinct :public Item_sum_int
public:
Item_sum_count_distinct(List<Item> &list)
:Item_sum_int(list), table(0), field_lengths(0), tmp_table_param(0),
- force_copy_fields(0), tree(0), original(0), always_null(FALSE)
+ force_copy_fields(0), tree(0), count(0),
+ original(0), always_null(FALSE)
{ quick_group= 0; }
Item_sum_count_distinct(THD *thd, Item_sum_count_distinct *item)
:Item_sum_int(thd, item), table(item->table),
field_lengths(item->field_lengths),
tmp_table_param(item->tmp_table_param),
- force_copy_fields(0), tree(item->tree), original(item),
- tree_key_length(item->tree_key_length),
+ force_copy_fields(0), tree(item->tree), count(item->count),
+ original(item), tree_key_length(item->tree_key_length),
always_null(item->always_null)
{}
~Item_sum_count_distinct();
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 008496b1e90..44d9a063e7a 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1369,11 +1369,9 @@ bool get_interval_value(Item *args,interval_type int_type,
interval->second= array[0];
interval->second_part= array[1];
break;
- /* purecov: begin deadcode */
- case INTERVAL_LAST:
- DBUG_ASSERT(0);
- break;
- /* purecov: end */
+ case INTERVAL_LAST: /* purecov: begin deadcode */
+ DBUG_ASSERT(0);
+ break; /* purecov: end */
}
return 0;
}
@@ -1395,17 +1393,6 @@ String *Item_date::val_str(String *str)
}
-int Item_date::save_in_field(Field *field, bool no_conversions)
-{
- TIME ltime;
- if (get_date(&ltime, TIME_FUZZY_DATE))
- return set_field_to_null(field);
- field->set_notnull();
- field->store_time(&ltime, MYSQL_TIMESTAMP_DATE);
- return 0;
-}
-
-
longlong Item_date::val_int()
{
DBUG_ASSERT(fixed == 1);
@@ -2200,7 +2187,7 @@ void Item_extract::fix_length_and_dec()
case INTERVAL_HOUR_MICROSECOND: max_length=13; date_value=0; break;
case INTERVAL_MINUTE_MICROSECOND: max_length=11; date_value=0; break;
case INTERVAL_SECOND_MICROSECOND: max_length=9; date_value=0; break;
- case INTERVAL_LAST: DBUG_ASSERT(0); break; /* purecov: deadcode */
+ case INTERVAL_LAST: DBUG_ASSERT(0); break; /* purecov: deadcode */
}
}
@@ -2270,8 +2257,7 @@ longlong Item_extract::val_int()
ltime.second_part)*neg;
case INTERVAL_SECOND_MICROSECOND: return ((longlong)ltime.second*1000000L+
ltime.second_part)*neg;
- case INTERVAL_LAST: DBUG_ASSERT(0); return(0); /* purecov: deadcode */
- /* purecov: end */
+ case INTERVAL_LAST: DBUG_ASSERT(0); break; /* purecov: deadcode */
}
return 0; // Impossible
}
@@ -2386,7 +2372,8 @@ String *Item_char_typecast::val_str(String *str)
{ // Safe even if const arg
char char_type[40];
my_snprintf(char_type, sizeof(char_type), "%s(%lu)",
- cast_cs == &my_charset_bin ? "BINARY" : "CHAR", (ulong) length);
+ cast_cs == &my_charset_bin ? "BINARY" : "CHAR",
+ (ulong) length);
if (!res->alloced_length())
{ // Don't change const str
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 2a6ddd1bc65..360307a677f 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -360,12 +360,20 @@ public:
decimals=0;
max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
}
- int save_in_field(Field *to, bool no_conversions);
Field *tmp_table_field(TABLE *table)
{
return tmp_table_field_from_field_type(table, 0);
}
bool result_as_longlong() { return TRUE; }
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ DBUG_ASSERT(fixed == 1);
+ return val_decimal_from_date(decimal_value);
+ }
+ int save_in_field(Field *field, bool no_conversions)
+ {
+ return save_date_in_field(field);
+ }
};
@@ -382,29 +390,61 @@ public:
return tmp_table_field_from_field_type(table, 0);
}
bool result_as_longlong() { return TRUE; }
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ DBUG_ASSERT(fixed == 1);
+ return val_decimal_from_date(decimal_value);
+ }
+ int save_in_field(Field *field, bool no_conversions)
+ {
+ return save_date_in_field(field);
+ }
+};
+
+
+class Item_str_timefunc :public Item_str_func
+{
+public:
+ Item_str_timefunc() :Item_str_func() {}
+ Item_str_timefunc(Item *a) :Item_str_func(a) {}
+ Item_str_timefunc(Item *a,Item *b) :Item_str_func(a,b) {}
+ Item_str_timefunc(Item *a, Item *b, Item *c) :Item_str_func(a, b ,c) {}
+ enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
+ void fix_length_and_dec()
+ {
+ decimals=0;
+ max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
+ }
+ Field *tmp_table_field(TABLE *table)
+ {
+ return tmp_table_field_from_field_type(table, 0);
+ }
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ DBUG_ASSERT(fixed == 1);
+ return val_decimal_from_time(decimal_value);
+ }
+ int save_in_field(Field *field, bool no_conversions)
+ {
+ return save_time_in_field(field);
+ }
};
/* Abstract CURTIME function. Children should define what time zone is used */
-class Item_func_curtime :public Item_func
+class Item_func_curtime :public Item_str_timefunc
{
longlong value;
char buff[9*2+32];
uint buff_length;
public:
- Item_func_curtime() :Item_func() {}
- Item_func_curtime(Item *a) :Item_func(a) {}
- enum Item_result result_type () const { return STRING_RESULT; }
- enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
+ Item_func_curtime() :Item_str_timefunc() {}
+ Item_func_curtime(Item *a) :Item_str_timefunc(a) {}
double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; }
longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
String *val_str(String *str);
void fix_length_and_dec();
- Field *tmp_table_field(TABLE *table)
- {
- return tmp_table_field_from_field_type(table, 0);
- }
/*
Abstract method that defines which time zone is used for conversion.
Converts time current time in my_time_t representation to broken-down
@@ -626,10 +666,10 @@ class Item_func_convert_tz :public Item_date_func
};
-class Item_func_sec_to_time :public Item_str_func
+class Item_func_sec_to_time :public Item_str_timefunc
{
public:
- Item_func_sec_to_time(Item *item) :Item_str_func(item) {}
+ Item_func_sec_to_time(Item *item) :Item_str_timefunc(item) {}
double val_real()
{
DBUG_ASSERT(fixed == 1);
@@ -639,17 +679,12 @@ public:
String *val_str(String *);
void fix_length_and_dec()
{
+ Item_str_timefunc::fix_length_and_dec();
collation.set(&my_charset_bin);
maybe_null=1;
decimals= DATETIME_DEC;
- max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
}
- enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
const char *func_name() const { return "sec_to_time"; }
- Field *tmp_table_field(TABLE *table)
- {
- return tmp_table_field_from_field_type(table, 0);
- }
bool result_as_longlong() { return TRUE; }
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
@@ -774,6 +809,15 @@ public:
}
bool result_as_longlong() { return TRUE; }
longlong val_int();
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ DBUG_ASSERT(fixed == 1);
+ return val_decimal_from_date(decimal_value);
+ }
+ int save_in_field(Field *field, bool no_conversions)
+ {
+ return save_date_in_field(field);
+ }
};
@@ -792,6 +836,15 @@ public:
}
bool result_as_longlong() { return TRUE; }
longlong val_int();
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ DBUG_ASSERT(fixed == 1);
+ return val_decimal_from_time(decimal_value);
+ }
+ int save_in_field(Field *field, bool no_conversions)
+ {
+ return save_time_in_field(field);
+ }
};
@@ -809,12 +862,21 @@ public:
}
bool result_as_longlong() { return TRUE; }
longlong val_int();
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ DBUG_ASSERT(fixed == 1);
+ return val_decimal_from_date(decimal_value);
+ }
+ int save_in_field(Field *field, bool no_conversions)
+ {
+ return save_date_in_field(field);
+ }
};
-class Item_func_makedate :public Item_str_func
+class Item_func_makedate :public Item_date_func
{
public:
- Item_func_makedate(Item *a,Item *b) :Item_str_func(a,b) {}
+ Item_func_makedate(Item *a,Item *b) :Item_date_func(a,b) {}
String *val_str(String *str);
const char *func_name() const { return "makedate"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
@@ -823,11 +885,6 @@ public:
decimals=0;
max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
}
- Field *tmp_table_field(TABLE *table)
- {
- return tmp_table_field_from_field_type(table, 0);
- }
- bool result_as_longlong() { return TRUE; }
longlong val_int();
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
@@ -853,45 +910,46 @@ public:
void print(String *str);
const char *func_name() const { return "add_time"; }
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ DBUG_ASSERT(fixed == 1);
+ if (cached_field_type == MYSQL_TYPE_TIME)
+ return val_decimal_from_time(decimal_value);
+ if (cached_field_type == MYSQL_TYPE_DATETIME)
+ return val_decimal_from_date(decimal_value);
+ return Item_str_func::val_decimal(decimal_value);
+ }
+ int save_in_field(Field *field, bool no_conversions)
+ {
+ if (cached_field_type == MYSQL_TYPE_TIME)
+ return save_time_in_field(field);
+ if (cached_field_type == MYSQL_TYPE_DATETIME)
+ return save_date_in_field(field);
+ return Item_str_func::save_in_field(field, no_conversions);
+ }
};
-class Item_func_timediff :public Item_str_func
+class Item_func_timediff :public Item_str_timefunc
{
public:
Item_func_timediff(Item *a, Item *b)
- :Item_str_func(a, b) {}
+ :Item_str_timefunc(a, b) {}
String *val_str(String *str);
const char *func_name() const { return "timediff"; }
- enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
void fix_length_and_dec()
{
- decimals=0;
- max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
+ Item_str_timefunc::fix_length_and_dec();
maybe_null= 1;
}
- Field *tmp_table_field(TABLE *table)
- {
- return tmp_table_field_from_field_type(table, 0);
- }
};
-class Item_func_maketime :public Item_str_func
+class Item_func_maketime :public Item_str_timefunc
{
public:
Item_func_maketime(Item *a, Item *b, Item *c)
- :Item_str_func(a, b ,c) {}
+ :Item_str_timefunc(a, b ,c) {}
String *val_str(String *str);
const char *func_name() const { return "maketime"; }
- enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
- void fix_length_and_dec()
- {
- decimals=0;
- max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
- }
- Field *tmp_table_field(TABLE *table)
- {
- return tmp_table_field_from_field_type(table, 0);
- }
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
};
diff --git a/sql/key.cc b/sql/key.cc
index be21bf11c3c..dceeab1c011 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -19,37 +19,54 @@
#include "mysql_priv.h"
- /*
- ** Search after with key field is. If no key starts with field test
- ** if field is part of some key.
- **
- ** returns number of key. keylength is set to length of key before
- ** (not including) field
- ** Used when calculating key for NEXT_NUMBER
- */
-
-int find_ref_key(KEY *key, uint key_count, Field *field, uint *key_length)
+/*
+ Search after a key that starts with 'field'
+
+ SYNOPSIS
+ find_ref_key()
+ key First key to check
+ key_count How many keys to check
+ record Start of record
+ field Field to search after
+ key_length On partial match, contains length of fields before
+ field
+
+ NOTES
+ Used when calculating key for NEXT_NUMBER
+
+ IMPLEMENTATION
+ If no key starts with field test if field is part of some key. If we find
+ one, then return first key and set key_length to the number of bytes
+ preceding 'field'.
+
+ RETURN
+ -1 field is not part of the key
+ # Key part for key matching key.
+ key_length is set to length of key before (not including) field
+*/
+
+int find_ref_key(KEY *key, uint key_count, byte *record, Field *field,
+ uint *key_length)
{
reg2 int i;
reg3 KEY *key_info;
uint fieldpos;
- fieldpos= field->offset();
-
- /* Test if some key starts as fieldpos */
+ fieldpos= field->offset(record);
+ /* Test if some key starts as fieldpos */
for (i= 0, key_info= key ;
i < (int) key_count ;
i++, key_info++)
{
if (key_info->key_part[0].offset == fieldpos)
- { /* Found key. Calc keylength */
+ { /* Found key. Calc keylength */
*key_length=0;
- return(i); /* Use this key */
+ return(i); /* Use this key */
}
}
- /* Test if some key contains fieldpos */
+ /* Test if some key contains fieldpos */
for (i= 0, key_info= key;
i < (int) key_count ;
i++, key_info++)
@@ -62,7 +79,7 @@ int find_ref_key(KEY *key, uint key_count, Field *field, uint *key_length)
j++, key_part++)
{
if (key_part->offset == fieldpos)
- return(i); /* Use this key */
+ return(i); /* Use this key */
*key_length+=key_part->store_length;
}
}
diff --git a/sql/log.cc b/sql/log.cc
index 620445aecfa..b12eca9bb07 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1344,7 +1344,7 @@ binlog_trans_log_savepos(THD *thd, my_off_t *pos)
(binlog_trx_data*) thd->ha_data[binlog_hton->slot];
DBUG_ASSERT(mysql_bin_log.is_open());
*pos= trx_data->position();
- DBUG_PRINT("return", ("*pos=%u", *pos));
+ DBUG_PRINT("return", ("*pos: %lu", (ulong) *pos));
DBUG_VOID_RETURN;
}
@@ -1368,7 +1368,7 @@ static void
binlog_trans_log_truncate(THD *thd, my_off_t pos)
{
DBUG_ENTER("binlog_trans_log_truncate");
- DBUG_PRINT("enter", ("pos=%u", pos));
+ DBUG_PRINT("enter", ("pos: %lu", (ulong) pos));
DBUG_ASSERT(thd->ha_data[binlog_hton->slot] != NULL);
/* Only true if binlog_trans_log_savepos() wasn't called before */
@@ -1444,8 +1444,8 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data,
DBUG_ENTER("binlog_end_trans");
int error=0;
IO_CACHE *trans_log= &trx_data->trans_log;
- DBUG_PRINT("enter", ("transaction: %s, end_ev=%p",
- all ? "all" : "stmt", end_ev));
+ DBUG_PRINT("enter", ("transaction: %s end_ev: 0x%lx",
+ all ? "all" : "stmt", (long) end_ev));
DBUG_PRINT("info", ("thd->options={ %s%s}",
FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
FLAGSTR(thd->options, OPTION_BEGIN)));
@@ -3417,12 +3417,13 @@ int THD::binlog_setup_trx_data()
void
THD::binlog_start_trans_and_stmt()
{
- DBUG_ENTER("binlog_start_trans_and_stmt");
binlog_trx_data *trx_data= (binlog_trx_data*) ha_data[binlog_hton->slot];
- DBUG_PRINT("enter", ("trx_data=0x%lu", trx_data));
- if (trx_data)
- DBUG_PRINT("enter", ("trx_data->before_stmt_pos=%u",
- trx_data->before_stmt_pos));
+ DBUG_ENTER("binlog_start_trans_and_stmt");
+ DBUG_PRINT("enter", ("trx_data: 0x%lx trx_data->before_stmt_pos: %lu",
+ (long) trx_data,
+ (trx_data ? (ulong) trx_data->before_stmt_pos :
+ (ulong) 0)));
+
if (trx_data == NULL ||
trx_data->before_stmt_pos == MY_OFF_T_UNDEF)
{
@@ -3453,8 +3454,8 @@ int THD::binlog_write_table_map(TABLE *table, bool is_trans)
{
int error;
DBUG_ENTER("THD::binlog_write_table_map");
- DBUG_PRINT("enter", ("table: %0xlx (%s: #%u)",
- (long) table, table->s->table_name,
+ DBUG_PRINT("enter", ("table: 0x%lx (%s: #%lu)",
+ (long) table, table->s->table_name.str,
table->s->table_map_id));
/* Pre-conditions */
@@ -3517,7 +3518,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
{
DBUG_ENTER("MYSQL_BIN_LOG::flush_and_set_pending_rows_event(event)");
DBUG_ASSERT(mysql_bin_log.is_open());
- DBUG_PRINT("enter", ("event=%p", event));
+ DBUG_PRINT("enter", ("event: 0x%lx", (long) event));
int error= 0;
@@ -3526,7 +3527,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
DBUG_ASSERT(trx_data);
- DBUG_PRINT("info", ("trx_data->pending()=%p", trx_data->pending()));
+ DBUG_PRINT("info", ("trx_data->pending(): 0x%lx", (long) trx_data->pending()));
if (Rows_log_event* pending= trx_data->pending())
{
@@ -3681,9 +3682,9 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
my_off_t trans_log_pos= my_b_tell(trans_log);
if (event_info->get_cache_stmt() || trans_log_pos != 0)
{
- DBUG_PRINT("info", ("Using trans_log: cache=%d, trans_log_pos=%u",
+ DBUG_PRINT("info", ("Using trans_log: cache: %d, trans_log_pos: %lu",
event_info->get_cache_stmt(),
- trans_log_pos));
+ (ulong) trans_log_pos));
if (trans_log_pos == 0)
thd->binlog_start_trans_and_stmt();
file= trans_log;
@@ -3725,15 +3726,17 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
}
if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
{
- DBUG_PRINT("info",("number of auto_inc intervals: %lu",
- thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements()));
+ DBUG_PRINT("info",("number of auto_inc intervals: %u",
+ thd->auto_inc_intervals_in_cur_stmt_for_binlog.
+ nb_elements()));
/*
If the auto_increment was second in a table's index (possible with
MyISAM or BDB) (table->next_number_key_offset != 0), such event is
in fact not necessary. We could avoid logging it.
*/
- Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,
- thd->auto_inc_intervals_in_cur_stmt_for_binlog.minimum());
+ Intvar_log_event e(thd, (uchar) INSERT_ID_EVENT,
+ thd->auto_inc_intervals_in_cur_stmt_for_binlog.
+ minimum());
if (e.write(file))
goto err;
}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index f11822d8ad0..112f4aee135 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -846,7 +846,7 @@ Log_event* Log_event::read_log_event(IO_CACHE* file,
LOG_EVENT_MINIMAL_HEADER_LEN);
LOCK_MUTEX;
- DBUG_PRINT("info", ("my_b_tell=%lu", my_b_tell(file)));
+ DBUG_PRINT("info", ("my_b_tell: %lu", (ulong) my_b_tell(file)));
if (my_b_read(file, (byte *) head, header_size))
{
DBUG_PRINT("info", ("Log_event::read_log_event(IO_CACHE*,Format_desc*) \
@@ -1499,7 +1499,8 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
}
else
time_zone_len= 0;
- DBUG_PRINT("info",("Query_log_event has flags2=%lu sql_mode=%lu",flags2,sql_mode));
+ DBUG_PRINT("info",("Query_log_event has flags2: %lu sql_mode: %lu",
+ (ulong) flags2, sql_mode));
}
#endif /* MYSQL_CLIENT */
@@ -1547,7 +1548,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
common_header_len= description_event->common_header_len;
post_header_len= description_event->post_header_len[event_type-1];
- DBUG_PRINT("info",("event_len=%ld, common_header_len=%d, post_header_len=%d",
+ DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
event_len, common_header_len, post_header_len));
/*
@@ -1595,7 +1596,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
case Q_FLAGS2_CODE:
flags2_inited= 1;
flags2= uint4korr(pos);
- DBUG_PRINT("info",("In Query_log_event, read flags2: %lu", flags2));
+ DBUG_PRINT("info",("In Query_log_event, read flags2: %lu", (ulong) flags2));
pos+= 4;
break;
case Q_SQL_MODE_CODE:
@@ -3370,8 +3371,8 @@ Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
#ifndef DBUG_OFF
char buff[22];
DBUG_ENTER("Rotate_log_event::Rotate_log_event(...,flags)");
- DBUG_PRINT("enter",("new_log_ident %s pos %s flags %lu", new_log_ident_arg,
- llstr(pos_arg, buff), flags));
+ DBUG_PRINT("enter",("new_log_ident: %s pos: %s flags: %lu", new_log_ident_arg,
+ llstr(pos_arg, buff), (ulong) flags));
#endif
if (flags & DUP_NAME)
new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
@@ -4152,7 +4153,7 @@ Slave_log_event::Slave_log_event(THD* thd_arg,
memcpy(master_log, rli->group_master_log_name, master_log_len + 1);
master_port = mi->port;
master_pos = rli->group_master_log_pos;
- DBUG_PRINT("info", ("master_log: %s pos: %d", master_log,
+ DBUG_PRINT("info", ("master_log: %s pos: %lu", master_log,
(ulong) master_pos));
}
else
@@ -5344,8 +5345,8 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
uint8 const common_header_len= description_event->common_header_len;
uint8 const post_header_len= description_event->post_header_len[event_type-1];
- DBUG_PRINT("enter",("event_len=%ld, common_header_len=%d, "
- "post_header_len=%d",
+ DBUG_PRINT("enter",("event_len: %u common_header_len: %d "
+ "post_header_len: %d",
event_len, common_header_len,
post_header_len));
@@ -5375,7 +5376,7 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
const byte* const ptr_rows_data= var_start + byte_count + 1;
my_size_t const data_size= event_len - (ptr_rows_data - (const byte *) buf);
- DBUG_PRINT("info",("m_table_id=%lu, m_flags=%d, m_width=%u, data_size=%lu",
+ DBUG_PRINT("info",("m_table_id: %lu m_flags: %d m_width: %lu data_size: %lu",
m_table_id, m_flags, m_width, data_size));
m_rows_buf= (byte*)my_malloc(data_size, MYF(MY_WME));
@@ -5416,7 +5417,7 @@ int Rows_log_event::do_add_row_data(byte *const row_data,
*/
DBUG_ENTER("Rows_log_event::do_add_row_data");
DBUG_PRINT("enter", ("row_data: 0x%lx length: %lu", (ulong) row_data,
- length));
+ (ulong) length));
/*
Don't print debug messages when running valgrind since they can
trigger false warnings.
@@ -5517,7 +5518,7 @@ unpack_row(RELAY_LOG_INFO *rli,
byte *const record= table->record[0];
DBUG_ENTER("unpack_row");
DBUG_ASSERT(record && row);
- DBUG_PRINT("enter", ("row=0x%lx; table->record[0]=0x%lx", row, record));
+ DBUG_PRINT("enter", ("row: 0x%lx table->record[0]: 0x%lx", (long) row, (long) record));
my_size_t master_null_bytes= table->s->null_bytes;
if (colcnt != table->s->fields)
@@ -5558,9 +5559,11 @@ unpack_row(RELAY_LOG_INFO *rli,
if (bitmap_is_set(cols, field_ptr - begin_ptr))
{
DBUG_ASSERT(table->record[0] <= f->ptr);
- DBUG_ASSERT(f->ptr < table->record[0] + table->s->reclength + (f->pack_length_in_rec() == 0));
+ DBUG_ASSERT(f->ptr < (table->record[0] + table->s->reclength +
+ (f->pack_length_in_rec() == 0)));
- DBUG_PRINT("info", ("unpacking column '%s' to 0x%lx", f->field_name, f->ptr));
+ DBUG_PRINT("info", ("unpacking column '%s' to 0x%lx", f->field_name,
+ (long) f->ptr));
ptr= f->unpack(f->ptr, ptr);
/* Field...::unpack() cannot return 0 */
DBUG_ASSERT(ptr != NULL);
@@ -5594,7 +5597,8 @@ unpack_row(RELAY_LOG_INFO *rli,
uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
Field *const f= *field_ptr;
- DBUG_PRINT("info", ("processing column '%s' @ 0x%lx", f->field_name, f->ptr));
+ DBUG_PRINT("info", ("processing column '%s' @ 0x%lx", f->field_name,
+ (long) f->ptr));
if (event_type == WRITE_ROWS_EVENT && (f->flags & mask) == mask)
{
slave_print_msg(ERROR_LEVEL, rli, ER_NO_DEFAULT_FOR_FIELD,
@@ -6070,7 +6074,7 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
uint8 common_header_len= description_event->common_header_len;
uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
- DBUG_PRINT("info",("event_len=%ld, common_header_len=%d, post_header_len=%d",
+ DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
event_len, common_header_len, post_header_len));
/*
@@ -6118,10 +6122,10 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
m_colcnt= net_field_length(&ptr_after_colcnt);
- DBUG_PRINT("info",("m_dblen=%d off=%d m_tbllen=%d off=%d m_colcnt=%d off=%d",
- m_dblen, ptr_dblen-(const byte*)vpart,
- m_tbllen, ptr_tbllen-(const byte*)vpart,
- m_colcnt, ptr_colcnt-(const byte*)vpart));
+ DBUG_PRINT("info",("m_dblen: %lu off: %ld m_tbllen: %lu off: %ld m_colcnt: %lu off: %ld",
+ m_dblen, (long) (ptr_dblen-(const byte*)vpart),
+ m_tbllen, (long) (ptr_tbllen-(const byte*)vpart),
+ m_colcnt, (long) (ptr_colcnt-(const byte*)vpart)));
/* Allocate mem for all fields in one go. If fails, catched in is_valid() */
m_memory= my_multi_malloc(MYF(MY_WME),
@@ -6523,11 +6527,11 @@ copy_extra_record_fields(TABLE *table,
my_size_t master_reclength,
my_ptrdiff_t master_fields)
{
- DBUG_PRINT("info", ("Copying to %p "
- "from field %ld at offset %u "
- "to field %d at offset %u",
- table->record[0],
- master_fields, master_reclength,
+ DBUG_PRINT("info", ("Copying to 0x%lx "
+ "from field %lu at offset %lu "
+ "to field %d at offset %lu",
+ (long) table->record[0],
+ (ulong) master_fields, (ulong) master_reclength,
table->s->fields, table->s->reclength));
/*
Copying the extra fields of the slave that does not exist on
diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc
index 89607129026..30a271df064 100644
--- a/sql/my_decimal.cc
+++ b/sql/my_decimal.cc
@@ -15,6 +15,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysql_priv.h"
+#include <time.h>
+
#ifndef MYSQL_CLIENT
/*
@@ -190,6 +192,23 @@ int str2my_decimal(uint mask, const char *from, uint length,
}
+my_decimal *date2my_decimal(TIME *ltime, my_decimal *dec)
+{
+ longlong date;
+ date = (ltime->year*100L + ltime->month)*100L + ltime->day;
+ if (ltime->time_type > MYSQL_TIMESTAMP_DATE)
+ date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
+ if (int2my_decimal(E_DEC_FATAL_ERROR, date, FALSE, dec))
+ return dec;
+ if (ltime->second_part)
+ {
+ dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
+ dec->frac= 6;
+ }
+ return dec;
+}
+
+
#ifndef DBUG_OFF
/* routines for debugging print */
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index 3ce8cfee75d..9e2dea26700 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -295,7 +295,12 @@ int string2my_decimal(uint mask, const String *str, my_decimal *d)
{
return str2my_decimal(mask, str->ptr(), str->length(), str->charset(), d);
}
-#endif
+
+
+my_decimal *date2my_decimal(TIME *ltime, my_decimal *dec);
+
+
+#endif /*defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY) */
inline
int double2my_decimal(uint mask, double val, my_decimal *d)
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 3dfb6aed9b0..8bc5f127b1d 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1435,7 +1435,8 @@ void print_plan(JOIN* join,uint idx, double record_count, double read_time,
#endif
void mysql_print_status();
/* key.cc */
-int find_ref_key(KEY *key, uint key_count, Field *field, uint *key_length);
+int find_ref_key(KEY *key, uint key_count, byte *record, Field *field,
+ uint *key_length);
void key_copy(byte *to_key, byte *from_record, KEY *key_info, uint key_length);
void key_restore(byte *to_record, byte *from_key, KEY *key_info,
uint key_length);
@@ -1804,7 +1805,7 @@ ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder,
uint s_length, SQL_SELECT *select,
ha_rows max_rows, bool sort_positions,
ha_rows *examined_rows);
-void filesort_free_buffers(TABLE *table);
+void filesort_free_buffers(TABLE *table, bool full);
void change_double_for_sort(double nr,byte *to);
double my_double_round(double value, int dec, bool truncate);
int get_quick_record(SQL_SELECT *select);
@@ -1824,7 +1825,7 @@ int create_frm(THD *thd, const char *name, const char *db, const char *table,
HA_CREATE_INFO *create_info, uint keys);
void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form);
int rename_file_ext(const char * from,const char * to,const char * ext);
-bool check_db_name(char *db);
+bool check_db_name(LEX_STRING *db);
bool check_column_name(const char *name);
bool check_table_name(const char *name, uint length);
char *get_field(MEM_ROOT *mem, Field *field);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index a5c465d2408..b37996f5109 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1610,7 +1610,7 @@ static void network_init(void)
if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
{
sql_print_error("The socket file path is too long (> %u): %s",
- sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
+ (uint) sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
unireg_abort(1);
}
if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
@@ -2121,7 +2121,7 @@ the thread stack. Please read http://www.mysql.com/doc/en/Linux.html\n\n",
#ifdef HAVE_STACKTRACE
if (!(test_flags & TEST_NO_STACKTRACE))
{
- fprintf(stderr,"thd=%p\n",thd);
+ fprintf(stderr,"thd: 0x%lx\n",(long) thd);
print_stacktrace(thd ? (gptr) thd->thread_stack : (gptr) 0,
thread_stack);
}
@@ -3219,7 +3219,7 @@ server.");
using_update_log=1;
}
- if (plugin_init(0))
+ if (plugin_init(opt_bootstrap))
{
sql_print_error("Failed to init plugins.");
return 1;
@@ -3537,7 +3537,7 @@ int main(int argc, char **argv)
if (stack_size && stack_size < thread_stack)
{
if (global_system_variables.log_warnings)
- sql_print_warning("Asked for %ld thread stack, but got %ld",
+ sql_print_warning("Asked for %lu thread stack, but got %ld",
thread_stack, (long) stack_size);
#if defined(__ia64__) || defined(__ia64)
thread_stack= stack_size*2;
@@ -4083,7 +4083,7 @@ static void create_new_thread(THD *thd)
int error;
thread_created++;
threads.append(thd);
- DBUG_PRINT("info",(("creating thread %d"), thd->thread_id));
+ DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
thd->connect_time = time(NULL);
if ((error=pthread_create(&thd->real_id,&connection_attrib,
handle_one_connection,
@@ -5347,7 +5347,8 @@ master-ssl",
(gptr*) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"merge", OPT_MERGE, "Enable Merge storage engine. Disable with \
--skip-merge.",
- (gptr*) &opt_merge, (gptr*) &opt_merge, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ (gptr*) &opt_merge, (gptr*) &opt_merge, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
+ 0},
{"myisam-recover", OPT_MYISAM_RECOVER,
"Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
(gptr*) &myisam_recover_options_str, (gptr*) &myisam_recover_options_str, 0,
diff --git a/sql/mysqld.cc.rej b/sql/mysqld.cc.rej
new file mode 100644
index 00000000000..62f0357622d
--- /dev/null
+++ b/sql/mysqld.cc.rej
@@ -0,0 +1,17 @@
+***************
+*** 5316,5322 ****
+ (gptr*) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"merge", OPT_MERGE, "Enable Merge storage engine. Disable with \
+ --skip-merge.",
+! (gptr*) &opt_merge, (gptr*) &opt_merge, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0},
+ {"myisam-recover", OPT_MYISAM_RECOVER,
+ "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
+ (gptr*) &myisam_recover_options_str, (gptr*) &myisam_recover_options_str, 0,
+--- 5336,5342 ----
+ (gptr*) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"merge", OPT_MERGE, "Enable Merge storage engine. Disable with \
+ --skip-merge.",
+! (gptr*) &opt_merge, (gptr*) &opt_merge, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"myisam-recover", OPT_MYISAM_RECOVER,
+ "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
+ (gptr*) &myisam_recover_options_str, (gptr*) &myisam_recover_options_str, 0,
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index a55fef5555c..ec4c4675e76 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -809,7 +809,7 @@ my_real_read(NET *net, ulong *complen)
{
my_bool interrupted = vio_should_retry(net->vio);
- DBUG_PRINT("info",("vio_read returned %d, errno: %d",
+ DBUG_PRINT("info",("vio_read returned %ld, errno: %d",
length, vio_errno(net->vio)));
#if !defined(__WIN__) || defined(MYSQL_SERVER)
/*
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 79b3e023a5f..bcf2bce82b7 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1003,7 +1003,7 @@ QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
range_end();
if (free_file)
{
- DBUG_PRINT("info", ("Freeing separate handler %p (free=%d)", file,
+ DBUG_PRINT("info", ("Freeing separate handler 0x%lx (free: %d)", (long) file,
free_file));
file->ha_external_lock(current_thd, F_UNLCK);
file->close();
@@ -2011,7 +2011,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
double scan_time;
DBUG_ENTER("SQL_SELECT::test_quick_select");
DBUG_PRINT("enter",("keys_to_use: %lu prev_tables: %lu const_tables: %lu",
- keys_to_use.to_ulonglong(), (ulong) prev_tables,
+ (ulong) keys_to_use.to_ulonglong(), (ulong) prev_tables,
(ulong) const_tables));
DBUG_PRINT("info", ("records: %lu", (ulong) head->file->stats.records));
delete quick;
@@ -3396,7 +3396,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records)
n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, rows2double(records)));
if (busy_blocks < 1.0)
busy_blocks= 1.0;
- DBUG_PRINT("info",("sweep: nblocks=%g, busy_blocks=%g", n_blocks,
+ DBUG_PRINT("info",("sweep: nblocks: %g, busy_blocks: %g", n_blocks,
busy_blocks));
/*
Disabled: Bail out if # of blocks to read is bigger than # of blocks in
@@ -3420,7 +3420,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records)
result= busy_blocks;
}
}
- DBUG_PRINT("info",("returning cost=%g", result));
+ DBUG_PRINT("return",("cost: %g", result));
DBUG_RETURN(result);
}
@@ -3514,7 +3514,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
ha_rows roru_total_records;
double roru_intersect_part= 1.0;
DBUG_ENTER("get_best_disjunct_quick");
- DBUG_PRINT("info", ("Full table scan cost =%g", read_time));
+ DBUG_PRINT("info", ("Full table scan cost: %g", read_time));
if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root,
sizeof(TRP_RANGE*)*
@@ -3558,7 +3558,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
non_cpk_scan_records += (*cur_child)->records;
}
- DBUG_PRINT("info", ("index_merge scans cost=%g", imerge_cost));
+ DBUG_PRINT("info", ("index_merge scans cost %g", imerge_cost));
if (imerge_too_expensive || (imerge_cost > read_time) ||
(non_cpk_scan_records+cpk_scan_records >= param->table->file->stats.records) &&
read_time != DBL_MAX)
@@ -4172,7 +4172,7 @@ static bool ror_intersect_add(ROR_INTERSECT_INFO *info,
DBUG_PRINT("info", ("Current out_rows= %g", info->out_rows));
DBUG_PRINT("info", ("Adding scan on %s",
info->param->table->key_info[ror_scan->keynr].name));
- DBUG_PRINT("info", ("is_cpk_scan=%d",is_cpk_scan));
+ DBUG_PRINT("info", ("is_cpk_scan: %d",is_cpk_scan));
selectivity_mult = ror_scan_selectivity(info, ror_scan);
if (selectivity_mult == 1.0)
@@ -9700,8 +9700,8 @@ void cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
*records= num_groups;
DBUG_PRINT("info",
- ("table rows=%u, keys/block=%u, keys/group=%u, result rows=%u, blocks=%u",
- table_records, keys_per_block, keys_per_group, *records,
+ ("table rows: %u keys/block: %u keys/group: %u result rows: %lu blocks: %u",
+ table_records, keys_per_block, keys_per_group, (ulong) *records,
num_blocks));
DBUG_VOID_RETURN;
}
@@ -10814,7 +10814,7 @@ static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
if (!tmp.length())
tmp.append(STRING_WITH_LEN("(empty)"));
- DBUG_PRINT("info", ("SEL_TREE %p (%s) scans:%s", tree, msg, tmp.ptr()));
+ DBUG_PRINT("info", ("SEL_TREE: 0x%lx (%s) scans: %s", (long) tree, msg, tmp.ptr()));
DBUG_VOID_RETURN;
}
@@ -11056,7 +11056,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::dbug_dump(int indent, bool verbose)
#endif /* NOT_USED */
/*****************************************************************************
-** Instantiate templates
+** Instantiate templates
*****************************************************************************/
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
diff --git a/sql/parse_file.h b/sql/parse_file.h
index 5fb65b4c7ec..0a02bf7eb75 100644
--- a/sql/parse_file.h
+++ b/sql/parse_file.h
@@ -106,21 +106,4 @@ public:
MEM_ROOT *mem_root,
bool bad_format_errors);
};
-
-
-/*
- Custom version of standard offsetof() macro which can be used to get
- offsets of members in class for non-POD types (according to the current
- version of C++ standard offsetof() macro can't be used in such cases and
- attempt to do so causes warnings to be emitted, OTOH in many cases it is
- still OK to assume that all instances of the class has the same offsets
- for the same members).
-
- This is temporary solution which should be removed once File_parser class
- and related routines are refactored.
-*/
-
-#define my_offsetof(TYPE, MEMBER) \
- ((size_t)((char *)&(((TYPE *)0x10)->MEMBER) - (char*)0x10))
-
#endif /* _PARSE_FILE_H_ */
diff --git a/sql/protocol.cc b/sql/protocol.cc
index a2ae194c374..6fe4e34d5a9 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -46,7 +46,7 @@ bool Protocol_prep::net_store_data(const char *from, uint length)
packet->realloc(packet_length+9+length))
return 1;
char *to=(char*) net_store_length((char*) packet->ptr()+packet_length,
- (ulonglong) length);
+ length);
memcpy(to,from,length);
packet->length((uint) (to+length-packet->ptr()));
return 0;
@@ -282,8 +282,8 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
}
buff[0]=0; // No fields
- pos=net_store_length(buff+1,(ulonglong) affected_rows);
- pos=net_store_length(pos, (ulonglong) id);
+ pos=net_store_length(buff+1,affected_rows);
+ pos=net_store_length(pos, id);
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
DBUG_PRINT("info",
@@ -458,7 +458,7 @@ void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
ulonglong for bigger numbers.
*/
-char *net_store_length(char *pkg, uint length)
+static char *net_store_length_fast(char *pkg, uint length)
{
uchar *packet=(uchar*) pkg;
if (length < 251)
@@ -481,7 +481,7 @@ char *net_store_length(char *pkg, uint length)
char *net_store_data(char *to,const char *from, uint length)
{
- to=net_store_length(to,length);
+ to=net_store_length_fast(to,length);
memcpy(to,from,length);
return to+length;
}
@@ -490,7 +490,7 @@ char *net_store_data(char *to,int32 from)
{
char buff[20];
uint length=(uint) (int10_to_str(from,buff,10)-buff);
- to=net_store_length(to,length);
+ to=net_store_length_fast(to,length);
memcpy(to,buff,length);
return to+length;
}
@@ -499,7 +499,7 @@ char *net_store_data(char *to,longlong from)
{
char buff[22];
uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
- to=net_store_length(to,length);
+ to=net_store_length_fast(to,length);
memcpy(to,buff,length);
return to+length;
}
@@ -563,7 +563,7 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
if (flags & SEND_NUM_ROWS)
{ // Packet with number of elements
- char *pos=net_store_length(buff, (uint) list->elements);
+ char *pos=net_store_length(buff, list->elements);
(void) my_net_write(&thd->net, buff,(uint) (pos-buff));
}
diff --git a/sql/protocol.h b/sql/protocol.h
index 85c22724b74..7e2bc1516ec 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -166,7 +166,6 @@ void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L,
const char *info=0);
void send_eof(THD *thd);
bool send_old_password_request(THD *thd);
-char *net_store_length(char *packet,uint length);
char *net_store_data(char *to,const char *from, uint length);
char *net_store_data(char *to,int32 from);
char *net_store_data(char *to,longlong from);
diff --git a/sql/records.cc b/sql/records.cc
index b2505600b22..f8b6a7d1df9 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -20,7 +20,7 @@
#include "mysql_priv.h"
static int rr_quick(READ_RECORD *info);
-static int rr_sequential(READ_RECORD *info);
+int rr_sequential(READ_RECORD *info);
static int rr_from_tempfile(READ_RECORD *info);
static int rr_unpack_from_tempfile(READ_RECORD *info);
static int rr_unpack_from_buffer(READ_RECORD *info);
@@ -251,6 +251,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
} /* init_read_record */
+
void end_read_record(READ_RECORD *info)
{ /* free cache if used */
if (info->cache)
@@ -260,7 +261,7 @@ void end_read_record(READ_RECORD *info)
}
if (info->table)
{
- filesort_free_buffers(info->table);
+ filesort_free_buffers(info->table,0);
(void) info->file->extra(HA_EXTRA_NO_CACHE);
if (info->read_record != rr_quick) // otherwise quick_range does it
(void) info->file->ha_index_or_rnd_end();
@@ -356,7 +357,7 @@ static int rr_index(READ_RECORD *info)
}
-static int rr_sequential(READ_RECORD *info)
+int rr_sequential(READ_RECORD *info)
{
int tmp;
while ((tmp=info->file->rnd_next(info->record)))
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 2b034d50d6a..762fcfb7a6a 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -564,8 +564,8 @@ err:
mysql_free_result(res);
if (error)
{
- sql_print_error("While trying to obtain the list of slaves from the master \
-'%s:%d', user '%s' got the following error: '%s'",
+ sql_print_error("While trying to obtain the list of slaves from the master "
+ "'%s:%d', user '%s' got the following error: '%s'",
mi->host, mi->port, mi->user, error);
DBUG_RETURN(1);
}
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index f01fc5d1c9e..a2edb9dc8a8 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -402,7 +402,7 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,
bool look_for_description_event)
{
DBUG_ENTER("init_relay_log_pos");
- DBUG_PRINT("info", ("pos=%lu", pos));
+ DBUG_PRINT("info", ("pos: %lu", (ulong) pos));
*errmsg=0;
pthread_mutex_t *log_lock=rli->relay_log.get_log_lock();
@@ -855,7 +855,7 @@ void st_relay_log_info::close_temporary_tables()
Don't ask for disk deletion. For now, anyway they will be deleted when
slave restarts, but it is a better intention to not delete them.
*/
- DBUG_PRINT("info", ("table: %p", table));
+ DBUG_PRINT("info", ("table: 0x%lx", (long) table));
close_temporary(table, 1, 0);
}
save_temporary_tables= 0;
diff --git a/sql/rpl_tblmap.cc b/sql/rpl_tblmap.cc
index a0272b23ee8..97f0066233c 100644
--- a/sql/rpl_tblmap.cc
+++ b/sql/rpl_tblmap.cc
@@ -50,17 +50,17 @@ table_mapping::~table_mapping()
st_table* table_mapping::get_table(ulong table_id)
{
DBUG_ENTER("table_mapping::get_table(ulong)");
- DBUG_PRINT("enter", ("table_id=%d", table_id));
+ DBUG_PRINT("enter", ("table_id: %lu", table_id));
entry *e= find_entry(table_id);
if (e)
{
- DBUG_PRINT("info", ("tid %d -> table %p (%s)",
- table_id, e->table,
+ DBUG_PRINT("info", ("tid %lu -> table 0x%lx (%s)",
+ table_id, (long) e->table,
MAYBE_TABLE_NAME(e->table)));
DBUG_RETURN(e->table);
}
- DBUG_PRINT("info", ("tid %d is not mapped!", table_id));
+ DBUG_PRINT("info", ("tid %lu is not mapped!", table_id));
DBUG_RETURN(NULL);
}
@@ -93,9 +93,9 @@ int table_mapping::expand()
int table_mapping::set_table(ulong table_id, TABLE* table)
{
DBUG_ENTER("table_mapping::set_table(ulong,TABLE*)");
- DBUG_PRINT("enter", ("table_id=%d, table=%p (%s)",
+ DBUG_PRINT("enter", ("table_id: %lu table: 0x%lx (%s)",
table_id,
- table, MAYBE_TABLE_NAME(table)));
+ (long) table, MAYBE_TABLE_NAME(table)));
entry *e= find_entry(table_id);
if (e == 0)
{
@@ -111,8 +111,8 @@ int table_mapping::set_table(ulong table_id, TABLE* table)
e->table= table;
my_hash_insert(&m_table_ids,(byte *)e);
- DBUG_PRINT("info", ("tid %d -> table %p (%s)",
- table_id, e->table,
+ DBUG_PRINT("info", ("tid %lu -> table 0x%lx (%s)",
+ table_id, (long) e->table,
MAYBE_TABLE_NAME(e->table)));
DBUG_RETURN(0); // All OK
}
diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc
index c80b6dc3f69..4bed1343e55 100644
--- a/sql/rpl_utility.cc
+++ b/sql/rpl_utility.cc
@@ -25,7 +25,7 @@ field_length_from_packed(enum_field_types const field_type,
switch (field_type) {
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
- length= ~0UL;
+ length= ~(uint32) 0;
break;
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_TINY:
@@ -71,7 +71,7 @@ field_length_from_packed(enum_field_types const field_type,
break;
break;
case MYSQL_TYPE_BIT:
- length= ~0UL;
+ length= ~(uint32) 0;
break;
default:
/* This case should never be chosen */
@@ -85,7 +85,7 @@ field_length_from_packed(enum_field_types const field_type,
case MYSQL_TYPE_SET:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_VARCHAR:
- length= ~0UL; // NYI
+ length= ~(uint32) 0; // NYI
break;
case MYSQL_TYPE_TINY_BLOB:
@@ -93,7 +93,7 @@ field_length_from_packed(enum_field_types const field_type,
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_GEOMETRY:
- length= ~0UL; // NYI
+ length= ~(uint32) 0; // NYI
break;
}
@@ -131,7 +131,8 @@ table_def::compatible_with(RELAY_LOG_INFO *rli, TABLE *table)
slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_WRONG_TABLE_DEF,
"Table width mismatch - "
"received %u columns, %s.%s has %u columns",
- size(), tsh->db.str, tsh->table_name.str, tsh->fields);
+ (uint) size(), tsh->db.str, tsh->table_name.str,
+ tsh->fields);
}
for (uint col= 0 ; col < cols_to_check ; ++col)
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 5590e71c810..dc78eb2f509 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -3943,7 +3943,7 @@ sys_var_event_scheduler::update(THD *thd, set_var *var)
DBUG_RETURN(TRUE);
}
- DBUG_PRINT("new_value", ("%lu", (bool)var->save_result.ulong_value));
+ DBUG_PRINT("info", ("new_value: %d", (int) var->save_result.ulong_value));
Item_result var_type= var->value->result_type();
diff --git a/sql/slave.cc b/sql/slave.cc
index b497b7c8520..4c5f0fc4764 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1609,7 +1609,7 @@ static ulong read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings)
DBUG_RETURN(packet_error);
}
- DBUG_PRINT("info",( "len=%u, net->read_pos[4] = %d\n",
+ DBUG_PRINT("exit", ("len: %lu net->read_pos[4]: %d",
len, mysql->net.read_pos[4]));
DBUG_RETURN(len - 1);
}
@@ -1800,7 +1800,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
ev->when = time(NULL);
ev->thd = thd; // because up to this point, ev->thd == 0
exec_res = ev->exec_event(rli);
- DBUG_PRINT("info", ("exec_event result = %d", exec_res));
+ DBUG_PRINT("info", ("exec_event result: %d", exec_res));
DBUG_ASSERT(rli->sql_thd==thd);
/*
Format_description_log_event should not be deleted because it will be
@@ -1951,9 +1951,9 @@ pthread_handler_t handle_slave_io(void *arg)
// we can get killed during safe_connect
if (!safe_connect(thd, mysql, mi))
{
- sql_print_information("Slave I/O thread: connected to master '%s@%s:%d',\
- replication started in log '%s' at position %s", mi->user,
- mi->host, mi->port,
+ sql_print_information("Slave I/O thread: connected to master '%s@%s:%d',"
+ "replication started in log '%s' at position %s",
+ mi->user, mi->host, mi->port,
IO_RPL_LOG_NAME,
llstr(mi->master_log_pos,llbuff));
/*
@@ -2604,7 +2604,7 @@ static int process_io_rotate(MASTER_INFO *mi, Rotate_log_event *rev)
/* Safe copy as 'rev' has been "sanitized" in Rotate_log_event's ctor */
memcpy(mi->master_log_name, rev->new_log_ident, rev->ident_len+1);
mi->master_log_pos= rev->pos;
- DBUG_PRINT("info", ("master_log_pos: '%s' %d",
+ DBUG_PRINT("info", ("master_log_pos: '%s' %lu",
mi->master_log_name, (ulong) mi->master_log_pos));
#ifndef DBUG_OFF
/*
@@ -2721,7 +2721,7 @@ static int queue_binlog_ver_1_event(MASTER_INFO *mi, const char *buf,
int error = process_io_create_file(mi,(Create_file_log_event*)ev);
delete ev;
mi->master_log_pos += inc_pos;
- DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
pthread_mutex_unlock(&mi->data_lock);
my_free((char*)tmp_buf, MYF(0));
DBUG_RETURN(error);
@@ -2748,7 +2748,7 @@ static int queue_binlog_ver_1_event(MASTER_INFO *mi, const char *buf,
}
delete ev;
mi->master_log_pos+= inc_pos;
- DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
pthread_mutex_unlock(&mi->data_lock);
DBUG_RETURN(0);
}
@@ -2804,7 +2804,7 @@ static int queue_binlog_ver_3_event(MASTER_INFO *mi, const char *buf,
delete ev;
mi->master_log_pos+= inc_pos;
err:
- DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
pthread_mutex_unlock(&mi->data_lock);
DBUG_RETURN(0);
}
@@ -2977,7 +2977,8 @@ int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len)
rli->ign_master_log_pos_end= mi->master_log_pos;
}
rli->relay_log.signal_update(); // the slave SQL thread needs to re-check
- DBUG_PRINT("info", ("master_log_pos: %d, event originating from the same server, ignored", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu, event originating from the same server, ignored",
+ (ulong) mi->master_log_pos));
}
else
{
@@ -2985,7 +2986,7 @@ int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len)
if (likely(!(rli->relay_log.appendv(buf,event_len,0))))
{
mi->master_log_pos+= inc_pos;
- DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
}
else
@@ -3106,8 +3107,8 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
{
last_errno=mysql_errno(mysql);
suppress_warnings= 0;
- sql_print_error("Slave I/O thread: error %s to master \
-'%s@%s:%d': \
+ sql_print_error("Slave I/O thread: error %s to master "
+ "'%s@%s:%d': \
Error: '%s' errno: %d retry-time: %d retries: %lu",
(reconnect ? "reconnecting" : "connecting"),
mi->user, mi->host, mi->port,
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 47a623ec749..622d9efdde0 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -899,7 +899,7 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
break;
val= (*splocal)->this_item();
- DBUG_PRINT("info", ("print %p", val));
+ DBUG_PRINT("info", ("print 0x%lx", (long) val));
str_value= sp_get_item_value(val, &str_value_holder);
if (str_value)
res|= qbuf.append(*str_value);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index aa13c2f08f4..721b6b5a003 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -3871,7 +3871,7 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
GRANT_COLUMN *grant_column;
ulong want_access= grant->want_privilege & ~grant->privilege;
DBUG_ENTER("check_grant_column");
- DBUG_PRINT("enter", ("table: %s want_access: %u", table_name, want_access));
+ DBUG_PRINT("enter", ("table: %s want_access: %lu", table_name, want_access));
if (!want_access)
DBUG_RETURN(0); // Already checked
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index a5621290123..0d792113d51 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1087,7 +1087,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
if (!lock_in_use)
VOID(pthread_mutex_lock(&LOCK_open));
- DBUG_PRINT("info", ("thd->open_tables: %p", thd->open_tables));
+ DBUG_PRINT("info", ("thd->open_tables: 0x%lx", (long) thd->open_tables));
/*
End open index scans and table scans and remove references to the tables
@@ -1184,6 +1184,16 @@ static inline uint tmpkeyval(THD *thd, TABLE *table)
void close_temporary_tables(THD *thd)
{
TABLE *table;
+ TABLE *next;
+ /*
+ TODO: 5.1 maintains prev link in temporary_tables
+ double-linked list so we could fix it. But it is not necessary
+ at this time when the list is being destroyed
+ */
+ TABLE *prev_table;
+ /* Assume thd->options has OPTION_QUOTE_SHOW_CREATE */
+ bool was_quote_show= TRUE;
+
if (!thd->temporary_tables)
return;
@@ -1199,12 +1209,7 @@ void close_temporary_tables(THD *thd)
return;
}
- TABLE *next,
- *prev_table /* TODO: 5.1 maintaines prev link in temporary_tables
- double-linked list so we could fix it. But it is not necessary
- at this time when the list is being destroyed */;
- bool was_quote_show= true; /* to assume thd->options has OPTION_QUOTE_SHOW_CREATE */
- // Better add "if exists", in case a RESET MASTER has been done
+ /* Better add "if exists", in case a RESET MASTER has been done */
const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ";
uint stub_len= sizeof(stub) - 1;
char buf[256];
@@ -1310,7 +1315,7 @@ void close_temporary_tables(THD *thd)
}
}
if (!was_quote_show)
- thd->options &= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
+ thd->options&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
thd->temporary_tables=0;
}
@@ -2076,7 +2081,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(0); // VIEW
}
- DBUG_PRINT("info", ("inserting table %p into the cache", table));
+ DBUG_PRINT("info", ("inserting table 0x%lx into the cache", (long) table));
VOID(my_hash_insert(&open_cache,(byte*) table));
}
@@ -2117,6 +2122,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
table->file->ft_handler= 0;
if (table->timestamp_field)
table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
+ table->pos_in_table_list= table_list;
table_list->updatable= 1; // It is not derived table nor non-updatable VIEW
table->clear_column_bitmaps();
DBUG_ASSERT(table->key_read == 0);
@@ -2406,7 +2412,7 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock)
{
DBUG_PRINT("info", ("share: 0x%lx locked_by_logger: %d "
"locked_by_flush: %d locked_by_name: %d "
- "db_stat: %u version: %u",
+ "db_stat: %u version: %lu",
(ulong) search->s, search->locked_by_logger,
search->locked_by_flush, search->locked_by_name,
search->db_stat,
@@ -3560,6 +3566,7 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
if (thd->slave_thread)
slave_open_temp_tables++;
}
+ tmp_table->pos_in_table_list= 0;
DBUG_RETURN(tmp_table);
}
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index 732981b58f3..37094b992e5 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -85,8 +85,9 @@ void mysql_client_binlog_statement(THD* thd)
since it will read from unassigned memory.
*/
DBUG_PRINT("info",
- ("bytes_decoded=%d; strptr=0x%lu; endptr=0x%lu ('%c':%d)",
- bytes_decoded, strptr, endptr, *endptr, *endptr));
+ ("bytes_decoded: %d strptr: 0x%lx endptr: 0x%lx ('%c':%d)",
+ bytes_decoded, (long) strptr, (long) endptr, *endptr,
+ *endptr));
#endif
if (bytes_decoded < 0)
@@ -113,8 +114,8 @@ void mysql_client_binlog_statement(THD* thd)
order to be able to read exactly what is necessary.
*/
- DBUG_PRINT("info",("binlog base64 decoded_len=%d, bytes_decoded=%d",
- decoded_len, bytes_decoded));
+ DBUG_PRINT("info",("binlog base64 decoded_len: %lu bytes_decoded: %d",
+ (ulong) decoded_len, bytes_decoded));
/*
Now we start to read events of the buffer, until there are no
@@ -151,20 +152,21 @@ void mysql_client_binlog_statement(THD* thd)
bufptr += event_len;
DBUG_PRINT("info",("ev->get_type_code()=%d", ev->get_type_code()));
- DBUG_PRINT("info",("bufptr+EVENT_TYPE_OFFSET=0x%lx",
- bufptr+EVENT_TYPE_OFFSET));
#ifndef HAVE_purify
/*
This debug printout should not be used for valgrind builds
since it will read from unassigned memory.
*/
- DBUG_PRINT("info", ("bytes_decoded=%d; bufptr=0x%lx; buf[EVENT_LEN_OFFSET]=%u",
- bytes_decoded, bufptr, uint4korr(bufptr+EVENT_LEN_OFFSET)));
+ DBUG_PRINT("info",("bufptr+EVENT_TYPE_OFFSET: 0x%lx",
+ (long) (bufptr+EVENT_TYPE_OFFSET)));
+ DBUG_PRINT("info", ("bytes_decoded: %d bufptr: 0x%lx buf[EVENT_LEN_OFFSET]: %lu",
+ bytes_decoded, (long) bufptr,
+ (ulong) uint4korr(bufptr+EVENT_LEN_OFFSET)));
#endif
ev->thd= thd;
if (int err= ev->exec_event(thd->rli_fake))
{
- DBUG_PRINT("info", ("exec_event() - error=%d", error));
+ DBUG_PRINT("error", ("exec_event() returned: %d", err));
/*
TODO: Maybe a better error message since the BINLOG statement
now contains several events.
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index ee3b8aa79fe..3362ec76fc2 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -523,7 +523,8 @@ void Query_cache_query::init_n_lock()
my_rwlock_init(&lock, NULL);
lock_writing();
DBUG_PRINT("qcache", ("inited & locked query for block 0x%lx",
- ((byte*) this)-ALIGN_SIZE(sizeof(Query_cache_block))));
+ (long) (((byte*) this) -
+ ALIGN_SIZE(sizeof(Query_cache_block)))));
DBUG_VOID_RETURN;
}
@@ -532,7 +533,8 @@ void Query_cache_query::unlock_n_destroy()
{
DBUG_ENTER("Query_cache_query::unlock_n_destroy");
DBUG_PRINT("qcache", ("destroyed & unlocked query for block 0x%lx",
- ((byte*)this)-ALIGN_SIZE(sizeof(Query_cache_block))));
+ (long) (((byte*) this) -
+ ALIGN_SIZE(sizeof(Query_cache_block)))));
/*
The following call is not needed on system where one can destroy an
active semaphore
@@ -698,6 +700,7 @@ void query_cache_abort(NET *net)
void query_cache_end_of_result(THD *thd)
{
+ Query_cache_block *query_block;
DBUG_ENTER("query_cache_end_of_result");
/* See the comment on double-check locking usage above. */
@@ -713,13 +716,9 @@ void query_cache_end_of_result(THD *thd)
if (unlikely(query_cache.query_cache_size == 0 ||
query_cache.flush_in_progress))
- {
- STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
- DBUG_VOID_RETURN;
- }
+ goto end;
- Query_cache_block *query_block= ((Query_cache_block*)
- thd->net.query_cache_query);
+ query_block= ((Query_cache_block*) thd->net.query_cache_query);
if (query_block)
{
DUMP(&query_cache);
@@ -738,27 +737,21 @@ void query_cache_end_of_result(THD *thd)
header->query()));
query_cache.wreck(__LINE__, "");
- STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
-
- DBUG_VOID_RETURN;
+ BLOCK_UNLOCK_WR(query_block);
+ goto end;
}
#endif
header->found_rows(current_thd->limit_found_rows);
header->result()->type= Query_cache_block::RESULT;
header->writer(0);
thd->net.query_cache_query= 0;
+ BLOCK_UNLOCK_WR(query_block);
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
- STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
-
- BLOCK_UNLOCK_WR(query_block);
- }
- else
- {
- // Cache was flushed or resized and query was deleted => do nothing
- STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
}
+end:
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
DBUG_VOID_RETURN;
}
@@ -875,8 +868,8 @@ sql mode: 0x%lx, sort len: %lu, conncat len: %lu",
flags.character_set_client_num,
flags.character_set_results_num,
flags.collation_connection_num,
- flags.limit,
- (ulong)flags.time_zone,
+ (ulong) flags.limit,
+ (ulong) flags.time_zone,
flags.sql_mode,
flags.max_sort_length,
flags.group_concat_max_len));
@@ -1119,8 +1112,8 @@ sql mode: 0x%lx, sort len: %lu, conncat len: %lu",
flags.character_set_client_num,
flags.character_set_results_num,
flags.collation_connection_num,
- flags.limit,
- (ulong)flags.time_zone,
+ (ulong) flags.limit,
+ (ulong) flags.time_zone,
flags.sql_mode,
flags.max_sort_length,
flags.group_concat_max_len));
@@ -1234,9 +1227,9 @@ sql mode: 0x%lx, sort len: %lu, conncat len: %lu",
if (engine_data != table->engine_data())
{
DBUG_PRINT("qcache",
- ("Handler require invalidation queries of %s.%s %lld-%lld",
- table_list.db, table_list.alias,
- engine_data, table->engine_data()));
+ ("Handler require invalidation queries of %s.%s %lu-%lu",
+ table_list.db, table_list.alias,
+ (ulong) engine_data, (ulong) table->engine_data()));
invalidate_table((byte *) table->db(), table->key_length());
}
else
@@ -1257,10 +1250,10 @@ sql mode: 0x%lx, sort len: %lu, conncat len: %lu",
#ifndef EMBEDDED_LIBRARY
do
{
- DBUG_PRINT("qcache", ("Results (len %lu, used %lu, headers %lu)",
+ DBUG_PRINT("qcache", ("Results (len: %lu used: %lu headers: %lu)",
result_block->length, result_block->used,
- result_block->headers_len()+
- ALIGN_SIZE(sizeof(Query_cache_result))));
+ (ulong) (result_block->headers_len()+
+ ALIGN_SIZE(sizeof(Query_cache_result)))));
Query_cache_result *result = result_block->result();
if (net_real_write(&thd->net, result->data(),
@@ -2034,7 +2027,7 @@ Query_cache::append_result_data(Query_cache_block **current_block,
{
DBUG_ENTER("Query_cache::append_result_data");
DBUG_PRINT("qcache", ("append %lu bytes to 0x%lx query",
- data_len, query_block));
+ data_len, (long) query_block));
if (query_block->query()->add(data_len) > query_cache_limit)
{
@@ -2476,11 +2469,11 @@ Query_cache::insert_table(uint key_len, char *key,
table_block->table()->engine_data() != engine_data)
{
DBUG_PRINT("qcache",
- ("Handler require invalidation queries of %s.%s %lld-%lld",
+ ("Handler require invalidation queries of %s.%s %lu-%lu",
table_block->table()->db(),
table_block->table()->table(),
- engine_data,
- table_block->table()->engine_data()));
+ (ulong) engine_data,
+ (ulong) table_block->table()->engine_data()));
/*
as far as we delete all queries with this table, table block will be
deleted, too
@@ -2988,7 +2981,7 @@ static TABLE_COUNTER_TYPE process_and_count_tables(TABLE_LIST *tables_used,
DBUG_PRINT("qcache", ("table: %s db: %s type: %u",
tables_used->table->s->table_name.str,
tables_used->table->s->db.str,
- tables_used->table->s->db_type));
+ tables_used->table->s->db_type->db_type));
if (tables_used->derived)
{
table_count--;
@@ -3043,10 +3036,10 @@ Query_cache::is_cacheable(THD *thd, uint32 query_len, char *query, LEX *lex,
OPTION_TO_QUERY_CACHE))) &&
lex->safe_to_cache_query)
{
- DBUG_PRINT("qcache", ("options %lx %lx, type %u",
- OPTION_TO_QUERY_CACHE,
- lex->select_lex.options,
- (int) thd->variables.query_cache_type));
+ DBUG_PRINT("qcache", ("options: %lx %lx type: %u",
+ (long) OPTION_TO_QUERY_CACHE,
+ (long) lex->select_lex.options,
+ (int) thd->variables.query_cache_type));
if (!(table_count= process_and_count_tables(tables_used, tables_type)))
DBUG_RETURN(0);
@@ -3062,10 +3055,10 @@ Query_cache::is_cacheable(THD *thd, uint32 query_len, char *query, LEX *lex,
}
DBUG_PRINT("qcache",
- ("not interesting query: %d or not cacheable, options %lx %lx, type %u",
+ ("not interesting query: %d or not cacheable, options %lx %lx type: %u",
(int) lex->sql_command,
- OPTION_TO_QUERY_CACHE,
- lex->select_lex.options,
+ (long) OPTION_TO_QUERY_CACHE,
+ (long) lex->select_lex.options,
(int) thd->variables.query_cache_type));
DBUG_RETURN(0);
}
@@ -3656,7 +3649,8 @@ void Query_cache::queries_dump()
DBUG_PRINT("qcache", ("F:%u C:%u L:%lu T:'%s' (%u) '%s' '%s'",
flags.client_long_flag,
flags.character_set_client_num,
- (ulong)flags.limit, flags.time_zone->get_name(),
+ (ulong)flags.limit,
+ flags.time_zone->get_name()->ptr(),
len, str, strend(str)+1));
DBUG_PRINT("qcache", ("-b- 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx", (ulong) block,
(ulong) block->next, (ulong) block->prev,
@@ -3765,7 +3759,7 @@ my_bool Query_cache::check_integrity(bool locked)
{
DBUG_PRINT("error",
("block 0x%lx do not aligned by %d", (ulong) block,
- ALIGN_SIZE(1)));
+ (int) ALIGN_SIZE(1)));
result = 1;
}
// Check memory allocation
@@ -3876,9 +3870,8 @@ my_bool Query_cache::check_integrity(bool locked)
break;
}
default:
- DBUG_PRINT("error",
- ("block 0x%lx have incorrect type %u",
- block, block->type));
+ DBUG_PRINT("error", ("block 0x%lx have incorrect type %u",
+ (long) block, block->type));
result = 1;
}
@@ -3976,8 +3969,8 @@ my_bool Query_cache::check_integrity(bool locked)
} while (block != bins[i].free_blocks);
if (count != bins[i].number)
{
- DBUG_PRINT("error", ("bin[%d].number is %d, but bin have %d blocks",
- bins[i].number, count));
+ DBUG_PRINT("error", ("bins[%d].number = %d, but bin have %d blocks",
+ i, bins[i].number, count));
result = 1;
}
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 20acb28bc77..07510c1fbb0 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -551,7 +551,7 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
void THD::awake(THD::killed_state state_to_set)
{
DBUG_ENTER("THD::awake");
- DBUG_PRINT("enter", ("this=0x%lx", this));
+ DBUG_PRINT("enter", ("this: 0x%lx", (long) this));
THD_CHECK_SENTRY(this);
safe_mutex_assert_owner(&LOCK_delete);
@@ -799,7 +799,7 @@ void THD::add_changed_table(const char *key, long key_length)
{
list_include(prev_changed, curr, changed_table_dup(key, key_length));
DBUG_PRINT("info",
- ("key_length %u %u", key_length, (*prev_changed)->key_length));
+ ("key_length %ld %u", key_length, (*prev_changed)->key_length));
DBUG_VOID_RETURN;
}
else if (cmp == 0)
@@ -809,7 +809,7 @@ void THD::add_changed_table(const char *key, long key_length)
{
list_include(prev_changed, curr, changed_table_dup(key, key_length));
DBUG_PRINT("info",
- ("key_length %u %u", key_length,
+ ("key_length %ld %u", key_length,
(*prev_changed)->key_length));
DBUG_VOID_RETURN;
}
@@ -821,7 +821,7 @@ void THD::add_changed_table(const char *key, long key_length)
}
}
*prev_changed = changed_table_dup(key, key_length);
- DBUG_PRINT("info", ("key_length %u %u", key_length,
+ DBUG_PRINT("info", ("key_length %ld %u", key_length,
(*prev_changed)->key_length));
DBUG_VOID_RETURN;
}
@@ -2518,7 +2518,9 @@ my_size_t THD::max_row_length_blob(TABLE *table, const byte *data) const
for (uint *ptr= beg ; ptr != end ; ++ptr)
{
Field_blob* const blob= (Field_blob*) table->field[*ptr];
- length+= blob->get_length((const char *) (data + blob->offset())) + 2;
+ length+= blob->get_length((const char*) (data +
+ blob->offset(table->record[0]))) +
+ HA_KEY_BLOB_LENGTH;
}
return length;
@@ -2621,9 +2623,9 @@ namespace {
return m_memory != 0;
}
- byte *slot(int const s)
+ byte *slot(uint s)
{
- DBUG_ASSERT(0 <= s && s < sizeof(m_ptr)/sizeof(*m_ptr));
+ DBUG_ASSERT(s < sizeof(m_ptr)/sizeof(*m_ptr));
DBUG_ASSERT(m_ptr[s] != 0);
DBUG_ASSERT(m_alloc_checked == true);
return m_ptr[s];
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 2cf7de5ee9e..218c56959a3 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -425,6 +425,12 @@ public:
{ return strdup_root(mem_root,str); }
inline char *strmake(const char *str, uint size)
{ return strmake_root(mem_root,str,size); }
+ inline bool LEX_STRING_make(LEX_STRING *lex_str, const char *str, uint size)
+ {
+ return ((lex_str->str=
+ strmake_root(mem_root, str, (lex_str->length= size)))) == 0;
+ }
+
inline char *memdup(const char *str, uint size)
{ return memdup_root(mem_root,str,size); }
inline char *memdup_w_gap(const char *str, uint size, uint gap)
@@ -838,6 +844,12 @@ public:
struct st_mysql_data **data_tail;
void clear_data_list();
struct st_mysql_data *alloc_new_dataset();
+ /*
+ In embedded server it points to the statement that is processed
+ in the current query. We store some results directly in statement
+ fields then.
+ */
+ struct st_mysql_stmt *current_stmt;
#endif
NET net; // client connection descriptor
MEM_ROOT warn_root; // For warnings and errors
@@ -1628,8 +1640,7 @@ public:
return TRUE;
}
*p_db= strmake(db, db_length);
- if (p_db_length)
- *p_db_length= db_length;
+ *p_db_length= db_length;
return FALSE;
}
};
@@ -2065,7 +2076,7 @@ public:
inline bool unique_add(void *ptr)
{
DBUG_ENTER("unique_add");
- DBUG_PRINT("info", ("tree %u - %u", tree.elements_in_tree, max_elements));
+ DBUG_PRINT("info", ("tree %u - %lu", tree.elements_in_tree, max_elements));
if (tree.elements_in_tree > max_elements && flush())
DBUG_RETURN(1);
DBUG_RETURN(!tree_insert(&tree, ptr, 0, tree.custom_arg));
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 37096fd897e..0c154069bd6 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1302,8 +1302,8 @@ err:
bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
{
- int path_length, db_length;
- char *db_name;
+ int path_length;
+ LEX_STRING db_name;
bool system_db= 0;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong db_access;
@@ -1323,25 +1323,26 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
/* Called from SP to restore the original database, which was NULL */
DBUG_ASSERT(no_access_check);
system_db= 1;
- db_name= NULL;
- db_length= 0;
+ db_name.str= NULL;
+ db_name.length= 0;
goto end;
}
/*
Now we need to make a copy because check_db_name requires a
non-constant argument. TODO: fix check_db_name.
*/
- if ((db_name= my_strdup(name, MYF(MY_WME))) == NULL)
+ if ((db_name.str= my_strdup(name, MYF(MY_WME))) == NULL)
DBUG_RETURN(1); /* the error is set */
- db_length= strlen(db_name);
- if (check_db_name(db_name))
+ db_name.length= strlen(db_name.str);
+ if (check_db_name(&db_name))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), db_name);
- my_free(db_name, MYF(0));
+ my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str);
+ my_free(db_name.str, MYF(0));
DBUG_RETURN(1);
}
- DBUG_PRINT("info",("Use database: %s", db_name));
- if (!my_strcasecmp(system_charset_info, db_name, information_schema_name.str))
+ DBUG_PRINT("info",("Use database: %s", db_name.str));
+ if (!my_strcasecmp(system_charset_info, db_name.str,
+ information_schema_name.str))
{
system_db= 1;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -1356,34 +1357,35 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
if (test_all_bits(sctx->master_access, DB_ACLS))
db_access=DB_ACLS;
else
- db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name, 0) |
+ db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user,
+ db_name.str, 0) |
sctx->master_access);
if (!(db_access & DB_ACLS) && (!grant_option ||
- check_grant_db(thd,db_name)))
+ check_grant_db(thd, db_name.str)))
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user,
sctx->priv_host,
- db_name);
+ db_name.str);
general_log_print(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR),
- sctx->priv_user, sctx->priv_host, db_name);
- my_free(db_name,MYF(0));
+ sctx->priv_user, sctx->priv_host, db_name.str);
+ my_free(db_name.str, MYF(0));
DBUG_RETURN(1);
}
}
#endif
- if (check_db_dir_existence(db_name))
+ if (check_db_dir_existence(db_name.str))
{
- my_error(ER_BAD_DB_ERROR, MYF(0), db_name);
- my_free(db_name, MYF(0));
+ my_error(ER_BAD_DB_ERROR, MYF(0), db_name.str);
+ my_free(db_name.str, MYF(0));
DBUG_RETURN(1);
}
end:
x_free(thd->db);
- DBUG_ASSERT(db_name == NULL || db_name[0] != '\0');
- thd->reset_db(db_name, db_length); // THD::~THD will free this
+ DBUG_ASSERT(db_name.str == NULL || db_name.str[0] != '\0');
+ thd->reset_db(db_name.str, db_name.length); // THD::~THD will free this
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!no_access_check)
sctx->db_access= db_access;
@@ -1397,7 +1399,7 @@ end:
{
HA_CREATE_INFO create;
- load_db_opt_by_name(thd, db_name, &create);
+ load_db_opt_by_name(thd, db_name.str, &create);
thd->db_charset= create.default_table_charset ?
create.default_table_charset :
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index a0cd419e6c6..5da2a7660a4 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -354,7 +354,7 @@ cleanup:
{
thd->row_count_func= deleted;
send_ok(thd,deleted);
- DBUG_PRINT("info",("%d records deleted",deleted));
+ DBUG_PRINT("info",("%ld records deleted",(long) deleted));
}
DBUG_RETURN(error >= 0 || thd->net.report_error);
}
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index a6ab100cad4..5951acdcc40 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -367,9 +367,9 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
strlen(tables->alias) + 1)))
{
table= hash_tables->table;
- DBUG_PRINT("info-in-hash",("'%s'.'%s' as '%s' tab %p",
+ DBUG_PRINT("info-in-hash",("'%s'.'%s' as '%s' table: 0x%lx",
hash_tables->db, hash_tables->table_name,
- hash_tables->alias, table));
+ hash_tables->alias, (long) table));
if (!table)
{
/*
@@ -633,7 +633,8 @@ int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags,
TABLE **table_ptr;
bool did_lock= FALSE;
DBUG_ENTER("mysql_ha_flush");
- DBUG_PRINT("enter", ("tables: %p mode_flags: 0x%02x", tables, mode_flags));
+ DBUG_PRINT("enter", ("tables: 0x%lx mode_flags: 0x%02x",
+ (long) tables, mode_flags));
if (tables)
{
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index c35ef4079d3..ca40dc9013a 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -164,6 +164,7 @@ void lex_start(THD *thd, const uchar *buf, uint length)
lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc;
lex->select_lex.group_list.empty();
lex->select_lex.order_list.empty();
+ lex->select_lex.udf_list.empty();
lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
lex->sql_command= SQLCOM_END;
lex->duplicates= DUP_ERROR;
@@ -176,7 +177,8 @@ void lex_start(THD *thd, const uchar *buf, uint length)
lex->reset_query_tables_list(FALSE);
lex->expr_allows_subselect= TRUE;
- lex->name= 0;
+ lex->name.str= 0;
+ lex->name.length= 0;
lex->event_parse_data= NULL;
lex->nest_level=0 ;
@@ -1174,6 +1176,7 @@ void st_select_lex::init_select()
braces= 0;
when_list.empty();
expr_list.empty();
+ udf_list.empty();
interval_list.empty();
use_index.empty();
ftfunc_list_alloc.empty();
@@ -1187,7 +1190,7 @@ void st_select_lex::init_select()
select_limit= 0; /* denotes the default limit = HA_POS_ERROR */
offset_limit= 0; /* denotes the default offset = 0 */
with_sum_func= 0;
-
+ is_correlated= 0;
}
/*
@@ -1381,6 +1384,8 @@ void st_select_lex::mark_as_dependent(SELECT_LEX *last)
SELECT_LEX_UNIT *munit= s->master_unit();
munit->uncacheable|= UNCACHEABLE_DEPENDENT;
}
+ is_correlated= TRUE;
+ this->master_unit()->item->is_correlated= TRUE;
}
bool st_select_lex_node::set_braces(bool value) { return 1; }
@@ -1443,7 +1448,7 @@ bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc)
bool st_select_lex::add_item_to_list(THD *thd, Item *item)
{
DBUG_ENTER("st_select_lex::add_item_to_list");
- DBUG_PRINT("info", ("Item: %p", item));
+ DBUG_PRINT("info", ("Item: 0x%lx", (long) item));
DBUG_RETURN(item_list.push_back(item));
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 7e09675cb0a..dd00018f5f8 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -496,7 +496,7 @@ public:
void set_thd(THD *thd_arg) { thd= thd_arg; }
friend void lex_start(THD *thd, const uchar *buf, uint length);
- friend int subselect_union_engine::exec();
+ friend int subselect_union_engine::exec(bool);
List<Item> *get_unit_column_types();
};
@@ -588,6 +588,8 @@ public:
query processing end even if we use temporary table
*/
bool subquery_in_having;
+ /* TRUE <=> this SELECT is correlated w.r.t. some ancestor select */
+ bool is_correlated;
/*
This variable is required to ensure proper work of subqueries and
stored procedures. Generally, one should use the states of
@@ -607,6 +609,8 @@ public:
/* exclude this select from check of unique_table() */
bool exclude_from_table_unique_test;
+ List<udf_func> udf_list; /* udf function calls stack */
+
void init_query();
void init_select();
st_select_lex_unit* master_unit();
@@ -908,7 +912,8 @@ typedef struct st_lex : public Query_tables_list
/* The values of tok_start/tok_end as they were one call of MYSQLlex before */
const uchar *tok_start_prev, *tok_end_prev;
- char *length,*dec,*change,*name;
+ char *length,*dec,*change;
+ LEX_STRING name;
Table_ident *like_name;
char *help_arg;
char *backup_dir; /* For RESTORE/BACKUP */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 9233ccd747e..c188329b70a 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -390,9 +390,9 @@ int check_user(THD *thd, enum enum_server_command command,
NO_ACCESS)) // authentication is OK
{
DBUG_PRINT("info",
- ("Capabilities: %lx packet_length: %ld Host: '%s' "
+ ("Capabilities: %lu packet_length: %ld Host: '%s' "
"Login user: '%s' Priv_user: '%s' Using password: %s "
- "Access: %u db: '%s'",
+ "Access: %lu db: '%s'",
thd->client_capabilities,
thd->max_client_packet_length,
thd->main_security_ctx.host_or_ip,
@@ -998,7 +998,7 @@ static int check_connection(THD *thd)
if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
thd->variables.sql_mode|= MODE_IGNORE_SPACE;
#ifdef HAVE_OPENSSL
- DBUG_PRINT("info", ("client capabilities: %d", thd->client_capabilities));
+ DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
if (thd->client_capabilities & CLIENT_SSL)
{
/* Do the SSL layering. */
@@ -1051,11 +1051,14 @@ static int check_connection(THD *thd)
Old clients send null-terminated string as password; new clients send
the size (1 byte) + string (not null-terminated). Hence in case of empty
password both send '\0'.
+
+ This strlen() can't be easily deleted without changing protocol.
*/
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
*passwd++ : strlen(passwd);
db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
db + passwd_len + 1 : 0;
+ /* strlen() can't be easily deleted without changing protocol */
uint db_len= db ? strlen(db) : 0;
if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
@@ -1154,7 +1157,7 @@ pthread_handler_t handle_one_connection(void *arg)
of handle_one_connection, which is thd. We need to know the
start of the stack so that we could check for stack overruns.
*/
- DBUG_PRINT("info", ("handle_one_connection called by thread %d\n",
+ DBUG_PRINT("info", ("handle_one_connection called by thread %lu\n",
thd->thread_id));
/* now that we've called my_thread_init(), it is safe to call DBUG_* */
@@ -1317,28 +1320,31 @@ pthread_handler_t handle_bootstrap(void *arg)
thd->init_for_queries();
while (fgets(buff, thd->net.max_packet, file))
{
- ulong length= (ulong) strlen(buff);
- while (buff[length-1] != '\n' && !feof(file))
- {
- /*
- We got only a part of the current string. Will try to increase
- net buffer then read the rest of the current string.
- */
- if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
- {
- net_send_error(thd, ER_NET_PACKET_TOO_LARGE, NullS);
- thd->fatal_error();
- break;
- }
- buff= (char*) thd->net.buff;
- fgets(buff + length, thd->net.max_packet - length, file);
- length+= (ulong) strlen(buff + length);
- }
- if (thd->is_fatal_error)
- break;
+ /* strlen() can't be deleted because fgets() doesn't return length */
+ ulong length= (ulong) strlen(buff);
+ while (buff[length-1] != '\n' && !feof(file))
+ {
+ /*
+ We got only a part of the current string. Will try to increase
+ net buffer then read the rest of the current string.
+ */
+ /* purecov: begin tested */
+ if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
+ {
+ net_send_error(thd, ER_NET_PACKET_TOO_LARGE, NullS);
+ thd->fatal_error();
+ break;
+ }
+ buff= (char*) thd->net.buff;
+ fgets(buff + length, thd->net.max_packet - length, file);
+ length+= (ulong) strlen(buff + length);
+ /* purecov: end */
+ }
+ if (thd->is_fatal_error)
+ break; /* purecov: inspected */
while (length && (my_isspace(thd->charset(), buff[length-1]) ||
- buff[length-1] == ';'))
+ buff[length-1] == ';'))
length--;
buff[length]=0;
thd->query_length=length;
@@ -1423,24 +1429,30 @@ void cleanup_items(Item *item)
*/
static
-int mysql_table_dump(THD* thd, char* db, char* tbl_name)
+int mysql_table_dump(THD *thd, LEX_STRING *db, char *tbl_name)
{
TABLE* table;
TABLE_LIST* table_list;
int error = 0;
DBUG_ENTER("mysql_table_dump");
- db = (db && db[0]) ? db : thd->db;
+ if (db->length == 0)
+ {
+ db->str= thd->db; /* purecov: inspected */
+ db->length= thd->db_length; /* purecov: inspected */
+ }
if (!(table_list = (TABLE_LIST*) thd->calloc(sizeof(TABLE_LIST))))
DBUG_RETURN(1); // out of memory
- table_list->db= db;
+ table_list->db= db->str;
table_list->table_name= table_list->alias= tbl_name;
table_list->lock_type= TL_READ_NO_INSERT;
table_list->prev_global= &table_list; // can be removed after merge with 4.1
- if (!db || check_db_name(db))
+ if (check_db_name(db))
{
- my_error(ER_WRONG_DB_NAME ,MYF(0), db ? db : "NULL");
+ /* purecov: begin inspected */
+ my_error(ER_WRONG_DB_NAME ,MYF(0), db->str ? db->str : "NULL");
goto err;
+ /* purecov: end */
}
if (lower_case_table_names)
my_casedn_str(files_charset_info, tbl_name);
@@ -1600,7 +1612,7 @@ bool do_command(THD *thd)
command= COM_END; // Wrong command
DBUG_PRINT("info",("Command on %s = %d (%s)",
vio_description(net->vio), command,
- command_name[command]));
+ command_name[command].str));
}
net->read_timeout=old_timeout; // restore it
/*
@@ -1669,7 +1681,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
statistic_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB],
&LOCK_status);
thd->convert_string(&tmp, system_charset_info,
- packet, strlen(packet), thd->charset());
+ packet, packet_length-1, thd->charset());
if (!mysql_change_db(thd, tmp.str, FALSE))
{
general_log_print(thd, command, "%s",thd->db);
@@ -1687,7 +1699,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
case COM_TABLE_DUMP:
{
- char *db, *tbl_name;
+ char *tbl_name;
+ LEX_STRING db;
uint db_len= *(uchar*) packet;
if (db_len >= packet_length || db_len > NAME_LEN)
{
@@ -1703,34 +1716,41 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
statistic_increment(thd->status_var.com_other, &LOCK_status);
thd->enable_slow_log= opt_log_slow_admin_statements;
- db= thd->alloc(db_len + tbl_len + 2);
- if (!db)
+ db.str= thd->alloc(db_len + tbl_len + 2);
+ db.length= db_len;
+ if (!db.str)
{
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
break;
}
- tbl_name= strmake(db, packet + 1, db_len)+1;
+ tbl_name= strmake(db.str, packet + 1, db_len)+1;
strmake(tbl_name, packet + db_len + 2, tbl_len);
- mysql_table_dump(thd, db, tbl_name);
+ mysql_table_dump(thd, &db, tbl_name);
break;
}
case COM_CHANGE_USER:
{
+ statistic_increment(thd->status_var.com_other, &LOCK_status);
+ char *user= (char*) packet, *packet_end= packet+ packet_length;
+ char *passwd= strend(user)+1;
+
thd->change_user();
thd->clear_error(); // if errors from rollback
- statistic_increment(thd->status_var.com_other, &LOCK_status);
- char *user= (char*) packet;
- char *passwd= strend(user)+1;
/*
Old clients send null-terminated string ('\0' for empty string) for
password. New clients send the size (1 byte) + string (not null
terminated, so also '\0' for empty string).
*/
- char db_buff[NAME_LEN+1]; // buffer to store db in utf8
+ char db_buff[NAME_LEN+1]; // buffer to store db in utf8
char *db= passwd;
- uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
- *passwd++ : strlen(passwd);
+ char *save_db;
+ uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ *passwd++ : strlen(passwd));
+ uint dummy_errors, save_db_length, db_length, res;
+ Security_context save_security_ctx= *thd->security_ctx;
+ USER_CONN *save_user_connect;
+
db+= passwd_len + 1;
#ifndef EMBEDDED_LIBRARY
/* Small check for incoming packet */
@@ -1741,17 +1761,22 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
#endif
/* Convert database name to utf8 */
- uint dummy_errors;
+ /*
+ Handle problem with old bug in client protocol where db had an extra
+ \0
+ */
+ db_length= (packet_end - db);
+ if (db_length > 0 && db[db_length-1] == 0)
+ db_length--;
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
- system_charset_info, db, strlen(db),
+ system_charset_info, db, db_length,
thd->charset(), &dummy_errors)]= 0;
db= db_buff;
/* Save user and privileges */
- uint save_db_length= thd->db_length;
- char *save_db= thd->db;
- Security_context save_security_ctx= *thd->security_ctx;
- USER_CONN *save_user_connect= thd->user_connect;
+ save_db_length= thd->db_length;
+ save_db= thd->db;
+ save_user_connect= thd->user_connect;
if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
{
@@ -1762,7 +1787,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* Clear variables that are allocated */
thd->user_connect= 0;
- int res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
+ res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
if (res)
{
@@ -1822,7 +1847,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (alloc_query(thd, packet, packet_length))
break; // fatal error is set
char *packet_end= thd->query + thd->query_length;
- general_log_print(thd, command, "%.*b", thd->query_length, thd->query);
+ /* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */
+ const char *format= "%.*b";
+ general_log_print(thd, command, format, thd->query_length, thd->query);
DBUG_PRINT("query",("%-.4096s",thd->query));
if (!(specialflag & SPECIAL_NO_PRIOR))
@@ -1872,29 +1899,31 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break;
#else
{
- char *fields, *pend;
+ char *fields, *packet_end= packet + packet_length - 1, *arg_end;
/* Locked closure of all tables */
TABLE_LIST *locked_tables= NULL;
TABLE_LIST table_list;
LEX_STRING conv_name;
/* Saved variable value */
my_bool old_innodb_table_locks= thd->variables.innodb_table_locks;
-
+ uint dummy;
/* used as fields initializator */
lex_start(thd, 0, 0);
-
statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS],
&LOCK_status);
bzero((char*) &table_list,sizeof(table_list));
- if (thd->copy_db_to(&table_list.db, 0))
+ if (thd->copy_db_to(&table_list.db, &dummy))
break;
- pend= strend(packet);
+ /*
+ We have name + wildcard in packet, separated by endzero
+ */
+ arg_end= strend(packet);
thd->convert_string(&conv_name, system_charset_info,
- packet, (uint) (pend-packet), thd->charset());
+ packet, (uint) (arg_end - packet), thd->charset());
table_list.alias= table_list.table_name= conv_name.str;
- packet= pend+1;
+ packet= arg_end + 1;
if (!my_strcasecmp(system_charset_info, table_list.db,
information_schema_name.str))
@@ -1904,7 +1933,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
table_list.schema_table= schema_table;
}
- thd->query_length= strlen(packet); // for simplicity: don't optimize
+ thd->query_length= (uint) (packet_end - packet); // Don't count end \0
if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1)))
break;
general_log_print(thd, command, "%s %s", table_list.table_name, fields);
@@ -1940,24 +1969,27 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
error=TRUE; // End server
break;
+#ifdef REMOVED
case COM_CREATE_DB: // QQ: To be removed
{
- char *db=thd->strdup(packet), *alias;
+ LEX_STRING db, alias;
HA_CREATE_INFO create_info;
statistic_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB],
&LOCK_status);
- // null test to handle EOM
- if (!db || !(alias= thd->strdup(db)) || check_db_name(db))
+ if (thd->LEX_STRING_make(&db, packet, packet_length -1) ||
+ thd->LEX_STRING_make(&alias, db.str, db.length) ||
+ check_db_name(&db))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL");
+ my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
break;
}
- if (check_access(thd,CREATE_ACL,db,0,1,0,is_schema_db(db)))
+ if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0,
+ is_schema_db(db.str)))
break;
general_log_print(thd, command, packet);
bzero(&create_info, sizeof(create_info));
- mysql_create_db(thd, (lower_case_table_names == 2 ? alias : db),
+ mysql_create_db(thd, (lower_case_table_names == 2 ? alias.str : db.str),
&create_info, 0);
break;
}
@@ -1965,14 +1997,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
statistic_increment(thd->status_var.com_stat[SQLCOM_DROP_DB],
&LOCK_status);
- char *db=thd->strdup(packet);
- /* null test to handle EOM */
- if (!db || check_db_name(db))
+ LEX_STRING db;
+
+ if (thd->LEX_STRING_make(&db, packet, packet_length - 1) ||
+ check_db_name(&db))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL");
+ my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
break;
}
- if (check_access(thd,DROP_ACL,db,0,1,0,is_schema_db(db)))
+ if (check_access(thd, DROP_ACL, db.str, 0, 1, 0, is_schema_db(db.str)))
break;
if (thd->locked_tables || thd->active_transaction())
{
@@ -1980,10 +2013,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
break;
}
- general_log_print(thd, command, db);
- mysql_rm_db(thd, db, 0, 0);
+ general_log_print(thd, command, db.str);
+ mysql_rm_db(thd, db.str, 0, 0);
break;
}
+#endif
#ifndef EMBEDDED_LIBRARY
case COM_BINLOG_DUMP:
{
@@ -2065,37 +2099,47 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
case COM_STATISTICS:
{
- general_log_print(thd, command, NullS);
- statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS],
- &LOCK_status);
+ STATUS_VAR current_global_status_var;
+ ulong uptime;
+ uint length;
#ifndef EMBEDDED_LIBRARY
- char buff[200];
+ char buff[250];
+ uint buff_len= sizeof(buff);
#else
char *buff= thd->net.last_error;
+ uint buff_len= sizeof(thd->net.last_error);
#endif
- STATUS_VAR current_global_status_var;
+ general_log_print(thd, command, NullS);
+ statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS],
+ &LOCK_status);
calc_sum_of_all_status(&current_global_status_var);
-
- ulong uptime = (ulong) (thd->start_time - start_time);
- sprintf((char*) buff,
- "Uptime: %lu Threads: %d Questions: %lu Slow queries: %lu Opens: %lu Flush tables: %lu Open tables: %u Queries per second avg: %.3f",
- uptime,
- (int) thread_count, (ulong) thd->query_id,
- current_global_status_var.long_query_count,
- current_global_status_var.opened_tables, refresh_version,
- cached_open_tables(),
- (uptime ? (ulonglong2double(thd->query_id) / (double) uptime) :
- (double) 0));
+ uptime= (ulong) (thd->start_time - start_time);
+ length= my_snprintf((char*) buff, buff_len - 1,
+ "Uptime: %lu Threads: %d Questions: %lu "
+ "Slow queries: %lu Opens: %lu Flush tables: %lu "
+ "Open tables: %u Queries per second avg: %.3f",
+ uptime,
+ (int) thread_count, (ulong) thd->query_id,
+ current_global_status_var.long_query_count,
+ current_global_status_var.opened_tables,
+ refresh_version,
+ cached_open_tables(),
+ (uptime ? (ulonglong2double(thd->query_id) /
+ (double) uptime) : (double) 0));
#ifdef SAFEMALLOC
if (sf_malloc_cur_memory) // Using SAFEMALLOC
- sprintf(strend(buff), " Memory in use: %ldK Max memory used: %ldK",
- (sf_malloc_cur_memory+1023L)/1024L,
- (sf_malloc_max_memory+1023L)/1024L);
+ {
+ char *end= buff + length;
+ length+= my_snprintf(end, buff_len - length - 1,
+ end," Memory in use: %ldK Max memory used: %ldK",
+ (sf_malloc_cur_memory+1023L)/1024L,
+ (sf_malloc_max_memory+1023L)/1024L);
+ }
#endif
#ifndef EMBEDDED_LIBRARY
- VOID(my_net_write(net, buff,(uint) strlen(buff)));
- VOID(net_flush(net));
+ VOID(my_net_write(net, buff, length));
+ VOID(net_flush(net));
#endif
break;
}
@@ -2292,26 +2336,28 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
DBUG_RETURN(1);
#else
{
- char *db;
+ LEX_STRING db;
+ uint dummy;
if (lex->select_lex.db == NULL &&
- thd->copy_db_to(&lex->select_lex.db, 0))
+ thd->copy_db_to(&lex->select_lex.db, &dummy))
{
DBUG_RETURN(1);
}
- db= lex->select_lex.db;
- if (check_db_name(db))
+ db.str= lex->select_lex.db;
+ db.length= strlen(db.str);
+ if (check_db_name(&db))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), db);
+ my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
DBUG_RETURN(1);
}
- if (check_access(thd, SELECT_ACL, db, &thd->col_access, 0, 0,
- is_schema_db(db)))
+ if (check_access(thd, SELECT_ACL, db.str, &thd->col_access, 0, 0,
+ is_schema_db(db.str)))
DBUG_RETURN(1); /* purecov: inspected */
- if (!thd->col_access && check_grant_db(thd,db))
+ if (!thd->col_access && check_grant_db(thd, db.str))
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
thd->security_ctx->priv_user, thd->security_ctx->priv_host,
- db);
+ db.str);
DBUG_RETURN(1);
}
break;
@@ -2868,11 +2914,6 @@ mysql_execute_command(THD *thd)
if (check_grant(thd, CREATE_ACL, all_tables, 0, 1, 0))
goto error;
}
- if (strlen(first_table->table_name) > NAME_LEN)
- {
- my_error(ER_WRONG_TABLE_NAME, MYF(0), first_table->table_name);
- break;
- }
pthread_mutex_lock(&LOCK_active_mi);
/*
fetch_master_table will send the error to the client on failure.
@@ -3102,11 +3143,6 @@ end_with_restore_list:
if (lex->alter_info.flags & ALTER_DROP_PARTITION)
priv_needed|= DROP_ACL;
- if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN))
- {
- my_error(ER_WRONG_TABLE_NAME, MYF(0), lex->name);
- goto error;
- }
/* Must be set in the parser */
DBUG_ASSERT(select_lex->db);
if (check_access(thd, priv_needed, first_table->db,
@@ -3122,11 +3158,11 @@ end_with_restore_list:
{
if (check_grant(thd, priv_needed, all_tables, 0, UINT_MAX, 0))
goto error;
- if (lex->name && !test_all_bits(priv,INSERT_ACL | CREATE_ACL))
+ if (lex->name.str && !test_all_bits(priv,INSERT_ACL | CREATE_ACL))
{ // Rename of table
TABLE_LIST tmp_table;
bzero((char*) &tmp_table,sizeof(tmp_table));
- tmp_table.table_name=lex->name;
+ tmp_table.table_name= lex->name.str;
tmp_table.db=select_lex->db;
tmp_table.grant.privilege=priv;
if (check_grant(thd, INSERT_ACL | CREATE_ACL, &tmp_table, 0,
@@ -3154,7 +3190,7 @@ end_with_restore_list:
}
thd->enable_slow_log= opt_log_slow_admin_statements;
- res= mysql_alter_table(thd, select_lex->db, lex->name,
+ res= mysql_alter_table(thd, select_lex->db, lex->name.str,
&lex->create_info,
first_table, lex->create_list,
lex->key_list,
@@ -3472,8 +3508,12 @@ end_with_restore_list:
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
thd->lock)
{
+ /* INSERT ... SELECT should invalidate only the very first table */
+ TABLE_LIST *save_table= first_table->next_local;
+ first_table->next_local= 0;
mysql_unlock_tables(thd, thd->lock);
query_cache_invalidate3(thd, first_table, 1);
+ first_table->next_local= save_table;
thd->lock=0;
}
delete result;
@@ -3766,9 +3806,10 @@ end_with_restore_list:
break;
}
char *alias;
- if (!(alias=thd->strdup(lex->name)) || check_db_name(lex->name))
+ if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
+ check_db_name(&lex->name))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
+ my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
break;
}
/*
@@ -3780,17 +3821,18 @@ end_with_restore_list:
*/
#ifdef HAVE_REPLICATION
if (thd->slave_thread &&
- (!rpl_filter->db_ok(lex->name) ||
- !rpl_filter->db_ok_with_wild_table(lex->name)))
+ (!rpl_filter->db_ok(lex->name.str) ||
+ !rpl_filter->db_ok_with_wild_table(lex->name.str)))
{
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
#endif
- if (check_access(thd,CREATE_ACL,lex->name,0,1,0,is_schema_db(lex->name)))
+ if (check_access(thd,CREATE_ACL,lex->name.str, 0, 1, 0,
+ is_schema_db(lex->name.str)))
break;
- res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name),
- &lex->create_info, 0);
+ res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
+ lex->name.str), &lex->create_info, 0);
break;
}
case SQLCOM_DROP_DB:
@@ -3800,9 +3842,9 @@ end_with_restore_list:
res= -1;
break;
}
- if (check_db_name(lex->name))
+ if (check_db_name(&lex->name))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
+ my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
break;
}
/*
@@ -3814,14 +3856,15 @@ end_with_restore_list:
*/
#ifdef HAVE_REPLICATION
if (thd->slave_thread &&
- (!rpl_filter->db_ok(lex->name) ||
- !rpl_filter->db_ok_with_wild_table(lex->name)))
+ (!rpl_filter->db_ok(lex->name.str) ||
+ !rpl_filter->db_ok_with_wild_table(lex->name.str)))
{
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
#endif
- if (check_access(thd,DROP_ACL,lex->name,0,1,0,is_schema_db(lex->name)))
+ if (check_access(thd,DROP_ACL,lex->name.str,0,1,0,
+ is_schema_db(lex->name.str)))
break;
if (thd->locked_tables || thd->active_transaction())
{
@@ -3829,7 +3872,7 @@ end_with_restore_list:
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
- res= mysql_rm_db(thd, lex->name, lex->drop_if_exists, 0);
+ res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
break;
}
case SQLCOM_RENAME_DB:
@@ -3855,6 +3898,11 @@ end_with_restore_list:
break;
}
#endif
+ if (check_db_name(newdb))
+ {
+ my_error(ER_WRONG_DB_NAME, MYF(0), newdb->str);
+ break;
+ }
if (check_access(thd,ALTER_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) ||
check_access(thd,DROP_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) ||
check_access(thd,CREATE_ACL,newdb->str,0,1,0,is_schema_db(newdb->str)))
@@ -3876,11 +3924,10 @@ end_with_restore_list:
}
case SQLCOM_ALTER_DB:
{
- char *db= lex->name;
- DBUG_ASSERT(db); /* Must be set in the parser */
- if (!strip_sp(db) || check_db_name(db))
+ LEX_STRING *db= &lex->name;
+ if (check_db_name(db))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), db);
+ my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
break;
}
/*
@@ -3892,14 +3939,14 @@ end_with_restore_list:
*/
#ifdef HAVE_REPLICATION
if (thd->slave_thread &&
- (!rpl_filter->db_ok(db) ||
- !rpl_filter->db_ok_with_wild_table(db)))
+ (!rpl_filter->db_ok(db->str) ||
+ !rpl_filter->db_ok_with_wild_table(db->str)))
{
my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
break;
}
#endif
- if (check_access(thd, ALTER_ACL, db, 0, 1, 0, is_schema_db(db)))
+ if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0, is_schema_db(db->str)))
break;
if (thd->locked_tables || thd->active_transaction())
{
@@ -3907,21 +3954,22 @@ end_with_restore_list:
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
- res= mysql_alter_db(thd, db, &lex->create_info);
+ res= mysql_alter_db(thd, db->str, &lex->create_info);
break;
}
case SQLCOM_SHOW_CREATE_DB:
{
- if (!strip_sp(lex->name) || check_db_name(lex->name))
+ if (check_db_name(&lex->name))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
+ my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
break;
}
- res=mysqld_show_create_db(thd,lex->name,&lex->create_info);
+ res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
break;
}
case SQLCOM_CREATE_EVENT:
case SQLCOM_ALTER_EVENT:
+ do
{
DBUG_ASSERT(lex->event_parse_data);
if (lex->table_or_sp_used())
@@ -3947,16 +3995,15 @@ end_with_restore_list:
if (!res)
send_ok(thd);
- /* Don't do it, if we are inside a SP */
- if (!thd->spcont)
- {
- delete lex->sphead;
- lex->sphead= NULL;
- }
-
- /* lex->unit.cleanup() is called outside, no need to call it here */
- break;
+ } while (0);
+ /* Don't do it, if we are inside a SP */
+ if (!thd->spcont)
+ {
+ delete lex->sphead;
+ lex->sphead= NULL;
}
+ /* lex->unit.cleanup() is called outside, no need to call it here */
+ break;
case SQLCOM_DROP_EVENT:
case SQLCOM_SHOW_CREATE_EVENT:
{
@@ -6301,7 +6348,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
}
if (table->is_derived_table() == FALSE && table->db.str &&
- check_db_name(table->db.str))
+ check_db_name(&table->db))
{
my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
DBUG_RETURN(0);
@@ -7585,7 +7632,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
#ifdef NOT_NECESSARY_TO_CHECK_CREATE_TABLE_EXIST_WHEN_PREPARING_STATEMENT
/* This code throws an ill error for CREATE TABLE t1 SELECT * FROM t1 */
/*
- Only do the check for PS, becasue we on execute we have to check that
+ Only do the check for PS, because we on execute we have to check that
against the opened tables to ensure we don't use a table that is part
of the view (which can only be done after the table has been opened).
*/
diff --git a/sql/sql_parse.cc.rej b/sql/sql_parse.cc.rej
new file mode 100644
index 00000000000..6e2bd03867d
--- /dev/null
+++ b/sql/sql_parse.cc.rej
@@ -0,0 +1,166 @@
+***************
+*** 67,109 ****
+ static void decrease_user_connections(USER_CONN *uc);
+ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
+ static bool check_multi_update_lock(THD *thd);
+- static void remove_escape(char *name);
+ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
+
+ const char *any_db="*any*"; // Special symbol for check_access
+
+! LEX_STRING command_name[]={
+! (char *)STRING_WITH_LEN("Sleep"),
+! (char *)STRING_WITH_LEN("Quit"),
+! (char *)STRING_WITH_LEN("Init DB"),
+! (char *)STRING_WITH_LEN("Query"),
+! (char *)STRING_WITH_LEN("Field List"),
+! (char *)STRING_WITH_LEN("Create DB"),
+! (char *)STRING_WITH_LEN("Drop DB"),
+! (char *)STRING_WITH_LEN("Refresh"),
+! (char *)STRING_WITH_LEN("Shutdown"),
+! (char *)STRING_WITH_LEN("Statistics"),
+! (char *)STRING_WITH_LEN("Processlist"),
+! (char *)STRING_WITH_LEN("Connect"),
+! (char *)STRING_WITH_LEN("Kill"),
+! (char *)STRING_WITH_LEN("Debug"),
+! (char *)STRING_WITH_LEN("Ping"),
+! (char *)STRING_WITH_LEN("Time"),
+! (char *)STRING_WITH_LEN("Delayed insert"),
+! (char *)STRING_WITH_LEN("Change user"),
+! (char *)STRING_WITH_LEN("Binlog Dump"),
+! (char *)STRING_WITH_LEN("Table Dump"),
+! (char *)STRING_WITH_LEN("Connect Out"),
+! (char *)STRING_WITH_LEN("Register Slave"),
+! (char *)STRING_WITH_LEN("Prepare"),
+! (char *)STRING_WITH_LEN("Execute"),
+! (char *)STRING_WITH_LEN("Long Data"),
+! (char *)STRING_WITH_LEN("Close stmt"),
+! (char *)STRING_WITH_LEN("Reset stmt"),
+! (char *)STRING_WITH_LEN("Set option"),
+! (char *)STRING_WITH_LEN("Fetch"),
+! (char *)STRING_WITH_LEN("Daemon"),
+! (char *)STRING_WITH_LEN("Error") // Last command number
+ };
+
+ const char *xa_state_names[]={
+--- 67,108 ----
+ static void decrease_user_connections(USER_CONN *uc);
+ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
+ static bool check_multi_update_lock(THD *thd);
+ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
+
+ const char *any_db="*any*"; // Special symbol for check_access
+
+! const LEX_STRING command_name[]={
+! C_STRING_WITH_LEN("Sleep"),
+! C_STRING_WITH_LEN("Quit"),
+! C_STRING_WITH_LEN("Init DB"),
+! C_STRING_WITH_LEN("Query"),
+! C_STRING_WITH_LEN("Field List"),
+! C_STRING_WITH_LEN("Create DB"),
+! C_STRING_WITH_LEN("Drop DB"),
+! C_STRING_WITH_LEN("Refresh"),
+! C_STRING_WITH_LEN("Shutdown"),
+! C_STRING_WITH_LEN("Statistics"),
+! C_STRING_WITH_LEN("Processlist"),
+! C_STRING_WITH_LEN("Connect"),
+! C_STRING_WITH_LEN("Kill"),
+! C_STRING_WITH_LEN("Debug"),
+! C_STRING_WITH_LEN("Ping"),
+! C_STRING_WITH_LEN("Time"),
+! C_STRING_WITH_LEN("Delayed insert"),
+! C_STRING_WITH_LEN("Change user"),
+! C_STRING_WITH_LEN("Binlog Dump"),
+! C_STRING_WITH_LEN("Table Dump"),
+! C_STRING_WITH_LEN("Connect Out"),
+! C_STRING_WITH_LEN("Register Slave"),
+! C_STRING_WITH_LEN("Prepare"),
+! C_STRING_WITH_LEN("Execute"),
+! C_STRING_WITH_LEN("Long Data"),
+! C_STRING_WITH_LEN("Close stmt"),
+! C_STRING_WITH_LEN("Reset stmt"),
+! C_STRING_WITH_LEN("Set option"),
+! C_STRING_WITH_LEN("Fetch"),
+! C_STRING_WITH_LEN("Daemon"),
+! C_STRING_WITH_LEN("Error") // Last command number
+ };
+
+ const char *xa_state_names[]={
+***************
+*** 1738,1744 ****
+ password. New clients send the size (1 byte) + string (not null
+ terminated, so also '\0' for empty string).
+ */
+! char db_buff[NAME_LEN+1]; // buffer to store db in utf8
+ char *db= passwd;
+ uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ *passwd++ : strlen(passwd);
+--- 1736,1742 ----
+ password. New clients send the size (1 byte) + string (not null
+ terminated, so also '\0' for empty string).
+ */
+! char db_buff[NAME_LEN+1]; // buffer to store db in utf8
+ char *db= passwd;
+ uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ *passwd++ : strlen(passwd);
+***************
+*** 2315,2321 ****
+ DBUG_RETURN(1);
+ }
+ db= lex->select_lex.db;
+- remove_escape(db); // Fix escaped '_'
+ if (check_db_name(db))
+ {
+ my_error(ER_WRONG_DB_NAME, MYF(0), db);
+--- 2312,2317 ----
+ DBUG_RETURN(1);
+ }
+ db= lex->select_lex.db;
+ if (check_db_name(db))
+ {
+ my_error(ER_WRONG_DB_NAME, MYF(0), db);
+***************
+*** 6310,6345 ****
+ }
+
+
+- /* Fix escaping of _, % and \ in database and table names (for ODBC) */
+-
+- static void remove_escape(char *name)
+- {
+- if (!*name) // For empty DB names
+- return;
+- char *to;
+- #ifdef USE_MB
+- char *strend=name+(uint) strlen(name);
+- #endif
+- for (to=name; *name ; name++)
+- {
+- #ifdef USE_MB
+- int l;
+- if (use_mb(system_charset_info) &&
+- (l = my_ismbchar(system_charset_info, name, strend)))
+- {
+- while (l--)
+- *to++ = *name++;
+- name--;
+- continue;
+- }
+- #endif
+- if (*name == '\\' && name[1])
+- name++; // Skip '\\'
+- *to++= *name;
+- }
+- *to=0;
+- }
+-
+ /****************************************************************************
+ ** save order by and tables in own lists
+ ****************************************************************************/
+--- 6296,6301 ----
+ }
+
+
+ /****************************************************************************
+ ** save order by and tables in own lists
+ ****************************************************************************/
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 8df527fd25b..266a5bad34d 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -4480,7 +4480,7 @@ that are reorganised.
{
if (!alt_part_info->use_default_partitions)
{
- DBUG_PRINT("info", ("part_info= %x", tab_part_info));
+ DBUG_PRINT("info", ("part_info: 0x%lx", (long) tab_part_info));
tab_part_info->use_default_partitions= FALSE;
}
tab_part_info->use_default_no_partitions= FALSE;
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 013c3a17fd6..0c6a5fe5846 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1665,7 +1665,7 @@ static bool check_prepared_statement(Prepared_statement *stmt,
enum enum_sql_command sql_command= lex->sql_command;
int res= 0;
DBUG_ENTER("check_prepared_statement");
- DBUG_PRINT("enter",("command: %d, param_count: %ld",
+ DBUG_PRINT("enter",("command: %d, param_count: %u",
sql_command, stmt->param_count));
lex->first_lists_tables_same();
@@ -1916,9 +1916,12 @@ void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length)
thd->stmt_map.erase(stmt);
}
else
- general_log_print(thd, COM_STMT_PREPARE, "[%lu] %.*b", stmt->id,
+ {
+ const char *format= "[%lu] %.*b";
+ general_log_print(thd, COM_STMT_PREPARE, format, stmt->id,
stmt->query_length, stmt->query);
+ }
/* check_prepared_statemnt sends the metadata packet in case of success */
DBUG_VOID_RETURN;
}
@@ -2262,7 +2265,7 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
DBUG_VOID_RETURN;
DBUG_PRINT("exec_query", ("%s", stmt->query));
- DBUG_PRINT("info",("stmt: %p", stmt));
+ DBUG_PRINT("info",("stmt: 0x%lx", (long) stmt));
sp_cache_flush_obsolete(&thd->sp_proc_cache);
sp_cache_flush_obsolete(&thd->sp_func_cache);
@@ -2300,9 +2303,11 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
if (error == 0)
- general_log_print(thd, COM_STMT_EXECUTE, "[%lu] %.*b", stmt->id,
+ {
+ const char *format= "[%lu] %.*b";
+ general_log_print(thd, COM_STMT_EXECUTE, format, stmt->id,
thd->query_length, thd->query);
-
+ }
DBUG_VOID_RETURN;
set_params_data_err:
@@ -2355,7 +2360,7 @@ void mysql_sql_stmt_execute(THD *thd)
DBUG_VOID_RETURN;
}
- DBUG_PRINT("info",("stmt: %p", stmt));
+ DBUG_PRINT("info",("stmt: 0x%lx", (long) stmt));
/*
If the free_list is not empty, we'll wrongly free some externally
@@ -2719,7 +2724,8 @@ void Prepared_statement::setup_set_params()
Prepared_statement::~Prepared_statement()
{
DBUG_ENTER("Prepared_statement::~Prepared_statement");
- DBUG_PRINT("enter",("stmt: %p cursor: %p", this, cursor));
+ DBUG_PRINT("enter",("stmt: 0x%lx cursor: 0x%lx",
+ (long) this, (long) cursor));
delete cursor;
/*
We have to call free on the items even if cleanup is called as some items,
@@ -2740,7 +2746,7 @@ Query_arena::Type Prepared_statement::type() const
void Prepared_statement::cleanup_stmt()
{
DBUG_ENTER("Prepared_statement::cleanup_stmt");
- DBUG_PRINT("enter",("stmt: %p", this));
+ DBUG_PRINT("enter",("stmt: 0x%lx", (long) this));
/* The order is important */
lex->unit.cleanup();
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 7ffbb649cb8..d4f6288c298 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1111,7 +1111,7 @@ bool change_master(THD* thd, MASTER_INFO* mi)
{
mi->master_log_pos= lex_mi->pos;
}
- DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
if (lex_mi->host)
strmake(mi->host, lex_mi->host, sizeof(mi->host)-1);
@@ -1228,7 +1228,7 @@ bool change_master(THD* thd, MASTER_INFO* mi)
}
}
mi->rli.group_master_log_pos = mi->master_log_pos;
- DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
/*
Coordinates in rli were spoilt by the 'if (need_relay_log_purge)' block,
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 6758f9d68d0..9a4e93dfb94 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -158,8 +158,8 @@ static int join_read_prev_same(READ_RECORD *info);
static int join_read_prev(READ_RECORD *info);
static int join_ft_read_first(JOIN_TAB *tab);
static int join_ft_read_next(READ_RECORD *info);
-static int join_read_always_key_or_null(JOIN_TAB *tab);
-static int join_read_next_same_or_null(READ_RECORD *info);
+int join_read_always_key_or_null(JOIN_TAB *tab);
+int join_read_next_same_or_null(READ_RECORD *info);
static COND *make_cond_for_table(COND *cond,table_map table,
table_map used_table);
static Item* part_of_refkey(TABLE *form,Field *field);
@@ -505,11 +505,12 @@ err:
DBUG_RETURN(-1); /* purecov: inspected */
}
+
/*
test if it is known for optimisation IN subquery
- SYNOPSYS
- JOIN::test_in_subselect
+ SYNOPSIS
+ JOIN::test_in_subselect()
where - pointer for variable in which conditions should be
stored if subquery is known
@@ -544,6 +545,35 @@ bool JOIN::test_in_subselect(Item **where)
/*
+ Check if the passed HAVING clause is a clause added by subquery optimizer
+
+ SYNOPSIS
+ is_having_subq_predicates()
+ having Having clause
+
+ RETURN
+ TRUE The passed HAVING clause was added by the subquery optimizer
+ FALSE Otherwise
+*/
+
+bool is_having_subq_predicates(Item *having)
+{
+ if (having->type() == Item::FUNC_ITEM)
+ {
+ if (((Item_func *) having)->functype() == Item_func::ISNOTNULLTEST_FUNC)
+ return TRUE;
+ if (((Item_func *) having)->functype() == Item_func::TRIG_COND_FUNC)
+ {
+ having= ((Item_func*)having)->arguments()[0];
+ if (((Item_func *) having)->functype() == Item_func::ISNOTNULLTEST_FUNC)
+ return TRUE;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
global select optimisation.
return 0 - success
1 - error
@@ -1028,9 +1058,7 @@ JOIN::optimize()
}
} else if (join_tab[0].type == JT_REF_OR_NULL &&
join_tab[0].ref.items[0]->name == in_left_expr_name &&
- having->type() == Item::FUNC_ITEM &&
- ((Item_func *) having)->functype() ==
- Item_func::ISNOTNULLTEST_FUNC)
+ is_having_subq_predicates(having))
{
join_tab[0].type= JT_INDEX_SUBQUERY;
error= 0;
@@ -1276,14 +1304,14 @@ JOIN::reinit()
exec_tmp_table1->file->extra(HA_EXTRA_RESET_STATE);
exec_tmp_table1->file->delete_all_rows();
free_io_cache(exec_tmp_table1);
- filesort_free_buffers(exec_tmp_table1);
+ filesort_free_buffers(exec_tmp_table1,0);
}
if (exec_tmp_table2)
{
exec_tmp_table2->file->extra(HA_EXTRA_RESET_STATE);
exec_tmp_table2->file->delete_all_rows();
free_io_cache(exec_tmp_table2);
- filesort_free_buffers(exec_tmp_table2);
+ filesort_free_buffers(exec_tmp_table2,0);
}
if (items0)
set_items_ref_array(items0);
@@ -1446,6 +1474,7 @@ JOIN::exec()
curr_join->examined_rows= 0;
if ((curr_join->select_lex->options & OPTION_SCHEMA_TABLE) &&
+ !thd->lex->describe &&
get_schema_tables_result(curr_join))
{
DBUG_VOID_RETURN;
@@ -2547,6 +2576,9 @@ typedef struct key_field_t { // Used when finding key fields
when val IS NULL.
*/
bool null_rejecting;
+
+ /* TRUE<=> This ref access is an outer subquery reference access */
+ bool outer_ref;
} KEY_FIELD;
/* Values in optimize */
@@ -2848,6 +2880,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
cond->functype() == Item_func::MULT_EQUAL_FUNC) &&
((*value)->type() == Item::FIELD_ITEM) &&
((Item_field*)*value)->field->maybe_null());
+ (*key_fields)->outer_ref= FALSE;
(*key_fields)++;
}
@@ -2906,7 +2939,7 @@ add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
}
static void
-add_key_fields(KEY_FIELD **key_fields,uint *and_level,
+add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
COND *cond, table_map usable_tables,
SARGABLE_PARAM **sargables)
{
@@ -2919,28 +2952,56 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level,
{
Item *item;
while ((item=li++))
- add_key_fields(key_fields,and_level,item,usable_tables,sargables);
+ add_key_fields(join, key_fields, and_level, item, usable_tables,
+ sargables);
for (; org_key_fields != *key_fields ; org_key_fields++)
org_key_fields->level= *and_level;
}
else
{
(*and_level)++;
- add_key_fields(key_fields,and_level,li++,usable_tables,sargables);
+ add_key_fields(join, key_fields, and_level, li++, usable_tables,
+ sargables);
Item *item;
while ((item=li++))
{
KEY_FIELD *start_key_fields= *key_fields;
(*and_level)++;
- add_key_fields(key_fields,and_level,item,usable_tables,sargables);
+ add_key_fields(join, key_fields, and_level, item, usable_tables,
+ sargables);
*key_fields=merge_key_fields(org_key_fields,start_key_fields,
*key_fields,++(*and_level));
}
}
return;
}
- /* If item is of type 'field op field/constant' add it to key_fields */
+ /*
+ Subquery optimization: check if the encountered condition is one
+ added by condition push down into subquery.
+ */
+ {
+ if (cond->type() == Item::FUNC_ITEM &&
+ ((Item_func*)cond)->functype() == Item_func::TRIG_COND_FUNC)
+ {
+ cond= ((Item_func*)cond)->arguments()[0];
+ if (!join->group_list && !join->order &&
+ join->unit->item &&
+ join->unit->item->substype() == Item_subselect::IN_SUBS &&
+ !join->unit->first_select()->next_select())
+ {
+ KEY_FIELD *save= *key_fields;
+ add_key_fields(join, key_fields, and_level, cond, usable_tables,
+ sargables);
+ // Indicate that this ref access candidate is for subquery lookup:
+ for (; save != *key_fields; save++)
+ save->outer_ref= TRUE;
+ }
+ return;
+ }
+ }
+
+ /* If item is of type 'field op field/constant' add it to key_fields */
if (cond->type() != Item::FUNC_ITEM)
return;
Item_func *cond_func= (Item_func*) cond;
@@ -3114,6 +3175,7 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
keyuse.used_tables=key_field->val->used_tables();
keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL;
keyuse.null_rejecting= key_field->null_rejecting;
+ keyuse.outer_ref= key_field->outer_ref;
VOID(insert_dynamic(keyuse_array,(gptr) &keyuse));
}
}
@@ -3236,7 +3298,7 @@ sort_keyuse(KEYUSE *a,KEYUSE *b)
Here we can add 'ref' access candidates for t1 and t2, but not for t3.
*/
-static void add_key_fields_for_nj(TABLE_LIST *nested_join_table,
+static void add_key_fields_for_nj(JOIN *join, TABLE_LIST *nested_join_table,
KEY_FIELD **end, uint *and_level,
SARGABLE_PARAM **sargables)
{
@@ -3248,12 +3310,13 @@ static void add_key_fields_for_nj(TABLE_LIST *nested_join_table,
while ((table= li++))
{
if (table->nested_join)
- add_key_fields_for_nj(table, end, and_level, sargables);
+ add_key_fields_for_nj(join, table, end, and_level, sargables);
else
if (!table->on_expr)
tables |= table->table->map;
}
- add_key_fields(end, and_level, nested_join_table->on_expr, tables, sargables);
+ add_key_fields(join, end, and_level, nested_join_table->on_expr, tables,
+ sargables);
}
@@ -3328,7 +3391,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
return TRUE;
if (cond)
{
- add_key_fields(&end,&and_level,cond,normal_tables,sargables);
+ add_key_fields(join_tab->join, &end, &and_level, cond, normal_tables,
+ sargables);
for (; field != end ; field++)
{
add_key_part(keyuse,field);
@@ -3350,8 +3414,9 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
into account as well.
*/
if (*join_tab[i].on_expr_ref)
- add_key_fields(&end,&and_level,*join_tab[i].on_expr_ref,
- join_tab[i].table->map,sargables);
+ add_key_fields(join_tab->join, &end, &and_level,
+ *join_tab[i].on_expr_ref,
+ join_tab[i].table->map, sargables);
}
/* Process ON conditions for the nested joins */
@@ -3361,7 +3426,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
while ((table= li++))
{
if (table->nested_join)
- add_key_fields_for_nj(table, &end, &and_level, sargables);
+ add_key_fields_for_nj(join_tab->join, table, &end, &and_level,
+ sargables);
}
}
@@ -6257,7 +6323,7 @@ void JOIN::cleanup(bool full)
if (tables > const_tables) // Test for not-const tables
{
free_io_cache(table[const_tables]);
- filesort_free_buffers(table[const_tables]);
+ filesort_free_buffers(table[const_tables],full);
}
if (full)
@@ -9491,7 +9557,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
bool maybe_null=(*cur_group->item)->maybe_null;
key_part_info->null_bit=0;
key_part_info->field= field;
- key_part_info->offset= field->offset();
+ key_part_info->offset= field->offset(table->record[0]);
key_part_info->length= (uint16) field->key_length();
key_part_info->type= (uint8) field->key_type();
key_part_info->key_type =
@@ -9588,7 +9654,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
{
key_part_info->null_bit=0;
key_part_info->field= *reg_field;
- key_part_info->offset= (*reg_field)->offset();
+ key_part_info->offset= (*reg_field)->offset(table->record[0]);
key_part_info->length= (uint16) (*reg_field)->pack_length();
key_part_info->type= (uint8) (*reg_field)->key_type();
key_part_info->key_type =
@@ -10180,7 +10246,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
if (join->result->send_eof())
rc= 1; // Don't send error
}
- DBUG_PRINT("info",("%ld records output",join->send_records));
+ DBUG_PRINT("info",("%ld records output", (long) join->send_records));
}
else
rc= -1;
@@ -11012,6 +11078,13 @@ join_init_quick_read_record(JOIN_TAB *tab)
}
+int rr_sequential(READ_RECORD *info);
+int init_read_record_seq(JOIN_TAB *tab)
+{
+ tab->read_record.read_record= rr_sequential;
+ return tab->read_record.file->ha_rnd_init(1);
+}
+
static int
test_if_quick_select(JOIN_TAB *tab)
{
@@ -11141,7 +11214,7 @@ join_ft_read_next(READ_RECORD *info)
Reading of key with key reference and one part that may be NULL
*/
-static int
+int
join_read_always_key_or_null(JOIN_TAB *tab)
{
int res;
@@ -11157,7 +11230,7 @@ join_read_always_key_or_null(JOIN_TAB *tab)
}
-static int
+int
join_read_next_same_or_null(READ_RECORD *info)
{
int error;
@@ -12427,6 +12500,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
/* Fill schema tables with data before filesort if it's necessary */
if ((join->select_lex->options & OPTION_SCHEMA_TABLE) &&
+ !thd->lex->describe &&
get_schema_tables_result(join))
goto err;
@@ -12560,8 +12634,9 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
DBUG_RETURN(0);
}
Field **first_field=entry->field+entry->s->fields - field_count;
- offset= field_count ?
- entry->field[entry->s->fields - field_count]->offset() : 0;
+ offset= (field_count ?
+ entry->field[entry->s->fields - field_count]->
+ offset(entry->record[0]) : 0);
reclength=entry->s->reclength-offset;
free_io_cache(entry); // Safety
@@ -13761,9 +13836,16 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
if (real_pos->type() == Item::FIELD_ITEM)
{
Item_field *item;
- pos= real_pos;
- if (!(item= new Item_field(thd, ((Item_field*) pos))))
+ if (!(item= new Item_field(thd, ((Item_field*) real_pos))))
goto err;
+ if (pos->type() == Item::REF_ITEM)
+ {
+ /* preserve the names of the ref when dereferncing */
+ Item_ref *ref= (Item_ref *) pos;
+ item->db_name= ref->db_name;
+ item->table_name= ref->table_name;
+ item->name= ref->name;
+ }
pos= item;
if (item->field->flags & BLOB_FLAG)
{
diff --git a/sql/sql_select.h b/sql/sql_select.h
index a66529a6459..323df568271 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -36,6 +36,8 @@ typedef struct keyuse_t {
satisfied if val has NULL 'value'.
*/
bool null_rejecting;
+ /* TRUE<=> This ref access is an outer subquery reference access */
+ bool outer_ref;
} KEYUSE;
class store_key;
@@ -494,10 +496,11 @@ class store_key :public Sql_alloc
Field *to_field; // Store data here
char *null_ptr;
char err;
- public:
+public:
+ bool null_key; /* TRUE <=> the value of the key has a null part */
enum store_key_result { STORE_KEY_OK, STORE_KEY_FATAL, STORE_KEY_CONV };
store_key(THD *thd, Field *field_arg, char *ptr, char *null, uint length)
- :null_ptr(null),err(0)
+ :null_ptr(null), err(0), null_key(0)
{
if (field_arg->type() == FIELD_TYPE_BLOB)
{
@@ -540,6 +543,7 @@ class store_key_field: public store_key
table->write_set);
copy_field.do_copy(&copy_field);
dbug_tmp_restore_column_map(table->write_set, old_map);
+ null_key= to_field->is_null();
return err != 0 ? STORE_KEY_FATAL : STORE_KEY_OK;
}
const char *name() const { return field_name; }
@@ -564,8 +568,8 @@ public:
table->write_set);
int res= item->save_in_field(to_field, 1);
dbug_tmp_restore_column_map(table->write_set, old_map);
+ null_key= to_field->is_null() || item->null_value;
return (err != 0 || res > 2 ? STORE_KEY_FATAL : (store_key_result) res);
-
}
const char *name() const { return "func"; }
};
@@ -595,6 +599,7 @@ public:
err= res;
}
}
+ null_key= to_field->is_null() || item->null_value;
return (err > 2 ? STORE_KEY_FATAL : (store_key_result) err);
}
const char *name() const { return "const"; }
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index dc8946df876..227cc37cdaf 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -4986,7 +4986,7 @@ bool get_schema_tables_result(JOIN *join)
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
table_list->table->file->delete_all_rows();
free_io_cache(table_list->table);
- filesort_free_buffers(table_list->table);
+ filesort_free_buffers(table_list->table,1);
table_list->table->null_row= 0;
}
else
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 1d7768d8b93..17e5018c6eb 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3743,7 +3743,7 @@ static void wait_while_table_is_used(THD *thd,TABLE *table,
enum ha_extra_function function)
{
DBUG_ENTER("wait_while_table_is_used");
- DBUG_PRINT("enter", ("table: '%s' share: 0x%lx db_stat: %u version: %u",
+ DBUG_PRINT("enter", ("table: '%s' share: 0x%lx db_stat: %u version: %lu",
table->s->table_name.str, (ulong) table->s,
table->db_stat, table->s->version));
@@ -4168,7 +4168,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
goto send_result;
}
- table->table->pos_in_table_list= table;
if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
{
char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
@@ -4631,7 +4630,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table);
DBUG_RETURN(TRUE);
}
- if (!src_db || check_db_name(src_db))
+ if (!src_db || check_db_name(&table_ident->db))
{
my_error(ER_WRONG_DB_NAME, MYF(0), src_db ? src_db : "NULL");
DBUG_RETURN(-1);
@@ -6793,8 +6792,6 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
}
else
{
- t->pos_in_table_list= table;
-
if (t->file->ha_table_flags() & HA_HAS_CHECKSUM &&
!(check_opt->flags & T_EXTEND))
protocol->store((ulonglong)t->file->checksum());
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index c4c40ea63c8..219ca8260ed 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -248,14 +248,15 @@ print_plan(JOIN* join, uint idx, double record_count, double read_time,
if (join->best_read == DBL_MAX)
{
fprintf(DBUG_FILE,
- "%s; idx:%u, best: DBL_MAX, atime: %g, itime: %g, count: %g\n",
- info, idx, current_read_time, read_time, record_count);
+ "%s; idx: %u best: DBL_MAX atime: %g itime: %g count: %g\n",
+ info, idx, current_read_time, read_time, record_count);
}
else
{
fprintf(DBUG_FILE,
- "%s; idx:%u, best: %g, accumulated: %g, increment: %g, count: %g\n",
- info, idx, join->best_read, current_read_time, read_time, record_count);
+ "%s; idx :%u best: %g accumulated: %g increment: %g count: %g\n",
+ info, idx, join->best_read, current_read_time, read_time,
+ record_count);
}
/* Print the tables in JOIN->positions */
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index fb56b7ae3b0..8baf84585b2 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1612,7 +1612,7 @@ Handle_old_incorrect_sql_modes_hook::process_unknown_string(char *&unknown_key,
char *end)
{
DBUG_ENTER("Handle_old_incorrect_sql_modes_hook::process_unknown_string");
- DBUG_PRINT("info", ("unknown key:%60s", unknown_key));
+ DBUG_PRINT("info", ("unknown key: %60s", unknown_key));
if (unknown_key + INVALID_SQL_MODES_LENGTH + 1 < end &&
unknown_key[INVALID_SQL_MODES_LENGTH] == '=' &&
@@ -1654,7 +1654,7 @@ process_unknown_string(char *&unknown_key, gptr base, MEM_ROOT *mem_root,
char *end)
{
DBUG_ENTER("Handle_old_incorrect_trigger_table_hook::process_unknown_string");
- DBUG_PRINT("info", ("unknown key:%60s", unknown_key));
+ DBUG_PRINT("info", ("unknown key: %60s", unknown_key));
if (unknown_key + INVALID_TRIGGER_TABLE_LENGTH + 1 < end &&
unknown_key[INVALID_TRIGGER_TABLE_LENGTH] == '=' &&
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 1d119b99df0..2575f17d256 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -691,7 +691,7 @@ int mysql_update(THD *thd,
thd->row_count_func=
(thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
send_ok(thd, (ulong) thd->row_count_func, id, buff);
- DBUG_PRINT("info",("%d records updated",updated));
+ DBUG_PRINT("info",("%ld records updated", (long) updated));
}
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
thd->abort_on_warning= 0;
@@ -788,7 +788,7 @@ static table_map get_table_map(List<Item> *items)
while ((item= (Item_field *) item_it++))
map|= item->used_tables();
- DBUG_PRINT("info",("table_map: 0x%08x", map));
+ DBUG_PRINT("info", ("table_map: 0x%08lx", (long) map));
return map;
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 6a829171125..f5ad6f1e278 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -735,7 +735,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text
UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
NCHAR_STRING opt_component key_cache_name
- sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem
+ sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
%type <lex_str_ptr>
opt_table_alias
@@ -745,7 +745,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <simple_string>
remember_name remember_end opt_ident opt_db text_or_password
- opt_constraint constraint ident_or_empty
+ opt_constraint constraint
%type <string>
text_string opt_gconcat_separator
@@ -797,8 +797,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <item_list>
expr_list udf_expr_list udf_expr_list2 when_list
- ident_list ident_list_arg
- expr_list_opt
+ ident_list ident_list_arg opt_expr_list
%type <var_type>
option_type opt_var_type opt_var_ident_type
@@ -1229,7 +1228,8 @@ create:
lex->create_info.options=$2 | $4;
lex->create_info.db_type= lex->thd->variables.table_type;
lex->create_info.default_table_charset= NULL;
- lex->name= 0;
+ lex->name.str= 0;
+ lex->name.length= 0;
lex->like_name= 0;
}
create2
@@ -1269,7 +1269,7 @@ create:
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_CREATE_DB;
- lex->name=$4.str;
+ lex->name= $4;
lex->create_info.options=$3;
}
| CREATE
@@ -1504,7 +1504,7 @@ clear_privileges:
sp_name:
ident '.' ident
{
- if (!$1.str || check_db_name($1.str))
+ if (!$1.str || check_db_name(&$1))
{
my_error(ER_WRONG_DB_NAME, MYF(0), $1.str);
YYABORT;
@@ -3094,7 +3094,7 @@ size_number:
uint text_shift_number= 0;
longlong prefix_number;
char *start_ptr= $1.str;
- uint str_len= strlen(start_ptr);
+ uint str_len= $1.length;
char *end_ptr= start_ptr + str_len;
int error;
prefix_number= my_strtoll10(start_ptr, &end_ptr, &error);
@@ -4618,7 +4618,8 @@ alter:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- lex->name= 0;
+ lex->name.str= 0;
+ lex->name.length= 0;
lex->sql_command= SQLCOM_ALTER_TABLE;
lex->duplicates= DUP_ERROR;
if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
@@ -4628,7 +4629,6 @@ alter:
lex->key_list.empty();
lex->col_list.empty();
lex->select_lex.init_order();
- lex->name= 0;
lex->like_name= 0;
lex->select_lex.db=
((TABLE_LIST*) lex->select_lex.table_list.first)->db;
@@ -4653,7 +4653,8 @@ alter:
THD *thd= Lex->thd;
lex->sql_command=SQLCOM_ALTER_DB;
lex->name= $3;
- if (lex->name == NULL && thd->copy_db_to(&lex->name, NULL))
+ if (lex->name.str == NULL &&
+ thd->copy_db_to(&lex->name.str, &lex->name.length))
YYABORT;
}
| ALTER PROCEDURE sp_name
@@ -4803,8 +4804,8 @@ opt_ev_sql_stmt: /* empty*/ { $$= 0;}
ident_or_empty:
- /* empty */ { $$= 0; }
- | ident { $$= $1.str; };
+ /* empty */ { $$.str= 0; $$.length= 0; }
+ | ident { $$= $1; };
alter_commands:
| DISCARD TABLESPACE { Lex->alter_info.tablespace_op= DISCARD_TABLESPACE; }
@@ -5082,19 +5083,20 @@ alter_list_item:
{
LEX *lex=Lex;
THD *thd= lex->thd;
+ uint dummy;
lex->select_lex.db=$3->db.str;
if (lex->select_lex.db == NULL &&
- thd->copy_db_to(&lex->select_lex.db, NULL))
+ thd->copy_db_to(&lex->select_lex.db, &dummy))
{
YYABORT;
}
if (check_table_name($3->table.str,$3->table.length) ||
- $3->db.str && check_db_name($3->db.str))
+ $3->db.str && check_db_name(&$3->db))
{
my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str);
YYABORT;
}
- lex->name= $3->table.str;
+ lex->name= $3->table;
lex->alter_info.flags|= ALTER_RENAME;
}
| CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate
@@ -6361,11 +6363,11 @@ function_call_generic:
{
#ifdef HAVE_DLOPEN
udf_func *udf= 0;
+ LEX *lex= Lex;
if (using_udf_functions &&
(udf= find_udf($1.str, $1.length)) &&
udf->type == UDFTYPE_AGGREGATE)
{
- LEX *lex= Lex;
if (lex->current_select->inc_in_sum_expr())
{
yyerror(ER(ER_SYNTAX_ERROR));
@@ -6373,10 +6375,10 @@ function_call_generic:
}
}
/* Temporary placing the result of find_udf in $3 */
- $<udf>$= udf;
+ lex->current_select->udf_list.push_front(udf);
#endif
}
- expr_list_opt ')'
+ udf_expr_list ')'
{
THD *thd= YYTHD;
LEX *lex= Lex;
@@ -6401,9 +6403,10 @@ function_call_generic:
{
#ifdef HAVE_DLOPEN
/* Retrieving the result of find_udf */
- udf_func *udf= $<udf>3;
+ udf_func *udf;
+ LEX *lex= Lex;
- if (udf)
+ if (NULL != (udf= lex->current_select->udf_list.pop()))
{
if (udf->type == UDFTYPE_AGGREGATE)
{
@@ -6426,7 +6429,7 @@ function_call_generic:
YYABORT;
}
}
- | ident '.' ident '(' udf_expr_list ')'
+ | ident '.' ident '(' opt_expr_list ')'
{
THD *thd= YYTHD;
Create_qfunc *builder;
@@ -6499,12 +6502,29 @@ udf_expr_list3:
udf_expr:
remember_name expr remember_end select_alias
{
+ udf_func *udf= Select->udf_list.head();
+ /*
+ Use Item::name as a storage for the attribute value of user
+ defined function argument. It is safe to use Item::name
+ because the syntax will not allow having an explicit name here.
+ See WL#1017 re. udf attributes.
+ */
if ($4.str)
{
+ if (!udf)
+ {
+ /*
+ Disallow using AS to specify explicit names for the arguments
+ of stored routine calls
+ */
+ yyerror(ER(ER_SYNTAX_ERROR));
+ YYABORT;
+ }
+
$2->is_autogenerated_name= FALSE;
$2->set_name($4.str, $4.length, system_charset_info);
}
- else
+ else if (udf)
$2->set_name($1, (uint) ($3 - $1), YYTHD->charset());
$$= $2;
}
@@ -6665,12 +6685,10 @@ cast_type:
| DECIMAL_SYM float_options { $$=ITEM_CAST_DECIMAL; Lex->charset= NULL; }
;
-expr_list_opt:
- /* empty */
- { $$ = NULL; }
- | expr_list
- { $$ = $1;}
- ;
+opt_expr_list:
+ /* empty */ { $$= NULL; }
+ | expr_list { $$= $1;}
+ ;
expr_list:
{ Select->expr_list.push_front(new List<Item>); }
@@ -7627,7 +7645,7 @@ drop:
LEX *lex=Lex;
lex->sql_command= SQLCOM_DROP_DB;
lex->drop_if_exists=$3;
- lex->name=$4.str;
+ lex->name= $4;
}
| DROP FUNCTION_SYM if_exists sp_name
{
@@ -8274,7 +8292,7 @@ show_param:
{
Lex->sql_command=SQLCOM_SHOW_CREATE_DB;
Lex->create_info.options=$3;
- Lex->name=$4.str;
+ Lex->name= $4;
}
| CREATE TABLE_SYM table_ident
{
@@ -10279,7 +10297,8 @@ grant_ident:
{
LEX *lex= Lex;
THD *thd= lex->thd;
- if (thd->copy_db_to(&lex->current_select->db, NULL))
+ uint dummy;
+ if (thd->copy_db_to(&lex->current_select->db, &dummy))
YYABORT;
if (lex->grant == GLOBAL_ACLS)
lex->grant = DB_ACLS & ~GRANT_ACL;
diff --git a/sql/strfunc.cc b/sql/strfunc.cc
index ef769a5b16e..2d2530eb876 100644
--- a/sql/strfunc.cc
+++ b/sql/strfunc.cc
@@ -150,7 +150,7 @@ uint find_type2(TYPELIB *typelib, const char *x, uint length, CHARSET_INFO *cs)
int pos;
const char *j;
DBUG_ENTER("find_type2");
- DBUG_PRINT("enter",("x: '%.*s' lib: 0x%lx", length, x, typelib));
+ DBUG_PRINT("enter",("x: '%.*s' lib: 0x%lx", length, x, (long) typelib));
if (!typelib->count)
{
diff --git a/sql/table.cc b/sql/table.cc
index 7f80b95c954..926b44dedbc 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -30,7 +30,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share,
uchar *head, File file);
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
uint types, char **names);
-static uint find_field(Field **fields, uint start, uint length);
+static uint find_field(Field **fields, byte *record, uint start, uint length);
/* Get column name from column hash */
@@ -1069,6 +1069,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
Field *field;
if (new_field_pack_flag <= 1)
key_part->fieldnr= (uint16) find_field(share->field,
+ share->default_values,
(uint) key_part->offset,
(uint) key_part->length);
if (!key_part->fieldnr)
@@ -1232,24 +1233,19 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
if (share->found_next_number_field)
{
- /*
- We must have a table object for find_ref_key to calculate field offset
- */
- TABLE tmp_table;
- tmp_table.record[0]= share->default_values;
-
reg_field= *share->found_next_number_field;
- reg_field->table= &tmp_table;
if ((int) (share->next_number_index= (uint)
- find_ref_key(share->key_info, share->keys, reg_field,
+ find_ref_key(share->key_info, share->keys,
+ share->default_values, reg_field,
&share->next_number_key_offset)) < 0)
{
+ /* Wrong field definition */
+ DBUG_ASSERT(0);
reg_field->unireg_check= Field::NONE; /* purecov: inspected */
share->found_next_number_field= 0;
}
else
reg_field->flags |= AUTO_INCREMENT_FLAG;
- reg_field->table= 0;
}
if (share->blob_fields)
@@ -1343,7 +1339,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
Field **field_ptr;
DBUG_ENTER("open_table_from_share");
DBUG_PRINT("enter",("name: '%s.%s' form: 0x%lx", share->db.str,
- share->table_name.str, outparam));
+ share->table_name.str, (long) outparam));
error= 1;
bzero((char*) outparam, sizeof(*outparam));
@@ -1969,7 +1965,7 @@ TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
# field number +1
*/
-static uint find_field(Field **fields, uint start, uint length)
+static uint find_field(Field **fields, byte *record, uint start, uint length)
{
Field **field;
uint i, pos;
@@ -1977,7 +1973,7 @@ static uint find_field(Field **fields, uint start, uint length)
pos= 0;
for (field= fields, i=1 ; *field ; i++,field++)
{
- if ((*field)->offset() == start)
+ if ((*field)->offset(record) == start)
{
if ((*field)->key_length() == length)
return (i);
@@ -2258,7 +2254,7 @@ char *get_field(MEM_ROOT *mem, Field *field)
SYNPOSIS
check_db_name()
- name Name of database
+ org_name Name of database and length
NOTES
If lower_case_table_names is set then database is converted to lower case
@@ -2268,35 +2264,35 @@ char *get_field(MEM_ROOT *mem, Field *field)
1 error
*/
-bool check_db_name(char *name)
+bool check_db_name(LEX_STRING *org_name)
{
- char *start= name;
- /* Used to catch empty names and names with end space */
- bool last_char_is_space= TRUE;
+ char *name= org_name->str;
+
+ if (!org_name->length || org_name->length > NAME_LEN)
+ return 1;
if (lower_case_table_names && name != any_db)
my_casedn_str(files_charset_info, name);
- while (*name)
- {
#if defined(USE_MB) && defined(USE_MB_IDENT)
- last_char_is_space= my_isspace(system_charset_info, *name);
- if (use_mb(system_charset_info))
+ if (use_mb(system_charset_info))
+ {
+ bool last_char_is_space= TRUE;
+ char *end= name + org_name->length;
+ while (name < end)
{
- int len=my_ismbchar(system_charset_info, name,
- name+system_charset_info->mbmaxlen);
- if (len)
- {
- name += len;
- continue;
- }
+ int len;
+ last_char_is_space= my_isspace(system_charset_info, *name);
+ len= my_ismbchar(system_charset_info, name, end);
+ if (!len)
+ len= 1;
+ name+= len;
}
-#else
- last_char_is_space= *name==' ';
-#endif
- name++;
+ return last_char_is_space;
}
- return last_char_is_space || (uint) (name - start) > NAME_LEN;
+ else
+#endif
+ return org_name->str[org_name->length - 1] != ' '; /* purecov: inspected */
}
@@ -2405,8 +2401,8 @@ table_check_intact(TABLE *table, const uint table_f_count,
my_bool error= FALSE;
my_bool fields_diff_count;
DBUG_ENTER("table_check_intact");
- DBUG_PRINT("info",("table=%s expected_count=%d",table->alias, table_f_count));
- DBUG_PRINT("info",("last_create_time=%d", *last_create_time));
+ DBUG_PRINT("info",("table: %s expected_count: %d last_create_time: %ld",
+ table->alias, table_f_count, *last_create_time));
if ((fields_diff_count= (table->s->fields != table_f_count)) ||
(*last_create_time != table->file->stats.create_time))
@@ -4096,6 +4092,23 @@ void st_table_list::reinit_before_use(THD *thd)
embedding->nested_join->join_list.head() == embedded);
}
+/*
+ Return subselect that contains the FROM list this table is taken from
+
+ SYNOPSIS
+ st_table_list::containing_subselect()
+
+ RETURN
+ Subselect item for the subquery that contains the FROM list
+ this table is taken from if there is any
+ 0 - otherwise
+
+*/
+
+Item_subselect *st_table_list::containing_subselect()
+{
+ return (select_lex ? select_lex->master_unit()->item : 0);
+}
/*****************************************************************************
** Instansiate templates
diff --git a/sql/table.cc.rej b/sql/table.cc.rej
new file mode 100644
index 00000000000..fd728ba9965
--- /dev/null
+++ b/sql/table.cc.rej
@@ -0,0 +1,17 @@
+***************
+*** 2246,2252 ****
+
+ bool check_db_name(char *name)
+ {
+! char *start=name;
+ /* Used to catch empty names and names with end space */
+ bool last_char_is_space= TRUE;
+
+--- 2257,2263 ----
+
+ bool check_db_name(char *name)
+ {
+! char *start= name;
+ /* Used to catch empty names and names with end space */
+ bool last_char_is_space= TRUE;
+
diff --git a/sql/table.h b/sql/table.h
index 434fb5a4d11..55f889f42b9 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -18,6 +18,7 @@
/* Structs that defines the TABLE */
class Item; /* Needed by ORDER */
+class Item_subselect;
class GRANT_TABLE;
class st_select_lex_unit;
class st_select_lex;
@@ -74,6 +75,9 @@ enum release_type { RELEASE_NORMAL, RELEASE_WAIT_FOR_DROP };
typedef struct st_filesort_info
{
IO_CACHE *io_cache; /* If sorted through filebyte */
+ uchar **sort_keys; /* Buffer for sorting keys */
+ byte *buffpek; /* Buffer for buffpek structures */
+ uint buffpek_len; /* Max number of buffpeks in the buffer */
byte *addon_buf; /* Pointer to a buffer if sorted with fields */
uint addon_length; /* Length of the buffer */
struct st_sort_addon_field *addon_field; /* Pointer to the fields info */
@@ -859,6 +863,7 @@ typedef struct st_table_list
procedure.
*/
void reinit_before_use(THD *thd);
+ Item_subselect *containing_subselect();
private:
bool prep_check_option(THD *thd, uint8 check_opt_type);
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 3d9f278b3f7..6acf17520d9 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -961,13 +961,12 @@ TIME_to_gmt_sec(const TIME *t, const TIME_ZONE_INFO *sp,
*/
if (shift)
{
- if (local_t > (TIMESTAMP_MAX_VALUE - shift*86400L +
- sp->revtis[i].rt_offset - saved_seconds))
+ if (local_t > (my_time_t) (TIMESTAMP_MAX_VALUE - shift*86400L +
+ sp->revtis[i].rt_offset - saved_seconds))
{
DBUG_RETURN(0); /* my_time_t overflow */
}
- else
- local_t+= shift*86400L;
+ local_t+= shift*86400L;
}
if (sp->revtis[i].rt_type)
@@ -1744,8 +1743,8 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
tz_leapcnt++;
DBUG_PRINT("info",
- ("time_zone_leap_second table: tz_leapcnt=%u tt_time=%lld offset=%ld",
- tz_leapcnt, (longlong)tz_lsis[tz_leapcnt-1].ls_trans,
+ ("time_zone_leap_second table: tz_leapcnt:%u tt_time: %lu offset: %ld",
+ tz_leapcnt, (ulong) tz_lsis[tz_leapcnt-1].ls_trans,
tz_lsis[tz_leapcnt-1].ls_corr));
res= table->file->index_next(table->record[0]);
@@ -2058,8 +2057,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
tz_info->timecnt++;
DBUG_PRINT("info",
- ("time_zone_transition table: tz_id=%u tt_time=%lld tt_id=%u",
- tzid, (longlong)ttime, ttid));
+ ("time_zone_transition table: tz_id: %u tt_time:%lu tt_id: %u",
+ tzid, (ulong) ttime, ttid));
res= table->file->index_next_same(table->record[0],
(byte*)table->field[0]->ptr, 4);
diff --git a/sql/unireg.cc b/sql/unireg.cc
index a20c59fd796..4514f969913 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -469,16 +469,16 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo,
int2store(pos+6, key->block_size);
pos+=8;
key_parts+=key->key_parts;
- DBUG_PRINT("loop",("flags: %d key_parts: %d at 0x%lx",
- key->flags,key->key_parts,
- key->key_part));
+ DBUG_PRINT("loop", ("flags: %d key_parts: %d at 0x%lx",
+ key->flags, key->key_parts,
+ (long) key->key_part));
for (key_part=key->key_part,key_part_end=key_part+key->key_parts ;
key_part != key_part_end ;
key_part++)
{
uint offset;
- DBUG_PRINT("loop",("field: %d startpos: %lu length: %ld",
+ DBUG_PRINT("loop",("field: %d startpos: %lu length: %d",
key_part->fieldnr, key_part->offset + data_offset,
key_part->length));
int2store(pos,key_part->fieldnr+1+FIELD_NAME_USED);