Merge mysql.com:/home/jonas/src/mysql-5.0

into mysql.com:/home/jonas/src/mysql-5.0-ndb


ndb/src/kernel/blocks/dbtc/DbtcMain.cpp:
  Auto merged
This commit is contained in:
unknown 2005-02-06 10:47:42 +01:00
commit 721d763496
36 changed files with 379 additions and 104 deletions

View file

@ -195,7 +195,7 @@ static void usage(void)
puts("and you are welcome to modify and redistribute it under the GPL license.\n");
puts("This program can be used to CHECK (-c,-m,-C), REPAIR (-r), ANALYZE (-a)");
puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be");
puts("used at the same time. It works on MyISAM and in some cases on BDB tables.");
puts("used at the same time. Not all options are supported by all storage engines.");
puts("Please consult the MySQL manual for latest information about the");
puts("above. The options -c,-r,-a and -o are exclusive to each other, which");
puts("means that the last option will be used, if several was specified.\n");

View file

@ -918,9 +918,11 @@ if test "$ac_cv_header_termio_h" = "no" -a "$ac_cv_header_termios_h" = "no"
then
AC_CHECK_FUNC(gtty, , AC_CHECK_LIB(compat, gtty))
fi
# We make a special variable for client library's to avoid including
# thread libs in the client.
NON_THREADED_CLIENT_LIBS="$LIBS $ZLIB_LIBS"
# We make a special variable for non-threaded version of LIBS to avoid
# including thread libs into non-threaded version of MySQL client library.
# Later in this script LIBS will be augmented with a threads library.
NON_THREADED_LIBS="$LIBS"
AC_MSG_CHECKING([for int8])
case $SYSTEM_TYPE in
@ -1497,7 +1499,7 @@ then
if test -f /usr/lib/libxnet.so -a "$SYSTEM_TYPE" = "sni-sysv4"
then
LIBS="-lxnet $LIBS"
NON_THREADED_CLIENT_LIBS="$NON_THREADED_CLIENT_LIBS -lxnet"
NON_THREADED_LIBS="-lxnet $NON_THREADED_LIBS"
with_named_thread="-Kthread $LDFLAGS -lxnet"
LD_FLAGS=""
CFLAGS="-Kthread $CFLAGS"
@ -2444,7 +2446,7 @@ dnl This probably should be cleaned up more - for now the threaded
dnl client is just using plain-old libs.
sql_client_dirs="libmysql strings regex client"
linked_client_targets="linked_libmysql_sources"
CLIENT_LIBS=$NON_THREADED_CLIENT_LIBS
if test "$THREAD_SAFE_CLIENT" != "no"
then
sql_client_dirs="libmysql_r $sql_client_dirs"
@ -2452,9 +2454,11 @@ then
AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should be client be thread safe])
fi
CLIENT_LIBS="$CLIENT_LIBS $STATIC_NSS_FLAGS"
CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS"
AC_SUBST(CLIENT_LIBS)
AC_SUBST(NON_THREADED_LIBS)
AC_SUBST(STATIC_NSS_FLAGS)
AC_SUBST(sql_client_dirs)
AC_SUBST(linked_client_targets)

View file

@ -62,7 +62,7 @@ void ft_free_stopwords(void);
#define FT_SORTED 2
#define FT_EXPAND 4 /* query expansion */
FT_INFO *ft_init_search(uint,void *, uint, byte *, uint, byte *);
FT_INFO *ft_init_search(uint,void *, uint, byte *, uint,CHARSET_INFO *, byte *);
my_bool ft_boolean_check_syntax_string(const byte *);
#ifdef __cplusplus

View file

@ -366,6 +366,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
reset_tree(& ftb->no_dupes);
}
ftbw->off=0; /* in case of reinit */
if (_ft2_search(ftb, ftbw, 1))
return;
}
@ -374,7 +375,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
uint query_len)
uint query_len, CHARSET_INFO *cs)
{
FTB *ftb;
FTB_EXPR *ftbe;
@ -386,8 +387,8 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
ftb->state=UNINITIALIZED;
ftb->info=info;
ftb->keynr=keynr;
ftb->charset= ((keynr==NO_SUCH_KEY) ?
default_charset_info : info->s->keyinfo[keynr].seg->charset);
ftb->charset=cs;
DBUG_ASSERT(keynr==NO_SUCH_KEY || cs == info->s->keyinfo[keynr].seg->charset);
ftb->with_scan=0;
ftb->lastpos=HA_OFFSET_ERROR;
bzero(& ftb->no_dupes, sizeof(TREE));

View file

@ -57,11 +57,12 @@ const struct _ft_vft _ft_vft_boolean = {
FT_INFO *ft_init_search(uint flags, void *info, uint keynr,
byte *query, uint query_len, byte *record)
byte *query, uint query_len, CHARSET_INFO *cs,
byte *record)
{
FT_INFO *res;
if (flags & FT_BOOL)
res= ft_init_boolean_search((MI_INFO *)info, keynr, query, query_len);
res= ft_init_boolean_search((MI_INFO *)info, keynr, query, query_len,cs);
else
res= ft_init_nlq_search((MI_INFO *)info, keynr, query, query_len, flags,
record);

View file

@ -131,7 +131,7 @@ FT_WORD * _mi_ft_parserecord(MI_INFO *, uint, const byte *);
uint _mi_ft_parse(TREE *, MI_INFO *, uint, const byte *, my_bool);
FT_INFO *ft_init_nlq_search(MI_INFO *, uint, byte *, uint, uint, byte *);
FT_INFO *ft_init_boolean_search(MI_INFO *, uint, byte *, uint);
FT_INFO *ft_init_boolean_search(MI_INFO *, uint, byte *, uint, CHARSET_INFO *);
extern const struct _ft_vft _ft_vft_nlq;
int ft_nlq_read_next(FT_INFO *, char *);

View file

@ -1,7 +1,9 @@
reset master;
create database `drop-temp+table-test`;
use `drop-temp+table-test`;
create temporary table shortn1 (a int);
create temporary table `table:name` (a int);
create temporary table shortn2 (a int);
select get_lock("a",10);
get_lock("a",10)
1
@ -10,9 +12,13 @@ get_lock("a",10)
1
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 4 Format_desc 1 95 Server ver: VERSION, Binlog ver: 4
master-bin.000001 95 Query 1 213 create database `drop-temp+table-test`
master-bin.000001 213 Query 1 336 use `drop-temp+table-test`; create temporary table `table:name` (a int)
master-bin.000001 336 Query 1 494 use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`table:name`
master-bin.000001 494 Query 1 594 use `drop-temp+table-test`; DO RELEASE_LOCK("a")
master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
master-bin.000001 # Query 1 # create database `drop-temp+table-test`
master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn1 (a int)
master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table `table:name` (a int)
master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn2 (a int)
master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`shortn2`
master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`table:name`
master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`shortn1`
master-bin.000001 # Query 1 # use `drop-temp+table-test`; DO RELEASE_LOCK("a")
drop database `drop-temp+table-test`;

View file

@ -737,3 +737,15 @@ one 2
two 2
three 1
drop table t1;
create table t1(f1 datetime);
insert into t1 values (now());
create table t2 select f2 from (select max(now()) f2 from t1) a;
show columns from t2;
Field Type Null Key Default Extra
f2 datetime NO 0000-00-00 00:00:00
drop table t2;
create table t2 select f2 from (select now() f2 from t1) a;
show columns from t2;
Field Type Null Key Default Extra
f2 datetime NO 0000-00-00 00:00:00
drop table t2, t1;

View file

@ -633,3 +633,15 @@ No Field Count
0 1 100
0 2 100
drop table t1, t2;
CREATE TABLE t1 (
ID int(11) NOT NULL auto_increment,
NO int(11) NOT NULL default '0',
SEQ int(11) NOT NULL default '0',
PRIMARY KEY (ID),
KEY t1$NO (SEQ,NO)
) ENGINE=MyISAM;
INSERT INTO t1 (SEQ, NO) SELECT "1" AS SEQ, IF(MAX(NO) IS NULL, 0, MAX(NO)) + 1 AS NO FROM t1 WHERE (SEQ = 1);
select SQL_BUFFER_RESULT * from t1 WHERE (SEQ = 1);
ID NO SEQ
1 1 1
drop table t1;

View file

@ -96,3 +96,11 @@ f2
19781126
19781126
DROP TABLE t1, t2, t3;
CREATE TABLE t1 (y YEAR);
INSERT INTO t1 VALUES ('abc');
Warnings:
Warning 1264 Out of range value adjusted for column 'y' at row 1
SELECT * FROM t1;
y
0000
DROP TABLE t1;

View file

@ -1137,3 +1137,39 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
drop table t2;
create table t1(a1 int, f1 char(10));
create table t2
select f2,a1 from (select a1, CAST('2004-12-31' AS DATE) f2 from t1) a
union
select f2,a1 from (select a1, CAST('2004-12-31' AS DATE) f2 from t1) a
order by f2, a1;
show columns from t2;
Field Type Null Key Default Extra
f2 date YES NULL
a1 int(11) YES NULL
drop table t1, t2;
create table t1 (f1 int);
create table t2 (f1 int, f2 int ,f3 date);
create table t3 (f1 int, f2 char(10));
create table t4
(
select t2.f3 as sdate
from t1
left outer join t2 on (t1.f1 = t2.f1)
inner join t3 on (t2.f2 = t3.f1)
order by t1.f1, t3.f1, t2.f3
)
union
(
select cast('2004-12-31' as date) as sdate
from t1
left outer join t2 on (t1.f1 = t2.f1)
inner join t3 on (t2.f2 = t3.f1)
group by t1.f1
order by t1.f1, t3.f1, t2.f3
)
order by sdate;
show columns from t4;
Field Type Null Key Default Extra
sdate date YES NULL
drop table t1, t2, t3, t4;

View file

@ -4,7 +4,9 @@ connection con1;
reset master;
create database `drop-temp+table-test`;
use `drop-temp+table-test`;
create temporary table shortn1 (a int);
create temporary table `table:name` (a int);
create temporary table shortn2 (a int);
select get_lock("a",10);
disconnect con1;
@ -15,5 +17,6 @@ connection con2;
select get_lock("a",10);
let $VERSION=`select version()`;
--replace_result $VERSION VERSION
--replace_column 2 # 5 #
show binlog events;
drop database `drop-temp+table-test`;

View file

@ -473,3 +473,17 @@ INSERT INTO t1 VALUES
select val, count(*) from t1 group by val;
drop table t1;
#
# Bug 7833: Wrong datatype of aggregate column is returned
#
create table t1(f1 datetime);
insert into t1 values (now());
create table t2 select f2 from (select max(now()) f2 from t1) a;
show columns from t2;
drop table t2;
create table t2 select f2 from (select now() f2 from t1) a;
show columns from t2;
drop table t2, t1;

View file

@ -107,3 +107,10 @@ SELECT * FROM t2;
SELECT * FROM t3;
DROP TABLE t1, t2, t3;
# Test that setting YEAR to invalid string results in default value, not
# 2000. (Bug #6067)
CREATE TABLE t1 (y YEAR);
INSERT INTO t1 VALUES ('abc');
SELECT * FROM t1;
DROP TABLE t1;

View file

@ -682,3 +682,38 @@ show create table t1;
drop table t1;
drop table t2;
#
# Bug 6931: Date Type column problem when using UNION-Table.
#
create table t1(a1 int, f1 char(10));
create table t2
select f2,a1 from (select a1, CAST('2004-12-31' AS DATE) f2 from t1) a
union
select f2,a1 from (select a1, CAST('2004-12-31' AS DATE) f2 from t1) a
order by f2, a1;
show columns from t2;
drop table t1, t2;
create table t1 (f1 int);
create table t2 (f1 int, f2 int ,f3 date);
create table t3 (f1 int, f2 char(10));
create table t4
(
select t2.f3 as sdate
from t1
left outer join t2 on (t1.f1 = t2.f1)
inner join t3 on (t2.f2 = t3.f1)
order by t1.f1, t3.f1, t2.f3
)
union
(
select cast('2004-12-31' as date) as sdate
from t1
left outer join t2 on (t1.f1 = t2.f1)
inner join t3 on (t2.f2 = t3.f1)
group by t1.f1
order by t1.f1, t3.f1, t2.f3
)
order by sdate;
show columns from t4;
drop table t1, t2, t3, t4;

View file

@ -8817,13 +8817,14 @@ void Dblqh::finishScanrec(Signal* signal)
return;
}
ndbrequire(restart.p->scanState == ScanRecord::IN_QUEUE);
ScanRecordPtr tmpScan = scanptr;
TcConnectionrecPtr tmpTc = tcConnectptr;
tcConnectptr.i = restart.p->scanTcrec;
ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
restart.p->scanNumber = scanNumber;
restart.p->scanState = ScanRecord::WAIT_ACC_SCAN;
queue.remove(restart);
scans.add(restart);
@ -8838,10 +8839,18 @@ void Dblqh::finishScanrec(Signal* signal)
ndbout_c("adding-r (%d %d)", restart.p->scanNumber, restart.p->fragPtrI);
#endif
}
scanptr = restart;
continueAfterReceivingAllAiLab(signal);
restart.p->scanState = ScanRecord::SCAN_FREE; // set in initScanRec
if(tcConnectptr.p->transactionState == TcConnectionrec::SCAN_STATE_USED)
{
jam();
scanptr = restart;
continueAfterReceivingAllAiLab(signal);
}
else
{
ndbrequire(tcConnectptr.p->transactionState == TcConnectionrec::WAIT_SCAN_AI);
}
scanptr = tmpScan;
tcConnectptr = tmpTc;
}//Dblqh::finishScanrec()

View file

@ -9220,6 +9220,8 @@ void Dbtc::execDIGETPRIMCONF(Signal* signal)
scanFragptr.p->lqhBlockref = ref;
scanFragptr.p->m_connectCount = getNodeInfo(tnodeid).m_connectCount;
sendScanFragReq(signal, scanptr.p, scanFragptr.p);
if(ERROR_INSERTED(8035))
globalTransporterRegistry.performSend();
attrbufptr.i = cachePtr.p->firstAttrbuf;
while (attrbufptr.i != RNIL) {
jam();
@ -9229,6 +9231,8 @@ void Dbtc::execDIGETPRIMCONF(Signal* signal)
attrbufptr.p,
ref);
attrbufptr.i = attrbufptr.p->attrbuf[ZINBUF_NEXT];
if(ERROR_INSERTED(8035))
globalTransporterRegistry.performSend();
}//while
scanFragptr.p->scanFragState = ScanFragRec::LQH_ACTIVE;
scanFragptr.p->startFragTimer(ctcTimer);

View file

@ -35,7 +35,8 @@ getTable(Ndb* pNdb, int i){
int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
int records = ctx->getNumRecords();
int records = ctx->getProperty("Rows", ctx->getNumRecords());
HugoTransactions hugoTrans(*ctx->getTab());
if (hugoTrans.loadTable(GETNDB(step), records) != 0){
return NDBT_FAILED;
@ -264,7 +265,7 @@ int runVerifyTable(NDBT_Context* ctx, NDBT_Step* step){
int runScanRead(NDBT_Context* ctx, NDBT_Step* step){
int loops = ctx->getNumLoops();
int records = ctx->getNumRecords();
int records = ctx->getProperty("Rows", ctx->getNumRecords());
int parallelism = ctx->getProperty("Parallelism", 240);
int abort = ctx->getProperty("AbortProb", 5);
@ -375,7 +376,20 @@ int runScanReadError(NDBT_Context* ctx, NDBT_Step* step){
restarter.insertErrorInAllNodes(0);
return result;
}
int
runInsertError(NDBT_Context* ctx, NDBT_Step* step){
int error = ctx->getProperty("ErrorCode");
NdbRestarter restarter;
ctx->setProperty("ErrorCode", (Uint32)0);
if (restarter.insertErrorInAllNodes(error) != 0){
ndbout << "Could not insert error in all nodes "<<endl;
return NDBT_FAILED;
}
return NDBT_OK;
}
int runScanReadErrorOneNode(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
int loops = ctx->getNumLoops();
@ -1258,6 +1272,16 @@ TESTCASE("ScanRead100",
STEPS(runScanRead, 100);
FINALIZER(runClearTable);
}
TESTCASE("Scan-bug8262",
""){
TC_PROPERTY("Rows", 1);
TC_PROPERTY("ErrorCode", 8035);
INITIALIZER(runLoadTable);
INITIALIZER(runInsertError); // Will reset error code
STEPS(runScanRead, 25);
FINALIZER(runInsertError);
FINALIZER(runClearTable);
}
TESTCASE("ScanRead40RandomTable",
"Verify scan requirement: Scan with 40 simultaneous threads. "\
"Use random table for the scan"){

View file

@ -353,6 +353,10 @@ max-time: 500
cmd: testScan
args: -n ScanRestart T1
max-time: 500
cmd: testScan
args: -l 100 -n Scan-bug8262 T7
max-time: 500
cmd: testScan
args: -n ScanParallelism

View file

@ -140,6 +140,9 @@ SUFFIXES = .sh
-e 's!@''IS_LINUX''@!@IS_LINUX@!' \
-e "s!@""CONF_COMMAND""@!@CONF_COMMAND@!" \
-e 's!@''MYSQLD_USER''@!@MYSQLD_USER@!' \
-e 's!@''STATIC_NSS_FLAGS''@!@STATIC_NSS_FLAGS@!' \
-e 's!@''NON_THREADED_LIBS''@!@NON_THREADED_LIBS@!' \
-e 's!@''ZLIB_DEPS''@!@ZLIB_DEPS@!' \
-e "s!@MAKE@!$(MAKE)!" \
$< > $@-t
@CHMOD@ +x $@-t

View file

@ -221,7 +221,7 @@ $CP mysql-test/std_data/*.dat mysql-test/std_data/*.frm \
mysql-test/std_data/des_key_file mysql-test/std_data/*.*001 \
$BASE/mysql-test/std_data
$CP mysql-test/t/*test mysql-test/t/*.opt mysql-test/t/*.slave-mi mysql-test/t/*.sh $BASE/mysql-test/t
$CP mysql-test/r/*result mysql-test/r/*.require $BASE/mysql-test/r
$CP mysql-test/r/*result mysql-test/r/*result.es mysql-test/r/*.require $BASE/mysql-test/r
if [ $BASE_SYSTEM != "netware" ] ; then
chmod a+x $BASE/bin/*

View file

@ -82,13 +82,14 @@ version='@VERSION@'
socket='@MYSQL_UNIX_ADDR@'
port='@MYSQL_TCP_PORT@'
ldflags='@LDFLAGS@'
client_libs='@CLIENT_LIBS@'
# Create options
libs="$ldflags -L$pkglibdir -lmysqlclient $client_libs"
libs="$ldflags -L$pkglibdir -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@"
libs=`echo "$libs" | sed -e 's; \+; ;g' | sed -e 's;^ *;;' | sed -e 's; *\$;;'`
libs_r="$ldflags -L$pkglibdir -lmysqlclient_r @LIBS@ @ZLIB_LIBS@ @openssl_libs@"
libs_r="$ldflags -L$pkglibdir -lmysqlclient_r @ZLIB_DEPS@ @LIBS@ @openssl_libs@"
libs_r=`echo "$libs_r" | sed -e 's; \+; ;g' | sed -e 's;^ *;;' | sed -e 's; *\$;;'`
cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
include="-I$pkgincludedir"

View file

@ -261,6 +261,7 @@ static Field::field_cast_enum field_cast_date[]=
Field::FIELD_CAST_BLOB, Field::FIELD_CAST_STOP};
static Field::field_cast_enum field_cast_newdate[]=
{Field::FIELD_CAST_NEWDATE,
Field::FIELD_CAST_DATE,
Field::FIELD_CAST_DATETIME,
Field::FIELD_CAST_STRING, Field::FIELD_CAST_VARSTRING,
Field::FIELD_CAST_BLOB, Field::FIELD_CAST_STOP};
@ -6834,6 +6835,40 @@ Field *make_field(char *ptr, uint32 field_length,
}
/*
Check if field_type is appropriate field type
to create field for tmp table using
item->tmp_table_field() method
SYNOPSIS
field_types_to_be_kept()
field_type - field type
NOTE
it is used in function get_holder_example_field()
from item.cc
RETURN
1 - can use item->tmp_table_field() method
0 - can not use item->tmp_table_field() method
*/
bool field_types_to_be_kept(enum_field_types field_type)
{
switch (field_type)
{
case FIELD_TYPE_DATE:
case FIELD_TYPE_NEWDATE:
case FIELD_TYPE_TIME:
case FIELD_TYPE_DATETIME:
return 1;
default:
return 0;
}
}
/* Create a field suitable for create of table */
create_field::create_field(Field *old_field,Field *orig_field)

View file

@ -1333,6 +1333,7 @@ enum_field_types get_blob_type_from_length(ulong length);
uint32 calc_pack_length(enum_field_types type,uint32 length);
int set_field_to_null(Field *field);
int set_field_to_null_with_conversions(Field *field, bool no_conversions);
bool field_types_to_be_kept(enum_field_types field_type);
/*
The following are for the interface with the .frm file

View file

@ -88,8 +88,12 @@ class ha_myisam: public handler
ft_handler->please->reinit_search(ft_handler);
return 0;
}
FT_INFO *ft_init_ext(uint flags, uint inx,const byte *key, uint keylen)
{ return ft_init_search(flags,file,inx,(byte*) key,keylen, table->record[0]); }
FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
{
return ft_init_search(flags,file,inx,
(byte *)key->ptr(), key->length(), key->charset(),
table->record[0]);
}
int ft_read(byte *buf);
int rnd_init(bool scan);
int rnd_next(byte *buf);

View file

@ -455,8 +455,7 @@ public:
int compare_key(key_range *range);
virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
void ft_end() { ft_handler=NULL; }
virtual FT_INFO *ft_init_ext(uint flags,uint inx,const byte *key,
uint keylen)
virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
{ return NULL; }
virtual int ft_read(byte *buf) { return HA_ERR_WRONG_COMMAND; }
virtual int rnd_next(byte *buf)=0;

View file

@ -3633,7 +3633,53 @@ void Item_cache_row::bring_value()
}
Item_type_holder::Item_type_holder(THD *thd, Item *item)
/*
Returns field for temporary table dependind on item type
SYNOPSIS
get_holder_example_field()
thd - thread handler
item - pointer to item
table - empty table object
NOTE
It is possible to return field for Item_func
items only if field type of this item is
date or time or datetime type.
also see function field_types_to_be_kept() from
field.cc
RETURN
# - field
0 - no field
*/
Field *get_holder_example_field(THD *thd, Item *item, TABLE *table)
{
DBUG_ASSERT(table);
Item_func *tmp_item= 0;
if (item->type() == Item::FIELD_ITEM)
return (((Item_field*) item)->field);
if (item->type() == Item::FUNC_ITEM)
tmp_item= (Item_func *) item;
else if (item->type() == Item::SUM_FUNC_ITEM)
{
Item_sum *item_sum= (Item_sum *) item;
if (item_sum->keep_field_type())
{
if (item_sum->args[0]->type() == Item::FIELD_ITEM)
return (((Item_field*) item_sum->args[0])->field);
if (item_sum->args[0]->type() == Item::FUNC_ITEM)
tmp_item= (Item_func *) item_sum->args[0];
}
}
return (tmp_item && field_types_to_be_kept(tmp_item->field_type()) ?
tmp_item->tmp_table_field(table) : 0);
}
Item_type_holder::Item_type_holder(THD *thd, Item *item, TABLE *table)
:Item(thd, item), item_type(item->result_type()),
orig_type(item_type)
{
@ -3643,10 +3689,7 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item)
It is safe assign pointer on field, because it will be used just after
all JOIN::prepare calls and before any SELECT execution
*/
if (item->type() == Item::FIELD_ITEM)
field_example= ((Item_field*) item)->field;
else
field_example= 0;
field_example= get_holder_example_field(thd, item, table);
max_length= real_length(item);
maybe_null= item->maybe_null;
collation.set(item->collation);
@ -3686,25 +3729,23 @@ inline bool is_attr_compatible(Item *from, Item *to)
(to->maybe_null || !from->maybe_null) &&
(to->result_type() != STRING_RESULT ||
from->result_type() != STRING_RESULT ||
my_charset_same(from->collation.collation,
to->collation.collation)));
(from->collation.collation == to->collation.collation)));
}
bool Item_type_holder::join_types(THD *thd, Item *item)
bool Item_type_holder::join_types(THD *thd, Item *item, TABLE *table)
{
uint32 new_length= real_length(item);
bool use_new_field= 0, use_expression_type= 0;
Item_result new_result_type= type_convertor[item_type][item->result_type()];
bool item_is_a_field= item->type() == Item::FIELD_ITEM;
Field *field= get_holder_example_field(thd, item, table);
bool item_is_a_field= field;
/*
Check if both items point to fields: in this case we
can adjust column types of result table in the union smartly.
*/
if (field_example && item_is_a_field)
{
Field *field= ((Item_field *)item)->field;
/* Can 'field_example' field store data of the column? */
if ((use_new_field=
(!field->field_cast_compatible(field_example->field_cast_type()) ||
@ -3745,7 +3786,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
It is safe to assign a pointer to field here, because it will be used
before any table is closed.
*/
field_example= ((Item_field*) item)->field;
field_example= field;
}
old_cs= collation.collation->name;

View file

@ -1579,14 +1579,14 @@ protected:
Item_result orig_type;
Field *field_example;
public:
Item_type_holder(THD*, Item*);
Item_type_holder(THD*, Item*, TABLE *);
Item_result result_type () const { return item_type; }
enum Type type() const { return TYPE_HOLDER; }
double val_real();
longlong val_int();
String *val_str(String*);
bool join_types(THD *thd, Item *);
bool join_types(THD *thd, Item *, TABLE *);
Field *example() { return field_example; }
static uint32 real_length(Item *item);
void cleanup()

View file

@ -3139,9 +3139,7 @@ void Item_func_match::init_search(bool no_order)
if (join_key && !no_order)
flags|=FT_SORTED;
ft_handler=table->file->ft_init_ext(flags, key,
(byte*) ft_tmp->ptr(),
ft_tmp->length());
ft_handler=table->file->ft_init_ext(flags, key, ft_tmp);
if (join_key)
table->file->ft_handler=ft_handler;
@ -3183,12 +3181,12 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
}
/*
Check that all columns come from the same table.
We've already checked that columns in MATCH are fields so
We've already checked that columns in MATCH are fields so
PARAM_TABLE_BIT can only appear from AGAINST argument.
*/
if ((used_tables_cache & ~PARAM_TABLE_BIT) != item->used_tables())
key=NO_SUCH_KEY;
if (key == NO_SUCH_KEY && !(flags & FT_BOOL))
{
my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH");

View file

@ -1332,7 +1332,7 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
table->null_row= 0;
table->status= STATUS_NO_RECORD;
table->keys_in_use_for_query= table->s->keys_in_use;
table->maybe_null= test(table->outer_join= table_list->outer_join);
table->maybe_null= table_list->outer_join;
table->tablenr= tablenr;
table->map= (table_map) 1 << tablenr;
table->force_index= table_list->force_index;

View file

@ -3611,7 +3611,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
if (!value) // IS NULL or IS NOT NULL
{
if (field->table->outer_join) // Can't use a key on this
if (field->table->maybe_null) // Can't use a key on this
DBUG_RETURN(0);
if (!maybe_null) // Not null field
DBUG_RETURN(type == Item_func::ISNULL_FUNC ? &null_element : 0);

View file

@ -497,58 +497,58 @@ void close_temporary(TABLE *table,bool delete_table)
void close_temporary_tables(THD *thd)
{
TABLE *table,*next;
char *query, *end;
uint query_buf_size;
bool found_user_tables = 0;
char *query, *name_in_query, *end;
uint greatest_key_length= 0;
if (!thd->temporary_tables)
return;
/*
We write a DROP TEMPORARY TABLE for each temp table left, so that our
replication slave can clean them up. Not one multi-table DROP TABLE binlog
event: this would cause problems if slave uses --replicate-*-table.
*/
LINT_INIT(end);
query_buf_size= 50; // Enough for DROP ... TABLE IF EXISTS
/* We'll re-use always same buffer so make it big enough for longest name */
for (table=thd->temporary_tables ; table ; table=table->next)
/*
We are going to add 4 ` around the db/table names, so 1 does not look
enough; indeed it is enough, because table->key_length is greater (by 8,
because of server_id and thread_id) than db||table.
*/
query_buf_size+= table->s->key_length+1;
greatest_key_length= max(greatest_key_length, table->s->key_length);
if ((query = alloc_root(thd->mem_root, query_buf_size)))
if ((query = alloc_root(thd->mem_root, greatest_key_length+50)))
// Better add "if exists", in case a RESET MASTER has been done
end=strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ");
name_in_query= strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `");
for (table=thd->temporary_tables ; table ; table=next)
{
if (query) // we might be out of memory, but this is not fatal
/*
In we are OOM for 'query' this is not fatal. We skip temporary tables
not created directly by the user.
*/
if (query && mysql_bin_log.is_open() && (table->s->table_name[0] != '#'))
{
// skip temporary tables not created directly by the user
if (table->s->table_name[0] != '#')
found_user_tables = 1;
end = strxmov(end,"`",table->s->db,"`.`",
table->s->table_name,"`,", NullS);
/*
Here we assume table_cache_key always starts
with \0 terminated db name
*/
end = strxmov(name_in_query, table->s->db, "`.`",
table->s->table_name, "`", NullS);
Query_log_event qinfo(thd, query, (ulong)(end-query), 0, FALSE);
/*
Imagine the thread had created a temp table, then was doing a SELECT, and
the SELECT was killed. Then it's not clever to mark the statement above as
"killed", because it's not really a statement updating data, and there
are 99.99% chances it will succeed on slave. And, if thread is
killed now, it's not clever either.
If a real update (one updating a persistent table) was killed on the
master, then this real update will be logged with error_code=killed,
rightfully causing the slave to stop.
*/
qinfo.error_code= 0;
mysql_bin_log.write(&qinfo);
}
next=table->next;
close_temporary(table);
}
if (query && found_user_tables && mysql_bin_log.is_open())
{
/* The -1 is to remove last ',' */
thd->clear_error();
Query_log_event qinfo(thd, query, (ulong)(end-query)-1, 0, FALSE);
/*
Imagine the thread had created a temp table, then was doing a SELECT, and
the SELECT was killed. Then it's not clever to mark the statement above as
"killed", because it's not really a statement updating data, and there
are 99.99% chances it will succeed on slave.
If a real update (one updating a persistent table) was killed on the
master, then this real update will be logged with error_code=killed,
rightfully causing the slave to stop.
*/
qinfo.error_code= 0;
mysql_bin_log.write(&qinfo);
}
thd->temporary_tables=0;
}
@ -854,7 +854,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
table->tablenr=thd->current_tablenr++;
table->used_fields=0;
table->const_table=0;
table->outer_join= table->null_row= table->maybe_null= table->force_index= 0;
table->null_row= table->maybe_null= table->force_index= 0;
table->status=STATUS_NO_RECORD;
table->keys_in_use_for_query= share->keys_in_use;
table->used_keys= share->keys_for_keyread;
@ -1078,7 +1078,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
table->tablenr=thd->current_tablenr++;
table->used_fields=0;
table->const_table=0;
table->outer_join= table->null_row= table->maybe_null= table->force_index= 0;
table->null_row= table->maybe_null= table->force_index= 0;
table->status=STATUS_NO_RECORD;
table->keys_in_use_for_query= table->s->keys_in_use;
table->insert_values= 0;
@ -1150,7 +1150,6 @@ bool reopen_table(TABLE *table,bool locked)
tmp.tablenr= table->tablenr;
tmp.used_fields= table->used_fields;
tmp.const_table= table->const_table;
tmp.outer_join= table->outer_join;
tmp.null_row= table->null_row;
tmp.maybe_null= table->maybe_null;
tmp.status= table->status;

View file

@ -9181,7 +9181,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
tab->info="const row not found";
/* Mark for EXPLAIN that the row was not found */
pos->records_read=0.0;
if (!table->outer_join || error > 0)
if (!table->maybe_null || error > 0)
DBUG_RETURN(error);
}
}
@ -9200,7 +9200,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
tab->info="unique row not found";
/* Mark for EXPLAIN that the row was not found */
pos->records_read=0.0;
if (!table->outer_join || error > 0)
if (!table->maybe_null || error > 0)
DBUG_RETURN(error);
}
if (table->key_read)

View file

@ -153,6 +153,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
SELECT_LEX *sl, *first_select;
select_result *tmp_result;
bool is_union;
TABLE *empty_table= 0;
DBUG_ENTER("st_select_lex_unit::prepare");
describe= test(additional_options & SELECT_DESCRIBE);
@ -249,13 +250,21 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
goto err;
if (sl == first_select)
{
/*
We need to create an empty table object. It is used
to create tmp_table fields in Item_type_holder.
The main reason of this is that we can't create
field object without table.
*/
DBUG_ASSERT(!empty_table);
empty_table= (TABLE*) thd->calloc(sizeof(TABLE));
types.empty();
List_iterator_fast<Item> it(sl->item_list);
Item *item_tmp;
while ((item_tmp= it++))
{
/* Error's in 'new' will be detected after loop */
types.push_back(new Item_type_holder(thd_arg, item_tmp));
types.push_back(new Item_type_holder(thd_arg, item_tmp, empty_table));
}
if (thd_arg->is_fatal_error)
@ -274,7 +283,8 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
Item *type, *item_tmp;
while ((type= tp++, item_tmp= it++))
{
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp,
empty_table))
DBUG_RETURN(TRUE);
}
}

View file

@ -217,14 +217,18 @@ struct st_table {
uint derived_select_number;
int current_lock; /* Type of lock on table */
my_bool copy_blobs; /* copy_blobs when storing */
/*
0 or JOIN_TYPE_{LEFT|RIGHT}. Currently this is only compared to 0.
If maybe_null !=0, this table is inner w.r.t. some outer join operation,
and null_row may be true.
*/
uint maybe_null;
/*
Used in outer joins: if true, all columns are considered to have NULL
values, including columns declared as "not null".
If true, the current table row is considered to have all columns set to
NULL, including columns declared as "not null" (see maybe_null).
*/
my_bool null_row;
/* 0 or JOIN_TYPE_{LEFT|RIGHT}, same as TABLE_LIST::outer_join */
my_bool outer_join;
my_bool maybe_null; /* true if (outer_join != 0) */
my_bool force_index;
my_bool distinct,const_table,no_rows;
my_bool key_read, no_keyread;

View file

@ -16,7 +16,7 @@
# Process this file with automake to create Makefile.in
noinst_LTLIBRARIES=libz.la
pkglib_LTLIBRARIES=libz.la
noinst_HEADERS= crc32.h deflate.h inffast.h inffixed.h inflate.h \
inftrees.h trees.h zconf.h zlib.h zutil.h