Re: Parsing of VIEW definitions - Mailing list pgsql-general

From Tom Lane
Subject Re: Parsing of VIEW definitions
Date
Msg-id 17596.1044723298@sss.pgh.pa.us
Whole thread Raw
In response to Parsing of VIEW definitions  (Eric B.Ridge <ebr@tcdi.com>)
Responses Re: Parsing of VIEW definitions  (Eric B.Ridge <ebr@tcdi.com>)
List pgsql-general
"Eric B.Ridge" <ebr@tcdi.com> writes:
> I'm just curious...
> If you have a view:
>     create foo_view as select * from foo;
> Then you query it:
>     select * from foo_view;

> What, behind the scenes, actually happens?

There's a pretty good description in the Programmer's Guide:
http://www.ca.postgresql.org/users-lounge/docs/7.3/postgres/rules.html

After reading that you can try looking at it for yourself.  For example:

regression=# create table foo (f1 int, f2 text);
CREATE TABLE
regression=# create view foo_view as select * from foo;
CREATE VIEW
regression=# select ev_action from pg_rewrite
regression-# where ev_class = 'foo_view'::regclass; -- before 7.3 use a join

In CVS tip I get:

 ({QUERY :commandType 1 :querySource 0 :utilityStmt <> :resultRelation 0 :into <> :isPortal false :isBinary false
:hasAggsfalse :hasSubLinks false :rtable ({RTE :alias {ALIAS :aliasname *OLD* :colnames <>} :eref {ALIAS :aliasname
*OLD*:colnames ("f1" "f2")} :rtekind 0 :relid 2581139 :inh false :inFromCl false :checkForRead false :checkForWrite
false:checkAsUser 1} {RTE :alias {ALIAS :aliasname *NEW* :colnames <>} :eref {ALIAS :aliasname *NEW* :colnames ("f1"
"f2")}:rtekind 0 :relid 2581139 :inh false :inFromCl false :checkForRead false :checkForWrite false :checkAsUser 1}
{RTE:alias <> :eref {ALIAS :aliasname foo :colnames ("f1" "f2")} :rtekind 0 :relid 2581134 :inh true :inFromCl true
:checkForReadtrue :checkForWrite false :checkAsUser 1}) :jointree {FROMEXPR :fromlist ({RANGETBLREF :rtindex 3}) :quals
<>}:rowMarks () :targetList ({TARGETENTRY :resdom {RESDOM :resno 1 :restype 23 :restypmod -1 :resname f1
:ressortgroupref0 :reskey 0 :reskeyop 0 :resjunk false} :expr! 
 {VAR :varno 3 :varattno 1 :vartype 23 :vartypmod -1 :varlevelsup 0 :varnoold 3 :varoattno 1}} {TARGETENTRY :resdom
{RESDOM:resno 2 :restype 25 :restypmod -1 :resname f2 :ressortgroupref 0 :reskey 0 :reskeyop 0 :resjunk false} :expr
{VAR:varno 3 :varattno 2 :vartype 25 :vartypmod -1 :varlevelsup 0 :varnoold 3 :varoattno 2}}) :groupClause <>
:havingQual<> :distinctClause <> :sortClause <> :limitOffset <> :limitCount <> :setOperations <> :resultRelations ()}) 

which is a flattened textual representation of the internal querytree
data structure that represents the SELECT.  The above-cited
documentation would give you a rough idea about the parts of this data
structure, and you can find the details in src/include/nodes/*.h
(mostly primnodes.h and parsenodes.h for stuff appearing in a Query
tree).

> Is the definition of "foo_view" looked up in the system catalog, query
> rewritten, parsed, then executed?

The Query representation is rebuilt from this textual form and then
substituted into the referencing query.  I wouldn't call that "parsing",
though --- the work of the parser phase is long over.  See
http://www.ca.postgresql.org/users-lounge/docs/7.3/postgres/overview.html

> In other words, does the query *literally* get rewritten as:
>     select * from (select * from foo) as foo;
> before it is parsed?

Substituting "planned" for "parsed", yes, pretty nearly.  What the
planner sees is practically indistinguishable from what it sees if you
write out the view's definition as a sub-select like that.  Exercise for
the student: turn on DEBUG_PRINT_REWRITTEN and compare the post-rewrite
query trees for the two cases.  (Also set DEBUG_PRETTY_PRINT to make the
trees dumped into the postmaster log easier to read.)

            regards, tom lane

pgsql-general by date:

Previous
From: ahoward
Date:
Subject: connection pooling
Next
From: "Greg Sabino Mullane"
Date:
Subject: Minor change in news release for 7.3.2