On Sun, 2006-01-15 at 17:33 -0500, Tom Lane wrote:
> BTW, I wonder whether it wouldn't be a better idea to declare the
> pg_prepared_statement view's parameter_types column as regtype[]
> instead of oid[].

Yeah, good point -- I had thought that using type names would be
ambiguous in the presence of schemas, but of course regtype solves that
problem. Attached is a patch that implements this -- barring any
objections I'll apply this tomorrow.

-Neil

============================================================
*** doc/src/sgml/catalogs.sgml	324ea64622e513dbf036e56cc38f4ccc2955ef6e
--- doc/src/sgml/catalogs.sgml	156840ca28113a4e95833cd9b5c5d410e047c366
***************
*** 284,291 ****
        <entry>
         The initial value of the transition state.  This is a text
         field containing the initial value in its external string
!        representation.  If this field is null, the transition state
!        value starts out null.
        </entry>
       </row>
      </tbody>
--- 284,291 ----
        <entry>
         The initial value of the transition state.  This is a text
         field containing the initial value in its external string
!        representation.  If this field is NULL, the transition state
!        value starts out NULL.
        </entry>
       </row>
      </tbody>
***************
*** 293,302 ****
    </table>
  
    <para>
!    New aggregate functions are registered with the <command>CREATE
!    AGGREGATE</command> command.  See <xref linkend="xaggr"> for more
!    information about writing aggregate functions and the meaning of
!    the transition functions, etc.
    </para>
  
   </sect1>
--- 293,303 ----
    </table>
  
    <para>
!    New aggregate functions are registered with the <xref
!    linkend="sql-createaggregate" endterm="sql-createaggregate-title">
!    command.  See <xref linkend="xaggr"> for more information about
!    writing aggregate functions and the meaning of the transition
!    functions, etc.
    </para>
  
   </sect1>
***************
*** 1018,1024 ****
        <entry><type>bool</type></entry>
        <entry></entry>
        <entry>
!        Role may log in, that is, this role can be given as the initial
         session authorization identifier.
        </entry>
       </row>
--- 1019,1025 ----
        <entry><type>bool</type></entry>
        <entry></entry>
        <entry>
!        Role may log in. That is, this role can be given as the initial
         session authorization identifier.
        </entry>
       </row>
***************
*** 1561,1567 ****
        <entry><structfield>relukeys</structfield></entry>
        <entry><type>int2</type></entry>
        <entry></entry>
!       <entry>unused  (<emphasis>not</emphasis> the number of unique keys)</entry>
       </row>
  
       <row>
--- 1562,1568 ----
        <entry><structfield>relukeys</structfield></entry>
        <entry><type>int2</type></entry>
        <entry></entry>
!       <entry>Unused  (<emphasis>not</emphasis> the number of unique keys)</entry>
       </row>
  
       <row>
***************
*** 1568,1574 ****
        <entry><structfield>relfkeys</structfield></entry>
        <entry><type>int2</type></entry>
        <entry></entry>
!       <entry>unused  (<emphasis>not</emphasis> the number of foreign keys on the table)</entry>
       </row>
  
       <row>
--- 1569,1575 ----
        <entry><structfield>relfkeys</structfield></entry>
        <entry><type>int2</type></entry>
        <entry></entry>
!       <entry>Unused  (<emphasis>not</emphasis> the number of foreign keys on the table)</entry>
       </row>
  
       <row>
***************
*** 1575,1581 ****
        <entry><structfield>relrefs</structfield></entry>
        <entry><type>int2</type></entry>
        <entry></entry>
!       <entry>unused</entry>
       </row>
  
       <row>
--- 1576,1582 ----
        <entry><structfield>relrefs</structfield></entry>
        <entry><type>int2</type></entry>
        <entry></entry>
!       <entry>Unused</entry>
       </row>
  
       <row>
***************
*** 1583,1589 ****
        <entry><type>bool</type></entry>
        <entry></entry>
        <entry>
!        True if we generate an OID for each row of the relation.
        </entry>
       </row>
  
--- 1584,1590 ----
        <entry><type>bool</type></entry>
        <entry></entry>
        <entry>
!        True if we generate an OID for each row of the relation
        </entry>
       </row>
  
***************
*** 1592,1598 ****
        <entry><type>bool</type></entry>
        <entry></entry>
        <entry>
!        True if the table has (or once had) a primary key.
        </entry>
       </row>
  
--- 1593,1599 ----
        <entry><type>bool</type></entry>
        <entry></entry>
        <entry>
!        True if the table has (or once had) a primary key
        </entry>
       </row>
  
***************
*** 1601,1607 ****
        <entry><type>bool</type></entry>
        <entry></entry>
        <entry>True if table has rules; see
!        <structname>pg_rewrite</structname> catalog.
        </entry>
       </row>
  
--- 1602,1608 ----
        <entry><type>bool</type></entry>
        <entry></entry>
        <entry>True if table has rules; see
!        <structname>pg_rewrite</structname> catalog
        </entry>
       </row>
  
***************
*** 1609,1615 ****
        <entry><structfield>relhassubclass</structfield></entry>
        <entry><type>bool</type></entry>
        <entry></entry>
!       <entry>True if table has (or once had) any inheritance children.</entry>
       </row>
  
       <row>
--- 1610,1616 ----
        <entry><structfield>relhassubclass</structfield></entry>
        <entry><type>bool</type></entry>
        <entry></entry>
!       <entry>True if table has (or once had) any inheritance children</entry>
       </row>
  
       <row>
***************
*** 1620,1626 ****
         Access privileges; see
         <xref linkend="sql-grant" endterm="sql-grant-title"> and
         <xref linkend="sql-revoke" endterm="sql-revoke-title">
!        for details.
        </entry>
       </row>
      </tbody>
--- 1621,1627 ----
         Access privileges; see
         <xref linkend="sql-grant" endterm="sql-grant-title"> and
         <xref linkend="sql-revoke" endterm="sql-revoke-title">
!        for details
        </entry>
       </row>
      </tbody>
***************
*** 2030,2036 ****
         Access privileges; see
         <xref linkend="sql-grant" endterm="sql-grant-title"> and
         <xref linkend="sql-revoke" endterm="sql-revoke-title">
!        for details.
        </entry>
       </row>
      </tbody>
--- 2031,2037 ----
         Access privileges; see
         <xref linkend="sql-grant" endterm="sql-grant-title"> and
         <xref linkend="sql-revoke" endterm="sql-revoke-title">
!        for details
        </entry>
       </row>
      </tbody>
***************
*** 2131,2137 ****
        <entry><type>char</type></entry>
        <entry></entry>
        <entry>
!        A code defining the specific semantics of this dependency relationship; see text.
        </entry>
       </row>
  
--- 2132,2138 ----
        <entry><type>char</type></entry>
        <entry></entry>
        <entry>
!        A code defining the specific semantics of this dependency relationship; see text
        </entry>
       </row>
  
***************
*** 2273,2279 ****
        <entry><structfield>description</structfield></entry>
        <entry><type>text</type></entry>
        <entry></entry>
!       <entry>Arbitrary text that serves as the description of this object.</entry>
       </row>
      </tbody>
     </tgroup>
--- 2274,2280 ----
        <entry><structfield>description</structfield></entry>
        <entry><type>text</type></entry>
        <entry></entry>
!       <entry>Arbitrary text that serves as the description of this object</entry>
       </row>
      </tbody>
     </tgroup>
***************
*** 2335,2341 ****
        <entry><structfield>indisunique</structfield></entry>
        <entry><type>bool</type></entry>
        <entry></entry>
!       <entry>If true, this is a unique index.</entry>
       </row>
  
       <row>
--- 2336,2342 ----
        <entry><structfield>indisunique</structfield></entry>
        <entry><type>bool</type></entry>
        <entry></entry>
!       <entry>If true, this is a unique index</entry>
       </row>
  
       <row>
***************
*** 2350,2356 ****
        <entry><structfield>indisclustered</structfield></entry>
        <entry><type>bool</type></entry>
        <entry></entry>
!       <entry>If true, the table was last clustered on this index.</entry>
       </row>
  
       <row>
--- 2351,2357 ----
        <entry><structfield>indisclustered</structfield></entry>
        <entry><type>bool</type></entry>
        <entry></entry>
!       <entry>If true, the table was last clustered on this index</entry>
       </row>
  
       <row>
***************
*** 2385,2391 ****
        <entry>Expression trees (in <function>nodeToString()</function> representation)
        for index attributes that are not simple column references.  This is a
        list with one element for each zero entry in <structfield>indkey</>.
!       Null if all index attributes are simple references.</entry>
       </row>
  
       <row>
--- 2386,2392 ----
        <entry>Expression trees (in <function>nodeToString()</function> representation)
        for index attributes that are not simple column references.  This is a
        list with one element for each zero entry in <structfield>indkey</>.
!       NULL if all index attributes are simple references.</entry>
       </row>
  
       <row>
***************
*** 2393,2399 ****
        <entry><type>text</type></entry>
        <entry></entry>
        <entry>Expression tree (in <function>nodeToString()</function> representation)
!       for partial index predicate.  Null if not a partial index.</entry>
       </row>
      </tbody>
     </tgroup>
--- 2394,2400 ----
        <entry><type>text</type></entry>
        <entry></entry>
        <entry>Expression tree (in <function>nodeToString()</function> representation)
!       for partial index predicate.  NULL if not a partial index.</entry>
       </row>
      </tbody>
     </tgroup>
***************
*** 2435,2441 ****
        <entry><type>oid</type></entry>
        <entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
        <entry>
!        The OID of the child table.
        </entry>
       </row>
  
--- 2436,2442 ----
        <entry><type>oid</type></entry>
        <entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
        <entry>
!        The OID of the child table
        </entry>
       </row>
  
***************
*** 2444,2450 ****
        <entry><type>oid</type></entry>
        <entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
        <entry>
!        The OID of the parent table.
        </entry>
       </row>
  
--- 2445,2451 ----
        <entry><type>oid</type></entry>
        <entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry>
        <entry>
!        The OID of the parent table
        </entry>
       </row>
  
***************
*** 2556,2562 ****
         Access privileges; see
         <xref linkend="sql-grant" endterm="sql-grant-title"> and
         <xref linkend="sql-revoke" endterm="sql-revoke-title">
!        for details.
        </entry>
       </row>
      </tbody>
--- 2557,2563 ----
         Access privileges; see
         <xref linkend="sql-grant" endterm="sql-grant-title"> and
         <xref linkend="sql-revoke" endterm="sql-revoke-title">
!        for details
        </entry>
       </row>
      </tbody>
***************
*** 2683,2689 ****
        <entry><structfield>listenerpid</structfield></entry>
        <entry><type>int4</type></entry>
        <entry></entry>
!       <entry>PID of the server process that created this entry.</entry>
       </row>
  
       <row>
--- 2684,2690 ----
        <entry><structfield>listenerpid</structfield></entry>
        <entry><type>int4</type></entry>
        <entry></entry>
!       <entry>PID of the server process that created this entry</entry>
       </row>
  
       <row>
***************
*** 2752,2758 ****
         Access privileges; see
         <xref linkend="sql-grant" endterm="sql-grant-title"> and
         <xref linkend="sql-revoke" endterm="sql-revoke-title">
!        for details.
        </entry>
       </row>
      </tbody>
--- 2753,2759 ----
         Access privileges; see
         <xref linkend="sql-grant" endterm="sql-grant-title"> and
         <xref linkend="sql-revoke" endterm="sql-revoke-title">
!        for details
        </entry>
       </row>
      </tbody>
***************
*** 3030,3037 ****
    </table>
  
    <para>
!    Unused column contain zeroes, for example <structfield>oprleft</structfield> is zero for a
!    prefix operator.
    </para>
  
   </sect1>
--- 3031,3038 ----
    </table>
  
    <para>
!    Unused column contain zeroes. For example, <structfield>oprleft</structfield>
!    is zero for a prefix operator.
    </para>
  
   </sect1>
***************
*** 3123,3131 ****
    <para>
     There are not currently any commands that manipulate procedural language
     templates; to change the built-in information, a superuser must modify
!    the table using ordinary INSERT, DELETE, or UPDATE commands.  It is
!    likely that a future release of <productname>PostgreSQL</productname>
!    will offer commands to change the entries in a cleaner fashion.
    </para>
  
    <para>
--- 3124,3133 ----
    <para>
     There are not currently any commands that manipulate procedural language
     templates; to change the built-in information, a superuser must modify
!    the table using ordinary <command>INSERT</command>, <command>DELETE</command>,
!    or <command>UPDATE</command> commands.  It is likely that a future
!    release of <productname>PostgreSQL</productname> will offer
!    commands to change the entries in a cleaner fashion.
    </para>
  
    <para>
***************
*** 3349,3355 ****
         Access privileges; see
         <xref linkend="sql-grant" endterm="sql-grant-title"> and
         <xref linkend="sql-revoke" endterm="sql-revoke-title">
!        for details.
        </entry>
       </row>
      </tbody>
--- 3351,3357 ----
         Access privileges; see
         <xref linkend="sql-grant" endterm="sql-grant-title"> and
         <xref linkend="sql-revoke" endterm="sql-revoke-title">
!        for details
        </entry>
       </row>
      </tbody>
***************
*** 3552,3558 ****
        <entry><type>char</type></entry>
        <entry></entry>
        <entry>
!        A code defining the specific semantics of this dependency relationship; see text.
        </entry>
       </row>
  
--- 3554,3560 ----
        <entry><type>char</type></entry>
        <entry></entry>
        <entry>
!        A code defining the specific semantics of this dependency relationship; see text
        </entry>
       </row>
  
***************
*** 3743,3750 ****
        <entry></entry>
        <entry>
         Numerical statistics of the appropriate kind for the
!        <replaceable>N</>th <quote>slot</quote>, or null if the slot
!        kind does not involve numerical values.
        </entry>
       </row>
  
--- 3745,3752 ----
        <entry></entry>
        <entry>
         Numerical statistics of the appropriate kind for the
!        <replaceable>N</>th <quote>slot</quote>, or NULL if the slot
!        kind does not involve numerical values
        </entry>
       </row>
  
***************
*** 3754,3760 ****
        <entry></entry>
        <entry>
         Column data values of the appropriate kind for the
!        <replaceable>N</>th <quote>slot</quote>, or null if the slot
         kind does not store any data values.  Each array's element
         values are actually of the specific column's data type, so there
         is no way to define these columns' type more specifically than
--- 3756,3762 ----
        <entry></entry>
        <entry>
         Column data values of the appropriate kind for the
!        <replaceable>N</>th <quote>slot</quote>, or NULL if the slot
         kind does not store any data values.  Each array's element
         values are actually of the specific column's data type, so there
         is no way to define these columns' type more specifically than
***************
*** 3831,3837 ****
         Access privileges; see
         <xref linkend="sql-grant" endterm="sql-grant-title"> and
         <xref linkend="sql-revoke" endterm="sql-revoke-title">
!        for details.
        </entry>
       </row>
      </tbody>
--- 3833,3839 ----
         Access privileges; see
         <xref linkend="sql-grant" endterm="sql-grant-title"> and
         <xref linkend="sql-revoke" endterm="sql-revoke-title">
!        for details
        </entry>
       </row>
      </tbody>
***************
*** 3955,3961 ****
        <entry><structfield>tgargs</structfield></entry>
        <entry><type>bytea</type></entry>
        <entry></entry>
!       <entry>Argument strings to pass to trigger, each null-terminated</entry>
       </row>
      </tbody>
     </tgroup>
--- 3957,3963 ----
        <entry><structfield>tgargs</structfield></entry>
        <entry><type>bytea</type></entry>
        <entry></entry>
!       <entry>Argument strings to pass to trigger, each NULL-terminated</entry>
       </row>
      </tbody>
     </tgroup>
***************
*** 4374,4385 ****
  
       <row>
        <entry><link linkend="view-pg-prepared-statements"><structname>pg_prepared_statements</structname></link></entry>
!       <entry>current prepared statements</entry>
       </row>
  
       <row>
        <entry><link linkend="view-pg-prepared-xacts"><structname>pg_prepared_xacts</structname></link></entry>
!       <entry>currently prepared transactions</entry>
       </row>
  
       <row>
--- 4376,4387 ----
  
       <row>
        <entry><link linkend="view-pg-prepared-statements"><structname>pg_prepared_statements</structname></link></entry>
!       <entry>prepared statements</entry>
       </row>
  
       <row>
        <entry><link linkend="view-pg-prepared-xacts"><structname>pg_prepared_xacts</structname></link></entry>
!       <entry>prepared transactions</entry>
       </row>
  
       <row>
***************
*** 4684,4690 ****
        <entry><type>xid</type></entry>
        <entry></entry>
        <entry>
!        ID of the transaction that is holding or awaiting this lock.
        </entry>
       </row>
       <row>
--- 4686,4692 ----
        <entry><type>xid</type></entry>
        <entry></entry>
        <entry>
!        ID of the transaction that is holding or awaiting this lock
        </entry>
       </row>
       <row>
***************
*** 4693,4699 ****
        <entry></entry>
        <entry>
         Process ID of the server process holding or awaiting this
!        lock.  Null if the lock is held by a prepared transaction.
        </entry>
       </row>
       <row>
--- 4695,4701 ----
        <entry></entry>
        <entry>
         Process ID of the server process holding or awaiting this
!        lock.  NULL if the lock is held by a prepared transaction.
        </entry>
       </row>
       <row>
***************
*** 4801,4810 ****
    <para>
     <structname>pg_prepared_statements</structname> contains one row
     for each prepared statement. Rows are added to the view when a new
!    prepared statement is created, and removed when a prepared
!    statement is released (for example, via the <xref
!    linkend="sql-deallocate" endterm="sql-deallocate-title">
!    command).
    </para>
  
    <table>
--- 4803,4811 ----
    <para>
     <structname>pg_prepared_statements</structname> contains one row
     for each prepared statement. Rows are added to the view when a new
!    prepared statement is created and removed when a prepared statement
!    is released (for example, via the <xref linkend="sql-deallocate"
!    endterm="sql-deallocate-title"> command).
    </para>
  
    <table>
***************
*** 4825,4831 ****
        <entry><type>text</type></entry>
        <entry></entry>
        <entry>
!        The identifier of the prepared statement.
        </entry>
       </row>
       <row>
--- 4826,4832 ----
        <entry><type>text</type></entry>
        <entry></entry>
        <entry>
!        The identifier of the prepared statement
        </entry>
       </row>
       <row>
***************
*** 4846,4861 ****
        <entry><type>timestamptz</type></entry>
        <entry></entry>
        <entry>
!        The time at which the prepared statement was created.
        </entry>
       </row>
       <row>
        <entry><structfield>parameter_types</structfield></entry>
!       <entry><type>oid[]</type></entry>
        <entry></entry>
        <entry>
!        The expected parameter types for the prepared statement in the form of
!        an array of type OIDs.
        </entry>
       </row>
       <row>
--- 4847,4864 ----
        <entry><type>timestamptz</type></entry>
        <entry></entry>
        <entry>
!        The time at which the prepared statement was created
        </entry>
       </row>
       <row>
        <entry><structfield>parameter_types</structfield></entry>
!       <entry><type>regtype[]</type></entry>
        <entry></entry>
        <entry>
!        The expected parameter types for the prepared statement in the
!        form of an array of <type>regtype</type>. The OID corresponding
!        to an element of this array can be obtained by casting the
!        <type>regtype</type> value to <type>oid</type>.
        </entry>
       </row>
       <row>
***************
*** 4866,4872 ****
         <literal>true</literal> if the prepared statement was created
         via the <command>PREPARE</command> SQL statement;
         <literal>false</literal> if the statement was prepared via the
!        frontend/backend protocol.
        </entry>
       </row>
      </tbody>
--- 4869,4875 ----
         <literal>true</literal> if the prepared statement was created
         via the <command>PREPARE</command> SQL statement;
         <literal>false</literal> if the statement was prepared via the
!        frontend/backend protocol
        </entry>
       </row>
      </tbody>
***************
*** 5733,5739 ****
        <entry><structfield>definition</structfield></entry>
        <entry><type>text</type></entry>
        <entry></entry>
!       <entry>view definition (a reconstructed SELECT query)</entry>
       </row>
      </tbody>
     </tgroup>
--- 5736,5742 ----
        <entry><structfield>definition</structfield></entry>
        <entry><type>text</type></entry>
        <entry></entry>
!       <entry>view definition (a reconstructed <command>SELECT</command> query)</entry>
       </row>
      </tbody>
     </tgroup>
============================================================
*** src/backend/catalog/system_views.sql	e786475cb67cb61259f8eb6be7ffdc0a9aa35cfe
--- src/backend/catalog/system_views.sql	4f6a0e0e4a1ce155c6ea7522621349c0bb8ac39a
***************
*** 160,166 ****
      SELECT P.name, P.statement, P.prepare_time, P.parameter_types, P.from_sql
      FROM pg_prepared_statement() AS P
      (name text, statement text, prepare_time timestamptz,
!      parameter_types oid[], from_sql boolean);
  
  CREATE VIEW pg_settings AS 
      SELECT * 
--- 160,166 ----
      SELECT P.name, P.statement, P.prepare_time, P.parameter_types, P.from_sql
      FROM pg_prepared_statement() AS P
      (name text, statement text, prepare_time timestamptz,
!      parameter_types regtype[], from_sql boolean);
  
  CREATE VIEW pg_settings AS 
      SELECT * 
============================================================
*** src/backend/commands/prepare.c	60c59c26662b7109e1efb6374c142c045e8d329f
--- src/backend/commands/prepare.c	57029b712c4f4c257f07d036d469f1291903bcea
***************
*** 45,51 ****
  static void InitQueryHashTable(void);
  static ParamListInfo EvaluateParams(EState *estate,
  			   List *params, List *argtypes);
! static Datum build_oid_array(List *oid_list);
  
  /*
   * Implements the 'PREPARE' utility statement.
--- 45,51 ----
  static void InitQueryHashTable(void);
  static ParamListInfo EvaluateParams(EState *estate,
  			   List *params, List *argtypes);
! static Datum build_regtype_array(List *oid_list);
  
  /*
   * Implements the 'PREPARE' utility statement.
***************
*** 674,680 ****
  
  /*
   * This set returning function reads all the prepared statements and
!  * returns a set of (name, statement, prepare_time, param_types).
   */
  Datum
  pg_prepared_statement(PG_FUNCTION_ARGS)
--- 674,680 ----
  
  /*
   * This set returning function reads all the prepared statements and
!  * returns a set of (name, statement, prepare_time, param_types, from_sql).
   */
  Datum
  pg_prepared_statement(PG_FUNCTION_ARGS)
***************
*** 721,727 ****
  		TupleDescInitEntry(tupdesc, (AttrNumber) 3, "prepare_time",
  						   TIMESTAMPTZOID, -1, 0);
  		TupleDescInitEntry(tupdesc, (AttrNumber) 4, "parameter_types",
! 						   OIDARRAYOID, -1, 0);
  		TupleDescInitEntry(tupdesc, (AttrNumber) 5, "from_sql",
  						   BOOLOID, -1, 0);
  
--- 721,727 ----
  		TupleDescInitEntry(tupdesc, (AttrNumber) 3, "prepare_time",
  						   TIMESTAMPTZOID, -1, 0);
  		TupleDescInitEntry(tupdesc, (AttrNumber) 4, "parameter_types",
! 						   REGTYPEARRAYOID, -1, 0);
  		TupleDescInitEntry(tupdesc, (AttrNumber) 5, "from_sql",
  						   BOOLOID, -1, 0);
  
***************
*** 757,763 ****
  									CStringGetDatum(prep_stmt->query_string));
  
  		values[2] = TimestampTzGetDatum(prep_stmt->prepare_time);
! 		values[3] = build_oid_array(prep_stmt->argtype_list);
  		values[4] = BoolGetDatum(prep_stmt->from_sql);
  
  		tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
--- 757,763 ----
  									CStringGetDatum(prep_stmt->query_string));
  
  		values[2] = TimestampTzGetDatum(prep_stmt->prepare_time);
! 		values[3] = build_regtype_array(prep_stmt->argtype_list);
  		values[4] = BoolGetDatum(prep_stmt->from_sql);
  
  		tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
***************
*** 770,786 ****
  
  /*
   * This utility function takes a List of Oids, and returns a Datum
!  * pointing to a Postgres array containing those OIDs. The empty list
!  * is returned as a zero-element array, not NULL.
   */
  static Datum
! build_oid_array(List *oid_list)
  {
! 	ListCell *lc;
! 	int len;
! 	int i;
! 	Datum *tmp_ary;
! 	ArrayType *ary;
  
  	len = list_length(oid_list);
  	tmp_ary = (Datum *) palloc(len * sizeof(Datum));
--- 770,786 ----
  
  /*
   * This utility function takes a List of Oids, and returns a Datum
!  * pointing to a Postgres array of regtypes. The empty list is
!  * returned as a zero-element array, not NULL.
   */
  static Datum
! build_regtype_array(List *oid_list)
  {
! 	ListCell   *lc;
! 	int			len;
! 	int			i;
! 	Datum	   *tmp_ary;
! 	ArrayType  *ary;
  
  	len = list_length(oid_list);
  	tmp_ary = (Datum *) palloc(len * sizeof(Datum));
***************
*** 787,795 ****
  
  	i = 0;
  	foreach(lc, oid_list)
! 		tmp_ary[i++] = ObjectIdGetDatum(lfirst_oid(lc));
  
! 	/* XXX: this hardcodes assumptions about the OID type... */
! 	ary = construct_array(tmp_ary, len, OIDOID, sizeof(Oid), true, 'i');
  	return PointerGetDatum(ary);
  }
--- 787,802 ----
  
  	i = 0;
  	foreach(lc, oid_list)
! 	{
! 		Oid		oid;
! 		Datum	oid_str;
  
! 		oid = lfirst_oid(lc);
! 		oid_str = DirectFunctionCall1(oidout, ObjectIdGetDatum(oid));
! 		tmp_ary[i++] = DirectFunctionCall1(regtypein, oid_str);
! 	}
! 
! 	/* XXX: this hardcodes assumptions about the regtype type */
! 	ary = construct_array(tmp_ary, len, REGTYPEOID, 4, true, 'i');
  	return PointerGetDatum(ary);
  }
============================================================
*** src/include/catalog/pg_type.h	656f52744f5fdb7f5aa9d8c24d46ef70fde1e57c
--- src/include/catalog/pg_type.h	6af0e81fe97b7dd722c54df037339297d414c23a
***************
*** 406,412 ****
  DATA(insert OID = 1008 (  _regproc	 PGNSP PGUID -1 f b t \054 0	24 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
  DATA(insert OID = 1009 (  _text		 PGNSP PGUID -1 f b t \054 0	25 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
  DATA(insert OID = 1028 (  _oid		 PGNSP PGUID -1 f b t \054 0	26 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
- #define OIDARRAYOID			1028
  DATA(insert OID = 1010 (  _tid		 PGNSP PGUID -1 f b t \054 0	27 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
  DATA(insert OID = 1011 (  _xid		 PGNSP PGUID -1 f b t \054 0	28 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
  DATA(insert OID = 1012 (  _cid		 PGNSP PGUID -1 f b t \054 0	29 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
--- 406,411 ----
***************
*** 517,522 ****
--- 516,522 ----
  DATA(insert OID = 2209 ( _regoperator  PGNSP PGUID -1 f b t \054 0 2204 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
  DATA(insert OID = 2210 ( _regclass	   PGNSP PGUID -1 f b t \054 0 2205 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
  DATA(insert OID = 2211 ( _regtype	   PGNSP PGUID -1 f b t \054 0 2206 array_in array_out array_recv array_send - i x f 0 -1 0 _null_ _null_ ));
+ #define REGTYPEARRAYOID	2211
  
  /*
   * pseudo-types
============================================================
*** src/test/regress/expected/prepare.out	64b0450b880f73c12262a4af051b68db51be450c
--- src/test/regress/expected/prepare.out	54ad409f7c958299697c41fe9a019816e71ebed8
***************
*** 148,166 ****
      SELECT * FROM road WHERE thepath = $1;
  SELECT name, statement, parameter_types FROM pg_prepared_statements
      ORDER BY name;
!  name |                                                                                    statement                                                                                    |   parameter_types    
! ------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------
   q2   | PREPARE q2(text) AS
  	SELECT datname, datistemplate, datallowconn
! 	FROM pg_database WHERE datname = $1;                                                                          | {25}
   q3   | PREPARE q3(text, int, float, boolean, oid, smallint) AS
  	SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR
! 	ten = $3::bigint OR true = $4 OR oid = $5 OR odd = $6::int); | {25,23,701,16,26,21}
   q5   | PREPARE q5(int, text) AS
! 	SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2;                                                                                              | {23,25}
   q6   | PREPARE q6 AS
!     SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2;                                                                                                     | {23,19}
   q7   | PREPARE q7(unknown) AS
!     SELECT * FROM road WHERE thepath = $1;                                                                                                               | {602}
  (5 rows)
  
--- 148,166 ----
      SELECT * FROM road WHERE thepath = $1;
  SELECT name, statement, parameter_types FROM pg_prepared_statements
      ORDER BY name;
!  name |                                                                                    statement                                                                                    |                    parameter_types                     
! ------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------
   q2   | PREPARE q2(text) AS
  	SELECT datname, datistemplate, datallowconn
! 	FROM pg_database WHERE datname = $1;                                                                          | {text}
   q3   | PREPARE q3(text, int, float, boolean, oid, smallint) AS
  	SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR
! 	ten = $3::bigint OR true = $4 OR oid = $5 OR odd = $6::int); | {text,integer,"double precision",boolean,oid,smallint}
   q5   | PREPARE q5(int, text) AS
! 	SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2;                                                                                              | {integer,text}
   q6   | PREPARE q6 AS
!     SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2;                                                                                                     | {integer,name}
   q7   | PREPARE q7(unknown) AS
!     SELECT * FROM road WHERE thepath = $1;                                                                                                               | {path}
  (5 rows)
  
============================================================
*** src/test/regress/expected/rules.out	d2b7b350c3d01bd98ee6ceaa0e92acb34c2380f6
--- src/test/regress/expected/rules.out	b34e70eeb88ed7655fb82d371c119c6249cf473c
***************
*** 1280,1286 ****
   pg_group                 | SELECT pg_authid.rolname AS groname, pg_authid.oid AS grosysid, ARRAY(SELECT pg_auth_members.member FROM pg_auth_members WHERE (pg_auth_members.roleid = pg_authid.oid)) AS grolist FROM pg_authid WHERE (NOT pg_authid.rolcanlogin);
   pg_indexes               | SELECT n.nspname AS schemaname, c.relname AS tablename, i.relname AS indexname, t.spcname AS "tablespace", pg_get_indexdef(i.oid) AS indexdef FROM ((((pg_index x JOIN pg_class c ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = i.reltablespace))) WHERE ((c.relkind = 'r'::"char") AND (i.relkind = 'i'::"char"));
   pg_locks                 | SELECT l.locktype, l."database", l.relation, l.page, l.tuple, l.transactionid, l.classid, l.objid, l.objsubid, l."transaction", l.pid, l."mode", l."granted" FROM pg_lock_status() l(locktype text, "database" oid, relation oid, page integer, tuple smallint, transactionid xid, classid oid, objid oid, objsubid smallint, "transaction" xid, pid integer, "mode" text, "granted" boolean);
!  pg_prepared_statements   | SELECT p.name, p."statement", p.prepare_time, p.parameter_types, p.from_sql FROM pg_prepared_statement() p(name text, "statement" text, prepare_time timestamp with time zone, parameter_types oid[], from_sql boolean);
   pg_prepared_xacts        | SELECT p."transaction", p.gid, p."prepared", u.rolname AS "owner", d.datname AS "database" FROM ((pg_prepared_xact() p("transaction" xid, gid text, "prepared" timestamp with time zone, ownerid oid, dbid oid) LEFT JOIN pg_authid u ON ((p.ownerid = u.oid))) LEFT JOIN pg_database d ON ((p.dbid = d.oid)));
   pg_roles                 | SELECT pg_authid.rolname, pg_authid.rolsuper, pg_authid.rolinherit, pg_authid.rolcreaterole, pg_authid.rolcreatedb, pg_authid.rolcatupdate, pg_authid.rolcanlogin, pg_authid.rolconnlimit, '********'::text AS rolpassword, pg_authid.rolvaliduntil, pg_authid.rolconfig, pg_authid.oid FROM pg_authid;
   pg_rules                 | SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition FROM ((pg_rewrite r JOIN pg_class c ON ((c.oid = r.ev_class))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (r.rulename <> '_RETURN'::name);
--- 1280,1286 ----
   pg_group                 | SELECT pg_authid.rolname AS groname, pg_authid.oid AS grosysid, ARRAY(SELECT pg_auth_members.member FROM pg_auth_members WHERE (pg_auth_members.roleid = pg_authid.oid)) AS grolist FROM pg_authid WHERE (NOT pg_authid.rolcanlogin);
   pg_indexes               | SELECT n.nspname AS schemaname, c.relname AS tablename, i.relname AS indexname, t.spcname AS "tablespace", pg_get_indexdef(i.oid) AS indexdef FROM ((((pg_index x JOIN pg_class c ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = i.reltablespace))) WHERE ((c.relkind = 'r'::"char") AND (i.relkind = 'i'::"char"));
   pg_locks                 | SELECT l.locktype, l."database", l.relation, l.page, l.tuple, l.transactionid, l.classid, l.objid, l.objsubid, l."transaction", l.pid, l."mode", l."granted" FROM pg_lock_status() l(locktype text, "database" oid, relation oid, page integer, tuple smallint, transactionid xid, classid oid, objid oid, objsubid smallint, "transaction" xid, pid integer, "mode" text, "granted" boolean);
!  pg_prepared_statements   | SELECT p.name, p."statement", p.prepare_time, p.parameter_types, p.from_sql FROM pg_prepared_statement() p(name text, "statement" text, prepare_time timestamp with time zone, parameter_types regtype[], from_sql boolean);
   pg_prepared_xacts        | SELECT p."transaction", p.gid, p."prepared", u.rolname AS "owner", d.datname AS "database" FROM ((pg_prepared_xact() p("transaction" xid, gid text, "prepared" timestamp with time zone, ownerid oid, dbid oid) LEFT JOIN pg_authid u ON ((p.ownerid = u.oid))) LEFT JOIN pg_database d ON ((p.dbid = d.oid)));
   pg_roles                 | SELECT pg_authid.rolname, pg_authid.rolsuper, pg_authid.rolinherit, pg_authid.rolcreaterole, pg_authid.rolcreatedb, pg_authid.rolcatupdate, pg_authid.rolcanlogin, pg_authid.rolconnlimit, '********'::text AS rolpassword, pg_authid.rolvaliduntil, pg_authid.rolconfig, pg_authid.oid FROM pg_authid;
   pg_rules                 | SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition FROM ((pg_rewrite r JOIN pg_class c ON ((c.oid = r.ev_class))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (r.rulename <> '_RETURN'::name);
---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
       subscribe-nomail command to [EMAIL PROTECTED] so that your
       message can get through to the mailing list cleanly

Reply via email to