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
455dffbb
Commit
455dffbb
authored
Dec 04, 2008
by
Peter Eisentraut
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Default values for function arguments
Pavel Stehule, with some tweaks by Peter Eisentraut
parent
7b640b03
Changes
29
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
2848 additions
and
2166 deletions
+2848
-2166
doc/src/sgml/func.sgml
doc/src/sgml/func.sgml
+17
-3
doc/src/sgml/ref/create_function.sgml
doc/src/sgml/ref/create_function.sgml
+24
-2
doc/src/sgml/xfunc.sgml
doc/src/sgml/xfunc.sgml
+55
-1
src/backend/catalog/namespace.c
src/backend/catalog/namespace.c
+80
-7
src/backend/catalog/pg_aggregate.c
src/backend/catalog/pg_aggregate.c
+4
-3
src/backend/catalog/pg_proc.c
src/backend/catalog/pg_proc.c
+11
-2
src/backend/commands/functioncmds.c
src/backend/commands/functioncmds.c
+43
-5
src/backend/commands/proclang.c
src/backend/commands/proclang.c
+5
-3
src/backend/nodes/copyfuncs.c
src/backend/nodes/copyfuncs.c
+2
-1
src/backend/nodes/equalfuncs.c
src/backend/nodes/equalfuncs.c
+2
-1
src/backend/parser/gram.y
src/backend/parser/gram.y
+43
-5
src/backend/parser/parse_func.c
src/backend/parser/parse_func.c
+22
-3
src/backend/tcop/utility.c
src/backend/tcop/utility.c
+2
-2
src/backend/utils/adt/ruleutils.c
src/backend/utils/adt/ruleutils.c
+78
-8
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.c
+18
-6
src/include/catalog/catversion.h
src/include/catalog/catversion.h
+2
-2
src/include/catalog/namespace.h
src/include/catalog/namespace.h
+2
-1
src/include/catalog/pg_attribute.h
src/include/catalog/pg_attribute.h
+23
-19
src/include/catalog/pg_class.h
src/include/catalog/pg_class.h
+2
-2
src/include/catalog/pg_proc.h
src/include/catalog/pg_proc.h
+2087
-2082
src/include/catalog/pg_proc_fn.h
src/include/catalog/pg_proc_fn.h
+3
-2
src/include/commands/defrem.h
src/include/commands/defrem.h
+2
-2
src/include/nodes/parsenodes.h
src/include/nodes/parsenodes.h
+2
-1
src/include/parser/parse_func.h
src/include/parser/parse_func.h
+3
-2
src/include/utils/builtins.h
src/include/utils/builtins.h
+2
-1
src/test/regress/expected/opr_sanity.out
src/test/regress/expected/opr_sanity.out
+8
-0
src/test/regress/expected/polymorphism.out
src/test/regress/expected/polymorphism.out
+187
-0
src/test/regress/sql/opr_sanity.sql
src/test/regress/sql/opr_sanity.sql
+5
-0
src/test/regress/sql/polymorphism.sql
src/test/regress/sql/polymorphism.sql
+114
-0
No files found.
doc/src/sgml/func.sgml
View file @
455dffbb
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.46
0 2008/11/14 00:51:46 tgl
Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.46
1 2008/12/04 17:51:26 petere
Exp $ -->
<chapter
id=
"functions"
>
<title>
Functions and Operators
</title>
...
...
@@ -11710,6 +11710,10 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
<primary>
pg_get_function_arguments
</primary>
</indexterm>
<indexterm>
<primary>
pg_get_function_identity_arguments
</primary>
</indexterm>
<indexterm>
<primary>
pg_get_function_result
</primary>
</indexterm>
...
...
@@ -11799,7 +11803,12 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
<row>
<entry><literal><function>
pg_get_function_arguments
</function>
(
<parameter>
func_oid
</parameter>
)
</literal></entry>
<entry><type>
text
</type></entry>
<entry>
get argument list for function
</entry>
<entry>
get argument list of function's definition (with default values)
</entry>
</row>
<row>
<entry><literal><function>
pg_get_function_identity_arguments
</function>
(
<parameter>
func_oid
</parameter>
)
</literal></entry>
<entry><type>
text
</type></entry>
<entry>
get argument list to identify a function (without argument names, default values)
</entry>
</row>
<row>
<entry><literal><function>
pg_get_function_result
</function>
(
<parameter>
func_oid
</parameter>
)
</literal></entry>
...
...
@@ -11921,6 +11930,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
<command>
CREATE FUNCTION
</>
.
<function>
pg_get_function_result
</function>
similarly returns the
appropriate
<literal>
RETURNS
</>
clause for the function.
<function>
pg_get_function_identity_arguments
</function>
returns the
argument list necessary to identify a function, in the form it
would need to appear in within
<command>
ALTER FUNCTION
</>
, for
instance. This form omits default values and argument names, for
example.
</para>
<para>
...
...
doc/src/sgml/ref/create_function.sgml
View file @
455dffbb
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/create_function.sgml,v 1.8
1 2008/11/14 10:22:4
6 petere Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/create_function.sgml,v 1.8
2 2008/12/04 17:51:2
6 petere Exp $
-->
<refentry id="SQL-CREATEFUNCTION">
...
...
@@ -21,7 +21,7 @@ $PostgreSQL: pgsql/doc/src/sgml/ref/create_function.sgml,v 1.81 2008/11/14 10:22
<refsynopsisdiv>
<synopsis>
CREATE [ OR REPLACE ] FUNCTION
<replaceable class="parameter">name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] )
<replaceable class="parameter">name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [
{ DEFAULT | = } <replaceable class="parameter">defexpr</replaceable>] [
, ...] ] )
[ RETURNS <replaceable class="parameter">rettype</replaceable>
| RETURNS TABLE ( <replaceable class="parameter">colname</replaceable> <replaceable class="parameter">coltype</replaceable> [, ...] ) ]
{ LANGUAGE <replaceable class="parameter">langname</replaceable>
...
...
@@ -154,6 +154,20 @@ CREATE [ OR REPLACE ] FUNCTION
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">defexpr</replaceable></term>
<listitem>
<para>
An expression to be used as default value if the parameter is
not specified. The expression has to be convertable to the
argument type of the parameter. All parameters after a
parameter with default value have to be parameters with default
values as well.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">rettype</replaceable></term>
...
...
@@ -667,6 +681,14 @@ COMMIT;
either before or after <replaceable class="parameter">argname</replaceable>.
But only the first way is standard-compliant.
</para>
<para>
The SQL standard does not specify parameter defaults. The syntax
with the <literal>DEFAULT</literal> key word is from Oracle, and it
is somewhat in the spirit of the standard: SQL/PSM uses it for
variable default values. The syntax with <literal>=</literal> is
used in T-SQL and Firebird.
</para>
</refsect1>
...
...
doc/src/sgml/xfunc.sgml
View file @
455dffbb
<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.13
3 2008/10/31 19:37:56 tgl
Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.13
4 2008/12/04 17:51:26 petere
Exp $ -->
<sect1 id="xfunc">
<title>User-Defined Functions</title>
...
...
@@ -663,6 +663,60 @@ SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]);
</para>
</sect2>
<sect2 id="xfunc-parameter-defaults">
<title><acronym>SQL</> Functions with Parameters Default Values</title>
<indexterm>
<primary>default values</primary>
</indexterm>
<para>
Functions can be declared with parameters with default values or
expressions. The default expressions are used as parameter value
if the parameter is not explicitly specified in a function call.
All parameters after a a parameter with default value have to be
parameters with default values as well.
</para>
<para>
For example:
<screen>
CREATE FUNCTION foo(a int DEFAULT 1, b int DEFAULT 2, c int DEFAULT 3)
RETURNS int
LANGUAGE SQL
AS $$
SELECT $1 + $2 + $3;
$$;
SELECT foo(10, 20, 30);
foo
-----
60
(1 row)
SELECT foo(10, 20);
foo
-----
33
(1 row)
SELECT foo(10);
foo
-----
15
(1 row)
SELECT foo();
foo
-----
6
(1 row)
</screen>
Instead of the key word <literal>DEFAULT</literal>,
the <literal>=</literal> sign can also be used.
</para>
</sect2>
<sect2 id="xfunc-sql-table-functions">
<title><acronym>SQL</acronym> Functions as Table Sources</title>
...
...
src/backend/catalog/namespace.c
View file @
455dffbb
...
...
@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.11
2 2008/09/09 18:58:08 tgl
Exp $
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.11
3 2008/12/04 17:51:26 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -571,6 +571,11 @@ TypeIsVisible(Oid typid)
* If expand_variadic is false, variadic arguments are not treated specially,
* and the returned nvargs will always be zero.
*
* If expand_variadic is true, functions with argument default values
* will also be retrieved. If expand_variadic is false, default
* values will not be taken into account and functions that do not
* have exactly nargs arguments in total will not be considered.
*
* We search a single namespace if the function name is qualified, else
* all namespaces in the search path. The return list will never contain
* multiple entries with identical argument lists --- in the multiple-
...
...
@@ -621,13 +626,45 @@ FuncnameGetCandidates(List *names, int nargs, bool expand_variadic)
int
pathpos
=
0
;
bool
variadic
;
Oid
va_elem_type
;
List
*
defaults
=
NIL
;
FuncCandidateList
newResult
;
/*
* Check if function has some parameter defaults if some
* parameters are missing.
*/
if
(
pronargs
>
nargs
&&
expand_variadic
)
{
bool
isnull
;
Datum
proargdefaults
;
char
*
str
;
/* skip when not enough default expressions */
if
(
nargs
+
procform
->
pronargdefaults
<
pronargs
)
continue
;
proargdefaults
=
SysCacheGetAttr
(
PROCOID
,
proctup
,
Anum_pg_proc_proargdefaults
,
&
isnull
);
Assert
(
!
isnull
);
str
=
TextDatumGetCString
(
proargdefaults
);
defaults
=
(
List
*
)
stringToNode
(
str
);
Assert
(
IsA
(
defaults
,
List
));
/*
* If we don't have to use all default parameters, we skip
* some cells from the left.
*/
defaults
=
list_copy_tail
(
defaults
,
procform
->
pronargdefaults
-
pronargs
+
nargs
);
pfree
(
str
);
}
/*
* Check if function is variadic, and get variadic element type if so.
* If expand_variadic is false, we should just ignore variadic-ness.
*/
if
(
expand_variadic
)
if
(
pronargs
<=
nargs
&&
expand_variadic
)
{
va_elem_type
=
procform
->
provariadic
;
variadic
=
OidIsValid
(
va_elem_type
);
...
...
@@ -638,11 +675,16 @@ FuncnameGetCandidates(List *names, int nargs, bool expand_variadic)
variadic
=
false
;
}
Assert
(
!
variadic
||
!
defaults
);
/* Ignore if it doesn't match requested argument count */
if
(
nargs
>=
0
&&
(
variadic
?
(
pronargs
>
nargs
)
:
(
pronargs
!=
nargs
)))
(
variadic
?
(
pronargs
>
nargs
)
:
(
defaults
?
(
pronargs
<
nargs
)
:
(
pronargs
!=
nargs
)
)))
continue
;
Assert
(
!
variadic
||
(
pronargs
<=
nargs
));
Assert
(
!
defaults
||
(
pronargs
>
nargs
));
if
(
OidIsValid
(
namespaceId
))
{
/* Consider only procs in specified namespace */
...
...
@@ -681,6 +723,7 @@ FuncnameGetCandidates(List *names, int nargs, bool expand_variadic)
newResult
->
pathpos
=
pathpos
;
newResult
->
oid
=
HeapTupleGetOid
(
proctup
);
newResult
->
nargs
=
effective_nargs
;
newResult
->
argdefaults
=
defaults
;
memcpy
(
newResult
->
args
,
procform
->
proargtypes
.
values
,
pronargs
*
sizeof
(
Oid
));
if
(
variadic
)
...
...
@@ -695,6 +738,8 @@ FuncnameGetCandidates(List *names, int nargs, bool expand_variadic)
else
newResult
->
nvargs
=
0
;
any_variadic
=
variadic
||
defaults
;
/*
* Does it have the same arguments as something we already accepted?
* If so, decide which one to keep. We can skip this check for the
...
...
@@ -704,6 +749,9 @@ FuncnameGetCandidates(List *names, int nargs, bool expand_variadic)
*/
if
(
any_variadic
||
!
OidIsValid
(
namespaceId
))
{
if
(
defaults
)
effective_nargs
=
nargs
;
/*
* If we have an ordered list from SearchSysCacheList (the normal
* case), then any conflicting proc must immediately adjoin this
...
...
@@ -732,6 +780,8 @@ FuncnameGetCandidates(List *names, int nargs, bool expand_variadic)
for
(
prevResult
=
resultList
;
prevResult
;
prevResult
=
prevResult
->
next
)
{
if
(
!
defaults
)
{
if
(
effective_nargs
==
prevResult
->
nargs
&&
memcmp
(
newResult
->
args
,
...
...
@@ -739,6 +789,14 @@ FuncnameGetCandidates(List *names, int nargs, bool expand_variadic)
effective_nargs
*
sizeof
(
Oid
))
==
0
)
break
;
}
else
{
if
(
memcmp
(
newResult
->
args
,
prevResult
->
args
,
effective_nargs
*
sizeof
(
Oid
))
==
0
)
break
;
}
}
}
if
(
prevResult
)
{
...
...
@@ -777,6 +835,20 @@ FuncnameGetCandidates(List *names, int nargs, bool expand_variadic)
pfree
(
newResult
);
continue
;
/* keep previous result */
}
if
(
defaults
)
{
if
(
prevResult
->
argdefaults
!=
NIL
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_AMBIGUOUS_FUNCTION
),
errmsg
(
"functions with parameter defaults %s and %s are ambiguous"
,
func_signature_string
(
names
,
pronargs
,
procform
->
proargtypes
.
values
),
func_signature_string
(
names
,
prevResult
->
nargs
,
prevResult
->
args
))));
/* else, previous result didn't have defaults */
pfree
(
newResult
);
continue
;
/* keep previous result */
}
/* non-variadic can replace a previous variadic */
Assert
(
prevResult
->
nvargs
>
0
);
}
...
...
@@ -784,6 +856,7 @@ FuncnameGetCandidates(List *names, int nargs, bool expand_variadic)
prevResult
->
pathpos
=
pathpos
;
prevResult
->
oid
=
newResult
->
oid
;
prevResult
->
nvargs
=
newResult
->
nvargs
;
prevResult
->
argdefaults
=
newResult
->
argdefaults
;
pfree
(
newResult
);
continue
;
/* args are same, of course */
}
...
...
src/backend/catalog/pg_aggregate.c
View file @
455dffbb
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.9
7 2008/11/14 19:47:50 tgl
Exp $
* $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.9
8 2008/12/04 17:51:26 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -229,7 +229,8 @@ AggregateCreate(const char *aggName,
PointerGetDatum
(
NULL
),
/* parameterNames */
PointerGetDatum
(
NULL
),
/* proconfig */
1
,
/* procost */
0
);
/* prorows */
0
,
/* prorows */
NULL
);
/* parameterDefaults */
/*
* Okay to create the pg_aggregate entry.
...
...
@@ -321,7 +322,7 @@ lookup_agg_function(List *fnName,
*/
fdresult
=
func_get_detail
(
fnName
,
NIL
,
nargs
,
input_types
,
false
,
&
fnOid
,
rettype
,
&
retset
,
&
nvargs
,
&
true_oid_array
);
&
true_oid_array
,
NULL
);
/* only valid case is a normal function not returning a set */
if
(
fdresult
!=
FUNCDETAIL_NORMAL
||
!
OidIsValid
(
fnOid
))
...
...
src/backend/catalog/pg_proc.c
View file @
455dffbb
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.15
4 2008/11/02 01:45:27 tgl
Exp $
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.15
5 2008/12/04 17:51:26 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -75,7 +75,8 @@ ProcedureCreate(const char *procedureName,
Datum
parameterNames
,
Datum
proconfig
,
float4
procost
,
float4
prorows
)
float4
prorows
,
List
*
parameterDefaults
)
{
Oid
retval
;
int
parameterCount
;
...
...
@@ -295,6 +296,7 @@ ProcedureCreate(const char *procedureName,
values
[
Anum_pg_proc_proretset
-
1
]
=
BoolGetDatum
(
returnsSet
);
values
[
Anum_pg_proc_provolatile
-
1
]
=
CharGetDatum
(
volatility
);
values
[
Anum_pg_proc_pronargs
-
1
]
=
UInt16GetDatum
(
parameterCount
);
values
[
Anum_pg_proc_pronargdefaults
-
1
]
=
UInt16GetDatum
(
list_length
(
parameterDefaults
));
values
[
Anum_pg_proc_prorettype
-
1
]
=
ObjectIdGetDatum
(
returnType
);
values
[
Anum_pg_proc_proargtypes
-
1
]
=
PointerGetDatum
(
parameterTypes
);
if
(
allParameterTypes
!=
PointerGetDatum
(
NULL
))
...
...
@@ -309,6 +311,13 @@ ProcedureCreate(const char *procedureName,
values
[
Anum_pg_proc_proargnames
-
1
]
=
parameterNames
;
else
nulls
[
Anum_pg_proc_proargnames
-
1
]
=
true
;
if
(
parameterDefaults
!=
PointerGetDatum
(
NULL
))
{
Assert
(
list_length
(
parameterDefaults
)
>
0
);
values
[
Anum_pg_proc_proargdefaults
-
1
]
=
CStringGetTextDatum
(
nodeToString
(
parameterDefaults
));
}
else
nulls
[
Anum_pg_proc_proargdefaults
-
1
]
=
true
;
values
[
Anum_pg_proc_prosrc
-
1
]
=
CStringGetTextDatum
(
prosrc
);
if
(
probin
)
values
[
Anum_pg_proc_probin
-
1
]
=
CStringGetTextDatum
(
probin
);
...
...
src/backend/commands/functioncmds.c
View file @
455dffbb
...
...
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.10
1 2008/11/02 01:45:27 tgl
Exp $
* $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.10
2 2008/12/04 17:51:26 petere
Exp $
*
* DESCRIPTION
* These routines take the parse tree and pick out the
...
...
@@ -49,8 +49,10 @@
#include "commands/proclang.h"
#include "miscadmin.h"
#include "parser/parse_coerce.h"
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
#include "parser/parse_type.h"
#include "parser/parse_utilcmd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
...
...
@@ -164,7 +166,9 @@ examine_parameter_list(List *parameters, Oid languageOid,
ArrayType
**
allParameterTypes
,
ArrayType
**
parameterModes
,
ArrayType
**
parameterNames
,
Oid
*
requiredResultType
)
List
**
parameterDefaults
,
Oid
*
requiredResultType
,
const
char
*
queryString
)
{
int
parameterCount
=
list_length
(
parameters
);
Oid
*
inTypes
;
...
...
@@ -177,6 +181,8 @@ examine_parameter_list(List *parameters, Oid languageOid,
bool
have_names
=
false
;
ListCell
*
x
;
int
i
;
bool
have_defaults
=
false
;
ParseState
*
pstate
;
*
requiredResultType
=
InvalidOid
;
/* default result */
...
...
@@ -184,6 +190,10 @@ examine_parameter_list(List *parameters, Oid languageOid,
allTypes
=
(
Datum
*
)
palloc
(
parameterCount
*
sizeof
(
Datum
));
paramModes
=
(
Datum
*
)
palloc
(
parameterCount
*
sizeof
(
Datum
));
paramNames
=
(
Datum
*
)
palloc0
(
parameterCount
*
sizeof
(
Datum
));
*
parameterDefaults
=
NIL
;
pstate
=
make_parsestate
(
NULL
);
pstate
->
p_sourcetext
=
queryString
;
/* Scan the list and extract data into work arrays */
i
=
0
;
...
...
@@ -276,9 +286,33 @@ examine_parameter_list(List *parameters, Oid languageOid,
have_names
=
true
;
}
if
(
fp
->
defexpr
)
{
if
(
fp
->
mode
!=
FUNC_PARAM_IN
&&
fp
->
mode
!=
FUNC_PARAM_INOUT
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_FUNCTION_DEFINITION
),
errmsg
(
"only IN and INOUT parameters can have default values"
)));
*
parameterDefaults
=
lappend
(
*
parameterDefaults
,
coerce_to_specific_type
(
NULL
,
transformExpr
(
pstate
,
fp
->
defexpr
),
toid
,
"DEFAULT"
));
have_defaults
=
true
;
}
else
{
if
(
have_defaults
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_FUNCTION_DEFINITION
),
errmsg
(
"parameter without default value specified after parameter with default value"
)));
}
i
++
;
}
free_parsestate
(
pstate
);
/* Now construct the proper outputs as needed */
*
parameterTypes
=
buildoidvector
(
inTypes
,
inCount
);
...
...
@@ -653,7 +687,7 @@ interpret_AS_clause(Oid languageOid, const char *languageName,
* Execute a CREATE FUNCTION utility statement.
*/
void
CreateFunction
(
CreateFunctionStmt
*
stmt
)
CreateFunction
(
CreateFunctionStmt
*
stmt
,
const
char
*
queryString
)
{
char
*
probin_str
;
char
*
prosrc_str
;
...
...
@@ -680,6 +714,7 @@ CreateFunction(CreateFunctionStmt *stmt)
HeapTuple
languageTuple
;
Form_pg_language
languageStruct
;
List
*
as_clause
;
List
*
defaults
=
NULL
;
/* Convert list of names to a name and namespace */
namespaceId
=
QualifiedNameGetCreationNamespace
(
stmt
->
funcname
,
...
...
@@ -753,7 +788,9 @@ CreateFunction(CreateFunctionStmt *stmt)
&
allParameterTypes
,
&
parameterModes
,
&
parameterNames
,
&
requiredResultType
);
&
defaults
,
&
requiredResultType
,
queryString
);
if
(
stmt
->
returnType
)
{
...
...
@@ -836,7 +873,8 @@ CreateFunction(CreateFunctionStmt *stmt)
PointerGetDatum
(
parameterNames
),
PointerGetDatum
(
proconfig
),
procost
,
prorows
);
prorows
,
defaults
);
}
...
...
src/backend/commands/proclang.c
View file @
455dffbb
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.8
0 2008/11/02 01:45:27 tgl
Exp $
* $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.8
1 2008/12/04 17:51:26 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -149,7 +149,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
PointerGetDatum
(
NULL
),
PointerGetDatum
(
NULL
),
1
,
0
);
0
,
NULL
);
}
/*
...
...
@@ -182,7 +183,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
PointerGetDatum
(
NULL
),
PointerGetDatum
(
NULL
),
1
,
0
);
0
,
NULL
);
}
}
else
...
...
src/backend/nodes/copyfuncs.c
View file @
455dffbb
...
...
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.41
4 2008/12/04 11:42:23 heikki
Exp $
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.41
5 2008/12/04 17:51:26 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -2448,6 +2448,7 @@ _copyFunctionParameter(FunctionParameter *from)
COPY_STRING_FIELD
(
name
);
COPY_NODE_FIELD
(
argType
);
COPY_SCALAR_FIELD
(
mode
);
COPY_NODE_FIELD
(
defexpr
);
return
newnode
;
}
...
...
src/backend/nodes/equalfuncs.c
View file @
455dffbb
...
...
@@ -22,7 +22,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.3
39 2008/12/04 11:42:24 heikki
Exp $
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.3
40 2008/12/04 17:51:26 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -1165,6 +1165,7 @@ _equalFunctionParameter(FunctionParameter *a, FunctionParameter *b)
COMPARE_STRING_FIELD
(
name
);
COMPARE_NODE_FIELD
(
argType
);
COMPARE_SCALAR_FIELD
(
mode
);
COMPARE_NODE_FIELD
(
defexpr
);
return
true
;
}
...
...
src/backend/parser/gram.y
View file @
455dffbb
...
...
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.64
2 2008/12/04 11:42:24 heikki
Exp $
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.64
3 2008/12/04 17:51:26 petere
Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
...
...
@@ -255,6 +255,7 @@ static TypeName *TableFuncTypeName(List *columns);
%type <list> stmtblock stmtmulti
OptTableElementList TableElementList OptInherit definition
OptWith opt_distinct opt_definition func_args func_args_list
func_args_with_defaults func_args_with_defaults_list
func_as createfunc_opt_list alterfunc_opt_list
aggr_args old_aggr_definition old_aggr_list
oper_argtypes RuleActionList RuleActionMulti
...
...
@@ -278,7 +279,7 @@ static TypeName *TableFuncTypeName(List *columns);
%type <into> into_clause create_as_target
%type <defelt> createfunc_opt_item common_func_opt_item
%type <fun_param> func_arg table_func_column
%type <fun_param> func_arg
func_arg_with_default
table_func_column
%type <fun_param_mode> arg_class
%type <typnam> func_return func_type
...
...
@@ -4170,7 +4171,7 @@ opt_nulls_order: NULLS_FIRST { $$ = SORTBY_NULLS_FIRST; }
*****************************************************************************/
CreateFunctionStmt:
CREATE opt_or_replace FUNCTION func_name func_args
CREATE opt_or_replace FUNCTION func_name func_args
_with_defaults
RETURNS func_return createfunc_opt_list opt_definition
{
CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
...
...
@@ -4182,7 +4183,7 @@ CreateFunctionStmt:
n->withClause = $9;
$$ = (Node *)n;
}
| CREATE opt_or_replace FUNCTION func_name func_args
| CREATE opt_or_replace FUNCTION func_name func_args
_with_defaults
RETURNS TABLE '(' table_func_column_list ')' createfunc_opt_list opt_definition
{
CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
...
...
@@ -4195,7 +4196,7 @@ CreateFunctionStmt:
n->withClause = $12;
$$ = (Node *)n;
}
| CREATE opt_or_replace FUNCTION func_name func_args
| CREATE opt_or_replace FUNCTION func_name func_args
_with_defaults
createfunc_opt_list opt_definition
{
CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
...
...
@@ -4223,6 +4224,21 @@ func_args_list:
| func_args_list ',' func_arg { $$ = lappend($1, $3); }
;
/*
* func_args_with_defaults is separate because we only want to accept
* defaults in CREATE FUNCTION, not in ALTER etc.
*/
func_args_with_defaults:
'(' func_args_with_defaults_list ')' { $$ = $2; }
| '(' ')' { $$ = NIL; }
;
func_args_with_defaults_list:
func_arg_with_default { $$ = list_make1( $1); }
| func_args_with_defaults_list ',' func_arg_with_default { $$ = lappend($1, $3); }
;
/*
* The style with arg_class first is SQL99 standard, but Oracle puts
* param_name first; accept both since it's likely people will try both
...
...
@@ -4240,6 +4256,7 @@ func_arg:
n->name = $2;
n->argType = $3;
n->mode = $1;
n->defexpr = NULL;
$$ = n;
}
| param_name arg_class func_type
...
...
@@ -4248,6 +4265,7 @@ func_arg:
n->name = $1;
n->argType = $3;
n->mode = $2;
n->defexpr = NULL;
$$ = n;
}
| param_name func_type
...
...
@@ -4256,6 +4274,7 @@ func_arg:
n->name = $1;
n->argType = $2;
n->mode = FUNC_PARAM_IN;
n->defexpr = NULL;
$$ = n;
}
| arg_class func_type
...
...
@@ -4264,6 +4283,7 @@ func_arg:
n->name = NULL;
n->argType = $2;
n->mode = $1;
n->defexpr = NULL;
$$ = n;
}
| func_type
...
...
@@ -4272,6 +4292,7 @@ func_arg:
n->name = NULL;
n->argType = $1;
n->mode = FUNC_PARAM_IN;
n->defexpr = NULL;
$$ = n;
}
;
...
...
@@ -4322,6 +4343,23 @@ func_type: Typename { $$ = $1; }
}
;
func_arg_with_default:
func_arg
{
$$ = $1;
}
| func_arg DEFAULT a_expr
{
$$ = $1;
$$->defexpr = $3;
}
| func_arg '=' a_expr
{
$$ = $1;
$$->defexpr = $3;
}
;
createfunc_opt_list:
/* Must be at least one to prevent conflict */
...
...
src/backend/parser/parse_func.c
View file @
455dffbb
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.20
7 2008/09/01 20:42:44 tgl
Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.20
8 2008/12/04 17:51:26 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -77,6 +77,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
bool
retset
;
int
nvargs
;
FuncDetailCode
fdresult
;
List
*
argdefaults
;
/*
* Most of the rest of the parser just assumes that functions do not have
...
...
@@ -164,7 +165,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
fdresult
=
func_get_detail
(
funcname
,
fargs
,
nargs
,
actual_arg_types
,
!
func_variadic
,
&
funcid
,
&
rettype
,
&
retset
,
&
nvargs
,
&
declared_arg_types
);
&
declared_arg_types
,
&
argdefaults
);
if
(
fdresult
==
FUNCDETAIL_COERCION
)
{
/*
...
...
@@ -234,6 +235,21 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
parser_errposition
(
pstate
,
location
)));
}
/* add stored expressions as called values for arguments with defaults */
if
(
argdefaults
)
{
ListCell
*
lc
;
foreach
(
lc
,
argdefaults
)
{
Node
*
expr
=
(
Node
*
)
lfirst
(
lc
);
fargs
=
lappend
(
fargs
,
expr
);
actual_arg_types
[
nargs
++
]
=
exprType
(
expr
);
}
}
/*
* enforce consistency with polymorphic argument and return types,
* possibly adjusting return type or declared_arg_types (which will be
...
...
@@ -729,7 +745,8 @@ func_get_detail(List *funcname,
Oid
*
rettype
,
/* return value */
bool
*
retset
,
/* return value */
int
*
nvargs
,
/* return value */
Oid
**
true_typeids
)
/* return value */
Oid
**
true_typeids
,
/* return value */
List
**
argdefaults
)
/* return value */
{
FuncCandidateList
raw_candidates
;
FuncCandidateList
best_candidate
;
...
...
@@ -870,6 +887,8 @@ func_get_detail(List *funcname,
*
funcid
=
best_candidate
->
oid
;
*
nvargs
=
best_candidate
->
nvargs
;
*
true_typeids
=
best_candidate
->
args
;
if
(
argdefaults
)
*
argdefaults
=
best_candidate
->
argdefaults
;
ftup
=
SearchSysCache
(
PROCOID
,
ObjectIdGetDatum
(
best_candidate
->
oid
),
...
...
src/backend/tcop/utility.c
View file @
455dffbb
...
...
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.30
1 2008/11/07 18:25:06 tgl
Exp $
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.30
2 2008/12/04 17:51:26 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -700,7 +700,7 @@ ProcessUtility(Node *parsetree,
break
;
case
T_CreateFunctionStmt
:
/* CREATE FUNCTION */
CreateFunction
((
CreateFunctionStmt
*
)
parsetree
);
CreateFunction
((
CreateFunctionStmt
*
)
parsetree
,
queryString
);
break
;
case
T_AlterFunctionStmt
:
/* ALTER FUNCTION */
...
...
src/backend/utils/adt/ruleutils.c
View file @
455dffbb
...
...
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.28
7 2008/10/06 20:29:38 tgl
Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.28
8 2008/12/04 17:51:27 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -141,7 +141,8 @@ static char *pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
static
char
*
pg_get_expr_worker
(
text
*
expr
,
Oid
relid
,
char
*
relname
,
int
prettyFlags
);
static
int
print_function_arguments
(
StringInfo
buf
,
HeapTuple
proctup
,
bool
print_table_args
);
bool
print_table_args
,
bool
full
);
static
void
print_function_rettype
(
StringInfo
buf
,
HeapTuple
proctup
);
static
void
make_ruledef
(
StringInfo
buf
,
HeapTuple
ruletup
,
TupleDesc
rulettc
,
int
prettyFlags
);
...
...
@@ -1449,7 +1450,7 @@ pg_get_functiondef(PG_FUNCTION_ARGS)
nsp
=
get_namespace_name
(
proc
->
pronamespace
);
appendStringInfo
(
&
buf
,
"CREATE OR REPLACE FUNCTION %s("
,
quote_qualified_identifier
(
nsp
,
name
));
(
void
)
print_function_arguments
(
&
buf
,
proctup
,
false
);
(
void
)
print_function_arguments
(
&
buf
,
proctup
,
false
,
true
);
appendStringInfoString
(
&
buf
,
")
\n
RETURNS "
);
print_function_rettype
(
&
buf
,
proctup
);
appendStringInfo
(
&
buf
,
"
\n
LANGUAGE %s
\n
"
,
...
...
@@ -1598,13 +1599,43 @@ pg_get_function_arguments(PG_FUNCTION_ARGS)
if
(
!
HeapTupleIsValid
(
proctup
))
elog
(
ERROR
,
"cache lookup failed for function %u"
,
funcid
);
(
void
)
print_function_arguments
(
&
buf
,
proctup
,
false
);
(
void
)
print_function_arguments
(
&
buf
,
proctup
,
false
,
true
);
ReleaseSysCache
(
proctup
);
PG_RETURN_TEXT_P
(
string_to_text
(
buf
.
data
));
}
/*
* pg_get_function_identity_arguments
* Get a formatted list of arguments for a function.
* This is everything that would go between the parentheses in
* ALTER FUNCTION, etc. skip names and defaults/
*/
Datum
pg_get_function_identity_arguments
(
PG_FUNCTION_ARGS
)
{
Oid
funcid
=
PG_GETARG_OID
(
0
);
StringInfoData
buf
;
HeapTuple
proctup
;
initStringInfo
(
&
buf
);
proctup
=
SearchSysCache
(
PROCOID
,
ObjectIdGetDatum
(
funcid
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
proctup
))
elog
(
ERROR
,
"cache lookup failed for function %u"
,
funcid
);
(
void
)
print_function_arguments
(
&
buf
,
proctup
,
false
,
false
);
ReleaseSysCache
(
proctup
);
PG_RETURN_TEXT_P
(
string_to_text
(
buf
.
data
));
}
/*
* pg_get_function_result
* Get a nicely-formatted version of the result type of a function.
...
...
@@ -1649,7 +1680,7 @@ print_function_rettype(StringInfo buf, HeapTuple proctup)
{
/* It might be a table function; try to print the arguments */
appendStringInfoString
(
&
rbuf
,
"TABLE("
);
ntabargs
=
print_function_arguments
(
&
rbuf
,
proctup
,
true
);
ntabargs
=
print_function_arguments
(
&
rbuf
,
proctup
,
true
,
true
);
if
(
ntabargs
>
0
)
appendStringInfoString
(
&
rbuf
,
")"
);
else
...
...
@@ -1672,10 +1703,12 @@ print_function_rettype(StringInfo buf, HeapTuple proctup)
* append the desired subset of arguments to buf. We print only TABLE
* arguments when print_table_args is true, and all the others when it's false.
* Function return value is the number of arguments printed.
* When full is false, then don't print argument names and argument defaults.
*/
static
int
print_function_arguments
(
StringInfo
buf
,
HeapTuple
proctup
,
bool
print_table_args
)
bool
print_table_args
,
bool
full
)
{
int
numargs
;
Oid
*
argtypes
;
...
...
@@ -1683,10 +1716,37 @@ print_function_arguments(StringInfo buf, HeapTuple proctup,
char
*
argmodes
;
int
argsprinted
;
int
i
;
Datum
proargdefaults
;
List
*
argdefaults
;
int
nargdefaults
;
bool
isnull
;
List
*
dcontext
=
NIL
;
numargs
=
get_func_arg_info
(
proctup
,
&
argtypes
,
&
argnames
,
&
argmodes
);
proargdefaults
=
SysCacheGetAttr
(
PROCOID
,
proctup
,
Anum_pg_proc_proargdefaults
,
&
isnull
);
if
(
!
isnull
)
{
char
*
str
;
str
=
TextDatumGetCString
(
proargdefaults
);
argdefaults
=
(
List
*
)
stringToNode
(
str
);
Assert
(
IsA
(
argdefaults
,
List
));
nargdefaults
=
list_length
(
argdefaults
);
/* we will need deparse context */
//dcontext = deparse_context_for("", InvalidOid);
dcontext
=
NULL
;
pfree
(
str
);
}
else
{
argdefaults
=
NIL
;
nargdefaults
=
0
;
}
argsprinted
=
0
;
for
(
i
=
0
;
i
<
numargs
;
i
++
)
{
...
...
@@ -1723,9 +1783,19 @@ print_function_arguments(StringInfo buf, HeapTuple proctup,
if
(
argsprinted
)
appendStringInfoString
(
buf
,
", "
);
appendStringInfoString
(
buf
,
modename
);
if
(
argname
&&
argname
[
0
])
if
(
argname
&&
argname
[
0
]
&&
full
)
appendStringInfo
(
buf
,
"%s "
,
argname
);
appendStringInfoString
(
buf
,
format_type_be
(
argtype
));
/* search given default expression, expect less numargs */
if
(
nargdefaults
>
0
&&
i
>=
(
numargs
-
nargdefaults
)
&&
full
)
{
Node
*
expr
;
expr
=
(
Node
*
)
list_nth
(
argdefaults
,
i
-
(
numargs
-
nargdefaults
));
appendStringInfo
(
buf
,
" DEFAULT %s"
,
deparse_expression
(
expr
,
dcontext
,
false
,
false
));
}
argsprinted
++
;
}
...
...
@@ -6002,7 +6072,7 @@ generate_function_name(Oid funcid, int nargs, Oid *argtypes,
p_result
=
func_get_detail
(
list_make1
(
makeString
(
proname
)),
NIL
,
nargs
,
argtypes
,
false
,
&
p_funcid
,
&
p_rettype
,
&
p_retset
,
&
p_nvargs
,
&
p_true_typeids
);
&
p_retset
,
&
p_nvargs
,
&
p_true_typeids
,
NULL
);
if
((
p_result
==
FUNCDETAIL_NORMAL
||
p_result
==
FUNCDETAIL_AGGREGATE
)
&&
p_funcid
==
funcid
)
nspname
=
NULL
;
...
...
src/bin/pg_dump/pg_dump.c
View file @
455dffbb
...
...
@@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.50
5 2008/11/09 21:24:32 tgl
Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.50
6 2008/12/04 17:51:27 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -6733,13 +6733,15 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
PQExpBuffer
delqry
;
PQExpBuffer
asPart
;
PGresult
*
res
;
char
*
funcsig
;
char
*
funcsig
;
/* identity signature */
char
*
funcfullsig
;
/* full signature */
char
*
funcsig_tag
;
int
ntups
;
char
*
proretset
;
char
*
prosrc
;
char
*
probin
;
char
*
funcargs
;
char
*
funciargs
;
char
*
funcresult
;
char
*
proallargtypes
;
char
*
proargmodes
;
...
...
@@ -6782,6 +6784,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
appendPQExpBuffer
(
query
,
"SELECT proretset, prosrc, probin, "
"pg_catalog.pg_get_function_arguments(oid) as funcargs, "
"pg_catalog.pg_get_function_identity_arguments(oid) as funciargs, "
"pg_catalog.pg_get_function_result(oid) as funcresult, "
"provolatile, proisstrict, prosecdef, "
"proconfig, procost, prorows, "
...
...
@@ -6893,6 +6896,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
if
(
g_fout
->
remoteVersion
>=
80400
)
{
funcargs
=
PQgetvalue
(
res
,
0
,
PQfnumber
(
res
,
"funcargs"
));
funciargs
=
PQgetvalue
(
res
,
0
,
PQfnumber
(
res
,
"funciargs"
));
funcresult
=
PQgetvalue
(
res
,
0
,
PQfnumber
(
res
,
"funcresult"
));
proallargtypes
=
proargmodes
=
proargnames
=
NULL
;
}
...
...
@@ -6901,7 +6905,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
proallargtypes
=
PQgetvalue
(
res
,
0
,
PQfnumber
(
res
,
"proallargtypes"
));
proargmodes
=
PQgetvalue
(
res
,
0
,
PQfnumber
(
res
,
"proargmodes"
));
proargnames
=
PQgetvalue
(
res
,
0
,
PQfnumber
(
res
,
"proargnames"
));
funcargs
=
funcresult
=
NULL
;
funcargs
=
func
iargs
=
func
result
=
NULL
;
}
provolatile
=
PQgetvalue
(
res
,
0
,
PQfnumber
(
res
,
"provolatile"
));
proisstrict
=
PQgetvalue
(
res
,
0
,
PQfnumber
(
res
,
"proisstrict"
));
...
...
@@ -7007,11 +7011,19 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
}
}
if
(
funcargs
)
funcsig
=
format_function_arguments
(
finfo
,
funcargs
);
/* funcargs and funciargs are supported from 8.4 */
if
(
funciargs
)
{
funcsig
=
format_function_arguments
(
finfo
,
funciargs
);
funcfullsig
=
format_function_arguments
(
finfo
,
funcargs
);
}
else
{
funcsig
=
format_function_arguments_old
(
finfo
,
nallargs
,
allargtypes
,
argmodes
,
argnames
);
funcfullsig
=
funcsig
;
}
funcsig_tag
=
format_function_signature
(
finfo
,
false
);
/*
...
...
@@ -7021,7 +7033,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
fmtId
(
finfo
->
dobj
.
namespace
->
dobj
.
name
),
funcsig
);
appendPQExpBuffer
(
q
,
"CREATE FUNCTION %s "
,
funcsig
);
appendPQExpBuffer
(
q
,
"CREATE FUNCTION %s "
,
func
full
sig
);
if
(
funcresult
)
appendPQExpBuffer
(
q
,
"RETURNS %s"
,
funcresult
);
else
...
...
src/include/catalog/catversion.h
View file @
455dffbb
...
...
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.51
0 2008/12/03 13:28:53 heikki
Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.51
1 2008/12/04 17:51:27 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 2008120
3
1
#define CATALOG_VERSION_NO 2008120
4
1
#endif
src/include/catalog/namespace.h
View file @
455dffbb
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/namespace.h,v 1.5
5 2008/07/16 01:30:23 tgl
Exp $
* $PostgreSQL: pgsql/src/include/catalog/namespace.h,v 1.5
6 2008/12/04 17:51:27 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -30,6 +30,7 @@ typedef struct _FuncCandidateList
Oid
oid
;
/* the function or operator's OID */
int
nargs
;
/* number of arg types returned */
int
nvargs
;
/* number of args to become variadic array */
List
*
argdefaults
;
/* list of parameter defaults */
Oid
args
[
1
];
/* arg types --- VARIABLE LENGTH ARRAY */
}
*
FuncCandidateList
;
/* VARIABLE LENGTH STRUCT */
...
...
src/include/catalog/pg_attribute.h
View file @
455dffbb
...
...
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.14
1 2008/11/09 21:24:33 tgl
Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.14
2 2008/12/04 17:51:27 petere
Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
...
...
@@ -300,15 +300,17 @@ DATA(insert ( 1247 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
{ 1255, {"proretset"}, 16, -1, 1, 11, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"provolatile"}, 18, -1, 1, 12, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"pronargs"}, 21, -1, 2, 13, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
{ 1255, {"prorettype"}, 26, -1, 4, 14, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"proargtypes"}, 30, -1, -1, 15, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"proallargtypes"}, 1028, -1, -1, 16, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proargmodes"}, 1002, -1, -1, 17, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proargnames"}, 1009, -1, -1, 18, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"prosrc"}, 25, -1, -1, 19, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"probin"}, 17, -1, -1, 20, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proconfig"}, 1009, -1, -1, 21, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proacl"}, 1034, -1, -1, 22, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
{ 1255, {"pronargdefaults"}, 21, -1, 2, 14, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
{ 1255, {"prorettype"}, 26, -1, 4, 15, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"proargtypes"}, 30, -1, -1, 16, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"proallargtypes"}, 1028, -1, -1, 17, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proargmodes"}, 1002, -1, -1, 18, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proargnames"}, 1009, -1, -1, 19, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proargdefaults"}, 25, -1, -1, 20, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"prosrc"}, 25, -1, -1, 21, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"probin"}, 17, -1, -1, 22, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proconfig"}, 1009, -1, -1, 23, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
{ 1255, {"proacl"}, 1034, -1, -1, 24, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
DATA
(
insert
(
1255
proname
19
-
1
NAMEDATALEN
1
0
-
1
-
1
f
p
c
t
f
f
t
0
));
DATA
(
insert
(
1255
pronamespace
26
-
1
4
2
0
-
1
-
1
t
p
i
t
f
f
t
0
));
...
...
@@ -323,15 +325,17 @@ DATA(insert ( 1255 proisstrict 16 -1 1 10 0 -1 -1 t p c t f f t 0));
DATA
(
insert
(
1255
proretset
16
-
1
1
11
0
-
1
-
1
t
p
c
t
f
f
t
0
));
DATA
(
insert
(
1255
provolatile
18
-
1
1
12
0
-
1
-
1
t
p
c
t
f
f
t
0
));
DATA
(
insert
(
1255
pronargs
21
-
1
2
13
0
-
1
-
1
t
p
s
t
f
f
t
0
));
DATA
(
insert
(
1255
prorettype
26
-
1
4
14
0
-
1
-
1
t
p
i
t
f
f
t
0
));
DATA
(
insert
(
1255
proargtypes
30
-
1
-
1
15
1
-
1
-
1
f
p
i
t
f
f
t
0
));
DATA
(
insert
(
1255
proallargtypes
1028
-
1
-
1
16
1
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
proargmodes
1002
-
1
-
1
17
1
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
proargnames
1009
-
1
-
1
18
1
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
prosrc
25
-
1
-
1
19
0
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
probin
17
-
1
-
1
20
0
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
proconfig
1009
-
1
-
1
21
1
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
proacl
1034
-
1
-
1
22
1
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
pronargdefaults
21
-
1
2
14
0
-
1
-
1
t
p
s
t
f
f
t
0
));
DATA
(
insert
(
1255
prorettype
26
-
1
4
15
0
-
1
-
1
t
p
i
t
f
f
t
0
));
DATA
(
insert
(
1255
proargtypes
30
-
1
-
1
16
1
-
1
-
1
f
p
i
t
f
f
t
0
));
DATA
(
insert
(
1255
proallargtypes
1028
-
1
-
1
17
1
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
proargmodes
1002
-
1
-
1
18
1
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
proargnames
1009
-
1
-
1
19
1
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
proargdefaults
25
-
1
-
1
20
0
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
prosrc
25
-
1
-
1
21
0
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
probin
17
-
1
-
1
22
0
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
proconfig
1009
-
1
-
1
23
1
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
proacl
1034
-
1
-
1
24
1
-
1
-
1
f
x
i
f
f
f
t
0
));
DATA
(
insert
(
1255
ctid
27
0
6
-
1
0
-
1
-
1
f
p
s
t
f
f
t
0
));
DATA
(
insert
(
1255
oid
26
0
4
-
2
0
-
1
-
1
t
p
i
t
f
f
t
0
));
DATA
(
insert
(
1255
xmin
28
0
4
-
3
0
-
1
-
1
t
p
i
t
f
f
t
0
));
...
...
src/include/catalog/pg_class.h
View file @
455dffbb
...
...
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.10
8 2008/11/09 21:24:33 tgl
Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.10
9 2008/12/04 17:51:27 petere
Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
...
...
@@ -125,7 +125,7 @@ DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 28 0 t
DESCR
(
""
);
DATA
(
insert
OID
=
1249
(
pg_attribute
PGNSP
75
PGUID
0
1249
0
0
0
0
0
f
f
r
17
0
f
f
f
f
f
3
_null_
_null_
));
DESCR
(
""
);
DATA
(
insert
OID
=
1255
(
pg_proc
PGNSP
81
PGUID
0
1255
0
0
0
0
0
f
f
r
2
2
0
t
f
f
f
f
3
_null_
_null_
));
DATA
(
insert
OID
=
1255
(
pg_proc
PGNSP
81
PGUID
0
1255
0
0
0
0
0
f
f
r
2
4
0
t
f
f
f
f
3
_null_
_null_
));
DESCR
(
""
);
DATA
(
insert
OID
=
1259
(
pg_class
PGNSP
83
PGUID
0
1259
0
0
0
0
0
f
f
r
24
0
t
f
f
f
f
3
_null_
_null_
));
DESCR
(
""
);
...
...
src/include/catalog/pg_proc.h
View file @
455dffbb
This diff is collapsed.
Click to expand it.
src/include/catalog/pg_proc_fn.h
View file @
455dffbb
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_proc_fn.h,v 1.
1 2008/03/27 03:57:34 tgl
Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_proc_fn.h,v 1.
2 2008/12/04 17:51:27 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -33,7 +33,8 @@ extern Oid ProcedureCreate(const char *procedureName,
Datum
parameterNames
,
Datum
proconfig
,
float4
procost
,
float4
prorows
);
float4
prorows
,
List
*
parameterDefaults
);
extern
bool
function_parse_error_transpose
(
const
char
*
prosrc
);
...
...
src/include/commands/defrem.h
View file @
455dffbb
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.
89 2008/06/14 18:04:34 tgl
Exp $
* $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.
90 2008/12/04 17:51:27 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -45,7 +45,7 @@ extern char *ChooseRelationName(const char *name1, const char *name2,
extern
Oid
GetDefaultOpClass
(
Oid
type_id
,
Oid
am_id
);
/* commands/functioncmds.c */
extern
void
CreateFunction
(
CreateFunctionStmt
*
stmt
);
extern
void
CreateFunction
(
CreateFunctionStmt
*
stmt
,
const
char
*
queryString
);
extern
void
RemoveFunction
(
RemoveFuncStmt
*
stmt
);
extern
void
RemoveFunctionById
(
Oid
funcOid
);
extern
void
SetFunctionReturnType
(
Oid
funcOid
,
Oid
newRetType
);
...
...
src/include/nodes/parsenodes.h
View file @
455dffbb
...
...
@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.38
0 2008/12/04 11:42:24 heikki
Exp $
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.38
1 2008/12/04 17:51:27 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -1686,6 +1686,7 @@ typedef struct FunctionParameter
char
*
name
;
/* parameter name, or NULL if not given */
TypeName
*
argType
;
/* TypeName for parameter type */
FunctionParameterMode
mode
;
/* IN/OUT/INOUT */
Node
*
defexpr
;
/* Default expression, or NULL if not given */
}
FunctionParameter
;
typedef
struct
AlterFunctionStmt
...
...
src/include/parser/parse_func.h
View file @
455dffbb
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/parser/parse_func.h,v 1.6
0 2008/07/16 01:30:23 tgl
Exp $
* $PostgreSQL: pgsql/src/include/parser/parse_func.h,v 1.6
1 2008/12/04 17:51:27 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -49,7 +49,8 @@ extern Node *ParseFuncOrColumn(ParseState *pstate,
extern
FuncDetailCode
func_get_detail
(
List
*
funcname
,
List
*
fargs
,
int
nargs
,
Oid
*
argtypes
,
bool
expand_variadic
,
Oid
*
funcid
,
Oid
*
rettype
,
bool
*
retset
,
int
*
nvargs
,
Oid
**
true_typeids
);
bool
*
retset
,
int
*
nvargs
,
Oid
**
true_typeids
,
List
**
argdefaults
);
extern
int
func_match_argtypes
(
int
nargs
,
Oid
*
input_typeids
,
...
...
src/include/utils/builtins.h
View file @
455dffbb
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.32
6 2008/11/03 20:17:20 adunstan
Exp $
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.32
7 2008/12/04 17:51:28 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -553,6 +553,7 @@ extern Datum pg_get_userbyid(PG_FUNCTION_ARGS);
extern
Datum
pg_get_serial_sequence
(
PG_FUNCTION_ARGS
);
extern
Datum
pg_get_functiondef
(
PG_FUNCTION_ARGS
);
extern
Datum
pg_get_function_arguments
(
PG_FUNCTION_ARGS
);
extern
Datum
pg_get_function_identity_arguments
(
PG_FUNCTION_ARGS
);
extern
Datum
pg_get_function_result
(
PG_FUNCTION_ARGS
);
extern
char
*
deparse_expression
(
Node
*
expr
,
List
*
dpcontext
,
bool
forceprefix
,
bool
showimplicit
);
...
...
src/test/regress/expected/opr_sanity.out
View file @
455dffbb
...
...
@@ -61,6 +61,14 @@ WHERE prosrc IS NULL OR prosrc = '' OR prosrc = '-';
-----+---------
(0 rows)
-- pronargdefaults should be 0 iff proargdefaults is null
SELECT p.oid, p.proname
FROM pg_proc AS p
WHERE pronargdefaults <> 0 OR proargdefaults IS NOT NULL;
oid | proname
-----+---------
(0 rows)
-- probin should be non-empty for C functions, null everywhere else
SELECT p1.oid, p1.proname
FROM pg_proc as p1
...
...
src/test/regress/expected/polymorphism.out
View file @
455dffbb
...
...
@@ -776,3 +776,190 @@ select pg_typeof(myleast(10, 1, 20, 33)); -- polymorphic input
integer
(1 row)
-- test functions with parameter defaults
-- test basic functionality
create function dfunc(a int = 1, int = 2) returns int as $$
select $1 + $2;
$$ language sql;
select dfunc();
dfunc
-------
3
(1 row)
select dfunc(10);
dfunc
-------
12
(1 row)
select dfunc(10, 20);
dfunc
-------
30
(1 row)
drop function dfunc(); -- fail
ERROR: function dfunc() does not exist
drop function dfunc(int); -- fail
ERROR: function dfunc(integer) does not exist
drop function dfunc(int, int); -- ok
-- fail, gap in arguments with defaults
create function dfunc(a int = 1, b int) returns int as $$
select $1 + $2;
$$ language sql;
ERROR: parameter without default value specified after parameter with default value
-- check implicit coercion
create function dfunc(a int DEFAULT 1.0, int DEFAULT '-1') returns int as $$
select $1 + $2;
$$ language sql;
select dfunc();
dfunc
-------
0
(1 row)
create function dfunc(a text DEFAULT 'Hello', b text DEFAULT 'World') returns text as $$
select $1 || ', ' || $2;
$$ language sql;
select dfunc(); -- fail; which dfunc should be called? int or text
ERROR: functions with parameter defaults dfunc(text, text) and dfunc(integer, integer) are ambiguous
select dfunc('Hi'); -- ok
dfunc
-----------
Hi, World
(1 row)
select dfunc('Hi', 'City'); -- ok
dfunc
----------
Hi, City
(1 row)
select dfunc(0); -- ok
dfunc
-------
-1
(1 row)
select dfunc(10, 20); -- ok
dfunc
-------
30
(1 row)
drop function dfunc(int, int);
drop function dfunc(text, text);
create function dfunc(int = 1, int = 2) returns int as $$
select 2;
$$ language sql;
create function dfunc(int = 1, int = 2, int = 3, int = 4) returns int as $$
select 4;
$$ language sql;
-- Now, dfunc(nargs = 2) and dfunc(nargs = 4) are ambiguous when called
-- with 0 or 1 arguments. For 2 arguments, a normall call of
-- dfunc(nargs = 2) takes place.
select dfunc(); -- fail
ERROR: functions with parameter defaults dfunc(integer, integer, integer, integer) and dfunc(integer, integer) are ambiguous
select dfunc(1); -- fail
ERROR: functions with parameter defaults dfunc(integer, integer, integer, integer) and dfunc(integer, integer) are ambiguous
select dfunc(1, 2); -- ok
dfunc
-------
2
(1 row)
select dfunc(1, 2, 3); -- ok
dfunc
-------
4
(1 row)
select dfunc(1, 2, 3, 4); -- ok
dfunc
-------
4
(1 row)
drop function dfunc(int, int);
drop function dfunc(int, int, int, int);
-- default values are not allowed for output parameters
create function dfunc(out int = 20) returns int as $$
select 1;
$$ language sql;
ERROR: only IN and INOUT parameters can have default values
-- polymorphic parameter test
create function dfunc(anyelement = 'World'::text) returns text as $$
select 'Hello, ' || $1::text;
$$ language sql;
select dfunc();
dfunc
--------------
Hello, World
(1 row)
select dfunc(0);
dfunc
----------
Hello, 0
(1 row)
select dfunc(to_date('20081215','YYYYMMDD'));
dfunc
-------------------
Hello, 12-15-2008
(1 row)
select dfunc('City'::text);
dfunc
-------------
Hello, City
(1 row)
drop function dfunc(anyelement);
-- check null values
create function dfunc(int = null, int = null, int = null) returns int[] as $$
select array[$1, $2, $3];
$$ language sql;
select dfunc(1);
dfunc
---------------
{1,NULL,NULL}
(1 row)
select dfunc(1, 2);
dfunc
------------
{1,2,NULL}
(1 row)
select dfunc(1, 2, 3);
dfunc
---------
{1,2,3}
(1 row)
drop function dfunc(int, int, int);
-- The conflict detection algorithm doesn't consider the actual parameter
-- types. It detects any possible conflict for n arguments for some
-- function. This is unwanted behavior, but solving it needs a move of
-- coercion routines.
create function dfunc(int = 1, int = 2, int = 3) returns int as $$
select 3;
$$ language sql;
create function dfunc(int = 1, int = 2) returns int as $$
select 2;
$$ language sql;
-- for n = 1 dfunc(narg=2) and dfunc(narg=3) are ambiguous
select dfunc(1); -- fail
ERROR: functions with parameter defaults dfunc(integer, integer, integer) and dfunc(integer, integer) are ambiguous
create function dfunc(text) returns text as $$
select $1;
$$ language sql;
-- Will fail, it detects ambiguity between dfunc(int, int, int) and
-- dfunc(int, int), but dfunc(text) isn't in conflict with either.
select dfunc('Hi');
ERROR: functions with parameter defaults dfunc(integer, integer, integer) and dfunc(integer, integer) are ambiguous
drop function dfunc(int, int, int);
drop function dfunc(int, int);
drop function dfunc(text);
src/test/regress/sql/opr_sanity.sql
View file @
455dffbb
...
...
@@ -62,6 +62,11 @@ SELECT p1.oid, p1.proname
FROM
pg_proc
as
p1
WHERE
prosrc
IS
NULL
OR
prosrc
=
''
OR
prosrc
=
'-'
;
-- pronargdefaults should be 0 iff proargdefaults is null
SELECT
p
.
oid
,
p
.
proname
FROM
pg_proc
AS
p
WHERE
pronargdefaults
<>
0
OR
proargdefaults
IS
NOT
NULL
;
-- probin should be non-empty for C functions, null everywhere else
SELECT
p1
.
oid
,
p1
.
proname
FROM
pg_proc
as
p1
...
...
src/test/regress/sql/polymorphism.sql
View file @
455dffbb
...
...
@@ -480,3 +480,117 @@ select pg_typeof('' || ''); -- text
select
pg_typeof
(
pg_typeof
(
0
));
-- regtype
select
pg_typeof
(
array
[
1
.
2
,
55
.
5
]);
-- numeric[]
select
pg_typeof
(
myleast
(
10
,
1
,
20
,
33
));
-- polymorphic input
-- test functions with parameter defaults
-- test basic functionality
create
function
dfunc
(
a
int
=
1
,
int
=
2
)
returns
int
as
$$
select
$
1
+
$
2
;
$$
language
sql
;
select
dfunc
();
select
dfunc
(
10
);
select
dfunc
(
10
,
20
);
drop
function
dfunc
();
-- fail
drop
function
dfunc
(
int
);
-- fail
drop
function
dfunc
(
int
,
int
);
-- ok
-- fail, gap in arguments with defaults
create
function
dfunc
(
a
int
=
1
,
b
int
)
returns
int
as
$$
select
$
1
+
$
2
;
$$
language
sql
;
-- check implicit coercion
create
function
dfunc
(
a
int
DEFAULT
1
.
0
,
int
DEFAULT
'-1'
)
returns
int
as
$$
select
$
1
+
$
2
;
$$
language
sql
;
select
dfunc
();
create
function
dfunc
(
a
text
DEFAULT
'Hello'
,
b
text
DEFAULT
'World'
)
returns
text
as
$$
select
$
1
||
', '
||
$
2
;
$$
language
sql
;
select
dfunc
();
-- fail; which dfunc should be called? int or text
select
dfunc
(
'Hi'
);
-- ok
select
dfunc
(
'Hi'
,
'City'
);
-- ok
select
dfunc
(
0
);
-- ok
select
dfunc
(
10
,
20
);
-- ok
drop
function
dfunc
(
int
,
int
);
drop
function
dfunc
(
text
,
text
);
create
function
dfunc
(
int
=
1
,
int
=
2
)
returns
int
as
$$
select
2
;
$$
language
sql
;
create
function
dfunc
(
int
=
1
,
int
=
2
,
int
=
3
,
int
=
4
)
returns
int
as
$$
select
4
;
$$
language
sql
;
-- Now, dfunc(nargs = 2) and dfunc(nargs = 4) are ambiguous when called
-- with 0 or 1 arguments. For 2 arguments, a normall call of
-- dfunc(nargs = 2) takes place.
select
dfunc
();
-- fail
select
dfunc
(
1
);
-- fail
select
dfunc
(
1
,
2
);
-- ok
select
dfunc
(
1
,
2
,
3
);
-- ok
select
dfunc
(
1
,
2
,
3
,
4
);
-- ok
drop
function
dfunc
(
int
,
int
);
drop
function
dfunc
(
int
,
int
,
int
,
int
);
-- default values are not allowed for output parameters
create
function
dfunc
(
out
int
=
20
)
returns
int
as
$$
select
1
;
$$
language
sql
;
-- polymorphic parameter test
create
function
dfunc
(
anyelement
=
'World'
::
text
)
returns
text
as
$$
select
'Hello, '
||
$
1
::
text
;
$$
language
sql
;
select
dfunc
();
select
dfunc
(
0
);
select
dfunc
(
to_date
(
'20081215'
,
'YYYYMMDD'
));
select
dfunc
(
'City'
::
text
);
drop
function
dfunc
(
anyelement
);
-- check null values
create
function
dfunc
(
int
=
null
,
int
=
null
,
int
=
null
)
returns
int
[]
as
$$
select
array
[
$
1
,
$
2
,
$
3
];
$$
language
sql
;
select
dfunc
(
1
);
select
dfunc
(
1
,
2
);
select
dfunc
(
1
,
2
,
3
);
drop
function
dfunc
(
int
,
int
,
int
);
-- The conflict detection algorithm doesn't consider the actual parameter
-- types. It detects any possible conflict for n arguments for some
-- function. This is unwanted behavior, but solving it needs a move of
-- coercion routines.
create
function
dfunc
(
int
=
1
,
int
=
2
,
int
=
3
)
returns
int
as
$$
select
3
;
$$
language
sql
;
create
function
dfunc
(
int
=
1
,
int
=
2
)
returns
int
as
$$
select
2
;
$$
language
sql
;
-- for n = 1 dfunc(narg=2) and dfunc(narg=3) are ambiguous
select
dfunc
(
1
);
-- fail
create
function
dfunc
(
text
)
returns
text
as
$$
select
$
1
;
$$
language
sql
;
-- Will fail, it detects ambiguity between dfunc(int, int, int) and
-- dfunc(int, int), but dfunc(text) isn't in conflict with either.
select
dfunc
(
'Hi'
);
drop
function
dfunc
(
int
,
int
,
int
);
drop
function
dfunc
(
int
,
int
);
drop
function
dfunc
(
text
);
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