From 649ab86dfd31e07ba3302fce1832e4e8dbcb8101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20Fi=C5=82onowicz?= Date: Tue, 31 Oct 2023 19:05:25 +0100 Subject: [PATCH] feat(oracle): change parsing of Oracle NUMBER data type --- ibis/backends/oracle/__init__.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/ibis/backends/oracle/__init__.py b/ibis/backends/oracle/__init__.py index 60a48d735430..2db020fc59e2 100644 --- a/ibis/backends/oracle/__init__.py +++ b/ibis/backends/oracle/__init__.py @@ -255,11 +255,26 @@ def _metadata(self, query: str) -> Iterable[tuple[str, dt.DataType]]: con.execute(drop_view) for name, type_string, precision, scale, nullable in results: - if precision is not None and scale is not None and precision != 0: + # NUMBER(null, null) --> FLOAT + # (null, null) --> from_string() + if type_string == "NUMBER" and precision is None and scale is None: + typ = dt.Float64(nullable=nullable) + + # (null, 0) --> INT + # (null, 3), (null, 6), (null, 9) --> from_string() - TIMESTAMP(3)/(6)/(9) + elif precision is None and (scale is not None and scale == 0): + typ = dt.Int64(nullable=nullable) + + # NUMBER(*, 0) --> INT + # (*, 0) --> from_string() - INTERVAL DAY(3) TO SECOND(0) + elif type_string == "NUMBER" and precision is not None and (scale is not None and scale == 0): + typ = dt.Int64(nullable=nullable) + + # NUMBER(*, > 0) --> DECIMAL + # (*, > 0) --> from_string() - INTERVAL DAY(3) TO SECOND(2) + elif type_string == "NUMBER" and precision is not None and (scale is not None and scale > 0): typ = dt.Decimal(precision=precision, scale=scale, nullable=nullable) - elif precision == 0: - # TODO: how to disambiguate between int and float here without inspecting the value? - typ = dt.float + else: typ = OracleType.from_string(type_string, nullable=nullable) yield name, typ