Skip to content

Commit 0a876c7

Browse files
authored
Merge pull request #157 from techouse/fix/datetime-defaults
🦺 enhance the translation of SQLite timestamp expressions that use `current_timestamp` within date/time functions
2 parents c69c712 + e703708 commit 0a876c7

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

src/sqlite3_to_mysql/transporter.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ class SQLite3toMySQL(SQLite3toMySQLAttributes):
8282
r"^(datetime|date|time)\s*\(\s*'now'(?:\s*,\s*'(localtime|utc)')?\s*\)$",
8383
re.IGNORECASE,
8484
)
85+
SQLITE_CURRENT_TS_FUNC: t.Pattern[str] = re.compile(
86+
r"^(datetime|date|time)\s*\(\s*current_timestamp(?:\s*,\s*'(localtime|utc)')?\s*\)$",
87+
re.IGNORECASE,
88+
)
8589
STRFTIME_NOW: t.Pattern[str] = re.compile(
8690
r"^strftime\s*\(\s*'([^']+)'\s*,\s*'now'(?:\s*,\s*'(localtime|utc)')?\s*\)$",
8791
re.IGNORECASE,
@@ -577,6 +581,10 @@ def _translate_default_for_mysql(self, column_type: str, default: str) -> str:
577581

578582
s: str = self._strip_wrapping_parentheses(raw)
579583
u: str = s.upper()
584+
sqlite_current_ts_match: t.Optional[re.Match[str]] = self.SQLITE_CURRENT_TS_FUNC.match(s)
585+
sqlite_current_ts_func: t.Optional[str] = (
586+
sqlite_current_ts_match.group(1).lower() if sqlite_current_ts_match else None
587+
)
580588

581589
# NULL passthrough
582590
if u == "NULL":
@@ -590,6 +598,7 @@ def _translate_default_for_mysql(self, column_type: str, default: str) -> str:
590598
if base.startswith("TIMESTAMP") and (
591599
self.CURRENT_TS.match(s)
592600
or (self.SQLITE_NOW_FUNC.match(s) and s.lower().startswith("datetime"))
601+
or sqlite_current_ts_func == "datetime"
593602
or self.STRFTIME_NOW.match(s)
594603
):
595604
len_match: t.Optional[re.Match[str]] = self.COLUMN_LENGTH_PATTERN.search(column_type)
@@ -609,6 +618,7 @@ def _translate_default_for_mysql(self, column_type: str, default: str) -> str:
609618
if base.startswith("DATETIME") and (
610619
self.CURRENT_TS.match(s)
611620
or (self.SQLITE_NOW_FUNC.match(s) and s.lower().startswith("datetime"))
621+
or sqlite_current_ts_func == "datetime"
612622
or self.STRFTIME_NOW.match(s)
613623
):
614624
if not self._allow_current_ts_dt:
@@ -633,6 +643,7 @@ def _translate_default_for_mysql(self, column_type: str, default: str) -> str:
633643
self.CURRENT_DATE.match(s)
634644
or self.CURRENT_TS.match(s) # map CURRENT_TIMESTAMP → CURRENT_DATE for DATE
635645
or (self.SQLITE_NOW_FUNC.match(s) and s.lower().startswith("date"))
646+
or sqlite_current_ts_func == "date"
636647
or self.STRFTIME_NOW.match(s)
637648
)
638649
and self._allow_expr_defaults
@@ -647,6 +658,7 @@ def _translate_default_for_mysql(self, column_type: str, default: str) -> str:
647658
self.CURRENT_TIME.match(s)
648659
or self.CURRENT_TS.match(s) # map CURRENT_TIMESTAMP → CURRENT_TIME for TIME
649660
or (self.SQLITE_NOW_FUNC.match(s) and s.lower().startswith("time"))
661+
or sqlite_current_ts_func == "time"
650662
or self.STRFTIME_NOW.match(s)
651663
)
652664
and self._allow_expr_defaults

tests/unit/sqlite3_to_mysql_test.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2014,6 +2014,19 @@ def _mk(*, expr: bool, ts_dt: bool, fsp: bool) -> SQLite3toMySQL:
20142014
("TIMESTAMP(3)", "CURRENT_TIMESTAMP", {"expr": False, "ts_dt": True, "fsp": True}, "CURRENT_TIMESTAMP(3)"),
20152015
# SQLite-style now -> map to CURRENT_TIMESTAMP (with FSP when allowed)
20162016
("DATETIME(2)", "datetime('now')", {"expr": False, "ts_dt": True, "fsp": True}, "CURRENT_TIMESTAMP(2)"),
2017+
# datetime(current_timestamp, ...) should also map to CURRENT/UTC TIMESTAMP
2018+
(
2019+
"DATETIME",
2020+
"datetime(current_timestamp, 'localtime')",
2021+
{"expr": False, "ts_dt": True, "fsp": False},
2022+
"CURRENT_TIMESTAMP",
2023+
),
2024+
(
2025+
"DATETIME(3)",
2026+
"datetime(current_timestamp, 'utc')",
2027+
{"expr": False, "ts_dt": True, "fsp": True},
2028+
"UTC_TIMESTAMP(3)",
2029+
),
20172030
# --- DATE mapping (from 'now' forms or CURRENT_TIMESTAMP) ---
20182031
# Only map when expression defaults are allowed
20192032
("DATE", "datetime('now')", {"expr": True, "ts_dt": False, "fsp": False}, "CURRENT_DATE"),

0 commit comments

Comments
 (0)