1 /*
2  * This file and its contents are licensed under the Timescale License.
3  * Please see the included NOTICE for copyright information and
4  * LICENSE-TIMESCALE for a copy of the license.
5  */
6 
7 #include <postgres.h>
8 #include <utils/builtins.h>
9 #include "dimension.h"
10 #include "guc.h"
11 #include "jsonb_utils.h"
12 #include "policy_utils.h"
13 #include "time_utils.h"
14 
15 /* Helper function to compare jsonb label value in the config
16  * with passed in value.
17  * This function is used for labels defined on the hypertable's dimension
18  * Parameters:
19  * config - jsonb config value
20  * label - label we are looking for inside the config
21  * partitioning_type - Oid for hypertable's dimension column
22  * lag_value - value we will compare against the config's
23  *             value for the label
24  * lag_type - Oid for lag_value
25  * Returns:
26  *    True, if config value is equal to lag_value
27  */
28 bool
policy_config_check_hypertable_lag_equality(Jsonb * config,const char * json_label,Oid partitioning_type,Oid lag_type,Datum lag_datum)29 policy_config_check_hypertable_lag_equality(Jsonb *config, const char *json_label,
30 											Oid partitioning_type, Oid lag_type, Datum lag_datum)
31 {
32 	if (IS_INTEGER_TYPE(partitioning_type))
33 	{
34 		bool found;
35 		int64 config_value = ts_jsonb_get_int64_field(config, json_label, &found);
36 
37 		if (!found)
38 			ereport(ERROR,
39 					(errcode(ERRCODE_INTERNAL_ERROR),
40 					 errmsg("could not find %s in config for existing job", json_label)));
41 
42 		switch (lag_type)
43 		{
44 			case INT2OID:
45 				return config_value == DatumGetInt16(lag_datum);
46 			case INT4OID:
47 				return config_value == DatumGetInt32(lag_datum);
48 			case INT8OID:
49 				return config_value == DatumGetInt64(lag_datum);
50 			default:
51 				return false;
52 		}
53 	}
54 	else
55 	{
56 		if (lag_type != INTERVALOID)
57 			return false;
58 		Interval *config_value = ts_jsonb_get_interval_field(config, json_label);
59 		if (config_value == NULL)
60 			ereport(ERROR,
61 					(errcode(ERRCODE_INTERNAL_ERROR),
62 					 errmsg("could not find %s in config for job", json_label)));
63 
64 		return DatumGetBool(
65 			DirectFunctionCall2(interval_eq, IntervalPGetDatum(config_value), lag_datum));
66 	}
67 }
68 
69 Datum
subtract_interval_from_now(Interval * lag,Oid time_dim_type)70 subtract_interval_from_now(Interval *lag, Oid time_dim_type)
71 {
72 #ifdef TS_DEBUG
73 	Datum res = ts_get_mock_time_or_current_time();
74 #else
75 	Datum res = TimestampTzGetDatum(GetCurrentTimestamp());
76 #endif
77 
78 	switch (time_dim_type)
79 	{
80 		case TIMESTAMPOID:
81 			res = DirectFunctionCall1(timestamptz_timestamp, res);
82 			res = DirectFunctionCall2(timestamp_mi_interval, res, IntervalPGetDatum(lag));
83 
84 			return res;
85 		case TIMESTAMPTZOID:
86 			res = DirectFunctionCall2(timestamptz_mi_interval, res, IntervalPGetDatum(lag));
87 
88 			return res;
89 		case DATEOID:
90 			res = DirectFunctionCall1(timestamptz_timestamp, res);
91 			res = DirectFunctionCall2(timestamp_mi_interval, res, IntervalPGetDatum(lag));
92 			res = DirectFunctionCall1(timestamp_date, res);
93 
94 			return res;
95 		default:
96 			/* this should never happen as otherwise hypertable has unsupported time type */
97 			ereport(ERROR,
98 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
99 					 errmsg("unsupported time type %s", format_type_be(time_dim_type))));
100 			pg_unreachable();
101 	}
102 }
103