From 0fcb8211855edffb4350d4381dc1c57feadc2531 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Tue, 13 Aug 2019 10:35:11 -0400 Subject: [PATCH] TT#63000 db_redis: use a min string length of 10 digits for bigints Change-Id: I3505c151a565be8383a4eec5268a27e3b7415db0 (cherry picked from commit 640695c72953f95b6a46bfff86cc249898f57fa6) --- debian/patches/series | 1 + .../sipwise/db_redis_bigint_min_len.patch | 86 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 debian/patches/sipwise/db_redis_bigint_min_len.patch diff --git a/debian/patches/series b/debian/patches/series index 2a237ea23..a2fac4db2 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -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 diff --git a/debian/patches/sipwise/db_redis_bigint_min_len.patch b/debian/patches/sipwise/db_redis_bigint_min_len.patch new file mode 100644 index 000000000..ef17bf6e7 --- /dev/null +++ b/debian/patches/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; +