In my python program, I need to write a function which takes hive data type as input and return whether or not the data type is valid or not.
Primitive data types supported in hive are as follows :
supported_data_types: Set = {'void', 'boolean', 'tinyint', 'smallint', 'int', 'bigint', 'float', 'double',
'decimal', 'string', 'varchar', 'timestamp', 'date', 'binary'}
Complex data types supported by hive are :
arrays: array<data_type>
maps: map<primitive_type, data_type>
structs: struct<col_name : data_type [comment col_comment], ...>
union: union<data_type, data_type, ...>
In my python program, I have one variable which stores primitive or complex hive data type. I need to write a function which can return True if the data type of the variable is valid, otherwise I have to return false.
Primitive data types are easy to validate, I just need to write :
def validate_datatype(_type: str):
_type = _type.strip()
if _type in HIVE_SUPPORTED_DATA_TYPES:
return True
I also managed to validate array and map data types, to any level of nesting. I observe the fact that for array, any valid type has syntax : array<data_type>. So, if I have a type array<data_type>, I recursively validate data_type. In case of map, its key is always primitive datatype, so, it is also possible to validate map data type recursively. I used following function to recursively validate data types.
def validate_datatype(_type: str) -> bool:
_type = _type.strip()
if _type in HIVE_SUPPORTED_DATA_TYPES:
return True
# Array type has syntax : array<data_type>, where data_type is any valid data_type
if _type.startswith('array<'):
assert _type.endswith(">"), "could not find matching '>' for data type 'array<' "
return validate_datatype(_type[6:-1])
# Map type has syntax : map<primitive_type, data_type>, where primitive type can only be one of
# primitive types present in HIVE_SUPPORTED_DATA_TYPES. data_type can be any(primitive or complex)
# valid hive data type
if _type.startswith('map<'):
assert _type.endswith(">"), "could not find matching '>' for data type 'map<' "
primitive_type, data_type = _type[4:-1].split(',', 1)
if primitive_type.strip() in HIVE_SUPPORTED_DATA_TYPES and validate_datatype(data_type):
return True
Such recursive function is not possible (at least in my opinion) to validate struct data type, which has following syntax : struct<col1_name : data_type, col2_name : data_type, ... > (Assume that I don't have to worry about [COMMENT col_comment] part right now. I don't receive any inputs with column comments.)
To validate struct data type, I first need to write some other function to extract columns from the struct data type. Let this abstract function be extract_columns which has following syntax.
@abstractmethod
def extract_columns(dt: str) -> List[Tuple[str, str]]:
pass
I should get following results for following inputs :
dt = "struct<col_1: int, col_2 : struct<nested_col_1 : int, nested_col_2 : str>>"
extract_columns(dt)
>> [('col_1','int'), ('col_2', 'struct<nested_col_1 : int, nested_col_2 : str>')]
If I can manage to write such a function, I can manage to recursively validate the data_types. Since struct can contain many internal struct and other complex data types, I can not use split at : (might also split the nested structs, which I don't want to), or , (might also split at nested map and nested struct types, again, which I don't want to).
So, in my opinion, re might be able to extract such list of columns, but, I'm not able to figure our re for this. Can anyone help me here? Many thanks in advance.