mirror of https://github.com/citusdata/citus.git
Don't copyObject into the wrong memory context
utilityStmt sometimes (such as when it's inside of a plpgsql function) comes from a cached plan, which is kept in a child of the CacheMemoryContext. When we naively call copyObject we're copying it into a statement-local context, which corrupts the cached plan when it's thrown away.pull/2104/head
parent
663c9b2a39
commit
f8fb7a27fb
|
@ -62,6 +62,7 @@
|
|||
#include "foreign/foreign.h"
|
||||
#include "lib/stringinfo.h"
|
||||
#include "nodes/bitmapset.h"
|
||||
#include "nodes/memnodes.h"
|
||||
#include "nodes/nodes.h"
|
||||
#include "nodes/params.h"
|
||||
#include "nodes/parsenodes.h"
|
||||
|
@ -311,12 +312,17 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
|||
|
||||
if (IsA(parsetree, CopyStmt))
|
||||
{
|
||||
/* copy parse tree since we might scribble on it to fix the schema name */
|
||||
parsetree = copyObject(parsetree);
|
||||
MemoryContext planContext = GetMemoryChunkContext(parsetree);
|
||||
MemoryContext previousContext;
|
||||
|
||||
parsetree = copyObject(parsetree);
|
||||
parsetree = ProcessCopyStmt((CopyStmt *) parsetree, completionTag,
|
||||
&commandMustRunAsOwner);
|
||||
|
||||
previousContext = MemoryContextSwitchTo(planContext);
|
||||
parsetree = copyObject(parsetree);
|
||||
MemoryContextSwitchTo(previousContext);
|
||||
|
||||
if (parsetree == NULL)
|
||||
{
|
||||
return;
|
||||
|
|
|
@ -1233,9 +1233,31 @@ SELECT copy_in_plpgsql();
|
|||
|
||||
(1 row)
|
||||
|
||||
-- test prepared COPY on a non-distributed table
|
||||
CREATE TABLE local_ddl (x int);
|
||||
CREATE OR REPLACE FUNCTION local_copy_in_plpgsql()
|
||||
RETURNS VOID AS
|
||||
$BODY$
|
||||
BEGIN
|
||||
COPY local_ddl (x) FROM PROGRAM 'echo 1' WITH CSV;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
SELECT local_copy_in_plpgsql();
|
||||
local_copy_in_plpgsql
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT local_copy_in_plpgsql();
|
||||
local_copy_in_plpgsql
|
||||
-----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
DROP FUNCTION ddl_in_plpgsql();
|
||||
DROP FUNCTION copy_in_plpgsql();
|
||||
DROP TABLE prepare_ddl;
|
||||
DROP TABLE local_ddl;
|
||||
-- clean-up functions
|
||||
DROP FUNCTION plpgsql_test_1();
|
||||
DROP FUNCTION plpgsql_test_2();
|
||||
|
|
|
@ -563,9 +563,24 @@ $BODY$ LANGUAGE plpgsql;
|
|||
SELECT copy_in_plpgsql();
|
||||
SELECT copy_in_plpgsql();
|
||||
|
||||
-- test prepared COPY on a non-distributed table
|
||||
CREATE TABLE local_ddl (x int);
|
||||
|
||||
CREATE OR REPLACE FUNCTION local_copy_in_plpgsql()
|
||||
RETURNS VOID AS
|
||||
$BODY$
|
||||
BEGIN
|
||||
COPY local_ddl (x) FROM PROGRAM 'echo 1' WITH CSV;
|
||||
END;
|
||||
$BODY$ LANGUAGE plpgsql;
|
||||
|
||||
SELECT local_copy_in_plpgsql();
|
||||
SELECT local_copy_in_plpgsql();
|
||||
|
||||
DROP FUNCTION ddl_in_plpgsql();
|
||||
DROP FUNCTION copy_in_plpgsql();
|
||||
DROP TABLE prepare_ddl;
|
||||
DROP TABLE local_ddl;
|
||||
|
||||
-- clean-up functions
|
||||
DROP FUNCTION plpgsql_test_1();
|
||||
|
|
Loading…
Reference in New Issue