[CBRD-26572] add SQL function 'UUID'#6873
Conversation
: arg (int) : returns bit(128) : support UUIDv4 / UUIDv7 : uuid(7) = UUIDv7 : uuid(), uuid(4), uuid( int ) = UUIDv4
| case PT_SYS_GUID: | ||
| /* | ||
| * constant folding for this expression is never performed : is always resolved on server | ||
| * PT_SYS_GUID and PT_UUID can be used as an attribute's default function | ||
| * We must perform a semantic check to ensure that the attribute domain and the default function type are compatible. | ||
| * During semantic checking, flag.do_not_fold is not considered; therefore, a dummy value is returned. | ||
| * Any PT_EXPR that contains PT_SYS_GUID or PT_UUID must always have flag.do_not_fold set to true. | ||
| */ | ||
| db_make_string (result, "0123456789ABCDEF0123456789ABCDEF"); | ||
| return 1; | ||
| case PT_UUID: | ||
| db_make_bit (result, GUID_STANDARD_BYTES_LENGTH * 8, "0123456789ABCDEF", GUID_STANDARD_BYTES_LENGTH * 8); | ||
| return 1; |
There was a problem hiding this comment.
해당 코드는 DEFAULT 지원 시 필요합니다.
더미 데이터로 UUID 및 SYS_GUID를 수행하여 column type과 function return domain의 호환을 확인합니다.
더미 데이터의 값이 조회될 경우는 없습니다.
There was a problem hiding this comment.
Pull request overview
Adds a new SQL built-in function UUID to generate UUID values as BIT(128), with support for UUIDv4 (random) and UUIDv7 (time-ordered) and statement-level monotonic behavior for v7.
Changes:
- Introduces
UUIDparsing/type-checking and execution paths, including new arithmetic opcodes for UUIDv4/UUIDv7. - Implements UUID generation helpers (UUIDv4 hex for
SYS_GUID()compatibility; UUIDv4/v7 binary forUUID()). - Extends query execution state to carry millisecond epoch time and adds per-thread UUIDv7 monotonic state.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/thread/thread_entry.hpp | Adds per-thread UUIDv7 monotonic state + inline accessors. |
| src/thread/thread_entry.cpp | Initializes UUIDv7 per-thread state in thread entry constructor. |
| src/storage/storage_common.h | Adds new opcode identifiers T_UUID4 / T_UUID7. |
| src/query/string_opfunc.h | Adds UUID version enum/constants and new UUID function declarations. |
| src/query/string_opfunc.c | Implements UUIDv4 (hex) and UUID(v4/v7) binary generation helpers. |
| src/query/query_executor.h | Adds sys_epochtime_ms to val_descr for UUIDv7 epoch ms precision. |
| src/query/query_executor.c | Initializes/copies sys_epochtime_ms in XASL state. |
| src/query/fetch.c | Executes new UUID opcodes and routes SYS_GUID to db_uuidv4. |
| src/parser/xasl_generation.c | Generates regu vars for UUID() / UUID(int) and adds semantic error for unsupported literal versions. |
| src/parser/type_checking.c | Adds overload/type rules for UUID and domain precision for BIT(128). |
| src/parser/parser_message.h | Adds message id for unsupported UUID versions. |
| src/parser/parse_tree_cl.c | Adds printing support for uuid(...) and opcode name mapping. |
| src/parser/parse_tree.h | Adds PT_UUID node/operator plumbing. |
| src/parser/keyword.c | Registers uuid as a function keyword. |
| src/parser/csql_grammar.y | Parses UUID function with 0 or 1 argument and disables caching/folding. |
| src/optimizer/query_graph.c | Marks UUID as a heavy expression for ranking. |
| msg/ko_KR.utf8/cubrid.msg | Adds Korean semantic error message for unsupported UUID versions. |
| msg/en_US.utf8/cubrid.msg | Adds English semantic error message for unsupported UUID versions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
UUID 함수의 인자값으로 컬럼을 받을 수 없는 문제가 있어 해결 후 다시 open하도록 하겠습니다. |
| T_UUID, | ||
| T_UUID4, | ||
| T_UUID7, |
There was a problem hiding this comment.
T_UUID4, T_UUID7은 컬럼을 인자로 받기 위해 T_UUID로 통합되었기에 당장 사용되지는 않습니다.
하지만 DEFAULT 지원 시 필요할 수 있어 우선 남겨두고자 합니다.
현재 default 함수는 to_char를 제외하면 인자값을 허용하지 않습니다.
이를 우회하기 위해 default 지정 시 T_UUID4, T_UUID7을 사용하는 방식을 고려하고 있습니다.
(default에선 컬럼이 인자로 올 수 없습니다.)
There was a problem hiding this comment.
언제쯤 필요하게 될까요?
추후 작업을 위해 미리 넣어 두는 것이라면 #ifdef 등으로 묶어 두는 것은 어떤가요?
There was a problem hiding this comment.
default 처리 PR은 곧 진행해야 할 것 같으니, 그냥 두어도 괜찮을 듯 합니다.
There was a problem hiding this comment.
PR 순서로 UUID_FORMAT -> SYS_GUID DEFAULT & UUID DEFAULT 를 생각하고 있습니다.
|
/run all |
|
/run all |
|
/run all |
|
test_sql 실패는 develop merge 시 해결되는 케이스입니다. |
|
|
|
Last reviewed commit: 2f7281e |
|
Last reviewed commit: 36877ca |
SymbolStack.java 파일에 함수명을 추가하였으나 실행은 할 수 없습니다. PL/CSQL에서 bit 타입은 지원하지 않으며 return 타입이 bit 형 이기 때문에 다음과 같이 실행불가한 상태입니다. |
|
Last reviewed commit: e49130e |
|
Last reviewed commit: 46a902b |
| T_UUID, | ||
| T_UUID4, | ||
| T_UUID7, | ||
| T_UUID_FORMAT, |
There was a problem hiding this comment.
T_UUID4, T_UUID7 — XASL 생성 경로가 없는 데드 코드(Dead Code)
T_UUID4와 T_UUID7가 OPERATOR_TYPE enum에 추가되고 fetch.c에도 case 핸들러가 구현되어 있습니다. 그러나 xasl_generation.c에서 PT_UUID를 변환할 때는 오직 T_UUID만 생성됩니다:
case PT_UUID:
regu = pt_make_regu_arith (r1, r2, NULL, T_UUID, domain); // T_UUID4/T_UUID7는 생성 안됨
break;즉, 런타임에 T_UUID4나 T_UUID7 opcode가 실행될 경로가 존재하지 않습니다. 이로 인해 발생하는 문제:
- XASL 직렬화 호환성 리스크:
OPERATOR_TYPEenum에 새 값이 삽입되면, 이후 모든 enum 값이 shift됩니다. XASL 플랜 캐시 등 enum 값을 직렬화하는 경로에서T_SLEEP이후 opcode들의 값이 변경되어 기존 캐시와의 호환성 문제가 생길 수 있습니다. - 유지보수 혼란: 실제로 실행되지 않는 코드 경로가 존재하면 향후 리팩토링 시 혼란을 야기합니다.
이 PR에서 실제로 사용하지 않을 예정이라면 T_UUID4, T_UUID7을 enum과 fetch.c에서 제거하는 것을 권장합니다.
There was a problem hiding this comment.
default 에서 사용할 수 도 있어 추후 PR에서 판단할 예정입니다.
| } | ||
|
|
||
| /* Save updated state back to thread */ | ||
| thread_set_uuidv7_state (thread_p, last_ms, seq); | ||
|
|
||
| /* Generate random bytes for the lower part (bytes 7-15) */ | ||
| error_code = crypt_generate_random_bytes ((char *) (out_bytes + 7), GUID_STANDARD_BYTES_LENGTH - 7); | ||
| if (error_code != NO_ERROR) | ||
| { | ||
| return error_code; | ||
| } |
There was a problem hiding this comment.
UUIDv7 스레드 상태 업데이트 순서 — 오류 발생 시 시퀀스 소모 문제
thread_set_uuidv7_state 호출이 crypt_generate_random_bytes 호출보다 먼저 이루어지고 있습니다:
/* Save updated state back to thread */
thread_set_uuidv7_state (thread_p, last_ms, seq); // ← 상태 먼저 커밋
/* Generate random bytes for the lower part (bytes 7-15) */
error_code = crypt_generate_random_bytes (...);
if (error_code != NO_ERROR)
{
return error_code; // ← 이미 상태는 진행된 상태
}crypt_generate_random_bytes가 실패하면, UUID는 실제로 생성되지 않았음에도 불구하고 thread_p->uuidv7_last_ms와 thread_p->uuidv7_seq는 이미 증가한 상태로 남습니다. 이후 정상적인 재시도 시 시퀀스 번호가 불필요하게 소모됩니다.
crypt_generate_random_bytes가 일상적으로 실패하는 케이스는 드물지만, 고부하 환경이나 RNG 초기화 실패 상황에서는 연속적인 오류 시 시퀀스가 빠르게 소모될 수 있습니다. 상태 업데이트를 성공 확인 이후로 이동하는 것이 더 견고한 설계입니다:
/* Generate random bytes first, THEN commit state */
error_code = crypt_generate_random_bytes ((char *) (out_bytes + 7), GUID_STANDARD_BYTES_LENGTH - 7);
if (error_code != NO_ERROR)
{
return error_code;
}
/* Save updated state back to thread only on success */
thread_set_uuidv7_state (thread_p, last_ms, seq);There was a problem hiding this comment.
실패한다면 해당 statement가 취소될 것이기에 불필요한 염려라고 생각합니다.
| || node->info.expr.op == PT_DECRYPT || node->info.expr.op == PT_BIN | ||
| || node->info.expr.op == PT_MD5 || node->info.expr.op == PT_SHA_ONE | ||
| || node->info.expr.op == PT_SPACE || node->info.expr.op == PT_PRIOR | ||
| || node->info.expr.op == PT_UUID_FORMAT || node->info.expr.op == PT_UUID |
There was a problem hiding this comment.
PT_UUID_FORMAT이 unary-style op 목록 조건에 포함되어 있습니다. 하지만:
csql_grammar.y에uuid_format()SQL 문법 규칙이 없어서 파서 단에서 생성되지 않습니다.- 이 블록 이후의
case PT_UUID_FORMAT:XASL 생성 코드가 없어, 만약 도달한다면 오류가 됩니다. fetch.c에서는#if 0으로 비활성화되어 있습니다.
fetch.c에서 #if 0으로 격리된 것과 동일하게, 이 조건에서도 PT_UUID_FORMAT을 제거하거나 #if 0으로 감싸는 것이 코드 일관성 측면에서 바람직합니다:
| || node->info.expr.op == PT_UUID_FORMAT || node->info.expr.op == PT_UUID | |
| || node->info.expr.op == PT_UUID |
There was a problem hiding this comment.
default에서 판단할 예정입니다.
|
✅ TC Branch Finalized for Engine PR was merged. Cleanup Results: TC develop branch is ready for the next PR. |
|
✅ TC Branch Finalized for Engine PR was merged. Cleanup Results: TC develop branch is ready for the next PR. |
http://jira.cubrid.org/browse/CBRD-26572
http://jira.cubrid.org/browse/CBRD-26573
Purpose
Implementation
Remarks