mirror of https://github.com/citusdata/citus.git
parent
dfe68a28aa
commit
14e9c6f249
|
@ -301,13 +301,20 @@ CitusEndScan(CustomScanState *node)
|
|||
|
||||
|
||||
/*
|
||||
* CitusReScan is just a place holder for rescan callback. Currently, we don't
|
||||
* support rescan given that there is not any way to reach this code path.
|
||||
* CitusReScan is not normally called, except in certain cases of
|
||||
* DECLARE .. CURSOR WITH HOLD ..
|
||||
*/
|
||||
static void
|
||||
CitusReScan(CustomScanState *node)
|
||||
{
|
||||
CitusScanState *scanState = (CitusScanState *) node;
|
||||
EState *executorState = scanState->customScanState.ss.ps.state;
|
||||
ParamListInfo paramListInfo = executorState->es_param_list_info;
|
||||
|
||||
if (paramListInfo != NULL)
|
||||
{
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("rescan is unsupported"),
|
||||
errdetail("We don't expect this code path to be executed.")));
|
||||
errmsg("Cursors for queries on distributed tables with "
|
||||
"parameters are currently unsupported")));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,7 +210,100 @@ SELECT customer_key, c_name, c_address
|
|||
ERROR: relation "customer_few" does not exist
|
||||
LINE 2: FROM customer_few ORDER BY customer_key LIMIT 5;
|
||||
^
|
||||
-- Test DECLARE CURSOR statements
|
||||
-- Test DECLARE CURSOR .. WITH HOLD without parameters that calls ReScan on the top-level CustomScan
|
||||
CREATE TABLE cursor_me (x int, y int);
|
||||
SELECT create_distributed_table('cursor_me', 'x');
|
||||
create_distributed_table
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO cursor_me SELECT s/10, s FROM generate_series(1, 100) s;
|
||||
DECLARE holdCursor CURSOR WITH HOLD FOR
|
||||
SELECT * FROM cursor_me WHERE x = 1 ORDER BY y;
|
||||
FETCH NEXT FROM holdCursor;
|
||||
x | y
|
||||
---+----
|
||||
1 | 10
|
||||
(1 row)
|
||||
|
||||
FETCH FORWARD 3 FROM holdCursor;
|
||||
x | y
|
||||
---+----
|
||||
1 | 11
|
||||
1 | 12
|
||||
1 | 13
|
||||
(3 rows)
|
||||
|
||||
FETCH LAST FROM holdCursor;
|
||||
x | y
|
||||
---+----
|
||||
1 | 19
|
||||
(1 row)
|
||||
|
||||
FETCH BACKWARD 3 FROM holdCursor;
|
||||
x | y
|
||||
---+----
|
||||
1 | 18
|
||||
1 | 17
|
||||
1 | 16
|
||||
(3 rows)
|
||||
|
||||
FETCH FORWARD 3 FROM holdCursor;
|
||||
x | y
|
||||
---+----
|
||||
1 | 17
|
||||
1 | 18
|
||||
1 | 19
|
||||
(3 rows)
|
||||
|
||||
CLOSE holdCursor;
|
||||
-- Test DECLARE CURSOR .. WITH HOLD with parameter
|
||||
CREATE OR REPLACE FUNCTION declares_cursor(p int)
|
||||
RETURNS void AS $$
|
||||
DECLARE c CURSOR WITH HOLD FOR SELECT * FROM cursor_me WHERE x = $1;
|
||||
$$ LANGUAGE SQL;
|
||||
SELECT declares_cursor(5);
|
||||
ERROR: Cursors for queries on distributed tables with parameters are currently unsupported
|
||||
CREATE OR REPLACE FUNCTION cursor_plpgsql(p int)
|
||||
RETURNS SETOF int AS $$
|
||||
DECLARE
|
||||
val int;
|
||||
my_cursor CURSOR (a INTEGER) FOR SELECT y FROM cursor_me WHERE x = $1 ORDER BY y;
|
||||
BEGIN
|
||||
-- Open the cursor
|
||||
OPEN my_cursor(p);
|
||||
|
||||
LOOP
|
||||
FETCH my_cursor INTO val;
|
||||
EXIT WHEN NOT FOUND;
|
||||
|
||||
RETURN NEXT val;
|
||||
END LOOP;
|
||||
|
||||
-- Close the cursor
|
||||
CLOSE my_cursor;
|
||||
END; $$
|
||||
LANGUAGE plpgsql;
|
||||
SELECT cursor_plpgsql(4);
|
||||
cursor_plpgsql
|
||||
----------------
|
||||
40
|
||||
41
|
||||
42
|
||||
43
|
||||
44
|
||||
45
|
||||
46
|
||||
47
|
||||
48
|
||||
49
|
||||
(10 rows)
|
||||
|
||||
DROP FUNCTION declares_cursor(int);
|
||||
DROP FUNCTION cursor_plpgsql(int);
|
||||
DROP TABLE cursor_me;
|
||||
-- Test DECLARE CURSOR statement with SCROLL
|
||||
DECLARE holdCursor SCROLL CURSOR WITH HOLD FOR
|
||||
SELECT l_orderkey, l_linenumber, l_quantity, l_discount
|
||||
FROM lineitem
|
||||
|
|
|
@ -122,8 +122,58 @@ COMMIT;
|
|||
SELECT customer_key, c_name, c_address
|
||||
FROM customer_few ORDER BY customer_key LIMIT 5;
|
||||
|
||||
-- Test DECLARE CURSOR statements
|
||||
-- Test DECLARE CURSOR .. WITH HOLD without parameters that calls ReScan on the top-level CustomScan
|
||||
CREATE TABLE cursor_me (x int, y int);
|
||||
SELECT create_distributed_table('cursor_me', 'x');
|
||||
INSERT INTO cursor_me SELECT s/10, s FROM generate_series(1, 100) s;
|
||||
|
||||
DECLARE holdCursor CURSOR WITH HOLD FOR
|
||||
SELECT * FROM cursor_me WHERE x = 1 ORDER BY y;
|
||||
|
||||
FETCH NEXT FROM holdCursor;
|
||||
FETCH FORWARD 3 FROM holdCursor;
|
||||
FETCH LAST FROM holdCursor;
|
||||
FETCH BACKWARD 3 FROM holdCursor;
|
||||
FETCH FORWARD 3 FROM holdCursor;
|
||||
|
||||
CLOSE holdCursor;
|
||||
|
||||
-- Test DECLARE CURSOR .. WITH HOLD with parameter
|
||||
CREATE OR REPLACE FUNCTION declares_cursor(p int)
|
||||
RETURNS void AS $$
|
||||
DECLARE c CURSOR WITH HOLD FOR SELECT * FROM cursor_me WHERE x = $1;
|
||||
$$ LANGUAGE SQL;
|
||||
|
||||
SELECT declares_cursor(5);
|
||||
|
||||
CREATE OR REPLACE FUNCTION cursor_plpgsql(p int)
|
||||
RETURNS SETOF int AS $$
|
||||
DECLARE
|
||||
val int;
|
||||
my_cursor CURSOR (a INTEGER) FOR SELECT y FROM cursor_me WHERE x = $1 ORDER BY y;
|
||||
BEGIN
|
||||
-- Open the cursor
|
||||
OPEN my_cursor(p);
|
||||
|
||||
LOOP
|
||||
FETCH my_cursor INTO val;
|
||||
EXIT WHEN NOT FOUND;
|
||||
|
||||
RETURN NEXT val;
|
||||
END LOOP;
|
||||
|
||||
-- Close the cursor
|
||||
CLOSE my_cursor;
|
||||
END; $$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
SELECT cursor_plpgsql(4);
|
||||
|
||||
DROP FUNCTION declares_cursor(int);
|
||||
DROP FUNCTION cursor_plpgsql(int);
|
||||
DROP TABLE cursor_me;
|
||||
|
||||
-- Test DECLARE CURSOR statement with SCROLL
|
||||
DECLARE holdCursor SCROLL CURSOR WITH HOLD FOR
|
||||
SELECT l_orderkey, l_linenumber, l_quantity, l_discount
|
||||
FROM lineitem
|
||||
|
|
Loading…
Reference in New Issue