sqlglot.generators.starrocks
1from __future__ import annotations 2 3import typing as t 4 5from sqlglot import exp, transforms 6from sqlglot.dialects.dialect import ( 7 approx_count_distinct_sql, 8 arrow_json_extract_sql, 9 no_pivot_sql, 10 rename_func, 11 weekstart_unit_to_str, 12 inline_array_sql, 13 property_sql, 14 var_map_sql, 15) 16from sqlglot.generator import Generator 17from sqlglot.generators.mysql import MySQLGenerator 18 19 20def _eliminate_between_in_delete(expression: exp.Expr) -> exp.Expr: 21 """ 22 StarRocks doesn't support BETWEEN in DELETE statements, so we convert 23 BETWEEN expressions to explicit comparisons. 24 25 https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/DELETE/#parameters 26 27 Example: 28 >>> from sqlglot import parse_one 29 >>> expr = parse_one("DELETE FROM t WHERE x BETWEEN 1 AND 10") 30 >>> print(_eliminate_between_in_delete(expr).sql(dialect="starrocks")) 31 DELETE FROM t WHERE x >= 1 AND x <= 10 32 """ 33 if where := expression.args.get("where"): 34 for between in where.find_all(exp.Between): 35 between.replace( 36 exp.and_( 37 exp.GTE(this=between.this.copy(), expression=between.args["low"]), 38 exp.LTE(this=between.this.copy(), expression=between.args["high"]), 39 copy=False, 40 ) 41 ) 42 return expression 43 44 45# https://docs.starrocks.io/docs/sql-reference/sql-functions/spatial-functions/st_distance_sphere/ 46def st_distance_sphere(self, expression: exp.StDistance) -> str: 47 point1 = expression.this 48 point2 = expression.expression 49 50 point1_x = self.func("ST_X", point1) 51 point1_y = self.func("ST_Y", point1) 52 point2_x = self.func("ST_X", point2) 53 point2_y = self.func("ST_Y", point2) 54 55 return self.func("ST_Distance_Sphere", point1_x, point1_y, point2_x, point2_y) 56 57 58class StarRocksGenerator(MySQLGenerator): 59 EXCEPT_INTERSECT_SUPPORT_ALL_CLAUSE = False 60 JSON_TYPE_REQUIRED_FOR_EXTRACTION = False 61 VARCHAR_REQUIRES_SIZE = False 62 PARSE_JSON_NAME: str | None = "PARSE_JSON" 63 WITH_PROPERTIES_PREFIX = "PROPERTIES" 64 UPDATE_STATEMENT_SUPPORTS_FROM = True 65 INSERT_OVERWRITE = " OVERWRITE" 66 CAST_TO_INT_ROUNDS = False 67 68 # StarRocks doesn't support "IS TRUE/FALSE" syntax. 69 IS_BOOL_ALLOWED = False 70 # StarRocks doesn't support renaming a table with a database. 71 RENAME_TABLE_WITH_DB = False 72 73 ALTER_PARTITION_OPTIONS = ( 74 *MySQLGenerator.ALTER_PARTITION_OPTIONS, 75 exp.DistributedByProperty, 76 exp.PartitionedByProperty, 77 ) 78 79 CAST_MAPPING: t.ClassVar[dict[exp.DType, str]] = {} 80 81 TYPE_MAPPING = { 82 **MySQLGenerator.TYPE_MAPPING, 83 exp.DType.HLLSKETCH: "HLL", 84 exp.DType.INT128: "LARGEINT", 85 exp.DType.TEXT: "STRING", 86 exp.DType.TIMESTAMP: "DATETIME", 87 exp.DType.TIMESTAMPTZ: "DATETIME", 88 } 89 90 SQL_SECURITY_VIEW_LOCATION: t.ClassVar = exp.Properties.Location.POST_SCHEMA 91 92 PROPERTIES_LOCATION = { 93 **MySQLGenerator.PROPERTIES_LOCATION, 94 exp.PrimaryKey: exp.Properties.Location.POST_SCHEMA, 95 exp.UniqueKeyProperty: exp.Properties.Location.POST_SCHEMA, 96 exp.RollupProperty: exp.Properties.Location.POST_SCHEMA, 97 exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA, 98 exp.Property: exp.Properties.Location.POST_WITH, 99 } 100 101 TRANSFORMS = { 102 # StarRocks uses the native TRIM(str, chars)/LTRIM/RTRIM function form, not 103 # MySQL's TRIM(chars FROM str) syntax, so it falls back to the base generator. 104 **{ 105 k: v 106 for k, v in MySQLGenerator.TRANSFORMS.items() 107 if k not in (exp.DateDiff, exp.DateTrunc, exp.Pivot, exp.ToMap, exp.Trim) 108 }, 109 exp.ArgMax: rename_func("MAX_BY"), 110 exp.ArgMin: rename_func("MIN_BY"), 111 exp.Array: inline_array_sql, 112 exp.ArrayAgg: rename_func("ARRAY_AGG"), 113 # a <@ b (ArrayContainedBy) is equivalent to ARRAY_CONTAINS_ALL(b, a) 114 exp.ArrayContainedBy: lambda self, e: self.func("ARRAY_CONTAINS_ALL", e.expression, e.this), 115 exp.ArrayContainsAll: rename_func("ARRAY_CONTAINS_ALL"), 116 exp.ArrayFilter: rename_func("ARRAY_FILTER"), 117 exp.ArrayToString: rename_func("ARRAY_JOIN"), 118 exp.ApproxDistinct: approx_count_distinct_sql, 119 exp.CurrentVersion: lambda *_: "CURRENT_VERSION()", 120 exp.Delete: transforms.preprocess([_eliminate_between_in_delete]), 121 exp.Flatten: rename_func("ARRAY_FLATTEN"), 122 exp.JSONExtractScalar: arrow_json_extract_sql, 123 exp.JSONExtract: arrow_json_extract_sql, 124 # Both MAP forms (two-array MAP([keys], [values]) and variadic MAP(k1, v1, ...)) 125 # generate StarRocks' variadic MAP(k1, v1, k2, v2, ...) constructor 126 exp.Map: lambda self, e: var_map_sql(self, e, "MAP"), 127 exp.Property: property_sql, 128 exp.RegexpLike: rename_func("REGEXP"), 129 # Inherited from MySQL, minus operations StarRocks supports natively 130 # (QUALIFY, FULL OUTER JOIN, SEMI/ANTI JOIN) 131 exp.Select: transforms.preprocess( 132 [ 133 transforms.eliminate_distinct_on, 134 transforms.unnest_generate_date_array_using_recursive_cte, 135 ] 136 ), 137 exp.SchemaCommentProperty: lambda self, e: self.naked_property(e), 138 exp.SqlSecurityProperty: lambda self, e: f"SECURITY {self.sql(e.this)}", 139 exp.StDistance: st_distance_sphere, 140 exp.StrToUnix: lambda self, e: self.func("UNIX_TIMESTAMP", e.this, self.format_time(e)), 141 exp.TimestampTrunc: lambda self, e: self.func( 142 "DATE_TRUNC", weekstart_unit_to_str(self, e), e.this 143 ), 144 exp.TimeStrToDate: rename_func("TO_DATE"), 145 exp.UnixToStr: lambda self, e: self.func("FROM_UNIXTIME", e.this, self.format_time(e)), 146 exp.UnixToTime: rename_func("FROM_UNIXTIME"), 147 exp.VarMap: lambda self, e: var_map_sql(self, e, "MAP"), 148 } 149 150 # https://docs.starrocks.io/docs/sql-reference/sql-statements/keywords/#reserved-keywords 151 RESERVED_KEYWORDS = { 152 "add", 153 "all", 154 "alter", 155 "analyze", 156 "and", 157 "array", 158 "as", 159 "asc", 160 "between", 161 "bigint", 162 "bitmap", 163 "both", 164 "by", 165 "case", 166 "char", 167 "character", 168 "check", 169 "collate", 170 "column", 171 "compaction", 172 "convert", 173 "create", 174 "cross", 175 "cube", 176 "current_date", 177 "current_role", 178 "current_time", 179 "current_timestamp", 180 "current_user", 181 "database", 182 "databases", 183 "decimal", 184 "decimalv2", 185 "decimal32", 186 "decimal64", 187 "decimal128", 188 "default", 189 "deferred", 190 "delete", 191 "dense_rank", 192 "desc", 193 "describe", 194 "distinct", 195 "double", 196 "drop", 197 "dual", 198 "else", 199 "except", 200 "exists", 201 "explain", 202 "false", 203 "first_value", 204 "float", 205 "for", 206 "force", 207 "from", 208 "full", 209 "function", 210 "grant", 211 "group", 212 "grouping", 213 "grouping_id", 214 "groups", 215 "having", 216 "hll", 217 "host", 218 "if", 219 "ignore", 220 "immediate", 221 "in", 222 "index", 223 "infile", 224 "inner", 225 "insert", 226 "int", 227 "integer", 228 "intersect", 229 "into", 230 "is", 231 "join", 232 "json", 233 "key", 234 "keys", 235 "kill", 236 "lag", 237 "largeint", 238 "last_value", 239 "lateral", 240 "lead", 241 "left", 242 "like", 243 "limit", 244 "load", 245 "localtime", 246 "localtimestamp", 247 "maxvalue", 248 "minus", 249 "mod", 250 "not", 251 "ntile", 252 "null", 253 "on", 254 "or", 255 "order", 256 "outer", 257 "outfile", 258 "over", 259 "partition", 260 "percentile", 261 "primary", 262 "procedure", 263 "qualify", 264 "range", 265 "rank", 266 "read", 267 "regexp", 268 "release", 269 "rename", 270 "replace", 271 "revoke", 272 "right", 273 "rlike", 274 "row", 275 "row_number", 276 "rows", 277 "schema", 278 "schemas", 279 "select", 280 "set", 281 "set_var", 282 "show", 283 "smallint", 284 "system", 285 "table", 286 "terminated", 287 "text", 288 "then", 289 "tinyint", 290 "to", 291 "true", 292 "union", 293 "unique", 294 "unsigned", 295 "update", 296 "use", 297 "using", 298 "values", 299 "varchar", 300 "when", 301 "where", 302 "with", 303 } 304 305 def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str: 306 # IGNORE NULLS follows the first argument, e.g. LAG(x IGNORE NULLS, 1, 0) 307 # https://docs.starrocks.io/docs/sql-reference/sql-functions/Window_function/ 308 func = expression.this 309 if isinstance(func, (exp.FirstValue, exp.LastValue, exp.Lag, exp.Lead)): 310 return self.func( 311 func.sql_name(), 312 Generator.ignorenulls_sql(self, exp.IgnoreNulls(this=func.this)), 313 func.args.get("offset"), 314 func.args.get("default"), 315 ) 316 317 return super().ignorenulls_sql(expression) 318 319 def respectnulls_sql(self, expression: exp.RespectNulls) -> str: 320 # RESPECT NULLS is the default behavior, and StarRocks rejects the keyword 321 return self.sql(expression, "this") 322 323 def create_sql(self, expression: exp.Create) -> str: 324 # Starrocks' primary key is defined outside of the schema, so we need to move it there 325 schema = expression.this 326 if isinstance(schema, exp.Schema): 327 primary_key = schema.find(exp.PrimaryKey) 328 329 if primary_key: 330 props = expression.args.get("properties") 331 332 if not props: 333 props = exp.Properties(expressions=[]) 334 expression.set("properties", props) 335 336 # Verify if the first one is an engine property. Is true then insert it after the engine, 337 # otherwise insert it at the beginning 338 engine = props.find(exp.EngineProperty) 339 engine_index = (engine.index or 0) if engine else -1 340 props.set("expressions", primary_key.pop(), engine_index + 1, overwrite=False) 341 342 return super().create_sql(expression) 343 344 def partitionedbyproperty_sql(self, expression: exp.PartitionedByProperty) -> str: 345 this = expression.this 346 if isinstance(this, exp.Schema): 347 # For MVs, StarRocks needs outer parentheses. 348 create = expression.find_ancestor(exp.Create) 349 350 sql = self.expressions(this, flat=True) 351 if (create and create.kind == "VIEW") or all( 352 isinstance(col, (exp.Column, exp.Identifier)) for col in this.expressions 353 ): 354 sql = f"({sql})" 355 356 return f"PARTITION BY {sql}" 357 358 return f"PARTITION BY {self.sql(this)}" 359 360 def clusterproperty_sql(self, expression: exp.ClusterProperty) -> str: 361 """Generate StarRocks ORDER BY clause for clustering.""" 362 if expression.this: 363 self.unsupported(f"Unsupported CLUSTER BY {self.sql(expression, 'this')}") 364 return "" 365 expressions = self.expressions(expression, flat=True) 366 return f"ORDER BY ({expressions})" 367 368 def refreshtriggerproperty_sql(self, expression: exp.RefreshTriggerProperty) -> str: 369 """Generate StarRocks REFRESH clause for materialized views. 370 There is a little difference of the syntax between StarRocks and Doris. 371 """ 372 method = self.sql(expression, "method") 373 method = f" {method}" if method else "" 374 kind = self.sql(expression, "kind") 375 kind = f" {kind}" if kind else "" 376 starts = self.sql(expression, "starts") 377 starts = f" START ({starts})" if starts else "" 378 every = self.sql(expression, "every") 379 unit = self.sql(expression, "unit") 380 every = f" EVERY (INTERVAL {every} {unit})" if every and unit else "" 381 382 return f"REFRESH{method}{kind}{starts}{every}" 383 384 def refresh_sql(self, expression: exp.Refresh) -> str: 385 this = self.sql(expression, "this") 386 kind = "" if isinstance(expression.this, exp.Literal) else f"{expression.text('kind')} " 387 partition_start = self.sql(expression, "partition_start") 388 partition_end = self.sql(expression, "partition_end") 389 partition = ( 390 f" PARTITION START ({partition_start}) END ({partition_end})" if partition_start else "" 391 ) 392 force = " FORCE" if expression.args.get("force") else "" 393 mode = self.sql(expression, "mode") 394 mode = f" WITH {mode} MODE" if mode else "" 395 396 return f"REFRESH {kind}{this}{partition}{force}{mode}" 397 398 def datediff_sql(self, expression: exp.DateDiff) -> str: 399 # DATEDIFF compares only the date parts, whereas DATE_DIFF counts elapsed units 400 # https://docs.starrocks.io/docs/sql-reference/sql-functions/date-time-functions/datediff/ 401 unit = expression.args.get("unit") 402 if expression.args.get("date_part_boundary") and (not unit or unit.name.upper() == "DAY"): 403 return self.func("DATEDIFF", expression.this, expression.expression) 404 405 return self.func( 406 "DATE_DIFF", 407 weekstart_unit_to_str(self, expression), 408 expression.this, 409 expression.expression, 410 ) 411 412 def pivot_sql(self, expression: exp.Pivot) -> str: 413 # Only PIVOT (...) is supported, not UNPIVOT or DuckDB's PIVOT statement 414 # https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/SELECT/SELECT_PIVOT/ 415 if expression.unpivot or expression.this: 416 return no_pivot_sql(self, expression) 417 return super().pivot_sql(expression) 418 419 def tomap_sql(self, expression: exp.ToMap) -> str: 420 struct = expression.this 421 if not isinstance(struct, exp.Struct): 422 return f"MAP {self.sql(struct)}" 423 424 entries = ", ".join( 425 f"{self.sql(e, 'this')}:{self.sql(e, 'expression')}" for e in struct.expressions 426 ) 427 return f"MAP{{{entries}}}" 428 429 def timeslice_sql(self, expression: exp.TimeSlice) -> str: 430 interval = exp.Interval(this=expression.expression, unit=expression.unit) 431 kind = expression.text("kind").upper() 432 boundary = exp.var("CEIL" if kind == "END" else "FLOOR") if kind else None 433 return self.func("TIME_SLICE", expression.this, interval, boundary)
47def st_distance_sphere(self, expression: exp.StDistance) -> str: 48 point1 = expression.this 49 point2 = expression.expression 50 51 point1_x = self.func("ST_X", point1) 52 point1_y = self.func("ST_Y", point1) 53 point2_x = self.func("ST_X", point2) 54 point2_y = self.func("ST_Y", point2) 55 56 return self.func("ST_Distance_Sphere", point1_x, point1_y, point2_x, point2_y)
59class StarRocksGenerator(MySQLGenerator): 60 EXCEPT_INTERSECT_SUPPORT_ALL_CLAUSE = False 61 JSON_TYPE_REQUIRED_FOR_EXTRACTION = False 62 VARCHAR_REQUIRES_SIZE = False 63 PARSE_JSON_NAME: str | None = "PARSE_JSON" 64 WITH_PROPERTIES_PREFIX = "PROPERTIES" 65 UPDATE_STATEMENT_SUPPORTS_FROM = True 66 INSERT_OVERWRITE = " OVERWRITE" 67 CAST_TO_INT_ROUNDS = False 68 69 # StarRocks doesn't support "IS TRUE/FALSE" syntax. 70 IS_BOOL_ALLOWED = False 71 # StarRocks doesn't support renaming a table with a database. 72 RENAME_TABLE_WITH_DB = False 73 74 ALTER_PARTITION_OPTIONS = ( 75 *MySQLGenerator.ALTER_PARTITION_OPTIONS, 76 exp.DistributedByProperty, 77 exp.PartitionedByProperty, 78 ) 79 80 CAST_MAPPING: t.ClassVar[dict[exp.DType, str]] = {} 81 82 TYPE_MAPPING = { 83 **MySQLGenerator.TYPE_MAPPING, 84 exp.DType.HLLSKETCH: "HLL", 85 exp.DType.INT128: "LARGEINT", 86 exp.DType.TEXT: "STRING", 87 exp.DType.TIMESTAMP: "DATETIME", 88 exp.DType.TIMESTAMPTZ: "DATETIME", 89 } 90 91 SQL_SECURITY_VIEW_LOCATION: t.ClassVar = exp.Properties.Location.POST_SCHEMA 92 93 PROPERTIES_LOCATION = { 94 **MySQLGenerator.PROPERTIES_LOCATION, 95 exp.PrimaryKey: exp.Properties.Location.POST_SCHEMA, 96 exp.UniqueKeyProperty: exp.Properties.Location.POST_SCHEMA, 97 exp.RollupProperty: exp.Properties.Location.POST_SCHEMA, 98 exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA, 99 exp.Property: exp.Properties.Location.POST_WITH, 100 } 101 102 TRANSFORMS = { 103 # StarRocks uses the native TRIM(str, chars)/LTRIM/RTRIM function form, not 104 # MySQL's TRIM(chars FROM str) syntax, so it falls back to the base generator. 105 **{ 106 k: v 107 for k, v in MySQLGenerator.TRANSFORMS.items() 108 if k not in (exp.DateDiff, exp.DateTrunc, exp.Pivot, exp.ToMap, exp.Trim) 109 }, 110 exp.ArgMax: rename_func("MAX_BY"), 111 exp.ArgMin: rename_func("MIN_BY"), 112 exp.Array: inline_array_sql, 113 exp.ArrayAgg: rename_func("ARRAY_AGG"), 114 # a <@ b (ArrayContainedBy) is equivalent to ARRAY_CONTAINS_ALL(b, a) 115 exp.ArrayContainedBy: lambda self, e: self.func("ARRAY_CONTAINS_ALL", e.expression, e.this), 116 exp.ArrayContainsAll: rename_func("ARRAY_CONTAINS_ALL"), 117 exp.ArrayFilter: rename_func("ARRAY_FILTER"), 118 exp.ArrayToString: rename_func("ARRAY_JOIN"), 119 exp.ApproxDistinct: approx_count_distinct_sql, 120 exp.CurrentVersion: lambda *_: "CURRENT_VERSION()", 121 exp.Delete: transforms.preprocess([_eliminate_between_in_delete]), 122 exp.Flatten: rename_func("ARRAY_FLATTEN"), 123 exp.JSONExtractScalar: arrow_json_extract_sql, 124 exp.JSONExtract: arrow_json_extract_sql, 125 # Both MAP forms (two-array MAP([keys], [values]) and variadic MAP(k1, v1, ...)) 126 # generate StarRocks' variadic MAP(k1, v1, k2, v2, ...) constructor 127 exp.Map: lambda self, e: var_map_sql(self, e, "MAP"), 128 exp.Property: property_sql, 129 exp.RegexpLike: rename_func("REGEXP"), 130 # Inherited from MySQL, minus operations StarRocks supports natively 131 # (QUALIFY, FULL OUTER JOIN, SEMI/ANTI JOIN) 132 exp.Select: transforms.preprocess( 133 [ 134 transforms.eliminate_distinct_on, 135 transforms.unnest_generate_date_array_using_recursive_cte, 136 ] 137 ), 138 exp.SchemaCommentProperty: lambda self, e: self.naked_property(e), 139 exp.SqlSecurityProperty: lambda self, e: f"SECURITY {self.sql(e.this)}", 140 exp.StDistance: st_distance_sphere, 141 exp.StrToUnix: lambda self, e: self.func("UNIX_TIMESTAMP", e.this, self.format_time(e)), 142 exp.TimestampTrunc: lambda self, e: self.func( 143 "DATE_TRUNC", weekstart_unit_to_str(self, e), e.this 144 ), 145 exp.TimeStrToDate: rename_func("TO_DATE"), 146 exp.UnixToStr: lambda self, e: self.func("FROM_UNIXTIME", e.this, self.format_time(e)), 147 exp.UnixToTime: rename_func("FROM_UNIXTIME"), 148 exp.VarMap: lambda self, e: var_map_sql(self, e, "MAP"), 149 } 150 151 # https://docs.starrocks.io/docs/sql-reference/sql-statements/keywords/#reserved-keywords 152 RESERVED_KEYWORDS = { 153 "add", 154 "all", 155 "alter", 156 "analyze", 157 "and", 158 "array", 159 "as", 160 "asc", 161 "between", 162 "bigint", 163 "bitmap", 164 "both", 165 "by", 166 "case", 167 "char", 168 "character", 169 "check", 170 "collate", 171 "column", 172 "compaction", 173 "convert", 174 "create", 175 "cross", 176 "cube", 177 "current_date", 178 "current_role", 179 "current_time", 180 "current_timestamp", 181 "current_user", 182 "database", 183 "databases", 184 "decimal", 185 "decimalv2", 186 "decimal32", 187 "decimal64", 188 "decimal128", 189 "default", 190 "deferred", 191 "delete", 192 "dense_rank", 193 "desc", 194 "describe", 195 "distinct", 196 "double", 197 "drop", 198 "dual", 199 "else", 200 "except", 201 "exists", 202 "explain", 203 "false", 204 "first_value", 205 "float", 206 "for", 207 "force", 208 "from", 209 "full", 210 "function", 211 "grant", 212 "group", 213 "grouping", 214 "grouping_id", 215 "groups", 216 "having", 217 "hll", 218 "host", 219 "if", 220 "ignore", 221 "immediate", 222 "in", 223 "index", 224 "infile", 225 "inner", 226 "insert", 227 "int", 228 "integer", 229 "intersect", 230 "into", 231 "is", 232 "join", 233 "json", 234 "key", 235 "keys", 236 "kill", 237 "lag", 238 "largeint", 239 "last_value", 240 "lateral", 241 "lead", 242 "left", 243 "like", 244 "limit", 245 "load", 246 "localtime", 247 "localtimestamp", 248 "maxvalue", 249 "minus", 250 "mod", 251 "not", 252 "ntile", 253 "null", 254 "on", 255 "or", 256 "order", 257 "outer", 258 "outfile", 259 "over", 260 "partition", 261 "percentile", 262 "primary", 263 "procedure", 264 "qualify", 265 "range", 266 "rank", 267 "read", 268 "regexp", 269 "release", 270 "rename", 271 "replace", 272 "revoke", 273 "right", 274 "rlike", 275 "row", 276 "row_number", 277 "rows", 278 "schema", 279 "schemas", 280 "select", 281 "set", 282 "set_var", 283 "show", 284 "smallint", 285 "system", 286 "table", 287 "terminated", 288 "text", 289 "then", 290 "tinyint", 291 "to", 292 "true", 293 "union", 294 "unique", 295 "unsigned", 296 "update", 297 "use", 298 "using", 299 "values", 300 "varchar", 301 "when", 302 "where", 303 "with", 304 } 305 306 def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str: 307 # IGNORE NULLS follows the first argument, e.g. LAG(x IGNORE NULLS, 1, 0) 308 # https://docs.starrocks.io/docs/sql-reference/sql-functions/Window_function/ 309 func = expression.this 310 if isinstance(func, (exp.FirstValue, exp.LastValue, exp.Lag, exp.Lead)): 311 return self.func( 312 func.sql_name(), 313 Generator.ignorenulls_sql(self, exp.IgnoreNulls(this=func.this)), 314 func.args.get("offset"), 315 func.args.get("default"), 316 ) 317 318 return super().ignorenulls_sql(expression) 319 320 def respectnulls_sql(self, expression: exp.RespectNulls) -> str: 321 # RESPECT NULLS is the default behavior, and StarRocks rejects the keyword 322 return self.sql(expression, "this") 323 324 def create_sql(self, expression: exp.Create) -> str: 325 # Starrocks' primary key is defined outside of the schema, so we need to move it there 326 schema = expression.this 327 if isinstance(schema, exp.Schema): 328 primary_key = schema.find(exp.PrimaryKey) 329 330 if primary_key: 331 props = expression.args.get("properties") 332 333 if not props: 334 props = exp.Properties(expressions=[]) 335 expression.set("properties", props) 336 337 # Verify if the first one is an engine property. Is true then insert it after the engine, 338 # otherwise insert it at the beginning 339 engine = props.find(exp.EngineProperty) 340 engine_index = (engine.index or 0) if engine else -1 341 props.set("expressions", primary_key.pop(), engine_index + 1, overwrite=False) 342 343 return super().create_sql(expression) 344 345 def partitionedbyproperty_sql(self, expression: exp.PartitionedByProperty) -> str: 346 this = expression.this 347 if isinstance(this, exp.Schema): 348 # For MVs, StarRocks needs outer parentheses. 349 create = expression.find_ancestor(exp.Create) 350 351 sql = self.expressions(this, flat=True) 352 if (create and create.kind == "VIEW") or all( 353 isinstance(col, (exp.Column, exp.Identifier)) for col in this.expressions 354 ): 355 sql = f"({sql})" 356 357 return f"PARTITION BY {sql}" 358 359 return f"PARTITION BY {self.sql(this)}" 360 361 def clusterproperty_sql(self, expression: exp.ClusterProperty) -> str: 362 """Generate StarRocks ORDER BY clause for clustering.""" 363 if expression.this: 364 self.unsupported(f"Unsupported CLUSTER BY {self.sql(expression, 'this')}") 365 return "" 366 expressions = self.expressions(expression, flat=True) 367 return f"ORDER BY ({expressions})" 368 369 def refreshtriggerproperty_sql(self, expression: exp.RefreshTriggerProperty) -> str: 370 """Generate StarRocks REFRESH clause for materialized views. 371 There is a little difference of the syntax between StarRocks and Doris. 372 """ 373 method = self.sql(expression, "method") 374 method = f" {method}" if method else "" 375 kind = self.sql(expression, "kind") 376 kind = f" {kind}" if kind else "" 377 starts = self.sql(expression, "starts") 378 starts = f" START ({starts})" if starts else "" 379 every = self.sql(expression, "every") 380 unit = self.sql(expression, "unit") 381 every = f" EVERY (INTERVAL {every} {unit})" if every and unit else "" 382 383 return f"REFRESH{method}{kind}{starts}{every}" 384 385 def refresh_sql(self, expression: exp.Refresh) -> str: 386 this = self.sql(expression, "this") 387 kind = "" if isinstance(expression.this, exp.Literal) else f"{expression.text('kind')} " 388 partition_start = self.sql(expression, "partition_start") 389 partition_end = self.sql(expression, "partition_end") 390 partition = ( 391 f" PARTITION START ({partition_start}) END ({partition_end})" if partition_start else "" 392 ) 393 force = " FORCE" if expression.args.get("force") else "" 394 mode = self.sql(expression, "mode") 395 mode = f" WITH {mode} MODE" if mode else "" 396 397 return f"REFRESH {kind}{this}{partition}{force}{mode}" 398 399 def datediff_sql(self, expression: exp.DateDiff) -> str: 400 # DATEDIFF compares only the date parts, whereas DATE_DIFF counts elapsed units 401 # https://docs.starrocks.io/docs/sql-reference/sql-functions/date-time-functions/datediff/ 402 unit = expression.args.get("unit") 403 if expression.args.get("date_part_boundary") and (not unit or unit.name.upper() == "DAY"): 404 return self.func("DATEDIFF", expression.this, expression.expression) 405 406 return self.func( 407 "DATE_DIFF", 408 weekstart_unit_to_str(self, expression), 409 expression.this, 410 expression.expression, 411 ) 412 413 def pivot_sql(self, expression: exp.Pivot) -> str: 414 # Only PIVOT (...) is supported, not UNPIVOT or DuckDB's PIVOT statement 415 # https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/SELECT/SELECT_PIVOT/ 416 if expression.unpivot or expression.this: 417 return no_pivot_sql(self, expression) 418 return super().pivot_sql(expression) 419 420 def tomap_sql(self, expression: exp.ToMap) -> str: 421 struct = expression.this 422 if not isinstance(struct, exp.Struct): 423 return f"MAP {self.sql(struct)}" 424 425 entries = ", ".join( 426 f"{self.sql(e, 'this')}:{self.sql(e, 'expression')}" for e in struct.expressions 427 ) 428 return f"MAP{{{entries}}}" 429 430 def timeslice_sql(self, expression: exp.TimeSlice) -> str: 431 interval = exp.Interval(this=expression.expression, unit=expression.unit) 432 kind = expression.text("kind").upper() 433 boundary = exp.var("CEIL" if kind == "END" else "FLOOR") if kind else None 434 return self.func("TIME_SLICE", expression.this, interval, boundary)
Generator converts a given syntax tree to the corresponding SQL string.
Arguments:
- pretty: Whether to format the produced SQL string. Default: False.
- identify: Determines when an identifier should be quoted. Possible values are: False (default): Never quote, except in cases where it's mandatory by the dialect. True: Always quote except for specials cases. 'safe': Only quote identifiers that are case insensitive.
- normalize: Whether to normalize identifiers to lowercase. Default: False.
- pad: The pad size in a formatted string. For example, this affects the indentation of a projection in a query, relative to its nesting level. Default: 2.
- indent: The indentation size in a formatted string. For example, this affects the
indentation of subqueries and filters under a
WHEREclause. Default: 2. - normalize_functions: How to normalize function names. Possible values are: "upper" or True (default): Convert names to uppercase. "lower": Convert names to lowercase. False: Disables function name normalization.
- unsupported_level: Determines the generator's behavior when it encounters unsupported expressions. Default ErrorLevel.WARN.
- max_unsupported: Maximum number of unsupported messages to include in a raised UnsupportedError. This is only relevant if unsupported_level is ErrorLevel.RAISE. Default: 3
- leading_comma: Whether the comma is leading or trailing in select expressions. This is only relevant when generating in pretty mode. Default: False
- max_text_width: The max number of characters in a segment before creating new lines in pretty mode. The default is on the smaller end because the length only represents a segment and not the true line length. Default: 80
- comments: Whether to preserve comments in the output SQL code. Default: True
ALTER_PARTITION_OPTIONS =
(<class 'sqlglot.expressions.properties.PartitionByListProperty'>, <class 'sqlglot.expressions.properties.PartitionByRangeProperty'>, <class 'sqlglot.expressions.properties.DistributedByProperty'>, <class 'sqlglot.expressions.properties.PartitionedByProperty'>)
TYPE_MAPPING =
{<DType.NCHAR: 'NCHAR'>: 'CHAR', <DType.NVARCHAR: 'NVARCHAR'>: 'VARCHAR', <DType.INET: 'INET'>: 'INET', <DType.ROWVERSION: 'ROWVERSION'>: 'VARBINARY', <DType.UBIGINT: 'UBIGINT'>: 'BIGINT', <DType.UINT: 'UINT'>: 'INT', <DType.UMEDIUMINT: 'UMEDIUMINT'>: 'MEDIUMINT', <DType.USMALLINT: 'USMALLINT'>: 'SMALLINT', <DType.UTINYINT: 'UTINYINT'>: 'TINYINT', <DType.UDECIMAL: 'UDECIMAL'>: 'DECIMAL', <DType.UDOUBLE: 'UDOUBLE'>: 'DOUBLE', <DType.DATETIME2: 'DATETIME2'>: 'DATETIME', <DType.SMALLDATETIME: 'SMALLDATETIME'>: 'DATETIME', <DType.TIMESTAMP: 'TIMESTAMP'>: 'DATETIME', <DType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>: 'DATETIME', <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>: 'DATETIME', <DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: 'TIMESTAMP', <DType.HLLSKETCH: 'HLLSKETCH'>: 'HLL', <DType.INT128: 'INT128'>: 'LARGEINT', <DType.TEXT: 'TEXT'>: 'STRING'}
PROPERTIES_LOCATION =
{<class 'sqlglot.expressions.properties.AggregateKeyProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.AllowedValuesProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.AlgorithmProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.ApiProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.ApplicationProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.AutoIncrementProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.AutoRefreshProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.BackupProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.BlockCompressionProperty'>: <PropertiesLocation.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.properties.CalledOnNullInputProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.CatalogProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.CharacterSetProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.ChecksumProperty'>: <PropertiesLocation.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.properties.CollateProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.ComputeProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.CopyGrantsProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.query.Cluster'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.ClusteredByProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.ClusterProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.DistributedByProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.DuplicateKeyProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.DataBlocksizeProperty'>: <PropertiesLocation.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.properties.DatabaseProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.DataDeletionProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.DefinerProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.DictRange'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.DictProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.DynamicProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.DistKeyProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.DistStyleProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.EmptyProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.EncodeProperty'>: <PropertiesLocation.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.properties.EngineProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.EnviromentProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.HandlerProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.ParameterStyleProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.ExecuteAsProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.ExternalProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.FallbackProperty'>: <PropertiesLocation.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.properties.FileFormatProperty'>: <PropertiesLocation.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.properties.FreespaceProperty'>: <PropertiesLocation.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.properties.GlobalProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.HeapProperty'>: <PropertiesLocation.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.properties.HybridProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.InheritsProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.IcebergProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.IncludeProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.InputModelProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.IsolatedLoadingProperty'>: <PropertiesLocation.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.properties.JournalProperty'>: <PropertiesLocation.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.properties.LanguageProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.LikeProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.LocationProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.LockProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.LockingProperty'>: <PropertiesLocation.POST_ALIAS: 'POST_ALIAS'>, <class 'sqlglot.expressions.properties.LogProperty'>: <PropertiesLocation.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.properties.MaskingProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.MaterializedProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.MergeBlockRatioProperty'>: <PropertiesLocation.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.properties.ModuleProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.NetworkProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.NoPrimaryIndexProperty'>: <PropertiesLocation.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.properties.OnProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.OnCommitProperty'>: <PropertiesLocation.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.query.Order'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.OutputModelProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.PartitionedByProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.PartitionedOfProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.PhysicalProperty'>: <PropertiesLocation.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.constraints.PrimaryKey'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.Property'>: <PropertiesLocation.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.properties.RefreshTriggerProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.RemoteWithConnectionModelProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.ReturnsProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.RollupProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.RowAccessProperty'>: <PropertiesLocation.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.properties.RowFormatProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.RowFormatDelimitedProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.RowFormatSerdeProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.SampleProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.SchemaCommentProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.SecureProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.SecurityIntegrationProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.SerdeProperties'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ddl.Set'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.SettingsProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.SetProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.SetConfigProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.SharingProperty'>: <PropertiesLocation.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.ddl.SequenceProperties'>: <PropertiesLocation.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.ddl.TriggerProperties'>: <PropertiesLocation.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.properties.SortKeyProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.SqlReadWriteProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.SqlSecurityProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.StabilityProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.StorageHandlerProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.StorageProperty'>: <PropertiesLocation.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.properties.StreamingTableProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.StrictProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.Tags'>: <PropertiesLocation.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.properties.TableSpaceProperty'>: <PropertiesLocation.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.properties.TemporaryProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.ToTableProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.TransientProperty'>: <PropertiesLocation.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.properties.TransformModelProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ddl.MergeTreeTTL'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.UnloggedProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.UsingProperty'>: <PropertiesLocation.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.properties.UsingTemplateProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.ViewAttributeProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.VirtualProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.VolatileProperty'>: <PropertiesLocation.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.properties.WithDataProperty'>: <PropertiesLocation.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.properties.WithJournalTableProperty'>: <PropertiesLocation.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.properties.WithProcedureOptions'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.WithSchemaBindingProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.WithSystemVersioningProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.ForceProperty'>: <PropertiesLocation.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.properties.PartitionByRangeProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.PartitionByListProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.properties.UniqueKeyProperty'>: <PropertiesLocation.POST_SCHEMA: 'POST_SCHEMA'>}
TRANSFORMS =
{<class 'sqlglot.expressions.query.JSONPathFilter'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathKey'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathRecursive'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathRoot'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathScript'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathSelector'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathSlice'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathSubscript'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathUnion'>: <function <lambda>>, <class 'sqlglot.expressions.query.JSONPathWildcard'>: <function <lambda>>, <class 'sqlglot.expressions.core.Adjacent'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.AllowedValuesProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.AnalyzeColumns'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.AnalyzeWith'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.array.ArrayContainedBy'>: <function StarRocksGenerator.<lambda>>, <class 'sqlglot.expressions.array.ArrayContainsAll'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.array.ArrayOverlaps'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.AssumeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.AutoRefreshProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.BackupProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.BinaryColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.CaseSpecificColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.CalledOnNullInputProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.math.Ceil'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.CharacterSetColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.CharacterSetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.ClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.CollateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.CommentColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.functions.ConnectByRoot'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.string.ConvertToCharset'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.CopyGrantsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.CredentialsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.functions.CurrentCatalog'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.functions.SessionUser'>: <function MySQLGenerator.<lambda>>, <class 'sqlglot.expressions.constraints.DateFormatColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.DefaultColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ApiProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ApplicationProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.CatalogProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ComputeProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.DatabaseProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.DynamicProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.EmptyProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.EncodeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.EndStatement'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.EnviromentProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.HandlerProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ParameterStyleProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.EphemeralColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.ExcludeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ExecuteAsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.Except'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ExternalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.math.Floor'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.Get'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.GlobalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.HeapProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.HybridProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.IcebergProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.InheritsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.InlineLengthColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.InputModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.Intersect'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.datatypes.IntervalSpan'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.functions.Int64'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONBContainsAnyTopKeys'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONBContainsAllTopKeys'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONBContainsTopKey'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONBDeleteAtPath'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONBPathExists'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONObject'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.json.JSONObjectAgg'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.LanguageProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.LocationProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.LogProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.MaskingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.MaterializedProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.functions.NetFunc'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.NetworkProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.NonClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.NoPrimaryIndexProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.NotForReplicationColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.OnCommitProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.OnProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.OnUpdateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.core.Operator'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.OutputModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.core.ExtendsLeft'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.core.ExtendsRight'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.PathColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.PartitionedByBucket'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.PartitionByTruncate'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.core.PivotAny'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.array.PositionalColumn'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.ProjectionPolicyColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.InvisibleColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.ZeroFillColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.Put'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.RemoteWithConnectionModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ReturnsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.RowAccessProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.core.SafeFunc'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SampleProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SecureProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SecurityIntegrationProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SetConfigProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SettingsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SharingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SqlReadWriteProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.SqlSecurityProperty'>: <function StarRocksGenerator.<lambda>>, <class 'sqlglot.expressions.properties.StabilityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.Stream'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.StreamingTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.StrictProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ddl.SwapTable'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.TableColumn'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.Tags'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.TemporaryProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.TitleColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ToTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.TransformModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.TransientProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.VirtualProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ddl.TriggerExecute'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.Union'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.UnloggedProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.UsingTemplateProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.query.UsingData'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.UppercaseColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.temporal.UtcDate'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.temporal.UtcTime'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.temporal.UtcTimestamp'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.query.Variadic'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.array.VarMap'>: <function StarRocksGenerator.<lambda>>, <class 'sqlglot.expressions.properties.ViewAttributeProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.VolatileProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.WithJournalTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.WithProcedureOptions'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.WithSchemaBindingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.constraints.WithOperator'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.properties.ForceProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.aggregate.ArrayAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.math.BitwiseAndAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.math.BitwiseOrAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.math.BitwiseXorAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.math.BitwiseCount'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.string.Chr'>: <function MySQLGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.CurrentDate'>: <function no_paren_current_date_sql>, <class 'sqlglot.expressions.functions.CurrentVersion'>: <function StarRocksGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.DateAdd'>: <function date_add_sql.<locals>.func>, <class 'sqlglot.expressions.temporal.DateStrToDate'>: <function datestrtodate_sql>, <class 'sqlglot.expressions.temporal.DateSub'>: <function date_add_sql.<locals>.func>, <class 'sqlglot.expressions.temporal.Day'>: <function remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.temporal.DayOfMonth'>: <function remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.temporal.DayOfWeek'>: <function remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.temporal.DayOfYear'>: <function remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.aggregate.GroupConcat'>: <function MySQLGenerator.<lambda>>, <class 'sqlglot.expressions.core.ILike'>: <function no_ilike_sql>, <class 'sqlglot.expressions.functions.If'>: <function if_sql.<locals>._if_sql>, <class 'sqlglot.expressions.json.JSONExtractScalar'>: <function arrow_json_extract_sql>, <class 'sqlglot.expressions.string.Length'>: <function length_or_char_length_sql>, <class 'sqlglot.expressions.aggregate.LogicalOr'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.aggregate.LogicalAnd'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.aggregate.Max'>: <function max_or_greatest>, <class 'sqlglot.expressions.aggregate.Min'>: <function min_or_least>, <class 'sqlglot.expressions.temporal.Month'>: <function remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.core.NullSafeEQ'>: <function MySQLGenerator.<lambda>>, <class 'sqlglot.expressions.core.NullSafeNEQ'>: <function MySQLGenerator.<lambda>>, <class 'sqlglot.expressions.string.NumberToStr'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.query.Select'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.aggregate.Stddev'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.string.StrPosition'>: <function MySQLGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.StrToDate'>: <function _str_to_date_sql>, <class 'sqlglot.expressions.temporal.StrToTime'>: <function _str_to_date_sql>, <class 'sqlglot.expressions.string.Stuff'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.query.TableSample'>: <function no_tablesample_sql>, <class 'sqlglot.expressions.temporal.TimeFromParts'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.temporal.TimestampAdd'>: <function date_add_interval_sql.<locals>.func>, <class 'sqlglot.expressions.temporal.TimestampDiff'>: <function MySQLGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.TimestampSub'>: <function date_add_interval_sql.<locals>.func>, <class 'sqlglot.expressions.temporal.TimeStrToUnix'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.temporal.TimeStrToTime'>: <function MySQLGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.TimeToStr'>: <function remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.math.Trunc'>: <function MySQLGenerator.<lambda>>, <class 'sqlglot.expressions.functions.TryCast'>: <function no_trycast_sql>, <class 'sqlglot.expressions.temporal.TsOrDsAdd'>: <function date_add_sql.<locals>.func>, <class 'sqlglot.expressions.temporal.TsOrDsDiff'>: <function MySQLGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.TsOrDsToDate'>: <function _ts_or_ds_to_date_sql>, <class 'sqlglot.expressions.string.Unicode'>: <function MySQLGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.UnixToTime'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.aggregate.Variance'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.aggregate.VariancePop'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.temporal.Week'>: <function remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.temporal.WeekOfYear'>: <function remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.temporal.Year'>: <function remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.aggregate.ArgMax'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.aggregate.ArgMin'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.array.Array'>: <function inline_array_sql>, <class 'sqlglot.expressions.array.ArrayFilter'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.array.ArrayToString'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.core.ApproxDistinct'>: <function approx_count_distinct_sql>, <class 'sqlglot.expressions.dml.Delete'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.array.Flatten'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.json.JSONExtract'>: <function arrow_json_extract_sql>, <class 'sqlglot.expressions.array.Map'>: <function StarRocksGenerator.<lambda>>, <class 'sqlglot.expressions.properties.Property'>: <function property_sql>, <class 'sqlglot.expressions.core.RegexpLike'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.properties.SchemaCommentProperty'>: <function StarRocksGenerator.<lambda>>, <class 'sqlglot.expressions.array.StDistance'>: <function st_distance_sphere>, <class 'sqlglot.expressions.temporal.StrToUnix'>: <function StarRocksGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.TimestampTrunc'>: <function StarRocksGenerator.<lambda>>, <class 'sqlglot.expressions.temporal.TimeStrToDate'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.temporal.UnixToStr'>: <function StarRocksGenerator.<lambda>>}
RESERVED_KEYWORDS =
{'char', 'outfile', 'outer', 'describe', 'check', 'current_role', 'ignore', 'int', 'maxvalue', 'character', 'tinyint', 'where', 'distinct', 'group', 'read', 'null', 'regexp', 'key', 'using', 'delete', 'largeint', 'show', 'and', 'unsigned', 'on', 'when', 'text', 'full', 'rename', 'bitmap', 'drop', 'union', 'as', 'decimal', 'double', 'except', 'by', 'hll', 'between', 'to', 'cross', 'groups', 'set', 'integer', 'array', 'dense_rank', 'ntile', 'last_value', 'decimal64', 'schemas', 'over', 'load', 'cube', 'not', 'localtime', 'mod', 'is', 'use', 'like', 'current_date', 'procedure', 'qualify', 'decimalv2', 'partition', 'host', 'table', 'column', 'then', 'schema', 'bigint', 'if', 'grouping_id', 'in', 'keys', 'with', 'databases', 'into', 'add', 'release', 'update', 'true', 'rows', 'revoke', 'smallint', 'varchar', 'grouping', 'infile', 'rank', 'terminated', 'analyze', 'false', 'minus', 'inner', 'json', 'decimal32', 'primary', 'compaction', 'left', 'deferred', 'else', 'current_time', 'collate', 'case', 'unique', 'desc', 'values', 'insert', 'for', 'all', 'intersect', 'float', 'both', 'limit', 'database', 'from', 'select', 'decimal128', 'default', 'or', 'having', 'create', 'row_number', 'lag', 'explain', 'current_timestamp', 'current_user', 'rlike', 'function', 'alter', 'percentile', 'lead', 'kill', 'order', 'localtimestamp', 'right', 'lateral', 'grant', 'row', 'dual', 'first_value', 'convert', 'asc', 'exists', 'replace', 'index', 'range', 'set_var', 'join', 'immediate', 'system', 'force'}
306 def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str: 307 # IGNORE NULLS follows the first argument, e.g. LAG(x IGNORE NULLS, 1, 0) 308 # https://docs.starrocks.io/docs/sql-reference/sql-functions/Window_function/ 309 func = expression.this 310 if isinstance(func, (exp.FirstValue, exp.LastValue, exp.Lag, exp.Lead)): 311 return self.func( 312 func.sql_name(), 313 Generator.ignorenulls_sql(self, exp.IgnoreNulls(this=func.this)), 314 func.args.get("offset"), 315 func.args.get("default"), 316 ) 317 318 return super().ignorenulls_sql(expression)
324 def create_sql(self, expression: exp.Create) -> str: 325 # Starrocks' primary key is defined outside of the schema, so we need to move it there 326 schema = expression.this 327 if isinstance(schema, exp.Schema): 328 primary_key = schema.find(exp.PrimaryKey) 329 330 if primary_key: 331 props = expression.args.get("properties") 332 333 if not props: 334 props = exp.Properties(expressions=[]) 335 expression.set("properties", props) 336 337 # Verify if the first one is an engine property. Is true then insert it after the engine, 338 # otherwise insert it at the beginning 339 engine = props.find(exp.EngineProperty) 340 engine_index = (engine.index or 0) if engine else -1 341 props.set("expressions", primary_key.pop(), engine_index + 1, overwrite=False) 342 343 return super().create_sql(expression)
def
partitionedbyproperty_sql( self, expression: sqlglot.expressions.properties.PartitionedByProperty) -> str:
345 def partitionedbyproperty_sql(self, expression: exp.PartitionedByProperty) -> str: 346 this = expression.this 347 if isinstance(this, exp.Schema): 348 # For MVs, StarRocks needs outer parentheses. 349 create = expression.find_ancestor(exp.Create) 350 351 sql = self.expressions(this, flat=True) 352 if (create and create.kind == "VIEW") or all( 353 isinstance(col, (exp.Column, exp.Identifier)) for col in this.expressions 354 ): 355 sql = f"({sql})" 356 357 return f"PARTITION BY {sql}" 358 359 return f"PARTITION BY {self.sql(this)}"
361 def clusterproperty_sql(self, expression: exp.ClusterProperty) -> str: 362 """Generate StarRocks ORDER BY clause for clustering.""" 363 if expression.this: 364 self.unsupported(f"Unsupported CLUSTER BY {self.sql(expression, 'this')}") 365 return "" 366 expressions = self.expressions(expression, flat=True) 367 return f"ORDER BY ({expressions})"
Generate StarRocks ORDER BY clause for clustering.
def
refreshtriggerproperty_sql( self, expression: sqlglot.expressions.properties.RefreshTriggerProperty) -> str:
369 def refreshtriggerproperty_sql(self, expression: exp.RefreshTriggerProperty) -> str: 370 """Generate StarRocks REFRESH clause for materialized views. 371 There is a little difference of the syntax between StarRocks and Doris. 372 """ 373 method = self.sql(expression, "method") 374 method = f" {method}" if method else "" 375 kind = self.sql(expression, "kind") 376 kind = f" {kind}" if kind else "" 377 starts = self.sql(expression, "starts") 378 starts = f" START ({starts})" if starts else "" 379 every = self.sql(expression, "every") 380 unit = self.sql(expression, "unit") 381 every = f" EVERY (INTERVAL {every} {unit})" if every and unit else "" 382 383 return f"REFRESH{method}{kind}{starts}{every}"
Generate StarRocks REFRESH clause for materialized views. There is a little difference of the syntax between StarRocks and Doris.
385 def refresh_sql(self, expression: exp.Refresh) -> str: 386 this = self.sql(expression, "this") 387 kind = "" if isinstance(expression.this, exp.Literal) else f"{expression.text('kind')} " 388 partition_start = self.sql(expression, "partition_start") 389 partition_end = self.sql(expression, "partition_end") 390 partition = ( 391 f" PARTITION START ({partition_start}) END ({partition_end})" if partition_start else "" 392 ) 393 force = " FORCE" if expression.args.get("force") else "" 394 mode = self.sql(expression, "mode") 395 mode = f" WITH {mode} MODE" if mode else "" 396 397 return f"REFRESH {kind}{this}{partition}{force}{mode}"
399 def datediff_sql(self, expression: exp.DateDiff) -> str: 400 # DATEDIFF compares only the date parts, whereas DATE_DIFF counts elapsed units 401 # https://docs.starrocks.io/docs/sql-reference/sql-functions/date-time-functions/datediff/ 402 unit = expression.args.get("unit") 403 if expression.args.get("date_part_boundary") and (not unit or unit.name.upper() == "DAY"): 404 return self.func("DATEDIFF", expression.this, expression.expression) 405 406 return self.func( 407 "DATE_DIFF", 408 weekstart_unit_to_str(self, expression), 409 expression.this, 410 expression.expression, 411 )
413 def pivot_sql(self, expression: exp.Pivot) -> str: 414 # Only PIVOT (...) is supported, not UNPIVOT or DuckDB's PIVOT statement 415 # https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/SELECT/SELECT_PIVOT/ 416 if expression.unpivot or expression.this: 417 return no_pivot_sql(self, expression) 418 return super().pivot_sql(expression)
420 def tomap_sql(self, expression: exp.ToMap) -> str: 421 struct = expression.this 422 if not isinstance(struct, exp.Struct): 423 return f"MAP {self.sql(struct)}" 424 425 entries = ", ".join( 426 f"{self.sql(e, 'this')}:{self.sql(e, 'expression')}" for e in struct.expressions 427 ) 428 return f"MAP{{{entries}}}"
430 def timeslice_sql(self, expression: exp.TimeSlice) -> str: 431 interval = exp.Interval(this=expression.expression, unit=expression.unit) 432 kind = expression.text("kind").upper() 433 boundary = exp.var("CEIL" if kind == "END" else "FLOOR") if kind else None 434 return self.func("TIME_SLICE", expression.this, interval, boundary)
Inherited Members
- sqlglot.generator.Generator
- Generator
- WINDOW_FUNCS_WITH_NULL_ORDERING
- IGNORE_NULLS_IN_FUNC
- IGNORE_NULLS_BEFORE_ORDER
- CREATE_FUNCTION_RETURN_AS
- MATCHED_BY_SOURCE
- SUPPORTS_MERGE_WHERE
- SINGLE_STRING_INTERVAL
- AUTO_REFRESH_BARE_INTERVALS
- GROUPINGS_SEP
- SUPPORTS_GROUPING_SETS_AS_SUFFIX
- INDEX_ON
- INOUT_SEPARATOR
- DIRECTED_JOINS
- QUERY_HINTS
- SAFE_INT_DIVISION
- LIMIT_IS_TOP
- RETURNING_END
- EXTRACT_ALLOWS_QUOTES
- TZ_TO_WITH_TIME_ZONE
- ALTER_TABLE_INCLUDE_COLUMN_KEYWORD
- UNNEST_WITH_ORDINALITY
- SEMI_ANTI_JOIN_WITH_SIDE
- COMPUTED_COLUMN_WITH_TYPE
- SUPPORTS_TABLE_COPY
- TABLESAMPLE_REQUIRES_PARENS
- TABLESAMPLE_SIZE_IS_ROWS
- TABLESAMPLE_KEYWORDS
- TABLESAMPLE_WITH_METHOD
- TABLESAMPLE_SEED_KEYWORD
- HISTORICAL_DATA_POST_ALIAS
- COLLATE_IS_FUNC
- DATA_TYPE_SPECIFIERS_ALLOWED
- ENSURE_BOOLS
- CTE_RECURSIVE_KEYWORD_REQUIRED
- SUPPORTS_SINGLE_ARG_CONCAT
- SUPPORTS_TABLE_ALIAS_COLUMNS
- SUPPORTS_NAMED_CTE_COLUMNS
- UNPIVOT_ALIASES_ARE_IDENTIFIERS
- PIVOT_ALIAS_WITH_AS
- SUPPORTS_SELECT_INTO
- SUPPORTS_UNLOGGED_TABLES
- SUPPORTS_CREATE_TABLE_LIKE
- SUPPORTS_ALTER_COLUMN_IF_EXISTS
- LIKE_PROPERTY_INSIDE_SCHEMA
- MULTI_ARG_DISTINCT
- JSON_PATH_SINGLE_QUOTE_ESCAPE
- JSON_PATH_KEY_QUOTED_FORCES_BRACKETS
- SUPPORTED_JSON_PATH_PARTS
- CAN_IMPLEMENT_ARRAY_ANY
- SUPPORTS_WINDOW_EXCLUDE
- SET_OP_MODIFIERS
- SET_OP_LIMITS
- SET_OP_PARENTHESIZED_OPERANDS
- COPY_PARAMS_ARE_WRAPPED
- COPY_PARAMS_EQ_REQUIRED
- COPY_HAS_INTO_KEYWORD
- UNICODE_SUBSTITUTE
- STAR_EXCEPT
- HEX_FUNC
- QUOTE_JSON_PATH
- SUPPORTS_EXPLODING_PROJECTIONS
- ARRAY_CONCAT_IS_VAR_LEN
- SUPPORTS_CONVERT_TIMEZONE
- SUPPORTS_UNIX_SECONDS
- ALTER_SET_WRAPPED
- NORMALIZE_EXTRACT_DATE_PARTS
- ARRAY_SIZE_NAME
- ALTER_SET_TYPE
- ARRAY_SIZE_DIM_REQUIRED
- SUPPORTS_BETWEEN_FLAGS
- SUPPORTS_LIKE_QUANTIFIERS
- MATCH_AGAINST_TABLE_PREFIX
- SET_ASSIGNMENT_REQUIRES_VARIABLE_KEYWORD
- DECLARE_DEFAULT_ASSIGNMENT
- STAR_EXCLUDE_REQUIRES_DERIVED_TABLE
- SUPPORTS_DROP_ALTER_ICEBERG_PROPERTY
- UNSUPPORTED_TYPES
- TYPE_PARAM_SETTINGS
- TIME_PART_SINGULARS
- TOKEN_MAPPING
- STRUCT_DELIMITER
- PARAMETER_TOKEN
- NAMED_PLACEHOLDER_TOKEN
- EXPRESSION_PRECEDES_PROPERTIES_CREATABLES
- WITH_SEPARATED_COMMENTS
- EXCLUDE_COMMENTS
- UNWRAPPED_INTERVAL_VALUES
- PARAMETERIZABLE_TEXT_TYPES
- EXPRESSIONS_WITHOUT_NESTED_CTES
- RESPECT_IGNORE_NULLS_UNSUPPORTED_EXPRESSIONS
- MOD_OPERATOR
- MOD_PAREN_PARENT_TYPES
- SAFE_JSON_PATH_KEY_RE
- SENTINEL_LINE_BREAK
- pretty
- identify
- normalize
- pad
- unsupported_level
- max_unsupported
- leading_comma
- max_text_width
- comments
- dialect
- normalize_functions
- unsupported_messages
- generate
- preprocess
- unsupported
- sep
- seg
- sanitize_comment
- maybe_comment
- wrap
- no_identify
- normalize_func
- indent
- sql
- uncache_sql
- cache_sql
- characterset_sql
- column_parts
- column_sql
- pseudocolumn_sql
- columnposition_sql
- columndef_sql
- columnconstraint_sql
- autoincrementcolumnconstraint_sql
- compresscolumnconstraint_sql
- generatedasidentitycolumnconstraint_sql
- generatedasrowcolumnconstraint_sql
- periodforsystemtimeconstraint_sql
- notnullcolumnconstraint_sql
- primarykeycolumnconstraint_sql
- uniquecolumnconstraint_sql
- inoutcolumnconstraint_sql
- createable_sql
- sequenceproperties_sql
- triggerproperties_sql
- triggerreferencing_sql
- triggerevent_sql
- clone_sql
- describe_sql
- heredoc_sql
- prepend_ctes
- with_sql
- cte_sql
- tablealias_sql
- bitstring_sql
- hexstring_sql
- bytestring_sql
- unicodestring_sql
- rawstring_sql
- datatypeparam_sql
- datatype_param_bound_limiter
- directory_sql
- delete_sql
- drop_sql
- set_operation
- set_operations
- fetch_sql
- limitoptions_sql
- filter_sql
- hint_sql
- indexparameters_sql
- index_sql
- dynamicidentifier_sql
- identifier_sql
- hex_sql
- lowerhex_sql
- inputoutputformat_sql
- national_sql
- properties_sql
- root_properties
- properties
- with_properties
- property_name
- property_sql
- uuidproperty_sql
- likeproperty_sql
- fallbackproperty_sql
- journalproperty_sql
- freespaceproperty_sql
- checksumproperty_sql
- mergeblockratioproperty_sql
- moduleproperty_sql
- datablocksizeproperty_sql
- blockcompressionproperty_sql
- isolatedloadingproperty_sql
- partitionboundspec_sql
- partitionedofproperty_sql
- lockingproperty_sql
- lockingstatement_sql
- withdataproperty_sql
- withsystemversioningproperty_sql
- insert_sql
- introducer_sql
- kill_sql
- pseudotype_sql
- objectidentifier_sql
- onconflict_sql
- returning_sql
- rowformatdelimitedproperty_sql
- withtablehint_sql
- indextablehint_sql
- historicaldata_sql
- table_parts
- table_sql
- tablefromrows_sql
- tablesample_sql
- version_sql
- tuple_sql
- update_sql
- values_sql
- var_sql
- into_sql
- from_sql
- groupingsets_sql
- rollup_sql
- rollupindex_sql
- rollupproperty_sql
- cube_sql
- group_sql
- having_sql
- connect_sql
- prior_sql
- join_sql
- lambda_sql
- lateral_op
- lateral_sql
- limit_sql
- offset_sql
- setitem_sql
- set_sql
- queryband_sql
- pragma_sql
- lock_sql
- literal_sql
- escape_str
- loaddata_sql
- null_sql
- boolean_sql
- booland_sql
- boolor_sql
- order_sql
- withfill_sql
- cluster_sql
- distribute_sql
- sort_sql
- ordered_sql
- matchrecognizemeasure_sql
- matchrecognize_sql
- query_modifiers
- options_modifier
- forclause_sql
- queryoption_sql
- offset_limit_modifiers
- after_limit_modifiers
- select_sql
- schema_sql
- schema_columns_sql
- star_sql
- parameter_sql
- sessionparameter_sql
- placeholder_sql
- subquery_sql
- qualify_sql
- unnest_sql
- prewhere_sql
- where_sql
- window_sql
- partition_by_sql
- partitionbyexcluding_sql
- windowspec_sql
- withingroup_sql
- between_sql
- bracket_offset_expressions
- bracket_sql
- all_sql
- any_sql
- exists_sql
- case_sql
- constraint_sql
- nextvaluefor_sql
- trim_sql
- convert_concat_args
- concat_sql
- concatws_sql
- check_sql
- foreignkey_sql
- primarykey_sql
- timeserieskey_sql
- if_sql
- matchagainst_sql
- jsonkeyvalue_sql
- jsonpath_sql
- json_path_part
- formatjson_sql
- formatphrase_sql
- jsonarray_sql
- jsonarrayagg_sql
- jsoncolumndef_sql
- jsonschema_sql
- jsontable_sql
- openjsoncolumndef_sql
- openjson_sql
- in_sql
- in_unnest_op
- interval_sql
- return_sql
- reference_sql
- anonymous_sql
- paren_sql
- neg_sql
- not_sql
- alias_sql
- pivotalias_sql
- aliases_sql
- atindex_sql
- fromtimezone_sql
- fromiso8601date_sql
- fromiso8601timestamp_sql
- fromiso8601timestampnanos_sql
- add_sql
- and_sql
- or_sql
- xor_sql
- connector_sql
- bitwiseand_sql
- bitwiseleftshift_sql
- bitwisenot_sql
- bitwiseor_sql
- bitwiserightshift_sql
- bitwisexor_sql
- strtotime_sql
- strtodate_sql
- parsedatetime_sql
- currentdate_sql
- collate_sql
- command_sql
- comment_sql
- mergetreettlaction_sql
- mergetreettl_sql
- transaction_sql
- commit_sql
- rollback_sql
- modifycolumn_sql
- alterindex_sql
- alterdiststyle_sql
- altersortkey_sql
- renamecolumn_sql
- alterset_sql
- alter_sql
- altersession_sql
- add_column_sql
- droppartition_sql
- dropprimarykey_sql
- addconstraint_sql
- replacecolumns_sql
- addpartition_sql
- distinct_sql
- havingmax_sql
- div_sql
- safedivide_sql
- overlaps_sql
- distance_sql
- distancend_sql
- dot_sql
- eq_sql
- propertyeq_sql
- escape_sql
- glob_sql
- gt_sql
- gte_sql
- is_sql
- like_sql
- ilike_sql
- match_sql
- similarto_sql
- lt_sql
- lte_sql
- mod_sql
- mul_sql
- neq_sql
- nullsafeeq_sql
- nullsafeneq_sql
- sub_sql
- trycast_sql
- jsoncast_sql
- try_sql
- log_sql
- use_sql
- binary
- ceil_floor
- function_fallback_sql
- function_name
- func
- format_args
- too_wide
- format_time
- expressions
- op_expressions
- naked_property
- tag_sql
- token_sql
- userdefinedfunction_sql
- macrooverloads_sql
- macrooverload_sql
- joinhint_sql
- kwarg_sql
- when_sql
- whens_sql
- merge_sql
- tochar_sql
- tonumber_sql
- dictproperty_sql
- dictrange_sql
- dictsubproperty_sql
- aggregatekeyproperty_sql
- duplicatekeyproperty_sql
- uniquekeyproperty_sql
- distributedbyproperty_sql
- oncluster_sql
- clusteredbyproperty_sql
- anyvalue_sql
- querytransform_sql
- indexconstraintoption_sql
- checkcolumnconstraint_sql
- indexcolumnconstraint_sql
- nvl2_sql
- nthvalue_sql
- comprehension_sql
- columnprefix_sql
- opclass_sql
- predict_sql
- generateembedding_sql
- generatetext_sql
- generatetable_sql
- generatebool_sql
- generateint_sql
- generatedouble_sql
- mltranslate_sql
- mlforecast_sql
- aiforecast_sql
- featuresattime_sql
- vectorsearch_sql
- forin_sql
- toarray_sql
- tsordstotime_sql
- tsordstotimestamp_sql
- tsordstodatetime_sql
- tsordstodate_sql
- unixdate_sql
- lastday_sql
- dateadd_sql
- arrayinsert_sql
- arrayany_sql
- struct_sql
- truncatetable_sql
- convert_sql
- copyparameter_sql
- credentials_sql
- copy_sql
- semicolon_sql
- datadeletionproperty_sql
- maskingpolicycolumnconstraint_sql
- gapfill_sql
- scope_resolution
- scoperesolution_sql
- parsejson_sql
- rand_sql
- changes_sql
- pad_sql
- summarize_sql
- explodinggenerateseries_sql
- json_sql
- jsonvalue_sql
- skipjsoncolumn_sql
- conditionalinsert_sql
- multitableinserts_sql
- oncondition_sql
- jsonextractquote_sql
- jsonexists_sql
- arrayagg_sql
- slice_sql
- apply_sql
- grant_sql
- revoke_sql
- grantprivilege_sql
- grantprincipal_sql
- columns_sql
- overlay_sql
- todouble_sql
- string_sql
- median_sql
- overflowtruncatebehavior_sql
- unixseconds_sql
- arraysort_sql
- arraysize_sql
- attach_sql
- detach_sql
- attachoption_sql
- watermarkcolumnconstraint_sql
- encodeproperty_sql
- includeproperty_sql
- xmlelement_sql
- xmlkeyvalueoption_sql
- partitionbyrangepropertydynamic_sql
- unpivotcolumns_sql
- analyzesample_sql
- analyzestatistics_sql
- analyzehistogram_sql
- analyzedelete_sql
- analyzelistchainedrows_sql
- analyzevalidate_sql
- analyze_sql
- xmltable_sql
- xmlnamespace_sql
- export_sql
- declare_sql
- declareitem_sql
- recursivewithsearch_sql
- parameterizedagg_sql
- anonymousaggfunc_sql
- combinedaggfunc_sql
- combinedparameterizedagg_sql
- install_sql
- liststage_sql
- get_put_sql
- translatecharacters_sql
- decodecase_sql
- semanticview_sql
- getextract_sql
- datefromunixdate_sql
- space_sql
- buildproperty_sql
- modelattribute_sql
- directorystage_sql
- uuid_sql
- initcap_sql
- localtime_sql
- localtimestamp_sql
- weekstart_name
- weekstart_sql
- chr_sql
- weightstring_sql
- block_sql
- functionspecification_sql
- storedprocedure_sql
- ifblock_sql
- casestatement_sql
- whileblock_sql
- loopblock_sql
- repeatblock_sql
- leave_sql
- iterate_sql
- execute_sql
- executesql_sql
- altermodifysqlsecurity_sql
- usingproperty_sql
- renameindex_sql
- sqlglot.generators.mysql.MySQLGenerator
- BYTE_STRING_FUNCTION
- SELECT_KINDS
- TRY_SUPPORTED
- SUPPORTS_UESCAPE
- SUPPORTS_DECODE_CASE
- SUPPORTS_MODIFY_COLUMN
- SUPPORTS_CHANGE_COLUMN
- SUPPORTS_ALTER_COLUMN_NULLABILITY
- AFTER_HAVING_MODIFIER_TRANSFORMS
- INTERVAL_ALLOWS_PLURAL_FORM
- LOCKING_READS_SUPPORTED
- NULL_ORDERING_SUPPORTED
- JOIN_HINTS
- TABLE_HINTS
- DUPLICATE_KEY_UPDATE_WITH_SET
- QUERY_HINT_SEP
- VALUES_AS_TABLE
- NVL2_SUPPORTED
- LAST_DAY_SUPPORTS_DATE_PART
- JSON_PATH_BRACKETED_KEY_SUPPORTED
- JSON_KEY_VALUE_PAIR_SEP
- SUPPORTS_TO_NUMBER
- PAD_FILL_PATTERN_IS_REQUIRED
- WRAP_DERIVED_VALUES
- SUPPORTS_MEDIAN
- UNSIGNED_TYPE_MAPPING
- TIMESTAMP_TYPE_MAPPING
- LIMIT_FETCH
- LIMIT_ONLY_LITERALS
- CHAR_CAST_MAPPING
- SIGNED_CAST_MAPPING
- TIMESTAMP_FUNC_TYPES
- makeinterval_sql
- locate_properties
- computedcolumnconstraint_sql
- array_sql
- arraycontainsall_sql
- arraycontainedby_sql
- dpipe_sql
- intdiv_sql
- extract_sql
- datatype_sql
- jsonarraycontains_sql
- cast_sql
- show_sql
- alterrename_sql
- altercolumn_sql
- timestamptrunc_sql
- converttimezone_sql
- attimezone_sql
- isascii_sql
- currentschema_sql
- partition_sql
- partitionbyrangeproperty_sql
- partitionbylistproperty_sql
- partitionlist_sql
- partitionrange_sql