Skip to content

Conversation

@jongmin-won
Copy link
Contributor

@jongmin-won jongmin-won commented Sep 25, 2025

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

Purpose

기존 Fixed NUMERIC 타입에는 다음과 같은 제약이 있습니다.

  1. 표현 가능한 자릿수가 최대 38자리로 제한됨
  2. Precision과 Scale을 고정값으로 지정해야 함

이러한 제약을 개선하기 위해 Scale 범위 확장과 Precision/Scale 미지정 시 Floating-Point NUMERIC 타입 지원을 단계적으로 구현합니다.


Phase-1. Fixed NUMERIC의 최대 범위 및 scale 범위 확장 (1/2) : #6385

1) Fixed NUMERIC의 최대 범위 및 scale 범위 확장

  • 지수 표현 : 1.0 * 10^−127 <= |Value| < 1.0 * 10^122
numeric(p,s)
  • p (precision): 유효 자릿수.
    • 가장 왼쪽의 0이 아닌 숫자부터 가장 오른쪽 유효 숫자까지의 자릿수
    • 범위 : 1 ~ 38
    • 16바이트 base-256 정밀도로, 최대 38자리 십진수 표현 가능.
  • s (scale): 소수점 기준 소수부 자릿수.
    • 범위 : -84 ~ 127
    • 음수 scale은 소수점 왼쪽에서 반올림 단위를 지정

2) 리터럴 값 NUMERIC Parsing 로직 수정

  • 정수부와 소수부를 분리하여 파싱
  • Oracle 방식 처럼 Precision, Scale을 일관되게 해석
    • precision : 가장 왼쪽의 0이 아닌 숫자부터 가장 오른쪽 유효 숫자까지의 자릿수
    • scale : 소수점 기준으로, 소수부의 시작부터 가장 오른쪽 유효 숫자까지의 자릿수
  • 최대 유효 숫자를 초과할 경우 반올림 처리
  • Trailing Zero 제거는 수행하지 않고 기존 동작을 유지

3) NUMERIC 최대 범위 확장 (Phase-1 에서 범위만 확장 했으며, 해당 구현은 Phase-3 에서 정상 동작 예정)

  • 지수 표현 : 1.0 * 10^-252 <= |Value| < 1.0 * 10^254
  • Precision : 1 <= prec <= 43
  • Scale : -211 <= scale <= 252

Phase-1. Scale 범위 확장에 따른 산술 연산 및 내장 함수 수정 (2/2) : #6520

  • Scale 범위(Fixed Numeric) 및 NUMERIC 범위 확장에 따라 산술 연산 및 내장 함수가 수정 됩니다.

1) 산술 연산

1-1) 추가
  • DB_TYPE_NUMERIC을 대상으로 하는 신규 연산 함수를 추가함.
1-2) 수정
  • 기존 연산 함수는 Serial, DB_TYPE_SHORT, DB_TYPE_INTEGER, DB_TYPE_BIGINT 타입에 대해 사용되도록 정리함.

2) 비교 연산

2-1) 추가
  • 확장된 scale 범위를 지원할 수 있도록 fp_numeric_compare 함수를 새로 도입함.

3) NUMERIC 매핑(lookup) 테이블 확장

  • Fixed Numeric: precision overflow 확인용으로 사용.
  • Float Numeric: db_value 내부 데이터에서 precision(유효 자릿수)을 직접 계산하기 위해 사용.
  • 매핑 테이블 구조 : powers_of_10[10^n][10^n 값을 base-256으로 변환한 바이트 값]
  • AS-IS
- 최대 지수 (10^n) : (TWICE_NUM_MAX_PREC + 1) = 76 + 1 = 77

- 10^n 값을 base-256으로 변환한 바이트 값 : DB_NUMERIC_BUF_SIZE = 16
  • TO-BE
- 최대 지수 (10^n, POW10_MAX_INDEX)
(((DB_MAX_NUMERIC_PRECISION - DB_MIN_NUMERIC_SCALE) + DB_MAX_NUMERIC_SCALE) + 6)
= ((43 - (-211)) + 252) + 6 = 506 + 6
= 512

- 10^n 값을 base-256으로 변환한 바이트 값 (POW10_BUF_SIZE)
floor(POW10_MAX_INDEX * log256(10)) + 1
= floor(512 * 0.41524...) + 1 = 212 + 1
= 213
  • 유효 바이트 index : _gv_powers_of_10_significant_bytes[POW10_BUF_SIZE]
    • 매핑 테이블 접근을 위한 보조 인덱스로 사용됨.
value buffer 내에서 "0이 아닌 첫 번째 유효 바이트" 를 찾고
-> 해당 위치에 대응하는 index 값을 _gv_powers_of_10_significant_bytes에서 가져온 뒤
-> powers_of_10 테이블에서 precision 계산에 활용함.

4) 내장 함수

4-1) 추가
  • MOD()
    • 기존 : double 기반 계산 후 출력
    • 변경 : numeric 기반 계산 후 출력
4-2) 수정
  • abs(), round(), trunc(), floor(), ceil(), width_bucket()
    • 확장된 scale 범위를 모두 처리할 수 있도록 수정함.
  • typeof()
    • 음수 scale 출력
    • precision/scale이 default일 경우에는 단순히 NUMERIC만 출력하도록 변경
  • to_number()
    • format 범위 확장 (-211 ~ 15)
    • 양수 scale은 기존과 동일하게 최대 15까지 유지

Phase-2. NUMERIC 저장 방식 개선 : #6623

  • TODO

Implementation

N/A

Remarks

N/A

jongmin-won and others added 2 commits September 25, 2025 12:41
http://jira.cubrid.org/browse/CBRD-26243

Purpose
1. Extension of the maximum NUMERIC range
- Exponential form: 1.0 * 10^-252 <= |Value| < 1.0 * 10^254
- Precision: 1 <= prec <= 43
- Scale: -211 <= scale <= 252

2. Extension of the maximum range and scale for Fixed NUMERIC
- Exponential form: 1.0 * 10^-127 <= |Value| < 1.0 * 10^122
- Precision: 1 <= prec <= 38
- Scale: -84 <= scale <= 127

3. Modification of NUMERIC literal parsing logic
- Parse integer and fractional parts separately
- Interpret precision and scale consistently, following Oracle’s approach
- Apply rounding when the maximum number of significant digits is exceeded
- Do not remove trailing zeros; behavior remains the same as before

Remarks
1. In Numeric parsing, DB_MAX_NUMERIC_PRECISION(43) is temporarily replaced with phase_1_tmp_max_prec(38).
- Currently (Phase-1), only the maximum range extension of NUMERIC has been applied. Using DB_MAX_NUMERIC_PRECISION(43) as is would not work correctly.
- Therefore, the full NUMERIC range (43, -211) is not yet supported. Only values within 1 <= prec <= 38 and -84 <= scale <= 127 are guaranteed to work properly.
@jongmin-won jongmin-won self-assigned this Sep 25, 2025
@jongmin-won jongmin-won changed the title Feature/scale range fp numeric [CBRD-26006] Scale Range Expansion and Floating-Point NUMERIC Type Support Sep 25, 2025
jongmin-won and others added 5 commits November 6, 2025 17:46
…odified for extended scale range (2/2) (#6520)

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

Arithmetic Operations and Built-in Function Updates Following Scale (Fixed Numeric) and NUMERIC Range Expansion

1. Arithmetic Operations
1-1. Added
- New arithmetic functions are used for DB_TYPE_NUMERIC.
- Functions: fp_numeric_db_value_(add, sub, mul, div)

1-2. Modified
- Existing arithmetic functions are used for Serial, DB_TYPE_SHORT, DB_TYPE_INTEGER, and DB_TYPE_BIGINT.
- Functions: numeric_db_value_(add, sub, mul, div)

2. NUMERIC Mapping Table Expansion
- Fixed Numeric: Used to check precision overflow.
- FP Numeric: Used to calculate precision (significant digits) directly from db_value data.

3. Comparison Operations
- Added fp_numeric_compare() to support comparison up to the expanded scale range.

4. Built-in Functions
4-1. Added
1) MOD()
- Previous: Calculated using double precision and returned as a double value.
- Changed: Uses fp_numeric and returns a Numeric value (Improved precision, available only for DB_TYPE_NUMERIC).

4-2. Modified
1) abs(), round(), trunc() 
- Buffer expanded for base-256 -> decimal string conversion.

2) typeof()
- Negative scale output supported.
- When precision = DB_MAX_NUMERIC_PRECISION, omit precision/scale and display only NUMERIC (to be verified in Phase-3).

3) floor(), ceil()
- Fixed overflow when scale > 38 during conversion from decimal string to base-256.

4) WIDTH_BUCKET()
- Core dump for values >= 39 digits -> replaced sub/div operations with fp_sub/fp_div.

5) MIN(), MAX()
- Fixed scale overgrowth in PT_TYPE_NUMERIC domain calculation.

6) TO_NUMBER()
- Extended format range.
- The previous scale limit (0–15) had no clear reason.
- Although extension beyond 15 was considered, the upper bound remains 15 to avoid potential side effects.
http://jira.cubrid.org/browse/CBRD-26367

In the previous (develop) version, Fixed Numeric values were always stored using a fixed 16-byte layout.
With this update, they are now stored using a variable-length format depending on their precision.

For Floating Numeric values, the precision at input time cannot be determined in advance,
so they are always stored using the maximum size: 20 bytes (2-byte header + 18-byte data for precision 43).
- Header: 2 bytes
- Data area for precision 43: 18 bytes
- Total size: 20 bytes

1. DB_MAX_NUMERIC_PRECISION Increased
- The maximum precision has been expanded from 38 digits to 43 digits.

2. Numeric Rounding Rule Updated
- Until phase-1, values exceeding 38 digits were rounded at the 39th digit.
- Starting from phase-2, rounding is performed at the 44th digit when exceeding 43 digits.

3. Fixed Numeric Storage Changed from Fixed to Variable Length
- Previously, Fixed Numeric values were always stored in a 16-byte fixed format.
- They are now stored using a variable-length format based on the precision value.
- Length calculation:
  - log10(256) = 2.40824
  - byte = ceil(precision / log10(256))
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.

2 participants