Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
94bdc485
Commit
94bdc485
authored
May 17, 2002
by
Peter Eisentraut
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Extend syntax of CREATE FUNCTION to resemble SQL99.
parent
97f7ceaa
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
504 additions
and
271 deletions
+504
-271
doc/src/sgml/ref/create_function.sgml
doc/src/sgml/ref/create_function.sgml
+196
-152
doc/src/sgml/release.sgml
doc/src/sgml/release.sgml
+2
-1
src/backend/commands/functioncmds.c
src/backend/commands/functioncmds.c
+128
-23
src/backend/nodes/copyfuncs.c
src/backend/nodes/copyfuncs.c
+7
-8
src/backend/nodes/equalfuncs.c
src/backend/nodes/equalfuncs.c
+6
-8
src/backend/parser/gram.y
src/backend/parser/gram.y
+122
-20
src/backend/parser/keywords.c
src/backend/parser/keywords.c
+12
-1
src/backend/tcop/postgres.c
src/backend/tcop/postgres.c
+3
-3
src/backend/tcop/utility.c
src/backend/tcop/utility.c
+3
-3
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.c
+17
-43
src/include/commands/defrem.h
src/include/commands/defrem.h
+2
-2
src/include/nodes/nodes.h
src/include/nodes/nodes.h
+2
-2
src/include/nodes/parsenodes.h
src/include/nodes/parsenodes.h
+4
-5
No files found.
doc/src/sgml/ref/create_function.sgml
View file @
94bdc485
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.3
7 2002/04/23 02:07:15 tgl
Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.3
8 2002/05/17 18:32:52 petere
Exp $
-->
<refentry id="SQL-CREATEFUNCTION">
...
...
@@ -17,13 +17,13 @@ $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.37 2002/04/23
<synopsis>
CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">argtype</replaceable> [, ...] ] )
RETURNS <replaceable class="parameter">rettype</replaceable>
AS '<replaceable class="parameter">definition</replaceable>'
LANGUAGE <replaceable class="parameter">langname</replaceable>
[ WITH ( <replaceable class="parameter">attribute</replaceable> [, ...] ) ]
CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">argtype</replaceable> [, ...] ] )
RETURNS <replaceable class="parameter">rettype</replaceable>
AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
LANGUAGE <replaceable class="parameter">langname</replaceable>
{ LANGUAGE <replaceable class="parameter">langname</replaceable>
| IMMUTABLE | STABLE | VOLATILE
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
| IMPLICIT CAST
| AS '<replaceable class="parameter">definition</replaceable>'
|
AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
} ...
[ WITH ( <replaceable class="parameter">attribute</replaceable> [, ...] ) ]
</synopsis>
</refsynopsisdiv>
...
...
@@ -33,8 +33,13 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
<para>
<command>CREATE FUNCTION</command> defines a new function.
<command>CREATE OR REPLACE FUNCTION</command> will either create
a new function, or replace an existing definition.
<command>CREATE OR REPLACE FUNCTION</command> will either create a
new function, or replace an existing definition.
</para>
<para>
The user that creates the function becomes the owner of the function.
</para>
<variablelist>
<title>Parameters</title>
...
...
@@ -81,7 +86,7 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
<listitem>
<para>
The return data type. The
output
type may be specified as a
The return data type. The
return
type may be specified as a
base type, complex type, <literal>setof</literal> type,
<literal>opaque</literal>, or the same as the type of an
existing column.
...
...
@@ -95,6 +100,105 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">langname</replaceable></term>
<listitem>
<para>
The name of the language that the function is implemented in.
May be <literal>SQL</literal>, <literal>C</literal>,
<literal>internal</literal>, or the name of a user-defined
procedural language. (See also <xref linkend="app-createlang"
endterm="app-createlang-title">.) For backward compatibility,
the name may be enclosed by single quotes.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>IMMUTABLE</term>
<term>STABLE</term>
<term>VOLATILE</term>
<listitem>
<para>
These attributes inform the system whether it is safe to
replace multiple evaluations of the function with a single
evaluation, for run-time optimization. At most one choice
should be specified. If none of these appear,
<literal>VOLATILE</literal> is the default assumption.
</para>
<para>
<literal>IMMUTABLE</literal> indicates that the function always
returns the same result when given the same argument values; that
is, it does not do database lookups or otherwise use information not
directly present in its parameter list. If this option is given,
any call of the function with all-constant arguments can be
immediately replaced with the function value.
</para>
<para>
<literal>STABLE</literal> indicates that within a single table scan
the function will consistently
return the same result for the same argument values, but that its
result could change across SQL statements. This is the appropriate
selection for functions whose results depend on database lookups,
parameter variables (such as the current time zone), etc. Also note
that the <literal>CURRENT_TIMESTAMP</> family of functions qualify
as stable, since their values do not change within a transaction.
</para>
<para>
<literal>VOLATILE</literal> indicates that the function value can
change even within a single table scan, so no optimizations can be
made. Relatively few database functions are volatile in this sense;
some examples are <literal>random()</>, <literal>currval()</>,
<literal>timeofday()</>. Note that any function that has side-effects
must be classified volatile, even if its result is quite predictable,
to prevent calls from being optimized away; an example is
<literal>setval()</>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CALLED ON NULL INPUT</term>
<term>RETURNS NULL ON NULL INPUT</term>
<term>STRICT</term>
<listitem>
<para>
<literal>CALLED ON NULL INPUT</literal> (the default) indicates
that the function will be called normally when some of its
arguments are null. It is then the function author's
responsibility to check for NULLs if necessary and respond
appropriately.
</para>
<para>
<literal>RETURNS NULL ON NULL INPUT</literal> or
<literal>STRICT</literal> indicates that the function always
returns NULL whenever any of its arguments are NULL. If this
parameter is specified, the function is not executed when there
are NULL arguments; instead a NULL result is assumed
automatically.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>IMPLICIT CAST</literal</term>
<listitem>
<para>
Indicates that the function may be used for implicit type
conversions. See <xref linkend="sql-createfunction-cast-functions"
endterm="sql-createfunction-cast-functions-title"> for more detail.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">definition</replaceable></term>
...
...
@@ -125,116 +229,56 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">langname</replaceable></term>
<listitem>
<para>
May be <literal>SQL</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
<xref linkend="sql-createlanguage" endterm="sql-createlanguage-title">
for details. For backward compatibility, the name may be
enclosed by single quotes.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">attribute</replaceable></term>
<listitem>
<para>
An optional piece of information about the function, used for
optimization. See below for details.
</para>
</listitem>
</varlistentry>
The historical way to specify optional pieces of information
about the function. The following attributes may appear here:
<variablelist>
<varlistentry>
<term>isStrict</term>
<listitem>
<para>
Equivalent to <literal>STRICT</literal> or <literal>RETURNS NULL ON NULL INPUT</literal>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>isImmutable</term>
<term>isCachable</term>
<term>isStable</term>
<term>isVolatile</term>
<listitem>
<para>
Equivalent to <literal>IMMUTABLE</literal>,
<literal>STABLE</literal>, <literal>VOLATILE</literal>.
<literal>isCachable</literal> is an obsolete equivalent of
<literal>isImmutable</literal>; it's still accepted for
backwards-compatibility reasons.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>implicitCoercion</term>
<listitem>
<para>
Same as <literal>IMPLICIT CAST</literal>
</para>
</listitem>
</varlistentry>
</variablelist>
Attribute names are not case-sensitive.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
The user that creates the function becomes the owner of the function.
</para>
<para>
The following attributes may appear in the WITH clause:
<variablelist>
<varlistentry>
<term>isStrict</term>
<listitem>
<para>
<option>isStrict</option> indicates that the function always
returns NULL whenever any of its arguments are NULL. If this
attribute is specified, the function is not executed when there
are NULL arguments; instead a NULL result is assumed automatically.
When <option>isStrict</option> is not specified, the function will
be called for NULL inputs. It is then the function author's
responsibility to check for NULLs if necessary and respond
appropriately.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>isImmutable</term>
<term>isCachable</term>
<term>isStable</term>
<term>isVolatile</term>
<listitem>
<para>
These attributes inform the system whether it is safe to replace
multiple evaluations of the function with a single evaluation.
At most one choice should be specified. (If none of these appear,
<option>isVolatile</option> is the default assumption.)
<option>isImmutable</option> indicates that the function always
returns the same result when given the same argument values; that
is, it does not do database lookups or otherwise use information not
directly present in its parameter list. If this option is given,
any call of the function with all-constant arguments can be
immediately replaced with the function value.
<option>isCachable</option> is an
obsolete equivalent of <option>isImmutable</option>; it's still
accepted for backwards-compatibility reasons.
<option>isStable</option> indicates that within a single table scan
the function will consistently
return the same result for the same argument values, but that its
result could change across SQL statements. This is the appropriate
selection for functions whose results depend on database lookups,
parameter variables (such as the current timezone), etc. Also note
that the <literal>CURRENT_TIMESTAMP</> family of functions qualify
as stable, since their values do not change within a transaction.
<option>isVolatile</option> indicates that the function value can
change even within a single table scan, so no optimizations can be
made. Relatively few database functions are volatile in this sense;
some examples are <literal>random()</>, <literal>currval()</>,
<literal>timeofday()</>. Note that any function that has side-effects
must be classified volatile, even if its result is quite predictable,
to prevent calls from being optimized away; an example is
<literal>setval()</>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>implicitCoercion</term>
<listitem>
<para>
<option>implicitCoercion</option> indicates that the function
may be used for implicit type conversions.
See <xref linkend="coercion-functions"
endterm="coercion-functions-title"> for more detail.
</para>
</listitem>
</varlistentry>
</variablelist>
Attribute names are not case-sensitive.
</para>
</refsect1>
...
...
@@ -328,21 +372,18 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
</para>
</refsect1>
<refsect1 id="COERCION-FUNCTIONS">
<refsect1info>
<date>2002-04-11</date>
</refsect1info>
<title id="coercion-functions-title">
Type Coercion Functions
<refsect1 id="sql-createfunction-cast-function">
<title id="sql-createfunction-cast-functions-title">
Type Cast Functions
</title>
<para>
A function that has one
parameter and is named the same as its output
datatype (including the schema name) is considered to be a <firstterm>type
c
oercion
function</>: it can be invoked to convert a value of its input
datatype into a value
A function that has one
argument and is named the same as its return
data
type (including the schema name) is considered to be a <firstterm>type
c
asting
function</>: it can be invoked to convert a value of its input
data
type into a value
of its output datatype. For example,
<programlisting>
SELECT CAST(42 AS text);
SELECT CAST(42 AS text);
</programlisting>
converts the integer constant 42 to text by invoking a function
<literal>text(int4)</>, if such a function exists and returns type
...
...
@@ -350,31 +391,33 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
</para>
<para>
If a potential coercion function is marked <literal>implicitCoercion</>,
then it can be invoked in any context where the conversion it defines
is required. Coercion functions not so marked can be invoked only by
explicit <literal>CAST</>,
<replaceable>x</><literal>::</><replaceable>typename</>,
or <replaceable>typename</>(<replaceable>x</>) constructs.
For example, supposing that foo.f1 is a column of type text, then
If a potential cast function is marked <literal>IMPLICIT CAST</>,
then it can be invoked implicitly in any context where the
conversion it defines is required. Cast functions not so marked
can be invoked only by explicit <literal>CAST</>,
<replaceable>x</><literal>::</><replaceable>typename</>, or
<replaceable>typename</>(<replaceable>x</>) constructs. For
example, supposing that <literal>foo.f1</literal> is a column of
type <type>text</type>, then
<programlisting>
INSERT INTO foo(f1) VALUES(42);
INSERT INTO foo(f1) VALUES(42);
</programlisting>
will be allowed if <literal>text(int4)</> is marked
<literal>
implicitCoercion
</>, otherwise not.
<literal>
IMPLICIT CAST
</>, otherwise not.
</para>
<para>
It is wise to be conservative about marking coercion functions as
implicit coercions. An overabundance of implicit coercion paths
can cause <productname>PostgreSQL</productname> to choose surprising
interpretations of commands,
or to be unable to resolve commands at all because there are multiple
possible interpretations. A good rule of thumb is to make coercions
implicitly invokable only for information-preserving transformations
between types in the same general type category. For example, int2
to int4 coercion can reasonably be implicit, but be wary of marking
int4 to text or float8 to int4 as implicit coercions.
It is wise to be conservative about marking cast functions as
implicit casts. An overabundance of implicit casting paths can
cause <productname>PostgreSQL</productname> to choose surprising
interpretations of commands, or to be unable to resolve commands at
all because there are multiple possible interpretations. A good
rule of thumb is to make cast implicitly invokable only for
information-preserving transformations between types in the same
general type category. For example, <type>int2</type> to
<type>int4</type> casts can reasonably be implicit, but be wary of
marking <type>int4</type> to <type>text</type> or
<type>float8</type> to <type>int4</type> as implicit casts.
</para>
</refsect1>
...
...
@@ -403,7 +446,7 @@ SELECT one() AS answer;
user-created shared library named <filename>funcs.so</> (the extension
may vary across platforms). The shared library file is sought in the
server's dynamic library search path. This particular routine calculates
a check digit and returns
TRUE
if the check digit in the function
a check digit and returns
true
if the check digit in the function
parameters is correct. It is intended for use in a CHECK
constraint.
...
...
@@ -422,7 +465,7 @@ CREATE TABLE product (
</para>
<para>
Th
is
example creates a function that does type conversion from the
Th
e next
example creates a function that does type conversion from the
user-defined type complex to the built-in type point. The
function is implemented by a dynamically loaded object that was
compiled from C source (we illustrate the now-deprecated alternative
...
...
@@ -436,7 +479,7 @@ CREATE TABLE product (
<programlisting>
CREATE FUNCTION point(complex) RETURNS point
AS '/home/bernie/pgsql/lib/complex.so', 'complex_to_point'
LANGUAGE C
WITH (isStrict)
;
LANGUAGE C
STRICT
;
</programlisting>
The C declaration of the function could be:
...
...
@@ -466,7 +509,7 @@ Point * complex_to_point (Complex *z)
<para>
A <command>CREATE FUNCTION</command> command is defined in SQL99.
The <application>PostgreSQL</application> version is similar but
not compatible. The attributes are not portable, neither are the
not
fully
compatible. The attributes are not portable, neither are the
different available languages.
</para>
</refsect1>
...
...
@@ -476,10 +519,11 @@ Point * complex_to_point (Complex *z)
<title>See Also</title>
<para>
<xref linkend="sql-dropfunction">,
<xref linkend="sql-grant">,
<xref linkend="sql-load">,
<xref linkend="sql-revoke">,
<xref linkend="sql-dropfunction" endterm="sql-dropfunction-title">,
<xref linkend="sql-grant" endterm="sql-grant-title">,
<xref linkend="sql-load" endterm="sql-load-title">,
<xref linkend="sql-revoke" endterm="sql-revoke-title">,
<xref linkend="app-createlang">,
<citetitle>PostgreSQL Programmer's Guide</citetitle>
</para>
</refsect1>
...
...
doc/src/sgml/release.sgml
View file @
94bdc485
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.13
5 2002/05/17 01:19:16 tgl
Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.13
6 2002/05/17 18:32:52 petere
Exp $
-->
<appendix id="release">
...
...
@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters.
-->
<literallayout><![CDATA[
Syntax of CREATE FUNCTION has been extended to resemble SQL99
Effects of SET within a transaction block now roll back if transaction aborts
New SET LOCAL syntax sets a parameter for the life of the current transaction
Datestyle, timezone, client_encoding can be set in postgresql.conf
...
...
src/backend/commands/functioncmds.c
View file @
94bdc485
...
...
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.
3 2002/04/27 03:45:01 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.
4 2002/05/17 18:32:52 petere
Exp $
*
* DESCRIPTION
* These routines take the parse tree and pick out the
...
...
@@ -159,6 +159,104 @@ compute_parameter_types(List *argTypes, Oid languageOid,
return
parameterCount
;
}
/*
* Dissect the list of options assembled in gram.y into function
* attributes.
*/
static
void
compute_attributes_sql_style
(
const
List
*
options
,
List
**
as
,
char
**
language
,
char
*
volatility_p
,
bool
*
strict_p
,
bool
*
security_definer
,
bool
*
implicit_cast
)
{
const
List
*
option
;
DefElem
*
as_item
=
NULL
;
DefElem
*
language_item
=
NULL
;
DefElem
*
volatility_item
=
NULL
;
DefElem
*
strict_item
=
NULL
;
DefElem
*
security_item
=
NULL
;
DefElem
*
implicit_item
=
NULL
;
foreach
(
option
,
options
)
{
DefElem
*
defel
=
(
DefElem
*
)
lfirst
(
option
);
if
(
strcmp
(
defel
->
defname
,
"as"
)
==
0
)
{
if
(
as_item
)
elog
(
ERROR
,
"conflicting or redundant options"
);
as_item
=
defel
;
}
else
if
(
strcmp
(
defel
->
defname
,
"language"
)
==
0
)
{
if
(
language_item
)
elog
(
ERROR
,
"conflicting or redundant options"
);
language_item
=
defel
;
}
else
if
(
strcmp
(
defel
->
defname
,
"volatility"
)
==
0
)
{
if
(
volatility_item
)
elog
(
ERROR
,
"conflicting or redundant options"
);
volatility_item
=
defel
;
}
else
if
(
strcmp
(
defel
->
defname
,
"strict"
)
==
0
)
{
if
(
strict_item
)
elog
(
ERROR
,
"conflicting or redundant options"
);
strict_item
=
defel
;
}
else
if
(
strcmp
(
defel
->
defname
,
"security"
)
==
0
)
{
if
(
security_item
)
elog
(
ERROR
,
"conflicting or redundant options"
);
security_item
=
defel
;
}
else
if
(
strcmp
(
defel
->
defname
,
"implicit"
)
==
0
)
{
if
(
implicit_item
)
elog
(
ERROR
,
"conflicting or redundant options"
);
implicit_item
=
defel
;
}
else
elog
(
ERROR
,
"invalid CREATE FUNCTION option"
);
}
if
(
as_item
)
*
as
=
(
List
*
)
as_item
->
arg
;
else
elog
(
ERROR
,
"no function body specified"
);
if
(
language_item
)
*
language
=
strVal
(
language_item
->
arg
);
else
elog
(
ERROR
,
"no language specified"
);
if
(
volatility_item
)
{
if
(
strcmp
(
strVal
(
volatility_item
->
arg
),
"immutable"
)
==
0
)
*
volatility_p
=
PROVOLATILE_IMMUTABLE
;
else
if
(
strcmp
(
strVal
(
volatility_item
->
arg
),
"stable"
)
==
0
)
*
volatility_p
=
PROVOLATILE_STABLE
;
else
if
(
strcmp
(
strVal
(
volatility_item
->
arg
),
"volatile"
)
==
0
)
*
volatility_p
=
PROVOLATILE_VOLATILE
;
else
elog
(
ERROR
,
"invalid volatility"
);
}
if
(
strict_item
)
*
strict_p
=
intVal
(
strict_item
->
arg
);
if
(
security_item
)
*
security_definer
=
intVal
(
security_item
->
arg
);
if
(
implicit_item
)
*
implicit_cast
=
intVal
(
implicit_item
->
arg
);
}
/*-------------
* Interpret the parameters *parameters and return their contents as
* *byte_pct_p, etc.
...
...
@@ -183,23 +281,14 @@ compute_parameter_types(List *argTypes, Oid languageOid,
*------------
*/
static
void
compute_
full_attributes
(
List
*
parameters
,
int32
*
byte_pct_p
,
int32
*
perbyte_cpu_p
,
int32
*
percall_cpu_p
,
int32
*
outin_ratio_p
,
bool
*
isImplicit_p
,
bool
*
isStrict_p
,
char
*
volatility_p
)
compute_
attributes_with_style
(
List
*
parameters
,
int32
*
byte_pct_p
,
int32
*
perbyte_cpu_p
,
int32
*
percall_cpu_p
,
int32
*
outin_ratio_p
,
bool
*
isImplicit_p
,
bool
*
isStrict_p
,
char
*
volatility_p
)
{
List
*
pl
;
/* the defaults */
*
byte_pct_p
=
BYTE_PCT
;
*
perbyte_cpu_p
=
PERBYTE_CPU
;
*
percall_cpu_p
=
PERCALL_CPU
;
*
outin_ratio_p
=
OUTIN_RATIO
;
*
isImplicit_p
=
false
;
*
isStrict_p
=
false
;
*
volatility_p
=
PROVOLATILE_VOLATILE
;
foreach
(
pl
,
parameters
)
{
DefElem
*
param
=
(
DefElem
*
)
lfirst
(
pl
);
...
...
@@ -290,12 +379,13 @@ interpret_AS_clause(Oid languageOid, const char *languageName, const List *as,
* Execute a CREATE FUNCTION utility statement.
*/
void
CreateFunction
(
Procedure
Stmt
*
stmt
)
CreateFunction
(
CreateFunction
Stmt
*
stmt
)
{
char
*
probin_str
;
char
*
prosrc_str
;
Oid
prorettype
;
bool
returnsSet
;
char
*
language
;
char
languageName
[
NAMEDATALEN
];
Oid
languageOid
;
char
*
funcname
;
...
...
@@ -308,10 +398,12 @@ CreateFunction(ProcedureStmt *stmt)
percall_cpu
,
outin_ratio
;
bool
isImplicit
,
isStrict
;
isStrict
,
security
;
char
volatility
;
HeapTuple
languageTuple
;
Form_pg_language
languageStruct
;
List
*
as_clause
;
/* Convert list of names to a name and namespace */
namespaceId
=
QualifiedNameGetCreationNamespace
(
stmt
->
funcname
,
...
...
@@ -322,8 +414,21 @@ CreateFunction(ProcedureStmt *stmt)
if
(
aclresult
!=
ACLCHECK_OK
)
aclcheck_error
(
aclresult
,
get_namespace_name
(
namespaceId
));
/* defaults attributes */
byte_pct
=
BYTE_PCT
;
perbyte_cpu
=
PERBYTE_CPU
;
percall_cpu
=
PERCALL_CPU
;
outin_ratio
=
OUTIN_RATIO
;
isImplicit
=
false
;
isStrict
=
false
;
volatility
=
PROVOLATILE_VOLATILE
;
/* override attributes from explicit list */
compute_attributes_sql_style
(
stmt
->
options
,
&
as_clause
,
&
language
,
&
volatility
,
&
isStrict
,
&
security
,
&
isImplicit
);
/* Convert language name to canonical case */
case_translate_language_name
(
stmt
->
language
,
languageName
);
case_translate_language_name
(
language
,
languageName
);
/* Look up the language and validate permissions */
languageTuple
=
SearchSysCache
(
LANGNAME
,
...
...
@@ -363,12 +468,12 @@ CreateFunction(ProcedureStmt *stmt)
parameterCount
=
compute_parameter_types
(
stmt
->
argTypes
,
languageOid
,
parameterTypes
);
compute_
full_attributes
(
stmt
->
withClause
,
&
byte_pct
,
&
perbyte_cpu
,
&
percall_cpu
,
&
outin_ratio
,
&
isImplicit
,
&
isStrict
,
&
volatility
);
compute_
attributes_with_style
(
stmt
->
withClause
,
&
byte_pct
,
&
perbyte_cpu
,
&
percall_cpu
,
&
outin_ratio
,
&
isImplicit
,
&
isStrict
,
&
volatility
);
interpret_AS_clause
(
languageOid
,
languageName
,
stmt
->
as
,
interpret_AS_clause
(
languageOid
,
languageName
,
as_clause
,
&
prosrc_str
,
&
probin_str
);
/*
...
...
src/backend/nodes/copyfuncs.c
View file @
94bdc485
...
...
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.18
6 2002/05/17 01:19:17 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.18
7 2002/05/17 18:32:52 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -2098,18 +2098,17 @@ _copyIndexStmt(IndexStmt *from)
return
newnode
;
}
static
Procedure
Stmt
*
_copy
ProcedureStmt
(
Procedure
Stmt
*
from
)
static
CreateFunction
Stmt
*
_copy
CreateFunctionStmt
(
CreateFunction
Stmt
*
from
)
{
ProcedureStmt
*
newnode
=
makeNode
(
Procedure
Stmt
);
CreateFunctionStmt
*
newnode
=
makeNode
(
CreateFunction
Stmt
);
newnode
->
replace
=
from
->
replace
;
Node_Copy
(
from
,
newnode
,
funcname
);
Node_Copy
(
from
,
newnode
,
argTypes
);
Node_Copy
(
from
,
newnode
,
returnType
);
Node_Copy
(
from
,
newnode
,
options
);
Node_Copy
(
from
,
newnode
,
withClause
);
Node_Copy
(
from
,
newnode
,
as
);
newnode
->
language
=
pstrdup
(
from
->
language
);
return
newnode
;
}
...
...
@@ -2865,8 +2864,8 @@ copyObject(void *from)
case
T_IndexStmt
:
retval
=
_copyIndexStmt
(
from
);
break
;
case
T_
Procedure
Stmt
:
retval
=
_copy
Procedure
Stmt
(
from
);
case
T_
CreateFunction
Stmt
:
retval
=
_copy
CreateFunction
Stmt
(
from
);
break
;
case
T_RemoveAggrStmt
:
retval
=
_copyRemoveAggrStmt
(
from
);
...
...
src/backend/nodes/equalfuncs.c
View file @
94bdc485
...
...
@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.13
3 2002/05/17 01:19:17 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.13
4 2002/05/17 18:32:52 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -923,7 +923,7 @@ _equalIndexStmt(IndexStmt *a, IndexStmt *b)
}
static
bool
_equal
ProcedureStmt
(
ProcedureStmt
*
a
,
Procedure
Stmt
*
b
)
_equal
CreateFunctionStmt
(
CreateFunctionStmt
*
a
,
CreateFunction
Stmt
*
b
)
{
if
(
a
->
replace
!=
b
->
replace
)
return
false
;
...
...
@@ -933,11 +933,9 @@ _equalProcedureStmt(ProcedureStmt *a, ProcedureStmt *b)
return
false
;
if
(
!
equal
(
a
->
returnType
,
b
->
returnType
))
return
false
;
if
(
!
equal
(
a
->
withClause
,
b
->
withClause
))
return
false
;
if
(
!
equal
(
a
->
as
,
b
->
as
))
if
(
!
equal
(
a
->
options
,
b
->
options
))
return
false
;
if
(
!
equal
str
(
a
->
language
,
b
->
languag
e
))
if
(
!
equal
(
a
->
withClause
,
b
->
withClaus
e
))
return
false
;
return
true
;
...
...
@@ -2020,8 +2018,8 @@ equal(void *a, void *b)
case
T_IndexStmt
:
retval
=
_equalIndexStmt
(
a
,
b
);
break
;
case
T_
Procedure
Stmt
:
retval
=
_equal
Procedure
Stmt
(
a
,
b
);
case
T_
CreateFunction
Stmt
:
retval
=
_equal
CreateFunction
Stmt
(
a
,
b
);
break
;
case
T_RemoveAggrStmt
:
retval
=
_equalRemoveAggrStmt
(
a
,
b
);
...
...
src/backend/parser/gram.y
View file @
94bdc485
...
...
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.31
6 2002/05/17 01:19:17 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.31
7 2002/05/17 18:32:52 petere
Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
...
...
@@ -141,7 +141,7 @@ static void doNegateFloat(Value *v);
DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropAssertStmt, DropTrigStmt,
DropRuleStmt, DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt,
NotifyStmt, OptimizableStmt,
Procedure
Stmt, ReindexStmt,
NotifyStmt, OptimizableStmt,
CreateFunction
Stmt, ReindexStmt,
RemoveAggrStmt, RemoveFuncStmt, RemoveOperStmt,
RenameStmt, RevokeStmt, RuleActionStmt, RuleActionStmtOrEmpty,
RuleStmt, SelectStmt, TransactionStmt, TruncateStmt,
...
...
@@ -201,7 +201,7 @@ static void doNegateFloat(Value *v);
%type <list> stmtblock, stmtmulti,
OptTableElementList, OptInherit, definition, opt_distinct,
opt_with, func_args, func_args_list, func_as,
opt_with, func_args, func_args_list, func_as,
createfunc_opt_list
oper_argtypes, RuleActionList, RuleActionMulti,
opt_column_list, columnList, opt_name_list,
sort_clause, sortby_list, index_params, index_list, name_list,
...
...
@@ -214,6 +214,7 @@ static void doNegateFloat(Value *v);
%type <range> into_clause, OptTempTableName
%type <defelt> createfunc_opt_item
%type <typnam> func_arg, func_return, func_type, aggr_argtype
%type <boolean> opt_arg, TriggerForOpt, TriggerForType, OptTemp, OptWithOids
...
...
@@ -388,6 +389,9 @@ static void doNegateFloat(Value *v);
TEMP, TEMPLATE, TOAST, TRUNCATE, TRUSTED,
UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
%token <keyword> CALLED, DEFINER, EXTERNAL, IMMUTABLE, IMPLICIT, INPUT,
INVOKER, SECURITY, STABLE, STRICT, VOLATILE
/* The grammar thinks these are keywords, but they are not in the keywords.c
* list and so can never be entered directly. The filter in parser.c
* creates these tokens when required.
...
...
@@ -467,6 +471,7 @@ stmt : AlterDatabaseSetStmt
| CreateStmt
| CreateAsStmt
| CreateDomainStmt
| CreateFunctionStmt
| CreateSchemaStmt
| CreateGroupStmt
| CreateSeqStmt
...
...
@@ -494,7 +499,6 @@ stmt : AlterDatabaseSetStmt
| UnlistenStmt
| LockStmt
| NotifyStmt
| ProcedureStmt
| ReindexStmt
| RemoveAggrStmt
| RemoveOperStmt
...
...
@@ -2769,17 +2773,16 @@ RecipeStmt: EXECUTE RECIPE recipe_name
*
*****************************************************************************/
Procedure
Stmt: CREATE opt_or_replace FUNCTION func_name func_args
RETURNS func_return
AS func_as LANGUAGE ColId_or_Scon
st opt_with
CreateFunction
Stmt: CREATE opt_or_replace FUNCTION func_name func_args
RETURNS func_return
createfunc_opt_li
st opt_with
{
ProcedureStmt *n = makeNode(Procedure
Stmt);
CreateFunctionStmt *n = makeNode(CreateFunction
Stmt);
n->replace = $2;
n->funcname = $4;
n->argTypes = $5;
n->returnType = $7;
n->withClause = $12;
n->as = $9;
n->language = $11;
n->options = $8;
n->withClause = $9;
$$ = (Node *)n;
};
...
...
@@ -2787,10 +2790,6 @@ opt_or_replace: OR REPLACE { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; }
;
opt_with: WITH definition { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;
func_args: '(' func_args_list ')' { $$ = $2; }
| '(' ')' { $$ = NIL; }
;
...
...
@@ -2831,12 +2830,6 @@ opt_arg: IN
}
;
func_as: Sconst
{ $$ = makeList1(makeString($1)); }
| Sconst ',' Sconst
{ $$ = makeList2(makeString($1), makeString($3)); }
;
func_return: func_type
{
/* We can catch over-specified arguments here if we want to,
...
...
@@ -2864,6 +2857,104 @@ func_type: Typename
}
;
createfunc_opt_list: createfunc_opt_item
{ $$ = makeList1($1); }
| createfunc_opt_list createfunc_opt_item
{ $$ = lappend($1, $2); }
;
createfunc_opt_item: AS func_as
{
$$ = makeNode(DefElem);
$$->defname = "as";
$$->arg = (Node *)$2;
}
| LANGUAGE ColId_or_Sconst
{
$$ = makeNode(DefElem);
$$->defname = "language";
$$->arg = (Node *)makeString($2);
}
| IMMUTABLE
{
$$ = makeNode(DefElem);
$$->defname = "volatility";
$$->arg = (Node *)makeString("immutable");
}
| STABLE
{
$$ = makeNode(DefElem);
$$->defname = "volatility";
$$->arg = (Node *)makeString("stable");
}
| VOLATILE
{
$$ = makeNode(DefElem);
$$->defname = "volatility";
$$->arg = (Node *)makeString("volatile");
}
| CALLED ON NULL_P INPUT
{
$$ = makeNode(DefElem);
$$->defname = "strict";
$$->arg = (Node *)makeInteger(FALSE);
}
| RETURNS NULL_P ON NULL_P INPUT
{
$$ = makeNode(DefElem);
$$->defname = "strict";
$$->arg = (Node *)makeInteger(TRUE);
}
| STRICT
{
$$ = makeNode(DefElem);
$$->defname = "strict";
$$->arg = (Node *)makeInteger(TRUE);
}
| EXTERNAL SECURITY DEFINER
{
$$ = makeNode(DefElem);
$$->defname = "security";
$$->arg = (Node *)makeInteger(TRUE);
}
| EXTERNAL SECURITY INVOKER
{
$$ = makeNode(DefElem);
$$->defname = "security";
$$->arg = (Node *)makeInteger(FALSE);
}
| SECURITY DEFINER
{
$$ = makeNode(DefElem);
$$->defname = "security";
$$->arg = (Node *)makeInteger(TRUE);
}
| SECURITY INVOKER
{
$$ = makeNode(DefElem);
$$->defname = "security";
$$->arg = (Node *)makeInteger(FALSE);
}
| IMPLICIT CAST
{
$$ = makeNode(DefElem);
$$->defname = "implicit";
$$->arg = (Node *)makeInteger(TRUE);
}
;
func_as: Sconst
{ $$ = makeList1(makeString($1)); }
| Sconst ',' Sconst
{ $$ = makeList2(makeString($1), makeString($3)); }
;
opt_with: WITH definition { $$ = $2; }
| /*EMPTY*/ { $$ = NIL; }
;
/*****************************************************************************
*
* QUERY:
...
...
@@ -6137,6 +6228,7 @@ unreserved_keyword:
| BEGIN_TRANS
| BY
| CACHE
| CALLED
| CASCADE
| CHAIN
| CHARACTERISTICS
...
...
@@ -6156,6 +6248,7 @@ unreserved_keyword:
| DAY_P
| DECLARE
| DEFERRED
| DEFINER
| DELETE
| DELIMITERS
| DOMAIN_P
...
...
@@ -6168,6 +6261,7 @@ unreserved_keyword:
| EXCLUSIVE
| EXECUTE
| EXPLAIN
| EXTERNAL
| FETCH
| FORCE
| FORWARD
...
...
@@ -6176,13 +6270,17 @@ unreserved_keyword:
| HANDLER
| HOUR_P
| IMMEDIATE
| IMMUTABLE
| IMPLICIT
| INCREMENT
| INDEX
| INHERITS
| INOUT
| INPUT
| INSENSITIVE
| INSERT
| INSTEAD
| INVOKER
| ISOLATION
| KEY
| LANGUAGE
...
...
@@ -6238,18 +6336,21 @@ unreserved_keyword:
| SCHEMA
| SCROLL
| SECOND_P
| SECURITY
| SESSION
| SEQUENCE
| SERIALIZABLE
| SET
| SHARE
| SHOW
| STABLE
| START
| STATEMENT
| STATISTICS
| STDIN
| STDOUT
| STORAGE
| STRICT
| SYSID
| TEMP
| TEMPLATE
...
...
@@ -6272,6 +6373,7 @@ unreserved_keyword:
| VARYING
| VERSION
| VIEW
| VOLATILE
| WITH
| WITHOUT
| WORK
...
...
src/backend/parser/keywords.c
View file @
94bdc485
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.1
09 2002/05/03 00:32:16 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.1
10 2002/05/17 18:32:52 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -57,6 +57,7 @@ static const ScanKeyword ScanKeywords[] = {
{
"both"
,
BOTH
},
{
"by"
,
BY
},
{
"cache"
,
CACHE
},
{
"called"
,
CALLED
},
{
"cascade"
,
CASCADE
},
{
"case"
,
CASE
},
{
"cast"
,
CAST
},
...
...
@@ -95,6 +96,7 @@ static const ScanKeyword ScanKeywords[] = {
{
"default"
,
DEFAULT
},
{
"deferrable"
,
DEFERRABLE
},
{
"deferred"
,
DEFERRED
},
{
"definer"
,
DEFINER
},
{
"delete"
,
DELETE
},
{
"delimiters"
,
DELIMITERS
},
{
"desc"
,
DESC
},
...
...
@@ -114,6 +116,7 @@ static const ScanKeyword ScanKeywords[] = {
{
"execute"
,
EXECUTE
},
{
"exists"
,
EXISTS
},
{
"explain"
,
EXPLAIN
},
{
"external"
,
EXTERNAL
},
{
"extract"
,
EXTRACT
},
{
"false"
,
FALSE_P
},
{
"fetch"
,
FETCH
},
...
...
@@ -134,6 +137,8 @@ static const ScanKeyword ScanKeywords[] = {
{
"hour"
,
HOUR_P
},
{
"ilike"
,
ILIKE
},
{
"immediate"
,
IMMEDIATE
},
{
"immutable"
,
IMMUTABLE
},
{
"implicit"
,
IMPLICIT
},
{
"in"
,
IN
},
{
"increment"
,
INCREMENT
},
{
"index"
,
INDEX
},
...
...
@@ -141,6 +146,7 @@ static const ScanKeyword ScanKeywords[] = {
{
"initially"
,
INITIALLY
},
{
"inner"
,
INNER_P
},
{
"inout"
,
INOUT
},
{
"input"
,
INPUT
},
{
"insensitive"
,
INSENSITIVE
},
{
"insert"
,
INSERT
},
{
"instead"
,
INSTEAD
},
...
...
@@ -149,6 +155,7 @@ static const ScanKeyword ScanKeywords[] = {
{
"intersect"
,
INTERSECT
},
{
"interval"
,
INTERVAL
},
{
"into"
,
INTO
},
{
"invoker"
,
INVOKER
},
{
"is"
,
IS
},
{
"isnull"
,
ISNULL
},
{
"isolation"
,
ISOLATION
},
...
...
@@ -234,6 +241,7 @@ static const ScanKeyword ScanKeywords[] = {
{
"schema"
,
SCHEMA
},
{
"scroll"
,
SCROLL
},
{
"second"
,
SECOND_P
},
{
"security"
,
SECURITY
},
{
"select"
,
SELECT
},
{
"sequence"
,
SEQUENCE
},
{
"serializable"
,
SERIALIZABLE
},
...
...
@@ -245,12 +253,14 @@ static const ScanKeyword ScanKeywords[] = {
{
"show"
,
SHOW
},
{
"smallint"
,
SMALLINT
},
{
"some"
,
SOME
},
{
"stable"
,
STABLE
},
{
"start"
,
START
},
{
"statement"
,
STATEMENT
},
{
"statistics"
,
STATISTICS
},
{
"stdin"
,
STDIN
},
{
"stdout"
,
STDOUT
},
{
"storage"
,
STORAGE
},
{
"strict"
,
STRICT
},
{
"substring"
,
SUBSTRING
},
{
"sysid"
,
SYSID
},
{
"table"
,
TABLE
},
...
...
@@ -288,6 +298,7 @@ static const ScanKeyword ScanKeywords[] = {
{
"verbose"
,
VERBOSE
},
{
"version"
,
VERSION
},
{
"view"
,
VIEW
},
{
"volatile"
,
VOLATILE
},
{
"when"
,
WHEN
},
{
"where"
,
WHERE
},
{
"with"
,
WITH
},
...
...
src/backend/tcop/postgres.c
View file @
94bdc485
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.26
5 2002/05/17 01:19:18 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.26
6 2002/05/17 18:32:52 petere
Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
...
...
@@ -1688,7 +1688,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if
(
!
IsUnderPostmaster
)
{
puts
(
"
\n
POSTGRES backend interactive interface "
);
puts
(
"$Revision: 1.26
5 $ $Date: 2002/05/17 01:19:18
$
\n
"
);
puts
(
"$Revision: 1.26
6 $ $Date: 2002/05/17 18:32:52
$
\n
"
);
}
/*
...
...
@@ -2229,7 +2229,7 @@ CreateCommandTag(Node *parsetree)
tag
=
"CREATE"
;
break
;
case
T_
Procedure
Stmt
:
/* CREATE FUNCTION */
case
T_
CreateFunction
Stmt
:
/* CREATE FUNCTION */
tag
=
"CREATE"
;
break
;
...
...
src/backend/tcop/utility.c
View file @
94bdc485
...
...
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.15
4 2002/05/17 01:19:18 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.15
5 2002/05/17 18:32:52 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -574,8 +574,8 @@ ProcessUtility(Node *parsetree,
}
break
;
case
T_
Procedure
Stmt
:
/* CREATE FUNCTION */
CreateFunction
((
Procedure
Stmt
*
)
parsetree
);
case
T_
CreateFunction
Stmt
:
/* CREATE FUNCTION */
CreateFunction
((
CreateFunction
Stmt
*
)
parsetree
);
break
;
case
T_IndexStmt
:
/* CREATE INDEX */
...
...
src/bin/pg_dump/pg_dump.c
View file @
94bdc485
...
...
@@ -22,7 +22,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.26
0 2002/05/13 17:45:30 tgl
Exp $
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.26
1 2002/05/17 18:32:52 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -3152,18 +3152,14 @@ dumpProcLangs(Archive *fout, FuncInfo *finfo, int numFuncs)
(
*
deps
)[
depIdx
++
]
=
strdup
(
lanplcallfoid
);
appendPQExpBuffer
(
delqry
,
"DROP PROCEDURAL LANGUAGE "
);
formatStringLiteral
(
delqry
,
lanname
,
CONV_ALL
);
appendPQExpBuffer
(
delqry
,
";
\n
"
);
appendPQExpBuffer
(
delqry
,
"DROP PROCEDURAL LANGUAGE %s;
\n
"
,
fmtId
(
lanname
,
force_quotes
));
appendPQExpBuffer
(
defqry
,
"CREATE %sPROCEDURAL LANGUAGE "
,
appendPQExpBuffer
(
defqry
,
"CREATE %sPROCEDURAL LANGUAGE
%s
"
,
(
PQgetvalue
(
res
,
i
,
i_lanpltrusted
)[
0
]
==
't'
)
?
"TRUSTED "
:
""
);
formatStringLiteral
(
defqry
,
lanname
,
CONV_ALL
);
appendPQExpBuffer
(
defqry
,
" HANDLER %s
LANCOMPILER
"
,
"TRUSTED "
:
""
,
fmtId
(
lanname
,
force_quotes
)
);
appendPQExpBuffer
(
defqry
,
" HANDLER %s
;
\n
"
,
fmtId
(
finfo
[
fidx
].
proname
,
force_quotes
));
formatStringLiteral
(
defqry
,
lancompiler
,
CONV_ALL
);
appendPQExpBuffer
(
defqry
,
";
\n
"
);
(
*
deps
)[
depIdx
++
]
=
NULL
;
/* End of List */
...
...
@@ -3221,9 +3217,6 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
char
*
proimplicit
;
char
*
proisstrict
;
char
*
lanname
;
char
*
listSep
;
char
*
listSepComma
=
","
;
char
*
listSepNone
=
""
;
char
*
rettypename
;
if
(
finfo
->
dumped
)
...
...
@@ -3337,52 +3330,33 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
rettypename
=
getFormattedTypeName
(
finfo
->
prorettype
,
zeroAsOpaque
);
appendPQExpBuffer
(
q
,
"CREATE FUNCTION %s "
,
fn
->
data
);
appendPQExpBuffer
(
q
,
"RETURNS %s%s %s LANGUAGE "
,
appendPQExpBuffer
(
q
,
"RETURNS %s%s %s LANGUAGE
%s
"
,
(
proretset
[
0
]
==
't'
)
?
"SETOF "
:
""
,
rettypename
,
asPart
->
data
);
formatStringLiteral
(
q
,
lanname
,
CONV_ALL
);
asPart
->
data
,
fmtId
(
lanname
,
force_quotes
)
);
free
(
rettypename
);
if
(
provolatile
[
0
]
!=
PROVOLATILE_VOLATILE
||
proimplicit
[
0
]
==
't'
||
proisstrict
[
0
]
==
't'
)
/* OR in new attrs here */
if
(
provolatile
[
0
]
!=
PROVOLATILE_VOLATILE
)
{
appendPQExpBuffer
(
q
,
" WITH ("
);
listSep
=
listSepNone
;
if
(
provolatile
[
0
]
==
PROVOLATILE_IMMUTABLE
)
{
appendPQExpBuffer
(
q
,
"%s isImmutable"
,
listSep
);
listSep
=
listSepComma
;
}
appendPQExpBuffer
(
q
,
" IMMUTABLE"
);
else
if
(
provolatile
[
0
]
==
PROVOLATILE_STABLE
)
{
appendPQExpBuffer
(
q
,
"%s isStable"
,
listSep
);
listSep
=
listSepComma
;
}
appendPQExpBuffer
(
q
,
" STABLE"
);
else
if
(
provolatile
[
0
]
!=
PROVOLATILE_VOLATILE
)
{
write_msg
(
NULL
,
"Unexpected provolatile value for function %s
\n
"
,
finfo
->
proname
);
exit_nicely
();
}
}
if
(
proimplicit
[
0
]
==
't'
)
{
appendPQExpBuffer
(
q
,
"%s implicitCoercion"
,
listSep
);
listSep
=
listSepComma
;
}
if
(
proimplicit
[
0
]
==
't'
)
appendPQExpBuffer
(
q
,
" IMPLICIT CAST"
);
if
(
proisstrict
[
0
]
==
't'
)
{
appendPQExpBuffer
(
q
,
"%s isStrict"
,
listSep
);
listSep
=
listSepComma
;
}
appendPQExpBuffer
(
q
,
" )"
);
}
if
(
proisstrict
[
0
]
==
't'
)
appendPQExpBuffer
(
q
,
" STRICT"
);
appendPQExpBuffer
(
q
,
";
\n
"
);
...
...
src/include/commands/defrem.h
View file @
94bdc485
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: defrem.h,v 1.3
6 2002/04/16 23:08:12 tgl
Exp $
* $Id: defrem.h,v 1.3
7 2002/05/17 18:32:52 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -38,7 +38,7 @@ extern void ReindexDatabase(const char *databaseName, bool force, bool all);
* DefineFoo and RemoveFoo are now both in foocmds.c
*/
extern
void
CreateFunction
(
Procedure
Stmt
*
stmt
);
extern
void
CreateFunction
(
CreateFunction
Stmt
*
stmt
);
extern
void
RemoveFunction
(
List
*
functionName
,
List
*
argTypes
);
extern
void
DefineOperator
(
List
*
names
,
List
*
parameters
);
...
...
src/include/nodes/nodes.h
View file @
94bdc485
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: nodes.h,v 1.10
7 2002/05/12 23:43:04 tgl
Exp $
* $Id: nodes.h,v 1.10
8 2002/05/17 18:32:52 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -160,7 +160,7 @@ typedef enum NodeTag
T_CommentStmt
,
T_FetchStmt
,
T_IndexStmt
,
T_
Procedure
Stmt
,
T_
CreateFunction
Stmt
,
T_RemoveAggrStmt
,
T_RemoveFuncStmt
,
T_RemoveOperStmt
,
...
...
src/include/nodes/parsenodes.h
View file @
94bdc485
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parsenodes.h,v 1.17
7 2002/05/17 01:19:19 tgl
Exp $
* $Id: parsenodes.h,v 1.17
8 2002/05/17 18:32:52 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -1200,17 +1200,16 @@ typedef struct IndexStmt
* Create Function Statement
* ----------------------
*/
typedef
struct
Procedure
Stmt
typedef
struct
CreateFunction
Stmt
{
NodeTag
type
;
bool
replace
;
/* T => replace if already exists */
List
*
funcname
;
/* qualified name of function to create */
List
*
argTypes
;
/* list of argument types (TypeName nodes) */
TypeName
*
returnType
;
/* the return type */
List
*
options
;
/* a list of DefElem */
List
*
withClause
;
/* a list of DefElem */
List
*
as
;
/* definition of function body */
char
*
language
;
/* C, SQL, etc */
}
ProcedureStmt
;
}
CreateFunctionStmt
;
/* ----------------------
* Drop Aggregate Statement
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment