diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:17:33 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:17:33 +0000 |
commit | 5e45211a64149b3c659b90ff2de6fa982a5a93ed (patch) | |
tree | 739caf8c461053357daa9f162bef34516c7bf452 /doc/src/sgml/html/typeconv-func.html | |
parent | Initial commit. (diff) | |
download | postgresql-15-5e45211a64149b3c659b90ff2de6fa982a5a93ed.tar.xz postgresql-15-5e45211a64149b3c659b90ff2de6fa982a5a93ed.zip |
Adding upstream version 15.5.upstream/15.5
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/src/sgml/html/typeconv-func.html')
-rw-r--r-- | doc/src/sgml/html/typeconv-func.html | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/doc/src/sgml/html/typeconv-func.html b/doc/src/sgml/html/typeconv-func.html new file mode 100644 index 0000000..63be92a --- /dev/null +++ b/doc/src/sgml/html/typeconv-func.html @@ -0,0 +1,268 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>10.3. Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="typeconv-oper.html" title="10.2. Operators" /><link rel="next" href="typeconv-query.html" title="10.4. Value Storage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">10.3. Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="typeconv-oper.html" title="10.2. Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><th width="60%" align="center">Chapter 10. Type Conversion</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.5 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="typeconv-query.html" title="10.4. Value Storage">Next</a></td></tr></table><hr /></div><div class="sect1" id="TYPECONV-FUNC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">10.3. Functions</h2></div></div></div><a id="id-1.5.9.8.2" class="indexterm"></a><p> + The specific function that is referenced by a function call + is determined using the following procedure. + </p><div class="procedure" id="id-1.5.9.8.4"><p class="title"><strong>Function Type Resolution</strong></p><ol class="procedure" type="1"><li class="step"><p> +Select the functions to be considered from the +<code class="classname">pg_proc</code> system catalog. If a non-schema-qualified +function name was used, the functions +considered are those with the matching name and argument count that are +visible in the current search path (see <a class="xref" href="ddl-schemas.html#DDL-SCHEMAS-PATH" title="5.9.3. The Schema Search Path">Section 5.9.3</a>). +If a qualified function name was given, only functions in the specified +schema are considered. +</p><ol type="a" class="substeps"><li class="step"><p> +If the search path finds multiple functions of identical argument types, +only the one appearing earliest in the path is considered. Functions of +different argument types are considered on an equal footing regardless of +search path position. +</p></li><li class="step"><p> +If a function is declared with a <code class="literal">VARIADIC</code> array parameter, and +the call does not use the <code class="literal">VARIADIC</code> keyword, then the function +is treated as if the array parameter were replaced by one or more occurrences +of its element type, as needed to match the call. After such expansion the +function might have effective argument types identical to some non-variadic +function. In that case the function appearing earlier in the search path is +used, or if the two functions are in the same schema, the non-variadic one is +preferred. +</p><p> +This creates a security hazard when calling, via qualified name + <a href="#ftn.FUNC-QUALIFIED-SECURITY" class="footnote"><sup class="footnote" id="FUNC-QUALIFIED-SECURITY">[10]</sup></a>, +a variadic function found in a schema that permits untrusted users to create +objects. A malicious user can take control and execute arbitrary SQL +functions as though you executed them. Substitute a call bearing +the <code class="literal">VARIADIC</code> keyword, which bypasses this hazard. Calls +populating <code class="literal">VARIADIC "any"</code> parameters often have no +equivalent formulation containing the <code class="literal">VARIADIC</code> keyword. To +issue those calls safely, the function's schema must permit only trusted users +to create objects. +</p></li><li class="step"><p> +Functions that have default values for parameters are considered to match any +call that omits zero or more of the defaultable parameter positions. If more +than one such function matches a call, the one appearing earliest in the +search path is used. If there are two or more such functions in the same +schema with identical parameter types in the non-defaulted positions (which is +possible if they have different sets of defaultable parameters), the system +will not be able to determine which to prefer, and so an <span class="quote">“<span class="quote">ambiguous +function call</span>”</span> error will result if no better match to the call can be +found. +</p><p> +This creates an availability hazard when calling, via qualified +name<a href="typeconv-func.html#ftn.FUNC-QUALIFIED-SECURITY" class="footnoteref"><sup class="footnoteref">[10]</sup></a>, any function found in a +schema that permits untrusted users to create objects. A malicious user can +create a function with the name of an existing function, replicating that +function's parameters and appending novel parameters having default values. +This precludes new calls to the original function. To forestall this hazard, +place functions in schemas that permit only trusted users to create objects. +</p></li></ol></li><li class="step"><p> +Check for a function accepting exactly the input argument types. +If one exists (there can be only one exact match in the set of +functions considered), use it. Lack of an exact match creates a security +hazard when calling, via qualified +name<a href="typeconv-func.html#ftn.FUNC-QUALIFIED-SECURITY" class="footnoteref"><sup class="footnoteref">[10]</sup></a>, a function found in a +schema that permits untrusted users to create objects. In such situations, +cast arguments to force an exact match. (Cases involving <code class="type">unknown</code> +will never find a match at this step.) +</p></li><li class="step"><p> +If no exact match is found, see if the function call appears +to be a special type conversion request. This happens if the function call +has just one argument and the function name is the same as the (internal) +name of some data type. Furthermore, the function argument must be either +an unknown-type literal, or a type that is binary-coercible to the named +data type, or a type that could be converted to the named data type by +applying that type's I/O functions (that is, the conversion is either to or +from one of the standard string types). When these conditions are met, +the function call is treated as a form of <code class="literal">CAST</code> specification. + <a href="#ftn.id-1.5.9.8.4.4.1.2" class="footnote"><sup class="footnote" id="id-1.5.9.8.4.4.1.2">[11]</sup></a> +</p></li><li class="step"><p> +Look for the best match. +</p><ol type="a" class="substeps"><li class="step"><p> +Discard candidate functions for which the input types do not match +and cannot be converted (using an implicit conversion) to match. +<code class="type">unknown</code> literals are +assumed to be convertible to anything for this purpose. If only one +candidate remains, use it; else continue to the next step. +</p></li><li class="step"><p> +If any input argument is of a domain type, treat it as being of the +domain's base type for all subsequent steps. This ensures that domains +act like their base types for purposes of ambiguous-function resolution. +</p></li><li class="step"><p> +Run through all candidates and keep those with the most exact matches +on input types. Keep all candidates if none have exact matches. +If only one candidate remains, use it; else continue to the next step. +</p></li><li class="step"><p> +Run through all candidates and keep those that accept preferred types (of the +input data type's type category) at the most positions where type conversion +will be required. +Keep all candidates if none accept preferred types. +If only one candidate remains, use it; else continue to the next step. +</p></li><li class="step"><p> +If any input arguments are <code class="type">unknown</code>, check the type categories +accepted +at those argument positions by the remaining candidates. At each position, +select the <code class="type">string</code> category if any candidate accepts that category. +(This bias towards string +is appropriate since an unknown-type literal looks like a string.) +Otherwise, if all the remaining candidates accept the same type category, +select that category; otherwise fail because +the correct choice cannot be deduced without more clues. +Now discard candidates that do not accept the selected type category. +Furthermore, if any candidate accepts a preferred type in that category, +discard candidates that accept non-preferred types for that argument. +Keep all candidates if none survive these tests. +If only one candidate remains, use it; else continue to the next step. +</p></li><li class="step"><p> +If there are both <code class="type">unknown</code> and known-type arguments, and all +the known-type arguments have the same type, assume that the +<code class="type">unknown</code> arguments are also of that type, and check which +candidates can accept that type at the <code class="type">unknown</code>-argument +positions. If exactly one candidate passes this test, use it. +Otherwise, fail. +</p></li></ol></li></ol></div><p> +Note that the <span class="quote">“<span class="quote">best match</span>”</span> rules are identical for operator and +function type resolution. +Some examples follow. +</p><div class="example" id="id-1.5.9.8.6"><p class="title"><strong>Example 10.6. Rounding Function Argument Type Resolution</strong></p><div class="example-contents"><p> +There is only one <code class="function">round</code> function that takes two +arguments; it takes a first argument of type <code class="type">numeric</code> and +a second argument of type <code class="type">integer</code>. +So the following query automatically converts +the first argument of type <code class="type">integer</code> to +<code class="type">numeric</code>: + +</p><pre class="screen"> +SELECT round(4, 4); + + round +-------- + 4.0000 +(1 row) +</pre><p> + +That query is actually transformed by the parser to: +</p><pre class="screen"> +SELECT round(CAST (4 AS numeric), 4); +</pre><p> +</p><p> +Since numeric constants with decimal points are initially assigned the +type <code class="type">numeric</code>, the following query will require no type +conversion and therefore might be slightly more efficient: +</p><pre class="screen"> +SELECT round(4.0, 4); +</pre><p> +</p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.8.7"><p class="title"><strong>Example 10.7. Variadic Function Resolution</strong></p><div class="example-contents"><p> +</p><pre class="screen"> +CREATE FUNCTION public.variadic_example(VARIADIC numeric[]) RETURNS int + LANGUAGE sql AS 'SELECT 1'; +CREATE FUNCTION +</pre><p> + +This function accepts, but does not require, the VARIADIC keyword. It +tolerates both integer and numeric arguments: + +</p><pre class="screen"> +SELECT public.variadic_example(0), + public.variadic_example(0.0), + public.variadic_example(VARIADIC array[0.0]); + variadic_example | variadic_example | variadic_example +------------------+------------------+------------------ + 1 | 1 | 1 +(1 row) +</pre><p> + +However, the first and second calls will prefer more-specific functions, if +available: + +</p><pre class="screen"> +CREATE FUNCTION public.variadic_example(numeric) RETURNS int + LANGUAGE sql AS 'SELECT 2'; +CREATE FUNCTION + +CREATE FUNCTION public.variadic_example(int) RETURNS int + LANGUAGE sql AS 'SELECT 3'; +CREATE FUNCTION + +SELECT public.variadic_example(0), + public.variadic_example(0.0), + public.variadic_example(VARIADIC array[0.0]); + variadic_example | variadic_example | variadic_example +------------------+------------------+------------------ + 3 | 2 | 1 +(1 row) +</pre><p> + +Given the default configuration and only the first function existing, the +first and second calls are insecure. Any user could intercept them by +creating the second or third function. By matching the argument type exactly +and using the <code class="literal">VARIADIC</code> keyword, the third call is secure. +</p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.8.8"><p class="title"><strong>Example 10.8. Substring Function Type Resolution</strong></p><div class="example-contents"><p> +There are several <code class="function">substr</code> functions, one of which +takes types <code class="type">text</code> and <code class="type">integer</code>. If called +with a string constant of unspecified type, the system chooses the +candidate function that accepts an argument of the preferred category +<code class="literal">string</code> (namely of type <code class="type">text</code>). + +</p><pre class="screen"> +SELECT substr('1234', 3); + + substr +-------- + 34 +(1 row) +</pre><p> +</p><p> +If the string is declared to be of type <code class="type">varchar</code>, as might be the case +if it comes from a table, then the parser will try to convert it to become <code class="type">text</code>: +</p><pre class="screen"> +SELECT substr(varchar '1234', 3); + + substr +-------- + 34 +(1 row) +</pre><p> + +This is transformed by the parser to effectively become: +</p><pre class="screen"> +SELECT substr(CAST (varchar '1234' AS text), 3); +</pre><p> +</p><p> +</p><div class="note"><h3 class="title">Note</h3><p> +The parser learns from the <code class="structname">pg_cast</code> catalog that +<code class="type">text</code> and <code class="type">varchar</code> +are binary-compatible, meaning that one can be passed to a function that +accepts the other without doing any physical conversion. Therefore, no +type conversion call is really inserted in this case. +</p></div><p> +</p><p> +And, if the function is called with an argument of type <code class="type">integer</code>, +the parser will try to convert that to <code class="type">text</code>: +</p><pre class="screen"> +SELECT substr(1234, 3); +ERROR: function substr(integer, integer) does not exist +HINT: No function matches the given name and argument types. You might need +to add explicit type casts. +</pre><p> + +This does not work because <code class="type">integer</code> does not have an implicit cast +to <code class="type">text</code>. An explicit cast will work, however: +</p><pre class="screen"> +SELECT substr(CAST (1234 AS text), 3); + + substr +-------- + 34 +(1 row) +</pre><p> +</p></div></div><br class="example-break" /><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.FUNC-QUALIFIED-SECURITY" class="footnote"><p><a href="#FUNC-QUALIFIED-SECURITY" class="para"><sup class="para">[10] </sup></a> + The hazard does not arise with a non-schema-qualified name, because a + search path containing schemas that permit untrusted users to create + objects is not a <a class="link" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.9.6. Usage Patterns">secure schema usage + pattern</a>. + </p></div><div id="ftn.id-1.5.9.8.4.4.1.2" class="footnote"><p><a href="#id-1.5.9.8.4.4.1.2" class="para"><sup class="para">[11] </sup></a> + The reason for this step is to support function-style cast specifications + in cases where there is not an actual cast function. If there is a cast + function, it is conventionally named after its output type, and so there + is no need to have a special case. See + <a class="xref" href="sql-createcast.html" title="CREATE CAST"><span class="refentrytitle">CREATE CAST</span></a> + for additional commentary. + </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="typeconv-oper.html" title="10.2. Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="typeconv-query.html" title="10.4. Value Storage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">10.2. Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.5 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 10.4. Value Storage</td></tr></table></div></body></html>
\ No newline at end of file |