Schema-qualified names
Introduction to PostgreSQL schemas
A schema in PostgreSQL (and in the ANSI SQL standard) is a collection of tables, views, functions, constraints, indexes and sequences. PostgreSQL allows you to define multiple schemas in the same database, and different schemas can include datastructres (such as tables) with the same name. You can think of them as namespaces for tables.
Here is the hierarchy of names:
- each PostgreSQL instance can have multiple databases;
- each database can contain multiple schemas;
- each schema can contain multiple tables (and views, functions and so on).
In SQL syntax you will use qualified names including a schema, such as myschema.mytable
anywhere were you use a “normal” unqualified name mytable
. Default objects created by the user are
in the schema named public
(this schema is not normally printed in query results because the
current search_path
includes public
). Objects used internally by PostgreSQL are in system-defined schemas
such as pg_catalog
, pg_toast
and information_schema
.
The pg-el library represents schema-qualified names using pg-qualified-name
objects, which are
cl-defstruct
objects. This means you can create them as follows:
(make-pg-qualified-name :schema "myschema" :name "mytable")
You can then use these objects anywhere you would use a normal table name, escaping special
characters using pg-print-qualified-name
. The pg-tables
function will return normal string names
for tables in the public
namespace, and pg-qualified-name
objects for tables in other namespaces.
ELISP> (let ((res (pg-exec *pg* "SHOW search_path")))
(pg-result res :tuple 0))
("\"$user\", public")
ELISP> (let ((res (pg-exec *pg* "CREATE SCHEMA custom")))
(pg-result res :status))
"CREATE SCHEMA"
ELISP> (let* ((qn (make-pg-qualified-name :schema "custom" :name "mytable"))
(sql (format "CREATE TABLE IF NOT EXISTS %s(id INTEGER)"
(pg-print-qualified-name qn)))
(res (pg-exec *pg* sql)))
(pg-result res :status))
"CREATE TABLE"
ELISP> (pg-tables *pg*)
("purchases" "customers" #s(pg-qualified-name :schema "custom" :name "mytable"))
;; We can use schema-qualified names as parameters for a prepared query.
ELISP> (let* ((qn (make-pg-qualified-name :schema "custom" :name "mytable"))
(pqn (pg-print-qualified-name qn))
(sql "SELECT pg_total_relation_size($1)")
(res (pg-exec-prepared *pg* sql `((,pqn . "text")))))
(pg-result res :tuple 0))
(0)