Skip to content

Commit 1f9cc96

Browse files
committed
introduce safe function PrelLastChild(), fixes for get_range_by_idx()
1 parent a2c30a5 commit 1f9cc96

File tree

5 files changed

+42
-31
lines changed

5 files changed

+42
-31
lines changed

src/hooks.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTb
227227
rte->inh = true; /* we must restore 'inh' flag! */
228228

229229
children = PrelGetChildrenArray(prel);
230-
ranges = list_make1_irange(make_irange(0, PrelChildrenCount(prel) - 1, false));
230+
ranges = list_make1_irange(make_irange(0, PrelLastChild(prel), false));
231231

232232
/* Make wrappers over restrictions and collect final rangeset */
233233
InitWalkerContext(&context, prel, NULL, false);

src/nodes_common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ rescan_append_common(CustomScanState *node)
502502
Assert(prel);
503503

504504
/* First we select all available partitions... */
505-
ranges = list_make1_irange(make_irange(0, PrelChildrenCount(prel) - 1, false));
505+
ranges = list_make1_irange(make_irange(0, PrelLastChild(prel), false));
506506

507507
InitWalkerContext(&scan_state->wcxt, prel, econtext, false);
508508
foreach (lc, scan_state->custom_exprs)

src/pg_pathman.c

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ handle_modification_query(Query *parse)
320320
return;
321321

322322
/* Parse syntax tree and extract partition ranges */
323-
ranges = list_make1_irange(make_irange(0, PrelChildrenCount(prel) - 1, false));
323+
ranges = list_make1_irange(make_irange(0, PrelLastChild(prel), false));
324324
expr = (Expr *) eval_const_expressions(NULL, parse->jointree->quals);
325325
if (!expr)
326326
return;
@@ -680,7 +680,7 @@ walk_expr_tree(Expr *expr, WalkerContext *context)
680680
result->orig = (const Node *) expr;
681681
result->args = NIL;
682682
result->rangeset = list_make1_irange(
683-
make_irange(0, PrelChildrenCount(context->prel) - 1, true));
683+
make_irange(0, PrelLastChild(context->prel), true));
684684
result->paramsel = 1.0;
685685
return result;
686686
}
@@ -839,7 +839,7 @@ create_partitions_internal(Oid relid, Datum value, Oid value_type)
839839

840840
/* Read max & min range values from PartRelationInfo */
841841
min_rvalue = prel->ranges[0].min;
842-
max_rvalue = prel->ranges[PrelChildrenCount(prel) - 1].max;
842+
max_rvalue = prel->ranges[PrelLastChild(prel)].max;
843843

844844
/* If this is a *date type*, cast 'range_interval' to INTERVAL */
845845
if (is_date_type_internal(value_type))
@@ -1183,9 +1183,7 @@ handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
11831183
elog(ERROR, "Unknown partitioning type %u", prel->parttype);
11841184
}
11851185

1186-
result->rangeset = list_make1_irange(make_irange(0,
1187-
PrelChildrenCount(prel) - 1,
1188-
true));
1186+
result->rangeset = list_make1_irange(make_irange(0, PrelLastChild(prel), true));
11891187
result->paramsel = 1.0;
11901188
}
11911189

@@ -1211,9 +1209,7 @@ handle_binary_opexpr_param(const PartRelationInfo *prel,
12111209
tce = lookup_type_cache(vartype, TYPECACHE_BTREE_OPFAMILY);
12121210
strategy = get_op_opfamily_strategy(expr->opno, tce->btree_opf);
12131211

1214-
result->rangeset = list_make1_irange(make_irange(0,
1215-
PrelChildrenCount(prel) - 1,
1216-
true));
1212+
result->rangeset = list_make1_irange(make_irange(0, PrelLastChild(prel), true));
12171213

12181214
if (strategy == BTEqualStrategyNumber)
12191215
{
@@ -1311,7 +1307,7 @@ handle_const(const Const *c, WalkerContext *context)
13111307
if (!context->for_insert)
13121308
{
13131309
result->rangeset = list_make1_irange(make_irange(0,
1314-
PrelChildrenCount(prel) - 1,
1310+
PrelLastChild(prel),
13151311
true));
13161312
result->paramsel = 1.0;
13171313

@@ -1382,9 +1378,7 @@ handle_opexpr(const OpExpr *expr, WalkerContext *context)
13821378
}
13831379
}
13841380

1385-
result->rangeset = list_make1_irange(make_irange(0,
1386-
PrelChildrenCount(prel) - 1,
1387-
true));
1381+
result->rangeset = list_make1_irange(make_irange(0, PrelLastChild(prel), true));
13881382
result->paramsel = 1.0;
13891383
return result;
13901384
}
@@ -1456,7 +1450,7 @@ handle_boolexpr(const BoolExpr *expr, WalkerContext *context)
14561450

14571451
if (expr->boolop == AND_EXPR)
14581452
result->rangeset = list_make1_irange(make_irange(0,
1459-
PrelChildrenCount(prel) - 1,
1453+
PrelLastChild(prel),
14601454
false));
14611455
else
14621456
result->rangeset = NIL;
@@ -1479,7 +1473,7 @@ handle_boolexpr(const BoolExpr *expr, WalkerContext *context)
14791473
break;
14801474
default:
14811475
result->rangeset = list_make1_irange(make_irange(0,
1482-
PrelChildrenCount(prel) - 1,
1476+
PrelLastChild(prel),
14831477
false));
14841478
break;
14851479
}
@@ -1581,9 +1575,7 @@ handle_arrexpr(const ScalarArrayOpExpr *expr, WalkerContext *context)
15811575
result->paramsel = DEFAULT_INEQ_SEL;
15821576

15831577
handle_arrexpr_return:
1584-
result->rangeset = list_make1_irange(make_irange(0,
1585-
PrelChildrenCount(prel) - 1,
1586-
true));
1578+
result->rangeset = list_make1_irange(make_irange(0, PrelLastChild(prel), true));
15871579
return result;
15881580
}
15891581

src/pl_funcs.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "pathman.h"
1212
#include "init.h"
1313
#include "utils.h"
14+
#include "relation_info.h"
1415

1516
#include "access/htup_details.h"
1617
#include "access/nbtree.h"
@@ -289,17 +290,23 @@ get_range_by_idx(PG_FUNCTION_ARGS)
289290
prel = get_pathman_relation_info(parent_oid);
290291
shout_if_prel_is_invalid(parent_oid, prel, PT_RANGE);
291292

292-
if (((uint32) abs(idx)) >= PrelChildrenCount(prel))
293+
/* Now we have to deal with 'idx' */
294+
if (idx < -1)
295+
{
296+
elog(ERROR, "Negative indices other than -1 (last partition) are not allowed");
297+
}
298+
else if (idx == -1 && PrelChildrenCount(prel) > 0)
299+
{
300+
idx = PrelLastChild(prel);
301+
}
302+
else if (((uint32) abs(idx)) >= PrelChildrenCount(prel))
303+
{
293304
elog(ERROR, "Partition #%d does not exist (total amount is %u)",
294305
idx, PrelChildrenCount(prel));
306+
}
295307

296308
ranges = PrelGetRangesArray(prel);
297309

298-
if (idx == -1)
299-
idx = PrelChildrenCount(prel) - 1;
300-
else if (idx < -1)
301-
elog(ERROR, "Negative indices other than -1 (last partition) are not allowed");
302-
303310
elems[0] = ranges[idx].min;
304311
elems[1] = ranges[idx].max;
305312

@@ -343,7 +350,7 @@ get_max_range_value(PG_FUNCTION_ARGS)
343350

344351
ranges = PrelGetRangesArray(prel);
345352

346-
PG_RETURN_DATUM(ranges[PrelChildrenCount(prel) - 1].max);
353+
PG_RETURN_DATUM(ranges[PrelLastChild(prel)].max);
347354
}
348355

349356
/*

src/relation_info.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,25 @@ typedef enum
107107
* PartRelationInfo field access macros.
108108
*/
109109

110-
#define PrelGetChildrenArray(prel) ( (prel)->children )
110+
#define PrelGetChildrenArray(prel) ( (prel)->children )
111111

112-
#define PrelGetRangesArray(prel) ( (prel)->ranges )
112+
#define PrelGetRangesArray(prel) ( (prel)->ranges )
113113

114-
#define PrelChildrenCount(prel) ( (prel)->children_count )
114+
#define PrelChildrenCount(prel) ( (prel)->children_count )
115115

116-
#define PrelIsValid(prel) ( (prel) && (prel)->valid )
116+
#define PrelIsValid(prel) ( (prel) && (prel)->valid )
117+
118+
inline static uint32
119+
PrelLastChild(const PartRelationInfo *prel)
120+
{
121+
Assert(PrelIsValid(prel));
122+
123+
if (PrelChildrenCount(prel) == 0)
124+
elog(ERROR, "pg_pathman's cache entry for relation %u has 0 children",
125+
prel->key);
126+
127+
return PrelChildrenCount(prel) - 1; /* last partition */
128+
}
117129

118130

119131
const PartRelationInfo *refresh_pathman_relation_info(Oid relid,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy