TT#63000 db_redis: use a min string length of 10 digits for bigints

Change-Id: I3505c151a565be8383a4eec5268a27e3b7415db0
(cherry picked from commit 640695c729)
changes/13/32413/1
Richard Fuchs 7 years ago
parent 7d5921199d
commit 0fcb821185

@ -45,3 +45,4 @@ sipwise/db_redis_fix_scan_usage.patch
sipwise/db_redis_skip_not_eq_type_keys.patch
sipwise/db_redis_update_type_keys.patch
sipwise/db_redis_range_compare_timestamps.patch
sipwise/db_redis_bigint_min_len.patch

@ -0,0 +1,86 @@
--- a/src/modules/db_redis/redis_dbase.c
+++ b/src/modules/db_redis/redis_dbase.c
@@ -109,14 +109,14 @@
LM_DBG("converting bigint value %lld to str\n", VAL_BIGINT(v));
_str->s = (char*)pkg_malloc(_str->len);
if (!_str->s) goto memerr;
- snprintf(_str->s, _str->len, "%lld", VAL_BIGINT(v));
+ snprintf(_str->s, _str->len, "%010lld", VAL_BIGINT(v));
_str->len = strlen(_str->s);
break;
case DB1_UBIGINT:
LM_DBG("converting ubigint value %llu to str\n", VAL_UBIGINT(v));
_str->s = (char*)pkg_malloc(_str->len);
if (!_str->s) goto memerr;
- snprintf(_str->s, _str->len, "%llu", VAL_UBIGINT(v));
+ snprintf(_str->s, _str->len, "%010llu", VAL_UBIGINT(v));
_str->len = strlen(_str->s);
break;
case DB1_STRING:
@@ -306,7 +306,8 @@
k->len, k->s);
break;
} else if (op && strcmp(op, OP_EQ)
- && !((VAL_TYPE(&v) == DB1_DATETIME || VAL_TYPE(&v) == DB1_BIGINT || VAL_TYPE(&v) == DB1_INT)
+ && !((VAL_TYPE(&v) == DB1_DATETIME || VAL_TYPE(&v) == DB1_BIGINT
+ || VAL_TYPE(&v) == DB1_UBIGINT)
&& (!strcmp(op, OP_LT) || !strcmp(op, OP_GT)))) {
LM_DBG("Skipping non-EQ op (%s) for given key '%.*s'\n",
op, k->len, k->s);
@@ -344,7 +345,8 @@
val.len, val.s);
key_name->len += (1 + val.len);
}
- if (op && (VAL_TYPE(&v) == DB1_DATETIME || VAL_TYPE(&v) == DB1_BIGINT || VAL_TYPE(&v) == DB1_INT)
+ if (op && (VAL_TYPE(&v) == DB1_DATETIME || VAL_TYPE(&v) == DB1_BIGINT
+ || VAL_TYPE(&v) == DB1_UBIGINT)
&& (!strcmp(op, OP_LT) || !strcmp(op, OP_GT))) {
// Special case: we support matching < or > against timestamps and ints using a special
// key scanning method. We do this only for a single timestamp/int occurance, and we
@@ -365,7 +367,8 @@
(unsigned long long) *ts_scan_start);
*key_found = 0; // this forces a table scan using the new match key
}
- else if ((VAL_TYPE(&v) == DB1_BIGINT || VAL_TYPE(&v) == DB1_INT) && *ts_scan_start == 0) {
+ else if ((VAL_TYPE(&v) == DB1_BIGINT
+ || VAL_TYPE(&v) == DB1_UBIGINT) && *ts_scan_start == 0) {
*ts_scan_start = key_name->len | ((uint64_t) val.len << 31);
*ts_scan_start |= 0x4000000000000000ULL; // length is variable
if (!strcmp(op, OP_LT))
@@ -872,6 +875,7 @@
// ex: 12345
// if >, we match: 2????, 1[3-9]???, ..., plus ?????*
// if <. we match: ?, ??, ???, ????, 1[0-1]???, 12[0-2]??, etc
+ // ... however we expect a minimum length of 10 digits as per BIGINT printf format
match = pkg_malloc(ts_scan_key->len + 6);
if (!match) {
@@ -895,7 +899,7 @@
// copy unchanged prefix
memcpy(match, ts_scan_key->s, scan_offset);
- // append a number of ?. if length is 3 digits, we do ? and ??
+ // append a number of ?. minimum string length is 10 digits
for (int i = 0; i < scan_length - 1; i++) {
int len = scan_offset + i;
char match_char = ts_scan_key->s[len];
@@ -910,6 +914,10 @@
strcpy(match + len + 1, suffix);
len = strlen(match);
+ // minimum bigint printf string length
+ if (i < 10)
+ continue;
+
str match_pattern = {match, len};
LM_DBG("running timestamp/int range matching using pattern '%.*s'\n", len, match);
@@ -929,6 +937,8 @@
// skip numbers that are at the edge of their match range
if (match_char == '0' && scan_lt)
continue;
+ if (match_char == '1' && scan_lt && i == 0) // no leading 0
+ continue;
if (match_char == '9' && !scan_lt)
continue;
Loading…
Cancel
Save