Skip to content

[CBRD-27158] Add SQL testcase for GROUP BY + window function corrupti… - #3314

Merged
kiho-um merged 9 commits into
CUBRID:developfrom
kiho-um:CBRD-27158
Aug 27, 2026
Merged

kiho-um merged 9 commits into
CUBRID:developfrom
kiho-um:CBRD-27158

Conversation

@kiho-um

@kiho-um kiho-um commented Aug 20, 2026 •

Copy link
Copy Markdown
Contributor

…on in set operations

http://jira.cubrid.org/browse/CBRD-27158

Purpose

GROUP BY + 집계 + 윈도우 함수 + ORDER BY 쿼리가 집합 연산(UNION/INTERSECT/EXCEPT)에 포함될 때
결과 행이 깨지는 문제 (CUBRID/cubrid#7607). mq_rewrite_aggregate_as_derived에서 만드는
히든 derived 컬럼명이 unique하지 않아 발생.

기존 TC 수정(PR #3190, develop 머지 완료 / PR #3296, release/11.4 백포트 완료)은
CUBRID 고유 pseudocolumn(rownum, orderby_num(), groupby_num(), inst_num())과
GROUP BY/집합연산 조합만 커버했고, 실제 ANSI 윈도우 함수(OVER절)를 사용하는 시나리오는
검증되지 않았습니다. 이 TC는 그 공백을 메우기 위한 신규 전용 테스트입니다.

Implementation

Case 1~6 (최초 커버리지)

Case 12: UNION ALL 두/한 분기에서 윈도우 함수 히든 컬럼 유니크성
Case 3
4: INTERSECT/EXCEPT에도 동일 fix 적용 확인
Case 5: 3-way UNION ALL
Case 6: 집합연산 전체 결과에 대한 바깥 ORDER BY
Case 7~8 (원본 Jira 재현 쿼리, 리뷰 요청으로 추가)

Case 7: 원본 리포트의 재현 쿼리(repro_setop_t2/t3, 분기 자체에 ORDER BY) standalone 버전
Case 8: Case 7을 UNION으로 묶은 버전 — 원본 이슈가 실제로 보고된 그 모양
Case 9~16 (리뷰어 bagus-kim 제안 커버리지 확장)

Case 9/10: 식 기준 ORDER BY(ca+1)로 만들어지는 히든 컬럼
Case 11/12: 같은 분기에 식 기준 ORDER BY 키 2개
Case 13/14: 분기 ORDER BY + LIMIT 조합
Case 15/16: 같은 분기에 윈도우 함수 2개 + 분기 ORDER BY
각 7~16 케이스는 "정상값 확인용 standalone" → "그 값이 UNION에서도 안 깨지는지 확인" 순서로 짝을 이룹니다.

리뷰 대응 수정 및 추가사항

Case 1~5: 집합연산 결과에 명시적 order by 추가 (병렬 워커로 인한 순서 비보장 리스크 제거)
Case 2: row_number()/rank()에 grp 타이브레이크 추가 (동점 시 비결정적이었던 문제 수정)
Case 3(INTERSECT)/Case 4(EXCEPT): 두 번째 분기를 실제로 다르게 만들어서 진짜 필터링이 일어나도록 수정 (기존엔 아무것도 안 걸러지고 있었음)
Case 17: PARTITION BY 윈도우(카테고리별 누적합)를 UNION ALL 두 분기에서 — 분기별 파티션 키 히든 컬럼이 유니크한지
Case 18: 한 분기 안에 PARTITION BY 윈도우 함수 2개(row_number(), rank()) — 각 파티션 윈도우가 서로 다른 히든 컬럼을 갖는지
Case 19: Case 17 패턴을 INTERSECT로 — 두 번째 분기를 cat='A'로 실제로 다르게 만들어서 집합연산에서도 파티션 키 히든 컬럼이 유니크한지

Remarks

  • CUBRID 11.5.0(develop, 여러 빌드)에서 16개 케이스 전부 실행 검증 완료.
    greptile-apps 자동 리뷰 2건 중 P1(순서 미보장)은 반영, P2(마스킹된 히든 이름)는 실제 결과값 비교로 충분히 커버된다고 판단해 별도 조치 없음.
    bagus-kim님 리뷰 코멘트 전부 반영 완료 (인라인 2건 + 일반 코멘트 Case 711 제안 전부).
    ssihil님 리뷰 코멘트 제안 — PARTITION BY 커버리지, Case 17
    19) 전부 반영 완료

@greptile-apps

greptile-apps Bot commented Aug 20, 2026

Copy link
Copy Markdown

Reviews (1): Last reviewed commit: "[CBRD-27158] Add SQL testcase for GROUP ..." | Re-trigger Greptile

Comment on lines +60 to +62
union all
select grp, sum(val), sum(sum(val)) over (order by grp) as running_total from tb group by grp;
show trace;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 집합 연산 결과 순서 미보장

Cases 1~5는 집합 연산 전체에 최종 ORDER BY가 없는데도 answer fixture에서 특정 행 순서를 고정합니다. 실행기가 다른 합법적인 순서로 행을 반환하면 계산 결과가 정확해도 byte-for-byte 비교가 실패하므로, 각 쿼리의 최종 결과 순서를 명시적으로 안정화해야 합니다.

Knowledge Base Used: SQL functional test suites (sql/)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

지적하신 대로 Cases 1, 2, 3, 4, 5 전부 최상위 ORDER BY가 없어서 순서가 보장되지 않았습니다. 트레이스에 UNION (... parallel workers: ? ...)가 찍혀 있어 병렬 워커 개입 시 값은 맞아도 순서가 달라질 리스크가 실재했습니다(CBRD-26522에서 겪은 것과 동일). 각 케이스 끝에 order by 1,2,3(Case 2는 1,2,3,4)을 추가했고, 재실행으로 안정적인 순서를 확인 후 답지도 재생성했습니다.

Comment on lines +23 to +27
* Note: table/column names use letters (ta/tb), not digits, because CTP
* masks digits in the trace output to ?, same convention as
* CBRD-26571 cbrd_26571.sql and CBRD-26522s cbrd_26522.sql.
*
* Coverage:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 마스킹된 hidden 이름 검증

CTP가 a_1, a_2 같은 숫자 suffix를 모두 a_?로 정규화하므로 현재 trace fixture는 고유한 이름과 충돌한 이름을 구분하지 못합니다. 결과값에 충돌 증상이 드러나지 않는 회귀도 탐지할 수 있도록 hidden-column 유일성을 관찰 가능한 방식으로 검증해야 합니다.

Knowledge Base Used: SQL functional test suites (sql/)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

.answer에 트레이스 외 실제 결과값도 함께 기록되어 있어, 별도 조치는 하지 않습니다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

맞습니다. .answer를 보니 각 케이스마다 실제 결과 행(예: g1 30 30, g2 70 100 등)이 trace와 함께 기록되어 있어, hidden 컬럼이 충돌하면 결과값 자체가 달라지므로 CTP가 mismatch로 잡을 수 있습니다. 제 우려는 해소됩니다. LGTM입니다.

Tip: You can customize Greptile's behavior for this repo with .greptile/rules.md and .greptile/config.json.

@bagus-kim

Copy link
Copy Markdown
Contributor

추가 TC 시나리오 입니다. 추가를 검토 바랍니다.

  • Case7 : CBRD-27158 에 있는 repro_setop_t2 관련 내용 : 해당 구문이 수정된 코드의 조건에 부합됨으로 추가
  • Case8 : 식 기준 ORDER BY (ca + 1)로 만든 히든 컬럼
  • Case9 : 히든 컬럼 2개
  • Case10 : 분기 ORDER BY + LIMIT
  • Case11 : 히든 컬럼+윈도우 함수

drop table if exists tc, td;
create table tc (ca int, cb datetime);
create table td (cd int);

insert into tc values (1, '2026-01-01 00:00:00');
insert into td values (0), (1), (2), (3);
commit;

evaluate 'Case 8: hidden column produced by an expression ORDER BY';
select /*+ recompile / count(cb) as col_a, dense_rank() over (order by ca asc) as col_b, count(ca) as col_c
from tc group by ca order by ca + 1;
show trace;
(select /
+ recompile */ count(cb) as col_a, dense_rank() over (order by ca asc) as col_b, count(ca) as col_c
from tc group by ca order by ca + 1)
union
select cd as col_a, cd as col_b, cd as col_c from td where cd < 0;
show trace;

evaluate 'Case 9: two hidden columns, both expressions, so the name counter advances twice';
select /*+ recompile / count(cb) as col_a, dense_rank() over (order by ca asc) as col_b, count(ca) as col_c
from tc group by ca order by ca + 1, ca * 2;
show trace;
-- standalone reference: the set-operation result below must match the block above
(select /
+ recompile */ count(cb) as col_a, dense_rank() over (order by ca asc) as col_b, count(ca) as col_c
from tc group by ca order by ca + 1, ca * 2)
union
select cd as col_a, cd as col_b, cd as col_c from td where cd < 0;
show trace;

evaluate 'Case 10: branch ORDER BY with LIMIT, so orderby_num and the limit push down path join in';
select /*+ recompile / count(cb) as col_a, dense_rank() over (order by ca asc) as col_b, count(ca) as col_c
from tc group by ca order by ca limit 1;
show trace;
-- standalone reference: the set-operation result below must match the block above
(select /
+ recompile */ count(cb) as col_a, dense_rank() over (order by ca asc) as col_b, count(ca) as col_c
from tc group by ca order by ca limit 1)
union
select cd as col_a, cd as col_b, cd as col_c from td where cd < 0;
show trace;

evaluate 'Case 11: hidden column plus two window functions in one branch, the old counter made a_1 and a_2 back to
back';
select /*+ recompile / count(cb) as col_a, row_number() over (order by ca asc) as col_b,
dense_rank() over (order by ca desc) as col_c, count(ca) as col_d
from tc group by ca order by ca;
show trace;
-- standalone reference: the set-operation result below must match the block above
(select /
+ recompile */ count(cb) as col_a, row_number() over (order by ca asc) as col_b,
dense_rank() over (order by ca desc) as col_c, count(ca) as col_d
from tc group by ca order by ca)
union
select cd as col_a, cd as col_b, cd as col_c, cd as col_d from td where cd < 0;
show trace;

Comment thread sql/_36_guava/cbrd_27158/cases/cbrd_27158.sql Outdated
Comment thread sql/_36_guava/cbrd_27158/cases/cbrd_27158.sql
@kiho-um

kiho-um commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor Author

추가 TC 시나리오 입니다. 추가를 검토 바랍니다.

  • Case7 : CBRD-27158 에 있는 repro_setop_t2 관련 내용 : 해당 구문이 수정된 코드의 조건에 부합됨으로 추가
  • Case8 : 식 기준 ORDER BY (ca + 1)로 만든 히든 컬럼
  • Case9 : 히든 컬럼 2개
  • Case10 : 분기 ORDER BY + LIMIT
  • Case11 : 히든 컬럼+윈도우 함수

drop table if exists tc, td; create table tc (ca int, cb datetime); create table td (cd int);

insert into tc values (1, '2026-01-01 00:00:00'); insert into td values (0), (1), (2), (3); commit;

evaluate 'Case 8: hidden column produced by an expression ORDER BY'; select /*+ recompile / count(cb) as col_a, dense_rank() over (order by ca asc) as col_b, count(ca) as col_c from tc group by ca order by ca + 1; show trace; (select /+ recompile */ count(cb) as col_a, dense_rank() over (order by ca asc) as col_b, count(ca) as col_c from tc group by ca order by ca + 1) union select cd as col_a, cd as col_b, cd as col_c from td where cd < 0; show trace;

evaluate 'Case 9: two hidden columns, both expressions, so the name counter advances twice'; select /*+ recompile / count(cb) as col_a, dense_rank() over (order by ca asc) as col_b, count(ca) as col_c from tc group by ca order by ca + 1, ca * 2; show trace; -- standalone reference: the set-operation result below must match the block above (select /+ recompile */ count(cb) as col_a, dense_rank() over (order by ca asc) as col_b, count(ca) as col_c from tc group by ca order by ca + 1, ca * 2) union select cd as col_a, cd as col_b, cd as col_c from td where cd < 0; show trace;

evaluate 'Case 10: branch ORDER BY with LIMIT, so orderby_num and the limit push down path join in'; select /*+ recompile / count(cb) as col_a, dense_rank() over (order by ca asc) as col_b, count(ca) as col_c from tc group by ca order by ca limit 1; show trace; -- standalone reference: the set-operation result below must match the block above (select /+ recompile */ count(cb) as col_a, dense_rank() over (order by ca asc) as col_b, count(ca) as col_c from tc group by ca order by ca limit 1) union select cd as col_a, cd as col_b, cd as col_c from td where cd < 0; show trace;

evaluate 'Case 11: hidden column plus two window functions in one branch, the old counter made a_1 and a_2 back to back'; select /*+ recompile / count(cb) as col_a, row_number() over (order by ca asc) as col_b, dense_rank() over (order by ca desc) as col_c, count(ca) as col_d from tc group by ca order by ca; show trace; -- standalone reference: the set-operation result below must match the block above (select /+ recompile */ count(cb) as col_a, row_number() over (order by ca asc) as col_b, dense_rank() over (order by ca desc) as col_c, count(ca) as col_d from tc group by ca order by ca) union select cd as col_a, cd as col_b, cd as col_c, cd as col_d from td where cd < 0; show trace;

[답변]
TC 시나리오 6개 반영 하겠습니다.

* the wrong column and silently produce the wrong row order.
* this is the most direct way "corrupted rows" would surface
*/

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.

CBRD-27158 이슈에 있는 재현 시나리오에 대한 추가를 검토해 주세요.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

빠졌네요. 반영하겠습니다.

@kiho-um
kiho-um requested a review from kwonhoil August 26, 2026 07:21
drop table if exists tg, tf;


drop table if exists ta, tb;

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.

set trace off; 추가해 주세요.

@ssihil

ssihil commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

추가 시나리오 제안합니다.

기존 TC 의 OVER 절은 전부 (ORDER BY ...) 뿐이라 PARTITION BY 가 0건. PARTITION BY 는 파티션 키를 derived 재작성의 추가 hidden 컬럼 으로 만들므로, hidden 컬럼 유니크성 검증면을 직접 넓힌다.

drop table if exists tp, tq;
create table tp (id int primary key, cat varchar(10), grp varchar(10), val int);
create table tq (id int primary key, cat varchar(10), grp varchar(10), val int);

-- tp: cat 2개(A,B) × grp 로 (cat,grp) 그룹이 파티션 안에 여러 개 생기게 둔다
insert into tp values (1,'A','g1',10),(2,'A','g1',20),(3,'A','g2',30),
(4,'B','g1',100),(5,'B','g2',200),(6,'B','g2',50);
insert into tq values (1,'A','g1',5),(2,'B','g2',7);
commit;

-- (cat,grp) 그룹합: A/g1=30, A/g2=30, B/g1=100, B/g2=250 | tq: A/g1=5, B/g2=7
-- partition by cat, order by grp 누적:
-- A: g1->30, g2->60 | B: g1->100, g2->350 | tq A: g1->5 tq B: g2->7

evaluate 'Case A1: PARTITION BY window in two UNION ALL branches -> partition-key hidden column stays unique per branch';
select /*+ recompile */ cat, grp, sum(val), sum(sum(val)) over (partition by cat order by grp) as rt
from tp group by cat, grp
union all
select cat, grp, sum(val), sum(sum(val)) over (partition by cat order by grp) as rt
from tq group by cat, grp
order by 1, 2, 3, 4;
show trace;
-- expect (order by 1,2,3,4):
-- A g1 5 5
-- A g1 30 30
-- A g2 30 60
-- B g1 100 100
-- B g2 7 7
-- B g2 250 350

evaluate 'Case A2: two PARTITION BY window functions in the same branch (row_number, rank) -> each partition window gets its own unique hidden columns';
select /*+ recompile */ cat, grp, sum(val) as s,
row_number() over (partition by cat order by sum(val), grp) as rn,
rank() over (partition by cat order by sum(val) desc, grp) as rk
from tp group by cat, grp
union all
select cat, grp, sum(val) as s,
row_number() over (partition by cat order by sum(val), grp) as rn,
rank() over (partition by cat order by sum(val) desc, grp) as rk
from tq group by cat, grp
order by 1, 2, 3, 4, 5;
show trace;
-- expect (order by 1,2,3,4,5):
-- A g1 5 1 1
-- A g1 30 1 1
-- A g2 30 2 2
-- B g1 100 1 2
-- B g2 7 1 1
-- B g2 250 2 1

evaluate 'Case A3: PARTITION BY window combined via INTERSECT -> partition-key hidden columns unique across set-op branches';
select /*+ recompile */ cat, grp, sum(val), sum(sum(val)) over (partition by cat order by grp) as rt
from tp group by cat, grp
intersect
select cat, grp, sum(val), sum(sum(val)) over (partition by cat order by grp) as rt
from tp where cat = 'A' group by cat, grp
order by 1, 2, 3;
show trace;
-- 두 branch 는 실제로 다르다(2번째는 cat='A' 만) -> 실질 교집합.
-- A 파티션 행은 cat='A' 필터로도 rt 가 동일해 교집합에 남고, B 행은 빠진다.
-- expect:
-- A g1 30 30
-- A g2 30 60

drop table if exists tp, tq;

@kiho-um

kiho-um commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

추가 시나리오 제안합니다.

기존 TC 의 OVER 절은 전부 (ORDER BY ...) 뿐이라 PARTITION BY 가 0건. PARTITION BY 는 파티션 키를 derived 재작성의 추가 hidden 컬럼 으로 만들므로, hidden 컬럼 유니크성 검증면을 직접 넓힌다.

drop table if exists tp, tq; create table tp (id int primary key, cat varchar(10), grp varchar(10), val int); create table tq (id int primary key, cat varchar(10), grp varchar(10), val int);

-- tp: cat 2개(A,B) × grp 로 (cat,grp) 그룹이 파티션 안에 여러 개 생기게 둔다 insert into tp values (1,'A','g1',10),(2,'A','g1',20),(3,'A','g2',30), (4,'B','g1',100),(5,'B','g2',200),(6,'B','g2',50); insert into tq values (1,'A','g1',5),(2,'B','g2',7); commit;

-- (cat,grp) 그룹합: A/g1=30, A/g2=30, B/g1=100, B/g2=250 | tq: A/g1=5, B/g2=7 -- partition by cat, order by grp 누적: -- A: g1->30, g2->60 | B: g1->100, g2->350 | tq A: g1->5 tq B: g2->7

evaluate 'Case A1: PARTITION BY window in two UNION ALL branches -> partition-key hidden column stays unique per branch'; select /*+ recompile */ cat, grp, sum(val), sum(sum(val)) over (partition by cat order by grp) as rt from tp group by cat, grp union all select cat, grp, sum(val), sum(sum(val)) over (partition by cat order by grp) as rt from tq group by cat, grp order by 1, 2, 3, 4; show trace; -- expect (order by 1,2,3,4): -- A g1 5 5 -- A g1 30 30 -- A g2 30 60 -- B g1 100 100 -- B g2 7 7 -- B g2 250 350

evaluate 'Case A2: two PARTITION BY window functions in the same branch (row_number, rank) -> each partition window gets its own unique hidden columns'; select /*+ recompile */ cat, grp, sum(val) as s, row_number() over (partition by cat order by sum(val), grp) as rn, rank() over (partition by cat order by sum(val) desc, grp) as rk from tp group by cat, grp union all select cat, grp, sum(val) as s, row_number() over (partition by cat order by sum(val), grp) as rn, rank() over (partition by cat order by sum(val) desc, grp) as rk from tq group by cat, grp order by 1, 2, 3, 4, 5; show trace; -- expect (order by 1,2,3,4,5): -- A g1 5 1 1 -- A g1 30 1 1 -- A g2 30 2 2 -- B g1 100 1 2 -- B g2 7 1 1 -- B g2 250 2 1

evaluate 'Case A3: PARTITION BY window combined via INTERSECT -> partition-key hidden columns unique across set-op branches'; select /*+ recompile */ cat, grp, sum(val), sum(sum(val)) over (partition by cat order by grp) as rt from tp group by cat, grp intersect select cat, grp, sum(val), sum(sum(val)) over (partition by cat order by grp) as rt from tp where cat = 'A' group by cat, grp order by 1, 2, 3; show trace; -- 두 branch 는 실제로 다르다(2번째는 cat='A' 만) -> 실질 교집합. -- A 파티션 행은 cat='A' 필터로도 rt 가 동일해 교집합에 남고, B 행은 빠진다. -- expect: -- A g1 30 30 -- A g2 30 60

drop table if exists tp, tq;

[답변]
시나리오 3개 추가 반영 했습니다.

@kiho-um
kiho-um merged commit 25e6364 into CUBRID:develop Aug 27, 2026
kiho-um added a commit to kiho-um/cubrid-testcases that referenced this pull request Aug 31, 2026
…ndow function corrupti… (CUBRID#3314)

http://jira.cubrid.org/browse/CBRD-27158

Purpose
GROUP BY + 집계 + 윈도우 함수 + ORDER BY 쿼리가 집합 연산(UNION/INTERSECT/EXCEPT)에 포함될 때
결과 행이 깨지는 문제 (CUBRID/cubrid#7607). mq_rewrite_aggregate_as_derived에서 만드는
히든 derived 컬럼명이 unique하지 않아 발생.

기존 TC 수정(PR CUBRID#3190, develop 머지 완료 / PR CUBRID#3296, release/11.4 백포트 완료)은
CUBRID 고유 pseudocolumn(rownum, orderby_num(), groupby_num(), inst_num())과
GROUP BY/집합연산 조합만 커버했고, 실제 ANSI 윈도우 함수(OVER절)를 사용하는 시나리오는
검증되지 않았습니다. 이 TC는 그 공백을 메우기 위한 신규 전용 테스트입니다.

Implementation
Case 1~6 (최초 커버리지)

Case 12: UNION ALL 두/한 분기에서 윈도우 함수 히든 컬럼 유니크성
Case 34: INTERSECT/EXCEPT에도 동일 fix 적용 확인
Case 5: 3-way UNION ALL
Case 6: 집합연산 전체 결과에 대한 바깥 ORDER BY
Case 7~8 (원본 Jira 재현 쿼리, 리뷰 요청으로 추가)

Case 7: 원본 리포트의 재현 쿼리(repro_setop_t2/t3, 분기 자체에 ORDER BY) standalone 버전
Case 8: Case 7을 UNION으로 묶은 버전 — 원본 이슈가 실제로 보고된 그 모양
Case 9~16 (리뷰어 bagus-kim 제안 커버리지 확장)

Case 9/10: 식 기준 ORDER BY(ca+1)로 만들어지는 히든 컬럼
Case 11/12: 같은 분기에 식 기준 ORDER BY 키 2개
Case 13/14: 분기 ORDER BY + LIMIT 조합
Case 15/16: 같은 분기에 윈도우 함수 2개 + 분기 ORDER BY
각 7~16 케이스는 "정상값 확인용 standalone" → "그 값이 UNION에서도 안 깨지는지 확인" 순서로 짝을 이룹니다.

리뷰 대응 수정 및 추가사항

Case 1~5: 집합연산 결과에 명시적 order by 추가 (병렬 워커로 인한 순서 비보장 리스크 제거)
Case 2: row_number()/rank()에 grp 타이브레이크 추가 (동점 시 비결정적이었던 문제 수정)
Case 3(INTERSECT)/Case 4(EXCEPT): 두 번째 분기를 실제로 다르게 만들어서 진짜 필터링이 일어나도록 수정 (기존엔 아무것도 안 걸러지고 있었음)
Case 17: PARTITION BY 윈도우(카테고리별 누적합)를 UNION ALL 두 분기에서 — 분기별 파티션 키 히든 컬럼이 유니크한지
Case 18: 한 분기 안에 PARTITION BY 윈도우 함수 2개(row_number(), rank()) — 각 파티션 윈도우가 서로 다른 히든 컬럼을 갖는지
Case 19: Case 17 패턴을 INTERSECT로 — 두 번째 분기를 cat='A'로 실제로 다르게 만들어서 집합연산에서도 파티션 키 히든 컬럼이 유니크한지

Remarks
CUBRID 11.5.0(develop, 여러 빌드)에서 16개 케이스 전부 실행 검증 완료.
greptile-apps 자동 리뷰 2건 중 P1(순서 미보장)은 반영, P2(마스킹된 히든 이름)는 실제 결과값 비교로 충분히 커버된다고 판단해 별도 조치 없음.
bagus-kim님 리뷰 코멘트 전부 반영 완료 (인라인 2건 + 일반 코멘트 Case 7~11 제안 전부).
ssihil님 리뷰 코멘트 제안 — PARTITION BY 커버리지, Case 17~19) 3건 반영 완료
kiho-um added a commit that referenced this pull request Sep 1, 2026
…e answer for 11.4's leaner trace output (#3391)

* [CBRD-27158] Add new test case for add SQL testcase for GROUP BY + window function corrupti… (#3314)

http://jira.cubrid.org/browse/CBRD-27158

Purpose
GROUP BY + 집계 + 윈도우 함수 + ORDER BY 쿼리가 집합 연산(UNION/INTERSECT/EXCEPT)에 포함될 때
결과 행이 깨지는 문제 (CUBRID/cubrid#7607). mq_rewrite_aggregate_as_derived에서 만드는
히든 derived 컬럼명이 unique하지 않아 발생.

기존 TC 수정(PR #3190, develop 머지 완료 / PR #3296, release/11.4 백포트 완료)은
CUBRID 고유 pseudocolumn(rownum, orderby_num(), groupby_num(), inst_num())과
GROUP BY/집합연산 조합만 커버했고, 실제 ANSI 윈도우 함수(OVER절)를 사용하는 시나리오는
검증되지 않았습니다. 이 TC는 그 공백을 메우기 위한 신규 전용 테스트입니다.

Implementation
Case 1~6 (최초 커버리지)

Case 12: UNION ALL 두/한 분기에서 윈도우 함수 히든 컬럼 유니크성
Case 34: INTERSECT/EXCEPT에도 동일 fix 적용 확인
Case 5: 3-way UNION ALL
Case 6: 집합연산 전체 결과에 대한 바깥 ORDER BY
Case 7~8 (원본 Jira 재현 쿼리, 리뷰 요청으로 추가)

Case 7: 원본 리포트의 재현 쿼리(repro_setop_t2/t3, 분기 자체에 ORDER BY) standalone 버전
Case 8: Case 7을 UNION으로 묶은 버전 — 원본 이슈가 실제로 보고된 그 모양
Case 9~16 (리뷰어 bagus-kim 제안 커버리지 확장)

Case 9/10: 식 기준 ORDER BY(ca+1)로 만들어지는 히든 컬럼
Case 11/12: 같은 분기에 식 기준 ORDER BY 키 2개
Case 13/14: 분기 ORDER BY + LIMIT 조합
Case 15/16: 같은 분기에 윈도우 함수 2개 + 분기 ORDER BY
각 7~16 케이스는 "정상값 확인용 standalone" → "그 값이 UNION에서도 안 깨지는지 확인" 순서로 짝을 이룹니다.

리뷰 대응 수정 및 추가사항

Case 1~5: 집합연산 결과에 명시적 order by 추가 (병렬 워커로 인한 순서 비보장 리스크 제거)
Case 2: row_number()/rank()에 grp 타이브레이크 추가 (동점 시 비결정적이었던 문제 수정)
Case 3(INTERSECT)/Case 4(EXCEPT): 두 번째 분기를 실제로 다르게 만들어서 진짜 필터링이 일어나도록 수정 (기존엔 아무것도 안 걸러지고 있었음)
Case 17: PARTITION BY 윈도우(카테고리별 누적합)를 UNION ALL 두 분기에서 — 분기별 파티션 키 히든 컬럼이 유니크한지
Case 18: 한 분기 안에 PARTITION BY 윈도우 함수 2개(row_number(), rank()) — 각 파티션 윈도우가 서로 다른 히든 컬럼을 갖는지
Case 19: Case 17 패턴을 INTERSECT로 — 두 번째 분기를 cat='A'로 실제로 다르게 만들어서 집합연산에서도 파티션 키 히든 컬럼이 유니크한지

Remarks
CUBRID 11.5.0(develop, 여러 빌드)에서 16개 케이스 전부 실행 검증 완료.
greptile-apps 자동 리뷰 2건 중 P1(순서 미보장)은 반영, P2(마스킹된 히든 이름)는 실제 결과값 비교로 충분히 커버된다고 판단해 별도 조치 없음.
bagus-kim님 리뷰 코멘트 전부 반영 완료 (인라인 2건 + 일반 코멘트 Case 7~11 제안 전부).
ssihil님 리뷰 코멘트 제안 — PARTITION BY 커버리지, Case 17~19) 3건 반영 완료

* [CBRD-27158-11.4] Backport from develop to 11.4 - fix query plan trace answer for 11.4's leaner trace output
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants