Skip to content

Commit

Permalink
make distinct on accept any expression
Browse files Browse the repository at this point in the history
  • Loading branch information
koskimas committed Dec 11, 2022
1 parent 606b001 commit cb8d192
Show file tree
Hide file tree
Showing 9 changed files with 26 additions and 42 deletions.
2 changes: 1 addition & 1 deletion src/operation-node/operation-node-transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ export class OperationNodeTransformer {
kind: 'SelectQueryNode',
from: this.transformNode(node.from),
selections: this.transformNodeList(node.selections),
distinctOnSelections: this.transformNodeList(node.distinctOnSelections),
distinctOn: this.transformNodeList(node.distinctOn),
joins: this.transformNodeList(node.joins),
groupBy: this.transformNode(node.groupBy),
orderBy: this.transformNode(node.orderBy),
Expand Down
13 changes: 6 additions & 7 deletions src/operation-node/select-query-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@ import { WithNode } from './with-node.js'
import { SelectModifierNode } from './select-modifier-node.js'
import { ExplainNode } from './explain-node.js'
import { SetOperationNode } from './set-operation-node.js'
import { SimpleReferenceExpressionNode } from './simple-reference-expression-node.js'

export interface SelectQueryNode extends OperationNode {
readonly kind: 'SelectQueryNode'
readonly from: FromNode
readonly selections?: ReadonlyArray<SelectionNode>
readonly distinctOnSelections?: ReadonlyArray<SimpleReferenceExpressionNode>
readonly distinctOn?: ReadonlyArray<OperationNode>
readonly joins?: ReadonlyArray<JoinNode>
readonly groupBy?: GroupByNode
readonly orderBy?: OrderByNode
Expand Down Expand Up @@ -67,15 +66,15 @@ export const SelectQueryNode = freeze({
})
},

cloneWithDistinctOnSelections(
cloneWithDistinctOn(
select: SelectQueryNode,
selections: ReadonlyArray<SimpleReferenceExpressionNode>
expressions: ReadonlyArray<OperationNode>
): SelectQueryNode {
return freeze({
...select,
distinctOnSelections: select.distinctOnSelections
? freeze([...select.distinctOnSelections, ...selections])
: freeze(selections),
distinctOn: select.distinctOn
? freeze([...select.distinctOn, ...expressions])
: freeze(expressions),
})
},

Expand Down
9 changes: 3 additions & 6 deletions src/parser/expression-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
import { AliasNode } from '../operation-node/alias-node.js'
import { isOperationNodeSource } from '../operation-node/operation-node-source.js'
import { OperationNode } from '../operation-node/operation-node.js'
import { SimpleReferenceExpressionNode } from '../operation-node/simple-reference-expression-node.js'
import { ExpressionBuilder } from '../query-builder/expression-builder.js'
import { SelectQueryBuilder } from '../query-builder/select-query-builder.js'
import { isFunction } from '../util/object-utils.js'
Expand All @@ -30,13 +29,11 @@ export type AliasedExpressionOrFactory<DB, TB extends keyof DB> =

export function parseExpression(
exp: ExpressionOrFactory<any, any, any>
): SimpleReferenceExpressionNode {
): OperationNode {
if (isOperationNodeSource(exp)) {
return exp.toOperationNode() as SimpleReferenceExpressionNode
return exp.toOperationNode()
} else if (isFunction(exp)) {
return exp(
createExpressionBuilder()
).toOperationNode() as SimpleReferenceExpressionNode
return exp(createExpressionBuilder()).toOperationNode()
}

throw new Error(`invalid expression: ${JSON.stringify(exp)}`)
Expand Down
11 changes: 4 additions & 7 deletions src/parser/partition-by-parser.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { DynamicReferenceBuilder } from '../dynamic/dynamic-reference-builder.js'
import { ColumnNode } from '../operation-node/column-node.js'
import { GroupByItemNode } from '../operation-node/group-by-item-node.js'
import { PartitionByItemNode } from '../operation-node/partition-by-item-node.js'
import { ReferenceNode } from '../operation-node/reference-node.js'
import { SimpleReferenceExpressionNode } from '../operation-node/simple-reference-expression-node.js'
import {
parseReferenceExpressionOrList,
StringReference,
Expand All @@ -20,9 +18,8 @@ export function parsePartitionBy(
partitionBy: PartitionByExpressionOrList<any, any>
): PartitionByItemNode[] {
return (
parseReferenceExpressionOrList(partitionBy) as (
| ColumnNode
| ReferenceNode
)[]
parseReferenceExpressionOrList(
partitionBy
) as SimpleReferenceExpressionNode[]
).map(PartitionByItemNode.create)
}
12 changes: 6 additions & 6 deletions src/parser/reference-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import { OperationNode } from '../operation-node/operation-node.js'
import { Expression } from '../expression/expression.js'
import { SimpleReferenceExpressionNode } from '../operation-node/simple-reference-expression-node.js'

export type StringReference<DB, TB extends keyof DB> =
| AnyColumn<DB, TB>
| AnyColumnWithTable<DB, TB>

export type SimpleReferenceExpression<DB, TB extends keyof DB> =
| StringReference<DB, TB>
| DynamicReferenceBuilder<any>
Expand All @@ -34,10 +38,6 @@ export type ReferenceExpressionOrList<DB, TB extends keyof DB> =
| ReferenceExpression<DB, TB>
| ReadonlyArray<ReferenceExpression<DB, TB>>

export type StringReference<DB, TB extends keyof DB> =
| AnyColumn<DB, TB>
| AnyColumnWithTable<DB, TB>

export type ExtractTypeFromReferenceExpression<
DB,
TB extends keyof DB,
Expand Down Expand Up @@ -88,7 +88,7 @@ export function parseSimpleReferenceExpression(

export function parseReferenceExpressionOrList(
arg: ReferenceExpressionOrList<any, any>
): SimpleReferenceExpressionNode[] {
): OperationNode[] {
if (isReadonlyArray(arg)) {
return arg.map((it) => parseReferenceExpression(it))
} else {
Expand All @@ -98,7 +98,7 @@ export function parseReferenceExpressionOrList(

export function parseReferenceExpression(
exp: ReferenceExpression<any, any>
): SimpleReferenceExpressionNode {
): OperationNode {
if (isExpressionOrFactory(exp)) {
return parseExpression(exp)
}
Expand Down
8 changes: 2 additions & 6 deletions src/query-builder/select-query-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,11 +493,7 @@ export class SelectQueryBuilder<DB, TB extends keyof DB, O>
}

/**
* Adds `distinct on` selections to the select clause.
*
* Takes the same inputs as the {@link SelectQueryBuilder.select | select} method.
* See the {@link SelectQueryBuilder.select | select} method's documentation for
* more examples.
* Adds `distinct on` expressions to the select clause.
*
* ### Examples
*
Expand Down Expand Up @@ -530,7 +526,7 @@ export class SelectQueryBuilder<DB, TB extends keyof DB, O>
distinctOn(selection: ReferenceExpressionOrList<DB, TB>): any {
return new SelectQueryBuilder({
...this.#props,
queryNode: SelectQueryNode.cloneWithDistinctOnSelections(
queryNode: SelectQueryNode.cloneWithDistinctOn(
this.#props.queryNode,
parseReferenceExpressionOrList(selection)
),
Expand Down
11 changes: 4 additions & 7 deletions src/query-compiler/default-query-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ import { PartitionByItemNode } from '../operation-node/partition-by-item-node.js
import { SetOperationNode } from '../operation-node/set-operation-node.js'
import { BinaryOperationNode } from '../operation-node/binary-operation-node.js'
import { UnaryOperationNode } from '../operation-node/unary-operation-node.js'
import { SimpleReferenceExpressionNode } from '../operation-node/simple-reference-expression-node.js'

export class DefaultQueryCompiler
extends OperationNodeVisitor
Expand Down Expand Up @@ -146,8 +145,8 @@ export class DefaultQueryCompiler

this.append('select ')

if (node.distinctOnSelections) {
this.compileDistinctOn(node.distinctOnSelections)
if (node.distinctOn) {
this.compileDistinctOn(node.distinctOn)
this.append(' ')
}

Expand Down Expand Up @@ -226,11 +225,9 @@ export class DefaultQueryCompiler
this.visitNode(node.column)
}

protected compileDistinctOn(
selections: ReadonlyArray<SimpleReferenceExpressionNode>
): void {
protected compileDistinctOn(expressions: ReadonlyArray<OperationNode>): void {
this.append('distinct on (')
this.compileList(selections)
this.compileList(expressions)
this.append(')')
}

Expand Down
1 change: 0 additions & 1 deletion src/schema/alter-column-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
ColumnDataType,
DataTypeNode,
} from '../operation-node/data-type-node.js'
import { OperationNode } from '../operation-node/operation-node.js'
import { OperationNodeSource } from '../operation-node/operation-node-source.js'
import {
DefaultValueExpression,
Expand Down
1 change: 0 additions & 1 deletion src/schema/alter-table-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import { UniqueConstraintNode } from '../operation-node/unique-constraint-node.j
import { CheckConstraintNode } from '../operation-node/check-constraint-node.js'
import { ForeignKeyConstraintNode } from '../operation-node/foreign-key-constraint-node.js'
import { ColumnNode } from '../operation-node/column-node.js'
import { DefaultValueExpression } from '../parser/default-value-parser.js'
import { parseTable } from '../parser/table-parser.js'
import { DropConstraintNode } from '../operation-node/drop-constraint-node.js'
import { Expression } from '../expression/expression.js'
Expand Down

0 comments on commit cb8d192

Please sign in to comment.