I mentioned the other day that ruleutils.c fails for cases like this: explain select * from (select x from (values(1,2),(3,4)) as x(c1,c2) offset 0) ss where (x).c2 > 0; ERROR: record type has not been registered
The problem is that the rewriter/planner expands the intermediate sub-select's reference to the whole-row variable "x" into a RowExpr, essentially ROW(x.c1, x.c2). Then the (x).c2 expression becomes a FieldSelect applied to a Var that references a RowExpr. ruleutils.c's get_name_for_var_field fails to deal with this case. Even if we taught it to drill down through a RowExpr, it would come up with the wrong answer: in this case it'd return "column2" not "c2", because the RowExpr expansion lost all trace of reference to the intermediate level's aliases. In this particular case it might be possible to dodge the problem by somehow getting ResolveNew to emit a new whole-row variable instead of doing the RowExpr expansion, but I'm pretty sure that that won't work in general; and it would certainly make ResolveNew's API even more grungily awful than it is now :-(. What I am considering doing is attaching an optional list of field names to RowExpr nodes. This would normally be NIL in a RowExpr that actually came from a ROW() construct, but when we are using RowExpr to expand a whole-row variable we'd attach the correct list of column aliases to it. Then get_name_for_var_field() would only need to grab the correct list element and not drill down any further. The main objection to this scheme is that it isn't back-patchable; but I don't see any feasible solution to the problem anyway in the back branches. Fortunately it only affects EXPLAIN of some pretty bizarre corner cases. pg_get_ruledef isn't affected because it doesn't have to deal with parsetrees in which a RowExpr substitution has occurred. Comments, objections, better ideas? regards, tom lane -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers