Commit 29ceacc3 authored by Alexander Korotkov's avatar Alexander Korotkov

Improve error reporting in jsonpath

This commit contains multiple improvements to error reporting in jsonpath
including but not limited to getting rid of following things:

 * definition of error messages in macros,
 * errdetail() when valueable information could fit to errmsg(),
 * word "singleton" which is not properly explained anywhere,
 * line breaks in error messages.

Reported-by: Tom Lane
Discussion: https://postgr.es/m/14890.1555523005%40sss.pgh.pa.us
Author: Alexander Korotkov
Reviewed-by: Tom Lane
parent b84dbc8e
This diff is collapsed.
...@@ -511,7 +511,11 @@ makeItemLikeRegex(JsonPathParseItem *expr, JsonPathString *pattern, ...@@ -511,7 +511,11 @@ makeItemLikeRegex(JsonPathParseItem *expr, JsonPathString *pattern,
cflags |= REG_EXPANDED; cflags |= REG_EXPANDED;
break; break;
default: default:
yyerror(NULL, "unrecognized flag of LIKE_REGEX predicate"); ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("invalid input syntax for type %s", "jsonpath"),
errdetail("unrecognized flag character \"%c\" in LIKE_REGEX predicate",
flags->val[i])));
break; break;
} }
} }
......
...@@ -142,9 +142,9 @@ hex_fail \\x{hex_dig}{0,1} ...@@ -142,9 +142,9 @@ hex_fail \\x{hex_dig}{0,1}
<xnq,xq,xvq,xsq>{hex_char} { parseHexChar(yytext); } <xnq,xq,xvq,xsq>{hex_char} { parseHexChar(yytext); }
<xnq,xq,xvq,xsq>{unicode}*{unicodefail} { yyerror(NULL, "Unicode sequence is invalid"); } <xnq,xq,xvq,xsq>{unicode}*{unicodefail} { yyerror(NULL, "invalid unicode sequence"); }
<xnq,xq,xvq,xsq>{hex_fail} { yyerror(NULL, "Hex character sequence is invalid"); } <xnq,xq,xvq,xsq>{hex_fail} { yyerror(NULL, "invalid hex character sequence"); }
<xnq,xq,xvq,xsq>{unicode}+\\ { <xnq,xq,xvq,xsq>{unicode}+\\ {
/* throw back the \\, and treat as unicode */ /* throw back the \\, and treat as unicode */
...@@ -152,11 +152,11 @@ hex_fail \\x{hex_dig}{0,1} ...@@ -152,11 +152,11 @@ hex_fail \\x{hex_dig}{0,1}
parseUnicode(yytext, yyleng); parseUnicode(yytext, yyleng);
} }
<xnq,xq,xvq,xsq>\\. { yyerror(NULL, "Escape sequence is invalid"); } <xnq,xq,xvq,xsq>\\. { yyerror(NULL, "escape sequence is invalid"); }
<xnq,xq,xvq,xsq>\\ { yyerror(NULL, "Unexpected end after backslash"); } <xnq,xq,xvq,xsq>\\ { yyerror(NULL, "unexpected end after backslash"); }
<xq,xvq,xsq><<EOF>> { yyerror(NULL, "Unexpected end of quoted string"); } <xq,xvq,xsq><<EOF>> { yyerror(NULL, "unexpected end of quoted string"); }
<xq>\" { <xq>\" {
yylval->str = scanstring; yylval->str = scanstring;
...@@ -186,7 +186,7 @@ hex_fail \\x{hex_dig}{0,1} ...@@ -186,7 +186,7 @@ hex_fail \\x{hex_dig}{0,1}
<xc>\* { } <xc>\* { }
<xc><<EOF>> { yyerror(NULL, "Unexpected end of comment"); } <xc><<EOF>> { yyerror(NULL, "unexpected end of comment"); }
\&\& { return AND_P; } \&\& { return AND_P; }
...@@ -261,7 +261,7 @@ hex_fail \\x{hex_dig}{0,1} ...@@ -261,7 +261,7 @@ hex_fail \\x{hex_dig}{0,1}
return INT_P; return INT_P;
} }
({realfail1}|{realfail2}) { yyerror(NULL, "Floating point number is invalid"); } ({realfail1}|{realfail2}) { yyerror(NULL, "invalid floating point number"); }
{any}+ { {any}+ {
addstring(true, yytext, yyleng); addstring(true, yytext, yyleng);
...@@ -295,17 +295,16 @@ jsonpath_yyerror(JsonPathParseResult **result, const char *message) ...@@ -295,17 +295,16 @@ jsonpath_yyerror(JsonPathParseResult **result, const char *message)
{ {
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("bad jsonpath representation"),
/* translator: %s is typically "syntax error" */ /* translator: %s is typically "syntax error" */
errdetail("%s at end of input", message))); errmsg("%s at end of jsonpath input", _(message))));
} }
else else
{ {
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR), (errcode(ERRCODE_SYNTAX_ERROR),
errmsg("bad jsonpath representation"),
/* translator: first %s is typically "syntax error" */ /* translator: first %s is typically "syntax error" */
errdetail("%s at or near \"%s\"", message, yytext))); errmsg("%s at or near \"%s\" of jsonpath input",
_(message), yytext)));
} }
} }
...@@ -495,7 +494,7 @@ hexval(char c) ...@@ -495,7 +494,7 @@ hexval(char c)
return c - 'a' + 0xA; return c - 'a' + 0xA;
if (c >= 'A' && c <= 'F') if (c >= 'A' && c <= 'F')
return c - 'A' + 0xA; return c - 'A' + 0xA;
elog(ERROR, "invalid hexadecimal digit"); jsonpath_yyerror(NULL, "invalid hexadecimal digit");
return 0; /* not reached */ return 0; /* not reached */
} }
......
...@@ -454,10 +454,10 @@ select '$ ? (@ like_regex "pattern" flag "xsms")'::jsonpath; ...@@ -454,10 +454,10 @@ select '$ ? (@ like_regex "pattern" flag "xsms")'::jsonpath;
(1 row) (1 row)
select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath; select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath;
ERROR: bad jsonpath representation ERROR: invalid input syntax for type jsonpath
LINE 1: select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath; LINE 1: select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath;
^ ^
DETAIL: unrecognized flag of LIKE_REGEX predicate at or near """ DETAIL: unrecognized flag character "a" in LIKE_REGEX predicate
select '$ < 1'::jsonpath; select '$ < 1'::jsonpath;
jsonpath jsonpath
---------- ----------
...@@ -547,20 +547,17 @@ select '$ ? (@.a < +1)'::jsonpath; ...@@ -547,20 +547,17 @@ select '$ ? (@.a < +1)'::jsonpath;
(1 row) (1 row)
select '$ ? (@.a < .1)'::jsonpath; select '$ ? (@.a < .1)'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '$ ? (@.a < .1)'::jsonpath; LINE 1: select '$ ? (@.a < .1)'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '$ ? (@.a < -.1)'::jsonpath; select '$ ? (@.a < -.1)'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '$ ? (@.a < -.1)'::jsonpath; LINE 1: select '$ ? (@.a < -.1)'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '$ ? (@.a < +.1)'::jsonpath; select '$ ? (@.a < +.1)'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '$ ? (@.a < +.1)'::jsonpath; LINE 1: select '$ ? (@.a < +.1)'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '$ ? (@.a < 0.1)'::jsonpath; select '$ ? (@.a < 0.1)'::jsonpath;
jsonpath jsonpath
----------------- -----------------
...@@ -616,20 +613,17 @@ select '$ ? (@.a < +1e1)'::jsonpath; ...@@ -616,20 +613,17 @@ select '$ ? (@.a < +1e1)'::jsonpath;
(1 row) (1 row)
select '$ ? (@.a < .1e1)'::jsonpath; select '$ ? (@.a < .1e1)'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '$ ? (@.a < .1e1)'::jsonpath; LINE 1: select '$ ? (@.a < .1e1)'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '$ ? (@.a < -.1e1)'::jsonpath; select '$ ? (@.a < -.1e1)'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '$ ? (@.a < -.1e1)'::jsonpath; LINE 1: select '$ ? (@.a < -.1e1)'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '$ ? (@.a < +.1e1)'::jsonpath; select '$ ? (@.a < +.1e1)'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '$ ? (@.a < +.1e1)'::jsonpath; LINE 1: select '$ ? (@.a < +.1e1)'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '$ ? (@.a < 0.1e1)'::jsonpath; select '$ ? (@.a < 0.1e1)'::jsonpath;
jsonpath jsonpath
--------------- ---------------
...@@ -685,20 +679,17 @@ select '$ ? (@.a < +1e-1)'::jsonpath; ...@@ -685,20 +679,17 @@ select '$ ? (@.a < +1e-1)'::jsonpath;
(1 row) (1 row)
select '$ ? (@.a < .1e-1)'::jsonpath; select '$ ? (@.a < .1e-1)'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '$ ? (@.a < .1e-1)'::jsonpath; LINE 1: select '$ ? (@.a < .1e-1)'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '$ ? (@.a < -.1e-1)'::jsonpath; select '$ ? (@.a < -.1e-1)'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '$ ? (@.a < -.1e-1)'::jsonpath; LINE 1: select '$ ? (@.a < -.1e-1)'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '$ ? (@.a < +.1e-1)'::jsonpath; select '$ ? (@.a < +.1e-1)'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '$ ? (@.a < +.1e-1)'::jsonpath; LINE 1: select '$ ? (@.a < +.1e-1)'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '$ ? (@.a < 0.1e-1)'::jsonpath; select '$ ? (@.a < 0.1e-1)'::jsonpath;
jsonpath jsonpath
------------------ ------------------
...@@ -754,20 +745,17 @@ select '$ ? (@.a < +1e+1)'::jsonpath; ...@@ -754,20 +745,17 @@ select '$ ? (@.a < +1e+1)'::jsonpath;
(1 row) (1 row)
select '$ ? (@.a < .1e+1)'::jsonpath; select '$ ? (@.a < .1e+1)'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '$ ? (@.a < .1e+1)'::jsonpath; LINE 1: select '$ ? (@.a < .1e+1)'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '$ ? (@.a < -.1e+1)'::jsonpath; select '$ ? (@.a < -.1e+1)'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '$ ? (@.a < -.1e+1)'::jsonpath; LINE 1: select '$ ? (@.a < -.1e+1)'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '$ ? (@.a < +.1e+1)'::jsonpath; select '$ ? (@.a < +.1e+1)'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '$ ? (@.a < +.1e+1)'::jsonpath; LINE 1: select '$ ? (@.a < +.1e+1)'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '$ ? (@.a < 0.1e+1)'::jsonpath; select '$ ? (@.a < 0.1e+1)'::jsonpath;
jsonpath jsonpath
--------------- ---------------
...@@ -811,10 +799,9 @@ select '0'::jsonpath; ...@@ -811,10 +799,9 @@ select '0'::jsonpath;
(1 row) (1 row)
select '00'::jsonpath; select '00'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected IDENT_P at end of jsonpath input
LINE 1: select '00'::jsonpath; LINE 1: select '00'::jsonpath;
^ ^
DETAIL: syntax error, unexpected IDENT_P at end of input
select '0.0'::jsonpath; select '0.0'::jsonpath;
jsonpath jsonpath
---------- ----------
...@@ -870,10 +857,9 @@ select '0.0010e+2'::jsonpath; ...@@ -870,10 +857,9 @@ select '0.0010e+2'::jsonpath;
(1 row) (1 row)
select '1e'::jsonpath; select '1e'::jsonpath;
ERROR: bad jsonpath representation ERROR: invalid floating point number at or near "1e" of jsonpath input
LINE 1: select '1e'::jsonpath; LINE 1: select '1e'::jsonpath;
^ ^
DETAIL: Floating point number is invalid at or near "1e"
select '1.e'::jsonpath; select '1.e'::jsonpath;
jsonpath jsonpath
---------- ----------
...@@ -881,10 +867,9 @@ select '1.e'::jsonpath; ...@@ -881,10 +867,9 @@ select '1.e'::jsonpath;
(1 row) (1 row)
select '1.2e'::jsonpath; select '1.2e'::jsonpath;
ERROR: bad jsonpath representation ERROR: invalid floating point number at or near "1.2e" of jsonpath input
LINE 1: select '1.2e'::jsonpath; LINE 1: select '1.2e'::jsonpath;
^ ^
DETAIL: Floating point number is invalid at or near "1.2e"
select '1.2.e'::jsonpath; select '1.2.e'::jsonpath;
jsonpath jsonpath
---------- ----------
...@@ -940,22 +925,18 @@ select '(1.2).e3'::jsonpath; ...@@ -940,22 +925,18 @@ select '(1.2).e3'::jsonpath;
(1 row) (1 row)
select '1..e'::jsonpath; select '1..e'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '1..e'::jsonpath; LINE 1: select '1..e'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '1..e3'::jsonpath; select '1..e3'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected '.' at or near "." of jsonpath input
LINE 1: select '1..e3'::jsonpath; LINE 1: select '1..e3'::jsonpath;
^ ^
DETAIL: syntax error, unexpected '.' at or near "."
select '(1.).e'::jsonpath; select '(1.).e'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected ')' at or near ")" of jsonpath input
LINE 1: select '(1.).e'::jsonpath; LINE 1: select '(1.).e'::jsonpath;
^ ^
DETAIL: syntax error, unexpected ')' at or near ")"
select '(1.).e3'::jsonpath; select '(1.).e3'::jsonpath;
ERROR: bad jsonpath representation ERROR: syntax error, unexpected ')' at or near ")" of jsonpath input
LINE 1: select '(1.).e3'::jsonpath; LINE 1: select '(1.).e3'::jsonpath;
^ ^
DETAIL: syntax error, unexpected ')' at or near ")"
...@@ -2,20 +2,17 @@ ...@@ -2,20 +2,17 @@
-- checks for double-quoted values -- checks for double-quoted values
-- basic unicode input -- basic unicode input
SELECT '"\u"'::jsonpath; -- ERROR, incomplete escape SELECT '"\u"'::jsonpath; -- ERROR, incomplete escape
ERROR: bad jsonpath representation ERROR: invalid unicode sequence at or near "\u" of jsonpath input
LINE 1: SELECT '"\u"'::jsonpath; LINE 1: SELECT '"\u"'::jsonpath;
^ ^
DETAIL: Unicode sequence is invalid at or near "\u"
SELECT '"\u00"'::jsonpath; -- ERROR, incomplete escape SELECT '"\u00"'::jsonpath; -- ERROR, incomplete escape
ERROR: bad jsonpath representation ERROR: invalid unicode sequence at or near "\u00" of jsonpath input
LINE 1: SELECT '"\u00"'::jsonpath; LINE 1: SELECT '"\u00"'::jsonpath;
^ ^
DETAIL: Unicode sequence is invalid at or near "\u00"
SELECT '"\u000g"'::jsonpath; -- ERROR, g is not a hex digit SELECT '"\u000g"'::jsonpath; -- ERROR, g is not a hex digit
ERROR: bad jsonpath representation ERROR: invalid unicode sequence at or near "\u000" of jsonpath input
LINE 1: SELECT '"\u000g"'::jsonpath; LINE 1: SELECT '"\u000g"'::jsonpath;
^ ^
DETAIL: Unicode sequence is invalid at or near "\u000"
SELECT '"\u0000"'::jsonpath; -- OK, legal escape SELECT '"\u0000"'::jsonpath; -- OK, legal escape
ERROR: unsupported Unicode escape sequence ERROR: unsupported Unicode escape sequence
LINE 1: SELECT '"\u0000"'::jsonpath; LINE 1: SELECT '"\u0000"'::jsonpath;
...@@ -165,20 +162,17 @@ DETAIL: \u0000 cannot be converted to text. ...@@ -165,20 +162,17 @@ DETAIL: \u0000 cannot be converted to text.
-- checks for quoted key names -- checks for quoted key names
-- basic unicode input -- basic unicode input
SELECT '$."\u"'::jsonpath; -- ERROR, incomplete escape SELECT '$."\u"'::jsonpath; -- ERROR, incomplete escape
ERROR: bad jsonpath representation ERROR: invalid unicode sequence at or near "\u" of jsonpath input
LINE 1: SELECT '$."\u"'::jsonpath; LINE 1: SELECT '$."\u"'::jsonpath;
^ ^
DETAIL: Unicode sequence is invalid at or near "\u"
SELECT '$."\u00"'::jsonpath; -- ERROR, incomplete escape SELECT '$."\u00"'::jsonpath; -- ERROR, incomplete escape
ERROR: bad jsonpath representation ERROR: invalid unicode sequence at or near "\u00" of jsonpath input
LINE 1: SELECT '$."\u00"'::jsonpath; LINE 1: SELECT '$."\u00"'::jsonpath;
^ ^
DETAIL: Unicode sequence is invalid at or near "\u00"
SELECT '$."\u000g"'::jsonpath; -- ERROR, g is not a hex digit SELECT '$."\u000g"'::jsonpath; -- ERROR, g is not a hex digit
ERROR: bad jsonpath representation ERROR: invalid unicode sequence at or near "\u000" of jsonpath input
LINE 1: SELECT '$."\u000g"'::jsonpath; LINE 1: SELECT '$."\u000g"'::jsonpath;
^ ^
DETAIL: Unicode sequence is invalid at or near "\u000"
SELECT '$."\u0000"'::jsonpath; -- OK, legal escape SELECT '$."\u0000"'::jsonpath; -- OK, legal escape
ERROR: unsupported Unicode escape sequence ERROR: unsupported Unicode escape sequence
LINE 1: SELECT '$."\u0000"'::jsonpath; LINE 1: SELECT '$."\u0000"'::jsonpath;
......
...@@ -2,17 +2,17 @@ ...@@ -2,17 +2,17 @@
-- checks for double-quoted values -- checks for double-quoted values
-- basic unicode input -- basic unicode input
SELECT '"\u"'::jsonpath; -- ERROR, incomplete escape SELECT '"\u"'::jsonpath; -- ERROR, incomplete escape
ERROR: bad jsonpath representation ERROR: invalid input syntax for type jsonpath
LINE 1: SELECT '"\u"'::jsonpath; LINE 1: SELECT '"\u"'::jsonpath;
^ ^
DETAIL: Unicode sequence is invalid at or near "\u" DETAIL: Unicode sequence is invalid at or near "\u"
SELECT '"\u00"'::jsonpath; -- ERROR, incomplete escape SELECT '"\u00"'::jsonpath; -- ERROR, incomplete escape
ERROR: bad jsonpath representation ERROR: invalid input syntax for type jsonpath
LINE 1: SELECT '"\u00"'::jsonpath; LINE 1: SELECT '"\u00"'::jsonpath;
^ ^
DETAIL: Unicode sequence is invalid at or near "\u00" DETAIL: Unicode sequence is invalid at or near "\u00"
SELECT '"\u000g"'::jsonpath; -- ERROR, g is not a hex digit SELECT '"\u000g"'::jsonpath; -- ERROR, g is not a hex digit
ERROR: bad jsonpath representation ERROR: invalid input syntax for type jsonpath
LINE 1: SELECT '"\u000g"'::jsonpath; LINE 1: SELECT '"\u000g"'::jsonpath;
^ ^
DETAIL: Unicode sequence is invalid at or near "\u000" DETAIL: Unicode sequence is invalid at or near "\u000"
...@@ -156,17 +156,17 @@ DETAIL: \u0000 cannot be converted to text. ...@@ -156,17 +156,17 @@ DETAIL: \u0000 cannot be converted to text.
-- checks for quoted key names -- checks for quoted key names
-- basic unicode input -- basic unicode input
SELECT '$."\u"'::jsonpath; -- ERROR, incomplete escape SELECT '$."\u"'::jsonpath; -- ERROR, incomplete escape
ERROR: bad jsonpath representation ERROR: invalid input syntax for type jsonpath
LINE 1: SELECT '$."\u"'::jsonpath; LINE 1: SELECT '$."\u"'::jsonpath;
^ ^
DETAIL: Unicode sequence is invalid at or near "\u" DETAIL: Unicode sequence is invalid at or near "\u"
SELECT '$."\u00"'::jsonpath; -- ERROR, incomplete escape SELECT '$."\u00"'::jsonpath; -- ERROR, incomplete escape
ERROR: bad jsonpath representation ERROR: invalid input syntax for type jsonpath
LINE 1: SELECT '$."\u00"'::jsonpath; LINE 1: SELECT '$."\u00"'::jsonpath;
^ ^
DETAIL: Unicode sequence is invalid at or near "\u00" DETAIL: Unicode sequence is invalid at or near "\u00"
SELECT '$."\u000g"'::jsonpath; -- ERROR, g is not a hex digit SELECT '$."\u000g"'::jsonpath; -- ERROR, g is not a hex digit
ERROR: bad jsonpath representation ERROR: invalid input syntax for type jsonpath
LINE 1: SELECT '$."\u000g"'::jsonpath; LINE 1: SELECT '$."\u000g"'::jsonpath;
^ ^
DETAIL: Unicode sequence is invalid at or near "\u000" DETAIL: Unicode sequence is invalid at or near "\u000"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment