diff --git a/changelogs/fragments/1-clickhouse_client.yml b/changelogs/fragments/1-clickhouse_client.yml index e5ea06b..8b6ef88 100644 --- a/changelogs/fragments/1-clickhouse_client.yml +++ b/changelogs/fragments/1-clickhouse_client.yml @@ -1,2 +1,2 @@ bugfixes: -- clickhouse_client - Add support for returning values of types ``UUID``, ``timedelta``, and ``decimal``. +- clickhouse_client - Add support for returned values of types ``UUID`` and ``decimal``. diff --git a/changelogs/fragments/2-clickhouse_client.yml b/changelogs/fragments/2-clickhouse_client.yml new file mode 100644 index 0000000..ab64f79 --- /dev/null +++ b/changelogs/fragments/2-clickhouse_client.yml @@ -0,0 +1,2 @@ +bugfixes: +- clickhouse_client - Add support for returned values of types ``IPv4Address`` and ``IPv6Address``. diff --git a/plugins/modules/clickhouse_client.py b/plugins/modules/clickhouse_client.py index 3101cfb..efdad9a 100644 --- a/plugins/modules/clickhouse_client.py +++ b/plugins/modules/clickhouse_client.py @@ -115,6 +115,14 @@ type: dict ''' from decimal import Decimal + +HAS_IPADDRESS = False +try: + from ipaddress import IPv4Address, IPv6Address + HAS_IPADDRESS = True +except ImportError: + pass + from uuid import UUID from ansible.module_utils.basic import AnsibleModule @@ -156,10 +164,16 @@ def vals_to_supported(result): if is_uuid(val): # As tuple does not support change, # we need some conversion here - result[idx_row] = replace_val_in_tuple(row, idx_val, str(val)) + row = replace_val_in_tuple(row, idx_val, str(val)) + result[idx_row] = row elif isinstance(val, Decimal): - result[idx_row] = replace_val_in_tuple(row, idx_val, float(val)) + row = replace_val_in_tuple(row, idx_val, float(val)) + result[idx_row] = row + + elif isinstance(val, IPv4Address) or isinstance(val, IPv6Address): + row = replace_val_in_tuple(row, idx_val, str(val)) + result[idx_row] = row return result @@ -255,6 +269,13 @@ def main(): # Will fail if no driver informing the user check_clickhouse_driver(module) + # There's no ipaddress package in Python 2 + if not HAS_IPADDRESS: + msg = ("If you use Python 2 on your target host, " + "make sure you have the py2-ipaddress Python package installed there to avoid " + "crashes while querying tables containing columns of IPv4|6Address types.") + module.warn(msg) + # Connect to DB client = connect_to_db_via_client(module, main_conn_kwargs, client_kwargs) diff --git a/tests/integration/targets/clickhouse_client/tasks/initial.yml b/tests/integration/targets/clickhouse_client/tasks/initial.yml index cd4d7ff..0861f52 100644 --- a/tests/integration/targets/clickhouse_client/tasks/initial.yml +++ b/tests/integration/targets/clickhouse_client/tasks/initial.yml @@ -92,7 +92,7 @@ community.clickhouse.clickhouse_client: execute: "INSERT INTO decimal_datetime VALUES ('4.01', '2019-01-01 00:00:00')" -- name: Insert Decimal and DateTime +- name: Select Decimal and DateTime register: result community.clickhouse.clickhouse_client: execute: "SELECT * FROM decimal_datetime" @@ -101,3 +101,41 @@ ansible.builtin.assert: that: - result.result == [[4.01, '2019-01-01T00:00:00']] + + +- name: Create table with Map column + community.clickhouse.clickhouse_client: + execute: CREATE TABLE map (x Map(String, UInt64)) ENGINE = Memory + +- name: Insert Map + community.clickhouse.clickhouse_client: + execute: "INSERT INTO map VALUES ({'a': 1, 'b': 2})" + +- name: Select Map + register: result + community.clickhouse.clickhouse_client: + execute: "SELECT * FROM map" + +- name: Check the ret vals + ansible.builtin.assert: + that: + - result.result[0][0]['a'] == 1 + + +- name: Create table with IPv4 and IPv6 columns + community.clickhouse.clickhouse_client: + execute: CREATE TABLE ip (v4 IPv4, v6 IPv6) ENGINE = Memory + +- name: Insert IPv4 and IPv6 + community.clickhouse.clickhouse_client: + execute: "INSERT INTO ip VALUES ('192.168.0.1', '001:44c8:129:2632:33:0:252:2')" + +- name: Select IPv4 and IPv6 + register: result + community.clickhouse.clickhouse_client: + execute: "SELECT * FROM ip" + +- name: Check the ret vals + ansible.builtin.assert: + that: + - result.result == [["192.168.0.1", "1:44c8:129:2632:33:0:252:2"]]