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

into  mysql.com:/usr/home/bar/mysql-5.0
This commit is contained in:
unknown 2006-04-04 15:42:32 +05:00
commit 0a2cd4bb9f
12 changed files with 164 additions and 28 deletions

View File

@ -12,7 +12,7 @@ explain extended select count(a) as b from t1 where a=0 having b >=0;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings: Warnings:
Note 1003 select count(`test`.`t1`.`a`) AS `b` from `test`.`t1` where (`test`.`t1`.`a` = 0) having (count(`test`.`t1`.`a`) >= 0) Note 1003 select count(`test`.`t1`.`a`) AS `b` from `test`.`t1` where 0 having (count(`test`.`t1`.`a`) >= 0)
drop table t1; drop table t1;
CREATE TABLE t1 ( CREATE TABLE t1 (
raw_id int(10) NOT NULL default '0', raw_id int(10) NOT NULL default '0',

View File

@ -3371,3 +3371,22 @@ NULL a NULL
drop table t1,t2; drop table t1,t2;
select * from (select * left join t on f1=f2) tt; select * from (select * left join t on f1=f2) tt;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'on f1=f2) tt' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'on f1=f2) tt' at line 1
CREATE TABLE t1 (sku int PRIMARY KEY, pr int);
CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255));
INSERT INTO t1 VALUES
(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10);
INSERT INTO t2 VALUES
(10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'),
(50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh');
SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
sku sppr name sku pr
20 10 bbb 10 10
20 10 bbb 20 10
EXPLAIN
SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
DROP TABLE t1,t2;

View File

@ -547,7 +547,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 Using index 1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings: Warnings:
Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = _latin1'1'))) and (`test`.`t1`.`numeropost` = _latin1'1')) Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = _latin1'1'))
drop table t1; drop table t1;
CREATE TABLE t1 (a int(1)); CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);

View File

@ -15,7 +15,7 @@ explain extended select * from t1 where UNIQ=0x38afba1d73e6a18a;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const UNIQ UNIQ 8 const 1 1 SIMPLE t1 const UNIQ UNIQ 8 const 1
Warnings: Warnings:
Note 1003 select `test`.`t1`.`ID` AS `ID`,`test`.`t1`.`UNIQ` AS `UNIQ` from `test`.`t1` where (`test`.`t1`.`UNIQ` = 4084688022709641610) Note 1003 select `test`.`t1`.`ID` AS `ID`,`test`.`t1`.`UNIQ` AS `UNIQ` from `test`.`t1` where 1
drop table t1; drop table t1;
select x'hello'; select x'hello';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'x'hello'' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'x'hello'' at line 1

View File

@ -2848,3 +2848,26 @@ drop table t1,t2;
# #
--error 1064 --error 1064
select * from (select * left join t on f1=f2) tt; select * from (select * left join t on f1=f2) tt;
#
# Bug #16504: re-evaluation of Item_equal object after reading const table
#
CREATE TABLE t1 (sku int PRIMARY KEY, pr int);
CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255));
INSERT INTO t1 VALUES
(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10);
INSERT INTO t2 VALUES
(10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'),
(50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh');
SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
EXPLAIN
SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
DROP TABLE t1,t2;

View File

@ -11840,7 +11840,8 @@ void Dbdih::newCrashedReplica(Uint32 nodeId, ReplicaRecordPtr ncrReplicaPtr)
/* THAT THE NEW REPLICA IS NOT STARTED YET AND REPLICA_LAST_GCI IS*/ /* THAT THE NEW REPLICA IS NOT STARTED YET AND REPLICA_LAST_GCI IS*/
/* SET TO -1 TO INDICATE THAT IT IS NOT DEAD YET. */ /* SET TO -1 TO INDICATE THAT IT IS NOT DEAD YET. */
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
arrGuard(ncrReplicaPtr.p->noCrashedReplicas + 1, 8); arrGuardErr(ncrReplicaPtr.p->noCrashedReplicas + 1, 8,
NDBD_EXIT_MAX_CRASHED_REPLICAS);
ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] = ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
SYSFILE->lastCompletedGCI[nodeId]; SYSFILE->lastCompletedGCI[nodeId];
ncrReplicaPtr.p->noCrashedReplicas = ncrReplicaPtr.p->noCrashedReplicas + 1; ncrReplicaPtr.p->noCrashedReplicas = ncrReplicaPtr.p->noCrashedReplicas + 1;

View File

@ -3054,7 +3054,7 @@ void Dbtc::tckeyreq050Lab(Signal* signal)
/* NODE IF POSSIBLE TO AVOID UNNECESSARY COMMUNICATION */ /* NODE IF POSSIBLE TO AVOID UNNECESSARY COMMUNICATION */
/* WITH SIMPLE READS. */ /* WITH SIMPLE READS. */
/*-------------------------------------------------------------*/ /*-------------------------------------------------------------*/
arrGuard(tnoOfBackup, 4); arrGuard(tnoOfBackup, MAX_REPLICAS);
UintR Tindex; UintR Tindex;
UintR TownNode = cownNodeid; UintR TownNode = cownNodeid;
for (Tindex = 1; Tindex <= tnoOfBackup; Tindex++) { for (Tindex = 1; Tindex <= tnoOfBackup; Tindex++) {
@ -6325,7 +6325,7 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr, Uint32 errCode)
jam(); jam();
tcConnectptr.i = apiConnectptr.p->currentTcConnect; tcConnectptr.i = apiConnectptr.p->currentTcConnect;
ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord); ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
arrGuard(apiConnectptr.p->currentReplicaNo, 4); arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo]; hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo];
ptrCheckGuard(hostptr, chostFilesize, hostRecord); ptrCheckGuard(hostptr, chostFilesize, hostRecord);
if (hostptr.p->hostStatus == HS_ALIVE) { if (hostptr.p->hostStatus == HS_ALIVE) {
@ -6351,7 +6351,7 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr, Uint32 errCode)
jam(); jam();
tcConnectptr.i = apiConnectptr.p->currentTcConnect; tcConnectptr.i = apiConnectptr.p->currentTcConnect;
ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord); ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
arrGuard(apiConnectptr.p->currentReplicaNo, 4); arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo]; hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo];
ptrCheckGuard(hostptr, chostFilesize, hostRecord); ptrCheckGuard(hostptr, chostFilesize, hostRecord);
if (hostptr.p->hostStatus == HS_ALIVE) { if (hostptr.p->hostStatus == HS_ALIVE) {
@ -6377,7 +6377,7 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr, Uint32 errCode)
jam(); jam();
tcConnectptr.i = apiConnectptr.p->currentTcConnect; tcConnectptr.i = apiConnectptr.p->currentTcConnect;
ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord); ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
arrGuard(apiConnectptr.p->currentReplicaNo, 4); arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo]; hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo];
ptrCheckGuard(hostptr, chostFilesize, hostRecord); ptrCheckGuard(hostptr, chostFilesize, hostRecord);
if (hostptr.p->hostStatus == HS_ALIVE) { if (hostptr.p->hostStatus == HS_ALIVE) {
@ -6552,7 +6552,7 @@ void Dbtc::sendAbortedAfterTimeout(Signal* signal, int Tcheck)
// in time to the ABORT signal we will declare it as dead. // in time to the ABORT signal we will declare it as dead.
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
UintR Ti = 0; UintR Ti = 0;
arrGuard(tcConnectptr.p->noOfNodes, 4); arrGuard(tcConnectptr.p->noOfNodes, MAX_REPLICAS+1);
for (Ti = 0; Ti < tcConnectptr.p->noOfNodes; Ti++) { for (Ti = 0; Ti < tcConnectptr.p->noOfNodes; Ti++) {
jam(); jam();
if (tcConnectptr.p->tcNodedata[Ti] != 0) { if (tcConnectptr.p->tcNodedata[Ti] != 0) {
@ -7545,7 +7545,7 @@ void Dbtc::execABORTCONF(Signal* signal)
warningReport(signal, 18); warningReport(signal, 18);
return; return;
}//if }//if
arrGuard(apiConnectptr.p->currentReplicaNo, 4); arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
if (tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo] != if (tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo] !=
tnodeid) { tnodeid) {
warningReport(signal, 19); warningReport(signal, 19);
@ -7561,7 +7561,7 @@ void Dbtc::toAbortHandlingLab(Signal* signal)
do { do {
if (tcurrentReplicaNo != (Uint8)Z8NIL) { if (tcurrentReplicaNo != (Uint8)Z8NIL) {
jam(); jam();
arrGuard(tcurrentReplicaNo, 4); arrGuard(tcurrentReplicaNo, MAX_REPLICAS);
const LqhTransConf::OperationStatus stat = const LqhTransConf::OperationStatus stat =
(LqhTransConf::OperationStatus) (LqhTransConf::OperationStatus)
tcConnectptr.p->failData[tcurrentReplicaNo]; tcConnectptr.p->failData[tcurrentReplicaNo];
@ -7695,7 +7695,7 @@ void Dbtc::execCOMMITCONF(Signal* signal)
warningReport(signal, 10); warningReport(signal, 10);
return; return;
}//if }//if
arrGuard(apiConnectptr.p->currentReplicaNo, 4); arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
if (tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo] != if (tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo] !=
tnodeid) { tnodeid) {
warningReport(signal, 11); warningReport(signal, 11);
@ -7715,7 +7715,7 @@ void Dbtc::toCommitHandlingLab(Signal* signal)
do { do {
if (tcurrentReplicaNo != (Uint8)Z8NIL) { if (tcurrentReplicaNo != (Uint8)Z8NIL) {
jam(); jam();
arrGuard(tcurrentReplicaNo, 4); arrGuard(tcurrentReplicaNo, MAX_REPLICAS);
switch (tcConnectptr.p->failData[tcurrentReplicaNo]) { switch (tcConnectptr.p->failData[tcurrentReplicaNo]) {
case LqhTransConf::InvalidStatus: case LqhTransConf::InvalidStatus:
jam(); jam();
@ -7840,7 +7840,7 @@ void Dbtc::execCOMPLETECONF(Signal* signal)
warningReport(signal, 14); warningReport(signal, 14);
return; return;
}//if }//if
arrGuard(apiConnectptr.p->currentReplicaNo, 4); arrGuard(apiConnectptr.p->currentReplicaNo, MAX_REPLICAS);
if (tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo] != if (tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo] !=
tnodeid) { tnodeid) {
warningReport(signal, 15); warningReport(signal, 15);
@ -7860,7 +7860,7 @@ void Dbtc::toCompleteHandlingLab(Signal* signal)
do { do {
if (tcurrentReplicaNo != (Uint8)Z8NIL) { if (tcurrentReplicaNo != (Uint8)Z8NIL) {
jam(); jam();
arrGuard(tcurrentReplicaNo, 4); arrGuard(tcurrentReplicaNo, MAX_REPLICAS);
switch (tcConnectptr.p->failData[tcurrentReplicaNo]) { switch (tcConnectptr.p->failData[tcurrentReplicaNo]) {
case LqhTransConf::InvalidStatus: case LqhTransConf::InvalidStatus:
jam(); jam();
@ -8150,6 +8150,7 @@ void Dbtc::setupFailData(Signal* signal)
case OS_PREPARED: case OS_PREPARED:
case OS_COMMITTING: case OS_COMMITTING:
jam(); jam();
arrGuard(tcConnectptr.p->lastReplicaNo, MAX_REPLICAS);
for (tindex = 0; tindex <= tcConnectptr.p->lastReplicaNo; tindex++) { for (tindex = 0; tindex <= tcConnectptr.p->lastReplicaNo; tindex++) {
jam(); jam();
/*------------------------------------------------------------------- /*-------------------------------------------------------------------
@ -8157,13 +8158,13 @@ void Dbtc::setupFailData(Signal* signal)
* IN THIS CASE ALL LQH'S ARE PREPARED AND WAITING FOR * IN THIS CASE ALL LQH'S ARE PREPARED AND WAITING FOR
* COMMIT/ABORT DECISION. * COMMIT/ABORT DECISION.
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
arrGuard(tindex, 4);
tcConnectptr.p->failData[tindex] = LqhTransConf::Prepared; tcConnectptr.p->failData[tindex] = LqhTransConf::Prepared;
}//for }//for
break; break;
case OS_COMMITTED: case OS_COMMITTED:
case OS_COMPLETING: case OS_COMPLETING:
jam(); jam();
arrGuard(tcConnectptr.p->lastReplicaNo, MAX_REPLICAS);
for (tindex = 0; tindex <= tcConnectptr.p->lastReplicaNo; tindex++) { for (tindex = 0; tindex <= tcConnectptr.p->lastReplicaNo; tindex++) {
jam(); jam();
/*------------------------------------------------------------------- /*-------------------------------------------------------------------
@ -8171,19 +8172,18 @@ void Dbtc::setupFailData(Signal* signal)
* IN THIS CASE ALL LQH'S ARE COMMITTED AND WAITING FOR * IN THIS CASE ALL LQH'S ARE COMMITTED AND WAITING FOR
* COMPLETE MESSAGE. * COMPLETE MESSAGE.
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
arrGuard(tindex, 4);
tcConnectptr.p->failData[tindex] = LqhTransConf::Committed; tcConnectptr.p->failData[tindex] = LqhTransConf::Committed;
}//for }//for
break; break;
case OS_COMPLETED: case OS_COMPLETED:
jam(); jam();
arrGuard(tcConnectptr.p->lastReplicaNo, MAX_REPLICAS);
for (tindex = 0; tindex <= tcConnectptr.p->lastReplicaNo; tindex++) { for (tindex = 0; tindex <= tcConnectptr.p->lastReplicaNo; tindex++) {
jam(); jam();
/*------------------------------------------------------------------- /*-------------------------------------------------------------------
* KEYDATA IS USED TO KEEP AN INDICATION OF STATE IN LQH. * KEYDATA IS USED TO KEEP AN INDICATION OF STATE IN LQH.
* IN THIS CASE ALL LQH'S ARE COMPLETED. * IN THIS CASE ALL LQH'S ARE COMPLETED.
*-------------------------------------------------------------------*/ *-------------------------------------------------------------------*/
arrGuard(tindex, 4);
tcConnectptr.p->failData[tindex] = LqhTransConf::InvalidStatus; tcConnectptr.p->failData[tindex] = LqhTransConf::InvalidStatus;
}//for }//for
break; break;

View File

@ -57,7 +57,7 @@ make
cp extra/comp_err extra/comp_err.linux cp extra/comp_err extra/comp_err.linux
cp libmysql/conf_to_src libmysql/conf_to_src.linux cp libmysql/conf_to_src libmysql/conf_to_src.linux
#cp libmysql_r/conf_to_src libmysql_r/conf_to_src.linux #cp libmysql_r/conf_to_src libmysql_r/conf_to_src.linux
cp sql/.libs/gen_lex_hash sql/gen_lex_hash.linux cp sql/gen_lex_hash sql/gen_lex_hash.linux
cp strings/conf_to_src strings/conf_to_src.linux cp strings/conf_to_src strings/conf_to_src.linux
# Delete mysql_version.h # Delete mysql_version.h

View File

@ -3777,7 +3777,7 @@ Item *Item_field::replace_equal_field(byte *arg)
if (item_equal) if (item_equal)
{ {
Item_field *subst= item_equal->get_first(); Item_field *subst= item_equal->get_first();
if (!field->eq(subst->field)) if (subst && !field->eq(subst->field))
return subst; return subst;
} }
return this; return this;

View File

@ -3602,7 +3602,8 @@ void Item_equal::add(Item *c)
Item_func_eq *func= new Item_func_eq(c, const_item); Item_func_eq *func= new Item_func_eq(c, const_item);
func->set_cmp_func(); func->set_cmp_func();
func->quick_fix_field(); func->quick_fix_field();
cond_false = !(func->val_int()); if ((cond_false= !func->val_int()))
const_item_cache= 1;
} }
void Item_equal::add(Item_field *f) void Item_equal::add(Item_field *f)
@ -3734,13 +3735,45 @@ void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
} while (swap); } while (swap);
} }
/*
Check appearance of new constant items in the multiple equality object
SYNOPSIS
update_const()
DESCRIPTION
The function checks appearance of new constant items among
the members of multiple equalities. Each new constant item is
compared with the designated constant item if there is any in the
multiple equality. If there is none the first new constant item
becomes designated.
RETURN VALUES
none
*/
void Item_equal::update_const()
{
List_iterator<Item_field> it(fields);
Item *item;
while ((item= it++))
{
if (item->const_item())
{
it.remove();
add(item);
}
}
}
bool Item_equal::fix_fields(THD *thd, Item **ref) bool Item_equal::fix_fields(THD *thd, Item **ref)
{ {
List_iterator_fast<Item_field> li(fields); List_iterator_fast<Item_field> li(fields);
Item *item; Item *item;
not_null_tables_cache= used_tables_cache= 0; not_null_tables_cache= used_tables_cache= 0;
const_item_cache= 0; const_item_cache= 0;
while ((item=li++)) while ((item= li++))
{ {
table_map tmp_table_map; table_map tmp_table_map;
used_tables_cache|= item->used_tables(); used_tables_cache|= item->used_tables();

View File

@ -1196,6 +1196,7 @@ public:
bool contains(Field *field); bool contains(Field *field);
Item_field* get_first() { return fields.head(); } Item_field* get_first() { return fields.head(); }
void merge(Item_equal *item); void merge(Item_equal *item);
void update_const();
enum Functype functype() const { return MULT_EQUAL_FUNC; } enum Functype functype() const { return MULT_EQUAL_FUNC; }
longlong val_int(); longlong val_int();
const char *func_name() const { return "multiple equal"; } const char *func_name() const { return "multiple equal"; }

View File

@ -2148,7 +2148,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
s->type=JT_SYSTEM; s->type=JT_SYSTEM;
join->const_table_map|=table->map; join->const_table_map|=table->map;
set_position(join,const_count++,s,(KEYUSE*) 0); set_position(join,const_count++,s,(KEYUSE*) 0);
if ((tmp= join_read_const_table(s,join->positions+const_count-1))) if ((tmp= join_read_const_table(s, join->positions+const_count-1)))
{ {
if (tmp > 0) if (tmp > 0)
DBUG_RETURN(1); // Fatal error DBUG_RETURN(1); // Fatal error
@ -2201,7 +2201,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
found_const_table_map)) found_const_table_map))
DBUG_RETURN(1); DBUG_RETURN(1);
if ((tmp=join_read_const_table(s, if ((tmp=join_read_const_table(s,
join->positions+const_count-1))) join->positions+const_count-1)))
{ {
if (tmp > 0) if (tmp > 0)
DBUG_RETURN(1); // Fatal error DBUG_RETURN(1); // Fatal error
@ -6796,8 +6796,8 @@ static COND *build_equal_items_for_cond(COND *cond,
return item_equal; return item_equal;
} }
/* /*
For each field reference in cond, not from equalitym predicates, For each field reference in cond, not from equal item predicates,
set a pointer to the multiple equality if belongs to (if there is any) set a pointer to the multiple equality it belongs to (if there is any)
*/ */
cond= cond->transform(&Item::equal_fields_propagator, cond= cond->transform(&Item::equal_fields_propagator,
(byte *) inherited); (byte *) inherited);
@ -6982,7 +6982,7 @@ static int compare_fields_by_table_order(Item_field *field1,
NOTES NOTES
Before generating an equality function checks that it has not Before generating an equality function checks that it has not
been generated for multiple equalies of the upper levels. been generated for multiple equalities of the upper levels.
E.g. for the following where condition E.g. for the following where condition
WHERE a=5 AND ((a=b AND b=c) OR c>4) WHERE a=5 AND ((a=b AND b=c) OR c>4)
the upper level AND condition will contain =(5,a), the upper level AND condition will contain =(5,a),
@ -7155,7 +7155,7 @@ static COND* substitute_for_best_equal_field(COND *cond,
{ {
cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal); cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
// This occurs when eliminate_item_equal() founds that cond is // This occurs when eliminate_item_equal() founds that cond is
// always false and substitues it with Item_int 0. // always false and substitutes it with Item_int 0.
// Due to this, value of item_equal will be 0, so just return it. // Due to this, value of item_equal will be 0, so just return it.
if (cond->type() != Item::COND_ITEM) if (cond->type() != Item::COND_ITEM)
break; break;
@ -7177,6 +7177,44 @@ static COND* substitute_for_best_equal_field(COND *cond,
} }
/*
Check appearance of new constant items in multiple equalities
of a condition after reading a constant table
SYNOPSIS
update_const_equal_items()
cond condition whose multiple equalities are to be checked
table constant table that has been read
DESCRIPTION
The function retrieves the cond condition and for each encountered
multiple equality checks whether new constants have appeared after
reading the constant (single row) table tab. If so it adjusts
the multiple equality appropriately.
*/
static void update_const_equal_items(COND *cond, JOIN_TAB *tab)
{
if (!(cond->used_tables() & tab->table->map))
return;
if (cond->type() == Item::COND_ITEM)
{
List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
List_iterator_fast<Item> li(*cond_list);
Item *item;
while ((item= li++))
update_const_equal_items(item, tab);
}
else if (cond->type() == Item::FUNC_ITEM &&
((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
{
Item_equal *item_equal= (Item_equal *) cond;
item_equal->update_const();
}
}
/* /*
change field = field to field = const for each found field = const in the change field = field to field = const for each found field = const in the
and_level and_level
@ -10151,6 +10189,27 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
} }
if (!table->null_row) if (!table->null_row)
table->maybe_null=0; table->maybe_null=0;
/* Check appearance of new constant items in Item_equal objects */
JOIN *join= tab->join;
if (join->conds)
update_const_equal_items(join->conds, tab);
TABLE_LIST *tbl;
for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
{
TABLE_LIST *embedded;
TABLE_LIST *embedding= tbl;
do
{
embedded= embedding;
if (embedded->on_expr)
update_const_equal_items(embedded->on_expr, tab);
embedding= embedded->embedding;
}
while (embedding &&
embedding->nested_join->join_list.head() == embedded);
}
DBUG_RETURN(0); DBUG_RETURN(0);
} }