dbt/adapters/maxcompute/column.py (84 lines of code) (raw):
from dataclasses import dataclass
from typing import TypeVar, Any
from dbt.adapters.base.column import Column
from odps.models.table import TableSchema
from odps.types import Decimal, Varchar
Self = TypeVar("Self", bound="MaxComputeColumn")
@dataclass
class MaxComputeColumn(Column):
table_column: TableSchema.TableColumn = None
comment: str = ""
TYPE_LABELS = {
"TEXT": "STRING",
"INTEGER": "INT",
"BOOL": "BOOLEAN",
"NUMERIC": "DECIMAL",
"REAL": "FLOAT",
}
@property
def quoted(self):
return "`{}`".format(self.column)
def literal(self, value):
return "cast({} as {})".format(value, self.data_type)
@classmethod
def numeric_type(cls, dtype: str, precision: Any, scale: Any) -> str:
return "DECIMAL({}, {})".format(precision, scale)
def is_string(self) -> bool:
lower = self.dtype.lower()
if lower.startswith("char") or lower.startswith("varchar"):
return True
return lower in [
"string",
"text",
"character varying",
"character",
"char",
"varchar",
]
def is_integer(self) -> bool:
return self.dtype.lower() in [
# real types
"tinyint",
"smallint",
"integer",
"bigint",
"smallserial",
"serial",
"bigserial",
# aliases
"int",
"int2",
"int4",
"int8",
"serial2",
"serial4",
"serial8",
]
def is_numeric(self) -> bool:
lower = self.dtype.lower()
if lower.startswith("decimal") or lower.startswith("numeric"):
return True
return lower in ["numeric", "decimal"]
def string_type(cls, size: int = 0) -> str:
return "string"
def can_expand_to(self: Self, other_column: Self) -> bool:
"""returns True if both columns are strings"""
return self.is_string() and other_column.is_string()
def __repr__(self) -> str:
return "<MaxComputeColumn {} ({})>".format(self.name, self.dtype)
@classmethod
def from_odps_column(cls, column: TableSchema.TableColumn):
char_size = None
numeric_precision = None
numeric_scale = None
if isinstance(column.type, Decimal):
numeric_precision = column.type.precision
numeric_scale = column.type.scale
elif isinstance(column.type, Varchar):
char_size = column.type.size_limit
return cls(
column=column.name,
dtype=column.type.name.lower(),
char_size=char_size,
numeric_precision=numeric_precision,
numeric_scale=numeric_scale,
table_column=column,
comment=column.comment,
)