]> granicus.if.org Git - postgresql/commitdiff
Revise handling of oldstyle/newstyle functions per recent discussions
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 20 Nov 2000 20:36:57 +0000 (20:36 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 20 Nov 2000 20:36:57 +0000 (20:36 +0000)
in pghackers list.  Support for oldstyle internal functions is gone
(no longer needed, since conversion is complete) and pg_language entry
'internal' now implies newstyle call convention.  pg_language entry
'newC' is gone; both old and newstyle dynamically loaded C functions
are now called language 'C'.  A newstyle function must be identified
by an associated info routine.  See src/backend/utils/fmgr/README.

52 files changed:
contrib/fulltextindex/README.fti
contrib/fulltextindex/fti.c
contrib/fulltextindex/fti.pl
contrib/fulltextindex/fti.sql.in
contrib/lo/lo.c
contrib/lo/lo.sql.in
contrib/noupdate/noup.c
contrib/noupdate/noup.sql.in
contrib/pgcrypto/pgcrypto.c
contrib/pgcrypto/pgcrypto.sql.in
contrib/soundex/soundex.c
contrib/soundex/soundex.sql.in
contrib/spi/autoinc.c
contrib/spi/autoinc.sql.in
contrib/spi/insert_username.c
contrib/spi/insert_username.sql.in
contrib/spi/moddatetime.c
contrib/spi/moddatetime.sql.in
contrib/spi/refint.c
contrib/spi/refint.sql.in
contrib/spi/timetravel.c
contrib/spi/timetravel.sql.in
doc/src/sgml/ref/create_function.sgml
doc/src/sgml/ref/create_language.sgml
doc/src/sgml/trigger.sgml
doc/src/sgml/xfunc.sgml
src/backend/catalog/pg_proc.c
src/backend/commands/define.c
src/backend/commands/remove.c
src/backend/commands/trigger.c
src/backend/utils/Gen_fmgrtab.sh
src/backend/utils/cache/lsyscache.c
src/backend/utils/fmgr/dfmgr.c
src/backend/utils/fmgr/fmgr.c
src/bin/scripts/createlang.sh
src/include/catalog/catversion.h
src/include/catalog/pg_language.h
src/include/fmgr.h
src/include/utils/fmgrtab.h
src/include/utils/lsyscache.h
src/pl/plperl/plperl.c
src/pl/plpgsql/src/pl_handler.c
src/pl/tcl/pltcl.c
src/test/regress/input/create_function_1.source
src/test/regress/input/create_function_2.source
src/test/regress/input/misc.source
src/test/regress/output/create_function_1.source
src/test/regress/output/create_function_2.source
src/test/regress/output/misc.source
src/test/regress/regress.c
src/test/regress/sql/drop.sql
src/tutorial/funcs_new.c

index fdb6fcf3b10663d9b4ea6d442f9cbee5a52cbb75..10838db6912641d129643c6abff8025551523d1b 100644 (file)
@@ -57,7 +57,7 @@ sub-string will fit.
 The create the function that contains the trigger::
 
        create function fti() returns opaque as
-           '/path/to/fti.so' language 'newC';
+           '/path/to/fti.so' language 'C';
 
 And finally define the trigger on the 'cds' table:
 
index a98fcd47dc7a86be4d71f0552f4d75021b5a198f..bb4636ff3e03937508f9e4b6281fe8809824201a 100644 (file)
@@ -17,7 +17,7 @@
        Example:
 
 create function fti() returns opaque as
-'/home/boekhold/src/postgresql-6.2/contrib/fti/fti.so' language 'newC';
+'/home/boekhold/src/postgresql-6.2/contrib/fti/fti.so' language 'C';
 
 create table title_fti (string varchar(25), id oid);
 create index title_fti_idx on title_fti (string);
@@ -93,6 +93,8 @@ static int    nDeletePlans = 0;
 static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans);
 
 /***********************************************************************/
+PG_FUNCTION_INFO_V1(fti);
+
 Datum
 fti(PG_FUNCTION_ARGS)
 {
index 6b6d68e4900ac35412c907dbf977179817d74431..02bf057e94a6597ef584ea82272a649e9818426b 100644 (file)
@@ -29,7 +29,7 @@
 #
 #              create function fti() returns opaque as
 #                      '/path/to/fti/file/fti.so'
-#              language 'newC';
+#              language 'C';
 #
 #              create trigger my_fti_trigger after update or insert or delete
 #                      on mytable
index c0b3662ae592645680e25606a441cd3f7729a643..e0da2353c52447eb1b019fb516d827abf4842c21 100644 (file)
@@ -1,3 +1,3 @@
 create function fti() returns opaque as
        'MODULE_PATHNAME'
-       language 'newC';
\ No newline at end of file
+       language 'C';
\ No newline at end of file
index 386c2c2d2f76263abfd7c6584e2257954255d0e8..5de00ad5ca4bccca3f791feea61f26c11337c4ac 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     PostgreSQL type definitions for managed LargeObjects.
  *
- *     $Id: lo.c,v 1.4 2000/06/09 01:10:58 tgl Exp $
+ *     $Id: lo.c,v 1.5 2000/11/20 20:36:55 tgl Exp $
  *
  */
 
@@ -140,6 +140,8 @@ lo(Oid oid)
 /*
  * This handles the trigger that protects us from orphaned large objects
  */
+PG_FUNCTION_INFO_V1(lo_manage);
+
 Datum
 lo_manage(PG_FUNCTION_ARGS)
 {
index 4aa75a60fe17ec9935e6eb411d829d178bcb90af..9b340b196f8425d0f46384421d6376d60f6c8a5f 100644 (file)
@@ -1,7 +1,7 @@
 --
 --     PostgreSQL code for LargeObjects
 --
---     $Id: lo.sql.in,v 1.4 2000/06/19 13:53:42 momjian Exp $
+--     $Id: lo.sql.in,v 1.5 2000/11/20 20:36:55 tgl Exp $
 --
 --
 --     Create the data type
@@ -44,7 +44,7 @@ create function lo(oid)
 create function lo_manage()
        returns opaque
        as 'MODULE_PATHNAME'
-       language 'newC';
+       language 'C';
 
 -- This allows us to map lo to oid
 --
index 5035e127be86c90c0e493f1e787135e1963d56ad..af857c41f6e33ebb9bc9ba2373b7547d71da42d5 100644 (file)
@@ -16,6 +16,8 @@ extern Datum noup(PG_FUNCTION_ARGS);
  * EXECUTE PROCEDURE noup ('col').
  */
 
+PG_FUNCTION_INFO_V1(noup);
+
 Datum
 noup(PG_FUNCTION_ARGS)
 {
index cc1e6fa146fce8cb2c4599588f1d6bc1725788f0..abf92837d1d626ab3b9e0c63abea97c410f289bc 100644 (file)
@@ -3,5 +3,4 @@ DROP FUNCTION noup ();
 CREATE FUNCTION noup ()
        RETURNS opaque
        AS 'MODULE_PATHNAME'
-       LANGUAGE 'newC'
-;
+       LANGUAGE 'C';
index 4897edb9d2542116655cfa5b01c5652791d9c488..e4978dea2daae700a2bf7e352493db54ecb38bac 100644 (file)
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: pgcrypto.c,v 1.1 2000/10/31 13:11:28 petere Exp $
+ * $Id: pgcrypto.c,v 1.2 2000/11/20 20:36:56 tgl Exp $
  */
 
 #include <postgres.h>
@@ -59,6 +59,8 @@ find_digest(pg_digest *hbuf, text *name, int silent);
 
 
 /* SQL function: hash(text, text) returns text */
+PG_FUNCTION_INFO_V1(digest);
+
 Datum
 digest(PG_FUNCTION_ARGS)
 {
@@ -95,6 +97,8 @@ digest(PG_FUNCTION_ARGS)
 }
 
 /* check if given hash exists */
+PG_FUNCTION_INFO_V1(digest_exists);
+
 Datum
 digest_exists(PG_FUNCTION_ARGS)
 {
index a30b3116e5e1c6b897cee32aa9fddbf261a37901..2059c0d8e5998081d76640bf0eff194377a952bd 100644 (file)
@@ -4,9 +4,9 @@
 
 CREATE FUNCTION digest(text, text) RETURNS text
   AS '@MODULE_FILENAME@',
-  'digest' LANGUAGE 'newC';
+  'digest' LANGUAGE 'C';
 
 CREATE FUNCTION digest_exists(text) RETURNS bool
   AS '@MODULE_FILENAME@',
-  'digest_exists' LANGUAGE 'newC';
+  'digest_exists' LANGUAGE 'C';
 
index f2acba403666a21e00ea57120a6de082e52212c0..f66cb21f2426517986a4b51972387775c7712e76 100644 (file)
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/contrib/soundex/Attic/soundex.c,v 1.7 2000/10/04 19:25:34 petere Exp $ */
+/* $Header: /cvsroot/pgsql/contrib/soundex/Attic/soundex.c,v 1.8 2000/11/20 20:36:57 tgl Exp $ */
 #include "postgres.h"
 #include "fmgr.h"
 #include "utils/builtins.h"
@@ -7,11 +7,9 @@
 #include <stdio.h>
 
 
-Datum
-text_soundex(PG_FUNCTION_ARGS);
+Datum text_soundex(PG_FUNCTION_ARGS);
 
-static void
-soundex(const char *instr, char *outstr);
+static void soundex(const char *instr, char *outstr);
 
 #define SOUNDEX_LEN 4
 
@@ -24,6 +22,8 @@ soundex(const char *instr, char *outstr);
 /*
  * SQL function: text_soundex(text) returns text
  */
+PG_FUNCTION_INFO_V1(text_soundex);
+
 Datum
 text_soundex(PG_FUNCTION_ARGS)
 {
@@ -36,6 +36,7 @@ text_soundex(PG_FUNCTION_ARGS)
 
        PG_RETURN_TEXT_P(_textin(outstr));
 }
+
 #endif /* not SOUNDEX_TEST */
 
 
index 4cb0ad0e4dbf2849d245d4ba169a16f9f8fb1e0e..4805694f9a6b5fca1b0584b412cf0ae8aa371b85 100644 (file)
@@ -1,5 +1,5 @@
 CREATE FUNCTION text_soundex(text) RETURNS text
-  AS '@MODULE_FILENAME@', 'text_soundex' LANGUAGE 'newC';
+  AS '@MODULE_FILENAME@', 'text_soundex' LANGUAGE 'C';
 
 CREATE FUNCTION soundex(text) RETURNS text
-  AS '@MODULE_FILENAME@', 'text_soundex' LANGUAGE 'newC';
+  AS '@MODULE_FILENAME@', 'text_soundex' LANGUAGE 'C';
index f8b86217e73b79115cef4017d32a4d013246dc12..8592ea7ed9bcdc112197b7286dcd136b3d7b8d82 100644 (file)
@@ -5,6 +5,8 @@
 
 extern Datum autoinc(PG_FUNCTION_ARGS);
 
+PG_FUNCTION_INFO_V1(autoinc);
+
 Datum
 autoinc(PG_FUNCTION_ARGS)
 {
index d587b567b37b33e85b1f144796c55b9dfd24c49b..367674294352dc28fedce86ff9b6490a45558764 100644 (file)
@@ -3,4 +3,4 @@ DROP FUNCTION autoinc();
 CREATE FUNCTION autoinc() 
        RETURNS opaque 
        AS 'MODULE_PATHNAME'
-       LANGUAGE 'newC';
+       LANGUAGE 'C';
index 978a873ec90dd67b7fe22009c560344b3e88d747..6bc31444200332ca913bb50c7a21c7f62d85ec2a 100644 (file)
@@ -12,6 +12,8 @@
 
 extern Datum   insert_username(PG_FUNCTION_ARGS);
 
+PG_FUNCTION_INFO_V1(insert_username);
+
 Datum
 insert_username(PG_FUNCTION_ARGS)
 {
index d60aebc1b0e73434b55de2872c85ea200c4fbb00..436fc88b73cdbe23da6899aa10da43a69a681e79 100644 (file)
@@ -3,4 +3,4 @@ DROP FUNCTION insert_username();
 CREATE FUNCTION insert_username() 
        RETURNS opaque 
        AS 'MODULE_PATHNAME'
-       LANGUAGE 'newC';
+       LANGUAGE 'C';
index 0229eb8f155015d9f06fd70a9a802a8e7fe543d3..73b151851888d29eb2d2ebdcf00a28dbe012a899 100644 (file)
@@ -17,6 +17,8 @@ OH, me, I'm Terry Mackintosh <terry@terrym.com>
 
 extern Datum   moddatetime(PG_FUNCTION_ARGS);
 
+PG_FUNCTION_INFO_V1(moddatetime);
+
 Datum
 moddatetime(PG_FUNCTION_ARGS)
 {
index cfb7c3c508b0af84458ab44ddf5937fef565703b..d497900ecf19431fc5719307325d74f75121df0b 100644 (file)
@@ -3,4 +3,4 @@ DROP FUNCTION moddatetime();
 CREATE FUNCTION moddatetime() 
        RETURNS opaque 
        AS 'MODULE_PATHNAME'
-       LANGUAGE 'newC';
+       LANGUAGE 'C';
index 4bbe761573b9bdce64543df3b6d437a648e60385..d7a8d73c8e1e3e08a995e3d9ae73d82349640295 100644 (file)
@@ -36,6 +36,8 @@ static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans);
  * check_primary_key ('Fkey1', 'Fkey2', 'Ptable', 'Pkey1', 'Pkey2').
  */
 
+PG_FUNCTION_INFO_V1(check_primary_key);
+
 Datum
 check_primary_key(PG_FUNCTION_ARGS)
 {
@@ -216,6 +218,8 @@ check_primary_key(PG_FUNCTION_ARGS)
  * 'Ftable1', 'Fkey11', 'Fkey12', 'Ftable2', 'Fkey21', 'Fkey22').
  */
 
+PG_FUNCTION_INFO_V1(check_foreign_key);
+
 Datum
 check_foreign_key(PG_FUNCTION_ARGS)
 {
index 91448e8a2ed03e82cb68fc050427dc6d70a0cfdf..d193319d9d4bfaf37341feeb0704227a28eec61d 100644 (file)
@@ -4,11 +4,9 @@ DROP FUNCTION check_foreign_key ();
 CREATE FUNCTION check_primary_key ()
        RETURNS opaque
        AS 'MODULE_PATHNAME'
-       LANGUAGE 'newC'
-;
+       LANGUAGE 'C';
 
 CREATE FUNCTION check_foreign_key ()
        RETURNS opaque
        AS 'MODULE_PATHNAME'
-       LANGUAGE 'newC'
-;
+       LANGUAGE 'C';
index cd50cd84890696f69117eff6b8da16313f1e8017..41e7b092b32b7e63a0d7cb016e92311db75e8663 100644 (file)
@@ -47,6 +47,8 @@ static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans);
  * timetravel ('date_on', 'date_off').
  */
 
+PG_FUNCTION_INFO_V1(timetravel);
+
 Datum
 timetravel(PG_FUNCTION_ARGS)
 {
@@ -326,6 +328,8 @@ timetravel(PG_FUNCTION_ARGS)
  * set_timetravel (relname, on) --
  *                                     turn timetravel for specified relation ON/OFF
  */
+PG_FUNCTION_INFO_V1(set_timetravel);
+
 Datum
 set_timetravel(PG_FUNCTION_ARGS)
 {
index 0de680cb39ad5427202d15023bd16684136de5c2..46912abf6d78588fd2237290c6eee0d2810bcf8d 100644 (file)
@@ -4,9 +4,9 @@ DROP FUNCTION set_timetravel(name, int4);
 CREATE FUNCTION timetravel() 
        RETURNS opaque 
        AS 'MODULE_PATHNAME'
-       LANGUAGE 'newC';
+       LANGUAGE 'C';
 
 CREATE FUNCTION set_timetravel(name, int4) 
        RETURNS int4 
        AS 'MODULE_PATHNAME'
-       LANGUAGE 'newC' WITH (isStrict);
+       LANGUAGE 'C' WITH (isStrict);
index 20a7b6f8b039ba64e0d4825eb460436b9b4d659e..bb733b8df2e1124e0bf76dc32085abb47f2ed5ab 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.19 2000/11/02 19:26:44 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.20 2000/11/20 20:36:46 tgl Exp $
 Postgres documentation
 -->
 
@@ -119,8 +119,7 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
       <listitem>
        <para>
        May be '<literal>sql</literal>',
-       '<literal>C</literal>', '<literal>newC</literal>',
-       '<literal>internal</literal>', '<literal>newinternal</literal>',
+       '<literal>C</literal>', '<literal>internal</literal>',
        or '<replaceable class="parameter">plname</replaceable>',
        where '<replaceable class="parameter">plname</replaceable>'
        is the name of a created procedural language. See
@@ -258,7 +257,7 @@ CREATE
    </para>
 
    <para>
-    Two <literal>internal</literal> or <literal>newinternal</literal>
+    Two <literal>internal</literal>
     functions cannot have the same C name without causing
     errors at link time.  To get around that, give them different C names
     (for example, use the argument types as part of the C names), then
index 934b6cbaf9e139b96a6e5edce44e0be34b2ef0e3..f5e1c6ffa900ae4ccf581f5279ffe15b6be80166 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.13 2000/11/04 21:04:54 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.14 2000/11/20 20:36:46 tgl Exp $
 Postgres documentation
 -->
 
@@ -163,7 +163,8 @@ ERROR:  PL handler function <replaceable class="parameter">funcname</replaceable
     <note>
      <para>
       In <productname>Postgres</productname> 7.1 and later, call handlers
-      must adhere to the "new style" function manager interface.
+      must adhere to the "version 1" function manager interface, not the
+      old-style interface.
      </para>
     </note>
 
@@ -180,7 +181,7 @@ ERROR:  PL handler function <replaceable class="parameter">funcname</replaceable
    </para>
 
    <para>
-    The call handler is called in the same way as any other new-style
+    The call handler is called in the same way as any other
     function: it receives a pointer to a FunctionCallInfoData struct
     containing argument values and information about the called function,
     and it is expected to return a Datum result (and possibly set the
@@ -269,9 +270,7 @@ ERROR:  PL handler function <replaceable class="parameter">funcname</replaceable
    lanname   | lanispl | lanpltrusted | lanplcallfoid | lancompiler
 -------------+---------+--------------+---------------+-------------
  internal    | f       | f            |             0 | n/a
- newinternal | f       | f            |             0 | n/a
  C           | f       | f            |             0 | /bin/cc
- newC        | f       | f            |             0 | /bin/cc
  sql         | f       | f            |             0 | postgres
 </computeroutput>
 </programlisting>
@@ -279,8 +278,9 @@ ERROR:  PL handler function <replaceable class="parameter">funcname</replaceable
 
    <para>
     The call handler for a procedural language must normally be written
-    in C and registered as 'newinternal' or 'newC' language, depending
+    in C and registered as 'internal' or 'C' language, depending
     on whether it is linked into the backend or dynamically loaded.
+    The call handler cannot use the old-style 'C' function interface.
    </para>
 
    <para> 
@@ -306,6 +306,8 @@ ERROR:  PL handler function <replaceable class="parameter">funcname</replaceable
 #include "catalog/pg_proc.h"
 #include "catalog/pg_type.h"
 
+PG_FUNCTION_INFO_V1(plsample_call_handler);
+
 Datum
 plsample_call_handler(PG_FUNCTION_ARGS)
 {
@@ -344,7 +346,7 @@ plsample_call_handler(PG_FUNCTION_ARGS)
    <programlisting>
 CREATE FUNCTION plsample_call_handler () RETURNS opaque
     AS '/usr/local/pgsql/lib/plsample.so'
-    LANGUAGE 'newC';
+    LANGUAGE 'C';
 CREATE PROCEDURAL LANGUAGE 'plsample'
     HANDLER plsample_call_handler
     LANCOMPILER 'PL/Sample';
index 0b3442517c93a7be03c1ec2582b902215b9a3728..d248887a59941e78ec6b107d6756e5f5ee5d0c80 100644 (file)
@@ -22,7 +22,7 @@
    <para>
     The trigger function must be created before the trigger is created as a
     function taking no arguments and returning opaque.  If the function is
-    written in C, it must follow the "new style" function manager interface.
+    written in C, it must use the "version 1" function manager interface.
    </para>
 
    <para>
@@ -447,6 +447,8 @@ execution of Q) or after Q is done.
 
 extern Datum trigf(PG_FUNCTION_ARGS);
 
+PG_FUNCTION_INFO_V1(trigf);
+
 Datum
 trigf(PG_FUNCTION_ARGS)
 {
@@ -513,7 +515,7 @@ trigf(PG_FUNCTION_ARGS)
 
     <programlisting>
 create function trigf () returns opaque as 
-'...path_to_so' language 'newC';
+'...path_to_so' language 'C';
 
 create table ttest (x int4);
     </programlisting>
index d02718d53a7e8b4479114ddb078de2753b7d2415..f2dc29817460700a7a9006fd1e0f5c4ede7a156d 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.22 2000/10/23 00:46:06 tgl Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.23 2000/11/20 20:36:47 tgl Exp $
 -->
 
  <chapter id="xfunc">
@@ -339,9 +339,9 @@ SELECT clean_EMP();
    </para>
 
    <para>
-    There are two procedural languages available with the standard
-    <productname>Postgres</productname> distribution (PLTCL and PLSQL), and other
-    languages can be defined.
+    There are currently three procedural languages available in the standard
+    <productname>Postgres</productname> distribution (PLSQL, PLTCL and
+    PLPERL), and other languages can be defined.
     Refer to <xref linkend="xplang-title" endterm="xplang-title"> for
     more information.
    </para>
@@ -366,12 +366,7 @@ SELECT clean_EMP();
 
    <para>
     Internal functions are declared in <command>CREATE FUNCTION</command>
-    with language name <literal>internal</literal> or
-    <literal>newinternal</literal>, depending on whether they follow the
-    old (pre-7.1) or new (7.1 and later) function call conventions.
-    The details of the call conventions are the same as for
-    <literal>C</literal> and <literal>newC</literal> functions respectively;
-    see the next section for details.
+    with language name <literal>internal</literal>.
    </para>
   </sect1>
 
@@ -404,9 +399,9 @@ SELECT clean_EMP();
    <para>
     The string which specifies the object file (the first string in the AS
     clause) should be the <emphasis>full path</emphasis> of the object
-    code file for the function, bracketed by quotation marks.  If a
+    code file for the function, bracketed by single quote marks.  If a
     link symbol is given in the AS clause, the link symbol should also be
-    bracketed by single quotation marks, and should be exactly the
+    bracketed by single quote marks, and should be exactly the
     same as the name of the function in the C source code. On Unix systems
     the command <command>nm</command> will print all of the link
     symbols in a dynamically loadable object.
@@ -422,11 +417,11 @@ SELECT clean_EMP();
 
    <para>
     Two different calling conventions are currently used for C functions.
-    The "old style" (pre-<productname>Postgres</productname>-7.1) method
-    is selected by writing language name '<literal>C</literal>' in the
-    <command>CREATE FUNCTION</command> command, while the "new style"
-    (7.1 and later) method is selecting by writing language name
-    '<literal>newC</literal>'.  Old-style functions are now deprecated
+    The newer "version 1" calling convention is indicated by writing
+    a <literal>PG_FUNCTION_INFO_V1()</literal> macro call for the function,
+    as illustrated below.  Lack of such a macro indicates an old-style
+    ("version 0") function.  The language name specified in CREATE FUNCTION
+    is 'C' in either case.  Old-style functions are now deprecated
     because of portability problems and lack of functionality, but they
     are still supported for compatibility reasons.
    </para>
@@ -484,7 +479,7 @@ SELECT clean_EMP();
         <entry>include/postgres.h</entry>
        </row>
        <row>
-        <entry>char</entry>
+        <entry>"char"</entry>
         <entry>char</entry>
         <entry>N/A</entry>
        </row>
@@ -583,16 +578,6 @@ SELECT clean_EMP();
         <entry>TimeInterval</entry>
         <entry>utils/nabstime.h</entry>
        </row>
-       <row>
-        <entry>uint2</entry>
-        <entry>uint16</entry>
-        <entry>include/c.h</entry>
-       </row>
-       <row>
-        <entry>uint4</entry>
-        <entry>uint32</entry>
-        <entry>include/c.h</entry>
-       </row>
        <row>
         <entry>xid</entry>
         <entry>(XID *)</entry>
@@ -694,7 +679,7 @@ typedef struct {
     </para>
 
     <para>
-     Obviously,  the  data  field is not long enough to hold
+     Obviously,  the  data  field shown here is not long enough to hold
      all possible strings; it's impossible to declare such
      a  structure  in  <acronym>C</acronym>.  When manipulating 
      variable-length types, we must  be  careful  to  allocate  
@@ -721,12 +706,12 @@ memmove(destination-&gt;data, buffer, 40);
    </sect2>
 
    <sect2>
-    <title>Old-style Calling Conventions for C-Language Functions</title>
+    <title>Version-0 Calling Conventions for C-Language Functions</title>
 
     <para>
      We present the "old style" calling convention first --- although
      this approach is now deprecated, it's easier to get a handle on
-     initially.  In the "old style" method, the arguments and result
+     initially.  In the version-0 method, the arguments and result
      of the C function are just declared in normal C style, but being
      careful to use the C representation of each SQL data type as shown
      above.
@@ -854,26 +839,39 @@ CREATE FUNCTION concat_text(text, text) RETURNS text
     </para>
 
     <para>
-     Although this old-style calling convention is simple to use,
+     Although this calling convention is simple to use,
      it is not very portable; on some architectures there are problems
      with passing smaller-than-int data types this way.  Also, there is
      no simple way to return a NULL result, nor to cope with NULL arguments
-     in any way other than making the function strict.  The new-style
+     in any way other than making the function strict.  The version-1
      convention, presented next, overcomes these objections.
     </para>
    </sect2>
 
    <sect2>
-    <title>New-style Calling Conventions for C-Language Functions</title>
+    <title>Version-1 Calling Conventions for C-Language Functions</title>
 
     <para>
-     The new-style calling convention relies on macros to suppress most
+     The version-1 calling convention relies on macros to suppress most
      of the complexity of passing arguments and results.  The C declaration
-     of a new-style function is always
+     of a version-1 function is always
      <programlisting>
                 Datum funcname(PG_FUNCTION_ARGS)
      </programlisting>
-     Each actual argument is fetched using a PG_GETARG_xxx() macro that
+     In addition, the macro call
+     <programlisting>
+                PG_FUNCTION_INFO_V1(funcname);
+     </programlisting>
+     must appear in the same source file (conventionally it's written
+     just before the function itself).  This macro call is not needed
+     for "internal"-language functions, since Postgres currently assumes
+     all internal functions are version-1.  However, it is
+     <emphasis>required</emphasis> for dynamically-loaded functions.
+    </para>
+
+    <para>
+     In a version-1 function,
+     each actual argument is fetched using a PG_GETARG_xxx() macro that
      corresponds to the argument's datatype, and the result is returned
      using a PG_RETURN_xxx() macro for the return type.
     </para>
@@ -887,6 +885,8 @@ CREATE FUNCTION concat_text(text, text) RETURNS text
 #include "fmgr.h"
 
 /* By Value */
+
+PG_FUNCTION_INFO_V1(add_one);
          
 Datum
 add_one(PG_FUNCTION_ARGS)
@@ -898,6 +898,8 @@ add_one(PG_FUNCTION_ARGS)
 
 /* By Reference, Fixed Length */
 
+PG_FUNCTION_INFO_V1(add_one_float8);
+
 Datum
 add_one_float8(PG_FUNCTION_ARGS)
 {
@@ -907,6 +909,8 @@ add_one_float8(PG_FUNCTION_ARGS)
     PG_RETURN_FLOAT8(arg + 1.0);
 }
 
+PG_FUNCTION_INFO_V1(makepoint);
+
 Datum
 makepoint(PG_FUNCTION_ARGS)
 {
@@ -922,6 +926,8 @@ makepoint(PG_FUNCTION_ARGS)
 
 /* By Reference, Variable Length */
 
+PG_FUNCTION_INFO_V1(copytext);
+
 Datum
 copytext(PG_FUNCTION_ARGS)
 {
@@ -940,6 +946,8 @@ copytext(PG_FUNCTION_ARGS)
     PG_RETURN_TEXT_P(new_t);
 }
 
+PG_FUNCTION_INFO_V1(concat_text);
+
 Datum
 concat_text(PG_FUNCTION_ARGS)
 {
@@ -959,12 +967,11 @@ concat_text(PG_FUNCTION_ARGS)
 
     <para>
      The <command>CREATE FUNCTION</command> commands are the same as
-     for the old-style equivalents, except that the language is specified
-     as '<literal>newC</literal>' not '<literal>C</literal>'.
+     for the old-style equivalents.
     </para>
 
     <para>
-     At first glance, the new-style coding conventions may appear to be
+     At first glance, the version-1 coding conventions may appear to be
      just pointless obscurantism.  However, they do offer a number of
      improvements, because the macros can hide unnecessary detail.
      An example is that in coding add_one_float8, we no longer need to
@@ -973,11 +980,14 @@ concat_text(PG_FUNCTION_ARGS)
      to deal with fetching "toasted" (compressed or out-of-line) values.
      The old-style copytext and concat_text functions shown above are
      actually wrong in the presence of toasted values, because they don't
-     call pg_detoast_datum() on their inputs.
+     call pg_detoast_datum() on their inputs.  (The handler for old-style
+     dynamically-loaded functions currently takes care of this detail,
+     but it does so less efficiently than is possible for a version-1
+     function.)
     </para>
 
     <para>
-     The new-style function call conventions also make it possible to
+     The version-1 function call conventions also make it possible to
      test for NULL inputs to a non-strict function, return a NULL result
      (from either strict or non-strict functions), return "set" results,
      and implement trigger functions and procedural-language call handlers.
@@ -1026,7 +1036,9 @@ c_overpaid(TupleTableSlot *t, /* the current instance of EMP */
     return salary &gt; limit;
 }
 
-/* In new-style coding, the above would look like this: */
+/* In version-1 coding, the above would look like this: */
+
+PG_FUNCTION_INFO_V1(c_overpaid);
 
 Datum
 c_overpaid(PG_FUNCTION_ARGS)
index 9d3ce5c50d6b084d1f880315cc797c3f2e290862..5d63ebf161652bc1ae2a254aa1452efb2d4f8b56 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.50 2000/11/16 22:30:17 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.51 2000/11/20 20:36:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -229,50 +229,35 @@ ProcedureCreate(char *procedureName,
         * FUNCTION xyz AS '' LANGUAGE 'internal'.      To preserve some modicum
         * of backwards compatibility, accept an empty 'prosrc' value as
         * meaning the supplied SQL function name.
-        *
-        * XXX: we could treat "internal" and "newinternal" language specs
-        * as equivalent, and take the actual language ID from the table of
-        * known builtin functions.  Is that a better idea than making the
-        * user specify the right thing?  Not sure.
         */
 
-       if (languageObjectId == INTERNALlanguageId ||
-               languageObjectId == NEWINTERNALlanguageId)
+       if (languageObjectId == INTERNALlanguageId)
        {
-               Oid                     actualLangID;
-
                if (strlen(prosrc) == 0)
                        prosrc = procedureName;
-               actualLangID = fmgr_internal_language(prosrc);
-               if (actualLangID == InvalidOid)
+               if (fmgr_internal_function(prosrc) == InvalidOid)
                        elog(ERROR,
                                 "ProcedureCreate: there is no builtin function named \"%s\"",
                                 prosrc);
-               if (actualLangID != languageObjectId)
-                       elog(ERROR,
-                                "ProcedureCreate: \"%s\" is not %s internal function",
-                                prosrc,
-                                ((languageObjectId == INTERNALlanguageId) ?
-                                 "an old-style" : "a new-style"));
        }
 
        /*
         * If this is a dynamically loadable procedure, make sure that the
         * library file exists, is loadable, and contains the specified link
-        * symbol.
+        * symbol.  Also check for a valid function information record.
         *
         * We used to perform these checks only when the function was first
         * called, but it seems friendlier to verify the library's validity
         * at CREATE FUNCTION time.
         */
 
-       if (languageObjectId == ClanguageId ||
-               languageObjectId == NEWClanguageId)
+       if (languageObjectId == ClanguageId)
        {
                /* If link symbol is specified as "-", substitute procedure name */
                if (strcmp(prosrc, "-") == 0)
                        prosrc = procedureName;
-               (void) load_external_function(probin, prosrc);
+               (void) load_external_function(probin, prosrc, true);
+               (void) fetch_finfo_record(probin, prosrc);
        }
 
        /*
index 9d681a4a50fe2b6d814ed4df6963e1d986da94c4..63ccf32543fd8111688d8413cf8af69a7d14ab6a 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.48 2000/11/16 22:30:18 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.49 2000/11/20 20:36:47 tgl Exp $
  *
  * DESCRIPTION
  *       The "DefineFoo" routines take the parse tree and pick out the
@@ -66,7 +66,7 @@ case_translate_language_name(const char *input, char *output)
 {
 /*-------------------------------------------------------------------------
   Translate the input language name to lower case, except if it's "C",
-  translate to upper case, or "newC", translate to that spelling.
+  translate to upper case.
 --------------------------------------------------------------------------*/
        int                     i;
 
@@ -77,8 +77,6 @@ case_translate_language_name(const char *input, char *output)
 
        if (strcmp(output, "c") == 0)
                output[0] = 'C';
-       else if (strcmp(output, "newc") == 0)
-               output[3] = 'C';
 }
 
 
@@ -183,8 +181,7 @@ interpret_AS_clause(const char *languageName, const List *as,
 {
        Assert(as != NIL);
 
-       if (strcmp(languageName, "C") == 0 ||
-               strcmp(languageName, "newC") == 0)
+       if (strcmp(languageName, "C") == 0)
        {
 
                /*
@@ -230,8 +227,8 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
 
        char            languageName[NAMEDATALEN];
        /*
-        * name of language of function, with case adjusted: "C", "newC",
-        * "internal", "newinternal", "sql", etc.
+        * name of language of function, with case adjusted: "C",
+        * "internal", "sql", etc.
         */
 
        bool            returnsSet;
@@ -255,9 +252,7 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
         * Apply appropriate security checks depending on language.
         */
        if (strcmp(languageName, "C") == 0 ||
-               strcmp(languageName, "newC") == 0 ||
-               strcmp(languageName, "internal") == 0 ||
-               strcmp(languageName, "newinternal") == 0)
+               strcmp(languageName, "internal") == 0)
        {
                if (!superuser())
                        elog(ERROR,
@@ -283,8 +278,8 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
                if (!HeapTupleIsValid(languageTuple))
                        elog(ERROR,
                                 "Unrecognized language specified in a CREATE FUNCTION: "
-                                "'%s'.\n\tRecognized languages are sql, C, newC, "
-                                "internal, newinternal, and created procedural languages.",
+                                "'%s'.\n\tRecognized languages are sql, C, "
+                                "internal, and created procedural languages.",
                                 languageName);
 
                /* Check that this language is a PL */
index fdcd0e7e744846e0664b8117ffb0d94c3f5ce4a0..cb11b47a37c4c35f8a8d5c7bdff195c262cfd268 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.55 2000/11/16 22:30:18 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.56 2000/11/20 20:36:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -344,8 +344,7 @@ RemoveFunction(char *functionName,          /* function name to be removed */
        if (!HeapTupleIsValid(tup))
                func_error("RemoveFunction", functionName, nargs, argList, NULL);
 
-       if (((Form_pg_proc) GETSTRUCT(tup))->prolang == INTERNALlanguageId ||
-               ((Form_pg_proc) GETSTRUCT(tup))->prolang == NEWINTERNALlanguageId)
+       if (((Form_pg_proc) GETSTRUCT(tup))->prolang == INTERNALlanguageId)
        {
                /* "Helpful" notice when removing a builtin function ... */
                elog(NOTICE, "Removing built-in function \"%s\"", functionName);
index 22dfcac05244d438de49ed929f4c4bb2cd0be29b..cc31a0eb48bce75b705bb89662ca200f30cb8498 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.80 2000/11/16 22:30:18 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.81 2000/11/20 20:36:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -169,10 +169,7 @@ CreateTrigger(CreateTrigStmt *stmt)
        funclang = ((Form_pg_proc) GETSTRUCT(tuple))->prolang;
        ReleaseSysCache(tuple);
 
-       if (funclang != ClanguageId &&
-               funclang != NEWClanguageId &&
-               funclang != INTERNALlanguageId &&
-               funclang != NEWINTERNALlanguageId)
+       if (funclang != ClanguageId && funclang != INTERNALlanguageId)
        {
                HeapTuple       langTup;
 
@@ -180,10 +177,10 @@ CreateTrigger(CreateTrigStmt *stmt)
                                                                 ObjectIdGetDatum(funclang),
                                                                 0, 0, 0);
                if (!HeapTupleIsValid(langTup))
-                       elog(ERROR, "CreateTrigger: cache lookup for PL %u failed",
+                       elog(ERROR, "CreateTrigger: cache lookup for language %u failed",
                                 funclang);
                if (((Form_pg_language) GETSTRUCT(langTup))->lanispl == false)
-                       elog(ERROR, "CreateTrigger: only builtin, C and PL functions are supported");
+                       elog(ERROR, "CreateTrigger: only internal, C and PL functions are supported");
                ReleaseSysCache(langTup);
        }
 
index 41a0bc3d712ee1a80a8a256d215e39e2487b58af..00f12e3e1f1cae4962125661dd2631f0295d6a1c 100644 (file)
@@ -9,7 +9,7 @@
 #
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/backend/utils/Attic/Gen_fmgrtab.sh,v 1.17 2000/07/13 16:07:06 petere Exp $
+#    $Header: /cvsroot/pgsql/src/backend/utils/Attic/Gen_fmgrtab.sh,v 1.18 2000/11/20 20:36:48 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -82,7 +82,7 @@ trap 'echo "Caught signal." ; cleanup ; exit 1' 1 2 15
 
 #
 # Generate the file containing raw pg_proc tuple data
-# (but only for "internal" and "newinternal" language procedures...).
+# (but only for "internal" language procedures...).
 #
 # Unlike genbki.sh, which can run through cpp last, we have to
 # deal with preprocessor statements first (before we sort the
@@ -99,7 +99,6 @@ sed   -e 's/^.*OID[^=]*=[^0-9]*//' \
        -e 's/[         ]*).*$//' | \
 $AWK '
 /^#/           { print; next; }
-$4 == "11"     { print; next; }
 $4 == "12"     { print; next; }' > $CPPTMPFILE
 
 if [ $? -ne 0 ]; then
@@ -182,10 +181,6 @@ FuNkYfMgRsTuFf
 # Generate fmgr's built-in-function table.
 #
 # Print out the function declarations, then the table that refers to them.
-# NB: the function declarations are bogus in the case of old-style functions,
-# although they should be correct for new-style.  Therefore we need to compile
-# this table definition as a separate C file that won't need to include any
-# "real" declarations for those functions!
 #
 cat > "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
 /*-------------------------------------------------------------------------
@@ -205,10 +200,6 @@ cat > "$$-$TABLEFILE" <<FuNkYfMgRtAbStUfF
  *     It has been GENERATED by $CMDNAME
  *     from $INFILE
  *
- *     We lie here to cc about the return type and arguments of old-style
- *     builtin functions; all ld cares about is the fact that it
- *     will need to resolve an external function reference.
- *
  *-------------------------------------------------------------------------
  */
 
@@ -237,13 +228,11 @@ FuNkYfMgRtAbStUfF
 # conditional expression instead.  Not all awks have conditional expressions.
 
 $AWK 'BEGIN {
-    Strict["t"] = "true"
-    Strict["f"] = "false"
-    OldStyle["11"] = "true"
-    OldStyle["12"] = "false"
+    Bool["t"] = "true"
+    Bool["f"] = "false"
 }
 { printf ("  { %d, \"%s\", %d, %s, %s, %s },\n"), \
-       $1, $(NF-1), $9, Strict[$8], OldStyle[$4], $(NF-1)
+       $1, $(NF-1), $9, Bool[$8], Bool[$10], $(NF-1)
 }' $RAWFILE >> "$$-$TABLEFILE"
 
 if [ $? -ne 0 ]; then
index e07445837a5b83f42e32be173cb743f468ba8919..24b2cbada95dfaa5ec66538f087b222654c89c11 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.47 2000/11/16 22:30:33 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.48 2000/11/20 20:36:49 tgl Exp $
  *
  * NOTES
  *       Eventually, the index information should go through here, too.
@@ -731,6 +731,27 @@ get_typalign(Oid typid)
 
 #endif
 
+char
+get_typstorage(Oid typid)
+{
+       HeapTuple       tp;
+
+       tp = SearchSysCache(TYPEOID,
+                                               ObjectIdGetDatum(typid),
+                                               0, 0, 0);
+       if (HeapTupleIsValid(tp))
+       {
+               Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
+               char    result;
+
+               result = typtup->typstorage;
+               ReleaseSysCache(tp);
+               return result;
+       }
+       else
+               return 'p';
+}
+
 /*
  * get_typdefault
  *
index 2dfddebd0a8731dc29191f35fcb77167d62b7955..ae8eb6785e58b58a3f338e8fc7e91fd5a6de1417 100644 (file)
@@ -8,20 +8,17 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.45 2000/11/16 22:30:34 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.46 2000/11/20 20:36:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
+#include "postgres.h"
+
 #include <sys/types.h>
 #include <sys/stat.h>
 
-#include "postgres.h"
-
-#include "catalog/pg_proc.h"
 #include "dynloader.h"
 #include "utils/dynamic_loader.h"
-#include "utils/builtins.h"
-#include "utils/syscache.h"
 
 
 /*
@@ -46,55 +43,16 @@ static DynamicFileList *file_tail = (DynamicFileList *) NULL;
 #define SAME_INODE(A,B) ((A).st_ino == (B).inode && (A).st_dev == (B).device)
 
 
+/*
+ * Load the specified dynamic-link library file, and look for a function
+ * named funcname in it.  If the function is not found, we raise an error
+ * if signalNotFound is true, else return (PGFunction) NULL.  Note that
+ * errors in loading the library will provoke elog regardless of
+ * signalNotFound. 
+ */
 PGFunction
-fmgr_dynamic(Oid functionId)
-{
-       HeapTuple       procedureTuple;
-       Form_pg_proc procedureStruct;
-       char       *proname,
-                          *prosrcstring,
-                          *probinstring;
-       Datum           prosrcattr,
-                               probinattr;
-       PGFunction      user_fn;
-       bool            isnull;
-
-       procedureTuple = SearchSysCache(PROCOID,
-                                                                       ObjectIdGetDatum(functionId),
-                                                                       0, 0, 0);
-       if (!HeapTupleIsValid(procedureTuple))
-               elog(ERROR, "fmgr_dynamic: function %u: cache lookup failed",
-                        functionId);
-       procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
-
-       proname = NameStr(procedureStruct->proname);
-
-       prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
-                                                                Anum_pg_proc_prosrc, &isnull);
-       if (isnull)
-               elog(ERROR, "fmgr: Could not extract prosrc for %u from pg_proc",
-                        functionId);
-       prosrcstring = DatumGetCString(DirectFunctionCall1(textout, prosrcattr));
-
-       probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
-                                                                Anum_pg_proc_probin, &isnull);
-       if (isnull)
-               elog(ERROR, "fmgr: Could not extract probin for %u from pg_proc",
-                        functionId);
-       probinstring = DatumGetCString(DirectFunctionCall1(textout, probinattr));
-
-       user_fn = load_external_function(probinstring, prosrcstring);
-
-       pfree(prosrcstring);
-       pfree(probinstring);
-
-       ReleaseSysCache(procedureTuple);
-
-       return user_fn;
-}
-
-PGFunction
-load_external_function(char *filename, char *funcname)
+load_external_function(char *filename, char *funcname,
+                                          bool signalNotFound)
 {
        DynamicFileList *file_scanner;
        PGFunction      retval;
@@ -164,7 +122,7 @@ load_external_function(char *filename, char *funcname)
 
        retval = pg_dlsym(file_scanner->handle, funcname);
 
-       if (retval == (PGFunction) NULL)
+       if (retval == (PGFunction) NULL && signalNotFound)
                elog(ERROR, "Can't find function %s in file %s", funcname, filename);
 
        return retval;
@@ -217,5 +175,5 @@ load_file(char *filename)
                }
        }
 
-       load_external_function(filename, (char *) NULL);
+       load_external_function(filename, (char *) NULL, false);
 }
index 5287615eea0fbcf491f6268dbbbf7dfbe9c2fe82..d4353a482460946b71f5a83f9532ec94aa244f21 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.47 2000/11/16 22:30:34 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.48 2000/11/20 20:36:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -20,6 +20,7 @@
 #include "executor/functions.h"
 #include "utils/builtins.h"
 #include "utils/fmgrtab.h"
+#include "utils/lsyscache.h"
 #include "utils/syscache.h"
 
 /*
@@ -42,7 +43,19 @@ typedef int32 ((*func_ptr) ());
 typedef char *((*func_ptr) ());
 #endif
 
+/*
+ * For an oldstyle function, fn_extra points to a record like this:
+ */
+typedef struct
+{
+       func_ptr        func;                   /* Address of the oldstyle function */
+       bool            arg_toastable[FUNC_MAX_ARGS]; /* is n'th arg of a toastable
+                                                                                          * datatype? */
+} Oldstyle_fnextra;
 
+
+static void fmgr_info_C_lang(FmgrInfo *finfo, HeapTuple procedureTuple);
+static void fmgr_info_other_lang(FmgrInfo *finfo, HeapTuple procedureTuple);
 static Datum fmgr_oldstyle(PG_FUNCTION_ARGS);
 static Datum fmgr_untrusted(PG_FUNCTION_ARGS);
 
@@ -104,9 +117,6 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
        const FmgrBuiltin *fbp;
        HeapTuple       procedureTuple;
        Form_pg_proc procedureStruct;
-       HeapTuple       languageTuple;
-       Form_pg_language languageStruct;
-       Oid                     language;
        char       *prosrc;
 
        finfo->fn_oid = functionId;
@@ -120,16 +130,8 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
                 */
                finfo->fn_nargs = fbp->nargs;
                finfo->fn_strict = fbp->strict;
-               finfo->fn_retset = false; /* assume no builtins return sets! */
-               if (fbp->oldstyle)
-               {
-                       finfo->fn_addr = fmgr_oldstyle;
-                       finfo->fn_extra = (void *) fbp->func;
-               }
-               else
-               {
-                       finfo->fn_addr = fbp->func;
-               }
+               finfo->fn_retset = fbp->retset;
+               finfo->fn_addr = fbp->func;
                return;
        }
 
@@ -148,16 +150,15 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
 
        if (!procedureStruct->proistrusted)
        {
+               /* This isn't really supported anymore... */
                finfo->fn_addr = fmgr_untrusted;
                ReleaseSysCache(procedureTuple);
                return;
        }
 
-       language = procedureStruct->prolang;
-       switch (language)
+       switch (procedureStruct->prolang)
        {
                case INTERNALlanguageId:
-               case NEWINTERNALlanguageId:
                        /*
                         * For an ordinary builtin function, we should never get
                         * here because the isbuiltin() search above will have
@@ -175,24 +176,12 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
                                elog(ERROR, "fmgr_info: function %s not in internal table",
                                         prosrc);
                        pfree(prosrc);
-                       if (fbp->oldstyle)
-                       {
-                               finfo->fn_addr = fmgr_oldstyle;
-                               finfo->fn_extra = (void *) fbp->func;
-                       }
-                       else
-                       {
-                               finfo->fn_addr = fbp->func;
-                       }
+                       /* Should we check that nargs, strict, retset match the table? */
+                       finfo->fn_addr = fbp->func;
                        break;
 
                case ClanguageId:
-                       finfo->fn_addr = fmgr_oldstyle;
-                       finfo->fn_extra = (void *) fmgr_dynamic(functionId);
-                       break;
-
-               case NEWClanguageId:
-                       finfo->fn_addr = fmgr_dynamic(functionId);
+                       fmgr_info_C_lang(finfo, procedureTuple);
                        break;
 
                case SQLlanguageId:
@@ -200,92 +189,234 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
                        break;
 
                default:
-                       /*
-                        * Might be a created procedural language; try to look it up.
-                        */
-                       languageTuple = SearchSysCache(LANGOID,
-                                                                                  ObjectIdGetDatum(language),
-                                                                                  0, 0, 0);
-                       if (!HeapTupleIsValid(languageTuple))
-                               elog(ERROR, "fmgr_info: cache lookup for language %u failed",
-                                        language);
-                       languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
-                       if (languageStruct->lanispl)
-                       {
-                               FmgrInfo        plfinfo;
-
-                               fmgr_info(languageStruct->lanplcallfoid, &plfinfo);
-                               finfo->fn_addr = plfinfo.fn_addr;
-                               /*
-                                * If lookup of the PL handler function produced nonnull
-                                * fn_extra, complain --- it must be an oldstyle function!
-                                * We no longer support oldstyle PL handlers.
-                                */
-                               if (plfinfo.fn_extra != NULL)
-                                       elog(ERROR, "fmgr_info: language %u has old-style handler",
-                                                language);
-                       }
-                       else
+                       fmgr_info_other_lang(finfo, procedureTuple);
+                       break;
+       }
+
+       ReleaseSysCache(procedureTuple);
+}
+
+/*
+ * Special fmgr_info processing for C-language functions
+ */
+static void
+fmgr_info_C_lang(FmgrInfo *finfo, HeapTuple procedureTuple)
+{
+       Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
+       Datum           prosrcattr,
+                               probinattr;
+       char       *prosrcstring,
+                          *probinstring;
+       PGFunction      user_fn;
+       Pg_finfo_record *inforec;
+       Oldstyle_fnextra *fnextra;
+       bool            isnull;
+       int                     i;
+
+       /* Get prosrc and probin strings (link symbol and library filename) */
+       prosrcattr = SysCacheGetAttr(PROCOID, procedureTuple,
+                                                                Anum_pg_proc_prosrc, &isnull);
+       if (isnull)
+               elog(ERROR, "fmgr: Could not extract prosrc for %u from pg_proc",
+                        finfo->fn_oid);
+       prosrcstring = DatumGetCString(DirectFunctionCall1(textout, prosrcattr));
+
+       probinattr = SysCacheGetAttr(PROCOID, procedureTuple,
+                                                                Anum_pg_proc_probin, &isnull);
+       if (isnull)
+               elog(ERROR, "fmgr: Could not extract probin for %u from pg_proc",
+                        finfo->fn_oid);
+       probinstring = DatumGetCString(DirectFunctionCall1(textout, probinattr));
+
+       /* Look up the function itself */
+       user_fn = load_external_function(probinstring, prosrcstring, true);
+
+       /* Get the function information record (real or default) */
+       inforec = fetch_finfo_record(probinstring, prosrcstring);
+
+       switch (inforec->api_version)
+       {
+               case 0:
+                       /* Old style: need to use a handler */
+                       finfo->fn_addr = fmgr_oldstyle;
+                       /* OK to use palloc here because fn_mcxt is CurrentMemoryContext */
+                       fnextra = (Oldstyle_fnextra *) palloc(sizeof(Oldstyle_fnextra));
+                       finfo->fn_extra = (void *) fnextra;
+                       MemSet(fnextra, 0, sizeof(Oldstyle_fnextra));
+                       fnextra->func = (func_ptr) user_fn;
+                       for (i = 0; i < procedureStruct->pronargs; i++)
                        {
-                               elog(ERROR, "fmgr_info: function %u: unsupported language %u",
-                                        functionId, language);
+                               fnextra->arg_toastable[i] =
+                                       TypeIsToastable(procedureStruct->proargtypes[i]);
                        }
-                       ReleaseSysCache(languageTuple);
+                       break;
+               case 1:
+                       /* New style: call directly */
+                       finfo->fn_addr = user_fn;
+                       break;
+               default:
+                       /* Shouldn't get here if fetch_finfo_record did its job */
+                       elog(ERROR, "Unknown function API version %d",
+                                inforec->api_version);
                        break;
        }
 
-       ReleaseSysCache(procedureTuple);
+       pfree(prosrcstring);
+       pfree(probinstring);
 }
 
+/*
+ * Special fmgr_info processing for other-language functions
+ */
+static void
+fmgr_info_other_lang(FmgrInfo *finfo, HeapTuple procedureTuple)
+{
+       Form_pg_proc procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);
+       Oid                     language = procedureStruct->prolang;
+       HeapTuple       languageTuple;
+       Form_pg_language languageStruct;
+
+       languageTuple = SearchSysCache(LANGOID,
+                                                                  ObjectIdGetDatum(language),
+                                                                  0, 0, 0);
+       if (!HeapTupleIsValid(languageTuple))
+               elog(ERROR, "fmgr_info: cache lookup for language %u failed",
+                        language);
+       languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
+       if (languageStruct->lanispl)
+       {
+               FmgrInfo        plfinfo;
+
+               fmgr_info(languageStruct->lanplcallfoid, &plfinfo);
+               finfo->fn_addr = plfinfo.fn_addr;
+               /*
+                * If lookup of the PL handler function produced nonnull
+                * fn_extra, complain --- it must be an oldstyle function!
+                * We no longer support oldstyle PL handlers.
+                */
+               if (plfinfo.fn_extra != NULL)
+                       elog(ERROR, "fmgr_info: language %u has old-style handler",
+                                language);
+       }
+       else
+       {
+               elog(ERROR, "fmgr_info: function %u: unsupported language %u",
+                        finfo->fn_oid, language);
+       }
+       ReleaseSysCache(languageTuple);
+}
 
 /*
- * Specialized lookup routine for pg_proc.c: given the alleged name of
- * an internal function, return the OID of the function's language.
- * If the name is not known, return InvalidOid.
+ * Fetch and validate the information record for the given external function.
+ *
+ * If no info function exists for the given name, it is not an error.
+ * Instead we return a default info record for a version-0 function.
+ * We want to raise an error here only if the info function returns
+ * something bogus.
+ *
+ * This function is broken out of fmgr_info_C_lang() so that ProcedureCreate()
+ * can validate the information record for a function not yet entered into
+ * pg_proc.
+ */
+Pg_finfo_record *
+fetch_finfo_record(char *filename, char *funcname)
+{
+       char       *infofuncname;
+       PGFInfoFunction infofunc;
+       Pg_finfo_record *inforec;
+       static Pg_finfo_record default_inforec = { 0 };
+
+       /* Compute name of info func */
+       infofuncname = (char *) palloc(strlen(funcname) + 10);
+       sprintf(infofuncname, "pg_finfo_%s", funcname);
+
+       /* Try to look up the info function */
+       infofunc = (PGFInfoFunction) load_external_function(filename,
+                                                                                                               infofuncname,
+                                                                                                               false);
+       if (infofunc == (PGFInfoFunction) NULL)
+       {
+               /* Not found --- assume version 0 */
+               pfree(infofuncname);
+               return &default_inforec;
+       }
+
+       /* Found, so call it */
+       inforec = (*infofunc)();
+
+       /* Validate result as best we can */
+       if (inforec == NULL)
+               elog(ERROR, "Null result from %s", infofuncname);
+       switch (inforec->api_version)
+       {
+               case 0:
+               case 1:
+                       /* OK, no additional fields to validate */
+                       break;
+               default:
+                       elog(ERROR, "Unknown version %d reported by %s",
+                                inforec->api_version, infofuncname);
+                       break;
+       }
+
+       pfree(infofuncname);
+       return inforec;
+}
+
+
+/*
+ * Specialized lookup routine for ProcedureCreate(): given the alleged name
+ * of an internal function, return the OID of the function.
+ * If the name is not recognized, return InvalidOid.
  */
 Oid
-fmgr_internal_language(const char *proname)
+fmgr_internal_function(const char *proname)
 {
        const FmgrBuiltin *fbp = fmgr_lookupByName(proname);
 
        if (fbp == NULL)
                return InvalidOid;
-       return fbp->oldstyle ? INTERNALlanguageId : NEWINTERNALlanguageId;
+       return fbp->foid;
 }
 
 
 /*
- * Handler for old-style internal and "C" language functions
- *
- * We expect fmgr_info to have placed the old-style function's address
- * in fn_extra of *flinfo.  This is a bit of a hack since fn_extra is really
- * void * which might be a different size than a pointer to function, but
- * it will work on any machine that our old-style call interface works on...
+ * Handler for old-style "C" language functions
  */
 static Datum
 fmgr_oldstyle(PG_FUNCTION_ARGS)
 {
-       char       *returnValue = NULL;
+       Oldstyle_fnextra *fnextra;
        int                     n_arguments = fcinfo->nargs;
        int                     i;
        bool            isnull;
        func_ptr        user_fn;
+       char       *returnValue;
 
        if (fcinfo->flinfo == NULL || fcinfo->flinfo->fn_extra == NULL)
-               elog(ERROR, "Internal error: fmgr_oldstyle received NULL function pointer");
+               elog(ERROR, "Internal error: fmgr_oldstyle received NULL pointer");
+       fnextra = (Oldstyle_fnextra *) fcinfo->flinfo->fn_extra;
 
        /*
         * Result is NULL if any argument is NULL, but we still call the function
         * (peculiar, but that's the way it worked before, and after all this is
         * a backwards-compatibility wrapper).  Note, however, that we'll never
         * get here with NULL arguments if the function is marked strict.
+        *
+        * We also need to detoast any TOAST-ed inputs, since it's unlikely that
+        * an old-style function knows about TOASTing.
         */
        isnull = false;
        for (i = 0; i < n_arguments; i++)
-               isnull |= PG_ARGISNULL(i);
+       {
+               if (PG_ARGISNULL(i))
+                       isnull = true;
+               else if (fnextra->arg_toastable[i])
+                       fcinfo->arg[i] = PointerGetDatum(PG_DETOAST_DATUM(fcinfo->arg[i]));
+       }
        fcinfo->isnull = isnull;
 
-       user_fn = (func_ptr) fcinfo->flinfo->fn_extra;
+       user_fn = fnextra->func;
 
        switch (n_arguments)
        {
@@ -411,6 +542,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
                         */
                        elog(ERROR, "fmgr_oldstyle: function %u: too many arguments (%d > %d)",
                                 fcinfo->flinfo->fn_oid, n_arguments, 16);
+                       returnValue = NULL;     /* keep compiler quiet */
                        break;
        }
 
index 3fc0a1b02fa4e06302b2e34d56fda8f537371385..02c27aaf90bb1bad2d3d843384ff43f2c2c586b7 100644 (file)
@@ -8,7 +8,7 @@
 #
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createlang.sh,v 1.19 2000/11/13 23:37:53 momjian Exp $
+#    $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createlang.sh,v 1.20 2000/11/20 20:36:50 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -259,7 +259,7 @@ fi
 # ----------
 # Create the call handler and the language
 # ----------
-$PSQL "CREATE FUNCTION $handler () RETURNS OPAQUE AS '$PGLIB/${object}$DLSUFFIX' LANGUAGE 'newC'"
+$PSQL "CREATE FUNCTION $handler () RETURNS OPAQUE AS '$PGLIB/${object}$DLSUFFIX' LANGUAGE 'C'"
 if [ $? -ne 0 ]; then
        echo "$CMDNAME: language installation failed" 1>&2
        exit 1
index e3f4c6ff8992f5fe5ff09ddbf4e90c615c0e4b9d..558feef575ba0f005f55ecdc182942b568be354d 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: catversion.h,v 1.61 2000/11/20 05:18:40 vadim Exp $
+ * $Id: catversion.h,v 1.62 2000/11/20 20:36:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                             yyyymmddN */
-#define CATALOG_VERSION_NO     200011191
+#define CATALOG_VERSION_NO     200011201
 
 #endif
index 0d597d8c4daf82f28d6c0a733522434340e14dac..423f2e9470043e333e08d2421f034d102ee7f273 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_language.h,v 1.11 2000/05/28 17:56:16 tgl Exp $
+ * $Id: pg_language.h,v 1.12 2000/11/20 20:36:50 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -63,18 +63,12 @@ typedef FormData_pg_language *Form_pg_language;
  * ----------------
  */
 
-DATA(insert OID = 11 ( internal f f 0 "n/a" ));
-DESCR("old-style built-in functions");
-#define INTERNALlanguageId 11
-DATA(insert OID = 12 ( newinternal f f 0 "n/a" ));
-DESCR("new-style built-in functions");
-#define NEWINTERNALlanguageId 12
+DATA(insert OID = 12 ( internal f f 0 "n/a" ));
+DESCR("Built-in functions");
+#define INTERNALlanguageId 12
 DATA(insert OID = 13 ( "C" f f 0 "/bin/cc" ));
-DESCR("Dynamically-loaded old-style C functions");
+DESCR("Dynamically-loaded C functions");
 #define ClanguageId 13
-DATA(insert OID = 10 ( "newC" f f 0 "/bin/cc" ));
-DESCR("Dynamically-loaded new-style C functions");
-#define NEWClanguageId 10
 DATA(insert OID = 14 ( "sql" f f 0 "postgres"));
 DESCR("SQL-language functions");
 #define SQLlanguageId 14
index 28634262bcc13a964342cb652a23bcfb1058dd93..08faf956299220e7f8f9bbc5f733bde600defe9b 100644 (file)
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: fmgr.h,v 1.10 2000/08/24 03:29:11 tgl Exp $
+ * $Id: fmgr.h,v 1.11 2000/11/20 20:36:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -208,6 +208,43 @@ extern struct varlena * pg_detoast_datum_copy(struct varlena * datum);
 #define PG_RETURN_VARCHAR_P(x) PG_RETURN_POINTER(x)
 
 
+/*-------------------------------------------------------------------------
+ *             Support for detecting call convention of dynamically-loaded functions
+ *
+ * Dynamically loaded functions may use either the version-1 ("new style")
+ * or version-0 ("old style") calling convention.  Version 1 is the call
+ * convention defined in this header file; version 0 is the old "plain C"
+ * convention.  A version-1 function must be accompanied by the macro call
+ *
+ *             PG_FUNCTION_INFO_V1(function_name);
+ *
+ * Note that internal functions do not need this decoration since they are
+ * assumed to be version-1.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+typedef struct
+{
+       int                     api_version;    /* specifies call convention version number */
+       /* More fields may be added later, for version numbers > 1. */
+} Pg_finfo_record;
+
+/* Expected signature of an info function */
+typedef Pg_finfo_record * (*PGFInfoFunction) (void);
+
+/* Macro to build an info function associated with the given function name */
+
+#define PG_FUNCTION_INFO_V1(funcname) \
+extern Pg_finfo_record * CppConcat(pg_finfo_,funcname) (void); \
+Pg_finfo_record * \
+CppConcat(pg_finfo_,funcname) (void) \
+{ \
+       static Pg_finfo_record my_finfo = { 1 }; \
+       return &my_finfo; \
+}
+
+
 /*-------------------------------------------------------------------------
  *             Support routines and macros for callers of fmgr-compatible functions
  *-------------------------------------------------------------------------
@@ -297,13 +334,14 @@ extern Datum OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2,
 /*
  * Routines in fmgr.c
  */
-extern Oid fmgr_internal_language(const char *proname);
+extern Pg_finfo_record *fetch_finfo_record(char *filename, char *funcname);
+extern Oid fmgr_internal_function(const char *proname);
 
 /*
  * Routines in dfmgr.c
  */
-extern PGFunction fmgr_dynamic(Oid functionId);
-extern PGFunction load_external_function(char *filename, char *funcname);
+extern PGFunction load_external_function(char *filename, char *funcname,
+                                                                                bool signalNotFound);
 extern void load_file(char *filename);
 
 
index e6cfe519650c41689d569e3dcfdf34f3530ef0dd..9d46aeae694f0d66d390fe5b3423e55a24c8c3e4 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: fmgrtab.h,v 1.13 2000/05/28 17:56:20 tgl Exp $
+ * $Id: fmgrtab.h,v 1.14 2000/11/20 20:36:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,7 +28,7 @@ typedef struct
        const char *funcName;           /* C name of the function */
     short       nargs;                 /* 0..FUNC_MAX_ARGS, or -1 if variable count */
     bool        strict;                        /* T if function is "strict" */
-       bool            oldstyle;               /* T if function uses old fmgr interface */
+       bool            retset;                 /* T if function returns a set */
     PGFunction  func;                  /* pointer to compiled function */
 } FmgrBuiltin;
 
index f8547baa884664b84bf093b7f3525d9b66871ae4..903e09aaf9cfc6a22cbb18b0a334fbe8c7432336 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: lsyscache.h,v 1.27 2000/11/16 22:30:49 tgl Exp $
+ * $Id: lsyscache.h,v 1.28 2000/11/20 20:36:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -39,6 +39,9 @@ extern char *get_rel_name(Oid relid);
 extern int16 get_typlen(Oid typid);
 extern bool get_typbyval(Oid typid);
 extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval);
+extern char get_typstorage(Oid typid);
 extern Datum get_typdefault(Oid typid);
 
+#define TypeIsToastable(typid)  (get_typstorage(typid) != 'p')
+
 #endif  /* LSYSCACHE_H */
index 81a4cd75d4b968922eaf5ddec2f53bc109e90d66..0b2d7d4e4256ea2cc1a3f2f9ab6377ba922e64b5 100644 (file)
@@ -33,7 +33,7 @@
  *       ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.15 2000/11/16 22:30:49 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.16 2000/11/20 20:36:51 tgl Exp $
  *
  **********************************************************************/
 
@@ -258,6 +258,7 @@ plperl_init_safe_interp(void)
  *                               call this function for execution of
  *                               perl procedures.
  **********************************************************************/
+PG_FUNCTION_INFO_V1(plperl_call_handler);
 
 /* keep non-static */
 Datum
index 31788b0706106bce7c5ada6edce8616acedc7e7f..d9e208ee98b987aa544e09d3ba8aea3cd7e6f559 100644 (file)
@@ -3,7 +3,7 @@
  *                       procedural language
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.5 2000/05/29 01:59:14 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.6 2000/11/20 20:36:52 tgl Exp $
  *
  *       This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -66,6 +66,8 @@ static PLpgSQL_function *compiled_functions = NULL;
  * call this function for execution of PL/pgSQL procedures.
  * ----------
  */
+PG_FUNCTION_INFO_V1(plpgsql_call_handler);
+
 Datum
 plpgsql_call_handler(PG_FUNCTION_ARGS)
 {
index 8658cac3065322f0fbd0013a851fc2755f06fd78..94a67ef043303dfbac4c1df6622ed1583c026e58 100644 (file)
@@ -31,7 +31,7 @@
  *       ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.29 2000/11/16 22:30:52 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.30 2000/11/20 20:36:52 tgl Exp $
  *
  **********************************************************************/
 
@@ -325,6 +325,7 @@ pltcl_init_load_unknown(void)
  *                               call this function for execution of
  *                               PL/Tcl procedures.
  **********************************************************************/
+PG_FUNCTION_INFO_V1(pltcl_call_handler);
 
 /* keep non-static */
 Datum
@@ -371,6 +372,12 @@ pltcl_call_handler(PG_FUNCTION_ARGS)
        return retval;
 }
 
+
+/*
+ * Alternate handler for unsafe functions
+ */
+PG_FUNCTION_INFO_V1(pltclu_call_handler);
+
 /* keep non-static */
 Datum
 pltclu_call_handler(PG_FUNCTION_ARGS)
index 0f82a3bea40a17596d7d19454cbdc3e77eaa782c..6d91674cd56d1c0e9ddf03c5cb1bb10d26432793 100644 (file)
@@ -15,30 +15,30 @@ CREATE FUNCTION widget_out(opaque)
 CREATE FUNCTION check_primary_key ()
        RETURNS opaque
        AS '@abs_builddir@/../../../contrib/spi/refint@DLSUFFIX@'
-       LANGUAGE 'newC';
+       LANGUAGE 'C';
 
 CREATE FUNCTION check_foreign_key ()
        RETURNS opaque
        AS '@abs_builddir@/../../../contrib/spi/refint@DLSUFFIX@'
-       LANGUAGE 'newC';
+       LANGUAGE 'C';
 
 CREATE FUNCTION autoinc ()
        RETURNS opaque
        AS '@abs_builddir@/../../../contrib/spi/autoinc@DLSUFFIX@'
-       LANGUAGE 'newC';
+       LANGUAGE 'C';
 
 CREATE FUNCTION funny_dup17 ()
         RETURNS opaque
         AS '@abs_builddir@/regress@DLSUFFIX@'
-        LANGUAGE 'newC';
+        LANGUAGE 'C';
 
 CREATE FUNCTION ttdummy ()
         RETURNS opaque
         AS '@abs_builddir@/regress@DLSUFFIX@'
-        LANGUAGE 'newC';
+        LANGUAGE 'C';
 
 CREATE FUNCTION set_ttdummy (int4)
         RETURNS int4
         AS '@abs_builddir@/regress@DLSUFFIX@'
-        LANGUAGE 'newC';
+        LANGUAGE 'C';
 
index af6695764ac96dc12aba3658e103a42b8672df34..b1c0eab138608bf17232ed586a0b40a3a458a721 100644 (file)
@@ -30,28 +30,33 @@ CREATE FUNCTION user_relns()
 CREATE FUNCTION pt_in_widget(point, widget)
    RETURNS bool
    AS '@abs_builddir@/regress@DLSUFFIX@'
-   LANGUAGE 'newC';
+   LANGUAGE 'C';
 
 CREATE FUNCTION overpaid(emp)
    RETURNS bool
    AS '@abs_builddir@/regress@DLSUFFIX@'
-   LANGUAGE 'newC';
+   LANGUAGE 'C';
 
 CREATE FUNCTION boxarea(box)
    RETURNS float8
    AS '@abs_builddir@/regress@DLSUFFIX@'
-   LANGUAGE 'newC';
+   LANGUAGE 'C';
 
 CREATE FUNCTION interpt_pp(path, path)
    RETURNS point
    AS '@abs_builddir@/regress@DLSUFFIX@'
-   LANGUAGE 'newC';
+   LANGUAGE 'C';
 
 CREATE FUNCTION reverse_name(name)
    RETURNS name
    AS '@abs_builddir@/regress@DLSUFFIX@'
    LANGUAGE 'c';
 
+CREATE FUNCTION oldstyle_length(int4, text)
+   RETURNS int4
+   AS '@abs_builddir@/regress@DLSUFFIX@'
+   LANGUAGE 'c';
+
 --
 -- Function dynamic loading
 --
index 9e9ebdb75bc57a4ce51eba3cf1bc60e2dacd6fb2..dbb8df847090ba1185eba934c84fe9fd610546c4 100644 (file)
@@ -215,6 +215,19 @@ SELECT user_relns() AS user_relns
 --SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer'))) AS equip_name;
 
 
+--
+-- check that old-style C functions work properly with TOASTed values
+--
+create table oldstyle_test(i int4, t text);
+insert into oldstyle_test values(null,null);
+insert into oldstyle_test values(0,'12');
+insert into oldstyle_test values(1000,'12');
+insert into oldstyle_test values(0, repeat('x', 50000));
+
+select i, length(t), octet_length(t), oldstyle_length(i,t) from oldstyle_test;
+
+drop table oldstyle_test;
+
 --
 -- functional joins
 --
index d3815a9aadde7ff392c2ce68a98e6f6c91ca9eb6..d075a61eb8a4df8f9485250acbd431a4e87fee34 100644 (file)
@@ -13,24 +13,24 @@ CREATE FUNCTION widget_out(opaque)
 CREATE FUNCTION check_primary_key ()
        RETURNS opaque
        AS '@abs_builddir@/../../../contrib/spi/refint@DLSUFFIX@'
-       LANGUAGE 'newC';
+       LANGUAGE 'C';
 CREATE FUNCTION check_foreign_key ()
        RETURNS opaque
        AS '@abs_builddir@/../../../contrib/spi/refint@DLSUFFIX@'
-       LANGUAGE 'newC';
+       LANGUAGE 'C';
 CREATE FUNCTION autoinc ()
        RETURNS opaque
        AS '@abs_builddir@/../../../contrib/spi/autoinc@DLSUFFIX@'
-       LANGUAGE 'newC';
+       LANGUAGE 'C';
 CREATE FUNCTION funny_dup17 ()
         RETURNS opaque
         AS '@abs_builddir@/regress@DLSUFFIX@'
-        LANGUAGE 'newC';
+        LANGUAGE 'C';
 CREATE FUNCTION ttdummy ()
         RETURNS opaque
         AS '@abs_builddir@/regress@DLSUFFIX@'
-        LANGUAGE 'newC';
+        LANGUAGE 'C';
 CREATE FUNCTION set_ttdummy (int4)
         RETURNS int4
         AS '@abs_builddir@/regress@DLSUFFIX@'
-        LANGUAGE 'newC';
+        LANGUAGE 'C';
index def359de90fd9b144d56b51a8ac99075836a260e..a5f39a00bb00f2f7ae6174dc2977305181008cea 100644 (file)
@@ -23,23 +23,27 @@ CREATE FUNCTION user_relns()
 CREATE FUNCTION pt_in_widget(point, widget)
    RETURNS bool
    AS '@abs_builddir@/regress@DLSUFFIX@'
-   LANGUAGE 'newC';
+   LANGUAGE 'C';
 CREATE FUNCTION overpaid(emp)
    RETURNS bool
    AS '@abs_builddir@/regress@DLSUFFIX@'
-   LANGUAGE 'newC';
+   LANGUAGE 'C';
 CREATE FUNCTION boxarea(box)
    RETURNS float8
    AS '@abs_builddir@/regress@DLSUFFIX@'
-   LANGUAGE 'newC';
+   LANGUAGE 'C';
 CREATE FUNCTION interpt_pp(path, path)
    RETURNS point
    AS '@abs_builddir@/regress@DLSUFFIX@'
-   LANGUAGE 'newC';
+   LANGUAGE 'C';
 CREATE FUNCTION reverse_name(name)
    RETURNS name
    AS '@abs_builddir@/regress@DLSUFFIX@'
    LANGUAGE 'c';
+CREATE FUNCTION oldstyle_length(int4, text)
+   RETURNS int4
+   AS '@abs_builddir@/regress@DLSUFFIX@'
+   LANGUAGE 'c';
 --
 -- Function dynamic loading
 --
index 144ad33f24220b59914f69a5d67ee91b8d2e4083..768dba5c3c7789af4804bbdfffe292f9d16fa9bc 100644 (file)
@@ -657,6 +657,24 @@ SELECT user_relns() AS user_relns
 
 --SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer'))) AS equip_name;
 --
+-- check that old-style C functions work properly with TOASTed values
+--
+create table oldstyle_test(i int4, t text);
+insert into oldstyle_test values(null,null);
+insert into oldstyle_test values(0,'12');
+insert into oldstyle_test values(1000,'12');
+insert into oldstyle_test values(0, repeat('x', 50000));
+select i, length(t), octet_length(t), oldstyle_length(i,t) from oldstyle_test;
+  i   | length | octet_length | oldstyle_length 
+------+--------+--------------+-----------------
+      |        |              |                
+    0 |      2 |            2 |               2
+ 1000 |      2 |            2 |            1002
+    0 |  50000 |          581 |           50000
+(4 rows)
+
+drop table oldstyle_test;
+--
 -- functional joins
 --
 --
index 479527fc3fc862948764d5fa71e46fda60d3326c..bd65c4233da2922223d689393f47101c40b97954 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.44 2000/08/24 23:34:11 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.45 2000/11/20 20:36:53 tgl Exp $
  */
 
 #include <float.h>                             /* faked on sunos */
@@ -25,10 +25,13 @@ extern void regress_lseg_construct(LSEG *lseg, Point *pt1, Point *pt2);
 extern Datum overpaid(PG_FUNCTION_ARGS);
 extern Datum boxarea(PG_FUNCTION_ARGS);
 extern char *reverse_name(char *string);
+extern int oldstyle_length(int n, text *t);
 
 /*
 ** Distance from a point to a path
 */
+PG_FUNCTION_INFO_V1(regress_dist_ptpath);
+
 Datum
 regress_dist_ptpath(PG_FUNCTION_ARGS)
 {
@@ -69,6 +72,8 @@ regress_dist_ptpath(PG_FUNCTION_ARGS)
 
 /* this essentially does a cartesian product of the lsegs in the
    two paths, and finds the min distance between any two lsegs */
+PG_FUNCTION_INFO_V1(regress_path_dist);
+
 Datum
 regress_path_dist(PG_FUNCTION_ARGS)
 {
@@ -129,6 +134,8 @@ POLYGON    *poly;
 }
 
 /* return the point where two paths intersect, or NULL if no intersection. */
+PG_FUNCTION_INFO_V1(interpt_pp);
+
 Datum
 interpt_pp(PG_FUNCTION_ARGS)
 {
@@ -182,6 +189,8 @@ Point          *pt2;
        lseg->m = point_sl(pt1, pt2);
 }
 
+PG_FUNCTION_INFO_V1(overpaid);
+
 Datum
 overpaid(PG_FUNCTION_ARGS)
 {
@@ -254,6 +263,8 @@ WIDGET         *widget;
        return result;
 }
 
+PG_FUNCTION_INFO_V1(pt_in_widget);
+
 Datum
 pt_in_widget(PG_FUNCTION_ARGS)
 {
@@ -265,6 +276,8 @@ pt_in_widget(PG_FUNCTION_ARGS)
 
 #define ABS(X) ((X) >= 0 ? (X) : -(X))
 
+PG_FUNCTION_INFO_V1(boxarea);
+
 Datum
 boxarea(PG_FUNCTION_ARGS)
 {
@@ -278,8 +291,7 @@ boxarea(PG_FUNCTION_ARGS)
 }
 
 char *
-reverse_name(string)
-char      *string;
+reverse_name(char *string)
 {
        int                     i;
        int                     len;
@@ -301,6 +313,20 @@ char          *string;
        return new_string;
 }
 
+/* This rather silly function is just to test that oldstyle functions
+ * work correctly on toast-able inputs.
+ */
+int
+oldstyle_length(int n, text *t)
+{
+       int             len = 0;
+
+       if (t)
+               len = VARSIZE(t) - VARHDRSZ;
+
+       return n + len;
+}
+
 #include "executor/spi.h"              /* this is what you need to work with SPI */
 #include "commands/trigger.h"  /* -"- and triggers */
 
@@ -312,6 +338,8 @@ static bool fd17b_recursion = true;
 static bool fd17a_recursion = true;
 extern Datum funny_dup17(PG_FUNCTION_ARGS);
 
+PG_FUNCTION_INFO_V1(funny_dup17);
+
 Datum
 funny_dup17(PG_FUNCTION_ARGS)
 {
@@ -428,6 +456,8 @@ extern Datum set_ttdummy(PG_FUNCTION_ARGS);
 static void *splan = NULL;
 static bool ttoff = false;
 
+PG_FUNCTION_INFO_V1(ttdummy);
+
 Datum
 ttdummy(PG_FUNCTION_ARGS)
 {
@@ -625,6 +655,8 @@ ttdummy(PG_FUNCTION_ARGS)
        return PointerGetDatum(rettuple);
 }
 
+PG_FUNCTION_INFO_V1(set_ttdummy);
+
 Datum
 set_ttdummy(PG_FUNCTION_ARGS)
 {
index 254c62100dc1829bcbb0c077bf4b8bec56f840a9..fc89483208e5bc5a2fdfe0f14d5c44fa51c7e7f1 100644 (file)
@@ -38,6 +38,7 @@ DROP FUNCTION interpt_pp(path,path);
 
 DROP FUNCTION reverse_name(name);
 
+DROP FUNCTION oldstyle_length(int4, text);
 
 --
 -- OPERATOR REMOVAL
index 0734e67a113d9b06c25ba5a325baeb9cec8013ff..20f609d5d2d88c7d84d05f990ad535bba827d90f 100644 (file)
@@ -30,6 +30,8 @@ Datum   c_overpaid(PG_FUNCTION_ARGS);
 
 /* By Value */
          
+PG_FUNCTION_INFO_V1(add_one);
+
 Datum
 add_one(PG_FUNCTION_ARGS)
 {
@@ -40,6 +42,8 @@ add_one(PG_FUNCTION_ARGS)
 
 /* By Reference, Fixed Length */
 
+PG_FUNCTION_INFO_V1(add_one_float8);
+
 Datum
 add_one_float8(PG_FUNCTION_ARGS)
 {
@@ -49,6 +53,8 @@ add_one_float8(PG_FUNCTION_ARGS)
     PG_RETURN_FLOAT8(arg + 1.0);
 }
 
+PG_FUNCTION_INFO_V1(makepoint);
+
 Datum
 makepoint(PG_FUNCTION_ARGS)
 {
@@ -64,6 +70,8 @@ makepoint(PG_FUNCTION_ARGS)
 
 /* By Reference, Variable Length */
 
+PG_FUNCTION_INFO_V1(copytext);
+
 Datum
 copytext(PG_FUNCTION_ARGS)
 {
@@ -82,6 +90,8 @@ copytext(PG_FUNCTION_ARGS)
     PG_RETURN_TEXT_P(new_t);
 }
 
+PG_FUNCTION_INFO_V1(concat_text);
+
 Datum
 concat_text(PG_FUNCTION_ARGS)
 {
@@ -99,6 +109,8 @@ concat_text(PG_FUNCTION_ARGS)
 
 /* Composite types */
 
+PG_FUNCTION_INFO_V1(c_overpaid);
+
 Datum
 c_overpaid(PG_FUNCTION_ARGS)
 {