buildaquery 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- buildaquery/__init__.py +0 -0
- buildaquery/abstract_syntax_tree/README.md +54 -0
- buildaquery/abstract_syntax_tree/__init__.py +1 -0
- buildaquery/abstract_syntax_tree/models.py +285 -0
- buildaquery/compiler/README.md +48 -0
- buildaquery/compiler/__init__.py +0 -0
- buildaquery/compiler/postgres/README.md +25 -0
- buildaquery/compiler/postgres/postgres_compiler.py +366 -0
- buildaquery/execution/README.md +42 -0
- buildaquery/execution/__init__.py +0 -0
- buildaquery/execution/base.py +33 -0
- buildaquery/execution/postgres.py +118 -0
- buildaquery/tests/test_ast.py +40 -0
- buildaquery/tests/test_compiler_postgres.py +343 -0
- buildaquery/tests/test_execution.py +56 -0
- buildaquery/tests/test_traversal.py +44 -0
- buildaquery/traversal/README.md +46 -0
- buildaquery/traversal/__init__.py +1 -0
- buildaquery/traversal/visitor_pattern.py +36 -0
- buildaquery-0.1.0.dist-info/METADATA +255 -0
- buildaquery-0.1.0.dist-info/RECORD +24 -0
- buildaquery-0.1.0.dist-info/WHEEL +4 -0
- buildaquery-0.1.0.dist-info/entry_points.txt +6 -0
- buildaquery-0.1.0.dist-info/licenses/LICENSE.txt +21 -0
buildaquery/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Abstract Syntax Tree (AST)
|
|
2
|
+
|
|
3
|
+
The `abstract_syntax_tree` module defines the data structures used to represent SQL queries as an Abstract Syntax Tree. This representation is agnostic of any specific SQL dialect and serves as the intermediate format that the query builder constructs and the compiler translates into SQL.
|
|
4
|
+
|
|
5
|
+
## Core Concepts
|
|
6
|
+
|
|
7
|
+
The AST is built using a hierarchy of nodes, all inheriting from the base `ASTNode` class.
|
|
8
|
+
|
|
9
|
+
### Node Categories
|
|
10
|
+
|
|
11
|
+
- **`ExpressionNode`**: Represents values, column references, and operations (e.g., `LiteralNode`, `ColumnNode`, `BinaryOperationNode`, `FunctionCallNode`).
|
|
12
|
+
- **`StatementNode`**: Represents complete SQL statements. Currently, `SelectStatementNode` is the primary implementation.
|
|
13
|
+
- **`FromClauseNode`**: Represents entities that can appear in a `FROM` clause, such as `TableNode` or `JoinClauseNode`.
|
|
14
|
+
|
|
15
|
+
## Key Components
|
|
16
|
+
|
|
17
|
+
- **`SelectStatementNode`**: The central node for `SELECT` queries. It encapsulates the select list, `FROM` table/joins, `WHERE` conditions, `GROUP BY`, `HAVING`, `ORDER BY`, and pagination (`LIMIT`, `OFFSET`, `TOP`).
|
|
18
|
+
- **`TopClauseNode`**: A specialized node for limiting results, particularly for dialects that support the `TOP` syntax. It is mutually exclusive with standard `LIMIT`/`OFFSET`.
|
|
19
|
+
- **`JoinClauseNode`**: Represents various types of table joins (INNER, LEFT, etc.) with associated join conditions.
|
|
20
|
+
- **Operations**: Support for both binary (e.g., `+`, `-`, `AND`, `OR`) and unary (e.g., `NOT`, `-`) operations.
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
Nodes are typically instantiated and composed to build a tree representing a query. For example:
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from buildaquery.abstract_syntax_tree.models import SelectStatementNode, ColumnNode, TableNode
|
|
28
|
+
|
|
29
|
+
# SELECT * FROM users
|
|
30
|
+
query = SelectStatementNode(
|
|
31
|
+
select_list=[ColumnNode(name="*")],
|
|
32
|
+
from_table=TableNode(name="users")
|
|
33
|
+
)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
This tree can then be processed by visitors (see the `traversal` module) for compilation or analysis.
|
|
37
|
+
|
|
38
|
+
## TODOs
|
|
39
|
+
|
|
40
|
+
To make the AST more robust and capable of representing the full scope of the SQL language, the following enhancements are planned:
|
|
41
|
+
|
|
42
|
+
- **DML Support**:
|
|
43
|
+
- [x] Implement `InsertStatementNode` and `UpdateStatementNode`.
|
|
44
|
+
- [x] Implement `DeleteStatementNode`.
|
|
45
|
+
- **Advanced Query Features**:
|
|
46
|
+
- [x] **CTEs**: Add `WithClauseNode` for common table expressions.
|
|
47
|
+
- [x] **Set Operations**: Implement `UnionNode`, `IntersectNode`, and `ExceptNode`.
|
|
48
|
+
- [x] **DISTINCT**: Add support for `SELECT DISTINCT`.
|
|
49
|
+
- **Richer Expression Logic**:
|
|
50
|
+
- **Specialized Expressions**: Add [x] `CaseExpressionNode`, [x] `InNode`, and [x] `BetweenNode`.
|
|
51
|
+
- [x] **Subqueries**: Enable `SelectStatementNode` to be used within expressions.
|
|
52
|
+
- [x] **Window Functions**: Support `OVER` clauses and partitioning.
|
|
53
|
+
- [x] **Schema & Namespacing**: Update `TableNode` and `ColumnNode` to support qualified names (e.g., `schema.table`) and add a `CastNode` for type casting.
|
|
54
|
+
- **DDL Support**: [x] Add nodes for `CREATE`, `ALTER`, and `DROP` statements for schema management.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .models import *
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
# ==================================================
|
|
6
|
+
# Base classes
|
|
7
|
+
# ==================================================
|
|
8
|
+
@dataclass
|
|
9
|
+
class ASTNode(ABC):
|
|
10
|
+
"""
|
|
11
|
+
A generic AST node. All specific AST node types will inherit from this base class.
|
|
12
|
+
"""
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class ExpressionNode(ASTNode):
|
|
17
|
+
"""
|
|
18
|
+
A base class for all expression nodes in the AST.
|
|
19
|
+
"""
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
# ==================================================
|
|
23
|
+
# Specific expression nodes
|
|
24
|
+
# ==================================================
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class LiteralNode(ExpressionNode):
|
|
28
|
+
"""
|
|
29
|
+
Represents a literal value in the AST, such as a number or string.
|
|
30
|
+
"""
|
|
31
|
+
value: Any
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class ColumnNode(ExpressionNode):
|
|
35
|
+
"""
|
|
36
|
+
Represents a column reference in the AST.
|
|
37
|
+
"""
|
|
38
|
+
name: str
|
|
39
|
+
table: str | None = None
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class BinaryOperationNode(ExpressionNode):
|
|
43
|
+
"""
|
|
44
|
+
Represents a binary operation in the AST, such as addition, subtraction, etc.
|
|
45
|
+
"""
|
|
46
|
+
left: ExpressionNode
|
|
47
|
+
operator: str
|
|
48
|
+
right: ExpressionNode
|
|
49
|
+
|
|
50
|
+
# ==================================================
|
|
51
|
+
# Statement nodes
|
|
52
|
+
# ==================================================
|
|
53
|
+
|
|
54
|
+
@dataclass
|
|
55
|
+
class StatementNode(ASTNode):
|
|
56
|
+
"""
|
|
57
|
+
A base class for all statement nodes in the AST.
|
|
58
|
+
"""
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
@dataclass
|
|
62
|
+
class FromClauseNode(ASTNode):
|
|
63
|
+
"""
|
|
64
|
+
Represents a FROM clause in the AST, anything can appears here, including subqueries, joins, etc.
|
|
65
|
+
"""
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
@dataclass
|
|
69
|
+
class SubqueryNode(ExpressionNode, FromClauseNode):
|
|
70
|
+
"""
|
|
71
|
+
Represents a subquery that can be used in an expression or a FROM clause.
|
|
72
|
+
"""
|
|
73
|
+
statement: 'SelectStatementNode'
|
|
74
|
+
alias: str | None = None
|
|
75
|
+
|
|
76
|
+
@dataclass
|
|
77
|
+
class JoinClauseNode(FromClauseNode):
|
|
78
|
+
"""
|
|
79
|
+
Represents a JOIN clause in the AST.
|
|
80
|
+
"""
|
|
81
|
+
left: FromClauseNode
|
|
82
|
+
right: FromClauseNode
|
|
83
|
+
on_condition: ExpressionNode
|
|
84
|
+
join_type: str
|
|
85
|
+
|
|
86
|
+
@dataclass
|
|
87
|
+
class OrderByClauseNode(ASTNode):
|
|
88
|
+
"""
|
|
89
|
+
Represents a single item in the ORDER BY clause in the AST.
|
|
90
|
+
"""
|
|
91
|
+
expression: ExpressionNode
|
|
92
|
+
direction: str = "ASC" # default to ascending order
|
|
93
|
+
|
|
94
|
+
@dataclass
|
|
95
|
+
class TopClauseNode(ASTNode):
|
|
96
|
+
"""
|
|
97
|
+
Represents a TOP clause in the AST.
|
|
98
|
+
"""
|
|
99
|
+
count: int
|
|
100
|
+
# Optional: Column to order by for TOP clause, if not already specified in ORDER BY
|
|
101
|
+
on_expression: ExpressionNode | None = None
|
|
102
|
+
direction: str = "DESC" # default to descending order for TOP
|
|
103
|
+
|
|
104
|
+
@dataclass
|
|
105
|
+
class TableNode(FromClauseNode):
|
|
106
|
+
"""
|
|
107
|
+
Represents a table reference in the AST.
|
|
108
|
+
"""
|
|
109
|
+
name: str
|
|
110
|
+
schema: str | None = None
|
|
111
|
+
alias: str | None = None
|
|
112
|
+
|
|
113
|
+
@dataclass
|
|
114
|
+
class AliasNode(ExpressionNode):
|
|
115
|
+
"""Represents an aliased expression (e.g., 'column AS new_name')."""
|
|
116
|
+
expression: ExpressionNode
|
|
117
|
+
name: str
|
|
118
|
+
|
|
119
|
+
@dataclass
|
|
120
|
+
class OverClauseNode(ASTNode):
|
|
121
|
+
"""Represents an OVER clause for window functions."""
|
|
122
|
+
partition_by: list[ExpressionNode] | None = None
|
|
123
|
+
order_by: list[OrderByClauseNode] | None = None
|
|
124
|
+
|
|
125
|
+
@dataclass
|
|
126
|
+
class CastNode(ExpressionNode):
|
|
127
|
+
"""Represents a type cast (e.g., 'CAST(column AS type)' or 'column::type')."""
|
|
128
|
+
expression: ExpressionNode
|
|
129
|
+
data_type: str
|
|
130
|
+
|
|
131
|
+
@dataclass
|
|
132
|
+
class FunctionCallNode(ExpressionNode):
|
|
133
|
+
"""Represents a function call (e.g., COUNT(*), MAX(price))."""
|
|
134
|
+
name: str
|
|
135
|
+
args: list[ExpressionNode]
|
|
136
|
+
over: OverClauseNode | None = None # optional OVER clause for window functions
|
|
137
|
+
|
|
138
|
+
@dataclass
|
|
139
|
+
class UnaryOperationNode(ExpressionNode):
|
|
140
|
+
"""Represents a unary operation (e.g., NOT, -)."""
|
|
141
|
+
operator: str
|
|
142
|
+
operand: ExpressionNode
|
|
143
|
+
|
|
144
|
+
@dataclass
|
|
145
|
+
class InNode(ExpressionNode):
|
|
146
|
+
"""Represents an IN expression (e.g., 'column IN (1, 2, 3)')."""
|
|
147
|
+
expression: ExpressionNode
|
|
148
|
+
values: list[ExpressionNode]
|
|
149
|
+
negated: bool = False
|
|
150
|
+
|
|
151
|
+
@dataclass
|
|
152
|
+
class WhenThenNode(ASTNode):
|
|
153
|
+
"""Represents a WHEN ... THEN ... clause in a CASE expression."""
|
|
154
|
+
condition: ExpressionNode
|
|
155
|
+
result: ExpressionNode
|
|
156
|
+
|
|
157
|
+
@dataclass
|
|
158
|
+
class CaseExpressionNode(ExpressionNode):
|
|
159
|
+
"""Represents a CASE expression (e.g., 'CASE WHEN cond THEN res ELSE default END')."""
|
|
160
|
+
cases: list[WhenThenNode]
|
|
161
|
+
else_result: ExpressionNode | None = None
|
|
162
|
+
|
|
163
|
+
@dataclass
|
|
164
|
+
class BetweenNode(ExpressionNode):
|
|
165
|
+
"""Represents a BETWEEN expression (e.g., 'column BETWEEN 1 AND 10')."""
|
|
166
|
+
expression: ExpressionNode
|
|
167
|
+
low: ExpressionNode
|
|
168
|
+
high: ExpressionNode
|
|
169
|
+
negated: bool = False
|
|
170
|
+
|
|
171
|
+
@dataclass
|
|
172
|
+
class StarNode(ExpressionNode):
|
|
173
|
+
"""Represents the '*' in 'SELECT *'."""
|
|
174
|
+
pass
|
|
175
|
+
|
|
176
|
+
@dataclass
|
|
177
|
+
class WhereClauseNode(ASTNode):
|
|
178
|
+
"""A wrapper for the expression in a WHERE clause."""
|
|
179
|
+
condition: ExpressionNode
|
|
180
|
+
|
|
181
|
+
@dataclass
|
|
182
|
+
class GroupByClauseNode(ASTNode):
|
|
183
|
+
"""A wrapper for the list of expressions in a GROUP BY clause."""
|
|
184
|
+
expressions: list[ExpressionNode]
|
|
185
|
+
|
|
186
|
+
@dataclass
|
|
187
|
+
class HavingClauseNode(ASTNode):
|
|
188
|
+
"""A wrapper for the expression in a HAVING clause."""
|
|
189
|
+
condition: ExpressionNode
|
|
190
|
+
|
|
191
|
+
@dataclass
|
|
192
|
+
class CTENode(ASTNode):
|
|
193
|
+
"""Represents a Common Table Expression (WITH clause)."""
|
|
194
|
+
name: str
|
|
195
|
+
subquery: 'SelectStatementNode'
|
|
196
|
+
|
|
197
|
+
@dataclass
|
|
198
|
+
class SelectStatementNode(StatementNode):
|
|
199
|
+
"""
|
|
200
|
+
Represents a SELECT statement in the AST.
|
|
201
|
+
"""
|
|
202
|
+
select_list: list[ExpressionNode] # list of expressions to select (eg: columns, functions, etc.)
|
|
203
|
+
distinct: bool = False # toggle between SELECT ALL and SELECT DISTINCT
|
|
204
|
+
ctes: list[CTENode] | None = None # optional list of Common Table Expressions
|
|
205
|
+
from_table: FromClauseNode | None = None # the table to select from, optional for edge cases
|
|
206
|
+
where_clause: WhereClauseNode | None = None # optional where clause for filtering results
|
|
207
|
+
group_by: GroupByClauseNode | None = None # optional group by clause for aggregation
|
|
208
|
+
having_clause: HavingClauseNode | None = None # optional having clause for filtering groups in aggregation
|
|
209
|
+
order_by_clause: list[OrderByClauseNode] | None = None # optional list of order by clauses for sorting results
|
|
210
|
+
top_clause: TopClauseNode | None = None # optional top clause, mutually exclusive with limit and offset
|
|
211
|
+
limit: int | None = None # optional limit for number of results to return
|
|
212
|
+
offset: int | None = None # optional offset for skipping results
|
|
213
|
+
|
|
214
|
+
@dataclass
|
|
215
|
+
class DeleteStatementNode(StatementNode):
|
|
216
|
+
"""
|
|
217
|
+
Represents a DELETE statement in the AST.
|
|
218
|
+
"""
|
|
219
|
+
table: TableNode
|
|
220
|
+
where_clause: WhereClauseNode | None = None
|
|
221
|
+
|
|
222
|
+
@dataclass
|
|
223
|
+
class ColumnDefinitionNode(ASTNode):
|
|
224
|
+
"""Represents a column definition in a CREATE TABLE statement."""
|
|
225
|
+
name: str
|
|
226
|
+
data_type: str
|
|
227
|
+
primary_key: bool = False
|
|
228
|
+
not_null: bool = False
|
|
229
|
+
default: ExpressionNode | None = None
|
|
230
|
+
|
|
231
|
+
@dataclass
|
|
232
|
+
class CreateStatementNode(StatementNode):
|
|
233
|
+
"""Represents a CREATE TABLE statement."""
|
|
234
|
+
table: TableNode
|
|
235
|
+
columns: list[ColumnDefinitionNode]
|
|
236
|
+
if_not_exists: bool = False
|
|
237
|
+
|
|
238
|
+
@dataclass
|
|
239
|
+
class DropStatementNode(StatementNode):
|
|
240
|
+
"""Represents a DROP TABLE statement."""
|
|
241
|
+
table: TableNode
|
|
242
|
+
if_exists: bool = False
|
|
243
|
+
cascade: bool = False
|
|
244
|
+
|
|
245
|
+
@dataclass
|
|
246
|
+
class InsertStatementNode(StatementNode):
|
|
247
|
+
"""
|
|
248
|
+
Represents an INSERT statement in the AST.
|
|
249
|
+
"""
|
|
250
|
+
table: TableNode
|
|
251
|
+
values: list[ExpressionNode]
|
|
252
|
+
columns: list[ColumnNode] | None = None
|
|
253
|
+
|
|
254
|
+
@dataclass
|
|
255
|
+
class UpdateStatementNode(StatementNode):
|
|
256
|
+
"""
|
|
257
|
+
Represents an UPDATE statement in the AST.
|
|
258
|
+
"""
|
|
259
|
+
table: TableNode
|
|
260
|
+
set_clauses: dict[str, ExpressionNode] # Map column names to new values/expressions
|
|
261
|
+
where_clause: WhereClauseNode | None = None
|
|
262
|
+
|
|
263
|
+
@dataclass
|
|
264
|
+
class SetOperationNode(StatementNode):
|
|
265
|
+
"""
|
|
266
|
+
Base class for set operations like UNION, INTERSECT, EXCEPT.
|
|
267
|
+
"""
|
|
268
|
+
left: StatementNode
|
|
269
|
+
right: StatementNode
|
|
270
|
+
all: bool = False
|
|
271
|
+
|
|
272
|
+
@dataclass
|
|
273
|
+
class UnionNode(SetOperationNode):
|
|
274
|
+
"""Represents a UNION operation."""
|
|
275
|
+
pass
|
|
276
|
+
|
|
277
|
+
@dataclass
|
|
278
|
+
class IntersectNode(SetOperationNode):
|
|
279
|
+
"""Represents an INTERSECT operation."""
|
|
280
|
+
pass
|
|
281
|
+
|
|
282
|
+
@dataclass
|
|
283
|
+
class ExceptNode(SetOperationNode):
|
|
284
|
+
"""Represents an EXCEPT operation."""
|
|
285
|
+
pass
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Compiler
|
|
2
|
+
|
|
3
|
+
The `compiler` module is responsible for translating the dialect-agnostic Abstract Syntax Tree (AST) into specific SQL dialects.
|
|
4
|
+
|
|
5
|
+
## Core Concepts
|
|
6
|
+
|
|
7
|
+
### `CompiledQuery` Dataclass
|
|
8
|
+
Every compiler returns a `CompiledQuery` object instead of a raw string. This ensures that queries are handled safely and consistently.
|
|
9
|
+
|
|
10
|
+
- **`sql` (str)**: The SQL query string containing placeholders (e.g., `%s` for PostgreSQL).
|
|
11
|
+
- **`params` (list[Any])**: A list of values corresponding to the placeholders in the SQL string.
|
|
12
|
+
|
|
13
|
+
### Parametrization
|
|
14
|
+
To prevent SQL injection, the compilers are designed to automatically parametrize all literal values. When a `LiteralNode` is encountered, the compiler:
|
|
15
|
+
1. Appends a placeholder to the SQL string.
|
|
16
|
+
2. Appends the literal value to the `params` list.
|
|
17
|
+
|
|
18
|
+
## Implementations
|
|
19
|
+
|
|
20
|
+
### PostgreSQL (`PostgresCompiler`)
|
|
21
|
+
The initial implementation supports PostgreSQL.
|
|
22
|
+
|
|
23
|
+
#### Key Features:
|
|
24
|
+
- **DISTINCT Support**: Handles `SELECT DISTINCT` queries.
|
|
25
|
+
- **DML Support**: Supports `INSERT`, `UPDATE`, and `DELETE` operations.
|
|
26
|
+
- **Set Operations**: Support for `UNION`, `INTERSECT`, and `EXCEPT` (including `ALL`).
|
|
27
|
+
- **CTEs**: Support for `WITH` clauses.
|
|
28
|
+
- **Specialized Expressions**: Support for `IN`, `BETWEEN`, and `CASE`.
|
|
29
|
+
- **Subqueries**: Support for subqueries in `FROM` and `WHERE` clauses.
|
|
30
|
+
- **Window Functions**: Support for `OVER` clauses, `PARTITION BY`, and `ORDER BY`.
|
|
31
|
+
- **DDL Support**: Support for `CREATE TABLE` and `DROP TABLE`.
|
|
32
|
+
- **Qualified Names**: Supports `schema.table` and `table.column` naming conventions.
|
|
33
|
+
- **Type Casting**: Supports `CAST(expression AS type)`.
|
|
34
|
+
- **Clause Ordering**: Ensures `SELECT`, `FROM`, `WHERE`, `GROUP BY`, `HAVING`, `ORDER BY`, and `LIMIT` are placed in the correct sequence.
|
|
35
|
+
- **TOP Translation**: Automatically translates `TopClauseNode` into PostgreSQL-compliant `LIMIT` and `ORDER BY` logic.
|
|
36
|
+
- **Mutual Exclusivity Enforcement**: Raises a `ValueError` if a query attempts to use both `TOP` and standard `LIMIT/OFFSET`.
|
|
37
|
+
|
|
38
|
+
## Usage Example
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from buildaquery.compiler.postgres.postgres_compiler import PostgresCompiler
|
|
42
|
+
|
|
43
|
+
compiler = PostgresCompiler()
|
|
44
|
+
compiled = compiler.compile(ast_root)
|
|
45
|
+
|
|
46
|
+
print(compiled.sql) # "SELECT * FROM users WHERE id = %s"
|
|
47
|
+
print(compiled.params) # [123]
|
|
48
|
+
```
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# PostgreSQL Compiler
|
|
2
|
+
|
|
3
|
+
This sub-module provides the concrete implementation of the SQL compiler for PostgreSQL.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Standard DML Support**: Compiles `SELECT`, `INSERT`, `UPDATE`, and `DELETE` statements.
|
|
8
|
+
- **Set Operations**: Supports `UNION`, `INTERSECT`, and `EXCEPT` (and their `ALL` variants).
|
|
9
|
+
- **CTEs**: Supports Common Table Expressions (`WITH` clause).
|
|
10
|
+
- **Specialized Expressions**: Supports `IN`, `BETWEEN`, and `CASE` operators.
|
|
11
|
+
- **Subqueries**: Handles subqueries in `FROM` and `WHERE` clauses.
|
|
12
|
+
- **Window Functions**: Supports window functions with `OVER`, `PARTITION BY`, and `ORDER BY`.
|
|
13
|
+
- **DDL Support**: Handles `CREATE TABLE` and `DROP TABLE` statements.
|
|
14
|
+
- **DISTINCT**: Supports `SELECT DISTINCT`.
|
|
15
|
+
- **Qualified Names**: Handles `schema.table` and `table.column` identifiers.
|
|
16
|
+
- **Type Casting**: Supports `CAST(expression AS type)`.
|
|
17
|
+
- **Filtering**: Translates `WhereClauseNode` and complex binary/unary operations.
|
|
18
|
+
- **Parametrization**: Automatically uses `%s` placeholders for all literal values to ensure security.
|
|
19
|
+
- **Dialect Specifics**:
|
|
20
|
+
- Translates `TopClauseNode` into a combination of `LIMIT` and `ORDER BY`.
|
|
21
|
+
- Handles PostgreSQL-specific operator precedence through grouping.
|
|
22
|
+
|
|
23
|
+
## Implementation Details
|
|
24
|
+
|
|
25
|
+
The compiler is implemented as a `Visitor` that recursively traverses the AST. For expression nodes, it generally follows a post-order traversal to build the SQL string from the bottom up.
|