]> granicus.if.org Git - postgresql/blob - doc/src/sgml/array.sgml
Spell-check and markup police
[postgresql] / doc / src / sgml / array.sgml
1 <!-- $Header: /cvsroot/pgsql/doc/src/sgml/array.sgml,v 1.19 2002/01/20 22:19:55 petere Exp $ -->
2
3 <chapter id="arrays">
4  <title>Arrays</title>
5
6  <indexterm>
7   <primary>arrays</primary>
8  </indexterm>
9
10  <para>
11   <productname>PostgreSQL</productname> allows columns of a table to be
12   defined as variable-length multidimensional arrays. Arrays of any
13   built-in type or user-defined type can be created.  To illustrate
14   their use, we create this table:
15 <programlisting>
16 CREATE TABLE sal_emp (
17     name            text,
18     pay_by_quarter  integer[],
19     schedule        text[][]
20 );
21 </programlisting>
22   As shown, an array data type is named by appending square brackets
23   (<literal>[]</>) to the data type name of the array elements.
24   The above query will create a table named
25   <structname>sal_emp</structname> with a <type>text</type> string
26   (<structfield>name</structfield>), a one-dimensional array of type
27   <type>integer</type> (<structfield>pay_by_quarter</structfield>),
28   which represents the employee's salary by quarter, and a
29   two-dimensional array of <type>text</type>
30   (<structfield>schedule</structfield>), which represents the
31   employee's weekly schedule.
32  </para>
33
34  <para>
35   Now we do some <command>INSERT</command>s.  Observe that to write an array
36   value, we enclose the element values within curly braces and separate them
37   by commas.  If you know C, this is not unlike the syntax for
38   initializing structures.
39      
40 <programlisting>
41 INSERT INTO sal_emp
42     VALUES ('Bill',
43     '{10000, 10000, 10000, 10000}',
44     '{{"meeting", "lunch"}, {}}');
45
46 INSERT INTO sal_emp
47     VALUES ('Carol',
48     '{20000, 25000, 25000, 25000}',
49     '{{"talk", "consult"}, {"meeting"}}');
50 </programlisting>
51  </para>
52
53  <para>
54   Now, we can run some queries on <structname>sal_emp</structname>.
55   First, we show how to access a single element of an array at a time.
56   This query retrieves the names of the employees whose pay changed in
57   the second quarter:
58      
59 <programlisting>
60 SELECT name FROM sal_emp WHERE pay_by_quarter[1] &lt;&gt; pay_by_quarter[2];
61
62  name
63 -------
64  Carol
65 (1 row)
66 </programlisting>
67
68   The array subscript numbers are written within square brackets.
69   <productname>PostgreSQL</productname> uses the
70   <quote>one-based</quote> numbering convention for arrays, that is,
71   an array of <replaceable>n</> elements starts with <literal>array[1]</literal> and
72   ends with <literal>array[<replaceable>n</>]</literal>.
73  </para>
74
75  <para>
76   This query retrieves the third quarter pay of all employees:
77      
78 <programlisting>
79 SELECT pay_by_quarter[3] FROM sal_emp;
80
81  pay_by_quarter
82 ----------------
83           10000
84           25000
85 (2 rows)
86 </programlisting>
87  </para>
88
89  <para>
90   We can also access arbitrary rectangular slices of an array, or
91   subarrays.  An array slice is denoted by writing
92   <literal><replaceable>lower subscript</replaceable> :
93   <replaceable>upper subscript</replaceable></literal> for one or more
94   array dimensions.  This query retrieves the first item on Bill's
95   schedule for the first two days of the week:
96      
97 <programlisting>
98 SELECT schedule[1:2][1:1] FROM sal_emp WHERE name = 'Bill';
99
100       schedule
101 --------------------
102  {{"meeting"},{""}}
103 (1 row)
104 </programlisting>
105
106   We could also have written
107
108 <programlisting>
109 SELECT schedule[1:2][1] FROM sal_emp WHERE name = 'Bill';
110 </programlisting>
111
112   with the same result.  An array subscripting operation is taken to
113   represent an array slice if any of the subscripts are written in the
114   form <replaceable>lower</replaceable> <literal>:</literal>
115   <replaceable>upper</replaceable>.  A lower bound of 1 is assumed for
116   any subscript where only one value is specified.
117  </para>
118
119  <para>
120   An array value can be replaced completely:
121
122 <programlisting>
123 UPDATE sal_emp SET pay_by_quarter = '{25000,25000,27000,27000}'
124     WHERE name = 'Carol';
125 </programlisting>
126
127   or updated at a single element:
128
129 <programlisting>
130 UPDATE sal_emp SET pay_by_quarter[4] = 15000
131     WHERE name = 'Bill';
132 </programListing>
133
134   or updated in a slice:
135
136 <programlisting>
137 UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}'
138     WHERE name = 'Carol';
139 </programlisting>
140  </para>
141
142  <para>
143   An array can be enlarged by assigning to an element adjacent to
144   those already present, or by assigning to a slice that is adjacent
145   to or overlaps the data already present.  For example, if an array
146   value currently has 4 elements, it will have five elements after an
147   update that assigns to array[5].  Currently, enlargement in this
148   fashion is only allowed for one-dimensional arrays, not
149   multidimensional arrays.
150  </para>
151
152  <para>
153   The syntax for <command>CREATE TABLE</command> allows fixed-length
154   arrays to be defined:
155
156 <programlisting>
157 CREATE TABLE tictactoe (
158     squares   integer[3][3]
159 );
160 </programlisting>
161
162   However, the current implementation does not enforce the array size
163   limits --- the behavior is the same as for arrays of unspecified
164   length.
165  </para>
166
167  <para>
168   Actually, the current implementation does not enforce the declared
169   number of dimensions either.  Arrays of a particular element type are
170   all considered to be of the same type, regardless of size or number
171   of dimensions.
172  </para>
173
174  <para>
175   The current dimensions of any array value can be retrieved with the
176   <function>array_dims</function> function:
177
178 <programlisting>
179 SELECT array_dims(schedule) FROM sal_emp WHERE name = 'Carol';
180
181  array_dims
182 ------------
183  [1:2][1:1]
184 (1 row)
185 </programlisting>
186
187   <function>array_dims</function> produces a <type>text</type> result,
188   which is convenient for people to read but perhaps not so convenient
189   for programs.
190  </para>
191
192  <para>
193   To search for a value in an array, you must check each value of the
194   array. This can be done by hand (if you know the size of the array):
195
196 <programlisting>
197 SELECT * FROM sal_emp WHERE pay_by_quarter[1] = 10000 OR
198                             pay_by_quarter[2] = 10000 OR
199                             pay_by_quarter[3] = 10000 OR
200                             pay_by_quarter[4] = 10000;
201 </programlisting>
202
203   However, this quickly becomes tedious for large arrays, and is not
204   helpful if the size of the array is unknown. Although it is not part
205   of the primary <productname>PostgreSQL</productname> distribution,
206   there is an extension available that defines new functions and
207   operators for iterating over array values. Using this, the above
208   query could be:
209
210 <programlisting>
211 SELECT * FROM sal_emp WHERE pay_by_quarter[1:4] *= 10000;
212 </programlisting>
213
214   To search the entire array (not just specified columns), you could
215   use:
216
217 <programlisting>
218 SELECT * FROM sal_emp WHERE pay_by_quarter *= 10000;
219 </programlisting>
220
221   In addition, you could find rows where the array had all values
222   equal to 10 000 with:
223
224 <programlisting>
225 SELECT * FROM sal_emp WHERE pay_by_quarter **= 10000;
226 </programlisting>
227
228   To install this optional module, look in the
229   <filename>contrib/array</filename> directory of the
230   <productname>PostgreSQL</productname> source distribution.
231  </para>
232
233  <tip>
234   <para>
235    Arrays are not sets; using arrays in the manner described in the
236    previous paragraph is often a sign of database misdesign.  The
237    array field should generally be split off into a separate table.
238    Tables can obviously be searched easily.
239   </para>
240  </tip>
241
242  <note>
243   <para>
244    A limitation of the present array implementation is that individual
245    elements of an array cannot be SQL NULLs.  The entire array can be set
246    to NULL, but you can't have an array with some elements NULL and some
247    not.  Fixing this is on the to-do list.
248   </para>
249  </note>
250
251  <formalpara>
252   <title>Quoting array elements.</title>
253   <para>
254    As shown above, when writing an array literal value you may write double
255    quotes around any individual array
256    element.  You <emphasis>must</> do so if the element value would otherwise
257    confuse the array-value parser.  For example, elements containing curly
258    braces, commas, double quotes, backslashes, or white space must be
259    double-quoted.  To put a double quote or backslash in an array element
260    value, precede it with a backslash.
261   </para>
262  </formalpara>
263
264  <tip>
265   <para>
266    Remember that what you write in an SQL query will first be interpreted
267    as a string literal, and then as an array.  This doubles the number of
268    backslashes you need.  For example, to insert a <type>text</> array
269    value containing a backslash and a double quote, you'd need to write
270 <programlisting>
271 INSERT ... VALUES ('{"\\\\","\\""}');
272 </programlisting>
273    The string-literal processor removes one level of backslashes, so that
274    what arrives at the array-value parser looks like <literal>{"\\","\""}</>.
275    In turn, the strings fed to the <type>text</> data type's input routine
276    become <literal>\</> and <literal>"</> respectively.  (If we were working
277    with a data type whose input routine also treated backslashes specially,
278    <type>bytea</> for example, we might need as many as eight backslashes
279    in the query to get one backslash into the stored array element.)
280   </para>
281  </tip>
282
283 </chapter>