Skip to content

Commit 1ccedcd

Browse files
feat: add alter type query support. (#1363)
Co-authored-by: Igal Klebanov <igalklebanov@gmail.com>
1 parent b65f323 commit 1ccedcd

17 files changed

Lines changed: 677 additions & 18 deletions

src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type { KyselyTypeError } from './util/type-error.js'
77

88
export * from './kysely.js'
99
export * from './query-creator.js'
10+
export * from './query-finalizer.js'
1011

1112
export * from './expression/expression.js'
1213
export {
@@ -49,7 +50,7 @@ export type * from './query-executor/query-executor-provider.js'
4950
export * from './query-compiler/default-query-compiler.js'
5051
export * from './query-compiler/compiled-query.js'
5152

52-
export * from './schema/schema.js'
53+
export * from './schema/schema-module.js'
5354
export * from './schema/create-table-builder.js'
5455
export * from './schema/create-type-builder.js'
5556
export * from './schema/drop-table-builder.js'
@@ -235,6 +236,9 @@ export * from './operation-node/values-node.js'
235236
export * from './operation-node/when-node.js'
236237
export * from './operation-node/where-node.js'
237238
export * from './operation-node/with-node.js'
239+
export * from './operation-node/alter-type-node.js'
240+
export * from './operation-node/add-value-node.js'
241+
export * from './operation-node/rename-value-node.js'
238242

239243
export type * from './util/column-type.js'
240244
export * from './util/compilable.js'

src/kysely.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Dialect } from './dialect/dialect.js'
2-
import { SchemaModule } from './schema/schema.js'
2+
import { SchemaModule } from './schema/schema-module.js'
33
import { DynamicModule } from './dynamic/dynamic.js'
44
import { DefaultConnectionProvider } from './driver/default-connection-provider.js'
55
import type { QueryExecutor } from './query-executor/query-executor.js'
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { OperationNode } from './operation-node.js'
2+
import { freeze } from '../util/object-utils.js'
3+
import type { ValueNode } from './value-node.js'
4+
5+
export type AddValueNodeProps = Omit<AddValueNode, 'kind' | 'value'>
6+
7+
export interface AddValueNode extends OperationNode {
8+
readonly kind: 'AddValueNode'
9+
readonly value: ValueNode
10+
readonly ifNotExists?: boolean
11+
readonly neighborValue?: ValueNode
12+
readonly isBefore?: boolean
13+
}
14+
15+
type AddValueNodeFactory = Readonly<{
16+
is(node: OperationNode): node is AddValueNode
17+
create(value: ValueNode): Readonly<AddValueNode>
18+
cloneWith(
19+
node: AddValueNode,
20+
props: AddValueNodeProps,
21+
): Readonly<AddValueNode>
22+
}>
23+
24+
/**
25+
* @internal
26+
*/
27+
export const AddValueNode: AddValueNodeFactory = freeze<AddValueNodeFactory>({
28+
is(node): node is AddValueNode {
29+
return node.kind === 'AddValueNode'
30+
},
31+
32+
create(value) {
33+
return freeze({
34+
kind: 'AddValueNode',
35+
value,
36+
})
37+
},
38+
39+
cloneWith(node, props) {
40+
return freeze({
41+
...node,
42+
...props,
43+
})
44+
},
45+
})
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import type { OperationNode } from './operation-node.js'
2+
import { freeze } from '../util/object-utils.js'
3+
import type { SchemableIdentifierNode } from './schemable-identifier-node.js'
4+
import type { IdentifierNode } from './identifier-node.js'
5+
import type { AddValueNode } from './add-value-node.js'
6+
import type { RenameValueNode } from './rename-value-node.js'
7+
8+
export type AlterTypeNodeProps = Omit<AlterTypeNode, 'kind' | 'name'>
9+
10+
export interface AlterTypeNode extends OperationNode {
11+
readonly kind: 'AlterTypeNode'
12+
readonly name: SchemableIdentifierNode
13+
readonly addValue?: AddValueNode
14+
readonly renameTo?: IdentifierNode
15+
readonly renameValue?: RenameValueNode
16+
readonly setSchema?: IdentifierNode
17+
}
18+
19+
type AlterTypeNodeFactory = Readonly<{
20+
is(node: OperationNode): node is AlterTypeNode
21+
create(name: SchemableIdentifierNode): Readonly<AlterTypeNode>
22+
cloneWith(
23+
node: AlterTypeNode,
24+
props: AlterTypeNodeProps,
25+
): Readonly<AlterTypeNode>
26+
}>
27+
28+
/**
29+
* @internal
30+
*/
31+
export const AlterTypeNode: AlterTypeNodeFactory = freeze<AlterTypeNodeFactory>(
32+
{
33+
is(node): node is AlterTypeNode {
34+
return node.kind === 'AlterTypeNode'
35+
},
36+
37+
create(name) {
38+
return freeze({
39+
kind: 'AlterTypeNode',
40+
name,
41+
})
42+
},
43+
44+
cloneWith(node, props) {
45+
return freeze({
46+
...node,
47+
...props,
48+
})
49+
},
50+
},
51+
)

src/operation-node/operation-node-transformer.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ import type { OrActionNode } from './or-action-node.js'
9999
import type { CollateNode } from './collate-node.js'
100100
import type { QueryId } from '../util/query-id.js'
101101
import type { RenameConstraintNode } from './rename-constraint-node.js'
102+
import type { AddValueNode } from './add-value-node.js'
103+
import type { AlterTypeNode } from './alter-type-node.js'
104+
import type { RenameValueNode } from './rename-value-node.js'
102105

103106
/**
104107
* Transforms an operation node tree into another one.
@@ -242,6 +245,9 @@ export class OperationNodeTransformer {
242245
OutputNode: this.transformOutput.bind(this),
243246
OrActionNode: this.transformOrAction.bind(this),
244247
CollateNode: this.transformCollate.bind(this),
248+
AlterTypeNode: this.transformAlterType.bind(this),
249+
AddValueNode: this.transformAddValue.bind(this),
250+
RenameValueNode: this.transformRenameValue.bind(this),
245251
})
246252

247253
transformNode<T extends OperationNode | undefined>(
@@ -1289,6 +1295,44 @@ export class OperationNodeTransformer {
12891295
})
12901296
}
12911297

1298+
protected transformAlterType(
1299+
node: AlterTypeNode,
1300+
queryId?: QueryId,
1301+
): AlterTypeNode {
1302+
return requireAllProps<AlterTypeNode>({
1303+
kind: 'AlterTypeNode',
1304+
name: this.transformNode(node.name, queryId),
1305+
addValue: this.transformNode(node.addValue, queryId),
1306+
renameTo: this.transformNode(node.renameTo, queryId),
1307+
renameValue: this.transformNode(node.renameValue, queryId),
1308+
setSchema: this.transformNode(node.setSchema, queryId),
1309+
})
1310+
}
1311+
1312+
protected transformAddValue(
1313+
node: AddValueNode,
1314+
queryId?: QueryId,
1315+
): AddValueNode {
1316+
return requireAllProps<AddValueNode>({
1317+
kind: 'AddValueNode',
1318+
value: this.transformNode(node.value, queryId),
1319+
ifNotExists: node.ifNotExists,
1320+
isBefore: node.isBefore,
1321+
neighborValue: this.transformNode(node.neighborValue, queryId),
1322+
})
1323+
}
1324+
1325+
protected transformRenameValue(
1326+
node: RenameValueNode,
1327+
queryId?: QueryId,
1328+
): RenameValueNode {
1329+
return requireAllProps<RenameValueNode>({
1330+
kind: 'RenameValueNode',
1331+
oldValue: this.transformNode(node.oldValue, queryId),
1332+
newValue: this.transformNode(node.newValue, queryId),
1333+
})
1334+
}
1335+
12921336
protected transformDataType(
12931337
node: DataTypeNode,
12941338
_queryId?: QueryId,

src/operation-node/operation-node-visitor.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ import type { RefreshMaterializedViewNode } from './refresh-materialized-view-no
100100
import type { OrActionNode } from './or-action-node.js'
101101
import type { CollateNode } from './collate-node.js'
102102
import type { RenameConstraintNode } from './rename-constraint-node.js'
103+
import type { AlterTypeNode } from './alter-type-node.js'
104+
import type { AddValueNode } from './add-value-node.js'
105+
import type { RenameValueNode } from './rename-value-node.js'
103106

104107
export abstract class OperationNodeVisitor {
105108
protected readonly nodeStack: OperationNode[] = []
@@ -207,6 +210,9 @@ export abstract class OperationNodeVisitor {
207210
OutputNode: this.visitOutput.bind(this),
208211
OrActionNode: this.visitOrAction.bind(this),
209212
CollateNode: this.visitCollate.bind(this),
213+
AlterTypeNode: this.visitAlterType.bind(this),
214+
AddValueNode: this.visitAddValue.bind(this),
215+
RenameValueNode: this.visitRenameValue.bind(this),
210216
})
211217

212218
protected readonly visitNode = (node: OperationNode): void => {
@@ -324,4 +330,7 @@ export abstract class OperationNodeVisitor {
324330
protected abstract visitOutput(node: OutputNode): void
325331
protected abstract visitOrAction(node: OrActionNode): void
326332
protected abstract visitCollate(node: CollateNode): void
333+
protected abstract visitAlterType(node: AlterTypeNode): void
334+
protected abstract visitAddValue(node: AddValueNode): void
335+
protected abstract visitRenameValue(node: RenameValueNode): void
327336
}

src/operation-node/operation-node.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ export type OperationNodeKind =
9898
| 'OrActionNode'
9999
| 'CollateNode'
100100
| 'RenameConstraintNode'
101+
| 'AlterTypeNode'
102+
| 'AddValueNode'
103+
| 'RenameValueNode'
101104

102105
export interface OperationNode {
103106
readonly kind: OperationNodeKind
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { freeze } from '../util/object-utils.js'
2+
import type { OperationNode } from './operation-node.js'
3+
import type { ValueNode } from './value-node.js'
4+
5+
export type RenameValueNodeProps = Omit<RenameValueNode, 'kind'>
6+
7+
export interface RenameValueNode extends OperationNode {
8+
readonly kind: 'RenameValueNode'
9+
readonly oldValue: ValueNode
10+
readonly newValue: ValueNode
11+
}
12+
13+
type RenameValueNodeFactory = Readonly<{
14+
is(node: OperationNode): node is RenameValueNode
15+
create(
16+
existingEnumValue: ValueNode,
17+
newEnumValue: ValueNode,
18+
): Readonly<RenameValueNode>
19+
}>
20+
21+
export const RenameValueNode: RenameValueNodeFactory =
22+
freeze<RenameValueNodeFactory>({
23+
is(node): node is RenameValueNode {
24+
return node.kind === 'RenameValueNode'
25+
},
26+
27+
create(oldValue, newValue) {
28+
return freeze({
29+
kind: 'RenameValueNode',
30+
oldValue,
31+
newValue,
32+
})
33+
},
34+
})

src/operation-node/root-operation-node.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { AlterTableNode } from './alter-table-node.js'
2+
import type { AlterTypeNode } from './alter-type-node.js'
23
import type { CreateIndexNode } from './create-index-node.js'
34
import type { CreateSchemaNode } from './create-schema-node.js'
45
import type { CreateTableNode } from './create-table-node.js'
@@ -29,11 +30,13 @@ export type RootOperationNode =
2930
| RawNode
3031
| CreateTypeNode
3132
| DropTypeNode
33+
| AlterTypeNode
3234

3335
const ROOT_OPERATION_NODE_KINDS: Readonly<
3436
Record<RootOperationNode['kind'], true>
3537
> = {
3638
AlterTableNode: true,
39+
AlterTypeNode: true,
3740
CreateIndexNode: true,
3841
CreateSchemaNode: true,
3942
CreateTableNode: true,

src/query-compiler/default-query-compiler.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ import type { CollateNode } from '../operation-node/collate-node.js'
117117
import type { QueryId } from '../util/query-id.js'
118118
import type { RenameConstraintNode } from '../operation-node/rename-constraint-node.js'
119119
import type { RootOperationNode } from '../operation-node/root-operation-node.js'
120+
import type { AddValueNode } from '../operation-node/add-value-node.js'
121+
import type { AlterTypeNode } from '../operation-node/alter-type-node.js'
122+
import type { RenameValueNode } from '../operation-node/rename-value-node.js'
120123

121124
const LIT_WRAP_REGEX = /'/g
122125

@@ -1461,6 +1464,46 @@ export class DefaultQueryCompiler
14611464
}
14621465
}
14631466

1467+
protected override visitAlterType(node: AlterTypeNode): void {
1468+
this.append('alter type ')
1469+
this.visitNode(node.name)
1470+
this.append(' ')
1471+
1472+
if (node.addValue) {
1473+
this.visitNode(node.addValue)
1474+
} else if (node.renameTo) {
1475+
this.append('rename to ')
1476+
this.visitNode(node.renameTo)
1477+
} else if (node.renameValue) {
1478+
this.visitNode(node.renameValue)
1479+
} else if (node.setSchema) {
1480+
this.append('set schema ')
1481+
this.visitNode(node.setSchema)
1482+
}
1483+
}
1484+
1485+
protected override visitAddValue(node: AddValueNode): void {
1486+
this.append('add value ')
1487+
1488+
if (node.ifNotExists) {
1489+
this.append('if not exists ')
1490+
}
1491+
1492+
this.visitNode(node.value)
1493+
1494+
if (node.neighborValue) {
1495+
this.append(node.isBefore ? ' before ' : ' after ')
1496+
this.visitNode(node.neighborValue)
1497+
}
1498+
}
1499+
1500+
protected override visitRenameValue(node: RenameValueNode): void {
1501+
this.append('rename value ')
1502+
this.visitNode(node.oldValue)
1503+
this.append(' to ')
1504+
this.visitNode(node.newValue)
1505+
}
1506+
14641507
protected override visitExplain(node: ExplainNode): void {
14651508
this.append('explain')
14661509

0 commit comments

Comments
 (0)