Sophie

Sophie

distrib > Mandriva > current > i586 > by-pkgid > 0c4c6d655e53170864975423b832d491 > files > 261

postgresql8.5-docs-8.5-0.alpha3.1mdv2010.1.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>hstore</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REV="MADE"
HREF="mailto:pgsql-docs@postgresql.org"><LINK
REL="HOME"
TITLE="PostgreSQL 8.5alpha3 Documentation"
HREF="index.html"><LINK
REL="UP"
TITLE="Additional Supplied Modules"
HREF="contrib.html"><LINK
REL="PREVIOUS"
TITLE="fuzzystrmatch"
HREF="fuzzystrmatch.html"><LINK
REL="NEXT"
TITLE="intagg"
HREF="intagg.html"><LINK
REL="STYLESHEET"
TYPE="text/css"
HREF="stylesheet.css"><META
HTTP-EQUIV="Content-Type"
CONTENT="text/html; charset=ISO-8859-1"><META
NAME="creation"
CONTENT="2010-04-15T09:31:23"></HEAD
><BODY
CLASS="SECT1"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="5"
ALIGN="center"
VALIGN="bottom"
><A
HREF="index.html"
>PostgreSQL 8.5alpha3 Documentation</A
></TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="top"
><A
TITLE="fuzzystrmatch"
HREF="fuzzystrmatch.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="top"
><A
TITLE="Additional Supplied Modules"
HREF="contrib.html"
>Fast Backward</A
></TD
><TD
WIDTH="60%"
ALIGN="center"
VALIGN="bottom"
>Appendix F. Additional Supplied Modules</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="top"
><A
TITLE="Additional Supplied Modules"
HREF="contrib.html"
>Fast Forward</A
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="top"
><A
TITLE="intagg"
HREF="intagg.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="HSTORE"
>F.13. hstore</A
></H1
><P
>  This module implements the <TT
CLASS="TYPE"
>hstore</TT
> data type for storing sets of
  key/value pairs within a single <SPAN
CLASS="PRODUCTNAME"
>PostgreSQL</SPAN
> value.
  This can be useful in various scenarios, such as rows with many attributes
  that are rarely examined, or semi-structured data.  Keys and values are
  simply text strings.
 </P
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN114395"
>F.13.1. <TT
CLASS="TYPE"
>hstore</TT
> External Representation</A
></H2
><P
>&#13;   The text representation of an <TT
CLASS="TYPE"
>hstore</TT
>, used for input and output,
   includes zero or more <TT
CLASS="REPLACEABLE"
><I
>key</I
></TT
> <TT
CLASS="LITERAL"
>=&gt;</TT
>
   <TT
CLASS="REPLACEABLE"
><I
>value</I
></TT
> pairs separated by commas. Some examples:

   </P><PRE
CLASS="PROGRAMLISTING"
>    k =&gt; v
    foo =&gt; bar, baz =&gt; whatever
    "1-a" =&gt; "anything at all"
   </PRE
><P>

   The order of the pairs is not significant (and may not be reproduced on
   output). Whitespace between pairs or around the <TT
CLASS="LITERAL"
>=&gt;</TT
> sign is
   ignored. Double-quote keys and values that include whitespace, commas,
   <TT
CLASS="LITERAL"
>=</TT
>s or <TT
CLASS="LITERAL"
>&gt;</TT
>s. To include a double quote or a
   backslash in a key or value, escape it with a backslash.
  </P
><P
>   Each key in an <TT
CLASS="TYPE"
>hstore</TT
> is unique. If you declare an <TT
CLASS="TYPE"
>hstore</TT
>
   with duplicate keys, only one will be stored in the <TT
CLASS="TYPE"
>hstore</TT
> and
   there is no guarantee as to which will be kept:

   </P><PRE
CLASS="PROGRAMLISTING"
>% select 'a=&gt;1,a=&gt;2'::hstore;
  hstore
----------
 "a"=&gt;"1"
   </PRE
><P>
  </P
><P
>   A value (but not a key) can be an SQL <TT
CLASS="LITERAL"
>NULL</TT
>. For example:

   </P><PRE
CLASS="PROGRAMLISTING"
>    key =&gt; NULL
   </PRE
><P>

   The <TT
CLASS="LITERAL"
>NULL</TT
> keyword is case-insensitive. Double-quote the
   <TT
CLASS="LITERAL"
>NULL</TT
> to treat it as the ordinary string "NULL".
  </P
><DIV
CLASS="NOTE"
><BLOCKQUOTE
CLASS="NOTE"
><P
><B
>Note: </B
>   Keep in mind that the <TT
CLASS="TYPE"
>hstore</TT
> text format, when used for input,
   applies <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>before</I
></SPAN
> any required quoting or escaping. If you are
   passing an <TT
CLASS="TYPE"
>hstore</TT
> literal via a parameter, then no additional
   processing is needed. But if you're passing it as a quoted literal
   constant, then any single-quote characters and (depending on the setting of
   the <TT
CLASS="VARNAME"
>standard_conforming_strings</TT
> configuration parameter)
   backslash characters need to be escaped correctly. See
   <A
HREF="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS"
>Section 4.1.2.1</A
> for more on the handling of string
   constants.
  </P
></BLOCKQUOTE
></DIV
><P
>   On output, double quotes always surround keys and values, even when it's
   not strictly necessary.
  </P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN114425"
>F.13.2. <TT
CLASS="TYPE"
>hstore</TT
> Operators and Functions</A
></H2
><DIV
CLASS="TABLE"
><A
NAME="HSTORE-OP-TABLE"
></A
><P
><B
>Table F-5. <TT
CLASS="TYPE"
>hstore</TT
> Operators</B
></P
><TABLE
BORDER="1"
CLASS="CALSTABLE"
><COL><COL><COL><COL><THEAD
><TR
><TH
>Operator</TH
><TH
>Description</TH
><TH
>Example</TH
><TH
>Result</TH
></TR
></THEAD
><TBODY
><TR
><TD
><TT
CLASS="TYPE"
>hstore</TT
> <TT
CLASS="LITERAL"
>-&gt;</TT
> <TT
CLASS="TYPE"
>text</TT
></TD
><TD
>get value for key (<TT
CLASS="LITERAL"
>NULL</TT
> if not present)</TD
><TD
><TT
CLASS="LITERAL"
>'a=&gt;x, b=&gt;y'::hstore -&gt; 'a'</TT
></TD
><TD
><TT
CLASS="LITERAL"
>x</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>hstore</TT
> <TT
CLASS="LITERAL"
>-&gt;</TT
> <TT
CLASS="TYPE"
>text[]</TT
></TD
><TD
>get values for keys (<TT
CLASS="LITERAL"
>NULL</TT
> if not present)</TD
><TD
><TT
CLASS="LITERAL"
>'a=&gt;x, b=&gt;y, c=&gt;z'::hstore -&gt; ARRAY['c','a']</TT
></TD
><TD
><TT
CLASS="LITERAL"
>{"z","x"}</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>text</TT
> <TT
CLASS="LITERAL"
>=&gt;</TT
> <TT
CLASS="TYPE"
>text</TT
></TD
><TD
>make single-pair <TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
><TT
CLASS="LITERAL"
>'a' =&gt; 'b'</TT
></TD
><TD
><TT
CLASS="LITERAL"
>"a"=&gt;"b"</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>text[]</TT
> <TT
CLASS="LITERAL"
>=&gt;</TT
> <TT
CLASS="TYPE"
>text[]</TT
></TD
><TD
>construct an <TT
CLASS="TYPE"
>hstore</TT
> from separate key and value arrays</TD
><TD
><TT
CLASS="LITERAL"
>ARRAY['a','b'] =&gt; ARRAY['1','2']</TT
></TD
><TD
><TT
CLASS="LITERAL"
>"a"=&gt;"1","b"=&gt;"2"</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>hstore</TT
> <TT
CLASS="LITERAL"
>=&gt;</TT
> <TT
CLASS="TYPE"
>text[]</TT
></TD
><TD
>extract a subset of an <TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
><TT
CLASS="LITERAL"
>'a=&gt;1,b=&gt;2,c=&gt;3'::hstore =&gt; ARRAY['b','c','x']</TT
></TD
><TD
><TT
CLASS="LITERAL"
>"b"=&gt;"2", "c"=&gt;"3"</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>hstore</TT
> <TT
CLASS="LITERAL"
>||</TT
> <TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>concatenate <TT
CLASS="TYPE"
>hstore</TT
>s</TD
><TD
><TT
CLASS="LITERAL"
>'a=&gt;b, c=&gt;d'::hstore || 'c=&gt;x, d=&gt;q'::hstore</TT
></TD
><TD
><TT
CLASS="LITERAL"
>"a"=&gt;"b", "c"=&gt;"x", "d"=&gt;"q"</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>hstore</TT
> <TT
CLASS="LITERAL"
>?</TT
> <TT
CLASS="TYPE"
>text</TT
></TD
><TD
>does <TT
CLASS="TYPE"
>hstore</TT
> contain key?</TD
><TD
><TT
CLASS="LITERAL"
>'a=&gt;1'::hstore ? 'a'</TT
></TD
><TD
><TT
CLASS="LITERAL"
>t</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>hstore</TT
> <TT
CLASS="LITERAL"
>?&amp;</TT
> <TT
CLASS="TYPE"
>text[]</TT
></TD
><TD
>does <TT
CLASS="TYPE"
>hstore</TT
> contain all specified keys?</TD
><TD
><TT
CLASS="LITERAL"
>'a=&gt;1,b=&gt;2'::hstore ?&amp; ARRAY['a','b']</TT
></TD
><TD
><TT
CLASS="LITERAL"
>t</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>hstore</TT
> <TT
CLASS="LITERAL"
>?|</TT
> <TT
CLASS="TYPE"
>text[]</TT
></TD
><TD
>does <TT
CLASS="TYPE"
>hstore</TT
> contain any of the specified keys?</TD
><TD
><TT
CLASS="LITERAL"
>'a=&gt;1,b=&gt;2'::hstore ?| ARRAY['b','c']</TT
></TD
><TD
><TT
CLASS="LITERAL"
>t</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>hstore</TT
> <TT
CLASS="LITERAL"
>@&gt;</TT
> <TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>does left operand contain right?</TD
><TD
><TT
CLASS="LITERAL"
>'a=&gt;b, b=&gt;1, c=&gt;NULL'::hstore @&gt; 'b=&gt;1'</TT
></TD
><TD
><TT
CLASS="LITERAL"
>t</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>hstore</TT
> <TT
CLASS="LITERAL"
>&lt;@</TT
> <TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>is left operand contained in right?</TD
><TD
><TT
CLASS="LITERAL"
>'a=&gt;c'::hstore &lt;@ 'a=&gt;b, b=&gt;1, c=&gt;NULL'</TT
></TD
><TD
><TT
CLASS="LITERAL"
>f</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>hstore</TT
> <TT
CLASS="LITERAL"
>-</TT
> <TT
CLASS="TYPE"
>text</TT
></TD
><TD
>delete key from left operand</TD
><TD
><TT
CLASS="LITERAL"
>'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - 'b'::text</TT
></TD
><TD
><TT
CLASS="LITERAL"
>"a"=&gt;"1", "c"=&gt;"3"</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>hstore</TT
> <TT
CLASS="LITERAL"
>-</TT
> <TT
CLASS="TYPE"
>text[]</TT
></TD
><TD
>delete keys from left operand</TD
><TD
><TT
CLASS="LITERAL"
>'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - ARRAY['a','b']</TT
></TD
><TD
><TT
CLASS="LITERAL"
>"c"=&gt;"3"</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>hstore</TT
> <TT
CLASS="LITERAL"
>-</TT
> <TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>delete matching pairs from left operand</TD
><TD
><TT
CLASS="LITERAL"
>'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - 'a=&gt;4, b=&gt;2'::hstore</TT
></TD
><TD
><TT
CLASS="LITERAL"
>"a"=&gt;"1", "c"=&gt;"3"</TT
></TD
></TR
><TR
><TD
><TT
CLASS="TYPE"
>record</TT
> <TT
CLASS="LITERAL"
>#=</TT
> <TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>replace fields in <TT
CLASS="TYPE"
>record</TT
> with matching values from <TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>see Examples section</TD
><TD
>&nbsp;</TD
></TR
><TR
><TD
><TT
CLASS="LITERAL"
>%%</TT
> <TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>convert <TT
CLASS="TYPE"
>hstore</TT
> to array of alternating keys and values</TD
><TD
><TT
CLASS="LITERAL"
>%% 'a=&gt;foo, b=&gt;bar'::hstore</TT
></TD
><TD
><TT
CLASS="LITERAL"
>{a,foo,b,bar}</TT
></TD
></TR
><TR
><TD
><TT
CLASS="LITERAL"
>%#</TT
> <TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>convert <TT
CLASS="TYPE"
>hstore</TT
> to two-dimensional key/value array</TD
><TD
><TT
CLASS="LITERAL"
>%# 'a=&gt;foo, b=&gt;bar'::hstore</TT
></TD
><TD
><TT
CLASS="LITERAL"
>{{a,foo},{b,bar}}</TT
></TD
></TR
></TBODY
></TABLE
></DIV
><DIV
CLASS="NOTE"
><BLOCKQUOTE
CLASS="NOTE"
><P
><B
>Note: </B
>   Prior to PostgreSQL 8.2, the containment operators <TT
CLASS="LITERAL"
>@&gt;</TT
>
   and <TT
CLASS="LITERAL"
>&lt;@</TT
> were called <TT
CLASS="LITERAL"
>@</TT
> and <TT
CLASS="LITERAL"
>~</TT
>,
   respectively. These names are still available, but are deprecated and will
   eventually be removed. Notice that the old names are reversed from the
   convention formerly followed by the core geometric datatypes!
   </P
></BLOCKQUOTE
></DIV
><DIV
CLASS="TABLE"
><A
NAME="HSTORE-FUNC-TABLE"
></A
><P
><B
>Table F-6. <TT
CLASS="TYPE"
>hstore</TT
> Functions</B
></P
><TABLE
BORDER="1"
CLASS="CALSTABLE"
><COL><COL><COL><COL><COL><THEAD
><TR
><TH
>Function</TH
><TH
>Return Type</TH
><TH
>Description</TH
><TH
>Example</TH
><TH
>Result</TH
></TR
></THEAD
><TBODY
><TR
><TD
><CODE
CLASS="FUNCTION"
>hstore(record)</CODE
></TD
><TD
><TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>construct an <TT
CLASS="TYPE"
>hstore</TT
> from a record or row</TD
><TD
><TT
CLASS="LITERAL"
>hstore(ROW(1,2))</TT
></TD
><TD
><TT
CLASS="LITERAL"
>f1=&gt;1,f2=&gt;2</TT
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>hstore(text[])</CODE
></TD
><TD
><TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>construct an <TT
CLASS="TYPE"
>hstore</TT
> from an array, which may be either
       a key/value array, or a two-dimensional array</TD
><TD
><TT
CLASS="LITERAL"
>hstore(ARRAY['a','1','b','2']) || hstore(ARRAY[['c','3'],['d','4']])</TT
></TD
><TD
><TT
CLASS="LITERAL"
>a=&gt;1, b=&gt;2, c=&gt;3, d=&gt;4</TT
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>akeys(hstore)</CODE
></TD
><TD
><TT
CLASS="TYPE"
>text[]</TT
></TD
><TD
>get <TT
CLASS="TYPE"
>hstore</TT
>'s keys as an array</TD
><TD
><TT
CLASS="LITERAL"
>akeys('a=&gt;1,b=&gt;2')</TT
></TD
><TD
><TT
CLASS="LITERAL"
>{a,b}</TT
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>skeys(hstore)</CODE
></TD
><TD
><TT
CLASS="TYPE"
>setof text</TT
></TD
><TD
>get <TT
CLASS="TYPE"
>hstore</TT
>'s keys as a set</TD
><TD
><TT
CLASS="LITERAL"
>skeys('a=&gt;1,b=&gt;2')</TT
></TD
><TD
><PRE
CLASS="PROGRAMLISTING"
>a
b</PRE
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>avals(hstore)</CODE
></TD
><TD
><TT
CLASS="TYPE"
>text[]</TT
></TD
><TD
>get <TT
CLASS="TYPE"
>hstore</TT
>'s values as an array</TD
><TD
><TT
CLASS="LITERAL"
>avals('a=&gt;1,b=&gt;2')</TT
></TD
><TD
><TT
CLASS="LITERAL"
>{1,2}</TT
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>svals(hstore)</CODE
></TD
><TD
><TT
CLASS="TYPE"
>setof text</TT
></TD
><TD
>get <TT
CLASS="TYPE"
>hstore</TT
>'s values as a set</TD
><TD
><TT
CLASS="LITERAL"
>svals('a=&gt;1,b=&gt;2')</TT
></TD
><TD
><PRE
CLASS="PROGRAMLISTING"
>1
2</PRE
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>hstore_to_array(hstore)</CODE
></TD
><TD
><TT
CLASS="TYPE"
>text[]</TT
></TD
><TD
>get <TT
CLASS="TYPE"
>hstore</TT
>'s keys and values as an array of alternating
       keys and values</TD
><TD
><TT
CLASS="LITERAL"
>hstore_to_array('a=&gt;1,b=&gt;2')</TT
></TD
><TD
><TT
CLASS="LITERAL"
>{a,1,b,2}</TT
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>hstore_to_matrix(hstore)</CODE
></TD
><TD
><TT
CLASS="TYPE"
>text[]</TT
></TD
><TD
>get <TT
CLASS="TYPE"
>hstore</TT
>'s keys and values as a two-dimensional array</TD
><TD
><TT
CLASS="LITERAL"
>hstore_to_matrix('a=&gt;1,b=&gt;2')</TT
></TD
><TD
><TT
CLASS="LITERAL"
>{{a,1},{b,2}}</TT
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>each(hstore)</CODE
></TD
><TD
><TT
CLASS="TYPE"
>setof(key text, value text)</TT
></TD
><TD
>get <TT
CLASS="TYPE"
>hstore</TT
>'s keys and values as a set</TD
><TD
><TT
CLASS="LITERAL"
>select * from each('a=&gt;1,b=&gt;2')</TT
></TD
><TD
><PRE
CLASS="PROGRAMLISTING"
> key | value
-----+-------
 a   | 1
 b   | 2</PRE
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>exist(hstore,text)</CODE
></TD
><TD
><TT
CLASS="TYPE"
>boolean</TT
></TD
><TD
>does <TT
CLASS="TYPE"
>hstore</TT
> contain key?</TD
><TD
><TT
CLASS="LITERAL"
>exist('a=&gt;1','a')</TT
></TD
><TD
><TT
CLASS="LITERAL"
>t</TT
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>defined(hstore,text)</CODE
></TD
><TD
><TT
CLASS="TYPE"
>boolean</TT
></TD
><TD
>does <TT
CLASS="TYPE"
>hstore</TT
> contain non-<TT
CLASS="LITERAL"
>NULL</TT
> value for key?</TD
><TD
><TT
CLASS="LITERAL"
>defined('a=&gt;NULL','a')</TT
></TD
><TD
><TT
CLASS="LITERAL"
>f</TT
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>delete(hstore,text)</CODE
></TD
><TD
><TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>delete pair with matching key</TD
><TD
><TT
CLASS="LITERAL"
>delete('a=&gt;1,b=&gt;2','b')</TT
></TD
><TD
><TT
CLASS="LITERAL"
>"a"=&#62;"1"</TT
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>delete(hstore,text[])</CODE
></TD
><TD
><TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>delete pairs with matching keys</TD
><TD
><TT
CLASS="LITERAL"
>delete('a=&gt;1,b=&gt;2,c=&gt;3',ARRAY['a','b'])</TT
></TD
><TD
><TT
CLASS="LITERAL"
>"c"=&#62;"3"</TT
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>delete(hstore,hstore)</CODE
></TD
><TD
><TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>delete pairs matching those in the second argument</TD
><TD
><TT
CLASS="LITERAL"
>delete('a=&gt;1,b=&gt;2','a=&gt;4,b=&gt;2'::hstore)</TT
></TD
><TD
><TT
CLASS="LITERAL"
>"a"=&#62;"1"</TT
></TD
></TR
><TR
><TD
><CODE
CLASS="FUNCTION"
>populate_record(record,hstore)</CODE
></TD
><TD
><TT
CLASS="TYPE"
>record</TT
></TD
><TD
>replace fields in <TT
CLASS="TYPE"
>record</TT
> with matching values from <TT
CLASS="TYPE"
>hstore</TT
></TD
><TD
>see Examples section</TD
><TD
>&nbsp;</TD
></TR
></TBODY
></TABLE
></DIV
><DIV
CLASS="NOTE"
><BLOCKQUOTE
CLASS="NOTE"
><P
><B
>Note: </B
>    The function <CODE
CLASS="FUNCTION"
>populate_record</CODE
> is actually declared
    with <TT
CLASS="TYPE"
>anyelement</TT
>, not <TT
CLASS="TYPE"
>record</TT
>, as its first argument,
    but it will reject non-record types with a runtime error.
   </P
></BLOCKQUOTE
></DIV
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN114803"
>F.13.3. Indexes</A
></H2
><P
>   <TT
CLASS="TYPE"
>hstore</TT
> has GiST and GIN index support for the <TT
CLASS="LITERAL"
>@&gt;</TT
>,
   <TT
CLASS="LITERAL"
>?</TT
>, <TT
CLASS="LITERAL"
>?&#38;</TT
> and <TT
CLASS="LITERAL"
>?|</TT
> operators. For example:
  </P
><PRE
CLASS="PROGRAMLISTING"
>CREATE INDEX hidx ON testhstore USING GIST (h);

CREATE INDEX hidx ON testhstore USING GIN (h);
  </PRE
><P
>   <TT
CLASS="TYPE"
>hstore</TT
> also supports <TT
CLASS="TYPE"
>btree</TT
> or <TT
CLASS="TYPE"
>hash</TT
> indexes for
   the <TT
CLASS="LITERAL"
>=</TT
> operator. This allows <TT
CLASS="TYPE"
>hstore</TT
> columns to be
   declared <TT
CLASS="LITERAL"
>UNIQUE</TT
>, or to be used in <TT
CLASS="LITERAL"
>GROUP BY</TT
>,
   <TT
CLASS="LITERAL"
>ORDER BY</TT
> or <TT
CLASS="LITERAL"
>DISTINCT</TT
> expressions. The sort ordering
   for <TT
CLASS="TYPE"
>hstore</TT
> values is not particularly useful, but these indexes
   may be useful for equivalence lookups. Create indexes for <TT
CLASS="LITERAL"
>=</TT
>
   comparisons as follows:
  </P
><PRE
CLASS="PROGRAMLISTING"
>CREATE INDEX hidx ON testhstore USING BTREE (h);

CREATE INDEX hidx ON testhstore USING HASH (h);
  </PRE
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN114825"
>F.13.4. Examples</A
></H2
><P
>   Add a key, or update an existing key with a new value:
  </P
><PRE
CLASS="PROGRAMLISTING"
>UPDATE tab SET h = h || ('c' =&gt; '3');
  </PRE
><P
>   Delete a key:
  </P
><PRE
CLASS="PROGRAMLISTING"
>UPDATE tab SET h = delete(h, 'k1');
  </PRE
><P
>   Convert a <TT
CLASS="TYPE"
>record</TT
> to an <TT
CLASS="TYPE"
>hstore</TT
>:
  </P
><PRE
CLASS="PROGRAMLISTING"
>CREATE TABLE test (col1 integer, col2 text, col3 text);
INSERT INTO test VALUES (123, 'foo', 'bar');

SELECT hstore(t) FROM test AS t;
                   hstore                    
---------------------------------------------
 "col1"=&gt;"123", "col2"=&gt;"foo", "col3"=&gt;"bar"
(1 row)
  </PRE
><P
>   Convert an <TT
CLASS="TYPE"
>hstore</TT
> to a predefined <TT
CLASS="TYPE"
>record</TT
> type:
  </P
><PRE
CLASS="PROGRAMLISTING"
>CREATE TABLE test (col1 integer, col2 text, col3 text);

SELECT * FROM populate_record(null::test,
                              '"col1"=&gt;"456", "col2"=&gt;"zzz"');
 col1 | col2 | col3 
------+------+------
  456 | zzz  | 
(1 row)
  </PRE
><P
>   Modify an existing record using the values from an <TT
CLASS="TYPE"
>hstore</TT
>:
  </P
><PRE
CLASS="PROGRAMLISTING"
>CREATE TABLE test (col1 integer, col2 text, col3 text);
INSERT INTO test VALUES (123, 'foo', 'bar');

SELECT (r).* FROM (SELECT t #= '"col3"=&gt;"baz"' AS r FROM test t) s;
 col1 | col2 | col3 
------+------+------
  123 | foo  | baz
(1 row)
  </PRE
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN114842"
>F.13.5. Statistics</A
></H2
><P
>   The <TT
CLASS="TYPE"
>hstore</TT
> type, because of its intrinsic liberality, could
   contain a lot of different keys. Checking for valid keys is the task of the
   application. The following examples demonstrate several techniques for
   checking keys and obtaining statistics.
  </P
><P
>   Simple example:
  </P
><PRE
CLASS="PROGRAMLISTING"
>SELECT * FROM each('aaa=&gt;bq, b=&gt;NULL, ""=&gt;1');
  </PRE
><P
>   Using a table:
  </P
><PRE
CLASS="PROGRAMLISTING"
>SELECT (each(h)).key, (each(h)).value INTO stat FROM testhstore;
  </PRE
><P
>   Online statistics:
  </P
><PRE
CLASS="PROGRAMLISTING"
>SELECT key, count(*) FROM
  (SELECT (each(h)).key FROM testhstore) AS stat
  GROUP BY key
  ORDER BY count DESC, key;
    key    | count
-----------+-------
 line      |   883
 query     |   207
 pos       |   203
 node      |   202
 space     |   197
 status    |   195
 public    |   194
 title     |   190
 org       |   189
...................
  </PRE
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN114852"
>F.13.6. Compatibility</A
></H2
><P
>   <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>When upgrading from older versions, always load the new
   version of this module into the database before restoring a dump.
   Otherwise, many new features will be unavailable.</I
></SPAN
>
  </P
><P
>   As of PostgreSQL 8.5, <TT
CLASS="TYPE"
>hstore</TT
> uses a different internal
   representation than previous versions. This presents no obstacle for
   dump/restore upgrades since the text representation (used in the dump) is
   unchanged.
  </P
><P
>   In the event of a binary upgrade, upward compatibility is maintained by
   having the new code recognize old-format data. This will entail a slight
   performance penalty when processing data that has not yet been modified by
   the new code. It is possible to force an upgrade of all values in a table
   column by doing an <TT
CLASS="LITERAL"
>UPDATE</TT
> statement as follows:
  </P
><PRE
CLASS="PROGRAMLISTING"
>UPDATE tablename SET hstorecol = hstorecol || '';
  </PRE
><P
>   Another way to do it is:
  </P><PRE
CLASS="PROGRAMLISTING"
>ALTER TABLE tablename ALTER hstorecol TYPE hstore USING hstorecol || '';
  </PRE
><P>
   The <TT
CLASS="COMMAND"
>ALTER TABLE</TT
> method requires an exclusive lock on the table,
   but does not result in bloating the table with old row versions.
  </P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN114864"
>F.13.7. Authors</A
></H2
><P
>   Oleg Bartunov <CODE
CLASS="EMAIL"
>&#60;<A
HREF="mailto:oleg@sai.msu.su"
>oleg@sai.msu.su</A
>&#62;</CODE
>, Moscow, Moscow University, Russia
  </P
><P
>   Teodor Sigaev <CODE
CLASS="EMAIL"
>&#60;<A
HREF="mailto:teodor@sigaev.ru"
>teodor@sigaev.ru</A
>&#62;</CODE
>, Moscow, Delta-Soft Ltd., Russia
  </P
><P
>   Additional enhancements by Andrew Gierth <CODE
CLASS="EMAIL"
>&#60;<A
HREF="mailto:andrew@tao11.riddles.org.uk"
>andrew@tao11.riddles.org.uk</A
>&#62;</CODE
>,
   United Kingdom
  </P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="fuzzystrmatch.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="intagg.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>fuzzystrmatch</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="contrib.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>intagg</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>