@@ -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