Late Binding Views
In my view, the most significant feature missing from PostgreSQL is the
ability to create views without hard dependencies.
Views reference objects by
oid
not by
name
,
hence creating a view always has the potential to break automated schema
updates.
Amazon Redshift solves this using
late binding views
CREATE VIEW ... WITH NO SCHEMA BINDING;
Redshift keeps a record of column types in a separate table
SELECT pg_get_late_binding_view_cols(); (public,myview,tag_id,integer,1) (public,myview,name,"character varying(20)",2) (public,myview,created,"timestamp with time zone",3)
Rules
Internally PostgreSQL implements views using the rule system. Prior to
PostgreSQL 16 tables were converted to views when an
ON SELECT
rule was added
CREATE TABLE tag ( tag_id integer NOT NULL, name varchar(20) NOT NULL, created timestamp with time zone NOT NULL DEFAULT now() ); CREATE TABLE tag2 ( tag_id integer NOT NULL, name varchar(20) NOT NULL, created timestamp with time zone NOT NULL DEFAULT now() ); CREATE RULE "_RETURN" AS ON SELECT TO tag DO INSTEAD SELECT * FROM tag2;
Removing Dependencies
It is possible, but not advisable to remove view dependencies manually
test=# select relname,oid,relkind from pg_catalog.pg_class where relname in ('tag', 'tag2'); relname | oid | relkind ---------+-------+--------- tag | 16385 | v tag2 | 16390 | r (2 rows) test=# DELETE FROM pg_depend WHERE refobjid='tag2'::regclass; DELETE 7 test=# DROP TABLE tag2; DROP TABLE test=# SELECT * FROM tag ; ERROR: could not open relation with OID 16390
Solutions
It would be possible to skip dependencies when a rule is created
--- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -162,6 +162,7 @@ InsertRule(const char *rulname, referenced.objectId = eventrel_oid; referenced.objectSubId = 0; +#if 0 recordDependencyOn(&myself, &referenced, (evtype == CMD_SELECT) ? DEPENDENCY_INTERNAL : DEPENDENCY_AUTO); @@ -170,6 +171,7 @@ InsertRule(const char *rulname, */ recordDependencyOnExpr(&myself, (Node *) action, NIL, DEPENDENCY_NORMAL); +#endif if (event_qual != NULL) {
This almost works, but the view definition can no longer described with
\d+
.
Feel free to contact me with ideas!
Further Reading
The dependency ladder by Federico Campoli