Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

split() treats the delimiter as a regular expression while replace() treats it literally

未关闭
#2,568 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 3 天内回复

@mmustafasenoglu 已经在做这个了。

开始于 2026年9月13日。

  • #2569 来自 @mmustafasenoglu —— 未关闭

评估

难度
3/5
预计耗时
1-2 天
新手友好度
82/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
c, postgresql
领域
databases

调研方向

阅读 src/backend/utils/adt/agtype.c,从 age_split() 开始,并将其分隔符处理与 age_replace() 进行比较。通过 Cypher 路径和直接 SQL 路径分别运行提供的 psql 复现。完成标准是:'.'、'|' 和 '+' 等字面分隔符无需进行正则表达式转义即可正确分割,同时替换行为保持一致。

由索引模型根据 Issue 内容生成。

描述

bug

AGE Version: extension 1.8.0 on PostgreSQL 18.6
Installation Method: Docker
API: Cypher and direct SQL

Steps to reproduce (paste into psql as-is)

LOAD 'age';
SET search_path = ag_catalog, public;

-- Cypher path (re-run: DROP GRAPH xdb CASCADE first)
SELECT * FROM create_graph('xdb');
SELECT * FROM cypher('xdb', $$ RETURN split('a.b.c', '.') $$) AS (r agtype);

-- SQL path (same C function, no graph needed)
SELECT age_split('a.b.c', '.');        -- -> ["", "", "", "", "", ""]
SELECT age_split('a1b1c', '1');        -- -> ["a", "b", "c"]   (plain delimiter: works)
SELECT age_replace('a.b.c', '.', '-'); -- -> "a-b-c"
SELECT age_split('a.b.c', '\.');      -- -> ["a", "b", "c"]   (only because it is regex-escaped)
SELECT age_split('a|b', '|');          -- -> ["a", "|", "b"]
SELECT age_split('a+b+c', '+');        -- -> ERROR: invalid regular expression: quantifier operand invalid

Expected behavior

openCypher defines the split delimiter as a literal string: split('a.b.c', '.') → ['a','b','c']. Neo4j, Memgraph and FalkorDB all return this without any escaping, and replace('a.b.c', '.', '-') → 'a-b-c' in AGE too — so both functions must interpret '.' identically.

Actual behavior

  • split('a.b.c', '.') → ["","","","","",""] (six empty strings): the delimiter is compiled as a regular expression, so '.' matches every character.
  • split('a1b1c', '1') → ["a","b","c"]: plain delimiters work, so the regex interpretation only surfaces for metacharacters — exactly where queries silently break.
  • split('a.b.c', '\.') → ["a","b","c"]: correct only because the user manually regex-escapes the dot.
  • split('a|b', '|') → ["a","|","b"]: the empty-alternation regex splits at every position.
  • split('a+b+c', '+') → ERROR: invalid regular expression: quantifier operand invalid.
  • replace('a.b.c', '.', '-') → "a-b-c": the same engine treats the same delimiter literally.

The engine is internally inconsistent, deviates from openCypher and all sibling engines, and silently corrupts results for common literal delimiters ('.', '|', '+', ...).

Root cause

age_split() (src/backend/utils/adt/agtype.c) passes the delimiter verbatim to PostgreSQL's regexp_split_to_array(), which compiles it as a regular expression; age_replace() performs a literal replacement. Cypher split()/replace() are rewritten to these same SQL functions, so both APIs are affected.

主要语言
C
星标
4.9k
派生
535
平均合并
10 天 13 小时
30 天内合并 PR
7

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

apache/age 的其他 Issue

查看 apache/age 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。