summaryrefslogtreecommitdiffstats
path: root/sqlglot/dialects/teradata.py
diff options
context:
space:
mode:
Diffstat (limited to 'sqlglot/dialects/teradata.py')
-rw-r--r--sqlglot/dialects/teradata.py87
1 files changed, 87 insertions, 0 deletions
diff --git a/sqlglot/dialects/teradata.py b/sqlglot/dialects/teradata.py
new file mode 100644
index 0000000..4340820
--- /dev/null
+++ b/sqlglot/dialects/teradata.py
@@ -0,0 +1,87 @@
+from __future__ import annotations
+
+from sqlglot import exp, generator, parser
+from sqlglot.dialects.dialect import Dialect
+from sqlglot.tokens import TokenType
+
+
+class Teradata(Dialect):
+ class Parser(parser.Parser):
+ CHARSET_TRANSLATORS = {
+ "GRAPHIC_TO_KANJISJIS",
+ "GRAPHIC_TO_LATIN",
+ "GRAPHIC_TO_UNICODE",
+ "GRAPHIC_TO_UNICODE_PadSpace",
+ "KANJI1_KanjiEBCDIC_TO_UNICODE",
+ "KANJI1_KanjiEUC_TO_UNICODE",
+ "KANJI1_KANJISJIS_TO_UNICODE",
+ "KANJI1_SBC_TO_UNICODE",
+ "KANJISJIS_TO_GRAPHIC",
+ "KANJISJIS_TO_LATIN",
+ "KANJISJIS_TO_UNICODE",
+ "LATIN_TO_GRAPHIC",
+ "LATIN_TO_KANJISJIS",
+ "LATIN_TO_UNICODE",
+ "LOCALE_TO_UNICODE",
+ "UNICODE_TO_GRAPHIC",
+ "UNICODE_TO_GRAPHIC_PadGraphic",
+ "UNICODE_TO_GRAPHIC_VarGraphic",
+ "UNICODE_TO_KANJI1_KanjiEBCDIC",
+ "UNICODE_TO_KANJI1_KanjiEUC",
+ "UNICODE_TO_KANJI1_KANJISJIS",
+ "UNICODE_TO_KANJI1_SBC",
+ "UNICODE_TO_KANJISJIS",
+ "UNICODE_TO_LATIN",
+ "UNICODE_TO_LOCALE",
+ "UNICODE_TO_UNICODE_FoldSpace",
+ "UNICODE_TO_UNICODE_Fullwidth",
+ "UNICODE_TO_UNICODE_Halfwidth",
+ "UNICODE_TO_UNICODE_NFC",
+ "UNICODE_TO_UNICODE_NFD",
+ "UNICODE_TO_UNICODE_NFKC",
+ "UNICODE_TO_UNICODE_NFKD",
+ }
+
+ FUNCTION_PARSERS = {
+ **parser.Parser.FUNCTION_PARSERS, # type: ignore
+ "TRANSLATE": lambda self: self._parse_translate(self.STRICT_CAST),
+ }
+
+ def _parse_translate(self, strict: bool) -> exp.Expression:
+ this = self._parse_conjunction()
+
+ if not self._match(TokenType.USING):
+ self.raise_error("Expected USING in TRANSLATE")
+
+ if self._match_texts(self.CHARSET_TRANSLATORS):
+ charset_split = self._prev.text.split("_TO_")
+ to = self.expression(exp.CharacterSet, this=charset_split[1])
+ else:
+ self.raise_error("Expected a character set translator after USING in TRANSLATE")
+
+ return self.expression(exp.Cast if strict else exp.TryCast, this=this, to=to)
+
+ # FROM before SET in Teradata UPDATE syntax
+ # https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/Teradata-VantageTM-SQL-Data-Manipulation-Language-17.20/Statement-Syntax/UPDATE/UPDATE-Syntax-Basic-Form-FROM-Clause
+ def _parse_update(self) -> exp.Expression:
+ return self.expression(
+ exp.Update,
+ **{ # type: ignore
+ "this": self._parse_table(alias_tokens=self.UPDATE_ALIAS_TOKENS),
+ "from": self._parse_from(),
+ "expressions": self._match(TokenType.SET)
+ and self._parse_csv(self._parse_equality),
+ "where": self._parse_where(),
+ },
+ )
+
+ class Generator(generator.Generator):
+ # FROM before SET in Teradata UPDATE syntax
+ # https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/Teradata-VantageTM-SQL-Data-Manipulation-Language-17.20/Statement-Syntax/UPDATE/UPDATE-Syntax-Basic-Form-FROM-Clause
+ def update_sql(self, expression: exp.Update) -> str:
+ this = self.sql(expression, "this")
+ from_sql = self.sql(expression, "from")
+ set_sql = self.expressions(expression, flat=True)
+ where_sql = self.sql(expression, "where")
+ sql = f"UPDATE {this}{from_sql} SET {set_sql}{where_sql}"
+ return self.prepend_ctes(expression, sql)