From 1d6b7e852571d0fa9dabe68e2d4ca8eea90dad2e Mon Sep 17 00:00:00 2001 From: Mayur Singal <39544459+ulixius9@users.noreply.github.com> Date: Fri, 17 Jun 2022 17:42:54 +0530 Subject: [PATCH] Fix #3289: Added precision details of column (#5437) * Fix #3289: Added precision details of column * Resolved review comments --- .../source/database/sql_column_handler.py | 20 +++++++++++++++- .../src/metadata/utils/column_type_parser.py | 24 ++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/ingestion/src/metadata/ingestion/source/database/sql_column_handler.py b/ingestion/src/metadata/ingestion/source/database/sql_column_handler.py index a8467df3154..83c58d40aa2 100644 --- a/ingestion/src/metadata/ingestion/source/database/sql_column_handler.py +++ b/ingestion/src/metadata/ingestion/source/database/sql_column_handler.py @@ -42,7 +42,14 @@ class SqlColumnHandlerMixin: col_type: str, col_data_length: str, arr_data_type: str, + precision: Optional[Tuple[str, str]], ) -> str: + if precision: + return ( + data_type_display + if data_type_display + else f"{col_type}({precision[0]},{precision[1]})" + ) dataTypeDisplay = ( f"{data_type_display}" if data_type_display @@ -162,6 +169,9 @@ class SqlColumnHandlerMixin: ) ] col_data_length = self._check_col_length(col_type, column["type"]) + precision = ColumnTypeParser.check_col_precision( + col_type, column["type"] + ) if col_type == "NULL" or col_type is None: col_type = DataType.VARCHAR.name data_type_display = col_type.lower() @@ -171,7 +181,11 @@ class SqlColumnHandlerMixin: ) ) dataTypeDisplay = self._get_display_datatype( - data_type_display, col_type, col_data_length, arr_data_type + data_type_display, + col_type, + col_data_length, + arr_data_type, + precision, ) col_data_length = 1 if col_data_length is None else col_data_length om_column = Column( @@ -184,6 +198,10 @@ class SqlColumnHandlerMixin: children=children, arrayDataType=arr_data_type, ) + if precision: + om_column.precision = precision[0] + om_column.scale = precision[1] + else: col_obj = self._process_complex_col_type( column=column, parsed_string=parsed_string diff --git a/ingestion/src/metadata/utils/column_type_parser.py b/ingestion/src/metadata/utils/column_type_parser.py index 08d17375962..50e1f2ed5c0 100644 --- a/ingestion/src/metadata/utils/column_type_parser.py +++ b/ingestion/src/metadata/utils/column_type_parser.py @@ -1,5 +1,5 @@ import re -from typing import Any, Dict, List, Type, Union +from typing import Any, Dict, List, Optional, Tuple, Type, Union from sqlalchemy.sql import sqltypes as types from sqlalchemy.types import TypeEngine @@ -18,6 +18,15 @@ def create_sqlalchemy_type(name: str): return sqlalchemy_type +NUMERIC_TYPES_SUPPORTING_PRECISION = { + "DOUBLE", + "NUMBER", + "NUMERIC", + "FLOAT", + "DECIMAL", +} + + class ColumnTypeParser: _BRACKETS = {"(": ")", "[": "]", "{": "}", "<": ">"} @@ -323,6 +332,19 @@ class ColumnTypeParser: parts.append(buf) return parts + @staticmethod + def check_col_precision( + datatype: str, col_raw_type: object + ) -> Optional[Tuple[str, str]]: + """ + Method retuerns the precision details of column if available + """ + if datatype and datatype.upper() in NUMERIC_TYPES_SUPPORTING_PRECISION: + args = re.search(r"\((.*)\)", str(col_raw_type)) + if args and args.group(1): + args = tuple(re.split(r"\s*,\s*", args.group(1))) + return args + @staticmethod def is_primitive_om_type(raw_type: str) -> bool: return not ColumnTypeParser._COMPLEX_TYPE.match(raw_type)