Skip to content

add nameconst#24887

Open
daviszhen wants to merge 13 commits into
matrixorigin:mainfrom
daviszhen:0603-add-nameconst
Open

add nameconst#24887
daviszhen wants to merge 13 commits into
matrixorigin:mainfrom
daviszhen:0603-add-nameconst

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 ##24486

What this PR does / why we need it:

增加name_const函数

daviszhen added 5 commits June 3, 2026 18:52
  第一参数 name:

  - 必须是 literal constant。
  - 不能是 NULL。
  - 可以是字符串 literal,也可以是数字 literal,最终用于生成结果列名。
  - 不能引用表字段。
  - 不能是函数、CAST(...)、表达式、子查询等。

  第二参数 value:

  - 必须是 literal constant。
  - 支持各种 literal 类型:整数、uint64 边界值、decimal、float/double、字符串、NULL 等。
  - 支持负数字面量,例如 -1、-12.34。
  - 不支持列引用。
  - 不支持函数调用。
  - 不支持 CAST(...)。
  - 不支持即使可 constant fold 的表达式,例如 abs(-1)。

  合法例子:

  select name_const('myname', 14);
  select name_const(123, -456);
  select name_const('x', 18446744073709551615);
  select name_const('x', 'abc');
  select name_const('x', null);
  select name_const('x', -12.34);

  非法例子:

  select name_const(null, 1);
  select name_const(a, 1) from t;
  select name_const('x', a) from t;
  select name_const('x', cast(14 as signed));
  select name_const('x', abs(-1));
  select name_const('x', now());

  核心点:NAME_CONST 不是普通可折叠表达式函数。它更接近 MySQL 的行为,只接受 literal 形态的参数;第二参数虽然类型可以比较宽,但表达式形态必须受限,不能先通过 constant fold 把函数或 cast 伪装成 literal。
@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 →

@aunjgr aunjgr 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.

MySQL NAME_CONST(name, value) — internal function used by replication. Returns value with column heading name.

Implementation:

  • foldNameConstArgs validates first arg is a non-null literal (column name), constant-folds the second arg (value)
  • validNameConstValueExpr allows literals, decimal-literal casts, and -literal forms
  • Binder integration at bindFuncExprAndConstFold case "name_const" — constant-folds before proceeding
  • BVT covers single/multi-row, NULL args, JOIN, subquery, negative values, and error cases

Clean, matches MySQL 8.0 semantics. LGTM.

@daviszhen

Copy link
Copy Markdown
Contributor Author

@mergify refresh

@mergify

mergify Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

refresh

✅ Pull request refreshed

@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.

I found two blocking issues in the NAME_CONST implementation.

  1. pkg/sql/plan/base_binder.go:1449-1567 routes name_const to goto between_fallback when proc == nil. That fallback is BETWEEN-specific and unconditionally reads fnArgs[2], but NAME_CONST only has two arguments, so any nil-proc binder/internal path will panic with an index-out-of-range.

  2. pkg/sql/plan/query_builder.go:4482-4492 only extracts the heading when the first argument is a bare *tree.NumVal, while pkg/sql/plan/base_binder.go:2978-2991 explicitly accepts parenthesized names by stripping *tree.ParenExpr. So select name_const(('myname'), (14)) is accepted, but the column heading falls back to name_const(...) instead of myname.

@daviszhen

Copy link
Copy Markdown
Contributor Author

I found two blocking issues in the NAME_CONST implementation.

  1. pkg/sql/plan/base_binder.go:1449-1567 routes name_const to goto between_fallback when proc == nil. That fallback is BETWEEN-specific and unconditionally reads fnArgs[2], but NAME_CONST only has two arguments, so any nil-proc binder/internal path will panic with an index-out-of-range.
  2. pkg/sql/plan/query_builder.go:4482-4492 only extracts the heading when the first argument is a bare *tree.NumVal, while pkg/sql/plan/base_binder.go:2978-2991 explicitly accepts parenthesized names by stripping *tree.ParenExpr. So select name_const(('myname'), (14)) is accepted, but the column heading falls back to name_const(...) instead of myname.

已经修改

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

Labels

kind/enhancement size/M Denotes a PR that changes [100,499] lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants