Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4875931

Browse files
committed
Fix normalization of numeric values in JSONB GIN indexes.
The default JSONB GIN opclass (jsonb_ops) converts numeric data valuesto strings for storage in the index. It must ensure that numeric valuesthat would compare equal (such as 12 and 12.00) produce identical strings,else index searches would have behavior different from regular JSONBcomparisons. Unfortunately the function charged with doing this wascompletely wrong: it could reduce distinct numeric values to the samestring, or reduce equivalent numeric values to different strings. Theformer type of error would only lead to search inefficiency, but thelatter type of error would cause index entries that should be found bya search to not be found.Repairing this bug therefore means that it will be necessary for 9.4 betatesters to reindex GIN jsonb_ops indexes, if they care about gettingcorrect results from index searches involving numeric data values withinthe comparison JSONB object.Per report from Thomas Fanghaenel.
1 parent5332b8c commit4875931

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

‎src/backend/utils/adt/numeric.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -629,15 +629,17 @@ numeric_out_sci(Numeric num, int scale)
629629
/*
630630
* numeric_normalize() -
631631
*
632-
*Output function for numeric data type without trailing zeroes.
632+
*Output function for numeric data type, suppressing insignificant trailing
633+
*zeroes and then any trailing decimal point. The intent of this is to
634+
*produce strings that are equal if and only if the input numeric values
635+
*compare equal.
633636
*/
634637
char*
635638
numeric_normalize(Numericnum)
636639
{
637640
NumericVarx;
638641
char*str;
639-
intorig,
640-
last;
642+
intlast;
641643

642644
/*
643645
* Handle NaN
@@ -649,18 +651,24 @@ numeric_normalize(Numeric num)
649651

650652
str=get_str_from_var(&x);
651653

652-
orig=last=strlen(str)-1;
653-
654-
for (;;)
654+
/* If there's no decimal point, there's certainly nothing to remove. */
655+
if (strchr(str,'.')!=NULL)
655656
{
656-
if (last==0||str[last]!='0')
657-
break;
657+
/*
658+
* Back up over trailing fractional zeroes. Since there is a decimal
659+
* point, this loop will terminate safely.
660+
*/
661+
last=strlen(str)-1;
662+
while (str[last]=='0')
663+
last--;
658664

659-
last--;
660-
}
665+
/* We want to get rid of the decimal point too, if it's now last. */
666+
if (str[last]=='.')
667+
last--;
661668

662-
if (last>0&&last!=orig)
663-
str[last]='\0';
669+
/* Delete whatever we backed up over. */
670+
str[last+1]='\0';
671+
}
664672

665673
returnstr;
666674
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp