mirror of
https://github.com/postgres/postgres.git
synced 2025-06-05 23:56:58 +03:00
Require that array literals produce "rectangular" arrays, i.e. all the
subarrays of a given dimension have the same number of elements/subarrays. Also repair a longstanding undocumented (as far as I can see) ability to explicitly set array bounds in the array literal syntax. It now can deal properly with negative array indicies. Modify array_out so that arrays with non-standard lower bounds (i.e. not 1) are output with the expicit dimension syntax. This fixes a longstanding issue whereby arrays with non-default lower bounds had them changed to default after a dump/reload cycle. Modify regression tests and docs to suit, and add some minimal documentation regarding the explicit dimension syntax.
This commit is contained in:
parent
39ec59f30f
commit
0e13d627be
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.35 2004/06/07 04:04:47 tgl Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.36 2004/08/05 03:29:11 joe Exp $ -->
|
||||||
|
|
||||||
<sect1 id="arrays">
|
<sect1 id="arrays">
|
||||||
<title>Arrays</title>
|
<title>Arrays</title>
|
||||||
@ -121,12 +121,23 @@ CREATE TABLE tictactoe (
|
|||||||
INSERT INTO sal_emp
|
INSERT INTO sal_emp
|
||||||
VALUES ('Bill',
|
VALUES ('Bill',
|
||||||
'{10000, 10000, 10000, 10000}',
|
'{10000, 10000, 10000, 10000}',
|
||||||
'{{"meeting", "lunch"}, {}}');
|
'{{"meeting", "lunch"}, {"meeting"}}');
|
||||||
|
ERROR: multidimensional arrays must have array expressions with matching dimensions
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
Note that multidimensional arrays must have matching extents for each
|
||||||
|
dimension. A mismatch causes an error report.
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
INSERT INTO sal_emp
|
||||||
|
VALUES ('Bill',
|
||||||
|
'{10000, 10000, 10000, 10000}',
|
||||||
|
'{{"meeting", "lunch"}, {"training", "presentation"}}');
|
||||||
|
|
||||||
INSERT INTO sal_emp
|
INSERT INTO sal_emp
|
||||||
VALUES ('Carol',
|
VALUES ('Carol',
|
||||||
'{20000, 25000, 25000, 25000}',
|
'{20000, 25000, 25000, 25000}',
|
||||||
'{{"talk", "consult"}, {"meeting"}}');
|
'{{"breakfast", "consulting"}, {"meeting", "lunch"}}');
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -138,59 +149,31 @@ INSERT INTO sal_emp
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
This can lead to surprising results. For example, the result of the
|
The result of the previous two inserts looks like this:
|
||||||
previous two inserts looks like this:
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
SELECT * FROM sal_emp;
|
SELECT * FROM sal_emp;
|
||||||
name | pay_by_quarter | schedule
|
name | pay_by_quarter | schedule
|
||||||
-------+---------------------------+--------------------
|
-------+---------------------------+-------------------------------------------
|
||||||
Bill | {10000,10000,10000,10000} | {{meeting},{""}}
|
Bill | {10000,10000,10000,10000} | {{meeting,lunch},{training,presentation}}
|
||||||
Carol | {20000,25000,25000,25000} | {{talk},{meeting}}
|
Carol | {20000,25000,25000,25000} | {{breakfast,consulting},{meeting,lunch}}
|
||||||
(2 rows)
|
(2 rows)
|
||||||
</programlisting>
|
</programlisting>
|
||||||
Because the <literal>[2][2]</literal> element of
|
|
||||||
<structfield>schedule</structfield> is missing in each of the
|
|
||||||
<command>INSERT</command> statements, the <literal>[1][2]</literal>
|
|
||||||
element is discarded.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<note>
|
|
||||||
<para>
|
|
||||||
Fixing this is on the to-do list.
|
|
||||||
</para>
|
|
||||||
</note>
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <literal>ARRAY</literal> expression syntax may also be used:
|
The <literal>ARRAY</literal> expression syntax may also be used:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
INSERT INTO sal_emp
|
INSERT INTO sal_emp
|
||||||
VALUES ('Bill',
|
VALUES ('Bill',
|
||||||
ARRAY[10000, 10000, 10000, 10000],
|
ARRAY[10000, 10000, 10000, 10000],
|
||||||
ARRAY[['meeting', 'lunch'], ['','']]);
|
ARRAY[['meeting', 'lunch'], ['training', 'presentation']]);
|
||||||
|
|
||||||
INSERT INTO sal_emp
|
INSERT INTO sal_emp
|
||||||
VALUES ('Carol',
|
VALUES ('Carol',
|
||||||
ARRAY[20000, 25000, 25000, 25000],
|
ARRAY[20000, 25000, 25000, 25000],
|
||||||
ARRAY[['talk', 'consult'], ['meeting', '']]);
|
ARRAY[['breakfast', 'consulting'], ['meeting', 'lunch']]);
|
||||||
SELECT * FROM sal_emp;
|
|
||||||
name | pay_by_quarter | schedule
|
|
||||||
-------+---------------------------+-------------------------------
|
|
||||||
Bill | {10000,10000,10000,10000} | {{meeting,lunch},{"",""}}
|
|
||||||
Carol | {20000,25000,25000,25000} | {{talk,consult},{meeting,""}}
|
|
||||||
(2 rows)
|
|
||||||
</programlisting>
|
</programlisting>
|
||||||
Note that with this syntax, multidimensional arrays must have matching
|
Notice that the array elements are ordinary SQL constants or
|
||||||
extents for each dimension. A mismatch causes an error report, rather than
|
|
||||||
silently discarding values as in the previous case.
|
|
||||||
For example:
|
|
||||||
<programlisting>
|
|
||||||
INSERT INTO sal_emp
|
|
||||||
VALUES ('Carol',
|
|
||||||
ARRAY[20000, 25000, 25000, 25000],
|
|
||||||
ARRAY[['talk', 'consult'], ['meeting']]);
|
|
||||||
ERROR: multidimensional arrays must have array expressions with matching dimensions
|
|
||||||
</programlisting>
|
|
||||||
Also notice that the array elements are ordinary SQL constants or
|
|
||||||
expressions; for instance, string literals are single quoted, instead of
|
expressions; for instance, string literals are single quoted, instead of
|
||||||
double quoted as they would be in an array literal. The <literal>ARRAY</>
|
double quoted as they would be in an array literal. The <literal>ARRAY</>
|
||||||
expression syntax is discussed in more detail in <xref
|
expression syntax is discussed in more detail in <xref
|
||||||
@ -248,8 +231,8 @@ SELECT pay_by_quarter[3] FROM sal_emp;
|
|||||||
SELECT schedule[1:2][1:1] FROM sal_emp WHERE name = 'Bill';
|
SELECT schedule[1:2][1:1] FROM sal_emp WHERE name = 'Bill';
|
||||||
|
|
||||||
schedule
|
schedule
|
||||||
--------------------
|
------------------------
|
||||||
{{meeting},{""}}
|
{{meeting},{training}}
|
||||||
(1 row)
|
(1 row)
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
@ -266,9 +249,10 @@ SELECT schedule[1:2][1] FROM sal_emp WHERE name = 'Bill';
|
|||||||
is specified, as in this example:
|
is specified, as in this example:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
SELECT schedule[1:2][2] FROM sal_emp WHERE name = 'Bill';
|
SELECT schedule[1:2][2] FROM sal_emp WHERE name = 'Bill';
|
||||||
|
|
||||||
schedule
|
schedule
|
||||||
---------------------------
|
-------------------------------------------
|
||||||
{{meeting,lunch},{"",""}}
|
{{meeting,lunch},{training,presentation}}
|
||||||
(1 row)
|
(1 row)
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
@ -546,6 +530,47 @@ SELECT * FROM sal_emp WHERE 10000 = ALL (pay_by_quarter);
|
|||||||
up to the next right brace or delimiter is taken as the item value.
|
up to the next right brace or delimiter is taken as the item value.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
By default, the lower bound index value of an array's dimensions is
|
||||||
|
set to one. If any of an array's dimensions has a lower bound index not
|
||||||
|
equal to one, an additional decoration that indicates the actual
|
||||||
|
array dimensions will precede the array structure decoration.
|
||||||
|
The decoration consists of square braces (<literal>[</> and <literal>]</>)
|
||||||
|
around each array dimension's lower and upper bound indicies, plus
|
||||||
|
a colon (<literal>:</>) delimiter character inbetween. Delimiting the
|
||||||
|
array dimension decoration from the array structure decoration is a
|
||||||
|
single assignment operator (<literal>=</>). For example:
|
||||||
|
<programlisting>
|
||||||
|
SELECT 1 || ARRAY[2,3] AS array;
|
||||||
|
|
||||||
|
array
|
||||||
|
---------------
|
||||||
|
[0:2]={1,2,3}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT ARRAY[1,2] || ARRAY[[3,4]] AS array;
|
||||||
|
|
||||||
|
array
|
||||||
|
--------------------------
|
||||||
|
[0:1][1:2]={{1,2},{3,4}}
|
||||||
|
(1 row)
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
In a similar fashion, an array with non-default indicies may be specified
|
||||||
|
using the same literal syntax. For example:
|
||||||
|
<programlisting>
|
||||||
|
SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2
|
||||||
|
FROM (SELECT '[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}'::int[] AS f1) AS ss;
|
||||||
|
|
||||||
|
e1 | e2
|
||||||
|
----+----
|
||||||
|
1 | 6
|
||||||
|
(1 row)
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
As shown previously, when writing an array value you may write double
|
As shown previously, when writing an array value you may write double
|
||||||
quotes around any individual array
|
quotes around any individual array
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.105 2004/06/16 01:26:47 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.106 2004/08/05 03:29:37 joe Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -217,7 +217,7 @@ array_in(PG_FUNCTION_ARGS)
|
|||||||
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
|
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
|
||||||
ndim, MAXDIM)));
|
ndim, MAXDIM)));
|
||||||
|
|
||||||
for (q = p; isdigit((unsigned char) *q); q++);
|
for (q = p; isdigit((unsigned char) *q) || (*q == '-') || (*q == '+'); q++);
|
||||||
if (q == p) /* no digits? */
|
if (q == p) /* no digits? */
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||||
@ -229,7 +229,7 @@ array_in(PG_FUNCTION_ARGS)
|
|||||||
*q = '\0';
|
*q = '\0';
|
||||||
lBound[ndim] = atoi(p);
|
lBound[ndim] = atoi(p);
|
||||||
p = q + 1;
|
p = q + 1;
|
||||||
for (q = p; isdigit((unsigned char) *q); q++);
|
for (q = p; isdigit((unsigned char) *q) || (*q == '-') || (*q == '+'); q++);
|
||||||
if (q == p) /* no digits? */
|
if (q == p) /* no digits? */
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||||
@ -270,6 +270,9 @@ array_in(PG_FUNCTION_ARGS)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int ndim_braces,
|
||||||
|
dim_braces[MAXDIM];
|
||||||
|
|
||||||
/* If array dimensions are given, expect '=' operator */
|
/* If array dimensions are given, expect '=' operator */
|
||||||
if (strncmp(p, ASSGN, strlen(ASSGN)) != 0)
|
if (strncmp(p, ASSGN, strlen(ASSGN)) != 0)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -278,6 +281,27 @@ array_in(PG_FUNCTION_ARGS)
|
|||||||
p += strlen(ASSGN);
|
p += strlen(ASSGN);
|
||||||
while (isspace((unsigned char) *p))
|
while (isspace((unsigned char) *p))
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* intuit dimensions from brace structure -- it better match what
|
||||||
|
* we were given
|
||||||
|
*/
|
||||||
|
if (*p != '{')
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||||
|
errmsg("array value must start with \"{\" or dimension information")));
|
||||||
|
ndim_braces = ArrayCount(p, dim_braces, typdelim);
|
||||||
|
if (ndim_braces != ndim)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||||
|
errmsg("array dimensions incompatible with array literal")));
|
||||||
|
for (i = 0; i < ndim; ++i)
|
||||||
|
{
|
||||||
|
if (dim[i] != dim_braces[i])
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||||
|
errmsg("array dimensions incompatible with array literal")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ARRAYDEBUG
|
#ifdef ARRAYDEBUG
|
||||||
@ -303,7 +327,6 @@ array_in(PG_FUNCTION_ARGS)
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||||
errmsg("missing left brace")));
|
errmsg("missing left brace")));
|
||||||
|
|
||||||
dataPtr = ReadArrayStr(p, nitems, ndim, dim, &my_extra->proc, typioparam,
|
dataPtr = ReadArrayStr(p, nitems, ndim, dim, &my_extra->proc, typioparam,
|
||||||
typmod, typdelim, typlen, typbyval, typalign,
|
typmod, typdelim, typlen, typbyval, typalign,
|
||||||
&nbytes);
|
&nbytes);
|
||||||
@ -334,13 +357,18 @@ ArrayCount(char *str, int *dim, char typdelim)
|
|||||||
int nest_level = 0,
|
int nest_level = 0,
|
||||||
i;
|
i;
|
||||||
int ndim = 1,
|
int ndim = 1,
|
||||||
temp[MAXDIM];
|
temp[MAXDIM],
|
||||||
|
nelems[MAXDIM],
|
||||||
|
nelems_last[MAXDIM];
|
||||||
bool scanning_string = false;
|
bool scanning_string = false;
|
||||||
bool eoArray = false;
|
bool eoArray = false;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
for (i = 0; i < MAXDIM; ++i)
|
for (i = 0; i < MAXDIM; ++i)
|
||||||
|
{
|
||||||
temp[i] = dim[i] = 0;
|
temp[i] = dim[i] = 0;
|
||||||
|
nelems_last[i] = nelems[i] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (strncmp(str, "{}", 2) == 0)
|
if (strncmp(str, "{}", 2) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -394,6 +422,16 @@ ArrayCount(char *str, int *dim, char typdelim)
|
|||||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||||
errmsg("malformed array literal: \"%s\"", str)));
|
errmsg("malformed array literal: \"%s\"", str)));
|
||||||
nest_level--;
|
nest_level--;
|
||||||
|
|
||||||
|
if ((nelems_last[nest_level] != 1) &&
|
||||||
|
(nelems[nest_level] != nelems_last[nest_level]))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||||
|
errmsg("multidimensional arrays must have "
|
||||||
|
"array expressions with matching "
|
||||||
|
"dimensions")));
|
||||||
|
nelems_last[nest_level] = nelems[nest_level];
|
||||||
|
nelems[nest_level] = 1;
|
||||||
if (nest_level == 0)
|
if (nest_level == 0)
|
||||||
eoArray = itemdone = true;
|
eoArray = itemdone = true;
|
||||||
else
|
else
|
||||||
@ -408,7 +446,10 @@ ArrayCount(char *str, int *dim, char typdelim)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (*ptr == typdelim && !scanning_string)
|
if (*ptr == typdelim && !scanning_string)
|
||||||
|
{
|
||||||
itemdone = true;
|
itemdone = true;
|
||||||
|
nelems[nest_level - 1]++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!itemdone)
|
if (!itemdone)
|
||||||
@ -684,8 +725,15 @@ array_out(PG_FUNCTION_ARGS)
|
|||||||
char *p,
|
char *p,
|
||||||
*tmp,
|
*tmp,
|
||||||
*retval,
|
*retval,
|
||||||
**values;
|
**values,
|
||||||
bool *needquotes;
|
/*
|
||||||
|
* 33 per dim since we assume 15 digits per number + ':' +'[]'
|
||||||
|
*
|
||||||
|
* +2 allows for assignment operator + trailing null
|
||||||
|
*/
|
||||||
|
dims_str[(MAXDIM * 33) + 2];
|
||||||
|
bool *needquotes,
|
||||||
|
needdims = false;
|
||||||
int nitems,
|
int nitems,
|
||||||
overall_length,
|
overall_length,
|
||||||
i,
|
i,
|
||||||
@ -693,7 +741,8 @@ array_out(PG_FUNCTION_ARGS)
|
|||||||
k,
|
k,
|
||||||
indx[MAXDIM];
|
indx[MAXDIM];
|
||||||
int ndim,
|
int ndim,
|
||||||
*dim;
|
*dim,
|
||||||
|
*lb;
|
||||||
ArrayMetaState *my_extra;
|
ArrayMetaState *my_extra;
|
||||||
|
|
||||||
element_type = ARR_ELEMTYPE(v);
|
element_type = ARR_ELEMTYPE(v);
|
||||||
@ -734,6 +783,7 @@ array_out(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
ndim = ARR_NDIM(v);
|
ndim = ARR_NDIM(v);
|
||||||
dim = ARR_DIMS(v);
|
dim = ARR_DIMS(v);
|
||||||
|
lb = ARR_LBOUND(v);
|
||||||
nitems = ArrayGetNItems(ndim, dim);
|
nitems = ArrayGetNItems(ndim, dim);
|
||||||
|
|
||||||
if (nitems == 0)
|
if (nitems == 0)
|
||||||
@ -742,6 +792,19 @@ array_out(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_CSTRING(retval);
|
PG_RETURN_CSTRING(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we will need to add explicit dimensions if any dimension
|
||||||
|
* has a lower bound other than one
|
||||||
|
*/
|
||||||
|
for (i = 0; i < ndim; i++)
|
||||||
|
{
|
||||||
|
if (lb[i] != 1)
|
||||||
|
{
|
||||||
|
needdims = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert all values to string form, count total space needed
|
* Convert all values to string form, count total space needed
|
||||||
* (including any overhead such as escaping backslashes), and detect
|
* (including any overhead such as escaping backslashes), and detect
|
||||||
@ -798,12 +861,28 @@ array_out(PG_FUNCTION_ARGS)
|
|||||||
*/
|
*/
|
||||||
for (i = j = 0, k = 1; i < ndim; k *= dim[i++], j += k);
|
for (i = j = 0, k = 1; i < ndim; k *= dim[i++], j += k);
|
||||||
|
|
||||||
retval = (char *) palloc(overall_length + 2 * j);
|
/* add explicit dimensions if required */
|
||||||
|
if (needdims)
|
||||||
|
{
|
||||||
|
char *ptr = dims_str;
|
||||||
|
|
||||||
|
for (i = 0; i < ndim; i++)
|
||||||
|
{
|
||||||
|
sprintf(ptr, "[%d:%d]", lb[i], lb[i] + dim[i] - 1);
|
||||||
|
ptr += strlen(ptr);
|
||||||
|
}
|
||||||
|
*ptr++ = *ASSGN;
|
||||||
|
*ptr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = (char *) palloc(strlen(dims_str) + overall_length + 2 * j);
|
||||||
p = retval;
|
p = retval;
|
||||||
|
|
||||||
#define APPENDSTR(str) (strcpy(p, (str)), p += strlen(p))
|
#define APPENDSTR(str) (strcpy(p, (str)), p += strlen(p))
|
||||||
#define APPENDCHAR(ch) (*p++ = (ch), *p = '\0')
|
#define APPENDCHAR(ch) (*p++ = (ch), *p = '\0')
|
||||||
|
|
||||||
|
if (needdims)
|
||||||
|
APPENDSTR(dims_str);
|
||||||
APPENDCHAR('{');
|
APPENDCHAR('{');
|
||||||
for (i = 0; i < ndim; indx[i++] = 0);
|
for (i = 0; i < ndim; indx[i++] = 0);
|
||||||
j = 0;
|
j = 0;
|
||||||
|
@ -28,8 +28,8 @@ INSERT INTO arrtest (a, b[1:2], c, d[1:2])
|
|||||||
VALUES ('{}', '{3,4}', '{foo,bar}', '{bar,foo}');
|
VALUES ('{}', '{3,4}', '{foo,bar}', '{bar,foo}');
|
||||||
SELECT * FROM arrtest;
|
SELECT * FROM arrtest;
|
||||||
a | b | c | d | e | f | g
|
a | b | c | d | e | f | g
|
||||||
-------------+-----------------+-----------+---------------+-----------+-----------------+-------------
|
-------------+-----------------+-----------+---------------+-----------------+-----------------+-------------
|
||||||
{1,2,3,4,5} | {{{0,0},{1,2}}} | {} | {} | {1.1,2.2} | {} | {}
|
{1,2,3,4,5} | {{{0,0},{1,2}}} | {} | {} | [0:1]={1.1,2.2} | {} | {}
|
||||||
{11,12,23} | {{3,4},{4,5}} | {foobar} | {{elt1,elt2}} | {3.4,6.7} | {"abc ",abcde} | {abc,abcde}
|
{11,12,23} | {{3,4},{4,5}} | {foobar} | {{elt1,elt2}} | {3.4,6.7} | {"abc ",abcde} | {abc,abcde}
|
||||||
{} | {3,4} | {foo,bar} | {bar,foo} | | |
|
{} | {3,4} | {foo,bar} | {bar,foo} | | |
|
||||||
(3 rows)
|
(3 rows)
|
||||||
@ -185,8 +185,8 @@ SELECT array_append(array[42], 6) AS "{42,6}";
|
|||||||
|
|
||||||
SELECT array_prepend(6, array[42]) AS "{6,42}";
|
SELECT array_prepend(6, array[42]) AS "{6,42}";
|
||||||
{6,42}
|
{6,42}
|
||||||
--------
|
--------------
|
||||||
{6,42}
|
[0:1]={6,42}
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT array_cat(ARRAY[1,2], ARRAY[3,4]) AS "{1,2,3,4}";
|
SELECT array_cat(ARRAY[1,2], ARRAY[3,4]) AS "{1,2,3,4}";
|
||||||
@ -197,8 +197,8 @@ SELECT array_cat(ARRAY[1,2], ARRAY[3,4]) AS "{1,2,3,4}";
|
|||||||
|
|
||||||
SELECT array_cat(ARRAY[1,2], ARRAY[[3,4],[5,6]]) AS "{{1,2},{3,4},{5,6}}";
|
SELECT array_cat(ARRAY[1,2], ARRAY[[3,4],[5,6]]) AS "{{1,2},{3,4},{5,6}}";
|
||||||
{{1,2},{3,4},{5,6}}
|
{{1,2},{3,4},{5,6}}
|
||||||
---------------------
|
--------------------------------
|
||||||
{{1,2},{3,4},{5,6}}
|
[0:2][1:2]={{1,2},{3,4},{5,6}}
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT array_cat(ARRAY[[3,4],[5,6]], ARRAY[1,2]) AS "{{3,4},{5,6},{1,2}}";
|
SELECT array_cat(ARRAY[[3,4],[5,6]], ARRAY[1,2]) AS "{{3,4},{5,6},{1,2}}";
|
||||||
@ -228,8 +228,8 @@ SELECT ARRAY[1,2] || 3 AS "{1,2,3}";
|
|||||||
|
|
||||||
SELECT 0 || ARRAY[1,2] AS "{0,1,2}";
|
SELECT 0 || ARRAY[1,2] AS "{0,1,2}";
|
||||||
{0,1,2}
|
{0,1,2}
|
||||||
---------
|
---------------
|
||||||
{0,1,2}
|
[0:2]={0,1,2}
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT ARRAY[1,2] || ARRAY[3,4] AS "{1,2,3,4}";
|
SELECT ARRAY[1,2] || ARRAY[3,4] AS "{1,2,3,4}";
|
||||||
@ -258,8 +258,8 @@ SELECT ARRAY[0,0] || ARRAY[1,1] || ARRAY[2,2] AS "{0,0,1,1,2,2}";
|
|||||||
|
|
||||||
SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}";
|
SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}";
|
||||||
{0,1,2,3}
|
{0,1,2,3}
|
||||||
-----------
|
-----------------
|
||||||
{0,1,2,3}
|
[0:3]={0,1,2,3}
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- array casts
|
-- array casts
|
||||||
|
@ -72,29 +72,29 @@ create table domarrtest
|
|||||||
( testint4arr domainint4arr
|
( testint4arr domainint4arr
|
||||||
, testtextarr domaintextarr
|
, testtextarr domaintextarr
|
||||||
);
|
);
|
||||||
INSERT INTO domarrtest values ('{2,2}', '{{"a","b"}{"c","d"}}');
|
INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"}}');
|
||||||
INSERT INTO domarrtest values ('{{2,2}{2,2}}', '{{"a","b"}}');
|
INSERT INTO domarrtest values ('{{2,2},{2,2}}', '{{"a","b"}}');
|
||||||
INSERT INTO domarrtest values ('{2,2}', '{{"a","b"}{"c","d"}{"e"}}');
|
INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"},{"e","f"}}');
|
||||||
INSERT INTO domarrtest values ('{2,2}', '{{"a"}{"c"}}');
|
INSERT INTO domarrtest values ('{2,2}', '{{"a"},{"c"}}');
|
||||||
INSERT INTO domarrtest values (NULL, '{{"a","b"}{"c","d","e"}}');
|
INSERT INTO domarrtest values (NULL, '{{"a","b","c"},{"d","e","f"}}');
|
||||||
select * from domarrtest;
|
select * from domarrtest;
|
||||||
testint4arr | testtextarr
|
testint4arr | testtextarr
|
||||||
---------------+---------------------
|
---------------+---------------------
|
||||||
{2,2} | {{a,c},{"",d}}
|
{2,2} | {{a,b},{c,d}}
|
||||||
{{2,2},{0,2}} | {{a,b}}
|
{{2,2},{2,2}} | {{a,b}}
|
||||||
{2,2} | {{a},{c},{e}}
|
{2,2} | {{a,b},{c,d},{e,f}}
|
||||||
{2,2} | {{c},{""}}
|
{2,2} | {{a},{c}}
|
||||||
| {{a,c,""},{"",d,e}}
|
| {{a,b,c},{d,e,f}}
|
||||||
(5 rows)
|
(5 rows)
|
||||||
|
|
||||||
select testint4arr[1], testtextarr[2:2] from domarrtest;
|
select testint4arr[1], testtextarr[2:2] from domarrtest;
|
||||||
testint4arr | testtextarr
|
testint4arr | testtextarr
|
||||||
-------------+-------------
|
-------------+-------------
|
||||||
2 | {{"",d}}
|
2 | {{c,d}}
|
||||||
|
|
|
|
||||||
|
2 | {{c,d}}
|
||||||
2 | {{c}}
|
2 | {{c}}
|
||||||
2 | {{""}}
|
| {{d,e,f}}
|
||||||
| {{"",d,e}}
|
|
||||||
(5 rows)
|
(5 rows)
|
||||||
|
|
||||||
drop table domarrtest;
|
drop table domarrtest;
|
||||||
|
@ -66,11 +66,11 @@ create table domarrtest
|
|||||||
( testint4arr domainint4arr
|
( testint4arr domainint4arr
|
||||||
, testtextarr domaintextarr
|
, testtextarr domaintextarr
|
||||||
);
|
);
|
||||||
INSERT INTO domarrtest values ('{2,2}', '{{"a","b"}{"c","d"}}');
|
INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"}}');
|
||||||
INSERT INTO domarrtest values ('{{2,2}{2,2}}', '{{"a","b"}}');
|
INSERT INTO domarrtest values ('{{2,2},{2,2}}', '{{"a","b"}}');
|
||||||
INSERT INTO domarrtest values ('{2,2}', '{{"a","b"}{"c","d"}{"e"}}');
|
INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"},{"e","f"}}');
|
||||||
INSERT INTO domarrtest values ('{2,2}', '{{"a"}{"c"}}');
|
INSERT INTO domarrtest values ('{2,2}', '{{"a"},{"c"}}');
|
||||||
INSERT INTO domarrtest values (NULL, '{{"a","b"}{"c","d","e"}}');
|
INSERT INTO domarrtest values (NULL, '{{"a","b","c"},{"d","e","f"}}');
|
||||||
select * from domarrtest;
|
select * from domarrtest;
|
||||||
select testint4arr[1], testtextarr[2:2] from domarrtest;
|
select testint4arr[1], testtextarr[2:2] from domarrtest;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user