mirror of
https://github.com/dimitri/pgloader.git
synced 2026-05-05 02:46:10 +02:00
Fix identifier quoting corner cases.
In cases when pgloader needs to build a new identifer from existing ones (mainly for renaming indexes, because they are unique per-table in the source database and unique per-schema in PostgreSQL), and we compose the new name from already quoted strings, pgloader was doing the wrong thing. Fix that by having a build-identifier function that may unquote parts then re-quote properly (if needed) the new identifier.
This commit is contained in:
parent
f6cb428c6d
commit
bae40d40c3
@ -32,7 +32,10 @@
|
||||
|
||||
(defpackage #:pgloader.quoting
|
||||
(:use #:cl #:pgloader.params)
|
||||
(:export #:apply-identifier-case))
|
||||
(:export #:apply-identifier-case
|
||||
#:build-identifier
|
||||
#:quoted-p
|
||||
#:ensure-unquoted))
|
||||
|
||||
(defpackage #:pgloader.catalog
|
||||
(:use #:cl #:pgloader.params #:pgloader.quoting)
|
||||
@ -251,6 +254,7 @@
|
||||
(defpackage #:pgloader.utils
|
||||
(:use #:cl
|
||||
#:pgloader.params
|
||||
#:pgloader.quoting
|
||||
#:pgloader.catalog
|
||||
#:pgloader.monitor
|
||||
#:pgloader.state
|
||||
@ -278,11 +282,9 @@
|
||||
;; charsets
|
||||
#:list-encodings-and-aliases
|
||||
#:show-encodings
|
||||
#:make-external-format
|
||||
|
||||
;; quoting
|
||||
#:apply-identifier-case))
|
||||
#:make-external-format))
|
||||
|
||||
(cl-user::export-inherited-symbols "pgloader.quoting" "pgloader.utils")
|
||||
(cl-user::export-inherited-symbols "pgloader.catalog" "pgloader.utils")
|
||||
(cl-user::export-inherited-symbols "pgloader.monitor" "pgloader.utils")
|
||||
(cl-user::export-inherited-symbols "pgloader.state" "pgloader.utils")
|
||||
|
||||
@ -150,10 +150,10 @@
|
||||
(index-name index)
|
||||
|
||||
;; in the general case, we build our own index name.
|
||||
(format nil "idx_~a_~a"
|
||||
(table-oid (index-table index))
|
||||
(index-name index))))
|
||||
(index-name (apply-identifier-case index-name)))
|
||||
(build-identifier "_"
|
||||
"idx"
|
||||
(table-oid (index-table index))
|
||||
(index-name index)))))
|
||||
(cond
|
||||
((or (index-primary index)
|
||||
(and (index-condef index) (index-unique index)))
|
||||
|
||||
@ -98,16 +98,6 @@
|
||||
(let ((table-name (table-name table)))
|
||||
(format nil "^~a$" (ensure-unquoted table-name))))
|
||||
|
||||
(defun ensure-unquoted (identifier)
|
||||
(cond ((pgloader.quoting::quoted-p identifier)
|
||||
;; when the table name comes from the user (e.g. in the
|
||||
;; load file) then we might have to unquote it: the
|
||||
;; PostgreSQL catalogs does not store object names in
|
||||
;; their quoted form.
|
||||
(subseq identifier 1 (1- (length identifier))))
|
||||
|
||||
(t identifier)))
|
||||
|
||||
(defun query-table-schema (table)
|
||||
"Get PostgreSQL schema name where to locate TABLE-NAME by following the
|
||||
current search_path rules. A PostgreSQL connection must be opened."
|
||||
|
||||
@ -132,7 +132,7 @@
|
||||
(every (lambda (field)
|
||||
(string-equal "integer" (coldef-dtype field)))
|
||||
pk-fields))
|
||||
(let ((pk-name (format nil "~a_pkey" (format-table-name table)))
|
||||
(let ((pk-name (build-identifier "_" (format-table-name table) "pkey"))
|
||||
(clist (mapcar #'coldef-name pk-fields)))
|
||||
;; now forge the index and get it a name
|
||||
(add-index table (make-index :name pk-name
|
||||
|
||||
@ -46,3 +46,25 @@
|
||||
(:quote (format nil "~s"
|
||||
(cl-ppcre:regex-replace-all "\"" identifier "\"\"")))
|
||||
(:none identifier))))
|
||||
|
||||
(defun ensure-unquoted (identifier)
|
||||
(cond ((quoted-p identifier)
|
||||
;; when the table name comes from the user (e.g. in the
|
||||
;; load file) then we might have to unquote it: the
|
||||
;; PostgreSQL catalogs does not store object names in
|
||||
;; their quoted form.
|
||||
(subseq identifier 1 (1- (length identifier))))
|
||||
|
||||
(t identifier)))
|
||||
|
||||
(defun build-identifier (sep &rest parts)
|
||||
"Concatenante PARTS into a PostgreSQL identifier, with SEP in between
|
||||
parts. That's useful for creating an index name from a table's oid and name."
|
||||
(apply-identifier-case
|
||||
(apply #'concatenate
|
||||
'string
|
||||
(loop :for (part . more?) :on parts
|
||||
:collect (ensure-unquoted (typecase part
|
||||
(string part)
|
||||
(t (princ-to-string part))))
|
||||
:when more? :collect sep))))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user