3

I have procedure and it works well.

CREATE OR REPLACE FUNCTION f_dynamic_copy(_tbl     text = 'tmp1')
RETURNS void AS
$func$
DECLARE
   _filename VARCHAR;
BEGIN
  _filename := '/tmp/' || random() || '.csv';
  EXECUTE format($$COPY (select id, 1, 1, 1 from my_first_table) TO %L$$, _filename);
  EXECUTE format($$COPY my_second_table FROM %L$$, _filename);
END
$func$  LANGUAGE plpgsql;

But I want to delete temporary files created in this procedure. How to do it?

1
  • 1
    You can't access the filesystem via neither plpgsql nor SQL for anything other than COPY FROM and COPY TO. You can use a plperlu function, or cron jobs to clean up old files. Commented May 18, 2016 at 6:40

2 Answers 2

3

I found solution for PostgreSQL 9.3+:

-- Delete temporary file
EXECUTE format(
  $$COPY (SELECT 1) TO PROGRAM 'rm %I'$$,
  _filename
);

So, my function is

CREATE OR REPLACE FUNCTION f_dynamic_copy(_tbl     text = 'tmp1')
RETURNS void AS
$func$
DECLARE
   _filename VARCHAR;
BEGIN
  _filename := '/tmp/' || random() || '.csv';
  EXECUTE format($$COPY (select id, 1, 1, 1 from my_first_table) TO %L$$, _filename);
  EXECUTE format($$COPY my_second_table FROM %L$$, _filename);

  -- Delete temporary file
  EXECUTE format(
    $$COPY (SELECT 1) TO PROGRAM 'rm %I'$$,
    _filename
  );

END
$func$  LANGUAGE plpgsql;
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, it is trick, hack. In my case filename has absolutely controlled structure, therefore Im sure this is secure solution. If attacker will override random() or format() function, I may have problem. But such fact - is very bad. And this should not happen.
1

plpgsql does not have a function to delete files. You would need to create the stored function in perl or python to be able to delete the temporary file. But do you really need a temporary file here wouldn't an INSERT SELECT do the job just as well with the need for a stored function?

INSERT INTO my_second_table SELECT id, 1, 1, 1 from my_first_table

3 Comments

Is there are significant difference here in performance? Well if COPY is t he only option, I guess it will have to be plpython or similar
postgresql.org/docs/current/static/populate.html "Note that loading a large number of rows using COPY is almost always faster than using INSERT, even if PREPARE is used and multiple insertions are batched into a single transaction". In my case COPY faster than INSERT in 5 times.
also what if you need to copy data from other DB instance?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.