1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <!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.2. Operators</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-overview.html" title="10.1. Overview" /><link rel="next" href="typeconv-func.html" title="10.3. Functions" /></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.2. Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="typeconv-overview.html" title="10.1. Overview">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 18.0 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="typeconv-func.html" title="10.3. Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="TYPECONV-OPER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">10.2. Operators <a href="#TYPECONV-OPER" class="id_link">#</a></h2></div></div></div><a id="id-1.5.9.7.2" class="indexterm"></a><p>
3 The specific operator that is referenced by an operator expression
4 is determined using the following procedure.
5 Note that this procedure is indirectly affected
6 by the precedence of the operators involved, since that will determine
7 which sub-expressions are taken to be the inputs of which operators.
8 See <a class="xref" href="sql-syntax-lexical.html#SQL-PRECEDENCE" title="4.1.6. Operator Precedence">Section 4.1.6</a> for more information.
9 </p><div class="procedure" id="id-1.5.9.7.4"><p class="title"><strong>Operator Type Resolution</strong></p><ol class="procedure" type="1"><li class="step" id="OP-RESOL-SELECT"><p>
10 Select the operators to be considered from the
11 <code class="classname">pg_operator</code> system catalog. If a non-schema-qualified
12 operator name was used (the usual case), the operators
13 considered are those with the matching name and argument count that are
14 visible in the current search path (see <a class="xref" href="ddl-schemas.html#DDL-SCHEMAS-PATH" title="5.10.3. The Schema Search Path">Section 5.10.3</a>).
15 If a qualified operator name was given, only operators in the specified
16 schema are considered.
17 </p><ol type="a" class="substeps"><li class="step"><p>
18 If the search path finds multiple operators with identical argument types,
19 only the one appearing earliest in the path is considered. Operators with
20 different argument types are considered on an equal footing regardless of
22 </p></li></ol></li><li class="step" id="OP-RESOL-EXACT-MATCH"><p>
23 Check for an operator accepting exactly the input argument types.
24 If one exists (there can be only one exact match in the set of
25 operators considered), use it. Lack of an exact match creates a security
26 hazard when calling, via qualified name
27 <a href="#ftn.OP-QUALIFIED-SECURITY" class="footnote"><sup class="footnote" id="OP-QUALIFIED-SECURITY">[9]</sup></a>
28 (not typical), any operator found in a schema that permits untrusted users to
29 create objects. In such situations, cast arguments to force an exact match.
30 </p><ol type="a" class="substeps"><li class="step" id="OP-RESOL-EXACT-UNKNOWN"><p>
31 If one argument of a binary operator invocation is of the <code class="type">unknown</code> type,
32 then assume it is the same type as the other argument for this check.
33 Invocations involving two <code class="type">unknown</code> inputs, or a prefix operator
34 with an <code class="type">unknown</code> input, will never find a match at this step.
35 </p></li><li class="step" id="OP-RESOL-EXACT-DOMAIN"><p>
36 If one argument of a binary operator invocation is of the <code class="type">unknown</code>
37 type and the other is of a domain type, next check to see if there is an
38 operator accepting exactly the domain's base type on both sides; if so, use it.
39 </p></li></ol></li><li class="step" id="OP-RESOL-BEST-MATCH"><p>
40 Look for the best match.
41 </p><ol type="a" class="substeps"><li class="step"><p>
42 Discard candidate operators for which the input types do not match
43 and cannot be converted (using an implicit conversion) to match.
44 <code class="type">unknown</code> literals are
45 assumed to be convertible to anything for this purpose. If only one
46 candidate remains, use it; else continue to the next step.
47 </p></li><li class="step"><p>
48 If any input argument is of a domain type, treat it as being of the
49 domain's base type for all subsequent steps. This ensures that domains
50 act like their base types for purposes of ambiguous-operator resolution.
51 </p></li><li class="step"><p>
52 Run through all candidates and keep those with the most exact matches
53 on input types. Keep all candidates if none have exact matches.
54 If only one candidate remains, use it; else continue to the next step.
55 </p></li><li class="step"><p>
56 Run through all candidates and keep those that accept preferred types (of the
57 input data type's type category) at the most positions where type conversion
59 Keep all candidates if none accept preferred types.
60 If only one candidate remains, use it; else continue to the next step.
61 </p></li><li class="step"><p>
62 If any input arguments are <code class="type">unknown</code>, check the type
63 categories accepted at those argument positions by the remaining
64 candidates. At each position, select the <code class="type">string</code> category
66 candidate accepts that category. (This bias towards string is appropriate
67 since an unknown-type literal looks like a string.) Otherwise, if
68 all the remaining candidates accept the same type category, select that
69 category; otherwise fail because the correct choice cannot be deduced
70 without more clues. Now discard
71 candidates that do not accept the selected type category. Furthermore,
72 if any candidate accepts a preferred type in that category,
73 discard candidates that accept non-preferred types for that argument.
74 Keep all candidates if none survive these tests.
75 If only one candidate remains, use it; else continue to the next step.
76 </p></li><li class="step" id="OP-RESOL-LAST-UNKNOWN"><p>
77 If there are both <code class="type">unknown</code> and known-type arguments, and all
78 the known-type arguments have the same type, assume that the
79 <code class="type">unknown</code> arguments are also of that type, and check which
80 candidates can accept that type at the <code class="type">unknown</code>-argument
81 positions. If exactly one candidate passes this test, use it.
83 </p></li></ol></li></ol></div><p>
85 </p><div class="example" id="id-1.5.9.7.6"><p class="title"><strong>Example 10.1. Square Root Operator Type Resolution</strong></p><div class="example-contents"><p>
86 There is only one square root operator (prefix <code class="literal">|/</code>)
87 defined in the standard catalog, and it takes an argument of type
88 <code class="type">double precision</code>.
89 The scanner assigns an initial type of <code class="type">integer</code> to the argument
90 in this query expression:
91 </p><pre class="screen">
92 SELECT |/ 40 AS "square root of 40";
99 So the parser does a type conversion on the operand and the query
102 </p><pre class="screen">
103 SELECT |/ CAST(40 AS double precision) AS "square root of 40";
105 </p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.7.7"><p class="title"><strong>Example 10.2. String Concatenation Operator Type Resolution</strong></p><div class="example-contents"><p>
106 A string-like syntax is used for working with string types and for
107 working with complex extension types.
108 Strings with unspecified type are matched with likely operator candidates.
110 An example with one unspecified argument:
111 </p><pre class="screen">
112 SELECT text 'abc' || 'def' AS "text and unknown";
120 In this case the parser looks to see if there is an operator taking <code class="type">text</code>
121 for both arguments. Since there is, it assumes that the second argument should
122 be interpreted as type <code class="type">text</code>.
124 Here is a concatenation of two values of unspecified types:
125 </p><pre class="screen">
126 SELECT 'abc' || 'def' AS "unspecified";
134 In this case there is no initial hint for which type to use, since no types
135 are specified in the query. So, the parser looks for all candidate operators
136 and finds that there are candidates accepting both string-category and
137 bit-string-category inputs. Since string category is preferred when available,
138 that category is selected, and then the
139 preferred type for strings, <code class="type">text</code>, is used as the specific
140 type to resolve the unknown-type literals as.
141 </p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.7.8"><p class="title"><strong>Example 10.3. Absolute-Value and Negation Operator Type Resolution</strong></p><div class="example-contents"><p>
142 The <span class="productname">PostgreSQL</span> operator catalog has several
143 entries for the prefix operator <code class="literal">@</code>, all of which implement
144 absolute-value operations for various numeric data types. One of these
145 entries is for type <code class="type">float8</code>, which is the preferred type in
146 the numeric category. Therefore, <span class="productname">PostgreSQL</span>
147 will use that entry when faced with an <code class="type">unknown</code> input:
148 </p><pre class="screen">
149 SELECT @ '-4.5' AS "abs";
155 Here the system has implicitly resolved the unknown-type literal as type
156 <code class="type">float8</code> before applying the chosen operator. We can verify that
157 <code class="type">float8</code> and not some other type was used:
158 </p><pre class="screen">
159 SELECT @ '-4.5e500' AS "abs";
161 ERROR: "-4.5e500" is out of range for type double precision
164 On the other hand, the prefix operator <code class="literal">~</code> (bitwise negation)
165 is defined only for integer data types, not for <code class="type">float8</code>. So, if we
166 try a similar case with <code class="literal">~</code>, we get:
167 </p><pre class="screen">
168 SELECT ~ '20' AS "negation";
170 ERROR: operator is not unique: ~ "unknown"
171 HINT: Could not choose a best candidate operator. You might need to add
174 This happens because the system cannot decide which of the several
175 possible <code class="literal">~</code> operators should be preferred. We can help
176 it out with an explicit cast:
177 </p><pre class="screen">
178 SELECT ~ CAST('20' AS int8) AS "negation";
185 </p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.7.9"><p class="title"><strong>Example 10.4. Array Inclusion Operator Type Resolution</strong></p><div class="example-contents"><p>
186 Here is another example of resolving an operator with one known and one
188 </p><pre class="screen">
189 SELECT array[1,2] <@ '{1,2,3}' as "is subset";
196 The <span class="productname">PostgreSQL</span> operator catalog has several
197 entries for the infix operator <code class="literal"><@</code>, but the only two that
198 could possibly accept an integer array on the left-hand side are
199 array inclusion (<code class="type">anyarray</code> <code class="literal"><@</code> <code class="type">anyarray</code>)
200 and range inclusion (<code class="type">anyelement</code> <code class="literal"><@</code> <code class="type">anyrange</code>).
201 Since none of these polymorphic pseudo-types (see <a class="xref" href="datatype-pseudo.html" title="8.21. Pseudo-Types">Section 8.21</a>) are considered preferred, the parser cannot
202 resolve the ambiguity on that basis.
203 However, <a class="xref" href="typeconv-oper.html#OP-RESOL-LAST-UNKNOWN" title="Step 3.f">Step 3.f</a> tells
204 it to assume that the unknown-type literal is of the same type as the other
205 input, that is, integer array. Now only one of the two operators can match,
206 so array inclusion is selected. (Had range inclusion been selected, we would
207 have gotten an error, because the string does not have the right format to be
209 </p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.7.10"><p class="title"><strong>Example 10.5. Custom Operator on a Domain Type</strong></p><div class="example-contents"><p>
210 Users sometimes try to declare operators applying just to a domain type.
211 This is possible but is not nearly as useful as it might seem, because the
212 operator resolution rules are designed to select operators applying to the
213 domain's base type. As an example consider
214 </p><pre class="screen">
215 CREATE DOMAIN mytext AS text CHECK(...);
216 CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...;
217 CREATE OPERATOR = (procedure=mytext_eq_text, leftarg=mytext, rightarg=text);
218 CREATE TABLE mytable (val mytext);
220 SELECT * FROM mytable WHERE val = 'foo';
222 This query will not use the custom operator. The parser will first see if
223 there is a <code class="type">mytext</code> <code class="literal">=</code> <code class="type">mytext</code> operator
224 (<a class="xref" href="typeconv-oper.html#OP-RESOL-EXACT-UNKNOWN" title="Step 2.a">Step 2.a</a>), which there is not;
225 then it will consider the domain's base type <code class="type">text</code>, and see if
226 there is a <code class="type">text</code> <code class="literal">=</code> <code class="type">text</code> operator
227 (<a class="xref" href="typeconv-oper.html#OP-RESOL-EXACT-DOMAIN" title="Step 2.b">Step 2.b</a>), which there is;
228 so it resolves the <code class="type">unknown</code>-type literal as <code class="type">text</code> and
229 uses the <code class="type">text</code> <code class="literal">=</code> <code class="type">text</code> operator.
230 The only way to get the custom operator to be used is to explicitly cast
232 </p><pre class="screen">
233 SELECT * FROM mytable WHERE val = text 'foo';
235 so that the <code class="type">mytext</code> <code class="literal">=</code> <code class="type">text</code> operator is found
236 immediately according to the exact-match rule. If the best-match rules
237 are reached, they actively discriminate against operators on domain types.
238 If they did not, such an operator would create too many ambiguous-operator
239 failures, because the casting rules always consider a domain as castable
240 to or from its base type, and so the domain operator would be considered
241 usable in all the same cases as a similarly-named operator on the base type.
242 </p></div></div><br class="example-break" /><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.OP-QUALIFIED-SECURITY" class="footnote"><p><a href="#OP-QUALIFIED-SECURITY" class="para"><sup class="para">[9] </sup></a>
243 The hazard does not arise with a non-schema-qualified name, because a
244 search path containing schemas that permit untrusted users to create
245 objects is not a <a class="link" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.10.6. Usage Patterns">secure schema usage
247 </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-overview.html" title="10.1. Overview">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-func.html" title="10.3. Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">10.1. Overview </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 10.3. Functions</td></tr></table></div></body></html>