From 32c4ca26c746da7132359b6c158f41dc04ad4f94 Mon Sep 17 00:00:00 2001 From: saschahofmann Date: Sat, 20 Apr 2024 14:25:17 +0200 Subject: [PATCH 01/13] Implement StringToDate operation --- ibis/expr/operations/temporal.py | 9 +++++++++ ibis/expr/types/strings.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/ibis/expr/operations/temporal.py b/ibis/expr/operations/temporal.py index 5eea8d969a76..a500dd017400 100644 --- a/ibis/expr/operations/temporal.py +++ b/ibis/expr/operations/temporal.py @@ -79,6 +79,15 @@ class StringToTimestamp(Value): dtype = dt.Timestamp(timezone="UTC") +@public +class StringToDate(Value): + arg: Value[dt.String] + format_str: Value[dt.String] + + shape = rlz.shape_like("arg") + dtype = dt.date + + @public class ExtractTemporalField(TemporalUnary): dtype = dt.int32 diff --git a/ibis/expr/types/strings.py b/ibis/expr/types/strings.py index c2e8c3dda17f..cdea2db7937d 100644 --- a/ibis/expr/types/strings.py +++ b/ibis/expr/types/strings.py @@ -1302,6 +1302,35 @@ def to_timestamp(self, format_str: str) -> ir.TimestampValue: """ return ops.StringToTimestamp(self, format_str).to_expr() + def to_date(self, format_str: str) -> ir.DateValue: + """Parse a string and return a date. + + Parameters + ---------- + format_str + Format string in `strptime` format + + Returns + ------- + DateValue + Parsed date value + + Examples + -------- + >>> import ibis + >>> ibis.options.interactive = True + >>> t = ibis.memtable({"ts": ["20170206"]}) + >>> t.ts.to_date("%Y%m%d") + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┃ StringToDate(ts, '%Y%m%d') ┃ + ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ + │ date │ + ├─────────────────────────────────┤ + │ 2017-02-06 │ + └─────────────────────────────────┘ + """ + return ops.StringToDate(self, format_str).to_expr() + def protocol(self): """Parse a URL and extract protocol. From 7759fb55c39fad29f164ef741e170916d8d8623b Mon Sep 17 00:00:00 2001 From: saschahofmann Date: Sat, 20 Apr 2024 14:31:19 +0200 Subject: [PATCH 02/13] Add first compilers --- ibis/backends/bigquery/compiler.py | 1 + ibis/backends/sql/compiler.py | 2 + ibis/backends/tests/test_temporal.py | 79 ++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) diff --git a/ibis/backends/bigquery/compiler.py b/ibis/backends/bigquery/compiler.py index ae17d4ee2c03..4e078e257ff1 100644 --- a/ibis/backends/bigquery/compiler.py +++ b/ibis/backends/bigquery/compiler.py @@ -122,6 +122,7 @@ class BigQueryCompiler(SQLGlotCompiler): ops.Modulus: "mod", ops.RegexReplace: "regexp_replace", ops.RegexSearch: "regexp_contains", + ops.StringToDate: "parse_date", ops.Time: "time", ops.TimeFromHMS: "time", ops.TimestampFromYMDHMS: "datetime", diff --git a/ibis/backends/sql/compiler.py b/ibis/backends/sql/compiler.py index 71d57b7481aa..612ddb760efe 100644 --- a/ibis/backends/sql/compiler.py +++ b/ibis/backends/sql/compiler.py @@ -801,6 +801,8 @@ def visit_IntervalFromInteger(self, op, *, arg, unit): ) ### String Instruments + def visit_StringToDate(self, op, *, arg, format_str): + return self.f.to_timestamp(arg, format_str).date() def visit_Strip(self, op, *, arg): return self.f.trim(arg, string.whitespace) diff --git a/ibis/backends/tests/test_temporal.py b/ibis/backends/tests/test_temporal.py index 0c8238218f1b..a4051679546d 100644 --- a/ibis/backends/tests/test_temporal.py +++ b/ibis/backends/tests/test_temporal.py @@ -1441,6 +1441,85 @@ def test_string_to_timestamp(alltypes, fmt): assert val.strftime("%m/%d/%y") == result["date_string_col"][i] + +@pytest.mark.parametrize( + "fmt", + [ + # "11/01/10" - "month/day/year" + param( + "%m/%d/%y", + id="mysql_format", + marks=[ + pytest.mark.never( + ["snowflake"], + reason=( + "(snowflake.connector.errors.ProgrammingError) 100096 (22007): " + "Can't parse '11/01/10' as timestamp with format '%m/%d/%y'" + ), + raises=SnowflakeProgrammingError, + ), + pytest.mark.never( + ["flink"], + raises=ValueError, + reason="Datetime formatting style is not supported.", + ), + ], + ), + param( + "MM/dd/yy", + id="pyspark_format", + marks=[ + pytest.mark.never( + ["bigquery"], + reason="400 Mismatch between format character 'M' and string character '0'", + raises=GoogleBadRequest, + ), + pytest.mark.never( + ["mysql"], + reason="NaTType does not support strftime", + raises=ValueError, + ), + pytest.mark.never( + ["trino"], + reason="datetime formatting style not supported", + raises=TrinoUserError, + ), + pytest.mark.never( + ["polars"], + reason="datetime formatting style not supported", + raises=PolarsComputeError, + ), + pytest.mark.never( + ["duckdb"], + reason="datetime formatting style not supported", + raises=DuckDBInvalidInputException, + ), + ], + ), + ], +) +@pytest.mark.notimpl( + [ + "dask", + "pandas", + "clickhouse", + "sqlite", + "datafusion", + "mssql", + "druid", + ], + raises=com.OperationNotDefinedError, +) +@pytest.mark.notimpl(["exasol"], raises=com.OperationNotDefinedError) +def test_string_to_date(alltypes, fmt): + table=alltypes + result = table.mutate(date=table.date_string_col.to_date(fmt)).execute() + + # TEST: do we get the same date out, that we put in? + # format string assumes that we are using pandas' strftime + for i, val in enumerate(result["date"]): + assert val.strftime("%m/%d/%y") == result["date_string_col"][i] + @pytest.mark.parametrize( ("date", "expected_index", "expected_day"), [ From 6556c05ba40f21e1b426bc458b4953ac754b2f77 Mon Sep 17 00:00:00 2001 From: saschahofmann Date: Sat, 20 Apr 2024 19:34:45 +0200 Subject: [PATCH 03/13] Implement fallback correctly on sql/compiler.py --- ibis/backends/sql/compiler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ibis/backends/sql/compiler.py b/ibis/backends/sql/compiler.py index 612ddb760efe..d57132074a44 100644 --- a/ibis/backends/sql/compiler.py +++ b/ibis/backends/sql/compiler.py @@ -802,7 +802,7 @@ def visit_IntervalFromInteger(self, op, *, arg, unit): ### String Instruments def visit_StringToDate(self, op, *, arg, format_str): - return self.f.to_timestamp(arg, format_str).date() + return self.f.date(self.f.str_to_time(arg, format_str)) def visit_Strip(self, op, *, arg): return self.f.trim(arg, string.whitespace) From 220ce40c7999e6d28720681875b62aecd906a49d Mon Sep 17 00:00:00 2001 From: saschahofmann Date: Sat, 20 Apr 2024 19:55:57 +0200 Subject: [PATCH 04/13] Implement for backends that support native function --- ibis/backends/clickhouse/compiler.py | 1 + ibis/backends/mysql/compiler.py | 1 + ibis/backends/oracle/compiler.py | 1 + ibis/backends/postgres/compiler.py | 1 + ibis/backends/snowflake/compiler.py | 1 + 5 files changed, 5 insertions(+) diff --git a/ibis/backends/clickhouse/compiler.py b/ibis/backends/clickhouse/compiler.py index ef3f03abb538..759f40c9d85c 100644 --- a/ibis/backends/clickhouse/compiler.py +++ b/ibis/backends/clickhouse/compiler.py @@ -105,6 +105,7 @@ class ClickHouseCompiler(SQLGlotCompiler): ops.Strftime: "formatDateTime", ops.StringLength: "length", ops.StringReplace: "replaceAll", + ops.StringToDate: 'toDate', ops.Strip: "trimBoth", ops.TimestampNow: "now", ops.TypeOf: "toTypeName", diff --git a/ibis/backends/mysql/compiler.py b/ibis/backends/mysql/compiler.py index 624c37cb2049..443e7f863c95 100644 --- a/ibis/backends/mysql/compiler.py +++ b/ibis/backends/mysql/compiler.py @@ -109,6 +109,7 @@ def POS_INF(self): ops.ExtractDayOfYear: "dayofyear", ops.Strftime: "date_format", ops.StringToTimestamp: "str_to_date", + ops.StringToDate: "str_to_date", ops.Log2: "log2", } diff --git a/ibis/backends/oracle/compiler.py b/ibis/backends/oracle/compiler.py index 9fd0a76890a7..33028cbc65a2 100644 --- a/ibis/backends/oracle/compiler.py +++ b/ibis/backends/oracle/compiler.py @@ -94,6 +94,7 @@ class OracleCompiler(SQLGlotCompiler): ops.LPad: "lpad", ops.RPad: "rpad", ops.StringAscii: "ascii", + ops.StringToDate: "to_date", ops.Strip: "trim", ops.Hash: "ora_hash", } diff --git a/ibis/backends/postgres/compiler.py b/ibis/backends/postgres/compiler.py index f825f005db32..f62c781aca81 100644 --- a/ibis/backends/postgres/compiler.py +++ b/ibis/backends/postgres/compiler.py @@ -101,6 +101,7 @@ class PostgresCompiler(SQLGlotCompiler): ops.MapKeys: "akeys", ops.MapValues: "avals", ops.RegexSearch: "regexp_like", + ops.StringToDate: "to_date", ops.TimeFromHMS: "make_time", } diff --git a/ibis/backends/snowflake/compiler.py b/ibis/backends/snowflake/compiler.py index 75bfd7ce6674..c0915d0598cc 100644 --- a/ibis/backends/snowflake/compiler.py +++ b/ibis/backends/snowflake/compiler.py @@ -78,6 +78,7 @@ class SnowflakeCompiler(SQLGlotCompiler): ops.Hash: "hash", ops.Median: "median", ops.Mode: "mode", + ops.StringToDate: "to_date", ops.StringToTimestamp: "to_timestamp_tz", ops.TimeFromHMS: "time_from_parts", ops.TimestampFromYMDHMS: "timestamp_from_parts", From b477d06f3095c650651e96e2849c026e3114819a Mon Sep 17 00:00:00 2001 From: saschahofmann Date: Sat, 20 Apr 2024 20:01:41 +0200 Subject: [PATCH 05/13] Fix formatting test --- ibis/backends/tests/test_temporal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ibis/backends/tests/test_temporal.py b/ibis/backends/tests/test_temporal.py index a4051679546d..cce4fd912d9e 100644 --- a/ibis/backends/tests/test_temporal.py +++ b/ibis/backends/tests/test_temporal.py @@ -1441,7 +1441,6 @@ def test_string_to_timestamp(alltypes, fmt): assert val.strftime("%m/%d/%y") == result["date_string_col"][i] - @pytest.mark.parametrize( "fmt", [ @@ -1512,7 +1511,7 @@ def test_string_to_timestamp(alltypes, fmt): ) @pytest.mark.notimpl(["exasol"], raises=com.OperationNotDefinedError) def test_string_to_date(alltypes, fmt): - table=alltypes + table = alltypes result = table.mutate(date=table.date_string_col.to_date(fmt)).execute() # TEST: do we get the same date out, that we put in? @@ -1520,6 +1519,7 @@ def test_string_to_date(alltypes, fmt): for i, val in enumerate(result["date"]): assert val.strftime("%m/%d/%y") == result["date_string_col"][i] + @pytest.mark.parametrize( ("date", "expected_index", "expected_day"), [ From 26c88acde3022cf0fd72271c3af9f339d201786f Mon Sep 17 00:00:00 2001 From: saschahofmann Date: Sat, 20 Apr 2024 20:13:36 +0200 Subject: [PATCH 06/13] Ruff formatting --- ibis/backends/clickhouse/compiler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ibis/backends/clickhouse/compiler.py b/ibis/backends/clickhouse/compiler.py index 759f40c9d85c..259aa52f5822 100644 --- a/ibis/backends/clickhouse/compiler.py +++ b/ibis/backends/clickhouse/compiler.py @@ -105,7 +105,7 @@ class ClickHouseCompiler(SQLGlotCompiler): ops.Strftime: "formatDateTime", ops.StringLength: "length", ops.StringReplace: "replaceAll", - ops.StringToDate: 'toDate', + ops.StringToDate: "toDate", ops.Strip: "trimBoth", ops.TimestampNow: "now", ops.TypeOf: "toTypeName", From 4574de456572227eb0560632d756af5c724fafb9 Mon Sep 17 00:00:00 2001 From: saschahofmann Date: Sun, 21 Apr 2024 18:24:57 +0200 Subject: [PATCH 07/13] Add to unsupported operations to several backends --- ibis/backends/clickhouse/compiler.py | 2 +- ibis/backends/datafusion/compiler.py | 1 + ibis/backends/druid/compiler.py | 1 + ibis/backends/exasol/compiler.py | 1 + ibis/backends/mssql/compiler.py | 1 + ibis/backends/postgres/compiler.py | 1 - ibis/backends/sqlite/compiler.py | 1 + 7 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ibis/backends/clickhouse/compiler.py b/ibis/backends/clickhouse/compiler.py index 259aa52f5822..0c1537297996 100644 --- a/ibis/backends/clickhouse/compiler.py +++ b/ibis/backends/clickhouse/compiler.py @@ -37,6 +37,7 @@ class ClickHouseCompiler(SQLGlotCompiler): ops.Time, ops.TimeDelta, ops.StringToTimestamp, + ops.StringToDate ops.Levenshtein, ) ) @@ -105,7 +106,6 @@ class ClickHouseCompiler(SQLGlotCompiler): ops.Strftime: "formatDateTime", ops.StringLength: "length", ops.StringReplace: "replaceAll", - ops.StringToDate: "toDate", ops.Strip: "trimBoth", ops.TimestampNow: "now", ops.TypeOf: "toTypeName", diff --git a/ibis/backends/datafusion/compiler.py b/ibis/backends/datafusion/compiler.py index 35ce655f30b7..74a9adbc4f99 100644 --- a/ibis/backends/datafusion/compiler.py +++ b/ibis/backends/datafusion/compiler.py @@ -59,6 +59,7 @@ class DataFusionCompiler(SQLGlotCompiler): ops.TimestampNow, ops.TypeOf, ops.Unnest, + ops.StringToDate, ops.StringToTimestamp, ) ) diff --git a/ibis/backends/druid/compiler.py b/ibis/backends/druid/compiler.py index ce4b3db9a26f..59e0d9e0c5dc 100644 --- a/ibis/backends/druid/compiler.py +++ b/ibis/backends/druid/compiler.py @@ -67,6 +67,7 @@ class DruidCompiler(SQLGlotCompiler): ops.Strftime, ops.StringAscii, ops.StringSplit, + ops.StringToDate, ops.StringToTimestamp, ops.TimeDelta, ops.TimestampBucket, diff --git a/ibis/backends/exasol/compiler.py b/ibis/backends/exasol/compiler.py index 1fff079b564e..488c93400baa 100644 --- a/ibis/backends/exasol/compiler.py +++ b/ibis/backends/exasol/compiler.py @@ -78,6 +78,7 @@ class ExasolCompiler(SQLGlotCompiler): ops.Strftime, ops.StringJoin, ops.StringSplit, + ops.StringToDate, ops.StringToTimestamp, ops.TimeDelta, ops.TimestampAdd, diff --git a/ibis/backends/mssql/compiler.py b/ibis/backends/mssql/compiler.py index af7f7fbe6b32..957e12646dc4 100644 --- a/ibis/backends/mssql/compiler.py +++ b/ibis/backends/mssql/compiler.py @@ -113,6 +113,7 @@ class MSSQLCompiler(SQLGlotCompiler): ops.RPad, ops.StartsWith, ops.StringSplit, + ops.StringToDate, ops.StringToTimestamp, ops.StructColumn, ops.TimestampAdd, diff --git a/ibis/backends/postgres/compiler.py b/ibis/backends/postgres/compiler.py index f62c781aca81..f825f005db32 100644 --- a/ibis/backends/postgres/compiler.py +++ b/ibis/backends/postgres/compiler.py @@ -101,7 +101,6 @@ class PostgresCompiler(SQLGlotCompiler): ops.MapKeys: "akeys", ops.MapValues: "avals", ops.RegexSearch: "regexp_like", - ops.StringToDate: "to_date", ops.TimeFromHMS: "make_time", } diff --git a/ibis/backends/sqlite/compiler.py b/ibis/backends/sqlite/compiler.py index d680b38c66a2..077510239cc6 100644 --- a/ibis/backends/sqlite/compiler.py +++ b/ibis/backends/sqlite/compiler.py @@ -66,6 +66,7 @@ class SQLiteCompiler(SQLGlotCompiler): ops.TimestampAdd, ops.TimestampSub, ops.TimestampDiff, + ops.StringToDate, ops.StringToTimestamp, ops.TimeDelta, ops.DateDelta, From d7c88f791414604c0770280505dd2dc10472c00f Mon Sep 17 00:00:00 2001 From: saschahofmann Date: Sun, 21 Apr 2024 18:34:28 +0200 Subject: [PATCH 08/13] Fix type in clickhouse, implement in polars, and use fallback for oracle --- ibis/backends/clickhouse/compiler.py | 2 +- ibis/backends/oracle/compiler.py | 1 - ibis/backends/polars/compiler.py | 7 +++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ibis/backends/clickhouse/compiler.py b/ibis/backends/clickhouse/compiler.py index 0c1537297996..f9b7ba2a8ff0 100644 --- a/ibis/backends/clickhouse/compiler.py +++ b/ibis/backends/clickhouse/compiler.py @@ -37,7 +37,7 @@ class ClickHouseCompiler(SQLGlotCompiler): ops.Time, ops.TimeDelta, ops.StringToTimestamp, - ops.StringToDate + ops.StringToDate, ops.Levenshtein, ) ) diff --git a/ibis/backends/oracle/compiler.py b/ibis/backends/oracle/compiler.py index 33028cbc65a2..9fd0a76890a7 100644 --- a/ibis/backends/oracle/compiler.py +++ b/ibis/backends/oracle/compiler.py @@ -94,7 +94,6 @@ class OracleCompiler(SQLGlotCompiler): ops.LPad: "lpad", ops.RPad: "rpad", ops.StringAscii: "ascii", - ops.StringToDate: "to_date", ops.Strip: "trim", ops.Hash: "ora_hash", } diff --git a/ibis/backends/polars/compiler.py b/ibis/backends/polars/compiler.py index efd27ed1f634..543ff807e017 100644 --- a/ibis/backends/polars/compiler.py +++ b/ibis/backends/polars/compiler.py @@ -935,6 +935,13 @@ def interval_from_integer(op, **kw): arg = translate(op.arg, **kw) return _make_duration(arg, dt.Interval(unit=op.unit)) +@translate.register(ops.StringToDate) +def string_to_date(op, **kw): + arg = translate(op.arg, **kw) + return arg.str.strptime( + dtype=pl.Date, + format=_literal_value(op.format_str), + ) @translate.register(ops.StringToTimestamp) def string_to_timestamp(op, **kw): From 4492cd8adb1e752f4800cf25414ab9b97371b8f3 Mon Sep 17 00:00:00 2001 From: saschahofmann Date: Sun, 21 Apr 2024 18:39:47 +0200 Subject: [PATCH 09/13] Fix linting --- ibis/backends/polars/compiler.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ibis/backends/polars/compiler.py b/ibis/backends/polars/compiler.py index 543ff807e017..c28e224c19c2 100644 --- a/ibis/backends/polars/compiler.py +++ b/ibis/backends/polars/compiler.py @@ -935,6 +935,7 @@ def interval_from_integer(op, **kw): arg = translate(op.arg, **kw) return _make_duration(arg, dt.Interval(unit=op.unit)) + @translate.register(ops.StringToDate) def string_to_date(op, **kw): arg = translate(op.arg, **kw) @@ -943,6 +944,7 @@ def string_to_date(op, **kw): format=_literal_value(op.format_str), ) + @translate.register(ops.StringToTimestamp) def string_to_timestamp(op, **kw): arg = translate(op.arg, **kw) From cf3dc279b88c375e434cef5517c91660f64b9e6d Mon Sep 17 00:00:00 2001 From: saschahofmann Date: Mon, 22 Apr 2024 22:44:21 +0200 Subject: [PATCH 10/13] Use SQLGlot str_to_date --- ibis/backends/bigquery/compiler.py | 1 - ibis/backends/mysql/compiler.py | 1 - ibis/backends/snowflake/compiler.py | 1 - ibis/backends/sql/compiler.py | 4 +--- 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/ibis/backends/bigquery/compiler.py b/ibis/backends/bigquery/compiler.py index 4e078e257ff1..ae17d4ee2c03 100644 --- a/ibis/backends/bigquery/compiler.py +++ b/ibis/backends/bigquery/compiler.py @@ -122,7 +122,6 @@ class BigQueryCompiler(SQLGlotCompiler): ops.Modulus: "mod", ops.RegexReplace: "regexp_replace", ops.RegexSearch: "regexp_contains", - ops.StringToDate: "parse_date", ops.Time: "time", ops.TimeFromHMS: "time", ops.TimestampFromYMDHMS: "datetime", diff --git a/ibis/backends/mysql/compiler.py b/ibis/backends/mysql/compiler.py index 443e7f863c95..624c37cb2049 100644 --- a/ibis/backends/mysql/compiler.py +++ b/ibis/backends/mysql/compiler.py @@ -109,7 +109,6 @@ def POS_INF(self): ops.ExtractDayOfYear: "dayofyear", ops.Strftime: "date_format", ops.StringToTimestamp: "str_to_date", - ops.StringToDate: "str_to_date", ops.Log2: "log2", } diff --git a/ibis/backends/snowflake/compiler.py b/ibis/backends/snowflake/compiler.py index c0915d0598cc..75bfd7ce6674 100644 --- a/ibis/backends/snowflake/compiler.py +++ b/ibis/backends/snowflake/compiler.py @@ -78,7 +78,6 @@ class SnowflakeCompiler(SQLGlotCompiler): ops.Hash: "hash", ops.Median: "median", ops.Mode: "mode", - ops.StringToDate: "to_date", ops.StringToTimestamp: "to_timestamp_tz", ops.TimeFromHMS: "time_from_parts", ops.TimestampFromYMDHMS: "timestamp_from_parts", diff --git a/ibis/backends/sql/compiler.py b/ibis/backends/sql/compiler.py index d57132074a44..89bc0db53f5e 100644 --- a/ibis/backends/sql/compiler.py +++ b/ibis/backends/sql/compiler.py @@ -277,6 +277,7 @@ class SQLGlotCompiler(abc.ABC): ops.StringLength: "length", ops.StringReplace: "replace", ops.StringSplit: "split", + ops.StringToDate: "str_to_date", ops.StringToTimestamp: "str_to_time", ops.Tan: "tan", ops.Translate: "translate", @@ -801,9 +802,6 @@ def visit_IntervalFromInteger(self, op, *, arg, unit): ) ### String Instruments - def visit_StringToDate(self, op, *, arg, format_str): - return self.f.date(self.f.str_to_time(arg, format_str)) - def visit_Strip(self, op, *, arg): return self.f.trim(arg, string.whitespace) From 6fcb0fabee0e666c7a804f8c18227cac8e4ead96 Mon Sep 17 00:00:00 2001 From: saschahofmann Date: Mon, 22 Apr 2024 23:12:28 +0200 Subject: [PATCH 11/13] Add to_date to flink compiler --- ibis/backends/flink/compiler.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ibis/backends/flink/compiler.py b/ibis/backends/flink/compiler.py index 2ba669c761f4..541d21f96a28 100644 --- a/ibis/backends/flink/compiler.py +++ b/ibis/backends/flink/compiler.py @@ -82,6 +82,7 @@ class FlinkCompiler(SQLGlotCompiler): ops.RegexSearch: "regexp", ops.StrRight: "right", ops.StringLength: "char_length", + ops.StringToDate: "to_date", ops.StringToTimestamp: "to_timestamp", ops.Strip: "trim", ops.TypeOf: "typeof", From 2b94772544a50e61f166738d15838118343290d9 Mon Sep 17 00:00:00 2001 From: saschahofmann Date: Mon, 22 Apr 2024 23:34:54 +0200 Subject: [PATCH 12/13] Update ibis/expr/types/strings.py Co-authored-by: Gil Forsyth --- ibis/expr/types/strings.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ibis/expr/types/strings.py b/ibis/expr/types/strings.py index cdea2db7937d..410f3f74b851 100644 --- a/ibis/expr/types/strings.py +++ b/ibis/expr/types/strings.py @@ -1321,13 +1321,13 @@ def to_date(self, format_str: str) -> ir.DateValue: >>> ibis.options.interactive = True >>> t = ibis.memtable({"ts": ["20170206"]}) >>> t.ts.to_date("%Y%m%d") - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - ┃ StringToDate(ts, '%Y%m%d') ┃ - ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ - │ date │ - ├─────────────────────────────────┤ - │ 2017-02-06 │ - └─────────────────────────────────┘ + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┃ StringToDate(ts, '%Y%m%d') ┃ + ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ + │ date │ + ├────────────────────────────┤ + │ 2017-02-06 │ + └────────────────────────────┘ """ return ops.StringToDate(self, format_str).to_expr() From 046889982a4a99f28c060fcb1e557b6a7652f384 Mon Sep 17 00:00:00 2001 From: saschahofmann Date: Wed, 24 Apr 2024 00:25:05 +0200 Subject: [PATCH 13/13] Add to_date to snowflake --- ibis/backends/snowflake/compiler.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ibis/backends/snowflake/compiler.py b/ibis/backends/snowflake/compiler.py index 75bfd7ce6674..c0915d0598cc 100644 --- a/ibis/backends/snowflake/compiler.py +++ b/ibis/backends/snowflake/compiler.py @@ -78,6 +78,7 @@ class SnowflakeCompiler(SQLGlotCompiler): ops.Hash: "hash", ops.Median: "median", ops.Mode: "mode", + ops.StringToDate: "to_date", ops.StringToTimestamp: "to_timestamp_tz", ops.TimeFromHMS: "time_from_parts", ops.TimestampFromYMDHMS: "timestamp_from_parts",