add cfg value check
This commit is contained in:
parent
083c07f6a6
commit
8a5532dd88
|
@ -22,10 +22,10 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int64_t taosStrHumanToInt64(const char* str);
|
int32_t taosStrHumanToInt64(const char* str, int64_t* out);
|
||||||
void taosInt64ToHumanStr(int64_t val, char* outStr);
|
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);
|
void taosInt32ToHumanStr(int32_t val, char* outStr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#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);
|
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) {
|
static FORCE_INLINE void taosEncryptPass(uint8_t *inBuf, size_t inLen, char *target) {
|
||||||
T_MD5_CTX context;
|
T_MD5_CTX context;
|
||||||
tMD5Init(&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) {
|
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) {
|
if (ival < pItem->imin || ival > pItem->imax) {
|
||||||
uError("cfg:%s, type:%s src:%s value:%d out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
|
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);
|
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) {
|
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) {
|
if (ival < pItem->imin || ival > pItem->imax) {
|
||||||
uError("cfg:%s, type:%s src:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
|
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);
|
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) {
|
static int32_t cfgSetFloat(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
|
||||||
float fval = (float)atof(value);
|
double dval;
|
||||||
if (fval < pItem->fmin || fval > pItem->fmax) {
|
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),
|
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;
|
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pItem->fval = fval;
|
pItem->fval = (float)dval;
|
||||||
pItem->stype = stype;
|
pItem->stype = stype;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -408,7 +413,9 @@ int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *p
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case CFG_DTYPE_INT32: {
|
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) {
|
if (ival < pItem->imin || ival > pItem->imax) {
|
||||||
uError("cfg:%s, type:%s value:%d out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
|
uError("cfg:%s, type:%s value:%d out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
|
||||||
cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax);
|
cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax);
|
||||||
|
@ -417,7 +424,9 @@ int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *p
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case CFG_DTYPE_INT64: {
|
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) {
|
if (ival < pItem->imin || ival > pItem->imax) {
|
||||||
uError("cfg:%s, type:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
|
uError("cfg:%s, type:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
|
||||||
cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax);
|
cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax);
|
||||||
|
@ -427,9 +436,11 @@ int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *p
|
||||||
} break;
|
} break;
|
||||||
case CFG_DTYPE_FLOAT:
|
case CFG_DTYPE_FLOAT:
|
||||||
case CFG_DTYPE_DOUBLE: {
|
case CFG_DTYPE_DOUBLE: {
|
||||||
float fval = (float)atof(pVal);
|
double dval;
|
||||||
if (fval < pItem->fmin || fval > pItem->fmax) {
|
int32_t code = parseCfgReal(pVal, &dval);
|
||||||
uError("cfg:%s, type:%s value:%f out of range[%f, %f]", pItem->name, cfgDtypeStr(pItem->dtype), fval,
|
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);
|
pItem->fmin, pItem->fmax);
|
||||||
terrno = TSDB_CODE_OUT_OF_RANGE;
|
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -23,45 +23,74 @@
|
||||||
#define UNIT_ONE_PEBIBYTE (UNIT_ONE_TEBIBYTE * UNIT_SIZE_CONVERT_FACTOR)
|
#define UNIT_ONE_PEBIBYTE (UNIT_ONE_TEBIBYTE * UNIT_SIZE_CONVERT_FACTOR)
|
||||||
#define UNIT_ONE_EXBIBYTE (UNIT_ONE_PEBIBYTE * UNIT_SIZE_CONVERT_FACTOR)
|
#define UNIT_ONE_EXBIBYTE (UNIT_ONE_PEBIBYTE * UNIT_SIZE_CONVERT_FACTOR)
|
||||||
|
|
||||||
int64_t taosStrHumanToInt64(const char* str) {
|
static int32_t parseCfgIntWithUnit(const char* str, double *res) {
|
||||||
size_t sLen = strlen(str);
|
double val, temp = INT64_MAX;
|
||||||
if (sLen < 2) return atoll(str);
|
char* endPtr;
|
||||||
|
errno = 0;
|
||||||
int64_t val = 0;
|
val = taosStr2Int64(str, &endPtr, 0);
|
||||||
|
if (*endPtr == '.' || errno == ERANGE) {
|
||||||
char* strNoUnit = NULL;
|
errno = 0;
|
||||||
char unit = str[sLen - 1];
|
val = taosStr2Double(str, &endPtr);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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);
|
int32_t taosStrHumanToInt64(const char* str, int64_t *out) {
|
||||||
return val;
|
double res;
|
||||||
|
int32_t code = parseCfgIntWithUnit(str, &res);
|
||||||
|
if (code == TSDB_CODE_SUCCESS) *out = (int64_t)res;
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BUILD_NO_CALL
|
#ifdef BUILD_NO_CALL
|
||||||
|
@ -83,35 +112,17 @@ void taosInt64ToHumanStr(int64_t val, char* outStr) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int32_t taosStrHumanToInt32(const char* str) {
|
int32_t taosStrHumanToInt32(const char* str, int32_t* out) {
|
||||||
size_t sLen = strlen(str);
|
double res;
|
||||||
if (sLen < 2) return atoll(str);
|
int32_t code = parseCfgIntWithUnit(str, &res);
|
||||||
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
int32_t val = 0;
|
if (res < INT32_MIN || res > INT32_MAX) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_RANGE;
|
||||||
char* strNoUnit = NULL;
|
return -1;
|
||||||
char unit = str[sLen - 1];
|
}
|
||||||
if ((unit == 'G') || (unit == 'g')) {
|
*out = (int32_t)res;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
return code;
|
||||||
taosMemoryFree(strNoUnit);
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BUILD_NO_CALL
|
#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;
|
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_sysdb_sql()
|
||||||
self.show_create_systb_sql()
|
self.show_create_systb_sql()
|
||||||
self.show_column_name()
|
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):
|
def stop(self):
|
||||||
tdSql.close()
|
tdSql.close()
|
||||||
|
|
Loading…
Reference in New Issue