@@ -2333,8 +2333,8 @@ func (p *Parser) parseDDL() ast.DDL {
2333
2333
return p .parseCreateTable (pos )
2334
2334
case p .Token .IsKeywordLike ("SEQUENCE" ):
2335
2335
return p .parseCreateSequence (pos )
2336
- case p .Token .IsKeywordLike ("VIEW" ) || p . Token . Kind == "OR" :
2337
- return p .parseCreateView (pos )
2336
+ case p .Token .IsKeywordLike ("VIEW" ):
2337
+ return p .parseCreateView (pos , false )
2338
2338
case p .Token .IsKeywordLike ("INDEX" ) || p .Token .IsKeywordLike ("UNIQUE" ) || p .Token .IsKeywordLike ("NULL_FILTERED" ):
2339
2339
return p .parseCreateIndex (pos )
2340
2340
case p .Token .IsKeywordLike ("VECTOR" ):
@@ -2345,8 +2345,19 @@ func (p *Parser) parseDDL() ast.DDL {
2345
2345
return p .parseCreateRole (pos )
2346
2346
case p .Token .IsKeywordLike ("CHANGE" ):
2347
2347
return p .parseCreateChangeStream (pos )
2348
+ case p .Token .IsKeywordLike ("MODEL" ):
2349
+ return p .parseCreateModel (pos , false )
2350
+ case p .Token .Kind == "OR" :
2351
+ p .expect ("OR" )
2352
+ p .expectKeywordLike ("REPLACE" )
2353
+ switch {
2354
+ case p .Token .IsKeywordLike ("VIEW" ):
2355
+ return p .parseCreateView (pos , true )
2356
+ case p .Token .IsKeywordLike ("MODEL" ):
2357
+ return p .parseCreateModel (pos , true )
2358
+ }
2348
2359
}
2349
- p .panicfAtToken (& p .Token , "expected pseudo keyword: DATABASE, TABLE, INDEX, UNIQUE, NULL_FILTERED, ROLE, CHANGE but: %s" , p .Token .AsString )
2360
+ p .panicfAtToken (& p .Token , "expected pseudo keyword: DATABASE, TABLE, INDEX, UNIQUE, NULL_FILTERED, ROLE, CHANGE, OR but: %s" , p .Token .AsString )
2350
2361
case p .Token .IsKeywordLike ("ALTER" ):
2351
2362
p .nextToken ()
2352
2363
switch {
@@ -2366,6 +2377,8 @@ func (p *Parser) parseDDL() ast.DDL {
2366
2377
return p .parseAlterChangeStream (pos )
2367
2378
case p .Token .IsKeywordLike ("STATISTICS" ):
2368
2379
return p .parseAlterStatistics (pos )
2380
+ case p .Token .IsKeywordLike ("MODEL" ):
2381
+ return p .parseAlterModel (pos )
2369
2382
}
2370
2383
p .panicfAtToken (& p .Token , "expected pseudo keyword: TABLE, CHANGE, but: %s" , p .Token .AsString )
2371
2384
case p .Token .IsKeywordLike ("DROP" ):
@@ -2391,8 +2404,10 @@ func (p *Parser) parseDDL() ast.DDL {
2391
2404
return p .parseDropRole (pos )
2392
2405
case p .Token .IsKeywordLike ("CHANGE" ):
2393
2406
return p .parseDropChangeStream (pos )
2407
+ case p .Token .IsKeywordLike ("MODEL" ):
2408
+ return p .parseDropModel (pos )
2394
2409
}
2395
- p .panicfAtToken (& p .Token , "expected pseudo keyword: TABLE, INDEX, ROLE, CHANGE, but: %s" , p .Token .AsString )
2410
+ p .panicfAtToken (& p .Token , "expected pseudo keyword: TABLE, INDEX, ROLE, CHANGE, MODEL, but: %s" , p .Token .AsString )
2396
2411
case p .Token .IsKeywordLike ("RENAME" ):
2397
2412
p .nextToken ()
2398
2413
return p .parseRenameTable (pos )
@@ -2603,13 +2618,7 @@ func (p *Parser) parseCreateSequence(pos token.Pos) *ast.CreateSequence {
2603
2618
}
2604
2619
}
2605
2620
2606
- func (p * Parser ) parseCreateView (pos token.Pos ) * ast.CreateView {
2607
- var orReplace bool
2608
- if p .Token .Kind == "OR" {
2609
- p .nextToken ()
2610
- p .expectKeywordLike ("REPLACE" )
2611
- orReplace = true
2612
- }
2621
+ func (p * Parser ) parseCreateView (pos token.Pos , orReplace bool ) * ast.CreateView {
2613
2622
p .expectKeywordLike ("VIEW" )
2614
2623
2615
2624
name := p .parsePath ()
@@ -3783,6 +3792,88 @@ func (p *Parser) parseAnalyze() *ast.Analyze {
3783
3792
}
3784
3793
}
3785
3794
3795
+ func (p * Parser ) tryParseCreateModelColumn () * ast.CreateModelColumn {
3796
+ name := p .parseIdent ()
3797
+ dataType := p .parseSchemaType ()
3798
+ options := p .tryParseOptions ()
3799
+
3800
+ return & ast.CreateModelColumn {
3801
+ Name : name ,
3802
+ DataType : dataType ,
3803
+ Options : options ,
3804
+ }
3805
+ }
3806
+
3807
+ func (p * Parser ) tryParseCreateModelInputOutput () * ast.CreateModelInputOutput {
3808
+ if ! p .Token .IsKeywordLike ("INPUT" ) {
3809
+ return nil
3810
+ }
3811
+
3812
+ pos := p .expectKeywordLike ("INPUT" ).Pos
3813
+ p .expect ("(" )
3814
+ inputColumns := parseCommaSeparatedList (p , p .tryParseCreateModelColumn )
3815
+ p .expect (")" )
3816
+
3817
+ p .expectKeywordLike ("OUTPUT" )
3818
+ p .expect ("(" )
3819
+ outputColumns := parseCommaSeparatedList (p , p .tryParseCreateModelColumn )
3820
+ rparen := p .expect (")" ).Pos
3821
+
3822
+ return & ast.CreateModelInputOutput {
3823
+ Input : pos ,
3824
+ Rparen : rparen ,
3825
+ InputColumns : inputColumns ,
3826
+ OutputColumns : outputColumns ,
3827
+ }
3828
+ }
3829
+
3830
+ func (p * Parser ) parseCreateModel (pos token.Pos , orReplace bool ) * ast.CreateModel {
3831
+ p .expectKeywordLike ("MODEL" )
3832
+ name := p .parseIdent ()
3833
+ ifNotExists := p .parseIfNotExists ()
3834
+ inputOutput := p .tryParseCreateModelInputOutput ()
3835
+ remote := p .expectKeywordLike ("REMOTE" ).Pos
3836
+ options := p .tryParseOptions ()
3837
+
3838
+ return & ast.CreateModel {
3839
+ Create : pos ,
3840
+ OrReplace : orReplace ,
3841
+ IfNotExists : ifNotExists ,
3842
+ Name : name ,
3843
+ InputOutput : inputOutput ,
3844
+ Remote : remote ,
3845
+ Options : options ,
3846
+ }
3847
+
3848
+ }
3849
+
3850
+ func (p * Parser ) parseAlterModel (pos token.Pos ) * ast.AlterModel {
3851
+ p .expectKeywordLike ("MODEL" )
3852
+ ifExists := p .parseIfExists ()
3853
+ name := p .parseIdent ()
3854
+ p .expect ("SET" )
3855
+ options := p .parseOptions ()
3856
+
3857
+ return & ast.AlterModel {
3858
+ Alter : pos ,
3859
+ IfExists : ifExists ,
3860
+ Name : name ,
3861
+ Options : options ,
3862
+ }
3863
+ }
3864
+
3865
+ func (p * Parser ) parseDropModel (pos token.Pos ) * ast.DropModel {
3866
+ p .expectKeywordLike ("MODEL" )
3867
+ ifExists := p .parseIfExists ()
3868
+ name := p .parseIdent ()
3869
+
3870
+ return & ast.DropModel {
3871
+ Drop : pos ,
3872
+ IfExists : ifExists ,
3873
+ Name : name ,
3874
+ }
3875
+ }
3876
+
3786
3877
var scalarSchemaTypes = []string {
3787
3878
"BOOL" ,
3788
3879
"INT64" ,
0 commit comments