|
18 | 18 | #include <utils/lsyscache.h> |
19 | 19 | #include <utils/snapmgr.h> |
20 | 20 |
|
| 21 | +#include "bgw_policy/policies_v2.h" |
21 | 22 | #include "debug_point.h" |
22 | 23 | #include "dimension.h" |
23 | 24 | #include "dimension_slice.h" |
@@ -666,16 +667,60 @@ continuous_agg_refresh(PG_FUNCTION_ARGS) |
666 | 667 | refresh_window.end_isnull = true; |
667 | 668 | } |
668 | 669 |
|
| 670 | + /* |
| 671 | + * For manual refreshes batching is opt-in: callers must set |
| 672 | + * buckets_per_batch in the options JSONB to trigger incremental refresh. |
| 673 | + * Default 0 = atomic single-pass refresh (keeps the previous behaviour). |
| 674 | + */ |
| 675 | + int32 buckets_per_batch = 0; |
| 676 | + int32 max_batches_per_execution = 0; |
| 677 | + bool refresh_newest_first = DEFAULT_REFRESH_NEWEST_FIRST; |
| 678 | + |
| 679 | + if (!PG_ARGISNULL(4)) |
| 680 | + { |
| 681 | + Jsonb *options = PG_GETARG_JSONB_P(4); |
| 682 | + bool found; |
| 683 | + |
| 684 | + int32 v = ts_jsonb_get_int32_field(options, POL_REFRESH_CONF_KEY_BUCKETS_PER_BATCH, &found); |
| 685 | + if (found) |
| 686 | + buckets_per_batch = v; |
| 687 | + |
| 688 | + v = ts_jsonb_get_int32_field(options, |
| 689 | + POL_REFRESH_CONF_KEY_MAX_BATCHES_PER_EXECUTION, |
| 690 | + &found); |
| 691 | + if (found) |
| 692 | + max_batches_per_execution = v; |
| 693 | + |
| 694 | + bool b = |
| 695 | + ts_jsonb_get_bool_field(options, POL_REFRESH_CONF_KEY_REFRESH_NEWEST_FIRST, &found); |
| 696 | + if (found) |
| 697 | + refresh_newest_first = b; |
| 698 | + } |
| 699 | + |
| 700 | + if (buckets_per_batch < 0) |
| 701 | + ereport(ERROR, |
| 702 | + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| 703 | + errmsg("invalid buckets per batch"), |
| 704 | + errdetail("buckets_per_batch: %d", buckets_per_batch), |
| 705 | + errhint("The buckets per batch should be greater than or equal to zero."))); |
| 706 | + |
| 707 | + if (max_batches_per_execution < 0) |
| 708 | + ereport(ERROR, |
| 709 | + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| 710 | + errmsg("invalid max batches per execution"), |
| 711 | + errdetail("max_batches_per_execution: %d", max_batches_per_execution), |
| 712 | + errhint( |
| 713 | + "The max batches per execution should be greater than or equal to zero."))); |
| 714 | + |
669 | 715 | ContinuousAggRefreshContext context = { |
670 | 716 | .callctx = CAGG_REFRESH_WINDOW, |
671 | | - .buckets_per_batch = DEFAULT_BUCKETS_PER_BATCH, |
672 | | - .refresh_newest_first = DEFAULT_REFRESH_NEWEST_FIRST, |
| 717 | + .buckets_per_batch = buckets_per_batch, |
| 718 | + .max_batches_per_execution = max_batches_per_execution, |
| 719 | + .refresh_newest_first = refresh_newest_first, |
673 | 720 | }; |
674 | 721 | continuous_agg_refresh_internal(cagg, |
675 | 722 | &refresh_window, |
676 | 723 | context, |
677 | | - PG_ARGISNULL(1), |
678 | | - PG_ARGISNULL(2), |
679 | 724 | force, |
680 | 725 | false /*extend_last_bucket*/); |
681 | 726 |
|
@@ -1082,8 +1127,8 @@ continuous_agg_refresh_single_window(const ContinuousAgg *cagg_arg, |
1082 | 1127 | void |
1083 | 1128 | continuous_agg_refresh_internal(const ContinuousAgg *cagg, |
1084 | 1129 | const InternalTimeRange *refresh_window, |
1085 | | - ContinuousAggRefreshContext context, const bool start_isnull, |
1086 | | - const bool end_isnull, bool force, bool extend_last_bucket) |
| 1130 | + ContinuousAggRefreshContext context, bool force, |
| 1131 | + bool extend_last_bucket) |
1087 | 1132 | { |
1088 | 1133 | /* Like regular materialized views, require owner to refresh. */ |
1089 | 1134 | if (!object_ownercheck(RelationRelationId, cagg->relid, GetUserId())) |
@@ -1140,11 +1185,12 @@ continuous_agg_refresh_internal(const ContinuousAgg *cagg, |
1140 | 1185 | (context.refresh_newest_first ? processing_batch == 1 : |
1141 | 1186 | processing_batch == context.number_of_batches); |
1142 | 1187 |
|
1143 | | - elog(DEBUG1, |
1144 | | - "refreshing continuous aggregate \"%s\" in window [ %s, %s ]", |
1145 | | - NameStr(cagg->data.user_view_name), |
1146 | | - ts_internal_to_time_string(batch_window->start, batch_window->type), |
1147 | | - ts_internal_to_time_string(batch_window->end, batch_window->type)); |
| 1188 | + if (context.number_of_batches > 1) |
| 1189 | + elog(DEBUG1, |
| 1190 | + "refreshing continuous aggregate \"%s\" in window [ %s, %s ]", |
| 1191 | + NameStr(cagg->data.user_view_name), |
| 1192 | + ts_internal_to_time_string(batch_window->start, batch_window->type), |
| 1193 | + ts_internal_to_time_string(batch_window->end, batch_window->type)); |
1148 | 1194 |
|
1149 | 1195 | bool refreshed = continuous_agg_refresh_single_window(cagg, |
1150 | 1196 | batch_window, |
|
0 commit comments