Skip to content

Commit c76ae4f

Browse files
committed
addressing reviewer comments and updating changelog
1 parent ff8a9c6 commit c76ae4f

File tree

2 files changed

+60
-22
lines changed

2 files changed

+60
-22
lines changed

Changelog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This changelog should be updated as part of a PR if the work is worth noting (mo
1111
Users can use the new `heartbeat_agg(timestamp, start_time, agg_interval, heartbeat_interval)` to track the liveness of a system in the range (`start_time`, `start_time` + `agg_interval`). Each timestamp seen in that range is assumed to indicate system liveness for the following `heartbeat_interval`.
1212
Once constructed, users can query heartbeat aggregates for `uptime` and `downtime`, as well as query for `live_ranges` or `dead_ranges`. Users can also check for `live_at(timestamp)`.
1313
Heartbeat aggregates can also interpolated to better see behavior around the boundaries of the individual aggregates.
14-
14+
- [#638](https://github.com/timescale/timescaledb-toolkit/pull/638): Introducing Time Vector Templates.
1515
#### Bug fixes
1616
- [#624](https://github.com/timescale/timescaledb-toolkit/pull/624): Remove partial aggregation for Candlestick aggregates.
1717
We've determined that the cause for the bad results lives somewhere in the functions that are used to support partial aggregation.

extension/src/time_vector.rs

Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,15 @@ pub fn timestamptz_to_string(time: pg_sys::TimestampTz) -> Result<String, Utf8Er
128128
}
129129

130130
#[pg_extern(immutable, schema = "toolkit_experimental", parallel_safe)]
131+
pub fn to_plotly<'a>(series: Timevector_TSTZ_F64<'a>) -> String {
132+
format_timevector(series,"{\"times\": {{ TIMES | json_encode() | safe }}, \"vals\": {{ VALUES | json_encode() | safe }}}".to_string())
133+
}
134+
135+
#[pg_extern(immutable, schema = "toolkit_experimental", parallel_safe)]
136+
pub fn to_text<'a>(series: Timevector_TSTZ_F64<'a>, format_string: String) -> String {
137+
format_timevector(series, format_string)
138+
}
139+
131140
pub fn format_timevector<'a>(series: Timevector_TSTZ_F64<'a>, format_string: String) -> String {
132141
let mut context = Context::new();
133142
let mut times: Vec<String> = Vec::new();
@@ -158,13 +167,25 @@ pub fn format_timevector<'a>(series: Timevector_TSTZ_F64<'a>, format_string: Str
158167
}
159168
}
160169
}
170+
171+
// without json_encode : [[2020-01-01 00:00:00+00, 30], [2020-01-02 00:00:00+00, 45], [2020-01-03 00:00:00+00, null], [2020-01-04 00:00:00+00, 55.5], [2020-01-05 00:00:00+00, 10]]
172+
// with json_encode : "[[\"2020-01-01 00:00:00+00\",\"30\"],[\"2020-01-02 00:00:00+00\",\"45\"],[\"2020-01-03 00:00:00+00\",\"null\"],[\"2020-01-04 00:00:00+00\",\"55.5\"],[\"2020-01-05 00:00:00+00\",\"10\"]]"`
173+
let timevals: Vec<(String, String)> = times
174+
.clone()
175+
.into_iter()
176+
.zip(values.clone())
177+
.collect::<Vec<_>>();
178+
161179
context.insert("TIMES", &times);
162180
context.insert("VALUES", &values);
181+
182+
context.insert("TIMEVALS", &timevals); // paired timevals: ex. (time,value).
163183
match format_string.as_ref() {
164-
"plotly" => Tera::one_off("{\"times\": {{ TIMES | json_encode(pretty=true) | safe }}, \"vals\": {{ VALUES | json_encode(pretty=true) | safe }}}", &context, true).expect("Failed to create plotly template"),
165-
"paired" => {
166-
Tera::one_off( "[{% for x in TIMES %}{\"time\": \"{{ x }}\", \"val\": {{ VALUES[loop.index0] }}}{% if not loop.last %},{% endif %} {% endfor %}]", &context, true).expect("Failed to create paired template")},
167-
format_string => Tera::one_off(format_string, &context, true).expect("Failed to create template with Tera")
184+
// "plotly" => Tera::one_off("{\"times\": {{ TIMES | json_encode(pretty=true) | safe }}, \"vals\": {{ VALUES | json_encode(pretty=true) | safe }}}", &context, true).expect("Failed to create plotly template"),
185+
// "paired" => {
186+
// Tera::one_off( "[{% for x in TIMES %}{\"time\": \"{{ x }}\", \"val\": {{ VALUES[loop.index0] }}}{% if not loop.last %},{% endif %} {% endfor %}]", &context, true).expect("Failed to create paired template")},
187+
format_string => Tera::one_off(format_string, &context, true)
188+
.expect("Failed to create template with Tera"),
168189
}
169190
}
170191

@@ -497,19 +518,21 @@ mod tests {
497518
None,
498519
);
499520

500-
let test_plotly_template = client.select(
501-
"SELECT toolkit_experimental.format_timevector(timevector(time, value),'plotly') FROM data",
502-
None,
503-
None,
504-
).first()
521+
let test_plotly_template = client
522+
.select(
523+
"SELECT toolkit_experimental.to_plotly(timevector(time, value)) FROM data",
524+
None,
525+
None,
526+
)
527+
.first()
505528
.get_one::<String>()
506529
.unwrap();
507530

508-
assert_eq!(test_plotly_template,"{\"times\": [\n \"2020-01-01 00:00:00+00\",\n \"2020-01-02 00:00:00+00\",\n \"2020-01-03 00:00:00+00\",\n \"2020-01-04 00:00:00+00\",\n \"2020-01-05 00:00:00+00\"\n], \"vals\": [\n \"30\",\n \"45\",\n \"null\",\n \"55.5\",\n \"10\"\n]}"
531+
assert_eq!(test_plotly_template,
532+
"{\"times\": [\"2020-01-01 00:00:00+00\",\"2020-01-02 00:00:00+00\",\"2020-01-03 00:00:00+00\",\"2020-01-04 00:00:00+00\",\"2020-01-05 00:00:00+00\"], \"vals\": [\"30\",\"45\",\"null\",\"55.5\",\"10\"]}"
509533
);
510-
511534
let test_paired_template = client.select(
512-
"SELECT toolkit_experimental.format_timevector(timevector(time, value),'paired') FROM data",
535+
"SELECT toolkit_experimental.to_text(timevector(time, value),'{{TIMEVALS}}') FROM data",
513536
None,
514537
None,
515538
).first()
@@ -518,19 +541,32 @@ mod tests {
518541

519542
assert_eq!(
520543
test_paired_template,
521-
"[{\"time\": \"2020-01-01 00:00:00+00\", \"val\": 30}, {\"time\": \"2020-01-02 00:00:00+00\", \"val\": 45}, {\"time\": \"2020-01-03 00:00:00+00\", \"val\": null}, {\"time\": \"2020-01-04 00:00:00+00\", \"val\": 55.5}, {\"time\": \"2020-01-05 00:00:00+00\", \"val\": 10} ]"
544+
"[[2020-01-01 00:00:00+00, 30], [2020-01-02 00:00:00+00, 45], [2020-01-03 00:00:00+00, null], [2020-01-04 00:00:00+00, 55.5], [2020-01-05 00:00:00+00, 10]]"
522545
);
523546

524-
let test_user_supplied_template = client.select(
525-
"SELECT toolkit_experimental.format_timevector(timevector(time, value),'{\"times\": {{ TIMES | json_encode(pretty=true) | safe }}, \"vals\": {{ VALUES | json_encode(pretty=true) | safe }}}') FROM data",
547+
let test_user_supplied_template = client
548+
.select(
549+
"SELECT toolkit_experimental.to_text(timevector(time,value), '{\"times\": {{ TIMES }}, \"vals\": {{ VALUES }}}') FROM data",
550+
None,
551+
None,
552+
)
553+
.first()
554+
.get_one::<String>()
555+
.unwrap();
556+
assert_eq!(
557+
test_user_supplied_template,"{\"times\": [2020-01-01 00:00:00+00, 2020-01-02 00:00:00+00, 2020-01-03 00:00:00+00, 2020-01-04 00:00:00+00, 2020-01-05 00:00:00+00], \"vals\": [30, 45, null, 55.5, 10]}"
558+
);
559+
let test_user_supplied_json_template = client.select(
560+
"SELECT toolkit_experimental.to_text(timevector(time, value),'{\"times\": {{ TIMES | json_encode() | safe }}, \"vals\": {{ VALUES | json_encode() | safe }}}') FROM data",
526561
None,
527562
None,
528563
).first()
529564
.get_one::<String>()
530565
.unwrap();
531566

532567
assert_eq!(
533-
test_user_supplied_template, "{\"times\": [\n \"2020-01-01 00:00:00+00\",\n \"2020-01-02 00:00:00+00\",\n \"2020-01-03 00:00:00+00\",\n \"2020-01-04 00:00:00+00\",\n \"2020-01-05 00:00:00+00\"\n], \"vals\": [\n \"30\",\n \"45\",\n \"null\",\n \"55.5\",\n \"10\"\n]}"
568+
test_user_supplied_json_template,
569+
"{\"times\": [\"2020-01-01 00:00:00+00\",\"2020-01-02 00:00:00+00\",\"2020-01-03 00:00:00+00\",\"2020-01-04 00:00:00+00\",\"2020-01-05 00:00:00+00\"], \"vals\": [\"30\",\"45\",\"null\",\"55.5\",\"10\"]}"
534570
);
535571
})
536572
}
@@ -557,11 +593,13 @@ mod tests {
557593
None,
558594
);
559595

560-
let test_plotly_template = client.select(
561-
"SELECT toolkit_experimental.format_timevector(timevector(time, value),'plotly') FROM data",
562-
None,
563-
None,
564-
).first()
596+
let test_plotly_template = client
597+
.select(
598+
"SELECT toolkit_experimental.to_plotly(timevector(time, value)) FROM data",
599+
None,
600+
None,
601+
)
602+
.first()
565603
.get_one::<String>()
566604
.unwrap();
567605

0 commit comments

Comments
 (0)