Fix ALTER TABLE ... DROP CONSTRAINT not to happen against non existing tables or constraints.

This commit is contained in:
Dimitri Fontaine 2013-11-05 21:24:32 +01:00
parent 6e9a3dfaf5
commit a9dd0aafa3
5 changed files with 36 additions and 12 deletions

View File

@ -56,6 +56,7 @@
#:list-tables
#:list-columns
#:list-tables-cols
#:list-tables-and-fkeys
#:list-reserved-keywords
#:reset-all-sequences
#:get-date-columns
@ -145,6 +146,7 @@
#:pgsql-execute
#:pgsql-execute-with-timing
#:apply-identifier-case
#:list-tables-and-fkeys
#:create-tables
#:format-pgsql-column
#:format-extra-type

View File

@ -126,6 +126,17 @@ select relname, array_agg(case when typname in ('date', 'timestamptz')
" schema table-name-list))
collect (cons relname cols))))
(defun list-tables-and-fkeys (&optional schema)
"Yet another table listing query."
(loop for (relname fkeys) in (pomo:query (format nil "
select relname, array_to_string(array_agg(conname), ',')
from pg_class c
join pg_namespace n on n.oid = c.relnamespace
left join pg_constraint co on c.oid = co.conrelid
where contype = 'f' and nspname = ~:[current_schema()~;'~a'~]
group by relname;" schema schema))
collect (cons relname (sq:split-sequence #\, fkeys))))
(defun list-columns (dbname table-name &key schema)
"Return a list of column names for given TABLE-NAME."
(pomo:with-connection

View File

@ -85,15 +85,19 @@
foreign-table
(pgsql-fkey-foreign-columns fk))))
(defmethod format-pgsql-drop-fkey ((fk pgsql-fkey) &key identifier-case)
(defmethod format-pgsql-drop-fkey ((fk pgsql-fkey)
&key all-pgsql-fkeys identifier-case)
"Generate the PostgreSQL statement to rebuild a MySQL Foreign Key"
(let* ((constraint-name
(apply-identifier-case (pgsql-fkey-name fk) identifier-case))
(table-name
(apply-identifier-case (pgsql-fkey-table-name fk) identifier-case)))
;; beware, IF EXISTS is only supported from 9.0 onward...
(format nil "alter table ~a drop constraint if exists ~a"
table-name constraint-name)))
(apply-identifier-case (pgsql-fkey-table-name fk) identifier-case))
(fkeys (cdr (assoc table-name all-pgsql-fkeys :test #'string=)))
(fkey-exists (member constraint-name fkeys :test #'string=)))
(when fkey-exists
;; we could do that without all-pgsql-fkeys in 9.2 and following with:
;; alter table if exists ... drop constraint if exists ...
(format nil "ALTER TABLE ~a DROP CONSTRAINT ~a" table-name constraint-name))))
;;;

View File

@ -232,13 +232,19 @@ GROUP BY table_name, index_name;" dbname)))
;; free resources
(cl-mysql:disconnect)))
(defun drop-fkeys (all-fkeys &key identifier-case)
(defun drop-fkeys (all-fkeys &key dbname identifier-case)
"Drop all Foreign Key Definitions given, to prepare for a clean run."
(loop for (table-name . fkeys) in all-fkeys
do
(loop for fkey in fkeys
for sql = (format-pgsql-drop-fkey fkey :identifier-case identifier-case)
do (pgsql-execute sql))))
(let ((all-pgsql-fkeys (list-tables-and-fkeys dbname)))
(loop for (table-name . fkeys) in all-fkeys
do
(loop for fkey in fkeys
for sql = (format-pgsql-drop-fkey fkey
:all-pgsql-fkeys all-pgsql-fkeys
:identifier-case identifier-case)
when sql
do
(log-message :notice "~a;" sql)
(pgsql-execute sql)))))
(defun create-fkeys (all-fkeys
&key
@ -251,7 +257,7 @@ GROUP BY table_name, index_name;" dbname)))
for sql =
(format-pgsql-create-fkey fkey :identifier-case identifier-case)
do
(log-message :notice "~a" sql)
(log-message :notice "~a;" sql)
(pgsql-execute-with-timing dbname "Foreign Keys" sql state))))

View File

@ -239,6 +239,7 @@
;; can DROP TABLE when asked
(when (and foreign-keys include-drop)
(drop-fkeys all-fkeys
:dbname pg-dbname
:identifier-case identifier-case))
;; now drop then create tables and types, etc