tconbeer / harlequin

The SQL IDE for Your Terminal.
https://harlequin.sh
MIT License
3.3k stars 76 forks source link

Harlequin can crash when loading the datetime `1-1-1` #568

Open tconbeer opened 3 weeks ago

tconbeer commented 3 weeks ago

Describe the bug Data table crashes if timezone conversion pushes timestamps negative.

To Reproduce select '1-1-1T00:00:00Z'::timestamptz (from a US timezone)

Expected behavior Should probably show null or a zero date, etc.

Actual behavior Harlequin crashes with OverflowError: date value out of range

│ ╭─────────────────────────────────── locals ───────────────────────────────────╮                                                                                       │
│ │ self = <textual_fastdatatable.backend.ArrowBackend object at 0x7fa42c340860> │                                                                                       │
│ ╰──────────────────────────────────────────────────────────────────────────────╯                                                                                       │
│                                                                                                                                                                        │
│ /home/tco/.local/pipx/venvs/harlequin/lib/python3.12/site-packages/textual_fastdatatable/backend.py:359 in _measure                                                    │
│                                                                                                                                                                        │
│   356 │   │   │   return max([measure_width(el, self._console) for el in [col_max, col_min]])                                                                          │
│   357 │   │   elif pt.is_temporal(arr.type):                                                                                                                           │
│   358 │   │   │   try:                                                                                                                                                 │
│ ❱ 359 │   │   │   │   value = arr.drop_null()[0].as_py()                                                                                                               │
│   360 │   │   │   except IndexError:                                                                                                                                   │
│   361 │   │   │   │   return 0                                                                                                                                         │
│   362 │   │   │   else:                                                                                                                                                │
│                                                                                                                                                                        │
│ ╭─────────────────────────────────── locals ───────────────────────────────────╮                                                                                       │
│ │  arr = <pyarrow.lib.ChunkedArray object at 0x7fa42c349e90>                   │                                                                                       │
│ │        [                                                                     │                                                                                       │
│ │          [                                                                   │                                                                                       │
│ │        │   0001-01-01 00:00:00.000000Z,                                      │                                                                                       │
│ │        │   0001-01-01 00:00:00.000000Z,                                      │                                                                                       │
│ │        │   0001-01-01 00:00:00.000000Z,                                      │                                                                                       │
│ │        │   0001-01-01 00:00:00.000000Z,                                      │                                                                                       │
│ │        │   0001-01-01 00:00:00.000000Z,                                      │                                                                                       │
│ │        │   ...                                                               │                                                                                       │
│ │        │   0001-01-01 00:00:00.000000Z,                                      │                                                                                       │
│ │        │   0001-01-01 00:00:00.000000Z,                                      │                                                                                       │
│ │        │   0001-01-01 00:00:00.000000Z,                                      │                                                                                       │
│ │        │   0001-01-01 00:00:00.000000Z,                                      │                                                                                       │
│ │        │   0001-01-01 00:00:00.000000Z                                       │                                                                                       │
│ │          ]                                                                   │                                                                                       │
│ │        ]                                                                     │                                                                                       │
│ │ self = <textual_fastdatatable.backend.ArrowBackend object at 0x7fa42c340860> │                                                                                       │
│ ╰──────────────────────────────────────────────────────────────────────────────╯                                                                                       │
│                                                                                                                                                                        │
│ in pyarrow.lib.TimestampScalar.as_py:533                                                                                                                               │
│                                                                                                                                                                        │
│ in pyarrow.lib._datetime_from_int:452                                                                                                                                  │
│                                                                                                                                                                        │
│ /home/tco/.local/pipx/venvs/harlequin/lib/python3.12/site-packages/pytz/tzinfo.py:204 in fromutc                                                                       │
│                                                                                                                                                                        │
│   201 │   │   dt = dt.replace(tzinfo=None)                                                                                                                             │
│   202 │   │   idx = max(0, bisect_right(self._utc_transition_times, dt) - 1)                                                                                           │
│   203 │   │   inf = self._transition_info[idx]                                                                                                                         │
│ ❱ 204 │   │   return (dt + inf[0]).replace(tzinfo=self._tzinfos[inf])                                                                                                  │
│   205 │                                                                                                                                                                │
│   206 │   def normalize(self, dt):                                                                                                                                     │
│   207 │   │   '''Correct the timezone information on the given datetime                                                                                                │
│                                                                                                                                                                        │
│ ╭───────────────────────────────────── locals ──────────────────────────────────────╮                                                                                  │
│ │   dt = datetime.datetime(1, 1, 1, 0, 0)                                           │                                                                                  │
│ │  idx = 0                                                                          │                                                                                  │
│ │  inf = (datetime.timedelta(days=-1, seconds=61200), datetime.timedelta(0), 'LMT') │                                                                                  │
│ │ self = <DstTzInfo 'America/Denver' LMT-1 day, 17:00:00 STD>                       │                                                                                  │
│ ╰───────────────────────────────────────────────────────────────────────────────────╯                                                                                  │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
OverflowError: date value out of range

Contributing Are you interested in contributing a fix?

Additional context Please provide as much as you can, but don't waste your time if it's definitely not relevant or you don't know.

What is the output of harlequin --version? 1.21.0

What database adapter are you using with Harlequin? (Default is duckdb) duckdb

What other options are you using when invoking Harlequin? (If you are using a profile, please add relevant items from your profile here). None

Can you tell us more about your system?

How did you install Harlequin?