Skip to content
This repository was archived by the owner on May 17, 2024. It is now read-only.

Commit cc66fd4

Browse files
author
Sergey Vasilyev
committed
Compile all AST elements always via dialects, never directly
The root authority on how to do the SQL syntax properly is the dialect — not the AST element itself. AST tree must only carry the intentions of what we want to execute, but not how it should/could be executed. This makes the AST truly independent of dialects and databases, allowing us to: - Focus on the main logic regardless of the SQL capabilities. - Create custom database connectors without involving AST changes every time. Before the change, adding a new database connector with unusual syntax would often require changing the AST elements to direct to `compiler.dialect.some_method()` — with only a subset of SQL being described in dialects. The other rather arbitrary part of SQL syntax was hard-coded in AST elements and could not be easily overridden without such changes. After the change, all the SQL logic is concentrated in one hierarchy of dialects, mostly in one base class.
1 parent e5b6150 commit cc66fd4

File tree

8 files changed

+475
-377
lines changed

8 files changed

+475
-377
lines changed

data_diff/abcs/compiler.py

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
1-
from typing import Any, Dict
2-
from abc import ABC, abstractmethod
1+
from abc import ABC
32

43

54
class AbstractCompiler(ABC):
6-
@abstractmethod
7-
def compile(self, elem: Any, params: Dict[str, Any] = None) -> str:
8-
...
5+
pass
96

107

118
class Compilable(ABC):
12-
# TODO generic syntax, so we can write Compilable[T] for expressions returning a value of type T
13-
@abstractmethod
14-
def compile(self, c: AbstractCompiler) -> str:
15-
...
9+
pass

data_diff/abcs/database_types.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import decimal
22
from abc import ABC, abstractmethod
3-
from typing import Sequence, Optional, Tuple, Type, Union, Dict, List
3+
from typing import Sequence, Optional, Tuple, Union, Dict, List
44
from datetime import datetime
55

66
from runtype import dataclass
77
from typing_extensions import Self
88

9+
from data_diff.abcs.compiler import AbstractCompiler
910
from data_diff.utils import ArithAlphanumeric, ArithUUID, Unknown
1011

1112

@@ -176,6 +177,10 @@ class UnknownColType(ColType):
176177
class AbstractDialect(ABC):
177178
"""Dialect-dependent query expressions"""
178179

180+
@abstractmethod
181+
def compile(self, compiler: AbstractCompiler, elem, params=None) -> str:
182+
raise NotImplementedError
183+
179184
@abstractmethod
180185
def parse_table_name(self, name: str) -> DbPath:
181186
"Parse the given table name into a DbPath"

data_diff/bound_exprs.py

-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from typing_extensions import Self
99

1010
from data_diff.abcs.database_types import AbstractDatabase
11-
from data_diff.abcs.compiler import AbstractCompiler
1211
from data_diff.queries.ast_classes import ExprNode, TablePath, Compilable
1312
from data_diff.queries.api import table
1413
from data_diff.schema import create_schema
@@ -37,10 +36,6 @@ def query(self, res_type=list):
3736
def type(self):
3837
return self.node.type
3938

40-
def compile(self, c: AbstractCompiler) -> str:
41-
assert c.database is self.database
42-
return self.node.compile(c)
43-
4439

4540
def bind_node(node, database):
4641
return BoundNode(database, node)

0 commit comments

Comments
 (0)