Refactor multirange_in()

This commit preserves the logic of multirange_in() but makes it more clear
what's going on.  Also, this commit fixes the compiler warning spotted by the
buildfarm.

Reported-by: Tom Lane
Discussion: https://postgr.es/m/2246043.1609290699%40sss.pgh.pa.us
This commit is contained in:
Alexander Korotkov 2020-12-30 21:11:31 +03:00
parent 7ca37fb040
commit 16d531a30a
1 changed files with 30 additions and 16 deletions

View File

@ -128,9 +128,9 @@ multirange_in(PG_FUNCTION_ARGS)
MultirangeType *ret; MultirangeType *ret;
MultirangeParseState parse_state; MultirangeParseState parse_state;
const char *ptr = input_str; const char *ptr = input_str;
const char *range_str = NULL; const char *range_str_begin = NULL;
int32 range_str_len; int32 range_str_len;
char *range_str_copy; char *range_str;
cache = get_multirange_io_data(fcinfo, mltrngtypoid, IOFunc_input); cache = get_multirange_io_data(fcinfo, mltrngtypoid, IOFunc_input);
rangetyp = cache->typcache->rngtype; rangetyp = cache->typcache->rngtype;
@ -170,7 +170,7 @@ multirange_in(PG_FUNCTION_ARGS)
case MULTIRANGE_BEFORE_RANGE: case MULTIRANGE_BEFORE_RANGE:
if (ch == '[' || ch == '(') if (ch == '[' || ch == '(')
{ {
range_str = ptr; range_str_begin = ptr;
parse_state = MULTIRANGE_IN_RANGE; parse_state = MULTIRANGE_IN_RANGE;
} }
else if (ch == '}' && ranges_seen == 0) else if (ch == '}' && ranges_seen == 0)
@ -191,14 +191,10 @@ multirange_in(PG_FUNCTION_ARGS)
errdetail("Expected range start."))); errdetail("Expected range start.")));
break; break;
case MULTIRANGE_IN_RANGE: case MULTIRANGE_IN_RANGE:
if (ch == '"') if (ch == ']' || ch == ')')
parse_state = MULTIRANGE_IN_RANGE_QUOTED;
else if (ch == '\\')
parse_state = MULTIRANGE_IN_RANGE_ESCAPED;
else if (ch == ']' || ch == ')')
{ {
range_str_len = ptr - range_str + 1; range_str_len = ptr - range_str_begin + 1;
range_str_copy = pnstrdup(range_str, range_str_len); range_str = pnstrdup(range_str_begin, range_str_len);
if (range_capacity == range_count) if (range_capacity == range_count)
{ {
range_capacity *= 2; range_capacity *= 2;
@ -207,7 +203,7 @@ multirange_in(PG_FUNCTION_ARGS)
} }
ranges_seen++; ranges_seen++;
range = DatumGetRangeTypeP(InputFunctionCall(&cache->typioproc, range = DatumGetRangeTypeP(InputFunctionCall(&cache->typioproc,
range_str_copy, range_str,
cache->typioparam, cache->typioparam,
typmod)); typmod));
if (!RangeIsEmpty(range)) if (!RangeIsEmpty(range))
@ -215,10 +211,22 @@ multirange_in(PG_FUNCTION_ARGS)
parse_state = MULTIRANGE_AFTER_RANGE; parse_state = MULTIRANGE_AFTER_RANGE;
} }
else else
/* include it in range_str */ ; {
if (ch == '"')
parse_state = MULTIRANGE_IN_RANGE_QUOTED;
else if (ch == '\\')
parse_state = MULTIRANGE_IN_RANGE_ESCAPED;
/*
* We will include this character into range_str once we
* find the end of the range value.
*/
}
break; break;
case MULTIRANGE_IN_RANGE_ESCAPED: case MULTIRANGE_IN_RANGE_ESCAPED:
/* include it in range_str */ /*
* We will include this character into range_str once we find
* the end of the range value.
*/
parse_state = MULTIRANGE_IN_RANGE; parse_state = MULTIRANGE_IN_RANGE;
break; break;
case MULTIRANGE_IN_RANGE_QUOTED: case MULTIRANGE_IN_RANGE_QUOTED:
@ -232,8 +240,11 @@ multirange_in(PG_FUNCTION_ARGS)
parse_state = MULTIRANGE_IN_RANGE; parse_state = MULTIRANGE_IN_RANGE;
else if (ch == '\\') else if (ch == '\\')
parse_state = MULTIRANGE_IN_RANGE_QUOTED_ESCAPED; parse_state = MULTIRANGE_IN_RANGE_QUOTED_ESCAPED;
else
/* include it in range_str */ ; /*
* We will include this character into range_str once we
* find the end of the range value.
*/
break; break;
case MULTIRANGE_AFTER_RANGE: case MULTIRANGE_AFTER_RANGE:
if (ch == ',') if (ch == ',')
@ -248,7 +259,10 @@ multirange_in(PG_FUNCTION_ARGS)
errdetail("Expected comma or end of multirange."))); errdetail("Expected comma or end of multirange.")));
break; break;
case MULTIRANGE_IN_RANGE_QUOTED_ESCAPED: case MULTIRANGE_IN_RANGE_QUOTED_ESCAPED:
/* include it in range_str */ /*
* We will include this character into range_str once we find
* the end of the range value.
*/
parse_state = MULTIRANGE_IN_RANGE_QUOTED; parse_state = MULTIRANGE_IN_RANGE_QUOTED;
break; break;
default: default: