diff --git a/README.md b/README.md index 80e716ce3..06018a9d6 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ The [Examples](https://github.com/GoogleCloudPlatform/professional-services-data #### Row Validations -(Note: Row hash validation is currently supported for BigQuery, Teradata, Impala/Hive, Oracle, SQL Server, Postgres, and Alloy DB. Struct and array data types are not currently supported. +(Note: Row hash validation is currently supported for BigQuery, Teradata, Impala/Hive, Oracle, SQL Server, Postgres, Db2 and Alloy DB. Struct and array data types are not currently supported. In addition, please note that SHA256 is not a supported function on Teradata systems. If you wish to perform this comparison on Teradata you will need to [deploy a UDF to perform the conversion](https://github.com/akuroda/teradata-udf-sha2/blob/master/src/sha256.c).) diff --git a/data_validation/query_builder/random_row_builder.py b/data_validation/query_builder/random_row_builder.py index 799da726c..869b62d57 100644 --- a/data_validation/query_builder/random_row_builder.py +++ b/data_validation/query_builder/random_row_builder.py @@ -52,6 +52,7 @@ clients.OracleClient: "DBMS_RANDOM.VALUE", PostgreSQLClient: "RANDOM()", clients.MSSQLClient: "NEWID()", + clients.DB2Client: "RAND()", } diff --git a/third_party/ibis/ibis_DB2/alchemy.py b/third_party/ibis/ibis_DB2/alchemy.py index b172f3729..be443967c 100644 --- a/third_party/ibis/ibis_DB2/alchemy.py +++ b/third_party/ibis/ibis_DB2/alchemy.py @@ -29,6 +29,7 @@ dt.BIGINT: sa.BIGINT, } _ibis_type_to_sqla.update(s_al._ibis_type_to_sqla) +_ibis_type_to_sqla[dts.String] = sa.sql.sqltypes.String(length=3000) def _to_sqla_type(itype, type_map=None): diff --git a/third_party/ibis/ibis_DB2/compiler.py b/third_party/ibis/ibis_DB2/compiler.py index 42fa9facc..57ae1c17a 100644 --- a/third_party/ibis/ibis_DB2/compiler.py +++ b/third_party/ibis/ibis_DB2/compiler.py @@ -493,7 +493,8 @@ def _mod(t, expr): def _string_join(t, expr): sep, elements = expr.op().args - return sa.func.concat(*map(t.translate, elements)) + columns = [col.name for col in map(t.translate, elements)] + return sa.sql.literal_column(" || ".join(columns)) def _literal(t, expr): diff --git a/third_party/ibis/ibis_DB2/expr/datatypes.py b/third_party/ibis/ibis_DB2/expr/datatypes.py index 6beae4d31..3915d7544 100644 --- a/third_party/ibis/ibis_DB2/expr/datatypes.py +++ b/third_party/ibis/ibis_DB2/expr/datatypes.py @@ -148,7 +148,7 @@ def name(value): _TYPE_KEYS = tuple(_TYPE_RULES.keys()) -class TypeParser_Oracle(dt.TypeParser): +class TypeParser_DB2(dt.TypeParser): def type(self) -> dt.DataType: if self._accept(Token_DB2.CLOB): return CLOB() diff --git a/third_party/ibis/ibis_addon/operations.py b/third_party/ibis/ibis_addon/operations.py index fa7e47ce2..768673e71 100644 --- a/third_party/ibis/ibis_addon/operations.py +++ b/third_party/ibis/ibis_addon/operations.py @@ -48,6 +48,13 @@ from third_party.ibis.ibis_mssql.compiler import MSSQLExprTranslator from ibis.backends.postgres.compiler import PostgreSQLExprTranslator +# avoid errors if Db2 is not installed and not needed +try: + from third_party.ibis.ibis_DB2.compiler import DB2ExprTranslator +except Exception: + DB2ExprTranslator = None + + # from third_party.ibis.ibis_snowflake.compiler import SnowflakeExprTranslator # from third_party.ibis.ibis_oracle.compiler import OracleExprTranslator <<<<<< DB2 @@ -213,6 +220,13 @@ def sa_format_hashbytes_oracle(translator, expr): hash_func = sa.func.standard_hash(compiled_arg, sa.sql.literal_column("'SHA256'")) return sa.func.lower(hash_func) +def sa_format_hashbytes_db2(translator, expr): + arg, how = expr.op().args + compiled_arg = translator.translate(arg) + hashfunc = sa.func.hash(compiled_arg,sa.sql.literal_column("2")) + hex = sa.func.hex(hashfunc) + return sa.func.lower(hex) + def sa_format_hashbytes_postgres(translator, expr): arg, how = expr.op().args compiled_arg = translator.translate(arg) @@ -292,3 +306,6 @@ def sa_cast_postgres(t, expr): PostgreSQLExprTranslator._registry[RawSQL] = sa_format_raw_sql PostgreSQLExprTranslator._registry[ToChar] = sa_format_to_char PostgreSQLExprTranslator._registry[Cast] = sa_cast_postgres + +if DB2ExprTranslator: #check if Db2 driver is loaded + DB2ExprTranslator._registry[HashBytes] = sa_format_hashbytes_db2