Commit 0e13d627 authored by Joe Conway's avatar Joe Conway

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.
parent 39ec59f3
<!-- $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 ( ...@@ -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 ...@@ -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>
Note that with this syntax, multidimensional arrays must have matching
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> </programlisting>
Also notice that the array elements are ordinary SQL constants or 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; ...@@ -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'; ...@@ -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); ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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]) ...@@ -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}"; ...@@ -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}"; ...@@ -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}"; ...@@ -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}"; ...@@ -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 ...@@ -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 ...@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment