@@ -1352,6 +1352,8 @@ class Parser(metaclass=_Parser):
13521352 "VALIDATE" : lambda self : self ._parse_analyze_validate (),
13531353 }
13541354
1355+ PARTITION_KEYWORDS = {"PARTITION" , "SUBPARTITION" }
1356+
13551357 AMBIGUOUS_ALIAS_TOKENS = (TokenType .LIMIT , TokenType .OFFSET )
13561358
13571359 OPERATION_MODIFIERS : t .Set [str ] = set ()
@@ -2984,11 +2986,13 @@ def _parse_cache(self) -> exp.Cache:
29842986 )
29852987
29862988 def _parse_partition (self ) -> t .Optional [exp .Partition ]:
2987- if not self ._match ( TokenType . PARTITION ):
2989+ if not self ._match_texts ( self . PARTITION_KEYWORDS ):
29882990 return None
29892991
29902992 return self .expression (
2991- exp .Partition , expressions = self ._parse_wrapped_csv (self ._parse_assignment )
2993+ exp .Partition ,
2994+ subpartition = self ._prev .text .upper () == "SUBPARTITION" ,
2995+ expressions = self ._parse_wrapped_csv (self ._parse_assignment ),
29922996 )
29932997
29942998 def _parse_value (self ) -> t .Optional [exp .Tuple ]:
@@ -7145,44 +7149,41 @@ def _parse_analyze(self) -> exp.Analyze | exp.Command:
71457149 else :
71467150 options .append (self ._prev .text .upper ())
71477151
7148- kind = None
7149- mode = None
71507152 this : t .Optional [exp .Expression ] = None
7151- partition : t .Optional [exp .Expression ] = None
71527153 inner_expression : t .Optional [exp .Expression ] = None
71537154
7155+ kind = self ._curr and self ._curr .text .upper ()
7156+
71547157 if self ._match (TokenType .TABLE ) or self ._match (TokenType .INDEX ):
7155- kind = self ._prev .text .upper ()
71567158 this = self ._parse_table_parts ()
71577159 elif self ._match_text_seq ("TABLES" ):
7158- kind = self ._prev .text .upper ()
71597160 if self ._match_set ((TokenType .FROM , TokenType .IN )):
71607161 kind = f"{ kind } { self ._prev .text .upper ()} "
71617162 this = self ._parse_table (schema = True , is_db_reference = True )
71627163 elif self ._match_text_seq ("DATABASE" ):
7163- kind = self ._prev .text .upper ()
71647164 this = self ._parse_table (schema = True , is_db_reference = True )
71657165 elif self ._match_text_seq ("CLUSTER" ):
7166- kind = self ._prev .text .upper ()
71677166 this = self ._parse_table ()
71687167 # Try matching inner expr keywords before fallback to parse table.
71697168 elif self ._match_texts (self .ANALYZE_EXPRESSION_PARSERS ):
7169+ kind = None
71707170 inner_expression = self .ANALYZE_EXPRESSION_PARSERS [self ._prev .text .upper ()](self )
71717171 else :
71727172 # Empty kind https://prestodb.io/docs/current/sql/analyze.html
7173+ kind = None
71737174 this = self ._parse_table_parts ()
71747175
7175- try :
7176- partition = self ._parse_partition ()
7177- except ParseError :
7176+ partition = self ._try_parse (self ._parse_partition )
7177+ if not partition and self ._match_texts (self .PARTITION_KEYWORDS ):
71787178 return self ._parse_as_command (start )
71797179
71807180 # https://docs.starrocks.io/docs/sql-reference/sql-statements/cbo_stats/ANALYZE_TABLE/
7181- if self ._match_text_seq ("WITH" , "SYNC" , "MODE" , advance = False ) or self ._match_text_seq (
7182- "WITH" , "ASYNC" , "MODE" , advance = False
7181+ if self ._match_text_seq ("WITH" , "SYNC" , "MODE" ) or self ._match_text_seq (
7182+ "WITH" , "ASYNC" , "MODE"
71837183 ):
7184- mode = f"WITH { self ._next .text .upper ()} MODE"
7185- self ._advance (3 )
7184+ mode = f"WITH { self ._tokens [self ._index - 2 ].text .upper ()} MODE"
7185+ else :
7186+ mode = None
71867187
71877188 if self ._match_texts (self .ANALYZE_EXPRESSION_PARSERS ):
71887189 inner_expression = self .ANALYZE_EXPRESSION_PARSERS [self ._prev .text .upper ()](self )
@@ -7200,7 +7201,7 @@ def _parse_analyze(self) -> exp.Analyze | exp.Command:
72007201 )
72017202
72027203 # https://spark.apache.org/docs/3.5.1/sql-ref-syntax-aux-analyze-table.html
7203- def _parse_analyze_statistics (self ) -> exp .Statistics :
7204+ def _parse_analyze_statistics (self ) -> exp .AnalyzeStatistics :
72047205 this = None
72057206 kind = self ._prev .text .upper ()
72067207 option = self ._prev .text .upper () if self ._match_text_seq ("DELTA" ) else None
@@ -7221,14 +7222,14 @@ def _parse_analyze_statistics(self) -> exp.Statistics:
72217222 sample = self ._parse_number ()
72227223 expressions = [
72237224 self .expression (
7224- exp .Sample ,
7225+ exp .AnalyzeSample ,
72257226 sample = sample ,
72267227 kind = self ._prev .text .upper () if self ._match (TokenType .PERCENT ) else None ,
72277228 )
72287229 ]
72297230
72307231 return self .expression (
7231- exp .Statistics , kind = kind , option = option , this = this , expressions = expressions
7232+ exp .AnalyzeStatistics , kind = kind , option = option , this = this , expressions = expressions
72327233 )
72337234
72347235 # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ANALYZE.html
@@ -7257,24 +7258,21 @@ def _parse_analyze_columns(self) -> t.Optional[exp.AnalyzeColumns]:
72577258 this = self ._prev .text .upper ()
72587259 if self ._match_text_seq ("COLUMNS" ):
72597260 return self .expression (exp .AnalyzeColumns , this = f"{ this } { self ._prev .text .upper ()} " )
7260- self .raise_error ("Expecting COLUMNS" )
72617261 return None
72627262
72637263 def _parse_analyze_delete (self ) -> t .Optional [exp .AnalyzeDelete ]:
72647264 kind = self ._prev .text .upper () if self ._match_text_seq ("SYSTEM" ) else None
72657265 if self ._match_text_seq ("STATISTICS" ):
72667266 return self .expression (exp .AnalyzeDelete , kind = kind )
7267- self .raise_error ("Expecting STATISTICS" )
72687267 return None
72697268
72707269 def _parse_analyze_list (self ) -> t .Optional [exp .AnalyzeListChainedRows ]:
72717270 if self ._match_text_seq ("CHAINED" , "ROWS" ):
72727271 return self .expression (exp .AnalyzeListChainedRows , expression = self ._parse_into ())
7273- self .raise_error ("Expecting CHAINED ROWS" )
72747272 return None
72757273
72767274 # https://dev.mysql.com/doc/refman/8.4/en/analyze-table.html
7277- def _parse_analyze_histogram (self ) -> exp .Histogram :
7275+ def _parse_analyze_histogram (self ) -> exp .AnalyzeHistogram :
72787276 this = self ._prev .text .upper ()
72797277 expression : t .Optional [exp .Expression ] = None
72807278 expressions = []
@@ -7305,7 +7303,7 @@ def _parse_analyze_histogram(self) -> exp.Histogram:
73057303 expression = self .expression (exp .UsingData , this = self ._parse_string ())
73067304
73077305 return self .expression (
7308- exp .Histogram ,
7306+ exp .AnalyzeHistogram ,
73097307 this = this ,
73107308 expressions = expressions ,
73117309 expression = expression ,
0 commit comments