From ea9a0f36f3ca10ad450d37586371648b3ab4c673 Mon Sep 17 00:00:00 2001 From: Andrey Klychkov Date: Wed, 5 Jun 2019 22:06:23 +0300 Subject: [PATCH] postgresql_table: 57352 bugfix, add schema handling (#57391) * 57352 bugfix, add schema handling * 57352 bugfix, added a changelog fragment * 57352 bugfix, added tests for rename * 57352 bugfix, fixed tests * 57352 bugfix, fixed typos, cosmetic changes --- ...ostgresql_table_bugfix_schema_handling.yml | 2 + .../database/postgresql/postgresql_table.py | 25 +++- .../postgresql/tasks/postgresql_table.yml | 125 ++++++++++++++++++ 3 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/57391-postgresql_table_bugfix_schema_handling.yml diff --git a/changelogs/fragments/57391-postgresql_table_bugfix_schema_handling.yml b/changelogs/fragments/57391-postgresql_table_bugfix_schema_handling.yml new file mode 100644 index 00000000000..f135234f7c5 --- /dev/null +++ b/changelogs/fragments/57391-postgresql_table_bugfix_schema_handling.yml @@ -0,0 +1,2 @@ +bugfixes: +- postgresql_table - fix schema handling (https://github.com/ansible/ansible/pull/57391) diff --git a/lib/ansible/modules/database/postgresql/postgresql_table.py b/lib/ansible/modules/database/postgresql/postgresql_table.py index 101ecb679a7..797c18f5a93 100644 --- a/lib/ansible/modules/database/postgresql/postgresql_table.py +++ b/lib/ansible/modules/database/postgresql/postgresql_table.py @@ -151,9 +151,9 @@ EXAMPLES = r''' - fillfactor=10 - autovacuum_analyze_threshold=1 -- name: Create an unlogged table +- name: Create an unlogged table in schema acme postgresql_table: - name: useless_data + name: acme.useless_data columns: waste_id int unlogged: true @@ -162,6 +162,11 @@ EXAMPLES = r''' table: foo rename: bar +- name: Rename table foo from schema acme to bar + postgresql_table: + name: acme.foo + rename: bar + - name: Set owner to someuser postgresql_table: name: foo @@ -178,9 +183,9 @@ EXAMPLES = r''' name: foo truncate: yes -- name: Drop table foo +- name: Drop table foo from schema acme postgresql_table: - name: foo + name: acme.foo state: absent - name: Drop table bar cascade @@ -260,12 +265,19 @@ class Table(object): def __exists_in_db(self): """Check table exists and refresh info""" + if "." in self.name: + schema = self.name.split('.')[-2] + tblname = self.name.split('.')[-1] + else: + schema = 'public' + tblname = self.name + query = ("SELECT t.tableowner, t.tablespace, c.reloptions " "FROM pg_tables AS t " "INNER JOIN pg_class AS c ON c.relname = t.tablename " "INNER JOIN pg_namespace AS n ON c.relnamespace = n.oid " "WHERE t.tablename = '%s' " - "AND n.nspname = 'public'" % self.name) + "AND n.nspname = '%s'" % (tblname, schema)) res = self.__exec_sql(query) if res: self.exists = True @@ -417,6 +429,9 @@ class Table(object): return self.__exec_sql(query, ddl=True) def drop(self, cascade=False): + if not self.exists: + return False + query = "DROP TABLE %s" % pg_quote_identifier(self.name, 'table') if cascade: query += " CASCADE" diff --git a/test/integration/targets/postgresql/tasks/postgresql_table.yml b/test/integration/targets/postgresql/tasks/postgresql_table.yml index 5291b081558..6a0bab20b3a 100644 --- a/test/integration/targets/postgresql/tasks/postgresql_table.yml +++ b/test/integration/targets/postgresql/tasks/postgresql_table.yml @@ -12,6 +12,14 @@ login_user: "{{ pg_user }}" name: alice +- name: postgresql_table - create test schema + become_user: "{{ pg_user }}" + become: yes + postgresql_schema: + database: postgres + login_user: "{{ pg_user }}" + name: acme + # # Check table creation # @@ -727,3 +735,120 @@ that: - result.rowcount == 0 when: postgres_version_resp.stdout is version('9.1', '>=') + +# +# Create, drop, and rename table in a specific schema: +# +- name: postgresql_table - create table in a specific schema + postgresql_table: + db: postgres + login_user: "{{ pg_user }}" + name: acme.test_schema_table + register: result + +- assert: + that: + - result.changed == true + - result.queries == ['CREATE TABLE "acme"."test_schema_table" ()'] + +- name: postgresql_table - check that table exists after the previous step + become_user: "{{ pg_user }}" + become: yes + postgresql_query: + db: postgres + login_user: "{{ pg_user }}" + query: "SELECT 1 FROM pg_stat_all_tables WHERE relname = 'test_schema_table' and schemaname = 'acme'" + ignore_errors: yes + register: result + +- assert: + that: + - result.rowcount == 1 + +- name: postgresql_table - try to create a table with the same name and schema again + postgresql_table: + db: postgres + login_user: "{{ pg_user }}" + name: acme.test_schema_table + register: result + +- assert: + that: + - result.changed == false + +- name: postgresql_table - create a table in the default schema for the next test + postgresql_table: + db: postgres + login_user: "{{ pg_user }}" + name: test_schema_table + register: result + +- assert: + that: + - result.changed == true + +- name: postgresql_table - drop the table from schema acme + postgresql_table: + db: postgres + login_user: "{{ pg_user }}" + name: postgres.acme.test_schema_table + state: absent + register: result + +- assert: + that: + - result.changed == true + - result.queries == ['DROP TABLE "postgres"."acme"."test_schema_table"'] + +- name: postgresql_table - check that the table doesn't exist after the previous step + become_user: "{{ pg_user }}" + become: yes + postgresql_query: + db: postgres + login_user: "{{ pg_user }}" + query: "SELECT 1 FROM pg_stat_all_tables WHERE relname = 'test_schema_table' and schemaname = 'acme'" + ignore_errors: yes + register: result + +- assert: + that: + - result.rowcount == 0 + +- name: postgresql_table - try to drop the table from schema acme again + postgresql_table: + db: postgres + login_user: "{{ pg_user }}" + name: acme.test_schema_table + state: absent + register: result + +- assert: + that: + - result.changed == false + +- name: postgresql_table - check that the table with the same name in schema public exists + become_user: "{{ pg_user }}" + become: yes + postgresql_query: + db: postgres + login_user: "{{ pg_user }}" + query: "SELECT 1 FROM pg_stat_all_tables WHERE relname = 'test_schema_table' and schemaname = 'public'" + ignore_errors: yes + register: result + +- assert: + that: + - result.rowcount == 1 + +- name: postgresql_table - rename the table that contents a schema name + postgresql_table: + db: postgres + login_user: "{{ pg_user }}" + name: public.test_schema_table + rename: new_test_schema_table + register: result + +- assert: + that: + - result.changed == true + - result.queries == ['ALTER TABLE "public"."test_schema_table" RENAME TO "new_test_schema_table"']