mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
7517d7e112
"Process NATURAL and USING joins according to SQL:2003". * Some of the main problems fixed by the patch: - in "select *" queries the * expanded correctly according to ANSI for arbitrary natural/using joins - natural/using joins are correctly transformed into JOIN ... ON for any number/nesting of the joins. - column references are correctly resolved against natural joins of any nesting and combined with arbitrary other joins. * This patch also contains a fix for name resolution of items inside the ON condition of JOIN ... ON - in this case items must be resolved only against the JOIN operands. To support such 'local' name resolution, the patch introduces a stack of name resolution contexts used at parse time. NOTICE: - This patch is not complete in the sense that - there are 2 test cases that still do not pass - one in join.test, one in select.test. Both are marked with a comment "TODO: WL#2486". - it does not include a new test specific for the task mysql-test/include/ps_query.inc: Adjusted according to standard NATURAL/USING join semantics., mysql-test/r/bdb.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/derived.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/errors.result: The column as a whole cannot be resolved, so different error message. mysql-test/r/fulltext.result: Adjusted according to standard JOIN ... ON semantics => the ON condition can refer only to the join operands. mysql-test/r/fulltext_order_by.result: More detailed error message. mysql-test/r/innodb.result: Adjusted according to standard NATURAL/USING join semantics. This test doesn't pass completetly yet! mysql-test/r/insert_select.result: More detailed error message. mysql-test/r/join.result: Adjusted according to standard NATURAL/USING join semantics. NOTICE: there is one test case that still fails, and it is commeted out and marked with WL#2486 in the test file. mysql-test/r/join_crash.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/join_nested.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/join_outer.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/multi_update.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/null_key.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/order_by.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/ps_2myisam.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/ps_3innodb.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/ps_4heap.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/ps_5merge.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/ps_6bdb.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/ps_7ndb.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/select.result: Adjusted according to standard NATURAL/USING join semantics. NOTICE: there is one failing test case which is commented with WL#2486 in the test file. mysql-test/r/subselect.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/type_ranges.result: Adjusted according to standard NATURAL/USING join semantics. mysql-test/r/union.result: More detailed error message. mysql-test/t/bdb.test: Adjusted according to standard NATURAL/USING join semantics. mysql-test/t/errors.test: Adjusted according to standard NATURAL/USING join semantics. mysql-test/t/fulltext.test: Adjusted according to standard JOIN ... ON semantics => the ON condition can refer only to the join operands. mysql-test/t/fulltext_order_by.test: More detailed error message. mysql-test/t/innodb.test: Adjusted according to standard NATURAL/USING join semantics. This test doesn't pass completetly yet! mysql-test/t/insert_select.test: More detailed error message. mysql-test/t/join.test: Adjusted according to standard NATURAL/USING join semantics. NOTICE: there is one test case that still fails, and it is commeted out and marked with WL#2486 in the test file. mysql-test/t/join_crash.test: Adjusted according to standard NATURAL/USING join semantics. mysql-test/t/join_nested.test: Adjusted according to standard NATURAL/USING join semantics. mysql-test/t/join_outer.test: Adjusted according to standard NATURAL/USING join semantics. mysql-test/t/null_key.test: Adjusted according to standard NATURAL/USING join semantics. mysql-test/t/order_by.test: Adjusted according to standard NATURAL/USING join semantics. mysql-test/t/select.test: Adjusted according to standard NATURAL/USING join semantics. NOTICE: there is one test case that still fails, and it is commeted out and marked with WL#2486 in the test file. mysql-test/t/subselect.test: Adjusted according to standard NATURAL/USING join semantics. mysql-test/t/type_ranges.test: Adjusted according to standard NATURAL/USING join semantics. mysql-test/t/union.test: More detailed error message. sql/item.cc: - extra parameter to find_field_in_tables - find_field_in_real_table renamed to find_field_in_table - fixed comments/typos sql/item.h: - added [first | last]_name_resolution_table to class Name_resolution_context - commented old code - standardized formatting sql/mysql_priv.h: - refactored the find_field_in_XXX procedures, - added a new procedure for natural join table references, - renamed the find_field_in_XXX procedures to clearer names sql/sp.cc: - pass the top-most list of the FROM clause to setup_tables - extra parameter to find_field_in_tables sql/sql_acl.cc: - renamed find_field_in_table => find_field_in_table_ref - extra parameter to find_field_in_table_ref - commented old code sql/sql_base.cc: This file contains the core of the implementation of the processing of NATURAL/USING joins (WL#2486). - added many comments to old code - refactored the group of find_field_in_XXX procedures, and added a new procedure for natural joins. There is one find_field_in_XXX procedure per each type of table reference (stored table, merge view, or natural join); one meta-procedure that selects the correct one depeneding on the table reference; and one procedure that goes over a list of table referenes. - NATURAL/USING joins are processed through the procedures: mark_common_columns, store_natural_using_join_columns, store_top_level_join_columns, setup_natural_join_row_types. The entry point to processing NATURAL/USING joins is the procedure 'setup_natural_join_row_types'. - Replaced the specialized Field_iterator_XXX iterators with one generic iterator over the fields of a table reference. - Simplified 'insert_fields' and 'setup_conds' due to encapsulation of the processing of natural joins in a separate set of procedures. sql/sql_class.h: - Commented old code. sql/sql_delete.cc: - Pass the FROM clause to setup_tables. sql/sql_help.cc: - pass the end name resolution table to find_field_in_tables - adjust the list of tables for name resolution sql/sql_insert.cc: - Changed the code that saves and restores the current context to support the list of tables for name resolution - context->first_name_resolution_table, and table_list->next_name_resolution_table. Needed to support an ugly trick to resolve inserted columns only in the first table. - Added Name_resolution_context::[first | last]_name_resolution_table. - Commented old code sql/sql_lex.cc: - set select_lex.parent_lex correctly - set correct state of the current name resolution context sql/sql_lex.h: - Added a stack of name resolution contexts to support local contexts for JOIN ... ON conditions. - Commented old code. sql/sql_load.cc: - Pass the FROM clause to setup_tables. sql/sql_olap.cc: - Pass the FROM clause to setup_tables. sql/sql_parse.cc: - correctly set SELECT_LEX::parent_lex - set the first table of the current name resoltion context - added support for NATURAL/USING joins - commented old code sql/sql_select.cc: - Pass the FROM clause to setup_tables. - Pass the end table to find_field_in_tables - Improved comments sql/sql_show.cc: - Set SELECT_LEX::parent_lex. sql/sql_update.cc: - Pass the FROM clause to setup_tables. sql/sql_yacc.yy: - Added support for a stack of name resolution contexts needed to implement name resolution for JOIN ... ON. A context is pushed for each new JOIN ... ON, and popped afterwards. - Added support for NATURAL/USING joins. sql/table.cc: - Added new class Natural_join_column to hide the heterogeneous representation of column references for stored tables and for views. - Added a new list TABLE_LIST::next_name_resolution_table to support name resolution with NATURAL/USING joins. Also added other members to TABLE_LIST to support NATURAL/USING joins. - Added a generic iterator over the fields of table references of various types - class Field_iterator_table_ref sql/table.h: - Added new class Natural_join_column to hide the heterogeneous representation of column references for stored tables and for views. - Added a new list TABLE_LIST::next_name_resolution_table to support name resolution with NATURAL/USING joins. Also added other members to TABLE_LIST to support NATURAL/USING joins. - Added a generic iterator over the fields of table references of various types - class Field_iterator_table_ref tests/mysql_client_test.c: Adjusted according to standard NATURAL JOIN syntax.
121 lines
4.9 KiB
Text
121 lines
4.9 KiB
Text
#
|
|
# This test gave a core dump
|
|
#
|
|
|
|
--disable_warnings
|
|
DROP TABLE IF EXISTS t1,t2,t3,t4;
|
|
--enable_warnings
|
|
|
|
CREATE TABLE t1 (
|
|
project_id int(11) NOT NULL auto_increment,
|
|
project_row_lock int(11) NOT NULL default '0',
|
|
project_name varchar(80) NOT NULL default '',
|
|
client_ptr int(11) NOT NULL default '0',
|
|
project_contact_ptr int(11) default NULL,
|
|
client_contact_ptr int(11) default NULL,
|
|
billing_contact_ptr int(11) default NULL,
|
|
comments mediumtext,
|
|
PRIMARY KEY (project_id),
|
|
UNIQUE KEY project (client_ptr,project_name)
|
|
) ENGINE=MyISAM PACK_KEYS=1;
|
|
|
|
INSERT INTO t1 VALUES (1,0,'Rejected Time',1,NULL,NULL,NULL,NULL);
|
|
INSERT INTO t1 VALUES (209,0,'MDGRAD Proposal/Investigation',97,NULL,NULL,NULL,'');
|
|
INSERT INTO t1 VALUES (208,0,'Font 9 Design',84,NULL,NULL,NULL,'');
|
|
INSERT INTO t1 VALUES (207,0,'Web Based Order Processing',95,NULL,NULL,NULL,'');
|
|
INSERT INTO t1 VALUES (205,0,'Mac Screen Saver',95,NULL,NULL,NULL,'');
|
|
INSERT INTO t1 VALUES (206,0,'Web Site',96,NULL,NULL,NULL,'');
|
|
INSERT INTO t1 VALUES (204,0,'Magnafire Glue',94,NULL,NULL,NULL,'');
|
|
INSERT INTO t1 VALUES (203,0,'Print Bid',93,NULL,NULL,NULL,'');
|
|
INSERT INTO t1 VALUES (202,0,'EPOC Port',92,NULL,NULL,NULL,'');
|
|
INSERT INTO t1 VALUES (201,0,'TravelMate',88,NULL,NULL,NULL,'');
|
|
|
|
CREATE TABLE t2 (
|
|
period_id int(11) NOT NULL auto_increment,
|
|
period_type enum('user_table','client_table','role_table','member_table','project_table') default NULL,
|
|
period_key int(11) default NULL,
|
|
start_date datetime default NULL,
|
|
end_date datetime default NULL,
|
|
work_load int(11) default NULL,
|
|
PRIMARY KEY (period_id),
|
|
KEY period_index (period_type,period_key),
|
|
KEY date_index (start_date,end_date)
|
|
) ENGINE=MyISAM PACK_KEYS=1;
|
|
|
|
INSERT INTO t2 VALUES (1,'user_table',98,'2000-01-01 00:00:00',NULL,NULL);
|
|
INSERT INTO t2 VALUES (2,'user_table',99,'2000-01-01 00:00:00',NULL,NULL);
|
|
INSERT INTO t2 VALUES (3,'user_table',100,'2000-01-01 00:00:00',NULL,NULL);
|
|
INSERT INTO t2 VALUES (49,'project_table',148,'2000-01-01 00:00:00',NULL,NULL);
|
|
INSERT INTO t2 VALUES (50,'client_table',68,'2000-01-01 00:00:00',NULL,NULL);
|
|
INSERT INTO t2 VALUES (51,'project_table',149,'2000-01-01 00:00:00',NULL,NULL);
|
|
INSERT INTO t2 VALUES (52,'project_table',150,'2000-01-01 00:00:00',NULL,NULL);
|
|
INSERT INTO t2 VALUES (53,'client_table',69,'2000-01-01 00:00:00',NULL,NULL);
|
|
INSERT INTO t2 VALUES (54,'project_table',151,'2000-01-01 00:00:00',NULL,NULL);
|
|
INSERT INTO t2 VALUES (55,'client_table',70,'2000-01-01 00:00:00',NULL,NULL);
|
|
INSERT INTO t2 VALUES (155,'role_table',1,'2000-01-01 00:00:00',NULL,NULL);
|
|
INSERT INTO t2 VALUES (156,'role_table',2,'2000-01-01 00:00:00',NULL,NULL);
|
|
INSERT INTO t2 VALUES (160,'member_table',1,'2000-01-01 00:00:00',NULL,1);
|
|
INSERT INTO t2 VALUES (161,'member_table',2,'2000-01-01 00:00:00',NULL,1);
|
|
INSERT INTO t2 VALUES (162,'member_table',3,'2000-01-01 00:00:00',NULL,1);
|
|
|
|
CREATE TABLE t3 (
|
|
budget_id int(11) NOT NULL auto_increment,
|
|
project_ptr int(11) NOT NULL default '0',
|
|
po_number varchar(20) NOT NULL default '',
|
|
status enum('open','closed') default NULL,
|
|
date_received datetime default NULL,
|
|
amount_received float(10,2) default NULL,
|
|
adjustment float(10,2) default NULL,
|
|
PRIMARY KEY (budget_id),
|
|
UNIQUE KEY po (project_ptr,po_number)
|
|
) ENGINE=MyISAM PACK_KEYS=1;
|
|
|
|
CREATE TABLE t4 (
|
|
client_id int(11) NOT NULL auto_increment,
|
|
client_row_lock int(11) NOT NULL default '0',
|
|
client_name varchar(80) NOT NULL default '',
|
|
contact_ptr int(11) default NULL,
|
|
comments mediumtext,
|
|
PRIMARY KEY (client_id),
|
|
UNIQUE KEY client_name (client_name)
|
|
) ENGINE=MyISAM PACK_KEYS=1;
|
|
|
|
INSERT INTO t4 VALUES (1,0,'CPS',NULL,NULL);
|
|
|
|
#
|
|
# The query that fails...
|
|
#
|
|
select distinct
|
|
t1.project_id as project_id,
|
|
t1.project_name as project_name,
|
|
t1.client_ptr as client_ptr,
|
|
t1.comments as comments,
|
|
sum( t3.amount_received ) + sum( t3.adjustment ) as total_budget
|
|
from
|
|
t2 as client_period ,
|
|
t2 as project_period,
|
|
t3 left join t1 on (t3.project_ptr = t1.project_id and
|
|
t3.date_received <= '2001-03-22 14:15:09')
|
|
left join t4 on t4.client_id = t1.client_ptr
|
|
where
|
|
1
|
|
and ( client_period.period_type = 'client_table'
|
|
and client_period.period_key = t4.client_id
|
|
and ( client_period.start_date <= '2001-03-22 14:15:09' or isnull( client_period.start_date ))
|
|
and ( client_period.end_date > '2001-03-21 14:15:09' or isnull( client_period.end_date ))
|
|
)
|
|
and ( project_period.period_type = 'project_table'
|
|
and project_period.period_key = t1.project_id
|
|
and ( project_period.start_date <= '2001-03-22 14:15:09' or isnull( project_period.start_date ))
|
|
and ( project_period.end_date > '2001-03-21 14:15:09' or isnull( project_period.end_date )) )
|
|
group by
|
|
client_id,
|
|
project_id ,
|
|
client_period.period_id ,
|
|
project_period.period_id
|
|
order by
|
|
client_name asc,
|
|
project_name asc;
|
|
DROP TABLE t1,t2,t3,t4;
|
|
|
|
# End of 4.1 tests
|