Contribution · PostgreSQL · RDBMS Core

PostgreSQL — 패치 두 건

PostgreSQL은 GitHub PR을 받지 않고 메일링리스트 워크플로로만 운영. 현재 두 건의 패치가 진행 중 — contrib/btree_gist NaN ordering 버그 수정(BUG #19501 / #19524)과 core docs config.sgml id/xreflabel 정합성 수정.

1. btree_gist NaN ordering — BUG #19501 / #19524

contrib/btree_gist/btree_float4.c·btree_float8.c의 5개 GiST 비교 콜백(gbt_float{4,8}{gt,ge,eq,le,lt})이 raw C 연산자를 사용. IEEE 754에서 NaN과의 모든 비교는 false를 돌려주므로, GiST가 "NaN ↔ NaN", "NaN > 1.0" 같은 케이스를 잘못 판정. 같은 float에 대해 regular btree opclass는 float4_cmp_internal()(NaN 모두 동등, NaN이 모든 non-NaN 위에 정렬)을 쓰니까 두 인덱스 종류가 같은 데이터에 대해 다른 결과를 돌려주는 상태.

SQL로 재현 가능한 세 시나리오:

  • Index/seq scan 불일치 — float GiST 인덱스에 WHERE v = 'NaN'::float8이 index scan에선 0 row, seq scan에선 NaN row를 정상 반환.
  • EXCLUDE 우회EXCLUDE USING gist (a WITH =)가 NaN 중복을 허용. gbt_float8eq(NaN, NaN)이 false로 평가되어 충돌 감지가 안 됨.
  • RLS 누수USING (a != 'NaN'::float8) 정책이 index scan 경로에서만 NaN row를 노출. predicate의 !=가 raw 연산자 의미로 인덱스 키에 적용되기 때문.

수정

5개의 boolean 콜백을 utils/float.h의 NaN-aware float{4,8}_{gt,ge,eq,le,lt} inline 헬퍼로 교체, picksplit 비교(gbt_float{4,8}key_cmp)도 float{4,8}_cmp_internal()로 교체. 이 헬퍼들은 regular btree opclass가 이미 쓰는 total order(NaN 모두 동등, NaN이 모든 non-NaN 위에 정렬)와 같으므로, 두 인덱스 종류의 동작이 일치하게 됨. on-disk 포맷 변경 없음 — 메모리 비교 경로만 수정.

회귀 테스트는 contrib/btree_gist/sql/float4.sql·float8.sql에 NaN 섹션을 추가: index scan ↔ seq scan 일치 확인, NaN이 finite 값 뒤로 정렬되는지 확인, EXCLUDE 제약이 NaN 중복을 정확히 거부하는지 확인. 패치 적용 후 make check 결과: core 245/245 + contrib btree_gist 32/32 + 전체 contrib 48 modules 통과.

패치 상세 →

2. config.sgml id / xreflabel 정합성 — core docs

doc/src/sgml/config.sgml의 두 군데 varlistentry attribute가 같은 파일의 다른 모든 항목과 어긋나 있어서 정합성을 맞춤. behaviour 변경 없음, on-disk 영향 없음, callsite churn 없음. git diff --stat: 1 file, +2/-2.

  • enable_group_by_reorderingvarlistentry id가 guc-enable-groupby-reordering로 단어 경계가 빠져 있음. 같은 파일의 다른 enable_* 파라미터는 모두 guc-enable-X-y-z 형태로 GUC 이름의 underscore 자리에 hyphen을 넣음. guc-enable-group-by-reordering로 수정.
  • quote_all_identifiersxreflabel"quote-all-identifiers" (hyphen) — 같은 파일의 다른 모든 xreflabel은 GUC 이름 그대로 underscore. "quote_all_identifiers"로 수정.

두 id 모두 incoming linkend 참조 없음 → 순수 정합성 변경.

패치 상세 →

제출 현황

관련 자료