Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1da1159

Browse files
committed
store: Use arg_min/arg_max to implement first/last aggregates
1 parent a1ad90a commit 1da1159

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

store/postgres/src/relational/rollup.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,16 @@ impl<'a> Agg<'a> {
4949
Sum => write!(w, "sum(\"{}\")", self.src_column.unwrap().name)?,
5050
Max => write!(w, "max(\"{}\")", self.src_column.unwrap().name)?,
5151
Min => write!(w, "min(\"{}\")", self.src_column.unwrap().name)?,
52-
First => write!(w, "first(\"{}\")", self.src_column.unwrap().name)?,
53-
Last => write!(w, "last(\"{}\")", self.src_column.unwrap().name)?,
52+
First => {
53+
let src = self.src_column.unwrap();
54+
let sql_type = src.column_type.sql_type();
55+
write!(w, "arg_min_{}((\"{}\", id))", sql_type, src.name)?
56+
}
57+
Last => {
58+
let src = self.src_column.unwrap();
59+
let sql_type = src.column_type.sql_type();
60+
write!(w, "arg_max_{}((\"{}\", id))", sql_type, src.name)?
61+
}
5462
Count => write!(w, "count(*)")?,
5563
}
5664
write!(w, " as \"{}\"", self.agg_column.name)
@@ -255,7 +263,7 @@ mod tests {
255263
timestamp: Int8!
256264
token: Bytes!
257265
price: BigDecimal!
258-
amount: BigDecimal!
266+
amount: Int!
259267
}
260268
261269
type Stats @aggregation(intervals: ["day", "hour"], source: "Data") {
@@ -271,6 +279,14 @@ mod tests {
271279
timestamp: Int8!
272280
max: BigDecimal! @aggregate(fn: "max", arg: "price")
273281
}
282+
283+
type OpenClose @aggregation(intervals: ["day"], source: "Data") {
284+
id: Int8!
285+
timestamp: Int8!
286+
open: BigDecimal! @aggregate(fn: "first", arg: "price")
287+
close: BigDecimal! @aggregate(fn: "last", arg: "price")
288+
first_amt: Int! @aggregate(fn: "first", arg: "amount")
289+
}
274290
"#;
275291

276292
const STATS_HOUR_SQL: &str = r#"\
@@ -299,6 +315,19 @@ mod tests {
299315
order by "sgd007"."data".timestamp) data \
300316
group by timestamp"#;
301317

318+
const OPEN_CLOSE_SQL: &str = r#"\
319+
insert into "sgd007"."open_close_day"(id, timestamp, block$, "open", "close", "first_amt")
320+
select max(id) as id, timestamp, $3, \
321+
arg_min_numeric(("price", id)) as "open", \
322+
arg_max_numeric(("price", id)) as "close", \
323+
arg_min_int4(("amount", id)) as "first_amt" \
324+
from (select id, timestamp/86400*86400 as timestamp, "amount", "price" \
325+
from "sgd007"."data"
326+
where "sgd007"."data".timestamp >= $1
327+
and "sgd007"."data".timestamp < $2
328+
order by "sgd007"."data".timestamp) data \
329+
group by timestamp"#;
330+
302331
#[track_caller]
303332
fn rollup_for<'a>(layout: &'a Layout, table_name: &str) -> &'a Rollup {
304333
layout
@@ -314,7 +343,7 @@ mod tests {
314343
let site = Arc::new(make_dummy_site(hash, nsp, "rollup".to_string()));
315344
let catalog = Catalog::for_tests(site.clone(), BTreeSet::new()).unwrap();
316345
let layout = Layout::new(site, &schema, catalog).unwrap();
317-
assert_eq!(3, layout.rollups.len());
346+
assert_eq!(4, layout.rollups.len());
318347

319348
// Intervals are non-decreasing
320349
assert!(layout.rollups[0].interval <= layout.rollups[1].interval);
@@ -327,5 +356,8 @@ mod tests {
327356
check_eqv(STATS_HOUR_SQL, &stats_hour.insert_sql);
328357
check_eqv(STATS_DAY_SQL, &stats_day.insert_sql);
329358
check_eqv(TOTAL_SQL, &stats_total.insert_sql);
359+
360+
let open_close = rollup_for(&layout, "open_close_day");
361+
check_eqv(OPEN_CLOSE_SQL, &open_close.insert_sql);
330362
}
331363
}

0 commit comments

Comments
 (0)