转储文件中视图预定义的目的是什么
What is the purpose of views' predefinitions in dump file
我正在处理我们使用 :sql
schema format Active Record 转储程序的项目(以支持更复杂的逻辑,如触发器)。
我们有很多视图,我可以在 database/structure.sql
文件中看到其中一些具有 "predefined" 架构,其中 NULL
如下:
CREATE VIEW public.my_view AS
SELECT
NULL::integer AS record_id,
NULL::integer AS another_record_id,
NULL::double precision AS some_field;
然后,数千行之后,定义中添加:
CREATE OR REPLACE VIEW public.my_view AS
-- actual query
我在 SQL 查询中看不到架构 "predefinition" 和定义之间对视图的任何引用。此外,还有其他立即创建的视图(没有该架构 "predefinition")。
我正在查看 Active Record 文档,但找不到任何提示。 Rails 在幕后使用 pg_dump
但我在 pg_dump
文档中也没有看到任何相关内容。
为什么有些视图需要提前预定义模式,而有些则不需要,即使其中 none 在 database/structure.sql
文件中的预定义和实际定义之间被引用?是为了防止在使用另一种结构(如物化视图等)时出现某些竞争条件吗?
这是因为视图可以有这样的循环依赖:
CREATE SCHEMA s;
CREATE OR REPLACE VIEW s.v AS SELECT 1 a;
CREATE OR REPLACE VIEW s.w AS SELECT a FROM s.v;
CREATE OR REPLACE VIEW s.v AS SELECT a FROM s.w;
无法在此表单中查询这些视图。例如。 select * from s.w
产生:
SQL Error [42P17]: ERROR: infinite recursion detected in rules for relation "w"
但是运行下面的pg_dump
命令:
pg_dump -U postgres -d postgres -s -n s
产生这个输出:
CREATE SCHEMA s;
CREATE VIEW s.v AS
SELECT
NULL::integer AS a;
CREATE VIEW s.w AS
SELECT v.a
FROM s.v;
CREATE OR REPLACE VIEW s.v AS
SELECT w.a
FROM s.w;
如您所见,必须创建虚拟视图,因为 s.v
在创建时无法访问 not-yet 现有的 s.w
。
您还可以在 pg_dump.c
's createDummyViewAsClause
function 中找到此逻辑,其文档如下:
/*
* Create a dummy AS clause for a view. This is used when the real view
* definition has to be postponed because of circular dependencies.
* We must duplicate the view's external properties -- column names and types
* (including collation) -- so that it works for subsequent references. [...]
*/
我正在处理我们使用 :sql
schema format Active Record 转储程序的项目(以支持更复杂的逻辑,如触发器)。
我们有很多视图,我可以在 database/structure.sql
文件中看到其中一些具有 "predefined" 架构,其中 NULL
如下:
CREATE VIEW public.my_view AS
SELECT
NULL::integer AS record_id,
NULL::integer AS another_record_id,
NULL::double precision AS some_field;
然后,数千行之后,定义中添加:
CREATE OR REPLACE VIEW public.my_view AS
-- actual query
我在 SQL 查询中看不到架构 "predefinition" 和定义之间对视图的任何引用。此外,还有其他立即创建的视图(没有该架构 "predefinition")。
我正在查看 Active Record 文档,但找不到任何提示。 Rails 在幕后使用 pg_dump
但我在 pg_dump
文档中也没有看到任何相关内容。
为什么有些视图需要提前预定义模式,而有些则不需要,即使其中 none 在 database/structure.sql
文件中的预定义和实际定义之间被引用?是为了防止在使用另一种结构(如物化视图等)时出现某些竞争条件吗?
这是因为视图可以有这样的循环依赖:
CREATE SCHEMA s;
CREATE OR REPLACE VIEW s.v AS SELECT 1 a;
CREATE OR REPLACE VIEW s.w AS SELECT a FROM s.v;
CREATE OR REPLACE VIEW s.v AS SELECT a FROM s.w;
无法在此表单中查询这些视图。例如。 select * from s.w
产生:
SQL Error [42P17]: ERROR: infinite recursion detected in rules for relation "w"
但是运行下面的pg_dump
命令:
pg_dump -U postgres -d postgres -s -n s
产生这个输出:
CREATE SCHEMA s;
CREATE VIEW s.v AS
SELECT
NULL::integer AS a;
CREATE VIEW s.w AS
SELECT v.a
FROM s.v;
CREATE OR REPLACE VIEW s.v AS
SELECT w.a
FROM s.w;
如您所见,必须创建虚拟视图,因为 s.v
在创建时无法访问 not-yet 现有的 s.w
。
您还可以在 pg_dump.c
's createDummyViewAsClause
function 中找到此逻辑,其文档如下:
/*
* Create a dummy AS clause for a view. This is used when the real view
* definition has to be postponed because of circular dependencies.
* We must duplicate the view's external properties -- column names and types
* (including collation) -- so that it works for subsequent references. [...]
*/