提交 c1a94208 编写于 作者: A Alexey Grishchenko

Revert "PL/Python adding support for multi-dimensional arrays"

This reverts commit 41857ff3.
上级 c63f1b5d
......@@ -550,9 +550,6 @@ CREATE FUNCTION test_type_conversion_float8(x float8) returns float8 AS $$ retur
CREATE FUNCTION test_type_conversion_numeric(x numeric) returns numeric AS $$ return x $$ language plpythonu;
CREATE FUNCTION test_type_conversion_text(x text) returns text AS $$ return x $$ language plpythonu;
CREATE FUNCTION test_type_conversion_bytea(x bytea) returns bytea AS $$ return x $$ language plpythonu;
CREATE FUNCTION test_type_conversion_array_int4(x int4[]) RETURNS int4[] AS $$ return x $$ LANGUAGE plpythonu;
CREATE FUNCTION test_type_conversion_array_numeric(x numeric[]) returns numeric[] AS $$ return x $$ language plpythonu;
CREATE FUNCTION test_type_conversion_array_text(x text[]) RETURNS text[] AS $$ return x $$ LANGUAGE plpythonu;
CREATE FUNCTION test_type_marshal() returns bytea AS $$
import marshal
return marshal.dumps('hello world')
......@@ -587,16 +584,6 @@ RETURNS circle AS $$
exec('y = ' + s)
return y
$$ language plpythonu;
CREATE FUNCTION test_return_array_int(s text)
RETURNS int[] AS $$
exec('y = ' + s)
return y
$$ language plpythonu;
CREATE FUNCTION test_return_array_text(s text)
RETURNS text[] AS $$
exec('y = ' + s)
return y
$$ language plpythonu;
CREATE FUNCTION test_return_setof_void(s text)
RETURNS setof void AS $$
exec('y = ' + s)
......
......@@ -878,180 +878,6 @@ SELECT * FROM test_return_circle(E'"test\\0"');
ERROR: could not convert Python object into cstring: Python string representation appears to contain null bytes
CONTEXT: while creating return value
PL/Python function "test_return_circle"
--
-- Case 5: Return array of integers
--
-- Test returning arrays of fixed-width elements from PL/Python functions
--
-- From Python None
SELECT test_return_array_int('None');
test_return_array_int
-----------------------
(1 row)
SELECT * FROM test_return_array_int('None');
test_return_array_int
-----------------------
(1 row)
-- From Python empty list
SELECT test_return_array_int('[]');
test_return_array_int
-----------------------
{}
(1 row)
SELECT * FROM test_return_array_int('[]');
test_return_array_int
-----------------------
{}
(1 row)
-- From Python non-empty list
SELECT test_return_array_int('[1,2]');
test_return_array_int
-----------------------
{1,2}
(1 row)
SELECT * FROM test_return_array_int('[1,2]');
test_return_array_int
-----------------------
{1,2}
(1 row)
-- From Python multiple lists
SELECT test_return_array_int('[[1,2,3],[4,5,6]]');
test_return_array_int
-----------------------
{{1,2,3},{4,5,6}}
(1 row)
SELECT * FROM test_return_array_int('[[1,2,3],[4,5,6]]');
test_return_array_int
-----------------------
{{1,2,3},{4,5,6}}
(1 row)
-- Error conditions
-- Multi-dimensional array with non-fixed dimension sizes
SELECT test_return_array_int('[[1,2,3],[1,2]]');
ERROR: Multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length 2 while expected 3 (plpython.c:4865)
CONTEXT: while creating return value
PL/Python function "test_return_array_int"
SELECT * FROM test_return_array_int('[[1,2,3],[1,2]]');
ERROR: Multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length 2 while expected 3 (plpython.c:4865)
CONTEXT: while creating return value
PL/Python function "test_return_array_int"
-- Multi-dimensional array with mix of arrays and atomic elements
SELECT test_return_array_int('[[1,2,3],[1,[2,3],[4,5]]]');
ERROR: invalid input syntax for integer: "[2, 3]"
CONTEXT: while creating return value
PL/Python function "test_return_array_int"
SELECT * FROM test_return_array_int('[[1,2,3],[1,[2,3],[4,5]]]');
ERROR: invalid input syntax for integer: "[2, 3]"
CONTEXT: while creating return value
PL/Python function "test_return_array_int"
-- Multi-dimensional array with missing dimensions
SELECT test_return_array_int('[[1,2,3],None,[4,5,6]]');
ERROR: Multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length -1 while expected 3 (plpython.c:4865)
DETAIL: TypeError: object of type 'NoneType' has no len()
CONTEXT: while creating return value
PL/Python function "test_return_array_int"
SELECT * FROM test_return_array_int('[[1,2,3],None,[4,5,6]]');
ERROR: Multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length -1 while expected 3 (plpython.c:4865)
DETAIL: TypeError: object of type 'NoneType' has no len()
CONTEXT: while creating return value
PL/Python function "test_return_array_int"
--
-- Case 5: Return array of texts
--
-- Test returning arrays of variable-width elements from PL/Python functions
--
-- From Python None
SELECT test_return_array_text('None');
test_return_array_text
------------------------
(1 row)
SELECT * FROM test_return_array_text('None');
test_return_array_text
------------------------
(1 row)
-- From Python empty list
SELECT test_return_array_text('[]');
test_return_array_text
------------------------
{}
(1 row)
SELECT * FROM test_return_array_text('[]');
test_return_array_text
------------------------
{}
(1 row)
-- From Python non-empty list
SELECT test_return_array_text('["abc","def"]');
test_return_array_text
------------------------
{abc,def}
(1 row)
SELECT * FROM test_return_array_text('["abc","def"]');
test_return_array_text
------------------------
{abc,def}
(1 row)
-- From Python multiple lists
SELECT test_return_array_text('[["a","bcd","ef"],[None,"gh","ijklm"]]');
test_return_array_text
------------------------------
{{a,bcd,ef},{NULL,gh,ijklm}}
(1 row)
SELECT * FROM test_return_array_text('[["a","bcd","ef"],[None,"gh","ijklm"]]');
test_return_array_text
------------------------------
{{a,bcd,ef},{NULL,gh,ijklm}}
(1 row)
-- Error conditions
-- Multi-dimensional array with non-fixed dimension sizes
SELECT test_return_array_text('[["a","bcd","ef"],[None,"gh","ijklm","ERROR"]]');
ERROR: Multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length 4 while expected 3 (plpython.c:4865)
CONTEXT: while creating return value
PL/Python function "test_return_array_text"
SELECT * FROM test_return_array_text('[["a","bcd","ef"],[None,"gh","ijklm","ERROR"]]');
ERROR: Multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length 4 while expected 3 (plpython.c:4865)
CONTEXT: while creating return value
PL/Python function "test_return_array_text"
-- Multi-dimensional array with mix of arrays and atomic elements
SELECT test_return_array_text('[[["a"],"b"],["c",["d","e"]]]');
ERROR: Multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length 2 while expected 1 (plpython.c:4865)
CONTEXT: while creating return value
PL/Python function "test_return_array_text"
SELECT * FROM test_return_array_text('[[["a"],"b"],["c",["d","e"]]]');
ERROR: Multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length 2 while expected 1 (plpython.c:4865)
CONTEXT: while creating return value
PL/Python function "test_return_array_text"
-- Multi-dimensional array with missing dimensions
SELECT test_return_array_text('[["abc","def"],None,["ghij","k"]]');
ERROR: Multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length -1 while expected 2 (plpython.c:4865)
DETAIL: TypeError: object of type 'NoneType' has no len()
CONTEXT: while creating return value
PL/Python function "test_return_array_text"
SELECT * FROM test_return_array_text('[["abc","def"],None,["ghij","k"]]');
ERROR: Multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length -1 while expected 2 (plpython.c:4865)
DETAIL: TypeError: object of type 'NoneType' has no len()
CONTEXT: while creating return value
PL/Python function "test_return_array_text"
-- ===================================================
-- TEST 2: RETURN VALUE TESTING - SETOF scalar values
-- ===================================================
......
......@@ -726,88 +726,6 @@ SELECT * FROM test_type_conversion_bytea(null);
(1 row)
-- 1-dimensional arrays
SELECT * FROM test_type_conversion_array_int4(array[1,2,null,3,4]::int4[]);
test_type_conversion_array_int4
---------------------------------
{1,2,NULL,3,4}
(1 row)
SELECT * FROM test_type_conversion_array_int4(null);
test_type_conversion_array_int4
---------------------------------
(1 row)
SELECT * FROM test_type_conversion_array_numeric(array[null,1.23,2.34,3.45,null]::numeric[]);
test_type_conversion_array_numeric
------------------------------------
{NULL,1.23,2.34,3.45,NULL}
(1 row)
SELECT * FROM test_type_conversion_array_text(array['abc','def','ghij',null]::text[]);
test_type_conversion_array_text
---------------------------------
{abc,def,ghij,NULL}
(1 row)
SELECT * FROM test_type_conversion_array_text(null);
test_type_conversion_array_text
---------------------------------
(1 row)
-- Multi-dimensional arrays
SELECT a, array_dims(a) FROM test_type_conversion_array_int4(array[
array[1,2,3,4], array[5,null,7,8], array[null,null,11,12]
]::int4[]) as a;
a | array_dims
--------------------------------------------+------------
{{1,2,3,4},{5,NULL,7,8},{NULL,NULL,11,12}} | [1:3][1:4]
(1 row)
SELECT a, array_dims(a) FROM test_type_conversion_array_int4(array[
array[ array[1,2,3,4], array[5,null,7,8], array[null,null,11,12] ],
array[ array[13,null,15,16], array[17,18,19,20], array[null,null,23,null] ],
array[ array[25,26,27,null], array[29,null,null,32], array[null,null,null,null] ]
]::int4[]) as a;
a | array_dims
------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------
{{{1,2,3,4},{5,NULL,7,8},{NULL,NULL,11,12}},{{13,NULL,15,16},{17,18,19,20},{NULL,NULL,23,NULL}},{{25,26,27,NULL},{29,NULL,NULL,32},{NULL,NULL,NULL,NULL}}} | [1:3][1:3][1:4]
(1 row)
SELECT a, array_dims(a) FROM test_type_conversion_array_numeric(array[
array[null,1.23,2.34,3.45,null],
array[4.56,5.67,null,null,6.78]
]::numeric[]) as a;
a | array_dims
---------------------------------------------------------+------------
{{NULL,1.23,2.34,3.45,NULL},{4.56,5.67,NULL,NULL,6.78}} | [1:2][1:5]
(1 row)
SELECT a, array_dims(a) FROM test_type_conversion_array_text(array[
array['abc','def','ghij',null],
array[null,'kl','mnopq','rst'],
array['uvw','',null,'xyz']
]::text[]) as a;
a | array_dims
-------------------------------------------------------------+------------
{{abc,def,ghij,NULL},{NULL,kl,mnopq,rst},{uvw,"",NULL,xyz}} | [1:3][1:4]
(1 row)
SELECT a, array_dims(a) FROM test_type_conversion_array_text(array[
array[ array['abc','def','ghij',null],
array[null,'kl','mnopq','rst'],
array['uvw','',null,'xyz'] ],
array[ array['A','BCD',null,'EFG'],
array[null,'HIJK','LMN','OPQR'],
array['STUV','WXYZ',null,null] ]
]::text[]) as a;
a | array_dims
-----------------------------------------------------------------------------------------------------------------------------+-----------------
{{{abc,def,ghij,NULL},{NULL,kl,mnopq,rst},{uvw,"",NULL,xyz}},{{A,BCD,NULL,EFG},{NULL,HIJK,LMN,OPQR},{STUV,WXYZ,NULL,NULL}}} | [1:2][1:3][1:4]
(1 row)
SELECT test_type_unmarshal(x) FROM test_type_marshal() x;
test_type_unmarshal
---------------------
......
......@@ -2552,111 +2552,62 @@ PLyList_FromArray(PLyDatumToOb *arg, Datum d)
{
ArrayType *array = DatumGetArrayTypeP(d);
PLyDatumToOb *elm = arg->elm;
int ndim;
int *dims;
int *lb;
char *dataptr;
bits8 *bitmap;
int bitmask;
PyObject *list;
int length;
int lbound;
int i;
int dim;
int indx[MAXDIM];
PyObject *lists[MAXDIM];
char *dataptr;
bits8 *bitmap;
int bitmask;
if (ARR_NDIM(array) == 0)
return PyList_New(0);
/* Array dimensions and left bounds */
ndim = ARR_NDIM(array);
dims = ARR_DIMS(array);
lb = ARR_LBOUND(array);
if (ARR_NDIM(array) != 1)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot convert multidimensional array to Python list"),
errdetail("PL/Python only supports one-dimensional arrays.")));
length = ARR_DIMS(array)[0];
lbound = ARR_LBOUND(array)[0];
list = PyList_New(length);
/* Internal array representation pointers */
dataptr = ARR_DATA_PTR(array);
bitmap = ARR_NULLBITMAP(array);
bitmask = 1;
/* Iterators initialization */
for (i = 0; i < ndim; i++) {
indx[i] = lb[i];
lists[i] = NULL;
}
lists[0] = PyList_New(dims[0]);
/* We need this incref to keep the pointer valid after the array traversal
* terminates, as this traversal does DECREF for all the lists in array */
Py_INCREF(lists[0]);
/* In this cycle we are going over array dimensions. Postgres offers you an
* option to iterate over all the multi-dimensional array elemens in order.
* For 3-dimesnional array the order of iteration would be following - first
* you start with [0,0,0] elements through [0,0,k], then [0,1,0] till [0,1,k]
* till [0,m,k], then [1,0,0] till [1,0,k] till [1,m,k], and so on.
* In Python, each 1-d array is a separate list object, so 3-d array of
* [n,m,k] element is a list of n m-element arrays, each element of which is
* k-element array. In this cycle we traverse from outter dimensions to
* inner ones, creating nested Python lists during traversal */
dim = 0;
while (dim >= 0)
for (i = 0; i < length; i++)
{
/* If we finished up iterating over current dimension - go one level up */
if (indx[dim] > dims[dim])
/* Get source element, checking for NULL */
if (bitmap && (*bitmap & bitmask) == 0)
{
Py_DECREF(lists[dim]);
indx[dim] = 0;
dim -= 1;
Py_INCREF(Py_None);
PyList_SET_ITEM(list, i, Py_None);
}
/* If we are processing inner dimension - create one more list */
else if (dim < ndim - 1)
else
{
lists[dim+1] = PyList_New(dims[dim+1]);
/* We need this INCREF as we keep array pointer on our side,
* while PyList_SET_ITEM steals the reference */
Py_INCREF(lists[dim+1]);
Datum itemvalue;
PyList_SET_ITEM(lists[dim], indx[dim] - lb[dim], lists[dim+1]);
indx[dim] += 1;
dim += 1;
indx[dim] = lb[dim];
itemvalue = fetch_att(dataptr, elm->typbyval, elm->typlen);
PyList_SET_ITEM(list, i, elm->func(elm, itemvalue));
dataptr = att_addlength_pointer(dataptr, elm->typlen, dataptr);
dataptr = (char *) att_align_nominal(dataptr, elm->typalign);
}
/* If we are iterating over the outter dimension, fill the list with
* values from the original Postgres array */
else if (dim == ndim - 1)
/* advance bitmap pointer if any */
if (bitmap)
{
for (indx[dim] = lb[dim]; indx[dim] <= dims[dim]; indx[dim]++)
bitmask <<= 1;
if (bitmask == 0x100 /* (1<<8) */)
{
/* checking for NULL */
if (bitmap && (*bitmap & bitmask) == 0)
{
Py_INCREF(Py_None);
PyList_SET_ITEM(lists[dim], indx[dim] - lb[dim], Py_None);
}
else
{
Datum itemvalue;
itemvalue = fetch_att(dataptr, elm->typbyval, elm->typlen);
PyList_SET_ITEM(lists[dim], indx[dim] - lb[dim], elm->func(elm, itemvalue));
dataptr = att_addlength_pointer(dataptr, elm->typlen, dataptr);
dataptr = (char *) att_align_nominal(dataptr, elm->typalign);
}
/* advance bitmap pointer if any */
if (bitmap)
{
bitmask <<= 1;
if (bitmask == 0x100 /* (1<<8) */)
{
bitmap++;
bitmask = 1;
}
}
bitmap++;
bitmask = 1;
}
}
}
return lists[0];
return list;
}
static PyObject *
......@@ -2905,116 +2856,39 @@ PLySequence_ToArray(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
Datum *elems;
bool *nulls;
int len;
PyObject *pyptr;
int ndim;
int dims[MAXDIM];
int lbs[MAXDIM];
int indx[MAXDIM];
PyObject *stack[MAXDIM];
int dim;
int idxelem;
int lbs;
Assert(plrv != Py_None);
if (!PySequence_Check(plrv))
PLy_elog(ERROR, "return value of function with array return type is not a Python sequence");
pyptr = plrv;
ndim = 0;
len = 1;
/* We want to iterate through all iterable objects except by strings */
while (pyptr != NULL && PySequence_Check(pyptr) &&
!(PyString_Check(pyptr) || PyBytes_Check(pyptr) || PyUnicode_Check(pyptr))) {
dims[ndim] = PySequence_Length(pyptr);
if (dims[ndim] < 0)
PLy_elog(ERROR, "Cannot determine sequence length for function return value");
len *= dims[ndim];
stack[ndim] = pyptr;
ndim += 1;
if (dims[ndim - 1] == 0) {
pyptr = NULL;
break;
}
pyptr = PySequence_GetItem(pyptr, 0);
}
/* Pyptr points to element of n-dimensional array, we don't need its reference */
Py_XDECREF(pyptr);
/* We need this incref to keep the pointer valid after the array traversal
* terminates, as this traversal does DECREF for all the lists in array, and
* stack[0] corresponds to function return value */
Py_INCREF(stack[0]);
len = PySequence_Length(plrv);
elems = palloc(sizeof(*elems) * len);
nulls = palloc(sizeof(*nulls) * len);
for (i = 0; i < ndim; i++) {
indx[i] = 0;
lbs[i] = 1;
}
/* In this cycle we are going over nested Python lists, fetching elements
* from the deepest level and putting them into a linear array for Postgres
* to interpret them as n-dimensional array. This is a cycle implementation
* of DFS (recursive traversal of nested arrays here), keeping the stack in
* "stack" variable */
dim = 0;
idxelem = 0;
while (dim >= 0)
for (i = 0; i < len; i++)
{
/* If we finished up iterating over current list - go one level up */
if (indx[dim] == dims[dim])
{
Py_DECREF(stack[dim]);
indx[dim] = 0;
dim -= 1;
}
/* If we are processing inner list - create one more list */
else if (dim < ndim - 1)
{
stack[dim+1] = PySequence_GetItem(stack[dim], indx[dim]);
if (PySequence_Length(stack[dim+1]) != dims[dim+1])
PLy_elog(ERROR, "Multidimensional arrays must have array expressions with matching dimensions. "
"PL/Python function return value has sequence length %d while expected %d",
(int)PySequence_Length(stack[dim+1]), dims[dim+1]);
indx[dim] += 1;
dim += 1;
}
/* If we are iterating over the outter list, fill the output array */
else if (dim == ndim - 1)
{
for (indx[dim] = 0; indx[dim] < dims[dim]; indx[dim]++) {
PyObject *obj = PySequence_GetItem(stack[dim], indx[dim]);
PyObject *obj = PySequence_GetItem(plrv, i);
if (obj == Py_None)
nulls[idxelem] = true;
else
{
nulls[idxelem] = false;
if (obj == Py_None)
nulls[i] = true;
else
{
nulls[i] = false;
/*
* We don't support arrays of row types yet, so the first argument
* can be NULL.
*/
elems[idxelem] = arg->elm->func(arg->elm, -1, obj);
}
Py_XDECREF(obj);
idxelem += 1;
}
/*
* We don't support arrays of row types yet, so the first argument
* can be NULL.
*/
elems[i] = arg->elm->func(arg->elm, -1, obj);
}
Py_XDECREF(obj);
}
array = construct_md_array(elems,
nulls,
ndim,
dims,
lbs,
get_element_type(arg->typoid),
arg->elm->typlen,
arg->elm->typbyval,
arg->elm->typalign);
lbs = 1;
array = construct_md_array(elems, nulls, 1, &len, &lbs,
get_element_type(arg->typoid), arg->elm->typlen, arg->elm->typbyval, arg->elm->typalign);
return PointerGetDatum(array);
}
......
......@@ -576,9 +576,6 @@ CREATE FUNCTION test_type_conversion_float8(x float8) returns float8 AS $$ retur
CREATE FUNCTION test_type_conversion_numeric(x numeric) returns numeric AS $$ return x $$ language plpythonu;
CREATE FUNCTION test_type_conversion_text(x text) returns text AS $$ return x $$ language plpythonu;
CREATE FUNCTION test_type_conversion_bytea(x bytea) returns bytea AS $$ return x $$ language plpythonu;
CREATE FUNCTION test_type_conversion_array_int4(x int4[]) RETURNS int4[] AS $$ return x $$ LANGUAGE plpythonu;
CREATE FUNCTION test_type_conversion_array_numeric(x numeric[]) returns numeric[] AS $$ return x $$ language plpythonu;
CREATE FUNCTION test_type_conversion_array_text(x text[]) RETURNS text[] AS $$ return x $$ LANGUAGE plpythonu;
CREATE FUNCTION test_type_marshal() returns bytea AS $$
import marshal
return marshal.dumps('hello world')
......@@ -614,16 +611,6 @@ RETURNS circle AS $$
exec('y = ' + s)
return y
$$ language plpythonu;
CREATE FUNCTION test_return_array_int(s text)
RETURNS int[] AS $$
exec('y = ' + s)
return y
$$ language plpythonu;
CREATE FUNCTION test_return_array_text(s text)
RETURNS text[] AS $$
exec('y = ' + s)
return y
$$ language plpythonu;
CREATE FUNCTION test_return_setof_void(s text)
RETURNS setof void AS $$
exec('y = ' + s)
......
......@@ -356,77 +356,6 @@ SELECT * FROM test_return_circle('{None: None}');
SELECT test_return_circle(E'"test\\0"');
SELECT * FROM test_return_circle(E'"test\\0"');
--
-- Case 5: Return array of integers
--
-- Test returning arrays of fixed-width elements from PL/Python functions
--
-- From Python None
SELECT test_return_array_int('None');
SELECT * FROM test_return_array_int('None');
-- From Python empty list
SELECT test_return_array_int('[]');
SELECT * FROM test_return_array_int('[]');
-- From Python non-empty list
SELECT test_return_array_int('[1,2]');
SELECT * FROM test_return_array_int('[1,2]');
-- From Python multiple lists
SELECT test_return_array_int('[[1,2,3],[4,5,6]]');
SELECT * FROM test_return_array_int('[[1,2,3],[4,5,6]]');
-- Error conditions
-- Multi-dimensional array with non-fixed dimension sizes
SELECT test_return_array_int('[[1,2,3],[1,2]]');
SELECT * FROM test_return_array_int('[[1,2,3],[1,2]]');
-- Multi-dimensional array with mix of arrays and atomic elements
SELECT test_return_array_int('[[1,2,3],[1,[2,3],[4,5]]]');
SELECT * FROM test_return_array_int('[[1,2,3],[1,[2,3],[4,5]]]');
-- Multi-dimensional array with missing dimensions
SELECT test_return_array_int('[[1,2,3],None,[4,5,6]]');
SELECT * FROM test_return_array_int('[[1,2,3],None,[4,5,6]]');
--
-- Case 5: Return array of texts
--
-- Test returning arrays of variable-width elements from PL/Python functions
--
-- From Python None
SELECT test_return_array_text('None');
SELECT * FROM test_return_array_text('None');
-- From Python empty list
SELECT test_return_array_text('[]');
SELECT * FROM test_return_array_text('[]');
-- From Python non-empty list
SELECT test_return_array_text('["abc","def"]');
SELECT * FROM test_return_array_text('["abc","def"]');
-- From Python multiple lists
SELECT test_return_array_text('[["a","bcd","ef"],[None,"gh","ijklm"]]');
SELECT * FROM test_return_array_text('[["a","bcd","ef"],[None,"gh","ijklm"]]');
-- Error conditions
-- Multi-dimensional array with non-fixed dimension sizes
SELECT test_return_array_text('[["a","bcd","ef"],[None,"gh","ijklm","ERROR"]]');
SELECT * FROM test_return_array_text('[["a","bcd","ef"],[None,"gh","ijklm","ERROR"]]');
-- Multi-dimensional array with mix of arrays and atomic elements
SELECT test_return_array_text('[[["a"],"b"],["c",["d","e"]]]');
SELECT * FROM test_return_array_text('[[["a"],"b"],["c",["d","e"]]]');
-- Multi-dimensional array with missing dimensions
SELECT test_return_array_text('[["abc","def"],None,["ghij","k"]]');
SELECT * FROM test_return_array_text('[["abc","def"],None,["ghij","k"]]');
-- ===================================================
-- TEST 2: RETURN VALUE TESTING - SETOF scalar values
......
......@@ -187,39 +187,6 @@ SELECT * FROM test_type_conversion_text('hello world');
SELECT * FROM test_type_conversion_text(null);
SELECT * FROM test_type_conversion_bytea('hello world');
SELECT * FROM test_type_conversion_bytea(null);
-- 1-dimensional arrays
SELECT * FROM test_type_conversion_array_int4(array[1,2,null,3,4]::int4[]);
SELECT * FROM test_type_conversion_array_int4(null);
SELECT * FROM test_type_conversion_array_numeric(array[null,1.23,2.34,3.45,null]::numeric[]);
SELECT * FROM test_type_conversion_array_text(array['abc','def','ghij',null]::text[]);
SELECT * FROM test_type_conversion_array_text(null);
-- Multi-dimensional arrays
SELECT a, array_dims(a) FROM test_type_conversion_array_int4(array[
array[1,2,3,4], array[5,null,7,8], array[null,null,11,12]
]::int4[]) as a;
SELECT a, array_dims(a) FROM test_type_conversion_array_int4(array[
array[ array[1,2,3,4], array[5,null,7,8], array[null,null,11,12] ],
array[ array[13,null,15,16], array[17,18,19,20], array[null,null,23,null] ],
array[ array[25,26,27,null], array[29,null,null,32], array[null,null,null,null] ]
]::int4[]) as a;
SELECT a, array_dims(a) FROM test_type_conversion_array_numeric(array[
array[null,1.23,2.34,3.45,null],
array[4.56,5.67,null,null,6.78]
]::numeric[]) as a;
SELECT a, array_dims(a) FROM test_type_conversion_array_text(array[
array['abc','def','ghij',null],
array[null,'kl','mnopq','rst'],
array['uvw','',null,'xyz']
]::text[]) as a;
SELECT a, array_dims(a) FROM test_type_conversion_array_text(array[
array[ array['abc','def','ghij',null],
array[null,'kl','mnopq','rst'],
array['uvw','',null,'xyz'] ],
array[ array['A','BCD',null,'EFG'],
array[null,'HIJK','LMN','OPQR'],
array['STUV','WXYZ',null,null] ]
]::text[]) as a;
SELECT test_type_unmarshal(x) FROM test_type_marshal() x;
SELECT (split(10)).*;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册