71 lines
2.7 KiB
Python
71 lines
2.7 KiB
Python
from sqlglot import exp, transforms
|
|
from sqlglot.dialects.dialect import Dialect, no_ilike_sql
|
|
from sqlglot.generator import Generator
|
|
from sqlglot.helper import csv
|
|
from sqlglot.tokens import Tokenizer, TokenType
|
|
|
|
|
|
def _limit_sql(self, expression):
|
|
return self.fetch_sql(exp.Fetch(direction="FIRST", count=expression.expression))
|
|
|
|
|
|
class Oracle(Dialect):
|
|
class Generator(Generator):
|
|
TYPE_MAPPING = {
|
|
**Generator.TYPE_MAPPING,
|
|
exp.DataType.Type.TINYINT: "NUMBER",
|
|
exp.DataType.Type.SMALLINT: "NUMBER",
|
|
exp.DataType.Type.INT: "NUMBER",
|
|
exp.DataType.Type.BIGINT: "NUMBER",
|
|
exp.DataType.Type.DECIMAL: "NUMBER",
|
|
exp.DataType.Type.DOUBLE: "DOUBLE PRECISION",
|
|
exp.DataType.Type.VARCHAR: "VARCHAR2",
|
|
exp.DataType.Type.NVARCHAR: "NVARCHAR2",
|
|
exp.DataType.Type.TEXT: "CLOB",
|
|
exp.DataType.Type.BINARY: "BLOB",
|
|
}
|
|
|
|
TRANSFORMS = {
|
|
**Generator.TRANSFORMS,
|
|
**transforms.UNALIAS_GROUP,
|
|
exp.ILike: no_ilike_sql,
|
|
exp.Limit: _limit_sql,
|
|
}
|
|
|
|
def query_modifiers(self, expression, *sqls):
|
|
return csv(
|
|
*sqls,
|
|
*[self.sql(sql) for sql in expression.args.get("laterals", [])],
|
|
*[self.sql(sql) for sql in expression.args.get("joins", [])],
|
|
self.sql(expression, "where"),
|
|
self.sql(expression, "group"),
|
|
self.sql(expression, "having"),
|
|
self.sql(expression, "qualify"),
|
|
self.sql(expression, "window"),
|
|
self.sql(expression, "distribute"),
|
|
self.sql(expression, "sort"),
|
|
self.sql(expression, "cluster"),
|
|
self.sql(expression, "order"),
|
|
self.sql(expression, "offset"), # offset before limit in oracle
|
|
self.sql(expression, "limit"),
|
|
sep="",
|
|
)
|
|
|
|
def alias_sql(self, expression):
|
|
if isinstance(expression.this, exp.Table):
|
|
to_sql = self.sql(expression, "alias")
|
|
# oracle does not allow "AS" between table and alias
|
|
to_sql = f" {to_sql}" if to_sql else ""
|
|
return f"{self.sql(expression, 'this')}{to_sql}"
|
|
return super().alias_sql(expression)
|
|
|
|
def offset_sql(self, expression):
|
|
return f"{super().offset_sql(expression)} ROWS"
|
|
|
|
class Tokenizer(Tokenizer):
|
|
KEYWORDS = {
|
|
**Tokenizer.KEYWORDS,
|
|
"TOP": TokenType.TOP,
|
|
"VARCHAR2": TokenType.VARCHAR,
|
|
"NVARCHAR2": TokenType.NVARCHAR,
|
|
}
|