Thread: Re: anonymous composite types
Neil Conway wrote: > This does not: > > create view pg_locks as select l.relation, l.database, l.backendpid, > l.mode, l.isgranted from pg_lock_info() as l(relation oid, database oid, > backendpid int4, mode text, isgranted bool); > ERROR: badly formatted planstring "COLUMNDEF "... > Reported by Neil Conway -- I never implemented readfuncs.c support for ColumnDef or TypeName, which is needed so that views can be created on functions returning type RECORD. Here's a patch. If there are no objections, please apply. Thanks, Joe Index: src/backend/nodes/outfuncs.c =================================================================== RCS file: /opt/src/cvs/pgsql-server/src/backend/nodes/outfuncs.c,v retrieving revision 1.166 diff -c -r1.166 outfuncs.c *** src/backend/nodes/outfuncs.c 4 Aug 2002 19:48:09 -0000 1.166 --- src/backend/nodes/outfuncs.c 7 Aug 2002 01:26:01 -0000 *************** *** 193,199 **** appendStringInfo(str, " TYPENAME :names "); _outNode(str, node->names); appendStringInfo(str, " :typeid %u :timezone %s :setof %s" ! " :pct_type %s typmod %d :arrayBounds ", node->typeid, booltostr(node->timezone), booltostr(node->setof), --- 193,199 ---- appendStringInfo(str, " TYPENAME :names "); _outNode(str, node->names); appendStringInfo(str, " :typeid %u :timezone %s :setof %s" ! " :pct_type %s :typmod %d :arrayBounds ", node->typeid, booltostr(node->timezone), booltostr(node->setof), Index: src/backend/nodes/readfuncs.c =================================================================== RCS file: /opt/src/cvs/pgsql-server/src/backend/nodes/readfuncs.c,v retrieving revision 1.127 diff -c -r1.127 readfuncs.c *** src/backend/nodes/readfuncs.c 4 Aug 2002 19:48:09 -0000 1.127 --- src/backend/nodes/readfuncs.c 7 Aug 2002 01:38:41 -0000 *************** *** 1465,1470 **** --- 1465,1544 ---- return local_node; } + static ColumnDef * + _readColumnDef(void) + { + ColumnDef *local_node; + char *token; + int length; + + local_node = makeNode(ColumnDef); + + token = pg_strtok(&length); /* eat :colname */ + token = pg_strtok(&length); /* now read it */ + local_node->colname = nullable_string(token, length); + + token = pg_strtok(&length); /* eat :typename */ + local_node->typename = nodeRead(true); /* now read it */ + + token = pg_strtok(&length); /* eat :is_not_null */ + token = pg_strtok(&length); /* get :is_not_null */ + local_node->is_not_null = strtobool(token); + + token = pg_strtok(&length); /* eat :raw_default */ + local_node->raw_default = nodeRead(true); /* now read it */ + + token = pg_strtok(&length); /* eat :cooked_default */ + token = pg_strtok(&length); /* now read it */ + local_node->cooked_default = nullable_string(token, length); + + token = pg_strtok(&length); /* eat :constraints */ + local_node->constraints = nodeRead(true); /* now read it */ + + token = pg_strtok(&length); /* eat :support */ + local_node->support = nodeRead(true); /* now read it */ + + return local_node; + } + + static TypeName * + _readTypeName(void) + { + TypeName *local_node; + char *token; + int length; + + local_node = makeNode(TypeName); + + token = pg_strtok(&length); /* eat :names */ + local_node->names = nodeRead(true); /* now read it */ + + token = pg_strtok(&length); /* eat :typeid */ + token = pg_strtok(&length); /* get typeid */ + local_node->typeid = atooid(token); + + token = pg_strtok(&length); /* eat :timezone */ + token = pg_strtok(&length); /* get timezone */ + local_node->timezone = strtobool(token); + + token = pg_strtok(&length); /* eat :setof */ + token = pg_strtok(&length); /* get setof */ + local_node->setof = strtobool(token); + + token = pg_strtok(&length); /* eat :pct_type */ + token = pg_strtok(&length); /* get pct_type */ + local_node->pct_type = strtobool(token); + + token = pg_strtok(&length); /* eat :typmod */ + token = pg_strtok(&length); /* get typmod */ + local_node->typmod = atoi(token); + + token = pg_strtok(&length); /* eat :arrayBounds */ + local_node->arrayBounds = nodeRead(true); /* now read it */ + + return local_node; + } + static ExprFieldSelect * _readExprFieldSelect(void) { *************** *** 2092,2097 **** --- 2166,2175 ---- return_value = _readRangeVar(); else if (length == 9 && strncmp(token, "COLUMNREF", length) == 0) return_value = _readColumnRef(); + else if (length == 9 && strncmp(token, "COLUMNDEF", length) == 0) + return_value = _readColumnDef(); + else if (length == 8 && strncmp(token, "TYPENAME", length) == 0) + return_value = _readTypeName(); else if (length == 15 && strncmp(token, "EXPRFIELDSELECT", length) == 0) return_value = _readExprFieldSelect(); else if (length == 5 && strncmp(token, "ALIAS", length) == 0)
Your patch has been added to the PostgreSQL unapplied patches list at: http://candle.pha.pa.us/cgi-bin/pgpatches I will try to apply it within the next 48 hours. --------------------------------------------------------------------------- Joe Conway wrote: > Neil Conway wrote: > > This does not: > > > > create view pg_locks as select l.relation, l.database, l.backendpid, > > l.mode, l.isgranted from pg_lock_info() as l(relation oid, database oid, > > backendpid int4, mode text, isgranted bool); > > ERROR: badly formatted planstring "COLUMNDEF "... > > > > Reported by Neil Conway -- I never implemented readfuncs.c support for > ColumnDef or TypeName, which is needed so that views can be created on > functions returning type RECORD. Here's a patch. > > If there are no objections, please apply. > > Thanks, > > Joe > > Index: src/backend/nodes/outfuncs.c > =================================================================== > RCS file: /opt/src/cvs/pgsql-server/src/backend/nodes/outfuncs.c,v > retrieving revision 1.166 > diff -c -r1.166 outfuncs.c > *** src/backend/nodes/outfuncs.c 4 Aug 2002 19:48:09 -0000 1.166 > --- src/backend/nodes/outfuncs.c 7 Aug 2002 01:26:01 -0000 > *************** > *** 193,199 **** > appendStringInfo(str, " TYPENAME :names "); > _outNode(str, node->names); > appendStringInfo(str, " :typeid %u :timezone %s :setof %s" > ! " :pct_type %s typmod %d :arrayBounds ", > node->typeid, > booltostr(node->timezone), > booltostr(node->setof), > --- 193,199 ---- > appendStringInfo(str, " TYPENAME :names "); > _outNode(str, node->names); > appendStringInfo(str, " :typeid %u :timezone %s :setof %s" > ! " :pct_type %s :typmod %d :arrayBounds ", > node->typeid, > booltostr(node->timezone), > booltostr(node->setof), > Index: src/backend/nodes/readfuncs.c > =================================================================== > RCS file: /opt/src/cvs/pgsql-server/src/backend/nodes/readfuncs.c,v > retrieving revision 1.127 > diff -c -r1.127 readfuncs.c > *** src/backend/nodes/readfuncs.c 4 Aug 2002 19:48:09 -0000 1.127 > --- src/backend/nodes/readfuncs.c 7 Aug 2002 01:38:41 -0000 > *************** > *** 1465,1470 **** > --- 1465,1544 ---- > return local_node; > } > > + static ColumnDef * > + _readColumnDef(void) > + { > + ColumnDef *local_node; > + char *token; > + int length; > + > + local_node = makeNode(ColumnDef); > + > + token = pg_strtok(&length); /* eat :colname */ > + token = pg_strtok(&length); /* now read it */ > + local_node->colname = nullable_string(token, length); > + > + token = pg_strtok(&length); /* eat :typename */ > + local_node->typename = nodeRead(true); /* now read it */ > + > + token = pg_strtok(&length); /* eat :is_not_null */ > + token = pg_strtok(&length); /* get :is_not_null */ > + local_node->is_not_null = strtobool(token); > + > + token = pg_strtok(&length); /* eat :raw_default */ > + local_node->raw_default = nodeRead(true); /* now read it */ > + > + token = pg_strtok(&length); /* eat :cooked_default */ > + token = pg_strtok(&length); /* now read it */ > + local_node->cooked_default = nullable_string(token, length); > + > + token = pg_strtok(&length); /* eat :constraints */ > + local_node->constraints = nodeRead(true); /* now read it */ > + > + token = pg_strtok(&length); /* eat :support */ > + local_node->support = nodeRead(true); /* now read it */ > + > + return local_node; > + } > + > + static TypeName * > + _readTypeName(void) > + { > + TypeName *local_node; > + char *token; > + int length; > + > + local_node = makeNode(TypeName); > + > + token = pg_strtok(&length); /* eat :names */ > + local_node->names = nodeRead(true); /* now read it */ > + > + token = pg_strtok(&length); /* eat :typeid */ > + token = pg_strtok(&length); /* get typeid */ > + local_node->typeid = atooid(token); > + > + token = pg_strtok(&length); /* eat :timezone */ > + token = pg_strtok(&length); /* get timezone */ > + local_node->timezone = strtobool(token); > + > + token = pg_strtok(&length); /* eat :setof */ > + token = pg_strtok(&length); /* get setof */ > + local_node->setof = strtobool(token); > + > + token = pg_strtok(&length); /* eat :pct_type */ > + token = pg_strtok(&length); /* get pct_type */ > + local_node->pct_type = strtobool(token); > + > + token = pg_strtok(&length); /* eat :typmod */ > + token = pg_strtok(&length); /* get typmod */ > + local_node->typmod = atoi(token); > + > + token = pg_strtok(&length); /* eat :arrayBounds */ > + local_node->arrayBounds = nodeRead(true); /* now read it */ > + > + return local_node; > + } > + > static ExprFieldSelect * > _readExprFieldSelect(void) > { > *************** > *** 2092,2097 **** > --- 2166,2175 ---- > return_value = _readRangeVar(); > else if (length == 9 && strncmp(token, "COLUMNREF", length) == 0) > return_value = _readColumnRef(); > + else if (length == 9 && strncmp(token, "COLUMNDEF", length) == 0) > + return_value = _readColumnDef(); > + else if (length == 8 && strncmp(token, "TYPENAME", length) == 0) > + return_value = _readTypeName(); > else if (length == 15 && strncmp(token, "EXPRFIELDSELECT", length) == 0) > return_value = _readExprFieldSelect(); > else if (length == 5 && strncmp(token, "ALIAS", length) == 0) > > > ---------------------------(end of broadcast)--------------------------- > TIP 2: you can get off all lists at once with the unregister command > (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000 + If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania 19026
Patch applied. Thanks. --------------------------------------------------------------------------- Joe Conway wrote: > Neil Conway wrote: > > This does not: > > > > create view pg_locks as select l.relation, l.database, l.backendpid, > > l.mode, l.isgranted from pg_lock_info() as l(relation oid, database oid, > > backendpid int4, mode text, isgranted bool); > > ERROR: badly formatted planstring "COLUMNDEF "... > > > > Reported by Neil Conway -- I never implemented readfuncs.c support for > ColumnDef or TypeName, which is needed so that views can be created on > functions returning type RECORD. Here's a patch. > > If there are no objections, please apply. > > Thanks, > > Joe > > Index: src/backend/nodes/outfuncs.c > =================================================================== > RCS file: /opt/src/cvs/pgsql-server/src/backend/nodes/outfuncs.c,v > retrieving revision 1.166 > diff -c -r1.166 outfuncs.c > *** src/backend/nodes/outfuncs.c 4 Aug 2002 19:48:09 -0000 1.166 > --- src/backend/nodes/outfuncs.c 7 Aug 2002 01:26:01 -0000 > *************** > *** 193,199 **** > appendStringInfo(str, " TYPENAME :names "); > _outNode(str, node->names); > appendStringInfo(str, " :typeid %u :timezone %s :setof %s" > ! " :pct_type %s typmod %d :arrayBounds ", > node->typeid, > booltostr(node->timezone), > booltostr(node->setof), > --- 193,199 ---- > appendStringInfo(str, " TYPENAME :names "); > _outNode(str, node->names); > appendStringInfo(str, " :typeid %u :timezone %s :setof %s" > ! " :pct_type %s :typmod %d :arrayBounds ", > node->typeid, > booltostr(node->timezone), > booltostr(node->setof), > Index: src/backend/nodes/readfuncs.c > =================================================================== > RCS file: /opt/src/cvs/pgsql-server/src/backend/nodes/readfuncs.c,v > retrieving revision 1.127 > diff -c -r1.127 readfuncs.c > *** src/backend/nodes/readfuncs.c 4 Aug 2002 19:48:09 -0000 1.127 > --- src/backend/nodes/readfuncs.c 7 Aug 2002 01:38:41 -0000 > *************** > *** 1465,1470 **** > --- 1465,1544 ---- > return local_node; > } > > + static ColumnDef * > + _readColumnDef(void) > + { > + ColumnDef *local_node; > + char *token; > + int length; > + > + local_node = makeNode(ColumnDef); > + > + token = pg_strtok(&length); /* eat :colname */ > + token = pg_strtok(&length); /* now read it */ > + local_node->colname = nullable_string(token, length); > + > + token = pg_strtok(&length); /* eat :typename */ > + local_node->typename = nodeRead(true); /* now read it */ > + > + token = pg_strtok(&length); /* eat :is_not_null */ > + token = pg_strtok(&length); /* get :is_not_null */ > + local_node->is_not_null = strtobool(token); > + > + token = pg_strtok(&length); /* eat :raw_default */ > + local_node->raw_default = nodeRead(true); /* now read it */ > + > + token = pg_strtok(&length); /* eat :cooked_default */ > + token = pg_strtok(&length); /* now read it */ > + local_node->cooked_default = nullable_string(token, length); > + > + token = pg_strtok(&length); /* eat :constraints */ > + local_node->constraints = nodeRead(true); /* now read it */ > + > + token = pg_strtok(&length); /* eat :support */ > + local_node->support = nodeRead(true); /* now read it */ > + > + return local_node; > + } > + > + static TypeName * > + _readTypeName(void) > + { > + TypeName *local_node; > + char *token; > + int length; > + > + local_node = makeNode(TypeName); > + > + token = pg_strtok(&length); /* eat :names */ > + local_node->names = nodeRead(true); /* now read it */ > + > + token = pg_strtok(&length); /* eat :typeid */ > + token = pg_strtok(&length); /* get typeid */ > + local_node->typeid = atooid(token); > + > + token = pg_strtok(&length); /* eat :timezone */ > + token = pg_strtok(&length); /* get timezone */ > + local_node->timezone = strtobool(token); > + > + token = pg_strtok(&length); /* eat :setof */ > + token = pg_strtok(&length); /* get setof */ > + local_node->setof = strtobool(token); > + > + token = pg_strtok(&length); /* eat :pct_type */ > + token = pg_strtok(&length); /* get pct_type */ > + local_node->pct_type = strtobool(token); > + > + token = pg_strtok(&length); /* eat :typmod */ > + token = pg_strtok(&length); /* get typmod */ > + local_node->typmod = atoi(token); > + > + token = pg_strtok(&length); /* eat :arrayBounds */ > + local_node->arrayBounds = nodeRead(true); /* now read it */ > + > + return local_node; > + } > + > static ExprFieldSelect * > _readExprFieldSelect(void) > { > *************** > *** 2092,2097 **** > --- 2166,2175 ---- > return_value = _readRangeVar(); > else if (length == 9 && strncmp(token, "COLUMNREF", length) == 0) > return_value = _readColumnRef(); > + else if (length == 9 && strncmp(token, "COLUMNDEF", length) == 0) > + return_value = _readColumnDef(); > + else if (length == 8 && strncmp(token, "TYPENAME", length) == 0) > + return_value = _readTypeName(); > else if (length == 15 && strncmp(token, "EXPRFIELDSELECT", length) == 0) > return_value = _readExprFieldSelect(); > else if (length == 5 && strncmp(token, "ALIAS", length) == 0) > > > ---------------------------(end of broadcast)--------------------------- > TIP 2: you can get off all lists at once with the unregister command > (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073