Skip to content

Commit

Permalink
Fix the invalid oidAssignments list for CTAS query with initplan (#12…
Browse files Browse the repository at this point in the history
…472)

If a query is a CTAS with initplan, it may reset 'Oid dispatch context'
when an exception occurs in preprocess_initplans, which will further
cause invlid list reference during the serialization of oidAssignments
when dispatching plan.

In this fix, we copy an extra list for oidAssignments for querys
that contain CTAS and initplan.

Co-authored-by: wuchengwen <wcw190496@alibaba-inc.com>
  • Loading branch information
dreamedcheng and wuchengwen authored Sep 9, 2021
1 parent e2f2312 commit ec02439
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 8 deletions.
21 changes: 19 additions & 2 deletions src/backend/executor/execMain.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
GpExecIdentity exec_identity;
bool shouldDispatch;
bool needDtx;
List *toplevelOidCache = NIL;

/* sanity checks: queryDesc must not be started already */
Assert(queryDesc != NULL);
Expand Down Expand Up @@ -581,11 +582,16 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
*
* For details please see github issue https://github.com/greenplum-db/gpdb/issues/10760
*/
List *toplevelOidCache = NIL;
if (queryDesc->ddesc != NULL)
{
queryDesc->ddesc->sliceTable = estate->es_sliceTable;
toplevelOidCache = GetAssignedOidsForDispatch();
/*
* For CTAS querys that contain initplan, we need to copy a new oid dispatch list,
* since the preprocess_initplan will start a subtransaction, and if it's rollbacked,
* the memory context of 'Oid dispatch context' will be reset, which will cause invalid
* list reference during the serialization of dispatch_oids when dispatching plan.
*/
toplevelOidCache = copyObject(GetAssignedOidsForDispatch());
}

/*
Expand Down Expand Up @@ -641,6 +647,12 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
estate->es_param_exec_vals,
needDtx, true);
}

if (toplevelOidCache != NIL)
{
list_free(toplevelOidCache);
toplevelOidCache = NIL;
}
}

/*
Expand Down Expand Up @@ -701,6 +713,11 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
}
PG_CATCH();
{
if (toplevelOidCache != NIL)
{
list_free(toplevelOidCache);
toplevelOidCache = NIL;
}
mppExecutorCleanup(queryDesc);
PG_RE_THROW();
}
Expand Down
36 changes: 30 additions & 6 deletions src/test/regress/expected/gpctas.out
Original file line number Diff line number Diff line change
Expand Up @@ -146,17 +146,16 @@ ALTER TABLE ctas_src DROP COLUMN col2;
INSERT INTO ctas_src(col1, col3,col4,col5)
SELECT g, 'a',True,g from generate_series(1,5) g;
CREATE TABLE ctas_dst as SELECT col1,col3,col4,col5 FROM ctas_src order by 1;
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'col4' as the Greenplum Database data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry.
-- This will fail to find some of the rows, if they're distributed incorrectly.
SELECT * FROM ctas_src, ctas_dst WHERE ctas_src.col1 = ctas_dst.col1;
col1 | col3 | col4 | col5 | col1 | col3 | col4 | col5
------+------+------+------+------+------+------+------
1 | a | t | 1 | 1 | a | t | 1
5 | a | t | 5 | 5 | a | t | 5
2 | a | t | 2 | 2 | a | t | 2
3 | a | t | 3 | 3 | a | t | 3
4 | a | t | 4 | 4 | a | t | 4
5 | a | t | 5 | 5 | a | t | 5
1 | a | t | 1 | 1 | a | t | 1
(5 rows)

-- Github Issue 9365: https://github.com/greenplum-db/gpdb/issues/9365
Expand Down Expand Up @@ -203,8 +202,7 @@ CREATE TABLE ctas_base(a int, b int);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
CREATE TABLE ctas_aocs WITH (appendonly=true, orientation=column) AS SELECT * FROM ctas_base WITH NO DATA;
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'a' as the Greenplum Database data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry.
SELECT * FROM ctas_aocs;
a | b
---+---
Expand Down Expand Up @@ -303,3 +301,29 @@ from
refresh materialized view sro_mv_issue_11999;
ERROR: division by zero
CONTEXT: SQL function "mv_action_select_issue_11999" statement 1
-- Test CTAS + initplan, and an exception was raised in preprocess_initplans
CREATE OR REPLACE FUNCTION public.exception_func()
RETURNS refcursor
LANGUAGE plpgsql
AS $function$declare cname refcursor = 'result'; begin open cname for select 1; raise sqlstate '02000'; return cname; exception when sqlstate '02000' then return cname; end;$function$;
SELECT exception_func() INTO TEMPORARY test_tmp1;
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named '' as the Greenplum Database data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
SELECT * FROM test_tmp1;
exception_func
----------------
result
(1 row)

CREATE TEMPORARY TABLE test_tmp2 AS SELECT exception_func();
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named '' as the Greenplum Database data distribution key for this table.
HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
SELECT * FROM test_tmp2;
exception_func
----------------
result
(1 row)

DROP FUNCTION public.exception_func();
DROP TABLE test_tmp1;
DROP TABLE test_tmp2;
19 changes: 19 additions & 0 deletions src/test/regress/sql/gpctas.sql
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,22 @@ from

-- then refresh should error out
refresh materialized view sro_mv_issue_11999;


-- Test CTAS + initplan, and an exception was raised in preprocess_initplans
CREATE OR REPLACE FUNCTION public.exception_func()
RETURNS refcursor
LANGUAGE plpgsql
AS $function$declare cname refcursor = 'result'; begin open cname for select 1; raise sqlstate '02000'; return cname; exception when sqlstate '02000' then return cname; end;$function$;

SELECT exception_func() INTO TEMPORARY test_tmp1;

SELECT * FROM test_tmp1;

CREATE TEMPORARY TABLE test_tmp2 AS SELECT exception_func();

SELECT * FROM test_tmp2;

DROP FUNCTION public.exception_func();
DROP TABLE test_tmp1;
DROP TABLE test_tmp2;

0 comments on commit ec02439

Please sign in to comment.