Commit ecea791e authored by malff/marcsql@weblab.(none)'s avatar malff/marcsql@weblab.(none)
Browse files

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

into  weblab.(none):/home/marcsql/TREE/mysql-5.0-30237
parents 88107378 82f99c93
Loading
Loading
Loading
Loading
+356 −0
Original line number Diff line number Diff line
drop table if exists t1_30237_bool;
create table t1_30237_bool(A boolean, B boolean, C boolean);
insert into t1_30237_bool values
(FALSE, FALSE, FALSE),
(FALSE, FALSE, NULL),
(FALSE, FALSE, TRUE),
(FALSE, NULL, FALSE),
(FALSE, NULL, NULL),
(FALSE, NULL, TRUE),
(FALSE, TRUE, FALSE),
(FALSE, TRUE, NULL),
(FALSE, TRUE, TRUE),
(NULL, FALSE, FALSE),
(NULL, FALSE, NULL),
(NULL, FALSE, TRUE),
(NULL, NULL, FALSE),
(NULL, NULL, NULL),
(NULL, NULL, TRUE),
(NULL, TRUE, FALSE),
(NULL, TRUE, NULL),
(NULL, TRUE, TRUE),
(TRUE, FALSE, FALSE),
(TRUE, FALSE, NULL),
(TRUE, FALSE, TRUE),
(TRUE, NULL, FALSE),
(TRUE, NULL, NULL),
(TRUE, NULL, TRUE),
(TRUE, TRUE, FALSE),
(TRUE, TRUE, NULL),
(TRUE, TRUE, TRUE) ;
Testing OR, XOR, AND
select A, B, A OR B, A XOR B, A AND B
from t1_30237_bool where C is null order by A, B;
A	B	A OR B	A XOR B	A AND B
NULL	NULL	NULL	NULL	NULL
NULL	0	NULL	NULL	0
NULL	1	1	NULL	NULL
0	NULL	NULL	NULL	0
0	0	0	0	0
0	1	1	1	0
1	NULL	1	NULL	NULL
1	0	1	1	0
1	1	1	0	1
Testing that OR is associative 
select A, B, C, (A OR B) OR C, A OR (B OR C), A OR B OR C
from t1_30237_bool order by A, B, C;
A	B	C	(A OR B) OR C	A OR (B OR C)	A OR B OR C
NULL	NULL	NULL	NULL	NULL	NULL
NULL	NULL	0	NULL	NULL	NULL
NULL	NULL	1	1	1	1
NULL	0	NULL	NULL	NULL	NULL
NULL	0	0	NULL	NULL	NULL
NULL	0	1	1	1	1
NULL	1	NULL	1	1	1
NULL	1	0	1	1	1
NULL	1	1	1	1	1
0	NULL	NULL	NULL	NULL	NULL
0	NULL	0	NULL	NULL	NULL
0	NULL	1	1	1	1
0	0	NULL	NULL	NULL	NULL
0	0	0	0	0	0
0	0	1	1	1	1
0	1	NULL	1	1	1
0	1	0	1	1	1
0	1	1	1	1	1
1	NULL	NULL	1	1	1
1	NULL	0	1	1	1
1	NULL	1	1	1	1
1	0	NULL	1	1	1
1	0	0	1	1	1
1	0	1	1	1	1
1	1	NULL	1	1	1
1	1	0	1	1	1
1	1	1	1	1	1
select count(*) from t1_30237_bool
where ((A OR B) OR C) != (A OR (B OR C));
count(*)
0
Testing that XOR is associative 
select A, B, C, (A XOR B) XOR C, A XOR (B XOR C), A XOR B XOR C
from t1_30237_bool order by A, B, C;
A	B	C	(A XOR B) XOR C	A XOR (B XOR C)	A XOR B XOR C
NULL	NULL	NULL	NULL	NULL	NULL
NULL	NULL	0	NULL	NULL	NULL
NULL	NULL	1	NULL	NULL	NULL
NULL	0	NULL	NULL	NULL	NULL
NULL	0	0	NULL	NULL	NULL
NULL	0	1	NULL	NULL	NULL
NULL	1	NULL	NULL	NULL	NULL
NULL	1	0	NULL	NULL	NULL
NULL	1	1	NULL	NULL	NULL
0	NULL	NULL	NULL	NULL	NULL
0	NULL	0	NULL	NULL	NULL
0	NULL	1	NULL	NULL	NULL
0	0	NULL	NULL	NULL	NULL
0	0	0	0	0	0
0	0	1	1	1	1
0	1	NULL	NULL	NULL	NULL
0	1	0	1	1	1
0	1	1	0	0	0
1	NULL	NULL	NULL	NULL	NULL
1	NULL	0	NULL	NULL	NULL
1	NULL	1	NULL	NULL	NULL
1	0	NULL	NULL	NULL	NULL
1	0	0	1	1	1
1	0	1	0	0	0
1	1	NULL	NULL	NULL	NULL
1	1	0	0	0	0
1	1	1	1	1	1
select count(*) from t1_30237_bool
where ((A XOR B) XOR C) != (A XOR (B XOR C));
count(*)
0
Testing that AND is associative 
select A, B, C, (A AND B) AND C, A AND (B AND C), A AND B AND C
from t1_30237_bool order by A, B, C;
A	B	C	(A AND B) AND C	A AND (B AND C)	A AND B AND C
NULL	NULL	NULL	NULL	NULL	NULL
NULL	NULL	0	0	0	0
NULL	NULL	1	NULL	NULL	NULL
NULL	0	NULL	0	0	0
NULL	0	0	0	0	0
NULL	0	1	0	0	0
NULL	1	NULL	NULL	NULL	NULL
NULL	1	0	0	0	0
NULL	1	1	NULL	NULL	NULL
0	NULL	NULL	0	0	0
0	NULL	0	0	0	0
0	NULL	1	0	0	0
0	0	NULL	0	0	0
0	0	0	0	0	0
0	0	1	0	0	0
0	1	NULL	0	0	0
0	1	0	0	0	0
0	1	1	0	0	0
1	NULL	NULL	NULL	NULL	NULL
1	NULL	0	0	0	0
1	NULL	1	NULL	NULL	NULL
1	0	NULL	0	0	0
1	0	0	0	0	0
1	0	1	0	0	0
1	1	NULL	NULL	NULL	NULL
1	1	0	0	0	0
1	1	1	1	1	1
select count(*) from t1_30237_bool
where ((A AND B) AND C) != (A AND (B AND C));
count(*)
0
Testing that AND has precedence over OR
select A, B, C, (A OR B) AND C, A OR (B AND C), A OR B AND C
from t1_30237_bool order by A, B, C;
A	B	C	(A OR B) AND C	A OR (B AND C)	A OR B AND C
NULL	NULL	NULL	NULL	NULL	NULL
NULL	NULL	0	0	NULL	NULL
NULL	NULL	1	NULL	NULL	NULL
NULL	0	NULL	NULL	NULL	NULL
NULL	0	0	0	NULL	NULL
NULL	0	1	NULL	NULL	NULL
NULL	1	NULL	NULL	NULL	NULL
NULL	1	0	0	NULL	NULL
NULL	1	1	1	1	1
0	NULL	NULL	NULL	NULL	NULL
0	NULL	0	0	0	0
0	NULL	1	NULL	NULL	NULL
0	0	NULL	0	0	0
0	0	0	0	0	0
0	0	1	0	0	0
0	1	NULL	NULL	NULL	NULL
0	1	0	0	0	0
0	1	1	1	1	1
1	NULL	NULL	NULL	1	1
1	NULL	0	0	1	1
1	NULL	1	1	1	1
1	0	NULL	NULL	1	1
1	0	0	0	1	1
1	0	1	1	1	1
1	1	NULL	NULL	1	1
1	1	0	0	1	1
1	1	1	1	1	1
select count(*) from t1_30237_bool
where (A OR (B AND C)) != (A OR B AND C);
count(*)
0
select A, B, C, (A AND B) OR C, A AND (B OR C), A AND B OR C
from t1_30237_bool order by A, B, C;
A	B	C	(A AND B) OR C	A AND (B OR C)	A AND B OR C
NULL	NULL	NULL	NULL	NULL	NULL
NULL	NULL	0	NULL	NULL	NULL
NULL	NULL	1	1	NULL	1
NULL	0	NULL	NULL	NULL	NULL
NULL	0	0	0	0	0
NULL	0	1	1	NULL	1
NULL	1	NULL	NULL	NULL	NULL
NULL	1	0	NULL	NULL	NULL
NULL	1	1	1	NULL	1
0	NULL	NULL	NULL	0	NULL
0	NULL	0	0	0	0
0	NULL	1	1	0	1
0	0	NULL	NULL	0	NULL
0	0	0	0	0	0
0	0	1	1	0	1
0	1	NULL	NULL	0	NULL
0	1	0	0	0	0
0	1	1	1	0	1
1	NULL	NULL	NULL	NULL	NULL
1	NULL	0	NULL	NULL	NULL
1	NULL	1	1	1	1
1	0	NULL	NULL	NULL	NULL
1	0	0	0	0	0
1	0	1	1	1	1
1	1	NULL	1	1	1
1	1	0	1	1	1
1	1	1	1	1	1
select count(*) from t1_30237_bool
where ((A AND B) OR C) != (A AND B OR C);
count(*)
0
Testing that AND has precedence over XOR
select A, B, C, (A XOR B) AND C, A XOR (B AND C), A XOR B AND C
from t1_30237_bool order by A, B, C;
A	B	C	(A XOR B) AND C	A XOR (B AND C)	A XOR B AND C
NULL	NULL	NULL	NULL	NULL	NULL
NULL	NULL	0	0	NULL	NULL
NULL	NULL	1	NULL	NULL	NULL
NULL	0	NULL	NULL	NULL	NULL
NULL	0	0	0	NULL	NULL
NULL	0	1	NULL	NULL	NULL
NULL	1	NULL	NULL	NULL	NULL
NULL	1	0	0	NULL	NULL
NULL	1	1	NULL	NULL	NULL
0	NULL	NULL	NULL	NULL	NULL
0	NULL	0	0	0	0
0	NULL	1	NULL	NULL	NULL
0	0	NULL	0	0	0
0	0	0	0	0	0
0	0	1	0	0	0
0	1	NULL	NULL	NULL	NULL
0	1	0	0	0	0
0	1	1	1	1	1
1	NULL	NULL	NULL	NULL	NULL
1	NULL	0	0	1	1
1	NULL	1	NULL	NULL	NULL
1	0	NULL	NULL	1	1
1	0	0	0	1	1
1	0	1	1	1	1
1	1	NULL	0	NULL	NULL
1	1	0	0	1	1
1	1	1	0	0	0
select count(*) from t1_30237_bool
where (A XOR (B AND C)) != (A XOR B AND C);
count(*)
0
select A, B, C, (A AND B) XOR C, A AND (B XOR C), A AND B XOR C
from t1_30237_bool order by A, B, C;
A	B	C	(A AND B) XOR C	A AND (B XOR C)	A AND B XOR C
NULL	NULL	NULL	NULL	NULL	NULL
NULL	NULL	0	NULL	NULL	NULL
NULL	NULL	1	NULL	NULL	NULL
NULL	0	NULL	NULL	NULL	NULL
NULL	0	0	0	0	0
NULL	0	1	1	NULL	1
NULL	1	NULL	NULL	NULL	NULL
NULL	1	0	NULL	NULL	NULL
NULL	1	1	NULL	0	NULL
0	NULL	NULL	NULL	0	NULL
0	NULL	0	0	0	0
0	NULL	1	1	0	1
0	0	NULL	NULL	0	NULL
0	0	0	0	0	0
0	0	1	1	0	1
0	1	NULL	NULL	0	NULL
0	1	0	0	0	0
0	1	1	1	0	1
1	NULL	NULL	NULL	NULL	NULL
1	NULL	0	NULL	NULL	NULL
1	NULL	1	NULL	NULL	NULL
1	0	NULL	NULL	NULL	NULL
1	0	0	0	0	0
1	0	1	1	1	1
1	1	NULL	NULL	NULL	NULL
1	1	0	1	1	1
1	1	1	0	0	0
select count(*) from t1_30237_bool
where ((A AND B) XOR C) != (A AND B XOR C);
count(*)
0
Testing that XOR has precedence over OR
select A, B, C, (A XOR B) OR C, A XOR (B OR C), A XOR B OR C
from t1_30237_bool order by A, B, C;
A	B	C	(A XOR B) OR C	A XOR (B OR C)	A XOR B OR C
NULL	NULL	NULL	NULL	NULL	NULL
NULL	NULL	0	NULL	NULL	NULL
NULL	NULL	1	1	NULL	1
NULL	0	NULL	NULL	NULL	NULL
NULL	0	0	NULL	NULL	NULL
NULL	0	1	1	NULL	1
NULL	1	NULL	NULL	NULL	NULL
NULL	1	0	NULL	NULL	NULL
NULL	1	1	1	NULL	1
0	NULL	NULL	NULL	NULL	NULL
0	NULL	0	NULL	NULL	NULL
0	NULL	1	1	1	1
0	0	NULL	NULL	NULL	NULL
0	0	0	0	0	0
0	0	1	1	1	1
0	1	NULL	1	1	1
0	1	0	1	1	1
0	1	1	1	1	1
1	NULL	NULL	NULL	NULL	NULL
1	NULL	0	NULL	NULL	NULL
1	NULL	1	1	0	1
1	0	NULL	1	NULL	1
1	0	0	1	1	1
1	0	1	1	0	1
1	1	NULL	NULL	0	NULL
1	1	0	0	0	0
1	1	1	1	0	1
select count(*) from t1_30237_bool
where ((A XOR B) OR C) != (A XOR B OR C);
count(*)
0
select A, B, C, (A OR B) XOR C, A OR (B XOR C), A OR B XOR C
from t1_30237_bool order by A, B, C;
A	B	C	(A OR B) XOR C	A OR (B XOR C)	A OR B XOR C
NULL	NULL	NULL	NULL	NULL	NULL
NULL	NULL	0	NULL	NULL	NULL
NULL	NULL	1	NULL	NULL	NULL
NULL	0	NULL	NULL	NULL	NULL
NULL	0	0	NULL	NULL	NULL
NULL	0	1	NULL	1	1
NULL	1	NULL	NULL	NULL	NULL
NULL	1	0	1	1	1
NULL	1	1	0	NULL	NULL
0	NULL	NULL	NULL	NULL	NULL
0	NULL	0	NULL	NULL	NULL
0	NULL	1	NULL	NULL	NULL
0	0	NULL	NULL	NULL	NULL
0	0	0	0	0	0
0	0	1	1	1	1
0	1	NULL	NULL	NULL	NULL
0	1	0	1	1	1
0	1	1	0	0	0
1	NULL	NULL	NULL	1	1
1	NULL	0	1	1	1
1	NULL	1	0	1	1
1	0	NULL	NULL	1	1
1	0	0	1	1	1
1	0	1	0	1	1
1	1	NULL	NULL	1	1
1	1	0	1	1	1
1	1	1	0	1	1
select count(*) from t1_30237_bool
where (A OR (B XOR C)) != (A OR B XOR C);
count(*)
0
drop table t1_30237_bool;
+93 −0
Original line number Diff line number Diff line

--disable_warnings
drop table if exists t1_30237_bool;
--enable_warnings

create table t1_30237_bool(A boolean, B boolean, C boolean);

insert into t1_30237_bool values
(FALSE, FALSE, FALSE),
(FALSE, FALSE, NULL),
(FALSE, FALSE, TRUE),
(FALSE, NULL, FALSE),
(FALSE, NULL, NULL),
(FALSE, NULL, TRUE),
(FALSE, TRUE, FALSE),
(FALSE, TRUE, NULL),
(FALSE, TRUE, TRUE),
(NULL, FALSE, FALSE),
(NULL, FALSE, NULL),
(NULL, FALSE, TRUE),
(NULL, NULL, FALSE),
(NULL, NULL, NULL),
(NULL, NULL, TRUE),
(NULL, TRUE, FALSE),
(NULL, TRUE, NULL),
(NULL, TRUE, TRUE),
(TRUE, FALSE, FALSE),
(TRUE, FALSE, NULL),
(TRUE, FALSE, TRUE),
(TRUE, NULL, FALSE),
(TRUE, NULL, NULL),
(TRUE, NULL, TRUE),
(TRUE, TRUE, FALSE),
(TRUE, TRUE, NULL),
(TRUE, TRUE, TRUE) ;

--echo Testing OR, XOR, AND
select A, B, A OR B, A XOR B, A AND B
  from t1_30237_bool where C is null order by A, B;

--echo Testing that OR is associative 
select A, B, C, (A OR B) OR C, A OR (B OR C), A OR B OR C
 from t1_30237_bool order by A, B, C;

select count(*) from t1_30237_bool
  where ((A OR B) OR C) != (A OR (B OR C));

--echo Testing that XOR is associative 
select A, B, C, (A XOR B) XOR C, A XOR (B XOR C), A XOR B XOR C
  from t1_30237_bool order by A, B, C;

select count(*) from t1_30237_bool
  where ((A XOR B) XOR C) != (A XOR (B XOR C));

--echo Testing that AND is associative 
select A, B, C, (A AND B) AND C, A AND (B AND C), A AND B AND C
  from t1_30237_bool order by A, B, C;

select count(*) from t1_30237_bool
  where ((A AND B) AND C) != (A AND (B AND C));

--echo Testing that AND has precedence over OR
select A, B, C, (A OR B) AND C, A OR (B AND C), A OR B AND C
  from t1_30237_bool order by A, B, C;
select count(*) from t1_30237_bool
  where (A OR (B AND C)) != (A OR B AND C);
select A, B, C, (A AND B) OR C, A AND (B OR C), A AND B OR C
  from t1_30237_bool order by A, B, C;
select count(*) from t1_30237_bool
  where ((A AND B) OR C) != (A AND B OR C);

--echo Testing that AND has precedence over XOR
select A, B, C, (A XOR B) AND C, A XOR (B AND C), A XOR B AND C
  from t1_30237_bool order by A, B, C;
select count(*) from t1_30237_bool
  where (A XOR (B AND C)) != (A XOR B AND C);
select A, B, C, (A AND B) XOR C, A AND (B XOR C), A AND B XOR C
  from t1_30237_bool order by A, B, C;
select count(*) from t1_30237_bool
  where ((A AND B) XOR C) != (A AND B XOR C);

--echo Testing that XOR has precedence over OR
select A, B, C, (A XOR B) OR C, A XOR (B OR C), A XOR B OR C
  from t1_30237_bool order by A, B, C;
select count(*) from t1_30237_bool
  where ((A XOR B) OR C) != (A XOR B OR C);
select A, B, C, (A OR B) XOR C, A OR (B XOR C), A OR B XOR C
  from t1_30237_bool order by A, B, C;
select count(*) from t1_30237_bool
  where (A OR (B XOR C)) != (A OR B XOR C);

drop table t1_30237_bool;
+18 −0
Original line number Diff line number Diff line
@@ -1361,6 +1361,7 @@ class Item_cond :public Item_bool_func
  Item_cond(List<Item> &nlist)
    :Item_bool_func(), list(nlist), abort_on_null(0) {}
  bool add(Item *item) { return list.push_back(item); }
  bool add_at_head(Item *item) { return list.push_front(item); }
  void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
  bool fix_fields(THD *, Item **ref);

@@ -1554,6 +1555,15 @@ class Item_cond_and :public Item_cond
  Item *neg_transformer(THD *thd);
};

inline bool is_cond_and(Item *item)
{
  if (item->type() != Item::COND_ITEM)
    return FALSE;

  Item_cond *cond_item= (Item_cond*) item;
  return (cond_item->functype() == Item_func::COND_AND_FUNC);
}

class Item_cond_or :public Item_cond
{
public:
@@ -1575,6 +1585,14 @@ class Item_cond_or :public Item_cond
  Item *neg_transformer(THD *thd);
};

inline bool is_cond_or(Item *item)
{
  if (item->type() != Item::COND_ITEM)
    return FALSE;

  Item_cond *cond_item= (Item_cond*) item;
  return (cond_item->functype() == Item_func::COND_OR_FUNC);
}

/*
  XOR is Item_cond, not an Item_int_func because we could like to
+97 −43
Original line number Diff line number Diff line
@@ -458,10 +458,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);

%pure_parser					/* We have threads */
/*
  Currently there is 251 shift/reduce conflict. We should not introduce
  new conflicts any more.
  Currently there are 245 shift/reduce conflicts.
  We should not introduce new conflicts any more.
*/
%expect 251
%expect 245

%token  END_OF_INPUT

@@ -1011,7 +1011,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
/* A dummy token to force the priority of table_ref production in a join. */
%left   TABLE_REF_PRIORITY
%left   SET_VAR
%left	OR_OR_SYM OR_SYM OR2_SYM XOR
%left	OR_OR_SYM OR_SYM OR2_SYM
%left	XOR
%left	AND_SYM AND_AND_SYM
%left	BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE
%left	EQ EQUAL_SYM GE GT_SYM LE LT NE IS LIKE REGEXP IN_SYM
@@ -1024,6 +1025,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%left	NEG '~'
%right	NOT_SYM NOT2_SYM
%right	BINARY COLLATE_SYM
%left   INTERVAL_SYM

%type <lex_str>
        IDENT IDENT_QUOTED TEXT_STRING DECIMAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM
@@ -1066,7 +1068,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <item>
	literal text_literal insert_ident order_ident
	simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
	variable variable_aux bool_term bool_factor bool_test bool_pri 
	variable variable_aux bool_factor
        bool_test bool_pri
	predicate bit_expr bit_term bit_factor value_expr term factor
	table_wild simple_expr udf_expr
	expr_or_default set_expr_or_default interval_expr
@@ -4465,52 +4468,102 @@ optional_braces:

/* all possible expressions */
expr:
	  bool_term { Select->expr_list.push_front(new List<Item>); }
          bool_or_expr
          bool_factor
        | expr or expr %prec OR_SYM
          {
            List<Item> *list= Select->expr_list.pop();
            if (list->elements)
            /*
              Design notes:
              Do not use a manually maintained stack like thd->lex->xxx_list,
              but use the internal bison stack ($$, $1 and $3) instead.
              Using the bison stack is:
              - more robust to changes in the grammar,
              - guaranteed to be in sync with the parser state,
              - better for performances (no memory allocation).
            */
            Item_cond_or *item1;
            Item_cond_or *item3;
            if (is_cond_or($1))
            {
              item1= (Item_cond_or*) $1;
              if (is_cond_or($3))
              {
              list->push_front($1);
              $$= new Item_cond_or(*list);
              /* optimize construction of logical OR to reduce
                 amount of objects for complex expressions */
                item3= (Item_cond_or*) $3;
                /*
                  (X1 OR X2) OR (Y1 OR Y2) ==> OR (X1, X2, Y1, Y2)
                */
                item3->add_at_head(item1->argument_list());
                $$ = $3;
              }
              else
              {
                /*
                  (X1 OR X2) OR Y ==> OR (X1, X2, Y)
                */
                item1->add($3);
                $$ = $1;
            delete list;
              }
	;

bool_or_expr:
	/* empty */
        | bool_or_expr or bool_term
          { Select->expr_list.head()->push_back($3); }
        ;

bool_term:
	bool_term XOR bool_term { $$= new Item_cond_xor($1,$3); }
	| bool_factor { Select->expr_list.push_front(new List<Item>); }
          bool_and_expr
            }
            else if (is_cond_or($3))
            {
              item3= (Item_cond_or*) $3;
              /*
                X OR (Y1 OR Y2) ==> OR (X, Y1, Y2)
              */
              item3->add_at_head($1);
              $$ = $3;
            }
            else
            {
              /* X OR Y */
              $$ = new (YYTHD->mem_root) Item_cond_or($1, $3);
            }
          }
        | expr XOR expr %prec XOR
          {
            /* XOR is a proprietary extension */
            $$ = new (YYTHD->mem_root) Item_cond_xor($1, $3);
          }
        | expr and expr %prec AND_SYM
          {
            List<Item> *list= Select->expr_list.pop();
            if (list->elements)
            /* See comments in rule expr: expr or expr */
            Item_cond_and *item1;
            Item_cond_and *item3;
            if (is_cond_and($1))
            {
              list->push_front($1);
              $$= new Item_cond_and(*list);
              /* optimize construction of logical AND to reduce
                 amount of objects for complex expressions */
              item1= (Item_cond_and*) $1;
              if (is_cond_and($3))
              {
                item3= (Item_cond_and*) $3;
                /*
                  (X1 AND X2) AND (Y1 AND Y2) ==> AND (X1, X2, Y1, Y2)
                */
                item3->add_at_head(item1->argument_list());
                $$ = $3;
              }
              else
              {
                /*
                  (X1 AND X2) AND Y ==> AND (X1, X2, Y)
                */
                item1->add($3);
                $$ = $1;
            delete list;
              }
	;

bool_and_expr:
	/* empty */
        | bool_and_expr and bool_factor
          { Select->expr_list.head()->push_back($3); }
            }
            else if (is_cond_and($3))
            {
              item3= (Item_cond_and*) $3;
              /*
                X AND (Y1 AND Y2) ==> AND (X, Y1, Y2)
              */
              item3->add_at_head($1);
              $$ = $3;
            }
            else
            {
              /* X AND Y */
              $$ = new (YYTHD->mem_root) Item_cond_and($1, $3);
            }
          }
        ;

bool_factor:
@@ -4648,7 +4701,8 @@ all_or_any: ALL { $$ = 1; }
        ;

interval_expr:
         INTERVAL_SYM expr { $$=$2; }
          INTERVAL_SYM expr %prec INTERVAL_SYM
          { $$=$2; }
        ;

simple_expr: