Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

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

オープン
#2,568 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@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() と比較してください。提供された psql の再現手順を、Cypher 経由と直接 SQL 経由の両方で実行してください。'.'、'|'、'+' などのリテラルの区切り文字が regex のエスケープなしで正しく分割され、置換の動作も一貫していれば完了です。

索引モデルが 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
フォーク
529
平均マージ
8日 15時間
マージ済み PR(30日)
3

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

apache/age のほかの issue

apache/age の issue をすべて見る

似ている issue

C の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。