sqlglot.dialects.postgres
1from __future__ import annotations 2 3from sqlglot import exp, tokens 4from sqlglot.dialects.dialect import Dialect 5from sqlglot.generators.postgres import PostgresGenerator 6from sqlglot.parsers.postgres import PostgresParser 7from sqlglot.tokens import TokenType 8from sqlglot.typing.postgres import EXPRESSION_METADATA 9 10 11class Postgres(Dialect): 12 EXPRESSION_METADATA = EXPRESSION_METADATA.copy() 13 INDEX_OFFSET = 1 14 ASCII_ONLY_NORMALIZATION = True 15 # Normalizing `x IS NOT NULL` to `NOT x IS NULL` is unsafe due to row values, 16 # e.g. `ROW(1, NULL) IS NOT NULL` is false whereas `NOT ROW(1, NULL) IS NULL` is true 17 NORMALIZE_NOT_NULL = False 18 TYPED_DIVISION = True 19 CONCAT_COALESCE = True 20 CONCAT_WS_COALESCE = True 21 NULL_ORDERING = "nulls_are_large" 22 SUPPORTS_LIMIT_ALL = True 23 TIME_FORMAT = "'YYYY-MM-DD HH24:MI:SS'" 24 TABLESAMPLE_SIZE_IS_PERCENT = True 25 TABLES_REFERENCEABLE_AS_COLUMNS = True 26 27 DEFAULT_FUNCTIONS_COLUMN_NAMES = { 28 exp.ExplodingGenerateSeries: "generate_series", 29 } 30 31 TIME_MAPPING = { 32 "d": "%u", # 1-based day of week 33 "D": "%u", # 1-based day of week 34 "dd": "%d", # day of month 35 "DD": "%d", # day of month 36 "ddd": "%j", # zero padded day of year 37 "DDD": "%j", # zero padded day of year 38 "FMDD": "%-d", # - is no leading zero for Python; same for FM in postgres 39 "FMDDD": "%-j", # day of year 40 "FMHH12": "%-I", # 9 41 "FMHH24": "%-H", # 9 42 "FMMI": "%-M", # Minute 43 "FMMM": "%-m", # 1 44 "FMSS": "%-S", # Second 45 "HH12": "%I", # 09 46 "HH24": "%H", # 09 47 "mi": "%M", # zero padded minute 48 "MI": "%M", # zero padded minute 49 "mm": "%m", # 01 50 "MM": "%m", # 01 51 "OF": "%z", # utc offset 52 "ss": "%S", # zero padded second 53 "SS": "%S", # zero padded second 54 "TMDay": "%A", # TM is locale dependent 55 "TMDy": "%a", 56 "TMMon": "%b", # Sep 57 "TMMonth": "%B", # September 58 "day": "%Aenlower", # tuesday 59 "dy": "%aenlower", # tue 60 "TZ": "%Z", # uppercase timezone name 61 "US": "%f", # zero padded microsecond 62 "ww": "%U", # 1-based week of year 63 "WW": "%U", # 1-based week of year 64 "yy": "%y", # 15 65 "YY": "%y", # 15 66 "yyy": "%Ythree", # 015 67 "YYY": "%Ythree", # 015 68 "yyyy": "%Y", # 2015 69 "YYYY": "%Y", # 2015 70 } 71 72 class Tokenizer(tokens.Tokenizer): 73 BIT_STRINGS = [("b'", "'"), ("B'", "'")] 74 HEX_STRINGS = [("x'", "'"), ("X'", "'")] 75 BYTE_STRINGS = [("e'", "'"), ("E'", "'")] 76 UNICODE_STRINGS = [("U&'", "'"), ("u&'", "'")] 77 BYTE_STRING_ESCAPES = ["'", "\\"] 78 HEREDOC_STRINGS = ["$"] 79 80 HEREDOC_TAG_IS_IDENTIFIER = True 81 HEREDOC_STRING_ALTERNATIVE = TokenType.PARAMETER 82 83 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.LOCK} 84 85 KEYWORDS = { 86 **tokens.Tokenizer.KEYWORDS, 87 "~": TokenType.RLIKE, 88 "@@": TokenType.DAT, 89 "@?": TokenType.AT_QMARK, 90 "@>": TokenType.AT_GT, 91 "<@": TokenType.LT_AT, 92 "?&": TokenType.QMARK_AMP, 93 "?|": TokenType.QMARK_PIPE, 94 "#-": TokenType.HASH_DASH, 95 "|/": TokenType.PIPE_SLASH, 96 "||/": TokenType.DPIPE_SLASH, 97 "BEGIN": TokenType.BEGIN, 98 "BIGSERIAL": TokenType.BIGSERIAL, 99 "CSTRING": TokenType.PSEUDO_TYPE, 100 "DECLARE": TokenType.COMMAND, 101 "DO": TokenType.COMMAND, 102 "EXEC": TokenType.COMMAND, 103 "HSTORE": TokenType.HSTORE, 104 "INT8": TokenType.BIGINT, 105 "MONEY": TokenType.MONEY, 106 "NAME": TokenType.NAME, 107 "OID": TokenType.OBJECT_IDENTIFIER, 108 "ONLY": TokenType.ONLY, 109 "POINT": TokenType.POINT, 110 "REFRESH": TokenType.COMMAND, 111 "REINDEX": TokenType.COMMAND, 112 "RESET": TokenType.COMMAND, 113 "SERIAL": TokenType.SERIAL, 114 "SMALLSERIAL": TokenType.SMALLSERIAL, 115 "TEMP": TokenType.TEMPORARY, 116 "TYPE": TokenType.TYPE, 117 "REGCLASS": TokenType.OBJECT_IDENTIFIER, 118 "REGCOLLATION": TokenType.OBJECT_IDENTIFIER, 119 "REGCONFIG": TokenType.OBJECT_IDENTIFIER, 120 "REGDICTIONARY": TokenType.OBJECT_IDENTIFIER, 121 "REGNAMESPACE": TokenType.OBJECT_IDENTIFIER, 122 "REGOPER": TokenType.OBJECT_IDENTIFIER, 123 "REGOPERATOR": TokenType.OBJECT_IDENTIFIER, 124 "REGPROC": TokenType.OBJECT_IDENTIFIER, 125 "REGPROCEDURE": TokenType.OBJECT_IDENTIFIER, 126 "REGROLE": TokenType.OBJECT_IDENTIFIER, 127 "REGTYPE": TokenType.OBJECT_IDENTIFIER, 128 "FLOAT": TokenType.DOUBLE, 129 "XML": TokenType.XML, 130 "VARIADIC": TokenType.VARIADIC, 131 "INOUT": TokenType.INOUT, 132 } 133 KEYWORDS.pop("/*+") 134 KEYWORDS.pop("DIV") 135 136 SINGLE_TOKENS = { 137 **tokens.Tokenizer.SINGLE_TOKENS, 138 "$": TokenType.HEREDOC_STRING, 139 } 140 141 VAR_SINGLE_TOKENS = {"$"} 142 143 Parser = PostgresParser 144 145 Generator = PostgresGenerator
12class Postgres(Dialect): 13 EXPRESSION_METADATA = EXPRESSION_METADATA.copy() 14 INDEX_OFFSET = 1 15 ASCII_ONLY_NORMALIZATION = True 16 # Normalizing `x IS NOT NULL` to `NOT x IS NULL` is unsafe due to row values, 17 # e.g. `ROW(1, NULL) IS NOT NULL` is false whereas `NOT ROW(1, NULL) IS NULL` is true 18 NORMALIZE_NOT_NULL = False 19 TYPED_DIVISION = True 20 CONCAT_COALESCE = True 21 CONCAT_WS_COALESCE = True 22 NULL_ORDERING = "nulls_are_large" 23 SUPPORTS_LIMIT_ALL = True 24 TIME_FORMAT = "'YYYY-MM-DD HH24:MI:SS'" 25 TABLESAMPLE_SIZE_IS_PERCENT = True 26 TABLES_REFERENCEABLE_AS_COLUMNS = True 27 28 DEFAULT_FUNCTIONS_COLUMN_NAMES = { 29 exp.ExplodingGenerateSeries: "generate_series", 30 } 31 32 TIME_MAPPING = { 33 "d": "%u", # 1-based day of week 34 "D": "%u", # 1-based day of week 35 "dd": "%d", # day of month 36 "DD": "%d", # day of month 37 "ddd": "%j", # zero padded day of year 38 "DDD": "%j", # zero padded day of year 39 "FMDD": "%-d", # - is no leading zero for Python; same for FM in postgres 40 "FMDDD": "%-j", # day of year 41 "FMHH12": "%-I", # 9 42 "FMHH24": "%-H", # 9 43 "FMMI": "%-M", # Minute 44 "FMMM": "%-m", # 1 45 "FMSS": "%-S", # Second 46 "HH12": "%I", # 09 47 "HH24": "%H", # 09 48 "mi": "%M", # zero padded minute 49 "MI": "%M", # zero padded minute 50 "mm": "%m", # 01 51 "MM": "%m", # 01 52 "OF": "%z", # utc offset 53 "ss": "%S", # zero padded second 54 "SS": "%S", # zero padded second 55 "TMDay": "%A", # TM is locale dependent 56 "TMDy": "%a", 57 "TMMon": "%b", # Sep 58 "TMMonth": "%B", # September 59 "day": "%Aenlower", # tuesday 60 "dy": "%aenlower", # tue 61 "TZ": "%Z", # uppercase timezone name 62 "US": "%f", # zero padded microsecond 63 "ww": "%U", # 1-based week of year 64 "WW": "%U", # 1-based week of year 65 "yy": "%y", # 15 66 "YY": "%y", # 15 67 "yyy": "%Ythree", # 015 68 "YYY": "%Ythree", # 015 69 "yyyy": "%Y", # 2015 70 "YYYY": "%Y", # 2015 71 } 72 73 class Tokenizer(tokens.Tokenizer): 74 BIT_STRINGS = [("b'", "'"), ("B'", "'")] 75 HEX_STRINGS = [("x'", "'"), ("X'", "'")] 76 BYTE_STRINGS = [("e'", "'"), ("E'", "'")] 77 UNICODE_STRINGS = [("U&'", "'"), ("u&'", "'")] 78 BYTE_STRING_ESCAPES = ["'", "\\"] 79 HEREDOC_STRINGS = ["$"] 80 81 HEREDOC_TAG_IS_IDENTIFIER = True 82 HEREDOC_STRING_ALTERNATIVE = TokenType.PARAMETER 83 84 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.LOCK} 85 86 KEYWORDS = { 87 **tokens.Tokenizer.KEYWORDS, 88 "~": TokenType.RLIKE, 89 "@@": TokenType.DAT, 90 "@?": TokenType.AT_QMARK, 91 "@>": TokenType.AT_GT, 92 "<@": TokenType.LT_AT, 93 "?&": TokenType.QMARK_AMP, 94 "?|": TokenType.QMARK_PIPE, 95 "#-": TokenType.HASH_DASH, 96 "|/": TokenType.PIPE_SLASH, 97 "||/": TokenType.DPIPE_SLASH, 98 "BEGIN": TokenType.BEGIN, 99 "BIGSERIAL": TokenType.BIGSERIAL, 100 "CSTRING": TokenType.PSEUDO_TYPE, 101 "DECLARE": TokenType.COMMAND, 102 "DO": TokenType.COMMAND, 103 "EXEC": TokenType.COMMAND, 104 "HSTORE": TokenType.HSTORE, 105 "INT8": TokenType.BIGINT, 106 "MONEY": TokenType.MONEY, 107 "NAME": TokenType.NAME, 108 "OID": TokenType.OBJECT_IDENTIFIER, 109 "ONLY": TokenType.ONLY, 110 "POINT": TokenType.POINT, 111 "REFRESH": TokenType.COMMAND, 112 "REINDEX": TokenType.COMMAND, 113 "RESET": TokenType.COMMAND, 114 "SERIAL": TokenType.SERIAL, 115 "SMALLSERIAL": TokenType.SMALLSERIAL, 116 "TEMP": TokenType.TEMPORARY, 117 "TYPE": TokenType.TYPE, 118 "REGCLASS": TokenType.OBJECT_IDENTIFIER, 119 "REGCOLLATION": TokenType.OBJECT_IDENTIFIER, 120 "REGCONFIG": TokenType.OBJECT_IDENTIFIER, 121 "REGDICTIONARY": TokenType.OBJECT_IDENTIFIER, 122 "REGNAMESPACE": TokenType.OBJECT_IDENTIFIER, 123 "REGOPER": TokenType.OBJECT_IDENTIFIER, 124 "REGOPERATOR": TokenType.OBJECT_IDENTIFIER, 125 "REGPROC": TokenType.OBJECT_IDENTIFIER, 126 "REGPROCEDURE": TokenType.OBJECT_IDENTIFIER, 127 "REGROLE": TokenType.OBJECT_IDENTIFIER, 128 "REGTYPE": TokenType.OBJECT_IDENTIFIER, 129 "FLOAT": TokenType.DOUBLE, 130 "XML": TokenType.XML, 131 "VARIADIC": TokenType.VARIADIC, 132 "INOUT": TokenType.INOUT, 133 } 134 KEYWORDS.pop("/*+") 135 KEYWORDS.pop("DIV") 136 137 SINGLE_TOKENS = { 138 **tokens.Tokenizer.SINGLE_TOKENS, 139 "$": TokenType.HEREDOC_STRING, 140 } 141 142 VAR_SINGLE_TOKENS = {"$"} 143 144 Parser = PostgresParser 145 146 Generator = PostgresGenerator
Whether identifiers are only normalized with respect to ASCII characters, e.g. Ä and
ä are different identifiers in DuckDB, but the same identifier in Spark.
Whether the behavior of a / b depends on the types of a and b.
False means a / b is always float division.
True means a / b is integer division if both a and b are integers.
A NULL arg in CONCAT yields NULL by default, but in some dialects it yields an empty string.
A NULL arg in CONCAT_WS yields NULL by default, but in some dialects it is skipped.
Default NULL ordering method to use if not explicitly set.
Possible values: "nulls_are_small", "nulls_are_large", "nulls_are_last"
Whether table names can be referenced as columns (treated as structs).
BigQuery allows tables to be referenced as columns in queries, automatically treating them as struct values containing all the table's columns.
For example, in BigQuery: SELECT t FROM my_table AS t -- Returns entire row as a struct
Maps function expressions to their default output column name(s).
For example, in Postgres, generate_series function outputs a column named "generate_series" by default, so we map the ExplodingGenerateSeries expression to "generate_series" string.
Associates this dialect's time formats with their equivalent Python strftime formats.
Mapping of an escaped sequence (\n) to its unescaped version (
).
Whether string literals support escape sequences (e.g. \n). Set by the metaclass based on the tokenizer's STRING_ESCAPES.
Whether byte string literals support escape sequences. Set by the metaclass based on the tokenizer's BYTE_STRING_ESCAPES.
73 class Tokenizer(tokens.Tokenizer): 74 BIT_STRINGS = [("b'", "'"), ("B'", "'")] 75 HEX_STRINGS = [("x'", "'"), ("X'", "'")] 76 BYTE_STRINGS = [("e'", "'"), ("E'", "'")] 77 UNICODE_STRINGS = [("U&'", "'"), ("u&'", "'")] 78 BYTE_STRING_ESCAPES = ["'", "\\"] 79 HEREDOC_STRINGS = ["$"] 80 81 HEREDOC_TAG_IS_IDENTIFIER = True 82 HEREDOC_STRING_ALTERNATIVE = TokenType.PARAMETER 83 84 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.LOCK} 85 86 KEYWORDS = { 87 **tokens.Tokenizer.KEYWORDS, 88 "~": TokenType.RLIKE, 89 "@@": TokenType.DAT, 90 "@?": TokenType.AT_QMARK, 91 "@>": TokenType.AT_GT, 92 "<@": TokenType.LT_AT, 93 "?&": TokenType.QMARK_AMP, 94 "?|": TokenType.QMARK_PIPE, 95 "#-": TokenType.HASH_DASH, 96 "|/": TokenType.PIPE_SLASH, 97 "||/": TokenType.DPIPE_SLASH, 98 "BEGIN": TokenType.BEGIN, 99 "BIGSERIAL": TokenType.BIGSERIAL, 100 "CSTRING": TokenType.PSEUDO_TYPE, 101 "DECLARE": TokenType.COMMAND, 102 "DO": TokenType.COMMAND, 103 "EXEC": TokenType.COMMAND, 104 "HSTORE": TokenType.HSTORE, 105 "INT8": TokenType.BIGINT, 106 "MONEY": TokenType.MONEY, 107 "NAME": TokenType.NAME, 108 "OID": TokenType.OBJECT_IDENTIFIER, 109 "ONLY": TokenType.ONLY, 110 "POINT": TokenType.POINT, 111 "REFRESH": TokenType.COMMAND, 112 "REINDEX": TokenType.COMMAND, 113 "RESET": TokenType.COMMAND, 114 "SERIAL": TokenType.SERIAL, 115 "SMALLSERIAL": TokenType.SMALLSERIAL, 116 "TEMP": TokenType.TEMPORARY, 117 "TYPE": TokenType.TYPE, 118 "REGCLASS": TokenType.OBJECT_IDENTIFIER, 119 "REGCOLLATION": TokenType.OBJECT_IDENTIFIER, 120 "REGCONFIG": TokenType.OBJECT_IDENTIFIER, 121 "REGDICTIONARY": TokenType.OBJECT_IDENTIFIER, 122 "REGNAMESPACE": TokenType.OBJECT_IDENTIFIER, 123 "REGOPER": TokenType.OBJECT_IDENTIFIER, 124 "REGOPERATOR": TokenType.OBJECT_IDENTIFIER, 125 "REGPROC": TokenType.OBJECT_IDENTIFIER, 126 "REGPROCEDURE": TokenType.OBJECT_IDENTIFIER, 127 "REGROLE": TokenType.OBJECT_IDENTIFIER, 128 "REGTYPE": TokenType.OBJECT_IDENTIFIER, 129 "FLOAT": TokenType.DOUBLE, 130 "XML": TokenType.XML, 131 "VARIADIC": TokenType.VARIADIC, 132 "INOUT": TokenType.INOUT, 133 } 134 KEYWORDS.pop("/*+") 135 KEYWORDS.pop("DIV") 136 137 SINGLE_TOKENS = { 138 **tokens.Tokenizer.SINGLE_TOKENS, 139 "$": TokenType.HEREDOC_STRING, 140 } 141 142 VAR_SINGLE_TOKENS = {"$"}
Inherited Members
- sqlglot.tokens.Tokenizer
- Tokenizer
- RAW_STRINGS
- IDENTIFIERS
- QUOTES
- STRING_ESCAPES
- ESCAPE_FOLLOW_CHARS
- IDENTIFIER_ESCAPES
- STRING_ESCAPES_ALLOWED_IN_RAW_STRINGS
- NESTED_COMMENTS
- HINT_START
- TOKENS_PRECEDING_HINT
- COMMAND_PREFIX_TOKENS
- NUMERIC_LITERALS
- NUMBERS_CAN_HAVE_DECIMALS
- COMMENTS
- dialect
- tokenize
- sql
- size
- tokens