From 639a208fa57ea674d165c4837e96f3ae4d7e3e61 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 19 Feb 2023 14:45:09 +0100 Subject: Merging upstream version 11.1.3. Signed-off-by: Daniel Baumann --- docs/sqlglot/dataframe/sql.html | 38 +- docs/sqlglot/dialects/bigquery.html | 1192 +- docs/sqlglot/dialects/clickhouse.html | 8 +- docs/sqlglot/dialects/databricks.html | 160 +- docs/sqlglot/dialects/dialect.html | 710 +- docs/sqlglot/dialects/drill.html | 644 +- docs/sqlglot/dialects/duckdb.html | 541 +- docs/sqlglot/dialects/hive.html | 238 +- docs/sqlglot/dialects/mysql.html | 2771 ++-- docs/sqlglot/dialects/oracle.html | 756 +- docs/sqlglot/dialects/postgres.html | 679 +- docs/sqlglot/dialects/presto.html | 973 +- docs/sqlglot/dialects/redshift.html | 816 +- docs/sqlglot/dialects/snowflake.html | 994 +- docs/sqlglot/dialects/spark.html | 561 +- docs/sqlglot/dialects/sqlite.html | 10 +- docs/sqlglot/dialects/starrocks.html | 8 +- docs/sqlglot/dialects/tableau.html | 8 +- docs/sqlglot/dialects/teradata.html | 774 +- docs/sqlglot/dialects/trino.html | 8 +- docs/sqlglot/dialects/tsql.html | 20 +- docs/sqlglot/executor.html | 56 +- docs/sqlglot/executor/python.html | 10 +- docs/sqlglot/expressions.html | 14865 +++++++++++---------- docs/sqlglot/generator.html | 10695 +++++++-------- docs/sqlglot/lineage.html | 2 +- docs/sqlglot/optimizer/annotate_types.html | 453 +- docs/sqlglot/optimizer/eliminate_subqueries.html | 230 +- docs/sqlglot/optimizer/optimizer.html | 257 +- docs/sqlglot/optimizer/qualify_columns.html | 811 +- docs/sqlglot/optimizer/qualify_tables.html | 4 +- docs/sqlglot/optimizer/scope.html | 2407 ++-- docs/sqlglot/parser.html | 14691 ++++++++++---------- docs/sqlglot/tokens.html | 3907 +++--- 34 files changed, 30964 insertions(+), 29333 deletions(-) (limited to 'docs/sqlglot') diff --git a/docs/sqlglot/dataframe/sql.html b/docs/sqlglot/dataframe/sql.html index 83f5418..6996f8e 100644 --- a/docs/sqlglot/dataframe/sql.html +++ b/docs/sqlglot/dataframe/sql.html @@ -632,7 +632,7 @@
def - createDataFrame( self, data: Sequence[Union[Dict[str, <MagicMock id='140700333898336'>], List[<MagicMock id='140700333898336'>], Tuple]], schema: Optional[<MagicMock id='140700333867312'>] = None, samplingRatio: Optional[float] = None, verifySchema: bool = False) -> sqlglot.dataframe.sql.DataFrame: + createDataFrame( self, data: Sequence[Union[Dict[str, <MagicMock id='139725215695536'>], List[<MagicMock id='139725215695536'>], Tuple]], schema: Optional[<MagicMock id='139725215622064'>] = None, samplingRatio: Optional[float] = None, verifySchema: bool = False) -> sqlglot.dataframe.sql.DataFrame: @@ -1500,7 +1500,7 @@
- DataFrame( spark: <MagicMock id='140700332957056'>, expression: sqlglot.expressions.Select, branch_id: Optional[str] = None, sequence_id: Optional[str] = None, last_op: sqlglot.dataframe.sql.operations.Operation = <Operation.INIT: -1>, pending_hints: Optional[List[sqlglot.expressions.Expression]] = None, output_expression_container: Optional[<MagicMock id='140700332981504'>] = None, **kwargs) + DataFrame( spark: <MagicMock id='139725216439680'>, expression: sqlglot.expressions.Select, branch_id: Optional[str] = None, sequence_id: Optional[str] = None, last_op: sqlglot.dataframe.sql.operations.Operation = <Operation.INIT: -1>, pending_hints: Optional[List[sqlglot.expressions.Expression]] = None, output_expression_container: Optional[<MagicMock id='139725216580944'>] = None, **kwargs) @@ -2238,7 +2238,7 @@ is unlikely to come up.

@operation(Operation.FROM)
def - fillna( self, value: <MagicMock id='140700331804992'>, subset: Union[str, Tuple[str, ...], List[str], NoneType] = None) -> sqlglot.dataframe.sql.DataFrame: + fillna( self, value: <MagicMock id='139725213592944'>, subset: Union[str, Tuple[str, ...], List[str], NoneType] = None) -> sqlglot.dataframe.sql.DataFrame: @@ -2307,7 +2307,7 @@ and check if it matches the type of the value provided. If not then make it null
@operation(Operation.FROM)
def - replace( self, to_replace: Union[bool, int, float, str, List, Dict], value: Union[bool, int, float, str, List, NoneType] = None, subset: Union[Collection[<MagicMock id='140700331990208'>], <MagicMock id='140700331990208'>, NoneType] = None) -> sqlglot.dataframe.sql.DataFrame: + replace( self, to_replace: Union[bool, int, float, str, List, Dict], value: Union[bool, int, float, str, List, NoneType] = None, subset: Union[Collection[<MagicMock id='139725213796384'>], <MagicMock id='139725213796384'>, NoneType] = None) -> sqlglot.dataframe.sql.DataFrame: @@ -2512,7 +2512,7 @@ and check if it matches the type of the value provided. If not then make it null
@operation(Operation.NO_OP)
def - repartition( self, numPartitions: Union[int, <MagicMock id='140700332136032'>], *cols: <MagicMock id='140700332245248'>) -> sqlglot.dataframe.sql.DataFrame: + repartition( self, numPartitions: Union[int, <MagicMock id='139725213899536'>], *cols: <MagicMock id='139725214009616'>) -> sqlglot.dataframe.sql.DataFrame: @@ -3179,7 +3179,7 @@ and check if it matches the type of the value provided. If not then make it null
- Column( expression: Union[<MagicMock id='140700332259696'>, sqlglot.expressions.Expression, NoneType]) + Column( expression: Union[<MagicMock id='139725214054480'>, sqlglot.expressions.Expression, NoneType]) @@ -3207,7 +3207,7 @@ and check if it matches the type of the value provided. If not then make it null
@classmethod
def - ensure_col( cls, value: Union[<MagicMock id='140700330611696'>, sqlglot.expressions.Expression, NoneType]): + ensure_col( cls, value: Union[<MagicMock id='139725214486192'>, sqlglot.expressions.Expression, NoneType]): @@ -3228,7 +3228,7 @@ and check if it matches the type of the value provided. If not then make it null
@classmethod
def - ensure_cols( cls, args: List[Union[<MagicMock id='140700330840736'>, sqlglot.expressions.Expression]]) -> List[sqlglot.dataframe.sql.Column]: + ensure_cols( cls, args: List[Union[<MagicMock id='139725212552544'>, sqlglot.expressions.Expression]]) -> List[sqlglot.dataframe.sql.Column]: @@ -3249,7 +3249,7 @@ and check if it matches the type of the value provided. If not then make it null
@classmethod
def - invoke_anonymous_function( cls, column: Optional[<MagicMock id='140700330924096'>], func_name: str, *args: Optional[<MagicMock id='140700330964112'>]) -> sqlglot.dataframe.sql.Column: + invoke_anonymous_function( cls, column: Optional[<MagicMock id='139725212635904'>], func_name: str, *args: Optional[<MagicMock id='139725212692304'>]) -> sqlglot.dataframe.sql.Column: @@ -3276,7 +3276,7 @@ and check if it matches the type of the value provided. If not then make it null
@classmethod
def - invoke_expression_over_column( cls, column: Optional[<MagicMock id='140700331029648'>], callable_expression: Callable, **kwargs) -> sqlglot.dataframe.sql.Column: + invoke_expression_over_column( cls, column: Optional[<MagicMock id='139725212757840'>], callable_expression: Callable, **kwargs) -> sqlglot.dataframe.sql.Column: @@ -3312,7 +3312,7 @@ and check if it matches the type of the value provided. If not then make it null
def - binary_op( self, klass: Callable, other: <MagicMock id='140700331083136'>, **kwargs) -> sqlglot.dataframe.sql.Column: + binary_op( self, klass: Callable, other: <MagicMock id='139725212831072'>, **kwargs) -> sqlglot.dataframe.sql.Column: @@ -3333,7 +3333,7 @@ and check if it matches the type of the value provided. If not then make it null
def - inverse_binary_op( self, klass: Callable, other: <MagicMock id='140700331093216'>, **kwargs) -> sqlglot.dataframe.sql.Column: + inverse_binary_op( self, klass: Callable, other: <MagicMock id='139725212841200'>, **kwargs) -> sqlglot.dataframe.sql.Column: @@ -3843,7 +3843,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string

def - isin( self, *cols: Union[<MagicMock id='140700331213104'>, Iterable[<MagicMock id='140700331213104'>]]): + isin( self, *cols: Union[<MagicMock id='139725213009472'>, Iterable[<MagicMock id='139725213009472'>]]): @@ -3864,7 +3864,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string

def - between( self, lowerBound: <MagicMock id='140700331299440'>, upperBound: <MagicMock id='140700329240384'>) -> sqlglot.dataframe.sql.Column: + between( self, lowerBound: <MagicMock id='139725213096576'>, upperBound: <MagicMock id='139725213134672'>) -> sqlglot.dataframe.sql.Column: @@ -3899,7 +3899,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string

def - over( self, window: <MagicMock id='140700329314480'>) -> sqlglot.dataframe.sql.Column: + over( self, window: <MagicMock id='139725213176000'>) -> sqlglot.dataframe.sql.Column: @@ -4109,7 +4109,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string

@classmethod
def - partitionBy( cls, *cols: Union[<MagicMock id='140700329626592'>, List[<MagicMock id='140700329626592'>]]) -> sqlglot.dataframe.sql.WindowSpec: + partitionBy( cls, *cols: Union[<MagicMock id='139725213424208'>, List[<MagicMock id='139725213424208'>]]) -> sqlglot.dataframe.sql.WindowSpec: @@ -4130,7 +4130,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string

@classmethod
def - orderBy( cls, *cols: Union[<MagicMock id='140700329828768'>, List[<MagicMock id='140700329828768'>]]) -> sqlglot.dataframe.sql.WindowSpec: + orderBy( cls, *cols: Union[<MagicMock id='139725213347952'>, List[<MagicMock id='139725213347952'>]]) -> sqlglot.dataframe.sql.WindowSpec: @@ -4355,7 +4355,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string

def - partitionBy( self, *cols: Union[<MagicMock id='140700329685440'>, List[<MagicMock id='140700329685440'>]]) -> sqlglot.dataframe.sql.WindowSpec: + partitionBy( self, *cols: Union[<MagicMock id='139725213251904'>, List[<MagicMock id='139725213251904'>]]) -> sqlglot.dataframe.sql.WindowSpec: @@ -4382,7 +4382,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string

def - orderBy( self, *cols: Union[<MagicMock id='140700329654400'>, List[<MagicMock id='140700329654400'>]]) -> sqlglot.dataframe.sql.WindowSpec: + orderBy( self, *cols: Union[<MagicMock id='139725212189360'>, List[<MagicMock id='139725212189360'>]]) -> sqlglot.dataframe.sql.WindowSpec: diff --git a/docs/sqlglot/dialects/bigquery.html b/docs/sqlglot/dialects/bigquery.html index 903fccb..af0a508 100644 --- a/docs/sqlglot/dialects/bigquery.html +++ b/docs/sqlglot/dialects/bigquery.html @@ -134,257 +134,259 @@ 31 return func 32 33 - 34def _date_trunc(args: t.Sequence) -> exp.Expression: - 35 unit = seq_get(args, 1) - 36 if isinstance(unit, exp.Column): - 37 unit = exp.Var(this=unit.name) - 38 return exp.DateTrunc(this=seq_get(args, 0), expression=unit) - 39 + 34def _date_add_sql( + 35 data_type: str, kind: str + 36) -> t.Callable[[generator.Generator, exp.Expression], str]: + 37 def func(self, expression): + 38 this = self.sql(expression, "this") + 39 return f"{data_type}_{kind}({this}, {self.sql(exp.Interval(this=expression.expression, unit=expression.args.get('unit') or exp.Literal.string('day')))})" 40 - 41def _date_add_sql( - 42 data_type: str, kind: str - 43) -> t.Callable[[generator.Generator, exp.Expression], str]: - 44 def func(self, expression): - 45 this = self.sql(expression, "this") - 46 return f"{data_type}_{kind}({this}, {self.sql(exp.Interval(this=expression.expression, unit=expression.args.get('unit') or exp.Literal.string('day')))})" - 47 - 48 return func - 49 - 50 - 51def _derived_table_values_to_unnest(self: generator.Generator, expression: exp.Values) -> str: - 52 if not isinstance(expression.unnest().parent, exp.From): - 53 expression = t.cast(exp.Values, transforms.remove_precision_parameterized_types(expression)) - 54 return self.values_sql(expression) - 55 rows = [tuple_exp.expressions for tuple_exp in expression.find_all(exp.Tuple)] - 56 structs = [] - 57 for row in rows: - 58 aliases = [ - 59 exp.alias_(value, column_name) - 60 for value, column_name in zip(row, expression.args["alias"].args["columns"]) - 61 ] - 62 structs.append(exp.Struct(expressions=aliases)) - 63 unnest_exp = exp.Unnest(expressions=[exp.Array(expressions=structs)]) - 64 return self.unnest_sql(unnest_exp) - 65 - 66 - 67def _returnsproperty_sql(self: generator.Generator, expression: exp.ReturnsProperty) -> str: - 68 this = expression.this - 69 if isinstance(this, exp.Schema): - 70 this = f"{this.this} <{self.expressions(this)}>" - 71 else: - 72 this = self.sql(this) - 73 return f"RETURNS {this}" - 74 - 75 - 76def _create_sql(self: generator.Generator, expression: exp.Create) -> str: - 77 kind = expression.args["kind"] - 78 returns = expression.find(exp.ReturnsProperty) - 79 if kind.upper() == "FUNCTION" and returns and returns.args.get("is_table"): - 80 expression = expression.copy() - 81 expression.set("kind", "TABLE FUNCTION") - 82 if isinstance( - 83 expression.expression, - 84 ( - 85 exp.Subquery, - 86 exp.Literal, - 87 ), - 88 ): - 89 expression.set("expression", expression.expression.this) - 90 - 91 return self.create_sql(expression) - 92 - 93 return self.create_sql(expression) - 94 - 95 - 96def _unqualify_unnest(expression: exp.Expression) -> exp.Expression: - 97 """Remove references to unnest table aliases since bigquery doesn't allow them. - 98 - 99 These are added by the optimizer's qualify_column step. -100 """ -101 if isinstance(expression, exp.Select): -102 unnests = { -103 unnest.alias -104 for unnest in expression.args.get("from", exp.From(expressions=[])).expressions -105 if isinstance(unnest, exp.Unnest) and unnest.alias -106 } -107 -108 if unnests: -109 expression = expression.copy() + 41 return func + 42 + 43 + 44def _derived_table_values_to_unnest(self: generator.Generator, expression: exp.Values) -> str: + 45 if not isinstance(expression.unnest().parent, exp.From): + 46 expression = t.cast(exp.Values, transforms.remove_precision_parameterized_types(expression)) + 47 return self.values_sql(expression) + 48 rows = [tuple_exp.expressions for tuple_exp in expression.find_all(exp.Tuple)] + 49 structs = [] + 50 for row in rows: + 51 aliases = [ + 52 exp.alias_(value, column_name) + 53 for value, column_name in zip(row, expression.args["alias"].args["columns"]) + 54 ] + 55 structs.append(exp.Struct(expressions=aliases)) + 56 unnest_exp = exp.Unnest(expressions=[exp.Array(expressions=structs)]) + 57 return self.unnest_sql(unnest_exp) + 58 + 59 + 60def _returnsproperty_sql(self: generator.Generator, expression: exp.ReturnsProperty) -> str: + 61 this = expression.this + 62 if isinstance(this, exp.Schema): + 63 this = f"{this.this} <{self.expressions(this)}>" + 64 else: + 65 this = self.sql(this) + 66 return f"RETURNS {this}" + 67 + 68 + 69def _create_sql(self: generator.Generator, expression: exp.Create) -> str: + 70 kind = expression.args["kind"] + 71 returns = expression.find(exp.ReturnsProperty) + 72 if kind.upper() == "FUNCTION" and returns and returns.args.get("is_table"): + 73 expression = expression.copy() + 74 expression.set("kind", "TABLE FUNCTION") + 75 if isinstance( + 76 expression.expression, + 77 ( + 78 exp.Subquery, + 79 exp.Literal, + 80 ), + 81 ): + 82 expression.set("expression", expression.expression.this) + 83 + 84 return self.create_sql(expression) + 85 + 86 return self.create_sql(expression) + 87 + 88 + 89def _unqualify_unnest(expression: exp.Expression) -> exp.Expression: + 90 """Remove references to unnest table aliases since bigquery doesn't allow them. + 91 + 92 These are added by the optimizer's qualify_column step. + 93 """ + 94 if isinstance(expression, exp.Select): + 95 unnests = { + 96 unnest.alias + 97 for unnest in expression.args.get("from", exp.From(expressions=[])).expressions + 98 if isinstance(unnest, exp.Unnest) and unnest.alias + 99 } +100 +101 if unnests: +102 expression = expression.copy() +103 +104 for select in expression.expressions: +105 for column in select.find_all(exp.Column): +106 if column.table in unnests: +107 column.set("table", None) +108 +109 return expression 110 -111 for select in expression.expressions: -112 for column in select.find_all(exp.Column): -113 if column.table in unnests: -114 column.set("table", None) -115 -116 return expression -117 -118 -119class BigQuery(Dialect): -120 unnest_column_only = True -121 time_mapping = { -122 "%M": "%-M", -123 "%d": "%-d", -124 "%m": "%-m", -125 "%y": "%-y", -126 "%H": "%-H", -127 "%I": "%-I", -128 "%S": "%-S", -129 "%j": "%-j", -130 } -131 -132 class Tokenizer(tokens.Tokenizer): -133 QUOTES = [ -134 (prefix + quote, quote) if prefix else quote -135 for quote in ["'", '"', '"""', "'''"] -136 for prefix in ["", "r", "R"] -137 ] -138 COMMENTS = ["--", "#", ("/*", "*/")] -139 IDENTIFIERS = ["`"] -140 STRING_ESCAPES = ["\\"] -141 HEX_STRINGS = [("0x", ""), ("0X", "")] -142 -143 KEYWORDS = { -144 **tokens.Tokenizer.KEYWORDS, -145 "BEGIN": TokenType.COMMAND, -146 "BEGIN TRANSACTION": TokenType.BEGIN, -147 "CURRENT_DATETIME": TokenType.CURRENT_DATETIME, -148 "CURRENT_TIME": TokenType.CURRENT_TIME, -149 "DECLARE": TokenType.COMMAND, -150 "GEOGRAPHY": TokenType.GEOGRAPHY, -151 "FLOAT64": TokenType.DOUBLE, -152 "INT64": TokenType.BIGINT, -153 "NOT DETERMINISTIC": TokenType.VOLATILE, -154 "UNKNOWN": TokenType.NULL, -155 } -156 KEYWORDS.pop("DIV") -157 -158 class Parser(parser.Parser): -159 FUNCTIONS = { -160 **parser.Parser.FUNCTIONS, # type: ignore -161 "DATE_TRUNC": _date_trunc, -162 "DATE_ADD": _date_add(exp.DateAdd), -163 "DATETIME_ADD": _date_add(exp.DatetimeAdd), -164 "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)), -165 "REGEXP_CONTAINS": exp.RegexpLike.from_arg_list, -166 "TIME_ADD": _date_add(exp.TimeAdd), -167 "TIMESTAMP_ADD": _date_add(exp.TimestampAdd), -168 "DATE_SUB": _date_add(exp.DateSub), -169 "DATETIME_SUB": _date_add(exp.DatetimeSub), -170 "TIME_SUB": _date_add(exp.TimeSub), -171 "TIMESTAMP_SUB": _date_add(exp.TimestampSub), -172 "PARSE_TIMESTAMP": lambda args: exp.StrToTime( -173 this=seq_get(args, 1), format=seq_get(args, 0) -174 ), -175 } -176 -177 FUNCTION_PARSERS = { -178 **parser.Parser.FUNCTION_PARSERS, # type: ignore -179 "ARRAY": lambda self: self.expression(exp.Array, expressions=[self._parse_statement()]), -180 } -181 FUNCTION_PARSERS.pop("TRIM") -182 -183 NO_PAREN_FUNCTIONS = { -184 **parser.Parser.NO_PAREN_FUNCTIONS, # type: ignore -185 TokenType.CURRENT_DATETIME: exp.CurrentDatetime, -186 TokenType.CURRENT_TIME: exp.CurrentTime, -187 } -188 -189 NESTED_TYPE_TOKENS = { -190 *parser.Parser.NESTED_TYPE_TOKENS, # type: ignore -191 TokenType.TABLE, -192 } -193 -194 ID_VAR_TOKENS = { -195 *parser.Parser.ID_VAR_TOKENS, # type: ignore -196 TokenType.VALUES, -197 } -198 -199 PROPERTY_PARSERS = { -200 **parser.Parser.PROPERTY_PARSERS, # type: ignore -201 "NOT DETERMINISTIC": lambda self: self.expression( -202 exp.VolatilityProperty, this=exp.Literal.string("VOLATILE") -203 ), -204 } -205 -206 class Generator(generator.Generator): -207 TRANSFORMS = { -208 **generator.Generator.TRANSFORMS, # type: ignore -209 **transforms.REMOVE_PRECISION_PARAMETERIZED_TYPES, # type: ignore -210 exp.ArraySize: rename_func("ARRAY_LENGTH"), -211 exp.DateAdd: _date_add_sql("DATE", "ADD"), -212 exp.DateSub: _date_add_sql("DATE", "SUB"), -213 exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"), -214 exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"), -215 exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})", -216 exp.DateStrToDate: datestrtodate_sql, -217 exp.GroupConcat: rename_func("STRING_AGG"), -218 exp.ILike: no_ilike_sql, -219 exp.IntDiv: rename_func("DIV"), -220 exp.Select: transforms.preprocess( -221 [_unqualify_unnest], transforms.delegate("select_sql") -222 ), -223 exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})", -224 exp.TimeAdd: _date_add_sql("TIME", "ADD"), -225 exp.TimeSub: _date_add_sql("TIME", "SUB"), -226 exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"), -227 exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"), -228 exp.TimeStrToTime: timestrtotime_sql, -229 exp.VariancePop: rename_func("VAR_POP"), -230 exp.Values: _derived_table_values_to_unnest, -231 exp.ReturnsProperty: _returnsproperty_sql, -232 exp.Create: _create_sql, -233 exp.Trim: lambda self, e: f"TRIM({self.format_args(e.this, e.expression)})", -234 exp.VolatilityProperty: lambda self, e: f"DETERMINISTIC" -235 if e.name == "IMMUTABLE" -236 else "NOT DETERMINISTIC", -237 exp.RegexpLike: rename_func("REGEXP_CONTAINS"), -238 } -239 -240 TYPE_MAPPING = { -241 **generator.Generator.TYPE_MAPPING, # type: ignore -242 exp.DataType.Type.TINYINT: "INT64", -243 exp.DataType.Type.SMALLINT: "INT64", -244 exp.DataType.Type.INT: "INT64", -245 exp.DataType.Type.BIGINT: "INT64", -246 exp.DataType.Type.DECIMAL: "NUMERIC", -247 exp.DataType.Type.FLOAT: "FLOAT64", -248 exp.DataType.Type.DOUBLE: "FLOAT64", -249 exp.DataType.Type.BOOLEAN: "BOOL", -250 exp.DataType.Type.TEXT: "STRING", -251 exp.DataType.Type.VARCHAR: "STRING", -252 exp.DataType.Type.NVARCHAR: "STRING", -253 } -254 -255 EXPLICIT_UNION = True +111 +112class BigQuery(Dialect): +113 unnest_column_only = True +114 time_mapping = { +115 "%M": "%-M", +116 "%d": "%-d", +117 "%m": "%-m", +118 "%y": "%-y", +119 "%H": "%-H", +120 "%I": "%-I", +121 "%S": "%-S", +122 "%j": "%-j", +123 } +124 +125 class Tokenizer(tokens.Tokenizer): +126 QUOTES = [ +127 (prefix + quote, quote) if prefix else quote +128 for quote in ["'", '"', '"""', "'''"] +129 for prefix in ["", "r", "R"] +130 ] +131 COMMENTS = ["--", "#", ("/*", "*/")] +132 IDENTIFIERS = ["`"] +133 STRING_ESCAPES = ["\\"] +134 HEX_STRINGS = [("0x", ""), ("0X", "")] +135 +136 KEYWORDS = { +137 **tokens.Tokenizer.KEYWORDS, +138 "BEGIN": TokenType.COMMAND, +139 "BEGIN TRANSACTION": TokenType.BEGIN, +140 "CURRENT_DATETIME": TokenType.CURRENT_DATETIME, +141 "CURRENT_TIME": TokenType.CURRENT_TIME, +142 "DECLARE": TokenType.COMMAND, +143 "GEOGRAPHY": TokenType.GEOGRAPHY, +144 "FLOAT64": TokenType.DOUBLE, +145 "INT64": TokenType.BIGINT, +146 "NOT DETERMINISTIC": TokenType.VOLATILE, +147 "UNKNOWN": TokenType.NULL, +148 } +149 KEYWORDS.pop("DIV") +150 +151 class Parser(parser.Parser): +152 FUNCTIONS = { +153 **parser.Parser.FUNCTIONS, # type: ignore +154 "DATE_TRUNC": lambda args: exp.DateTrunc( +155 unit=exp.Literal.string(seq_get(args, 1).name), # type: ignore +156 this=seq_get(args, 0), +157 ), +158 "DATE_ADD": _date_add(exp.DateAdd), +159 "DATETIME_ADD": _date_add(exp.DatetimeAdd), +160 "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)), +161 "REGEXP_CONTAINS": exp.RegexpLike.from_arg_list, +162 "TIME_ADD": _date_add(exp.TimeAdd), +163 "TIMESTAMP_ADD": _date_add(exp.TimestampAdd), +164 "DATE_SUB": _date_add(exp.DateSub), +165 "DATETIME_SUB": _date_add(exp.DatetimeSub), +166 "TIME_SUB": _date_add(exp.TimeSub), +167 "TIMESTAMP_SUB": _date_add(exp.TimestampSub), +168 "PARSE_TIMESTAMP": lambda args: exp.StrToTime( +169 this=seq_get(args, 1), format=seq_get(args, 0) +170 ), +171 } +172 +173 FUNCTION_PARSERS = { +174 **parser.Parser.FUNCTION_PARSERS, # type: ignore +175 "ARRAY": lambda self: self.expression(exp.Array, expressions=[self._parse_statement()]), +176 } +177 FUNCTION_PARSERS.pop("TRIM") +178 +179 NO_PAREN_FUNCTIONS = { +180 **parser.Parser.NO_PAREN_FUNCTIONS, # type: ignore +181 TokenType.CURRENT_DATETIME: exp.CurrentDatetime, +182 TokenType.CURRENT_TIME: exp.CurrentTime, +183 } +184 +185 NESTED_TYPE_TOKENS = { +186 *parser.Parser.NESTED_TYPE_TOKENS, # type: ignore +187 TokenType.TABLE, +188 } +189 +190 ID_VAR_TOKENS = { +191 *parser.Parser.ID_VAR_TOKENS, # type: ignore +192 TokenType.VALUES, +193 } +194 +195 PROPERTY_PARSERS = { +196 **parser.Parser.PROPERTY_PARSERS, # type: ignore +197 "NOT DETERMINISTIC": lambda self: self.expression( +198 exp.VolatilityProperty, this=exp.Literal.string("VOLATILE") +199 ), +200 } +201 +202 class Generator(generator.Generator): +203 TRANSFORMS = { +204 **generator.Generator.TRANSFORMS, # type: ignore +205 **transforms.REMOVE_PRECISION_PARAMETERIZED_TYPES, # type: ignore +206 exp.ArraySize: rename_func("ARRAY_LENGTH"), +207 exp.DateAdd: _date_add_sql("DATE", "ADD"), +208 exp.DateSub: _date_add_sql("DATE", "SUB"), +209 exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"), +210 exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"), +211 exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})", +212 exp.DateStrToDate: datestrtodate_sql, +213 exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, e.text("unit")), +214 exp.GroupConcat: rename_func("STRING_AGG"), +215 exp.ILike: no_ilike_sql, +216 exp.IntDiv: rename_func("DIV"), +217 exp.Select: transforms.preprocess( +218 [_unqualify_unnest], transforms.delegate("select_sql") +219 ), +220 exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})", +221 exp.TimeAdd: _date_add_sql("TIME", "ADD"), +222 exp.TimeSub: _date_add_sql("TIME", "SUB"), +223 exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"), +224 exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"), +225 exp.TimeStrToTime: timestrtotime_sql, +226 exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}", +227 exp.VariancePop: rename_func("VAR_POP"), +228 exp.Values: _derived_table_values_to_unnest, +229 exp.ReturnsProperty: _returnsproperty_sql, +230 exp.Create: _create_sql, +231 exp.Trim: lambda self, e: self.func(f"TRIM", e.this, e.expression), +232 exp.VolatilityProperty: lambda self, e: f"DETERMINISTIC" +233 if e.name == "IMMUTABLE" +234 else "NOT DETERMINISTIC", +235 exp.RegexpLike: rename_func("REGEXP_CONTAINS"), +236 } +237 +238 TYPE_MAPPING = { +239 **generator.Generator.TYPE_MAPPING, # type: ignore +240 exp.DataType.Type.TINYINT: "INT64", +241 exp.DataType.Type.SMALLINT: "INT64", +242 exp.DataType.Type.INT: "INT64", +243 exp.DataType.Type.BIGINT: "INT64", +244 exp.DataType.Type.DECIMAL: "NUMERIC", +245 exp.DataType.Type.FLOAT: "FLOAT64", +246 exp.DataType.Type.DOUBLE: "FLOAT64", +247 exp.DataType.Type.BOOLEAN: "BOOL", +248 exp.DataType.Type.TEXT: "STRING", +249 exp.DataType.Type.VARCHAR: "STRING", +250 exp.DataType.Type.NVARCHAR: "STRING", +251 } +252 PROPERTIES_LOCATION = { +253 **generator.Generator.PROPERTIES_LOCATION, # type: ignore +254 exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA, +255 } 256 -257 def array_sql(self, expression: exp.Array) -> str: -258 first_arg = seq_get(expression.expressions, 0) -259 if isinstance(first_arg, exp.Subqueryable): -260 return f"ARRAY{self.wrap(self.sql(first_arg))}" -261 -262 return inline_array_sql(self, expression) +257 EXPLICIT_UNION = True +258 +259 def array_sql(self, expression: exp.Array) -> str: +260 first_arg = seq_get(expression.expressions, 0) +261 if isinstance(first_arg, exp.Subqueryable): +262 return f"ARRAY{self.wrap(self.sql(first_arg))}" 263 -264 def transaction_sql(self, *_) -> str: -265 return "BEGIN TRANSACTION" -266 -267 def commit_sql(self, *_) -> str: -268 return "COMMIT TRANSACTION" -269 -270 def rollback_sql(self, *_) -> str: -271 return "ROLLBACK TRANSACTION" -272 -273 def in_unnest_op(self, expression: exp.Unnest) -> str: -274 return self.sql(expression) -275 -276 def except_op(self, expression: exp.Except) -> str: -277 if not expression.args.get("distinct", False): -278 self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery") -279 return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}" -280 -281 def intersect_op(self, expression: exp.Intersect) -> str: -282 if not expression.args.get("distinct", False): -283 self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery") -284 return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}" +264 return inline_array_sql(self, expression) +265 +266 def transaction_sql(self, *_) -> str: +267 return "BEGIN TRANSACTION" +268 +269 def commit_sql(self, *_) -> str: +270 return "COMMIT TRANSACTION" +271 +272 def rollback_sql(self, *_) -> str: +273 return "ROLLBACK TRANSACTION" +274 +275 def in_unnest_op(self, expression: exp.Unnest) -> str: +276 return self.sql(expression) +277 +278 def except_op(self, expression: exp.Except) -> str: +279 if not expression.args.get("distinct", False): +280 self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery") +281 return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}" +282 +283 def intersect_op(self, expression: exp.Intersect) -> str: +284 if not expression.args.get("distinct", False): +285 self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery") +286 return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
@@ -400,172 +402,181 @@
-
120class BigQuery(Dialect):
-121    unnest_column_only = True
-122    time_mapping = {
-123        "%M": "%-M",
-124        "%d": "%-d",
-125        "%m": "%-m",
-126        "%y": "%-y",
-127        "%H": "%-H",
-128        "%I": "%-I",
-129        "%S": "%-S",
-130        "%j": "%-j",
-131    }
-132
-133    class Tokenizer(tokens.Tokenizer):
-134        QUOTES = [
-135            (prefix + quote, quote) if prefix else quote
-136            for quote in ["'", '"', '"""', "'''"]
-137            for prefix in ["", "r", "R"]
-138        ]
-139        COMMENTS = ["--", "#", ("/*", "*/")]
-140        IDENTIFIERS = ["`"]
-141        STRING_ESCAPES = ["\\"]
-142        HEX_STRINGS = [("0x", ""), ("0X", "")]
-143
-144        KEYWORDS = {
-145            **tokens.Tokenizer.KEYWORDS,
-146            "BEGIN": TokenType.COMMAND,
-147            "BEGIN TRANSACTION": TokenType.BEGIN,
-148            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
-149            "CURRENT_TIME": TokenType.CURRENT_TIME,
-150            "DECLARE": TokenType.COMMAND,
-151            "GEOGRAPHY": TokenType.GEOGRAPHY,
-152            "FLOAT64": TokenType.DOUBLE,
-153            "INT64": TokenType.BIGINT,
-154            "NOT DETERMINISTIC": TokenType.VOLATILE,
-155            "UNKNOWN": TokenType.NULL,
-156        }
-157        KEYWORDS.pop("DIV")
-158
-159    class Parser(parser.Parser):
-160        FUNCTIONS = {
-161            **parser.Parser.FUNCTIONS,  # type: ignore
-162            "DATE_TRUNC": _date_trunc,
-163            "DATE_ADD": _date_add(exp.DateAdd),
-164            "DATETIME_ADD": _date_add(exp.DatetimeAdd),
-165            "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)),
-166            "REGEXP_CONTAINS": exp.RegexpLike.from_arg_list,
-167            "TIME_ADD": _date_add(exp.TimeAdd),
-168            "TIMESTAMP_ADD": _date_add(exp.TimestampAdd),
-169            "DATE_SUB": _date_add(exp.DateSub),
-170            "DATETIME_SUB": _date_add(exp.DatetimeSub),
-171            "TIME_SUB": _date_add(exp.TimeSub),
-172            "TIMESTAMP_SUB": _date_add(exp.TimestampSub),
-173            "PARSE_TIMESTAMP": lambda args: exp.StrToTime(
-174                this=seq_get(args, 1), format=seq_get(args, 0)
-175            ),
-176        }
-177
-178        FUNCTION_PARSERS = {
-179            **parser.Parser.FUNCTION_PARSERS,  # type: ignore
-180            "ARRAY": lambda self: self.expression(exp.Array, expressions=[self._parse_statement()]),
-181        }
-182        FUNCTION_PARSERS.pop("TRIM")
-183
-184        NO_PAREN_FUNCTIONS = {
-185            **parser.Parser.NO_PAREN_FUNCTIONS,  # type: ignore
-186            TokenType.CURRENT_DATETIME: exp.CurrentDatetime,
-187            TokenType.CURRENT_TIME: exp.CurrentTime,
-188        }
-189
-190        NESTED_TYPE_TOKENS = {
-191            *parser.Parser.NESTED_TYPE_TOKENS,  # type: ignore
-192            TokenType.TABLE,
-193        }
-194
-195        ID_VAR_TOKENS = {
-196            *parser.Parser.ID_VAR_TOKENS,  # type: ignore
-197            TokenType.VALUES,
-198        }
-199
-200        PROPERTY_PARSERS = {
-201            **parser.Parser.PROPERTY_PARSERS,  # type: ignore
-202            "NOT DETERMINISTIC": lambda self: self.expression(
-203                exp.VolatilityProperty, this=exp.Literal.string("VOLATILE")
-204            ),
-205        }
-206
-207    class Generator(generator.Generator):
-208        TRANSFORMS = {
-209            **generator.Generator.TRANSFORMS,  # type: ignore
-210            **transforms.REMOVE_PRECISION_PARAMETERIZED_TYPES,  # type: ignore
-211            exp.ArraySize: rename_func("ARRAY_LENGTH"),
-212            exp.DateAdd: _date_add_sql("DATE", "ADD"),
-213            exp.DateSub: _date_add_sql("DATE", "SUB"),
-214            exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"),
-215            exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"),
-216            exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})",
-217            exp.DateStrToDate: datestrtodate_sql,
-218            exp.GroupConcat: rename_func("STRING_AGG"),
-219            exp.ILike: no_ilike_sql,
-220            exp.IntDiv: rename_func("DIV"),
-221            exp.Select: transforms.preprocess(
-222                [_unqualify_unnest], transforms.delegate("select_sql")
-223            ),
-224            exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})",
-225            exp.TimeAdd: _date_add_sql("TIME", "ADD"),
-226            exp.TimeSub: _date_add_sql("TIME", "SUB"),
-227            exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"),
-228            exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"),
-229            exp.TimeStrToTime: timestrtotime_sql,
-230            exp.VariancePop: rename_func("VAR_POP"),
-231            exp.Values: _derived_table_values_to_unnest,
-232            exp.ReturnsProperty: _returnsproperty_sql,
-233            exp.Create: _create_sql,
-234            exp.Trim: lambda self, e: f"TRIM({self.format_args(e.this, e.expression)})",
-235            exp.VolatilityProperty: lambda self, e: f"DETERMINISTIC"
-236            if e.name == "IMMUTABLE"
-237            else "NOT DETERMINISTIC",
-238            exp.RegexpLike: rename_func("REGEXP_CONTAINS"),
-239        }
-240
-241        TYPE_MAPPING = {
-242            **generator.Generator.TYPE_MAPPING,  # type: ignore
-243            exp.DataType.Type.TINYINT: "INT64",
-244            exp.DataType.Type.SMALLINT: "INT64",
-245            exp.DataType.Type.INT: "INT64",
-246            exp.DataType.Type.BIGINT: "INT64",
-247            exp.DataType.Type.DECIMAL: "NUMERIC",
-248            exp.DataType.Type.FLOAT: "FLOAT64",
-249            exp.DataType.Type.DOUBLE: "FLOAT64",
-250            exp.DataType.Type.BOOLEAN: "BOOL",
-251            exp.DataType.Type.TEXT: "STRING",
-252            exp.DataType.Type.VARCHAR: "STRING",
-253            exp.DataType.Type.NVARCHAR: "STRING",
-254        }
-255
-256        EXPLICIT_UNION = True
+            
113class BigQuery(Dialect):
+114    unnest_column_only = True
+115    time_mapping = {
+116        "%M": "%-M",
+117        "%d": "%-d",
+118        "%m": "%-m",
+119        "%y": "%-y",
+120        "%H": "%-H",
+121        "%I": "%-I",
+122        "%S": "%-S",
+123        "%j": "%-j",
+124    }
+125
+126    class Tokenizer(tokens.Tokenizer):
+127        QUOTES = [
+128            (prefix + quote, quote) if prefix else quote
+129            for quote in ["'", '"', '"""', "'''"]
+130            for prefix in ["", "r", "R"]
+131        ]
+132        COMMENTS = ["--", "#", ("/*", "*/")]
+133        IDENTIFIERS = ["`"]
+134        STRING_ESCAPES = ["\\"]
+135        HEX_STRINGS = [("0x", ""), ("0X", "")]
+136
+137        KEYWORDS = {
+138            **tokens.Tokenizer.KEYWORDS,
+139            "BEGIN": TokenType.COMMAND,
+140            "BEGIN TRANSACTION": TokenType.BEGIN,
+141            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
+142            "CURRENT_TIME": TokenType.CURRENT_TIME,
+143            "DECLARE": TokenType.COMMAND,
+144            "GEOGRAPHY": TokenType.GEOGRAPHY,
+145            "FLOAT64": TokenType.DOUBLE,
+146            "INT64": TokenType.BIGINT,
+147            "NOT DETERMINISTIC": TokenType.VOLATILE,
+148            "UNKNOWN": TokenType.NULL,
+149        }
+150        KEYWORDS.pop("DIV")
+151
+152    class Parser(parser.Parser):
+153        FUNCTIONS = {
+154            **parser.Parser.FUNCTIONS,  # type: ignore
+155            "DATE_TRUNC": lambda args: exp.DateTrunc(
+156                unit=exp.Literal.string(seq_get(args, 1).name),  # type: ignore
+157                this=seq_get(args, 0),
+158            ),
+159            "DATE_ADD": _date_add(exp.DateAdd),
+160            "DATETIME_ADD": _date_add(exp.DatetimeAdd),
+161            "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)),
+162            "REGEXP_CONTAINS": exp.RegexpLike.from_arg_list,
+163            "TIME_ADD": _date_add(exp.TimeAdd),
+164            "TIMESTAMP_ADD": _date_add(exp.TimestampAdd),
+165            "DATE_SUB": _date_add(exp.DateSub),
+166            "DATETIME_SUB": _date_add(exp.DatetimeSub),
+167            "TIME_SUB": _date_add(exp.TimeSub),
+168            "TIMESTAMP_SUB": _date_add(exp.TimestampSub),
+169            "PARSE_TIMESTAMP": lambda args: exp.StrToTime(
+170                this=seq_get(args, 1), format=seq_get(args, 0)
+171            ),
+172        }
+173
+174        FUNCTION_PARSERS = {
+175            **parser.Parser.FUNCTION_PARSERS,  # type: ignore
+176            "ARRAY": lambda self: self.expression(exp.Array, expressions=[self._parse_statement()]),
+177        }
+178        FUNCTION_PARSERS.pop("TRIM")
+179
+180        NO_PAREN_FUNCTIONS = {
+181            **parser.Parser.NO_PAREN_FUNCTIONS,  # type: ignore
+182            TokenType.CURRENT_DATETIME: exp.CurrentDatetime,
+183            TokenType.CURRENT_TIME: exp.CurrentTime,
+184        }
+185
+186        NESTED_TYPE_TOKENS = {
+187            *parser.Parser.NESTED_TYPE_TOKENS,  # type: ignore
+188            TokenType.TABLE,
+189        }
+190
+191        ID_VAR_TOKENS = {
+192            *parser.Parser.ID_VAR_TOKENS,  # type: ignore
+193            TokenType.VALUES,
+194        }
+195
+196        PROPERTY_PARSERS = {
+197            **parser.Parser.PROPERTY_PARSERS,  # type: ignore
+198            "NOT DETERMINISTIC": lambda self: self.expression(
+199                exp.VolatilityProperty, this=exp.Literal.string("VOLATILE")
+200            ),
+201        }
+202
+203    class Generator(generator.Generator):
+204        TRANSFORMS = {
+205            **generator.Generator.TRANSFORMS,  # type: ignore
+206            **transforms.REMOVE_PRECISION_PARAMETERIZED_TYPES,  # type: ignore
+207            exp.ArraySize: rename_func("ARRAY_LENGTH"),
+208            exp.DateAdd: _date_add_sql("DATE", "ADD"),
+209            exp.DateSub: _date_add_sql("DATE", "SUB"),
+210            exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"),
+211            exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"),
+212            exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})",
+213            exp.DateStrToDate: datestrtodate_sql,
+214            exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, e.text("unit")),
+215            exp.GroupConcat: rename_func("STRING_AGG"),
+216            exp.ILike: no_ilike_sql,
+217            exp.IntDiv: rename_func("DIV"),
+218            exp.Select: transforms.preprocess(
+219                [_unqualify_unnest], transforms.delegate("select_sql")
+220            ),
+221            exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})",
+222            exp.TimeAdd: _date_add_sql("TIME", "ADD"),
+223            exp.TimeSub: _date_add_sql("TIME", "SUB"),
+224            exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"),
+225            exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"),
+226            exp.TimeStrToTime: timestrtotime_sql,
+227            exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}",
+228            exp.VariancePop: rename_func("VAR_POP"),
+229            exp.Values: _derived_table_values_to_unnest,
+230            exp.ReturnsProperty: _returnsproperty_sql,
+231            exp.Create: _create_sql,
+232            exp.Trim: lambda self, e: self.func(f"TRIM", e.this, e.expression),
+233            exp.VolatilityProperty: lambda self, e: f"DETERMINISTIC"
+234            if e.name == "IMMUTABLE"
+235            else "NOT DETERMINISTIC",
+236            exp.RegexpLike: rename_func("REGEXP_CONTAINS"),
+237        }
+238
+239        TYPE_MAPPING = {
+240            **generator.Generator.TYPE_MAPPING,  # type: ignore
+241            exp.DataType.Type.TINYINT: "INT64",
+242            exp.DataType.Type.SMALLINT: "INT64",
+243            exp.DataType.Type.INT: "INT64",
+244            exp.DataType.Type.BIGINT: "INT64",
+245            exp.DataType.Type.DECIMAL: "NUMERIC",
+246            exp.DataType.Type.FLOAT: "FLOAT64",
+247            exp.DataType.Type.DOUBLE: "FLOAT64",
+248            exp.DataType.Type.BOOLEAN: "BOOL",
+249            exp.DataType.Type.TEXT: "STRING",
+250            exp.DataType.Type.VARCHAR: "STRING",
+251            exp.DataType.Type.NVARCHAR: "STRING",
+252        }
+253        PROPERTIES_LOCATION = {
+254            **generator.Generator.PROPERTIES_LOCATION,  # type: ignore
+255            exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA,
+256        }
 257
-258        def array_sql(self, expression: exp.Array) -> str:
-259            first_arg = seq_get(expression.expressions, 0)
-260            if isinstance(first_arg, exp.Subqueryable):
-261                return f"ARRAY{self.wrap(self.sql(first_arg))}"
-262
-263            return inline_array_sql(self, expression)
+258        EXPLICIT_UNION = True
+259
+260        def array_sql(self, expression: exp.Array) -> str:
+261            first_arg = seq_get(expression.expressions, 0)
+262            if isinstance(first_arg, exp.Subqueryable):
+263                return f"ARRAY{self.wrap(self.sql(first_arg))}"
 264
-265        def transaction_sql(self, *_) -> str:
-266            return "BEGIN TRANSACTION"
-267
-268        def commit_sql(self, *_) -> str:
-269            return "COMMIT TRANSACTION"
-270
-271        def rollback_sql(self, *_) -> str:
-272            return "ROLLBACK TRANSACTION"
-273
-274        def in_unnest_op(self, expression: exp.Unnest) -> str:
-275            return self.sql(expression)
-276
-277        def except_op(self, expression: exp.Except) -> str:
-278            if not expression.args.get("distinct", False):
-279                self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery")
-280            return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
-281
-282        def intersect_op(self, expression: exp.Intersect) -> str:
-283            if not expression.args.get("distinct", False):
-284                self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery")
-285            return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
+265            return inline_array_sql(self, expression)
+266
+267        def transaction_sql(self, *_) -> str:
+268            return "BEGIN TRANSACTION"
+269
+270        def commit_sql(self, *_) -> str:
+271            return "COMMIT TRANSACTION"
+272
+273        def rollback_sql(self, *_) -> str:
+274            return "ROLLBACK TRANSACTION"
+275
+276        def in_unnest_op(self, expression: exp.Unnest) -> str:
+277            return self.sql(expression)
+278
+279        def except_op(self, expression: exp.Except) -> str:
+280            if not expression.args.get("distinct", False):
+281                self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery")
+282            return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
+283
+284        def intersect_op(self, expression: exp.Intersect) -> str:
+285            if not expression.args.get("distinct", False):
+286                self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery")
+287            return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
 
@@ -611,31 +622,31 @@
-
133    class Tokenizer(tokens.Tokenizer):
-134        QUOTES = [
-135            (prefix + quote, quote) if prefix else quote
-136            for quote in ["'", '"', '"""', "'''"]
-137            for prefix in ["", "r", "R"]
-138        ]
-139        COMMENTS = ["--", "#", ("/*", "*/")]
-140        IDENTIFIERS = ["`"]
-141        STRING_ESCAPES = ["\\"]
-142        HEX_STRINGS = [("0x", ""), ("0X", "")]
-143
-144        KEYWORDS = {
-145            **tokens.Tokenizer.KEYWORDS,
-146            "BEGIN": TokenType.COMMAND,
-147            "BEGIN TRANSACTION": TokenType.BEGIN,
-148            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
-149            "CURRENT_TIME": TokenType.CURRENT_TIME,
-150            "DECLARE": TokenType.COMMAND,
-151            "GEOGRAPHY": TokenType.GEOGRAPHY,
-152            "FLOAT64": TokenType.DOUBLE,
-153            "INT64": TokenType.BIGINT,
-154            "NOT DETERMINISTIC": TokenType.VOLATILE,
-155            "UNKNOWN": TokenType.NULL,
-156        }
-157        KEYWORDS.pop("DIV")
+            
126    class Tokenizer(tokens.Tokenizer):
+127        QUOTES = [
+128            (prefix + quote, quote) if prefix else quote
+129            for quote in ["'", '"', '"""', "'''"]
+130            for prefix in ["", "r", "R"]
+131        ]
+132        COMMENTS = ["--", "#", ("/*", "*/")]
+133        IDENTIFIERS = ["`"]
+134        STRING_ESCAPES = ["\\"]
+135        HEX_STRINGS = [("0x", ""), ("0X", "")]
+136
+137        KEYWORDS = {
+138            **tokens.Tokenizer.KEYWORDS,
+139            "BEGIN": TokenType.COMMAND,
+140            "BEGIN TRANSACTION": TokenType.BEGIN,
+141            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
+142            "CURRENT_TIME": TokenType.CURRENT_TIME,
+143            "DECLARE": TokenType.COMMAND,
+144            "GEOGRAPHY": TokenType.GEOGRAPHY,
+145            "FLOAT64": TokenType.DOUBLE,
+146            "INT64": TokenType.BIGINT,
+147            "NOT DETERMINISTIC": TokenType.VOLATILE,
+148            "UNKNOWN": TokenType.NULL,
+149        }
+150        KEYWORDS.pop("DIV")
 
@@ -664,53 +675,56 @@
-
159    class Parser(parser.Parser):
-160        FUNCTIONS = {
-161            **parser.Parser.FUNCTIONS,  # type: ignore
-162            "DATE_TRUNC": _date_trunc,
-163            "DATE_ADD": _date_add(exp.DateAdd),
-164            "DATETIME_ADD": _date_add(exp.DatetimeAdd),
-165            "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)),
-166            "REGEXP_CONTAINS": exp.RegexpLike.from_arg_list,
-167            "TIME_ADD": _date_add(exp.TimeAdd),
-168            "TIMESTAMP_ADD": _date_add(exp.TimestampAdd),
-169            "DATE_SUB": _date_add(exp.DateSub),
-170            "DATETIME_SUB": _date_add(exp.DatetimeSub),
-171            "TIME_SUB": _date_add(exp.TimeSub),
-172            "TIMESTAMP_SUB": _date_add(exp.TimestampSub),
-173            "PARSE_TIMESTAMP": lambda args: exp.StrToTime(
-174                this=seq_get(args, 1), format=seq_get(args, 0)
-175            ),
-176        }
-177
-178        FUNCTION_PARSERS = {
-179            **parser.Parser.FUNCTION_PARSERS,  # type: ignore
-180            "ARRAY": lambda self: self.expression(exp.Array, expressions=[self._parse_statement()]),
-181        }
-182        FUNCTION_PARSERS.pop("TRIM")
-183
-184        NO_PAREN_FUNCTIONS = {
-185            **parser.Parser.NO_PAREN_FUNCTIONS,  # type: ignore
-186            TokenType.CURRENT_DATETIME: exp.CurrentDatetime,
-187            TokenType.CURRENT_TIME: exp.CurrentTime,
-188        }
-189
-190        NESTED_TYPE_TOKENS = {
-191            *parser.Parser.NESTED_TYPE_TOKENS,  # type: ignore
-192            TokenType.TABLE,
-193        }
-194
-195        ID_VAR_TOKENS = {
-196            *parser.Parser.ID_VAR_TOKENS,  # type: ignore
-197            TokenType.VALUES,
-198        }
-199
-200        PROPERTY_PARSERS = {
-201            **parser.Parser.PROPERTY_PARSERS,  # type: ignore
-202            "NOT DETERMINISTIC": lambda self: self.expression(
-203                exp.VolatilityProperty, this=exp.Literal.string("VOLATILE")
-204            ),
-205        }
+            
152    class Parser(parser.Parser):
+153        FUNCTIONS = {
+154            **parser.Parser.FUNCTIONS,  # type: ignore
+155            "DATE_TRUNC": lambda args: exp.DateTrunc(
+156                unit=exp.Literal.string(seq_get(args, 1).name),  # type: ignore
+157                this=seq_get(args, 0),
+158            ),
+159            "DATE_ADD": _date_add(exp.DateAdd),
+160            "DATETIME_ADD": _date_add(exp.DatetimeAdd),
+161            "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)),
+162            "REGEXP_CONTAINS": exp.RegexpLike.from_arg_list,
+163            "TIME_ADD": _date_add(exp.TimeAdd),
+164            "TIMESTAMP_ADD": _date_add(exp.TimestampAdd),
+165            "DATE_SUB": _date_add(exp.DateSub),
+166            "DATETIME_SUB": _date_add(exp.DatetimeSub),
+167            "TIME_SUB": _date_add(exp.TimeSub),
+168            "TIMESTAMP_SUB": _date_add(exp.TimestampSub),
+169            "PARSE_TIMESTAMP": lambda args: exp.StrToTime(
+170                this=seq_get(args, 1), format=seq_get(args, 0)
+171            ),
+172        }
+173
+174        FUNCTION_PARSERS = {
+175            **parser.Parser.FUNCTION_PARSERS,  # type: ignore
+176            "ARRAY": lambda self: self.expression(exp.Array, expressions=[self._parse_statement()]),
+177        }
+178        FUNCTION_PARSERS.pop("TRIM")
+179
+180        NO_PAREN_FUNCTIONS = {
+181            **parser.Parser.NO_PAREN_FUNCTIONS,  # type: ignore
+182            TokenType.CURRENT_DATETIME: exp.CurrentDatetime,
+183            TokenType.CURRENT_TIME: exp.CurrentTime,
+184        }
+185
+186        NESTED_TYPE_TOKENS = {
+187            *parser.Parser.NESTED_TYPE_TOKENS,  # type: ignore
+188            TokenType.TABLE,
+189        }
+190
+191        ID_VAR_TOKENS = {
+192            *parser.Parser.ID_VAR_TOKENS,  # type: ignore
+193            TokenType.VALUES,
+194        }
+195
+196        PROPERTY_PARSERS = {
+197            **parser.Parser.PROPERTY_PARSERS,  # type: ignore
+198            "NOT DETERMINISTIC": lambda self: self.expression(
+199                exp.VolatilityProperty, this=exp.Literal.string("VOLATILE")
+200            ),
+201        }
 
@@ -767,85 +781,91 @@ Default: "nulls_are_small"
-
207    class Generator(generator.Generator):
-208        TRANSFORMS = {
-209            **generator.Generator.TRANSFORMS,  # type: ignore
-210            **transforms.REMOVE_PRECISION_PARAMETERIZED_TYPES,  # type: ignore
-211            exp.ArraySize: rename_func("ARRAY_LENGTH"),
-212            exp.DateAdd: _date_add_sql("DATE", "ADD"),
-213            exp.DateSub: _date_add_sql("DATE", "SUB"),
-214            exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"),
-215            exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"),
-216            exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})",
-217            exp.DateStrToDate: datestrtodate_sql,
-218            exp.GroupConcat: rename_func("STRING_AGG"),
-219            exp.ILike: no_ilike_sql,
-220            exp.IntDiv: rename_func("DIV"),
-221            exp.Select: transforms.preprocess(
-222                [_unqualify_unnest], transforms.delegate("select_sql")
-223            ),
-224            exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})",
-225            exp.TimeAdd: _date_add_sql("TIME", "ADD"),
-226            exp.TimeSub: _date_add_sql("TIME", "SUB"),
-227            exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"),
-228            exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"),
-229            exp.TimeStrToTime: timestrtotime_sql,
-230            exp.VariancePop: rename_func("VAR_POP"),
-231            exp.Values: _derived_table_values_to_unnest,
-232            exp.ReturnsProperty: _returnsproperty_sql,
-233            exp.Create: _create_sql,
-234            exp.Trim: lambda self, e: f"TRIM({self.format_args(e.this, e.expression)})",
-235            exp.VolatilityProperty: lambda self, e: f"DETERMINISTIC"
-236            if e.name == "IMMUTABLE"
-237            else "NOT DETERMINISTIC",
-238            exp.RegexpLike: rename_func("REGEXP_CONTAINS"),
-239        }
-240
-241        TYPE_MAPPING = {
-242            **generator.Generator.TYPE_MAPPING,  # type: ignore
-243            exp.DataType.Type.TINYINT: "INT64",
-244            exp.DataType.Type.SMALLINT: "INT64",
-245            exp.DataType.Type.INT: "INT64",
-246            exp.DataType.Type.BIGINT: "INT64",
-247            exp.DataType.Type.DECIMAL: "NUMERIC",
-248            exp.DataType.Type.FLOAT: "FLOAT64",
-249            exp.DataType.Type.DOUBLE: "FLOAT64",
-250            exp.DataType.Type.BOOLEAN: "BOOL",
-251            exp.DataType.Type.TEXT: "STRING",
-252            exp.DataType.Type.VARCHAR: "STRING",
-253            exp.DataType.Type.NVARCHAR: "STRING",
-254        }
-255
-256        EXPLICIT_UNION = True
+            
203    class Generator(generator.Generator):
+204        TRANSFORMS = {
+205            **generator.Generator.TRANSFORMS,  # type: ignore
+206            **transforms.REMOVE_PRECISION_PARAMETERIZED_TYPES,  # type: ignore
+207            exp.ArraySize: rename_func("ARRAY_LENGTH"),
+208            exp.DateAdd: _date_add_sql("DATE", "ADD"),
+209            exp.DateSub: _date_add_sql("DATE", "SUB"),
+210            exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"),
+211            exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"),
+212            exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})",
+213            exp.DateStrToDate: datestrtodate_sql,
+214            exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, e.text("unit")),
+215            exp.GroupConcat: rename_func("STRING_AGG"),
+216            exp.ILike: no_ilike_sql,
+217            exp.IntDiv: rename_func("DIV"),
+218            exp.Select: transforms.preprocess(
+219                [_unqualify_unnest], transforms.delegate("select_sql")
+220            ),
+221            exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})",
+222            exp.TimeAdd: _date_add_sql("TIME", "ADD"),
+223            exp.TimeSub: _date_add_sql("TIME", "SUB"),
+224            exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"),
+225            exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"),
+226            exp.TimeStrToTime: timestrtotime_sql,
+227            exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}",
+228            exp.VariancePop: rename_func("VAR_POP"),
+229            exp.Values: _derived_table_values_to_unnest,
+230            exp.ReturnsProperty: _returnsproperty_sql,
+231            exp.Create: _create_sql,
+232            exp.Trim: lambda self, e: self.func(f"TRIM", e.this, e.expression),
+233            exp.VolatilityProperty: lambda self, e: f"DETERMINISTIC"
+234            if e.name == "IMMUTABLE"
+235            else "NOT DETERMINISTIC",
+236            exp.RegexpLike: rename_func("REGEXP_CONTAINS"),
+237        }
+238
+239        TYPE_MAPPING = {
+240            **generator.Generator.TYPE_MAPPING,  # type: ignore
+241            exp.DataType.Type.TINYINT: "INT64",
+242            exp.DataType.Type.SMALLINT: "INT64",
+243            exp.DataType.Type.INT: "INT64",
+244            exp.DataType.Type.BIGINT: "INT64",
+245            exp.DataType.Type.DECIMAL: "NUMERIC",
+246            exp.DataType.Type.FLOAT: "FLOAT64",
+247            exp.DataType.Type.DOUBLE: "FLOAT64",
+248            exp.DataType.Type.BOOLEAN: "BOOL",
+249            exp.DataType.Type.TEXT: "STRING",
+250            exp.DataType.Type.VARCHAR: "STRING",
+251            exp.DataType.Type.NVARCHAR: "STRING",
+252        }
+253        PROPERTIES_LOCATION = {
+254            **generator.Generator.PROPERTIES_LOCATION,  # type: ignore
+255            exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA,
+256        }
 257
-258        def array_sql(self, expression: exp.Array) -> str:
-259            first_arg = seq_get(expression.expressions, 0)
-260            if isinstance(first_arg, exp.Subqueryable):
-261                return f"ARRAY{self.wrap(self.sql(first_arg))}"
-262
-263            return inline_array_sql(self, expression)
+258        EXPLICIT_UNION = True
+259
+260        def array_sql(self, expression: exp.Array) -> str:
+261            first_arg = seq_get(expression.expressions, 0)
+262            if isinstance(first_arg, exp.Subqueryable):
+263                return f"ARRAY{self.wrap(self.sql(first_arg))}"
 264
-265        def transaction_sql(self, *_) -> str:
-266            return "BEGIN TRANSACTION"
-267
-268        def commit_sql(self, *_) -> str:
-269            return "COMMIT TRANSACTION"
-270
-271        def rollback_sql(self, *_) -> str:
-272            return "ROLLBACK TRANSACTION"
-273
-274        def in_unnest_op(self, expression: exp.Unnest) -> str:
-275            return self.sql(expression)
-276
-277        def except_op(self, expression: exp.Except) -> str:
-278            if not expression.args.get("distinct", False):
-279                self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery")
-280            return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
-281
-282        def intersect_op(self, expression: exp.Intersect) -> str:
-283            if not expression.args.get("distinct", False):
-284                self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery")
-285            return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
+265            return inline_array_sql(self, expression)
+266
+267        def transaction_sql(self, *_) -> str:
+268            return "BEGIN TRANSACTION"
+269
+270        def commit_sql(self, *_) -> str:
+271            return "COMMIT TRANSACTION"
+272
+273        def rollback_sql(self, *_) -> str:
+274            return "ROLLBACK TRANSACTION"
+275
+276        def in_unnest_op(self, expression: exp.Unnest) -> str:
+277            return self.sql(expression)
+278
+279        def except_op(self, expression: exp.Except) -> str:
+280            if not expression.args.get("distinct", False):
+281                self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery")
+282            return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
+283
+284        def intersect_op(self, expression: exp.Intersect) -> str:
+285            if not expression.args.get("distinct", False):
+286                self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery")
+287            return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
 
@@ -905,12 +925,12 @@ Default: True
-
258        def array_sql(self, expression: exp.Array) -> str:
-259            first_arg = seq_get(expression.expressions, 0)
-260            if isinstance(first_arg, exp.Subqueryable):
-261                return f"ARRAY{self.wrap(self.sql(first_arg))}"
-262
-263            return inline_array_sql(self, expression)
+            
260        def array_sql(self, expression: exp.Array) -> str:
+261            first_arg = seq_get(expression.expressions, 0)
+262            if isinstance(first_arg, exp.Subqueryable):
+263                return f"ARRAY{self.wrap(self.sql(first_arg))}"
+264
+265            return inline_array_sql(self, expression)
 
@@ -928,8 +948,8 @@ Default: True
-
265        def transaction_sql(self, *_) -> str:
-266            return "BEGIN TRANSACTION"
+            
267        def transaction_sql(self, *_) -> str:
+268            return "BEGIN TRANSACTION"
 
@@ -947,8 +967,8 @@ Default: True
-
268        def commit_sql(self, *_) -> str:
-269            return "COMMIT TRANSACTION"
+            
270        def commit_sql(self, *_) -> str:
+271            return "COMMIT TRANSACTION"
 
@@ -966,8 +986,8 @@ Default: True
-
271        def rollback_sql(self, *_) -> str:
-272            return "ROLLBACK TRANSACTION"
+            
273        def rollback_sql(self, *_) -> str:
+274            return "ROLLBACK TRANSACTION"
 
@@ -985,8 +1005,8 @@ Default: True
-
274        def in_unnest_op(self, expression: exp.Unnest) -> str:
-275            return self.sql(expression)
+            
276        def in_unnest_op(self, expression: exp.Unnest) -> str:
+277            return self.sql(expression)
 
@@ -1004,10 +1024,10 @@ Default: True
-
277        def except_op(self, expression: exp.Except) -> str:
-278            if not expression.args.get("distinct", False):
-279                self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery")
-280            return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
+            
279        def except_op(self, expression: exp.Except) -> str:
+280            if not expression.args.get("distinct", False):
+281                self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery")
+282            return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
 
@@ -1025,10 +1045,10 @@ Default: True
-
282        def intersect_op(self, expression: exp.Intersect) -> str:
-283            if not expression.args.get("distinct", False):
-284                self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery")
-285            return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
+            
284        def intersect_op(self, expression: exp.Intersect) -> str:
+285            if not expression.args.get("distinct", False):
+286                self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery")
+287            return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
 
@@ -1058,11 +1078,6 @@ Default: True
columndef_sql
columnconstraint_sql
autoincrementcolumnconstraint_sql
-
checkcolumnconstraint_sql
-
commentcolumnconstraint_sql
-
collatecolumnconstraint_sql
-
encodecolumnconstraint_sql
-
defaultcolumnconstraint_sql
generatedasidentitycolumnconstraint_sql
notnullcolumnconstraint_sql
primarykeycolumnconstraint_sql
@@ -1103,6 +1118,7 @@ Default: True
datablocksizeproperty_sql
blockcompressionproperty_sql
isolatedloadingproperty_sql
+
lockingproperty_sql
insert_sql
intersect_sql
introducer_sql
@@ -1228,6 +1244,7 @@ Default: True
use_sql
binary
function_fallback_sql
+
func
format_args
text_width
format_time
@@ -1238,7 +1255,6 @@ Default: True
tag_sql
token_sql
userdefinedfunction_sql
-
userdefinedfunctionkwarg_sql
joinhint_sql
kwarg_sql
when_sql
diff --git a/docs/sqlglot/dialects/clickhouse.html b/docs/sqlglot/dialects/clickhouse.html index 06bc3cd..4b01cef 100644 --- a/docs/sqlglot/dialects/clickhouse.html +++ b/docs/sqlglot/dialects/clickhouse.html @@ -696,11 +696,6 @@ Default: True
columndef_sql
columnconstraint_sql
autoincrementcolumnconstraint_sql
-
checkcolumnconstraint_sql
-
commentcolumnconstraint_sql
-
collatecolumnconstraint_sql
-
encodecolumnconstraint_sql
-
defaultcolumnconstraint_sql
generatedasidentitycolumnconstraint_sql
notnullcolumnconstraint_sql
primarykeycolumnconstraint_sql
@@ -741,6 +736,7 @@ Default: True
datablocksizeproperty_sql
blockcompressionproperty_sql
isolatedloadingproperty_sql
+
lockingproperty_sql
insert_sql
intersect_sql
intersect_op
@@ -871,6 +867,7 @@ Default: True
use_sql
binary
function_fallback_sql
+
func
format_args
text_width
format_time
@@ -881,7 +878,6 @@ Default: True
tag_sql
token_sql
userdefinedfunction_sql
-
userdefinedfunctionkwarg_sql
joinhint_sql
kwarg_sql
when_sql
diff --git a/docs/sqlglot/dialects/databricks.html b/docs/sqlglot/dialects/databricks.html index 74464c8..2ad8268 100644 --- a/docs/sqlglot/dialects/databricks.html +++ b/docs/sqlglot/dialects/databricks.html @@ -48,6 +48,12 @@ +
  • + Databricks.Tokenizer +
      +
    + +
  • @@ -80,23 +86,32 @@
    4from sqlglot.dialects.dialect import parse_date_delta 5from sqlglot.dialects.spark import Spark 6from sqlglot.dialects.tsql import generate_date_delta_with_unit_sql - 7 + 7from sqlglot.tokens import TokenType 8 - 9class Databricks(Spark): -10 class Parser(Spark.Parser): -11 FUNCTIONS = { -12 **Spark.Parser.FUNCTIONS, -13 "DATEADD": parse_date_delta(exp.DateAdd), -14 "DATE_ADD": parse_date_delta(exp.DateAdd), -15 "DATEDIFF": parse_date_delta(exp.DateDiff), -16 } -17 -18 class Generator(Spark.Generator): -19 TRANSFORMS = { -20 **Spark.Generator.TRANSFORMS, # type: ignore -21 exp.DateAdd: generate_date_delta_with_unit_sql, -22 exp.DateDiff: generate_date_delta_with_unit_sql, -23 } + 9 +10class Databricks(Spark): +11 class Parser(Spark.Parser): +12 FUNCTIONS = { +13 **Spark.Parser.FUNCTIONS, +14 "DATEADD": parse_date_delta(exp.DateAdd), +15 "DATE_ADD": parse_date_delta(exp.DateAdd), +16 "DATEDIFF": parse_date_delta(exp.DateDiff), +17 } +18 +19 class Generator(Spark.Generator): +20 TRANSFORMS = { +21 **Spark.Generator.TRANSFORMS, # type: ignore +22 exp.DateAdd: generate_date_delta_with_unit_sql, +23 exp.DateDiff: generate_date_delta_with_unit_sql, +24 } +25 +26 PARAMETER_TOKEN = "$" +27 +28 class Tokenizer(Spark.Tokenizer): +29 SINGLE_TOKENS = { +30 **Spark.Tokenizer.SINGLE_TOKENS, +31 "$": TokenType.PARAMETER, +32 }
    @@ -112,21 +127,29 @@
    -
    10class Databricks(Spark):
    -11    class Parser(Spark.Parser):
    -12        FUNCTIONS = {
    -13            **Spark.Parser.FUNCTIONS,
    -14            "DATEADD": parse_date_delta(exp.DateAdd),
    -15            "DATE_ADD": parse_date_delta(exp.DateAdd),
    -16            "DATEDIFF": parse_date_delta(exp.DateDiff),
    -17        }
    -18
    -19    class Generator(Spark.Generator):
    -20        TRANSFORMS = {
    -21            **Spark.Generator.TRANSFORMS,  # type: ignore
    -22            exp.DateAdd: generate_date_delta_with_unit_sql,
    -23            exp.DateDiff: generate_date_delta_with_unit_sql,
    -24        }
    +            
    11class Databricks(Spark):
    +12    class Parser(Spark.Parser):
    +13        FUNCTIONS = {
    +14            **Spark.Parser.FUNCTIONS,
    +15            "DATEADD": parse_date_delta(exp.DateAdd),
    +16            "DATE_ADD": parse_date_delta(exp.DateAdd),
    +17            "DATEDIFF": parse_date_delta(exp.DateDiff),
    +18        }
    +19
    +20    class Generator(Spark.Generator):
    +21        TRANSFORMS = {
    +22            **Spark.Generator.TRANSFORMS,  # type: ignore
    +23            exp.DateAdd: generate_date_delta_with_unit_sql,
    +24            exp.DateDiff: generate_date_delta_with_unit_sql,
    +25        }
    +26
    +27        PARAMETER_TOKEN = "$"
    +28
    +29    class Tokenizer(Spark.Tokenizer):
    +30        SINGLE_TOKENS = {
    +31            **Spark.Tokenizer.SINGLE_TOKENS,
    +32            "$": TokenType.PARAMETER,
    +33        }
     
    @@ -147,11 +170,7 @@
    Inherited Members
    - -
    sqlglot.dialects.dialect.Dialect
    + -
    11    class Parser(Spark.Parser):
    -12        FUNCTIONS = {
    -13            **Spark.Parser.FUNCTIONS,
    -14            "DATEADD": parse_date_delta(exp.DateAdd),
    -15            "DATE_ADD": parse_date_delta(exp.DateAdd),
    -16            "DATEDIFF": parse_date_delta(exp.DateDiff),
    -17        }
    +            
    12    class Parser(Spark.Parser):
    +13        FUNCTIONS = {
    +14            **Spark.Parser.FUNCTIONS,
    +15            "DATEADD": parse_date_delta(exp.DateAdd),
    +16            "DATE_ADD": parse_date_delta(exp.DateAdd),
    +17            "DATEDIFF": parse_date_delta(exp.DateDiff),
    +18        }
     
    @@ -239,12 +258,14 @@ Default: "nulls_are_small"
    -
    19    class Generator(Spark.Generator):
    -20        TRANSFORMS = {
    -21            **Spark.Generator.TRANSFORMS,  # type: ignore
    -22            exp.DateAdd: generate_date_delta_with_unit_sql,
    -23            exp.DateDiff: generate_date_delta_with_unit_sql,
    -24        }
    +            
    20    class Generator(Spark.Generator):
    +21        TRANSFORMS = {
    +22            **Spark.Generator.TRANSFORMS,  # type: ignore
    +23            exp.DateAdd: generate_date_delta_with_unit_sql,
    +24            exp.DateDiff: generate_date_delta_with_unit_sql,
    +25        }
    +26
    +27        PARAMETER_TOKEN = "$"
     
    @@ -316,11 +337,6 @@ Default: True
    columndef_sql
    columnconstraint_sql
    autoincrementcolumnconstraint_sql
    -
    checkcolumnconstraint_sql
    -
    commentcolumnconstraint_sql
    -
    collatecolumnconstraint_sql
    -
    encodecolumnconstraint_sql
    -
    defaultcolumnconstraint_sql
    generatedasidentitycolumnconstraint_sql
    notnullcolumnconstraint_sql
    primarykeycolumnconstraint_sql
    @@ -360,6 +376,7 @@ Default: True
    datablocksizeproperty_sql
    blockcompressionproperty_sql
    isolatedloadingproperty_sql
    +
    lockingproperty_sql
    insert_sql
    intersect_sql
    intersect_op
    @@ -489,6 +506,7 @@ Default: True
    use_sql
    binary
    function_fallback_sql
    +
    func
    format_args
    text_width
    format_time
    @@ -499,7 +517,6 @@ Default: True
    tag_sql
    token_sql
    userdefinedfunction_sql
    -
    userdefinedfunctionkwarg_sql
    joinhint_sql
    kwarg_sql
    when_sql
    @@ -518,6 +535,39 @@ Default: True
    +
    + +
    + + class + Databricks.Tokenizer(sqlglot.dialects.spark.Spark.Tokenizer): + + + +
    + +
    29    class Tokenizer(Spark.Tokenizer):
    +30        SINGLE_TOKENS = {
    +31            **Spark.Tokenizer.SINGLE_TOKENS,
    +32            "$": TokenType.PARAMETER,
    +33        }
    +
    + + + + +
    +
    Inherited Members
    +
    + +
    +
    +