mirror of
https://github.com/dimitri/pgloader.git
synced 2026-05-04 10:31:02 +02:00
Another attempt at fixing #323.
Rather than trying hard to have PostgreSQL fully qualify the index name with tricks around search_path setting at the time ::regclass is executed, simply join on pg_namespace to retrieve that schema in a new slot in our pgsql-index structure so that we can then reuse it when needed. Also add a test case for the scenario, including both a UNIQUE constraint and a classic index, because the DROP and CREATE/ALTER instructions differ.
This commit is contained in:
parent
7dd69a11e1
commit
d9d9e06c0f
@ -272,21 +272,11 @@
|
||||
(defun list-indexes (table)
|
||||
"List all indexes for TABLE-NAME in SCHEMA. A PostgreSQL connection must
|
||||
be already established when calling that function."
|
||||
(let ((schema (or (table-schema table)
|
||||
(cdr (assoc "search_path" *pg-settings* :test #'string-equal))))
|
||||
(sql-set-search-path "SET search_path TO '';"))
|
||||
;; we force the search_path to emty value so that ::regclass special
|
||||
;; cast and the pg_get_indexdef() and the pg_get_contraintdef() returns
|
||||
;; the fully qualified table name, even when the table is found in the
|
||||
;; 'public' schema.
|
||||
(log-message :debug "~a" sql-set-search-path)
|
||||
(pgloader.pgsql:pgsql-execute sql-set-search-path)
|
||||
|
||||
(prog1
|
||||
(loop
|
||||
:with sql-index-list
|
||||
:= (let ((sql (format nil "
|
||||
(loop
|
||||
:with sql-index-list
|
||||
:= (let ((sql (format nil "
|
||||
select i.relname,
|
||||
n.nspname,
|
||||
indrelid::regclass,
|
||||
indrelid,
|
||||
indisprimary,
|
||||
@ -296,28 +286,26 @@ select i.relname,
|
||||
pg_get_constraintdef(c.oid)
|
||||
from pg_index x
|
||||
join pg_class i ON i.oid = x.indexrelid
|
||||
join pg_namespace n ON n.oid = i.relnamespace
|
||||
left join pg_constraint c ON c.conindid = i.oid
|
||||
where indrelid = '~:[~*public.~;~a.~]~a'::regclass"
|
||||
schema schema
|
||||
(table-name table))))
|
||||
(log-message :debug "~a" sql)
|
||||
sql)
|
||||
where indrelid = '~a'::regclass"
|
||||
(format-table-name table))))
|
||||
(log-message :debug "~a" sql)
|
||||
sql)
|
||||
|
||||
:for (index-name table-name table-oid primary unique sql conname condef)
|
||||
:in (pomo:query sql-index-list)
|
||||
:for (name schema table-name table-oid primary unique sql conname condef)
|
||||
:in (pomo:query sql-index-list)
|
||||
|
||||
:collect (make-pgsql-index :name index-name
|
||||
:table-name table-name
|
||||
:table-oid table-oid
|
||||
:primary primary
|
||||
:unique unique
|
||||
:columns nil
|
||||
:sql sql
|
||||
:conname (unless (eq :null conname) conname)
|
||||
:condef (unless (eq :null condef) condef)))
|
||||
(let ((sql-reset-search-path "reset search_path;"))
|
||||
(log-message :debug "~a" sql-reset-search-path)
|
||||
(pgloader.pgsql:pgsql-execute sql-reset-search-path)))))
|
||||
:collect (make-pgsql-index :name name
|
||||
:schema schema
|
||||
:table-name table-name
|
||||
:table-oid table-oid
|
||||
:primary primary
|
||||
:unique unique
|
||||
:columns nil
|
||||
:sql sql
|
||||
:conname (unless (eq :null conname) conname)
|
||||
:condef (unless (eq :null condef) condef))))
|
||||
|
||||
(defun sanitize-user-gucs (gucs)
|
||||
"Forbid certain actions such as setting a client_encoding different from utf8."
|
||||
|
||||
@ -239,7 +239,7 @@
|
||||
;; the struct is used both for supporting new index creation from non
|
||||
;; PostgreSQL system and for drop/create indexes when using the 'drop
|
||||
;; indexes' option (in CSV mode and the like)
|
||||
name table-name table-oid primary unique columns sql conname condef)
|
||||
name schema table-name table-oid primary unique columns sql conname condef)
|
||||
|
||||
(defgeneric format-pgsql-create-index (table index)
|
||||
(:documentation
|
||||
@ -268,11 +268,15 @@
|
||||
;; ensure good concurrency here, don't take the ACCESS EXCLUSIVE
|
||||
;; LOCK on the table before we have the index done already
|
||||
(or (pgsql-index-sql index)
|
||||
(format nil "CREATE UNIQUE INDEX ~a ON ~a (~{~a~^, ~});"
|
||||
(format nil "CREATE UNIQUE INDEX ~@[~a.~]~a ON ~a (~{~a~^, ~});"
|
||||
(pgsql-index-schema index)
|
||||
index-name
|
||||
(format-table-name table)
|
||||
(pgsql-index-columns index)))
|
||||
(format nil
|
||||
;; don't use the index schema name here, PostgreSQL doesn't
|
||||
;; like it, might be implicit from the table's schema
|
||||
;; itself...
|
||||
"ALTER TABLE ~a ADD ~a USING INDEX ~a;"
|
||||
(format-table-name table)
|
||||
(cond ((pgsql-index-primary index) "PRIMARY KEY")
|
||||
@ -286,15 +290,17 @@
|
||||
|
||||
(t
|
||||
(or (pgsql-index-sql index)
|
||||
(format nil "CREATE~:[~; UNIQUE~] INDEX ~a ON ~a (~{~a~^, ~});"
|
||||
(format nil "CREATE~:[~; UNIQUE~] INDEX ~@[~a.~]~a ON ~a (~{~a~^, ~});"
|
||||
(pgsql-index-unique index)
|
||||
(pgsql-index-schema index)
|
||||
index-name
|
||||
(format-table-name table)
|
||||
(pgsql-index-columns index)))))))
|
||||
|
||||
(defmethod format-pgsql-drop-index ((table table) (index pgsql-index))
|
||||
"Generate the PostgreSQL statement to DROP the index."
|
||||
(let* ((index-name (apply-identifier-case (pgsql-index-name index))))
|
||||
(let* ((schema-name (apply-identifier-case (pgsql-index-schema index)))
|
||||
(index-name (apply-identifier-case (pgsql-index-name index))))
|
||||
(cond ((pgsql-index-conname index)
|
||||
;; here always quote the constraint name, currently the name
|
||||
;; comes from one source only, the PostgreSQL database catalogs,
|
||||
@ -304,7 +310,7 @@
|
||||
(pgsql-index-conname index)))
|
||||
|
||||
(t
|
||||
(format nil "DROP INDEX ~a;" index-name)))))
|
||||
(format nil "DROP INDEX ~@[~a.~]~a;" schema-name index-name)))))
|
||||
|
||||
;;;
|
||||
;;; Parallel index building.
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
*/
|
||||
LOAD CSV
|
||||
FROM inline (a, b, c, d, e)
|
||||
INTO postgresql:///pgloader?partial (a, b, c, e)
|
||||
INTO postgresql:///pgloader?csv.partial (a, b, c, e)
|
||||
|
||||
WITH drop indexes,
|
||||
fields optionally enclosed by '"',
|
||||
@ -24,15 +24,16 @@ LOAD CSV
|
||||
standard_conforming_strings to 'on'
|
||||
|
||||
BEFORE LOAD DO
|
||||
$$ drop table if exists partial; $$,
|
||||
$$ create table partial (
|
||||
$$ drop table if exists csv.partial; $$,
|
||||
$$ create table csv.partial (
|
||||
a integer unique,
|
||||
b text,
|
||||
c text,
|
||||
d text,
|
||||
e text
|
||||
);
|
||||
$$;
|
||||
$$,
|
||||
$$ create index on csv.partial(b); $$ ;
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user