diff --git a/changelogs/fragments/66157-postgresql-create-unique-indexes.yml b/changelogs/fragments/66157-postgresql-create-unique-indexes.yml new file mode 100644 index 00000000000..399dce156f4 --- /dev/null +++ b/changelogs/fragments/66157-postgresql-create-unique-indexes.yml @@ -0,0 +1,2 @@ +minor_changes: + - database - add support to unique indexes in postgresql_idx diff --git a/lib/ansible/modules/database/postgresql/postgresql_idx.py b/lib/ansible/modules/database/postgresql/postgresql_idx.py index e51d6389afe..a87375afa2f 100644 --- a/lib/ansible/modules/database/postgresql/postgresql_idx.py +++ b/lib/ansible/modules/database/postgresql/postgresql_idx.py @@ -94,6 +94,13 @@ options: - Mutually exclusive with I(cascade=yes). type: bool default: yes + unique: + description: + - Enable unique index. + - Only btree currently supports unique indexes. + type: bool + default: no + version_added: '2.10' tablespace: description: - Set a tablespace for the index. @@ -205,6 +212,15 @@ EXAMPLES = r''' db: mydb idxname: test_idx state: stat + +- name: Create unique btree index if not exists test_unique_idx on column name of table products + postgresql_idx: + db: acme + table: products + columns: name + name: test_unique_idx + unique: yes + concurrent: no ''' RETURN = r''' @@ -376,7 +392,7 @@ class Index(object): self.exists = False return False - def create(self, tblname, idxtype, columns, cond, tblspace, storage_params, concurrent=True): + def create(self, tblname, idxtype, columns, cond, tblspace, storage_params, concurrent=True, unique=False): """Create PostgreSQL index. Return True if success, otherwise, return False. @@ -397,7 +413,12 @@ class Index(object): if idxtype is None: idxtype = "BTREE" - query = 'CREATE INDEX' + query = 'CREATE' + + if unique: + query += ' UNIQUE' + + query += ' INDEX' if concurrent: query += ' CONCURRENTLY' @@ -476,6 +497,7 @@ def main(): db=dict(type='str', aliases=['login_db']), state=dict(type='str', default='present', choices=['absent', 'present', 'stat']), concurrent=dict(type='bool', default=True), + unique=dict(type='bool', default=False), table=dict(type='str'), idxtype=dict(type='str', aliases=['type']), columns=dict(type='list', aliases=['column']), @@ -494,6 +516,7 @@ def main(): idxname = module.params["idxname"] state = module.params["state"] concurrent = module.params["concurrent"] + unique = module.params["unique"] table = module.params["table"] idxtype = module.params["idxtype"] columns = module.params["columns"] @@ -504,7 +527,10 @@ def main(): schema = module.params["schema"] if concurrent and cascade: - module.fail_json(msg="Cuncurrent mode and cascade parameters are mutually exclusive") + module.fail_json(msg="Concurrent mode and cascade parameters are mutually exclusive") + + if unique and (idxtype and idxtype != 'btree'): + module.fail_json(msg="Only btree currently supports unique indexes") if state == 'present': if not table: @@ -576,7 +602,7 @@ def main(): if storage_params: storage_params = ','.join(storage_params) - changed = index.create(table, idxtype, columns, cond, tablespace, storage_params, concurrent) + changed = index.create(table, idxtype, columns, cond, tablespace, storage_params, concurrent, unique) if changed: kw = index.get_info() diff --git a/test/integration/targets/postgresql_idx/tasks/postgresql_idx_initial.yml b/test/integration/targets/postgresql_idx/tasks/postgresql_idx_initial.yml index 0f16e201af0..b3cbb9507f4 100644 --- a/test/integration/targets/postgresql_idx/tasks/postgresql_idx_initial.yml +++ b/test/integration/targets/postgresql_idx/tasks/postgresql_idx_initial.yml @@ -253,6 +253,51 @@ - result.schema == 'public' - result.query == 'CREATE INDEX CONCURRENTLY test1_idx ON public.test_table USING BTREE (id) WHERE id > 1 AND id != 10' +- name: postgresql_idx - create unique index + become_user: "{{ pg_user }}" + become: yes + postgresql_idx: + db: postgres + login_user: "{{ pg_user }}" + table: test_table + columns: story + idxname: test_unique0_idx + unique: yes + register: result + ignore_errors: yes + +- assert: + that: + - result is changed + - result.tblname == 'test_table' + - result.name == 'test_unique0_idx' + - result.state == 'present' + - result.valid != '' + - result.tblspace == '' + - result.storage_params == [] + - result.schema == 'public' + - result.query == 'CREATE UNIQUE INDEX CONCURRENTLY test_unique0_idx ON public.test_table USING BTREE (story)' + +- name: postgresql_idx - avoid unique index with type different of btree + become_user: "{{ pg_user }}" + become: yes + postgresql_idx: + db: postgres + login_user: "{{ pg_user }}" + table: test_table + columns: story + idxname: test_unique0_idx + unique: yes + concurrent: no + type: brin + register: result + ignore_errors: yes + +- assert: + that: + - result is not changed + - result.msg == 'Only btree currently supports unique indexes' + # Get idx stat in check mode - name: postgresql_idx - test state stat in check_mode become_user: "{{ pg_user }}"