summaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_relation.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_relation.c')
-rw-r--r--src/backend/parser/parse_relation.c255
1 files changed, 115 insertions, 140 deletions
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 6713c665098..174c05790d9 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.77 2002/08/08 17:00:19 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.78 2002/08/29 00:17:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -900,17 +900,14 @@ addRangeTableEntryForFunction(ParseState *pstate,
* Now determine if the function returns a simple or composite type,
* and check/add column aliases.
*/
- functyptype = get_typtype(funcrettype);
-
if (coldeflist != NIL)
{
/*
* we *only* allow a coldeflist for functions returning a
* RECORD pseudo-type
*/
- if (functyptype != 'p' || (functyptype == 'p' && funcrettype != RECORDOID))
- elog(ERROR, "A column definition list is only allowed for"
- " functions returning RECORD");
+ if (funcrettype != RECORDOID)
+ elog(ERROR, "A column definition list is only allowed for functions returning RECORD");
}
else
{
@@ -918,57 +915,55 @@ addRangeTableEntryForFunction(ParseState *pstate,
* ... and a coldeflist is *required* for functions returning a
* RECORD pseudo-type
*/
- if (functyptype == 'p' && funcrettype == RECORDOID)
- elog(ERROR, "A column definition list is required for functions"
- " returning RECORD");
+ if (funcrettype == RECORDOID)
+ elog(ERROR, "A column definition list is required for functions returning RECORD");
}
+ functyptype = get_typtype(funcrettype);
+
if (functyptype == 'c')
{
/*
* Named composite data type, i.e. a table's row type
*/
Oid funcrelid = typeidTypeRelid(funcrettype);
+ Relation rel;
+ int maxattrs;
- if (OidIsValid(funcrelid))
- {
- /*
- * Get the rel's relcache entry. This access ensures that we have an
- * up-to-date relcache entry for the rel.
- */
- Relation rel;
- int maxattrs;
+ if (!OidIsValid(funcrelid))
+ elog(ERROR, "Invalid typrelid for complex type %u",
+ funcrettype);
- rel = heap_open(funcrelid, AccessShareLock);
-
- /*
- * Since the rel is open anyway, let's check that the number of column
- * aliases is reasonable.
- */
- maxattrs = RelationGetNumberOfAttributes(rel);
- if (maxattrs < numaliases)
- elog(ERROR, "Table \"%s\" has %d columns available but %d columns specified",
- RelationGetRelationName(rel), maxattrs, numaliases);
+ /*
+ * Get the rel's relcache entry. This access ensures that we have an
+ * up-to-date relcache entry for the rel.
+ */
+ rel = relation_open(funcrelid, AccessShareLock);
- /* fill in alias columns using actual column names */
- for (varattno = numaliases; varattno < maxattrs; varattno++)
- {
- char *attrname;
+ /*
+ * Since the rel is open anyway, let's check that the number of column
+ * aliases is reasonable.
+ */
+ maxattrs = RelationGetNumberOfAttributes(rel);
+ if (maxattrs < numaliases)
+ elog(ERROR, "Table \"%s\" has %d columns available but %d columns specified",
+ RelationGetRelationName(rel), maxattrs, numaliases);
- attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname));
- eref->colnames = lappend(eref->colnames, makeString(attrname));
- }
+ /* fill in alias columns using actual column names */
+ for (varattno = numaliases; varattno < maxattrs; varattno++)
+ {
+ char *attrname;
- /*
- * Drop the rel refcount, but keep the access lock till end of
- * transaction so that the table can't be deleted or have its schema
- * modified underneath us.
- */
- heap_close(rel, NoLock);
+ attrname = pstrdup(NameStr(rel->rd_att->attrs[varattno]->attname));
+ eref->colnames = lappend(eref->colnames, makeString(attrname));
}
- else
- elog(ERROR, "Invalid return relation specified for function %s",
- funcname);
+
+ /*
+ * Drop the rel refcount, but keep the access lock till end of
+ * transaction so that the table can't be deleted or have its schema
+ * modified underneath us.
+ */
+ relation_close(rel, NoLock);
}
else if (functyptype == 'b' || functyptype == 'd')
{
@@ -986,10 +981,12 @@ addRangeTableEntryForFunction(ParseState *pstate,
{
List *col;
+ /* Use the column definition list to form the alias list */
+ eref->colnames = NIL;
foreach(col, coldeflist)
{
- char *attrname;
ColumnDef *n = lfirst(col);
+ char *attrname;
attrname = pstrdup(n->colname);
eref->colnames = lappend(eref->colnames, makeString(attrname));
@@ -1277,63 +1274,58 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
char functyptype = get_typtype(funcrettype);
List *coldeflist = rte->coldeflist;
- /*
- * Build a suitable tupledesc representing the output rows
- */
if (functyptype == 'c')
{
+ /*
+ * Composite data type, i.e. a table's row type
+ * Same as ordinary relation RTE
+ */
Oid funcrelid = typeidTypeRelid(funcrettype);
- if (OidIsValid(funcrelid))
+ Relation rel;
+ int maxattrs;
+ int numaliases;
+
+ if (!OidIsValid(funcrelid))
+ elog(ERROR, "Invalid typrelid for complex type %u",
+ funcrettype);
+
+ rel = relation_open(funcrelid, AccessShareLock);
+ maxattrs = RelationGetNumberOfAttributes(rel);
+ numaliases = length(rte->eref->colnames);
+
+ for (varattno = 0; varattno < maxattrs; varattno++)
{
- /*
- * Composite data type, i.e. a table's row type
- * Same as ordinary relation RTE
- */
- Relation rel;
- int maxattrs;
- int numaliases;
-
- rel = heap_open(funcrelid, AccessShareLock);
- maxattrs = RelationGetNumberOfAttributes(rel);
- numaliases = length(rte->eref->colnames);
-
- for (varattno = 0; varattno < maxattrs; varattno++)
+ Form_pg_attribute attr = rel->rd_att->attrs[varattno];
+
+ if (attr->attisdropped)
+ continue;
+
+ if (colnames)
{
- Form_pg_attribute attr = rel->rd_att->attrs[varattno];
-
- if (attr->attisdropped)
- continue;
-
- if (colnames)
- {
- char *label;
-
- if (varattno < numaliases)
- label = strVal(nth(varattno, rte->eref->colnames));
- else
- label = NameStr(attr->attname);
- *colnames = lappend(*colnames, makeString(pstrdup(label)));
- }
-
- if (colvars)
- {
- Var *varnode;
-
- varnode = makeVar(rtindex,
- attr->attnum,
- attr->atttypid,
- attr->atttypmod,
- sublevels_up);
-
- *colvars = lappend(*colvars, varnode);
- }
+ char *label;
+
+ if (varattno < numaliases)
+ label = strVal(nth(varattno, rte->eref->colnames));
+ else
+ label = NameStr(attr->attname);
+ *colnames = lappend(*colnames, makeString(pstrdup(label)));
}
- heap_close(rel, AccessShareLock);
+ if (colvars)
+ {
+ Var *varnode;
+
+ varnode = makeVar(rtindex,
+ attr->attnum,
+ attr->atttypid,
+ attr->atttypmod,
+ sublevels_up);
+
+ *colvars = lappend(*colvars, varnode);
+ }
}
- else
- elog(ERROR, "Invalid return relation specified"
- " for function");
+
+ relation_close(rel, AccessShareLock);
}
else if (functyptype == 'b' || functyptype == 'd')
{
@@ -1376,12 +1368,9 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
if (colvars)
{
Var *varnode;
- HeapTuple typeTuple;
Oid atttypid;
- typeTuple = typenameType(colDef->typename);
- atttypid = HeapTupleGetOid(typeTuple);
- ReleaseSysCache(typeTuple);
+ atttypid = typenameTypeId(colDef->typename);
varnode = makeVar(rtindex,
attnum,
@@ -1394,8 +1383,7 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
}
}
else
- elog(ERROR, "Unknown kind of return type specified"
- " for function");
+ elog(ERROR, "Unknown kind of return type specified for function");
}
break;
case RTE_JOIN:
@@ -1595,9 +1583,6 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
char functyptype = get_typtype(funcrettype);
List *coldeflist = rte->coldeflist;
- /*
- * Build a suitable tupledesc representing the output rows
- */
if (functyptype == 'c')
{
/*
@@ -1605,36 +1590,33 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
* Same as ordinary relation RTE
*/
Oid funcrelid = typeidTypeRelid(funcrettype);
+ HeapTuple tp;
+ Form_pg_attribute att_tup;
- if (OidIsValid(funcrelid))
- {
- HeapTuple tp;
- Form_pg_attribute att_tup;
-
- tp = SearchSysCache(ATTNUM,
- ObjectIdGetDatum(funcrelid),
- Int16GetDatum(attnum),
- 0, 0);
- /* this shouldn't happen... */
- if (!HeapTupleIsValid(tp))
- elog(ERROR, "Relation %s does not have attribute %d",
- get_rel_name(funcrelid), attnum);
- att_tup = (Form_pg_attribute) GETSTRUCT(tp);
- /*
- * If dropped column, pretend it ain't there. See notes
- * in scanRTEForColumn.
- */
- if (att_tup->attisdropped)
- elog(ERROR, "Relation \"%s\" has no column \"%s\"",
- get_rel_name(funcrelid),
- NameStr(att_tup->attname));
- *vartype = att_tup->atttypid;
- *vartypmod = att_tup->atttypmod;
- ReleaseSysCache(tp);
- }
- else
- elog(ERROR, "Invalid return relation specified"
- " for function");
+ if (!OidIsValid(funcrelid))
+ elog(ERROR, "Invalid typrelid for complex type %u",
+ funcrettype);
+
+ tp = SearchSysCache(ATTNUM,
+ ObjectIdGetDatum(funcrelid),
+ Int16GetDatum(attnum),
+ 0, 0);
+ /* this shouldn't happen... */
+ if (!HeapTupleIsValid(tp))
+ elog(ERROR, "Relation \"%s\" does not have attribute %d",
+ get_rel_name(funcrelid), attnum);
+ att_tup = (Form_pg_attribute) GETSTRUCT(tp);
+ /*
+ * If dropped column, pretend it ain't there. See notes
+ * in scanRTEForColumn.
+ */
+ if (att_tup->attisdropped)
+ elog(ERROR, "Relation \"%s\" has no column \"%s\"",
+ get_rel_name(funcrelid),
+ NameStr(att_tup->attname));
+ *vartype = att_tup->atttypid;
+ *vartypmod = att_tup->atttypmod;
+ ReleaseSysCache(tp);
}
else if (functyptype == 'b' || functyptype == 'd')
{
@@ -1647,19 +1629,12 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
else if (functyptype == 'p' && funcrettype == RECORDOID)
{
ColumnDef *colDef = nth(attnum - 1, coldeflist);
- HeapTuple typeTuple;
- Oid atttypid;
-
- typeTuple = typenameType(colDef->typename);
- atttypid = HeapTupleGetOid(typeTuple);
- ReleaseSysCache(typeTuple);
- *vartype = atttypid;
+ *vartype = typenameTypeId(colDef->typename);
*vartypmod = -1;
}
else
- elog(ERROR, "Unknown kind of return type specified"
- " for function");
+ elog(ERROR, "Unknown kind of return type specified for function");
}
break;
case RTE_JOIN: