Обсуждение: BUG #16325: Assert failure on partitioning by int for a text value with a collation
BUG #16325: Assert failure on partitioning by int for a text value with a collation
От
PG Bug reporting form
Дата:
The following bug has been logged on the website:
Bug reference: 16325
Logged by: Alexander Lakhin
Email address: exclusion@gmail.com
PostgreSQL version: 12.2
Operating system: Ubuntu 18.04
Description:
The following query:
create table parted (i int) partition by list (i);
create table part_coll partition of parted for values in ('1' collate
"POSIX");
leads to an assert failure with the following stack trace:
Core was generated by `postgres: law regression [local] CREATE TABLE
'.
Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007f4e455fa801 in __GI_abort () at abort.c:79
#2 0x000055cd3d082f40 in ExceptionalCondition (
conditionName=conditionName@entry=0x55cd3d2b1f5b "!(strvalue != ((void
*)0))",
errorType=errorType@entry=0x55cd3d0d9e88 "FailedAssertion",
fileName=fileName@entry=0x55cd3d2b1f50 "snprintf.c",
lineNumber=lineNumber@entry=442) at assert.c:54
#3 0x000055cd3d0d0903 in dopr (target=target@entry=0x7ffe43ec6310,
format=0x55cd3d1fbfcd "\"",
format@entry=0x55cd3d1fbf70 "collation of partition bound value for
column \"%s\" does not match partition key collation \"%s\"",
args=0x7ffe43ec63c0) at snprintf.c:442
#4 0x000055cd3d0d0ff4 in pg_vsnprintf (str=<optimized out>,
count=<optimized out>, count@entry=1024,
fmt=fmt@entry=0x55cd3d1fbf70 "collation of partition bound value for
column \"%s\" does not match partition key collation \"%s\"",
args=args@entry=0x7ffe43ec63c0) at snprintf.c:195
#5 0x000055cd3d0d6e3c in pvsnprintf (buf=<optimized out>,
len=len@entry=1024,
fmt=fmt@entry=0x55cd3d1fbf70 "collation of partition bound value for
column \"%s\" does not match partition key collation \"%s\"",
args=args@entry=0x7ffe43ec63c0) at psprintf.c:110
#6 0x000055cd3ce1b357 in appendStringInfoVA (str=str@entry=0x7ffe43ec63a0,
fmt=fmt@entry=0x55cd3d1fbf70 "collation of partition bound value for
column \"%s\" does not match partition key collation \"%s\"",
args=args@entry=0x7ffe43ec63c0) at stringinfo.c:136
#7 0x000055cd3d087371 in errmsg (
fmt=fmt@entry=0x55cd3d1fbf70 "collation of partition bound value for
column \"%s\" does not match partition key collation \"%s\"") at
elog.c:794
#8 0x000055cd3cd3e3a4 in transformPartitionBoundValue
(pstate=pstate@entry=0x55cd3ed58148, val=0x55cd3ecbb1a8,
colName=colName@entry=0x55cd3ed58680 "i", colType=colType@entry=23,
colTypmod=colTypmod@entry=-1,
partCollation=partCollation@entry=0) at parse_utilcmd.c:4043
#9 0x000055cd3cd41231 in transformPartitionBound
(pstate=pstate@entry=0x55cd3ed58148,
parent=parent@entry=0x7f4e46f86290, spec=<optimized out>) at
parse_utilcmd.c:3802
#10 0x000055cd3cda67e4 in DefineRelation (stmt=stmt@entry=0x55cd3ed5a620,
relkind=relkind@entry=114 'r', ownerId=10,
ownerId@entry=0, typaddress=typaddress@entry=0x0,
queryString=queryString@entry=0x55cd3ec97fd8 "create table part_coll
partition of parted for values in ('1' collate \"POSIX\");") at
tablecmds.c:972
#11 0x000055cd3cf5ed12 in ProcessUtilitySlow
(pstate=pstate@entry=0x55cd3ed5a508, pstmt=pstmt@entry=0x55cd3ec99138,
queryString=queryString@entry=0x55cd3ec97fd8 "create table part_coll
partition of parted for values in ('1' collate \"POSIX\");",
context=context@entry=PROCESS_UTILITY_TOPLEVEL, params=params@entry=0x0,
queryEnv=queryEnv@entry=0x0,
dest=0x55cd3ec99230, completionTag=0x7ffe43ec6d30 "") at
utility.c:1014
#12 0x000055cd3cf5eac6 in standard_ProcessUtility (pstmt=0x55cd3ec99138,
queryString=0x55cd3ec97fd8 "create table part_coll partition of parted
for values in ('1' collate \"POSIX\");",
context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0,
dest=0x55cd3ec99230, completionTag=0x7ffe43ec6d30 "")
at utility.c:927
#13 0x000055cd3cf5eb74 in ProcessUtility (pstmt=pstmt@entry=0x55cd3ec99138,
queryString=<optimized out>,
context=context@entry=PROCESS_UTILITY_TOPLEVEL, params=<optimized out>,
queryEnv=<optimized out>,
dest=dest@entry=0x55cd3ec99230, completionTag=0x7ffe43ec6d30 "") at
utility.c:360
#14 0x000055cd3cf5b026 in PortalRunUtility
(portal=portal@entry=0x55cd3ecff288, pstmt=pstmt@entry=0x55cd3ec99138,
isTopLevel=isTopLevel@entry=true,
setHoldSnapshot=setHoldSnapshot@entry=false, dest=dest@entry=0x55cd3ec99230,
completionTag=completionTag@entry=0x7ffe43ec6d30 "") at pquery.c:1175
#15 0x000055cd3cf5bc70 in PortalRunMulti
(portal=portal@entry=0x55cd3ecff288, isTopLevel=isTopLevel@entry=true,
setHoldSnapshot=setHoldSnapshot@entry=false,
dest=dest@entry=0x55cd3ec99230, altdest=altdest@entry=0x55cd3ec99230,
completionTag=completionTag@entry=0x7ffe43ec6d30 "") at pquery.c:1321
#16 0x000055cd3cf5c9df in PortalRun (portal=portal@entry=0x55cd3ecff288,
count=count@entry=9223372036854775807,
isTopLevel=isTopLevel@entry=true, run_once=run_once@entry=true,
dest=dest@entry=0x55cd3ec99230,
altdest=altdest@entry=0x55cd3ec99230, completionTag=0x7ffe43ec6d30 "")
at pquery.c:796
#17 0x000055cd3cf58cc3 in exec_simple_query (
query_string=query_string@entry=0x55cd3ec97fd8 "create table part_coll
partition of parted for values in ('1' collate \"POSIX\");") at
postgres.c:1215
#18 0x000055cd3cf5ac67 in PostgresMain (argc=<optimized out>,
argv=argv@entry=0x55cd3ecc3388, dbname=<optimized out>,
username=<optimized out>) at postgres.c:4247
#19 0x000055cd3ceccf37 in BackendRun (port=port@entry=0x55cd3ecbba60) at
postmaster.c:4437
#20 0x000055cd3ced0229 in BackendStartup (port=port@entry=0x55cd3ecbba60) at
postmaster.c:4128
#21 0x000055cd3ced0545 in ServerLoop () at postmaster.c:1704
#22 0x000055cd3ced195e in PostmasterMain (argc=3, argv=<optimized out>) at
postmaster.c:1377
#23 0x000055cd3ce2cdf4 in main (argc=3, argv=0x55cd3ec92630) at main.c:228
Reproduced on REL_12..master.
Re: BUG #16325: Assert failure on partitioning by int for a textvalue with a collation
От
Dmitry Dolgov
Дата:
> On Sat, Mar 28, 2020 at 05:43:05AM +0000, PG Bug reporting form wrote:
>
>
> The following query:
> create table parted (i int) partition by list (i);
> create table part_coll partition of parted for values in ('1' collate
> "POSIX");
>
> leads to an assert failure with the following stack trace:
Thanks for reporting! Looks like transformPartitionBoundValue needs to
check that the source collumn is collatable, then we get more expected
result:
=# create table part_coll partition of parted for values in ('1' collate "POSIX");
ERROR: 42804: collations are not supported by type integer
Вложения
Re: BUG #16325: Assert failure on partitioning by int for a textvalue with a collation
От
Michael Paquier
Дата:
On Sat, Mar 28, 2020 at 01:53:03PM +0100, Dmitry Dolgov wrote:
> Thanks for reporting! Looks like transformPartitionBoundValue needs to
> check that the source collumn is collatable, then we get more expected
> result:
>
> =# create table part_coll partition of parted for values in ('1' collate "POSIX");
> ERROR: 42804: collations are not supported by type integer
We have here a side effect of 7c079d74, that has given the possibility
to pass down general expressions for partition bounds.
> + if (type_is_collatable(colType))
> + {
> + if (!OidIsValid(exprCollOid))
> + ereport(ERROR,
> + (errcode(ERRCODE_INDETERMINATE_COLLATION),
> + errmsg("could not determine which collation to use for partition expression"),
> + errhint("Use the COLLATE clause to set the collation explicitly.")));
> + }
> + else
> + {
> + if (OidIsValid(exprCollOid))
> + ereport(ERROR,
> + (errcode(ERRCODE_DATATYPE_MISMATCH),
> + errmsg("collations are not supported by type %s",
> + format_type_be(colType))));
> + }
> +
It seems to me that the first error cannot happen, and should not
happen. When the expression is transformed, there is a lookup at the
collation used via transformCollateClause() -> LookupCollation() ->
get_collation_oid() which would never return an invalid OID if the
collation exists, throwing an error instead. The reason why a similar
check exists in tablecmds.c is that there can be a collation override,
no?
--
Michael
Вложения
Re: BUG #16325: Assert failure on partitioning by int for a textvalue with a collation
От
Dmitry Dolgov
Дата:
> On Wed, Apr 01, 2020 at 04:08:42PM +0900, Michael Paquier wrote:
> > On Sat, Mar 28, 2020 at 01:53:03PM +0100, Dmitry Dolgov wrote:
> > Thanks for reporting! Looks like transformPartitionBoundValue needs to
> > check that the source collumn is collatable, then we get more expected
> > result:
> >
> > =# create table part_coll partition of parted for values in ('1' collate "POSIX");
> > ERROR: 42804: collations are not supported by type integer
>
> We have here a side effect of 7c079d74, that has given the possibility
> to pass down general expressions for partition bounds.
Yep. That's why I've placed a test for this fix close to those
introduced in this commit.
> > + if (type_is_collatable(colType))
> > + {
> > + if (!OidIsValid(exprCollOid))
> > + ereport(ERROR,
> > + (errcode(ERRCODE_INDETERMINATE_COLLATION),
> > + errmsg("could not determine which collation to use for partition expression"),
> > + errhint("Use the COLLATE clause to set the collation explicitly.")));
> > + }
> > + else
> > + {
> > + if (OidIsValid(exprCollOid))
> > + ereport(ERROR,
> > + (errcode(ERRCODE_DATATYPE_MISMATCH),
> > + errmsg("collations are not supported by type %s",
> > + format_type_be(colType))));
> > + }
> > +
>
> It seems to me that the first error cannot happen, and should not
> happen. When the expression is transformed, there is a lookup at the
> collation used via transformCollateClause() -> LookupCollation() ->
> get_collation_oid() which would never return an invalid OID if the
> collation exists, throwing an error instead. The reason why a similar
> check exists in tablecmds.c is that there can be a collation override,
> no?
Good point, I believe you're right. This means that the fix can be
reduced as in attachments.
Вложения
Re: BUG #16325: Assert failure on partitioning by int for a textvalue with a collation
От
Michael Paquier
Дата:
On Wed, Apr 01, 2020 at 02:01:17PM +0200, Dmitry Dolgov wrote:
> On Wed, Apr 01, 2020 at 04:08:42PM +0900, Michael Paquier wrote:
>> It seems to me that the first error cannot happen, and should not
>> happen. When the expression is transformed, there is a lookup at the
>> collation used via transformCollateClause() -> LookupCollation() ->
>> get_collation_oid() which would never return an invalid OID if the
>> collation exists, throwing an error instead. The reason why a similar
>> check exists in tablecmds.c is that there can be a collation override,
>> no?
>
> Good point, I believe you're right. This means that the fix can be
> reduced as in attachments.
Thanks.
> + /*
> + * No need to check if exprCollOid is invalid, since if it would be,
> + * then transformCollateClause will throw an error earlier
> + */
> + if (!type_is_collatable(colType))
> + ereport(ERROR,
> + (errcode(ERRCODE_DATATYPE_MISMATCH),
> + errmsg("collations are not supported by type %s",
> + format_type_be(colType))));
> +
>
> if (OidIsValid(exprCollOid) &&
> exprCollOid != DEFAULT_COLLATION_OID &&
> exprCollOid != partCollation)
Another point that could be made is that as we know that we are in the
presence of a CollateExpr() here, and exprCollOid will never be
InvalidOid. So there could be a point in using an assertion instead
of the check done below making sure that exprCollOid is always valid?
--
Michael
Вложения
Re: BUG #16325: Assert failure on partitioning by int for a textvalue with a collation
От
Dmitry Dolgov
Дата:
> On Thu, Apr 02, 2020 at 11:01:50AM +0900, Michael Paquier wrote:
>
> > + /*
> > + * No need to check if exprCollOid is invalid, since if it would be,
> > + * then transformCollateClause will throw an error earlier
> > + */
> > + if (!type_is_collatable(colType))
> > + ereport(ERROR,
> > + (errcode(ERRCODE_DATATYPE_MISMATCH),
> > + errmsg("collations are not supported by type %s",
> > + format_type_be(colType))));
> > +
> >
> > if (OidIsValid(exprCollOid) &&
> > exprCollOid != DEFAULT_COLLATION_OID &&
> > exprCollOid != partCollation)
>
> Another point that could be made is that as we know that we are in the
> presence of a CollateExpr() here, and exprCollOid will never be
> InvalidOid. So there could be a point in using an assertion instead
> of the check done below making sure that exprCollOid is always valid?
Thanks for the suggestion. It's not strictly related to the fix I guess,
but of course you're right, and we can indeed improve this part and
replace the check with an assert.
Вложения
Re: BUG #16325: Assert failure on partitioning by int for a textvalue with a collation
От
Michael Paquier
Дата:
On Fri, Apr 03, 2020 at 05:29:10PM +0200, Dmitry Dolgov wrote: > Thanks for the suggestion. It's not strictly related to the fix I guess, > but of course you're right, and we can indeed improve this part and > replace the check with an assert. Thanks for the new version of the patch. I have been playing a bit today, and finished with the version attached. Some comments have been tweaked, and I have moved the test in the block with the other invalid cases for consistency, adding an extra test able to trigger a similar error within the transformation step where a parse context exists. It is a bit late now so I cannot push that today, but I'll do that tomorrow. -- Michael
Вложения
Re: BUG #16325: Assert failure on partitioning by int for a textvalue with a collation
От
Michael Paquier
Дата:
On Tue, Apr 07, 2020 at 04:49:44PM +0900, Michael Paquier wrote: > Thanks for the new version of the patch. I have been playing a bit > today, and finished with the version attached. Some comments have > been tweaked, and I have moved the test in the block with the other > invalid cases for consistency, adding an extra test able to trigger a > similar error within the transformation step where a parse context > exists. It is a bit late now so I cannot push that today, but I'll > do that tomorrow. I was considering this stuff again, and I got cold feet regarding the fact that we may be able to hit the case of a collation not set if the type is collatable depending on how the restrictions now in place for partition bound expressions get lifted in the future, so I have committed what you sent as v1, after changing the first error message to use "partition bound expression" and after adding a comment on top of the new checks. -- Michael
Вложения
Re: BUG #16325: Assert failure on partitioning by int for a textvalue with a collation
От
Dmitry Dolgov
Дата:
> On Wed, Apr 08, 2020 at 03:06:39PM +0900, Michael Paquier wrote: > > I was considering this stuff again, and I got cold feet regarding the > fact that we may be able to hit the case of a collation not set if the > type is collatable depending on how the restrictions now in place for > partition bound expressions get lifted in the future, so I have > committed what you sent as v1, after changing the first error message > to use "partition bound expression" and after adding a comment on top > of the new checks. Thanks!