Skip to content

Commit d0fb4b4

Browse files
committed
Simplify retention policy chunk dropping
Call function to drop chunks directly instead of going through function manager.
1 parent 5d11033 commit d0fb4b4

5 files changed

Lines changed: 85 additions & 109 deletions

File tree

src/chunk.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4001,6 +4001,84 @@ ts_chunk_drop_single_chunk(PG_FUNCTION_ARGS)
40014001
PG_RETURN_BOOL(true);
40024002
}
40034003

4004+
/*
4005+
* Drop chunks from a hypertable, dropping everything older than the given boundary.
4006+
*
4007+
* The boundary is either an "older_than" value (matched against the chunk
4008+
* ranges) or, when use_creation_time is set, a "drop_created_before" value
4009+
* (matched against the chunk creation time).
4010+
*
4011+
* Returns the number of dropped chunks.
4012+
*/
4013+
int
4014+
ts_chunk_drop_chunks_by_boundary(Oid relid, Datum older_than, Oid older_than_type,
4015+
bool use_creation_time)
4016+
{
4017+
Cache *hcache = ts_hypertable_cache_pin();
4018+
Hypertable *ht = ts_resolve_hypertable_from_table_or_cagg(hcache, relid, false);
4019+
const Dimension *time_dim = hyperspace_get_open_dimension(ht->space, 0);
4020+
Oid time_type = ts_dimension_get_partition_type(time_dim);
4021+
int64 older_than_internal;
4022+
bool older_newer;
4023+
List *dropped_chunks;
4024+
MemoryContext oldcontext = CurrentMemoryContext;
4025+
4026+
/* UUID (v7) partitioning is treated as TIMESTAMPTZ, matching the boundary. */
4027+
if (IS_UUID_TYPE(time_type))
4028+
{
4029+
time_type = TIMESTAMPTZOID;
4030+
}
4031+
4032+
if (use_creation_time)
4033+
{
4034+
/* drop_created_before compares against the chunk creation time. */
4035+
int64 created_before =
4036+
ts_time_value_from_arg(older_than, older_than_type, TIMESTAMPTZOID, false);
4037+
older_than_internal = ts_internal_to_time_int64(created_before, TIMESTAMPTZOID);
4038+
older_newer = false;
4039+
}
4040+
else
4041+
{
4042+
older_than_internal = ts_time_value_from_arg(older_than, older_than_type, time_type, true);
4043+
older_newer = true;
4044+
}
4045+
4046+
PG_TRY();
4047+
{
4048+
dropped_chunks = ts_chunk_do_drop_chunks(ht,
4049+
older_than_internal,
4050+
PG_INT64_MIN,
4051+
DEBUG2,
4052+
time_type,
4053+
older_than_type,
4054+
older_newer);
4055+
}
4056+
PG_CATCH();
4057+
{
4058+
/* Replace the generic dependent objects hint with an accurate one since
4059+
* we don't support CASCADE here. */
4060+
ErrorData *edata;
4061+
4062+
/* CopyErrorData requires we leave the error context first. */
4063+
MemoryContextSwitchTo(oldcontext);
4064+
edata = CopyErrorData();
4065+
FlushErrorState();
4066+
4067+
if (edata->sqlerrcode == ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST)
4068+
{
4069+
edata->hint = pstrdup("Use DROP ... to drop the dependent objects.");
4070+
}
4071+
4072+
ts_cache_release(&hcache);
4073+
ReThrowError(edata);
4074+
}
4075+
PG_END_TRY();
4076+
4077+
ts_cache_release(&hcache);
4078+
4079+
return list_length(dropped_chunks);
4080+
}
4081+
40044082
Datum
40054083
ts_chunk_drop_chunks(PG_FUNCTION_ARGS)
40064084
{

src/chunk.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ extern TSDLLEXPORT void ts_chunk_drop_by_relid(Oid relid, DropBehavior behavior,
213213
extern TSDLLEXPORT List *ts_chunk_do_drop_chunks(Hypertable *ht, int64 older_than, int64 newer_than,
214214
int32 log_level, Oid time_type, Oid arg_type,
215215
bool older_newer);
216+
extern TSDLLEXPORT int ts_chunk_drop_chunks_by_boundary(Oid relid, Datum older_than,
217+
Oid older_than_type,
218+
bool use_creation_time);
216219
extern TSDLLEXPORT Chunk *
217220
ts_chunk_find_or_create_without_cuts(const Hypertable *ht, Hypercube *hc, const char *schema_name,
218221
const char *table_name, Oid chunk_table_relid, bool *created);

tsl/src/bgw_policy/job.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,10 @@ policy_retention_execute(int32 job_id, Jsonb *config)
300300
log_retention_boundary(LOG, &policy_data, "applying retention policy to hypertable");
301301
}
302302

303-
chunk_invoke_drop_chunks(policy_data.object_relid,
304-
policy_data.boundary,
305-
policy_data.boundary_type,
306-
policy_data.use_creation_time);
303+
ts_chunk_drop_chunks_by_boundary(policy_data.object_relid,
304+
policy_data.boundary,
305+
policy_data.boundary_type,
306+
policy_data.use_creation_time);
307307

308308
return true;
309309
}

tsl/src/chunk.c

Lines changed: 0 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434
#include "chunk.h"
3535
#include "compression/compression.h"
3636
#include "debug_point.h"
37-
#include "extension.h"
38-
#include "hypertable.h"
3937
#include "utils.h"
4038

4139
/* Data in a frozen chunk cannot be modified. So any operation
@@ -94,104 +92,3 @@ chunk_unfreeze_chunk(PG_FUNCTION_ARGS)
9492
bool ret = ts_chunk_unset_frozen(chunk);
9593
PG_RETURN_BOOL(ret);
9694
}
97-
98-
/*
99-
* Invoke drop_chunks via fmgr so that the call can be deparsed and sent to
100-
* remote data nodes.
101-
*
102-
* Given that drop_chunks is an SRF, and has pseudo parameter types, we need
103-
* to provide a FuncExpr with type information for the deparser.
104-
*
105-
* Returns the number of dropped chunks.
106-
*/
107-
int
108-
chunk_invoke_drop_chunks(Oid relid, Datum older_than, Datum older_than_type, bool use_creation_time)
109-
{
110-
EState *estate;
111-
ExprContext *econtext;
112-
FuncExpr *fexpr;
113-
List *args = NIL;
114-
int num_results = 0;
115-
SetExprState *state;
116-
Oid restype;
117-
Oid func_oid;
118-
Const *TypeNullCons = makeNullConst(older_than_type, -1, InvalidOid);
119-
Const *IntervalVal = makeConst(older_than_type,
120-
-1,
121-
InvalidOid,
122-
get_typlen(older_than_type),
123-
older_than,
124-
false,
125-
get_typbyval(older_than_type));
126-
Const *argarr[DROP_CHUNKS_NARGS] = { makeConst(REGCLASSOID,
127-
-1,
128-
InvalidOid,
129-
sizeof(relid),
130-
ObjectIdGetDatum(relid),
131-
false,
132-
false),
133-
TypeNullCons,
134-
TypeNullCons,
135-
castNode(Const, makeBoolConst(false, true)),
136-
TypeNullCons,
137-
TypeNullCons };
138-
Oid type_id[DROP_CHUNKS_NARGS] = { REGCLASSOID, ANYOID, ANYOID, BOOLOID, ANYOID, ANYOID };
139-
char *const schema_name = ts_extension_schema_name();
140-
List *const fqn = list_make2(makeString(schema_name), makeString(DROP_CHUNKS_FUNCNAME));
141-
142-
StaticAssertStmt(lengthof(type_id) == lengthof(argarr),
143-
"argarr and type_id should have matching lengths");
144-
145-
func_oid = LookupFuncName(fqn, lengthof(type_id), type_id, false);
146-
Assert(func_oid); /* LookupFuncName should not return an invalid OID */
147-
148-
/* decide whether to use "older_than" or "drop_created_before" */
149-
if (use_creation_time)
150-
{
151-
argarr[4] = IntervalVal;
152-
}
153-
else
154-
{
155-
argarr[1] = IntervalVal;
156-
}
157-
158-
/* Prepare the function expr with argument list */
159-
get_func_result_type(func_oid, &restype, NULL);
160-
161-
for (size_t i = 0; i < lengthof(argarr); i++)
162-
{
163-
args = lappend(args, argarr[i]);
164-
}
165-
166-
fexpr = makeFuncExpr(func_oid, restype, args, InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL);
167-
fexpr->funcretset = true;
168-
169-
/* Execute the SRF */
170-
estate = CreateExecutorState();
171-
econtext = CreateExprContext(estate);
172-
state = ExecInitFunctionResultSet(&fexpr->xpr, econtext, NULL);
173-
174-
while (true)
175-
{
176-
ExprDoneCond isdone;
177-
bool isnull;
178-
179-
ExecMakeFunctionResultSet(state, econtext, estate->es_query_cxt, &isnull, &isdone);
180-
181-
if (isdone == ExprEndResult)
182-
{
183-
break;
184-
}
185-
186-
if (!isnull)
187-
{
188-
num_results++;
189-
}
190-
}
191-
192-
/* Cleanup */
193-
FreeExprContext(econtext, false);
194-
FreeExecutorState(estate);
195-
196-
return num_results;
197-
}

tsl/src/chunk.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
extern Datum chunk_freeze_chunk(PG_FUNCTION_ARGS);
1313
extern Datum chunk_unfreeze_chunk(PG_FUNCTION_ARGS);
14-
extern int chunk_invoke_drop_chunks(Oid relid, Datum older_than, Datum older_than_type,
15-
bool use_creation_time);
1614
extern Datum chunk_merge_chunks(PG_FUNCTION_ARGS);
1715
extern Datum chunk_split_chunk(PG_FUNCTION_ARGS);
1816
extern void update_relstats(Relation catrel, Oid relid, BlockNumber num_pages, double ntuples);

0 commit comments

Comments
 (0)