Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
df0fbdf5
Commit
df0fbdf5
authored
Jan 30, 2007
by
malff/marcsql@weblab.(none)
Browse files
Options
Browse Files
Download
Plain Diff
Merge weblab.(none):/home/marcsql/TREE/mysql-5.0-21904
into weblab.(none):/home/marcsql/TREE/mysql-5.1-21904-merge
parents
04a99458
f5ad4eed
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
144 additions
and
17 deletions
+144
-17
sql/item_subselect.cc
sql/item_subselect.cc
+30
-0
sql/item_subselect.h
sql/item_subselect.h
+16
-0
sql/sql_yacc.yy
sql/sql_yacc.yy
+98
-17
No files found.
sql/item_subselect.cc
View file @
df0fbdf5
...
...
@@ -51,6 +51,10 @@ Item_subselect::Item_subselect():
void
Item_subselect
::
init
(
st_select_lex
*
select_lex
,
select_subselect
*
result
)
{
/*
Please see Item_singlerow_subselect::invalidate_and_restore_select_lex(),
which depends on alterations to the parse tree implemented here.
*/
DBUG_ENTER
(
"Item_subselect::init"
);
DBUG_PRINT
(
"enter"
,
(
"select_lex: 0x%lx"
,
(
long
)
select_lex
));
...
...
@@ -91,6 +95,12 @@ void Item_subselect::init(st_select_lex *select_lex,
DBUG_VOID_RETURN
;
}
st_select_lex
*
Item_subselect
::
get_select_lex
()
{
return
unit
->
first_select
();
}
void
Item_subselect
::
cleanup
()
{
DBUG_ENTER
(
"Item_subselect::cleanup"
);
...
...
@@ -307,6 +317,26 @@ Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
DBUG_VOID_RETURN
;
}
st_select_lex
*
Item_singlerow_subselect
::
invalidate_and_restore_select_lex
()
{
DBUG_ENTER
(
"Item_singlerow_subselect::invalidate_and_restore_select_lex"
);
st_select_lex
*
result
=
get_select_lex
();
DBUG_ASSERT
(
result
);
/*
This code restore the parse tree in it's state before the execution of
Item_singlerow_subselect::Item_singlerow_subselect(),
and in particular decouples this object from the SELECT_LEX,
so that the SELECT_LEX can be used with a different flavor
or Item_subselect instead, as part of query rewriting.
*/
unit
->
item
=
NULL
;
DBUG_RETURN
(
result
);
}
Item_maxmin_subselect
::
Item_maxmin_subselect
(
THD
*
thd_param
,
Item_subselect
*
parent
,
st_select_lex
*
select_lex
,
...
...
sql/item_subselect.h
View file @
df0fbdf5
...
...
@@ -126,6 +126,12 @@ public:
enum_parsing_place
place
()
{
return
parsing_place
;
}
bool
walk
(
Item_processor
processor
,
bool
walk_subquery
,
byte
*
arg
);
/**
Get the SELECT_LEX structure associated with this Item.
@return the SELECT_LEX structure associated with this Item
*/
st_select_lex
*
get_select_lex
();
friend
class
select_subselect
;
friend
class
Item_in_optimizer
;
friend
bool
Item_field
::
fix_fields
(
THD
*
,
Item
**
);
...
...
@@ -169,6 +175,16 @@ public:
bool
null_inside
();
void
bring_value
();
/**
This method is used to implement a special case of semantic tree
rewriting, mandated by a SQL:2003 exception in the specification.
The only caller of this method is handle_sql2003_note184_exception(),
see the code there for more details.
Do not call this method for other purposes.
@return the SELECT_LEX structure that was given in the constructor.
*/
st_select_lex
*
invalidate_and_restore_select_lex
();
friend
class
select_singlerow_subselect
;
};
...
...
sql/sql_yacc.yy
View file @
df0fbdf5
...
...
@@ -310,6 +310,81 @@ void case_stmt_action_end_case(LEX *lex, bool simple)
lex->sphead->do_cont_backpatch();
}
/**
Helper to resolve the SQL:2003 Syntax exception 1) in <in predicate>.
See SQL:2003, Part 2, section 8.4 <in predicate>, Note 184, page 383.
This function returns the proper item for the SQL expression
<code>left [NOT] IN ( expr )</code>
@param thd the current thread
@param left the in predicand
@param equal true for IN predicates, false for NOT IN predicates
@param expr first and only expression of the in value list
@return an expression representing the IN predicate.
*/
Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal,
Item *expr)
{
/*
Relevant references for this issue:
- SQL:2003, Part 2, section 8.4 <in predicate>, page 383,
- SQL:2003, Part 2, section 7.2 <row value expression>, page 296,
- SQL:2003, Part 2, section 6.3 <value expression primary>, page 174,
- SQL:2003, Part 2, section 7.15 <subquery>, page 370,
- SQL:2003 Feature F561, "Full value expressions".
The exception in SQL:2003 Note 184 means:
Item_singlerow_subselect, which corresponds to a <scalar subquery>,
should be re-interpreted as an Item_in_subselect, which corresponds
to a <table subquery> when used inside an <in predicate>.
Our reading of Note 184 is reccursive, so that all:
- IN (( <subquery> ))
- IN ((( <subquery> )))
- IN '('^N <subquery> ')'^N
- etc
should be interpreted as a <table subquery>, no matter how deep in the
expression the <subquery> is.
*/
Item *result;
DBUG_ENTER("handle_sql2003_note184_exception");
if (expr->type() == Item::SUBSELECT_ITEM)
{
Item_subselect *expr2 = (Item_subselect*) expr;
if (expr2->substype() == Item_subselect::SINGLEROW_SUBS)
{
Item_singlerow_subselect *expr3 = (Item_singlerow_subselect*) expr2;
st_select_lex *subselect;
/*
Implement the mandated change, by altering the semantic tree:
left IN Item_singlerow_subselect(subselect)
is modified to
left IN (subselect)
which is represented as
Item_in_subselect(left, subselect)
*/
subselect= expr3->invalidate_and_restore_select_lex();
result= new (thd->mem_root) Item_in_subselect(left, subselect);
if (! equal)
result = negate_expression(thd, result);
DBUG_RETURN(result);
}
}
if (equal)
result= new (thd->mem_root) Item_func_eq(left, expr);
else
result= new (thd->mem_root) Item_func_ne(left, expr);
DBUG_RETURN(result);
}
%}
%union {
int num;
...
...
@@ -6168,31 +6243,37 @@ bool_pri:
| predicate ;
predicate:
bit_expr IN_SYM '(' subselect ')'
{ $$= new Item_in_subselect($1, $4); }
| bit_expr not IN_SYM '(' subselect ')'
{ $$= negate_expression(YYTHD, new Item_in_subselect($1, $5)); }
bit_expr IN_SYM '(' subselect ')'
{
$$= new (YYTHD->mem_root) Item_in_subselect($1, $4);
}
| bit_expr not IN_SYM '(' subselect ')'
{
THD *thd= YYTHD;
Item *item= new (thd->mem_root) Item_in_subselect($1, $5);
$$= negate_expression(thd, item);
}
| bit_expr IN_SYM '(' expr ')'
{
$$= new Item_func_eq($1
, $4);
$$= handle_sql2003_note184_exception(YYTHD, $1, true
, $4);
}
| bit_expr IN_SYM '(' expr ',' expr_list ')'
{
$6->push_front($4);
$6->push_front($1);
$$= new
Item_func_in(*$6);
| bit_expr IN_SYM '(' expr ',' expr_list ')'
{
$6->push_front($4);
$6->push_front($1);
$$= new (YYTHD->mem_root)
Item_func_in(*$6);
}
| bit_expr not IN_SYM '(' expr ')'
{
$$= new Item_func_ne($1
, $5);
$$= handle_sql2003_note184_exception(YYTHD, $1, false
, $5);
}
| bit_expr not IN_SYM '(' expr ',' expr_list ')'
| bit_expr not IN_SYM '(' expr ',' expr_list ')'
{
$7->push_front($5);
$7->push_front($1);
Item_func_in *item = new
Item_func_in(*$7);
item->negate();
$$= item;
$7->push_front($5);
$7->push_front($1);
Item_func_in *item = new (YYTHD->mem_root)
Item_func_in(*$7);
item->negate();
$$= item;
}
| bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
{ $$= new Item_func_between($1,$3,$5); }
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment