From cd37a3bcaced9283c20baa52837c96b524baec54 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Tue, 10 Oct 2023 10:53:14 +0200 Subject: Merging upstream version 18.11.6. Signed-off-by: Daniel Baumann --- docs/sqlglot/dialects/redshift.html | 987 ++++++++++++++++++++---------------- 1 file changed, 543 insertions(+), 444 deletions(-) (limited to 'docs/sqlglot/dialects/redshift.html') diff --git a/docs/sqlglot/dialects/redshift.html b/docs/sqlglot/dialects/redshift.html index 309924e..3f07979 100644 --- a/docs/sqlglot/dialects/redshift.html +++ b/docs/sqlglot/dialects/redshift.html @@ -39,6 +39,9 @@
  • SUPPORTS_USER_DEFINED_TYPES
  • +
  • + INDEX_OFFSET +
  • TIME_FORMAT
  • @@ -54,6 +57,9 @@
  • TOKENIZER_CLASS
  • +
  • + INDEX_OFFSET +
  • SUPPORTS_USER_DEFINED_TYPES
  • @@ -147,6 +153,9 @@
  • INVERSE_ESCAPE_SEQUENCES
  • +
  • + INDEX_OFFSET +
  • can_identify
  • @@ -299,151 +308,170 @@ 31 RESOLVES_IDENTIFIERS_AS_UPPERCASE = None 32 33 SUPPORTS_USER_DEFINED_TYPES = False - 34 - 35 TIME_FORMAT = "'YYYY-MM-DD HH:MI:SS'" - 36 TIME_MAPPING = { - 37 **Postgres.TIME_MAPPING, - 38 "MON": "%b", - 39 "HH": "%H", - 40 } - 41 - 42 class Parser(Postgres.Parser): - 43 FUNCTIONS = { - 44 **Postgres.Parser.FUNCTIONS, - 45 "ADD_MONTHS": lambda args: exp.DateAdd( - 46 this=exp.TsOrDsToDate(this=seq_get(args, 0)), - 47 expression=seq_get(args, 1), - 48 unit=exp.var("month"), - 49 ), - 50 "DATEADD": _parse_date_add, - 51 "DATE_ADD": _parse_date_add, - 52 "DATEDIFF": lambda args: exp.DateDiff( - 53 this=exp.TsOrDsToDate(this=seq_get(args, 2)), - 54 expression=exp.TsOrDsToDate(this=seq_get(args, 1)), - 55 unit=seq_get(args, 0), - 56 ), - 57 "STRTOL": exp.FromBase.from_arg_list, - 58 } - 59 - 60 def _parse_types( - 61 self, check_func: bool = False, schema: bool = False, allow_identifiers: bool = True - 62 ) -> t.Optional[exp.Expression]: - 63 this = super()._parse_types( - 64 check_func=check_func, schema=schema, allow_identifiers=allow_identifiers - 65 ) - 66 - 67 if ( - 68 isinstance(this, exp.DataType) - 69 and this.is_type("varchar") - 70 and this.expressions - 71 and this.expressions[0].this == exp.column("MAX") - 72 ): - 73 this.set("expressions", [exp.var("MAX")]) - 74 - 75 return this + 34 INDEX_OFFSET = 0 + 35 + 36 TIME_FORMAT = "'YYYY-MM-DD HH:MI:SS'" + 37 TIME_MAPPING = { + 38 **Postgres.TIME_MAPPING, + 39 "MON": "%b", + 40 "HH": "%H", + 41 } + 42 + 43 class Parser(Postgres.Parser): + 44 FUNCTIONS = { + 45 **Postgres.Parser.FUNCTIONS, + 46 "ADD_MONTHS": lambda args: exp.DateAdd( + 47 this=exp.TsOrDsToDate(this=seq_get(args, 0)), + 48 expression=seq_get(args, 1), + 49 unit=exp.var("month"), + 50 ), + 51 "DATEADD": _parse_date_add, + 52 "DATE_ADD": _parse_date_add, + 53 "DATEDIFF": lambda args: exp.DateDiff( + 54 this=exp.TsOrDsToDate(this=seq_get(args, 2)), + 55 expression=exp.TsOrDsToDate(this=seq_get(args, 1)), + 56 unit=seq_get(args, 0), + 57 ), + 58 "STRTOL": exp.FromBase.from_arg_list, + 59 } + 60 + 61 def _parse_table( + 62 self, + 63 schema: bool = False, + 64 joins: bool = False, + 65 alias_tokens: t.Optional[t.Collection[TokenType]] = None, + 66 parse_bracket: bool = False, + 67 ) -> t.Optional[exp.Expression]: + 68 # Redshift supports UNPIVOTing SUPER objects, e.g. `UNPIVOT foo.obj[0] AS val AT attr` + 69 unpivot = self._match(TokenType.UNPIVOT) + 70 table = super()._parse_table( + 71 schema=schema, + 72 joins=joins, + 73 alias_tokens=alias_tokens, + 74 parse_bracket=parse_bracket, + 75 ) 76 - 77 def _parse_convert(self, strict: bool) -> t.Optional[exp.Expression]: - 78 to = self._parse_types() - 79 self._match(TokenType.COMMA) - 80 this = self._parse_bitwise() - 81 return self.expression(exp.TryCast, this=this, to=to) - 82 - 83 class Tokenizer(Postgres.Tokenizer): - 84 BIT_STRINGS = [] - 85 HEX_STRINGS = [] - 86 STRING_ESCAPES = ["\\", "'"] - 87 - 88 KEYWORDS = { - 89 **Postgres.Tokenizer.KEYWORDS, - 90 "HLLSKETCH": TokenType.HLLSKETCH, - 91 "SUPER": TokenType.SUPER, - 92 "SYSDATE": TokenType.CURRENT_TIMESTAMP, - 93 "TOP": TokenType.TOP, - 94 "UNLOAD": TokenType.COMMAND, - 95 "VARBYTE": TokenType.VARBINARY, - 96 } - 97 - 98 # Redshift allows # to appear as a table identifier prefix - 99 SINGLE_TOKENS = Postgres.Tokenizer.SINGLE_TOKENS.copy() -100 SINGLE_TOKENS.pop("#") + 77 return self.expression(exp.Pivot, this=table, unpivot=True) if unpivot else table + 78 + 79 def _parse_types( + 80 self, check_func: bool = False, schema: bool = False, allow_identifiers: bool = True + 81 ) -> t.Optional[exp.Expression]: + 82 this = super()._parse_types( + 83 check_func=check_func, schema=schema, allow_identifiers=allow_identifiers + 84 ) + 85 + 86 if ( + 87 isinstance(this, exp.DataType) + 88 and this.is_type("varchar") + 89 and this.expressions + 90 and this.expressions[0].this == exp.column("MAX") + 91 ): + 92 this.set("expressions", [exp.var("MAX")]) + 93 + 94 return this + 95 + 96 def _parse_convert(self, strict: bool) -> t.Optional[exp.Expression]: + 97 to = self._parse_types() + 98 self._match(TokenType.COMMA) + 99 this = self._parse_bitwise() +100 return self.expression(exp.TryCast, this=this, to=to) 101 -102 class Generator(Postgres.Generator): -103 LOCKING_READS_SUPPORTED = False -104 RENAME_TABLE_WITH_DB = False -105 QUERY_HINTS = False -106 VALUES_AS_TABLE = False -107 TZ_TO_WITH_TIME_ZONE = True -108 NVL2_SUPPORTED = True -109 -110 TYPE_MAPPING = { -111 **Postgres.Generator.TYPE_MAPPING, -112 exp.DataType.Type.BINARY: "VARBYTE", -113 exp.DataType.Type.INT: "INTEGER", -114 exp.DataType.Type.TIMETZ: "TIME", -115 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", -116 exp.DataType.Type.VARBINARY: "VARBYTE", -117 } -118 -119 PROPERTIES_LOCATION = { -120 **Postgres.Generator.PROPERTIES_LOCATION, -121 exp.LikeProperty: exp.Properties.Location.POST_WITH, -122 } -123 -124 TRANSFORMS = { -125 **Postgres.Generator.TRANSFORMS, -126 exp.Concat: concat_to_dpipe_sql, -127 exp.ConcatWs: concat_ws_to_dpipe_sql, -128 exp.CurrentTimestamp: lambda self, e: "SYSDATE", -129 exp.DateAdd: lambda self, e: self.func( -130 "DATEADD", exp.var(e.text("unit") or "day"), e.expression, e.this -131 ), -132 exp.DateDiff: lambda self, e: self.func( -133 "DATEDIFF", exp.var(e.text("unit") or "day"), e.expression, e.this -134 ), -135 exp.DistKeyProperty: lambda self, e: f"DISTKEY({e.name})", -136 exp.DistStyleProperty: lambda self, e: self.naked_property(e), -137 exp.FromBase: rename_func("STRTOL"), -138 exp.JSONExtract: _json_sql, -139 exp.JSONExtractScalar: _json_sql, -140 exp.SafeConcat: concat_to_dpipe_sql, -141 exp.Select: transforms.preprocess( -142 [transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins] -143 ), -144 exp.SortKeyProperty: lambda self, e: f"{'COMPOUND ' if e.args['compound'] else ''}SORTKEY({self.format_args(*e.this)})", -145 exp.TsOrDsToDate: ts_or_ds_to_date_sql("redshift"), -146 } -147 -148 # Postgres maps exp.Pivot to no_pivot_sql, but Redshift support pivots -149 TRANSFORMS.pop(exp.Pivot) -150 -151 # Redshift uses the POW | POWER (expr1, expr2) syntax instead of expr1 ^ expr2 (postgres) -152 TRANSFORMS.pop(exp.Pow) -153 -154 # Redshift supports ANY_VALUE(..) -155 TRANSFORMS.pop(exp.AnyValue) -156 -157 RESERVED_KEYWORDS = {*Postgres.Generator.RESERVED_KEYWORDS, "snapshot", "type"} -158 -159 def with_properties(self, properties: exp.Properties) -> str: -160 """Redshift doesn't have `WITH` as part of their with_properties so we remove it""" -161 return self.properties(properties, prefix=" ", suffix="") -162 -163 def datatype_sql(self, expression: exp.DataType) -> str: -164 """ -165 Redshift converts the `TEXT` data type to `VARCHAR(255)` by default when people more generally mean -166 VARCHAR of max length which is `VARCHAR(max)` in Redshift. Therefore if we get a `TEXT` data type -167 without precision we convert it to `VARCHAR(max)` and if it does have precision then we just convert -168 `TEXT` to `VARCHAR`. -169 """ -170 if expression.is_type("text"): -171 expression = expression.copy() -172 expression.set("this", exp.DataType.Type.VARCHAR) -173 precision = expression.args.get("expressions") -174 -175 if not precision: -176 expression.append("expressions", exp.var("MAX")) +102 class Tokenizer(Postgres.Tokenizer): +103 BIT_STRINGS = [] +104 HEX_STRINGS = [] +105 STRING_ESCAPES = ["\\", "'"] +106 +107 KEYWORDS = { +108 **Postgres.Tokenizer.KEYWORDS, +109 "HLLSKETCH": TokenType.HLLSKETCH, +110 "SUPER": TokenType.SUPER, +111 "SYSDATE": TokenType.CURRENT_TIMESTAMP, +112 "TOP": TokenType.TOP, +113 "UNLOAD": TokenType.COMMAND, +114 "VARBYTE": TokenType.VARBINARY, +115 } +116 +117 # Redshift allows # to appear as a table identifier prefix +118 SINGLE_TOKENS = Postgres.Tokenizer.SINGLE_TOKENS.copy() +119 SINGLE_TOKENS.pop("#") +120 +121 class Generator(Postgres.Generator): +122 LOCKING_READS_SUPPORTED = False +123 RENAME_TABLE_WITH_DB = False +124 QUERY_HINTS = False +125 VALUES_AS_TABLE = False +126 TZ_TO_WITH_TIME_ZONE = True +127 NVL2_SUPPORTED = True +128 +129 TYPE_MAPPING = { +130 **Postgres.Generator.TYPE_MAPPING, +131 exp.DataType.Type.BINARY: "VARBYTE", +132 exp.DataType.Type.INT: "INTEGER", +133 exp.DataType.Type.TIMETZ: "TIME", +134 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", +135 exp.DataType.Type.VARBINARY: "VARBYTE", +136 } +137 +138 PROPERTIES_LOCATION = { +139 **Postgres.Generator.PROPERTIES_LOCATION, +140 exp.LikeProperty: exp.Properties.Location.POST_WITH, +141 } +142 +143 TRANSFORMS = { +144 **Postgres.Generator.TRANSFORMS, +145 exp.Concat: concat_to_dpipe_sql, +146 exp.ConcatWs: concat_ws_to_dpipe_sql, +147 exp.CurrentTimestamp: lambda self, e: "SYSDATE", +148 exp.DateAdd: lambda self, e: self.func( +149 "DATEADD", exp.var(e.text("unit") or "day"), e.expression, e.this +150 ), +151 exp.DateDiff: lambda self, e: self.func( +152 "DATEDIFF", exp.var(e.text("unit") or "day"), e.expression, e.this +153 ), +154 exp.DistKeyProperty: lambda self, e: f"DISTKEY({e.name})", +155 exp.DistStyleProperty: lambda self, e: self.naked_property(e), +156 exp.FromBase: rename_func("STRTOL"), +157 exp.JSONExtract: _json_sql, +158 exp.JSONExtractScalar: _json_sql, +159 exp.SafeConcat: concat_to_dpipe_sql, +160 exp.Select: transforms.preprocess( +161 [transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins] +162 ), +163 exp.SortKeyProperty: lambda self, e: f"{'COMPOUND ' if e.args['compound'] else ''}SORTKEY({self.format_args(*e.this)})", +164 exp.TsOrDsToDate: ts_or_ds_to_date_sql("redshift"), +165 } +166 +167 # Postgres maps exp.Pivot to no_pivot_sql, but Redshift support pivots +168 TRANSFORMS.pop(exp.Pivot) +169 +170 # Redshift uses the POW | POWER (expr1, expr2) syntax instead of expr1 ^ expr2 (postgres) +171 TRANSFORMS.pop(exp.Pow) +172 +173 # Redshift supports ANY_VALUE(..) +174 TRANSFORMS.pop(exp.AnyValue) +175 +176 RESERVED_KEYWORDS = {*Postgres.Generator.RESERVED_KEYWORDS, "snapshot", "type"} 177 -178 return super().datatype_sql(expression) +178 def with_properties(self, properties: exp.Properties) -> str: +179 """Redshift doesn't have `WITH` as part of their with_properties so we remove it""" +180 return self.properties(properties, prefix=" ", suffix="") +181 +182 def datatype_sql(self, expression: exp.DataType) -> str: +183 """ +184 Redshift converts the `TEXT` data type to `VARCHAR(255)` by default when people more generally mean +185 VARCHAR of max length which is `VARCHAR(max)` in Redshift. Therefore if we get a `TEXT` data type +186 without precision we convert it to `VARCHAR(max)` and if it does have precision then we just convert +187 `TEXT` to `VARCHAR`. +188 """ +189 if expression.is_type("text"): +190 expression = expression.copy() +191 expression.set("this", exp.DataType.Type.VARCHAR) +192 precision = expression.args.get("expressions") +193 +194 if not precision: +195 expression.append("expressions", exp.var("MAX")) +196 +197 return super().datatype_sql(expression) @@ -464,151 +492,170 @@ 32 RESOLVES_IDENTIFIERS_AS_UPPERCASE = None 33 34 SUPPORTS_USER_DEFINED_TYPES = False - 35 - 36 TIME_FORMAT = "'YYYY-MM-DD HH:MI:SS'" - 37 TIME_MAPPING = { - 38 **Postgres.TIME_MAPPING, - 39 "MON": "%b", - 40 "HH": "%H", - 41 } - 42 - 43 class Parser(Postgres.Parser): - 44 FUNCTIONS = { - 45 **Postgres.Parser.FUNCTIONS, - 46 "ADD_MONTHS": lambda args: exp.DateAdd( - 47 this=exp.TsOrDsToDate(this=seq_get(args, 0)), - 48 expression=seq_get(args, 1), - 49 unit=exp.var("month"), - 50 ), - 51 "DATEADD": _parse_date_add, - 52 "DATE_ADD": _parse_date_add, - 53 "DATEDIFF": lambda args: exp.DateDiff( - 54 this=exp.TsOrDsToDate(this=seq_get(args, 2)), - 55 expression=exp.TsOrDsToDate(this=seq_get(args, 1)), - 56 unit=seq_get(args, 0), - 57 ), - 58 "STRTOL": exp.FromBase.from_arg_list, - 59 } - 60 - 61 def _parse_types( - 62 self, check_func: bool = False, schema: bool = False, allow_identifiers: bool = True - 63 ) -> t.Optional[exp.Expression]: - 64 this = super()._parse_types( - 65 check_func=check_func, schema=schema, allow_identifiers=allow_identifiers - 66 ) - 67 - 68 if ( - 69 isinstance(this, exp.DataType) - 70 and this.is_type("varchar") - 71 and this.expressions - 72 and this.expressions[0].this == exp.column("MAX") - 73 ): - 74 this.set("expressions", [exp.var("MAX")]) - 75 - 76 return this + 35 INDEX_OFFSET = 0 + 36 + 37 TIME_FORMAT = "'YYYY-MM-DD HH:MI:SS'" + 38 TIME_MAPPING = { + 39 **Postgres.TIME_MAPPING, + 40 "MON": "%b", + 41 "HH": "%H", + 42 } + 43 + 44 class Parser(Postgres.Parser): + 45 FUNCTIONS = { + 46 **Postgres.Parser.FUNCTIONS, + 47 "ADD_MONTHS": lambda args: exp.DateAdd( + 48 this=exp.TsOrDsToDate(this=seq_get(args, 0)), + 49 expression=seq_get(args, 1), + 50 unit=exp.var("month"), + 51 ), + 52 "DATEADD": _parse_date_add, + 53 "DATE_ADD": _parse_date_add, + 54 "DATEDIFF": lambda args: exp.DateDiff( + 55 this=exp.TsOrDsToDate(this=seq_get(args, 2)), + 56 expression=exp.TsOrDsToDate(this=seq_get(args, 1)), + 57 unit=seq_get(args, 0), + 58 ), + 59 "STRTOL": exp.FromBase.from_arg_list, + 60 } + 61 + 62 def _parse_table( + 63 self, + 64 schema: bool = False, + 65 joins: bool = False, + 66 alias_tokens: t.Optional[t.Collection[TokenType]] = None, + 67 parse_bracket: bool = False, + 68 ) -> t.Optional[exp.Expression]: + 69 # Redshift supports UNPIVOTing SUPER objects, e.g. `UNPIVOT foo.obj[0] AS val AT attr` + 70 unpivot = self._match(TokenType.UNPIVOT) + 71 table = super()._parse_table( + 72 schema=schema, + 73 joins=joins, + 74 alias_tokens=alias_tokens, + 75 parse_bracket=parse_bracket, + 76 ) 77 - 78 def _parse_convert(self, strict: bool) -> t.Optional[exp.Expression]: - 79 to = self._parse_types() - 80 self._match(TokenType.COMMA) - 81 this = self._parse_bitwise() - 82 return self.expression(exp.TryCast, this=this, to=to) - 83 - 84 class Tokenizer(Postgres.Tokenizer): - 85 BIT_STRINGS = [] - 86 HEX_STRINGS = [] - 87 STRING_ESCAPES = ["\\", "'"] - 88 - 89 KEYWORDS = { - 90 **Postgres.Tokenizer.KEYWORDS, - 91 "HLLSKETCH": TokenType.HLLSKETCH, - 92 "SUPER": TokenType.SUPER, - 93 "SYSDATE": TokenType.CURRENT_TIMESTAMP, - 94 "TOP": TokenType.TOP, - 95 "UNLOAD": TokenType.COMMAND, - 96 "VARBYTE": TokenType.VARBINARY, - 97 } - 98 - 99 # Redshift allows # to appear as a table identifier prefix -100 SINGLE_TOKENS = Postgres.Tokenizer.SINGLE_TOKENS.copy() -101 SINGLE_TOKENS.pop("#") + 78 return self.expression(exp.Pivot, this=table, unpivot=True) if unpivot else table + 79 + 80 def _parse_types( + 81 self, check_func: bool = False, schema: bool = False, allow_identifiers: bool = True + 82 ) -> t.Optional[exp.Expression]: + 83 this = super()._parse_types( + 84 check_func=check_func, schema=schema, allow_identifiers=allow_identifiers + 85 ) + 86 + 87 if ( + 88 isinstance(this, exp.DataType) + 89 and this.is_type("varchar") + 90 and this.expressions + 91 and this.expressions[0].this == exp.column("MAX") + 92 ): + 93 this.set("expressions", [exp.var("MAX")]) + 94 + 95 return this + 96 + 97 def _parse_convert(self, strict: bool) -> t.Optional[exp.Expression]: + 98 to = self._parse_types() + 99 self._match(TokenType.COMMA) +100 this = self._parse_bitwise() +101 return self.expression(exp.TryCast, this=this, to=to) 102 -103 class Generator(Postgres.Generator): -104 LOCKING_READS_SUPPORTED = False -105 RENAME_TABLE_WITH_DB = False -106 QUERY_HINTS = False -107 VALUES_AS_TABLE = False -108 TZ_TO_WITH_TIME_ZONE = True -109 NVL2_SUPPORTED = True -110 -111 TYPE_MAPPING = { -112 **Postgres.Generator.TYPE_MAPPING, -113 exp.DataType.Type.BINARY: "VARBYTE", -114 exp.DataType.Type.INT: "INTEGER", -115 exp.DataType.Type.TIMETZ: "TIME", -116 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", -117 exp.DataType.Type.VARBINARY: "VARBYTE", -118 } -119 -120 PROPERTIES_LOCATION = { -121 **Postgres.Generator.PROPERTIES_LOCATION, -122 exp.LikeProperty: exp.Properties.Location.POST_WITH, -123 } -124 -125 TRANSFORMS = { -126 **Postgres.Generator.TRANSFORMS, -127 exp.Concat: concat_to_dpipe_sql, -128 exp.ConcatWs: concat_ws_to_dpipe_sql, -129 exp.CurrentTimestamp: lambda self, e: "SYSDATE", -130 exp.DateAdd: lambda self, e: self.func( -131 "DATEADD", exp.var(e.text("unit") or "day"), e.expression, e.this -132 ), -133 exp.DateDiff: lambda self, e: self.func( -134 "DATEDIFF", exp.var(e.text("unit") or "day"), e.expression, e.this -135 ), -136 exp.DistKeyProperty: lambda self, e: f"DISTKEY({e.name})", -137 exp.DistStyleProperty: lambda self, e: self.naked_property(e), -138 exp.FromBase: rename_func("STRTOL"), -139 exp.JSONExtract: _json_sql, -140 exp.JSONExtractScalar: _json_sql, -141 exp.SafeConcat: concat_to_dpipe_sql, -142 exp.Select: transforms.preprocess( -143 [transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins] -144 ), -145 exp.SortKeyProperty: lambda self, e: f"{'COMPOUND ' if e.args['compound'] else ''}SORTKEY({self.format_args(*e.this)})", -146 exp.TsOrDsToDate: ts_or_ds_to_date_sql("redshift"), -147 } -148 -149 # Postgres maps exp.Pivot to no_pivot_sql, but Redshift support pivots -150 TRANSFORMS.pop(exp.Pivot) -151 -152 # Redshift uses the POW | POWER (expr1, expr2) syntax instead of expr1 ^ expr2 (postgres) -153 TRANSFORMS.pop(exp.Pow) -154 -155 # Redshift supports ANY_VALUE(..) -156 TRANSFORMS.pop(exp.AnyValue) -157 -158 RESERVED_KEYWORDS = {*Postgres.Generator.RESERVED_KEYWORDS, "snapshot", "type"} -159 -160 def with_properties(self, properties: exp.Properties) -> str: -161 """Redshift doesn't have `WITH` as part of their with_properties so we remove it""" -162 return self.properties(properties, prefix=" ", suffix="") -163 -164 def datatype_sql(self, expression: exp.DataType) -> str: -165 """ -166 Redshift converts the `TEXT` data type to `VARCHAR(255)` by default when people more generally mean -167 VARCHAR of max length which is `VARCHAR(max)` in Redshift. Therefore if we get a `TEXT` data type -168 without precision we convert it to `VARCHAR(max)` and if it does have precision then we just convert -169 `TEXT` to `VARCHAR`. -170 """ -171 if expression.is_type("text"): -172 expression = expression.copy() -173 expression.set("this", exp.DataType.Type.VARCHAR) -174 precision = expression.args.get("expressions") -175 -176 if not precision: -177 expression.append("expressions", exp.var("MAX")) +103 class Tokenizer(Postgres.Tokenizer): +104 BIT_STRINGS = [] +105 HEX_STRINGS = [] +106 STRING_ESCAPES = ["\\", "'"] +107 +108 KEYWORDS = { +109 **Postgres.Tokenizer.KEYWORDS, +110 "HLLSKETCH": TokenType.HLLSKETCH, +111 "SUPER": TokenType.SUPER, +112 "SYSDATE": TokenType.CURRENT_TIMESTAMP, +113 "TOP": TokenType.TOP, +114 "UNLOAD": TokenType.COMMAND, +115 "VARBYTE": TokenType.VARBINARY, +116 } +117 +118 # Redshift allows # to appear as a table identifier prefix +119 SINGLE_TOKENS = Postgres.Tokenizer.SINGLE_TOKENS.copy() +120 SINGLE_TOKENS.pop("#") +121 +122 class Generator(Postgres.Generator): +123 LOCKING_READS_SUPPORTED = False +124 RENAME_TABLE_WITH_DB = False +125 QUERY_HINTS = False +126 VALUES_AS_TABLE = False +127 TZ_TO_WITH_TIME_ZONE = True +128 NVL2_SUPPORTED = True +129 +130 TYPE_MAPPING = { +131 **Postgres.Generator.TYPE_MAPPING, +132 exp.DataType.Type.BINARY: "VARBYTE", +133 exp.DataType.Type.INT: "INTEGER", +134 exp.DataType.Type.TIMETZ: "TIME", +135 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", +136 exp.DataType.Type.VARBINARY: "VARBYTE", +137 } +138 +139 PROPERTIES_LOCATION = { +140 **Postgres.Generator.PROPERTIES_LOCATION, +141 exp.LikeProperty: exp.Properties.Location.POST_WITH, +142 } +143 +144 TRANSFORMS = { +145 **Postgres.Generator.TRANSFORMS, +146 exp.Concat: concat_to_dpipe_sql, +147 exp.ConcatWs: concat_ws_to_dpipe_sql, +148 exp.CurrentTimestamp: lambda self, e: "SYSDATE", +149 exp.DateAdd: lambda self, e: self.func( +150 "DATEADD", exp.var(e.text("unit") or "day"), e.expression, e.this +151 ), +152 exp.DateDiff: lambda self, e: self.func( +153 "DATEDIFF", exp.var(e.text("unit") or "day"), e.expression, e.this +154 ), +155 exp.DistKeyProperty: lambda self, e: f"DISTKEY({e.name})", +156 exp.DistStyleProperty: lambda self, e: self.naked_property(e), +157 exp.FromBase: rename_func("STRTOL"), +158 exp.JSONExtract: _json_sql, +159 exp.JSONExtractScalar: _json_sql, +160 exp.SafeConcat: concat_to_dpipe_sql, +161 exp.Select: transforms.preprocess( +162 [transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins] +163 ), +164 exp.SortKeyProperty: lambda self, e: f"{'COMPOUND ' if e.args['compound'] else ''}SORTKEY({self.format_args(*e.this)})", +165 exp.TsOrDsToDate: ts_or_ds_to_date_sql("redshift"), +166 } +167 +168 # Postgres maps exp.Pivot to no_pivot_sql, but Redshift support pivots +169 TRANSFORMS.pop(exp.Pivot) +170 +171 # Redshift uses the POW | POWER (expr1, expr2) syntax instead of expr1 ^ expr2 (postgres) +172 TRANSFORMS.pop(exp.Pow) +173 +174 # Redshift supports ANY_VALUE(..) +175 TRANSFORMS.pop(exp.AnyValue) +176 +177 RESERVED_KEYWORDS = {*Postgres.Generator.RESERVED_KEYWORDS, "snapshot", "type"} 178 -179 return super().datatype_sql(expression) +179 def with_properties(self, properties: exp.Properties) -> str: +180 """Redshift doesn't have `WITH` as part of their with_properties so we remove it""" +181 return self.properties(properties, prefix=" ", suffix="") +182 +183 def datatype_sql(self, expression: exp.DataType) -> str: +184 """ +185 Redshift converts the `TEXT` data type to `VARCHAR(255)` by default when people more generally mean +186 VARCHAR of max length which is `VARCHAR(max)` in Redshift. Therefore if we get a `TEXT` data type +187 without precision we convert it to `VARCHAR(max)` and if it does have precision then we just convert +188 `TEXT` to `VARCHAR`. +189 """ +190 if expression.is_type("text"): +191 expression = expression.copy() +192 expression.set("this", exp.DataType.Type.VARCHAR) +193 precision = expression.args.get("expressions") +194 +195 if not precision: +196 expression.append("expressions", exp.var("MAX")) +197 +198 return super().datatype_sql(expression) @@ -637,6 +684,18 @@ + +
    +
    + INDEX_OFFSET = +0 + + +
    + + + +
    @@ -887,8 +946,7 @@
    Inherited Members
    sqlglot.dialects.dialect.Dialect
    @@ -935,46 +993,64 @@
    -
    43    class Parser(Postgres.Parser):
    -44        FUNCTIONS = {
    -45            **Postgres.Parser.FUNCTIONS,
    -46            "ADD_MONTHS": lambda args: exp.DateAdd(
    -47                this=exp.TsOrDsToDate(this=seq_get(args, 0)),
    -48                expression=seq_get(args, 1),
    -49                unit=exp.var("month"),
    -50            ),
    -51            "DATEADD": _parse_date_add,
    -52            "DATE_ADD": _parse_date_add,
    -53            "DATEDIFF": lambda args: exp.DateDiff(
    -54                this=exp.TsOrDsToDate(this=seq_get(args, 2)),
    -55                expression=exp.TsOrDsToDate(this=seq_get(args, 1)),
    -56                unit=seq_get(args, 0),
    -57            ),
    -58            "STRTOL": exp.FromBase.from_arg_list,
    -59        }
    -60
    -61        def _parse_types(
    -62            self, check_func: bool = False, schema: bool = False, allow_identifiers: bool = True
    -63        ) -> t.Optional[exp.Expression]:
    -64            this = super()._parse_types(
    -65                check_func=check_func, schema=schema, allow_identifiers=allow_identifiers
    -66            )
    -67
    -68            if (
    -69                isinstance(this, exp.DataType)
    -70                and this.is_type("varchar")
    -71                and this.expressions
    -72                and this.expressions[0].this == exp.column("MAX")
    -73            ):
    -74                this.set("expressions", [exp.var("MAX")])
    -75
    -76            return this
    -77
    -78        def _parse_convert(self, strict: bool) -> t.Optional[exp.Expression]:
    -79            to = self._parse_types()
    -80            self._match(TokenType.COMMA)
    -81            this = self._parse_bitwise()
    -82            return self.expression(exp.TryCast, this=this, to=to)
    +            
     44    class Parser(Postgres.Parser):
    + 45        FUNCTIONS = {
    + 46            **Postgres.Parser.FUNCTIONS,
    + 47            "ADD_MONTHS": lambda args: exp.DateAdd(
    + 48                this=exp.TsOrDsToDate(this=seq_get(args, 0)),
    + 49                expression=seq_get(args, 1),
    + 50                unit=exp.var("month"),
    + 51            ),
    + 52            "DATEADD": _parse_date_add,
    + 53            "DATE_ADD": _parse_date_add,
    + 54            "DATEDIFF": lambda args: exp.DateDiff(
    + 55                this=exp.TsOrDsToDate(this=seq_get(args, 2)),
    + 56                expression=exp.TsOrDsToDate(this=seq_get(args, 1)),
    + 57                unit=seq_get(args, 0),
    + 58            ),
    + 59            "STRTOL": exp.FromBase.from_arg_list,
    + 60        }
    + 61
    + 62        def _parse_table(
    + 63            self,
    + 64            schema: bool = False,
    + 65            joins: bool = False,
    + 66            alias_tokens: t.Optional[t.Collection[TokenType]] = None,
    + 67            parse_bracket: bool = False,
    + 68        ) -> t.Optional[exp.Expression]:
    + 69            # Redshift supports UNPIVOTing SUPER objects, e.g. `UNPIVOT foo.obj[0] AS val AT attr`
    + 70            unpivot = self._match(TokenType.UNPIVOT)
    + 71            table = super()._parse_table(
    + 72                schema=schema,
    + 73                joins=joins,
    + 74                alias_tokens=alias_tokens,
    + 75                parse_bracket=parse_bracket,
    + 76            )
    + 77
    + 78            return self.expression(exp.Pivot, this=table, unpivot=True) if unpivot else table
    + 79
    + 80        def _parse_types(
    + 81            self, check_func: bool = False, schema: bool = False, allow_identifiers: bool = True
    + 82        ) -> t.Optional[exp.Expression]:
    + 83            this = super()._parse_types(
    + 84                check_func=check_func, schema=schema, allow_identifiers=allow_identifiers
    + 85            )
    + 86
    + 87            if (
    + 88                isinstance(this, exp.DataType)
    + 89                and this.is_type("varchar")
    + 90                and this.expressions
    + 91                and this.expressions[0].this == exp.column("MAX")
    + 92            ):
    + 93                this.set("expressions", [exp.var("MAX")])
    + 94
    + 95            return this
    + 96
    + 97        def _parse_convert(self, strict: bool) -> t.Optional[exp.Expression]:
    + 98            to = self._parse_types()
    + 99            self._match(TokenType.COMMA)
    +100            this = self._parse_bitwise()
    +101            return self.expression(exp.TryCast, this=this, to=to)
     
    @@ -999,7 +1075,7 @@ Default: 3
    FUNCTIONS = - {'ABS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Abs'>>, 'ANY_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AnyValue'>>, 'APPROX_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_COUNT_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxQuantile'>>, 'ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Array'>>, 'ARRAY_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAgg'>>, 'ARRAY_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAll'>>, 'ARRAY_ANY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAny'>>, 'ARRAY_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcat'>>, 'ARRAY_CAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcat'>>, 'ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_JOIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayJoin'>>, 'ARRAY_SIZE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySize'>>, 'ARRAY_SORT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySort'>>, 'ARRAY_SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySum'>>, 'ARRAY_UNION_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayUnionAgg'>>, 'AVG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Avg'>>, 'CASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Case'>>, 'CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cast'>>, 'CAST_TO_STR_TYPE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CastToStrType'>>, 'CEIL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CEILING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CHR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Chr'>>, 'CHAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Chr'>>, 'COALESCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'IFNULL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'NVL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'COLLATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Collate'>>, 'CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Concat'>>, 'CONCAT_WS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ConcatWs'>>, 'COUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Count'>>, 'COUNT_IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'CURRENT_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDate'>>, 'CURRENT_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDatetime'>>, 'CURRENT_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTime'>>, 'CURRENT_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestamp'>>, 'CURRENT_USER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentUser'>>, 'DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Date'>>, 'DATE_ADD': <function _parse_date_add>, 'DATEDIFF': <function Redshift.Parser.<lambda>>, 'DATE_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATE_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateStrToDate'>>, 'DATE_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateSub'>>, 'DATE_TO_DATE_STR': <function Parser.<lambda>>, 'DATE_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateToDi'>>, 'DATE_TRUNC': <function parse_timestamp_trunc>, 'DATETIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeAdd'>>, 'DATETIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeDiff'>>, 'DATETIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeSub'>>, 'DATETIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeTrunc'>>, 'DAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Day'>>, 'DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAYOFMONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAY_OF_WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAYOFWEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAY_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DAYOFYEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DECODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Decode'>>, 'DI_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DiToDate'>>, 'ENCODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Encode'>>, 'EXP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Exp'>>, 'EXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Explode'>>, 'EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Extract'>>, 'FIRST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.First'>>, 'FLOOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Floor'>>, 'FROM_BASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase'>>, 'FROM_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase64'>>, 'GENERATE_SERIES': <function _generate_series>, 'GREATEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Greatest'>>, 'GROUP_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GroupConcat'>>, 'HEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hex'>>, 'HLL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hll'>>, 'IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.If'>>, 'INITCAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Initcap'>>, 'IS_NAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, 'ISNAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, 'J_S_O_N_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArray'>>, 'J_S_O_N_ARRAY_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayAgg'>>, 'JSON_ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayContains'>>, 'JSONB_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtract'>>, 'JSONB_EXTRACT_SCALAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtractScalar'>>, 'JSON_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExtract'>>, 'JSON_EXTRACT_SCALAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExtractScalar'>>, 'JSON_FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONFormat'>>, 'J_S_O_N_OBJECT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONObject'>>, 'J_S_O_N_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONTable'>>, 'LAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Last'>>, 'LAST_DATE_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDateOfMonth'>>, 'LEAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Least'>>, 'LEFT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Left'>>, 'LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEVENSHTEIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Levenshtein'>>, 'LN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ln'>>, 'LOG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Log'>>, 'LOG10': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Log10'>>, 'LOG2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Log2'>>, 'LOGICAL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOLAND_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'LOGICAL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOLOR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'LOWER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lower'>>, 'LCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lower'>>, 'MD5': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5'>>, 'MD5_DIGEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5Digest'>>, 'MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Map'>>, 'MAP_FROM_ENTRIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapFromEntries'>>, 'MATCH_AGAINST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MatchAgainst'>>, 'MAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Max'>>, 'MIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Min'>>, 'MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Month'>>, 'MONTHS_BETWEEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MonthsBetween'>>, 'NEXT_VALUE_FOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NextValueFor'>>, 'NUMBER_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NumberToStr'>>, 'NVL2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Nvl2'>>, 'OPEN_J_S_O_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.OpenJSON'>>, 'PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParameterizedAgg'>>, 'PARSE_JSON': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'JSON_PARSE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'PERCENTILE_CONT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileCont'>>, 'PERCENTILE_DISC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileDisc'>>, 'POSEXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Posexplode'>>, 'POWER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'POW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quantile'>>, 'RANGE_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RangeN'>>, 'READ_CSV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ReadCSV'>>, 'REDUCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Reduce'>>, 'REGEXP_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpExtract'>>, 'REGEXP_I_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpILike'>>, 'REGEXP_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpLike'>>, 'REGEXP_REPLACE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpReplace'>>, 'REGEXP_SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpSplit'>>, 'REPEAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Repeat'>>, 'RIGHT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Right'>>, 'ROUND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Round'>>, 'ROW_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RowNumber'>>, 'SHA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA1': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA2'>>, 'SAFE_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeConcat'>>, 'SAFE_DIVIDE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeDivide'>>, 'SET_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SetAgg'>>, 'SORT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SortArray'>>, 'SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Split'>>, 'SQRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sqrt'>>, 'STANDARD_HASH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StandardHash'>>, 'STAR_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StarMap'>>, 'STARTS_WITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STARTSWITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STDDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDDEV_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevPop'>>, 'STDDEV_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevSamp'>>, 'STR_POSITION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToDate'>>, 'STR_TO_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToMap'>>, 'STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToTime'>>, 'STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToUnix'>>, 'STRUCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Struct'>>, 'STRUCT_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StructExtract'>>, 'STUFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'SUBSTRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Substring'>>, 'SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sum'>>, 'TIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeAdd'>>, 'TIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeDiff'>>, 'TIME_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToDate'>>, 'TIME_STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToTime'>>, 'TIME_STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToUnix'>>, 'TIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeSub'>>, 'TIME_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToStr'>>, 'TIME_TO_TIME_STR': <function Parser.<lambda>>, 'TIME_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToUnix'>>, 'TIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeTrunc'>>, 'TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Timestamp'>>, 'TIMESTAMP_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampAdd'>>, 'TIMESTAMP_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampDiff'>>, 'TIMESTAMP_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampSub'>>, 'TIMESTAMP_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampTrunc'>>, 'TO_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToBase64'>>, 'TO_CHAR': <function format_time_lambda.<locals>._format_time>, 'TO_DAYS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToDays'>>, 'TRANSFORM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Transform'>>, 'TRIM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Trim'>>, 'TRY_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryCast'>>, 'TS_OR_DI_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDiToDi'>>, 'TS_OR_DS_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsAdd'>>, 'TS_OR_DS_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDate'>>, 'TS_OR_DS_TO_DATE_STR': <function Parser.<lambda>>, 'UNHEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unhex'>>, 'UNIX_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToStr'>>, 'UNIX_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTime'>>, 'UNIX_TO_TIME_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTimeStr'>>, 'UPPER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'UCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'VAR_MAP': <function parse_var_map>, 'VARIANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'VAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Week'>>, 'WEEK_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WEEKOFYEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WHEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.When'>>, 'X_M_L_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.XMLTable'>>, 'XOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Xor'>>, 'YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Year'>>, 'GLOB': <function Parser.<lambda>>, 'LIKE': <function parse_like>, 'NOW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestamp'>>, 'TO_TIMESTAMP': <function _to_timestamp>, 'UNNEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Explode'>>, 'ADD_MONTHS': <function Redshift.Parser.<lambda>>, 'DATEADD': <function _parse_date_add>, 'STRTOL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase'>>} + {'ABS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Abs'>>, 'ANY_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AnyValue'>>, 'APPROX_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_COUNT_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxQuantile'>>, 'ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Array'>>, 'ARRAY_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAgg'>>, 'ARRAY_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAll'>>, 'ARRAY_ANY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAny'>>, 'ARRAY_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcat'>>, 'ARRAY_CAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcat'>>, 'ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_JOIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayJoin'>>, 'ARRAY_SIZE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySize'>>, 'ARRAY_SORT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySort'>>, 'ARRAY_SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySum'>>, 'ARRAY_UNION_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayUnionAgg'>>, 'AVG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Avg'>>, 'CASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Case'>>, 'CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cast'>>, 'CAST_TO_STR_TYPE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CastToStrType'>>, 'CEIL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CEILING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CHR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Chr'>>, 'CHAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Chr'>>, 'COALESCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'IFNULL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'NVL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'COLLATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Collate'>>, 'CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Concat'>>, 'CONCAT_WS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ConcatWs'>>, 'COUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Count'>>, 'COUNT_IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'CURRENT_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDate'>>, 'CURRENT_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDatetime'>>, 'CURRENT_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTime'>>, 'CURRENT_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestamp'>>, 'CURRENT_USER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentUser'>>, 'DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Date'>>, 'DATE_ADD': <function _parse_date_add>, 'DATEDIFF': <function Redshift.Parser.<lambda>>, 'DATE_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATE_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateStrToDate'>>, 'DATE_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateSub'>>, 'DATE_TO_DATE_STR': <function Parser.<lambda>>, 'DATE_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateToDi'>>, 'DATE_TRUNC': <function parse_timestamp_trunc>, 'DATETIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeAdd'>>, 'DATETIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeDiff'>>, 'DATETIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeSub'>>, 'DATETIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeTrunc'>>, 'DAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Day'>>, 'DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAYOFMONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAY_OF_WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAYOFWEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAY_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DAYOFYEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DECODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Decode'>>, 'DI_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DiToDate'>>, 'ENCODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Encode'>>, 'EXP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Exp'>>, 'EXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Explode'>>, 'EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Extract'>>, 'FIRST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.First'>>, 'FLOOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Floor'>>, 'FROM_BASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase'>>, 'FROM_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase64'>>, 'GENERATE_SERIES': <function _generate_series>, 'GREATEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Greatest'>>, 'GROUP_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GroupConcat'>>, 'HEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hex'>>, 'HLL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hll'>>, 'IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.If'>>, 'INITCAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Initcap'>>, 'IS_NAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, 'ISNAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, 'J_S_O_N_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArray'>>, 'J_S_O_N_ARRAY_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayAgg'>>, 'JSON_ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayContains'>>, 'JSONB_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtract'>>, 'JSONB_EXTRACT_SCALAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtractScalar'>>, 'JSON_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExtract'>>, 'JSON_EXTRACT_SCALAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExtractScalar'>>, 'JSON_FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONFormat'>>, 'J_S_O_N_OBJECT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONObject'>>, 'J_S_O_N_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONTable'>>, 'LAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Last'>>, 'LAST_DATE_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDateOfMonth'>>, 'LEAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Least'>>, 'LEFT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Left'>>, 'LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEVENSHTEIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Levenshtein'>>, 'LN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ln'>>, 'LOG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Log'>>, 'LOG10': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Log10'>>, 'LOG2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Log2'>>, 'LOGICAL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOLAND_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'LOGICAL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOLOR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'LOWER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lower'>>, 'LCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lower'>>, 'MD5': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5'>>, 'MD5_DIGEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5Digest'>>, 'MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Map'>>, 'MAP_FROM_ENTRIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapFromEntries'>>, 'MATCH_AGAINST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MatchAgainst'>>, 'MAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Max'>>, 'MIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Min'>>, 'MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Month'>>, 'MONTHS_BETWEEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MonthsBetween'>>, 'NEXT_VALUE_FOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NextValueFor'>>, 'NUMBER_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NumberToStr'>>, 'NVL2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Nvl2'>>, 'OPEN_J_S_O_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.OpenJSON'>>, 'PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParameterizedAgg'>>, 'PARSE_JSON': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'JSON_PARSE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'PERCENTILE_CONT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileCont'>>, 'PERCENTILE_DISC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileDisc'>>, 'POSEXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Posexplode'>>, 'POWER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'POW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'PREDICT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Predict'>>, 'QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quantile'>>, 'RANGE_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RangeN'>>, 'READ_CSV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ReadCSV'>>, 'REDUCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Reduce'>>, 'REGEXP_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpExtract'>>, 'REGEXP_I_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpILike'>>, 'REGEXP_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpLike'>>, 'REGEXP_REPLACE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpReplace'>>, 'REGEXP_SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpSplit'>>, 'REPEAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Repeat'>>, 'RIGHT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Right'>>, 'ROUND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Round'>>, 'ROW_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RowNumber'>>, 'SHA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA1': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA2'>>, 'SAFE_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeConcat'>>, 'SAFE_DIVIDE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeDivide'>>, 'SET_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SetAgg'>>, 'SORT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SortArray'>>, 'SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Split'>>, 'SQRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sqrt'>>, 'STANDARD_HASH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StandardHash'>>, 'STAR_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StarMap'>>, 'STARTS_WITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STARTSWITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STDDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDDEV_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevPop'>>, 'STDDEV_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevSamp'>>, 'STR_POSITION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToDate'>>, 'STR_TO_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToMap'>>, 'STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToTime'>>, 'STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToUnix'>>, 'STRUCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Struct'>>, 'STRUCT_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StructExtract'>>, 'STUFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'SUBSTRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Substring'>>, 'SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sum'>>, 'TIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeAdd'>>, 'TIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeDiff'>>, 'TIME_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToDate'>>, 'TIME_STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToTime'>>, 'TIME_STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToUnix'>>, 'TIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeSub'>>, 'TIME_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToStr'>>, 'TIME_TO_TIME_STR': <function Parser.<lambda>>, 'TIME_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToUnix'>>, 'TIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeTrunc'>>, 'TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Timestamp'>>, 'TIMESTAMP_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampAdd'>>, 'TIMESTAMP_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampDiff'>>, 'TIMESTAMP_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampSub'>>, 'TIMESTAMP_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampTrunc'>>, 'TO_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToBase64'>>, 'TO_CHAR': <function format_time_lambda.<locals>._format_time>, 'TO_DAYS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToDays'>>, 'TRANSFORM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Transform'>>, 'TRIM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Trim'>>, 'TRY_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryCast'>>, 'TS_OR_DI_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDiToDi'>>, 'TS_OR_DS_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsAdd'>>, 'TS_OR_DS_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDate'>>, 'TS_OR_DS_TO_DATE_STR': <function Parser.<lambda>>, 'UNHEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unhex'>>, 'UNIX_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToStr'>>, 'UNIX_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTime'>>, 'UNIX_TO_TIME_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTimeStr'>>, 'UPPER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'UCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'VAR_MAP': <function parse_var_map>, 'VARIANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'VAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Week'>>, 'WEEK_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WEEKOFYEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WHEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.When'>>, 'X_M_L_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.XMLTable'>>, 'XOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Xor'>>, 'YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Year'>>, 'GLOB': <function Parser.<lambda>>, 'LIKE': <function parse_like>, 'NOW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestamp'>>, 'TO_TIMESTAMP': <function _to_timestamp>, 'UNNEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Explode'>>, 'ADD_MONTHS': <function Redshift.Parser.<lambda>>, 'DATEADD': <function _parse_date_add>, 'STRTOL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase'>>}
    @@ -1019,6 +1095,18 @@ Default: 3 +
    +
    +
    + INDEX_OFFSET: int = +0 + + +
    + + + +
    @@ -1217,24 +1304,24 @@ Default: 3
    -
     84    class Tokenizer(Postgres.Tokenizer):
    - 85        BIT_STRINGS = []
    - 86        HEX_STRINGS = []
    - 87        STRING_ESCAPES = ["\\", "'"]
    - 88
    - 89        KEYWORDS = {
    - 90            **Postgres.Tokenizer.KEYWORDS,
    - 91            "HLLSKETCH": TokenType.HLLSKETCH,
    - 92            "SUPER": TokenType.SUPER,
    - 93            "SYSDATE": TokenType.CURRENT_TIMESTAMP,
    - 94            "TOP": TokenType.TOP,
    - 95            "UNLOAD": TokenType.COMMAND,
    - 96            "VARBYTE": TokenType.VARBINARY,
    - 97        }
    - 98
    - 99        # Redshift allows # to appear as a table identifier prefix
    -100        SINGLE_TOKENS = Postgres.Tokenizer.SINGLE_TOKENS.copy()
    -101        SINGLE_TOKENS.pop("#")
    +            
    103    class Tokenizer(Postgres.Tokenizer):
    +104        BIT_STRINGS = []
    +105        HEX_STRINGS = []
    +106        STRING_ESCAPES = ["\\", "'"]
    +107
    +108        KEYWORDS = {
    +109            **Postgres.Tokenizer.KEYWORDS,
    +110            "HLLSKETCH": TokenType.HLLSKETCH,
    +111            "SUPER": TokenType.SUPER,
    +112            "SYSDATE": TokenType.CURRENT_TIMESTAMP,
    +113            "TOP": TokenType.TOP,
    +114            "UNLOAD": TokenType.COMMAND,
    +115            "VARBYTE": TokenType.VARBINARY,
    +116        }
    +117
    +118        # Redshift allows # to appear as a table identifier prefix
    +119        SINGLE_TOKENS = Postgres.Tokenizer.SINGLE_TOKENS.copy()
    +120        SINGLE_TOKENS.pop("#")
     
    @@ -1346,83 +1433,83 @@ Default: 3
    -
    103    class Generator(Postgres.Generator):
    -104        LOCKING_READS_SUPPORTED = False
    -105        RENAME_TABLE_WITH_DB = False
    -106        QUERY_HINTS = False
    -107        VALUES_AS_TABLE = False
    -108        TZ_TO_WITH_TIME_ZONE = True
    -109        NVL2_SUPPORTED = True
    -110
    -111        TYPE_MAPPING = {
    -112            **Postgres.Generator.TYPE_MAPPING,
    -113            exp.DataType.Type.BINARY: "VARBYTE",
    -114            exp.DataType.Type.INT: "INTEGER",
    -115            exp.DataType.Type.TIMETZ: "TIME",
    -116            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
    -117            exp.DataType.Type.VARBINARY: "VARBYTE",
    -118        }
    -119
    -120        PROPERTIES_LOCATION = {
    -121            **Postgres.Generator.PROPERTIES_LOCATION,
    -122            exp.LikeProperty: exp.Properties.Location.POST_WITH,
    -123        }
    -124
    -125        TRANSFORMS = {
    -126            **Postgres.Generator.TRANSFORMS,
    -127            exp.Concat: concat_to_dpipe_sql,
    -128            exp.ConcatWs: concat_ws_to_dpipe_sql,
    -129            exp.CurrentTimestamp: lambda self, e: "SYSDATE",
    -130            exp.DateAdd: lambda self, e: self.func(
    -131                "DATEADD", exp.var(e.text("unit") or "day"), e.expression, e.this
    -132            ),
    -133            exp.DateDiff: lambda self, e: self.func(
    -134                "DATEDIFF", exp.var(e.text("unit") or "day"), e.expression, e.this
    -135            ),
    -136            exp.DistKeyProperty: lambda self, e: f"DISTKEY({e.name})",
    -137            exp.DistStyleProperty: lambda self, e: self.naked_property(e),
    -138            exp.FromBase: rename_func("STRTOL"),
    -139            exp.JSONExtract: _json_sql,
    -140            exp.JSONExtractScalar: _json_sql,
    -141            exp.SafeConcat: concat_to_dpipe_sql,
    -142            exp.Select: transforms.preprocess(
    -143                [transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins]
    -144            ),
    -145            exp.SortKeyProperty: lambda self, e: f"{'COMPOUND ' if e.args['compound'] else ''}SORTKEY({self.format_args(*e.this)})",
    -146            exp.TsOrDsToDate: ts_or_ds_to_date_sql("redshift"),
    -147        }
    -148
    -149        # Postgres maps exp.Pivot to no_pivot_sql, but Redshift support pivots
    -150        TRANSFORMS.pop(exp.Pivot)
    -151
    -152        # Redshift uses the POW | POWER (expr1, expr2) syntax instead of expr1 ^ expr2 (postgres)
    -153        TRANSFORMS.pop(exp.Pow)
    -154
    -155        # Redshift supports ANY_VALUE(..)
    -156        TRANSFORMS.pop(exp.AnyValue)
    -157
    -158        RESERVED_KEYWORDS = {*Postgres.Generator.RESERVED_KEYWORDS, "snapshot", "type"}
    -159
    -160        def with_properties(self, properties: exp.Properties) -> str:
    -161            """Redshift doesn't have `WITH` as part of their with_properties so we remove it"""
    -162            return self.properties(properties, prefix=" ", suffix="")
    -163
    -164        def datatype_sql(self, expression: exp.DataType) -> str:
    -165            """
    -166            Redshift converts the `TEXT` data type to `VARCHAR(255)` by default when people more generally mean
    -167            VARCHAR of max length which is `VARCHAR(max)` in Redshift. Therefore if we get a `TEXT` data type
    -168            without precision we convert it to `VARCHAR(max)` and if it does have precision then we just convert
    -169            `TEXT` to `VARCHAR`.
    -170            """
    -171            if expression.is_type("text"):
    -172                expression = expression.copy()
    -173                expression.set("this", exp.DataType.Type.VARCHAR)
    -174                precision = expression.args.get("expressions")
    -175
    -176                if not precision:
    -177                    expression.append("expressions", exp.var("MAX"))
    +            
    122    class Generator(Postgres.Generator):
    +123        LOCKING_READS_SUPPORTED = False
    +124        RENAME_TABLE_WITH_DB = False
    +125        QUERY_HINTS = False
    +126        VALUES_AS_TABLE = False
    +127        TZ_TO_WITH_TIME_ZONE = True
    +128        NVL2_SUPPORTED = True
    +129
    +130        TYPE_MAPPING = {
    +131            **Postgres.Generator.TYPE_MAPPING,
    +132            exp.DataType.Type.BINARY: "VARBYTE",
    +133            exp.DataType.Type.INT: "INTEGER",
    +134            exp.DataType.Type.TIMETZ: "TIME",
    +135            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
    +136            exp.DataType.Type.VARBINARY: "VARBYTE",
    +137        }
    +138
    +139        PROPERTIES_LOCATION = {
    +140            **Postgres.Generator.PROPERTIES_LOCATION,
    +141            exp.LikeProperty: exp.Properties.Location.POST_WITH,
    +142        }
    +143
    +144        TRANSFORMS = {
    +145            **Postgres.Generator.TRANSFORMS,
    +146            exp.Concat: concat_to_dpipe_sql,
    +147            exp.ConcatWs: concat_ws_to_dpipe_sql,
    +148            exp.CurrentTimestamp: lambda self, e: "SYSDATE",
    +149            exp.DateAdd: lambda self, e: self.func(
    +150                "DATEADD", exp.var(e.text("unit") or "day"), e.expression, e.this
    +151            ),
    +152            exp.DateDiff: lambda self, e: self.func(
    +153                "DATEDIFF", exp.var(e.text("unit") or "day"), e.expression, e.this
    +154            ),
    +155            exp.DistKeyProperty: lambda self, e: f"DISTKEY({e.name})",
    +156            exp.DistStyleProperty: lambda self, e: self.naked_property(e),
    +157            exp.FromBase: rename_func("STRTOL"),
    +158            exp.JSONExtract: _json_sql,
    +159            exp.JSONExtractScalar: _json_sql,
    +160            exp.SafeConcat: concat_to_dpipe_sql,
    +161            exp.Select: transforms.preprocess(
    +162                [transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins]
    +163            ),
    +164            exp.SortKeyProperty: lambda self, e: f"{'COMPOUND ' if e.args['compound'] else ''}SORTKEY({self.format_args(*e.this)})",
    +165            exp.TsOrDsToDate: ts_or_ds_to_date_sql("redshift"),
    +166        }
    +167
    +168        # Postgres maps exp.Pivot to no_pivot_sql, but Redshift support pivots
    +169        TRANSFORMS.pop(exp.Pivot)
    +170
    +171        # Redshift uses the POW | POWER (expr1, expr2) syntax instead of expr1 ^ expr2 (postgres)
    +172        TRANSFORMS.pop(exp.Pow)
    +173
    +174        # Redshift supports ANY_VALUE(..)
    +175        TRANSFORMS.pop(exp.AnyValue)
    +176
    +177        RESERVED_KEYWORDS = {*Postgres.Generator.RESERVED_KEYWORDS, "snapshot", "type"}
     178
    -179            return super().datatype_sql(expression)
    +179        def with_properties(self, properties: exp.Properties) -> str:
    +180            """Redshift doesn't have `WITH` as part of their with_properties so we remove it"""
    +181            return self.properties(properties, prefix=" ", suffix="")
    +182
    +183        def datatype_sql(self, expression: exp.DataType) -> str:
    +184            """
    +185            Redshift converts the `TEXT` data type to `VARCHAR(255)` by default when people more generally mean
    +186            VARCHAR of max length which is `VARCHAR(max)` in Redshift. Therefore if we get a `TEXT` data type
    +187            without precision we convert it to `VARCHAR(max)` and if it does have precision then we just convert
    +188            `TEXT` to `VARCHAR`.
    +189            """
    +190            if expression.is_type("text"):
    +191                expression = expression.copy()
    +192                expression.set("this", exp.DataType.Type.VARCHAR)
    +193                precision = expression.args.get("expressions")
    +194
    +195                if not precision:
    +196                    expression.append("expressions", exp.var("MAX"))
    +197
    +198            return super().datatype_sql(expression)
     
    @@ -1554,7 +1641,7 @@ Default: True
    PROPERTIES_LOCATION = - {<class 'sqlglot.expressions.AlgorithmProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.AutoIncrementProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.BlockCompressionProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CharacterSetProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ChecksumProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CollateProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Cluster'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ClusteredByProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DataBlocksizeProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.DefinerProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.DictRange'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DictProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DistKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DistStyleProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.EngineProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExternalProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.FallbackProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.FileFormatProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.FreespaceProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.HeapProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.IsolatedLoadingProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.JournalProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.LanguageProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LikeProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.LocationProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LockingProperty'>: <Location.POST_ALIAS: 'POST_ALIAS'>, <class 'sqlglot.expressions.LogProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.MaterializedProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.MergeBlockRatioProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.NoPrimaryIndexProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.OnProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.OnCommitProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.Order'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.PartitionedByProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.PrimaryKey'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Property'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.ReturnsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatDelimitedProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatSerdeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SampleProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SchemaCommentProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SerdeProperties'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Set'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SettingsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SetProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.SortKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.StabilityProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.TemporaryProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.ToTableProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.TransientProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.MergeTreeTTL'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.VolatileProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.WithDataProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <Location.POST_NAME: 'POST_NAME'>} + {<class 'sqlglot.expressions.AlgorithmProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.AutoIncrementProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.BlockCompressionProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CharacterSetProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ChecksumProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CollateProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Cluster'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ClusteredByProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DataBlocksizeProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.DefinerProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.DictRange'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DictProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DistKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DistStyleProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.EngineProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExternalProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.FallbackProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.FileFormatProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.FreespaceProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.HeapProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.InputModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.IsolatedLoadingProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.JournalProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.LanguageProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LikeProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.LocationProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LockingProperty'>: <Location.POST_ALIAS: 'POST_ALIAS'>, <class 'sqlglot.expressions.LogProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.MaterializedProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.MergeBlockRatioProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.NoPrimaryIndexProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.OnProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.OnCommitProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.Order'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.OutputModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.PartitionedByProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.PrimaryKey'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Property'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.RemoteWithConnectionModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ReturnsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatDelimitedProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatSerdeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SampleProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SchemaCommentProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SerdeProperties'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Set'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SettingsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SetProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.SortKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.StabilityProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.TemporaryProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.ToTableProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.TransientProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.TransformModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.MergeTreeTTL'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.VolatileProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.WithDataProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <Location.POST_NAME: 'POST_NAME'>}
    @@ -1567,7 +1654,7 @@ Default: True
    TRANSFORMS = - {<class 'sqlglot.expressions.DateAdd'>: <function Redshift.Generator.<lambda>>, <class 'sqlglot.expressions.TsOrDsAdd'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CaseSpecificColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CheckColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CollateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CommentColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DateFormatColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DefaultColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EncodeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExternalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.HeapProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InlineLengthColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.IntervalSpan'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LanguageProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LocationProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LogProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.MaterializedProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NoPrimaryIndexProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NonClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NotForReplicationColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnCommitProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnUpdateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PathColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ReturnsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SampleProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SettingsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StabilityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TemporaryProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ToTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TransientProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TitleColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UppercaseColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VarMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VolatileProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Array'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.ArrayConcat'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.ArrayContained'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.ArrayContains'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.ArrayOverlaps'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.BitwiseXor'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.ColumnDef'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.CurrentDate'>: <function no_paren_current_date_sql>, <class 'sqlglot.expressions.CurrentTimestamp'>: <function Redshift.Generator.<lambda>>, <class 'sqlglot.expressions.DateDiff'>: <function Redshift.Generator.<lambda>>, <class 'sqlglot.expressions.DateStrToDate'>: <function datestrtodate_sql>, <class 'sqlglot.expressions.DataType'>: <function _datatype_sql>, <class 'sqlglot.expressions.DateSub'>: <function _date_add_sql.<locals>.func>, <class 'sqlglot.expressions.Explode'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.GroupConcat'>: <function _string_agg_sql>, <class 'sqlglot.expressions.JSONExtract'>: <function _json_sql>, <class 'sqlglot.expressions.JSONExtractScalar'>: <function _json_sql>, <class 'sqlglot.expressions.JSONBExtract'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.JSONBExtractScalar'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.JSONBContains'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.LogicalOr'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.LogicalAnd'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Max'>: <function max_or_greatest>, <class 'sqlglot.expressions.MapFromEntries'>: <function no_map_from_entries_sql>, <class 'sqlglot.expressions.Min'>: <function min_or_least>, <class 'sqlglot.expressions.Merge'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.PercentileCont'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.PercentileDisc'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.RegexpLike'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.RegexpILike'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.Select'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.StrPosition'>: <function str_position_sql>, <class 'sqlglot.expressions.StrToTime'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.StructExtract'>: <function struct_extract_sql>, <class 'sqlglot.expressions.Substring'>: <function _substring_sql>, <class 'sqlglot.expressions.TimestampTrunc'>: <function timestamptrunc_sql>, <class 'sqlglot.expressions.TimeStrToTime'>: <function timestrtotime_sql>, <class 'sqlglot.expressions.TimeToStr'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.TableSample'>: <function no_tablesample_sql>, <class 'sqlglot.expressions.ToChar'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.Trim'>: <function trim_sql>, <class 'sqlglot.expressions.TryCast'>: <function no_trycast_sql>, <class 'sqlglot.expressions.TsOrDsToDate'>: <function ts_or_ds_to_date_sql.<locals>._ts_or_ds_to_date_sql>, <class 'sqlglot.expressions.UnixToTime'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.Xor'>: <function bool_xor_sql>, <class 'sqlglot.expressions.Concat'>: <function concat_to_dpipe_sql>, <class 'sqlglot.expressions.ConcatWs'>: <function concat_ws_to_dpipe_sql>, <class 'sqlglot.expressions.DistKeyProperty'>: <function Redshift.Generator.<lambda>>, <class 'sqlglot.expressions.DistStyleProperty'>: <function Redshift.Generator.<lambda>>, <class 'sqlglot.expressions.FromBase'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.SafeConcat'>: <function concat_to_dpipe_sql>, <class 'sqlglot.expressions.SortKeyProperty'>: <function Redshift.Generator.<lambda>>} + {<class 'sqlglot.expressions.DateAdd'>: <function Redshift.Generator.<lambda>>, <class 'sqlglot.expressions.TsOrDsAdd'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CaseSpecificColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CheckColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CollateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CommentColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DateFormatColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DefaultColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EncodeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExternalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.HeapProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InlineLengthColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InputModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.IntervalSpan'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LanguageProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LocationProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LogProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.MaterializedProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NoPrimaryIndexProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NonClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NotForReplicationColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnCommitProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnUpdateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OutputModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PathColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.RemoteWithConnectionModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ReturnsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SampleProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SettingsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StabilityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TemporaryProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ToTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TransientProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TransformModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TitleColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UppercaseColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VarMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VolatileProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Array'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.ArrayConcat'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.ArrayContained'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.ArrayContains'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.ArrayOverlaps'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.BitwiseXor'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.ColumnDef'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.CurrentDate'>: <function no_paren_current_date_sql>, <class 'sqlglot.expressions.CurrentTimestamp'>: <function Redshift.Generator.<lambda>>, <class 'sqlglot.expressions.DateDiff'>: <function Redshift.Generator.<lambda>>, <class 'sqlglot.expressions.DateStrToDate'>: <function datestrtodate_sql>, <class 'sqlglot.expressions.DataType'>: <function _datatype_sql>, <class 'sqlglot.expressions.DateSub'>: <function _date_add_sql.<locals>.func>, <class 'sqlglot.expressions.Explode'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.GroupConcat'>: <function _string_agg_sql>, <class 'sqlglot.expressions.JSONExtract'>: <function _json_sql>, <class 'sqlglot.expressions.JSONExtractScalar'>: <function _json_sql>, <class 'sqlglot.expressions.JSONBExtract'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.JSONBExtractScalar'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.JSONBContains'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.LogicalOr'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.LogicalAnd'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Max'>: <function max_or_greatest>, <class 'sqlglot.expressions.MapFromEntries'>: <function no_map_from_entries_sql>, <class 'sqlglot.expressions.Min'>: <function min_or_least>, <class 'sqlglot.expressions.Merge'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.PercentileCont'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.PercentileDisc'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.RegexpLike'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.RegexpILike'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.Select'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.StrPosition'>: <function str_position_sql>, <class 'sqlglot.expressions.StrToTime'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.StructExtract'>: <function struct_extract_sql>, <class 'sqlglot.expressions.Substring'>: <function _substring_sql>, <class 'sqlglot.expressions.TimestampTrunc'>: <function timestamptrunc_sql>, <class 'sqlglot.expressions.TimeStrToTime'>: <function timestrtotime_sql>, <class 'sqlglot.expressions.TimeToStr'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.TableSample'>: <function no_tablesample_sql>, <class 'sqlglot.expressions.ToChar'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.Trim'>: <function trim_sql>, <class 'sqlglot.expressions.TryCast'>: <function no_trycast_sql>, <class 'sqlglot.expressions.TsOrDsToDate'>: <function ts_or_ds_to_date_sql.<locals>._ts_or_ds_to_date_sql>, <class 'sqlglot.expressions.UnixToTime'>: <function Postgres.Generator.<lambda>>, <class 'sqlglot.expressions.VariancePop'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Variance'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Xor'>: <function bool_xor_sql>, <class 'sqlglot.expressions.Concat'>: <function concat_to_dpipe_sql>, <class 'sqlglot.expressions.ConcatWs'>: <function concat_ws_to_dpipe_sql>, <class 'sqlglot.expressions.DistKeyProperty'>: <function Redshift.Generator.<lambda>>, <class 'sqlglot.expressions.DistStyleProperty'>: <function Redshift.Generator.<lambda>>, <class 'sqlglot.expressions.FromBase'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.SafeConcat'>: <function concat_to_dpipe_sql>, <class 'sqlglot.expressions.SortKeyProperty'>: <function Redshift.Generator.<lambda>>}
    @@ -1599,9 +1686,9 @@ Default: True
    -
    160        def with_properties(self, properties: exp.Properties) -> str:
    -161            """Redshift doesn't have `WITH` as part of their with_properties so we remove it"""
    -162            return self.properties(properties, prefix=" ", suffix="")
    +            
    179        def with_properties(self, properties: exp.Properties) -> str:
    +180            """Redshift doesn't have `WITH` as part of their with_properties so we remove it"""
    +181            return self.properties(properties, prefix=" ", suffix="")
     
    @@ -1621,22 +1708,22 @@ Default: True
    -
    164        def datatype_sql(self, expression: exp.DataType) -> str:
    -165            """
    -166            Redshift converts the `TEXT` data type to `VARCHAR(255)` by default when people more generally mean
    -167            VARCHAR of max length which is `VARCHAR(max)` in Redshift. Therefore if we get a `TEXT` data type
    -168            without precision we convert it to `VARCHAR(max)` and if it does have precision then we just convert
    -169            `TEXT` to `VARCHAR`.
    -170            """
    -171            if expression.is_type("text"):
    -172                expression = expression.copy()
    -173                expression.set("this", exp.DataType.Type.VARCHAR)
    -174                precision = expression.args.get("expressions")
    -175
    -176                if not precision:
    -177                    expression.append("expressions", exp.var("MAX"))
    -178
    -179            return super().datatype_sql(expression)
    +            
    183        def datatype_sql(self, expression: exp.DataType) -> str:
    +184            """
    +185            Redshift converts the `TEXT` data type to `VARCHAR(255)` by default when people more generally mean
    +186            VARCHAR of max length which is `VARCHAR(max)` in Redshift. Therefore if we get a `TEXT` data type
    +187            without precision we convert it to `VARCHAR(max)` and if it does have precision then we just convert
    +188            `TEXT` to `VARCHAR`.
    +189            """
    +190            if expression.is_type("text"):
    +191                expression = expression.copy()
    +192                expression.set("this", exp.DataType.Type.VARCHAR)
    +193                precision = expression.args.get("expressions")
    +194
    +195                if not precision:
    +196                    expression.append("expressions", exp.var("MAX"))
    +197
    +198            return super().datatype_sql(expression)
     
    @@ -1697,6 +1784,18 @@ without precision we convert it to VARCHAR(max) and if it does have +
    +
    +
    + INDEX_OFFSET = +0 + + +
    + + + +
    @@ -2202,6 +2301,7 @@ without precision we convert it to VARCHAR(max) and if it does have
    comprehension_sql
    columnprefix_sql
    opclass_sql
    +
    predict_sql
    sqlglot.dialects.postgres.Postgres.Generator
    @@ -2211,7 +2311,6 @@ without precision we convert it to VARCHAR(max) and if it does have
    PARAMETER_TOKEN
    bracket_sql
    matchagainst_sql
    -
    INDEX_OFFSET
    NULL_ORDERING
    -- cgit v1.2.3