11import { SqlComponent } from "./SqlComponent" ;
22import type { SelectQuery } from "./SelectQuery" ;
3- import { ColumnReference , FunctionCall , IdentifierString , RawString } from "./ValueComponent" ;
3+ import {
4+ ColumnReference ,
5+ FunctionCall ,
6+ IdentifierString ,
7+ RawString ,
8+ ValueComponent ,
9+ TypeValue ,
10+ QualifiedName
11+ } from "./ValueComponent" ;
412import { SimpleSelectQuery } from "./SimpleSelectQuery" ;
513import { SelectClause , SelectItem , FromClause , TableSource , SourceExpression } from "./Clause" ;
614import { SelectValueCollector } from "../transformers/SelectValueCollector" ;
715
8- // Represents a CREATE TABLE query model
9- // Supports temporary tables and AS SELECT ...
16+ export type ReferentialAction = 'cascade' | 'restrict' | 'no action' | 'set null' | 'set default' ;
17+ export type ConstraintDeferrability = 'deferrable' | 'not deferrable' | null ;
18+ export type ConstraintInitially = 'immediate' | 'deferred' | null ;
19+ export type MatchType = 'full' | 'partial' | 'simple' | null ;
20+
21+ /**
22+ * Represents a REFERENCES clause definition that can be shared between column and table constraints.
23+ */
24+ export class ReferenceDefinition extends SqlComponent {
25+ static kind = Symbol ( "ReferenceDefinition" ) ;
26+ targetTable : QualifiedName ;
27+ columns : IdentifierString [ ] | null ;
28+ matchType : MatchType ;
29+ onDelete : ReferentialAction | null ;
30+ onUpdate : ReferentialAction | null ;
31+ deferrable : ConstraintDeferrability ;
32+ initially : ConstraintInitially ;
33+
34+ constructor ( params : {
35+ targetTable : QualifiedName ;
36+ columns ?: IdentifierString [ ] | null ;
37+ matchType ?: MatchType ;
38+ onDelete ?: ReferentialAction | null ;
39+ onUpdate ?: ReferentialAction | null ;
40+ deferrable ?: ConstraintDeferrability ;
41+ initially ?: ConstraintInitially ;
42+ } ) {
43+ super ( ) ;
44+ this . targetTable = params . targetTable ;
45+ this . columns = params . columns ? [ ...params . columns ] : null ;
46+ this . matchType = params . matchType ?? null ;
47+ this . onDelete = params . onDelete ?? null ;
48+ this . onUpdate = params . onUpdate ?? null ;
49+ this . deferrable = params . deferrable ?? null ;
50+ this . initially = params . initially ?? null ;
51+ }
52+ }
53+
54+ export type ColumnConstraintKind =
55+ | 'not-null'
56+ | 'null'
57+ | 'default'
58+ | 'primary-key'
59+ | 'unique'
60+ | 'references'
61+ | 'check'
62+ | 'generated-always-identity'
63+ | 'generated-by-default-identity'
64+ | 'raw' ;
65+
66+ /**
67+ * Column-level constraint definition.
68+ */
69+ export class ColumnConstraintDefinition extends SqlComponent {
70+ static kind = Symbol ( "ColumnConstraintDefinition" ) ;
71+ kind : ColumnConstraintKind ;
72+ constraintName ?: IdentifierString ;
73+ defaultValue ?: ValueComponent ;
74+ checkExpression ?: ValueComponent ;
75+ reference ?: ReferenceDefinition ;
76+ rawClause ?: RawString ;
77+
78+ constructor ( params : {
79+ kind : ColumnConstraintKind ;
80+ constraintName ?: IdentifierString ;
81+ defaultValue ?: ValueComponent ;
82+ checkExpression ?: ValueComponent ;
83+ reference ?: ReferenceDefinition ;
84+ rawClause ?: RawString ;
85+ } ) {
86+ super ( ) ;
87+ this . kind = params . kind ;
88+ this . constraintName = params . constraintName ;
89+ this . defaultValue = params . defaultValue ;
90+ this . checkExpression = params . checkExpression ;
91+ this . reference = params . reference ;
92+ this . rawClause = params . rawClause ;
93+ }
94+ }
95+
96+ export type TableConstraintKind = 'primary-key' | 'unique' | 'foreign-key' | 'check' | 'raw' ;
97+
98+ /**
99+ * Table-level constraint definition.
100+ */
101+ export class TableConstraintDefinition extends SqlComponent {
102+ static kind = Symbol ( "TableConstraintDefinition" ) ;
103+ kind : TableConstraintKind ;
104+ constraintName ?: IdentifierString ;
105+ columns : IdentifierString [ ] | null ;
106+ reference ?: ReferenceDefinition ;
107+ checkExpression ?: ValueComponent ;
108+ rawClause ?: RawString ;
109+ deferrable : ConstraintDeferrability ;
110+ initially : ConstraintInitially ;
111+
112+ constructor ( params : {
113+ kind : TableConstraintKind ;
114+ constraintName ?: IdentifierString ;
115+ columns ?: IdentifierString [ ] | null ;
116+ reference ?: ReferenceDefinition ;
117+ checkExpression ?: ValueComponent ;
118+ rawClause ?: RawString ;
119+ deferrable ?: ConstraintDeferrability ;
120+ initially ?: ConstraintInitially ;
121+ } ) {
122+ super ( ) ;
123+ this . kind = params . kind ;
124+ this . constraintName = params . constraintName ;
125+ this . columns = params . columns ? [ ...params . columns ] : null ;
126+ this . reference = params . reference ;
127+ this . checkExpression = params . checkExpression ;
128+ this . rawClause = params . rawClause ;
129+ this . deferrable = params . deferrable ?? null ;
130+ this . initially = params . initially ?? null ;
131+ }
132+ }
133+
134+ /**
135+ * Represents a single column definition within CREATE TABLE.
136+ */
137+ export class TableColumnDefinition extends SqlComponent {
138+ static kind = Symbol ( "TableColumnDefinition" ) ;
139+ name : IdentifierString ;
140+ dataType ?: TypeValue | RawString ;
141+ constraints : ColumnConstraintDefinition [ ] ;
142+
143+ constructor ( params : {
144+ name : IdentifierString ;
145+ dataType ?: TypeValue | RawString ;
146+ constraints ?: ColumnConstraintDefinition [ ] ;
147+ } ) {
148+ super ( ) ;
149+ this . name = params . name ;
150+ this . dataType = params . dataType ;
151+ this . constraints = params . constraints ? [ ...params . constraints ] : [ ] ;
152+ }
153+ }
154+
155+ // Represents a CREATE TABLE query model that supports column definitions and AS SELECT variants.
10156export class CreateTableQuery extends SqlComponent {
11- /** SqlComponent kind symbol for visitor pattern */
12157 static kind = Symbol ( "CreateTableQuery" ) ;
13- /** Table name (with optional schema) */
14158 tableName : IdentifierString ;
15- /** If true, this is a temporary table */
159+ namespaces : string [ ] | null ;
16160 isTemporary : boolean ;
17- /** If true, the statement includes IF NOT EXISTS */
18161 ifNotExists : boolean ;
19- /** Optional: SELECT query for AS SELECT ... */
162+ columns : TableColumnDefinition [ ] ;
163+ tableConstraints : TableConstraintDefinition [ ] ;
164+ tableOptions ?: RawString | null ;
20165 asSelectQuery ?: SelectQuery ;
21166
22167 constructor ( params : {
23168 tableName : string ;
169+ namespaces ?: string [ ] | null ;
24170 isTemporary ?: boolean ;
25171 ifNotExists ?: boolean ;
172+ columns ?: TableColumnDefinition [ ] ;
173+ tableConstraints ?: TableConstraintDefinition [ ] ;
174+ tableOptions ?: RawString | null ;
26175 asSelectQuery ?: SelectQuery ;
27176 } ) {
28177 super ( ) ;
29178 this . tableName = new IdentifierString ( params . tableName ) ;
179+ this . namespaces = params . namespaces ? [ ...params . namespaces ] : null ;
30180 this . isTemporary = params . isTemporary ?? false ;
31181 this . ifNotExists = params . ifNotExists ?? false ;
182+ this . columns = params . columns ? [ ...params . columns ] : [ ] ;
183+ this . tableConstraints = params . tableConstraints ? [ ...params . tableConstraints ] : [ ] ;
184+ this . tableOptions = params . tableOptions ?? null ;
32185 this . asSelectQuery = params . asSelectQuery ;
33186 }
34187
@@ -37,23 +190,36 @@ export class CreateTableQuery extends SqlComponent {
37190 */
38191 getSelectQuery ( ) : SimpleSelectQuery {
39192 let selectItems : SelectItem [ ] ;
193+
194+ // Prefer explicit AS SELECT query columns when present.
40195 if ( this . asSelectQuery ) {
41- // Use SelectValueCollector to get columns from asSelectQuery
42196 const collector = new SelectValueCollector ( ) ;
43197 const values = collector . collect ( this . asSelectQuery ) ;
44198 selectItems = values . map ( val => new SelectItem ( val . value , val . name ) ) ;
199+ } else if ( this . columns . length > 0 ) {
200+ // Use defined column names when the table definition is DDL-based.
201+ selectItems = this . columns . map ( column => new SelectItem (
202+ new ColumnReference ( null , column . name ) ,
203+ column . name . name
204+ ) ) ;
45205 } else {
46- // fallback: wildcard
206+ // Fallback to wild-card selection when no column metadata is available.
47207 selectItems = [ new SelectItem ( new RawString ( "*" ) ) ] ;
48208 }
209+
210+ // Build a simple SELECT ... FROM table query.
211+ const qualifiedName = this . namespaces && this . namespaces . length > 0
212+ ? [ ...this . namespaces , this . tableName . name ] . join ( "." )
213+ : this . tableName . name ;
214+
49215 return new SimpleSelectQuery ( {
50216 selectClause : new SelectClause ( selectItems ) ,
51217 fromClause : new FromClause (
52218 new SourceExpression (
53- new TableSource ( null , this . tableName . name ) ,
219+ new TableSource ( null , qualifiedName ) ,
54220 null
55221 ) ,
56- null // joins
222+ null
57223 ) ,
58224 } ) ;
59225 }
@@ -62,16 +228,20 @@ export class CreateTableQuery extends SqlComponent {
62228 * Returns a SelectQuery that counts all rows in this table.
63229 */
64230 getCountQuery ( ) : SimpleSelectQuery {
231+ const qualifiedName = this . namespaces && this . namespaces . length > 0
232+ ? [ ...this . namespaces , this . tableName . name ] . join ( "." )
233+ : this . tableName . name ;
234+
65235 return new SimpleSelectQuery ( {
66236 selectClause : new SelectClause ( [
67237 new SelectItem ( new FunctionCall ( null , "count" , new ColumnReference ( null , "*" ) , null ) )
68238 ] ) ,
69239 fromClause : new FromClause (
70240 new SourceExpression (
71- new TableSource ( null , this . tableName . name ) ,
241+ new TableSource ( null , qualifiedName ) ,
72242 null
73243 ) ,
74- null // joins
244+ null
75245 ) ,
76246 } ) ;
77247 }
0 commit comments