mirror of https://github.com/citusdata/citus.git
Merge pull request #3211 from citusdata/support-recordarray
Implement support for RECORD[] where we support RECORDpull/3237/head
commit
6d14f63f81
|
@ -1169,7 +1169,7 @@ FinalizeRouterPlan(PlannedStmt *localPlan, CustomScan *customScan)
|
||||||
/* build target entry pointing to remote scan range table entry */
|
/* build target entry pointing to remote scan range table entry */
|
||||||
Var *newVar = makeVarFromTargetEntry(customScanRangeTableIndex, targetEntry);
|
Var *newVar = makeVarFromTargetEntry(customScanRangeTableIndex, targetEntry);
|
||||||
|
|
||||||
if (newVar->vartype == RECORDOID)
|
if (newVar->vartype == RECORDOID || newVar->vartype == RECORDARRAYOID)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Add the anonymous composite type to the type cache and store
|
* Add the anonymous composite type to the type cache and store
|
||||||
|
@ -1263,7 +1263,7 @@ BlessRecordExpression(Expr *expr)
|
||||||
Oid rowArgTypeId = exprType(rowArg);
|
Oid rowArgTypeId = exprType(rowArg);
|
||||||
int rowArgTypeMod = exprTypmod(rowArg);
|
int rowArgTypeMod = exprTypmod(rowArg);
|
||||||
|
|
||||||
if (rowArgTypeId == RECORDOID)
|
if (rowArgTypeId == RECORDOID || rowArgTypeId == RECORDARRAYOID)
|
||||||
{
|
{
|
||||||
/* ensure nested rows are blessed as well */
|
/* ensure nested rows are blessed as well */
|
||||||
rowArgTypeMod = BlessRecordExpression((Expr *) rowArg);
|
rowArgTypeMod = BlessRecordExpression((Expr *) rowArg);
|
||||||
|
@ -1281,6 +1281,33 @@ BlessRecordExpression(Expr *expr)
|
||||||
|
|
||||||
typeMod = rowTupleDesc->tdtypmod;
|
typeMod = rowTupleDesc->tdtypmod;
|
||||||
}
|
}
|
||||||
|
else if (IsA(expr, ArrayExpr))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Handle row array expressions, e.g. SELECT ARRAY[(1,2)];
|
||||||
|
*/
|
||||||
|
ArrayExpr *arrayExpr = (ArrayExpr *) expr;
|
||||||
|
ListCell *elemCell = NULL;
|
||||||
|
|
||||||
|
foreach(elemCell, arrayExpr->elements)
|
||||||
|
{
|
||||||
|
Node *elemArg = (Node *) lfirst(elemCell);
|
||||||
|
int32 arrayTypeMod = BlessRecordExpression((Expr *) elemArg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Postgres allows ARRAY[(1,2),(1,2,3)]. We do not.
|
||||||
|
* If multiple RECORD shapes exist in an ArrayExpr, bail out.
|
||||||
|
*/
|
||||||
|
if (typeMod == -1)
|
||||||
|
{
|
||||||
|
typeMod = arrayTypeMod;
|
||||||
|
}
|
||||||
|
else if (arrayTypeMod != typeMod)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return typeMod;
|
return typeMod;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1402,7 +1402,7 @@ MasterExtendedOpNode(MultiExtendedOp *originalOpNode,
|
||||||
column->varoattno = walkerContext->columnId;
|
column->varoattno = walkerContext->columnId;
|
||||||
walkerContext->columnId++;
|
walkerContext->columnId++;
|
||||||
|
|
||||||
if (column->vartype == RECORDOID)
|
if (column->vartype == RECORDOID || column->vartype == RECORDARRAYOID)
|
||||||
{
|
{
|
||||||
column->vartypmod = BlessRecordExpression(originalTargetEntry->expr);
|
column->vartypmod = BlessRecordExpression(originalTargetEntry->expr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ MasterTargetList(List *workerTargetList)
|
||||||
masterColumn->varoattno = columnId;
|
masterColumn->varoattno = columnId;
|
||||||
columnId++;
|
columnId++;
|
||||||
|
|
||||||
if (masterColumn->vartype == RECORDOID)
|
if (masterColumn->vartype == RECORDOID || masterColumn->vartype == RECORDARRAYOID)
|
||||||
{
|
{
|
||||||
masterColumn->vartypmod = BlessRecordExpression(workerTargetEntry->expr);
|
masterColumn->vartypmod = BlessRecordExpression(workerTargetEntry->expr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ SELECT create_distributed_table('test','x');
|
||||||
CREATE OR REPLACE FUNCTION table_returner(INT) RETURNS TABLE(name text, id INT)
|
CREATE OR REPLACE FUNCTION table_returner(INT) RETURNS TABLE(name text, id INT)
|
||||||
AS $$
|
AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN QUERY SELECT $1::text, $1;
|
RETURN QUERY SELECT $1::text, $1;
|
||||||
END;
|
END;
|
||||||
$$ language plpgsql;
|
$$ language plpgsql;
|
||||||
SELECT create_distributed_function('table_returner(int)');
|
SELECT create_distributed_function('table_returner(int)');
|
||||||
|
@ -24,8 +24,8 @@ CREATE OR REPLACE FUNCTION record_returner(INOUT id int, OUT name text)
|
||||||
RETURNS record
|
RETURNS record
|
||||||
AS $$
|
AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
id := id + 1;
|
id := id + 1;
|
||||||
name := 'returned';
|
name := 'returned';
|
||||||
END;
|
END;
|
||||||
$$ language plpgsql;
|
$$ language plpgsql;
|
||||||
SELECT create_distributed_function('record_returner(int)');
|
SELECT create_distributed_function('record_returner(int)');
|
||||||
|
@ -54,6 +54,24 @@ SELECT (x,y) FROM test GROUP BY x, y ORDER BY x, y;
|
||||||
(2,3)
|
(2,3)
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
|
SELECT ARRAY[(x,(y,x)),(y,(x,y))] FROM test ORDER BY x, y;
|
||||||
|
array
|
||||||
|
-----------------------------------
|
||||||
|
{"(1,\"(2,1)\")","(2,\"(1,2)\")"}
|
||||||
|
{"(1,\"(3,1)\")","(3,\"(1,3)\")"}
|
||||||
|
{"(2,\"(2,2)\")","(2,\"(2,2)\")"}
|
||||||
|
{"(2,\"(3,2)\")","(3,\"(2,3)\")"}
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
SELECT ARRAY[[(x,(y,x))],[(x,(x,y))]] FROM test ORDER BY x, y;
|
||||||
|
array
|
||||||
|
---------------------------------------
|
||||||
|
{{"(1,\"(2,1)\")"},{"(1,\"(1,2)\")"}}
|
||||||
|
{{"(1,\"(3,1)\")"},{"(1,\"(1,3)\")"}}
|
||||||
|
{{"(2,\"(2,2)\")"},{"(2,\"(2,2)\")"}}
|
||||||
|
{{"(2,\"(3,2)\")"},{"(2,\"(2,3)\")"}}
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
select distinct (x,y) AS foo, x, y FROM test ORDER BY x, y;
|
select distinct (x,y) AS foo, x, y FROM test ORDER BY x, y;
|
||||||
foo | x | y
|
foo | x | y
|
||||||
-------+---+---
|
-------+---+---
|
||||||
|
@ -81,6 +99,11 @@ SELECT record_returner(x) FROM test ORDER BY x, y;
|
||||||
(3,returned)
|
(3,returned)
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
|
-- RECORD[] with varying shape unsupported
|
||||||
|
SELECT ARRAY[(x,(y,x),y),(y,(x,y))] FROM test ORDER BY x, y;
|
||||||
|
ERROR: input of anonymous composite types is not implemented
|
||||||
|
SELECT ARRAY[[(x,(y,x))],[((x,x),y)]] FROM test ORDER BY x, y;
|
||||||
|
ERROR: input of anonymous composite types is not implemented
|
||||||
-- router queries support row types
|
-- router queries support row types
|
||||||
SELECT (x,y) FROM test WHERE x = 1 ORDER BY x, y;
|
SELECT (x,y) FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
row
|
row
|
||||||
|
@ -96,6 +119,20 @@ SELECT (x,y) AS foo FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
(1,3)
|
(1,3)
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT ARRAY[(x,(y,x)),(y,(x,y))] FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
|
array
|
||||||
|
-----------------------------------
|
||||||
|
{"(1,\"(2,1)\")","(2,\"(1,2)\")"}
|
||||||
|
{"(1,\"(3,1)\")","(3,\"(1,3)\")"}
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT ARRAY[[(x,(y,x))],[(x,(x,y))]] FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
|
array
|
||||||
|
---------------------------------------
|
||||||
|
{{"(1,\"(2,1)\")"},{"(1,\"(1,2)\")"}}
|
||||||
|
{{"(1,\"(3,1)\")"},{"(1,\"(1,3)\")"}}
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
select distinct (x,y) AS foo, x, y FROM test WHERE x = 1 ORDER BY x, y;
|
select distinct (x,y) AS foo, x, y FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
foo | x | y
|
foo | x | y
|
||||||
-------+---+---
|
-------+---+---
|
||||||
|
@ -117,6 +154,11 @@ SELECT record_returner(x) FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
(2,returned)
|
(2,returned)
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
|
-- RECORD[] with varying shape unsupported
|
||||||
|
SELECT ARRAY[(x,(y,x),y),(y,(x,y))] FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
|
ERROR: input of anonymous composite types is not implemented
|
||||||
|
SELECT ARRAY[[(x,(y,x))],[((x,x),y)]] FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
|
ERROR: input of anonymous composite types is not implemented
|
||||||
-- nested row expressions
|
-- nested row expressions
|
||||||
SELECT (x,(x,y)) AS foo FROM test WHERE x = 1 ORDER BY x, y;
|
SELECT (x,(x,y)) AS foo FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
foo
|
foo
|
||||||
|
|
|
@ -8,7 +8,7 @@ SELECT create_distributed_table('test','x');
|
||||||
CREATE OR REPLACE FUNCTION table_returner(INT) RETURNS TABLE(name text, id INT)
|
CREATE OR REPLACE FUNCTION table_returner(INT) RETURNS TABLE(name text, id INT)
|
||||||
AS $$
|
AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN QUERY SELECT $1::text, $1;
|
RETURN QUERY SELECT $1::text, $1;
|
||||||
END;
|
END;
|
||||||
$$ language plpgsql;
|
$$ language plpgsql;
|
||||||
SELECT create_distributed_function('table_returner(int)');
|
SELECT create_distributed_function('table_returner(int)');
|
||||||
|
@ -17,8 +17,8 @@ CREATE OR REPLACE FUNCTION record_returner(INOUT id int, OUT name text)
|
||||||
RETURNS record
|
RETURNS record
|
||||||
AS $$
|
AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
id := id + 1;
|
id := id + 1;
|
||||||
name := 'returned';
|
name := 'returned';
|
||||||
END;
|
END;
|
||||||
$$ language plpgsql;
|
$$ language plpgsql;
|
||||||
SELECT create_distributed_function('record_returner(int)');
|
SELECT create_distributed_function('record_returner(int)');
|
||||||
|
@ -29,16 +29,26 @@ INSERT INTO test VALUES (1,2), (1,3), (2,2), (2,3);
|
||||||
-- multi-shard queries support row types
|
-- multi-shard queries support row types
|
||||||
SELECT (x,y) FROM test ORDER BY x, y;
|
SELECT (x,y) FROM test ORDER BY x, y;
|
||||||
SELECT (x,y) FROM test GROUP BY x, y ORDER BY x, y;
|
SELECT (x,y) FROM test GROUP BY x, y ORDER BY x, y;
|
||||||
|
SELECT ARRAY[(x,(y,x)),(y,(x,y))] FROM test ORDER BY x, y;
|
||||||
|
SELECT ARRAY[[(x,(y,x))],[(x,(x,y))]] FROM test ORDER BY x, y;
|
||||||
select distinct (x,y) AS foo, x, y FROM test ORDER BY x, y;
|
select distinct (x,y) AS foo, x, y FROM test ORDER BY x, y;
|
||||||
SELECT table_returner(x) FROM test ORDER BY x, y;
|
SELECT table_returner(x) FROM test ORDER BY x, y;
|
||||||
SELECT record_returner(x) FROM test ORDER BY x, y;
|
SELECT record_returner(x) FROM test ORDER BY x, y;
|
||||||
|
-- RECORD[] with varying shape unsupported
|
||||||
|
SELECT ARRAY[(x,(y,x),y),(y,(x,y))] FROM test ORDER BY x, y;
|
||||||
|
SELECT ARRAY[[(x,(y,x))],[((x,x),y)]] FROM test ORDER BY x, y;
|
||||||
|
|
||||||
-- router queries support row types
|
-- router queries support row types
|
||||||
SELECT (x,y) FROM test WHERE x = 1 ORDER BY x, y;
|
SELECT (x,y) FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
SELECT (x,y) AS foo FROM test WHERE x = 1 ORDER BY x, y;
|
SELECT (x,y) AS foo FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
|
SELECT ARRAY[(x,(y,x)),(y,(x,y))] FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
|
SELECT ARRAY[[(x,(y,x))],[(x,(x,y))]] FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
select distinct (x,y) AS foo, x, y FROM test WHERE x = 1 ORDER BY x, y;
|
select distinct (x,y) AS foo, x, y FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
SELECT table_returner(x) FROM test WHERE x = 1 ORDER BY x, y;
|
SELECT table_returner(x) FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
SELECT record_returner(x) FROM test WHERE x = 1 ORDER BY x, y;
|
SELECT record_returner(x) FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
|
-- RECORD[] with varying shape unsupported
|
||||||
|
SELECT ARRAY[(x,(y,x),y),(y,(x,y))] FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
|
SELECT ARRAY[[(x,(y,x))],[((x,x),y)]] FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
|
|
||||||
-- nested row expressions
|
-- nested row expressions
|
||||||
SELECT (x,(x,y)) AS foo FROM test WHERE x = 1 ORDER BY x, y;
|
SELECT (x,(x,y)) AS foo FROM test WHERE x = 1 ORDER BY x, y;
|
||||||
|
|
Loading…
Reference in New Issue