[hibernate-dev] 6.0 - formalized standard functions
Christian Beikov
christian.beikov at gmail.com
Wed May 31 10:19:52 EDT 2017
Answers inline...
Am 31.05.2017 um 14:38 schrieb Steve Ebersole:
> Thanks for reply Christian..
>
>
> On Wed, May 31, 2017 at 7:18 AM Christian Beikov
> <christian.beikov at gmail.com <mailto:christian.beikov at gmail.com>> wrote:
>
> Looks good. OTOH I'd also like to see the following functions
>
> * millisecond_diff
> * second_diff
> * minute_diff
> * hour_diff
> * day_diff
> * week_diff
> * month_diff
> * quater_diff
> * year_diff
>
>
> Why not basic temporal arithmetic? E.g. `second(x) - second(y)`
> (which isgenerally resolved to `extract(second from x) -
> extract(second from y)`...
That would only extract the second part of the date/time which is not
what these functions are about. These functions have semantics like
`(epoch(x) - epoch(y)) / unit_factor`. The functions "datediff" from SQL
Server[1] or "timestampdiff" from MySQL[2] have exactly these semantics.
To give an example, consider the following expression
second_diff(
'2017-01-01 00:01:01'::timestamp,
'2017-01-01 00:00:01'::timestamp
)
When defining second_diff(x, y) as `second(y) - second(x)`, the result
of that expression would be 0.
The semantics I anticipate are that this returns 60 which is what could
be implemented by doing `(epoch(y) - epoch(x)) / unit_factor` where
unit_factor for seconds would be simply 1.
This is not that easy to implement correctly(I have implementations for
the most common DBMS), although I think these are quite commonly needed
functions.
> * epoch - generally defined as `extract(epoch from ?1)`
>
>
> Because ANSI SQL does not define epoch as an extractable part of a
> temporal. TBH I do not think it defines milliseconds as extractable
> either but would have to check. Also, I am not sure of databases that
> support that, nor any alternate (which we'd *need* to support this as
> a standard func) for databases which do not.
I have implementations for the most common DBMS that use the proprietary
counterparts or calculate the epoch appropriately. Although I don't
think there are that many DBMS that don't support this in any way, the
question is if we ought to "not implement the function" because e.g.
SQLite can't do it. I think one of the main questions we should ask
ourselves is for which DBMS we'd like to provide support for these
stanard functions.
>
> * group_concat - string aggregation function
>
>
> How is this different from concat()?
>
> The group_concat function would probably be not be possible to
> implement
> for all DBMS, but at least the bigger ones have one or the other
> function that could be used to implement this.
>
>
> Unless I am missing something in your idea here (which is why I asked
> above) we can absolutely implement this on all databases - everyone
> has a concat operator as well. And a SQM/SQL-AST function need not
> evaluate to a db function - it just needs to be an expression.
group_concat is an aggregate and/or window function like count, sum, avg
etc. which aggregates text values. You can think of group_concat as
being the StringJoiner of SQL. It allows to do e.g.
select order.id, group_concat( concat ( i.amount, 'x ', i.product.name
), ', ' )
from Order o
left join o.items i
group by order.id
Assume you have data like
Order( id = 1, items = { Item( amount = 2, product.name = 'Beer' ),
Item( amount = 1, product.name = 'Burger' ) } )
this would produce 1 row [1, '2x Beer, 1x Burger']
This was just a simple example to demonstrate the purpose, but in
reality the function must also be able to have an order by clause. MySQL
defines group_concat([distinct] expression ORDER BY expression1
[,expressionN] [SEPARATOR sep]).
Other DBMS have similar functions like listagg, string_agg etc. that all
have that same functionality.
> Don't know what is best regarding the "str" function.
>
>
> `str()` is defined as `cast`; that's not the issue. The issue is
> merely the type - I am simply arguing that VARCHAR is more correct
VARCHAR as type sounds ok to me, but I don't think I ever used it.
Whenever I need conversion I do so to concat the value with some other
string so I use the concat operation without "str".
[1]
https://docs.microsoft.com/en-us/sql/t-sql/functions/datediff-transact-sql
[2]
https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_timestampdiff
More information about the hibernate-dev
mailing list