1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>10.2.Operators</title>
<link rel="stylesheet" href="stylesheet.css" type="text/css">
<link rev="made" href="pgsql-docs@postgresql.org">
<meta name="generator" content="DocBook XSL Stylesheets V1.70.0">
<link rel="start" href="index.html" title="PostgreSQL 8.1.4 Documentation">
<link rel="up" href="typeconv.html" title="Chapter10.Type Conversion">
<link rel="prev" href="typeconv.html" title="Chapter10.Type Conversion">
<link rel="next" href="typeconv-func.html" title="10.3.Functions">
<link rel="copyright" href="ln-legalnotice.html" title="Legal Notice">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="typeconv-oper"></a>10.2.Operators</h2></div></div></div>
<a name="id626376"></a><p> The specific operator to be used in an operator invocation is determined
by following
the procedure below. Note that this procedure is indirectly affected
by the precedence of the involved operators. See <a href="sql-syntax.html#sql-precedence" title="4.1.6.Lexical Precedence">Section4.1.6, “Lexical Precedence”</a> for more information.
</p>
<div class="procedure">
<a name="id626404"></a><p class="title"><b>Operator Type Resolution</b></p>
<ol type="1">
<li>
<p>Select the operators to be considered from the
<code class="classname">pg_operator</code> system catalog. If an unqualified
operator name was used (the usual case), the operators
considered are those of the right name and argument count that are
visible in the current search path (see <a href="ddl-schemas.html#ddl-schemas-path" title="5.7.3.The Schema Search Path">Section5.7.3, “The Schema Search Path”</a>).
If a qualified operator name was given, only operators in the specified
schema are considered.</p>
<ol type="a"><li><p>If the search path finds multiple operators of identical argument types,
only the one appearing earliest in the path is considered. But operators of
different argument types are considered on an equal footing regardless of
search path position.</p></li></ol>
</li>
<li>
<p>Check for an operator accepting exactly the input argument types.
If one exists (there can be only one exact match in the set of
operators considered), use it.</p>
<ol type="a"><li><p>If one argument of a binary operator invocation is of the <code class="type">unknown</code> type,
then assume it is the same type as the other argument for this check.
Other cases involving <code class="type">unknown</code> will never find a match at
this step.</p></li></ol>
</li>
<li>
<p>Look for the best match.</p>
<ol type="a">
<li><p>Discard candidate operators 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><p>Run through all candidates and keep those with the most exact matches
on input types. (Domains are considered the same as their base type
for this purpose.) Keep all candidates if none have any exact matches.
If only one candidate remains, use it; else continue to the next step.</p></li>
<li><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><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 does look 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 at a given argument position,
discard candidates that accept non-preferred types for that argument.</p></li>
<li><p>If only one candidate remains, use it. If no candidate or more than one
candidate remains,
then fail.</p></li>
</ol>
</li>
</ol>
</div>
<p>Some examples follow.</p>
<div class="example">
<a name="id626561"></a><p class="title"><b>Example10.1.Exponentiation Operator Type Resolution</b></p>
<div class="example-contents">
<p>There is only one exponentiation
operator defined in the catalog, and it takes arguments of type
<code class="type">double precision</code>.
The scanner assigns an initial type of <code class="type">integer</code> to both arguments
of this query expression:
</p>
<pre class="screen">SELECT 2 ^ 3 AS "exp";
exp
-----
8
(1 row)</pre>
<p>
So the parser does a type conversion on both operands and the query
is equivalent to
</p>
<pre class="screen">SELECT CAST(2 AS double precision) ^ CAST(3 AS double precision) AS "exp";</pre>
</div>
</div>
<br class="example-break"><div class="example">
<a name="id626595"></a><p class="title"><b>Example10.2.String Concatenation Operator Type Resolution</b></p>
<div class="example-contents">
<p>A string-like syntax is used for working with string types as well as for
working with complex extension types.
Strings with unspecified type are matched with likely operator candidates.</p>
<p>An example with one unspecified argument:
</p>
<pre class="screen">SELECT text 'abc' || 'def' AS "text and unknown";
text and unknown
------------------
abcdef
(1 row)</pre>
<p>In this case the parser looks to see if there is an operator taking <code class="type">text</code>
for both arguments. Since there is, it assumes that the second argument should
be interpreted as of type <code class="type">text</code>.</p>
<p>Here is a concatenation on unspecified types:
</p>
<pre class="screen">SELECT 'abc' || 'def' AS "unspecified";
unspecified
-------------
abcdef
(1 row)</pre>
<p>In this case there is no initial hint for which type to use, since no types
are specified in the query. So, the parser looks for all candidate operators
and finds that there are candidates accepting both string-category and
bit-string-category inputs. Since string category is preferred when available,
that category is selected, and then the
preferred type for strings, <code class="type">text</code>, is used as the specific
type to resolve the unknown literals to.</p>
</div>
</div>
<br class="example-break"><div class="example">
<a name="id626653"></a><p class="title"><b>Example10.3.Absolute-Value and Negation Operator Type Resolution</b></p>
<div class="example-contents">
<p>The <span class="productname">PostgreSQL</span> operator catalog has several
entries for the prefix operator <code class="literal">@</code>, all of which implement
absolute-value operations for various numeric data types. One of these
entries is for type <code class="type">float8</code>, which is the preferred type in
the numeric category. Therefore, <span class="productname">PostgreSQL</span>
will use that entry when faced with a non-numeric input:
</p>
<pre class="screen">SELECT @ '-4.5' AS "abs";
abs
-----
4.5
(1 row)</pre>
<p>
Here the system has performed an implicit conversion from <code class="type">text</code> to <code class="type">float8</code>
before applying the chosen operator. We can verify that <code class="type">float8</code> and
not some other type was used:
</p>
<pre class="screen">SELECT @ '-4.5e500' AS "abs";
ERROR: "-4.5e500" is out of range for type double precision</pre>
<p>On the other hand, the prefix operator <code class="literal">~</code> (bitwise negation)
is defined only for integer data types, not for <code class="type">float8</code>. So, if we
try a similar case with <code class="literal">~</code>, we get:
</p>
<pre class="screen">SELECT ~ '20' AS "negation";
ERROR: operator is not unique: ~ "unknown"
HINT: Could not choose a best candidate operator. You may need to add explicit
type casts.</pre>
<p>
This happens because the system can't decide which of the several
possible <code class="literal">~</code> operators should be preferred. We can help
it out with an explicit cast:
</p>
<pre class="screen">SELECT ~ CAST('20' AS int8) AS "negation";
negation
----------
-21
(1 row)</pre>
</div>
</div>
<br class="example-break">
</div></body>
</html>
|