postgresql_idx: add stat mode support (#64138)

* postgresql_idx: add stat mode support

* postgresql_idx: add stat mode support, add changelog

* postgresql_idx: add stat mode support, fix CI
This commit is contained in:
Andrey Klychkov 2019-11-05 13:26:51 +03:00 committed by John R Barker
parent e7cd5af1a6
commit 04c999f0f8
3 changed files with 99 additions and 8 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- postgresql_idx - add a new option ``stat`` to the ``state`` parameter (https://github.com/ansible/ansible/pull/64138).

View file

@ -49,11 +49,15 @@ options:
state: state:
description: description:
- Index state. - Index state.
- I(state=present) implies the index will be created if it does not exist. - C(present) implies the index will be created if it does not exist.
- I(state=absent) implies the index will be dropped if it exists. - C(absent) implies the index will be dropped if it exists.
- C(stat) returns index statistics information from the ``pg_stat_user_indexes`` standard view.
Supported from Ansible 2.10.
- "When C(stat) following parameters will be ignored:"
- I(schema), I(table), I(columns), I(cond), I(idxtype), I(tablespace), I(concurrent), I(cascade).
type: str type: str
default: present default: present
choices: [ absent, present ] choices: [ absent, present, stat ]
table: table:
description: description:
- Table to create index on it. - Table to create index on it.
@ -195,6 +199,12 @@ EXAMPLES = r'''
columns: id,comment columns: id,comment
idxname: test_idx idxname: test_idx
cond: id > 1 cond: id > 1
- name: Get index statistics of test_idx from mydb
postgresql_idx:
db: mydb
idxname: test_idx
state: stat
''' '''
RETURN = r''' RETURN = r'''
@ -233,6 +243,11 @@ valid:
returned: always returned: always
type: bool type: bool
sample: true sample: true
stat:
description: Index statistics.
returned: if state is stat
type: bool
sample: { 'idx_scan': 19239, 'idx_tup_read': 929329, 'idx_tup_fetch': 4949459 }
''' '''
try: try:
@ -313,6 +328,21 @@ class Index(object):
self.__exists_in_db() self.__exists_in_db()
return self.info return self.info
def get_stat(self):
"""Get and return index statistics.
Return index statistics dictionary if index exists, otherwise False.
"""
query = ("SELECT * FROM pg_stat_user_indexes "
"WHERE indexrelname = '%s' "
"AND schemaname = '%s'" % (self.name, self.schema))
result = exec_sql(self, query, add_to_executed=False)
if result:
return [dict(row) for row in result]
else:
return False
def __exists_in_db(self): def __exists_in_db(self):
"""Check index existence, collect info, add it to self.info dict. """Check index existence, collect info, add it to self.info dict.
@ -363,7 +393,6 @@ class Index(object):
if self.exists: if self.exists:
return False return False
changed = False
if idxtype is None: if idxtype is None:
idxtype = "BTREE" idxtype = "BTREE"
@ -410,7 +439,6 @@ class Index(object):
default False default False
concurrent (bool) -- build index in concurrent mode, default True concurrent (bool) -- build index in concurrent mode, default True
""" """
changed = False
if not self.exists: if not self.exists:
return False return False
@ -445,7 +473,7 @@ def main():
argument_spec.update( argument_spec.update(
idxname=dict(type='str', required=True, aliases=['name']), idxname=dict(type='str', required=True, aliases=['name']),
db=dict(type='str', aliases=['login_db']), db=dict(type='str', aliases=['login_db']),
state=dict(type='str', default='present', choices=['absent', 'present']), state=dict(type='str', default='present', choices=['absent', 'present', 'stat']),
concurrent=dict(type='bool', default=True), concurrent=dict(type='bool', default=True),
table=dict(type='str'), table=dict(type='str'),
idxtype=dict(type='str', aliases=['type']), idxtype=dict(type='str', aliases=['type']),
@ -506,7 +534,14 @@ def main():
# #
# check_mode start # check_mode start
if module.check_mode: if module.check_mode:
if state == 'present' and index.exists: if state == 'stat':
if index.exists:
kw['stat'] = index.get_stat()
kw['changed'] = False
module.exit_json(**kw)
elif state == 'present' and index.exists:
kw['changed'] = False kw['changed'] = False
module.exit_json(**kw) module.exit_json(**kw)
@ -524,7 +559,14 @@ def main():
# check_mode end # check_mode end
# #
if state == "present": if state == 'stat':
if index.exists:
kw['stat'] = index.get_stat()
kw['changed'] = False
module.exit_json(**kw)
elif state == "present":
if idxtype and idxtype.upper() not in VALID_IDX_TYPES: if idxtype and idxtype.upper() not in VALID_IDX_TYPES:
module.fail_json(msg="Index type '%s' of %s is not in valid types" % (idxtype, idxname)) module.fail_json(msg="Index type '%s' of %s is not in valid types" % (idxtype, idxname))

View file

@ -253,6 +253,53 @@
- result.schema == 'public' - result.schema == 'public'
- result.query == 'CREATE INDEX CONCURRENTLY test1_idx ON public.test_table USING BTREE (id) WHERE id > 1 AND id != 10' - result.query == 'CREATE INDEX CONCURRENTLY test1_idx ON public.test_table USING BTREE (id) WHERE id > 1 AND id != 10'
# Get idx stat in check mode
- name: postgresql_idx - test state stat in check_mode
become_user: "{{ pg_user }}"
become: yes
postgresql_idx:
db: postgres
login_user: "{{ pg_user }}"
idxname: test1_idx
state: stat
check_mode: yes
register: result
- assert:
that:
- result is not changed
- result.tblname == 'test_table'
- result.name == 'test1_idx'
- result.state == 'present'
- result.valid != ''
- result.tblspace == ''
- result.storage_params == []
- result.schema == 'public'
- result.stat != {}
# Get idx stat
- name: postgresql_idx - test state stat
become_user: "{{ pg_user }}"
become: yes
postgresql_idx:
db: postgres
login_user: "{{ pg_user }}"
idxname: test1_idx
state: stat
register: result
- assert:
that:
- result is not changed
- result.tblname == 'test_table'
- result.name == 'test1_idx'
- result.state == 'present'
- result.valid != ''
- result.tblspace == ''
- result.storage_params == []
- result.schema == 'public'
- result.stat != {}
# Drop index from specific schema with cascade in check_mode # Drop index from specific schema with cascade in check_mode
- name: postgresql_idx - drop index from specific schema cascade in check_mode - name: postgresql_idx - drop index from specific schema cascade in check_mode
become_user: "{{ pg_user }}" become_user: "{{ pg_user }}"