Review MySQL foreign key introspection SQL query.

It turns out sloppy SQL code made its way to pgloader wherein the GROUP
BY clause of the foreign key listing wasn't reference the whole set of
non aggregated output columns.

Thanks to thiagokronig for the new query, which fixes #345.
This commit is contained in:
Dimitri Fontaine 2016-03-09 18:36:44 +01:00
parent b7a873c03f
commit c1fc4f0879

View File

@ -252,36 +252,40 @@ GROUP BY table_name, index_name;"
(loop
:for (table-name name ftable-name cols fcols update-rule delete-rule)
:in (mysql-query (format nil "
SELECT tc.table_name, tc.constraint_name, k.referenced_table_name ft,
SELECT s.table_name, s.constraint_name, s.ft, s.cols, s.fcols,
rc.update_rule, rc.delete_rule
group_concat( k.column_name
order by k.ordinal_position) as cols,
FROM
(
SELECT tc.table_schema, tc.table_name,
tc.constraint_name, k.referenced_table_name ft,
group_concat( k.referenced_column_name
order by k.position_in_unique_constraint) as fcols,
group_concat( k.column_name
order by k.ordinal_position) as cols,
rc.update_rule, rc.delete_rule
group_concat( k.referenced_column_name
order by k.position_in_unique_constraint) as fcols
FROM information_schema.table_constraints tc
FROM information_schema.table_constraints tc
JOIN information_schema.referential_constraints rc
ON rc.constraint_schema = tc.table_schema
AND rc.constraint_name = tc.constraint_name
AND rc.table_name = tc.table_name
LEFT JOIN information_schema.key_column_usage k
ON k.table_schema = tc.table_schema
AND k.table_name = tc.table_name
AND k.constraint_name = tc.constraint_name
LEFT JOIN information_schema.key_column_usage k
ON k.table_schema = tc.table_schema
AND k.table_name = tc.table_name
AND k.constraint_name = tc.constraint_name
WHERE tc.table_schema = '~a'
AND k.referenced_table_schema = '~a'
AND tc.constraint_type = 'FOREIGN KEY'
~:[~*~;and tc.table_name in (~{'~a'~^,~})~]
~:[~*~;and (~{tc.table_name ~a~^ or ~})~]
~:[~*~;and (~{tc.table_name ~a~^ and ~})~]
WHERE tc.table_schema = '~a'
AND k.referenced_table_schema = '~a'
AND tc.constraint_type = 'FOREIGN KEY'
~:[~*~;and tc.table_name in (~{'~a'~^,~})~]
~:[~*~;and (~{tc.table_name ~a~^ or ~})~]
~:[~*~;and (~{tc.table_name ~a~^ and ~})~]
GROUP BY tc.table_name, tc.constraint_name, ft"
GROUP BY tc.table_schema, tc.table_name, tc.constraint_name, ft
) s
JOIN information_schema.referential_constraints rc
ON rc.constraint_schema = s.table_schema
AND rc.constraint_name = s.constraint_name
AND rc.table_name = s.table_name"
(db-name *connection*) (db-name *connection*)
only-tables ; do we print the clause?
only-tables