add cfg value check
This commit is contained in:
parent
083c07f6a6
commit
8a5532dd88
|
@ -22,10 +22,10 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
int64_t taosStrHumanToInt64(const char* str);
|
||||
int32_t taosStrHumanToInt64(const char* str, int64_t* out);
|
||||
void taosInt64ToHumanStr(int64_t val, char* outStr);
|
||||
|
||||
int32_t taosStrHumanToInt32(const char* str);
|
||||
int32_t taosStrHumanToInt32(const char* str, int32_t* out);
|
||||
void taosInt32ToHumanStr(int32_t val, char* outStr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -56,6 +56,8 @@ void taosIpPort2String(uint32_t ip, uint16_t port, char *str);
|
|||
|
||||
void *tmemmem(const char *haystack, int hlen, const char *needle, int nlen);
|
||||
|
||||
int32_t parseCfgReal(const char* str, double* out);
|
||||
|
||||
static FORCE_INLINE void taosEncryptPass(uint8_t *inBuf, size_t inLen, char *target) {
|
||||
T_MD5_CTX context;
|
||||
tMD5Init(&context);
|
||||
|
|
|
@ -174,7 +174,9 @@ static int32_t cfgSetBool(SConfigItem *pItem, const char *value, ECfgSrcType sty
|
|||
}
|
||||
|
||||
static int32_t cfgSetInt32(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
|
||||
int32_t ival = taosStrHumanToInt32(value);
|
||||
int32_t ival;
|
||||
int32_t code = taosStrHumanToInt32(value, &ival);
|
||||
if (code != TSDB_CODE_SUCCESS) return code;
|
||||
if (ival < pItem->imin || ival > pItem->imax) {
|
||||
uError("cfg:%s, type:%s src:%s value:%d out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
|
||||
cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), ival, pItem->imin, pItem->imax);
|
||||
|
@ -188,7 +190,9 @@ static int32_t cfgSetInt32(SConfigItem *pItem, const char *value, ECfgSrcType st
|
|||
}
|
||||
|
||||
static int32_t cfgSetInt64(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
|
||||
int64_t ival = taosStrHumanToInt64(value);
|
||||
int64_t ival;
|
||||
int32_t code = taosStrHumanToInt64(value, &ival);
|
||||
if (code != TSDB_CODE_SUCCESS) return code;
|
||||
if (ival < pItem->imin || ival > pItem->imax) {
|
||||
uError("cfg:%s, type:%s src:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
|
||||
cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), ival, pItem->imin, pItem->imax);
|
||||
|
@ -202,15 +206,16 @@ static int32_t cfgSetInt64(SConfigItem *pItem, const char *value, ECfgSrcType st
|
|||
}
|
||||
|
||||
static int32_t cfgSetFloat(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
|
||||
float fval = (float)atof(value);
|
||||
if (fval < pItem->fmin || fval > pItem->fmax) {
|
||||
double dval;
|
||||
int32_t code = parseCfgReal(value, &dval);
|
||||
if (dval < pItem->fmin || dval > pItem->fmax) {
|
||||
uError("cfg:%s, type:%s src:%s value:%f out of range[%f, %f]", pItem->name, cfgDtypeStr(pItem->dtype),
|
||||
cfgStypeStr(stype), fval, pItem->fmin, pItem->fmax);
|
||||
cfgStypeStr(stype), dval, pItem->fmin, pItem->fmax);
|
||||
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pItem->fval = fval;
|
||||
pItem->fval = (float)dval;
|
||||
pItem->stype = stype;
|
||||
return 0;
|
||||
}
|
||||
|
@ -408,7 +413,9 @@ int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *p
|
|||
}
|
||||
} break;
|
||||
case CFG_DTYPE_INT32: {
|
||||
int32_t ival = (int32_t)taosStrHumanToInt32(pVal);
|
||||
int32_t ival;
|
||||
int32_t code = (int32_t)taosStrHumanToInt32(pVal, &ival);
|
||||
if (code != TSDB_CODE_SUCCESS) return code;
|
||||
if (ival < pItem->imin || ival > pItem->imax) {
|
||||
uError("cfg:%s, type:%s value:%d out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
|
||||
cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax);
|
||||
|
@ -417,7 +424,9 @@ int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *p
|
|||
}
|
||||
} break;
|
||||
case CFG_DTYPE_INT64: {
|
||||
int64_t ival = (int64_t)taosStrHumanToInt64(pVal);
|
||||
int64_t ival;
|
||||
int32_t code = taosStrHumanToInt64(pVal, &ival);
|
||||
if (code != TSDB_CODE_SUCCESS) return code;
|
||||
if (ival < pItem->imin || ival > pItem->imax) {
|
||||
uError("cfg:%s, type:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
|
||||
cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax);
|
||||
|
@ -427,9 +436,11 @@ int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *p
|
|||
} break;
|
||||
case CFG_DTYPE_FLOAT:
|
||||
case CFG_DTYPE_DOUBLE: {
|
||||
float fval = (float)atof(pVal);
|
||||
if (fval < pItem->fmin || fval > pItem->fmax) {
|
||||
uError("cfg:%s, type:%s value:%f out of range[%f, %f]", pItem->name, cfgDtypeStr(pItem->dtype), fval,
|
||||
double dval;
|
||||
int32_t code = parseCfgReal(pVal, &dval);
|
||||
if (code != TSDB_CODE_SUCCESS) return code;
|
||||
if (dval < pItem->fmin || dval > pItem->fmax) {
|
||||
uError("cfg:%s, type:%s value:%f out of range[%f, %f]", pItem->name, cfgDtypeStr(pItem->dtype), dval,
|
||||
pItem->fmin, pItem->fmax);
|
||||
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||
return -1;
|
||||
|
|
|
@ -23,45 +23,74 @@
|
|||
#define UNIT_ONE_PEBIBYTE (UNIT_ONE_TEBIBYTE * UNIT_SIZE_CONVERT_FACTOR)
|
||||
#define UNIT_ONE_EXBIBYTE (UNIT_ONE_PEBIBYTE * UNIT_SIZE_CONVERT_FACTOR)
|
||||
|
||||
int64_t taosStrHumanToInt64(const char* str) {
|
||||
size_t sLen = strlen(str);
|
||||
if (sLen < 2) return atoll(str);
|
||||
|
||||
int64_t val = 0;
|
||||
|
||||
char* strNoUnit = NULL;
|
||||
char unit = str[sLen - 1];
|
||||
if ((unit == 'P') || (unit == 'p')) {
|
||||
strNoUnit = taosMemoryCalloc(sLen, 1);
|
||||
memcpy(strNoUnit, str, sLen - 1);
|
||||
|
||||
val = atof(strNoUnit) * UNIT_ONE_PEBIBYTE;
|
||||
} else if ((unit == 'T') || (unit == 't')) {
|
||||
strNoUnit = taosMemoryCalloc(sLen, 1);
|
||||
memcpy(strNoUnit, str, sLen - 1);
|
||||
|
||||
val = atof(strNoUnit) * UNIT_ONE_TEBIBYTE;
|
||||
} else if ((unit == 'G') || (unit == 'g')) {
|
||||
strNoUnit = taosMemoryCalloc(sLen, 1);
|
||||
memcpy(strNoUnit, str, sLen - 1);
|
||||
|
||||
val = atof(strNoUnit) * UNIT_ONE_GIBIBYTE;
|
||||
} else if ((unit == 'M') || (unit == 'm')) {
|
||||
strNoUnit = taosMemoryCalloc(sLen, 1);
|
||||
memcpy(strNoUnit, str, sLen - 1);
|
||||
|
||||
val = atof(strNoUnit) * UNIT_ONE_MEBIBYTE;
|
||||
} else if ((unit == 'K') || (unit == 'k')) {
|
||||
strNoUnit = taosMemoryCalloc(sLen, 1);
|
||||
memcpy(strNoUnit, str, sLen - 1);
|
||||
|
||||
val = atof(strNoUnit) * UNIT_ONE_KIBIBYTE;
|
||||
} else {
|
||||
val = atoll(str);
|
||||
static int32_t parseCfgIntWithUnit(const char* str, double *res) {
|
||||
double val, temp = INT64_MAX;
|
||||
char* endPtr;
|
||||
errno = 0;
|
||||
val = taosStr2Int64(str, &endPtr, 0);
|
||||
if (*endPtr == '.' || errno == ERANGE) {
|
||||
errno = 0;
|
||||
val = taosStr2Double(str, &endPtr);
|
||||
}
|
||||
if (endPtr == str || errno == ERANGE || isnan(val)) {
|
||||
terrno = TSDB_CODE_INVALID_CFG_VALUE;
|
||||
return -1;
|
||||
}
|
||||
while (isspace((unsigned char)*endPtr)) endPtr++;
|
||||
uint64_t factor = 1;
|
||||
if (*endPtr != '\0') {
|
||||
switch (*endPtr) {
|
||||
case 'P':
|
||||
case 'p': {
|
||||
temp /= UNIT_ONE_PEBIBYTE;
|
||||
factor = UNIT_ONE_PEBIBYTE;
|
||||
} break;
|
||||
case 'T':
|
||||
case 't': {
|
||||
temp /= UNIT_ONE_TEBIBYTE;
|
||||
factor = UNIT_ONE_TEBIBYTE;
|
||||
} break;
|
||||
case 'G':
|
||||
case 'g': {
|
||||
temp /= UNIT_ONE_GIBIBYTE;
|
||||
factor = UNIT_ONE_GIBIBYTE;
|
||||
} break;
|
||||
case 'M':
|
||||
case 'm': {
|
||||
temp /= UNIT_ONE_MEBIBYTE;
|
||||
factor = UNIT_ONE_MEBIBYTE;
|
||||
} break;
|
||||
case 'K':
|
||||
case 'k': {
|
||||
temp /= UNIT_ONE_KIBIBYTE;
|
||||
factor = UNIT_ONE_KIBIBYTE;
|
||||
} break;
|
||||
default:
|
||||
terrno = TSDB_CODE_INVALID_CFG_VALUE;
|
||||
return -1;
|
||||
}
|
||||
if ((val > 0 && val > temp) || (val < 0 && val < -temp)) {
|
||||
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||
return -1;
|
||||
}
|
||||
endPtr++;
|
||||
val *= factor;
|
||||
}
|
||||
while (isspace((unsigned char)*endPtr)) endPtr++;
|
||||
if (*endPtr) {
|
||||
terrno = TSDB_CODE_INVALID_CFG_VALUE;
|
||||
return -1;
|
||||
}
|
||||
val = rint(val);
|
||||
*res = val;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
taosMemoryFree(strNoUnit);
|
||||
return val;
|
||||
int32_t taosStrHumanToInt64(const char* str, int64_t *out) {
|
||||
double res;
|
||||
int32_t code = parseCfgIntWithUnit(str, &res);
|
||||
if (code == TSDB_CODE_SUCCESS) *out = (int64_t)res;
|
||||
return code;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
|
@ -83,35 +112,17 @@ void taosInt64ToHumanStr(int64_t val, char* outStr) {
|
|||
}
|
||||
#endif
|
||||
|
||||
int32_t taosStrHumanToInt32(const char* str) {
|
||||
size_t sLen = strlen(str);
|
||||
if (sLen < 2) return atoll(str);
|
||||
|
||||
int32_t val = 0;
|
||||
|
||||
char* strNoUnit = NULL;
|
||||
char unit = str[sLen - 1];
|
||||
if ((unit == 'G') || (unit == 'g')) {
|
||||
strNoUnit = taosMemoryCalloc(sLen, 1);
|
||||
memcpy(strNoUnit, str, sLen - 1);
|
||||
|
||||
val = atof(strNoUnit) * UNIT_ONE_GIBIBYTE;
|
||||
} else if ((unit == 'M') || (unit == 'm')) {
|
||||
strNoUnit = taosMemoryCalloc(sLen, 1);
|
||||
memcpy(strNoUnit, str, sLen - 1);
|
||||
|
||||
val = atof(strNoUnit) * UNIT_ONE_MEBIBYTE;
|
||||
} else if ((unit == 'K') || (unit == 'k')) {
|
||||
strNoUnit = taosMemoryCalloc(sLen, 1);
|
||||
memcpy(strNoUnit, str, sLen - 1);
|
||||
|
||||
val = atof(strNoUnit) * UNIT_ONE_KIBIBYTE;
|
||||
} else {
|
||||
val = atoll(str);
|
||||
int32_t taosStrHumanToInt32(const char* str, int32_t* out) {
|
||||
double res;
|
||||
int32_t code = parseCfgIntWithUnit(str, &res);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
if (res < INT32_MIN || res > INT32_MAX) {
|
||||
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||
return -1;
|
||||
}
|
||||
*out = (int32_t)res;
|
||||
}
|
||||
|
||||
taosMemoryFree(strNoUnit);
|
||||
return val;
|
||||
return code;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
|
|
|
@ -496,3 +496,21 @@ size_t twcsncspn(const TdUcs4 *wcs, size_t size, const TdUcs4 *reject, size_t rs
|
|||
|
||||
return index;
|
||||
}
|
||||
|
||||
int32_t parseCfgReal(const char* str, double* out) {
|
||||
double val;
|
||||
char *endPtr;
|
||||
errno = 0;
|
||||
val = taosStr2Double(str, &endPtr);
|
||||
if (str == endPtr || errno == ERANGE || isnan(val)) {
|
||||
terrno = TSDB_CODE_INVALID_CFG_VALUE;
|
||||
return -1;
|
||||
}
|
||||
while(isspace((unsigned char)*endPtr)) endPtr++;
|
||||
if (*endPtr != '\0') {
|
||||
terrno = TSDB_CODE_INVALID_CFG_VALUE;
|
||||
return -1;
|
||||
}
|
||||
*out = val;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -240,6 +240,49 @@ class TDTestCase:
|
|||
self.show_create_sysdb_sql()
|
||||
self.show_create_systb_sql()
|
||||
self.show_column_name()
|
||||
self.test_show_variables()
|
||||
|
||||
def get_variable(self, name: str, local: bool = True):
|
||||
if local:
|
||||
sql = 'show local variables'
|
||||
else:
|
||||
sql = f'select `value` from information_schema.ins_dnode_variables where name like "{name}"'
|
||||
tdSql.query(sql, queryTimes=1)
|
||||
res = tdSql.queryResult
|
||||
if local:
|
||||
for row in res:
|
||||
if row[0] == name:
|
||||
return row[1]
|
||||
else:
|
||||
if len(res) > 0:
|
||||
return res[0][0]
|
||||
raise Exception(f"variable {name} not found")
|
||||
|
||||
def test_show_variables(self):
|
||||
epsion = 0.0000001
|
||||
var = 'minimalTmpDirGB'
|
||||
expect_val: float = 10.11
|
||||
sql = f'ALTER LOCAL "{var}" "{expect_val}"'
|
||||
tdSql.execute(sql)
|
||||
val: float = float(self.get_variable(var))
|
||||
if val != expect_val:
|
||||
tdLog.exit(f'failed to set local {var} to {expect_val} actually {val}')
|
||||
|
||||
error_vals = ['a', '10a', '', '1.100r', '1.12 r']
|
||||
for error_val in error_vals:
|
||||
tdSql.error(f'ALTER LOCAL "{var}" "{error_val}"')
|
||||
|
||||
var = 'supportVnodes'
|
||||
expect_val = 1240 ## 1.211111 * 1024
|
||||
sql = f'ALTER DNODE 1 "{var}" "1.211111k"'
|
||||
tdSql.execute(sql, queryTimes=1)
|
||||
val = int(self.get_variable(var, False))
|
||||
if val != expect_val:
|
||||
tdLog.exit(f'failed to set dnode {var} to {expect_val} actually {val}')
|
||||
|
||||
error_vals = ['a', '10a', '', '1.100r', '1.12 r', '5k']
|
||||
for error_val in error_vals:
|
||||
tdSql.error(f'ALTER DNODE 1 "{var}" "{error_val}"')
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
|
|
Loading…
Reference in New Issue