Skip to content

Commit

Permalink
addressing reviewer comments and updating changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
thatzopoulos committed Dec 5, 2022
1 parent ff8a9c6 commit ba4e36a
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 21 deletions.
2 changes: 1 addition & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This changelog should be updated as part of a PR if the work is worth noting (mo
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`.
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)`.
Heartbeat aggregates can also interpolated to better see behavior around the boundaries of the individual aggregates.

- [#638](https://github.com/timescale/timescaledb-toolkit/pull/638): Introducing Time Vector Templates.
#### Bug fixes
- [#624](https://github.com/timescale/timescaledb-toolkit/pull/624): Remove partial aggregation for Candlestick aggregates.
We've determined that the cause for the bad results lives somewhere in the functions that are used to support partial aggregation.
Expand Down
79 changes: 59 additions & 20 deletions extension/src/time_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,15 @@ pub fn timestamptz_to_string(time: pg_sys::TimestampTz) -> Result<String, Utf8Er
}

#[pg_extern(immutable, schema = "toolkit_experimental", parallel_safe)]
pub fn to_plotly<'a>(series: Timevector_TSTZ_F64<'a>) -> String {
format_timevector(series,"{\"times\": {{ TIMES | json_encode() | safe }}, \"vals\": {{ VALUES | json_encode() | safe }}}".to_string())
}

#[pg_extern(immutable, schema = "toolkit_experimental", parallel_safe)]
pub fn to_text<'a>(series: Timevector_TSTZ_F64<'a>, format_string: String) -> String {
format_timevector(series, format_string)
}

pub fn format_timevector<'a>(series: Timevector_TSTZ_F64<'a>, format_string: String) -> String {
let mut context = Context::new();
let mut times: Vec<String> = Vec::new();
Expand Down Expand Up @@ -158,13 +167,25 @@ pub fn format_timevector<'a>(series: Timevector_TSTZ_F64<'a>, format_string: Str
}
}
}

// 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]]
// 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\"]]"`
let timevals: Vec<(String, String)> = times
.clone()
.into_iter()
.zip(values.clone())
.collect::<Vec<_>>();

context.insert("TIMES", &times);
context.insert("VALUES", &values);

context.insert("TIMEVALS", &timevals); // paired timevals: ex. (time,value).
match format_string.as_ref() {
"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"),
"paired" => {
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")},
format_string => Tera::one_off(format_string, &context, true).expect("Failed to create template with Tera")
// "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"),
// "paired" => {
// 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")},
format_string => Tera::one_off(format_string, &context, true)
.expect("Failed to create template with Tera"),
}
}

Expand Down Expand Up @@ -497,19 +518,20 @@ mod tests {
None,
);

let test_plotly_template = client.select(
"SELECT toolkit_experimental.format_timevector(timevector(time, value),'plotly') FROM data",
None,
None,
).first()
let test_plotly_template = client
.select(
"SELECT toolkit_experimental.to_plotly(timevector(time, value)) FROM data",
None,
None,
)
.first()
.get_one::<String>()
.unwrap();

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]}"
);

let test_paired_template = client.select(
"SELECT toolkit_experimental.format_timevector(timevector(time, value),'paired') FROM data",
"SELECT toolkit_experimental.to_text(timevector(time, value),'{{TIMEVALS}}') FROM data",
None,
None,
).first()
Expand All @@ -518,19 +540,34 @@ mod tests {

assert_eq!(
test_paired_template,
"[{\"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} ]"
"[[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]]"
// "[[\"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\"]]", // with json_encode passed in
// "[{\"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} ]" // Generated by this tera code : "[{% for x in TIMES %}{\"time\": \"{{ x }}\", \"val\": {{ VALUES[loop.index0] }}}{% if not loop.last %},{% endif %} {% endfor %}]"
);

let test_user_supplied_template = client.select(
"SELECT toolkit_experimental.format_timevector(timevector(time, value),'{\"times\": {{ TIMES | json_encode(pretty=true) | safe }}, \"vals\": {{ VALUES | json_encode(pretty=true) | safe }}}') FROM data",
let test_user_supplied_template = client
.select(
"SELECT toolkit_experimental.to_text(timevector(time,value), '{\"times\": {{ TIMES }}, \"vals\": {{ VALUES }}}') FROM data",
None,
None,
)
.first()
.get_one::<String>()
.unwrap();
assert_eq!(
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]}"
);
let test_user_supplied_json_template = client.select(
"SELECT toolkit_experimental.to_text(timevector(time, value),'{\"times\": {{ TIMES | json_encode() | safe }}, \"vals\": {{ VALUES | json_encode() | safe }}}') FROM data",
None,
None,
).first()
.get_one::<String>()
.unwrap();

assert_eq!(
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]}"
test_user_supplied_json_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\"]}"
);
})
}
Expand All @@ -557,11 +594,13 @@ mod tests {
None,
);

let test_plotly_template = client.select(
"SELECT toolkit_experimental.format_timevector(timevector(time, value),'plotly') FROM data",
None,
None,
).first()
let test_plotly_template = client
.select(
"SELECT toolkit_experimental.to_plotly(timevector(time, value)) FROM data",
None,
None,
)
.first()
.get_one::<String>()
.unwrap();

Expand Down

0 comments on commit ba4e36a

Please sign in to comment.