merge 6.0.0 into 6.0.0

【回合6.0.0】fix ecpg decdiv/decmul numeric to decimal overflow error & add Test

Created-by: wangzhengyuan1
Commit-by: zhang-wenzuo
Merged-by: opengauss_bot
Description: 【标题】(请简要描述下实现的内容)

【实现内容】:见链接
https://gitcode.com/opengauss/openGauss-server/pull/8025
https://gitcode.com/opengauss/openGauss-server/pull/8056
https://gitcode.com/opengauss/openGauss-server/pull/8083
【根因分析】:

【实现方案】:

【关联需求或issue】:
https://gitcode.com/opengauss/openGauss-server/issues/7291
【开发自验报告】:
1. 请附上自验结果(内容或者截图)
2. 是否可以添加fastcheck测试用例,如是,请补充fastcheck用例
3. 是否涉及资料修改,如是,在docs仓库补充资料
4. 是否考虑升级场景(系统表修改、日志持久化以及修改执行态数据格式)
5. 是否考虑在线扩容等扩展场景
6. 是否考虑异常场景/并发场景/前向兼容/性能场景
7. 是否对其他模块产生影响
8. 是否需要回合补丁版本(5.0、6.0),涉及(**结果错误|coredump|性能劣化|内存泄露|集群异常**)相关修复请排查回合补丁分支

【其他说明】:

See merge request: opengauss/openGauss-server!8317
This commit is contained in:
opengauss_bot
2025-08-27 10:54:40 +08:00
5 changed files with 135 additions and 0 deletions

View File

@ -930,6 +930,13 @@ static int select_div_scale(numeric* var1, numeric* var2, int* rscale)
return res_dscale;
}
static void Initial_Numeric_Local(numeric *var1)
{
int idx;
int total = sizeof(var1->local)/sizeof(var1->local[0]);
for (idx = 0; idx < total; idx++) { var1->local[idx] = 0; }
}
int PGTYPESnumeric_div(numeric* var1, numeric* var2, numeric* result)
{
NumericDigit* res_digits = NULL;
@ -986,9 +993,13 @@ int PGTYPESnumeric_div(numeric* var1, numeric* var2, numeric* result)
/*
* Initialize local variables
*/
Initial_Numeric_Local(&dividend);
init_numeric(&dividend);
for (i = 1; i < 10; i++) {
Initial_Numeric_Local(&divisor[i]);
init_numeric(&divisor[i]);
divisor[i].buf = NULL;
}
/*
@ -1383,11 +1394,59 @@ int PGTYPESnumeric_to_long(numeric* nv, long* lp)
return 0;
}
static bool get_decimal_from_overflow_numeric(numeric* src, decimal* dst)
{
bool result = false;
int radix = 10;
if (src->sign == NUMERIC_NAN) {
/* this should not happen actually */
src->ndigits = DECSIZE;
} else {
/* we must round up before convert the value */
int total = src->dscale + src->weight + 1;
if (total >= 0) {
int size = DECSIZE;
int carry = (src->digits[size] > 4) ? 1 : 0;
src->ndigits = DECSIZE;
while (carry) {
carry += src->digits[--size];
src->digits[size] = carry % radix;
carry /= radix;
}
if (size < 0) {
src->digits--;
src->weight++;
}
} else {
src->ndigits = Max(0, Min(total, DECSIZE));
}
}
if (src->ndigits == DECSIZE) {
dst->weight = src->weight;
dst->rscale = src->rscale;
dst->dscale = src->dscale;
dst->sign = src->sign;
dst->ndigits = src->ndigits;
for (int i = 0; i < src->ndigits; i++)
dst->digits[i] = src->digits[i];
result = true;
}
return result;
}
int PGTYPESnumeric_to_decimal(numeric* src, decimal* dst)
{
int i;
if (src->ndigits > DECSIZE) {
get_decimal_from_overflow_numeric(src, dst);
errno = PGTYPES_NUM_OVERFLOW;
return -1;
}

View File

@ -206,6 +206,32 @@ main(void)
}
free(decarr);
char* desc[] = {"43920000.0000000000000000000000", "53920000.0000000000000000000000", "720.0"};
decimal* dDqlx = PGTYPESdecimal_new();
decimal* dJcjxts = PGTYPESdecimal_new();
decimal* dtmp = PGTYPESdecimal_new();
int retdecdiv = 0;
int index = 0;
int breakTime = 3;
while (index < breakTime) {
char* number1 = desc[index];
char* number2 = "360.0";
retdecdiv = deccvasc(number1, strlen(number1), dDqlx);
retdecdiv = deccvasc(number2, strlen(number2), dJcjxts);
char printStr[60];
dectoasc(dDqlx, printStr, sizeof(printStr) - 1, -1);
printf("dDqlx = [%s]\n", printStr);
dectoasc(dJcjxts, printStr, sizeof(printStr) - 1, -1);
printf("dJcjxts = [%s]\n", printStr);
retdecdiv = decdiv(dDqlx, dJcjxts, dtmp);
dectoasc(dtmp, printStr, sizeof(printStr) - 1, -1);
printf("dtmp = [%s]\n", printStr);
free(dDqlx);
free(dJcjxts);
free(dtmp);
index++;
}
return (0);
}

View File

@ -1291,3 +1291,15 @@ dec[d,14,14]: 1.00000000000000000
12: -0.5000001
13: 1234567890123456789012345678.91
14:
dDqlx = [439200000.0000000000000000000000]
dJcjxts = [360.0]
dtmp = [122000.00000000000000000000000]
dtmp = [15811200000.000000000000000000000000]
dDqlx = [539200000.0000000000000000000000]
dJcjxts = [360.0]
dtmp = [1497777.7777777777777777777778]
dtmp = [19411200000.000000000000000000000000]
dDqlx = [720.0]
dJcjxts = [360.0]
dtmp = [2.0000000000000000]
dtmp = [259200.00]

View File

@ -231,6 +231,32 @@ main(void)
}
free(decarr);
char* desc[] = {"43920000.0000000000000000000000", "53920000.0000000000000000000000", "720.0"};
decimal* dDqlx = PGTYPESdecimal_new();
decimal* dJcjxts = PGTYPESdecimal_new();
decimal* dtmp = PGTYPESdecimal_new();
int retdecdiv = 0;
int index = 0;
int breakTime = 3;
while (index < breakTime) {
char* number1 = desc[index];
char* number2 = "360.0";
retdecdiv = deccvasc(number1, strlen(number1), dDqlx);
retdecdiv = deccvasc(number2, strlen(number2), dJcjxts);
char printStr[60];
dectoasc(dDqlx, printStr, sizeof(printStr) - 1, -1);
printf("dDqlx = [%s]\n", printStr);
dectoasc(dJcjxts, printStr, sizeof(printStr) - 1, -1);
printf("dJcjxts = [%s]\n", printStr);
retdecdiv = decdiv(dDqlx, dJcjxts, dtmp);
dectoasc(dtmp, printStr, sizeof(printStr) - 1, -1);
printf("dtmp = [%s]\n", printStr);
free(dDqlx);
free(dJcjxts);
free(dtmp);
index++;
}
return (0);
}

View File

@ -1291,3 +1291,15 @@ dec[d,14,14]: 1.00000000000000000
12: -0.5000001
13: 1234567890123456789012345678.91
14:
dDqlx = [439200000.0000000000000000000000]
dJcjxts = [360.0]
dtmp = [122000.00000000000000000000000]
dtmp = [15811200000.000000000000000000000000]
dDqlx = [539200000.0000000000000000000000]
dJcjxts = [360.0]
dtmp = [1497777.7777777777777777777778]
dtmp = [19411200000.000000000000000000000000]
dDqlx = [720.0]
dJcjxts = [360.0]
dtmp = [2.0000000000000000]
dtmp = [259200.00]