mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 10:30:33 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			418 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			418 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| .\" This is -*-nroff-*-
 | |
| .\" XXX standard disclaimer belongs here....
 | |
| .\" $Header: /cvsroot/pgsql/doc/man/Attic/create_function.l,v 1.1.1.1 1996/08/18 22:14:21 scrappy Exp $
 | |
| .TH "CREATE FUNCTION" SQL 11/05/95 Postgres95 Postgres95
 | |
| .SH "NAME"
 | |
| create function \(em define a new function
 | |
| .SH "SYNOPSIS"
 | |
| .nf
 | |
| \fBcreate function\fP function_name \fB(\fP
 | |
| 	([type1 {, type-n}])
 | |
| 	\fBreturns\fP type-r
 | |
| 	\fBas\fP {'/full/path/to/objectfile' | 'sql-queries'}
 | |
| 	\fBlanguage\fP {'c' \ 'sql' \ 'internal'}
 | |
| .fi
 | |
| .SH "DESCRIPTION"
 | |
| With this command, a Postgres user can register a function with Postgres.
 | |
| Subsequently, this user is treated as the owner of the function.
 | |
| .PP
 | |
| When defining a function with arguments, the input data types,
 | |
| .IR type-1 ,
 | |
| .IR type-2 ,
 | |
| \&...,
 | |
| .IR type-n ,
 | |
| and the return data type,
 | |
| .IR type-r
 | |
| must be specified, along with the language, which may be
 | |
| .IR "\*(lqc\*(rq"
 | |
| or
 | |
| .IR "\*(lqsql\*(rq" .
 | |
| or
 | |
| .IR "\*(lqinternal\*(rq" .
 | |
| (The
 | |
| .IR "arg is"
 | |
| clause may be left out if the function has no arguments, or
 | |
| alternatively the argument list may be left empty.)
 | |
| The input types may be base or complex types, or 
 | |
| .IR opaque .
 | |
| .IR Opaque
 | |
| indicates that the function accepts arguments of an
 | |
| invalid type such as (char *).
 | |
| The output type may be specified as a base type, complex type, 
 | |
| .IR "setof <type>",
 | |
| or 
 | |
| .IR opaque .
 | |
| The 
 | |
| .IR setof
 | |
| modifier indicates that the function will return a set of items,
 | |
| rather than a single item.  
 | |
| The
 | |
| .IR as
 | |
| clause of the command is treated differently for C and SQL
 | |
| functions, as explained below.
 | |
| .SH "C FUNCTIONS"
 | |
| Functions written in C can be defined to Postgres, which will dynamically
 | |
| load them into its address space.  The loading happens either using
 | |
| .IR load (l)
 | |
| or automatically the first time the function is necessary for
 | |
| execution. Repeated execution of a function will cause negligible
 | |
| additional overhead, as the function will remain in a main memory
 | |
| cache.
 | |
| .PP
 | |
| Internal functions are functions written in C which have been statically
 | |
| linked into the postgres backend process.  The 
 | |
| .BR as
 | |
| clause must still be specified when defining an internal function but
 | |
| the contents are ignored.
 | |
| .SH "Writing C Functions"
 | |
| The body of a C function following 
 | |
| .BR as
 | |
| should be the
 | |
| .BR "FULL PATH"
 | |
| of the object code (.o file) for the function, bracketed by quotation
 | |
| marks.  (Postgres will not compile a function automatically \(em it must
 | |
| be compiled before it is used in a
 | |
| .BR "define function"
 | |
| command.)
 | |
| .PP
 | |
| C functions with base type arguments can be written in a
 | |
| straightforward fashion.  The C equivalents of built-in Postgres types
 | |
| are accessible in a C file if 
 | |
| .nf
 | |
| \&.../src/backend/utils/builtins.h
 | |
| .fi
 | |
| is included as a header file.  This can be achieved by having
 | |
| .nf
 | |
| \&#include <utils/builtins.h>
 | |
| .fi
 | |
| at the top of the C source file and by compiling all C files with the
 | |
| following include options:
 | |
| .nf
 | |
| -I.../src/backend
 | |
| -I.../src/backend/port/<portname>
 | |
| -I.../src/backend/obj
 | |
| .fi
 | |
| before any \*(lq.c\*(rq programs in the 
 | |
| .IR cc
 | |
| command line, e.g.:
 | |
| .nf
 | |
| cc -I.../src/backend \e
 | |
|    -I.../src/backend/port/<portname> \e
 | |
|    -I.../src/backend/obj \e
 | |
|    -c progname.c
 | |
| .fi
 | |
| where \*(lq...\*(rq is the path to the installed Postgres source tree and
 | |
| \*(lq<portname>\*(rq is the name of the port for which the source tree
 | |
| has been built.
 | |
| .PP
 | |
| The convention for passing arguments to and from the user's C
 | |
| functions is to use pass-by-value for data types that are 32 bits (4
 | |
| bytes) or smaller, and pass-by-reference for data types that require
 | |
| more than 32 bits.
 | |
| .if t \{
 | |
| The following table gives the C type required for parameters in the C
 | |
| functions that will be loaded into Postgres.  The \*(lqDefined In\*(rq
 | |
| column gives the actual header file (in the
 | |
| .nf
 | |
| \&.../src/backend
 | |
| .fi
 | |
| directory) that the equivalent C type is defined.  However, if you
 | |
| include \*(lqutils/builtins.h\*(rq, these files will automatically be
 | |
| included.
 | |
| .SH "Equivalent C Types for Built-In Postgres Types"
 | |
| .PP
 | |
| .TS
 | |
| center;
 | |
| l l l
 | |
| l l l.
 | |
| \fBBuilt-In Type\fP	\fBC Type\fP	\fBDefined In\fP
 | |
| _
 | |
| abstime 	AbsoluteTime	utils/nabstime.h
 | |
| bool	bool	include/c.h
 | |
| box	(BOX *) 	utils/geo-decls.h
 | |
| bytea	(bytea *)	include/postgres.h
 | |
| char	char	N/A
 | |
| char16	Char16 or (char16 *)	include/postgres.h
 | |
| cid	CID	include/postgres.h
 | |
| int2	int2	include/postgres.h
 | |
| int28	(int28 *)	include/postgres.h
 | |
| int4	int4	include/postgres.h
 | |
| float4	float32 or (float4 *)	include/c.h or include/postgres.h
 | |
| float8	float64 or (float8 *)	include/c.h or include/postgres.h
 | |
| lseg	(LSEG *)	include/geo-decls.h
 | |
| name	(Name)	include/postgres.h
 | |
| oid	oid	include/postgres.h
 | |
| oid8	(oid8 *)	include/postgres.h
 | |
| path	(PATH *)	utils/geo-decls.h
 | |
| point	(POINT *)	utils/geo-decls.h
 | |
| regproc 	regproc or REGPROC	include/postgres.h
 | |
| reltime 	RelativeTime 	utils/nabstime.h
 | |
| text	(text *)	include/postgres.h
 | |
| tid	ItemPointer	storage/itemptr.h
 | |
| tinterval	TimeInterval	utils/nabstime.h
 | |
| uint2	uint16	include/c.h
 | |
| uint4	uint32	include/c.h
 | |
| xid	(XID *) 	include/postgres.h
 | |
| .TE
 | |
| \}
 | |
| .PP
 | |
| Complex arguments to C functions are passed into the C function as a
 | |
| special C type, TUPLE, defined in
 | |
| .nf
 | |
| \&.../src/libpq/libpq-fe.h.
 | |
| .fi
 | |
| Given a variable 
 | |
| .IR t
 | |
| of this type, the C function may extract attributes from the function
 | |
| using the function call:
 | |
| .nf
 | |
| GetAttributeByName(t, "fieldname", &isnull)
 | |
| .fi
 | |
| where 
 | |
| .IR isnull
 | |
| is a pointer to a 
 | |
| .IR bool ,
 | |
| which the function sets to
 | |
| .IR true
 | |
| if the field is null.  The result of this function should be cast
 | |
| appropriately as shown in the examples below.
 | |
| .SH "Compiling Dynamically-Loaded C Functions"
 | |
| .PP
 | |
| Different operating systems require different procedures for compiling
 | |
| C source files so that Postgres can load them dynamically.  This section
 | |
| discusses the required compiler and loader options on each system.
 | |
| .PP
 | |
| Under Linux ELF, object files can be generated by specifing the compiler
 | |
| flag -fpic.
 | |
| .PP
 | |
| Under Ultrix, all object files that Postgres is expected to load
 | |
| dynamically must be compiled using
 | |
| .IR /bin/cc
 | |
| with the \*(lq-G 0\*(rq option turned on.  The object file name in the
 | |
| .IR as
 | |
| clause should end in \*(lq.o\*(rq.
 | |
| .PP
 | |
| Under HP-UX, DEC OSF/1, AIX and SunOS 4, all object files must be
 | |
| turned into
 | |
| .IR "shared libraries"
 | |
| using the operating system's native object file loader,
 | |
| .IR ld (1).
 | |
| .PP
 | |
| Under HP-UX, an object file must be compiled using the native HP-UX C
 | |
| compiler,
 | |
| .IR /bin/cc ,
 | |
| with both the \*(lq+z\*(rq and \*(lq+u\*(rq flags turned on.  The
 | |
| first flag turns the object file into \*(lqposition-independent
 | |
| code\*(rq (PIC); the second flag removes some alignment restrictions
 | |
| that the PA-RISC architecture normally enforces.  The object file must
 | |
| then be turned into a shared library using the HP-UX loader,
 | |
| .IR /bin/ld .
 | |
| The command lines to compile a C source file, \*(lqfoo.c\*(rq, look
 | |
| like:
 | |
| .nf
 | |
| cc <other flags> +z +u -c foo.c
 | |
| ld <other flags> -b -o foo.sl foo.o
 | |
| .fi
 | |
| The object file name in the
 | |
| .BR as
 | |
| clause should end in \*(lq.sl\*(rq.
 | |
| .PP
 | |
| An extra step is required under versions of HP-UX prior to 9.00.  If
 | |
| the Postgres header file
 | |
| .nf
 | |
| include/c.h
 | |
| .fi
 | |
| is not included in the source file, then the following line must also
 | |
| be added at the top of every source file:
 | |
| .nf
 | |
| #pragma HP_ALIGN HPUX_NATURAL_S500
 | |
| .fi
 | |
| However, this line must not appear in programs compiled under HP-UX
 | |
| 9.00 or later.
 | |
| .PP
 | |
| Under DEC OSF/1, an object file must be compiled and then turned
 | |
| into a shared library using the OSF/1 loader,
 | |
| .IR /bin/ld .
 | |
| In this case, the command lines look like:
 | |
| .nf
 | |
| cc <other flags> -c foo.c
 | |
| ld <other flags> -shared -expect_unresolved '*' -o foo.so foo.o
 | |
| .fi
 | |
| The object file name in the
 | |
| .BR as
 | |
| clause should end in \*(lq.so\*(rq.
 | |
| .PP
 | |
| Under SunOS 4, an object file must be compiled and then turned into a
 | |
| shared library using the SunOS 4 loader,
 | |
| .IR /bin/ld .
 | |
| The command lines look like:
 | |
| .nf
 | |
| cc <other flags> -PIC -c foo.c
 | |
| ld <other flags> -dc -dp -Bdynamic -o foo.so foo.o
 | |
| .fi
 | |
| The object file name in the
 | |
| .BR as
 | |
| clause should end in \*(lq.so\*(rq.
 | |
| .PP
 | |
| Under AIX, object files are compiled normally but building the shared
 | |
| library requires a couple of steps.  First, create the object file:
 | |
| .nf
 | |
| cc <other flags> -c foo.c
 | |
| .fi
 | |
| You must then create a symbol \*(lqexports\*(rq file for the object
 | |
| file:
 | |
| .nf
 | |
| mkldexport foo.o `pwd` > foo.exp
 | |
| .fi
 | |
| Finally, you can create the shared library:
 | |
| .nf
 | |
| ld <other flags> -H512 -T512 -o foo.so -e _nostart \e
 | |
|    -bI:.../lib/postgres.exp -bE:foo.exp foo.o \e
 | |
|    -lm -lc 2>/dev/null
 | |
| .fi
 | |
| You should look at the Postgres User's Manual for an explanation of this
 | |
| procedure.
 | |
| .SH "SQL FUNCTIONS"
 | |
| SQL functions execute an arbitrary list of SQL queries, returning
 | |
| the results of the last query in the list.  SQL functions in general
 | |
| return sets.  If their returntype is not specified as a
 | |
| .IR setof ,
 | |
| then an arbitrary element of the last query's result will be returned.
 | |
| .PP
 | |
| The body of a SQL function following
 | |
| .BR as
 | |
| should be a list of queries separated by whitespace characters and
 | |
| bracketed within quotation marks.  Note that quotation marks used in
 | |
| the queries must be escaped, by preceding them with two backslashes
 | |
| (i.e. \e\e").
 | |
| .PP
 | |
| Arguments to the SQL function may be referenced in the queries using
 | |
| a $n syntax: $1 refers to the first argument, $2 to the second, and so
 | |
| on.  If an argument is complex, then a \*(lqdot\*(rq notation may be
 | |
| used to access attributes of the argument (e.g. \*(lq$1.emp\*(rq), or
 | |
| to invoke functions via a nested-dot syntax.
 | |
| .SH "EXAMPLES: C Functions"
 | |
| The following command defines a C function, overpaid, of two basetype
 | |
| arguments.
 | |
| .nf
 | |
| create function overpaid (float8, int4) returns bool
 | |
| 	as '/usr/postgres/src/adt/overpaid.o'
 | |
| 	language 'c'
 | |
| .fi
 | |
| The C file "overpaid.c" might look something like:
 | |
| .nf
 | |
| #include <utils/builtins.h>
 | |
| 
 | |
| bool overpaid(salary, age)
 | |
|         float8 *salary;
 | |
|         int4    age;
 | |
| {
 | |
|         if (*salary > 200000.00)
 | |
|                 return(TRUE);
 | |
|         if ((age < 30) & (*salary > 100000.00))
 | |
|                 return(TRUE);
 | |
|         return(FALSE);
 | |
| }
 | |
| .fi
 | |
| The overpaid function can be used in a query, e.g:
 | |
| .nf
 | |
| select name from EMP where overpaid(salary, age)	
 | |
| .fi
 | |
| One can also write this as a function of a single argument of type
 | |
| EMP:
 | |
| .nf
 | |
| create function overpaid_2 (EMP)
 | |
| 	returns bool
 | |
| 	as '/usr/postgres/src/adt/overpaid_2.o'
 | |
| 	language 'c'	
 | |
| .fi
 | |
| The following query is now accepted:
 | |
| .nf
 | |
| select name from EMP where overpaid_2(EMP)
 | |
| .fi
 | |
| In this case, in the body of the overpaid_2 function, the fields in the EMP
 | |
| record must be extracted.  The C file "overpaid_2.c" might look
 | |
| something like:
 | |
| .nf
 | |
| #include <utils/builtins.h>
 | |
| #include <libpq-fe.h>
 | |
| 
 | |
| bool overpaid_2(t)
 | |
| TUPLE t;
 | |
| {
 | |
|     float8 *salary;
 | |
|     int4    age;
 | |
|     bool    salnull, agenull;
 | |
| 
 | |
|     salary = (float8 *)GetAttributeByName(t, "salary",
 | |
|                                           &salnull);
 | |
|     age = (int4)GetAttributeByName(t, "age", &agenull);
 | |
|     if (!salnull && *salary > 200000.00)
 | |
|         return(TRUE);
 | |
|     if (!agenull && (age<30) && (*salary > 100000.00))
 | |
|         return(TRUE);
 | |
|     return(FALSE)
 | |
| }
 | |
| .fi
 | |
| .SH "EXAMPLES: SQL Functions"
 | |
| To illustrate a simple SQL function, consider the following,
 | |
| which might be used to debit a bank account:
 | |
| .nf
 | |
| create function TP1 (int4, float8) returns int4
 | |
| 	as 'update BANK set balance = BANK.balance - $2
 | |
| 		where BANK.acctountno = $1
 | |
| 	    select(x = 1)'
 | |
| 	    language 'sql'
 | |
| .fi
 | |
| A user could execute this function to debit account 17 by $100.00 as
 | |
| follows:
 | |
| .nf
 | |
| select (x = TP1( 17,100.0))
 | |
| .fi
 | |
| The following more interesting examples take a single argument of type
 | |
| EMP, and retrieve multiple results:
 | |
| .nf
 | |
| select function hobbies (EMP) returns set of HOBBIES
 | |
| 	as 'select (HOBBIES.all) from HOBBIES
 | |
| 		where $1.name = HOBBIES.person'
 | |
| 	language 'sql'
 | |
| .SH "SEE ALSO"
 | |
| .PP
 | |
| information(1), load(l), drop function(l).
 | |
| .SH "NOTES"
 | |
| .SH "Name Space Conflicts"
 | |
| More than one function may be defined with the same name, as long as
 | |
| the arguments they take are different.  In other words, function names
 | |
| can be
 | |
| .IR overloaded .
 | |
| A function may also have the same name as an attribute.  In the case
 | |
| that there is an ambiguity between a function on a complex type and
 | |
| an attribute of the complex type, the attribute will always be used.
 | |
| .SH "RESTRICTIONS"
 | |
| The name of the C function must be a legal C function name, and the
 | |
| name of the function in C code must be exactly the same as the name
 | |
| used in
 | |
| .BR "create function" .
 | |
| There is a subtle implication of this restriction: while the
 | |
| dynamic loading routines in most operating systems are more than 
 | |
| happy to allow you to load any number of shared libraries that 
 | |
| contain conflicting (identically-named) function names, they may 
 | |
| in fact botch the load in interesting ways.  For example, if you
 | |
| define a dynamically-loaded function that happens to have the
 | |
| same name as a function built into Postgres, the DEC OSF/1 dynamic 
 | |
| loader causes Postgres to call the function within itself rather than 
 | |
| allowing Postgres to call your function.  Hence, if you want your
 | |
| function to be used on different architectures, we recommend that 
 | |
| you do not overload C function names.
 | |
| .PP
 | |
| There is a clever trick to get around the problem just described.
 | |
| Since there is no problem overloading SQL functions, you can 
 | |
| define a set of C functions with different names and then define 
 | |
| a set of identically-named SQL function wrappers that take the
 | |
| appropriate argument types and call the matching C function.
 | |
| .PP
 | |
| .IR opaque
 | |
| cannot be given as an argument to a SQL function.
 | |
| .SH "BUGS"
 | |
| C functions cannot return a set of values.
 |