Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make FunctionModule's avg, max, min & sum functions nullable (consumer opt-in). #183

Merged
merged 6 commits into from
Oct 17, 2022
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 43 additions & 26 deletions src/query-builder/function-module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { DynamicReferenceBuilder } from '../dynamic/dynamic-reference-builder.js'
import { AggregateFunctionNode } from '../operation-node/aggregate-function-node.js'
import {
ExtractTypeFromReferenceExpression,
Expand Down Expand Up @@ -52,14 +51,15 @@ export class FunctionModule<DB, TB extends keyof DB> {
* Calls the `avg` function for the column given as the argument.
*
* If this is used in a `select` statement the type of the selected expression
* will be `number | string` by default. This is because Kysely can't know the
* type the db driver outputs. Sometimes the output can be larger than the
* largest javascript number and a string is returned instead. Most drivers
* allow you to configure the output type of large numbers and Kysely can't
* know if you've done so.
* will be `number | string | null` by default. This is because Kysely can't know
igalklebanov marked this conversation as resolved.
Show resolved Hide resolved
* the type the db driver outputs. Sometimes the output can be larger than the
* largest javascript number and a string is returned instead. Most drivers allow
* you to configure the output type of large numbers and Kysely can't know if
* you've done so. Sometimes a null is returned, e.g. when row count is 0, and
* no `group by` was used.
*
* You can specify the output type of the expression by providing
* the type as the first type argument:
* You can specify the output type of the expression by providing the type as
* the first type argument:
*
* ```ts
* const { avg } = db.fn
Expand All @@ -68,9 +68,12 @@ export class FunctionModule<DB, TB extends keyof DB> {
* .select(avg<number>('price').as('avg_price'))
* .execute()
* ```
*
* It is highly recommended to include null in the output type union and handle
* null values in post-execute code, or wrap the function with a coalesce function.
*/
avg<
O extends number | string,
O extends number | string | null = number | string,
C extends SimpleReferenceExpression<DB, TB> = SimpleReferenceExpression<
DB,
TB
Expand All @@ -88,11 +91,11 @@ export class FunctionModule<DB, TB extends keyof DB> {
* Calls the `count` function for the column given as the argument.
*
* If this is used in a `select` statement the type of the selected expression
* will be `number | string | bigint` by default. This is because Kysely can't
* know the type the db driver outputs. Sometimes the output can be larger than
* the largest javascript number and a string is returned instead. Most drivers
* allow you to configure the output type of large numbers and Kysely can't
* know if you've done so.
* will be `number | string | bigint | null` by default. This is because Kysely
igalklebanov marked this conversation as resolved.
Show resolved Hide resolved
* can't know the type the db driver outputs. Sometimes the output can be larger
* than the largest javascript number and a string is returned instead. Most
* drivers allow you to configure the output type of large numbers and Kysely
* can't know if you've done so.
*
* You can specify the output type of the expression by providing
* the type as the first type argument:
Expand Down Expand Up @@ -142,14 +145,19 @@ export class FunctionModule<DB, TB extends keyof DB> {
* ```
*/
max<
O extends number | string | bigint,
C extends SimpleReferenceExpression<DB, TB> = DynamicReferenceBuilder<any>
O extends number | string | bigint | null = number | string | bigint,
C extends SimpleReferenceExpression<DB, TB> = SimpleReferenceExpression<
DB,
TB
>
>(
column: C
): AggregateFunctionBuilder<
DB,
TB,
ExtractTypeFromReferenceExpression<DB, TB, C, O>
ExtractTypeFromReferenceExpression<DB, TB, C, O> | null extends O
? null
: never
igalklebanov marked this conversation as resolved.
Show resolved Hide resolved
> {
return new AggregateFunctionBuilder({
aggregateFunctionNode: AggregateFunctionNode.create(
Expand All @@ -174,14 +182,19 @@ export class FunctionModule<DB, TB extends keyof DB> {
*
*/
min<
O extends number | string | bigint,
C extends SimpleReferenceExpression<DB, TB> = DynamicReferenceBuilder<any>
O extends number | string | bigint | null = number | string | bigint,
C extends SimpleReferenceExpression<DB, TB> = SimpleReferenceExpression<
DB,
TB
>
>(
column: C
): AggregateFunctionBuilder<
DB,
TB,
ExtractTypeFromReferenceExpression<DB, TB, C, O>
ExtractTypeFromReferenceExpression<DB, TB, C, O> | null extends O
? null
: never
> {
return new AggregateFunctionBuilder({
aggregateFunctionNode: AggregateFunctionNode.create(
Expand All @@ -195,11 +208,12 @@ export class FunctionModule<DB, TB extends keyof DB> {
* Calls the `sum` function for the column given as the argument.
*
* If this is used in a `select` statement the type of the selected expression
* will be `number | string | bigint` by default. This is because Kysely can't
* know the type the db driver outputs. Sometimes the output can be larger than
* the largest javascript number and a string is returned instead. Most drivers
* allow you to configure the output type of large numbers and Kysely can't
* know if you've done so.
* will be `number | string | bigint | null` by default. This is because Kysely
igalklebanov marked this conversation as resolved.
Show resolved Hide resolved
* can't know the type the db driver outputs. Sometimes the output can be larger
* than the largest javascript number and a string is returned instead. Most
* drivers allow you to configure the output type of large numbers and Kysely
* can't know if you've done so. Sometimes a null is returned, e.g. when row
* count is 0, and no `group by` was used.
*
* You can specify the output type of the expression by providing
* the type as the first type argument:
Expand All @@ -211,9 +225,12 @@ export class FunctionModule<DB, TB extends keyof DB> {
* .select(sum<number>('price').as('total_price'))
* .execute()
* ```
*
* It is highly recommended to include null in the output type union and handle
* null values in post-execute code, or wrap the function with a coalesce function.
*/
sum<
O extends number | string | bigint,
O extends number | string | bigint | null = number | string | bigint,
igalklebanov marked this conversation as resolved.
Show resolved Hide resolved
C extends SimpleReferenceExpression<DB, TB> = SimpleReferenceExpression<
DB,
TB
Expand Down