aboutsummaryrefslogtreecommitdiff
path: root/src/backend/nodes
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2002-08-04 19:48:11 +0000
committerBruce Momjian <bruce@momjian.us>2002-08-04 19:48:11 +0000
commit9218689b69d6693674adc08dbfd66b119cac5ecd (patch)
tree6653ee94171718d49f6a5cbd275bac12790645df /src/backend/nodes
parent35d39ba0811b70a439dd5012b0d641843b67b4a9 (diff)
downloadpostgresql-9218689b69d6693674adc08dbfd66b119cac5ecd.tar.gz
postgresql-9218689b69d6693674adc08dbfd66b119cac5ecd.zip
Attached are two patches to implement and document anonymous composite
types for Table Functions, as previously proposed on HACKERS. Here is a brief explanation: 1. Creates a new pg_type typtype: 'p' for pseudo type (currently either 'b' for base or 'c' for catalog, i.e. a class). 2. Creates new builtin type of typtype='p' named RECORD. This is the first of potentially several pseudo types. 3. Modify FROM clause grammer to accept: SELECT * FROM my_func() AS m(colname1 type1, colname2 type1, ...) where m is the table alias, colname1, etc are the column names, and type1, etc are the column types. 4. When typtype == 'p' and the function return type is RECORD, a list of column defs is required, and when typtype != 'p', it is disallowed. 5. A check was added to ensure that the tupdesc provide via the parser and the actual return tupdesc match in number and type of attributes. When creating a function you can do: CREATE FUNCTION foo(text) RETURNS setof RECORD ... When using it you can do: SELECT * from foo(sqlstmt) AS (f1 int, f2 text, f3 timestamp) or SELECT * from foo(sqlstmt) AS f(f1 int, f2 text, f3 timestamp) or SELECT * from foo(sqlstmt) f(f1 int, f2 text, f3 timestamp) Included in the patches are adjustments to the regression test sql and expected files, and documentation. p.s. This potentially solves (or at least improves) the issue of builtin Table Functions. They can be bootstrapped as returning RECORD, and we can wrap system views around them with properly specified column defs. For example: CREATE VIEW pg_settings AS SELECT s.name, s.setting FROM show_all_settings()AS s(name text, setting text); Then we can also add the UPDATE RULE that I previously posted to pg_settings, and have pg_settings act like a virtual table, allowing settings to be queried and set. Joe Conway
Diffstat (limited to 'src/backend/nodes')
-rw-r--r--src/backend/nodes/copyfuncs.c4
-rw-r--r--src/backend/nodes/equalfuncs.c6
-rw-r--r--src/backend/nodes/outfuncs.c4
-rw-r--r--src/backend/nodes/readfuncs.c6
4 files changed, 16 insertions, 4 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index d7aefc9acfe..954a372181a 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.199 2002/08/04 04:31:44 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.200 2002/08/04 19:48:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1482,6 +1482,7 @@ _copyRangeTblEntry(RangeTblEntry *from)
newnode->relid = from->relid;
Node_Copy(from, newnode, subquery);
Node_Copy(from, newnode, funcexpr);
+ Node_Copy(from, newnode, coldeflist);
newnode->jointype = from->jointype;
Node_Copy(from, newnode, joinaliasvars);
Node_Copy(from, newnode, alias);
@@ -1707,6 +1708,7 @@ _copyRangeFunction(RangeFunction *from)
Node_Copy(from, newnode, funccallnode);
Node_Copy(from, newnode, alias);
+ Node_Copy(from, newnode, coldeflist);
return newnode;
}
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 9b655640b0d..da7567e7c33 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.146 2002/08/04 04:31:44 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.147 2002/08/04 19:48:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1607,6 +1607,8 @@ _equalRangeVar(RangeVar *a, RangeVar *b)
return false;
if (!equal(a->alias, b->alias))
return false;
+ if (!equal(a->coldeflist, b->coldeflist))
+ return false;
return true;
}
@@ -1742,6 +1744,8 @@ _equalRangeTblEntry(RangeTblEntry *a, RangeTblEntry *b)
return false;
if (!equal(a->funcexpr, b->funcexpr))
return false;
+ if (!equal(a->coldeflist, b->coldeflist))
+ return false;
if (a->jointype != b->jointype)
return false;
if (!equal(a->joinaliasvars, b->joinaliasvars))
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index c4dfbec67d0..b992e45a62f 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.165 2002/07/18 17:14:19 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.166 2002/08/04 19:48:09 momjian Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
@@ -1004,6 +1004,8 @@ _outRangeTblEntry(StringInfo str, RangeTblEntry *node)
case RTE_FUNCTION:
appendStringInfo(str, ":funcexpr ");
_outNode(str, node->funcexpr);
+ appendStringInfo(str, ":coldeflist ");
+ _outNode(str, node->coldeflist);
break;
case RTE_JOIN:
appendStringInfo(str, ":jointype %d :joinaliasvars ",
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index ba9eb0449ee..46b2ca2dc85 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.126 2002/07/18 17:14:19 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.127 2002/08/04 19:48:09 momjian Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
@@ -1545,6 +1545,10 @@ _readRangeTblEntry(void)
case RTE_FUNCTION:
token = pg_strtok(&length); /* eat :funcexpr */
local_node->funcexpr = nodeRead(true); /* now read it */
+
+ token = pg_strtok(&length); /* eat :coldeflist */
+ local_node->coldeflist = nodeRead(true); /* now read it */
+
break;
case RTE_JOIN: