List:Internals« Previous MessageNext Message »
From:Paul Cadach Date:June 21 2001 1:28am
Subject:Re: Testing MySQL 4.0
View as plain text  

----- Original Message -----
From: "Michael Widenius" <monty@stripped>
To: "Paul Cadach" <paul@stripped>
Cc: <internals@stripped>
Sent: Thursday, June 21, 2001 3:28 AM
Subject: Re: Testing MySQL 4.0


> Paul> Michael, can you explain which function sets already used in the
> Paul> listed above (to find where to split mysql_query())? I'm not
familiar with
> Paul> MySQL sources... :(((
> sql/ is where the big work should be done.
> The function mysql_select() should be slit to 3-7 smaller functions
> to handle the different stages instead of being a big massive
> function. The init part and free resources part should be pretty
> obvious, but the rest is a bit harder.

Back to story about using a class to hold and process select's information.
Splitting mysql_select() into parts will provide many (at least join, etc.)
"globals" for those parts. IMHO better to store them in classes' members
than somewhere else (thd, etc.).

> I know; GDB doesn't work really good with threads.
> try creating the following .gdbinit file in the directory you are
> doing debugging:

Ok, I'll try...


> Rename 'mysql_new_subselect()' to 'mysql_init_subselect()'
> This is more in line with mysql_init_select()

I've just track Sinisa's idea about UNIONs. For sub-select it calls
mysql_new_subselect() which allocates new select_lex and fills some fields
depended on sub-selects, then call mysql_init_select() to fill other common
parts (used for regular, sub- selects, and UNIONs) of select_lex structure.

> I would be greatfull if you can follow the same coding style as the
> rest of the code ;  This makes the total much easier to read.
> - Space around !=
> - If and command on different rows:

It's looks like my coding style but I've just copied 'select:' block and
modified it just a bit.

> The expr_expr change looks VERY long.
> Wouldn't some of the things, like
> expr NOT LIKE '(' subselect_stmt ')'
> be handle by adding '(' subselect_stmt ')' to 'simple_expr' ?

I think it's wrong way because it will provide syntax like:
select (select a from x)
which is ugly.

IMHO better is group all sub-select syntax into one non-terminal like
    NOT LIKE '(' subselect_stmt')
    LIKE '(' subselect_stmt ')'
and add next to ..._expr:
    expr subselect_subexpr
        $$ = mysql_subselect_make_item($1, $2);
where mysql_subselect_make_item() must deduce type of operation specified
before sub-select and create required Item_...

At least this will simplify YACC's source but brings complex
mysql_subselect_make_item() function. :(

I think for first time of modelling it's better to use YACC's sources...

> I assume you plan to separate functions classes to handle the
> different 'normal' sub selects like:
> expr IN_SYM '(' subselect_stmt ')'
> { $$= new Item_sub_select_in($1, $4); }

Yep. May be better is to enhance existing Item_... classes to handle
Item_subselect (for example, $$ = new Item_in($1, $4); ) which will works
with temporary table generated by sub-select?

> What do you plan to do with:
> expr GT_SYM some_all '(' subselect_stmt ')'
> It seams kind of stupid to have to do a separate class for
> each operator just to be able to handle 'some_all'.

It's just a flag for subselect execution... SOME/ANY will bring 'LIMIT 1' to
sub-query, while handling of ALL is much harder.

> We need to do some conversation to do this efficiently.
> For example:
> 1000 >= SOME (SELECT a FROM t1 WHERE X )
> should of be converted to the expression:
> If there is a row
> (SELECT 1 from T1 WHERE (X) AND (1000 >= A) LIMIT 1)
> return 1 else 0

Yea! I've thinking about converting original query to
    1000 < (SELECT MAX(a) FROM t1 WHERE X)
where sub-select will return just single value.

BTW, your solution brings one side effect: it will create dependences
between parent and child queries, which will make optimization like "execute
independed sub-queries before main query" impossible. :(((

> 1000 >= ALL (SELECT a FROM t1)
> should be converted to
> If there is a row
> (SELECT 1 from T1 WHERE (X) AND (1000 < A) LIMIT 1)
> return 0 else 1

My idea is to execute
    1000 >= (SELECT MIN(a) FROM t1 WHERE X)

> Note that you should not use NOT as MySQL doesn't use keys when you
> use Item_func_not().

Thanks for information.

BTW, does MIN(), MAX() functions works on non-values (strings, etc.)?