Skip to content

add time extract - #26257

Open
daviszhen wants to merge 40 commits into
matrixorigin:mainfrom
daviszhen:0727-add-time-extract
Open

add time extract#26257
daviszhen wants to merge 40 commits into
matrixorigin:mainfrom
daviszhen:0727-add-time-extract

Conversation

@daviszhen

Copy link
Copy Markdown
Contributor

What type of PR is this?

  • API-change
  • BUG
  • Improvement
  • Documentation
  • Feature
  • Test and CI
  • Code Refactoring

Which issue(s) this PR fixes:

issue #24504

What this PR does / why we need it:

此分支为 HOUR()、MINUTE()、SECOND() 增加 VARCHAR/CHAR/TEXT 字符串参数支持:

  • 同时支持 TIME、DATETIME 和 DATE 字符串。
  • DATETIME 优先按日历时间提取,避免跨天时间被错误计算为超过 24 小时。
  • TIME 支持 272:59:59 等扩展小时值。
  • 非法、空字符串及 SQL NULL 返回 NULL。
  • 补充函数分派、NULL/select-list、边界场景 UT 和对应 BVT。
  • 更新三个 BVT 结果文件,确认问题场景分别返回 12/30/45,DATE 返回 0。

pkg/sql/plan/function 全包测试通过,未发现阻塞问题。

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@daviszhen

Copy link
Copy Markdown
Contributor Author

Reviewed updated exact head bf9ee8d0756020ad50c92f437dbf7eb349da7257. The two previous blockers (year-zero leap day and plain alphanumeric compact-DATETIME suffixes) are fixed, but two reachable MySQL 8.4 compatibility gaps remain.

  1. P1 — Compact DATETIME fractional prefixes are rejected too strictly. mysqlCompactDatetimeSuffixForExtract requires a dot followed only by digits. MySQL 8.4.10 still extracts 15/30/45 from 20241220153045.123abc and 20241220153045. (and likewise the 12-digit form), because it consumes the valid compact-DATETIME/fractional prefix. This head returns NULL for all three. Keep rejecting the previously reported plain ...45abc form, but accept the fractional-prefix forms according to the oracle and add UT/BVT cases.
  2. P1 — Valid partial TIME coercions are lost. MySQL 8.4.10 returns HOUR/MINUTE/SECOND 0/0/12 for 12: and 0/34/0 for :34; this head returns NULL because mysqlClockFieldsForExtract requires both sides of the first colon. The same prefix-consumption mismatch rejects 12:34:56- and 12:34:56.., while MySQL returns 12/34/56. Please make the TIME-prefix scanner stop at the end of the valid coercible prefix rather than letting allowed punctuation poison the whole parse, and cover the exact boundary matrix.

Validation: official MySQL 8.4.10 container used as an independent oracle. A direct probe of the current parser reproduced every mismatch. The newly added focused unit tests pass with the deterministic CGo wrapper; CI is green and the head is mergeable.

  • compact DATETIME 支持小数前缀:接受 20241220153045.123abc、20241220153045. 及 12 位形式;仍拒绝无小数点的 ...45abc。
  • TIME 前缀解析支持 12:、:34、12:34:56-、12:34:56..,保留已解析的时分秒。
  • 修复紧凑 TIME 加尾随冒号:123:、1234:、12345:、123456: 按 MySQL 的 SS/MMSS/HHMMSS 规则解析。
  • 补充 HOUR、MINUTE、SECOND 的 UT 与 BVT 覆盖,并保持原有非法 compact DATETIME 后缀返回 NULL 的反向验证。

@XuPeng-SH XuPeng-SH left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep-reviewed updated exact head 9382044e1cdb43cae9472448463aee3c0f20b25d, including the author reply and the regressions added for the previous review. Those specific cases are fixed, but the replacement TIME-prefix state machine still has reachable MySQL 8.4 compatibility gaps.

P1 — Partial TIME prefix parsing still drops or rejects valid coercible fields

The parser returns immediately after a leading-colon minute and requires digits after a second colon, while also explicitly rejects a third colon and lets punctuation before the fractional dot poison compact fallback. Against MySQL 8.4.10:

  • :34:56 must yield 0/34/56; this head yields 0/34/0.
  • 12:34: must yield 12/34/0; this head returns NULL.
  • 12::56 must yield 0/0/12; this head returns NULL.
  • 12:34:56: must yield 12/34/56; this head returns NULL.
  • 12-.abc must yield 0/0/12; this head returns NULL.

These are the same public VARCHAR/CHAR/TEXT overloads and are reachable from ordinary SQL. Please model MySQL prefix consumption as one consistent scanner instead of special-casing only the previously reported examples, and add the exact boundary matrix above to UT/BVT.

Validation: official MySQL 8.4.10 container under default SQL mode; a direct probe test against this exact head reproduced all five mismatches. The PR's focused string-extract tests pass with the deterministic CGo wrapper, so existing green tests do not cover this remaining state space.

Comment thread pkg/sql/plan/function/func_unary.go Outdated
@daviszhen

Copy link
Copy Markdown
Contributor Author

Deep-reviewed updated exact head 9382044e1cdb43cae9472448463aee3c0f20b25d, including the author reply and the regressions added for the previous review. Those specific cases are fixed, but the replacement TIME-prefix state machine still has reachable MySQL 8.4 compatibility gaps.

P1 — Partial TIME prefix parsing still drops or rejects valid coercible fields

The parser returns immediately after a leading-colon minute and requires digits after a second colon, while also explicitly rejects a third colon and lets punctuation before the fractional dot poison compact fallback. Against MySQL 8.4.10:

  • :34:56 must yield 0/34/56; this head yields 0/34/0.
  • 12:34: must yield 12/34/0; this head returns NULL.
  • 12::56 must yield 0/0/12; this head returns NULL.
  • 12:34:56: must yield 12/34/56; this head returns NULL.
  • 12-.abc must yield 0/0/12; this head returns NULL.

These are the same public VARCHAR/CHAR/TEXT overloads and are reachable from ordinary SQL. Please model MySQL prefix consumption as one consistent scanner instead of special-casing only the previously reported examples, and add the exact boundary matrix above to UT/BVT.

Validation: official MySQL 8.4.10 container under default SQL mode; a direct probe test against this exact head reproduced all five mismatches. The PR's focused string-extract tests pass with the deterministic CGo wrapper, so existing green tests do not cover this remaining state space.

  • 重写 mysqlClockFieldsForExtract 的部分 TIME 前缀扫描逻辑,按已成功解析的字段返回结果,不再因后续不完整分隔符丢弃已有时分秒。
  • 支持 :34:56、12:34:、12::56、12:34:56: 和 12-.abc 的 MySQL 兼容解析结果。
  • 新增 mysqlCompactTimePrefixBoundary,允许紧凑 TIME 数字前缀后接纯标点,同时避免将带后续数字的日期样式字符串误识别为紧凑 TIME。
  • 增加 UT,覆盖 VARCHAR、CHAR、TEXT 三种输入类型及 HOUR/MINUTE/SECOND 三个函数。
  • 在 func_datetime_hour/minute/second BVT 中补充上述五个场景,并重新生成对应 result 文件。

@XuPeng-SH XuPeng-SH left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep re-review of exact head 208371b44ab1e64fddeff5dcba1eb0b1425da148, including the author comment and the added VARCHAR/CHAR/TEXT UT/BVT matrix. The five previously reported inputs are fixed, but the new prefix scanner still has reachable MySQL 8.4 compatibility gaps.

P1 — Prefix semantics still change across the compact, day-TIME, and DATETIME branches

The new mysqlCompactTimePrefixBoundary rejects a compact prefix whenever any later punctuation-delimited text contains a digit. MySQL instead keeps the already consumed compact prefix: 12-34 yields HOUR/MINUTE/SECOND 0/0/12, while this head returns NULL (func_unary.go:5050-5055,5131-5140). This is the numeric counterpart of the author-comment example 12-.abc.

The day-TIME path then applies compact-field semantics where MySQL treats the post-day field as hours. For 1 02, MySQL returns 26/0/0; this head returns 24/0/2 because 02 is parsed as compact seconds before adding the day (:5011-5032).

The separated-DATETIME path has the same state-fragmentation problem: 2024-12-20 12 and 2024-12-20 12: both return 12/0/0 in MySQL, but this head marks the grammar as matched-invalid and returns NULL because a minute is mandatory (:4909-4920). 2024-12-20 12::56 is another reachable case: MySQL returns 12/56/0, this head returns NULL.

Please make prefix consumption context-aware without reinterpreting already parsed fields, and add these boundary families to the oracle-derived UT/BVT matrix rather than only the individual examples.

Validation used an official MySQL 8.4.10 container with default SQL mode plus a direct probe of this exact parser. The author regressions pass under race (-count=5), the full function package passes, and build/vet/diff checks plus remote CI are green; the green suite does not cover these remaining branches.

@daviszhen

Copy link
Copy Markdown
Contributor Author

Deep re-review of exact head 208371b44ab1e64fddeff5dcba1eb0b1425da148, including the author comment and the added VARCHAR/CHAR/TEXT UT/BVT matrix. The five previously reported inputs are fixed, but the new prefix scanner still has reachable MySQL 8.4 compatibility gaps.

P1 — Prefix semantics still change across the compact, day-TIME, and DATETIME branches

The new mysqlCompactTimePrefixBoundary rejects a compact prefix whenever any later punctuation-delimited text contains a digit. MySQL instead keeps the already consumed compact prefix: 12-34 yields HOUR/MINUTE/SECOND 0/0/12, while this head returns NULL (func_unary.go:5050-5055,5131-5140). This is the numeric counterpart of the author-comment example 12-.abc.

The day-TIME path then applies compact-field semantics where MySQL treats the post-day field as hours. For 1 02, MySQL returns 26/0/0; this head returns 24/0/2 because 02 is parsed as compact seconds before adding the day (:5011-5032).

The separated-DATETIME path has the same state-fragmentation problem: 2024-12-20 12 and 2024-12-20 12: both return 12/0/0 in MySQL, but this head marks the grammar as matched-invalid and returns NULL because a minute is mandatory (:4909-4920). 2024-12-20 12::56 is another reachable case: MySQL returns 12/56/0, this head returns NULL.

Please make prefix consumption context-aware without reinterpreting already parsed fields, and add these boundary families to the oracle-derived UT/BVT matrix rather than only the individual examples.

Validation used an official MySQL 8.4.10 container with default SQL mode plus a direct probe of this exact parser. The author regressions pass under race (-count=5), the full function package passes, and build/vet/diff checks plus remote CI are green; the green suite does not cover these remaining branches.

  • 修正 compact TIME 前缀:12-34 保留已解析的 12 秒,不再因后续数字返回 NULL。
  • 修正 day-TIME 语义:1 02 将 02 解释为小时,结果为 26:00:00。
  • 修正不完整 DATETIME 前缀:支持 2024-12-20 12、12: 和 12::56,分别解析为 12:00:00、12:00:00、12:56:00。

同时为 VARCHAR、CHAR、TEXT 增加了完整的 UT/BVT 边界矩阵,并更新 HOUR、MINUTE、SECOND 的预期结果文件。

@XuPeng-SH XuPeng-SH left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking MySQL compatibility issue remains at eff97c01acb8f0c89b17910884827dca1dd76ff8.

Against MySQL 8.4.10, the following string arguments produce HOUR/MINUTE/SECOND as shown, but the current parser returns different results:

  • 2024-12-20foo: MySQL 0/20/24; current parser returns NULL (ok=false).
  • 2024-12-20 12:34::56: MySQL 12/34/56; current parser returns 12/34/0.
  • 2024-12-20 12-34: MySQL 12/34/0; current parser returns 12/0/0.

The date-time scanner still has isolated colon-specific branches and only recognizes an exact date-only form, so valid consumed prefix components are discarded or treated as invalid. Please make prefix consumption consistent after a valid date/clock prefix, and cover these cases for VARCHAR/CHAR/TEXT in UT and BVT.

@daviszhen

Copy link
Copy Markdown
Contributor Author

Blocking MySQL compatibility issue remains at eff97c01acb8f0c89b17910884827dca1dd76ff8.

Against MySQL 8.4.10, the following string arguments produce HOUR/MINUTE/SECOND as shown, but the current parser returns different results:

  • 2024-12-20foo: MySQL 0/20/24; current parser returns NULL (ok=false).
  • 2024-12-20 12:34::56: MySQL 12/34/56; current parser returns 12/34/0.
  • 2024-12-20 12-34: MySQL 12/34/0; current parser returns 12/0/0.

The date-time scanner still has isolated colon-specific branches and only recognizes an exact date-only form, so valid consumed prefix components are discarded or treated as invalid. Please make prefix consumption consistent after a valid date/clock prefix, and cover these cases for VARCHAR/CHAR/TEXT in UT and BVT.

  • 统一 DATETIME/TIME 的有效前缀消费规则,修复:

    • 2024-12-20foo → 0/20/24
    • 2024-12-20 12:34::56 → 12/34/56
    • 2024-12-20 12-34 → 12/34/0
  • 支持连续/混合日期分隔符、时钟前置正负号及内部空白边界。

  • 修正 compact DATETIME 小数后紧跟 +/- 的无效判断。

  • 为 VARCHAR、CHAR、TEXT 补充 UT,并同步更新 HOUR/MINUTE/SECOND 三组 BVT 和 result。

@XuPeng-SH XuPeng-SH left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep-reviewed updated exact head 6b614bb55028082f68bd6616d4ccbccaff5d03c2. The three cases from the previous review are fixed, but the replacement parser still has a blocking same-shape compatibility gap.

P1 — Grammar ownership and prefix-consumption precedence remain inconsistent

I ran an 82-case differential matrix against an official MySQL 8.4.10 server under its default SQL mode and a MatrixOne server built from this exact head. Nine cases still disagree. Representative HOUR/MINUTE/SECOND triples are:

input                              MySQL        this head
1 2                                0/0/1        26/0/0
12:34:56 78                        12/34/56     NULL
1-2-3 4:5:6                        0/0/1        4/5/6
12345-1-1 1:2:3                    NULL         1/23/45
--12:34                            NULL         12/34/0
2024-12-20 ++12:34                 12/34/0      NULL
2024-12-20 12:34:56+abc            0/20/24      12/34/56
2024-12-20 12:34:56-abc            0/20/24      12/34/56

These are not independent one-off omissions. mysqlSeparatedDatetimeClockForExtract, the day-TIME branch, compact fallback, and sign/suffix handling can each claim or reject the same prefix using different rules. For example, the separated-DATETIME classifier claims 12:34:56 78 as a date-shaped input and returns matched-invalid before the TIME scanner can preserve the valid clock, while any digit-only field before whitespace is treated as a day in 1 2 even though MySQL consumes a different compact prefix.

Please define one ordered grammar/consumption contract for ambiguous DATE/DATETIME/day-TIME/compact-TIME prefixes, with a single owner for sign, whitespace, and suffix termination, rather than adding branches for these examples. Add an oracle-derived regression matrix around the ambiguous boundaries above (nearest valid/invalid controls and VARCHAR/CHAR/TEXT), so the grammar classes—not only reported spellings—are closed.

Fresh exact-head service build, go list, build, vet, all TestStringTimeExtract* tests, and the full pkg/sql/plan/function suite pass. The existing green matrix does not cover these remaining states.

@daviszhen

Copy link
Copy Markdown
Contributor Author

Deep-reviewed updated exact head 6b614bb55028082f68bd6616d4ccbccaff5d03c2. The three cases from the previous review are fixed, but the replacement parser still has a blocking same-shape compatibility gap.

P1 — Grammar ownership and prefix-consumption precedence remain inconsistent

I ran an 82-case differential matrix against an official MySQL 8.4.10 server under its default SQL mode and a MatrixOne server built from this exact head. Nine cases still disagree. Representative HOUR/MINUTE/SECOND triples are:

input                              MySQL        this head
1 2                                0/0/1        26/0/0
12:34:56 78                        12/34/56     NULL
1-2-3 4:5:6                        0/0/1        4/5/6
12345-1-1 1:2:3                    NULL         1/23/45
--12:34                            NULL         12/34/0
2024-12-20 ++12:34                 12/34/0      NULL
2024-12-20 12:34:56+abc            0/20/24      12/34/56
2024-12-20 12:34:56-abc            0/20/24      12/34/56

These are not independent one-off omissions. mysqlSeparatedDatetimeClockForExtract, the day-TIME branch, compact fallback, and sign/suffix handling can each claim or reject the same prefix using different rules. For example, the separated-DATETIME classifier claims 12:34:56 78 as a date-shaped input and returns matched-invalid before the TIME scanner can preserve the valid clock, while any digit-only field before whitespace is treated as a day in 1 2 even though MySQL consumes a different compact prefix.

Please define one ordered grammar/consumption contract for ambiguous DATE/DATETIME/day-TIME/compact-TIME prefixes, with a single owner for sign, whitespace, and suffix termination, rather than adding branches for these examples. Add an oracle-derived regression matrix around the ambiguous boundaries above (nearest valid/invalid controls and VARCHAR/CHAR/TEXT), so the grammar classes—not only reported spellings—are closed.

Fresh exact-head service build, go list, build, vet, all TestStringTimeExtract* tests, and the full pkg/sql/plan/function suite pass. The existing green matrix does not cover these remaining states.

  • 明确解析优先级:依次处理外层符号、分隔 DATETIME、紧凑 DATETIME、TIME/day-TIME/紧凑 TIME,最后回退到 DATE prefix。
  • 修复 DATE、DATETIME、day-TIME、compact-TIME 对相同前缀的错误抢占。
  • 统一处理空白、连续符号和尾部 suffix,避免丢失已解析的合法时间字段。
  • 修复 reviewer 列出的 8 个兼容性输入,使结果与 MySQL 8.4.10 一致。
  • 增加 UT 和 BVT 回归矩阵,覆盖 VARCHAR/CHAR/TEXT 的 HOUR/MINUTE/SECOND 及相邻有效/无效边界。
  • 三组 BVT 结果文件已与 UT 对齐;HOUR(NOW()) 的无关动态结果变化不应提交。

@XuPeng-SH XuPeng-SH left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep-reviewed updated exact head eafe2e7009eb7aa7d4c91a9e813a9390f0b0716d. The eight cases from the previous review are fixed, but three reachable grammar families still disagree with MySQL 8.4.10.

P1 — day-TIME ownership cannot be decided by post-space digit count alone

mysqlDayTimeClockCandidateForExtract requires at least two leading digits after the day separator (func_unary.go:5129-5134). MySQL distinguishes a lone compact field from a one-digit clock field by the following separator, so this rule loses valid day-TIME values:

input     MySQL H/M/S   this head
1 2:3     26/3/0        0/0/1
12 3:4    291/4/0       0/0/12

The existing 1 2 versus 1 02 regression is not sufficient; cover one-digit post-day hour with and without minute/second separators.

P1 — valid three-digit-year DATETIME is routed to compact TIME

The separated-DATETIME gate accepts only exactly 2 or 4 year digits (func_unary.go:4889-4891). MySQL accepts 123-2-3 4:5:6 as a separated DATETIME and returns 4/5/6; this head skips the DATETIME owner and returns compact-TIME 0/1/23. The boundary should cover 1/2/3/4/5-digit year prefixes rather than only the previously reported 1- and 5-digit controls.

P1 — a bare trailing sign terminates DATETIME ownership

mysqlDatetimeClockSuffixForExtract rejects +/- only when another byte follows (func_unary.go:4985-4995), explicitly treating a bare sign as a valid clock suffix. MySQL instead falls back to the DATE prefix:

input                         MySQL H/M/S   this head
2024-12-20 12:34:56+         0/20/24       12/34/56
2024-12-20 12:34:56-         0/20/24       12/34/56

All five mismatches were independently reproduced against the official MySQL 8.4.10 image and with a direct probe of this exact production parser. Existing TestStringTimeExtract* tests pass under race (-count=3), the full function package, vet, and diff checks pass, and CI is green; the current oracle matrix simply does not close these adjacent states.

@daviszhen

Copy link
Copy Markdown
Contributor Author

Deep-reviewed updated exact head eafe2e7009eb7aa7d4c91a9e813a9390f0b0716d. The eight cases from the previous review are fixed, but three reachable grammar families still disagree with MySQL 8.4.10.

P1 — day-TIME ownership cannot be decided by post-space digit count alone

mysqlDayTimeClockCandidateForExtract requires at least two leading digits after the day separator (func_unary.go:5129-5134). MySQL distinguishes a lone compact field from a one-digit clock field by the following separator, so this rule loses valid day-TIME values:

input     MySQL H/M/S   this head
1 2:3     26/3/0        0/0/1
12 3:4    291/4/0       0/0/12

The existing 1 2 versus 1 02 regression is not sufficient; cover one-digit post-day hour with and without minute/second separators.

P1 — valid three-digit-year DATETIME is routed to compact TIME

The separated-DATETIME gate accepts only exactly 2 or 4 year digits (func_unary.go:4889-4891). MySQL accepts 123-2-3 4:5:6 as a separated DATETIME and returns 4/5/6; this head skips the DATETIME owner and returns compact-TIME 0/1/23. The boundary should cover 1/2/3/4/5-digit year prefixes rather than only the previously reported 1- and 5-digit controls.

P1 — a bare trailing sign terminates DATETIME ownership

mysqlDatetimeClockSuffixForExtract rejects +/- only when another byte follows (func_unary.go:4985-4995), explicitly treating a bare sign as a valid clock suffix. MySQL instead falls back to the DATE prefix:

input                         MySQL H/M/S   this head
2024-12-20 12:34:56+         0/20/24       12/34/56
2024-12-20 12:34:56-         0/20/24       12/34/56

All five mismatches were independently reproduced against the official MySQL 8.4.10 image and with a direct probe of this exact production parser. Existing TestStringTimeExtract* tests pass under race (-count=3), the full function package, vet, and diff checks pass, and CI is green; the current oracle matrix simply does not close these adjacent states.

  • day-TIME:一位 post-day 数字后有 : 时按小时解析,修复 1 2:3、12 3:4。
  • DATETIME:年份支持 2–4 位,三位年份如 123-2-3 4:5:6 可正确解析。
  • 尾随符号:完整 DATETIME clock 后的裸 +/- 终止 DATETIME 解析并回退 DATE 前缀。
  • 增加 VARCHAR、CHAR、TEXT 的 UT/BVT 边界矩阵,覆盖 day-TIME、1–5 位年份及尾随符号。

@XuPeng-SH XuPeng-SH left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep-reviewed updated exact head 21c67bd0c85c8569a4788cf9de35022b04e2e83a. The five cases from the previous review are fixed, but two adjacent grammar families still disagree with MySQL 8.4.10.

P1 — Separated-DATETIME ownership is not determined by year width alone

mysqlSeparatedDatetimeClockForExtract now accepts only 2–4 year digits (pkg/sql/plan/function/func_unary.go:4887-4891). The new one-digit control covers 1-2-3 4:5:6, but MySQL's ownership also depends on the following clock-field widths:

input                  MySQL H/M/S   this head
1-1-1 1:2:3            0/0/1         0/0/1
1-1-1 01:02:03         1/2/3         0/0/1
1-2-3 12:34:56         12/34/56      0/0/1
0-1-1 12:34:56         12/34/56      0/0/0

So treating every one-digit year as compact TIME is still an overfit boundary: changing only the width of the clock fields transfers ownership to DATETIME in MySQL. Please derive the owner from the complete prefix grammar and cover one-digit year × one-/two-digit clock fields (including year zero) for VARCHAR/CHAR/TEXT.

P1 — Pre-parse TrimSpace changes grammar ownership

timeStringToFixedWithNullOnError rewrites every nonempty input with strings.TrimSpace before classification (func_unary.go:4776-4785). That is not semantics-preserving for ambiguous prefixes:

input                     MySQL H/M/S   this head
'123:34:56 78'            NULL          NULL
'123:34:56 78 '           123/34/56     NULL
'838:59:59 78'            NULL          NULL
'838:59:59 78 '           838/59/59     NULL

The same result holds with surrounding tabs. Detecting an all-whitespace value as NULL must not discard leading/trailing whitespace from a nonempty value before the ordered grammar sees it. Please keep whitespace ownership inside the parser and add padded/unpadded controls around the same ambiguous prefix.

Validation used direct SQL string literals against the official MySQL 8.4.10 image and the exact-head production parser. The existing TestStringTimeExtract* suite passes under -race -count=3, and remote CI is green; those tests do not cover either adjacent family.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/bug Something isn't working size/XXL Denotes a PR that changes 2000+ lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants