1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-30 11:03:19 +03:00

Allow subscripting of hstore values.

This is basically a finger exercise to prove that it's possible for
an extension module to add subscripting ability.  Subscripted fetch
from an hstore is not different from the existing "hstore -> text"
operator.  Subscripted update does seem to be a little easier to
use than the traditional update method using hstore concatenation,
but it's not a fundamentally new ability.

However, there may be some value in the code as sample code, since
it shows what's basically the minimum-complexity way to implement
subscripting when one needn't consider nested container objects.

Discussion: https://postgr.es/m/3724341.1607551174@sss.pgh.pa.us
This commit is contained in:
Tom Lane
2020-12-11 18:58:07 -05:00
parent 8c15a29745
commit 0ec5f7e782
8 changed files with 392 additions and 5 deletions

View File

@ -713,6 +713,39 @@ b
</tbody>
</tgroup>
</table>
<para>
In addition to these operators and functions, values of
the <type>hstore</type> type can be subscripted, allowing them to act
like associative arrays. Only a single subscript of type <type>text</type>
can be specified; it is interpreted as a key and the corresponding
value is fetched or stored. For example,
<programlisting>
CREATE TABLE mytable (h hstore);
INSERT INTO mytable VALUES ('a=>b, c=>d');
SELECT h['a'] FROM mytable;
h
---
b
(1 row)
UPDATE mytable SET h['c'] = 'new';
SELECT h FROM mytable;
h
----------------------
"a"=>"b", "c"=>"new"
(1 row)
</programlisting>
A subscripted fetch returns <literal>NULL</literal> if the subscript
is <literal>NULL</literal> or that key does not exist in
the <type>hstore</type>. (Thus, a subscripted fetch is not greatly
different from the <literal>-&gt;</literal> operator.)
A subscripted update fails if the subscript is <literal>NULL</literal>;
otherwise, it replaces the value for that key, adding an entry to
the <type>hstore</type> if the key does not already exist.
</para>
</sect2>
<sect2>
@ -767,7 +800,16 @@ CREATE INDEX hidx ON testhstore USING HASH (h);
<para>
Add a key, or update an existing key with a new value:
<programlisting>
UPDATE tab SET h['c'] = '3';
</programlisting>
Another way to do the same thing is:
<programlisting>
UPDATE tab SET h = h || hstore('c', '3');
</programlisting>
If multiple keys are to be added or changed in one operation,
the concatenation approach is more efficient than subscripting:
<programlisting>
UPDATE tab SET h = h || hstore(array['q', 'w'], array['11', '12']);
</programlisting>
</para>

View File

@ -333,9 +333,11 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
return an <type>internal</type> result, which is a pointer to a struct
of methods (functions) that implement subscripting.
The detailed API for subscript functions appears
in <filename>src/include/nodes/subscripting.h</filename>;
it may also be useful to read the array implementation
in <filename>src/backend/utils/adt/arraysubs.c</filename>.
in <filename>src/include/nodes/subscripting.h</filename>.
It may also be useful to read the array implementation
in <filename>src/backend/utils/adt/arraysubs.c</filename>,
or the simpler code
in <filename>contrib/hstore/hstore_subs.c</filename>.
Additional information appears in
<xref linkend="sql-createtype-array"/> below.
</para>