From 1222db999dc8ad055e0320dd6704d814acca3b51 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 23 Apr 2018 15:29:12 -0400 Subject: [PATCH] Fix handling of partition bounds for boolean partitioning columns. Previously, you could partition by a boolean column as long as you spelled the bound values as string literals, for instance FOR VALUES IN ('t'). The trouble with this is that ruleutils.c printed that as FOR VALUES IN (TRUE), which is reasonable syntax but wasn't accepted by the grammar. That results in dump-and-reload failures for such cases. Apply a minimal fix that just causes TRUE and FALSE to be converted to strings 'true' and 'false'. This is pretty grotty, but it's too late for a more principled fix in v11 (to say nothing of v10). We should revisit the whole issue of how partition bound values are parsed for v12. Amit Langote Discussion: https://postgr.es/m/e05c5162-1103-7e37-d1ab-6de3e0afaf70@lab.ntt.co.jp --- doc/src/sgml/ref/create_table.sgml | 6 +++--- src/backend/parser/gram.y | 2 ++ src/test/regress/expected/create_table.out | 14 ++++++++++++++ src/test/regress/sql/create_table.sql | 7 +++++++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index 18a343c1ab..d52a3c49d6 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -86,9 +86,9 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI and partition_bound_spec is: -IN ( { numeric_literal | string_literal | NULL } [, ...] ) | -FROM ( { numeric_literal | string_literal | MINVALUE | MAXVALUE } [, ...] ) - TO ( { numeric_literal | string_literal | MINVALUE | MAXVALUE } [, ...] ) +IN ( { numeric_literal | string_literal | TRUE | FALSE | NULL } [, ...] ) | +FROM ( { numeric_literal | string_literal | TRUE | FALSE | MINVALUE | MAXVALUE } [, ...] ) + TO ( { numeric_literal | string_literal | TRUE | FALSE | MINVALUE | MAXVALUE } [, ...] ) index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are: diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 3b9b93f84d..43e207a233 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -2649,6 +2649,8 @@ ForValues: partbound_datum: Sconst { $$ = makeStringConst($1, @1); } | NumericOnly { $$ = makeAConst($1, @1); } + | TRUE_P { $$ = makeStringConst(pstrdup("true"), @1); } + | FALSE_P { $$ = makeStringConst(pstrdup("false"), @1); } | NULL_P { $$ = makeNullAConst(@1); } ; diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out index 1e99c96703..68dda4c0db 100644 --- a/src/test/regress/expected/create_table.out +++ b/src/test/regress/expected/create_table.out @@ -811,3 +811,17 @@ Partition of: arrlp FOR VALUES IN ('{1}', '{2}') Partition constraint: ((a IS NOT NULL) AND (((a)::anyarray OPERATOR(pg_catalog.=) '{1}'::integer[]) OR ((a)::anyarray OPERATOR(pg_catalog.=) '{2}'::integer[]))) DROP TABLE arrlp; +-- partition on boolean column +create table boolspart (a bool) partition by list (a); +create table boolspart_t partition of boolspart for values in (true); +create table boolspart_f partition of boolspart for values in (false); +\d+ boolspart + Table "public.boolspart" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | boolean | | | | plain | | +Partition key: LIST (a) +Partitions: boolspart_f FOR VALUES IN (false), + boolspart_t FOR VALUES IN (true) + +drop table boolspart; diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql index 754184756c..89e1059a71 100644 --- a/src/test/regress/sql/create_table.sql +++ b/src/test/regress/sql/create_table.sql @@ -668,3 +668,10 @@ CREATE TABLE arrlp (a int[]) PARTITION BY LIST (a); CREATE TABLE arrlp12 PARTITION OF arrlp FOR VALUES IN ('{1}', '{2}'); \d+ arrlp12 DROP TABLE arrlp; + +-- partition on boolean column +create table boolspart (a bool) partition by list (a); +create table boolspart_t partition of boolspart for values in (true); +create table boolspart_f partition of boolspart for values in (false); +\d+ boolspart +drop table boolspart; -- 2.40.0