Skip to content

Commit a2c30a5

Browse files
committed
improve error handling during pg_pathman's initialization
1 parent a4a4160 commit a2c30a5

File tree

1 file changed

+51
-15
lines changed

1 file changed

+51
-15
lines changed

src/init.c

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
#define PART_RELS_SIZE 10
4343
#define CHILD_FACTOR 500
4444

45-
4645
/* Storage for PartRelationInfos */
4746
HTAB *partitioned_rels = NULL;
4847

@@ -52,6 +51,9 @@ HTAB *parent_cache = NULL;
5251
bool initialization_needed = true;
5352
static bool relcache_callback_needed = true;
5453

54+
/* Help user in case of emergency */
55+
#define INIT_ERROR_HINT "pg_pathman will be disabled to allow you fix this"
56+
5557

5658
static bool init_pathman_relation_oids(void);
5759
static void fini_pathman_relation_oids(void);
@@ -284,9 +286,13 @@ fill_prel_with_partitions(const Oid *partitions,
284286
if (validate_hash_constraint(con_expr, prel, &hash))
285287
prel->children[hash] = partitions[i];
286288
else
287-
elog(ERROR,
288-
"Wrong constraint format for HASH partition \"%s\"",
289-
get_rel_name_or_relid(partitions[i]));
289+
{
290+
DisablePathman(); /* disable pg_pathman since config is broken */
291+
ereport(ERROR,
292+
(errmsg("Wrong constraint format for HASH partition \"%s\"",
293+
get_rel_name_or_relid(partitions[i])),
294+
errhint(INIT_ERROR_HINT)));
295+
}
290296
}
291297
break;
292298

@@ -302,15 +308,24 @@ fill_prel_with_partitions(const Oid *partitions,
302308
prel->ranges[i].max = range_max;
303309
}
304310
else
305-
elog(ERROR,
306-
"Wrong constraint format for RANGE partition \"%s\"",
307-
get_rel_name_or_relid(partitions[i]));
311+
{
312+
DisablePathman(); /* disable pg_pathman since config is broken */
313+
ereport(ERROR,
314+
(errmsg("Wrong constraint format for RANGE partition \"%s\"",
315+
get_rel_name_or_relid(partitions[i])),
316+
errhint(INIT_ERROR_HINT)));
317+
}
308318
}
309319
break;
310320

311321
default:
312-
elog(ERROR, "Unknown partitioning type for relation \"%s\"",
313-
get_rel_name_or_relid(prel->key));
322+
{
323+
DisablePathman(); /* disable pg_pathman since config is broken */
324+
ereport(ERROR,
325+
(errmsg("Unknown partitioning type for relation \"%s\"",
326+
get_rel_name_or_relid(prel->key)),
327+
errhint(INIT_ERROR_HINT)));
328+
}
314329
}
315330
}
316331

@@ -350,9 +365,12 @@ fill_prel_with_partitions(const Oid *partitions,
350365
for (i = 0; i < PrelChildrenCount(prel); i++)
351366
{
352367
if (prel->children[i] == InvalidOid)
368+
{
369+
DisablePathman(); /* disable pg_pathman since config is broken */
353370
elog(ERROR, "pg_pathman's cache for relation \"%s\" "
354371
"has not been properly initialized",
355372
get_rel_name_or_relid(prel->key));
373+
}
356374
}
357375
#endif
358376
}
@@ -605,11 +623,10 @@ read_pathman_config(void)
605623
if (get_rel_type_id(relid) == InvalidOid)
606624
{
607625
DisablePathman(); /* disable pg_pathman since config is broken */
608-
609626
ereport(ERROR,
610627
(errmsg("Table \"%s\" contains nonexistent relation %u",
611628
PATHMAN_CONFIG, relid),
612-
errdetail("pg_pathman will be disabled")));
629+
errhint(INIT_ERROR_HINT)));
613630
}
614631

615632
/* Create or update PartRelationInfo for this partitioned table */
@@ -638,17 +655,30 @@ get_partition_constraint_expr(Oid partition, AttrNumber part_attno)
638655
Expr *expr; /* expression tree for constraint */
639656

640657
conname = build_check_constraint_name_internal(partition, part_attno);
641-
conid = get_relation_constraint_oid(partition, conname, false);
658+
conid = get_relation_constraint_oid(partition, conname, true);
659+
if (conid == InvalidOid)
660+
{
661+
DisablePathman(); /* disable pg_pathman since config is broken */
662+
ereport(ERROR,
663+
(errmsg("constraint \"%s\" for partition \"%s\" does not exist",
664+
conname, get_rel_name_or_relid(partition)),
665+
errhint(INIT_ERROR_HINT)));
666+
}
642667

643668
con_tuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(conid));
644669
conbin_datum = SysCacheGetAttr(CONSTROID, con_tuple,
645670
Anum_pg_constraint_conbin,
646671
&conbin_isnull);
647672
if (conbin_isnull)
648673
{
649-
elog(DEBUG2, "conbin is null for constraint %s", conname);
674+
DisablePathman(); /* disable pg_pathman since config is broken */
675+
ereport(WARNING,
676+
(errmsg("constraint \"%s\" for partition \"%s\" has NULL conbin",
677+
conname, get_rel_name_or_relid(partition)),
678+
errhint(INIT_ERROR_HINT)));
650679
pfree(conname);
651-
return NULL;
680+
681+
return NULL; /* could not parse */
652682
}
653683
pfree(conname);
654684

@@ -690,6 +720,9 @@ validate_range_constraint(const Expr *expr,
690720
const BoolExpr *boolexpr = (const BoolExpr *) expr;
691721
const OpExpr *opexpr;
692722

723+
if (!expr)
724+
return false;
725+
693726
/* it should be an AND operator on top */
694727
if (!and_clause((Node *) expr))
695728
return false;
@@ -779,6 +812,9 @@ validate_hash_constraint(const Expr *expr,
779812
*type_hash_proc_expr;
780813
const Var *var; /* partitioned column */
781814

815+
if (!expr)
816+
return false;
817+
782818
if (!IsA(expr, OpExpr))
783819
return false;
784820
eq_expr = (const OpExpr *) expr;
@@ -825,7 +861,7 @@ validate_hash_constraint(const Expr *expr,
825861
return false;
826862

827863
/* Check that PARTITIONS_COUNT is equal to total amount of partitions */
828-
if (DatumGetUInt32(((Const*) second)->constvalue) != PrelChildrenCount(prel))
864+
if (DatumGetUInt32(((Const *) second)->constvalue) != PrelChildrenCount(prel))
829865
return false;
830866

831867
/* Check that CUR_PARTITION_HASH is Const */

0 commit comments

Comments
 (0)