From 13b4eb9ccef99779f76eca846cd0b493f61f4c59 Mon Sep 17 00:00:00 2001
From: Gerhard Schlager <mail@gerhard-schlager.at>
Date: Tue, 31 Mar 2020 15:07:52 +0200
Subject: [PATCH] FIX: Restore failed if schema contained objects not owned by
 the current DB user

---
 lib/backup_restore.rb          | 10 ++++++----
 lib/backup_restore/backuper.rb |  1 +
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/lib/backup_restore.rb b/lib/backup_restore.rb
index 4775fdd612b..4d75734c27d 100644
--- a/lib/backup_restore.rb
+++ b/lib/backup_restore.rb
@@ -83,12 +83,14 @@ module BackupRestore
   end
 
   def self.move_tables_between_schemas(source, destination)
+    owner = database_configuration.username
+
     ActiveRecord::Base.transaction do
-      DB.exec(move_tables_between_schemas_sql(source, destination))
+      DB.exec(move_tables_between_schemas_sql(source, destination, owner))
     end
   end
 
-  def self.move_tables_between_schemas_sql(source, destination)
+  def self.move_tables_between_schemas_sql(source, destination, owner)
     <<~SQL
       DO $$DECLARE row record;
       BEGIN
@@ -97,13 +99,13 @@ module BackupRestore
         -- otherwise extensions (like hstore & pg_trgm) won't work anymore...
         CREATE SCHEMA IF NOT EXISTS #{destination};
         -- move all <source> tables to <destination> schema
-        FOR row IN SELECT tablename FROM pg_tables WHERE schemaname = '#{source}'
+        FOR row IN SELECT tablename FROM pg_tables WHERE schemaname = '#{source}'  AND tableowner = '#{owner}'
         LOOP
           EXECUTE 'DROP TABLE IF EXISTS #{destination}.' || quote_ident(row.tablename) || ' CASCADE;';
           EXECUTE 'ALTER TABLE #{source}.' || quote_ident(row.tablename) || ' SET SCHEMA #{destination};';
         END LOOP;
         -- move all <source> views to <destination> schema
-        FOR row IN SELECT viewname FROM pg_views WHERE schemaname = '#{source}'
+        FOR row IN SELECT viewname FROM pg_views WHERE schemaname = '#{source}' AND viewowner = '#{owner}'
         LOOP
           EXECUTE 'DROP VIEW IF EXISTS #{destination}.' || quote_ident(row.viewname) || ' CASCADE;';
           EXECUTE 'ALTER VIEW #{source}.' || quote_ident(row.viewname) || ' SET SCHEMA #{destination};';
diff --git a/lib/backup_restore/backuper.rb b/lib/backup_restore/backuper.rb
index ae7cee86969..dd4f81c72ed 100644
--- a/lib/backup_restore/backuper.rb
+++ b/lib/backup_restore/backuper.rb
@@ -194,6 +194,7 @@ module BackupRestore
       [ password_argument,            # pass the password to pg_dump (if any)
         "pg_dump",                    # the pg_dump command
         "--schema=public",            # only public schema
+        "-T public.pg_*",             # exclude tables and views whose name starts with "pg_"
         "--file='#{@dump_filename}'", # output to the dump.sql file
         "--no-owner",                 # do not output commands to set ownership of objects
         "--no-privileges",            # prevent dumping of access privileges