Re: UNNEST with multiple args, and TABLE with multiple funcs - Mailing list pgsql-hackers
From | Tom Lane |
---|---|
Subject | Re: UNNEST with multiple args, and TABLE with multiple funcs |
Date | |
Msg-id | 10034.1384877606@sss.pgh.pa.us Whole thread Raw |
In response to | Re: UNNEST with multiple args, and TABLE with multiple funcs (Tom Lane <tgl@sss.pgh.pa.us>) |
Responses |
Re: UNNEST with multiple args, and TABLE with multiple
funcs
Re: UNNEST with multiple args, and TABLE with multiple funcs |
List | pgsql-hackers |
I wrote: > Andrew Gierth <andrew@tao11.riddles.org.uk> writes: >> Here is a new patch with the following changes on top of Heikki's >> version (all the changes in which I've otherwise kept): > Here is an updated version: I've been hacking on this patch all day yesterday. What I'm on about at the moment is reversing the decision to move range functions' funccoltypes etc into FuncExpr. That's a bad idea on the grounds of bloating FuncExpr, but the real problem with it is this: what happens if the planner decides to inline or const-simplify the function expression? You just lost a critical part of the RTE's infrastructure, that's what. So that's got to go, and I've been fooling with different ways to represent the info for multiple functions within RangeTblEntry. What I have at the moment is /* * Fields valid for a function RTE (else NIL/zero): * * There can be multiple function expressions in a functionRTE. * funccoldeflist is an integer list (of the same length as funcexprs) * containing true if function hada column definition list, else false. * funccolcounts is an integer list (of the same length as funcexprs) * showingthe number of RTE output columns produced by each function. * The length of eref->colnames must be equal to eitherthe sum of the * funccolcounts entries, or one more than the sum if funcordinality is * true. funccoltypes,funccoltypmods, and funccolcollations give type * information about each output column (these lists musthave the same * length as eref->colnames). Remember that when a function returns a * named composite type, anydropped columns in that type will have dummy * corresponding entries in these lists. * * Note: funccoltypes etcare derived from either the functions' declared * result types, or their column definition lists in case of functions * returning RECORD. Storing this data in the RTE is redundant in the * former case, but for simplicity westore it always. */ List *funcexprs; /* expression trees for func calls */ List *funccoldeflist; /* integer list of has-coldeflist booleans */ List *funccolcounts; /* number of output columnsfrom each func */ List *funccoltypes; /* OID list of column type OIDs */ List *funccoltypmods; /* integer list of column typmods */ List *funccolcollations; /* OID list of column collationOIDs */ bool funcordinality; /* is this called WITH ORDINALITY? */ which has the advantage that the ordinality column is no longer such a special case, it's right there in the lists. However, it turns out that in most places where I thought we could just consult the entry-per-column lists, we can't. We still have to do the get_expr_result_type() dance, because we need up-to-date information about which columns of a composite-returning function's output have been dropped since the RTE was made. That means we'd have to chase the entry-per-function lists in parallel with the entry-per-column lists, which is a PITA. I'm thinking possibly it's worth inventing a new Node type that would just be infrastructure for RTE_FUNCTION RTEs, so that we'd have something like this in RangeTblEntry: List *functions; /* List of RangeTblFunction nodes */ bool funcordinality; /* is this called WITHORDINALITY? */ and a node type RangeTblFunction with fields Node *funcexpr; /* executable expression for the function */ int funccolcount; /* number ofcolumns emitted by function */ /* These lists are NIL unless function had a column definition list: */ List *funccoltypes; /* OID list of column type OIDs */ List *funccoltypmods; /* integer list of column typmods */ List *funccolcollations; /* OID list of column collation OIDs */ BTW, the reason we need to store the column count explicitly is that we have to ignore the added columns if a composite type has had an ADD COLUMN done to it since the RTE was made. The submitted patch fails rather nastily in such cases, if the composite type isn't last in the function list. Thoughts, better ideas? regards, tom lane
pgsql-hackers by date: