@@ -52,6 +52,7 @@ typedef enum MaterializationPlanType
52
52
PLAN_TYPE_MERGE_DELETE ,
53
53
PLAN_TYPE_RANGES_SELECT ,
54
54
PLAN_TYPE_RANGES_DELETE ,
55
+ PLAN_TYPE_RANGES_PENDING ,
55
56
_MAX_MATERIALIZATION_PLAN_TYPES
56
57
} MaterializationPlanType ;
57
58
@@ -91,13 +92,15 @@ static char *create_materialization_merge_statement(MaterializationContext *cont
91
92
static char * create_materialization_merge_delete_statement (MaterializationContext * context );
92
93
static char * create_materialization_ranges_select_statement (MaterializationContext * context );
93
94
static char * create_materialization_ranges_delete_statement (MaterializationContext * context );
95
+ static char * create_materialization_ranges_pending_statement (MaterializationContext * context );
94
96
95
97
static void emit_materialization_insert_error (MaterializationContext * context );
96
98
static void emit_materialization_delete_error (MaterializationContext * context );
97
99
static void emit_materialization_exists_error (MaterializationContext * context );
98
100
static void emit_materialization_merge_error (MaterializationContext * context );
99
101
static void emit_materialization_ranges_select_error (MaterializationContext * context );
100
102
static void emit_materialization_ranges_delete_error (MaterializationContext * context );
103
+ static void emit_materialization_ranges_pending_error (MaterializationContext * context );
101
104
102
105
static void emit_materialization_insert_progress (MaterializationContext * context ,
103
106
uint64 rows_processed );
@@ -137,6 +140,11 @@ static MaterializationPlan materialization_plans[_MAX_MATERIALIZATION_PLAN_TYPES
137
140
.create_statement =
138
141
create_materialization_ranges_delete_statement ,
139
142
.emit_error = emit_materialization_ranges_delete_error },
143
+ [PLAN_TYPE_RANGES_PENDING ] = { .read_only = true,
144
+ .nargs = 3 ,
145
+ .create_statement =
146
+ create_materialization_ranges_pending_statement ,
147
+ .emit_error = emit_materialization_ranges_pending_error },
140
148
};
141
149
142
150
static Oid * create_materialization_plan_argtypes (MaterializationContext * context ,
@@ -201,6 +209,32 @@ continuous_agg_update_materialization(Hypertable *mat_ht, const ContinuousAgg *c
201
209
AtEOXact_GUC (false, save_nestlevel );
202
210
}
203
211
212
+ /* API to check for pending materialization ranges */
213
+ bool
214
+ continuous_agg_pending_materializations (const ContinuousAgg * cagg ,
215
+ InternalTimeRange materialization_range )
216
+ {
217
+ MaterializationContext context = {
218
+ .cagg = cagg ,
219
+ .internal_materialization_range = materialization_range ,
220
+ };
221
+
222
+ /* Lock down search_path */
223
+ int save_nestlevel = NewGUCNestLevel ();
224
+ RestrictSearchPath ();
225
+
226
+ if (materialization_range .start > materialization_range .end )
227
+ materialization_range .start = materialization_range .end ;
228
+
229
+ bool has_pending_materializations =
230
+ (execute_materialization_plan (& context , PLAN_TYPE_RANGES_PENDING ) > 0 );
231
+
232
+ /* Restore search_path */
233
+ AtEOXact_GUC (false, save_nestlevel );
234
+
235
+ return has_pending_materializations ;
236
+ }
237
+
204
238
static Datum
205
239
time_range_internal_to_min_time_value (Oid type )
206
240
{
@@ -558,6 +592,23 @@ create_materialization_ranges_delete_statement(MaterializationContext *context)
558
592
return query .data ;
559
593
}
560
594
595
+ static char *
596
+ create_materialization_ranges_pending_statement (MaterializationContext * context )
597
+ {
598
+ StringInfoData query ;
599
+ initStringInfo (& query );
600
+
601
+ appendStringInfo (& query ,
602
+ "SELECT * "
603
+ "FROM _timescaledb_catalog.continuous_aggs_materialization_ranges "
604
+ "WHERE materialization_id = $1 "
605
+ "AND pg_catalog.int8range(lowest_modified_value, greatest_modified_value) && "
606
+ "pg_catalog.int8range($2, $3) "
607
+ "LIMIT 1 " );
608
+
609
+ return query .data ;
610
+ }
611
+
561
612
static void
562
613
emit_materialization_insert_error (MaterializationContext * context )
563
614
{
@@ -612,6 +663,15 @@ emit_materialization_ranges_delete_error(MaterializationContext *context)
612
663
NameStr (* context -> materialization_table .name ));
613
664
}
614
665
666
+ static void
667
+ emit_materialization_ranges_pending_error (MaterializationContext * context )
668
+ {
669
+ elog (ERROR ,
670
+ "could not select pending materialization ranges \"%s.%s\"" ,
671
+ NameStr (* context -> materialization_table .schema ),
672
+ NameStr (* context -> materialization_table .name ));
673
+ }
674
+
615
675
static void
616
676
emit_materialization_insert_progress (MaterializationContext * context , uint64 rows_processed )
617
677
{
@@ -651,7 +711,8 @@ create_materialization_plan_argtypes(MaterializationContext *context,
651
711
switch (plan_type )
652
712
{
653
713
case PLAN_TYPE_RANGES_SELECT : /* 3 arguments */
654
- argtypes [0 ] = INT4OID ; /* materialization_id */
714
+ case PLAN_TYPE_RANGES_PENDING :
715
+ argtypes [0 ] = INT4OID ; /* materialization_id */
655
716
argtypes [1 ] = INT8OID ;
656
717
argtypes [2 ] = INT8OID ;
657
718
break ;
@@ -703,6 +764,7 @@ create_materialization_plan_args(MaterializationContext *context, Materializatio
703
764
switch (plan_type )
704
765
{
705
766
case PLAN_TYPE_RANGES_SELECT : /* 3 arguments */
767
+ case PLAN_TYPE_RANGES_PENDING :
706
768
{
707
769
(* values )[0 ] = Int32GetDatum (context -> cagg -> data .mat_hypertable_id );
708
770
(* values )[1 ] = Int64GetDatum (context -> internal_materialization_range .start );
0 commit comments