typeconv.sgml
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:19k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. <chapter Id="typeconv">
  2. <title>Type Conversion</title>
  3. <para>
  4. <acronym>SQL</acronym> queries can, intentionally or not, require
  5. mixing of different data types in the same expression. 
  6. <productname>Postgres</productname> has extensive facilities for
  7. evaluating mixed-type expressions.
  8. </para>
  9. <para>
  10. In many cases a user will not need
  11. to understand the details of the type conversion mechanism.
  12. However, the implicit conversions done by <productname>Postgres</productname>
  13. can affect the apparent results of a query, and these results
  14. can be tailored by a user or programmer
  15. using <emphasis>explicit</emphasis> type coersion.
  16. </para>
  17. <para>
  18. This chapter introduces the <productname>Postgres</productname>
  19.  type conversion mechanisms and conventions.
  20. Refer to the relevant sections in the User's Guide and Programmer's Guide
  21. for more information on specific data types and allowed functions and operators.
  22. </para>
  23. <para>
  24. The Programmer's Guide has more details on the exact algorithms used for
  25. implicit type conversion and coersion.
  26. </para>
  27. <sect1>
  28. <title>Overview</title>
  29. <para>
  30. <acronym>SQL</acronym> is a strongly typed language. That is, every data item
  31. has an associated data type which determines its behavior and allowed usage.
  32. <productname>Postgres</productname> has an extensible type system which is
  33. much more general and flexible than other <acronym>RDBMS</acronym> implementations.
  34. Hence, most type conversion behavior in <productname>Postgres</productname>
  35. should be governed by general rules rather than by ad-hoc heuristics to allow
  36. mixed-type expressions to be meaningful, even with user-defined types.
  37. </para>
  38. <para>
  39. The <productname>Postgres</productname> scanner/parser decodes lexical elements
  40. into only five fundamental categories: integers, floats, strings, names, and keywords.
  41. Most extended types are first tokenized into strings. The <acronym>SQL</acronym>
  42. language definition allows specifying type names with strings, and this mechanism
  43. is used by <productname>Postgres</productname>
  44. to start the parser down the correct path. For example, the query
  45. <programlisting>
  46. tgl=> SELECT text 'Origin' AS "Label", point '(0,0)' AS "Value";
  47. Label |Value
  48. ------+-----
  49. Origin|(0,0)
  50. (1 row)
  51. </programlisting>
  52. has two strings, of type <type>text</type> and <type>point</type>.
  53. If a type is not specified, then the placeholder type <type>unknown</type>
  54. is assigned initially, to be resolved in later stages as described below.
  55. </para>
  56. <para>
  57. There are four fundamental <acronym>SQL</acronym> constructs requiring
  58. distinct type conversion rules in the <productname>Postgres</productname>
  59. parser:
  60. </para>
  61. <variablelist>
  62. <varlistentry>
  63. <term>
  64. Operators
  65. </term>
  66. <listitem>
  67. <para>
  68. <productname>Postgres</productname> allows expressions with
  69. left- and right-unary (one argument) operators,
  70. as well as binary (two argument) operators.
  71. </para>
  72. </listitem>
  73. </varlistentry>
  74. <varlistentry>
  75. <term>
  76. Function calls
  77. </term>
  78. <listitem>
  79. <para>
  80. Much of the <productname>Postgres</productname> type system is built around a rich set of
  81. functions. Function calls have one or more arguments which, for any specific query,
  82. must be matched to the functions available in the system catalog.
  83. </para>
  84. </listitem>
  85. </varlistentry>
  86. <varlistentry>
  87. <term>
  88. Query targets
  89. </term>
  90. <listitem>
  91. <para>
  92. <acronym>SQL</acronym> INSERT statements place the results of query into a table. The expressions
  93. in the query must be matched up with, and perhaps converted to, the target columns of the insert.
  94. </para>
  95. </listitem>
  96. </varlistentry>
  97. <varlistentry>
  98. <term>
  99. UNION queries
  100. </term>
  101. <listitem>
  102. <para>
  103. Since all select results from a UNION SELECT statement must appear in a single set of columns, the types
  104. of each SELECT clause must be matched up and converted to a uniform set.
  105. </para>
  106. </listitem>
  107. </varlistentry>
  108. </variablelist>
  109. <para>
  110. Many of the general type conversion rules use simple conventions built on
  111. the <productname>Postgres</productname> function and operator system tables.
  112. There are some heuristics included in the conversion rules to better support
  113. conventions for the <acronym>SQL92</acronym> standard native types such as
  114. <type>smallint</type>, <type>integer</type>, and <type>float</type>.
  115. </para>
  116. <para>
  117. The <productname>Postgres</productname> parser uses the convention that all
  118. type conversion functions take a single argument of the source type and are
  119. named with the same name as the target type. Any function meeting this
  120. criteria is considered to be a valid conversion function, and may be used
  121. by the parser as such. This simple assumption gives the parser the power
  122. to explore type conversion possibilities without hardcoding, allowing
  123. extended user-defined types to use these same features transparently.
  124. </para>
  125. <para>
  126. An additional heuristic is provided in the parser to allow better guesses
  127. at proper behavior for <acronym>SQL</acronym> standard types. There are
  128. five categories of types defined: boolean, string, numeric, geometric,
  129. and user-defined. Each category, with the exception of user-defined, has
  130. a "preferred type" which is used to resolve ambiguities in candidates.
  131. Each "user-defined" type is its own "preferred type", so ambiguous
  132. expressions (those with multiple candidate parsing solutions)
  133. with only one user-defined type can resolve to a single best choice, while those with
  134. multiple user-defined types will remain ambiguous and throw an error.
  135. </para>
  136. <para>
  137. Ambiguous expressions which have candidate solutions within only one type category are
  138. likely to resolve, while ambiguous expressions with candidates spanning multiple
  139. categories are likely to throw an error and ask for clarification from the user.
  140. </para>
  141. <sect2>
  142. <title>Guidelines</title>
  143. <para>
  144. All type conversion rules are designed with several principles in mind:
  145. <itemizedlist mark="bullet" spacing="compact">
  146. <listitem>
  147. <para>
  148. Implicit conversions should never have suprising or unpredictable outcomes.
  149. </para>
  150. </listitem>
  151. <listitem>
  152. <para>
  153. User-defined types, of which the parser has no apriori knowledge, should be
  154. "higher" in the type heirarchy. In mixed-type expressions, native types shall always
  155. be converted to a user-defined type (of course, only if conversion is necessary).
  156. </para>
  157. </listitem>
  158. <listitem>
  159. <para>
  160. User-defined types are not related. Currently, <productname>Postgres</productname>
  161. does not have information available to it on relationships between types, other than
  162. hardcoded heuristics for built-in types and implicit relationships based on available functions
  163. in the catalog.
  164. </para>
  165. </listitem>
  166. <listitem>
  167. <para>
  168. There should be no extra overhead from the parser or executor
  169. if a query does not need implicit type conversion.
  170. That is, if a query is well formulated and the types already match up, then the query should proceed
  171. without spending extra time in the parser and without introducing unnecessary implicit conversion
  172. functions into the query.
  173. </para>
  174. <para>
  175. Additionally, if a query usually requires an implicit conversion for a function, and
  176. if then the user defines an explicit function with the correct argument types, the parser
  177. should use this new function and will no longer do the implicit conversion using the old function.
  178. </para>
  179. </listitem>
  180. </itemizedlist>
  181. </para>
  182. </sect2>
  183. </sect1>
  184. <sect1>
  185. <title>Operators</title>
  186. <sect2>
  187. <title>Conversion Procedure</title>
  188. <procedure>
  189. <title>Operator Evaluation</title>
  190. <step performance="required">
  191. <para>
  192. Check for an exact match in the pg_operator system catalog.
  193. </para>
  194. <substeps>
  195. <step performance="optional">
  196. <para>
  197. If one argument of a binary operator is <type>unknown</type>,
  198. then assume it is the same type as the other argument.
  199. </para>
  200. </step>
  201. <step performance="required">
  202. <para>
  203. Reverse the arguments, and look for an exact match with an operator which
  204. points to itself as being commutative.
  205. If found, then reverse the arguments in the parse tree and use this operator.
  206. </para>
  207. </step>
  208. </substeps>
  209. </step>
  210. <step performance="required">
  211. <para>
  212. Look for the best match.
  213. </para>
  214. <substeps>
  215. <step performance="optional">
  216. <para>
  217. Make a list of all operators of the same name.
  218. </para>
  219. </step>
  220. <step performance="required">
  221. <para>
  222. If only one operator is in the list, use it if the input type can be coerced,
  223. and throw an error if the type cannot be coerced.
  224. </para>
  225. </step>
  226. <step performance="required">
  227. <para>
  228. Keep all operators with the most explicit matches for types. Keep all if there
  229. are no explicit matches and move to the next step.
  230. If only one candidate remains, use it if the type can be coerced.
  231. </para>
  232. </step>
  233. <step performance="required">
  234. <para>
  235. If any input arguments are "unknown", categorize the input candidates as
  236. boolean, numeric, string, geometric, or user-defined. If there is a mix of
  237. categories, or more than one user-defined type, throw an error because
  238. the correct choice cannot be deduced without more clues.
  239. If only one category is present, then assign the "preferred type"
  240. to the input column which had been previously "unknown".
  241. </para>
  242. </step>
  243. <step performance="required">
  244. <para>
  245. Choose the candidate with the most exact type matches, and which matches
  246. the "preferred type" for each column category from the previous step.
  247. If there is still more than one candidate, or if there are none,
  248. then throw an error.
  249. </para>
  250. </step>
  251. </substeps>
  252. </step>
  253. </procedure>
  254. </sect2>
  255. <sect2>
  256. <title>Examples</title>
  257. <sect3>
  258. <title>Exponentiation Operator</title>
  259. <para>
  260. There is only one exponentiation
  261. operator defined in the catalog, and it takes <type>float8</type> arguments.
  262. The scanner assigns an initial type of <type>int4</type> to both arguments
  263. of this query expression:
  264. <programlisting>
  265. tgl=> select 2 ^ 3 AS "Exp";
  266. Exp
  267. ---
  268.   8
  269. (1 row)
  270. </programlisting>
  271. So the parser does a type conversion on both operands and the query
  272. is equivalent to
  273. <programlisting>
  274. tgl=> select float8(2) ^ float8(3) AS "Exp";
  275. Exp
  276. ---
  277.   8
  278. (1 row)
  279. </programlisting>
  280. or
  281. <programlisting>
  282. tgl=> select 2.0 ^ 3.0 AS "Exp";
  283. Exp
  284. ---
  285.   8
  286. (1 row)
  287. </programlisting>
  288. <note>
  289. <para>
  290. This last form has the least overhead, since no functions are called to do
  291. implicit type conversion. This is not an issue for small queries, but may
  292. have an impact on the performance of queries involving large tables.
  293. </para>
  294. </note>
  295. </para>
  296. </sect3>
  297. <sect3>
  298. <title>String Concatenation</title>
  299. <para>
  300. A string-like syntax is used for working with string types as well as for
  301. working with complex extended types.
  302. Strings with unspecified type are matched with likely operator candidates.
  303. </para>
  304. <para>
  305. One unspecified argument:
  306. <programlisting>
  307. tgl=> SELECT text 'abc' || 'def' AS "Text and Unknown";
  308. Text and Unknown
  309. ----------------
  310. abcdef
  311. (1 row)
  312. </programlisting>
  313. </para>
  314. <para>
  315. In this case the parser looks to see if there is an operator taking <type>text</type>
  316. for both arguments. Since there is, it assumes that the second argument should
  317. be interpreted as of type <type>text</type>.
  318. </para>
  319. <para>
  320. Concatenation on unspecified types:
  321. <programlisting>
  322. tgl=> SELECT 'abc' || 'def' AS "Unspecified";
  323. Unspecified
  324. -----------
  325. abcdef
  326. (1 row)
  327. </programlisting>
  328. </para>
  329. <para>
  330. In this case there is no initial hint for which type to use, since no types
  331. are specified in the query. So, the parser looks for all candidate operators
  332. and finds that all arguments for all the candidates are string types. It chooses
  333. the "preferred type" for strings, <type>text</type>, for this query.
  334. </para>
  335. <note>
  336. <para>
  337. If a user defines a new type and defines an operator <quote>||</quote> to work
  338. with it, then this query would no longer succeed as written. The parser would
  339. now have candidate types from two categories, and could not decide which to use.
  340. </para>
  341. </note>
  342. </sect3>
  343. <sect3>
  344. <title>Factorial</title>
  345. <para>
  346. This example illustrates an interesting result. Traditionally, the
  347. factorial operator is defined for integers only. The <productname>Postgres</productname>
  348. operator catalog has only one entry for factorial, taking an integer operand.
  349. If given a non-integer numeric argument, <productname>Postgres</productname>
  350. will try to convert that argument to an integer for evaluation of the
  351. factorial.
  352. <programlisting>
  353. tgl=> select (4.3 !);
  354. ?column?
  355. --------
  356.       24
  357. (1 row)
  358. </programlisting>
  359. <note>
  360. <para>
  361. Of course, this leads to a mathematically suspect result,
  362. since in principle the factorial of a non-integer is not defined.
  363. However, the role of a database is not to teach mathematics, but
  364. to be a tool for data manipulation. If a user chooses to take the
  365. factorial of a floating point number, <productname>Postgres</productname>
  366. will try to oblige.
  367. </para>
  368. </note>
  369. </para>
  370. </sect3>
  371. </sect2>
  372. </sect1>
  373. <sect1>
  374. <title>Functions</title>
  375. <procedure>
  376. <title>Function Evaluation</title>
  377. <step performance="required">
  378. <para>
  379. Check for an exact match in the pg_proc system catalog.
  380. </para></step>
  381. <step performance="required">
  382. <para>
  383. Look for the best match.
  384. </para>
  385. <substeps>
  386. <step performance="required">
  387. <para>
  388. Make a list of all functions of the same name with the same number of arguments.
  389. </para></step>
  390. <step performance="required">
  391. <para>
  392. If only one function is in the list, use it if the input types can be coerced,
  393. and throw an error if the types cannot be coerced.
  394. </para></step>
  395. <step performance="required">
  396. <para>
  397. Keep all functions with the most explicit matches for types. Keep all if there
  398. are no explicit matches and move to the next step.
  399. If only one candidate remains, use it if the type can be coerced.
  400. </para></step>
  401. <step performance="required">
  402. <para>
  403. If any input arguments are "unknown", categorize the input candidate arguments as
  404. boolean, numeric, string, geometric, or user-defined. If there is a mix of
  405. categories, or more than one user-defined type, throw an error because
  406. the correct choice cannot be deduced without more clues.
  407. If only one category is present, then assign the "preferred type"
  408. to the input column which had been previously "unknown".
  409. </para></step>
  410. <step performance="required">
  411. <para>
  412. Choose the candidate with the most exact type matches, and which matches
  413. the "preferred type" for each column category from the previous step.
  414. If there is still more than one candidate, or if there are none,
  415. then throw an error.
  416. </para></step>
  417. </substeps>
  418. </step>
  419. </procedure>
  420. <sect2>
  421. <title>Examples</title>
  422. <sect3>
  423. <title>Factorial Function</title>
  424. <para>
  425. There is only one factorial function defined in the pg_proc catalog.
  426. So the following query automatically converts the <type>int2</type> argument
  427. to <type>int4</type>:
  428. <programlisting>
  429. tgl=> select int4fac(int2 '4');
  430. int4fac
  431. -------
  432.      24
  433. (1 row)
  434. </programlisting>
  435. and is actually transformed by the parser to
  436. <programlisting>
  437. tgl=> select int4fac(int4(int2 '4'));
  438. int4fac
  439. -------
  440.      24
  441. (1 row)
  442. </programlisting>
  443. </para>
  444. </sect3>
  445. <sect3>
  446. <title>Substring Function</title>
  447. <para>
  448. There are two <function>substr</function> functions declared in pg_proc. However,
  449. only one takes two arguments, of types <type>text</type> and <type>int4</type>.
  450. </para>
  451. <para>
  452. If called with a string constant of unspecified type, the type is matched up
  453. directly with the only candidate function type:
  454. <programlisting>
  455. tgl=> select substr('1234', 3);
  456. substr
  457. ------
  458.     34
  459. (1 row)
  460. </programlisting>
  461. </para>
  462. <para>
  463. If the string is declared to be of type <type>varchar</type>, as might be the case
  464. if it comes from a table, then the parser will try to coerce it to become <type>text</type>:
  465. <programlisting>
  466. tgl=> select substr(varchar '1234', 3);
  467. substr
  468. ------
  469.     34
  470. (1 row)
  471. </programlisting>
  472. which is transformed by the parser to become
  473. <programlisting>
  474. tgl=> select substr(text(varchar '1234'), 3);
  475. substr
  476. ------
  477.     34
  478. (1 row)
  479. </programlisting>
  480. </para>
  481. <note>
  482. <para>
  483. There are some heuristics in the parser to optimize the relationship between the
  484. <type>char</type>, <type>varchar</type>, and <type>text</type> types.
  485. For this case, <function>substr</function> is called directly with the <type>varchar</type> string
  486. rather than inserting an explicit conversion call.
  487. </para>
  488. </note>
  489. <para>
  490. And, if the function is called with an <type>int4</type>, the parser will
  491. try to convert that to <type>text</type>:
  492. <programlisting>
  493. tgl=> select substr(1234, 3);
  494. substr
  495. ------
  496.     34
  497. (1 row)
  498. </programlisting>
  499. actually executes as
  500. <programlisting>
  501. tgl=> select substr(text(1234), 3);
  502. substr
  503. ------
  504.     34
  505. (1 row)
  506. </programlisting>
  507. </para>
  508. </sect3>
  509. </sect2>
  510. </sect1>
  511. <sect1>
  512. <title>Query Targets</title>
  513. <procedure>
  514. <title>Target Evaluation</title>
  515. <step performance="required">
  516. <para>
  517. Check for an exact match with the target.
  518. </para></step>
  519. <step performance="required">
  520. <para>
  521. Try to coerce the expression directly to the target type if necessary.
  522. </para></step>
  523. <step performance="required">
  524. <para>
  525. If the target is a fixed-length type (e.g. <type>char</type> or <type>varchar</type>
  526. declared with a length) then try to find a sizing function of the same name
  527. as the type taking two arguments, the first the type name and the second an
  528. integer length.
  529. </para></step>
  530. </procedure>
  531. <sect2>
  532. <title>Examples</title>
  533. <sect3>
  534. <title><type>varchar</type> Storage</title>
  535. <para>
  536. For a target column declared as <type>varchar(4)</type> the following query
  537. ensures that the target is sized correctly:
  538. <programlisting>
  539. tgl=> CREATE TABLE vv (v varchar(4));
  540. CREATE
  541. tgl=> INSERT INTO vv SELECT 'abc' || 'def';
  542. INSERT 392905 1
  543. tgl=> select * from vv;
  544. v
  545. ----
  546. abcd
  547. (1 row)
  548. </programlisting>
  549. </para>
  550. </sect3>
  551. </sect2>
  552. </sect1>
  553. <sect1>
  554. <title>UNION Queries</title>
  555. <para>
  556. The UNION construct is somewhat different in that it must match up
  557. possibly dissimilar types to become a single result set.
  558. </para>
  559. <procedure>
  560. <title>UNION Evaluation</title>
  561. <step performance="required">
  562. <para>
  563. Check for identical types for all results.
  564. </para></step>
  565. <step performance="required">
  566. <para>
  567. Coerce each result from the UNION clauses to match the type of the
  568. first SELECT clause or the target column.
  569. </para></step>
  570. </procedure>
  571. <sect2>
  572. <title>Examples</title>
  573. <sect3>
  574. <title>Underspecified Types</title>
  575. <para>
  576. <programlisting>
  577. tgl=> SELECT text 'a' AS "Text" UNION SELECT 'b';
  578. Text
  579. ----
  580. a
  581. b
  582. (2 rows)
  583. </programlisting>
  584. </para>
  585. </sect3>
  586. <sect3>
  587. <title>Simple UNION</title>
  588. <para>
  589. <programlisting>
  590. tgl=> SELECT 1.2 AS Float8 UNION SELECT 1;
  591. Float8
  592. ------
  593.      1
  594.    1.2
  595. (2 rows)
  596. </programlisting>
  597. </para>
  598. </sect3>
  599. <sect3>
  600. <title>Transposed UNION</title>
  601. <para>
  602. The types of the union are forced to match the types of
  603. the first/top clause in the union:
  604. <programlisting>
  605. tgl=> SELECT 1 AS "All integers"
  606. tgl-> UNION SELECT '2.2'::float4
  607. tgl-> UNION SELECT 3.3;
  608. All integers
  609. ------------
  610.            1
  611.            2
  612.            3
  613. (3 rows)
  614. </programlisting>
  615. </para>
  616. <para>
  617. An alternate parser strategy could be to choose the "best" type of the bunch, but
  618. this is more difficult because of the nice recursion technique used in the
  619. parser. However, the "best" type is used when selecting <emphasis>into</emphasis>
  620. a table:
  621. <programlisting>
  622. tgl=> CREATE TABLE ff (f float);
  623. CREATE
  624. tgl=> INSERT INTO ff
  625. tgl-> SELECT 1
  626. tgl-> UNION SELECT '2.2'::float4
  627. tgl-> UNION SELECT 3.3;
  628. INSERT 0 3
  629. tgl=> SELECT f AS "Floating point" from ff;
  630.   Floating point
  631. ----------------
  632.                1
  633. 2.20000004768372
  634.              3.3
  635. (3 rows)
  636. </programlisting>
  637. </para>
  638. </sect3>
  639. </sect2>
  640. </sect1>
  641. </chapter>