Commit 320d451d authored by unknown's avatar unknown

Merge ssmith@bk-internal.mysql.com:/home/bk/mysql-5.0

into  mysql.com:/home/stewart/Documents/MySQL/5.0/main

parents 3fad8218 4d2bf4be
......@@ -90,6 +90,9 @@ case "$cpu_family--$model_name" in
*Athlon*)
cpu_arg="athlon";
;;
*Opteron*)
cpu_arg="opteron";
;;
# Intel ia64
*Itanium*)
......@@ -147,6 +150,9 @@ case "$cc_ver--$cc_verno" in
ppc-*)
check_cpu_args='-mcpu=$cpu_arg -mtune=$cpu_arg'
;;
x86_64-*)
check_cpu_args='-mtune=$cpu_arg'
;;
*)
check_cpu_cflags=""
return
......
......@@ -244,7 +244,7 @@ contains the sum of the following flag and the locally stored len. */
#define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE)
/* Some macros to improve branch prediction and reduce cache misses */
#if defined(__GNUC__) && (__GNUC__ > 2)
#if defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER)
/* Tell the compiler that 'expr' probably evaluates to 'constant'. */
# define UNIV_EXPECT(expr,constant) __builtin_expect(expr, constant)
/* Tell the compiler that a pointer is likely to be NULL */
......
......@@ -53,21 +53,20 @@ sub collect_test_cases ($) {
else
{
# ----------------------------------------------------------------------
# Skip some tests listed in disabled.def
# Disable some tests listed in disabled.def
# ----------------------------------------------------------------------
my %skiplist;
my $skipfile= "$testdir/disabled.def";
if ( open(SKIPFILE, $skipfile) )
my %disabled;
if ( open(DISABLED, "$testdir/disabled.def" ) )
{
while ( <SKIPFILE> )
while ( <DISABLED> )
{
chomp;
if ( /^\s*(\S+)\s*:\s*(.*?)\s*$/ )
{
$skiplist{$1}= $2;
$disabled{$1}= $2;
}
}
close SKIPFILE;
close DISABLED;
}
foreach my $elem ( sort readdir(TESTDIR) ) {
......@@ -75,7 +74,7 @@ sub collect_test_cases ($) {
next if ! defined $tname;
next if $::opt_do_test and ! defined mtr_match_prefix($elem,$::opt_do_test);
collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,\%skiplist);
collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,\%disabled);
}
closedir TESTDIR;
}
......@@ -119,7 +118,7 @@ sub collect_one_test_case($$$$$$) {
my $tname= shift;
my $elem= shift;
my $cases= shift;
my $skiplist=shift;
my $disabled=shift;
my $path= "$testdir/$elem";
......@@ -188,7 +187,7 @@ sub collect_one_test_case($$$$$$) {
my $slave_mi_file= "$testdir/$tname.slave-mi";
my $master_sh= "$testdir/$tname-master.sh";
my $slave_sh= "$testdir/$tname-slave.sh";
my $disabled= "$testdir/$tname.disabled";
my $disabled_file= "$testdir/$tname.disabled";
$tinfo->{'master_opt'}= $::glob_win32 ? ["--default-time-zone=+3:00"] : [];
$tinfo->{'slave_opt'}= $::glob_win32 ? ["--default-time-zone=+3:00"] : [];
......@@ -292,18 +291,18 @@ sub collect_one_test_case($$$$$$) {
}
# FIXME why this late?
if ( $skiplist->{$tname} )
if ( $disabled->{$tname} )
{
$tinfo->{'skip'}= 1;
$tinfo->{'disable'}= 1; # Sub type of 'skip'
$tinfo->{'comment'}= $skiplist->{$tname} if $skiplist->{$tname};
$tinfo->{'comment'}= $disabled->{$tname} if $disabled->{$tname};
}
if ( -f $disabled )
if ( -f $disabled_file )
{
$tinfo->{'skip'}= 1;
$tinfo->{'disable'}= 1; # Sub type of 'skip'
$tinfo->{'comment'}= mtr_fromfile($disabled);
$tinfo->{'comment'}= mtr_fromfile($disabled_file);
}
# We can't restart a running server that may be in use
......
......@@ -186,8 +186,8 @@ sub spawn_parent_impl {
if ( $mode eq 'run' or $mode eq 'test' )
{
my $exit_value= -1;
my $signal_num= 0;
my $dumped_core= 0;
# my $signal_num= 0;
# my $dumped_core= 0;
if ( $mode eq 'run' )
{
......@@ -199,9 +199,10 @@ sub spawn_parent_impl {
mtr_error("$path ($pid) got lost somehow");
}
$exit_value= $? >> 8;
$signal_num= $? & 127;
$dumped_core= $? & 128;
$exit_value= $?;
# $exit_value= $? >> 8;
# $signal_num= $? & 127;
# $dumped_core= $? & 128;
return $exit_value;
}
......@@ -229,9 +230,10 @@ sub spawn_parent_impl {
if ( $ret_pid == $pid )
{
# We got termination of mysqltest, we are done
$exit_value= $? >> 8;
$signal_num= $? & 127;
$dumped_core= $? & 128;
$exit_value= $?;
# $exit_value= $? >> 8;
# $signal_num= $? & 127;
# $dumped_core= $? & 128;
last;
}
......@@ -473,6 +475,7 @@ sub mtr_stop_mysqld_servers ($) {
}
else
{
# Server is dead, we remove the pidfile if any
# Race, could have been removed between I tested with -f
# and the unlink() below, so I better check again with -f
......@@ -502,10 +505,12 @@ sub mtr_stop_mysqld_servers ($) {
# that for true Win32 processes, kill(0,$pid) will not return 1.
# ----------------------------------------------------------------------
start_reap_all(); # Avoid zombies
SIGNAL:
foreach my $sig (15,9)
{
my $retries= 10; # 10 seconds
my $retries= 20; # FIXME 20 seconds, this is silly!
kill($sig, keys %mysqld_pids);
while ( $retries-- and kill(0, keys %mysqld_pids) )
{
......@@ -514,6 +519,8 @@ sub mtr_stop_mysqld_servers ($) {
}
}
stop_reap_all(); # Get into control again
# ----------------------------------------------------------------------
# Now, we check if all we can find using kill(0,$pid) are dead,
# and just assume the rest are. We cleanup socket and PID files.
......@@ -632,7 +639,8 @@ sub mtr_mysqladmin_shutdown () {
$mysql_admin_pids{$pid}= 1;
}
# We wait blocking, we wait for the last one anyway
# As mysqladmin is such a simple program, we trust it to terminate.
# I.e. we wait blocking, and wait wait for them all before we go on.
while (keys %mysql_admin_pids)
{
foreach my $pid (keys %mysql_admin_pids)
......@@ -651,7 +659,8 @@ sub mtr_mysqladmin_shutdown () {
my $timeout= 20; # 20 seconds max
my $res= 1; # If we just fall through, we are done
# in the sense that the servers don't
# listen to their ports any longer
TIME:
while ( $timeout-- )
{
......@@ -669,6 +678,8 @@ sub mtr_mysqladmin_shutdown () {
last; # If we got here, we are done
}
$timeout or mtr_debug("At least one server is still listening to its port");
sleep(5) if $::glob_win32; # FIXME next startup fails if no sleep
return $res;
......@@ -752,6 +763,7 @@ sub mtr_ping_mysqld_server () {
#
##############################################################################
# FIXME check that the pidfile contains the expected pid!
sub sleep_until_file_created ($$$) {
my $pidfile= shift;
......@@ -762,7 +774,7 @@ sub sleep_until_file_created ($$$) {
{
if ( -r $pidfile )
{
return 1;
return $pid;
}
# Check if it died after the fork() was successful
......@@ -793,8 +805,12 @@ sub sleep_until_file_created ($$$) {
#
##############################################################################
# FIXME something is wrong, we sometimes terminate with "Hangup" written
# to tty, and no STDERR output telling us why.
sub mtr_exit ($) {
my $code= shift;
# cluck("Called mtr_exit()");
local $SIG{HUP} = 'IGNORE';
kill('HUP', -$$);
exit($code);
......
......@@ -10,7 +10,6 @@ sub mtr_report_test_name($);
sub mtr_report_test_passed($);
sub mtr_report_test_failed($);
sub mtr_report_test_skipped($);
sub mtr_report_test_disabled($);
sub mtr_show_failed_diff ($);
sub mtr_report_stats ($);
......
......@@ -341,7 +341,6 @@ sub main () {
if ( ! $glob_use_running_server )
{
if ( $opt_start_dirty )
{
kill_running_server();
......@@ -356,7 +355,7 @@ sub main () {
}
}
if ( $opt_start_and_exit or $opt_start_dirty )
if ( $opt_start_dirty )
{
if ( ndbcluster_start() )
{
......@@ -371,16 +370,13 @@ sub main () {
mtr_error("Can't start the mysqld server");
}
}
elsif ( $opt_bench )
{
run_benchmarks(shift); # Shift what? Extra arguments?!
}
else
{
if ( $opt_bench )
{
run_benchmarks(shift); # Shift what? Extra arguments?!
}
else
{
run_tests();
}
run_tests();
}
mtr_exit(0);
......@@ -1487,6 +1483,16 @@ sub run_testcase ($) {
}
}
# ----------------------------------------------------------------------
# If --start-and-exit given, stop here to let user manually run tests
# ----------------------------------------------------------------------
if ( $opt_start_and_exit )
{
mtr_report("\nServers started, exiting");
exit(0);
}
# ----------------------------------------------------------------------
# Run the test case
# ----------------------------------------------------------------------
......@@ -2248,7 +2254,8 @@ Misc options
script-debug Debug this script itself
compress Use the compressed protocol between client and server
timer Show test case execution time
start-and-exit Only initiate and start the "mysqld" servers
start-and-exit Only initiate and start the "mysqld" servers, use the startup
settings for the specified test case if any
start-dirty Only start the "mysqld" servers without initiation
fast Don't try to cleanup from earlier runs
reorder Reorder tests to get less server restarts
......
......@@ -165,7 +165,7 @@ c varchar(64) utf8_general_ci NO select,insert,update,references
select * from information_schema.COLUMNS where table_name="t1"
and column_name= "a";
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
NULL mysqltest t1 a 1 NULL YES int NULL NULL 10 NULL NULL NULL int(11) select,insert,update,references
NULL mysqltest t1 a 1 NULL YES int NULL NULL 10 0 NULL NULL int(11) select,insert,update,references
show columns from mysqltest.t1 where field like "%a%";
Field Type Null Key Default Extra
a int(11) YES NULL
......@@ -535,7 +535,7 @@ c float(5,2) NULL NULL 5 2
d decimal(6,4) NULL NULL 6 4
e float NULL NULL 12 NULL
f decimal(6,3) NULL NULL 6 3
g int(11) NULL NULL 10 NULL
g int(11) NULL NULL 10 0
h double(10,3) NULL NULL 10 3
i double NULL NULL 22 NULL
drop table t1;
......@@ -941,11 +941,11 @@ select column_name, NUMERIC_PRECISION, NUMERIC_SCALE
from information_schema.columns
where table_name='t1';
column_name NUMERIC_PRECISION NUMERIC_SCALE
f1 3 NULL
f2 5 NULL
f3 7 NULL
f4 10 NULL
f5 19 NULL
f1 3 0
f2 5 0
f3 7 0
f4 10 0
f5 19 0
f6 1 NULL
f7 64 NULL
drop table t1;
......
......@@ -2218,6 +2218,23 @@ a
1
2
3
select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1;
a a
NULL 1
1 2
2 2
3 2
1 3
2 3
3 3
select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
a a
2 1
3 1
2 2
3 2
2 3
3 3
select * from (t1 as t2 left join t1 as t3 using (a)) right outer join t1 using ( a );
a
1
......@@ -2739,3 +2756,14 @@ DROP TABLE t1,t2;
select x'10' + 0, X'10' + 0, b'10' + 0, B'10' + 0;
x'10' + 0 X'10' + 0 b'10' + 0 B'10' + 0
16 16 2 2
CREATE TABLE BUG_12595(a varchar(100));
INSERT INTO BUG_12595 VALUES ('hakan%'), ('hakank'), ("ha%an");
SELECT * FROM BUG_12595 WHERE a LIKE 'hakan*%' ESCAPE '*';
a
hakan%
SELECT * FROM BUG_12595 WHERE a LIKE 'hakan**%' ESCAPE '**';
ERROR HY000: Incorrect arguments to ESCAPE
SELECT * FROM BUG_12595 WHERE a LIKE 'ha%%an' ESCAPE '%';
a
ha%an
DROP TABLE BUG_12595;
......@@ -512,3 +512,46 @@ t1 CREATE TABLE `t1` (
KEY `c2` USING BTREE (`c2`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE txt1(a int);
CREATE TABLE tyt2(a int);
CREATE TABLE urkunde(a int);
FLUSH TABLES;
SELECT 1 FROM mysql.db, mysql.proc, mysql.user, mysql.time_zone, mysql.time_zone_name, txt1, tyt2, urkunde LIMIT 0;
1
SHOW OPEN TABLES;
Database Table In_use Name_locked
mysql db 0 0
test urkunde 0 0
mysql time_zone 0 0
mysql user 0 0
test txt1 0 0
mysql proc 0 0
test tyt2 0 0
mysql time_zone_name 0 0
SHOW OPEN TABLES FROM mysql;
Database Table In_use Name_locked
mysql db 0 0
mysql time_zone 0 0
mysql user 0 0
mysql proc 0 0
mysql time_zone_name 0 0
SHOW OPEN TABLES FROM mysql LIKE 'u%';
Database Table In_use Name_locked
mysql user 0 0
SHOW OPEN TABLES LIKE 't%';
Database Table In_use Name_locked
mysql time_zone 0 0
test txt1 0 0
test tyt2 0 0
mysql time_zone_name 0 0
SHOW OPEN TABLES LIKE '%o%';
Database Table In_use Name_locked
mysql time_zone 0 0
mysql proc 0 0
mysql time_zone_name 0 0
FLUSH TABLES;
SHOW OPEN TABLES;
Database Table In_use Name_locked
DROP TABLE txt1;
DROP TABLE tyt2;
DROP TABLE urkunde;
......@@ -615,6 +615,7 @@ show create database information_schema;
#
# Bug #11057 information_schema: columns table has some questionable contents
# Bug #12301 information_schema: NUMERIC_SCALE must be 0 for integer columns
#
create table t1(f1 LONGBLOB, f2 LONGTEXT);
select column_name,data_type,CHARACTER_OCTET_LENGTH,
......
......@@ -15,6 +15,7 @@ connection con1;
drop table if exists t1;
--enable_warnings
--disable_reconnect
create table t1 (kill_id int);
insert into t1 values(connection_id());
......@@ -25,7 +26,6 @@ kill @id;
connection con1;
--disable_reconnect
# this statement should fail
--error 2006,2013
select 1;
......
......@@ -1850,10 +1850,8 @@ select * from t1 left join (t1 as t2 left join t1 as t3 using (a)) using ( a );
select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1;
select * from t1 natural left join (t1 as t2 left join t1 as t3 using (a));
# right join on
# TODO: WL#2486 - there is a problem in the order of tables in RIGHT JOIN
# check how we set next_name_resolution_table
# select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1;
# select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1;
select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
# right [outer] joing using
select * from (t1 as t2 left join t1 as t3 using (a)) right outer join t1 using ( a );
select * from t1 right outer join (t1 as t2 left join t1 as t3 using (a)) using ( a );
......@@ -2350,3 +2348,14 @@ DROP TABLE t1,t2;
#
select x'10' + 0, X'10' + 0, b'10' + 0, B'10' + 0;
#
# BUG #12595
#
CREATE TABLE BUG_12595(a varchar(100));
INSERT INTO BUG_12595 VALUES ('hakan%'), ('hakank'), ("ha%an");
SELECT * FROM BUG_12595 WHERE a LIKE 'hakan*%' ESCAPE '*';
-- error 1210
SELECT * FROM BUG_12595 WHERE a LIKE 'hakan**%' ESCAPE '**';
SELECT * FROM BUG_12595 WHERE a LIKE 'ha%%an' ESCAPE '%';
DROP TABLE BUG_12595;
......@@ -387,3 +387,21 @@ SHOW CREATE TABLE t1;
DROP TABLE t1;
# End of 4.1 tests
#
# BUG 12183 - SHOW OPEN TABLES behavior doesn't match grammar
# First we close all open tables with FLUSH tables and then we open some.
CREATE TABLE txt1(a int);
CREATE TABLE tyt2(a int);
CREATE TABLE urkunde(a int);
FLUSH TABLES;
SELECT 1 FROM mysql.db, mysql.proc, mysql.user, mysql.time_zone, mysql.time_zone_name, txt1, tyt2, urkunde LIMIT 0;
SHOW OPEN TABLES;
SHOW OPEN TABLES FROM mysql;
SHOW OPEN TABLES FROM mysql LIKE 'u%';
SHOW OPEN TABLES LIKE 't%';
SHOW OPEN TABLES LIKE '%o%';
FLUSH TABLES;
SHOW OPEN TABLES;
DROP TABLE txt1;
DROP TABLE tyt2;
DROP TABLE urkunde;
This diff is collapsed.
......@@ -2792,8 +2792,14 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
{
/* If we are on execution stage */
String *escape_str= escape_item->val_str(&tmp_value1);
/* ESCAPE must be 1 char in length.*/
if (escape_str && escape_str->numchars() != 1)
{
my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
return TRUE;
}
escape= escape_str ? *(escape_str->ptr()) : '\\';
/*
We could also do boyer-more for non-const items, but as we would have to
recompute the tables for each row it's not worth it.
......
......@@ -2176,6 +2176,9 @@ void Item_func_lpad::fix_length_and_dec()
{
ulonglong length= ((ulonglong) args[1]->val_int() *
collation.collation->mbmaxlen);
/*a comment before (merged) */
length= max((ulonglong)args[0]->max_length, length);
/*a comment after */
if (length >= MAX_BLOB_WIDTH)
{
length= MAX_BLOB_WIDTH;
......
......@@ -981,7 +981,7 @@ bool fill_record_n_invoke_before_triggers(THD *thd, Field **field,
bool ignore_errors,
Table_triggers_list *triggers,
enum trg_event_type event);
OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild);
OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild);
inline TABLE_LIST *find_table_in_global_list(TABLE_LIST *table,
const char *db_name,
......
This diff is collapsed.
......@@ -623,38 +623,37 @@ bool mysqld_help(THD *thd, const char *mask)
Protocol *protocol= thd->protocol;
SQL_SELECT *select;
st_find_field used_fields[array_elements(init_used_fields)];
DBUG_ENTER("mysqld_help");
TABLE_LIST *leaves= 0;
TABLE_LIST tables[4];
List<String> topics_list, categories_list, subcategories_list;
String name, description, example;
int count_topics, count_categories, error;
uint mlen= strlen(mask);
size_t i;
MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("mysqld_help");
bzero((gptr)tables,sizeof(tables));
tables[0].alias= tables[0].table_name= (char*) "help_topic";
tables[0].lock_type= TL_READ;
tables[0].next_global= tables[0].next_local= &tables[1];
tables[0].next_name_resolution_table= tables[0].next_local;
tables[0].next_global= tables[0].next_local=
tables[0].next_name_resolution_table= &tables[1];
tables[1].alias= tables[1].table_name= (char*) "help_category";
tables[1].lock_type= TL_READ;
tables[1].next_global= tables[1].next_local= &tables[2];
tables[1].next_name_resolution_table= tables[1].next_local;
tables[1].next_global= tables[1].next_local=
tables[1].next_name_resolution_table= &tables[2];
tables[2].alias= tables[2].table_name= (char*) "help_relation";
tables[2].lock_type= TL_READ;
tables[2].next_global= tables[2].next_local= &tables[3];
tables[2].next_name_resolution_table= tables[2].next_local;
tables[2].next_global= tables[2].next_local=
tables[2].next_name_resolution_table= &tables[3];
tables[3].alias= tables[3].table_name= (char*) "help_keyword";
tables[3].lock_type= TL_READ;
tables[0].db= tables[1].db= tables[2].db= tables[3].db= (char*) "mysql";
List<String> topics_list, categories_list, subcategories_list;
String name, description, example;
int count_topics, count_categories, error;
uint mlen= strlen(mask);
MEM_ROOT *mem_root= thd->mem_root;
if (open_and_lock_tables(thd, tables))
goto error;
/*
Init tables and fields to be usable from items
tables do not contain VIEWs => we can pass 0 as conds
*/
setup_tables(thd, &thd->lex->select_lex.context,
......@@ -663,7 +662,6 @@ bool mysqld_help(THD *thd, const char *mask)
memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
goto error;
size_t i;
for (i=0; i<sizeof(tables)/sizeof(TABLE_LIST); i++)
tables[i].table->file->init_table_handle_for_HANDLER();
......
......@@ -891,8 +891,9 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
if (select_lex->group_list.elements == 0)
{
context->table_list->next_local= save_next_local;
/* first_name_resolution_table was set by resolve_in_table_list_only() */
context->first_name_resolution_table->
next_name_resolution_table= save_next_local;
next_name_resolution_table= save_next_local;
}
if (!res)
res= setup_fields(thd, 0, update_values, 1, 0, 0);
......@@ -2199,8 +2200,9 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
if (lex->select_lex.group_list.elements == 0)
{
context->table_list->next_local= save_next_local;
/* first_name_resolution_table was set by resolve_in_table_list_only() */
context->first_name_resolution_table->
next_name_resolution_table= save_next_local;
next_name_resolution_table= save_next_local;
}
res= res || setup_fields(thd, 0, *info.update_values, 1, 0, 0);
......
......@@ -1867,8 +1867,8 @@ TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local)
*/
if ((*link_to_local= test(select_lex.table_list.first)))
{
select_lex.context.table_list= first->next_local;
select_lex.context.first_name_resolution_table= first->next_local;
select_lex.context.table_list=
select_lex.context.first_name_resolution_table= first->next_local;
select_lex.table_list.first= (byte*) (first->next_local);
select_lex.table_list.elements--; //safety
first->next_local= 0;
......
......@@ -3254,8 +3254,8 @@ end_with_restore_list:
/* Skip first table, which is the table we are inserting in */
TABLE_LIST *second_table= first_table->next_local;
select_lex->table_list.first= (byte*) second_table;
select_lex->context.table_list= second_table;
select_lex->context.first_name_resolution_table= second_table;
select_lex->context.table_list=
select_lex->context.first_name_resolution_table= second_table;
res= mysql_insert_select_prepare(thd);
if (!res && (result= new select_insert(first_table, first_table->table,
&lex->field_list,
......@@ -3270,8 +3270,8 @@ end_with_restore_list:
which in turn resets context.table_list and
context.first_name_resolution_table.
*/
select_lex->context.table_list= first_table->next_local;
select_lex->context.first_name_resolution_table= first_table->next_local;
select_lex->context.table_list=
select_lex->context.first_name_resolution_table= second_table;
res= handle_select(thd, lex, result, OPTION_SETUP_TABLES_DONE);
delete result;
}
......@@ -6013,6 +6013,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
char *alias_str;
LEX *lex= thd->lex;
DBUG_ENTER("add_table_to_list");
LINT_INIT(previous_table_ref);
if (!table)
DBUG_RETURN(0); // End of memory
......@@ -6108,9 +6109,23 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
/* Store the table reference preceding the current one. */
if (table_list.elements > 0)
{
previous_table_ref= (TABLE_LIST*) table_list.next;
/*
table_list.next points to the last inserted TABLE_LIST->next_local'
element
*/
previous_table_ref= (TABLE_LIST*) (table_list.next -
offsetof(TABLE_LIST, next_local));
DBUG_ASSERT(previous_table_ref);
/*
Set next_name_resolution_table of the previous table reference to point
to the current table reference. In effect the list
TABLE_LIST::next_name_resolution_table coincides with
TABLE_LIST::next_local. Later this may be changed in
store_top_level_join_columns() for NATURAL/USING joins.
*/
previous_table_ref->next_name_resolution_table= ptr;
}
/*
Link the current table reference in a local list (list for current select).
Notice that as a side effect here we set the next_local field of the
......@@ -6118,15 +6133,6 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
list 'table_list'.
*/
table_list.link_in_list((byte*) ptr, (byte**) &ptr->next_local);
/*
Set next_name_resolution_table of the previous table reference to point to
the current table reference. In effect the list
TABLE_LIST::next_name_resolution_table coincides with
TABLE_LIST::next_local. Later this may be changed in
store_top_level_join_columns() for NATURAL/USING joins.
*/
if (table_list.elements > 1)
previous_table_ref->next_name_resolution_table= ptr;
ptr->next_name_resolution_table= NULL;
/* Link table in global list (all used tables) */
lex->add_to_query_tables(ptr);
......@@ -6161,10 +6167,12 @@ bool st_select_lex::init_nested_join(THD *thd)
NESTED_JOIN *nested_join;
DBUG_ENTER("init_nested_join");
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))) ||
!(nested_join= ptr->nested_join=
(NESTED_JOIN *) thd->calloc(sizeof(NESTED_JOIN))))
if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
sizeof(NESTED_JOIN))))
DBUG_RETURN(1);
nested_join= ptr->nested_join=
((NESTED_JOIN*) ((byte*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
join_list->push_front(ptr);
ptr->embedding= embedding;
ptr->join_list= join_list;
......@@ -6232,25 +6240,30 @@ TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
The function nest last join operation as if it was enclosed in braces.
RETURN VALUE
Pointer to TABLE_LIST element created for the new nested join, if success
0, otherwise
0 Error
# Pointer to TABLE_LIST element created for the new nested join
*/
TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
{
TABLE_LIST *ptr;
NESTED_JOIN *nested_join;
List<TABLE_LIST> *embedded_list;
DBUG_ENTER("nest_last_join");
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))) ||
!(nested_join= ptr->nested_join=
(NESTED_JOIN *) thd->calloc(sizeof(NESTED_JOIN))))
if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
sizeof(NESTED_JOIN))))
DBUG_RETURN(0);
nested_join= ptr->nested_join=
((NESTED_JOIN*) ((byte*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
ptr->embedding= embedding;
ptr->join_list= join_list;
List<TABLE_LIST> *embedded_list= &nested_join->join_list;
embedded_list= &nested_join->join_list;
embedded_list->empty();
for (int i=0; i < 2; i++)
for (uint i=0; i < 2; i++)
{
TABLE_LIST *table= join_list->pop();
table->join_list= embedded_list;
......
......@@ -2513,6 +2513,8 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables,
{
table->field[10]->store((longlong) field->max_length() - 1);
table->field[10]->set_notnull();
table->field[11]->store((longlong) 0);
table->field[11]->set_notnull();
break;
}
case FIELD_TYPE_BIT:
......@@ -3189,7 +3191,8 @@ int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond)
TABLE *table= tables->table;
CHARSET_INFO *cs= system_charset_info;
OPEN_TABLE_LIST *open_list;
if (!(open_list=list_open_tables(thd,wild)) && thd->is_fatal_error)
if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
&& thd->is_fatal_error)
DBUG_RETURN(1);
for (; open_list ; open_list=open_list->next)
......
......@@ -120,42 +120,38 @@ static void make_unique_view_field_name(Item *target,
bool check_duplicate_names(List<Item> &item_list, bool gen_unique_view_name)
{
Item *item;
List_iterator_fast<Item> it(item_list);
List_iterator_fast<Item> itc(item_list);
DBUG_ENTER("check_duplicate_names");
/* Test absence of duplicates names */
while ((item= it++))
{
Item *item;
List_iterator_fast<Item> it(item_list);
List_iterator_fast<Item> itc(item_list);
while ((item= it++))
Item *check;
/* treat underlying fields like set by user names */
if (item->real_item()->type() == Item::FIELD_ITEM)
item->is_autogenerated_name= FALSE;
itc.rewind();
while ((check= itc++) && check != item)
{
Item *check;
/* treat underlying fields like set by user names */
if (item->real_item()->type() == Item::FIELD_ITEM)
item->is_autogenerated_name= FALSE;
itc.rewind();
while ((check= itc++) && check != item)
if (my_strcasecmp(system_charset_info, item->name, check->name) == 0)
{
if (my_strcasecmp(system_charset_info, item->name, check->name) == 0)
{
if (!gen_unique_view_name)
{
my_error(ER_DUP_FIELDNAME, MYF(0), item->name);
DBUG_RETURN(TRUE);
}
else if (item->is_autogenerated_name)
make_unique_view_field_name(item, item_list, item);
else if (check->is_autogenerated_name)
make_unique_view_field_name(check, item_list, item);
else
{
my_error(ER_DUP_FIELDNAME, MYF(0), item->name);
DBUG_RETURN(TRUE);
}
}
if (!gen_unique_view_name)
goto err;
if (item->is_autogenerated_name)
make_unique_view_field_name(item, item_list, item);
else if (check->is_autogenerated_name)
make_unique_view_field_name(check, item_list, item);
else
goto err;
}
}
}
DBUG_RETURN(FALSE);
err:
my_error(ER_DUP_FIELDNAME, MYF(0), item->name);
DBUG_RETURN(TRUE);
}
......
......@@ -8681,8 +8681,10 @@ union_list:
}
select_init
{
/* Remove from the name resolution context stack the context of the
last select in the union. */
/*
Remove from the name resolution context stack the context of the
last select in the union.
*/
Lex->pop_context();
}
;
......
......@@ -2186,21 +2186,24 @@ bool st_table_list::is_leaf_for_name_resolution()
reverse order.
RETURN
- If 'this' is a nested table reference - the left-most child of
If 'this' is a nested table reference - the left-most child of
the tree rooted in 'this',
- else - 'this'
else return 'this'
*/
TABLE_LIST *st_table_list::first_leaf_for_name_resolution()
{
TABLE_LIST *cur_table_ref= this;
TABLE_LIST *next;
NESTED_JOIN *cur_nested_join= nested_join;
TABLE_LIST *cur_table_ref;
NESTED_JOIN *cur_nested_join;
LINT_INIT(cur_table_ref);
if (this->is_leaf_for_name_resolution())
if (is_leaf_for_name_resolution())
return this;
DBUG_ASSERT(nested_join);
while (cur_nested_join)
for (cur_nested_join= nested_join;
cur_nested_join;
cur_nested_join= cur_table_ref->nested_join)
{
List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
cur_table_ref= it++;
......@@ -2210,12 +2213,12 @@ TABLE_LIST *st_table_list::first_leaf_for_name_resolution()
*/
if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
{
TABLE_LIST *next;
while ((next= it++))
cur_table_ref= next;
}
if (cur_table_ref->is_leaf_for_name_resolution())
break;
cur_nested_join= cur_table_ref->nested_join;
}
return cur_table_ref;
}
......@@ -2247,13 +2250,16 @@ TABLE_LIST *st_table_list::first_leaf_for_name_resolution()
TABLE_LIST *st_table_list::last_leaf_for_name_resolution()
{
TABLE_LIST *cur_table_ref= this;
TABLE_LIST *next;
NESTED_JOIN *cur_nested_join= nested_join;
NESTED_JOIN *cur_nested_join;
LINT_INIT(cur_table_ref);
if (this->is_leaf_for_name_resolution())
if (is_leaf_for_name_resolution())
return this;
DBUG_ASSERT(nested_join);
while (cur_nested_join)
for (cur_nested_join= nested_join;
cur_nested_join;
cur_nested_join= cur_table_ref->nested_join)
{
/*
If 'this' is a RIGHT JOIN, the operands in 'join_list' are in reverse
......@@ -2262,6 +2268,7 @@ TABLE_LIST *st_table_list::last_leaf_for_name_resolution()
if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
{
List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
TABLE_LIST *next;
cur_table_ref= it++;
while ((next= it++))
cur_table_ref= next;
......@@ -2270,7 +2277,6 @@ TABLE_LIST *st_table_list::last_leaf_for_name_resolution()
cur_table_ref= cur_nested_join->join_list.head();
if (cur_table_ref->is_leaf_for_name_resolution())
break;
cur_nested_join= cur_table_ref->nested_join;
}
return cur_table_ref;
}
......@@ -2306,11 +2312,8 @@ const char *Natural_join_column::name()
DBUG_ASSERT(table_field == NULL);
return view_field->name;
}
else
{
DBUG_ASSERT(view_field == NULL);
return table_field->field_name;
}
return table_field->field_name;
}
......@@ -2319,13 +2322,10 @@ Item *Natural_join_column::create_item(THD *thd)
if (view_field)
{
DBUG_ASSERT(table_field == NULL);
return create_view_field(thd, table_ref, &view_field->item, view_field->name);
}
else
{
DBUG_ASSERT(view_field == NULL);
return new Item_field(thd, &thd->lex->current_select->context, table_field);
return create_view_field(thd, table_ref, &view_field->item,
view_field->name);
}
return new Item_field(thd, &thd->lex->current_select->context, table_field);
}
......@@ -2336,31 +2336,29 @@ Field *Natural_join_column::field()
DBUG_ASSERT(table_field == NULL);
return NULL;
}
else
{
DBUG_ASSERT(view_field == NULL);
return table_field;
}
return table_field;
}
const char *Natural_join_column::table_name()
{
return table_ref->alias;
/*
TODO: I think that it is sufficient to return just
table->alias, which is correctly set to either
the view name, the table name, or the alias to
the table reference (view or stored table).
/*
TODO:
I think that it is sufficient to return just
table->alias, which is correctly set to either
the view name, the table name, or the alias to
the table reference (view or stored table).
*/
#ifdef NOT_YET
if (view_field)
return table_ref->view_name.str;
else
{
DBUG_ASSERT(!strcmp(table_ref->table_name,
table_ref->table->s->table_name));
return table_ref->table_name;
}
*/
DBUG_ASSERT(!strcmp(table_ref->table_name,
table_ref->table->s->table_name));
return table_ref->table_name;
}
#endif
}
......@@ -2368,12 +2366,10 @@ const char *Natural_join_column::db_name()
{
if (view_field)
return table_ref->view_db.str;
else
{
DBUG_ASSERT(!strcmp(table_ref->db,
table_ref->table->s->db));
return table_ref->db;
}
DBUG_ASSERT(!strcmp(table_ref->db,
table_ref->table->s->db));
return table_ref->db;
}
......@@ -2381,8 +2377,7 @@ GRANT_INFO *Natural_join_column::grant()
{
if (view_field)
return &(table_ref->grant);
else
return &(table_ref->table->grant);
return &(table_ref->table->grant);
}
......@@ -2402,16 +2397,17 @@ GRANT_INFO *Natural_join_column::grant()
it is a view or a stored table colum.
RETURN
FALSE - if the column can be accessed
TRUE - if there are no access rights to all equivalent columns
FALSE The column can be accessed
TRUE There are no access rights to all equivalent columns
*/
bool
Natural_join_column::check_grants(THD *thd, const char *name, uint length)
{
GRANT_INFO *grant= NULL; /* If NULL do not check access rights. */
GRANT_INFO *grant;
const char *db_name;
const char *table_name;
if (view_field)
{
DBUG_ASSERT(table_field == NULL);
......@@ -2544,7 +2540,6 @@ void Field_iterator_table_ref::set_field_iterator()
(!table_ref->field_translation &&
table_ref->join_columns->elements ==
table_ref->table->s->fields)));
natural_join_it.set(table_ref);
field_it= &natural_join_it;
DBUG_PRINT("info",("field_it for '%s' is Field_iterator_natural_join",
table_ref->table_name));
......@@ -2554,7 +2549,6 @@ void Field_iterator_table_ref::set_field_iterator()
{
DBUG_ASSERT(table_ref->view &&
table_ref->effective_algorithm == VIEW_ALGORITHM_MERGE);
view_field_it.set(table_ref);
field_it= &view_field_it;
DBUG_PRINT("info", ("field_it for '%s' is Field_iterator_view",
table_ref->table_name));
......@@ -2563,12 +2557,11 @@ void Field_iterator_table_ref::set_field_iterator()
else
{
DBUG_ASSERT(table_ref->table || table_ref->view);
table_field_it.set(table_ref);
field_it= &table_field_it;
DBUG_PRINT("info", ("field_it for '%s' is Field_iterator_table",
table_ref->table_name));
}
field_it->set(table_ref);
DBUG_VOID_RETURN;
}
......@@ -2607,12 +2600,10 @@ const char *Field_iterator_table_ref::table_name()
return table_ref->view_name.str;
else if (table_ref->is_natural_join)
return natural_join_it.column_ref()->table_name();
else
{
DBUG_ASSERT(!strcmp(table_ref->table_name,
table_ref->table->s->table_name));
return table_ref->table_name;
}
DBUG_ASSERT(!strcmp(table_ref->table_name,
table_ref->table->s->table_name));
return table_ref->table_name;
}
......@@ -2622,11 +2613,9 @@ const char *Field_iterator_table_ref::db_name()
return table_ref->view_db.str;
else if (table_ref->is_natural_join)
return natural_join_it.column_ref()->db_name();
else
{
DBUG_ASSERT(!strcmp(table_ref->db, table_ref->table->s->db));
return table_ref->db;
}
DBUG_ASSERT(!strcmp(table_ref->db, table_ref->table->s->db));
return table_ref->db;
}
......@@ -2636,8 +2625,7 @@ GRANT_INFO *Field_iterator_table_ref::grant()
return &(table_ref->grant);
else if (table_ref->is_natural_join)
return natural_join_it.column_ref()->grant();
else
return &(table_ref->table->grant);
return &(table_ref->table->grant);
}
......@@ -2645,8 +2633,7 @@ bool Field_iterator_table_ref::is_coalesced()
{
if (table_ref->is_natural_join)
return natural_join_it.column_ref()->is_coalesced;
else
return FALSE;
return FALSE;
}
/*
......@@ -2663,29 +2650,30 @@ bool Field_iterator_table_ref::is_coalesced()
TODO
RETURN
Pointer to a column of a natural join (or its operand)
NULL if there was no memory to allocate the column
# Pointer to a column of a natural join (or its operand)
NULL No memory to allocate the column
*/
Natural_join_column *
Field_iterator_table_ref::get_or_create_column_ref(THD *thd, bool *is_created)
{
Natural_join_column *nj_col;
*is_created= TRUE;
if (field_it == &table_field_it)
return new Natural_join_column(table_field_it.field(), table_ref);
else if (field_it == &view_field_it)
return new Natural_join_column(view_field_it.field_translator(), table_ref);
else
{
/*
This is NATURAL join, we already have created a column reference,
so just return it.
*/
*is_created= FALSE;
Natural_join_column *nj_col= natural_join_it.column_ref();
DBUG_ASSERT(nj_col);
return nj_col;
}
if (field_it == &view_field_it)
return new Natural_join_column(view_field_it.field_translator(),
table_ref);
/*
This is NATURAL join, we already have created a column reference,
so just return it.
*/
*is_created= FALSE;
nj_col= natural_join_it.column_ref();
DBUG_ASSERT(nj_col);
return nj_col;
}
......
......@@ -374,7 +374,7 @@ struct Field_translator
Field (for tables), or a Field_translator (for views).
*/
class Natural_join_column
class Natural_join_column: public Sql_alloc
{
public:
Field_translator *view_field; /* Column reference of merge view. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment