1
0
Fork 0

Adding upstream version 21.0.1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-13 21:20:19 +01:00
parent 07f4660f31
commit 91f2cef5f0
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
115 changed files with 66603 additions and 60920 deletions

View file

@ -1,28 +1,27 @@
repos: repos:
- repo: local - repo: local
hooks: hooks:
- id: autoflake - id: ruff
name: autoflake name: ruff
entry: autoflake -i -r description: "Run 'ruff' for extremely fast Python linting"
language: system entry: ruff check
types: [ python ] --force-exclude --fix
--ignore E721
--ignore E741
language: python
types_or: [python, pyi]
require_serial: true require_serial: true
additional_dependencies: []
files: ^(sqlglot/|tests/|setup.py) files: ^(sqlglot/|tests/|setup.py)
- id: isort - id: ruff-format
args: [--combine-as] name: ruff-format
name: isort description: "Run 'ruff format' for extremely fast Python formatting"
entry: isort entry: ruff format
language: system --force-exclude
types: [ python ] --line-length 100
files: ^(sqlglot/|tests/|setup.py) language: python
types_or: [python, pyi]
require_serial: true require_serial: true
- id: black
name: black
entry: black --line-length 100
language: system
types: [ python ]
require_serial: true
files: ^(sqlglot/|tests/|setup.py)
- id: mypy - id: mypy
name: mypy name: mypy
entry: mypy sqlglot tests entry: mypy sqlglot tests

View file

@ -1,6 +1,88 @@
Changelog Changelog
========= =========
## [v21.0.0] - 2024-02-07
### :boom: BREAKING CHANGES
- due to [`b4e8868`](https://github.com/tobymao/sqlglot/commit/b4e886877ecfbafdd64c515c765c3c54764bd987) - improve transpilation of JSON paths across dialects *(PR [#2883](https://github.com/tobymao/sqlglot/pull/2883) by [@georgesittas](https://github.com/georgesittas))*:
improve transpilation of JSON paths across dialects (#2883)
- due to [`aa388ea`](https://github.com/tobymao/sqlglot/commit/aa388ea64404a26550dbb0734f4d3e35111f9e2c) - ignore nulls closes [#2896](https://github.com/tobymao/sqlglot/pull/2896) *(PR [#2898](https://github.com/tobymao/sqlglot/pull/2898) by [@tobymao](https://github.com/tobymao))*:
ignore nulls closes #2896 (#2898)
- due to [`617a8c0`](https://github.com/tobymao/sqlglot/commit/617a8c0dfc5e9f2716f7827381af0db2e135059e) - timestamp diff for mysql and databricks *(commit by [@tobymao](https://github.com/tobymao))*:
timestamp diff for mysql and databricks
- due to [`b00b393`](https://github.com/tobymao/sqlglot/commit/b00b393d853ae05a3fce4ef78d7673edbcabf67d) - use raise instead of assert for assert_is *(commit by [@tobymao](https://github.com/tobymao))*:
use raise instead of assert for assert_is
- due to [`326aa31`](https://github.com/tobymao/sqlglot/commit/326aa31e32e511f4e40d3a5a7b1d599b5e2c1307) - deprecate case where transforms can be plain strs *(PR [#2919](https://github.com/tobymao/sqlglot/pull/2919) by [@georgesittas](https://github.com/georgesittas))*:
deprecate case where transforms can be plain strs (#2919)
### :sparkles: New Features
- [`fb450f0`](https://github.com/tobymao/sqlglot/commit/fb450f0263ecd6b7c9d0f49d84441327d50b9d83) - add tsql right left auto casting closes [#2899](https://github.com/tobymao/sqlglot/pull/2899) *(commit by [@tobymao](https://github.com/tobymao))*
- [`617a8c0`](https://github.com/tobymao/sqlglot/commit/617a8c0dfc5e9f2716f7827381af0db2e135059e) - timestamp diff for mysql and databricks *(commit by [@tobymao](https://github.com/tobymao))*
- [`3fa92ca`](https://github.com/tobymao/sqlglot/commit/3fa92cac285cbb2bd9d8b5724dadb77be7e12731) - **redshift**: parse GETDATE *(PR [#2904](https://github.com/tobymao/sqlglot/pull/2904) by [@erickpeirson](https://github.com/erickpeirson))*
- [`d262139`](https://github.com/tobymao/sqlglot/commit/d26213998b27fa9b6a66b6d21ab5a3a15f65635e) - **snowflake**: implement parsing logic for SHOW TABLES *(PR [#2913](https://github.com/tobymao/sqlglot/pull/2913) by [@tekumara](https://github.com/tekumara))*
- [`838e780`](https://github.com/tobymao/sqlglot/commit/838e7800c32ad16074efef6a188ebd89083a9717) - improve transpilation of CREATE TABLE LIKE statement *(PR [#2923](https://github.com/tobymao/sqlglot/pull/2923) by [@georgesittas](https://github.com/georgesittas))*
- :arrow_lower_right: *addresses issue [#2922](https://github.com/tobymao/sqlglot/issues/2922) opened by [@tharwan](https://github.com/tharwan)*
- [`cbbad1f`](https://github.com/tobymao/sqlglot/commit/cbbad1fc40b6b2ca837ddb0f798b1802ad4063da) - improve transpilation of JSON path wildcards *(PR [#2924](https://github.com/tobymao/sqlglot/pull/2924) by [@georgesittas](https://github.com/georgesittas))*
### :bug: Bug Fixes
- [`aa388ea`](https://github.com/tobymao/sqlglot/commit/aa388ea64404a26550dbb0734f4d3e35111f9e2c) - ignore nulls closes [#2896](https://github.com/tobymao/sqlglot/pull/2896) *(PR [#2898](https://github.com/tobymao/sqlglot/pull/2898) by [@tobymao](https://github.com/tobymao))*
- [`b00b393`](https://github.com/tobymao/sqlglot/commit/b00b393d853ae05a3fce4ef78d7673edbcabf67d) - use raise instead of assert for assert_is *(commit by [@tobymao](https://github.com/tobymao))*
- [`ab97246`](https://github.com/tobymao/sqlglot/commit/ab972462b1c545b4a60bb88cb40cdb98cb64e360) - array overlaps closes [#2903](https://github.com/tobymao/sqlglot/pull/2903) *(commit by [@tobymao](https://github.com/tobymao))*
- [`f3bdcb0`](https://github.com/tobymao/sqlglot/commit/f3bdcb087bb993289c4a1a5d2de54155ae2d2681) - **duckdb**: fix JSON pointer path parsing, reduce warning noise *(PR [#2911](https://github.com/tobymao/sqlglot/pull/2911) by [@georgesittas](https://github.com/georgesittas))*
- [`072264f`](https://github.com/tobymao/sqlglot/commit/072264f8af25737050f7becd27af5a9331bde896) - **mysql**: SHOW SCHEMAS *(PR [#2916](https://github.com/tobymao/sqlglot/pull/2916) by [@barakalon](https://github.com/barakalon))*
- [`15fdff2`](https://github.com/tobymao/sqlglot/commit/15fdff2df3363ab8d3595e7eeb8baee65e525733) - **optimizer**: don't remove NOT parenthesis *(PR [#2917](https://github.com/tobymao/sqlglot/pull/2917) by [@barakalon](https://github.com/barakalon))*
- [`d20d826`](https://github.com/tobymao/sqlglot/commit/d20d826e9cc4a9b0d636a9b56b5547cd906a5903) - have table exclude this if schema target *(PR [#2921](https://github.com/tobymao/sqlglot/pull/2921) by [@eakmanrq](https://github.com/eakmanrq))*
### :recycle: Refactors
- [`b4e8868`](https://github.com/tobymao/sqlglot/commit/b4e886877ecfbafdd64c515c765c3c54764bd987) - improve transpilation of JSON paths across dialects *(PR [#2883](https://github.com/tobymao/sqlglot/pull/2883) by [@georgesittas](https://github.com/georgesittas))*
- :arrow_lower_right: *addresses issue [#2839](https://github.com/tobymao/sqlglot/issues/2839) opened by [@FlaviovLeal](https://github.com/FlaviovLeal)*
- [`9481f94`](https://github.com/tobymao/sqlglot/commit/9481f946b068e43d99c9aaae6e1c59abf384eeac) - several JSON path improvements *(PR [#2914](https://github.com/tobymao/sqlglot/pull/2914) by [@georgesittas](https://github.com/georgesittas))*
- [`326aa31`](https://github.com/tobymao/sqlglot/commit/326aa31e32e511f4e40d3a5a7b1d599b5e2c1307) - deprecate case where transforms can be plain strs *(PR [#2919](https://github.com/tobymao/sqlglot/pull/2919) by [@georgesittas](https://github.com/georgesittas))*
- [`15582f4`](https://github.com/tobymao/sqlglot/commit/15582f40bd18da3fa7adbe454b401ef8d31a131e) - move JSON path generation logic in Generator *(PR [#2920](https://github.com/tobymao/sqlglot/pull/2920) by [@georgesittas](https://github.com/georgesittas))*
### :wrench: Chores
- [`afb4f9b`](https://github.com/tobymao/sqlglot/commit/afb4f9bfe074200e60b5a870267fe21aa04a87c5) - switch to ruff *(commit by [@tobymao](https://github.com/tobymao))*
- [`f9fdf7b`](https://github.com/tobymao/sqlglot/commit/f9fdf7b3bb25aa7e830b70600728bb35ee1e4ff7) - switch to ruff *(PR [#2912](https://github.com/tobymao/sqlglot/pull/2912) by [@tobymao](https://github.com/tobymao))*
- [`71c33fa`](https://github.com/tobymao/sqlglot/commit/71c33fa13b9c416ae50acb10a9b08dcfcfd35f92) - pandas warning *(commit by [@tobymao](https://github.com/tobymao))*
## [v20.11.0] - 2024-01-29
### :boom: BREAKING CHANGES
- due to [`eb8b40a`](https://github.com/tobymao/sqlglot/commit/eb8b40aade54eec8b34a808dda95420dcf7a7e13) - deprecate NULL, TRUE, FALSE constant expressions *(PR [#2884](https://github.com/tobymao/sqlglot/pull/2884) by [@georgesittas](https://github.com/georgesittas))*:
deprecate NULL, TRUE, FALSE constant expressions (#2884)
### :sparkles: New Features
- [`3a8ed85`](https://github.com/tobymao/sqlglot/commit/3a8ed8573d5562110b312586ae6fca22038e5d05) - add alter table alter comment closes [#2889](https://github.com/tobymao/sqlglot/pull/2889) *(commit by [@tobymao](https://github.com/tobymao))*
### :bug: Bug Fixes
- [`dc2d7d7`](https://github.com/tobymao/sqlglot/commit/dc2d7d7dd4253fe6b247d534bd92327f186e9aa8) - **tsql**: len text transpilation closes [#2885](https://github.com/tobymao/sqlglot/pull/2885) *(commit by [@tobymao](https://github.com/tobymao))*
- [`ad50f47`](https://github.com/tobymao/sqlglot/commit/ad50f479c47d5b4990f1b41272c69079a453cf21) - type imports *(PR [#2886](https://github.com/tobymao/sqlglot/pull/2886) by [@tobymao](https://github.com/tobymao))*
- [`e4fb7f6`](https://github.com/tobymao/sqlglot/commit/e4fb7f6e1b8ab15ceb5acc6a93256c849c738740) - union should return union *(commit by [@tobymao](https://github.com/tobymao))*
- [`8f795ea`](https://github.com/tobymao/sqlglot/commit/8f795ea00164b69acba093c3684ab54b62138e8e) - don't expand star except/replace refs *(commit by [@tobymao](https://github.com/tobymao))*
- [`218121c`](https://github.com/tobymao/sqlglot/commit/218121c274656a1b252143a7d0fc2d73407115ca) - alter table cluster by closes [#2887](https://github.com/tobymao/sqlglot/pull/2887) *(commit by [@tobymao](https://github.com/tobymao))*
- [`5cec283`](https://github.com/tobymao/sqlglot/commit/5cec2839f8ed8477821bf766025f4b5de0621fe2) - bigquery script if statement closes [#2888](https://github.com/tobymao/sqlglot/pull/2888) *(commit by [@tobymao](https://github.com/tobymao))*
- [`5fc7791`](https://github.com/tobymao/sqlglot/commit/5fc7791a4d19d704c0d4fafe8924cf8f76fcb867) - all view column options without types closes [#2891](https://github.com/tobymao/sqlglot/pull/2891) *(commit by [@tobymao](https://github.com/tobymao))*
- [`102304e`](https://github.com/tobymao/sqlglot/commit/102304e28f2ed7126840789837ed797a75bae44e) - **postgres**: generate CurrentUser without parentheses closes [#2893](https://github.com/tobymao/sqlglot/pull/2893) *(commit by [@georgesittas](https://github.com/georgesittas))*
- [`43902db`](https://github.com/tobymao/sqlglot/commit/43902db25706a2434fe7e9ba39addd1c31c2aa64) - error level ignore comments closes [#2895](https://github.com/tobymao/sqlglot/pull/2895) *(commit by [@tobymao](https://github.com/tobymao))*
### :wrench: Chores
- [`eb8b40a`](https://github.com/tobymao/sqlglot/commit/eb8b40aade54eec8b34a808dda95420dcf7a7e13) - deprecate NULL, TRUE, FALSE constant expressions *(PR [#2884](https://github.com/tobymao/sqlglot/pull/2884) by [@georgesittas](https://github.com/georgesittas))*
- [`29cddd5`](https://github.com/tobymao/sqlglot/commit/29cddd5c3f5401033197d47e7544cedd91b8046c) - change warning message *(commit by [@tobymao](https://github.com/tobymao))*
- [`9eac93e`](https://github.com/tobymao/sqlglot/commit/9eac93e0acd5ae8b034045759fc48937586cbc2e) - upgrade black *(commit by [@tobymao](https://github.com/tobymao))*
- [`4f3fac7`](https://github.com/tobymao/sqlglot/commit/4f3fac7815e0d8206c80f1f255336ab630503d4d) - cleanup command parsing and warnings *(commit by [@tobymao](https://github.com/tobymao))*
## [v20.10.0] - 2024-01-24 ## [v20.10.0] - 2024-01-24
### :boom: BREAKING CHANGES ### :boom: BREAKING CHANGES
- due to [`1f5fc39`](https://github.com/tobymao/sqlglot/commit/1f5fc39c10b92b94bd94afa5fd038fdb9afeb4b4) - jsonpath parsing *(PR [#2867](https://github.com/tobymao/sqlglot/pull/2867) by [@tobymao](https://github.com/tobymao))*: - due to [`1f5fc39`](https://github.com/tobymao/sqlglot/commit/1f5fc39c10b92b94bd94afa5fd038fdb9afeb4b4) - jsonpath parsing *(PR [#2867](https://github.com/tobymao/sqlglot/pull/2867) by [@tobymao](https://github.com/tobymao))*:
@ -2485,4 +2567,6 @@ Changelog
[v20.7.1]: https://github.com/tobymao/sqlglot/compare/v20.6.0...v20.7.1 [v20.7.1]: https://github.com/tobymao/sqlglot/compare/v20.6.0...v20.7.1
[v20.8.0]: https://github.com/tobymao/sqlglot/compare/v20.7.1...v20.8.0 [v20.8.0]: https://github.com/tobymao/sqlglot/compare/v20.7.1...v20.8.0
[v20.9.0]: https://github.com/tobymao/sqlglot/compare/v20.8.0...v20.9.0 [v20.9.0]: https://github.com/tobymao/sqlglot/compare/v20.8.0...v20.9.0
[v20.10.0]: https://github.com/tobymao/sqlglot/compare/v20.9.0...v20.10.0 [v20.10.0]: https://github.com/tobymao/sqlglot/compare/v20.9.0...v20.10.0
[v20.11.0]: https://github.com/tobymao/sqlglot/compare/v20.10.0...v20.11.0
[v21.0.0]: https://github.com/tobymao/sqlglot/compare/v20.11.0...v21.0.0

View file

@ -2,15 +2,14 @@ import collections.abc
# moz_sql_parser 3.10 compatibility # moz_sql_parser 3.10 compatibility
collections.Iterable = collections.abc.Iterable collections.Iterable = collections.abc.Iterable
import gc
import timeit import timeit
import numpy as np import numpy as np
#import sqlfluff # import sqlfluff
#import moz_sql_parser # import moz_sql_parser
#import sqloxide # import sqloxide
#import sqlparse # import sqlparse
import sqltree import sqltree
import sqlglot import sqlglot
@ -170,7 +169,7 @@ def sqlglotrs_parse(sql):
def sqltree_parse(sql): def sqltree_parse(sql):
sqltree.api.sqltree(sql.replace('"', '`').replace("''", '"')) sqltree.api.sqltree(sql.replace('"', "`").replace("''", '"'))
def sqlparse_parse(sql): def sqlparse_parse(sql):
@ -206,11 +205,11 @@ def diff(row, column):
libs = [ libs = [
"sqlglot", "sqlglot",
"sqlglotrs", "sqlglotrs",
#"sqlfluff", # "sqlfluff",
"sqltree", "sqltree",
#"sqlparse", # "sqlparse",
#"moz_sql_parser", # "moz_sql_parser",
#"sqloxide", # "sqloxide",
] ]
table = [] table = []
@ -231,10 +230,12 @@ lines = [border(column.rjust(width) for column, width in widths.items())]
lines.append(border(str("-" * width) for width in widths.values())) lines.append(border(str("-" * width) for width in widths.values()))
for i, row in enumerate(table): for i, row in enumerate(table):
lines.append(border( lines.append(
(str(row[column])[0:7] + diff(row, column)).rjust(width)[0 : width] border(
for column, width in widths.items() (str(row[column])[0:7] + diff(row, column)).rjust(width)[0:width]
)) for column, width in widths.items()
)
)
for line in lines: for line in lines:
print(line) print(line)

File diff suppressed because one or more lines are too long

View file

@ -707,170 +707,171 @@ make check # Full test suite &amp; linter checks
<label class="view-source-button" for="mod-sqlglot-view-source"><span>View Source</span></label> <label class="view-source-button" for="mod-sqlglot-view-source"><span>View Source</span></label>
<div class="pdoc-code codehilite"><pre><span></span><span id="L-1"><a href="#L-1"><span class="linenos"> 1</span></a><span class="sd">&quot;&quot;&quot;</span> <div class="pdoc-code codehilite"><pre><span></span><span id="L-1"><a href="#L-1"><span class="linenos"> 1</span></a><span class="c1"># ruff: noqa: F401</span>
</span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a><span class="sd">.. include:: ../README.md</span> </span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a> </span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="sd">.. include:: ../README.md</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a><span class="sd">----</span> </span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a>
</span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="sd">----</span>
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a> </span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">annotations</span> </span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a> </span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">annotations</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="kn">import</span> <span class="nn">logging</span> </span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a>
</span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span> </span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a><span class="kn">import</span> <span class="nn">logging</span>
</span><span id="L-11"><a href="#L-11"><span class="linenos"> 11</span></a> </span><span id="L-11"><a href="#L-11"><span class="linenos"> 11</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span>
</span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a><span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">expressions</span> <span class="k">as</span> <span class="n">exp</span> </span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a>
</span><span id="L-13"><a href="#L-13"><span class="linenos"> 13</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.dialect</span> <span class="kn">import</span> <span class="n">Dialect</span> <span class="k">as</span> <span class="n">Dialect</span><span class="p">,</span> <span class="n">Dialects</span> <span class="k">as</span> <span class="n">Dialects</span> </span><span id="L-13"><a href="#L-13"><span class="linenos"> 13</span></a><span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">expressions</span> <span class="k">as</span> <span class="n">exp</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos"> 14</span></a><span class="kn">from</span> <span class="nn">sqlglot.diff</span> <span class="kn">import</span> <span class="n">diff</span> <span class="k">as</span> <span class="n">diff</span> </span><span id="L-14"><a href="#L-14"><span class="linenos"> 14</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.dialect</span> <span class="kn">import</span> <span class="n">Dialect</span> <span class="k">as</span> <span class="n">Dialect</span><span class="p">,</span> <span class="n">Dialects</span> <span class="k">as</span> <span class="n">Dialects</span>
</span><span id="L-15"><a href="#L-15"><span class="linenos"> 15</span></a><span class="kn">from</span> <span class="nn">sqlglot.errors</span> <span class="kn">import</span> <span class="p">(</span> </span><span id="L-15"><a href="#L-15"><span class="linenos"> 15</span></a><span class="kn">from</span> <span class="nn">sqlglot.diff</span> <span class="kn">import</span> <span class="n">diff</span> <span class="k">as</span> <span class="n">diff</span>
</span><span id="L-16"><a href="#L-16"><span class="linenos"> 16</span></a> <span class="n">ErrorLevel</span> <span class="k">as</span> <span class="n">ErrorLevel</span><span class="p">,</span> </span><span id="L-16"><a href="#L-16"><span class="linenos"> 16</span></a><span class="kn">from</span> <span class="nn">sqlglot.errors</span> <span class="kn">import</span> <span class="p">(</span>
</span><span id="L-17"><a href="#L-17"><span class="linenos"> 17</span></a> <span class="n">ParseError</span> <span class="k">as</span> <span class="n">ParseError</span><span class="p">,</span> </span><span id="L-17"><a href="#L-17"><span class="linenos"> 17</span></a> <span class="n">ErrorLevel</span> <span class="k">as</span> <span class="n">ErrorLevel</span><span class="p">,</span>
</span><span id="L-18"><a href="#L-18"><span class="linenos"> 18</span></a> <span class="n">TokenError</span> <span class="k">as</span> <span class="n">TokenError</span><span class="p">,</span> </span><span id="L-18"><a href="#L-18"><span class="linenos"> 18</span></a> <span class="n">ParseError</span> <span class="k">as</span> <span class="n">ParseError</span><span class="p">,</span>
</span><span id="L-19"><a href="#L-19"><span class="linenos"> 19</span></a> <span class="n">UnsupportedError</span> <span class="k">as</span> <span class="n">UnsupportedError</span><span class="p">,</span> </span><span id="L-19"><a href="#L-19"><span class="linenos"> 19</span></a> <span class="n">TokenError</span> <span class="k">as</span> <span class="n">TokenError</span><span class="p">,</span>
</span><span id="L-20"><a href="#L-20"><span class="linenos"> 20</span></a><span class="p">)</span> </span><span id="L-20"><a href="#L-20"><span class="linenos"> 20</span></a> <span class="n">UnsupportedError</span> <span class="k">as</span> <span class="n">UnsupportedError</span><span class="p">,</span>
</span><span id="L-21"><a href="#L-21"><span class="linenos"> 21</span></a><span class="kn">from</span> <span class="nn">sqlglot.expressions</span> <span class="kn">import</span> <span class="p">(</span> </span><span id="L-21"><a href="#L-21"><span class="linenos"> 21</span></a><span class="p">)</span>
</span><span id="L-22"><a href="#L-22"><span class="linenos"> 22</span></a> <span class="n">Expression</span> <span class="k">as</span> <span class="n">Expression</span><span class="p">,</span> </span><span id="L-22"><a href="#L-22"><span class="linenos"> 22</span></a><span class="kn">from</span> <span class="nn">sqlglot.expressions</span> <span class="kn">import</span> <span class="p">(</span>
</span><span id="L-23"><a href="#L-23"><span class="linenos"> 23</span></a> <span class="n">alias_</span> <span class="k">as</span> <span class="n">alias</span><span class="p">,</span> </span><span id="L-23"><a href="#L-23"><span class="linenos"> 23</span></a> <span class="n">Expression</span> <span class="k">as</span> <span class="n">Expression</span><span class="p">,</span>
</span><span id="L-24"><a href="#L-24"><span class="linenos"> 24</span></a> <span class="n">and_</span> <span class="k">as</span> <span class="n">and_</span><span class="p">,</span> </span><span id="L-24"><a href="#L-24"><span class="linenos"> 24</span></a> <span class="n">alias_</span> <span class="k">as</span> <span class="n">alias</span><span class="p">,</span>
</span><span id="L-25"><a href="#L-25"><span class="linenos"> 25</span></a> <span class="n">case</span> <span class="k">as</span> <span class="n">case</span><span class="p">,</span> </span><span id="L-25"><a href="#L-25"><span class="linenos"> 25</span></a> <span class="n">and_</span> <span class="k">as</span> <span class="n">and_</span><span class="p">,</span>
</span><span id="L-26"><a href="#L-26"><span class="linenos"> 26</span></a> <span class="n">cast</span> <span class="k">as</span> <span class="n">cast</span><span class="p">,</span> </span><span id="L-26"><a href="#L-26"><span class="linenos"> 26</span></a> <span class="n">case</span> <span class="k">as</span> <span class="n">case</span><span class="p">,</span>
</span><span id="L-27"><a href="#L-27"><span class="linenos"> 27</span></a> <span class="n">column</span> <span class="k">as</span> <span class="n">column</span><span class="p">,</span> </span><span id="L-27"><a href="#L-27"><span class="linenos"> 27</span></a> <span class="n">cast</span> <span class="k">as</span> <span class="n">cast</span><span class="p">,</span>
</span><span id="L-28"><a href="#L-28"><span class="linenos"> 28</span></a> <span class="n">condition</span> <span class="k">as</span> <span class="n">condition</span><span class="p">,</span> </span><span id="L-28"><a href="#L-28"><span class="linenos"> 28</span></a> <span class="n">column</span> <span class="k">as</span> <span class="n">column</span><span class="p">,</span>
</span><span id="L-29"><a href="#L-29"><span class="linenos"> 29</span></a> <span class="n">except_</span> <span class="k">as</span> <span class="n">except_</span><span class="p">,</span> </span><span id="L-29"><a href="#L-29"><span class="linenos"> 29</span></a> <span class="n">condition</span> <span class="k">as</span> <span class="n">condition</span><span class="p">,</span>
</span><span id="L-30"><a href="#L-30"><span class="linenos"> 30</span></a> <span class="n">from_</span> <span class="k">as</span> <span class="n">from_</span><span class="p">,</span> </span><span id="L-30"><a href="#L-30"><span class="linenos"> 30</span></a> <span class="n">except_</span> <span class="k">as</span> <span class="n">except_</span><span class="p">,</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos"> 31</span></a> <span class="n">func</span> <span class="k">as</span> <span class="n">func</span><span class="p">,</span> </span><span id="L-31"><a href="#L-31"><span class="linenos"> 31</span></a> <span class="n">from_</span> <span class="k">as</span> <span class="n">from_</span><span class="p">,</span>
</span><span id="L-32"><a href="#L-32"><span class="linenos"> 32</span></a> <span class="n">intersect</span> <span class="k">as</span> <span class="n">intersect</span><span class="p">,</span> </span><span id="L-32"><a href="#L-32"><span class="linenos"> 32</span></a> <span class="n">func</span> <span class="k">as</span> <span class="n">func</span><span class="p">,</span>
</span><span id="L-33"><a href="#L-33"><span class="linenos"> 33</span></a> <span class="n">maybe_parse</span> <span class="k">as</span> <span class="n">maybe_parse</span><span class="p">,</span> </span><span id="L-33"><a href="#L-33"><span class="linenos"> 33</span></a> <span class="n">intersect</span> <span class="k">as</span> <span class="n">intersect</span><span class="p">,</span>
</span><span id="L-34"><a href="#L-34"><span class="linenos"> 34</span></a> <span class="n">not_</span> <span class="k">as</span> <span class="n">not_</span><span class="p">,</span> </span><span id="L-34"><a href="#L-34"><span class="linenos"> 34</span></a> <span class="n">maybe_parse</span> <span class="k">as</span> <span class="n">maybe_parse</span><span class="p">,</span>
</span><span id="L-35"><a href="#L-35"><span class="linenos"> 35</span></a> <span class="n">or_</span> <span class="k">as</span> <span class="n">or_</span><span class="p">,</span> </span><span id="L-35"><a href="#L-35"><span class="linenos"> 35</span></a> <span class="n">not_</span> <span class="k">as</span> <span class="n">not_</span><span class="p">,</span>
</span><span id="L-36"><a href="#L-36"><span class="linenos"> 36</span></a> <span class="n">select</span> <span class="k">as</span> <span class="n">select</span><span class="p">,</span> </span><span id="L-36"><a href="#L-36"><span class="linenos"> 36</span></a> <span class="n">or_</span> <span class="k">as</span> <span class="n">or_</span><span class="p">,</span>
</span><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a> <span class="n">subquery</span> <span class="k">as</span> <span class="n">subquery</span><span class="p">,</span> </span><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a> <span class="n">select</span> <span class="k">as</span> <span class="n">select</span><span class="p">,</span>
</span><span id="L-38"><a href="#L-38"><span class="linenos"> 38</span></a> <span class="n">table_</span> <span class="k">as</span> <span class="n">table</span><span class="p">,</span> </span><span id="L-38"><a href="#L-38"><span class="linenos"> 38</span></a> <span class="n">subquery</span> <span class="k">as</span> <span class="n">subquery</span><span class="p">,</span>
</span><span id="L-39"><a href="#L-39"><span class="linenos"> 39</span></a> <span class="n">to_column</span> <span class="k">as</span> <span class="n">to_column</span><span class="p">,</span> </span><span id="L-39"><a href="#L-39"><span class="linenos"> 39</span></a> <span class="n">table_</span> <span class="k">as</span> <span class="n">table</span><span class="p">,</span>
</span><span id="L-40"><a href="#L-40"><span class="linenos"> 40</span></a> <span class="n">to_identifier</span> <span class="k">as</span> <span class="n">to_identifier</span><span class="p">,</span> </span><span id="L-40"><a href="#L-40"><span class="linenos"> 40</span></a> <span class="n">to_column</span> <span class="k">as</span> <span class="n">to_column</span><span class="p">,</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a> <span class="n">to_table</span> <span class="k">as</span> <span class="n">to_table</span><span class="p">,</span> </span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a> <span class="n">to_identifier</span> <span class="k">as</span> <span class="n">to_identifier</span><span class="p">,</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a> <span class="n">union</span> <span class="k">as</span> <span class="n">union</span><span class="p">,</span> </span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a> <span class="n">to_table</span> <span class="k">as</span> <span class="n">to_table</span><span class="p">,</span>
</span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a><span class="p">)</span> </span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a> <span class="n">union</span> <span class="k">as</span> <span class="n">union</span><span class="p">,</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a><span class="kn">from</span> <span class="nn">sqlglot.generator</span> <span class="kn">import</span> <span class="n">Generator</span> <span class="k">as</span> <span class="n">Generator</span> </span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a><span class="p">)</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a><span class="kn">from</span> <span class="nn">sqlglot.parser</span> <span class="kn">import</span> <span class="n">Parser</span> <span class="k">as</span> <span class="n">Parser</span> </span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a><span class="kn">from</span> <span class="nn">sqlglot.generator</span> <span class="kn">import</span> <span class="n">Generator</span> <span class="k">as</span> <span class="n">Generator</span>
</span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a><span class="kn">from</span> <span class="nn">sqlglot.schema</span> <span class="kn">import</span> <span class="n">MappingSchema</span> <span class="k">as</span> <span class="n">MappingSchema</span><span class="p">,</span> <span class="n">Schema</span> <span class="k">as</span> <span class="n">Schema</span> </span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a><span class="kn">from</span> <span class="nn">sqlglot.parser</span> <span class="kn">import</span> <span class="n">Parser</span> <span class="k">as</span> <span class="n">Parser</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a><span class="kn">from</span> <span class="nn">sqlglot.tokens</span> <span class="kn">import</span> <span class="n">Tokenizer</span> <span class="k">as</span> <span class="n">Tokenizer</span><span class="p">,</span> <span class="n">TokenType</span> <span class="k">as</span> <span class="n">TokenType</span> </span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a><span class="kn">from</span> <span class="nn">sqlglot.schema</span> <span class="kn">import</span> <span class="n">MappingSchema</span> <span class="k">as</span> <span class="n">MappingSchema</span><span class="p">,</span> <span class="n">Schema</span> <span class="k">as</span> <span class="n">Schema</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> </span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a><span class="kn">from</span> <span class="nn">sqlglot.tokens</span> <span class="kn">import</span> <span class="n">Tokenizer</span> <span class="k">as</span> <span class="n">Tokenizer</span><span class="p">,</span> <span class="n">TokenType</span> <span class="k">as</span> <span class="n">TokenType</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a><span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">TYPE_CHECKING</span><span class="p">:</span> </span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a>
</span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a> <span class="kn">from</span> <span class="nn">sqlglot._typing</span> <span class="kn">import</span> <span class="n">E</span> </span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a><span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">TYPE_CHECKING</span><span class="p">:</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dialects.dialect</span> <span class="kn">import</span> <span class="n">DialectType</span> <span class="k">as</span> <span class="n">DialectType</span> </span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a> <span class="kn">from</span> <span class="nn">sqlglot._typing</span> <span class="kn">import</span> <span class="n">E</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a> </span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dialects.dialect</span> <span class="kn">import</span> <span class="n">DialectType</span> <span class="k">as</span> <span class="n">DialectType</span>
</span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a><span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;sqlglot&quot;</span><span class="p">)</span> </span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a>
</span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a> </span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a><span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;sqlglot&quot;</span><span class="p">)</span>
</span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a> </span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a>
</span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a><span class="k">try</span><span class="p">:</span> </span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a>
</span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a> <span class="kn">from</span> <span class="nn">sqlglot._version</span> <span class="kn">import</span> <span class="n">__version__</span><span class="p">,</span> <span class="n">__version_tuple__</span> </span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a><span class="k">try</span><span class="p">:</span>
</span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a><span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span> </span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a> <span class="kn">from</span> <span class="nn">sqlglot._version</span> <span class="kn">import</span> <span class="n">__version__</span><span class="p">,</span> <span class="n">__version_tuple__</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span> </span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a><span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a> <span class="s2">&quot;Unable to set __version__, run `pip install -e .` or `python setup.py develop` first.&quot;</span> </span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a> <span class="p">)</span> </span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a> <span class="s2">&quot;Unable to set __version__, run `pip install -e .` or `python setup.py develop` first.&quot;</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a> </span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a> <span class="p">)</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a> </span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a>
</span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a><span class="n">pretty</span> <span class="o">=</span> <span class="kc">False</span> </span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a><span class="sd">&quot;&quot;&quot;Whether to format generated SQL by default.&quot;&quot;&quot;</span> </span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a><span class="n">pretty</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a> </span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a><span class="sd">&quot;&quot;&quot;Whether to format generated SQL by default.&quot;&quot;&quot;</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a><span class="n">schema</span> <span class="o">=</span> <span class="n">MappingSchema</span><span class="p">()</span> </span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a>
</span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a><span class="sd">&quot;&quot;&quot;The default schema used by SQLGlot (e.g. in the optimizer).&quot;&quot;&quot;</span> </span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a><span class="n">schema</span> <span class="o">=</span> <span class="n">MappingSchema</span><span class="p">()</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> </span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a><span class="sd">&quot;&quot;&quot;The default schema used by SQLGlot (e.g. in the optimizer).&quot;&quot;&quot;</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> </span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a>
</span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a><span class="k">def</span> <span class="nf">parse</span><span class="p">(</span> </span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a>
</span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span> </span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a><span class="k">def</span> <span class="nf">parse</span><span class="p">(</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">Expression</span><span class="p">]]:</span> </span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">Expression</span><span class="p">]]:</span>
</span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a><span class="sd"> Parses the given SQL string into a collection of syntax trees, one per parsed SQL statement.</span> </span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a> </span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a><span class="sd"> Parses the given SQL string into a collection of syntax trees, one per parsed SQL statement.</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a><span class="sd"> Args:</span> </span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a>
</span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a><span class="sd"> sql: the SQL code string to parse.</span> </span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a><span class="sd"> Args:</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a><span class="sd"> read: the SQL dialect to apply during parsing (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span> </span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a><span class="sd"> sql: the SQL code string to parse.</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a><span class="sd"> dialect: the SQL dialect (alias for read).</span> </span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a><span class="sd"> read: the SQL dialect to apply during parsing (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span>
</span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a><span class="sd"> **opts: other `sqlglot.parser.Parser` options.</span> </span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a><span class="sd"> dialect: the SQL dialect (alias for read).</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> </span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a><span class="sd"> **opts: other `sqlglot.parser.Parser` options.</span>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a><span class="sd"> Returns:</span> </span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a>
</span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a><span class="sd"> The resulting syntax tree collection.</span> </span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a><span class="sd"> Returns:</span>
</span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a><span class="sd"> The resulting syntax tree collection.</span>
</span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a> <span class="k">return</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">read</span> <span class="ow">or</span> <span class="n">dialect</span><span class="p">)</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> </span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> </span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> <span class="k">return</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">read</span> <span class="ow">or</span> <span class="n">dialect</span><span class="p">)</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span>
</span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> </span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a><span class="nd">@t</span><span class="o">.</span><span class="n">overload</span> </span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a>
</span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a><span class="k">def</span> <span class="nf">parse_one</span><span class="p">(</span><span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">into</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Type</span><span class="p">[</span><span class="n">E</span><span class="p">],</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span> </span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a><span class="nd">@t</span><span class="o">.</span><span class="n">overload</span>
</span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a> <span class="o">...</span> </span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a><span class="k">def</span> <span class="nf">parse_one</span><span class="p">(</span><span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">into</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Type</span><span class="p">[</span><span class="n">E</span><span class="p">],</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> </span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="o">...</span>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a> </span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a><span class="nd">@t</span><span class="o">.</span><span class="n">overload</span> </span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a>
</span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a><span class="k">def</span> <span class="nf">parse_one</span><span class="p">(</span><span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Expression</span><span class="p">:</span> </span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a><span class="nd">@t</span><span class="o">.</span><span class="n">overload</span>
</span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a> <span class="o">...</span> </span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a><span class="k">def</span> <span class="nf">parse_one</span><span class="p">(</span><span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Expression</span><span class="p">:</span>
</span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a> </span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a> <span class="o">...</span>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a> </span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a>
</span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a><span class="k">def</span> <span class="nf">parse_one</span><span class="p">(</span> </span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a>
</span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> </span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a><span class="k">def</span> <span class="nf">parse_one</span><span class="p">(</span>
</span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a> <span class="n">into</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">IntoType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a> <span class="o">**</span><span class="n">opts</span><span class="p">,</span> </span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a> <span class="n">into</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">IntoType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Expression</span><span class="p">:</span> </span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a> <span class="o">**</span><span class="n">opts</span><span class="p">,</span>
</span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Expression</span><span class="p">:</span>
</span><span id="L-107"><a href="#L-107"><span class="linenos">107</span></a><span class="sd"> Parses the given SQL string and returns a syntax tree for the first parsed SQL statement.</span> </span><span id="L-107"><a href="#L-107"><span class="linenos">107</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a> </span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a><span class="sd"> Parses the given SQL string and returns a syntax tree for the first parsed SQL statement.</span>
</span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a><span class="sd"> Args:</span> </span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a>
</span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a><span class="sd"> sql: the SQL code string to parse.</span> </span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a><span class="sd"> Args:</span>
</span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a><span class="sd"> read: the SQL dialect to apply during parsing (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span> </span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a><span class="sd"> sql: the SQL code string to parse.</span>
</span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a><span class="sd"> dialect: the SQL dialect (alias for read)</span> </span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a><span class="sd"> read: the SQL dialect to apply during parsing (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span>
</span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a><span class="sd"> into: the SQLGlot Expression to parse into.</span> </span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a><span class="sd"> dialect: the SQL dialect (alias for read)</span>
</span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a><span class="sd"> **opts: other `sqlglot.parser.Parser` options.</span> </span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a><span class="sd"> into: the SQLGlot Expression to parse into.</span>
</span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a> </span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a><span class="sd"> **opts: other `sqlglot.parser.Parser` options.</span>
</span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a><span class="sd"> Returns:</span> </span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a>
</span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a><span class="sd"> The syntax tree for the first parsed statement.</span> </span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a><span class="sd"> Returns:</span>
</span><span id="L-118"><a href="#L-118"><span class="linenos">118</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-118"><a href="#L-118"><span class="linenos">118</span></a><span class="sd"> The syntax tree for the first parsed statement.</span>
</span><span id="L-119"><a href="#L-119"><span class="linenos">119</span></a> </span><span id="L-119"><a href="#L-119"><span class="linenos">119</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-120"><a href="#L-120"><span class="linenos">120</span></a> <span class="n">dialect</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">read</span> <span class="ow">or</span> <span class="n">dialect</span><span class="p">)</span> </span><span id="L-120"><a href="#L-120"><span class="linenos">120</span></a>
</span><span id="L-121"><a href="#L-121"><span class="linenos">121</span></a> </span><span id="L-121"><a href="#L-121"><span class="linenos">121</span></a> <span class="n">dialect</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">read</span> <span class="ow">or</span> <span class="n">dialect</span><span class="p">)</span>
</span><span id="L-122"><a href="#L-122"><span class="linenos">122</span></a> <span class="k">if</span> <span class="n">into</span><span class="p">:</span> </span><span id="L-122"><a href="#L-122"><span class="linenos">122</span></a>
</span><span id="L-123"><a href="#L-123"><span class="linenos">123</span></a> <span class="n">result</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">parse_into</span><span class="p">(</span><span class="n">into</span><span class="p">,</span> <span class="n">sql</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> </span><span id="L-123"><a href="#L-123"><span class="linenos">123</span></a> <span class="k">if</span> <span class="n">into</span><span class="p">:</span>
</span><span id="L-124"><a href="#L-124"><span class="linenos">124</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-124"><a href="#L-124"><span class="linenos">124</span></a> <span class="n">result</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">parse_into</span><span class="p">(</span><span class="n">into</span><span class="p">,</span> <span class="n">sql</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span>
</span><span id="L-125"><a href="#L-125"><span class="linenos">125</span></a> <span class="n">result</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> </span><span id="L-125"><a href="#L-125"><span class="linenos">125</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-126"><a href="#L-126"><span class="linenos">126</span></a> </span><span id="L-126"><a href="#L-126"><span class="linenos">126</span></a> <span class="n">result</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span>
</span><span id="L-127"><a href="#L-127"><span class="linenos">127</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">result</span><span class="p">:</span> </span><span id="L-127"><a href="#L-127"><span class="linenos">127</span></a>
</span><span id="L-128"><a href="#L-128"><span class="linenos">128</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">expression</span><span class="p">:</span> </span><span id="L-128"><a href="#L-128"><span class="linenos">128</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">result</span><span class="p">:</span>
</span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;No expression was parsed from &#39;</span><span class="si">{</span><span class="n">sql</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span> </span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">expression</span><span class="p">:</span>
</span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;No expression was parsed from &#39;</span><span class="si">{</span><span class="n">sql</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span>
</span><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-132"><a href="#L-132"><span class="linenos">132</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;No expression was parsed from &#39;</span><span class="si">{</span><span class="n">sql</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span> </span><span id="L-132"><a href="#L-132"><span class="linenos">132</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-133"><a href="#L-133"><span class="linenos">133</span></a> </span><span id="L-133"><a href="#L-133"><span class="linenos">133</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;No expression was parsed from &#39;</span><span class="si">{</span><span class="n">sql</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span>
</span><span id="L-134"><a href="#L-134"><span class="linenos">134</span></a> </span><span id="L-134"><a href="#L-134"><span class="linenos">134</span></a>
</span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a><span class="k">def</span> <span class="nf">transpile</span><span class="p">(</span> </span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a>
</span><span id="L-136"><a href="#L-136"><span class="linenos">136</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> </span><span id="L-136"><a href="#L-136"><span class="linenos">136</span></a><span class="k">def</span> <span class="nf">transpile</span><span class="p">(</span>
</span><span id="L-137"><a href="#L-137"><span class="linenos">137</span></a> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="L-137"><a href="#L-137"><span class="linenos">137</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="L-138"><a href="#L-138"><span class="linenos">138</span></a> <span class="n">write</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="L-138"><a href="#L-138"><span class="linenos">138</span></a> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-139"><a href="#L-139"><span class="linenos">139</span></a> <span class="n">identity</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> </span><span id="L-139"><a href="#L-139"><span class="linenos">139</span></a> <span class="n">write</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-140"><a href="#L-140"><span class="linenos">140</span></a> <span class="n">error_level</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">ErrorLevel</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="L-140"><a href="#L-140"><span class="linenos">140</span></a> <span class="n">identity</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="L-141"><a href="#L-141"><span class="linenos">141</span></a> <span class="o">**</span><span class="n">opts</span><span class="p">,</span> </span><span id="L-141"><a href="#L-141"><span class="linenos">141</span></a> <span class="n">error_level</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">ErrorLevel</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-142"><a href="#L-142"><span class="linenos">142</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span> </span><span id="L-142"><a href="#L-142"><span class="linenos">142</span></a> <span class="o">**</span><span class="n">opts</span><span class="p">,</span>
</span><span id="L-143"><a href="#L-143"><span class="linenos">143</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-143"><a href="#L-143"><span class="linenos">143</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
</span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a><span class="sd"> Parses the given SQL string in accordance with the source dialect and returns a list of SQL strings transformed</span> </span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a><span class="sd"> to conform to the target dialect. Each string in the returned list represents a single transformed SQL statement.</span> </span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a><span class="sd"> Parses the given SQL string in accordance with the source dialect and returns a list of SQL strings transformed</span>
</span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a> </span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a><span class="sd"> to conform to the target dialect. Each string in the returned list represents a single transformed SQL statement.</span>
</span><span id="L-147"><a href="#L-147"><span class="linenos">147</span></a><span class="sd"> Args:</span> </span><span id="L-147"><a href="#L-147"><span class="linenos">147</span></a>
</span><span id="L-148"><a href="#L-148"><span class="linenos">148</span></a><span class="sd"> sql: the SQL code string to transpile.</span> </span><span id="L-148"><a href="#L-148"><span class="linenos">148</span></a><span class="sd"> Args:</span>
</span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a><span class="sd"> read: the source dialect used to parse the input string (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span> </span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a><span class="sd"> sql: the SQL code string to transpile.</span>
</span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a><span class="sd"> write: the target dialect into which the input should be transformed (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span> </span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a><span class="sd"> read: the source dialect used to parse the input string (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span>
</span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a><span class="sd"> identity: if set to `True` and if the target dialect is not specified the source dialect will be used as both:</span> </span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a><span class="sd"> write: the target dialect into which the input should be transformed (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span>
</span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a><span class="sd"> the source and the target dialect.</span> </span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a><span class="sd"> identity: if set to `True` and if the target dialect is not specified the source dialect will be used as both:</span>
</span><span id="L-153"><a href="#L-153"><span class="linenos">153</span></a><span class="sd"> error_level: the desired error level of the parser.</span> </span><span id="L-153"><a href="#L-153"><span class="linenos">153</span></a><span class="sd"> the source and the target dialect.</span>
</span><span id="L-154"><a href="#L-154"><span class="linenos">154</span></a><span class="sd"> **opts: other `sqlglot.generator.Generator` options.</span> </span><span id="L-154"><a href="#L-154"><span class="linenos">154</span></a><span class="sd"> error_level: the desired error level of the parser.</span>
</span><span id="L-155"><a href="#L-155"><span class="linenos">155</span></a> </span><span id="L-155"><a href="#L-155"><span class="linenos">155</span></a><span class="sd"> **opts: other `sqlglot.generator.Generator` options.</span>
</span><span id="L-156"><a href="#L-156"><span class="linenos">156</span></a><span class="sd"> Returns:</span> </span><span id="L-156"><a href="#L-156"><span class="linenos">156</span></a>
</span><span id="L-157"><a href="#L-157"><span class="linenos">157</span></a><span class="sd"> The list of transpiled SQL statements.</span> </span><span id="L-157"><a href="#L-157"><span class="linenos">157</span></a><span class="sd"> Returns:</span>
</span><span id="L-158"><a href="#L-158"><span class="linenos">158</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-158"><a href="#L-158"><span class="linenos">158</span></a><span class="sd"> The list of transpiled SQL statements.</span>
</span><span id="L-159"><a href="#L-159"><span class="linenos">159</span></a> <span class="n">write</span> <span class="o">=</span> <span class="p">(</span><span class="n">read</span> <span class="k">if</span> <span class="n">write</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">write</span><span class="p">)</span> <span class="k">if</span> <span class="n">identity</span> <span class="k">else</span> <span class="n">write</span> </span><span id="L-159"><a href="#L-159"><span class="linenos">159</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-160"><a href="#L-160"><span class="linenos">160</span></a> <span class="n">write</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">write</span><span class="p">)</span> </span><span id="L-160"><a href="#L-160"><span class="linenos">160</span></a> <span class="n">write</span> <span class="o">=</span> <span class="p">(</span><span class="n">read</span> <span class="k">if</span> <span class="n">write</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">write</span><span class="p">)</span> <span class="k">if</span> <span class="n">identity</span> <span class="k">else</span> <span class="n">write</span>
</span><span id="L-161"><a href="#L-161"><span class="linenos">161</span></a> <span class="k">return</span> <span class="p">[</span> </span><span id="L-161"><a href="#L-161"><span class="linenos">161</span></a> <span class="n">write</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">write</span><span class="p">)</span>
</span><span id="L-162"><a href="#L-162"><span class="linenos">162</span></a> <span class="n">write</span><span class="o">.</span><span class="n">generate</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> <span class="k">if</span> <span class="n">expression</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span> </span><span id="L-162"><a href="#L-162"><span class="linenos">162</span></a> <span class="k">return</span> <span class="p">[</span>
</span><span id="L-163"><a href="#L-163"><span class="linenos">163</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">parse</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="n">read</span><span class="p">,</span> <span class="n">error_level</span><span class="o">=</span><span class="n">error_level</span><span class="p">)</span> </span><span id="L-163"><a href="#L-163"><span class="linenos">163</span></a> <span class="n">write</span><span class="o">.</span><span class="n">generate</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> <span class="k">if</span> <span class="n">expression</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
</span><span id="L-164"><a href="#L-164"><span class="linenos">164</span></a> <span class="p">]</span> </span><span id="L-164"><a href="#L-164"><span class="linenos">164</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">parse</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="n">read</span><span class="p">,</span> <span class="n">error_level</span><span class="o">=</span><span class="n">error_level</span><span class="p">)</span>
</span><span id="L-165"><a href="#L-165"><span class="linenos">165</span></a> <span class="p">]</span>
</span></pre></div> </span></pre></div>
@ -926,22 +927,22 @@ make check # Full test suite &amp; linter checks
</div> </div>
<a class="headerlink" href="#parse"></a> <a class="headerlink" href="#parse"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="parse-72"><a href="#parse-72"><span class="linenos">72</span></a><span class="k">def</span> <span class="nf">parse</span><span class="p">(</span> <div class="pdoc-code codehilite"><pre><span></span><span id="parse-73"><a href="#parse-73"><span class="linenos">73</span></a><span class="k">def</span> <span class="nf">parse</span><span class="p">(</span>
</span><span id="parse-73"><a href="#parse-73"><span class="linenos">73</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span> </span><span id="parse-74"><a href="#parse-74"><span class="linenos">74</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span>
</span><span id="parse-74"><a href="#parse-74"><span class="linenos">74</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">Expression</span><span class="p">]]:</span> </span><span id="parse-75"><a href="#parse-75"><span class="linenos">75</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">Expression</span><span class="p">]]:</span>
</span><span id="parse-75"><a href="#parse-75"><span class="linenos">75</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="parse-76"><a href="#parse-76"><span class="linenos">76</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="parse-76"><a href="#parse-76"><span class="linenos">76</span></a><span class="sd"> Parses the given SQL string into a collection of syntax trees, one per parsed SQL statement.</span> </span><span id="parse-77"><a href="#parse-77"><span class="linenos">77</span></a><span class="sd"> Parses the given SQL string into a collection of syntax trees, one per parsed SQL statement.</span>
</span><span id="parse-77"><a href="#parse-77"><span class="linenos">77</span></a> </span><span id="parse-78"><a href="#parse-78"><span class="linenos">78</span></a>
</span><span id="parse-78"><a href="#parse-78"><span class="linenos">78</span></a><span class="sd"> Args:</span> </span><span id="parse-79"><a href="#parse-79"><span class="linenos">79</span></a><span class="sd"> Args:</span>
</span><span id="parse-79"><a href="#parse-79"><span class="linenos">79</span></a><span class="sd"> sql: the SQL code string to parse.</span> </span><span id="parse-80"><a href="#parse-80"><span class="linenos">80</span></a><span class="sd"> sql: the SQL code string to parse.</span>
</span><span id="parse-80"><a href="#parse-80"><span class="linenos">80</span></a><span class="sd"> read: the SQL dialect to apply during parsing (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span> </span><span id="parse-81"><a href="#parse-81"><span class="linenos">81</span></a><span class="sd"> read: the SQL dialect to apply during parsing (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span>
</span><span id="parse-81"><a href="#parse-81"><span class="linenos">81</span></a><span class="sd"> dialect: the SQL dialect (alias for read).</span> </span><span id="parse-82"><a href="#parse-82"><span class="linenos">82</span></a><span class="sd"> dialect: the SQL dialect (alias for read).</span>
</span><span id="parse-82"><a href="#parse-82"><span class="linenos">82</span></a><span class="sd"> **opts: other `sqlglot.parser.Parser` options.</span> </span><span id="parse-83"><a href="#parse-83"><span class="linenos">83</span></a><span class="sd"> **opts: other `sqlglot.parser.Parser` options.</span>
</span><span id="parse-83"><a href="#parse-83"><span class="linenos">83</span></a> </span><span id="parse-84"><a href="#parse-84"><span class="linenos">84</span></a>
</span><span id="parse-84"><a href="#parse-84"><span class="linenos">84</span></a><span class="sd"> Returns:</span> </span><span id="parse-85"><a href="#parse-85"><span class="linenos">85</span></a><span class="sd"> Returns:</span>
</span><span id="parse-85"><a href="#parse-85"><span class="linenos">85</span></a><span class="sd"> The resulting syntax tree collection.</span> </span><span id="parse-86"><a href="#parse-86"><span class="linenos">86</span></a><span class="sd"> The resulting syntax tree collection.</span>
</span><span id="parse-86"><a href="#parse-86"><span class="linenos">86</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="parse-87"><a href="#parse-87"><span class="linenos">87</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="parse-87"><a href="#parse-87"><span class="linenos">87</span></a> <span class="k">return</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">read</span> <span class="ow">or</span> <span class="n">dialect</span><span class="p">)</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> </span><span id="parse-88"><a href="#parse-88"><span class="linenos">88</span></a> <span class="k">return</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">read</span> <span class="ow">or</span> <span class="n">dialect</span><span class="p">)</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span>
</span></pre></div> </span></pre></div>
@ -976,40 +977,40 @@ make check # Full test suite &amp; linter checks
</div> </div>
<a class="headerlink" href="#parse_one"></a> <a class="headerlink" href="#parse_one"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="parse_one-100"><a href="#parse_one-100"><span class="linenos">100</span></a><span class="k">def</span> <span class="nf">parse_one</span><span class="p">(</span> <div class="pdoc-code codehilite"><pre><span></span><span id="parse_one-101"><a href="#parse_one-101"><span class="linenos">101</span></a><span class="k">def</span> <span class="nf">parse_one</span><span class="p">(</span>
</span><span id="parse_one-101"><a href="#parse_one-101"><span class="linenos">101</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> </span><span id="parse_one-102"><a href="#parse_one-102"><span class="linenos">102</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="parse_one-102"><a href="#parse_one-102"><span class="linenos">102</span></a> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="parse_one-103"><a href="#parse_one-103"><span class="linenos">103</span></a> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="parse_one-103"><a href="#parse_one-103"><span class="linenos">103</span></a> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="parse_one-104"><a href="#parse_one-104"><span class="linenos">104</span></a> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="parse_one-104"><a href="#parse_one-104"><span class="linenos">104</span></a> <span class="n">into</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">IntoType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="parse_one-105"><a href="#parse_one-105"><span class="linenos">105</span></a> <span class="n">into</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">IntoType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="parse_one-105"><a href="#parse_one-105"><span class="linenos">105</span></a> <span class="o">**</span><span class="n">opts</span><span class="p">,</span> </span><span id="parse_one-106"><a href="#parse_one-106"><span class="linenos">106</span></a> <span class="o">**</span><span class="n">opts</span><span class="p">,</span>
</span><span id="parse_one-106"><a href="#parse_one-106"><span class="linenos">106</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Expression</span><span class="p">:</span> </span><span id="parse_one-107"><a href="#parse_one-107"><span class="linenos">107</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Expression</span><span class="p">:</span>
</span><span id="parse_one-107"><a href="#parse_one-107"><span class="linenos">107</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="parse_one-108"><a href="#parse_one-108"><span class="linenos">108</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="parse_one-108"><a href="#parse_one-108"><span class="linenos">108</span></a><span class="sd"> Parses the given SQL string and returns a syntax tree for the first parsed SQL statement.</span> </span><span id="parse_one-109"><a href="#parse_one-109"><span class="linenos">109</span></a><span class="sd"> Parses the given SQL string and returns a syntax tree for the first parsed SQL statement.</span>
</span><span id="parse_one-109"><a href="#parse_one-109"><span class="linenos">109</span></a> </span><span id="parse_one-110"><a href="#parse_one-110"><span class="linenos">110</span></a>
</span><span id="parse_one-110"><a href="#parse_one-110"><span class="linenos">110</span></a><span class="sd"> Args:</span> </span><span id="parse_one-111"><a href="#parse_one-111"><span class="linenos">111</span></a><span class="sd"> Args:</span>
</span><span id="parse_one-111"><a href="#parse_one-111"><span class="linenos">111</span></a><span class="sd"> sql: the SQL code string to parse.</span> </span><span id="parse_one-112"><a href="#parse_one-112"><span class="linenos">112</span></a><span class="sd"> sql: the SQL code string to parse.</span>
</span><span id="parse_one-112"><a href="#parse_one-112"><span class="linenos">112</span></a><span class="sd"> read: the SQL dialect to apply during parsing (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span> </span><span id="parse_one-113"><a href="#parse_one-113"><span class="linenos">113</span></a><span class="sd"> read: the SQL dialect to apply during parsing (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span>
</span><span id="parse_one-113"><a href="#parse_one-113"><span class="linenos">113</span></a><span class="sd"> dialect: the SQL dialect (alias for read)</span> </span><span id="parse_one-114"><a href="#parse_one-114"><span class="linenos">114</span></a><span class="sd"> dialect: the SQL dialect (alias for read)</span>
</span><span id="parse_one-114"><a href="#parse_one-114"><span class="linenos">114</span></a><span class="sd"> into: the SQLGlot Expression to parse into.</span> </span><span id="parse_one-115"><a href="#parse_one-115"><span class="linenos">115</span></a><span class="sd"> into: the SQLGlot Expression to parse into.</span>
</span><span id="parse_one-115"><a href="#parse_one-115"><span class="linenos">115</span></a><span class="sd"> **opts: other `sqlglot.parser.Parser` options.</span> </span><span id="parse_one-116"><a href="#parse_one-116"><span class="linenos">116</span></a><span class="sd"> **opts: other `sqlglot.parser.Parser` options.</span>
</span><span id="parse_one-116"><a href="#parse_one-116"><span class="linenos">116</span></a> </span><span id="parse_one-117"><a href="#parse_one-117"><span class="linenos">117</span></a>
</span><span id="parse_one-117"><a href="#parse_one-117"><span class="linenos">117</span></a><span class="sd"> Returns:</span> </span><span id="parse_one-118"><a href="#parse_one-118"><span class="linenos">118</span></a><span class="sd"> Returns:</span>
</span><span id="parse_one-118"><a href="#parse_one-118"><span class="linenos">118</span></a><span class="sd"> The syntax tree for the first parsed statement.</span> </span><span id="parse_one-119"><a href="#parse_one-119"><span class="linenos">119</span></a><span class="sd"> The syntax tree for the first parsed statement.</span>
</span><span id="parse_one-119"><a href="#parse_one-119"><span class="linenos">119</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="parse_one-120"><a href="#parse_one-120"><span class="linenos">120</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="parse_one-120"><a href="#parse_one-120"><span class="linenos">120</span></a> </span><span id="parse_one-121"><a href="#parse_one-121"><span class="linenos">121</span></a>
</span><span id="parse_one-121"><a href="#parse_one-121"><span class="linenos">121</span></a> <span class="n">dialect</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">read</span> <span class="ow">or</span> <span class="n">dialect</span><span class="p">)</span> </span><span id="parse_one-122"><a href="#parse_one-122"><span class="linenos">122</span></a> <span class="n">dialect</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">read</span> <span class="ow">or</span> <span class="n">dialect</span><span class="p">)</span>
</span><span id="parse_one-122"><a href="#parse_one-122"><span class="linenos">122</span></a> </span><span id="parse_one-123"><a href="#parse_one-123"><span class="linenos">123</span></a>
</span><span id="parse_one-123"><a href="#parse_one-123"><span class="linenos">123</span></a> <span class="k">if</span> <span class="n">into</span><span class="p">:</span> </span><span id="parse_one-124"><a href="#parse_one-124"><span class="linenos">124</span></a> <span class="k">if</span> <span class="n">into</span><span class="p">:</span>
</span><span id="parse_one-124"><a href="#parse_one-124"><span class="linenos">124</span></a> <span class="n">result</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">parse_into</span><span class="p">(</span><span class="n">into</span><span class="p">,</span> <span class="n">sql</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> </span><span id="parse_one-125"><a href="#parse_one-125"><span class="linenos">125</span></a> <span class="n">result</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">parse_into</span><span class="p">(</span><span class="n">into</span><span class="p">,</span> <span class="n">sql</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span>
</span><span id="parse_one-125"><a href="#parse_one-125"><span class="linenos">125</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="parse_one-126"><a href="#parse_one-126"><span class="linenos">126</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="parse_one-126"><a href="#parse_one-126"><span class="linenos">126</span></a> <span class="n">result</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> </span><span id="parse_one-127"><a href="#parse_one-127"><span class="linenos">127</span></a> <span class="n">result</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span>
</span><span id="parse_one-127"><a href="#parse_one-127"><span class="linenos">127</span></a> </span><span id="parse_one-128"><a href="#parse_one-128"><span class="linenos">128</span></a>
</span><span id="parse_one-128"><a href="#parse_one-128"><span class="linenos">128</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">result</span><span class="p">:</span> </span><span id="parse_one-129"><a href="#parse_one-129"><span class="linenos">129</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">result</span><span class="p">:</span>
</span><span id="parse_one-129"><a href="#parse_one-129"><span class="linenos">129</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">expression</span><span class="p">:</span> </span><span id="parse_one-130"><a href="#parse_one-130"><span class="linenos">130</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">expression</span><span class="p">:</span>
</span><span id="parse_one-130"><a href="#parse_one-130"><span class="linenos">130</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;No expression was parsed from &#39;</span><span class="si">{</span><span class="n">sql</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span> </span><span id="parse_one-131"><a href="#parse_one-131"><span class="linenos">131</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;No expression was parsed from &#39;</span><span class="si">{</span><span class="n">sql</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span>
</span><span id="parse_one-131"><a href="#parse_one-131"><span class="linenos">131</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="parse_one-132"><a href="#parse_one-132"><span class="linenos">132</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="parse_one-132"><a href="#parse_one-132"><span class="linenos">132</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="parse_one-133"><a href="#parse_one-133"><span class="linenos">133</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="parse_one-133"><a href="#parse_one-133"><span class="linenos">133</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;No expression was parsed from &#39;</span><span class="si">{</span><span class="n">sql</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span> </span><span id="parse_one-134"><a href="#parse_one-134"><span class="linenos">134</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;No expression was parsed from &#39;</span><span class="si">{</span><span class="n">sql</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span>
</span></pre></div> </span></pre></div>
@ -1045,36 +1046,36 @@ make check # Full test suite &amp; linter checks
</div> </div>
<a class="headerlink" href="#transpile"></a> <a class="headerlink" href="#transpile"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="transpile-136"><a href="#transpile-136"><span class="linenos">136</span></a><span class="k">def</span> <span class="nf">transpile</span><span class="p">(</span> <div class="pdoc-code codehilite"><pre><span></span><span id="transpile-137"><a href="#transpile-137"><span class="linenos">137</span></a><span class="k">def</span> <span class="nf">transpile</span><span class="p">(</span>
</span><span id="transpile-137"><a href="#transpile-137"><span class="linenos">137</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> </span><span id="transpile-138"><a href="#transpile-138"><span class="linenos">138</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="transpile-138"><a href="#transpile-138"><span class="linenos">138</span></a> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="transpile-139"><a href="#transpile-139"><span class="linenos">139</span></a> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="transpile-139"><a href="#transpile-139"><span class="linenos">139</span></a> <span class="n">write</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="transpile-140"><a href="#transpile-140"><span class="linenos">140</span></a> <span class="n">write</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="transpile-140"><a href="#transpile-140"><span class="linenos">140</span></a> <span class="n">identity</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> </span><span id="transpile-141"><a href="#transpile-141"><span class="linenos">141</span></a> <span class="n">identity</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="transpile-141"><a href="#transpile-141"><span class="linenos">141</span></a> <span class="n">error_level</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">ErrorLevel</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="transpile-142"><a href="#transpile-142"><span class="linenos">142</span></a> <span class="n">error_level</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">ErrorLevel</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="transpile-142"><a href="#transpile-142"><span class="linenos">142</span></a> <span class="o">**</span><span class="n">opts</span><span class="p">,</span> </span><span id="transpile-143"><a href="#transpile-143"><span class="linenos">143</span></a> <span class="o">**</span><span class="n">opts</span><span class="p">,</span>
</span><span id="transpile-143"><a href="#transpile-143"><span class="linenos">143</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span> </span><span id="transpile-144"><a href="#transpile-144"><span class="linenos">144</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
</span><span id="transpile-144"><a href="#transpile-144"><span class="linenos">144</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="transpile-145"><a href="#transpile-145"><span class="linenos">145</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="transpile-145"><a href="#transpile-145"><span class="linenos">145</span></a><span class="sd"> Parses the given SQL string in accordance with the source dialect and returns a list of SQL strings transformed</span> </span><span id="transpile-146"><a href="#transpile-146"><span class="linenos">146</span></a><span class="sd"> Parses the given SQL string in accordance with the source dialect and returns a list of SQL strings transformed</span>
</span><span id="transpile-146"><a href="#transpile-146"><span class="linenos">146</span></a><span class="sd"> to conform to the target dialect. Each string in the returned list represents a single transformed SQL statement.</span> </span><span id="transpile-147"><a href="#transpile-147"><span class="linenos">147</span></a><span class="sd"> to conform to the target dialect. Each string in the returned list represents a single transformed SQL statement.</span>
</span><span id="transpile-147"><a href="#transpile-147"><span class="linenos">147</span></a> </span><span id="transpile-148"><a href="#transpile-148"><span class="linenos">148</span></a>
</span><span id="transpile-148"><a href="#transpile-148"><span class="linenos">148</span></a><span class="sd"> Args:</span> </span><span id="transpile-149"><a href="#transpile-149"><span class="linenos">149</span></a><span class="sd"> Args:</span>
</span><span id="transpile-149"><a href="#transpile-149"><span class="linenos">149</span></a><span class="sd"> sql: the SQL code string to transpile.</span> </span><span id="transpile-150"><a href="#transpile-150"><span class="linenos">150</span></a><span class="sd"> sql: the SQL code string to transpile.</span>
</span><span id="transpile-150"><a href="#transpile-150"><span class="linenos">150</span></a><span class="sd"> read: the source dialect used to parse the input string (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span> </span><span id="transpile-151"><a href="#transpile-151"><span class="linenos">151</span></a><span class="sd"> read: the source dialect used to parse the input string (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span>
</span><span id="transpile-151"><a href="#transpile-151"><span class="linenos">151</span></a><span class="sd"> write: the target dialect into which the input should be transformed (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span> </span><span id="transpile-152"><a href="#transpile-152"><span class="linenos">152</span></a><span class="sd"> write: the target dialect into which the input should be transformed (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span>
</span><span id="transpile-152"><a href="#transpile-152"><span class="linenos">152</span></a><span class="sd"> identity: if set to `True` and if the target dialect is not specified the source dialect will be used as both:</span> </span><span id="transpile-153"><a href="#transpile-153"><span class="linenos">153</span></a><span class="sd"> identity: if set to `True` and if the target dialect is not specified the source dialect will be used as both:</span>
</span><span id="transpile-153"><a href="#transpile-153"><span class="linenos">153</span></a><span class="sd"> the source and the target dialect.</span> </span><span id="transpile-154"><a href="#transpile-154"><span class="linenos">154</span></a><span class="sd"> the source and the target dialect.</span>
</span><span id="transpile-154"><a href="#transpile-154"><span class="linenos">154</span></a><span class="sd"> error_level: the desired error level of the parser.</span> </span><span id="transpile-155"><a href="#transpile-155"><span class="linenos">155</span></a><span class="sd"> error_level: the desired error level of the parser.</span>
</span><span id="transpile-155"><a href="#transpile-155"><span class="linenos">155</span></a><span class="sd"> **opts: other `sqlglot.generator.Generator` options.</span> </span><span id="transpile-156"><a href="#transpile-156"><span class="linenos">156</span></a><span class="sd"> **opts: other `sqlglot.generator.Generator` options.</span>
</span><span id="transpile-156"><a href="#transpile-156"><span class="linenos">156</span></a> </span><span id="transpile-157"><a href="#transpile-157"><span class="linenos">157</span></a>
</span><span id="transpile-157"><a href="#transpile-157"><span class="linenos">157</span></a><span class="sd"> Returns:</span> </span><span id="transpile-158"><a href="#transpile-158"><span class="linenos">158</span></a><span class="sd"> Returns:</span>
</span><span id="transpile-158"><a href="#transpile-158"><span class="linenos">158</span></a><span class="sd"> The list of transpiled SQL statements.</span> </span><span id="transpile-159"><a href="#transpile-159"><span class="linenos">159</span></a><span class="sd"> The list of transpiled SQL statements.</span>
</span><span id="transpile-159"><a href="#transpile-159"><span class="linenos">159</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="transpile-160"><a href="#transpile-160"><span class="linenos">160</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="transpile-160"><a href="#transpile-160"><span class="linenos">160</span></a> <span class="n">write</span> <span class="o">=</span> <span class="p">(</span><span class="n">read</span> <span class="k">if</span> <span class="n">write</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">write</span><span class="p">)</span> <span class="k">if</span> <span class="n">identity</span> <span class="k">else</span> <span class="n">write</span> </span><span id="transpile-161"><a href="#transpile-161"><span class="linenos">161</span></a> <span class="n">write</span> <span class="o">=</span> <span class="p">(</span><span class="n">read</span> <span class="k">if</span> <span class="n">write</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">write</span><span class="p">)</span> <span class="k">if</span> <span class="n">identity</span> <span class="k">else</span> <span class="n">write</span>
</span><span id="transpile-161"><a href="#transpile-161"><span class="linenos">161</span></a> <span class="n">write</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">write</span><span class="p">)</span> </span><span id="transpile-162"><a href="#transpile-162"><span class="linenos">162</span></a> <span class="n">write</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">write</span><span class="p">)</span>
</span><span id="transpile-162"><a href="#transpile-162"><span class="linenos">162</span></a> <span class="k">return</span> <span class="p">[</span> </span><span id="transpile-163"><a href="#transpile-163"><span class="linenos">163</span></a> <span class="k">return</span> <span class="p">[</span>
</span><span id="transpile-163"><a href="#transpile-163"><span class="linenos">163</span></a> <span class="n">write</span><span class="o">.</span><span class="n">generate</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> <span class="k">if</span> <span class="n">expression</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span> </span><span id="transpile-164"><a href="#transpile-164"><span class="linenos">164</span></a> <span class="n">write</span><span class="o">.</span><span class="n">generate</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">opts</span><span class="p">)</span> <span class="k">if</span> <span class="n">expression</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
</span><span id="transpile-164"><a href="#transpile-164"><span class="linenos">164</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">parse</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="n">read</span><span class="p">,</span> <span class="n">error_level</span><span class="o">=</span><span class="n">error_level</span><span class="p">)</span> </span><span id="transpile-165"><a href="#transpile-165"><span class="linenos">165</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">parse</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="n">read</span><span class="p">,</span> <span class="n">error_level</span><span class="o">=</span><span class="n">error_level</span><span class="p">)</span>
</span><span id="transpile-165"><a href="#transpile-165"><span class="linenos">165</span></a> <span class="p">]</span> </span><span id="transpile-166"><a href="#transpile-166"><span class="linenos">166</span></a> <span class="p">]</span>
</span></pre></div> </span></pre></div>

View file

@ -57,17 +57,18 @@
</span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a> </span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a>
</span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span> </span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a> </span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a>
</span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="kn">from</span> <span class="nn">typing_extensions</span> <span class="kn">import</span> <span class="n">Literal</span> <span class="k">as</span> <span class="n">Lit</span> <span class="c1"># noqa</span> </span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="kn">import</span> <span class="nn">sqlglot</span>
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a> </span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="kn">import</span> <span class="nn">sqlglot</span> </span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">TYPE_CHECKING</span><span class="p">:</span>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a> </span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a> <span class="kn">from</span> <span class="nn">typing_extensions</span> <span class="kn">import</span> <span class="n">Literal</span> <span class="k">as</span> <span class="n">Lit</span> <span class="c1"># noqa</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="c1"># A little hack for backwards compatibility with Python 3.7.</span> </span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a>
</span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a><span class="c1"># For example, we might want a TypeVar for objects that support comparison e.g. SupportsRichComparisonT from typeshed.</span> </span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a><span class="c1"># A little hack for backwards compatibility with Python 3.7.</span>
</span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a><span class="c1"># But Python 3.7 doesn&#39;t support Protocols, so we&#39;d also need typing_extensions, which we don&#39;t want as a dependency.</span> </span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a><span class="c1"># For example, we might want a TypeVar for objects that support comparison e.g. SupportsRichComparisonT from typeshed.</span>
</span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a><span class="n">A</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">TypeVar</span><span class="p">(</span><span class="s2">&quot;A&quot;</span><span class="p">,</span> <span class="n">bound</span><span class="o">=</span><span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> </span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a><span class="c1"># But Python 3.7 doesn&#39;t support Protocols, so we&#39;d also need typing_extensions, which we don&#39;t want as a dependency.</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a> </span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a><span class="n">A</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">TypeVar</span><span class="p">(</span><span class="s2">&quot;A&quot;</span><span class="p">,</span> <span class="n">bound</span><span class="o">=</span><span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a><span class="n">E</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">TypeVar</span><span class="p">(</span><span class="s2">&quot;E&quot;</span><span class="p">,</span> <span class="n">bound</span><span class="o">=</span><span class="s2">&quot;sqlglot.exp.Expression&quot;</span><span class="p">)</span> </span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a><span class="n">B</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">TypeVar</span><span class="p">(</span><span class="s2">&quot;B&quot;</span><span class="p">,</span> <span class="n">bound</span><span class="o">=</span><span class="s2">&quot;sqlglot.exp.Binary&quot;</span><span class="p">)</span>
</span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a><span class="n">T</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">TypeVar</span><span class="p">(</span><span class="s2">&quot;T&quot;</span><span class="p">)</span> </span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a><span class="n">E</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">TypeVar</span><span class="p">(</span><span class="s2">&quot;E&quot;</span><span class="p">,</span> <span class="n">bound</span><span class="o">=</span><span class="s2">&quot;sqlglot.exp.Expression&quot;</span><span class="p">)</span>
</span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a><span class="n">T</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">TypeVar</span><span class="p">(</span><span class="s2">&quot;T&quot;</span><span class="p">)</span>
</span></pre></div> </span></pre></div>

View file

@ -76,8 +76,8 @@
</span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a><span class="n">__version_tuple__</span><span class="p">:</span> <span class="n">VERSION_TUPLE</span> </span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a><span class="n">__version_tuple__</span><span class="p">:</span> <span class="n">VERSION_TUPLE</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a><span class="n">version_tuple</span><span class="p">:</span> <span class="n">VERSION_TUPLE</span> </span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a><span class="n">version_tuple</span><span class="p">:</span> <span class="n">VERSION_TUPLE</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a> </span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a>
</span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a><span class="n">__version__</span> <span class="o">=</span> <span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;20.10.0&#39;</span> </span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a><span class="n">__version__</span> <span class="o">=</span> <span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;21.0.0&#39;</span>
</span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a><span class="n">__version_tuple__</span> <span class="o">=</span> <span class="n">version_tuple</span> <span class="o">=</span> <span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> </span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a><span class="n">__version_tuple__</span> <span class="o">=</span> <span class="n">version_tuple</span> <span class="o">=</span> <span class="p">(</span><span class="mi">21</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</span></pre></div> </span></pre></div>
@ -97,7 +97,7 @@
<section id="version"> <section id="version">
<div class="attr variable"> <div class="attr variable">
<span class="name">version</span><span class="annotation">: str</span> = <span class="name">version</span><span class="annotation">: str</span> =
<span class="default_value">&#39;20.10.0&#39;</span> <span class="default_value">&#39;21.0.0&#39;</span>
</div> </div>
@ -109,7 +109,7 @@
<section id="version_tuple"> <section id="version_tuple">
<div class="attr variable"> <div class="attr variable">
<span class="name">version_tuple</span><span class="annotation">: object</span> = <span class="name">version_tuple</span><span class="annotation">: object</span> =
<span class="default_value">(20, 10, 0)</span> <span class="default_value">(21, 0, 0)</span>
</div> </div>

File diff suppressed because it is too large Load diff

View file

@ -76,7 +76,7 @@
<p>While there is a SQL standard, most SQL engines support a variation of that standard. This makes it difficult <p>While there is a SQL standard, most SQL engines support a variation of that standard. This makes it difficult
to write portable SQL code. SQLGlot bridges all the different variations, called "dialects", with an extensible to write portable SQL code. SQLGlot bridges all the different variations, called "dialects", with an extensible
SQL transpilation framework. </p> SQL transpilation framework.</p>
<p>The base <code><a href="dialects/dialect.html#Dialect">sqlglot.dialects.dialect.Dialect</a></code> class implements a generic dialect that aims to be as universal as possible.</p> <p>The base <code><a href="dialects/dialect.html#Dialect">sqlglot.dialects.dialect.Dialect</a></code> class implements a generic dialect that aims to be as universal as possible.</p>
@ -138,90 +138,91 @@ dialect implementations in order to understand how their various components can
<label class="view-source-button" for="mod-dialects-view-source"><span>View Source</span></label> <label class="view-source-button" for="mod-dialects-view-source"><span>View Source</span></label>
<div class="pdoc-code codehilite"><pre><span></span><span id="L-1"><a href="#L-1"><span class="linenos"> 1</span></a><span class="sd">&quot;&quot;&quot;</span> <div class="pdoc-code codehilite"><pre><span></span><span id="L-1"><a href="#L-1"><span class="linenos"> 1</span></a><span class="c1"># ruff: noqa: F401</span>
</span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a><span class="sd">## Dialects</span> </span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a> </span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="sd">## Dialects</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a><span class="sd">While there is a SQL standard, most SQL engines support a variation of that standard. This makes it difficult</span> </span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a>
</span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="sd">to write portable SQL code. SQLGlot bridges all the different variations, called &quot;dialects&quot;, with an extensible</span> </span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="sd">While there is a SQL standard, most SQL engines support a variation of that standard. This makes it difficult</span>
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a><span class="sd">SQL transpilation framework. </span> </span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a><span class="sd">to write portable SQL code. SQLGlot bridges all the different variations, called &quot;dialects&quot;, with an extensible</span>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a> </span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="sd">SQL transpilation framework.</span>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="sd">The base `sqlglot.dialects.dialect.Dialect` class implements a generic dialect that aims to be as universal as possible.</span> </span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a> </span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="sd">The base `sqlglot.dialects.dialect.Dialect` class implements a generic dialect that aims to be as universal as possible.</span>
</span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a><span class="sd">Each SQL variation has its own `Dialect` subclass, extending the corresponding `Tokenizer`, `Parser` and `Generator`</span> </span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a>
</span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a><span class="sd">classes as needed.</span> </span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a><span class="sd">Each SQL variation has its own `Dialect` subclass, extending the corresponding `Tokenizer`, `Parser` and `Generator`</span>
</span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a> </span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a><span class="sd">classes as needed.</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a><span class="sd">### Implementing a custom Dialect</span> </span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a>
</span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a> </span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a><span class="sd">### Implementing a custom Dialect</span>
</span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a><span class="sd">Creating a new SQL dialect may seem complicated at first, but it is actually quite simple in SQLGlot:</span> </span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a>
</span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a> </span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a><span class="sd">Creating a new SQL dialect may seem complicated at first, but it is actually quite simple in SQLGlot:</span>
</span><span id="L-17"><a href="#L-17"><span class="linenos">17</span></a><span class="sd">```python</span> </span><span id="L-17"><a href="#L-17"><span class="linenos">17</span></a>
</span><span id="L-18"><a href="#L-18"><span class="linenos">18</span></a><span class="sd">from sqlglot import exp</span> </span><span id="L-18"><a href="#L-18"><span class="linenos">18</span></a><span class="sd">```python</span>
</span><span id="L-19"><a href="#L-19"><span class="linenos">19</span></a><span class="sd">from sqlglot.dialects.dialect import Dialect</span> </span><span id="L-19"><a href="#L-19"><span class="linenos">19</span></a><span class="sd">from sqlglot import exp</span>
</span><span id="L-20"><a href="#L-20"><span class="linenos">20</span></a><span class="sd">from sqlglot.generator import Generator</span> </span><span id="L-20"><a href="#L-20"><span class="linenos">20</span></a><span class="sd">from sqlglot.dialects.dialect import Dialect</span>
</span><span id="L-21"><a href="#L-21"><span class="linenos">21</span></a><span class="sd">from sqlglot.tokens import Tokenizer, TokenType</span> </span><span id="L-21"><a href="#L-21"><span class="linenos">21</span></a><span class="sd">from sqlglot.generator import Generator</span>
</span><span id="L-22"><a href="#L-22"><span class="linenos">22</span></a> </span><span id="L-22"><a href="#L-22"><span class="linenos">22</span></a><span class="sd">from sqlglot.tokens import Tokenizer, TokenType</span>
</span><span id="L-23"><a href="#L-23"><span class="linenos">23</span></a> </span><span id="L-23"><a href="#L-23"><span class="linenos">23</span></a>
</span><span id="L-24"><a href="#L-24"><span class="linenos">24</span></a><span class="sd">class Custom(Dialect):</span> </span><span id="L-24"><a href="#L-24"><span class="linenos">24</span></a>
</span><span id="L-25"><a href="#L-25"><span class="linenos">25</span></a><span class="sd"> class Tokenizer(Tokenizer):</span> </span><span id="L-25"><a href="#L-25"><span class="linenos">25</span></a><span class="sd">class Custom(Dialect):</span>
</span><span id="L-26"><a href="#L-26"><span class="linenos">26</span></a><span class="sd"> QUOTES = [&quot;&#39;&quot;, &#39;&quot;&#39;] # Strings can be delimited by either single or double quotes</span> </span><span id="L-26"><a href="#L-26"><span class="linenos">26</span></a><span class="sd"> class Tokenizer(Tokenizer):</span>
</span><span id="L-27"><a href="#L-27"><span class="linenos">27</span></a><span class="sd"> IDENTIFIERS = [&quot;`&quot;] # Identifiers can be delimited by backticks</span> </span><span id="L-27"><a href="#L-27"><span class="linenos">27</span></a><span class="sd"> QUOTES = [&quot;&#39;&quot;, &#39;&quot;&#39;] # Strings can be delimited by either single or double quotes</span>
</span><span id="L-28"><a href="#L-28"><span class="linenos">28</span></a> </span><span id="L-28"><a href="#L-28"><span class="linenos">28</span></a><span class="sd"> IDENTIFIERS = [&quot;`&quot;] # Identifiers can be delimited by backticks</span>
</span><span id="L-29"><a href="#L-29"><span class="linenos">29</span></a><span class="sd"> # Associates certain meaningful words with tokens that capture their intent</span> </span><span id="L-29"><a href="#L-29"><span class="linenos">29</span></a>
</span><span id="L-30"><a href="#L-30"><span class="linenos">30</span></a><span class="sd"> KEYWORDS = {</span> </span><span id="L-30"><a href="#L-30"><span class="linenos">30</span></a><span class="sd"> # Associates certain meaningful words with tokens that capture their intent</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos">31</span></a><span class="sd"> **Tokenizer.KEYWORDS,</span> </span><span id="L-31"><a href="#L-31"><span class="linenos">31</span></a><span class="sd"> KEYWORDS = {</span>
</span><span id="L-32"><a href="#L-32"><span class="linenos">32</span></a><span class="sd"> &quot;INT64&quot;: TokenType.BIGINT,</span> </span><span id="L-32"><a href="#L-32"><span class="linenos">32</span></a><span class="sd"> **Tokenizer.KEYWORDS,</span>
</span><span id="L-33"><a href="#L-33"><span class="linenos">33</span></a><span class="sd"> &quot;FLOAT64&quot;: TokenType.DOUBLE,</span> </span><span id="L-33"><a href="#L-33"><span class="linenos">33</span></a><span class="sd"> &quot;INT64&quot;: TokenType.BIGINT,</span>
</span><span id="L-34"><a href="#L-34"><span class="linenos">34</span></a><span class="sd"> }</span> </span><span id="L-34"><a href="#L-34"><span class="linenos">34</span></a><span class="sd"> &quot;FLOAT64&quot;: TokenType.DOUBLE,</span>
</span><span id="L-35"><a href="#L-35"><span class="linenos">35</span></a> </span><span id="L-35"><a href="#L-35"><span class="linenos">35</span></a><span class="sd"> }</span>
</span><span id="L-36"><a href="#L-36"><span class="linenos">36</span></a><span class="sd"> class Generator(Generator):</span> </span><span id="L-36"><a href="#L-36"><span class="linenos">36</span></a>
</span><span id="L-37"><a href="#L-37"><span class="linenos">37</span></a><span class="sd"> # Specifies how AST nodes, i.e. subclasses of exp.Expression, should be converted into SQL</span> </span><span id="L-37"><a href="#L-37"><span class="linenos">37</span></a><span class="sd"> class Generator(Generator):</span>
</span><span id="L-38"><a href="#L-38"><span class="linenos">38</span></a><span class="sd"> TRANSFORMS = {</span> </span><span id="L-38"><a href="#L-38"><span class="linenos">38</span></a><span class="sd"> # Specifies how AST nodes, i.e. subclasses of exp.Expression, should be converted into SQL</span>
</span><span id="L-39"><a href="#L-39"><span class="linenos">39</span></a><span class="sd"> exp.Array: lambda self, e: f&quot;[{self.expressions(e)}]&quot;,</span> </span><span id="L-39"><a href="#L-39"><span class="linenos">39</span></a><span class="sd"> TRANSFORMS = {</span>
</span><span id="L-40"><a href="#L-40"><span class="linenos">40</span></a><span class="sd"> }</span> </span><span id="L-40"><a href="#L-40"><span class="linenos">40</span></a><span class="sd"> exp.Array: lambda self, e: f&quot;[{self.expressions(e)}]&quot;,</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos">41</span></a> </span><span id="L-41"><a href="#L-41"><span class="linenos">41</span></a><span class="sd"> }</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos">42</span></a><span class="sd"> # Specifies how AST nodes representing data types should be converted into SQL</span> </span><span id="L-42"><a href="#L-42"><span class="linenos">42</span></a>
</span><span id="L-43"><a href="#L-43"><span class="linenos">43</span></a><span class="sd"> TYPE_MAPPING = {</span> </span><span id="L-43"><a href="#L-43"><span class="linenos">43</span></a><span class="sd"> # Specifies how AST nodes representing data types should be converted into SQL</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos">44</span></a><span class="sd"> exp.DataType.Type.TINYINT: &quot;INT64&quot;,</span> </span><span id="L-44"><a href="#L-44"><span class="linenos">44</span></a><span class="sd"> TYPE_MAPPING = {</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos">45</span></a><span class="sd"> exp.DataType.Type.SMALLINT: &quot;INT64&quot;,</span> </span><span id="L-45"><a href="#L-45"><span class="linenos">45</span></a><span class="sd"> exp.DataType.Type.TINYINT: &quot;INT64&quot;,</span>
</span><span id="L-46"><a href="#L-46"><span class="linenos">46</span></a><span class="sd"> exp.DataType.Type.INT: &quot;INT64&quot;,</span> </span><span id="L-46"><a href="#L-46"><span class="linenos">46</span></a><span class="sd"> exp.DataType.Type.SMALLINT: &quot;INT64&quot;,</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos">47</span></a><span class="sd"> exp.DataType.Type.BIGINT: &quot;INT64&quot;,</span> </span><span id="L-47"><a href="#L-47"><span class="linenos">47</span></a><span class="sd"> exp.DataType.Type.INT: &quot;INT64&quot;,</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos">48</span></a><span class="sd"> exp.DataType.Type.DECIMAL: &quot;NUMERIC&quot;,</span> </span><span id="L-48"><a href="#L-48"><span class="linenos">48</span></a><span class="sd"> exp.DataType.Type.BIGINT: &quot;INT64&quot;,</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos">49</span></a><span class="sd"> exp.DataType.Type.FLOAT: &quot;FLOAT64&quot;,</span> </span><span id="L-49"><a href="#L-49"><span class="linenos">49</span></a><span class="sd"> exp.DataType.Type.DECIMAL: &quot;NUMERIC&quot;,</span>
</span><span id="L-50"><a href="#L-50"><span class="linenos">50</span></a><span class="sd"> exp.DataType.Type.DOUBLE: &quot;FLOAT64&quot;,</span> </span><span id="L-50"><a href="#L-50"><span class="linenos">50</span></a><span class="sd"> exp.DataType.Type.FLOAT: &quot;FLOAT64&quot;,</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos">51</span></a><span class="sd"> exp.DataType.Type.BOOLEAN: &quot;BOOL&quot;,</span> </span><span id="L-51"><a href="#L-51"><span class="linenos">51</span></a><span class="sd"> exp.DataType.Type.DOUBLE: &quot;FLOAT64&quot;,</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos">52</span></a><span class="sd"> exp.DataType.Type.TEXT: &quot;STRING&quot;,</span> </span><span id="L-52"><a href="#L-52"><span class="linenos">52</span></a><span class="sd"> exp.DataType.Type.BOOLEAN: &quot;BOOL&quot;,</span>
</span><span id="L-53"><a href="#L-53"><span class="linenos">53</span></a><span class="sd"> }</span> </span><span id="L-53"><a href="#L-53"><span class="linenos">53</span></a><span class="sd"> exp.DataType.Type.TEXT: &quot;STRING&quot;,</span>
</span><span id="L-54"><a href="#L-54"><span class="linenos">54</span></a><span class="sd">```</span> </span><span id="L-54"><a href="#L-54"><span class="linenos">54</span></a><span class="sd"> }</span>
</span><span id="L-55"><a href="#L-55"><span class="linenos">55</span></a> </span><span id="L-55"><a href="#L-55"><span class="linenos">55</span></a><span class="sd">```</span>
</span><span id="L-56"><a href="#L-56"><span class="linenos">56</span></a><span class="sd">The above example demonstrates how certain parts of the base `Dialect` class can be overridden to match a different</span> </span><span id="L-56"><a href="#L-56"><span class="linenos">56</span></a>
</span><span id="L-57"><a href="#L-57"><span class="linenos">57</span></a><span class="sd">specification. Even though it is a fairly realistic starting point, we strongly encourage the reader to study existing</span> </span><span id="L-57"><a href="#L-57"><span class="linenos">57</span></a><span class="sd">The above example demonstrates how certain parts of the base `Dialect` class can be overridden to match a different</span>
</span><span id="L-58"><a href="#L-58"><span class="linenos">58</span></a><span class="sd">dialect implementations in order to understand how their various components can be modified, depending on the use-case.</span> </span><span id="L-58"><a href="#L-58"><span class="linenos">58</span></a><span class="sd">specification. Even though it is a fairly realistic starting point, we strongly encourage the reader to study existing</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos">59</span></a> </span><span id="L-59"><a href="#L-59"><span class="linenos">59</span></a><span class="sd">dialect implementations in order to understand how their various components can be modified, depending on the use-case.</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos">60</span></a><span class="sd">----</span> </span><span id="L-60"><a href="#L-60"><span class="linenos">60</span></a>
</span><span id="L-61"><a href="#L-61"><span class="linenos">61</span></a><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-61"><a href="#L-61"><span class="linenos">61</span></a><span class="sd">----</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos">62</span></a> </span><span id="L-62"><a href="#L-62"><span class="linenos">62</span></a><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos">63</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.bigquery</span> <span class="kn">import</span> <span class="n">BigQuery</span> </span><span id="L-63"><a href="#L-63"><span class="linenos">63</span></a>
</span><span id="L-64"><a href="#L-64"><span class="linenos">64</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.clickhouse</span> <span class="kn">import</span> <span class="n">ClickHouse</span> </span><span id="L-64"><a href="#L-64"><span class="linenos">64</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.bigquery</span> <span class="kn">import</span> <span class="n">BigQuery</span>
</span><span id="L-65"><a href="#L-65"><span class="linenos">65</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.databricks</span> <span class="kn">import</span> <span class="n">Databricks</span> </span><span id="L-65"><a href="#L-65"><span class="linenos">65</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.clickhouse</span> <span class="kn">import</span> <span class="n">ClickHouse</span>
</span><span id="L-66"><a href="#L-66"><span class="linenos">66</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.dialect</span> <span class="kn">import</span> <span class="n">Dialect</span><span class="p">,</span> <span class="n">Dialects</span> </span><span id="L-66"><a href="#L-66"><span class="linenos">66</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.databricks</span> <span class="kn">import</span> <span class="n">Databricks</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos">67</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.doris</span> <span class="kn">import</span> <span class="n">Doris</span> </span><span id="L-67"><a href="#L-67"><span class="linenos">67</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.dialect</span> <span class="kn">import</span> <span class="n">Dialect</span><span class="p">,</span> <span class="n">Dialects</span>
</span><span id="L-68"><a href="#L-68"><span class="linenos">68</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.drill</span> <span class="kn">import</span> <span class="n">Drill</span> </span><span id="L-68"><a href="#L-68"><span class="linenos">68</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.doris</span> <span class="kn">import</span> <span class="n">Doris</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos">69</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.duckdb</span> <span class="kn">import</span> <span class="n">DuckDB</span> </span><span id="L-69"><a href="#L-69"><span class="linenos">69</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.drill</span> <span class="kn">import</span> <span class="n">Drill</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos">70</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.hive</span> <span class="kn">import</span> <span class="n">Hive</span> </span><span id="L-70"><a href="#L-70"><span class="linenos">70</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.duckdb</span> <span class="kn">import</span> <span class="n">DuckDB</span>
</span><span id="L-71"><a href="#L-71"><span class="linenos">71</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.mysql</span> <span class="kn">import</span> <span class="n">MySQL</span> </span><span id="L-71"><a href="#L-71"><span class="linenos">71</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.hive</span> <span class="kn">import</span> <span class="n">Hive</span>
</span><span id="L-72"><a href="#L-72"><span class="linenos">72</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.oracle</span> <span class="kn">import</span> <span class="n">Oracle</span> </span><span id="L-72"><a href="#L-72"><span class="linenos">72</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.mysql</span> <span class="kn">import</span> <span class="n">MySQL</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos">73</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.postgres</span> <span class="kn">import</span> <span class="n">Postgres</span> </span><span id="L-73"><a href="#L-73"><span class="linenos">73</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.oracle</span> <span class="kn">import</span> <span class="n">Oracle</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos">74</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.presto</span> <span class="kn">import</span> <span class="n">Presto</span> </span><span id="L-74"><a href="#L-74"><span class="linenos">74</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.postgres</span> <span class="kn">import</span> <span class="n">Postgres</span>
</span><span id="L-75"><a href="#L-75"><span class="linenos">75</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.redshift</span> <span class="kn">import</span> <span class="n">Redshift</span> </span><span id="L-75"><a href="#L-75"><span class="linenos">75</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.presto</span> <span class="kn">import</span> <span class="n">Presto</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos">76</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.snowflake</span> <span class="kn">import</span> <span class="n">Snowflake</span> </span><span id="L-76"><a href="#L-76"><span class="linenos">76</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.redshift</span> <span class="kn">import</span> <span class="n">Redshift</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos">77</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.spark</span> <span class="kn">import</span> <span class="n">Spark</span> </span><span id="L-77"><a href="#L-77"><span class="linenos">77</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.snowflake</span> <span class="kn">import</span> <span class="n">Snowflake</span>
</span><span id="L-78"><a href="#L-78"><span class="linenos">78</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.spark2</span> <span class="kn">import</span> <span class="n">Spark2</span> </span><span id="L-78"><a href="#L-78"><span class="linenos">78</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.spark</span> <span class="kn">import</span> <span class="n">Spark</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos">79</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.sqlite</span> <span class="kn">import</span> <span class="n">SQLite</span> </span><span id="L-79"><a href="#L-79"><span class="linenos">79</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.spark2</span> <span class="kn">import</span> <span class="n">Spark2</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos">80</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.starrocks</span> <span class="kn">import</span> <span class="n">StarRocks</span> </span><span id="L-80"><a href="#L-80"><span class="linenos">80</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.sqlite</span> <span class="kn">import</span> <span class="n">SQLite</span>
</span><span id="L-81"><a href="#L-81"><span class="linenos">81</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.tableau</span> <span class="kn">import</span> <span class="n">Tableau</span> </span><span id="L-81"><a href="#L-81"><span class="linenos">81</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.starrocks</span> <span class="kn">import</span> <span class="n">StarRocks</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos">82</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.teradata</span> <span class="kn">import</span> <span class="n">Teradata</span> </span><span id="L-82"><a href="#L-82"><span class="linenos">82</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.tableau</span> <span class="kn">import</span> <span class="n">Tableau</span>
</span><span id="L-83"><a href="#L-83"><span class="linenos">83</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.trino</span> <span class="kn">import</span> <span class="n">Trino</span> </span><span id="L-83"><a href="#L-83"><span class="linenos">83</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.teradata</span> <span class="kn">import</span> <span class="n">Teradata</span>
</span><span id="L-84"><a href="#L-84"><span class="linenos">84</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.tsql</span> <span class="kn">import</span> <span class="n">TSQL</span> </span><span id="L-84"><a href="#L-84"><span class="linenos">84</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.trino</span> <span class="kn">import</span> <span class="n">Trino</span>
</span><span id="L-85"><a href="#L-85"><span class="linenos">85</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.tsql</span> <span class="kn">import</span> <span class="n">TSQL</span>
</span></pre></div> </span></pre></div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -347,86 +347,84 @@
</span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a><span class="kn">import</span> <span class="nn">time</span> </span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a><span class="kn">import</span> <span class="nn">time</span>
</span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span> </span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span>
</span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a> </span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a>
</span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a><span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">maybe_parse</span> </span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a><span class="kn">from</span> <span class="nn">sqlglot.errors</span> <span class="kn">import</span> <span class="n">ExecuteError</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a><span class="kn">from</span> <span class="nn">sqlglot.errors</span> <span class="kn">import</span> <span class="n">ExecuteError</span> </span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a><span class="kn">from</span> <span class="nn">sqlglot.executor.python</span> <span class="kn">import</span> <span class="n">PythonExecutor</span>
</span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a><span class="kn">from</span> <span class="nn">sqlglot.executor.python</span> <span class="kn">import</span> <span class="n">PythonExecutor</span> </span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a><span class="kn">from</span> <span class="nn">sqlglot.executor.table</span> <span class="kn">import</span> <span class="n">Table</span><span class="p">,</span> <span class="n">ensure_tables</span>
</span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a><span class="kn">from</span> <span class="nn">sqlglot.executor.table</span> <span class="kn">import</span> <span class="n">Table</span><span class="p">,</span> <span class="n">ensure_tables</span> </span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a><span class="kn">from</span> <span class="nn">sqlglot.helper</span> <span class="kn">import</span> <span class="n">dict_depth</span>
</span><span id="L-17"><a href="#L-17"><span class="linenos">17</span></a><span class="kn">from</span> <span class="nn">sqlglot.helper</span> <span class="kn">import</span> <span class="n">dict_depth</span> </span><span id="L-17"><a href="#L-17"><span class="linenos">17</span></a><span class="kn">from</span> <span class="nn">sqlglot.optimizer</span> <span class="kn">import</span> <span class="n">optimize</span>
</span><span id="L-18"><a href="#L-18"><span class="linenos">18</span></a><span class="kn">from</span> <span class="nn">sqlglot.optimizer</span> <span class="kn">import</span> <span class="n">optimize</span> </span><span id="L-18"><a href="#L-18"><span class="linenos">18</span></a><span class="kn">from</span> <span class="nn">sqlglot.planner</span> <span class="kn">import</span> <span class="n">Plan</span>
</span><span id="L-19"><a href="#L-19"><span class="linenos">19</span></a><span class="kn">from</span> <span class="nn">sqlglot.planner</span> <span class="kn">import</span> <span class="n">Plan</span> </span><span id="L-19"><a href="#L-19"><span class="linenos">19</span></a><span class="kn">from</span> <span class="nn">sqlglot.schema</span> <span class="kn">import</span> <span class="n">ensure_schema</span><span class="p">,</span> <span class="n">flatten_schema</span><span class="p">,</span> <span class="n">nested_get</span><span class="p">,</span> <span class="n">nested_set</span>
</span><span id="L-20"><a href="#L-20"><span class="linenos">20</span></a><span class="kn">from</span> <span class="nn">sqlglot.schema</span> <span class="kn">import</span> <span class="n">ensure_schema</span><span class="p">,</span> <span class="n">flatten_schema</span><span class="p">,</span> <span class="n">nested_get</span><span class="p">,</span> <span class="n">nested_set</span> </span><span id="L-20"><a href="#L-20"><span class="linenos">20</span></a>
</span><span id="L-21"><a href="#L-21"><span class="linenos">21</span></a> </span><span id="L-21"><a href="#L-21"><span class="linenos">21</span></a><span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;sqlglot&quot;</span><span class="p">)</span>
</span><span id="L-22"><a href="#L-22"><span class="linenos">22</span></a><span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;sqlglot&quot;</span><span class="p">)</span> </span><span id="L-22"><a href="#L-22"><span class="linenos">22</span></a>
</span><span id="L-23"><a href="#L-23"><span class="linenos">23</span></a> </span><span id="L-23"><a href="#L-23"><span class="linenos">23</span></a><span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">TYPE_CHECKING</span><span class="p">:</span>
</span><span id="L-24"><a href="#L-24"><span class="linenos">24</span></a><span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">TYPE_CHECKING</span><span class="p">:</span> </span><span id="L-24"><a href="#L-24"><span class="linenos">24</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dialects.dialect</span> <span class="kn">import</span> <span class="n">DialectType</span>
</span><span id="L-25"><a href="#L-25"><span class="linenos">25</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dialects.dialect</span> <span class="kn">import</span> <span class="n">DialectType</span> </span><span id="L-25"><a href="#L-25"><span class="linenos">25</span></a> <span class="kn">from</span> <span class="nn">sqlglot.expressions</span> <span class="kn">import</span> <span class="n">Expression</span>
</span><span id="L-26"><a href="#L-26"><span class="linenos">26</span></a> <span class="kn">from</span> <span class="nn">sqlglot.executor.table</span> <span class="kn">import</span> <span class="n">Tables</span> </span><span id="L-26"><a href="#L-26"><span class="linenos">26</span></a> <span class="kn">from</span> <span class="nn">sqlglot.schema</span> <span class="kn">import</span> <span class="n">Schema</span>
</span><span id="L-27"><a href="#L-27"><span class="linenos">27</span></a> <span class="kn">from</span> <span class="nn">sqlglot.expressions</span> <span class="kn">import</span> <span class="n">Expression</span> </span><span id="L-27"><a href="#L-27"><span class="linenos">27</span></a>
</span><span id="L-28"><a href="#L-28"><span class="linenos">28</span></a> <span class="kn">from</span> <span class="nn">sqlglot.schema</span> <span class="kn">import</span> <span class="n">Schema</span> </span><span id="L-28"><a href="#L-28"><span class="linenos">28</span></a>
</span><span id="L-29"><a href="#L-29"><span class="linenos">29</span></a> </span><span id="L-29"><a href="#L-29"><span class="linenos">29</span></a><span class="n">PYTHON_TYPE_TO_SQLGLOT</span> <span class="o">=</span> <span class="p">{</span>
</span><span id="L-30"><a href="#L-30"><span class="linenos">30</span></a> </span><span id="L-30"><a href="#L-30"><span class="linenos">30</span></a> <span class="s2">&quot;dict&quot;</span><span class="p">:</span> <span class="s2">&quot;MAP&quot;</span><span class="p">,</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos">31</span></a><span class="n">PYTHON_TYPE_TO_SQLGLOT</span> <span class="o">=</span> <span class="p">{</span> </span><span id="L-31"><a href="#L-31"><span class="linenos">31</span></a><span class="p">}</span>
</span><span id="L-32"><a href="#L-32"><span class="linenos">32</span></a> <span class="s2">&quot;dict&quot;</span><span class="p">:</span> <span class="s2">&quot;MAP&quot;</span><span class="p">,</span> </span><span id="L-32"><a href="#L-32"><span class="linenos">32</span></a>
</span><span id="L-33"><a href="#L-33"><span class="linenos">33</span></a><span class="p">}</span> </span><span id="L-33"><a href="#L-33"><span class="linenos">33</span></a>
</span><span id="L-34"><a href="#L-34"><span class="linenos">34</span></a> </span><span id="L-34"><a href="#L-34"><span class="linenos">34</span></a><span class="k">def</span> <span class="nf">execute</span><span class="p">(</span>
</span><span id="L-35"><a href="#L-35"><span class="linenos">35</span></a> </span><span id="L-35"><a href="#L-35"><span class="linenos">35</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">Expression</span><span class="p">,</span>
</span><span id="L-36"><a href="#L-36"><span class="linenos">36</span></a><span class="k">def</span> <span class="nf">execute</span><span class="p">(</span> </span><span id="L-36"><a href="#L-36"><span class="linenos">36</span></a> <span class="n">schema</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Dict</span> <span class="o">|</span> <span class="n">Schema</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-37"><a href="#L-37"><span class="linenos">37</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">Expression</span><span class="p">,</span> </span><span id="L-37"><a href="#L-37"><span class="linenos">37</span></a> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-38"><a href="#L-38"><span class="linenos">38</span></a> <span class="n">schema</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Dict</span> <span class="o">|</span> <span class="n">Schema</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="L-38"><a href="#L-38"><span class="linenos">38</span></a> <span class="n">tables</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-39"><a href="#L-39"><span class="linenos">39</span></a> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="L-39"><a href="#L-39"><span class="linenos">39</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Table</span><span class="p">:</span>
</span><span id="L-40"><a href="#L-40"><span class="linenos">40</span></a> <span class="n">tables</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="L-40"><a href="#L-40"><span class="linenos">40</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos">41</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Table</span><span class="p">:</span> </span><span id="L-41"><a href="#L-41"><span class="linenos">41</span></a><span class="sd"> Run a sql query against data.</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos">42</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-42"><a href="#L-42"><span class="linenos">42</span></a>
</span><span id="L-43"><a href="#L-43"><span class="linenos">43</span></a><span class="sd"> Run a sql query against data.</span> </span><span id="L-43"><a href="#L-43"><span class="linenos">43</span></a><span class="sd"> Args:</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos">44</span></a> </span><span id="L-44"><a href="#L-44"><span class="linenos">44</span></a><span class="sd"> sql: a sql statement.</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos">45</span></a><span class="sd"> Args:</span> </span><span id="L-45"><a href="#L-45"><span class="linenos">45</span></a><span class="sd"> schema: database schema.</span>
</span><span id="L-46"><a href="#L-46"><span class="linenos">46</span></a><span class="sd"> sql: a sql statement.</span> </span><span id="L-46"><a href="#L-46"><span class="linenos">46</span></a><span class="sd"> This can either be an instance of `Schema` or a mapping in one of the following forms:</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos">47</span></a><span class="sd"> schema: database schema.</span> </span><span id="L-47"><a href="#L-47"><span class="linenos">47</span></a><span class="sd"> 1. {table: {col: type}}</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos">48</span></a><span class="sd"> This can either be an instance of `Schema` or a mapping in one of the following forms:</span> </span><span id="L-48"><a href="#L-48"><span class="linenos">48</span></a><span class="sd"> 2. {db: {table: {col: type}}}</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos">49</span></a><span class="sd"> 1. {table: {col: type}}</span> </span><span id="L-49"><a href="#L-49"><span class="linenos">49</span></a><span class="sd"> 3. {catalog: {db: {table: {col: type}}}}</span>
</span><span id="L-50"><a href="#L-50"><span class="linenos">50</span></a><span class="sd"> 2. {db: {table: {col: type}}}</span> </span><span id="L-50"><a href="#L-50"><span class="linenos">50</span></a><span class="sd"> read: the SQL dialect to apply during parsing (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos">51</span></a><span class="sd"> 3. {catalog: {db: {table: {col: type}}}}</span> </span><span id="L-51"><a href="#L-51"><span class="linenos">51</span></a><span class="sd"> tables: additional tables to register.</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos">52</span></a><span class="sd"> read: the SQL dialect to apply during parsing (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span> </span><span id="L-52"><a href="#L-52"><span class="linenos">52</span></a>
</span><span id="L-53"><a href="#L-53"><span class="linenos">53</span></a><span class="sd"> tables: additional tables to register.</span> </span><span id="L-53"><a href="#L-53"><span class="linenos">53</span></a><span class="sd"> Returns:</span>
</span><span id="L-54"><a href="#L-54"><span class="linenos">54</span></a> </span><span id="L-54"><a href="#L-54"><span class="linenos">54</span></a><span class="sd"> Simple columnar data structure.</span>
</span><span id="L-55"><a href="#L-55"><span class="linenos">55</span></a><span class="sd"> Returns:</span> </span><span id="L-55"><a href="#L-55"><span class="linenos">55</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-56"><a href="#L-56"><span class="linenos">56</span></a><span class="sd"> Simple columnar data structure.</span> </span><span id="L-56"><a href="#L-56"><span class="linenos">56</span></a> <span class="n">tables_</span> <span class="o">=</span> <span class="n">ensure_tables</span><span class="p">(</span><span class="n">tables</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">read</span><span class="p">)</span>
</span><span id="L-57"><a href="#L-57"><span class="linenos">57</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-57"><a href="#L-57"><span class="linenos">57</span></a>
</span><span id="L-58"><a href="#L-58"><span class="linenos">58</span></a> <span class="n">tables_</span> <span class="o">=</span> <span class="n">ensure_tables</span><span class="p">(</span><span class="n">tables</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">read</span><span class="p">)</span> </span><span id="L-58"><a href="#L-58"><span class="linenos">58</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">schema</span><span class="p">:</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos">59</span></a> </span><span id="L-59"><a href="#L-59"><span class="linenos">59</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos">60</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">schema</span><span class="p">:</span> </span><span id="L-60"><a href="#L-60"><span class="linenos">60</span></a> <span class="n">flattened_tables</span> <span class="o">=</span> <span class="n">flatten_schema</span><span class="p">(</span><span class="n">tables_</span><span class="o">.</span><span class="n">mapping</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="n">dict_depth</span><span class="p">(</span><span class="n">tables_</span><span class="o">.</span><span class="n">mapping</span><span class="p">))</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos">61</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="p">{}</span> </span><span id="L-61"><a href="#L-61"><span class="linenos">61</span></a>
</span><span id="L-62"><a href="#L-62"><span class="linenos">62</span></a> <span class="n">flattened_tables</span> <span class="o">=</span> <span class="n">flatten_schema</span><span class="p">(</span><span class="n">tables_</span><span class="o">.</span><span class="n">mapping</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="n">dict_depth</span><span class="p">(</span><span class="n">tables_</span><span class="o">.</span><span class="n">mapping</span><span class="p">))</span> </span><span id="L-62"><a href="#L-62"><span class="linenos">62</span></a> <span class="k">for</span> <span class="n">keys</span> <span class="ow">in</span> <span class="n">flattened_tables</span><span class="p">:</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos">63</span></a> </span><span id="L-63"><a href="#L-63"><span class="linenos">63</span></a> <span class="n">table</span> <span class="o">=</span> <span class="n">nested_get</span><span class="p">(</span><span class="n">tables_</span><span class="o">.</span><span class="n">mapping</span><span class="p">,</span> <span class="o">*</span><span class="nb">zip</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">keys</span><span class="p">))</span>
</span><span id="L-64"><a href="#L-64"><span class="linenos">64</span></a> <span class="k">for</span> <span class="n">keys</span> <span class="ow">in</span> <span class="n">flattened_tables</span><span class="p">:</span> </span><span id="L-64"><a href="#L-64"><span class="linenos">64</span></a> <span class="k">assert</span> <span class="n">table</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
</span><span id="L-65"><a href="#L-65"><span class="linenos">65</span></a> <span class="n">table</span> <span class="o">=</span> <span class="n">nested_get</span><span class="p">(</span><span class="n">tables_</span><span class="o">.</span><span class="n">mapping</span><span class="p">,</span> <span class="o">*</span><span class="nb">zip</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">keys</span><span class="p">))</span> </span><span id="L-65"><a href="#L-65"><span class="linenos">65</span></a>
</span><span id="L-66"><a href="#L-66"><span class="linenos">66</span></a> <span class="k">assert</span> <span class="n">table</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> </span><span id="L-66"><a href="#L-66"><span class="linenos">66</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">table</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos">67</span></a> </span><span id="L-67"><a href="#L-67"><span class="linenos">67</span></a> <span class="n">py_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">table</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">column</span><span class="p">])</span><span class="o">.</span><span class="vm">__name__</span>
</span><span id="L-68"><a href="#L-68"><span class="linenos">68</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">table</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span> </span><span id="L-68"><a href="#L-68"><span class="linenos">68</span></a> <span class="n">nested_set</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="p">[</span><span class="o">*</span><span class="n">keys</span><span class="p">,</span> <span class="n">column</span><span class="p">],</span> <span class="n">PYTHON_TYPE_TO_SQLGLOT</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">py_type</span><span class="p">)</span> <span class="ow">or</span> <span class="n">py_type</span><span class="p">)</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos">69</span></a> <span class="n">py_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">table</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">column</span><span class="p">])</span><span class="o">.</span><span class="vm">__name__</span> </span><span id="L-69"><a href="#L-69"><span class="linenos">69</span></a>
</span><span id="L-70"><a href="#L-70"><span class="linenos">70</span></a> <span class="n">nested_set</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="p">[</span><span class="o">*</span><span class="n">keys</span><span class="p">,</span> <span class="n">column</span><span class="p">],</span> <span class="n">PYTHON_TYPE_TO_SQLGLOT</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">py_type</span><span class="p">)</span> <span class="ow">or</span> <span class="n">py_type</span><span class="p">)</span> </span><span id="L-70"><a href="#L-70"><span class="linenos">70</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="n">ensure_schema</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">read</span><span class="p">)</span>
</span><span id="L-71"><a href="#L-71"><span class="linenos">71</span></a> </span><span id="L-71"><a href="#L-71"><span class="linenos">71</span></a>
</span><span id="L-72"><a href="#L-72"><span class="linenos">72</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="n">ensure_schema</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">read</span><span class="p">)</span> </span><span id="L-72"><a href="#L-72"><span class="linenos">72</span></a> <span class="k">if</span> <span class="n">tables_</span><span class="o">.</span><span class="n">supported_table_args</span> <span class="ow">and</span> <span class="n">tables_</span><span class="o">.</span><span class="n">supported_table_args</span> <span class="o">!=</span> <span class="n">schema</span><span class="o">.</span><span class="n">supported_table_args</span><span class="p">:</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos">73</span></a> </span><span id="L-73"><a href="#L-73"><span class="linenos">73</span></a> <span class="k">raise</span> <span class="n">ExecuteError</span><span class="p">(</span><span class="s2">&quot;Tables must support the same table args as schema&quot;</span><span class="p">)</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos">74</span></a> <span class="k">if</span> <span class="n">tables_</span><span class="o">.</span><span class="n">supported_table_args</span> <span class="ow">and</span> <span class="n">tables_</span><span class="o">.</span><span class="n">supported_table_args</span> <span class="o">!=</span> <span class="n">schema</span><span class="o">.</span><span class="n">supported_table_args</span><span class="p">:</span> </span><span id="L-74"><a href="#L-74"><span class="linenos">74</span></a>
</span><span id="L-75"><a href="#L-75"><span class="linenos">75</span></a> <span class="k">raise</span> <span class="n">ExecuteError</span><span class="p">(</span><span class="s2">&quot;Tables must support the same table args as schema&quot;</span><span class="p">)</span> </span><span id="L-75"><a href="#L-75"><span class="linenos">75</span></a> <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos">76</span></a> </span><span id="L-76"><a href="#L-76"><span class="linenos">76</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">optimize</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="n">schema</span><span class="p">,</span> <span class="n">leave_tables_isolated</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">read</span><span class="p">)</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos">77</span></a> <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> </span><span id="L-77"><a href="#L-77"><span class="linenos">77</span></a>
</span><span id="L-78"><a href="#L-78"><span class="linenos">78</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">optimize</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="n">schema</span><span class="p">,</span> <span class="n">leave_tables_isolated</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">read</span><span class="p">)</span> </span><span id="L-78"><a href="#L-78"><span class="linenos">78</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Optimization finished: </span><span class="si">%f</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">now</span><span class="p">)</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos">79</span></a> </span><span id="L-79"><a href="#L-79"><span class="linenos">79</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Optimized SQL: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos">80</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Optimization finished: </span><span class="si">%f</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">now</span><span class="p">)</span> </span><span id="L-80"><a href="#L-80"><span class="linenos">80</span></a>
</span><span id="L-81"><a href="#L-81"><span class="linenos">81</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Optimized SQL: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span> </span><span id="L-81"><a href="#L-81"><span class="linenos">81</span></a> <span class="n">plan</span> <span class="o">=</span> <span class="n">Plan</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos">82</span></a> </span><span id="L-82"><a href="#L-82"><span class="linenos">82</span></a>
</span><span id="L-83"><a href="#L-83"><span class="linenos">83</span></a> <span class="n">plan</span> <span class="o">=</span> <span class="n">Plan</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-83"><a href="#L-83"><span class="linenos">83</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Logical Plan: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">plan</span><span class="p">)</span>
</span><span id="L-84"><a href="#L-84"><span class="linenos">84</span></a> </span><span id="L-84"><a href="#L-84"><span class="linenos">84</span></a>
</span><span id="L-85"><a href="#L-85"><span class="linenos">85</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Logical Plan: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">plan</span><span class="p">)</span> </span><span id="L-85"><a href="#L-85"><span class="linenos">85</span></a> <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
</span><span id="L-86"><a href="#L-86"><span class="linenos">86</span></a> </span><span id="L-86"><a href="#L-86"><span class="linenos">86</span></a> <span class="n">result</span> <span class="o">=</span> <span class="n">PythonExecutor</span><span class="p">(</span><span class="n">tables</span><span class="o">=</span><span class="n">tables_</span><span class="p">)</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">plan</span><span class="p">)</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos">87</span></a> <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> </span><span id="L-87"><a href="#L-87"><span class="linenos">87</span></a>
</span><span id="L-88"><a href="#L-88"><span class="linenos">88</span></a> <span class="n">result</span> <span class="o">=</span> <span class="n">PythonExecutor</span><span class="p">(</span><span class="n">tables</span><span class="o">=</span><span class="n">tables_</span><span class="p">)</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">plan</span><span class="p">)</span> </span><span id="L-88"><a href="#L-88"><span class="linenos">88</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Query finished: </span><span class="si">%f</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">now</span><span class="p">)</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos">89</span></a> </span><span id="L-89"><a href="#L-89"><span class="linenos">89</span></a>
</span><span id="L-90"><a href="#L-90"><span class="linenos">90</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Query finished: </span><span class="si">%f</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">now</span><span class="p">)</span> </span><span id="L-90"><a href="#L-90"><span class="linenos">90</span></a> <span class="k">return</span> <span class="n">result</span>
</span><span id="L-91"><a href="#L-91"><span class="linenos">91</span></a>
</span><span id="L-92"><a href="#L-92"><span class="linenos">92</span></a> <span class="k">return</span> <span class="n">result</span>
</span></pre></div> </span></pre></div>
@ -466,63 +464,63 @@
</div> </div>
<a class="headerlink" href="#execute"></a> <a class="headerlink" href="#execute"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="execute-37"><a href="#execute-37"><span class="linenos">37</span></a><span class="k">def</span> <span class="nf">execute</span><span class="p">(</span> <div class="pdoc-code codehilite"><pre><span></span><span id="execute-35"><a href="#execute-35"><span class="linenos">35</span></a><span class="k">def</span> <span class="nf">execute</span><span class="p">(</span>
</span><span id="execute-38"><a href="#execute-38"><span class="linenos">38</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">Expression</span><span class="p">,</span> </span><span id="execute-36"><a href="#execute-36"><span class="linenos">36</span></a> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="n">Expression</span><span class="p">,</span>
</span><span id="execute-39"><a href="#execute-39"><span class="linenos">39</span></a> <span class="n">schema</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Dict</span> <span class="o">|</span> <span class="n">Schema</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="execute-37"><a href="#execute-37"><span class="linenos">37</span></a> <span class="n">schema</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Dict</span> <span class="o">|</span> <span class="n">Schema</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="execute-40"><a href="#execute-40"><span class="linenos">40</span></a> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="execute-38"><a href="#execute-38"><span class="linenos">38</span></a> <span class="n">read</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="execute-41"><a href="#execute-41"><span class="linenos">41</span></a> <span class="n">tables</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="execute-39"><a href="#execute-39"><span class="linenos">39</span></a> <span class="n">tables</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="execute-42"><a href="#execute-42"><span class="linenos">42</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Table</span><span class="p">:</span> </span><span id="execute-40"><a href="#execute-40"><span class="linenos">40</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Table</span><span class="p">:</span>
</span><span id="execute-43"><a href="#execute-43"><span class="linenos">43</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="execute-41"><a href="#execute-41"><span class="linenos">41</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="execute-44"><a href="#execute-44"><span class="linenos">44</span></a><span class="sd"> Run a sql query against data.</span> </span><span id="execute-42"><a href="#execute-42"><span class="linenos">42</span></a><span class="sd"> Run a sql query against data.</span>
</span><span id="execute-45"><a href="#execute-45"><span class="linenos">45</span></a> </span><span id="execute-43"><a href="#execute-43"><span class="linenos">43</span></a>
</span><span id="execute-46"><a href="#execute-46"><span class="linenos">46</span></a><span class="sd"> Args:</span> </span><span id="execute-44"><a href="#execute-44"><span class="linenos">44</span></a><span class="sd"> Args:</span>
</span><span id="execute-47"><a href="#execute-47"><span class="linenos">47</span></a><span class="sd"> sql: a sql statement.</span> </span><span id="execute-45"><a href="#execute-45"><span class="linenos">45</span></a><span class="sd"> sql: a sql statement.</span>
</span><span id="execute-48"><a href="#execute-48"><span class="linenos">48</span></a><span class="sd"> schema: database schema.</span> </span><span id="execute-46"><a href="#execute-46"><span class="linenos">46</span></a><span class="sd"> schema: database schema.</span>
</span><span id="execute-49"><a href="#execute-49"><span class="linenos">49</span></a><span class="sd"> This can either be an instance of `Schema` or a mapping in one of the following forms:</span> </span><span id="execute-47"><a href="#execute-47"><span class="linenos">47</span></a><span class="sd"> This can either be an instance of `Schema` or a mapping in one of the following forms:</span>
</span><span id="execute-50"><a href="#execute-50"><span class="linenos">50</span></a><span class="sd"> 1. {table: {col: type}}</span> </span><span id="execute-48"><a href="#execute-48"><span class="linenos">48</span></a><span class="sd"> 1. {table: {col: type}}</span>
</span><span id="execute-51"><a href="#execute-51"><span class="linenos">51</span></a><span class="sd"> 2. {db: {table: {col: type}}}</span> </span><span id="execute-49"><a href="#execute-49"><span class="linenos">49</span></a><span class="sd"> 2. {db: {table: {col: type}}}</span>
</span><span id="execute-52"><a href="#execute-52"><span class="linenos">52</span></a><span class="sd"> 3. {catalog: {db: {table: {col: type}}}}</span> </span><span id="execute-50"><a href="#execute-50"><span class="linenos">50</span></a><span class="sd"> 3. {catalog: {db: {table: {col: type}}}}</span>
</span><span id="execute-53"><a href="#execute-53"><span class="linenos">53</span></a><span class="sd"> read: the SQL dialect to apply during parsing (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span> </span><span id="execute-51"><a href="#execute-51"><span class="linenos">51</span></a><span class="sd"> read: the SQL dialect to apply during parsing (eg. &quot;spark&quot;, &quot;hive&quot;, &quot;presto&quot;, &quot;mysql&quot;).</span>
</span><span id="execute-54"><a href="#execute-54"><span class="linenos">54</span></a><span class="sd"> tables: additional tables to register.</span> </span><span id="execute-52"><a href="#execute-52"><span class="linenos">52</span></a><span class="sd"> tables: additional tables to register.</span>
</span><span id="execute-55"><a href="#execute-55"><span class="linenos">55</span></a> </span><span id="execute-53"><a href="#execute-53"><span class="linenos">53</span></a>
</span><span id="execute-56"><a href="#execute-56"><span class="linenos">56</span></a><span class="sd"> Returns:</span> </span><span id="execute-54"><a href="#execute-54"><span class="linenos">54</span></a><span class="sd"> Returns:</span>
</span><span id="execute-57"><a href="#execute-57"><span class="linenos">57</span></a><span class="sd"> Simple columnar data structure.</span> </span><span id="execute-55"><a href="#execute-55"><span class="linenos">55</span></a><span class="sd"> Simple columnar data structure.</span>
</span><span id="execute-58"><a href="#execute-58"><span class="linenos">58</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="execute-56"><a href="#execute-56"><span class="linenos">56</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="execute-59"><a href="#execute-59"><span class="linenos">59</span></a> <span class="n">tables_</span> <span class="o">=</span> <span class="n">ensure_tables</span><span class="p">(</span><span class="n">tables</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">read</span><span class="p">)</span> </span><span id="execute-57"><a href="#execute-57"><span class="linenos">57</span></a> <span class="n">tables_</span> <span class="o">=</span> <span class="n">ensure_tables</span><span class="p">(</span><span class="n">tables</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">read</span><span class="p">)</span>
</span><span id="execute-60"><a href="#execute-60"><span class="linenos">60</span></a> </span><span id="execute-58"><a href="#execute-58"><span class="linenos">58</span></a>
</span><span id="execute-61"><a href="#execute-61"><span class="linenos">61</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">schema</span><span class="p">:</span> </span><span id="execute-59"><a href="#execute-59"><span class="linenos">59</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">schema</span><span class="p">:</span>
</span><span id="execute-62"><a href="#execute-62"><span class="linenos">62</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="p">{}</span> </span><span id="execute-60"><a href="#execute-60"><span class="linenos">60</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="execute-63"><a href="#execute-63"><span class="linenos">63</span></a> <span class="n">flattened_tables</span> <span class="o">=</span> <span class="n">flatten_schema</span><span class="p">(</span><span class="n">tables_</span><span class="o">.</span><span class="n">mapping</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="n">dict_depth</span><span class="p">(</span><span class="n">tables_</span><span class="o">.</span><span class="n">mapping</span><span class="p">))</span> </span><span id="execute-61"><a href="#execute-61"><span class="linenos">61</span></a> <span class="n">flattened_tables</span> <span class="o">=</span> <span class="n">flatten_schema</span><span class="p">(</span><span class="n">tables_</span><span class="o">.</span><span class="n">mapping</span><span class="p">,</span> <span class="n">depth</span><span class="o">=</span><span class="n">dict_depth</span><span class="p">(</span><span class="n">tables_</span><span class="o">.</span><span class="n">mapping</span><span class="p">))</span>
</span><span id="execute-64"><a href="#execute-64"><span class="linenos">64</span></a> </span><span id="execute-62"><a href="#execute-62"><span class="linenos">62</span></a>
</span><span id="execute-65"><a href="#execute-65"><span class="linenos">65</span></a> <span class="k">for</span> <span class="n">keys</span> <span class="ow">in</span> <span class="n">flattened_tables</span><span class="p">:</span> </span><span id="execute-63"><a href="#execute-63"><span class="linenos">63</span></a> <span class="k">for</span> <span class="n">keys</span> <span class="ow">in</span> <span class="n">flattened_tables</span><span class="p">:</span>
</span><span id="execute-66"><a href="#execute-66"><span class="linenos">66</span></a> <span class="n">table</span> <span class="o">=</span> <span class="n">nested_get</span><span class="p">(</span><span class="n">tables_</span><span class="o">.</span><span class="n">mapping</span><span class="p">,</span> <span class="o">*</span><span class="nb">zip</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">keys</span><span class="p">))</span> </span><span id="execute-64"><a href="#execute-64"><span class="linenos">64</span></a> <span class="n">table</span> <span class="o">=</span> <span class="n">nested_get</span><span class="p">(</span><span class="n">tables_</span><span class="o">.</span><span class="n">mapping</span><span class="p">,</span> <span class="o">*</span><span class="nb">zip</span><span class="p">(</span><span class="n">keys</span><span class="p">,</span> <span class="n">keys</span><span class="p">))</span>
</span><span id="execute-67"><a href="#execute-67"><span class="linenos">67</span></a> <span class="k">assert</span> <span class="n">table</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> </span><span id="execute-65"><a href="#execute-65"><span class="linenos">65</span></a> <span class="k">assert</span> <span class="n">table</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
</span><span id="execute-68"><a href="#execute-68"><span class="linenos">68</span></a> </span><span id="execute-66"><a href="#execute-66"><span class="linenos">66</span></a>
</span><span id="execute-69"><a href="#execute-69"><span class="linenos">69</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">table</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span> </span><span id="execute-67"><a href="#execute-67"><span class="linenos">67</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">table</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="execute-70"><a href="#execute-70"><span class="linenos">70</span></a> <span class="n">py_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">table</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">column</span><span class="p">])</span><span class="o">.</span><span class="vm">__name__</span> </span><span id="execute-68"><a href="#execute-68"><span class="linenos">68</span></a> <span class="n">py_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">table</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">column</span><span class="p">])</span><span class="o">.</span><span class="vm">__name__</span>
</span><span id="execute-71"><a href="#execute-71"><span class="linenos">71</span></a> <span class="n">nested_set</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="p">[</span><span class="o">*</span><span class="n">keys</span><span class="p">,</span> <span class="n">column</span><span class="p">],</span> <span class="n">PYTHON_TYPE_TO_SQLGLOT</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">py_type</span><span class="p">)</span> <span class="ow">or</span> <span class="n">py_type</span><span class="p">)</span> </span><span id="execute-69"><a href="#execute-69"><span class="linenos">69</span></a> <span class="n">nested_set</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="p">[</span><span class="o">*</span><span class="n">keys</span><span class="p">,</span> <span class="n">column</span><span class="p">],</span> <span class="n">PYTHON_TYPE_TO_SQLGLOT</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">py_type</span><span class="p">)</span> <span class="ow">or</span> <span class="n">py_type</span><span class="p">)</span>
</span><span id="execute-70"><a href="#execute-70"><span class="linenos">70</span></a>
</span><span id="execute-71"><a href="#execute-71"><span class="linenos">71</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="n">ensure_schema</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">read</span><span class="p">)</span>
</span><span id="execute-72"><a href="#execute-72"><span class="linenos">72</span></a> </span><span id="execute-72"><a href="#execute-72"><span class="linenos">72</span></a>
</span><span id="execute-73"><a href="#execute-73"><span class="linenos">73</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="n">ensure_schema</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">read</span><span class="p">)</span> </span><span id="execute-73"><a href="#execute-73"><span class="linenos">73</span></a> <span class="k">if</span> <span class="n">tables_</span><span class="o">.</span><span class="n">supported_table_args</span> <span class="ow">and</span> <span class="n">tables_</span><span class="o">.</span><span class="n">supported_table_args</span> <span class="o">!=</span> <span class="n">schema</span><span class="o">.</span><span class="n">supported_table_args</span><span class="p">:</span>
</span><span id="execute-74"><a href="#execute-74"><span class="linenos">74</span></a> </span><span id="execute-74"><a href="#execute-74"><span class="linenos">74</span></a> <span class="k">raise</span> <span class="n">ExecuteError</span><span class="p">(</span><span class="s2">&quot;Tables must support the same table args as schema&quot;</span><span class="p">)</span>
</span><span id="execute-75"><a href="#execute-75"><span class="linenos">75</span></a> <span class="k">if</span> <span class="n">tables_</span><span class="o">.</span><span class="n">supported_table_args</span> <span class="ow">and</span> <span class="n">tables_</span><span class="o">.</span><span class="n">supported_table_args</span> <span class="o">!=</span> <span class="n">schema</span><span class="o">.</span><span class="n">supported_table_args</span><span class="p">:</span> </span><span id="execute-75"><a href="#execute-75"><span class="linenos">75</span></a>
</span><span id="execute-76"><a href="#execute-76"><span class="linenos">76</span></a> <span class="k">raise</span> <span class="n">ExecuteError</span><span class="p">(</span><span class="s2">&quot;Tables must support the same table args as schema&quot;</span><span class="p">)</span> </span><span id="execute-76"><a href="#execute-76"><span class="linenos">76</span></a> <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
</span><span id="execute-77"><a href="#execute-77"><span class="linenos">77</span></a> </span><span id="execute-77"><a href="#execute-77"><span class="linenos">77</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">optimize</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="n">schema</span><span class="p">,</span> <span class="n">leave_tables_isolated</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">read</span><span class="p">)</span>
</span><span id="execute-78"><a href="#execute-78"><span class="linenos">78</span></a> <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> </span><span id="execute-78"><a href="#execute-78"><span class="linenos">78</span></a>
</span><span id="execute-79"><a href="#execute-79"><span class="linenos">79</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">optimize</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="n">schema</span><span class="p">,</span> <span class="n">leave_tables_isolated</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">read</span><span class="p">)</span> </span><span id="execute-79"><a href="#execute-79"><span class="linenos">79</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Optimization finished: </span><span class="si">%f</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">now</span><span class="p">)</span>
</span><span id="execute-80"><a href="#execute-80"><span class="linenos">80</span></a> </span><span id="execute-80"><a href="#execute-80"><span class="linenos">80</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Optimized SQL: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
</span><span id="execute-81"><a href="#execute-81"><span class="linenos">81</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Optimization finished: </span><span class="si">%f</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">now</span><span class="p">)</span> </span><span id="execute-81"><a href="#execute-81"><span class="linenos">81</span></a>
</span><span id="execute-82"><a href="#execute-82"><span class="linenos">82</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Optimized SQL: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span> </span><span id="execute-82"><a href="#execute-82"><span class="linenos">82</span></a> <span class="n">plan</span> <span class="o">=</span> <span class="n">Plan</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="execute-83"><a href="#execute-83"><span class="linenos">83</span></a> </span><span id="execute-83"><a href="#execute-83"><span class="linenos">83</span></a>
</span><span id="execute-84"><a href="#execute-84"><span class="linenos">84</span></a> <span class="n">plan</span> <span class="o">=</span> <span class="n">Plan</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="execute-84"><a href="#execute-84"><span class="linenos">84</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Logical Plan: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">plan</span><span class="p">)</span>
</span><span id="execute-85"><a href="#execute-85"><span class="linenos">85</span></a> </span><span id="execute-85"><a href="#execute-85"><span class="linenos">85</span></a>
</span><span id="execute-86"><a href="#execute-86"><span class="linenos">86</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Logical Plan: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">plan</span><span class="p">)</span> </span><span id="execute-86"><a href="#execute-86"><span class="linenos">86</span></a> <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
</span><span id="execute-87"><a href="#execute-87"><span class="linenos">87</span></a> </span><span id="execute-87"><a href="#execute-87"><span class="linenos">87</span></a> <span class="n">result</span> <span class="o">=</span> <span class="n">PythonExecutor</span><span class="p">(</span><span class="n">tables</span><span class="o">=</span><span class="n">tables_</span><span class="p">)</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">plan</span><span class="p">)</span>
</span><span id="execute-88"><a href="#execute-88"><span class="linenos">88</span></a> <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> </span><span id="execute-88"><a href="#execute-88"><span class="linenos">88</span></a>
</span><span id="execute-89"><a href="#execute-89"><span class="linenos">89</span></a> <span class="n">result</span> <span class="o">=</span> <span class="n">PythonExecutor</span><span class="p">(</span><span class="n">tables</span><span class="o">=</span><span class="n">tables_</span><span class="p">)</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">plan</span><span class="p">)</span> </span><span id="execute-89"><a href="#execute-89"><span class="linenos">89</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Query finished: </span><span class="si">%f</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">now</span><span class="p">)</span>
</span><span id="execute-90"><a href="#execute-90"><span class="linenos">90</span></a> </span><span id="execute-90"><a href="#execute-90"><span class="linenos">90</span></a>
</span><span id="execute-91"><a href="#execute-91"><span class="linenos">91</span></a> <span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Query finished: </span><span class="si">%f</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">now</span><span class="p">)</span> </span><span id="execute-91"><a href="#execute-91"><span class="linenos">91</span></a> <span class="k">return</span> <span class="n">result</span>
</span><span id="execute-92"><a href="#execute-92"><span class="linenos">92</span></a>
</span><span id="execute-93"><a href="#execute-93"><span class="linenos">93</span></a> <span class="k">return</span> <span class="n">result</span>
</span></pre></div> </span></pre></div>

View file

@ -153,9 +153,9 @@
</span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a> </span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a>
</span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a> <span class="k">for</span> <span class="n">other</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tables</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> </span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a> <span class="k">for</span> <span class="n">other</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tables</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
</span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_table</span><span class="o">.</span><span class="n">columns</span> <span class="o">!=</span> <span class="n">other</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span> </span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_table</span><span class="o">.</span><span class="n">columns</span> <span class="o">!=</span> <span class="n">other</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Columns are different.&quot;</span><span class="p">)</span> </span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Columns are different.&quot;</span><span class="p">)</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_table</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">rows</span><span class="p">):</span> </span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_table</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">rows</span><span class="p">):</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Rows are different.&quot;</span><span class="p">)</span> </span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Rows are different.&quot;</span><span class="p">)</span>
</span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a> </span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a>
</span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_table</span> </span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_table</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a> </span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a>
@ -259,9 +259,9 @@
</span><span id="Context-45"><a href="#Context-45"><span class="linenos"> 45</span></a> </span><span id="Context-45"><a href="#Context-45"><span class="linenos"> 45</span></a>
</span><span id="Context-46"><a href="#Context-46"><span class="linenos"> 46</span></a> <span class="k">for</span> <span class="n">other</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tables</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> </span><span id="Context-46"><a href="#Context-46"><span class="linenos"> 46</span></a> <span class="k">for</span> <span class="n">other</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tables</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
</span><span id="Context-47"><a href="#Context-47"><span class="linenos"> 47</span></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_table</span><span class="o">.</span><span class="n">columns</span> <span class="o">!=</span> <span class="n">other</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span> </span><span id="Context-47"><a href="#Context-47"><span class="linenos"> 47</span></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_table</span><span class="o">.</span><span class="n">columns</span> <span class="o">!=</span> <span class="n">other</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="Context-48"><a href="#Context-48"><span class="linenos"> 48</span></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Columns are different.&quot;</span><span class="p">)</span> </span><span id="Context-48"><a href="#Context-48"><span class="linenos"> 48</span></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Columns are different.&quot;</span><span class="p">)</span>
</span><span id="Context-49"><a href="#Context-49"><span class="linenos"> 49</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_table</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">rows</span><span class="p">):</span> </span><span id="Context-49"><a href="#Context-49"><span class="linenos"> 49</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_table</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">rows</span><span class="p">):</span>
</span><span id="Context-50"><a href="#Context-50"><span class="linenos"> 50</span></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Rows are different.&quot;</span><span class="p">)</span> </span><span id="Context-50"><a href="#Context-50"><span class="linenos"> 50</span></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Rows are different.&quot;</span><span class="p">)</span>
</span><span id="Context-51"><a href="#Context-51"><span class="linenos"> 51</span></a> </span><span id="Context-51"><a href="#Context-51"><span class="linenos"> 51</span></a>
</span><span id="Context-52"><a href="#Context-52"><span class="linenos"> 52</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_table</span> </span><span id="Context-52"><a href="#Context-52"><span class="linenos"> 52</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_table</span>
</span><span id="Context-53"><a href="#Context-53"><span class="linenos"> 53</span></a> </span><span id="Context-53"><a href="#Context-53"><span class="linenos"> 53</span></a>
@ -456,9 +456,9 @@ evaluation of aggregation functions.</p>
</span><span id="Context.table-45"><a href="#Context.table-45"><span class="linenos">45</span></a> </span><span id="Context.table-45"><a href="#Context.table-45"><span class="linenos">45</span></a>
</span><span id="Context.table-46"><a href="#Context.table-46"><span class="linenos">46</span></a> <span class="k">for</span> <span class="n">other</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tables</span><span class="o">.</span><span class="n">values</span><span class="p">():</span> </span><span id="Context.table-46"><a href="#Context.table-46"><span class="linenos">46</span></a> <span class="k">for</span> <span class="n">other</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">tables</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
</span><span id="Context.table-47"><a href="#Context.table-47"><span class="linenos">47</span></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_table</span><span class="o">.</span><span class="n">columns</span> <span class="o">!=</span> <span class="n">other</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span> </span><span id="Context.table-47"><a href="#Context.table-47"><span class="linenos">47</span></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_table</span><span class="o">.</span><span class="n">columns</span> <span class="o">!=</span> <span class="n">other</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="Context.table-48"><a href="#Context.table-48"><span class="linenos">48</span></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Columns are different.&quot;</span><span class="p">)</span> </span><span id="Context.table-48"><a href="#Context.table-48"><span class="linenos">48</span></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Columns are different.&quot;</span><span class="p">)</span>
</span><span id="Context.table-49"><a href="#Context.table-49"><span class="linenos">49</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_table</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">rows</span><span class="p">):</span> </span><span id="Context.table-49"><a href="#Context.table-49"><span class="linenos">49</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_table</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">rows</span><span class="p">):</span>
</span><span id="Context.table-50"><a href="#Context.table-50"><span class="linenos">50</span></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Rows are different.&quot;</span><span class="p">)</span> </span><span id="Context.table-50"><a href="#Context.table-50"><span class="linenos">50</span></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Rows are different.&quot;</span><span class="p">)</span>
</span><span id="Context.table-51"><a href="#Context.table-51"><span class="linenos">51</span></a> </span><span id="Context.table-51"><a href="#Context.table-51"><span class="linenos">51</span></a>
</span><span id="Context.table-52"><a href="#Context.table-52"><span class="linenos">52</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_table</span> </span><span id="Context.table-52"><a href="#Context.table-52"><span class="linenos">52</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_table</span>
</span></pre></div> </span></pre></div>

View file

@ -66,6 +66,9 @@
<li> <li>
<a class="function" href="#arrayjoin">arrayjoin</a> <a class="function" href="#arrayjoin">arrayjoin</a>
</li> </li>
<li>
<a class="function" href="#jsonextract">jsonextract</a>
</li>
<li> <li>
<a class="variable" href="#ENV">ENV</a> <a class="variable" href="#ENV">ENV</a>
</li> </li>
@ -100,7 +103,7 @@
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a> </span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">exp</span> </span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">exp</span>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="kn">from</span> <span class="nn">sqlglot.generator</span> <span class="kn">import</span> <span class="n">Generator</span> </span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="kn">from</span> <span class="nn">sqlglot.generator</span> <span class="kn">import</span> <span class="n">Generator</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="kn">from</span> <span class="nn">sqlglot.helper</span> <span class="kn">import</span> <span class="n">PYTHON_VERSION</span> </span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="kn">from</span> <span class="nn">sqlglot.helper</span> <span class="kn">import</span> <span class="n">PYTHON_VERSION</span><span class="p">,</span> <span class="n">is_int</span><span class="p">,</span> <span class="n">seq_get</span>
</span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a> </span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a>
</span><span id="L-11"><a href="#L-11"><span class="linenos"> 11</span></a> </span><span id="L-11"><a href="#L-11"><span class="linenos"> 11</span></a>
</span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a><span class="k">class</span> <span class="nc">reverse_key</span><span class="p">:</span> </span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a><span class="k">class</span> <span class="nc">reverse_key</span><span class="p">:</span>
@ -237,79 +240,95 @@
</span><span id="L-143"><a href="#L-143"><span class="linenos">143</span></a> <span class="k">return</span> <span class="n">expression</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="p">(</span><span class="n">x</span> <span class="k">if</span> <span class="n">x</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">null</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">this</span><span class="p">)</span> <span class="k">if</span> <span class="n">x</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">)</span> </span><span id="L-143"><a href="#L-143"><span class="linenos">143</span></a> <span class="k">return</span> <span class="n">expression</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="p">(</span><span class="n">x</span> <span class="k">if</span> <span class="n">x</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">null</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">this</span><span class="p">)</span> <span class="k">if</span> <span class="n">x</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a> </span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a>
</span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a> </span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a>
</span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a><span class="n">ENV</span> <span class="o">=</span> <span class="p">{</span> </span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a><span class="nd">@null_if_any</span><span class="p">(</span><span class="s2">&quot;this&quot;</span><span class="p">,</span> <span class="s2">&quot;expression&quot;</span><span class="p">)</span>
</span><span id="L-147"><a href="#L-147"><span class="linenos">147</span></a> <span class="s2">&quot;exp&quot;</span><span class="p">:</span> <span class="n">exp</span><span class="p">,</span> </span><span id="L-147"><a href="#L-147"><span class="linenos">147</span></a><span class="k">def</span> <span class="nf">jsonextract</span><span class="p">(</span><span class="n">this</span><span class="p">,</span> <span class="n">expression</span><span class="p">):</span>
</span><span id="L-148"><a href="#L-148"><span class="linenos">148</span></a> <span class="c1"># aggs</span> </span><span id="L-148"><a href="#L-148"><span class="linenos">148</span></a> <span class="k">for</span> <span class="n">path_segment</span> <span class="ow">in</span> <span class="n">expression</span><span class="p">:</span>
</span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a> <span class="s2">&quot;ARRAYAGG&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> </span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">this</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
</span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a> <span class="s2">&quot;ARRAYUNIQUEAGG&quot;</span><span class="p">:</span> <span class="n">filter_nulls</span><span class="p">(</span><span class="k">lambda</span> <span class="n">acc</span><span class="p">:</span> <span class="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">acc</span><span class="p">))),</span> </span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a> <span class="n">this</span> <span class="o">=</span> <span class="n">this</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">path_segment</span><span class="p">)</span>
</span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a> <span class="s2">&quot;AVG&quot;</span><span class="p">:</span> <span class="n">filter_nulls</span><span class="p">(</span><span class="n">statistics</span><span class="o">.</span><span class="n">fmean</span> <span class="k">if</span> <span class="n">PYTHON_VERSION</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> <span class="k">else</span> <span class="n">statistics</span><span class="o">.</span><span class="n">mean</span><span class="p">),</span> <span class="c1"># type: ignore</span> </span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">this</span><span class="p">,</span> <span class="nb">list</span><span class="p">)</span> <span class="ow">and</span> <span class="n">is_int</span><span class="p">(</span><span class="n">path_segment</span><span class="p">):</span>
</span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a> <span class="s2">&quot;COUNT&quot;</span><span class="p">:</span> <span class="n">filter_nulls</span><span class="p">(</span><span class="k">lambda</span> <span class="n">acc</span><span class="p">:</span> <span class="nb">sum</span><span class="p">(</span><span class="mi">1</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">acc</span><span class="p">),</span> <span class="kc">False</span><span class="p">),</span> </span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a> <span class="n">this</span> <span class="o">=</span> <span class="n">seq_get</span><span class="p">(</span><span class="n">this</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">path_segment</span><span class="p">))</span>
</span><span id="L-153"><a href="#L-153"><span class="linenos">153</span></a> <span class="s2">&quot;MAX&quot;</span><span class="p">:</span> <span class="n">filter_nulls</span><span class="p">(</span><span class="nb">max</span><span class="p">),</span> </span><span id="L-153"><a href="#L-153"><span class="linenos">153</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-154"><a href="#L-154"><span class="linenos">154</span></a> <span class="s2">&quot;MIN&quot;</span><span class="p">:</span> <span class="n">filter_nulls</span><span class="p">(</span><span class="nb">min</span><span class="p">),</span> </span><span id="L-154"><a href="#L-154"><span class="linenos">154</span></a> <span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unable to extract value for </span><span class="si">{</span><span class="n">this</span><span class="si">}</span><span class="s2"> at </span><span class="si">{</span><span class="n">path_segment</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
</span><span id="L-155"><a href="#L-155"><span class="linenos">155</span></a> <span class="s2">&quot;SUM&quot;</span><span class="p">:</span> <span class="n">filter_nulls</span><span class="p">(</span><span class="nb">sum</span><span class="p">),</span> </span><span id="L-155"><a href="#L-155"><span class="linenos">155</span></a>
</span><span id="L-156"><a href="#L-156"><span class="linenos">156</span></a> <span class="c1"># scalar functions</span> </span><span id="L-156"><a href="#L-156"><span class="linenos">156</span></a> <span class="k">if</span> <span class="n">this</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-157"><a href="#L-157"><span class="linenos">157</span></a> <span class="s2">&quot;ABS&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">:</span> <span class="nb">abs</span><span class="p">(</span><span class="n">this</span><span class="p">)),</span> </span><span id="L-157"><a href="#L-157"><span class="linenos">157</span></a> <span class="k">break</span>
</span><span id="L-158"><a href="#L-158"><span class="linenos">158</span></a> <span class="s2">&quot;ADD&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span> <span class="o">+</span> <span class="n">this</span><span class="p">),</span> </span><span id="L-158"><a href="#L-158"><span class="linenos">158</span></a>
</span><span id="L-159"><a href="#L-159"><span class="linenos">159</span></a> <span class="s2">&quot;ARRAYANY&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arr</span><span class="p">,</span> <span class="n">func</span><span class="p">:</span> <span class="nb">any</span><span class="p">(</span><span class="n">func</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">arr</span><span class="p">)),</span> </span><span id="L-159"><a href="#L-159"><span class="linenos">159</span></a> <span class="k">return</span> <span class="n">this</span>
</span><span id="L-160"><a href="#L-160"><span class="linenos">160</span></a> <span class="s2">&quot;ARRAYJOIN&quot;</span><span class="p">:</span> <span class="n">arrayjoin</span><span class="p">,</span> </span><span id="L-160"><a href="#L-160"><span class="linenos">160</span></a>
</span><span id="L-161"><a href="#L-161"><span class="linenos">161</span></a> <span class="s2">&quot;BETWEEN&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">low</span><span class="p">,</span> <span class="n">high</span><span class="p">:</span> <span class="n">low</span> <span class="o">&lt;=</span> <span class="n">this</span> <span class="ow">and</span> <span class="n">this</span> <span class="o">&lt;=</span> <span class="n">high</span><span class="p">),</span> </span><span id="L-161"><a href="#L-161"><span class="linenos">161</span></a>
</span><span id="L-162"><a href="#L-162"><span class="linenos">162</span></a> <span class="s2">&quot;BITWISEAND&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&amp;</span> <span class="n">e</span><span class="p">),</span> </span><span id="L-162"><a href="#L-162"><span class="linenos">162</span></a><span class="n">ENV</span> <span class="o">=</span> <span class="p">{</span>
</span><span id="L-163"><a href="#L-163"><span class="linenos">163</span></a> <span class="s2">&quot;BITWISELEFTSHIFT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&lt;&lt;</span> <span class="n">e</span><span class="p">),</span> </span><span id="L-163"><a href="#L-163"><span class="linenos">163</span></a> <span class="s2">&quot;exp&quot;</span><span class="p">:</span> <span class="n">exp</span><span class="p">,</span>
</span><span id="L-164"><a href="#L-164"><span class="linenos">164</span></a> <span class="s2">&quot;BITWISEOR&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">|</span> <span class="n">e</span><span class="p">),</span> </span><span id="L-164"><a href="#L-164"><span class="linenos">164</span></a> <span class="c1"># aggs</span>
</span><span id="L-165"><a href="#L-165"><span class="linenos">165</span></a> <span class="s2">&quot;BITWISERIGHTSHIFT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&gt;&gt;</span> <span class="n">e</span><span class="p">),</span> </span><span id="L-165"><a href="#L-165"><span class="linenos">165</span></a> <span class="s2">&quot;ARRAYAGG&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
</span><span id="L-166"><a href="#L-166"><span class="linenos">166</span></a> <span class="s2">&quot;BITWISEXOR&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">^</span> <span class="n">e</span><span class="p">),</span> </span><span id="L-166"><a href="#L-166"><span class="linenos">166</span></a> <span class="s2">&quot;ARRAYUNIQUEAGG&quot;</span><span class="p">:</span> <span class="n">filter_nulls</span><span class="p">(</span><span class="k">lambda</span> <span class="n">acc</span><span class="p">:</span> <span class="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">acc</span><span class="p">))),</span>
</span><span id="L-167"><a href="#L-167"><span class="linenos">167</span></a> <span class="s2">&quot;CAST&quot;</span><span class="p">:</span> <span class="n">cast</span><span class="p">,</span> </span><span id="L-167"><a href="#L-167"><span class="linenos">167</span></a> <span class="s2">&quot;AVG&quot;</span><span class="p">:</span> <span class="n">filter_nulls</span><span class="p">(</span><span class="n">statistics</span><span class="o">.</span><span class="n">fmean</span> <span class="k">if</span> <span class="n">PYTHON_VERSION</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> <span class="k">else</span> <span class="n">statistics</span><span class="o">.</span><span class="n">mean</span><span class="p">),</span> <span class="c1"># type: ignore</span>
</span><span id="L-168"><a href="#L-168"><span class="linenos">168</span></a> <span class="s2">&quot;COALESCE&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="nb">next</span><span class="p">((</span><span class="n">a</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">args</span> <span class="k">if</span> <span class="n">a</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">),</span> <span class="kc">None</span><span class="p">),</span> </span><span id="L-168"><a href="#L-168"><span class="linenos">168</span></a> <span class="s2">&quot;COUNT&quot;</span><span class="p">:</span> <span class="n">filter_nulls</span><span class="p">(</span><span class="k">lambda</span> <span class="n">acc</span><span class="p">:</span> <span class="nb">sum</span><span class="p">(</span><span class="mi">1</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">acc</span><span class="p">),</span> <span class="kc">False</span><span class="p">),</span>
</span><span id="L-169"><a href="#L-169"><span class="linenos">169</span></a> <span class="s2">&quot;CONCAT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">args</span><span class="p">)),</span> </span><span id="L-169"><a href="#L-169"><span class="linenos">169</span></a> <span class="s2">&quot;MAX&quot;</span><span class="p">:</span> <span class="n">filter_nulls</span><span class="p">(</span><span class="nb">max</span><span class="p">),</span>
</span><span id="L-170"><a href="#L-170"><span class="linenos">170</span></a> <span class="s2">&quot;SAFECONCAT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">args</span><span class="p">)),</span> </span><span id="L-170"><a href="#L-170"><span class="linenos">170</span></a> <span class="s2">&quot;MIN&quot;</span><span class="p">:</span> <span class="n">filter_nulls</span><span class="p">(</span><span class="nb">min</span><span class="p">),</span>
</span><span id="L-171"><a href="#L-171"><span class="linenos">171</span></a> <span class="s2">&quot;CONCATWS&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="n">this</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">args</span><span class="p">)),</span> </span><span id="L-171"><a href="#L-171"><span class="linenos">171</span></a> <span class="s2">&quot;SUM&quot;</span><span class="p">:</span> <span class="n">filter_nulls</span><span class="p">(</span><span class="nb">sum</span><span class="p">),</span>
</span><span id="L-172"><a href="#L-172"><span class="linenos">172</span></a> <span class="s2">&quot;DATEDIFF&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span><span class="p">:</span> <span class="p">(</span><span class="n">this</span> <span class="o">-</span> <span class="n">expression</span><span class="p">)</span><span class="o">.</span><span class="n">days</span><span class="p">),</span> </span><span id="L-172"><a href="#L-172"><span class="linenos">172</span></a> <span class="c1"># scalar functions</span>
</span><span id="L-173"><a href="#L-173"><span class="linenos">173</span></a> <span class="s2">&quot;DATESTRTODATE&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">arg</span><span class="p">)),</span> </span><span id="L-173"><a href="#L-173"><span class="linenos">173</span></a> <span class="s2">&quot;ABS&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">:</span> <span class="nb">abs</span><span class="p">(</span><span class="n">this</span><span class="p">)),</span>
</span><span id="L-174"><a href="#L-174"><span class="linenos">174</span></a> <span class="s2">&quot;DIV&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span> <span class="o">/</span> <span class="n">this</span><span class="p">),</span> </span><span id="L-174"><a href="#L-174"><span class="linenos">174</span></a> <span class="s2">&quot;ADD&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span> <span class="o">+</span> <span class="n">this</span><span class="p">),</span>
</span><span id="L-175"><a href="#L-175"><span class="linenos">175</span></a> <span class="s2">&quot;DOT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span><span class="p">[</span><span class="n">this</span><span class="p">]),</span> </span><span id="L-175"><a href="#L-175"><span class="linenos">175</span></a> <span class="s2">&quot;ARRAYANY&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arr</span><span class="p">,</span> <span class="n">func</span><span class="p">:</span> <span class="nb">any</span><span class="p">(</span><span class="n">func</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">arr</span><span class="p">)),</span>
</span><span id="L-176"><a href="#L-176"><span class="linenos">176</span></a> <span class="s2">&quot;EQ&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">==</span> <span class="n">e</span><span class="p">),</span> </span><span id="L-176"><a href="#L-176"><span class="linenos">176</span></a> <span class="s2">&quot;ARRAYJOIN&quot;</span><span class="p">:</span> <span class="n">arrayjoin</span><span class="p">,</span>
</span><span id="L-177"><a href="#L-177"><span class="linenos">177</span></a> <span class="s2">&quot;EXTRACT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">)),</span> </span><span id="L-177"><a href="#L-177"><span class="linenos">177</span></a> <span class="s2">&quot;BETWEEN&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">low</span><span class="p">,</span> <span class="n">high</span><span class="p">:</span> <span class="n">low</span> <span class="o">&lt;=</span> <span class="n">this</span> <span class="ow">and</span> <span class="n">this</span> <span class="o">&lt;=</span> <span class="n">high</span><span class="p">),</span>
</span><span id="L-178"><a href="#L-178"><span class="linenos">178</span></a> <span class="s2">&quot;GETPATH&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">e</span><span class="p">)),</span> </span><span id="L-178"><a href="#L-178"><span class="linenos">178</span></a> <span class="s2">&quot;BITWISEAND&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&amp;</span> <span class="n">e</span><span class="p">),</span>
</span><span id="L-179"><a href="#L-179"><span class="linenos">179</span></a> <span class="s2">&quot;GT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&gt;</span> <span class="n">e</span><span class="p">),</span> </span><span id="L-179"><a href="#L-179"><span class="linenos">179</span></a> <span class="s2">&quot;BITWISELEFTSHIFT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&lt;&lt;</span> <span class="n">e</span><span class="p">),</span>
</span><span id="L-180"><a href="#L-180"><span class="linenos">180</span></a> <span class="s2">&quot;GTE&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&gt;=</span> <span class="n">e</span><span class="p">),</span> </span><span id="L-180"><a href="#L-180"><span class="linenos">180</span></a> <span class="s2">&quot;BITWISEOR&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">|</span> <span class="n">e</span><span class="p">),</span>
</span><span id="L-181"><a href="#L-181"><span class="linenos">181</span></a> <span class="s2">&quot;IF&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">predicate</span><span class="p">,</span> <span class="n">true</span><span class="p">,</span> <span class="n">false</span><span class="p">:</span> <span class="n">true</span> <span class="k">if</span> <span class="n">predicate</span> <span class="k">else</span> <span class="n">false</span><span class="p">,</span> </span><span id="L-181"><a href="#L-181"><span class="linenos">181</span></a> <span class="s2">&quot;BITWISERIGHTSHIFT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&gt;&gt;</span> <span class="n">e</span><span class="p">),</span>
</span><span id="L-182"><a href="#L-182"><span class="linenos">182</span></a> <span class="s2">&quot;INTDIV&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span> <span class="o">//</span> <span class="n">this</span><span class="p">),</span> </span><span id="L-182"><a href="#L-182"><span class="linenos">182</span></a> <span class="s2">&quot;BITWISEXOR&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">^</span> <span class="n">e</span><span class="p">),</span>
</span><span id="L-183"><a href="#L-183"><span class="linenos">183</span></a> <span class="s2">&quot;INTERVAL&quot;</span><span class="p">:</span> <span class="n">interval</span><span class="p">,</span> </span><span id="L-183"><a href="#L-183"><span class="linenos">183</span></a> <span class="s2">&quot;CAST&quot;</span><span class="p">:</span> <span class="n">cast</span><span class="p">,</span>
</span><span id="L-184"><a href="#L-184"><span class="linenos">184</span></a> <span class="s2">&quot;LEFT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span><span class="p">[:</span><span class="n">e</span><span class="p">]),</span> </span><span id="L-184"><a href="#L-184"><span class="linenos">184</span></a> <span class="s2">&quot;COALESCE&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="nb">next</span><span class="p">((</span><span class="n">a</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">args</span> <span class="k">if</span> <span class="n">a</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">),</span> <span class="kc">None</span><span class="p">),</span>
</span><span id="L-185"><a href="#L-185"><span class="linenos">185</span></a> <span class="s2">&quot;LIKE&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span> </span><span id="L-185"><a href="#L-185"><span class="linenos">185</span></a> <span class="s2">&quot;CONCAT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">args</span><span class="p">)),</span>
</span><span id="L-186"><a href="#L-186"><span class="linenos">186</span></a> <span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="nb">bool</span><span class="p">(</span><span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;_&quot;</span><span class="p">,</span> <span class="s2">&quot;.&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;%&quot;</span><span class="p">,</span> <span class="s2">&quot;.*&quot;</span><span class="p">),</span> <span class="n">this</span><span class="p">))</span> </span><span id="L-186"><a href="#L-186"><span class="linenos">186</span></a> <span class="s2">&quot;SAFECONCAT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">args</span><span class="p">)),</span>
</span><span id="L-187"><a href="#L-187"><span class="linenos">187</span></a> <span class="p">),</span> </span><span id="L-187"><a href="#L-187"><span class="linenos">187</span></a> <span class="s2">&quot;CONCATWS&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="n">this</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">args</span><span class="p">)),</span>
</span><span id="L-188"><a href="#L-188"><span class="linenos">188</span></a> <span class="s2">&quot;LOWER&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">arg</span><span class="o">.</span><span class="n">lower</span><span class="p">()),</span> </span><span id="L-188"><a href="#L-188"><span class="linenos">188</span></a> <span class="s2">&quot;DATEDIFF&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span><span class="p">:</span> <span class="p">(</span><span class="n">this</span> <span class="o">-</span> <span class="n">expression</span><span class="p">)</span><span class="o">.</span><span class="n">days</span><span class="p">),</span>
</span><span id="L-189"><a href="#L-189"><span class="linenos">189</span></a> <span class="s2">&quot;LT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&lt;</span> <span class="n">e</span><span class="p">),</span> </span><span id="L-189"><a href="#L-189"><span class="linenos">189</span></a> <span class="s2">&quot;DATESTRTODATE&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">arg</span><span class="p">)),</span>
</span><span id="L-190"><a href="#L-190"><span class="linenos">190</span></a> <span class="s2">&quot;LTE&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&lt;=</span> <span class="n">e</span><span class="p">),</span> </span><span id="L-190"><a href="#L-190"><span class="linenos">190</span></a> <span class="s2">&quot;DIV&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span> <span class="o">/</span> <span class="n">this</span><span class="p">),</span>
</span><span id="L-191"><a href="#L-191"><span class="linenos">191</span></a> <span class="s2">&quot;MAP&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="nb">dict</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">))),</span> <span class="c1"># type: ignore</span> </span><span id="L-191"><a href="#L-191"><span class="linenos">191</span></a> <span class="s2">&quot;DOT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span><span class="p">[</span><span class="n">this</span><span class="p">]),</span>
</span><span id="L-192"><a href="#L-192"><span class="linenos">192</span></a> <span class="s2">&quot;MOD&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span> <span class="o">%</span> <span class="n">this</span><span class="p">),</span> </span><span id="L-192"><a href="#L-192"><span class="linenos">192</span></a> <span class="s2">&quot;EQ&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">==</span> <span class="n">e</span><span class="p">),</span>
</span><span id="L-193"><a href="#L-193"><span class="linenos">193</span></a> <span class="s2">&quot;MUL&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span> <span class="o">*</span> <span class="n">this</span><span class="p">),</span> </span><span id="L-193"><a href="#L-193"><span class="linenos">193</span></a> <span class="s2">&quot;EXTRACT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">)),</span>
</span><span id="L-194"><a href="#L-194"><span class="linenos">194</span></a> <span class="s2">&quot;NEQ&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">!=</span> <span class="n">e</span><span class="p">),</span> </span><span id="L-194"><a href="#L-194"><span class="linenos">194</span></a> <span class="s2">&quot;GT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&gt;</span> <span class="n">e</span><span class="p">),</span>
</span><span id="L-195"><a href="#L-195"><span class="linenos">195</span></a> <span class="s2">&quot;ORD&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="nb">ord</span><span class="p">),</span> </span><span id="L-195"><a href="#L-195"><span class="linenos">195</span></a> <span class="s2">&quot;GTE&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&gt;=</span> <span class="n">e</span><span class="p">),</span>
</span><span id="L-196"><a href="#L-196"><span class="linenos">196</span></a> <span class="s2">&quot;ORDERED&quot;</span><span class="p">:</span> <span class="n">ordered</span><span class="p">,</span> </span><span id="L-196"><a href="#L-196"><span class="linenos">196</span></a> <span class="s2">&quot;IF&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">predicate</span><span class="p">,</span> <span class="n">true</span><span class="p">,</span> <span class="n">false</span><span class="p">:</span> <span class="n">true</span> <span class="k">if</span> <span class="n">predicate</span> <span class="k">else</span> <span class="n">false</span><span class="p">,</span>
</span><span id="L-197"><a href="#L-197"><span class="linenos">197</span></a> <span class="s2">&quot;POW&quot;</span><span class="p">:</span> <span class="nb">pow</span><span class="p">,</span> </span><span id="L-197"><a href="#L-197"><span class="linenos">197</span></a> <span class="s2">&quot;INTDIV&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span> <span class="o">//</span> <span class="n">this</span><span class="p">),</span>
</span><span id="L-198"><a href="#L-198"><span class="linenos">198</span></a> <span class="s2">&quot;RIGHT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span><span class="p">[</span><span class="o">-</span><span class="n">e</span><span class="p">:]),</span> </span><span id="L-198"><a href="#L-198"><span class="linenos">198</span></a> <span class="s2">&quot;INTERVAL&quot;</span><span class="p">:</span> <span class="n">interval</span><span class="p">,</span>
</span><span id="L-199"><a href="#L-199"><span class="linenos">199</span></a> <span class="s2">&quot;STRPOSITION&quot;</span><span class="p">:</span> <span class="n">str_position</span><span class="p">,</span> </span><span id="L-199"><a href="#L-199"><span class="linenos">199</span></a> <span class="s2">&quot;JSONEXTRACT&quot;</span><span class="p">:</span> <span class="n">jsonextract</span><span class="p">,</span>
</span><span id="L-200"><a href="#L-200"><span class="linenos">200</span></a> <span class="s2">&quot;SUB&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span> <span class="o">-</span> <span class="n">this</span><span class="p">),</span> </span><span id="L-200"><a href="#L-200"><span class="linenos">200</span></a> <span class="s2">&quot;LEFT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span><span class="p">[:</span><span class="n">e</span><span class="p">]),</span>
</span><span id="L-201"><a href="#L-201"><span class="linenos">201</span></a> <span class="s2">&quot;SUBSTRING&quot;</span><span class="p">:</span> <span class="n">substring</span><span class="p">,</span> </span><span id="L-201"><a href="#L-201"><span class="linenos">201</span></a> <span class="s2">&quot;LIKE&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span>
</span><span id="L-202"><a href="#L-202"><span class="linenos">202</span></a> <span class="s2">&quot;TIMESTRTOTIME&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">arg</span><span class="p">)),</span> </span><span id="L-202"><a href="#L-202"><span class="linenos">202</span></a> <span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="nb">bool</span><span class="p">(</span><span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;_&quot;</span><span class="p">,</span> <span class="s2">&quot;.&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;%&quot;</span><span class="p">,</span> <span class="s2">&quot;.*&quot;</span><span class="p">),</span> <span class="n">this</span><span class="p">))</span>
</span><span id="L-203"><a href="#L-203"><span class="linenos">203</span></a> <span class="s2">&quot;UPPER&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">arg</span><span class="o">.</span><span class="n">upper</span><span class="p">()),</span> </span><span id="L-203"><a href="#L-203"><span class="linenos">203</span></a> <span class="p">),</span>
</span><span id="L-204"><a href="#L-204"><span class="linenos">204</span></a> <span class="s2">&quot;YEAR&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">arg</span><span class="o">.</span><span class="n">year</span><span class="p">),</span> </span><span id="L-204"><a href="#L-204"><span class="linenos">204</span></a> <span class="s2">&quot;LOWER&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">arg</span><span class="o">.</span><span class="n">lower</span><span class="p">()),</span>
</span><span id="L-205"><a href="#L-205"><span class="linenos">205</span></a> <span class="s2">&quot;MONTH&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">arg</span><span class="o">.</span><span class="n">month</span><span class="p">),</span> </span><span id="L-205"><a href="#L-205"><span class="linenos">205</span></a> <span class="s2">&quot;LT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&lt;</span> <span class="n">e</span><span class="p">),</span>
</span><span id="L-206"><a href="#L-206"><span class="linenos">206</span></a> <span class="s2">&quot;DAY&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">arg</span><span class="o">.</span><span class="n">day</span><span class="p">),</span> </span><span id="L-206"><a href="#L-206"><span class="linenos">206</span></a> <span class="s2">&quot;LTE&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">&lt;=</span> <span class="n">e</span><span class="p">),</span>
</span><span id="L-207"><a href="#L-207"><span class="linenos">207</span></a> <span class="s2">&quot;CURRENTDATETIME&quot;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">,</span> </span><span id="L-207"><a href="#L-207"><span class="linenos">207</span></a> <span class="s2">&quot;MAP&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="nb">dict</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">))),</span> <span class="c1"># type: ignore</span>
</span><span id="L-208"><a href="#L-208"><span class="linenos">208</span></a> <span class="s2">&quot;CURRENTTIMESTAMP&quot;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">,</span> </span><span id="L-208"><a href="#L-208"><span class="linenos">208</span></a> <span class="s2">&quot;MOD&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span> <span class="o">%</span> <span class="n">this</span><span class="p">),</span>
</span><span id="L-209"><a href="#L-209"><span class="linenos">209</span></a> <span class="s2">&quot;CURRENTTIME&quot;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">,</span> </span><span id="L-209"><a href="#L-209"><span class="linenos">209</span></a> <span class="s2">&quot;MUL&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span> <span class="o">*</span> <span class="n">this</span><span class="p">),</span>
</span><span id="L-210"><a href="#L-210"><span class="linenos">210</span></a> <span class="s2">&quot;CURRENTDATE&quot;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">today</span><span class="p">,</span> </span><span id="L-210"><a href="#L-210"><span class="linenos">210</span></a> <span class="s2">&quot;NEQ&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span> <span class="o">!=</span> <span class="n">e</span><span class="p">),</span>
</span><span id="L-211"><a href="#L-211"><span class="linenos">211</span></a> <span class="s2">&quot;STRFTIME&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">fmt</span><span class="p">,</span> <span class="n">arg</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="n">fmt</span><span class="p">)),</span> </span><span id="L-211"><a href="#L-211"><span class="linenos">211</span></a> <span class="s2">&quot;ORD&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="nb">ord</span><span class="p">),</span>
</span><span id="L-212"><a href="#L-212"><span class="linenos">212</span></a> <span class="s2">&quot;TRIM&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="o">=</span><span class="kc">None</span><span class="p">:</span> <span class="n">this</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="n">e</span><span class="p">)),</span> </span><span id="L-212"><a href="#L-212"><span class="linenos">212</span></a> <span class="s2">&quot;ORDERED&quot;</span><span class="p">:</span> <span class="n">ordered</span><span class="p">,</span>
</span><span id="L-213"><a href="#L-213"><span class="linenos">213</span></a> <span class="s2">&quot;STRUCT&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="p">{</span> </span><span id="L-213"><a href="#L-213"><span class="linenos">213</span></a> <span class="s2">&quot;POW&quot;</span><span class="p">:</span> <span class="nb">pow</span><span class="p">,</span>
</span><span id="L-214"><a href="#L-214"><span class="linenos">214</span></a> <span class="n">args</span><span class="p">[</span><span class="n">x</span><span class="p">]:</span> <span class="n">args</span><span class="p">[</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> </span><span id="L-214"><a href="#L-214"><span class="linenos">214</span></a> <span class="s2">&quot;RIGHT&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="n">this</span><span class="p">[</span><span class="o">-</span><span class="n">e</span><span class="p">:]),</span>
</span><span id="L-215"><a href="#L-215"><span class="linenos">215</span></a> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">),</span> <span class="mi">2</span><span class="p">)</span> </span><span id="L-215"><a href="#L-215"><span class="linenos">215</span></a> <span class="s2">&quot;STRPOSITION&quot;</span><span class="p">:</span> <span class="n">str_position</span><span class="p">,</span>
</span><span id="L-216"><a href="#L-216"><span class="linenos">216</span></a> <span class="k">if</span> <span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">args</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">)</span> </span><span id="L-216"><a href="#L-216"><span class="linenos">216</span></a> <span class="s2">&quot;SUB&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">e</span><span class="p">,</span> <span class="n">this</span><span class="p">:</span> <span class="n">e</span> <span class="o">-</span> <span class="n">this</span><span class="p">),</span>
</span><span id="L-217"><a href="#L-217"><span class="linenos">217</span></a> <span class="p">},</span> </span><span id="L-217"><a href="#L-217"><span class="linenos">217</span></a> <span class="s2">&quot;SUBSTRING&quot;</span><span class="p">:</span> <span class="n">substring</span><span class="p">,</span>
</span><span id="L-218"><a href="#L-218"><span class="linenos">218</span></a><span class="p">}</span> </span><span id="L-218"><a href="#L-218"><span class="linenos">218</span></a> <span class="s2">&quot;TIMESTRTOTIME&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">arg</span><span class="p">)),</span>
</span><span id="L-219"><a href="#L-219"><span class="linenos">219</span></a> <span class="s2">&quot;UPPER&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">arg</span><span class="o">.</span><span class="n">upper</span><span class="p">()),</span>
</span><span id="L-220"><a href="#L-220"><span class="linenos">220</span></a> <span class="s2">&quot;YEAR&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">arg</span><span class="o">.</span><span class="n">year</span><span class="p">),</span>
</span><span id="L-221"><a href="#L-221"><span class="linenos">221</span></a> <span class="s2">&quot;MONTH&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">arg</span><span class="o">.</span><span class="n">month</span><span class="p">),</span>
</span><span id="L-222"><a href="#L-222"><span class="linenos">222</span></a> <span class="s2">&quot;DAY&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">arg</span><span class="p">:</span> <span class="n">arg</span><span class="o">.</span><span class="n">day</span><span class="p">),</span>
</span><span id="L-223"><a href="#L-223"><span class="linenos">223</span></a> <span class="s2">&quot;CURRENTDATETIME&quot;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">,</span>
</span><span id="L-224"><a href="#L-224"><span class="linenos">224</span></a> <span class="s2">&quot;CURRENTTIMESTAMP&quot;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">,</span>
</span><span id="L-225"><a href="#L-225"><span class="linenos">225</span></a> <span class="s2">&quot;CURRENTTIME&quot;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">,</span>
</span><span id="L-226"><a href="#L-226"><span class="linenos">226</span></a> <span class="s2">&quot;CURRENTDATE&quot;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">today</span><span class="p">,</span>
</span><span id="L-227"><a href="#L-227"><span class="linenos">227</span></a> <span class="s2">&quot;STRFTIME&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">fmt</span><span class="p">,</span> <span class="n">arg</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="n">fmt</span><span class="p">)),</span>
</span><span id="L-228"><a href="#L-228"><span class="linenos">228</span></a> <span class="s2">&quot;TRIM&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="o">=</span><span class="kc">None</span><span class="p">:</span> <span class="n">this</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="n">e</span><span class="p">)),</span>
</span><span id="L-229"><a href="#L-229"><span class="linenos">229</span></a> <span class="s2">&quot;STRUCT&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="p">{</span>
</span><span id="L-230"><a href="#L-230"><span class="linenos">230</span></a> <span class="n">args</span><span class="p">[</span><span class="n">x</span><span class="p">]:</span> <span class="n">args</span><span class="p">[</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span>
</span><span id="L-231"><a href="#L-231"><span class="linenos">231</span></a> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">),</span> <span class="mi">2</span><span class="p">)</span>
</span><span id="L-232"><a href="#L-232"><span class="linenos">232</span></a> <span class="k">if</span> <span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">args</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="L-233"><a href="#L-233"><span class="linenos">233</span></a> <span class="p">},</span>
</span><span id="L-234"><a href="#L-234"><span class="linenos">234</span></a><span class="p">}</span>
</span></pre></div> </span></pre></div>
@ -626,12 +645,44 @@ def foo(a, b): ...
</section>
<section id="jsonextract">
<input id="jsonextract-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
<div class="decorator">@null_if_any(&#39;this&#39;, &#39;expression&#39;)</div>
<span class="def">def</span>
<span class="name">jsonextract</span><span class="signature pdoc-code condensed">(<span class="param"><span class="n">this</span>, </span><span class="param"><span class="n">expression</span></span><span class="return-annotation">):</span></span>
<label class="view-source-button" for="jsonextract-view-source"><span>View Source</span></label>
</div>
<a class="headerlink" href="#jsonextract"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="jsonextract-147"><a href="#jsonextract-147"><span class="linenos">147</span></a><span class="nd">@null_if_any</span><span class="p">(</span><span class="s2">&quot;this&quot;</span><span class="p">,</span> <span class="s2">&quot;expression&quot;</span><span class="p">)</span>
</span><span id="jsonextract-148"><a href="#jsonextract-148"><span class="linenos">148</span></a><span class="k">def</span> <span class="nf">jsonextract</span><span class="p">(</span><span class="n">this</span><span class="p">,</span> <span class="n">expression</span><span class="p">):</span>
</span><span id="jsonextract-149"><a href="#jsonextract-149"><span class="linenos">149</span></a> <span class="k">for</span> <span class="n">path_segment</span> <span class="ow">in</span> <span class="n">expression</span><span class="p">:</span>
</span><span id="jsonextract-150"><a href="#jsonextract-150"><span class="linenos">150</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">this</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
</span><span id="jsonextract-151"><a href="#jsonextract-151"><span class="linenos">151</span></a> <span class="n">this</span> <span class="o">=</span> <span class="n">this</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">path_segment</span><span class="p">)</span>
</span><span id="jsonextract-152"><a href="#jsonextract-152"><span class="linenos">152</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">this</span><span class="p">,</span> <span class="nb">list</span><span class="p">)</span> <span class="ow">and</span> <span class="n">is_int</span><span class="p">(</span><span class="n">path_segment</span><span class="p">):</span>
</span><span id="jsonextract-153"><a href="#jsonextract-153"><span class="linenos">153</span></a> <span class="n">this</span> <span class="o">=</span> <span class="n">seq_get</span><span class="p">(</span><span class="n">this</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">path_segment</span><span class="p">))</span>
</span><span id="jsonextract-154"><a href="#jsonextract-154"><span class="linenos">154</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="jsonextract-155"><a href="#jsonextract-155"><span class="linenos">155</span></a> <span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unable to extract value for </span><span class="si">{</span><span class="n">this</span><span class="si">}</span><span class="s2"> at </span><span class="si">{</span><span class="n">path_segment</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
</span><span id="jsonextract-156"><a href="#jsonextract-156"><span class="linenos">156</span></a>
</span><span id="jsonextract-157"><a href="#jsonextract-157"><span class="linenos">157</span></a> <span class="k">if</span> <span class="n">this</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="jsonextract-158"><a href="#jsonextract-158"><span class="linenos">158</span></a> <span class="k">break</span>
</span><span id="jsonextract-159"><a href="#jsonextract-159"><span class="linenos">159</span></a>
</span><span id="jsonextract-160"><a href="#jsonextract-160"><span class="linenos">160</span></a> <span class="k">return</span> <span class="n">this</span>
</span></pre></div>
</section> </section>
<section id="ENV"> <section id="ENV">
<div class="attr variable"> <div class="attr variable">
<span class="name">ENV</span> = <span class="name">ENV</span> =
<input id="ENV-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="ENV-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="ENV-view-value"></label><span class="default_value">{&#39;exp&#39;: &lt;module &#39;<a href="../expressions.html">sqlglot.expressions</a>&#39; from &#39;/home/runner/work/sqlglot/sqlglot/sqlglot/expressions.py&#39;&gt;, &#39;ARRAYAGG&#39;: &lt;class &#39;list&#39;&gt;, &#39;ARRAYUNIQUEAGG&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;AVG&#39;: &lt;function fmean&gt;, &#39;COUNT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MAX&#39;: &lt;function max&gt;, &#39;MIN&#39;: &lt;function min&gt;, &#39;SUM&#39;: &lt;function sum&gt;, &#39;ABS&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ADD&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ARRAYANY&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ARRAYJOIN&#39;: &lt;function arrayjoin&gt;, &#39;BETWEEN&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISEAND&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISELEFTSHIFT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISEOR&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISERIGHTSHIFT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISEXOR&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CAST&#39;: &lt;function cast&gt;, &#39;COALESCE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CONCAT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;SAFECONCAT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CONCATWS&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DATEDIFF&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DATESTRTODATE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DIV&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DOT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;EQ&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;EXTRACT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;GETPATH&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;GT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;GTE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;IF&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;INTDIV&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;INTERVAL&#39;: &lt;function interval&gt;, &#39;LEFT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LIKE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LOWER&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LTE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MAP&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MOD&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MUL&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;NEQ&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ORD&#39;: &lt;function ord&gt;, &#39;ORDERED&#39;: &lt;function ordered&gt;, &#39;POW&#39;: &lt;built-in function pow&gt;, &#39;RIGHT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;STRPOSITION&#39;: &lt;function str_position&gt;, &#39;SUB&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;SUBSTRING&#39;: &lt;function substring&gt;, &#39;TIMESTRTOTIME&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;UPPER&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;YEAR&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MONTH&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DAY&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CURRENTDATETIME&#39;: &lt;built-in method now of type object&gt;, &#39;CURRENTTIMESTAMP&#39;: &lt;built-in method now of type object&gt;, &#39;CURRENTTIME&#39;: &lt;built-in method now of type object&gt;, &#39;CURRENTDATE&#39;: &lt;built-in method today of type object&gt;, &#39;STRFTIME&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;TRIM&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;STRUCT&#39;: &lt;function &lt;lambda&gt;&gt;}</span> <label class="view-value-button pdoc-button" for="ENV-view-value"></label><span class="default_value">{&#39;exp&#39;: &lt;module &#39;<a href="../expressions.html">sqlglot.expressions</a>&#39; from &#39;/home/runner/work/sqlglot/sqlglot/sqlglot/expressions.py&#39;&gt;, &#39;ARRAYAGG&#39;: &lt;class &#39;list&#39;&gt;, &#39;ARRAYUNIQUEAGG&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;AVG&#39;: &lt;function fmean&gt;, &#39;COUNT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MAX&#39;: &lt;function max&gt;, &#39;MIN&#39;: &lt;function min&gt;, &#39;SUM&#39;: &lt;function sum&gt;, &#39;ABS&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ADD&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ARRAYANY&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ARRAYJOIN&#39;: &lt;function arrayjoin&gt;, &#39;BETWEEN&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISEAND&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISELEFTSHIFT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISEOR&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISERIGHTSHIFT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISEXOR&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CAST&#39;: &lt;function cast&gt;, &#39;COALESCE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CONCAT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;SAFECONCAT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CONCATWS&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DATEDIFF&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DATESTRTODATE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DIV&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DOT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;EQ&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;EXTRACT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;GT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;GTE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;IF&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;INTDIV&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;INTERVAL&#39;: &lt;function interval&gt;, &#39;JSONEXTRACT&#39;: &lt;function jsonextract&gt;, &#39;LEFT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LIKE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LOWER&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LTE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MAP&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MOD&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MUL&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;NEQ&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ORD&#39;: &lt;function ord&gt;, &#39;ORDERED&#39;: &lt;function ordered&gt;, &#39;POW&#39;: &lt;built-in function pow&gt;, &#39;RIGHT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;STRPOSITION&#39;: &lt;function str_position&gt;, &#39;SUB&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;SUBSTRING&#39;: &lt;function substring&gt;, &#39;TIMESTRTOTIME&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;UPPER&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;YEAR&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MONTH&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DAY&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CURRENTDATETIME&#39;: &lt;built-in method now of type object&gt;, &#39;CURRENTTIMESTAMP&#39;: &lt;built-in method now of type object&gt;, &#39;CURRENTTIME&#39;: &lt;built-in method now of type object&gt;, &#39;CURRENTDATE&#39;: &lt;built-in method today of type object&gt;, &#39;STRFTIME&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;TRIM&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;STRUCT&#39;: &lt;function &lt;lambda&gt;&gt;}</span>
</div> </div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -87,6 +87,9 @@
<li> <li>
<a class="function" href="#find_new_name">find_new_name</a> <a class="function" href="#find_new_name">find_new_name</a>
</li> </li>
<li>
<a class="function" href="#is_int">is_int</a>
</li>
<li> <li>
<a class="function" href="#name_sequence">name_sequence</a> <a class="function" href="#name_sequence">name_sequence</a>
</li> </li>
@ -384,7 +387,7 @@
</span><span id="L-236"><a href="#L-236"><span class="linenos">236</span></a> </span><span id="L-236"><a href="#L-236"><span class="linenos">236</span></a>
</span><span id="L-237"><a href="#L-237"><span class="linenos">237</span></a> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="n">deps</span> <span class="ow">in</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">dag</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span> </span><span id="L-237"><a href="#L-237"><span class="linenos">237</span></a> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="n">deps</span> <span class="ow">in</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">dag</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
</span><span id="L-238"><a href="#L-238"><span class="linenos">238</span></a> <span class="k">for</span> <span class="n">dep</span> <span class="ow">in</span> <span class="n">deps</span><span class="p">:</span> </span><span id="L-238"><a href="#L-238"><span class="linenos">238</span></a> <span class="k">for</span> <span class="n">dep</span> <span class="ow">in</span> <span class="n">deps</span><span class="p">:</span>
</span><span id="L-239"><a href="#L-239"><span class="linenos">239</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">dep</span> <span class="ow">in</span> <span class="n">dag</span><span class="p">:</span> </span><span id="L-239"><a href="#L-239"><span class="linenos">239</span></a> <span class="k">if</span> <span class="n">dep</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">dag</span><span class="p">:</span>
</span><span id="L-240"><a href="#L-240"><span class="linenos">240</span></a> <span class="n">dag</span><span class="p">[</span><span class="n">dep</span><span class="p">]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span> </span><span id="L-240"><a href="#L-240"><span class="linenos">240</span></a> <span class="n">dag</span><span class="p">[</span><span class="n">dep</span><span class="p">]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
</span><span id="L-241"><a href="#L-241"><span class="linenos">241</span></a> </span><span id="L-241"><a href="#L-241"><span class="linenos">241</span></a>
</span><span id="L-242"><a href="#L-242"><span class="linenos">242</span></a> <span class="k">while</span> <span class="n">dag</span><span class="p">:</span> </span><span id="L-242"><a href="#L-242"><span class="linenos">242</span></a> <span class="k">while</span> <span class="n">dag</span><span class="p">:</span>
@ -468,174 +471,182 @@
</span><span id="L-320"><a href="#L-320"><span class="linenos">320</span></a> <span class="k">return</span> <span class="n">new</span> </span><span id="L-320"><a href="#L-320"><span class="linenos">320</span></a> <span class="k">return</span> <span class="n">new</span>
</span><span id="L-321"><a href="#L-321"><span class="linenos">321</span></a> </span><span id="L-321"><a href="#L-321"><span class="linenos">321</span></a>
</span><span id="L-322"><a href="#L-322"><span class="linenos">322</span></a> </span><span id="L-322"><a href="#L-322"><span class="linenos">322</span></a>
</span><span id="L-323"><a href="#L-323"><span class="linenos">323</span></a><span class="k">def</span> <span class="nf">name_sequence</span><span class="p">(</span><span class="n">prefix</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[],</span> <span class="nb">str</span><span class="p">]:</span> </span><span id="L-323"><a href="#L-323"><span class="linenos">323</span></a><span class="k">def</span> <span class="nf">is_int</span><span class="p">(</span><span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="L-324"><a href="#L-324"><span class="linenos">324</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns a name generator given a prefix (e.g. a0, a1, a2, ... if the prefix is &quot;a&quot;).&quot;&quot;&quot;</span> </span><span id="L-324"><a href="#L-324"><span class="linenos">324</span></a> <span class="k">try</span><span class="p">:</span>
</span><span id="L-325"><a href="#L-325"><span class="linenos">325</span></a> <span class="n">sequence</span> <span class="o">=</span> <span class="n">count</span><span class="p">()</span> </span><span id="L-325"><a href="#L-325"><span class="linenos">325</span></a> <span class="nb">int</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
</span><span id="L-326"><a href="#L-326"><span class="linenos">326</span></a> <span class="k">return</span> <span class="k">lambda</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prefix</span><span class="si">}{</span><span class="nb">next</span><span class="p">(</span><span class="n">sequence</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span> </span><span id="L-326"><a href="#L-326"><span class="linenos">326</span></a> <span class="k">return</span> <span class="kc">True</span>
</span><span id="L-327"><a href="#L-327"><span class="linenos">327</span></a> </span><span id="L-327"><a href="#L-327"><span class="linenos">327</span></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
</span><span id="L-328"><a href="#L-328"><span class="linenos">328</span></a> </span><span id="L-328"><a href="#L-328"><span class="linenos">328</span></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="L-329"><a href="#L-329"><span class="linenos">329</span></a><span class="k">def</span> <span class="nf">object_to_dict</span><span class="p">(</span><span class="n">obj</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">:</span> </span><span id="L-329"><a href="#L-329"><span class="linenos">329</span></a>
</span><span id="L-330"><a href="#L-330"><span class="linenos">330</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns a dictionary created from an object&#39;s attributes.&quot;&quot;&quot;</span> </span><span id="L-330"><a href="#L-330"><span class="linenos">330</span></a>
</span><span id="L-331"><a href="#L-331"><span class="linenos">331</span></a> <span class="k">return</span> <span class="p">{</span> </span><span id="L-331"><a href="#L-331"><span class="linenos">331</span></a><span class="k">def</span> <span class="nf">name_sequence</span><span class="p">(</span><span class="n">prefix</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[],</span> <span class="nb">str</span><span class="p">]:</span>
</span><span id="L-332"><a href="#L-332"><span class="linenos">332</span></a> <span class="o">**</span><span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="s2">&quot;copy&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">copy</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">vars</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">items</span><span class="p">()},</span> </span><span id="L-332"><a href="#L-332"><span class="linenos">332</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns a name generator given a prefix (e.g. a0, a1, a2, ... if the prefix is &quot;a&quot;).&quot;&quot;&quot;</span>
</span><span id="L-333"><a href="#L-333"><span class="linenos">333</span></a> <span class="o">**</span><span class="n">kwargs</span><span class="p">,</span> </span><span id="L-333"><a href="#L-333"><span class="linenos">333</span></a> <span class="n">sequence</span> <span class="o">=</span> <span class="n">count</span><span class="p">()</span>
</span><span id="L-334"><a href="#L-334"><span class="linenos">334</span></a> <span class="p">}</span> </span><span id="L-334"><a href="#L-334"><span class="linenos">334</span></a> <span class="k">return</span> <span class="k">lambda</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prefix</span><span class="si">}{</span><span class="nb">next</span><span class="p">(</span><span class="n">sequence</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span id="L-335"><a href="#L-335"><span class="linenos">335</span></a> </span><span id="L-335"><a href="#L-335"><span class="linenos">335</span></a>
</span><span id="L-336"><a href="#L-336"><span class="linenos">336</span></a> </span><span id="L-336"><a href="#L-336"><span class="linenos">336</span></a>
</span><span id="L-337"><a href="#L-337"><span class="linenos">337</span></a><span class="k">def</span> <span class="nf">split_num_words</span><span class="p">(</span> </span><span id="L-337"><a href="#L-337"><span class="linenos">337</span></a><span class="k">def</span> <span class="nf">object_to_dict</span><span class="p">(</span><span class="n">obj</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">:</span>
</span><span id="L-338"><a href="#L-338"><span class="linenos">338</span></a> <span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">sep</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">min_num_words</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">fill_from_start</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span> </span><span id="L-338"><a href="#L-338"><span class="linenos">338</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns a dictionary created from an object&#39;s attributes.&quot;&quot;&quot;</span>
</span><span id="L-339"><a href="#L-339"><span class="linenos">339</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]]:</span> </span><span id="L-339"><a href="#L-339"><span class="linenos">339</span></a> <span class="k">return</span> <span class="p">{</span>
</span><span id="L-340"><a href="#L-340"><span class="linenos">340</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-340"><a href="#L-340"><span class="linenos">340</span></a> <span class="o">**</span><span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="s2">&quot;copy&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">copy</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">vars</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">items</span><span class="p">()},</span>
</span><span id="L-341"><a href="#L-341"><span class="linenos">341</span></a><span class="sd"> Perform a split on a value and return N words as a result with `None` used for words that don&#39;t exist.</span> </span><span id="L-341"><a href="#L-341"><span class="linenos">341</span></a> <span class="o">**</span><span class="n">kwargs</span><span class="p">,</span>
</span><span id="L-342"><a href="#L-342"><span class="linenos">342</span></a> </span><span id="L-342"><a href="#L-342"><span class="linenos">342</span></a> <span class="p">}</span>
</span><span id="L-343"><a href="#L-343"><span class="linenos">343</span></a><span class="sd"> Args:</span> </span><span id="L-343"><a href="#L-343"><span class="linenos">343</span></a>
</span><span id="L-344"><a href="#L-344"><span class="linenos">344</span></a><span class="sd"> value: The value to be split.</span> </span><span id="L-344"><a href="#L-344"><span class="linenos">344</span></a>
</span><span id="L-345"><a href="#L-345"><span class="linenos">345</span></a><span class="sd"> sep: The value to use to split on.</span> </span><span id="L-345"><a href="#L-345"><span class="linenos">345</span></a><span class="k">def</span> <span class="nf">split_num_words</span><span class="p">(</span>
</span><span id="L-346"><a href="#L-346"><span class="linenos">346</span></a><span class="sd"> min_num_words: The minimum number of words that are going to be in the result.</span> </span><span id="L-346"><a href="#L-346"><span class="linenos">346</span></a> <span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">sep</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">min_num_words</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">fill_from_start</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="L-347"><a href="#L-347"><span class="linenos">347</span></a><span class="sd"> fill_from_start: Indicates that if `None` values should be inserted at the start or end of the list.</span> </span><span id="L-347"><a href="#L-347"><span class="linenos">347</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]]:</span>
</span><span id="L-348"><a href="#L-348"><span class="linenos">348</span></a> </span><span id="L-348"><a href="#L-348"><span class="linenos">348</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-349"><a href="#L-349"><span class="linenos">349</span></a><span class="sd"> Examples:</span> </span><span id="L-349"><a href="#L-349"><span class="linenos">349</span></a><span class="sd"> Perform a split on a value and return N words as a result with `None` used for words that don&#39;t exist.</span>
</span><span id="L-350"><a href="#L-350"><span class="linenos">350</span></a><span class="sd"> &gt;&gt;&gt; split_num_words(&quot;db.table&quot;, &quot;.&quot;, 3)</span> </span><span id="L-350"><a href="#L-350"><span class="linenos">350</span></a>
</span><span id="L-351"><a href="#L-351"><span class="linenos">351</span></a><span class="sd"> [None, &#39;db&#39;, &#39;table&#39;]</span> </span><span id="L-351"><a href="#L-351"><span class="linenos">351</span></a><span class="sd"> Args:</span>
</span><span id="L-352"><a href="#L-352"><span class="linenos">352</span></a><span class="sd"> &gt;&gt;&gt; split_num_words(&quot;db.table&quot;, &quot;.&quot;, 3, fill_from_start=False)</span> </span><span id="L-352"><a href="#L-352"><span class="linenos">352</span></a><span class="sd"> value: The value to be split.</span>
</span><span id="L-353"><a href="#L-353"><span class="linenos">353</span></a><span class="sd"> [&#39;db&#39;, &#39;table&#39;, None]</span> </span><span id="L-353"><a href="#L-353"><span class="linenos">353</span></a><span class="sd"> sep: The value to use to split on.</span>
</span><span id="L-354"><a href="#L-354"><span class="linenos">354</span></a><span class="sd"> &gt;&gt;&gt; split_num_words(&quot;db.table&quot;, &quot;.&quot;, 1)</span> </span><span id="L-354"><a href="#L-354"><span class="linenos">354</span></a><span class="sd"> min_num_words: The minimum number of words that are going to be in the result.</span>
</span><span id="L-355"><a href="#L-355"><span class="linenos">355</span></a><span class="sd"> [&#39;db&#39;, &#39;table&#39;]</span> </span><span id="L-355"><a href="#L-355"><span class="linenos">355</span></a><span class="sd"> fill_from_start: Indicates that if `None` values should be inserted at the start or end of the list.</span>
</span><span id="L-356"><a href="#L-356"><span class="linenos">356</span></a> </span><span id="L-356"><a href="#L-356"><span class="linenos">356</span></a>
</span><span id="L-357"><a href="#L-357"><span class="linenos">357</span></a><span class="sd"> Returns:</span> </span><span id="L-357"><a href="#L-357"><span class="linenos">357</span></a><span class="sd"> Examples:</span>
</span><span id="L-358"><a href="#L-358"><span class="linenos">358</span></a><span class="sd"> The list of words returned by `split`, possibly augmented by a number of `None` values.</span> </span><span id="L-358"><a href="#L-358"><span class="linenos">358</span></a><span class="sd"> &gt;&gt;&gt; split_num_words(&quot;db.table&quot;, &quot;.&quot;, 3)</span>
</span><span id="L-359"><a href="#L-359"><span class="linenos">359</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-359"><a href="#L-359"><span class="linenos">359</span></a><span class="sd"> [None, &#39;db&#39;, &#39;table&#39;]</span>
</span><span id="L-360"><a href="#L-360"><span class="linenos">360</span></a> <span class="n">words</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">sep</span><span class="p">)</span> </span><span id="L-360"><a href="#L-360"><span class="linenos">360</span></a><span class="sd"> &gt;&gt;&gt; split_num_words(&quot;db.table&quot;, &quot;.&quot;, 3, fill_from_start=False)</span>
</span><span id="L-361"><a href="#L-361"><span class="linenos">361</span></a> <span class="k">if</span> <span class="n">fill_from_start</span><span class="p">:</span> </span><span id="L-361"><a href="#L-361"><span class="linenos">361</span></a><span class="sd"> [&#39;db&#39;, &#39;table&#39;, None]</span>
</span><span id="L-362"><a href="#L-362"><span class="linenos">362</span></a> <span class="k">return</span> <span class="p">[</span><span class="kc">None</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">min_num_words</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">words</span><span class="p">))</span> <span class="o">+</span> <span class="n">words</span> </span><span id="L-362"><a href="#L-362"><span class="linenos">362</span></a><span class="sd"> &gt;&gt;&gt; split_num_words(&quot;db.table&quot;, &quot;.&quot;, 1)</span>
</span><span id="L-363"><a href="#L-363"><span class="linenos">363</span></a> <span class="k">return</span> <span class="n">words</span> <span class="o">+</span> <span class="p">[</span><span class="kc">None</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">min_num_words</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">words</span><span class="p">))</span> </span><span id="L-363"><a href="#L-363"><span class="linenos">363</span></a><span class="sd"> [&#39;db&#39;, &#39;table&#39;]</span>
</span><span id="L-364"><a href="#L-364"><span class="linenos">364</span></a> </span><span id="L-364"><a href="#L-364"><span class="linenos">364</span></a>
</span><span id="L-365"><a href="#L-365"><span class="linenos">365</span></a> </span><span id="L-365"><a href="#L-365"><span class="linenos">365</span></a><span class="sd"> Returns:</span>
</span><span id="L-366"><a href="#L-366"><span class="linenos">366</span></a><span class="k">def</span> <span class="nf">is_iterable</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span> </span><span id="L-366"><a href="#L-366"><span class="linenos">366</span></a><span class="sd"> The list of words returned by `split`, possibly augmented by a number of `None` values.</span>
</span><span id="L-367"><a href="#L-367"><span class="linenos">367</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-367"><a href="#L-367"><span class="linenos">367</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-368"><a href="#L-368"><span class="linenos">368</span></a><span class="sd"> Checks if the value is an iterable, excluding the types `str` and `bytes`.</span> </span><span id="L-368"><a href="#L-368"><span class="linenos">368</span></a> <span class="n">words</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">sep</span><span class="p">)</span>
</span><span id="L-369"><a href="#L-369"><span class="linenos">369</span></a> </span><span id="L-369"><a href="#L-369"><span class="linenos">369</span></a> <span class="k">if</span> <span class="n">fill_from_start</span><span class="p">:</span>
</span><span id="L-370"><a href="#L-370"><span class="linenos">370</span></a><span class="sd"> Examples:</span> </span><span id="L-370"><a href="#L-370"><span class="linenos">370</span></a> <span class="k">return</span> <span class="p">[</span><span class="kc">None</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">min_num_words</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">words</span><span class="p">))</span> <span class="o">+</span> <span class="n">words</span>
</span><span id="L-371"><a href="#L-371"><span class="linenos">371</span></a><span class="sd"> &gt;&gt;&gt; is_iterable([1,2])</span> </span><span id="L-371"><a href="#L-371"><span class="linenos">371</span></a> <span class="k">return</span> <span class="n">words</span> <span class="o">+</span> <span class="p">[</span><span class="kc">None</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">min_num_words</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">words</span><span class="p">))</span>
</span><span id="L-372"><a href="#L-372"><span class="linenos">372</span></a><span class="sd"> True</span> </span><span id="L-372"><a href="#L-372"><span class="linenos">372</span></a>
</span><span id="L-373"><a href="#L-373"><span class="linenos">373</span></a><span class="sd"> &gt;&gt;&gt; is_iterable(&quot;test&quot;)</span> </span><span id="L-373"><a href="#L-373"><span class="linenos">373</span></a>
</span><span id="L-374"><a href="#L-374"><span class="linenos">374</span></a><span class="sd"> False</span> </span><span id="L-374"><a href="#L-374"><span class="linenos">374</span></a><span class="k">def</span> <span class="nf">is_iterable</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="L-375"><a href="#L-375"><span class="linenos">375</span></a> </span><span id="L-375"><a href="#L-375"><span class="linenos">375</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-376"><a href="#L-376"><span class="linenos">376</span></a><span class="sd"> Args:</span> </span><span id="L-376"><a href="#L-376"><span class="linenos">376</span></a><span class="sd"> Checks if the value is an iterable, excluding the types `str` and `bytes`.</span>
</span><span id="L-377"><a href="#L-377"><span class="linenos">377</span></a><span class="sd"> value: The value to check if it is an iterable.</span> </span><span id="L-377"><a href="#L-377"><span class="linenos">377</span></a>
</span><span id="L-378"><a href="#L-378"><span class="linenos">378</span></a> </span><span id="L-378"><a href="#L-378"><span class="linenos">378</span></a><span class="sd"> Examples:</span>
</span><span id="L-379"><a href="#L-379"><span class="linenos">379</span></a><span class="sd"> Returns:</span> </span><span id="L-379"><a href="#L-379"><span class="linenos">379</span></a><span class="sd"> &gt;&gt;&gt; is_iterable([1,2])</span>
</span><span id="L-380"><a href="#L-380"><span class="linenos">380</span></a><span class="sd"> A `bool` value indicating if it is an iterable.</span> </span><span id="L-380"><a href="#L-380"><span class="linenos">380</span></a><span class="sd"> True</span>
</span><span id="L-381"><a href="#L-381"><span class="linenos">381</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-381"><a href="#L-381"><span class="linenos">381</span></a><span class="sd"> &gt;&gt;&gt; is_iterable(&quot;test&quot;)</span>
</span><span id="L-382"><a href="#L-382"><span class="linenos">382</span></a> <span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">Expression</span> </span><span id="L-382"><a href="#L-382"><span class="linenos">382</span></a><span class="sd"> False</span>
</span><span id="L-383"><a href="#L-383"><span class="linenos">383</span></a> </span><span id="L-383"><a href="#L-383"><span class="linenos">383</span></a>
</span><span id="L-384"><a href="#L-384"><span class="linenos">384</span></a> <span class="k">return</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="s2">&quot;__iter__&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">,</span> <span class="n">Expression</span><span class="p">))</span> </span><span id="L-384"><a href="#L-384"><span class="linenos">384</span></a><span class="sd"> Args:</span>
</span><span id="L-385"><a href="#L-385"><span class="linenos">385</span></a> </span><span id="L-385"><a href="#L-385"><span class="linenos">385</span></a><span class="sd"> value: The value to check if it is an iterable.</span>
</span><span id="L-386"><a href="#L-386"><span class="linenos">386</span></a> </span><span id="L-386"><a href="#L-386"><span class="linenos">386</span></a>
</span><span id="L-387"><a href="#L-387"><span class="linenos">387</span></a><span class="k">def</span> <span class="nf">flatten</span><span class="p">(</span><span class="n">values</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterator</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">]:</span> </span><span id="L-387"><a href="#L-387"><span class="linenos">387</span></a><span class="sd"> Returns:</span>
</span><span id="L-388"><a href="#L-388"><span class="linenos">388</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-388"><a href="#L-388"><span class="linenos">388</span></a><span class="sd"> A `bool` value indicating if it is an iterable.</span>
</span><span id="L-389"><a href="#L-389"><span class="linenos">389</span></a><span class="sd"> Flattens an iterable that can contain both iterable and non-iterable elements. Objects of</span> </span><span id="L-389"><a href="#L-389"><span class="linenos">389</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-390"><a href="#L-390"><span class="linenos">390</span></a><span class="sd"> type `str` and `bytes` are not regarded as iterables.</span> </span><span id="L-390"><a href="#L-390"><span class="linenos">390</span></a> <span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">Expression</span>
</span><span id="L-391"><a href="#L-391"><span class="linenos">391</span></a> </span><span id="L-391"><a href="#L-391"><span class="linenos">391</span></a>
</span><span id="L-392"><a href="#L-392"><span class="linenos">392</span></a><span class="sd"> Examples:</span> </span><span id="L-392"><a href="#L-392"><span class="linenos">392</span></a> <span class="k">return</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="s2">&quot;__iter__&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">,</span> <span class="n">Expression</span><span class="p">))</span>
</span><span id="L-393"><a href="#L-393"><span class="linenos">393</span></a><span class="sd"> &gt;&gt;&gt; list(flatten([[1, 2], 3, {4}, (5, &quot;bla&quot;)]))</span> </span><span id="L-393"><a href="#L-393"><span class="linenos">393</span></a>
</span><span id="L-394"><a href="#L-394"><span class="linenos">394</span></a><span class="sd"> [1, 2, 3, 4, 5, &#39;bla&#39;]</span> </span><span id="L-394"><a href="#L-394"><span class="linenos">394</span></a>
</span><span id="L-395"><a href="#L-395"><span class="linenos">395</span></a><span class="sd"> &gt;&gt;&gt; list(flatten([1, 2, 3]))</span> </span><span id="L-395"><a href="#L-395"><span class="linenos">395</span></a><span class="k">def</span> <span class="nf">flatten</span><span class="p">(</span><span class="n">values</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterator</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">]:</span>
</span><span id="L-396"><a href="#L-396"><span class="linenos">396</span></a><span class="sd"> [1, 2, 3]</span> </span><span id="L-396"><a href="#L-396"><span class="linenos">396</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-397"><a href="#L-397"><span class="linenos">397</span></a> </span><span id="L-397"><a href="#L-397"><span class="linenos">397</span></a><span class="sd"> Flattens an iterable that can contain both iterable and non-iterable elements. Objects of</span>
</span><span id="L-398"><a href="#L-398"><span class="linenos">398</span></a><span class="sd"> Args:</span> </span><span id="L-398"><a href="#L-398"><span class="linenos">398</span></a><span class="sd"> type `str` and `bytes` are not regarded as iterables.</span>
</span><span id="L-399"><a href="#L-399"><span class="linenos">399</span></a><span class="sd"> values: The value to be flattened.</span> </span><span id="L-399"><a href="#L-399"><span class="linenos">399</span></a>
</span><span id="L-400"><a href="#L-400"><span class="linenos">400</span></a> </span><span id="L-400"><a href="#L-400"><span class="linenos">400</span></a><span class="sd"> Examples:</span>
</span><span id="L-401"><a href="#L-401"><span class="linenos">401</span></a><span class="sd"> Yields:</span> </span><span id="L-401"><a href="#L-401"><span class="linenos">401</span></a><span class="sd"> &gt;&gt;&gt; list(flatten([[1, 2], 3, {4}, (5, &quot;bla&quot;)]))</span>
</span><span id="L-402"><a href="#L-402"><span class="linenos">402</span></a><span class="sd"> Non-iterable elements in `values`.</span> </span><span id="L-402"><a href="#L-402"><span class="linenos">402</span></a><span class="sd"> [1, 2, 3, 4, 5, &#39;bla&#39;]</span>
</span><span id="L-403"><a href="#L-403"><span class="linenos">403</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-403"><a href="#L-403"><span class="linenos">403</span></a><span class="sd"> &gt;&gt;&gt; list(flatten([1, 2, 3]))</span>
</span><span id="L-404"><a href="#L-404"><span class="linenos">404</span></a> <span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">values</span><span class="p">:</span> </span><span id="L-404"><a href="#L-404"><span class="linenos">404</span></a><span class="sd"> [1, 2, 3]</span>
</span><span id="L-405"><a href="#L-405"><span class="linenos">405</span></a> <span class="k">if</span> <span class="n">is_iterable</span><span class="p">(</span><span class="n">value</span><span class="p">):</span> </span><span id="L-405"><a href="#L-405"><span class="linenos">405</span></a>
</span><span id="L-406"><a href="#L-406"><span class="linenos">406</span></a> <span class="k">yield from</span> <span class="n">flatten</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> </span><span id="L-406"><a href="#L-406"><span class="linenos">406</span></a><span class="sd"> Args:</span>
</span><span id="L-407"><a href="#L-407"><span class="linenos">407</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-407"><a href="#L-407"><span class="linenos">407</span></a><span class="sd"> values: The value to be flattened.</span>
</span><span id="L-408"><a href="#L-408"><span class="linenos">408</span></a> <span class="k">yield</span> <span class="n">value</span> </span><span id="L-408"><a href="#L-408"><span class="linenos">408</span></a>
</span><span id="L-409"><a href="#L-409"><span class="linenos">409</span></a> </span><span id="L-409"><a href="#L-409"><span class="linenos">409</span></a><span class="sd"> Yields:</span>
</span><span id="L-410"><a href="#L-410"><span class="linenos">410</span></a> </span><span id="L-410"><a href="#L-410"><span class="linenos">410</span></a><span class="sd"> Non-iterable elements in `values`.</span>
</span><span id="L-411"><a href="#L-411"><span class="linenos">411</span></a><span class="k">def</span> <span class="nf">dict_depth</span><span class="p">(</span><span class="n">d</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span> </span><span id="L-411"><a href="#L-411"><span class="linenos">411</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-412"><a href="#L-412"><span class="linenos">412</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-412"><a href="#L-412"><span class="linenos">412</span></a> <span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">values</span><span class="p">:</span>
</span><span id="L-413"><a href="#L-413"><span class="linenos">413</span></a><span class="sd"> Get the nesting depth of a dictionary.</span> </span><span id="L-413"><a href="#L-413"><span class="linenos">413</span></a> <span class="k">if</span> <span class="n">is_iterable</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
</span><span id="L-414"><a href="#L-414"><span class="linenos">414</span></a> </span><span id="L-414"><a href="#L-414"><span class="linenos">414</span></a> <span class="k">yield from</span> <span class="n">flatten</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
</span><span id="L-415"><a href="#L-415"><span class="linenos">415</span></a><span class="sd"> Example:</span> </span><span id="L-415"><a href="#L-415"><span class="linenos">415</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-416"><a href="#L-416"><span class="linenos">416</span></a><span class="sd"> &gt;&gt;&gt; dict_depth(None)</span> </span><span id="L-416"><a href="#L-416"><span class="linenos">416</span></a> <span class="k">yield</span> <span class="n">value</span>
</span><span id="L-417"><a href="#L-417"><span class="linenos">417</span></a><span class="sd"> 0</span> </span><span id="L-417"><a href="#L-417"><span class="linenos">417</span></a>
</span><span id="L-418"><a href="#L-418"><span class="linenos">418</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({})</span> </span><span id="L-418"><a href="#L-418"><span class="linenos">418</span></a>
</span><span id="L-419"><a href="#L-419"><span class="linenos">419</span></a><span class="sd"> 1</span> </span><span id="L-419"><a href="#L-419"><span class="linenos">419</span></a><span class="k">def</span> <span class="nf">dict_depth</span><span class="p">(</span><span class="n">d</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
</span><span id="L-420"><a href="#L-420"><span class="linenos">420</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({&quot;a&quot;: &quot;b&quot;})</span> </span><span id="L-420"><a href="#L-420"><span class="linenos">420</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-421"><a href="#L-421"><span class="linenos">421</span></a><span class="sd"> 1</span> </span><span id="L-421"><a href="#L-421"><span class="linenos">421</span></a><span class="sd"> Get the nesting depth of a dictionary.</span>
</span><span id="L-422"><a href="#L-422"><span class="linenos">422</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({&quot;a&quot;: {}})</span> </span><span id="L-422"><a href="#L-422"><span class="linenos">422</span></a>
</span><span id="L-423"><a href="#L-423"><span class="linenos">423</span></a><span class="sd"> 2</span> </span><span id="L-423"><a href="#L-423"><span class="linenos">423</span></a><span class="sd"> Example:</span>
</span><span id="L-424"><a href="#L-424"><span class="linenos">424</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({&quot;a&quot;: {&quot;b&quot;: {}}})</span> </span><span id="L-424"><a href="#L-424"><span class="linenos">424</span></a><span class="sd"> &gt;&gt;&gt; dict_depth(None)</span>
</span><span id="L-425"><a href="#L-425"><span class="linenos">425</span></a><span class="sd"> 3</span> </span><span id="L-425"><a href="#L-425"><span class="linenos">425</span></a><span class="sd"> 0</span>
</span><span id="L-426"><a href="#L-426"><span class="linenos">426</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-426"><a href="#L-426"><span class="linenos">426</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({})</span>
</span><span id="L-427"><a href="#L-427"><span class="linenos">427</span></a> <span class="k">try</span><span class="p">:</span> </span><span id="L-427"><a href="#L-427"><span class="linenos">427</span></a><span class="sd"> 1</span>
</span><span id="L-428"><a href="#L-428"><span class="linenos">428</span></a> <span class="k">return</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">dict_depth</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">values</span><span class="p">())))</span> </span><span id="L-428"><a href="#L-428"><span class="linenos">428</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({&quot;a&quot;: &quot;b&quot;})</span>
</span><span id="L-429"><a href="#L-429"><span class="linenos">429</span></a> <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span> </span><span id="L-429"><a href="#L-429"><span class="linenos">429</span></a><span class="sd"> 1</span>
</span><span id="L-430"><a href="#L-430"><span class="linenos">430</span></a> <span class="c1"># d doesn&#39;t have attribute &quot;values&quot;</span> </span><span id="L-430"><a href="#L-430"><span class="linenos">430</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({&quot;a&quot;: {}})</span>
</span><span id="L-431"><a href="#L-431"><span class="linenos">431</span></a> <span class="k">return</span> <span class="mi">0</span> </span><span id="L-431"><a href="#L-431"><span class="linenos">431</span></a><span class="sd"> 2</span>
</span><span id="L-432"><a href="#L-432"><span class="linenos">432</span></a> <span class="k">except</span> <span class="ne">StopIteration</span><span class="p">:</span> </span><span id="L-432"><a href="#L-432"><span class="linenos">432</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({&quot;a&quot;: {&quot;b&quot;: {}}})</span>
</span><span id="L-433"><a href="#L-433"><span class="linenos">433</span></a> <span class="c1"># d.values() returns an empty sequence</span> </span><span id="L-433"><a href="#L-433"><span class="linenos">433</span></a><span class="sd"> 3</span>
</span><span id="L-434"><a href="#L-434"><span class="linenos">434</span></a> <span class="k">return</span> <span class="mi">1</span> </span><span id="L-434"><a href="#L-434"><span class="linenos">434</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-435"><a href="#L-435"><span class="linenos">435</span></a> </span><span id="L-435"><a href="#L-435"><span class="linenos">435</span></a> <span class="k">try</span><span class="p">:</span>
</span><span id="L-436"><a href="#L-436"><span class="linenos">436</span></a> </span><span id="L-436"><a href="#L-436"><span class="linenos">436</span></a> <span class="k">return</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">dict_depth</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">values</span><span class="p">())))</span>
</span><span id="L-437"><a href="#L-437"><span class="linenos">437</span></a><span class="k">def</span> <span class="nf">first</span><span class="p">(</span><span class="n">it</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">T</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">T</span><span class="p">:</span> </span><span id="L-437"><a href="#L-437"><span class="linenos">437</span></a> <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
</span><span id="L-438"><a href="#L-438"><span class="linenos">438</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns the first element from an iterable (useful for sets).&quot;&quot;&quot;</span> </span><span id="L-438"><a href="#L-438"><span class="linenos">438</span></a> <span class="c1"># d doesn&#39;t have attribute &quot;values&quot;</span>
</span><span id="L-439"><a href="#L-439"><span class="linenos">439</span></a> <span class="k">return</span> <span class="nb">next</span><span class="p">(</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">it</span><span class="p">)</span> </span><span id="L-439"><a href="#L-439"><span class="linenos">439</span></a> <span class="k">return</span> <span class="mi">0</span>
</span><span id="L-440"><a href="#L-440"><span class="linenos">440</span></a> </span><span id="L-440"><a href="#L-440"><span class="linenos">440</span></a> <span class="k">except</span> <span class="ne">StopIteration</span><span class="p">:</span>
</span><span id="L-441"><a href="#L-441"><span class="linenos">441</span></a> </span><span id="L-441"><a href="#L-441"><span class="linenos">441</span></a> <span class="c1"># d.values() returns an empty sequence</span>
</span><span id="L-442"><a href="#L-442"><span class="linenos">442</span></a><span class="k">def</span> <span class="nf">merge_ranges</span><span class="p">(</span><span class="n">ranges</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Tuple</span><span class="p">[</span><span class="n">A</span><span class="p">,</span> <span class="n">A</span><span class="p">]])</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Tuple</span><span class="p">[</span><span class="n">A</span><span class="p">,</span> <span class="n">A</span><span class="p">]]:</span> </span><span id="L-442"><a href="#L-442"><span class="linenos">442</span></a> <span class="k">return</span> <span class="mi">1</span>
</span><span id="L-443"><a href="#L-443"><span class="linenos">443</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-443"><a href="#L-443"><span class="linenos">443</span></a>
</span><span id="L-444"><a href="#L-444"><span class="linenos">444</span></a><span class="sd"> Merges a sequence of ranges, represented as tuples (low, high) whose values</span> </span><span id="L-444"><a href="#L-444"><span class="linenos">444</span></a>
</span><span id="L-445"><a href="#L-445"><span class="linenos">445</span></a><span class="sd"> belong to some totally-ordered set.</span> </span><span id="L-445"><a href="#L-445"><span class="linenos">445</span></a><span class="k">def</span> <span class="nf">first</span><span class="p">(</span><span class="n">it</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">T</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">T</span><span class="p">:</span>
</span><span id="L-446"><a href="#L-446"><span class="linenos">446</span></a> </span><span id="L-446"><a href="#L-446"><span class="linenos">446</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns the first element from an iterable (useful for sets).&quot;&quot;&quot;</span>
</span><span id="L-447"><a href="#L-447"><span class="linenos">447</span></a><span class="sd"> Example:</span> </span><span id="L-447"><a href="#L-447"><span class="linenos">447</span></a> <span class="k">return</span> <span class="nb">next</span><span class="p">(</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">it</span><span class="p">)</span>
</span><span id="L-448"><a href="#L-448"><span class="linenos">448</span></a><span class="sd"> &gt;&gt;&gt; merge_ranges([(1, 3), (2, 6)])</span> </span><span id="L-448"><a href="#L-448"><span class="linenos">448</span></a>
</span><span id="L-449"><a href="#L-449"><span class="linenos">449</span></a><span class="sd"> [(1, 6)]</span> </span><span id="L-449"><a href="#L-449"><span class="linenos">449</span></a>
</span><span id="L-450"><a href="#L-450"><span class="linenos">450</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-450"><a href="#L-450"><span class="linenos">450</span></a><span class="k">def</span> <span class="nf">merge_ranges</span><span class="p">(</span><span class="n">ranges</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Tuple</span><span class="p">[</span><span class="n">A</span><span class="p">,</span> <span class="n">A</span><span class="p">]])</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Tuple</span><span class="p">[</span><span class="n">A</span><span class="p">,</span> <span class="n">A</span><span class="p">]]:</span>
</span><span id="L-451"><a href="#L-451"><span class="linenos">451</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">ranges</span><span class="p">:</span> </span><span id="L-451"><a href="#L-451"><span class="linenos">451</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-452"><a href="#L-452"><span class="linenos">452</span></a> <span class="k">return</span> <span class="p">[]</span> </span><span id="L-452"><a href="#L-452"><span class="linenos">452</span></a><span class="sd"> Merges a sequence of ranges, represented as tuples (low, high) whose values</span>
</span><span id="L-453"><a href="#L-453"><span class="linenos">453</span></a> </span><span id="L-453"><a href="#L-453"><span class="linenos">453</span></a><span class="sd"> belong to some totally-ordered set.</span>
</span><span id="L-454"><a href="#L-454"><span class="linenos">454</span></a> <span class="n">ranges</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">ranges</span><span class="p">)</span> </span><span id="L-454"><a href="#L-454"><span class="linenos">454</span></a>
</span><span id="L-455"><a href="#L-455"><span class="linenos">455</span></a> </span><span id="L-455"><a href="#L-455"><span class="linenos">455</span></a><span class="sd"> Example:</span>
</span><span id="L-456"><a href="#L-456"><span class="linenos">456</span></a> <span class="n">merged</span> <span class="o">=</span> <span class="p">[</span><span class="n">ranges</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> </span><span id="L-456"><a href="#L-456"><span class="linenos">456</span></a><span class="sd"> &gt;&gt;&gt; merge_ranges([(1, 3), (2, 6)])</span>
</span><span id="L-457"><a href="#L-457"><span class="linenos">457</span></a> </span><span id="L-457"><a href="#L-457"><span class="linenos">457</span></a><span class="sd"> [(1, 6)]</span>
</span><span id="L-458"><a href="#L-458"><span class="linenos">458</span></a> <span class="k">for</span> <span class="n">start</span><span class="p">,</span> <span class="n">end</span> <span class="ow">in</span> <span class="n">ranges</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span> </span><span id="L-458"><a href="#L-458"><span class="linenos">458</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-459"><a href="#L-459"><span class="linenos">459</span></a> <span class="n">last_start</span><span class="p">,</span> <span class="n">last_end</span> <span class="o">=</span> <span class="n">merged</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> </span><span id="L-459"><a href="#L-459"><span class="linenos">459</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">ranges</span><span class="p">:</span>
</span><span id="L-460"><a href="#L-460"><span class="linenos">460</span></a> </span><span id="L-460"><a href="#L-460"><span class="linenos">460</span></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="L-461"><a href="#L-461"><span class="linenos">461</span></a> <span class="k">if</span> <span class="n">start</span> <span class="o">&lt;=</span> <span class="n">last_end</span><span class="p">:</span> </span><span id="L-461"><a href="#L-461"><span class="linenos">461</span></a>
</span><span id="L-462"><a href="#L-462"><span class="linenos">462</span></a> <span class="n">merged</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">last_start</span><span class="p">,</span> <span class="nb">max</span><span class="p">(</span><span class="n">last_end</span><span class="p">,</span> <span class="n">end</span><span class="p">))</span> </span><span id="L-462"><a href="#L-462"><span class="linenos">462</span></a> <span class="n">ranges</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">ranges</span><span class="p">)</span>
</span><span id="L-463"><a href="#L-463"><span class="linenos">463</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-463"><a href="#L-463"><span class="linenos">463</span></a>
</span><span id="L-464"><a href="#L-464"><span class="linenos">464</span></a> <span class="n">merged</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">))</span> </span><span id="L-464"><a href="#L-464"><span class="linenos">464</span></a> <span class="n">merged</span> <span class="o">=</span> <span class="p">[</span><span class="n">ranges</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span>
</span><span id="L-465"><a href="#L-465"><span class="linenos">465</span></a> </span><span id="L-465"><a href="#L-465"><span class="linenos">465</span></a>
</span><span id="L-466"><a href="#L-466"><span class="linenos">466</span></a> <span class="k">return</span> <span class="n">merged</span> </span><span id="L-466"><a href="#L-466"><span class="linenos">466</span></a> <span class="k">for</span> <span class="n">start</span><span class="p">,</span> <span class="n">end</span> <span class="ow">in</span> <span class="n">ranges</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
</span><span id="L-467"><a href="#L-467"><span class="linenos">467</span></a> </span><span id="L-467"><a href="#L-467"><span class="linenos">467</span></a> <span class="n">last_start</span><span class="p">,</span> <span class="n">last_end</span> <span class="o">=</span> <span class="n">merged</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span><span id="L-468"><a href="#L-468"><span class="linenos">468</span></a> </span><span id="L-468"><a href="#L-468"><span class="linenos">468</span></a>
</span><span id="L-469"><a href="#L-469"><span class="linenos">469</span></a><span class="k">def</span> <span class="nf">is_iso_date</span><span class="p">(</span><span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span> </span><span id="L-469"><a href="#L-469"><span class="linenos">469</span></a> <span class="k">if</span> <span class="n">start</span> <span class="o">&lt;=</span> <span class="n">last_end</span><span class="p">:</span>
</span><span id="L-470"><a href="#L-470"><span class="linenos">470</span></a> <span class="k">try</span><span class="p">:</span> </span><span id="L-470"><a href="#L-470"><span class="linenos">470</span></a> <span class="n">merged</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">last_start</span><span class="p">,</span> <span class="nb">max</span><span class="p">(</span><span class="n">last_end</span><span class="p">,</span> <span class="n">end</span><span class="p">))</span>
</span><span id="L-471"><a href="#L-471"><span class="linenos">471</span></a> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">text</span><span class="p">)</span> </span><span id="L-471"><a href="#L-471"><span class="linenos">471</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-472"><a href="#L-472"><span class="linenos">472</span></a> <span class="k">return</span> <span class="kc">True</span> </span><span id="L-472"><a href="#L-472"><span class="linenos">472</span></a> <span class="n">merged</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">))</span>
</span><span id="L-473"><a href="#L-473"><span class="linenos">473</span></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> </span><span id="L-473"><a href="#L-473"><span class="linenos">473</span></a>
</span><span id="L-474"><a href="#L-474"><span class="linenos">474</span></a> <span class="k">return</span> <span class="kc">False</span> </span><span id="L-474"><a href="#L-474"><span class="linenos">474</span></a> <span class="k">return</span> <span class="n">merged</span>
</span><span id="L-475"><a href="#L-475"><span class="linenos">475</span></a> </span><span id="L-475"><a href="#L-475"><span class="linenos">475</span></a>
</span><span id="L-476"><a href="#L-476"><span class="linenos">476</span></a> </span><span id="L-476"><a href="#L-476"><span class="linenos">476</span></a>
</span><span id="L-477"><a href="#L-477"><span class="linenos">477</span></a><span class="k">def</span> <span class="nf">is_iso_datetime</span><span class="p">(</span><span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span> </span><span id="L-477"><a href="#L-477"><span class="linenos">477</span></a><span class="k">def</span> <span class="nf">is_iso_date</span><span class="p">(</span><span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="L-478"><a href="#L-478"><span class="linenos">478</span></a> <span class="k">try</span><span class="p">:</span> </span><span id="L-478"><a href="#L-478"><span class="linenos">478</span></a> <span class="k">try</span><span class="p">:</span>
</span><span id="L-479"><a href="#L-479"><span class="linenos">479</span></a> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">text</span><span class="p">)</span> </span><span id="L-479"><a href="#L-479"><span class="linenos">479</span></a> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
</span><span id="L-480"><a href="#L-480"><span class="linenos">480</span></a> <span class="k">return</span> <span class="kc">True</span> </span><span id="L-480"><a href="#L-480"><span class="linenos">480</span></a> <span class="k">return</span> <span class="kc">True</span>
</span><span id="L-481"><a href="#L-481"><span class="linenos">481</span></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> </span><span id="L-481"><a href="#L-481"><span class="linenos">481</span></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
</span><span id="L-482"><a href="#L-482"><span class="linenos">482</span></a> <span class="k">return</span> <span class="kc">False</span> </span><span id="L-482"><a href="#L-482"><span class="linenos">482</span></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="L-483"><a href="#L-483"><span class="linenos">483</span></a> </span><span id="L-483"><a href="#L-483"><span class="linenos">483</span></a>
</span><span id="L-484"><a href="#L-484"><span class="linenos">484</span></a> </span><span id="L-484"><a href="#L-484"><span class="linenos">484</span></a>
</span><span id="L-485"><a href="#L-485"><span class="linenos">485</span></a><span class="c1"># Interval units that operate on date components</span> </span><span id="L-485"><a href="#L-485"><span class="linenos">485</span></a><span class="k">def</span> <span class="nf">is_iso_datetime</span><span class="p">(</span><span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="L-486"><a href="#L-486"><span class="linenos">486</span></a><span class="n">DATE_UNITS</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;day&quot;</span><span class="p">,</span> <span class="s2">&quot;week&quot;</span><span class="p">,</span> <span class="s2">&quot;month&quot;</span><span class="p">,</span> <span class="s2">&quot;quarter&quot;</span><span class="p">,</span> <span class="s2">&quot;year&quot;</span><span class="p">,</span> <span class="s2">&quot;year_month&quot;</span><span class="p">}</span> </span><span id="L-486"><a href="#L-486"><span class="linenos">486</span></a> <span class="k">try</span><span class="p">:</span>
</span><span id="L-487"><a href="#L-487"><span class="linenos">487</span></a> </span><span id="L-487"><a href="#L-487"><span class="linenos">487</span></a> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
</span><span id="L-488"><a href="#L-488"><span class="linenos">488</span></a> </span><span id="L-488"><a href="#L-488"><span class="linenos">488</span></a> <span class="k">return</span> <span class="kc">True</span>
</span><span id="L-489"><a href="#L-489"><span class="linenos">489</span></a><span class="k">def</span> <span class="nf">is_date_unit</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span> </span><span id="L-489"><a href="#L-489"><span class="linenos">489</span></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
</span><span id="L-490"><a href="#L-490"><span class="linenos">490</span></a> <span class="k">return</span> <span class="n">expression</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">in</span> <span class="n">DATE_UNITS</span> </span><span id="L-490"><a href="#L-490"><span class="linenos">490</span></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="L-491"><a href="#L-491"><span class="linenos">491</span></a>
</span><span id="L-492"><a href="#L-492"><span class="linenos">492</span></a>
</span><span id="L-493"><a href="#L-493"><span class="linenos">493</span></a><span class="c1"># Interval units that operate on date components</span>
</span><span id="L-494"><a href="#L-494"><span class="linenos">494</span></a><span class="n">DATE_UNITS</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;day&quot;</span><span class="p">,</span> <span class="s2">&quot;week&quot;</span><span class="p">,</span> <span class="s2">&quot;month&quot;</span><span class="p">,</span> <span class="s2">&quot;quarter&quot;</span><span class="p">,</span> <span class="s2">&quot;year&quot;</span><span class="p">,</span> <span class="s2">&quot;year_month&quot;</span><span class="p">}</span>
</span><span id="L-495"><a href="#L-495"><span class="linenos">495</span></a>
</span><span id="L-496"><a href="#L-496"><span class="linenos">496</span></a>
</span><span id="L-497"><a href="#L-497"><span class="linenos">497</span></a><span class="k">def</span> <span class="nf">is_date_unit</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="L-498"><a href="#L-498"><span class="linenos">498</span></a> <span class="k">return</span> <span class="n">expression</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">in</span> <span class="n">DATE_UNITS</span>
</span></pre></div> </span></pre></div>
@ -1157,7 +1168,7 @@ of the corresponding enum's identifier (e.g. FOO.value results in "FOO").</p>
</span><span id="tsort-237"><a href="#tsort-237"><span class="linenos">237</span></a> </span><span id="tsort-237"><a href="#tsort-237"><span class="linenos">237</span></a>
</span><span id="tsort-238"><a href="#tsort-238"><span class="linenos">238</span></a> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="n">deps</span> <span class="ow">in</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">dag</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span> </span><span id="tsort-238"><a href="#tsort-238"><span class="linenos">238</span></a> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="n">deps</span> <span class="ow">in</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">dag</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
</span><span id="tsort-239"><a href="#tsort-239"><span class="linenos">239</span></a> <span class="k">for</span> <span class="n">dep</span> <span class="ow">in</span> <span class="n">deps</span><span class="p">:</span> </span><span id="tsort-239"><a href="#tsort-239"><span class="linenos">239</span></a> <span class="k">for</span> <span class="n">dep</span> <span class="ow">in</span> <span class="n">deps</span><span class="p">:</span>
</span><span id="tsort-240"><a href="#tsort-240"><span class="linenos">240</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">dep</span> <span class="ow">in</span> <span class="n">dag</span><span class="p">:</span> </span><span id="tsort-240"><a href="#tsort-240"><span class="linenos">240</span></a> <span class="k">if</span> <span class="n">dep</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">dag</span><span class="p">:</span>
</span><span id="tsort-241"><a href="#tsort-241"><span class="linenos">241</span></a> <span class="n">dag</span><span class="p">[</span><span class="n">dep</span><span class="p">]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span> </span><span id="tsort-241"><a href="#tsort-241"><span class="linenos">241</span></a> <span class="n">dag</span><span class="p">[</span><span class="n">dep</span><span class="p">]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
</span><span id="tsort-242"><a href="#tsort-242"><span class="linenos">242</span></a> </span><span id="tsort-242"><a href="#tsort-242"><span class="linenos">242</span></a>
</span><span id="tsort-243"><a href="#tsort-243"><span class="linenos">243</span></a> <span class="k">while</span> <span class="n">dag</span><span class="p">:</span> </span><span id="tsort-243"><a href="#tsort-243"><span class="linenos">243</span></a> <span class="k">while</span> <span class="n">dag</span><span class="p">:</span>
@ -1335,6 +1346,29 @@ of the corresponding enum's identifier (e.g. FOO.value results in "FOO").</p>
</div> </div>
</section>
<section id="is_int">
<input id="is_int-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
<span class="def">def</span>
<span class="name">is_int</span><span class="signature pdoc-code condensed">(<span class="param"><span class="n">text</span><span class="p">:</span> <span class="nb">str</span></span><span class="return-annotation">) -> <span class="nb">bool</span>:</span></span>
<label class="view-source-button" for="is_int-view-source"><span>View Source</span></label>
</div>
<a class="headerlink" href="#is_int"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="is_int-324"><a href="#is_int-324"><span class="linenos">324</span></a><span class="k">def</span> <span class="nf">is_int</span><span class="p">(</span><span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="is_int-325"><a href="#is_int-325"><span class="linenos">325</span></a> <span class="k">try</span><span class="p">:</span>
</span><span id="is_int-326"><a href="#is_int-326"><span class="linenos">326</span></a> <span class="nb">int</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
</span><span id="is_int-327"><a href="#is_int-327"><span class="linenos">327</span></a> <span class="k">return</span> <span class="kc">True</span>
</span><span id="is_int-328"><a href="#is_int-328"><span class="linenos">328</span></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
</span><span id="is_int-329"><a href="#is_int-329"><span class="linenos">329</span></a> <span class="k">return</span> <span class="kc">False</span>
</span></pre></div>
</section> </section>
<section id="name_sequence"> <section id="name_sequence">
<input id="name_sequence-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="name_sequence-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
@ -1347,10 +1381,10 @@ of the corresponding enum's identifier (e.g. FOO.value results in "FOO").</p>
</div> </div>
<a class="headerlink" href="#name_sequence"></a> <a class="headerlink" href="#name_sequence"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="name_sequence-324"><a href="#name_sequence-324"><span class="linenos">324</span></a><span class="k">def</span> <span class="nf">name_sequence</span><span class="p">(</span><span class="n">prefix</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[],</span> <span class="nb">str</span><span class="p">]:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="name_sequence-332"><a href="#name_sequence-332"><span class="linenos">332</span></a><span class="k">def</span> <span class="nf">name_sequence</span><span class="p">(</span><span class="n">prefix</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[],</span> <span class="nb">str</span><span class="p">]:</span>
</span><span id="name_sequence-325"><a href="#name_sequence-325"><span class="linenos">325</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns a name generator given a prefix (e.g. a0, a1, a2, ... if the prefix is &quot;a&quot;).&quot;&quot;&quot;</span> </span><span id="name_sequence-333"><a href="#name_sequence-333"><span class="linenos">333</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns a name generator given a prefix (e.g. a0, a1, a2, ... if the prefix is &quot;a&quot;).&quot;&quot;&quot;</span>
</span><span id="name_sequence-326"><a href="#name_sequence-326"><span class="linenos">326</span></a> <span class="n">sequence</span> <span class="o">=</span> <span class="n">count</span><span class="p">()</span> </span><span id="name_sequence-334"><a href="#name_sequence-334"><span class="linenos">334</span></a> <span class="n">sequence</span> <span class="o">=</span> <span class="n">count</span><span class="p">()</span>
</span><span id="name_sequence-327"><a href="#name_sequence-327"><span class="linenos">327</span></a> <span class="k">return</span> <span class="k">lambda</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prefix</span><span class="si">}{</span><span class="nb">next</span><span class="p">(</span><span class="n">sequence</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span> </span><span id="name_sequence-335"><a href="#name_sequence-335"><span class="linenos">335</span></a> <span class="k">return</span> <span class="k">lambda</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">prefix</span><span class="si">}{</span><span class="nb">next</span><span class="p">(</span><span class="n">sequence</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span>
</span></pre></div> </span></pre></div>
@ -1370,12 +1404,12 @@ of the corresponding enum's identifier (e.g. FOO.value results in "FOO").</p>
</div> </div>
<a class="headerlink" href="#object_to_dict"></a> <a class="headerlink" href="#object_to_dict"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="object_to_dict-330"><a href="#object_to_dict-330"><span class="linenos">330</span></a><span class="k">def</span> <span class="nf">object_to_dict</span><span class="p">(</span><span class="n">obj</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="object_to_dict-338"><a href="#object_to_dict-338"><span class="linenos">338</span></a><span class="k">def</span> <span class="nf">object_to_dict</span><span class="p">(</span><span class="n">obj</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">:</span>
</span><span id="object_to_dict-331"><a href="#object_to_dict-331"><span class="linenos">331</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns a dictionary created from an object&#39;s attributes.&quot;&quot;&quot;</span> </span><span id="object_to_dict-339"><a href="#object_to_dict-339"><span class="linenos">339</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns a dictionary created from an object&#39;s attributes.&quot;&quot;&quot;</span>
</span><span id="object_to_dict-332"><a href="#object_to_dict-332"><span class="linenos">332</span></a> <span class="k">return</span> <span class="p">{</span> </span><span id="object_to_dict-340"><a href="#object_to_dict-340"><span class="linenos">340</span></a> <span class="k">return</span> <span class="p">{</span>
</span><span id="object_to_dict-333"><a href="#object_to_dict-333"><span class="linenos">333</span></a> <span class="o">**</span><span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="s2">&quot;copy&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">copy</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">vars</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">items</span><span class="p">()},</span> </span><span id="object_to_dict-341"><a href="#object_to_dict-341"><span class="linenos">341</span></a> <span class="o">**</span><span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="s2">&quot;copy&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">copy</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">vars</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="n">items</span><span class="p">()},</span>
</span><span id="object_to_dict-334"><a href="#object_to_dict-334"><span class="linenos">334</span></a> <span class="o">**</span><span class="n">kwargs</span><span class="p">,</span> </span><span id="object_to_dict-342"><a href="#object_to_dict-342"><span class="linenos">342</span></a> <span class="o">**</span><span class="n">kwargs</span><span class="p">,</span>
</span><span id="object_to_dict-335"><a href="#object_to_dict-335"><span class="linenos">335</span></a> <span class="p">}</span> </span><span id="object_to_dict-343"><a href="#object_to_dict-343"><span class="linenos">343</span></a> <span class="p">}</span>
</span></pre></div> </span></pre></div>
@ -1395,33 +1429,33 @@ of the corresponding enum's identifier (e.g. FOO.value results in "FOO").</p>
</div> </div>
<a class="headerlink" href="#split_num_words"></a> <a class="headerlink" href="#split_num_words"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="split_num_words-338"><a href="#split_num_words-338"><span class="linenos">338</span></a><span class="k">def</span> <span class="nf">split_num_words</span><span class="p">(</span> <div class="pdoc-code codehilite"><pre><span></span><span id="split_num_words-346"><a href="#split_num_words-346"><span class="linenos">346</span></a><span class="k">def</span> <span class="nf">split_num_words</span><span class="p">(</span>
</span><span id="split_num_words-339"><a href="#split_num_words-339"><span class="linenos">339</span></a> <span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">sep</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">min_num_words</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">fill_from_start</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span> </span><span id="split_num_words-347"><a href="#split_num_words-347"><span class="linenos">347</span></a> <span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">sep</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">min_num_words</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">fill_from_start</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="split_num_words-340"><a href="#split_num_words-340"><span class="linenos">340</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]]:</span> </span><span id="split_num_words-348"><a href="#split_num_words-348"><span class="linenos">348</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]]:</span>
</span><span id="split_num_words-341"><a href="#split_num_words-341"><span class="linenos">341</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="split_num_words-349"><a href="#split_num_words-349"><span class="linenos">349</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="split_num_words-342"><a href="#split_num_words-342"><span class="linenos">342</span></a><span class="sd"> Perform a split on a value and return N words as a result with `None` used for words that don&#39;t exist.</span> </span><span id="split_num_words-350"><a href="#split_num_words-350"><span class="linenos">350</span></a><span class="sd"> Perform a split on a value and return N words as a result with `None` used for words that don&#39;t exist.</span>
</span><span id="split_num_words-343"><a href="#split_num_words-343"><span class="linenos">343</span></a> </span><span id="split_num_words-351"><a href="#split_num_words-351"><span class="linenos">351</span></a>
</span><span id="split_num_words-344"><a href="#split_num_words-344"><span class="linenos">344</span></a><span class="sd"> Args:</span> </span><span id="split_num_words-352"><a href="#split_num_words-352"><span class="linenos">352</span></a><span class="sd"> Args:</span>
</span><span id="split_num_words-345"><a href="#split_num_words-345"><span class="linenos">345</span></a><span class="sd"> value: The value to be split.</span> </span><span id="split_num_words-353"><a href="#split_num_words-353"><span class="linenos">353</span></a><span class="sd"> value: The value to be split.</span>
</span><span id="split_num_words-346"><a href="#split_num_words-346"><span class="linenos">346</span></a><span class="sd"> sep: The value to use to split on.</span> </span><span id="split_num_words-354"><a href="#split_num_words-354"><span class="linenos">354</span></a><span class="sd"> sep: The value to use to split on.</span>
</span><span id="split_num_words-347"><a href="#split_num_words-347"><span class="linenos">347</span></a><span class="sd"> min_num_words: The minimum number of words that are going to be in the result.</span> </span><span id="split_num_words-355"><a href="#split_num_words-355"><span class="linenos">355</span></a><span class="sd"> min_num_words: The minimum number of words that are going to be in the result.</span>
</span><span id="split_num_words-348"><a href="#split_num_words-348"><span class="linenos">348</span></a><span class="sd"> fill_from_start: Indicates that if `None` values should be inserted at the start or end of the list.</span> </span><span id="split_num_words-356"><a href="#split_num_words-356"><span class="linenos">356</span></a><span class="sd"> fill_from_start: Indicates that if `None` values should be inserted at the start or end of the list.</span>
</span><span id="split_num_words-349"><a href="#split_num_words-349"><span class="linenos">349</span></a>
</span><span id="split_num_words-350"><a href="#split_num_words-350"><span class="linenos">350</span></a><span class="sd"> Examples:</span>
</span><span id="split_num_words-351"><a href="#split_num_words-351"><span class="linenos">351</span></a><span class="sd"> &gt;&gt;&gt; split_num_words(&quot;db.table&quot;, &quot;.&quot;, 3)</span>
</span><span id="split_num_words-352"><a href="#split_num_words-352"><span class="linenos">352</span></a><span class="sd"> [None, &#39;db&#39;, &#39;table&#39;]</span>
</span><span id="split_num_words-353"><a href="#split_num_words-353"><span class="linenos">353</span></a><span class="sd"> &gt;&gt;&gt; split_num_words(&quot;db.table&quot;, &quot;.&quot;, 3, fill_from_start=False)</span>
</span><span id="split_num_words-354"><a href="#split_num_words-354"><span class="linenos">354</span></a><span class="sd"> [&#39;db&#39;, &#39;table&#39;, None]</span>
</span><span id="split_num_words-355"><a href="#split_num_words-355"><span class="linenos">355</span></a><span class="sd"> &gt;&gt;&gt; split_num_words(&quot;db.table&quot;, &quot;.&quot;, 1)</span>
</span><span id="split_num_words-356"><a href="#split_num_words-356"><span class="linenos">356</span></a><span class="sd"> [&#39;db&#39;, &#39;table&#39;]</span>
</span><span id="split_num_words-357"><a href="#split_num_words-357"><span class="linenos">357</span></a> </span><span id="split_num_words-357"><a href="#split_num_words-357"><span class="linenos">357</span></a>
</span><span id="split_num_words-358"><a href="#split_num_words-358"><span class="linenos">358</span></a><span class="sd"> Returns:</span> </span><span id="split_num_words-358"><a href="#split_num_words-358"><span class="linenos">358</span></a><span class="sd"> Examples:</span>
</span><span id="split_num_words-359"><a href="#split_num_words-359"><span class="linenos">359</span></a><span class="sd"> The list of words returned by `split`, possibly augmented by a number of `None` values.</span> </span><span id="split_num_words-359"><a href="#split_num_words-359"><span class="linenos">359</span></a><span class="sd"> &gt;&gt;&gt; split_num_words(&quot;db.table&quot;, &quot;.&quot;, 3)</span>
</span><span id="split_num_words-360"><a href="#split_num_words-360"><span class="linenos">360</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="split_num_words-360"><a href="#split_num_words-360"><span class="linenos">360</span></a><span class="sd"> [None, &#39;db&#39;, &#39;table&#39;]</span>
</span><span id="split_num_words-361"><a href="#split_num_words-361"><span class="linenos">361</span></a> <span class="n">words</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">sep</span><span class="p">)</span> </span><span id="split_num_words-361"><a href="#split_num_words-361"><span class="linenos">361</span></a><span class="sd"> &gt;&gt;&gt; split_num_words(&quot;db.table&quot;, &quot;.&quot;, 3, fill_from_start=False)</span>
</span><span id="split_num_words-362"><a href="#split_num_words-362"><span class="linenos">362</span></a> <span class="k">if</span> <span class="n">fill_from_start</span><span class="p">:</span> </span><span id="split_num_words-362"><a href="#split_num_words-362"><span class="linenos">362</span></a><span class="sd"> [&#39;db&#39;, &#39;table&#39;, None]</span>
</span><span id="split_num_words-363"><a href="#split_num_words-363"><span class="linenos">363</span></a> <span class="k">return</span> <span class="p">[</span><span class="kc">None</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">min_num_words</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">words</span><span class="p">))</span> <span class="o">+</span> <span class="n">words</span> </span><span id="split_num_words-363"><a href="#split_num_words-363"><span class="linenos">363</span></a><span class="sd"> &gt;&gt;&gt; split_num_words(&quot;db.table&quot;, &quot;.&quot;, 1)</span>
</span><span id="split_num_words-364"><a href="#split_num_words-364"><span class="linenos">364</span></a> <span class="k">return</span> <span class="n">words</span> <span class="o">+</span> <span class="p">[</span><span class="kc">None</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">min_num_words</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">words</span><span class="p">))</span> </span><span id="split_num_words-364"><a href="#split_num_words-364"><span class="linenos">364</span></a><span class="sd"> [&#39;db&#39;, &#39;table&#39;]</span>
</span><span id="split_num_words-365"><a href="#split_num_words-365"><span class="linenos">365</span></a>
</span><span id="split_num_words-366"><a href="#split_num_words-366"><span class="linenos">366</span></a><span class="sd"> Returns:</span>
</span><span id="split_num_words-367"><a href="#split_num_words-367"><span class="linenos">367</span></a><span class="sd"> The list of words returned by `split`, possibly augmented by a number of `None` values.</span>
</span><span id="split_num_words-368"><a href="#split_num_words-368"><span class="linenos">368</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="split_num_words-369"><a href="#split_num_words-369"><span class="linenos">369</span></a> <span class="n">words</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">sep</span><span class="p">)</span>
</span><span id="split_num_words-370"><a href="#split_num_words-370"><span class="linenos">370</span></a> <span class="k">if</span> <span class="n">fill_from_start</span><span class="p">:</span>
</span><span id="split_num_words-371"><a href="#split_num_words-371"><span class="linenos">371</span></a> <span class="k">return</span> <span class="p">[</span><span class="kc">None</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">min_num_words</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">words</span><span class="p">))</span> <span class="o">+</span> <span class="n">words</span>
</span><span id="split_num_words-372"><a href="#split_num_words-372"><span class="linenos">372</span></a> <span class="k">return</span> <span class="n">words</span> <span class="o">+</span> <span class="p">[</span><span class="kc">None</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">min_num_words</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">words</span><span class="p">))</span>
</span></pre></div> </span></pre></div>
@ -1470,25 +1504,25 @@ of the corresponding enum's identifier (e.g. FOO.value results in "FOO").</p>
</div> </div>
<a class="headerlink" href="#is_iterable"></a> <a class="headerlink" href="#is_iterable"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="is_iterable-367"><a href="#is_iterable-367"><span class="linenos">367</span></a><span class="k">def</span> <span class="nf">is_iterable</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="is_iterable-375"><a href="#is_iterable-375"><span class="linenos">375</span></a><span class="k">def</span> <span class="nf">is_iterable</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="is_iterable-368"><a href="#is_iterable-368"><span class="linenos">368</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="is_iterable-376"><a href="#is_iterable-376"><span class="linenos">376</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="is_iterable-369"><a href="#is_iterable-369"><span class="linenos">369</span></a><span class="sd"> Checks if the value is an iterable, excluding the types `str` and `bytes`.</span> </span><span id="is_iterable-377"><a href="#is_iterable-377"><span class="linenos">377</span></a><span class="sd"> Checks if the value is an iterable, excluding the types `str` and `bytes`.</span>
</span><span id="is_iterable-370"><a href="#is_iterable-370"><span class="linenos">370</span></a> </span><span id="is_iterable-378"><a href="#is_iterable-378"><span class="linenos">378</span></a>
</span><span id="is_iterable-371"><a href="#is_iterable-371"><span class="linenos">371</span></a><span class="sd"> Examples:</span> </span><span id="is_iterable-379"><a href="#is_iterable-379"><span class="linenos">379</span></a><span class="sd"> Examples:</span>
</span><span id="is_iterable-372"><a href="#is_iterable-372"><span class="linenos">372</span></a><span class="sd"> &gt;&gt;&gt; is_iterable([1,2])</span> </span><span id="is_iterable-380"><a href="#is_iterable-380"><span class="linenos">380</span></a><span class="sd"> &gt;&gt;&gt; is_iterable([1,2])</span>
</span><span id="is_iterable-373"><a href="#is_iterable-373"><span class="linenos">373</span></a><span class="sd"> True</span> </span><span id="is_iterable-381"><a href="#is_iterable-381"><span class="linenos">381</span></a><span class="sd"> True</span>
</span><span id="is_iterable-374"><a href="#is_iterable-374"><span class="linenos">374</span></a><span class="sd"> &gt;&gt;&gt; is_iterable(&quot;test&quot;)</span> </span><span id="is_iterable-382"><a href="#is_iterable-382"><span class="linenos">382</span></a><span class="sd"> &gt;&gt;&gt; is_iterable(&quot;test&quot;)</span>
</span><span id="is_iterable-375"><a href="#is_iterable-375"><span class="linenos">375</span></a><span class="sd"> False</span> </span><span id="is_iterable-383"><a href="#is_iterable-383"><span class="linenos">383</span></a><span class="sd"> False</span>
</span><span id="is_iterable-376"><a href="#is_iterable-376"><span class="linenos">376</span></a>
</span><span id="is_iterable-377"><a href="#is_iterable-377"><span class="linenos">377</span></a><span class="sd"> Args:</span>
</span><span id="is_iterable-378"><a href="#is_iterable-378"><span class="linenos">378</span></a><span class="sd"> value: The value to check if it is an iterable.</span>
</span><span id="is_iterable-379"><a href="#is_iterable-379"><span class="linenos">379</span></a>
</span><span id="is_iterable-380"><a href="#is_iterable-380"><span class="linenos">380</span></a><span class="sd"> Returns:</span>
</span><span id="is_iterable-381"><a href="#is_iterable-381"><span class="linenos">381</span></a><span class="sd"> A `bool` value indicating if it is an iterable.</span>
</span><span id="is_iterable-382"><a href="#is_iterable-382"><span class="linenos">382</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="is_iterable-383"><a href="#is_iterable-383"><span class="linenos">383</span></a> <span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">Expression</span>
</span><span id="is_iterable-384"><a href="#is_iterable-384"><span class="linenos">384</span></a> </span><span id="is_iterable-384"><a href="#is_iterable-384"><span class="linenos">384</span></a>
</span><span id="is_iterable-385"><a href="#is_iterable-385"><span class="linenos">385</span></a> <span class="k">return</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="s2">&quot;__iter__&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">,</span> <span class="n">Expression</span><span class="p">))</span> </span><span id="is_iterable-385"><a href="#is_iterable-385"><span class="linenos">385</span></a><span class="sd"> Args:</span>
</span><span id="is_iterable-386"><a href="#is_iterable-386"><span class="linenos">386</span></a><span class="sd"> value: The value to check if it is an iterable.</span>
</span><span id="is_iterable-387"><a href="#is_iterable-387"><span class="linenos">387</span></a>
</span><span id="is_iterable-388"><a href="#is_iterable-388"><span class="linenos">388</span></a><span class="sd"> Returns:</span>
</span><span id="is_iterable-389"><a href="#is_iterable-389"><span class="linenos">389</span></a><span class="sd"> A `bool` value indicating if it is an iterable.</span>
</span><span id="is_iterable-390"><a href="#is_iterable-390"><span class="linenos">390</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="is_iterable-391"><a href="#is_iterable-391"><span class="linenos">391</span></a> <span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">Expression</span>
</span><span id="is_iterable-392"><a href="#is_iterable-392"><span class="linenos">392</span></a>
</span><span id="is_iterable-393"><a href="#is_iterable-393"><span class="linenos">393</span></a> <span class="k">return</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="s2">&quot;__iter__&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">,</span> <span class="n">Expression</span><span class="p">))</span>
</span></pre></div> </span></pre></div>
@ -1532,28 +1566,28 @@ of the corresponding enum's identifier (e.g. FOO.value results in "FOO").</p>
</div> </div>
<a class="headerlink" href="#flatten"></a> <a class="headerlink" href="#flatten"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="flatten-388"><a href="#flatten-388"><span class="linenos">388</span></a><span class="k">def</span> <span class="nf">flatten</span><span class="p">(</span><span class="n">values</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterator</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">]:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="flatten-396"><a href="#flatten-396"><span class="linenos">396</span></a><span class="k">def</span> <span class="nf">flatten</span><span class="p">(</span><span class="n">values</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">]</span> <span class="o">|</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterator</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">]:</span>
</span><span id="flatten-389"><a href="#flatten-389"><span class="linenos">389</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="flatten-397"><a href="#flatten-397"><span class="linenos">397</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="flatten-390"><a href="#flatten-390"><span class="linenos">390</span></a><span class="sd"> Flattens an iterable that can contain both iterable and non-iterable elements. Objects of</span> </span><span id="flatten-398"><a href="#flatten-398"><span class="linenos">398</span></a><span class="sd"> Flattens an iterable that can contain both iterable and non-iterable elements. Objects of</span>
</span><span id="flatten-391"><a href="#flatten-391"><span class="linenos">391</span></a><span class="sd"> type `str` and `bytes` are not regarded as iterables.</span> </span><span id="flatten-399"><a href="#flatten-399"><span class="linenos">399</span></a><span class="sd"> type `str` and `bytes` are not regarded as iterables.</span>
</span><span id="flatten-392"><a href="#flatten-392"><span class="linenos">392</span></a> </span><span id="flatten-400"><a href="#flatten-400"><span class="linenos">400</span></a>
</span><span id="flatten-393"><a href="#flatten-393"><span class="linenos">393</span></a><span class="sd"> Examples:</span> </span><span id="flatten-401"><a href="#flatten-401"><span class="linenos">401</span></a><span class="sd"> Examples:</span>
</span><span id="flatten-394"><a href="#flatten-394"><span class="linenos">394</span></a><span class="sd"> &gt;&gt;&gt; list(flatten([[1, 2], 3, {4}, (5, &quot;bla&quot;)]))</span> </span><span id="flatten-402"><a href="#flatten-402"><span class="linenos">402</span></a><span class="sd"> &gt;&gt;&gt; list(flatten([[1, 2], 3, {4}, (5, &quot;bla&quot;)]))</span>
</span><span id="flatten-395"><a href="#flatten-395"><span class="linenos">395</span></a><span class="sd"> [1, 2, 3, 4, 5, &#39;bla&#39;]</span> </span><span id="flatten-403"><a href="#flatten-403"><span class="linenos">403</span></a><span class="sd"> [1, 2, 3, 4, 5, &#39;bla&#39;]</span>
</span><span id="flatten-396"><a href="#flatten-396"><span class="linenos">396</span></a><span class="sd"> &gt;&gt;&gt; list(flatten([1, 2, 3]))</span> </span><span id="flatten-404"><a href="#flatten-404"><span class="linenos">404</span></a><span class="sd"> &gt;&gt;&gt; list(flatten([1, 2, 3]))</span>
</span><span id="flatten-397"><a href="#flatten-397"><span class="linenos">397</span></a><span class="sd"> [1, 2, 3]</span> </span><span id="flatten-405"><a href="#flatten-405"><span class="linenos">405</span></a><span class="sd"> [1, 2, 3]</span>
</span><span id="flatten-398"><a href="#flatten-398"><span class="linenos">398</span></a> </span><span id="flatten-406"><a href="#flatten-406"><span class="linenos">406</span></a>
</span><span id="flatten-399"><a href="#flatten-399"><span class="linenos">399</span></a><span class="sd"> Args:</span> </span><span id="flatten-407"><a href="#flatten-407"><span class="linenos">407</span></a><span class="sd"> Args:</span>
</span><span id="flatten-400"><a href="#flatten-400"><span class="linenos">400</span></a><span class="sd"> values: The value to be flattened.</span> </span><span id="flatten-408"><a href="#flatten-408"><span class="linenos">408</span></a><span class="sd"> values: The value to be flattened.</span>
</span><span id="flatten-401"><a href="#flatten-401"><span class="linenos">401</span></a> </span><span id="flatten-409"><a href="#flatten-409"><span class="linenos">409</span></a>
</span><span id="flatten-402"><a href="#flatten-402"><span class="linenos">402</span></a><span class="sd"> Yields:</span> </span><span id="flatten-410"><a href="#flatten-410"><span class="linenos">410</span></a><span class="sd"> Yields:</span>
</span><span id="flatten-403"><a href="#flatten-403"><span class="linenos">403</span></a><span class="sd"> Non-iterable elements in `values`.</span> </span><span id="flatten-411"><a href="#flatten-411"><span class="linenos">411</span></a><span class="sd"> Non-iterable elements in `values`.</span>
</span><span id="flatten-404"><a href="#flatten-404"><span class="linenos">404</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="flatten-412"><a href="#flatten-412"><span class="linenos">412</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="flatten-405"><a href="#flatten-405"><span class="linenos">405</span></a> <span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">values</span><span class="p">:</span> </span><span id="flatten-413"><a href="#flatten-413"><span class="linenos">413</span></a> <span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">values</span><span class="p">:</span>
</span><span id="flatten-406"><a href="#flatten-406"><span class="linenos">406</span></a> <span class="k">if</span> <span class="n">is_iterable</span><span class="p">(</span><span class="n">value</span><span class="p">):</span> </span><span id="flatten-414"><a href="#flatten-414"><span class="linenos">414</span></a> <span class="k">if</span> <span class="n">is_iterable</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
</span><span id="flatten-407"><a href="#flatten-407"><span class="linenos">407</span></a> <span class="k">yield from</span> <span class="n">flatten</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> </span><span id="flatten-415"><a href="#flatten-415"><span class="linenos">415</span></a> <span class="k">yield from</span> <span class="n">flatten</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
</span><span id="flatten-408"><a href="#flatten-408"><span class="linenos">408</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="flatten-416"><a href="#flatten-416"><span class="linenos">416</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="flatten-409"><a href="#flatten-409"><span class="linenos">409</span></a> <span class="k">yield</span> <span class="n">value</span> </span><span id="flatten-417"><a href="#flatten-417"><span class="linenos">417</span></a> <span class="k">yield</span> <span class="n">value</span>
</span></pre></div> </span></pre></div>
@ -1598,30 +1632,30 @@ type <code>str</code> and <code>bytes</code> are not regarded as iterables.</p>
</div> </div>
<a class="headerlink" href="#dict_depth"></a> <a class="headerlink" href="#dict_depth"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="dict_depth-412"><a href="#dict_depth-412"><span class="linenos">412</span></a><span class="k">def</span> <span class="nf">dict_depth</span><span class="p">(</span><span class="n">d</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="dict_depth-420"><a href="#dict_depth-420"><span class="linenos">420</span></a><span class="k">def</span> <span class="nf">dict_depth</span><span class="p">(</span><span class="n">d</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
</span><span id="dict_depth-413"><a href="#dict_depth-413"><span class="linenos">413</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="dict_depth-421"><a href="#dict_depth-421"><span class="linenos">421</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="dict_depth-414"><a href="#dict_depth-414"><span class="linenos">414</span></a><span class="sd"> Get the nesting depth of a dictionary.</span> </span><span id="dict_depth-422"><a href="#dict_depth-422"><span class="linenos">422</span></a><span class="sd"> Get the nesting depth of a dictionary.</span>
</span><span id="dict_depth-415"><a href="#dict_depth-415"><span class="linenos">415</span></a> </span><span id="dict_depth-423"><a href="#dict_depth-423"><span class="linenos">423</span></a>
</span><span id="dict_depth-416"><a href="#dict_depth-416"><span class="linenos">416</span></a><span class="sd"> Example:</span> </span><span id="dict_depth-424"><a href="#dict_depth-424"><span class="linenos">424</span></a><span class="sd"> Example:</span>
</span><span id="dict_depth-417"><a href="#dict_depth-417"><span class="linenos">417</span></a><span class="sd"> &gt;&gt;&gt; dict_depth(None)</span> </span><span id="dict_depth-425"><a href="#dict_depth-425"><span class="linenos">425</span></a><span class="sd"> &gt;&gt;&gt; dict_depth(None)</span>
</span><span id="dict_depth-418"><a href="#dict_depth-418"><span class="linenos">418</span></a><span class="sd"> 0</span> </span><span id="dict_depth-426"><a href="#dict_depth-426"><span class="linenos">426</span></a><span class="sd"> 0</span>
</span><span id="dict_depth-419"><a href="#dict_depth-419"><span class="linenos">419</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({})</span> </span><span id="dict_depth-427"><a href="#dict_depth-427"><span class="linenos">427</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({})</span>
</span><span id="dict_depth-420"><a href="#dict_depth-420"><span class="linenos">420</span></a><span class="sd"> 1</span> </span><span id="dict_depth-428"><a href="#dict_depth-428"><span class="linenos">428</span></a><span class="sd"> 1</span>
</span><span id="dict_depth-421"><a href="#dict_depth-421"><span class="linenos">421</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({&quot;a&quot;: &quot;b&quot;})</span> </span><span id="dict_depth-429"><a href="#dict_depth-429"><span class="linenos">429</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({&quot;a&quot;: &quot;b&quot;})</span>
</span><span id="dict_depth-422"><a href="#dict_depth-422"><span class="linenos">422</span></a><span class="sd"> 1</span> </span><span id="dict_depth-430"><a href="#dict_depth-430"><span class="linenos">430</span></a><span class="sd"> 1</span>
</span><span id="dict_depth-423"><a href="#dict_depth-423"><span class="linenos">423</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({&quot;a&quot;: {}})</span> </span><span id="dict_depth-431"><a href="#dict_depth-431"><span class="linenos">431</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({&quot;a&quot;: {}})</span>
</span><span id="dict_depth-424"><a href="#dict_depth-424"><span class="linenos">424</span></a><span class="sd"> 2</span> </span><span id="dict_depth-432"><a href="#dict_depth-432"><span class="linenos">432</span></a><span class="sd"> 2</span>
</span><span id="dict_depth-425"><a href="#dict_depth-425"><span class="linenos">425</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({&quot;a&quot;: {&quot;b&quot;: {}}})</span> </span><span id="dict_depth-433"><a href="#dict_depth-433"><span class="linenos">433</span></a><span class="sd"> &gt;&gt;&gt; dict_depth({&quot;a&quot;: {&quot;b&quot;: {}}})</span>
</span><span id="dict_depth-426"><a href="#dict_depth-426"><span class="linenos">426</span></a><span class="sd"> 3</span> </span><span id="dict_depth-434"><a href="#dict_depth-434"><span class="linenos">434</span></a><span class="sd"> 3</span>
</span><span id="dict_depth-427"><a href="#dict_depth-427"><span class="linenos">427</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="dict_depth-435"><a href="#dict_depth-435"><span class="linenos">435</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="dict_depth-428"><a href="#dict_depth-428"><span class="linenos">428</span></a> <span class="k">try</span><span class="p">:</span> </span><span id="dict_depth-436"><a href="#dict_depth-436"><span class="linenos">436</span></a> <span class="k">try</span><span class="p">:</span>
</span><span id="dict_depth-429"><a href="#dict_depth-429"><span class="linenos">429</span></a> <span class="k">return</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">dict_depth</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">values</span><span class="p">())))</span> </span><span id="dict_depth-437"><a href="#dict_depth-437"><span class="linenos">437</span></a> <span class="k">return</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">dict_depth</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">values</span><span class="p">())))</span>
</span><span id="dict_depth-430"><a href="#dict_depth-430"><span class="linenos">430</span></a> <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span> </span><span id="dict_depth-438"><a href="#dict_depth-438"><span class="linenos">438</span></a> <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
</span><span id="dict_depth-431"><a href="#dict_depth-431"><span class="linenos">431</span></a> <span class="c1"># d doesn&#39;t have attribute &quot;values&quot;</span> </span><span id="dict_depth-439"><a href="#dict_depth-439"><span class="linenos">439</span></a> <span class="c1"># d doesn&#39;t have attribute &quot;values&quot;</span>
</span><span id="dict_depth-432"><a href="#dict_depth-432"><span class="linenos">432</span></a> <span class="k">return</span> <span class="mi">0</span> </span><span id="dict_depth-440"><a href="#dict_depth-440"><span class="linenos">440</span></a> <span class="k">return</span> <span class="mi">0</span>
</span><span id="dict_depth-433"><a href="#dict_depth-433"><span class="linenos">433</span></a> <span class="k">except</span> <span class="ne">StopIteration</span><span class="p">:</span> </span><span id="dict_depth-441"><a href="#dict_depth-441"><span class="linenos">441</span></a> <span class="k">except</span> <span class="ne">StopIteration</span><span class="p">:</span>
</span><span id="dict_depth-434"><a href="#dict_depth-434"><span class="linenos">434</span></a> <span class="c1"># d.values() returns an empty sequence</span> </span><span id="dict_depth-442"><a href="#dict_depth-442"><span class="linenos">442</span></a> <span class="c1"># d.values() returns an empty sequence</span>
</span><span id="dict_depth-435"><a href="#dict_depth-435"><span class="linenos">435</span></a> <span class="k">return</span> <span class="mi">1</span> </span><span id="dict_depth-443"><a href="#dict_depth-443"><span class="linenos">443</span></a> <span class="k">return</span> <span class="mi">1</span>
</span></pre></div> </span></pre></div>
@ -1659,9 +1693,9 @@ type <code>str</code> and <code>bytes</code> are not regarded as iterables.</p>
</div> </div>
<a class="headerlink" href="#first"></a> <a class="headerlink" href="#first"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="first-438"><a href="#first-438"><span class="linenos">438</span></a><span class="k">def</span> <span class="nf">first</span><span class="p">(</span><span class="n">it</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">T</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">T</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="first-446"><a href="#first-446"><span class="linenos">446</span></a><span class="k">def</span> <span class="nf">first</span><span class="p">(</span><span class="n">it</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">T</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">T</span><span class="p">:</span>
</span><span id="first-439"><a href="#first-439"><span class="linenos">439</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns the first element from an iterable (useful for sets).&quot;&quot;&quot;</span> </span><span id="first-447"><a href="#first-447"><span class="linenos">447</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns the first element from an iterable (useful for sets).&quot;&quot;&quot;</span>
</span><span id="first-440"><a href="#first-440"><span class="linenos">440</span></a> <span class="k">return</span> <span class="nb">next</span><span class="p">(</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">it</span><span class="p">)</span> </span><span id="first-448"><a href="#first-448"><span class="linenos">448</span></a> <span class="k">return</span> <span class="nb">next</span><span class="p">(</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">it</span><span class="p">)</span>
</span></pre></div> </span></pre></div>
@ -1681,31 +1715,31 @@ type <code>str</code> and <code>bytes</code> are not regarded as iterables.</p>
</div> </div>
<a class="headerlink" href="#merge_ranges"></a> <a class="headerlink" href="#merge_ranges"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="merge_ranges-443"><a href="#merge_ranges-443"><span class="linenos">443</span></a><span class="k">def</span> <span class="nf">merge_ranges</span><span class="p">(</span><span class="n">ranges</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Tuple</span><span class="p">[</span><span class="n">A</span><span class="p">,</span> <span class="n">A</span><span class="p">]])</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Tuple</span><span class="p">[</span><span class="n">A</span><span class="p">,</span> <span class="n">A</span><span class="p">]]:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="merge_ranges-451"><a href="#merge_ranges-451"><span class="linenos">451</span></a><span class="k">def</span> <span class="nf">merge_ranges</span><span class="p">(</span><span class="n">ranges</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Tuple</span><span class="p">[</span><span class="n">A</span><span class="p">,</span> <span class="n">A</span><span class="p">]])</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Tuple</span><span class="p">[</span><span class="n">A</span><span class="p">,</span> <span class="n">A</span><span class="p">]]:</span>
</span><span id="merge_ranges-444"><a href="#merge_ranges-444"><span class="linenos">444</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="merge_ranges-452"><a href="#merge_ranges-452"><span class="linenos">452</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="merge_ranges-445"><a href="#merge_ranges-445"><span class="linenos">445</span></a><span class="sd"> Merges a sequence of ranges, represented as tuples (low, high) whose values</span> </span><span id="merge_ranges-453"><a href="#merge_ranges-453"><span class="linenos">453</span></a><span class="sd"> Merges a sequence of ranges, represented as tuples (low, high) whose values</span>
</span><span id="merge_ranges-446"><a href="#merge_ranges-446"><span class="linenos">446</span></a><span class="sd"> belong to some totally-ordered set.</span> </span><span id="merge_ranges-454"><a href="#merge_ranges-454"><span class="linenos">454</span></a><span class="sd"> belong to some totally-ordered set.</span>
</span><span id="merge_ranges-447"><a href="#merge_ranges-447"><span class="linenos">447</span></a> </span><span id="merge_ranges-455"><a href="#merge_ranges-455"><span class="linenos">455</span></a>
</span><span id="merge_ranges-448"><a href="#merge_ranges-448"><span class="linenos">448</span></a><span class="sd"> Example:</span> </span><span id="merge_ranges-456"><a href="#merge_ranges-456"><span class="linenos">456</span></a><span class="sd"> Example:</span>
</span><span id="merge_ranges-449"><a href="#merge_ranges-449"><span class="linenos">449</span></a><span class="sd"> &gt;&gt;&gt; merge_ranges([(1, 3), (2, 6)])</span> </span><span id="merge_ranges-457"><a href="#merge_ranges-457"><span class="linenos">457</span></a><span class="sd"> &gt;&gt;&gt; merge_ranges([(1, 3), (2, 6)])</span>
</span><span id="merge_ranges-450"><a href="#merge_ranges-450"><span class="linenos">450</span></a><span class="sd"> [(1, 6)]</span> </span><span id="merge_ranges-458"><a href="#merge_ranges-458"><span class="linenos">458</span></a><span class="sd"> [(1, 6)]</span>
</span><span id="merge_ranges-451"><a href="#merge_ranges-451"><span class="linenos">451</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="merge_ranges-459"><a href="#merge_ranges-459"><span class="linenos">459</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="merge_ranges-452"><a href="#merge_ranges-452"><span class="linenos">452</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">ranges</span><span class="p">:</span> </span><span id="merge_ranges-460"><a href="#merge_ranges-460"><span class="linenos">460</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">ranges</span><span class="p">:</span>
</span><span id="merge_ranges-453"><a href="#merge_ranges-453"><span class="linenos">453</span></a> <span class="k">return</span> <span class="p">[]</span> </span><span id="merge_ranges-461"><a href="#merge_ranges-461"><span class="linenos">461</span></a> <span class="k">return</span> <span class="p">[]</span>
</span><span id="merge_ranges-454"><a href="#merge_ranges-454"><span class="linenos">454</span></a> </span><span id="merge_ranges-462"><a href="#merge_ranges-462"><span class="linenos">462</span></a>
</span><span id="merge_ranges-455"><a href="#merge_ranges-455"><span class="linenos">455</span></a> <span class="n">ranges</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">ranges</span><span class="p">)</span> </span><span id="merge_ranges-463"><a href="#merge_ranges-463"><span class="linenos">463</span></a> <span class="n">ranges</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">ranges</span><span class="p">)</span>
</span><span id="merge_ranges-456"><a href="#merge_ranges-456"><span class="linenos">456</span></a> </span><span id="merge_ranges-464"><a href="#merge_ranges-464"><span class="linenos">464</span></a>
</span><span id="merge_ranges-457"><a href="#merge_ranges-457"><span class="linenos">457</span></a> <span class="n">merged</span> <span class="o">=</span> <span class="p">[</span><span class="n">ranges</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> </span><span id="merge_ranges-465"><a href="#merge_ranges-465"><span class="linenos">465</span></a> <span class="n">merged</span> <span class="o">=</span> <span class="p">[</span><span class="n">ranges</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span>
</span><span id="merge_ranges-458"><a href="#merge_ranges-458"><span class="linenos">458</span></a>
</span><span id="merge_ranges-459"><a href="#merge_ranges-459"><span class="linenos">459</span></a> <span class="k">for</span> <span class="n">start</span><span class="p">,</span> <span class="n">end</span> <span class="ow">in</span> <span class="n">ranges</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
</span><span id="merge_ranges-460"><a href="#merge_ranges-460"><span class="linenos">460</span></a> <span class="n">last_start</span><span class="p">,</span> <span class="n">last_end</span> <span class="o">=</span> <span class="n">merged</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span><span id="merge_ranges-461"><a href="#merge_ranges-461"><span class="linenos">461</span></a>
</span><span id="merge_ranges-462"><a href="#merge_ranges-462"><span class="linenos">462</span></a> <span class="k">if</span> <span class="n">start</span> <span class="o">&lt;=</span> <span class="n">last_end</span><span class="p">:</span>
</span><span id="merge_ranges-463"><a href="#merge_ranges-463"><span class="linenos">463</span></a> <span class="n">merged</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">last_start</span><span class="p">,</span> <span class="nb">max</span><span class="p">(</span><span class="n">last_end</span><span class="p">,</span> <span class="n">end</span><span class="p">))</span>
</span><span id="merge_ranges-464"><a href="#merge_ranges-464"><span class="linenos">464</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="merge_ranges-465"><a href="#merge_ranges-465"><span class="linenos">465</span></a> <span class="n">merged</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">))</span>
</span><span id="merge_ranges-466"><a href="#merge_ranges-466"><span class="linenos">466</span></a> </span><span id="merge_ranges-466"><a href="#merge_ranges-466"><span class="linenos">466</span></a>
</span><span id="merge_ranges-467"><a href="#merge_ranges-467"><span class="linenos">467</span></a> <span class="k">return</span> <span class="n">merged</span> </span><span id="merge_ranges-467"><a href="#merge_ranges-467"><span class="linenos">467</span></a> <span class="k">for</span> <span class="n">start</span><span class="p">,</span> <span class="n">end</span> <span class="ow">in</span> <span class="n">ranges</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
</span><span id="merge_ranges-468"><a href="#merge_ranges-468"><span class="linenos">468</span></a> <span class="n">last_start</span><span class="p">,</span> <span class="n">last_end</span> <span class="o">=</span> <span class="n">merged</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span><span id="merge_ranges-469"><a href="#merge_ranges-469"><span class="linenos">469</span></a>
</span><span id="merge_ranges-470"><a href="#merge_ranges-470"><span class="linenos">470</span></a> <span class="k">if</span> <span class="n">start</span> <span class="o">&lt;=</span> <span class="n">last_end</span><span class="p">:</span>
</span><span id="merge_ranges-471"><a href="#merge_ranges-471"><span class="linenos">471</span></a> <span class="n">merged</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">last_start</span><span class="p">,</span> <span class="nb">max</span><span class="p">(</span><span class="n">last_end</span><span class="p">,</span> <span class="n">end</span><span class="p">))</span>
</span><span id="merge_ranges-472"><a href="#merge_ranges-472"><span class="linenos">472</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="merge_ranges-473"><a href="#merge_ranges-473"><span class="linenos">473</span></a> <span class="n">merged</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">))</span>
</span><span id="merge_ranges-474"><a href="#merge_ranges-474"><span class="linenos">474</span></a>
</span><span id="merge_ranges-475"><a href="#merge_ranges-475"><span class="linenos">475</span></a> <span class="k">return</span> <span class="n">merged</span>
</span></pre></div> </span></pre></div>
@ -1736,12 +1770,12 @@ belong to some totally-ordered set.</p>
</div> </div>
<a class="headerlink" href="#is_iso_date"></a> <a class="headerlink" href="#is_iso_date"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="is_iso_date-470"><a href="#is_iso_date-470"><span class="linenos">470</span></a><span class="k">def</span> <span class="nf">is_iso_date</span><span class="p">(</span><span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="is_iso_date-478"><a href="#is_iso_date-478"><span class="linenos">478</span></a><span class="k">def</span> <span class="nf">is_iso_date</span><span class="p">(</span><span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="is_iso_date-471"><a href="#is_iso_date-471"><span class="linenos">471</span></a> <span class="k">try</span><span class="p">:</span> </span><span id="is_iso_date-479"><a href="#is_iso_date-479"><span class="linenos">479</span></a> <span class="k">try</span><span class="p">:</span>
</span><span id="is_iso_date-472"><a href="#is_iso_date-472"><span class="linenos">472</span></a> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">text</span><span class="p">)</span> </span><span id="is_iso_date-480"><a href="#is_iso_date-480"><span class="linenos">480</span></a> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
</span><span id="is_iso_date-473"><a href="#is_iso_date-473"><span class="linenos">473</span></a> <span class="k">return</span> <span class="kc">True</span> </span><span id="is_iso_date-481"><a href="#is_iso_date-481"><span class="linenos">481</span></a> <span class="k">return</span> <span class="kc">True</span>
</span><span id="is_iso_date-474"><a href="#is_iso_date-474"><span class="linenos">474</span></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> </span><span id="is_iso_date-482"><a href="#is_iso_date-482"><span class="linenos">482</span></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
</span><span id="is_iso_date-475"><a href="#is_iso_date-475"><span class="linenos">475</span></a> <span class="k">return</span> <span class="kc">False</span> </span><span id="is_iso_date-483"><a href="#is_iso_date-483"><span class="linenos">483</span></a> <span class="k">return</span> <span class="kc">False</span>
</span></pre></div> </span></pre></div>
@ -1759,12 +1793,12 @@ belong to some totally-ordered set.</p>
</div> </div>
<a class="headerlink" href="#is_iso_datetime"></a> <a class="headerlink" href="#is_iso_datetime"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="is_iso_datetime-478"><a href="#is_iso_datetime-478"><span class="linenos">478</span></a><span class="k">def</span> <span class="nf">is_iso_datetime</span><span class="p">(</span><span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="is_iso_datetime-486"><a href="#is_iso_datetime-486"><span class="linenos">486</span></a><span class="k">def</span> <span class="nf">is_iso_datetime</span><span class="p">(</span><span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="is_iso_datetime-479"><a href="#is_iso_datetime-479"><span class="linenos">479</span></a> <span class="k">try</span><span class="p">:</span> </span><span id="is_iso_datetime-487"><a href="#is_iso_datetime-487"><span class="linenos">487</span></a> <span class="k">try</span><span class="p">:</span>
</span><span id="is_iso_datetime-480"><a href="#is_iso_datetime-480"><span class="linenos">480</span></a> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">text</span><span class="p">)</span> </span><span id="is_iso_datetime-488"><a href="#is_iso_datetime-488"><span class="linenos">488</span></a> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
</span><span id="is_iso_datetime-481"><a href="#is_iso_datetime-481"><span class="linenos">481</span></a> <span class="k">return</span> <span class="kc">True</span> </span><span id="is_iso_datetime-489"><a href="#is_iso_datetime-489"><span class="linenos">489</span></a> <span class="k">return</span> <span class="kc">True</span>
</span><span id="is_iso_datetime-482"><a href="#is_iso_datetime-482"><span class="linenos">482</span></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> </span><span id="is_iso_datetime-490"><a href="#is_iso_datetime-490"><span class="linenos">490</span></a> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
</span><span id="is_iso_datetime-483"><a href="#is_iso_datetime-483"><span class="linenos">483</span></a> <span class="k">return</span> <span class="kc">False</span> </span><span id="is_iso_datetime-491"><a href="#is_iso_datetime-491"><span class="linenos">491</span></a> <span class="k">return</span> <span class="kc">False</span>
</span></pre></div> </span></pre></div>
@ -1774,7 +1808,7 @@ belong to some totally-ordered set.</p>
<section id="DATE_UNITS"> <section id="DATE_UNITS">
<div class="attr variable"> <div class="attr variable">
<span class="name">DATE_UNITS</span> = <span class="name">DATE_UNITS</span> =
<span class="default_value">{&#39;year_month&#39;, &#39;quarter&#39;, &#39;day&#39;, &#39;year&#39;, &#39;week&#39;, &#39;month&#39;}</span> <span class="default_value">{&#39;year_month&#39;, &#39;quarter&#39;, &#39;day&#39;, &#39;week&#39;, &#39;year&#39;, &#39;month&#39;}</span>
</div> </div>
@ -1794,8 +1828,8 @@ belong to some totally-ordered set.</p>
</div> </div>
<a class="headerlink" href="#is_date_unit"></a> <a class="headerlink" href="#is_date_unit"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="is_date_unit-490"><a href="#is_date_unit-490"><span class="linenos">490</span></a><span class="k">def</span> <span class="nf">is_date_unit</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="is_date_unit-498"><a href="#is_date_unit-498"><span class="linenos">498</span></a><span class="k">def</span> <span class="nf">is_date_unit</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span><span id="is_date_unit-491"><a href="#is_date_unit-491"><span class="linenos">491</span></a> <span class="k">return</span> <span class="n">expression</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">in</span> <span class="n">DATE_UNITS</span> </span><span id="is_date_unit-499"><a href="#is_date_unit-499"><span class="linenos">499</span></a> <span class="k">return</span> <span class="n">expression</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">in</span> <span class="n">DATE_UNITS</span>
</span></pre></div> </span></pre></div>

View file

@ -48,17 +48,14 @@
</ul> </ul>
</li> </li>
<li>
<a class="variable" href="#JSONPathNode">JSONPathNode</a>
</li>
<li> <li>
<a class="function" href="#parse">parse</a> <a class="function" href="#parse">parse</a>
</li> </li>
<li> <li>
<a class="variable" href="#MAPPING">MAPPING</a> <a class="variable" href="#JSON_PATH_PART_TRANSFORMS">JSON_PATH_PART_TRANSFORMS</a>
</li> </li>
<li> <li>
<a class="function" href="#generate">generate</a> <a class="variable" href="#ALL_JSON_PATH_PARTS">ALL_JSON_PATH_PARTS</a>
</li> </li>
</ul> </ul>
@ -87,8 +84,8 @@
</span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a> </span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a>
</span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span> </span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a> </span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a>
</span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="kn">from</span> <span class="nn">sqlglot.errors</span> <span class="kn">import</span> <span class="n">ParseError</span> </span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="kn">import</span> <span class="nn">sqlglot.expressions</span> <span class="k">as</span> <span class="nn">exp</span>
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a><span class="kn">from</span> <span class="nn">sqlglot.expressions</span> <span class="kn">import</span> <span class="n">SAFE_IDENTIFIER_RE</span> </span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a><span class="kn">from</span> <span class="nn">sqlglot.errors</span> <span class="kn">import</span> <span class="n">ParseError</span>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="kn">from</span> <span class="nn">sqlglot.tokens</span> <span class="kn">import</span> <span class="n">Token</span><span class="p">,</span> <span class="n">Tokenizer</span><span class="p">,</span> <span class="n">TokenType</span> </span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="kn">from</span> <span class="nn">sqlglot.tokens</span> <span class="kn">import</span> <span class="n">Token</span><span class="p">,</span> <span class="n">Tokenizer</span><span class="p">,</span> <span class="n">TokenType</span>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a> </span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">TYPE_CHECKING</span><span class="p">:</span> </span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">TYPE_CHECKING</span><span class="p">:</span>
@ -121,183 +118,165 @@
</span><span id="L-36"><a href="#L-36"><span class="linenos"> 36</span></a> <span class="n">STRING_ESCAPES</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;</span><span class="se">\\</span><span class="s2">&quot;</span><span class="p">]</span> </span><span id="L-36"><a href="#L-36"><span class="linenos"> 36</span></a> <span class="n">STRING_ESCAPES</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;</span><span class="se">\\</span><span class="s2">&quot;</span><span class="p">]</span>
</span><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a> </span><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a>
</span><span id="L-38"><a href="#L-38"><span class="linenos"> 38</span></a> </span><span id="L-38"><a href="#L-38"><span class="linenos"> 38</span></a>
</span><span id="L-39"><a href="#L-39"><span class="linenos"> 39</span></a><span class="n">JSONPathNode</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">]</span> </span><span id="L-39"><a href="#L-39"><span class="linenos"> 39</span></a><span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPath</span><span class="p">:</span>
</span><span id="L-40"><a href="#L-40"><span class="linenos"> 40</span></a> </span><span id="L-40"><a href="#L-40"><span class="linenos"> 40</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Takes in a JSON path string and parses it into a JSONPath expression.&quot;&quot;&quot;</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a> </span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a> <span class="n">tokens</span> <span class="o">=</span> <span class="n">JSONPathTokenizer</span><span class="p">()</span><span class="o">.</span><span class="n">tokenize</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a><span class="k">def</span> <span class="nf">_node</span><span class="p">(</span><span class="n">kind</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">JSONPathNode</span><span class="p">:</span> </span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a> <span class="n">size</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">tokens</span><span class="p">)</span>
</span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a> <span class="n">node</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;kind&quot;</span><span class="p">:</span> <span class="n">kind</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">}</span> </span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a>
</span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a> </span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a> <span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> </span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a>
</span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a> <span class="n">node</span><span class="p">[</span><span class="s2">&quot;value&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> </span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a> <span class="k">def</span> <span class="nf">_curr</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">TokenType</span><span class="p">]:</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a> </span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a> <span class="k">return</span> <span class="n">tokens</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">token_type</span> <span class="k">if</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">size</span> <span class="k">else</span> <span class="kc">None</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> <span class="k">return</span> <span class="n">node</span> </span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a>
</span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a> </span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a> <span class="k">def</span> <span class="nf">_prev</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">Token</span><span class="p">:</span>
</span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a> </span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a> <span class="k">return</span> <span class="n">tokens</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a><span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">JSONPathNode</span><span class="p">]:</span> </span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a>
</span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Takes in a JSONPath string and converts into a list of nodes.&quot;&quot;&quot;</span> </span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a> <span class="k">def</span> <span class="nf">_advance</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">Token</span><span class="p">:</span>
</span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a> <span class="n">tokens</span> <span class="o">=</span> <span class="n">JSONPathTokenizer</span><span class="p">()</span><span class="o">.</span><span class="n">tokenize</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> </span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a> <span class="k">nonlocal</span> <span class="n">i</span>
</span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a> <span class="n">size</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">tokens</span><span class="p">)</span> </span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a> <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
</span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a> </span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a> <span class="k">return</span> <span class="n">_prev</span><span class="p">()</span>
</span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span> </span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a>
</span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a> </span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a> <span class="k">def</span> <span class="nf">_error</span><span class="p">(</span><span class="n">msg</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a> <span class="k">def</span> <span class="nf">_curr</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">TokenType</span><span class="p">]:</span> </span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a> <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">msg</span><span class="si">}</span><span class="s2"> at index </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">path</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a> <span class="k">return</span> <span class="n">tokens</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">token_type</span> <span class="k">if</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">size</span> <span class="k">else</span> <span class="kc">None</span> </span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a>
</span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a> </span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a> <span class="nd">@t</span><span class="o">.</span><span class="n">overload</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a> <span class="k">def</span> <span class="nf">_prev</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">Token</span><span class="p">:</span> </span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a> <span class="k">def</span> <span class="nf">_match</span><span class="p">(</span><span class="n">token_type</span><span class="p">:</span> <span class="n">TokenType</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="p">:</span> <span class="n">Lit</span><span class="p">[</span><span class="kc">True</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Token</span><span class="p">:</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a> <span class="k">return</span> <span class="n">tokens</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> </span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a> <span class="k">pass</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a> </span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a>
</span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a> <span class="k">def</span> <span class="nf">_advance</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">Token</span><span class="p">:</span> </span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a> <span class="nd">@t</span><span class="o">.</span><span class="n">overload</span>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a> <span class="k">nonlocal</span> <span class="n">i</span> </span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a> <span class="k">def</span> <span class="nf">_match</span><span class="p">(</span><span class="n">token_type</span><span class="p">:</span> <span class="n">TokenType</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="p">:</span> <span class="n">Lit</span><span class="p">[</span><span class="kc">False</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">Token</span><span class="p">]:</span>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a> <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span> </span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a> <span class="k">pass</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a> <span class="k">return</span> <span class="n">_prev</span><span class="p">()</span> </span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a>
</span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a> </span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a> <span class="k">def</span> <span class="nf">_match</span><span class="p">(</span><span class="n">token_type</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> <span class="k">def</span> <span class="nf">_error</span><span class="p">(</span><span class="n">msg</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span> </span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> <span class="k">if</span> <span class="n">_curr</span><span class="p">()</span> <span class="o">==</span> <span class="n">token_type</span><span class="p">:</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">msg</span><span class="si">}</span><span class="s2"> at index </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">path</span><span class="si">}</span><span class="s2">&quot;</span> </span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> <span class="k">return</span> <span class="n">_advance</span><span class="p">()</span>
</span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a> </span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a> <span class="k">if</span> <span class="n">raise_unmatched</span><span class="p">:</span>
</span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="nd">@t</span><span class="o">.</span><span class="n">overload</span> </span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Expected </span><span class="si">{</span><span class="n">token_type</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">))</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="k">def</span> <span class="nf">_match</span><span class="p">(</span><span class="n">token_type</span><span class="p">:</span> <span class="n">TokenType</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="p">:</span> <span class="n">Lit</span><span class="p">[</span><span class="kc">True</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Token</span><span class="p">:</span> </span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="k">return</span> <span class="kc">None</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a> <span class="k">pass</span> </span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a>
</span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a> </span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a> <span class="k">def</span> <span class="nf">_parse_literal</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">:</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a> <span class="nd">@t</span><span class="o">.</span><span class="n">overload</span> </span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a> <span class="n">token</span> <span class="o">=</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STRING</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">IDENTIFIER</span><span class="p">)</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a> <span class="k">def</span> <span class="nf">_match</span><span class="p">(</span><span class="n">token_type</span><span class="p">:</span> <span class="n">TokenType</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="p">:</span> <span class="n">Lit</span><span class="p">[</span><span class="kc">False</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">Token</span><span class="p">]:</span> </span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a> <span class="k">if</span> <span class="n">token</span><span class="p">:</span>
</span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a> <span class="k">pass</span> </span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a> <span class="k">return</span> <span class="n">token</span><span class="o">.</span><span class="n">text</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> </span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STAR</span><span class="p">):</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a> <span class="k">def</span> <span class="nf">_match</span><span class="p">(</span><span class="n">token_type</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span> </span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathWildcard</span><span class="p">()</span>
</span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a> <span class="k">if</span> <span class="n">_curr</span><span class="p">()</span> <span class="o">==</span> <span class="n">token_type</span><span class="p">:</span> </span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">PLACEHOLDER</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">L_PAREN</span><span class="p">):</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> <span class="k">return</span> <span class="n">_advance</span><span class="p">()</span> </span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> <span class="n">script</span> <span class="o">=</span> <span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span> <span class="o">==</span> <span class="s2">&quot;(&quot;</span>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a> <span class="k">if</span> <span class="n">raise_unmatched</span><span class="p">:</span> </span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a> <span class="n">start</span> <span class="o">=</span> <span class="n">i</span>
</span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Expected </span><span class="si">{</span><span class="n">token_type</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">))</span> </span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a>
</span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a> <span class="k">return</span> <span class="kc">None</span> </span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a> <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
</span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a> </span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">L_BRACKET</span><span class="p">):</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> <span class="k">def</span> <span class="nf">_parse_literal</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">:</span> </span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> <span class="n">_parse_bracket</span><span class="p">()</span> <span class="c1"># nested call which we can throw away</span>
</span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> <span class="n">token</span> <span class="o">=</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STRING</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">IDENTIFIER</span><span class="p">)</span> </span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> <span class="k">if</span> <span class="n">_curr</span><span class="p">()</span> <span class="ow">in</span> <span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">R_BRACKET</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="k">if</span> <span class="n">token</span><span class="p">:</span> </span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="k">break</span>
</span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a> <span class="k">return</span> <span class="n">token</span><span class="o">.</span><span class="n">text</span> </span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a> <span class="n">_advance</span><span class="p">()</span>
</span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STAR</span><span class="p">):</span> </span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="k">return</span> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;wildcard&quot;</span><span class="p">)</span> </span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="n">expr_type</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathScript</span> <span class="k">if</span> <span class="n">script</span> <span class="k">else</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathFilter</span>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">PLACEHOLDER</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">L_PAREN</span><span class="p">):</span> </span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a> <span class="k">return</span> <span class="n">expr_type</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">path</span><span class="p">[</span><span class="n">tokens</span><span class="p">[</span><span class="n">start</span><span class="p">]</span><span class="o">.</span><span class="n">start</span> <span class="p">:</span> <span class="n">tokens</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">end</span><span class="p">])</span>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a> <span class="n">script</span> <span class="o">=</span> <span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span> <span class="o">==</span> <span class="s2">&quot;(&quot;</span> </span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a>
</span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a> <span class="n">start</span> <span class="o">=</span> <span class="n">i</span> </span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a> <span class="n">number</span> <span class="o">=</span> <span class="s2">&quot;-&quot;</span> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">DASH</span><span class="p">)</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
</span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a> </span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a>
</span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a> <span class="k">while</span> <span class="kc">True</span><span class="p">:</span> </span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a> <span class="n">token</span> <span class="o">=</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">NUMBER</span><span class="p">)</span>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">L_BRACKET</span><span class="p">):</span> </span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a> <span class="k">if</span> <span class="n">token</span><span class="p">:</span>
</span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a> <span class="n">_parse_bracket</span><span class="p">()</span> <span class="c1"># nested call which we can throw away</span> </span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a> <span class="n">number</span> <span class="o">+=</span> <span class="n">token</span><span class="o">.</span><span class="n">text</span>
</span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a> <span class="k">if</span> <span class="n">_curr</span><span class="p">()</span> <span class="ow">in</span> <span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">R_BRACKET</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span> </span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a>
</span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a> <span class="k">break</span> </span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a> <span class="k">if</span> <span class="n">number</span><span class="p">:</span>
</span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a> <span class="n">_advance</span><span class="p">()</span> </span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a> <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">number</span><span class="p">)</span>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a> <span class="k">return</span> <span class="n">_node</span><span class="p">(</span> </span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a>
</span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a> <span class="s2">&quot;script&quot;</span> <span class="k">if</span> <span class="n">script</span> <span class="k">else</span> <span class="s2">&quot;filter&quot;</span><span class="p">,</span> <span class="n">path</span><span class="p">[</span><span class="n">tokens</span><span class="p">[</span><span class="n">start</span><span class="p">]</span><span class="o">.</span><span class="n">start</span> <span class="p">:</span> <span class="n">tokens</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">end</span><span class="p">]</span> </span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a> <span class="p">)</span> </span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a>
</span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a> </span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a> <span class="k">def</span> <span class="nf">_parse_slice</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">:</span>
</span><span id="L-107"><a href="#L-107"><span class="linenos">107</span></a> <span class="n">number</span> <span class="o">=</span> <span class="s2">&quot;-&quot;</span> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">DASH</span><span class="p">)</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span> </span><span id="L-107"><a href="#L-107"><span class="linenos">107</span></a> <span class="n">start</span> <span class="o">=</span> <span class="n">_parse_literal</span><span class="p">()</span>
</span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a> </span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a> <span class="n">end</span> <span class="o">=</span> <span class="n">_parse_literal</span><span class="p">()</span> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COLON</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span>
</span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a> <span class="n">token</span> <span class="o">=</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">NUMBER</span><span class="p">)</span> </span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a> <span class="n">step</span> <span class="o">=</span> <span class="n">_parse_literal</span><span class="p">()</span> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COLON</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span>
</span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a> <span class="k">if</span> <span class="n">token</span><span class="p">:</span> </span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a>
</span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a> <span class="n">number</span> <span class="o">+=</span> <span class="n">token</span><span class="o">.</span><span class="n">text</span> </span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a> <span class="k">if</span> <span class="n">end</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">step</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a> </span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a> <span class="k">return</span> <span class="n">start</span>
</span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a> <span class="k">if</span> <span class="n">number</span><span class="p">:</span> </span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a>
</span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a> <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">number</span><span class="p">)</span> </span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathSlice</span><span class="p">(</span><span class="n">start</span><span class="o">=</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="n">end</span><span class="p">,</span> <span class="n">step</span><span class="o">=</span><span class="n">step</span><span class="p">)</span>
</span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a> <span class="k">return</span> <span class="kc">False</span> </span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a>
</span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a> </span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a> <span class="k">def</span> <span class="nf">_parse_bracket</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathPart</span><span class="p">:</span>
</span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a> <span class="k">def</span> <span class="nf">_parse_slice</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">:</span> </span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a> <span class="n">literal</span> <span class="o">=</span> <span class="n">_parse_slice</span><span class="p">()</span>
</span><span id="L-118"><a href="#L-118"><span class="linenos">118</span></a> <span class="n">start</span> <span class="o">=</span> <span class="n">_parse_literal</span><span class="p">()</span> </span><span id="L-118"><a href="#L-118"><span class="linenos">118</span></a>
</span><span id="L-119"><a href="#L-119"><span class="linenos">119</span></a> <span class="n">end</span> <span class="o">=</span> <span class="n">_parse_literal</span><span class="p">()</span> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COLON</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span> </span><span id="L-119"><a href="#L-119"><span class="linenos">119</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">literal</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">or</span> <span class="n">literal</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">False</span><span class="p">:</span>
</span><span id="L-120"><a href="#L-120"><span class="linenos">120</span></a> <span class="n">step</span> <span class="o">=</span> <span class="n">_parse_literal</span><span class="p">()</span> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COLON</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span> </span><span id="L-120"><a href="#L-120"><span class="linenos">120</span></a> <span class="n">indexes</span> <span class="o">=</span> <span class="p">[</span><span class="n">literal</span><span class="p">]</span>
</span><span id="L-121"><a href="#L-121"><span class="linenos">121</span></a> </span><span id="L-121"><a href="#L-121"><span class="linenos">121</span></a> <span class="k">while</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COMMA</span><span class="p">):</span>
</span><span id="L-122"><a href="#L-122"><span class="linenos">122</span></a> <span class="k">if</span> <span class="n">end</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">step</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> </span><span id="L-122"><a href="#L-122"><span class="linenos">122</span></a> <span class="n">literal</span> <span class="o">=</span> <span class="n">_parse_slice</span><span class="p">()</span>
</span><span id="L-123"><a href="#L-123"><span class="linenos">123</span></a> <span class="k">return</span> <span class="n">start</span> </span><span id="L-123"><a href="#L-123"><span class="linenos">123</span></a>
</span><span id="L-124"><a href="#L-124"><span class="linenos">124</span></a> <span class="k">return</span> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;slice&quot;</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="n">end</span><span class="p">,</span> <span class="n">step</span><span class="o">=</span><span class="n">step</span><span class="p">)</span> </span><span id="L-124"><a href="#L-124"><span class="linenos">124</span></a> <span class="k">if</span> <span class="n">literal</span><span class="p">:</span>
</span><span id="L-125"><a href="#L-125"><span class="linenos">125</span></a> </span><span id="L-125"><a href="#L-125"><span class="linenos">125</span></a> <span class="n">indexes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">literal</span><span class="p">)</span>
</span><span id="L-126"><a href="#L-126"><span class="linenos">126</span></a> <span class="k">def</span> <span class="nf">_parse_bracket</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">JSONPathNode</span><span class="p">:</span> </span><span id="L-126"><a href="#L-126"><span class="linenos">126</span></a>
</span><span id="L-127"><a href="#L-127"><span class="linenos">127</span></a> <span class="n">literal</span> <span class="o">=</span> <span class="n">_parse_slice</span><span class="p">()</span> </span><span id="L-127"><a href="#L-127"><span class="linenos">127</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">indexes</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
</span><span id="L-128"><a href="#L-128"><span class="linenos">128</span></a> </span><span id="L-128"><a href="#L-128"><span class="linenos">128</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">literal</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">literal</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">or</span> <span class="n">literal</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">False</span><span class="p">:</span> </span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a> <span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathPart</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathKey</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">indexes</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a> <span class="n">indexes</span> <span class="o">=</span> <span class="p">[</span><span class="n">literal</span><span class="p">]</span> </span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">literal</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathPart</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span>
</span><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a> <span class="k">while</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COMMA</span><span class="p">):</span> </span><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a> <span class="n">literal</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathScript</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathFilter</span><span class="p">)</span>
</span><span id="L-132"><a href="#L-132"><span class="linenos">132</span></a> <span class="n">literal</span> <span class="o">=</span> <span class="n">_parse_slice</span><span class="p">()</span> </span><span id="L-132"><a href="#L-132"><span class="linenos">132</span></a> <span class="p">):</span>
</span><span id="L-133"><a href="#L-133"><span class="linenos">133</span></a> </span><span id="L-133"><a href="#L-133"><span class="linenos">133</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathSelector</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">indexes</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</span><span id="L-134"><a href="#L-134"><span class="linenos">134</span></a> <span class="k">if</span> <span class="n">literal</span><span class="p">:</span> </span><span id="L-134"><a href="#L-134"><span class="linenos">134</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a> <span class="n">indexes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">literal</span><span class="p">)</span> </span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathSubscript</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">indexes</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</span><span id="L-136"><a href="#L-136"><span class="linenos">136</span></a> </span><span id="L-136"><a href="#L-136"><span class="linenos">136</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-137"><a href="#L-137"><span class="linenos">137</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">indexes</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span> </span><span id="L-137"><a href="#L-137"><span class="linenos">137</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathUnion</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="n">indexes</span><span class="p">)</span>
</span><span id="L-138"><a href="#L-138"><span class="linenos">138</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">literal</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span> </span><span id="L-138"><a href="#L-138"><span class="linenos">138</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-139"><a href="#L-139"><span class="linenos">139</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;key&quot;</span><span class="p">,</span> <span class="n">indexes</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> </span><span id="L-139"><a href="#L-139"><span class="linenos">139</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="s2">&quot;Cannot have empty segment&quot;</span><span class="p">))</span>
</span><span id="L-140"><a href="#L-140"><span class="linenos">140</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">literal</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)</span> <span class="ow">and</span> <span class="n">literal</span><span class="p">[</span><span class="s2">&quot;kind&quot;</span><span class="p">]</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;script&quot;</span><span class="p">,</span> <span class="s2">&quot;filter&quot;</span><span class="p">):</span> </span><span id="L-140"><a href="#L-140"><span class="linenos">140</span></a>
</span><span id="L-141"><a href="#L-141"><span class="linenos">141</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;selector&quot;</span><span class="p">,</span> <span class="n">indexes</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> </span><span id="L-141"><a href="#L-141"><span class="linenos">141</span></a> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">R_BRACKET</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="L-142"><a href="#L-142"><span class="linenos">142</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-142"><a href="#L-142"><span class="linenos">142</span></a>
</span><span id="L-143"><a href="#L-143"><span class="linenos">143</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;subscript&quot;</span><span class="p">,</span> <span class="n">indexes</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> </span><span id="L-143"><a href="#L-143"><span class="linenos">143</span></a> <span class="k">return</span> <span class="n">node</span>
</span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a>
</span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;union&quot;</span><span class="p">,</span> <span class="n">indexes</span><span class="p">)</span> </span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a> <span class="c1"># We canonicalize the JSON path AST so that it always starts with a</span>
</span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a> <span class="c1"># &quot;root&quot; element, so paths like &quot;field&quot; will be generated as &quot;$.field&quot;</span>
</span><span id="L-147"><a href="#L-147"><span class="linenos">147</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="s2">&quot;Cannot have empty segment&quot;</span><span class="p">))</span> </span><span id="L-147"><a href="#L-147"><span class="linenos">147</span></a> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">DOLLAR</span><span class="p">)</span>
</span><span id="L-148"><a href="#L-148"><span class="linenos">148</span></a> </span><span id="L-148"><a href="#L-148"><span class="linenos">148</span></a> <span class="n">expressions</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathPart</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathRoot</span><span class="p">()]</span>
</span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">R_BRACKET</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> </span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a>
</span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a> </span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a> <span class="k">while</span> <span class="n">_curr</span><span class="p">():</span>
</span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a> <span class="k">return</span> <span class="n">node</span> </span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">DOT</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COLON</span><span class="p">):</span>
</span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a> </span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a> <span class="n">recursive</span> <span class="o">=</span> <span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span> <span class="o">==</span> <span class="s2">&quot;..&quot;</span>
</span><span id="L-153"><a href="#L-153"><span class="linenos">153</span></a> <span class="n">nodes</span> <span class="o">=</span> <span class="p">[]</span> </span><span id="L-153"><a href="#L-153"><span class="linenos">153</span></a>
</span><span id="L-154"><a href="#L-154"><span class="linenos">154</span></a> </span><span id="L-154"><a href="#L-154"><span class="linenos">154</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">VAR</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">IDENTIFIER</span><span class="p">):</span>
</span><span id="L-155"><a href="#L-155"><span class="linenos">155</span></a> <span class="k">while</span> <span class="n">_curr</span><span class="p">():</span> </span><span id="L-155"><a href="#L-155"><span class="linenos">155</span></a> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span> <span class="o">|</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathWildcard</span><span class="p">]</span> <span class="o">=</span> <span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span>
</span><span id="L-156"><a href="#L-156"><span class="linenos">156</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">DOLLAR</span><span class="p">):</span> </span><span id="L-156"><a href="#L-156"><span class="linenos">156</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STAR</span><span class="p">):</span>
</span><span id="L-157"><a href="#L-157"><span class="linenos">157</span></a> <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_node</span><span class="p">(</span><span class="s2">&quot;root&quot;</span><span class="p">))</span> </span><span id="L-157"><a href="#L-157"><span class="linenos">157</span></a> <span class="n">value</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathWildcard</span><span class="p">()</span>
</span><span id="L-158"><a href="#L-158"><span class="linenos">158</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">DOT</span><span class="p">):</span> </span><span id="L-158"><a href="#L-158"><span class="linenos">158</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-159"><a href="#L-159"><span class="linenos">159</span></a> <span class="n">recursive</span> <span class="o">=</span> <span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span> <span class="o">==</span> <span class="s2">&quot;..&quot;</span> </span><span id="L-159"><a href="#L-159"><span class="linenos">159</span></a> <span class="n">value</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-160"><a href="#L-160"><span class="linenos">160</span></a> <span class="n">value</span> <span class="o">=</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">VAR</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STAR</span><span class="p">)</span> </span><span id="L-160"><a href="#L-160"><span class="linenos">160</span></a>
</span><span id="L-161"><a href="#L-161"><span class="linenos">161</span></a> <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span> </span><span id="L-161"><a href="#L-161"><span class="linenos">161</span></a> <span class="k">if</span> <span class="n">recursive</span><span class="p">:</span>
</span><span id="L-162"><a href="#L-162"><span class="linenos">162</span></a> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;recursive&quot;</span> <span class="k">if</span> <span class="n">recursive</span> <span class="k">else</span> <span class="s2">&quot;child&quot;</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="o">.</span><span class="n">text</span> <span class="k">if</span> <span class="n">value</span> <span class="k">else</span> <span class="kc">None</span><span class="p">)</span> </span><span id="L-162"><a href="#L-162"><span class="linenos">162</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathRecursive</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">value</span><span class="p">))</span>
</span><span id="L-163"><a href="#L-163"><span class="linenos">163</span></a> <span class="p">)</span> </span><span id="L-163"><a href="#L-163"><span class="linenos">163</span></a> <span class="k">elif</span> <span class="n">value</span><span class="p">:</span>
</span><span id="L-164"><a href="#L-164"><span class="linenos">164</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">L_BRACKET</span><span class="p">):</span> </span><span id="L-164"><a href="#L-164"><span class="linenos">164</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathKey</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">value</span><span class="p">))</span>
</span><span id="L-165"><a href="#L-165"><span class="linenos">165</span></a> <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_parse_bracket</span><span class="p">())</span> </span><span id="L-165"><a href="#L-165"><span class="linenos">165</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-166"><a href="#L-166"><span class="linenos">166</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">VAR</span><span class="p">):</span> </span><span id="L-166"><a href="#L-166"><span class="linenos">166</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="s2">&quot;Expected key name or * after DOT&quot;</span><span class="p">))</span>
</span><span id="L-167"><a href="#L-167"><span class="linenos">167</span></a> <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_node</span><span class="p">(</span><span class="s2">&quot;key&quot;</span><span class="p">,</span> <span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span><span class="p">))</span> </span><span id="L-167"><a href="#L-167"><span class="linenos">167</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">L_BRACKET</span><span class="p">):</span>
</span><span id="L-168"><a href="#L-168"><span class="linenos">168</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STAR</span><span class="p">):</span> </span><span id="L-168"><a href="#L-168"><span class="linenos">168</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_parse_bracket</span><span class="p">())</span>
</span><span id="L-169"><a href="#L-169"><span class="linenos">169</span></a> <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_node</span><span class="p">(</span><span class="s2">&quot;wildcard&quot;</span><span class="p">))</span> </span><span id="L-169"><a href="#L-169"><span class="linenos">169</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">VAR</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">IDENTIFIER</span><span class="p">):</span>
</span><span id="L-170"><a href="#L-170"><span class="linenos">170</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">PARAMETER</span><span class="p">):</span> </span><span id="L-170"><a href="#L-170"><span class="linenos">170</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathKey</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span><span class="p">))</span>
</span><span id="L-171"><a href="#L-171"><span class="linenos">171</span></a> <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_node</span><span class="p">(</span><span class="s2">&quot;current&quot;</span><span class="p">))</span> </span><span id="L-171"><a href="#L-171"><span class="linenos">171</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STAR</span><span class="p">):</span>
</span><span id="L-172"><a href="#L-172"><span class="linenos">172</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-172"><a href="#L-172"><span class="linenos">172</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathWildcard</span><span class="p">())</span>
</span><span id="L-173"><a href="#L-173"><span class="linenos">173</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unexpected </span><span class="si">{</span><span class="n">tokens</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">token_type</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">))</span> </span><span id="L-173"><a href="#L-173"><span class="linenos">173</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-174"><a href="#L-174"><span class="linenos">174</span></a> </span><span id="L-174"><a href="#L-174"><span class="linenos">174</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unexpected </span><span class="si">{</span><span class="n">tokens</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">token_type</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">))</span>
</span><span id="L-175"><a href="#L-175"><span class="linenos">175</span></a> <span class="k">return</span> <span class="n">nodes</span> </span><span id="L-175"><a href="#L-175"><span class="linenos">175</span></a>
</span><span id="L-176"><a href="#L-176"><span class="linenos">176</span></a> </span><span id="L-176"><a href="#L-176"><span class="linenos">176</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPath</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="n">expressions</span><span class="p">)</span>
</span><span id="L-177"><a href="#L-177"><span class="linenos">177</span></a> </span><span id="L-177"><a href="#L-177"><span class="linenos">177</span></a>
</span><span id="L-178"><a href="#L-178"><span class="linenos">178</span></a><span class="n">MAPPING</span> <span class="o">=</span> <span class="p">{</span> </span><span id="L-178"><a href="#L-178"><span class="linenos">178</span></a>
</span><span id="L-179"><a href="#L-179"><span class="linenos">179</span></a> <span class="s2">&quot;child&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;.</span><span class="si">{</span><span class="n">n</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&quot;</span> <span class="k">if</span> <span class="n">n</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;value&quot;</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> </span><span id="L-179"><a href="#L-179"><span class="linenos">179</span></a><span class="n">JSON_PATH_PART_TRANSFORMS</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Type</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">],</span> <span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="p">{</span>
</span><span id="L-180"><a href="#L-180"><span class="linenos">180</span></a> <span class="s2">&quot;filter&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;?</span><span class="si">{</span><span class="n">n</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">,</span> </span><span id="L-180"><a href="#L-180"><span class="linenos">180</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathFilter</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;?</span><span class="si">{</span><span class="n">e</span><span class="o">.</span><span class="n">this</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">,</span>
</span><span id="L-181"><a href="#L-181"><span class="linenos">181</span></a> <span class="s2">&quot;key&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;.</span><span class="si">{</span><span class="n">n</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&quot;</span> </span><span id="L-181"><a href="#L-181"><span class="linenos">181</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathKey</span><span class="p">:</span> <span class="k">lambda</span> <span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_jsonpathkey_sql</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
</span><span id="L-182"><a href="#L-182"><span class="linenos">182</span></a> <span class="k">if</span> <span class="n">SAFE_IDENTIFIER_RE</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">n</span><span class="p">[</span><span class="s2">&quot;value&quot;</span><span class="p">])</span> </span><span id="L-182"><a href="#L-182"><span class="linenos">182</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathRecursive</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;..</span><span class="si">{</span><span class="n">e</span><span class="o">.</span><span class="n">this</span><span class="w"> </span><span class="ow">or</span><span class="w"> </span><span class="s1">&#39;&#39;</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">,</span>
</span><span id="L-183"><a href="#L-183"><span class="linenos">183</span></a> <span class="k">else</span> <span class="sa">f</span><span class="s1">&#39;[</span><span class="si">{</span><span class="n">generate</span><span class="p">([</span><span class="n">n</span><span class="p">[</span><span class="s2">&quot;value&quot;</span><span class="p">]])</span><span class="si">}</span><span class="s1">]&#39;</span><span class="p">,</span> </span><span id="L-183"><a href="#L-183"><span class="linenos">183</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathRoot</span><span class="p">:</span> <span class="k">lambda</span> <span class="o">*</span><span class="n">_</span><span class="p">:</span> <span class="s2">&quot;$&quot;</span><span class="p">,</span>
</span><span id="L-184"><a href="#L-184"><span class="linenos">184</span></a> <span class="s2">&quot;recursive&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;..</span><span class="si">{</span><span class="n">n</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&quot;</span> <span class="k">if</span> <span class="n">n</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;value&quot;</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="s2">&quot;..&quot;</span><span class="p">,</span> </span><span id="L-184"><a href="#L-184"><span class="linenos">184</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathScript</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;(</span><span class="si">{</span><span class="n">e</span><span class="o">.</span><span class="n">this</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">,</span>
</span><span id="L-185"><a href="#L-185"><span class="linenos">185</span></a> <span class="s2">&quot;root&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">:</span> <span class="s2">&quot;$&quot;</span><span class="p">,</span> </span><span id="L-185"><a href="#L-185"><span class="linenos">185</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathSelector</span><span class="p">:</span> <span class="k">lambda</span> <span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">json_path_part</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">this</span><span class="p">)</span><span class="si">}</span><span class="s2">]&quot;</span><span class="p">,</span>
</span><span id="L-186"><a href="#L-186"><span class="linenos">186</span></a> <span class="s2">&quot;script&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;(</span><span class="si">{</span><span class="n">n</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">,</span> </span><span id="L-186"><a href="#L-186"><span class="linenos">186</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathSlice</span><span class="p">:</span> <span class="k">lambda</span> <span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="s2">&quot;:&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
</span><span id="L-187"><a href="#L-187"><span class="linenos">187</span></a> <span class="s2">&quot;slice&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="s2">&quot;:&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span> </span><span id="L-187"><a href="#L-187"><span class="linenos">187</span></a> <span class="s2">&quot;&quot;</span> <span class="k">if</span> <span class="n">p</span> <span class="ow">is</span> <span class="kc">False</span> <span class="k">else</span> <span class="bp">self</span><span class="o">.</span><span class="n">json_path_part</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
</span><span id="L-188"><a href="#L-188"><span class="linenos">188</span></a> <span class="s2">&quot;&quot;</span> <span class="k">if</span> <span class="n">p</span> <span class="ow">is</span> <span class="kc">False</span> <span class="k">else</span> <span class="n">generate</span><span class="p">([</span><span class="n">p</span><span class="p">])</span> </span><span id="L-188"><a href="#L-188"><span class="linenos">188</span></a> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="p">[</span><span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;start&quot;</span><span class="p">),</span> <span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;end&quot;</span><span class="p">),</span> <span class="n">e</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;step&quot;</span><span class="p">)]</span>
</span><span id="L-189"><a href="#L-189"><span class="linenos">189</span></a> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="p">[</span><span class="n">n</span><span class="p">[</span><span class="s2">&quot;start&quot;</span><span class="p">],</span> <span class="n">n</span><span class="p">[</span><span class="s2">&quot;end&quot;</span><span class="p">],</span> <span class="n">n</span><span class="p">[</span><span class="s2">&quot;step&quot;</span><span class="p">]]</span> </span><span id="L-189"><a href="#L-189"><span class="linenos">189</span></a> <span class="k">if</span> <span class="n">p</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
</span><span id="L-190"><a href="#L-190"><span class="linenos">190</span></a> <span class="k">if</span> <span class="n">p</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> </span><span id="L-190"><a href="#L-190"><span class="linenos">190</span></a> <span class="p">),</span>
</span><span id="L-191"><a href="#L-191"><span class="linenos">191</span></a> <span class="p">),</span> </span><span id="L-191"><a href="#L-191"><span class="linenos">191</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathSubscript</span><span class="p">:</span> <span class="k">lambda</span> <span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_jsonpathsubscript_sql</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
</span><span id="L-192"><a href="#L-192"><span class="linenos">192</span></a> <span class="s2">&quot;selector&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="n">generate</span><span class="p">([</span><span class="n">n</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">]])</span><span class="si">}</span><span class="s2">]&quot;</span><span class="p">,</span> </span><span id="L-192"><a href="#L-192"><span class="linenos">192</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathUnion</span><span class="p">:</span> <span class="k">lambda</span> <span class="bp">self</span><span class="p">,</span>
</span><span id="L-193"><a href="#L-193"><span class="linenos">193</span></a> <span class="s2">&quot;subscript&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="n">generate</span><span class="p">([</span><span class="n">n</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">]])</span><span class="si">}</span><span class="s2">]&quot;</span><span class="p">,</span> </span><span id="L-193"><a href="#L-193"><span class="linenos">193</span></a> <span class="n">e</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="s1">&#39;,&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">json_path_part</span><span class="p">(</span><span class="n">p</span><span class="p">)</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="n">e</span><span class="o">.</span><span class="n">expressions</span><span class="p">)</span><span class="si">}</span><span class="s2">]&quot;</span><span class="p">,</span>
</span><span id="L-194"><a href="#L-194"><span class="linenos">194</span></a> <span class="s2">&quot;union&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="s1">&#39;,&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">generate</span><span class="p">([</span><span class="n">p</span><span class="p">])</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="n">n</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">])</span><span class="si">}</span><span class="s2">]&quot;</span><span class="p">,</span> </span><span id="L-194"><a href="#L-194"><span class="linenos">194</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathWildcard</span><span class="p">:</span> <span class="k">lambda</span> <span class="o">*</span><span class="n">_</span><span class="p">:</span> <span class="s2">&quot;*&quot;</span><span class="p">,</span>
</span><span id="L-195"><a href="#L-195"><span class="linenos">195</span></a> <span class="s2">&quot;wildcard&quot;</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">:</span> <span class="s2">&quot;*&quot;</span><span class="p">,</span> </span><span id="L-195"><a href="#L-195"><span class="linenos">195</span></a><span class="p">}</span>
</span><span id="L-196"><a href="#L-196"><span class="linenos">196</span></a><span class="p">}</span> </span><span id="L-196"><a href="#L-196"><span class="linenos">196</span></a>
</span><span id="L-197"><a href="#L-197"><span class="linenos">197</span></a> </span><span id="L-197"><a href="#L-197"><span class="linenos">197</span></a><span class="n">ALL_JSON_PATH_PARTS</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">JSON_PATH_PART_TRANSFORMS</span><span class="p">)</span>
</span><span id="L-198"><a href="#L-198"><span class="linenos">198</span></a>
</span><span id="L-199"><a href="#L-199"><span class="linenos">199</span></a><span class="k">def</span> <span class="nf">generate</span><span class="p">(</span>
</span><span id="L-200"><a href="#L-200"><span class="linenos">200</span></a> <span class="n">nodes</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">JSONPathNode</span><span class="p">],</span>
</span><span id="L-201"><a href="#L-201"><span class="linenos">201</span></a> <span class="n">mapping</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[</span><span class="n">JSONPathNode</span><span class="p">],</span> <span class="nb">str</span><span class="p">]]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-202"><a href="#L-202"><span class="linenos">202</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="L-203"><a href="#L-203"><span class="linenos">203</span></a> <span class="n">mapping</span> <span class="o">=</span> <span class="n">MAPPING</span> <span class="k">if</span> <span class="n">mapping</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">mapping</span>
</span><span id="L-204"><a href="#L-204"><span class="linenos">204</span></a> <span class="n">path</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-205"><a href="#L-205"><span class="linenos">205</span></a>
</span><span id="L-206"><a href="#L-206"><span class="linenos">206</span></a> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">nodes</span><span class="p">:</span>
</span><span id="L-207"><a href="#L-207"><span class="linenos">207</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
</span><span id="L-208"><a href="#L-208"><span class="linenos">208</span></a> <span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">mapping</span><span class="p">[</span><span class="n">node</span><span class="p">[</span><span class="s2">&quot;kind&quot;</span><span class="p">]](</span><span class="n">node</span><span class="p">))</span>
</span><span id="L-209"><a href="#L-209"><span class="linenos">209</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="L-210"><a href="#L-210"><span class="linenos">210</span></a> <span class="n">escaped</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;&quot;&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&quot;&#39;</span><span class="p">)</span>
</span><span id="L-211"><a href="#L-211"><span class="linenos">211</span></a> <span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;&quot;</span><span class="si">{</span><span class="n">escaped</span><span class="si">}</span><span class="s1">&quot;&#39;</span><span class="p">)</span>
</span><span id="L-212"><a href="#L-212"><span class="linenos">212</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-213"><a href="#L-213"><span class="linenos">213</span></a> <span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">node</span><span class="p">))</span>
</span><span id="L-214"><a href="#L-214"><span class="linenos">214</span></a>
</span><span id="L-215"><a href="#L-215"><span class="linenos">215</span></a> <span class="k">return</span> <span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></pre></div> </span></pre></div>
@ -422,207 +401,187 @@
</div> </div>
</dl> </dl>
</div> </div>
</section>
<section id="JSONPathNode">
<div class="attr variable">
<span class="name">JSONPathNode</span> =
<span class="default_value">typing.Dict[str, typing.Any]</span>
</div>
<a class="headerlink" href="#JSONPathNode"></a>
</section> </section>
<section id="parse"> <section id="parse">
<input id="parse-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="parse-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function"> <div class="attr function">
<span class="def">def</span> <span class="def">def</span>
<span class="name">parse</span><span class="signature pdoc-code condensed">(<span class="param"><span class="n">path</span><span class="p">:</span> <span class="nb">str</span></span><span class="return-annotation">) -> <span class="n">List</span><span class="p">[</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]]</span>:</span></span> <span class="name">parse</span><span class="signature pdoc-code condensed">(<span class="param"><span class="n">path</span><span class="p">:</span> <span class="nb">str</span></span><span class="return-annotation">) -> <span class="n"><a href="expressions.html#JSONPath">sqlglot.expressions.JSONPath</a></span>:</span></span>
<label class="view-source-button" for="parse-view-source"><span>View Source</span></label> <label class="view-source-button" for="parse-view-source"><span>View Source</span></label>
</div> </div>
<a class="headerlink" href="#parse"></a> <a class="headerlink" href="#parse"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="parse-52"><a href="#parse-52"><span class="linenos"> 52</span></a><span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">JSONPathNode</span><span class="p">]:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="parse-40"><a href="#parse-40"><span class="linenos"> 40</span></a><span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPath</span><span class="p">:</span>
</span><span id="parse-53"><a href="#parse-53"><span class="linenos"> 53</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Takes in a JSONPath string and converts into a list of nodes.&quot;&quot;&quot;</span> </span><span id="parse-41"><a href="#parse-41"><span class="linenos"> 41</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Takes in a JSON path string and parses it into a JSONPath expression.&quot;&quot;&quot;</span>
</span><span id="parse-54"><a href="#parse-54"><span class="linenos"> 54</span></a> <span class="n">tokens</span> <span class="o">=</span> <span class="n">JSONPathTokenizer</span><span class="p">()</span><span class="o">.</span><span class="n">tokenize</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> </span><span id="parse-42"><a href="#parse-42"><span class="linenos"> 42</span></a> <span class="n">tokens</span> <span class="o">=</span> <span class="n">JSONPathTokenizer</span><span class="p">()</span><span class="o">.</span><span class="n">tokenize</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span><span id="parse-55"><a href="#parse-55"><span class="linenos"> 55</span></a> <span class="n">size</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">tokens</span><span class="p">)</span> </span><span id="parse-43"><a href="#parse-43"><span class="linenos"> 43</span></a> <span class="n">size</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">tokens</span><span class="p">)</span>
</span><span id="parse-56"><a href="#parse-56"><span class="linenos"> 56</span></a> </span><span id="parse-44"><a href="#parse-44"><span class="linenos"> 44</span></a>
</span><span id="parse-57"><a href="#parse-57"><span class="linenos"> 57</span></a> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span> </span><span id="parse-45"><a href="#parse-45"><span class="linenos"> 45</span></a> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
</span><span id="parse-58"><a href="#parse-58"><span class="linenos"> 58</span></a> </span><span id="parse-46"><a href="#parse-46"><span class="linenos"> 46</span></a>
</span><span id="parse-59"><a href="#parse-59"><span class="linenos"> 59</span></a> <span class="k">def</span> <span class="nf">_curr</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">TokenType</span><span class="p">]:</span> </span><span id="parse-47"><a href="#parse-47"><span class="linenos"> 47</span></a> <span class="k">def</span> <span class="nf">_curr</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">TokenType</span><span class="p">]:</span>
</span><span id="parse-60"><a href="#parse-60"><span class="linenos"> 60</span></a> <span class="k">return</span> <span class="n">tokens</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">token_type</span> <span class="k">if</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">size</span> <span class="k">else</span> <span class="kc">None</span> </span><span id="parse-48"><a href="#parse-48"><span class="linenos"> 48</span></a> <span class="k">return</span> <span class="n">tokens</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">token_type</span> <span class="k">if</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">size</span> <span class="k">else</span> <span class="kc">None</span>
</span><span id="parse-61"><a href="#parse-61"><span class="linenos"> 61</span></a> </span><span id="parse-49"><a href="#parse-49"><span class="linenos"> 49</span></a>
</span><span id="parse-62"><a href="#parse-62"><span class="linenos"> 62</span></a> <span class="k">def</span> <span class="nf">_prev</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">Token</span><span class="p">:</span> </span><span id="parse-50"><a href="#parse-50"><span class="linenos"> 50</span></a> <span class="k">def</span> <span class="nf">_prev</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">Token</span><span class="p">:</span>
</span><span id="parse-63"><a href="#parse-63"><span class="linenos"> 63</span></a> <span class="k">return</span> <span class="n">tokens</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> </span><span id="parse-51"><a href="#parse-51"><span class="linenos"> 51</span></a> <span class="k">return</span> <span class="n">tokens</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
</span><span id="parse-52"><a href="#parse-52"><span class="linenos"> 52</span></a>
</span><span id="parse-53"><a href="#parse-53"><span class="linenos"> 53</span></a> <span class="k">def</span> <span class="nf">_advance</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">Token</span><span class="p">:</span>
</span><span id="parse-54"><a href="#parse-54"><span class="linenos"> 54</span></a> <span class="k">nonlocal</span> <span class="n">i</span>
</span><span id="parse-55"><a href="#parse-55"><span class="linenos"> 55</span></a> <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
</span><span id="parse-56"><a href="#parse-56"><span class="linenos"> 56</span></a> <span class="k">return</span> <span class="n">_prev</span><span class="p">()</span>
</span><span id="parse-57"><a href="#parse-57"><span class="linenos"> 57</span></a>
</span><span id="parse-58"><a href="#parse-58"><span class="linenos"> 58</span></a> <span class="k">def</span> <span class="nf">_error</span><span class="p">(</span><span class="n">msg</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="parse-59"><a href="#parse-59"><span class="linenos"> 59</span></a> <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">msg</span><span class="si">}</span><span class="s2"> at index </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">path</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span id="parse-60"><a href="#parse-60"><span class="linenos"> 60</span></a>
</span><span id="parse-61"><a href="#parse-61"><span class="linenos"> 61</span></a> <span class="nd">@t</span><span class="o">.</span><span class="n">overload</span>
</span><span id="parse-62"><a href="#parse-62"><span class="linenos"> 62</span></a> <span class="k">def</span> <span class="nf">_match</span><span class="p">(</span><span class="n">token_type</span><span class="p">:</span> <span class="n">TokenType</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="p">:</span> <span class="n">Lit</span><span class="p">[</span><span class="kc">True</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Token</span><span class="p">:</span>
</span><span id="parse-63"><a href="#parse-63"><span class="linenos"> 63</span></a> <span class="k">pass</span>
</span><span id="parse-64"><a href="#parse-64"><span class="linenos"> 64</span></a> </span><span id="parse-64"><a href="#parse-64"><span class="linenos"> 64</span></a>
</span><span id="parse-65"><a href="#parse-65"><span class="linenos"> 65</span></a> <span class="k">def</span> <span class="nf">_advance</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">Token</span><span class="p">:</span> </span><span id="parse-65"><a href="#parse-65"><span class="linenos"> 65</span></a> <span class="nd">@t</span><span class="o">.</span><span class="n">overload</span>
</span><span id="parse-66"><a href="#parse-66"><span class="linenos"> 66</span></a> <span class="k">nonlocal</span> <span class="n">i</span> </span><span id="parse-66"><a href="#parse-66"><span class="linenos"> 66</span></a> <span class="k">def</span> <span class="nf">_match</span><span class="p">(</span><span class="n">token_type</span><span class="p">:</span> <span class="n">TokenType</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="p">:</span> <span class="n">Lit</span><span class="p">[</span><span class="kc">False</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">Token</span><span class="p">]:</span>
</span><span id="parse-67"><a href="#parse-67"><span class="linenos"> 67</span></a> <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span> </span><span id="parse-67"><a href="#parse-67"><span class="linenos"> 67</span></a> <span class="k">pass</span>
</span><span id="parse-68"><a href="#parse-68"><span class="linenos"> 68</span></a> <span class="k">return</span> <span class="n">_prev</span><span class="p">()</span> </span><span id="parse-68"><a href="#parse-68"><span class="linenos"> 68</span></a>
</span><span id="parse-69"><a href="#parse-69"><span class="linenos"> 69</span></a> </span><span id="parse-69"><a href="#parse-69"><span class="linenos"> 69</span></a> <span class="k">def</span> <span class="nf">_match</span><span class="p">(</span><span class="n">token_type</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
</span><span id="parse-70"><a href="#parse-70"><span class="linenos"> 70</span></a> <span class="k">def</span> <span class="nf">_error</span><span class="p">(</span><span class="n">msg</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span> </span><span id="parse-70"><a href="#parse-70"><span class="linenos"> 70</span></a> <span class="k">if</span> <span class="n">_curr</span><span class="p">()</span> <span class="o">==</span> <span class="n">token_type</span><span class="p">:</span>
</span><span id="parse-71"><a href="#parse-71"><span class="linenos"> 71</span></a> <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">msg</span><span class="si">}</span><span class="s2"> at index </span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">path</span><span class="si">}</span><span class="s2">&quot;</span> </span><span id="parse-71"><a href="#parse-71"><span class="linenos"> 71</span></a> <span class="k">return</span> <span class="n">_advance</span><span class="p">()</span>
</span><span id="parse-72"><a href="#parse-72"><span class="linenos"> 72</span></a> </span><span id="parse-72"><a href="#parse-72"><span class="linenos"> 72</span></a> <span class="k">if</span> <span class="n">raise_unmatched</span><span class="p">:</span>
</span><span id="parse-73"><a href="#parse-73"><span class="linenos"> 73</span></a> <span class="nd">@t</span><span class="o">.</span><span class="n">overload</span> </span><span id="parse-73"><a href="#parse-73"><span class="linenos"> 73</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Expected </span><span class="si">{</span><span class="n">token_type</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">))</span>
</span><span id="parse-74"><a href="#parse-74"><span class="linenos"> 74</span></a> <span class="k">def</span> <span class="nf">_match</span><span class="p">(</span><span class="n">token_type</span><span class="p">:</span> <span class="n">TokenType</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="p">:</span> <span class="n">Lit</span><span class="p">[</span><span class="kc">True</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Token</span><span class="p">:</span> </span><span id="parse-74"><a href="#parse-74"><span class="linenos"> 74</span></a> <span class="k">return</span> <span class="kc">None</span>
</span><span id="parse-75"><a href="#parse-75"><span class="linenos"> 75</span></a> <span class="k">pass</span> </span><span id="parse-75"><a href="#parse-75"><span class="linenos"> 75</span></a>
</span><span id="parse-76"><a href="#parse-76"><span class="linenos"> 76</span></a> </span><span id="parse-76"><a href="#parse-76"><span class="linenos"> 76</span></a> <span class="k">def</span> <span class="nf">_parse_literal</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">:</span>
</span><span id="parse-77"><a href="#parse-77"><span class="linenos"> 77</span></a> <span class="nd">@t</span><span class="o">.</span><span class="n">overload</span> </span><span id="parse-77"><a href="#parse-77"><span class="linenos"> 77</span></a> <span class="n">token</span> <span class="o">=</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STRING</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">IDENTIFIER</span><span class="p">)</span>
</span><span id="parse-78"><a href="#parse-78"><span class="linenos"> 78</span></a> <span class="k">def</span> <span class="nf">_match</span><span class="p">(</span><span class="n">token_type</span><span class="p">:</span> <span class="n">TokenType</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="p">:</span> <span class="n">Lit</span><span class="p">[</span><span class="kc">False</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">Token</span><span class="p">]:</span> </span><span id="parse-78"><a href="#parse-78"><span class="linenos"> 78</span></a> <span class="k">if</span> <span class="n">token</span><span class="p">:</span>
</span><span id="parse-79"><a href="#parse-79"><span class="linenos"> 79</span></a> <span class="k">pass</span> </span><span id="parse-79"><a href="#parse-79"><span class="linenos"> 79</span></a> <span class="k">return</span> <span class="n">token</span><span class="o">.</span><span class="n">text</span>
</span><span id="parse-80"><a href="#parse-80"><span class="linenos"> 80</span></a> </span><span id="parse-80"><a href="#parse-80"><span class="linenos"> 80</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STAR</span><span class="p">):</span>
</span><span id="parse-81"><a href="#parse-81"><span class="linenos"> 81</span></a> <span class="k">def</span> <span class="nf">_match</span><span class="p">(</span><span class="n">token_type</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span> </span><span id="parse-81"><a href="#parse-81"><span class="linenos"> 81</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathWildcard</span><span class="p">()</span>
</span><span id="parse-82"><a href="#parse-82"><span class="linenos"> 82</span></a> <span class="k">if</span> <span class="n">_curr</span><span class="p">()</span> <span class="o">==</span> <span class="n">token_type</span><span class="p">:</span> </span><span id="parse-82"><a href="#parse-82"><span class="linenos"> 82</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">PLACEHOLDER</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">L_PAREN</span><span class="p">):</span>
</span><span id="parse-83"><a href="#parse-83"><span class="linenos"> 83</span></a> <span class="k">return</span> <span class="n">_advance</span><span class="p">()</span> </span><span id="parse-83"><a href="#parse-83"><span class="linenos"> 83</span></a> <span class="n">script</span> <span class="o">=</span> <span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span> <span class="o">==</span> <span class="s2">&quot;(&quot;</span>
</span><span id="parse-84"><a href="#parse-84"><span class="linenos"> 84</span></a> <span class="k">if</span> <span class="n">raise_unmatched</span><span class="p">:</span> </span><span id="parse-84"><a href="#parse-84"><span class="linenos"> 84</span></a> <span class="n">start</span> <span class="o">=</span> <span class="n">i</span>
</span><span id="parse-85"><a href="#parse-85"><span class="linenos"> 85</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Expected </span><span class="si">{</span><span class="n">token_type</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">))</span> </span><span id="parse-85"><a href="#parse-85"><span class="linenos"> 85</span></a>
</span><span id="parse-86"><a href="#parse-86"><span class="linenos"> 86</span></a> <span class="k">return</span> <span class="kc">None</span> </span><span id="parse-86"><a href="#parse-86"><span class="linenos"> 86</span></a> <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
</span><span id="parse-87"><a href="#parse-87"><span class="linenos"> 87</span></a> </span><span id="parse-87"><a href="#parse-87"><span class="linenos"> 87</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">L_BRACKET</span><span class="p">):</span>
</span><span id="parse-88"><a href="#parse-88"><span class="linenos"> 88</span></a> <span class="k">def</span> <span class="nf">_parse_literal</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">:</span> </span><span id="parse-88"><a href="#parse-88"><span class="linenos"> 88</span></a> <span class="n">_parse_bracket</span><span class="p">()</span> <span class="c1"># nested call which we can throw away</span>
</span><span id="parse-89"><a href="#parse-89"><span class="linenos"> 89</span></a> <span class="n">token</span> <span class="o">=</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STRING</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">IDENTIFIER</span><span class="p">)</span> </span><span id="parse-89"><a href="#parse-89"><span class="linenos"> 89</span></a> <span class="k">if</span> <span class="n">_curr</span><span class="p">()</span> <span class="ow">in</span> <span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">R_BRACKET</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
</span><span id="parse-90"><a href="#parse-90"><span class="linenos"> 90</span></a> <span class="k">if</span> <span class="n">token</span><span class="p">:</span> </span><span id="parse-90"><a href="#parse-90"><span class="linenos"> 90</span></a> <span class="k">break</span>
</span><span id="parse-91"><a href="#parse-91"><span class="linenos"> 91</span></a> <span class="k">return</span> <span class="n">token</span><span class="o">.</span><span class="n">text</span> </span><span id="parse-91"><a href="#parse-91"><span class="linenos"> 91</span></a> <span class="n">_advance</span><span class="p">()</span>
</span><span id="parse-92"><a href="#parse-92"><span class="linenos"> 92</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STAR</span><span class="p">):</span> </span><span id="parse-92"><a href="#parse-92"><span class="linenos"> 92</span></a>
</span><span id="parse-93"><a href="#parse-93"><span class="linenos"> 93</span></a> <span class="k">return</span> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;wildcard&quot;</span><span class="p">)</span> </span><span id="parse-93"><a href="#parse-93"><span class="linenos"> 93</span></a> <span class="n">expr_type</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathScript</span> <span class="k">if</span> <span class="n">script</span> <span class="k">else</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathFilter</span>
</span><span id="parse-94"><a href="#parse-94"><span class="linenos"> 94</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">PLACEHOLDER</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">L_PAREN</span><span class="p">):</span> </span><span id="parse-94"><a href="#parse-94"><span class="linenos"> 94</span></a> <span class="k">return</span> <span class="n">expr_type</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">path</span><span class="p">[</span><span class="n">tokens</span><span class="p">[</span><span class="n">start</span><span class="p">]</span><span class="o">.</span><span class="n">start</span> <span class="p">:</span> <span class="n">tokens</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">end</span><span class="p">])</span>
</span><span id="parse-95"><a href="#parse-95"><span class="linenos"> 95</span></a> <span class="n">script</span> <span class="o">=</span> <span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span> <span class="o">==</span> <span class="s2">&quot;(&quot;</span> </span><span id="parse-95"><a href="#parse-95"><span class="linenos"> 95</span></a>
</span><span id="parse-96"><a href="#parse-96"><span class="linenos"> 96</span></a> <span class="n">start</span> <span class="o">=</span> <span class="n">i</span> </span><span id="parse-96"><a href="#parse-96"><span class="linenos"> 96</span></a> <span class="n">number</span> <span class="o">=</span> <span class="s2">&quot;-&quot;</span> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">DASH</span><span class="p">)</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
</span><span id="parse-97"><a href="#parse-97"><span class="linenos"> 97</span></a> </span><span id="parse-97"><a href="#parse-97"><span class="linenos"> 97</span></a>
</span><span id="parse-98"><a href="#parse-98"><span class="linenos"> 98</span></a> <span class="k">while</span> <span class="kc">True</span><span class="p">:</span> </span><span id="parse-98"><a href="#parse-98"><span class="linenos"> 98</span></a> <span class="n">token</span> <span class="o">=</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">NUMBER</span><span class="p">)</span>
</span><span id="parse-99"><a href="#parse-99"><span class="linenos"> 99</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">L_BRACKET</span><span class="p">):</span> </span><span id="parse-99"><a href="#parse-99"><span class="linenos"> 99</span></a> <span class="k">if</span> <span class="n">token</span><span class="p">:</span>
</span><span id="parse-100"><a href="#parse-100"><span class="linenos">100</span></a> <span class="n">_parse_bracket</span><span class="p">()</span> <span class="c1"># nested call which we can throw away</span> </span><span id="parse-100"><a href="#parse-100"><span class="linenos">100</span></a> <span class="n">number</span> <span class="o">+=</span> <span class="n">token</span><span class="o">.</span><span class="n">text</span>
</span><span id="parse-101"><a href="#parse-101"><span class="linenos">101</span></a> <span class="k">if</span> <span class="n">_curr</span><span class="p">()</span> <span class="ow">in</span> <span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">R_BRACKET</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span> </span><span id="parse-101"><a href="#parse-101"><span class="linenos">101</span></a>
</span><span id="parse-102"><a href="#parse-102"><span class="linenos">102</span></a> <span class="k">break</span> </span><span id="parse-102"><a href="#parse-102"><span class="linenos">102</span></a> <span class="k">if</span> <span class="n">number</span><span class="p">:</span>
</span><span id="parse-103"><a href="#parse-103"><span class="linenos">103</span></a> <span class="n">_advance</span><span class="p">()</span> </span><span id="parse-103"><a href="#parse-103"><span class="linenos">103</span></a> <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">number</span><span class="p">)</span>
</span><span id="parse-104"><a href="#parse-104"><span class="linenos">104</span></a> <span class="k">return</span> <span class="n">_node</span><span class="p">(</span> </span><span id="parse-104"><a href="#parse-104"><span class="linenos">104</span></a>
</span><span id="parse-105"><a href="#parse-105"><span class="linenos">105</span></a> <span class="s2">&quot;script&quot;</span> <span class="k">if</span> <span class="n">script</span> <span class="k">else</span> <span class="s2">&quot;filter&quot;</span><span class="p">,</span> <span class="n">path</span><span class="p">[</span><span class="n">tokens</span><span class="p">[</span><span class="n">start</span><span class="p">]</span><span class="o">.</span><span class="n">start</span> <span class="p">:</span> <span class="n">tokens</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">end</span><span class="p">]</span> </span><span id="parse-105"><a href="#parse-105"><span class="linenos">105</span></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="parse-106"><a href="#parse-106"><span class="linenos">106</span></a> <span class="p">)</span> </span><span id="parse-106"><a href="#parse-106"><span class="linenos">106</span></a>
</span><span id="parse-107"><a href="#parse-107"><span class="linenos">107</span></a> </span><span id="parse-107"><a href="#parse-107"><span class="linenos">107</span></a> <span class="k">def</span> <span class="nf">_parse_slice</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">:</span>
</span><span id="parse-108"><a href="#parse-108"><span class="linenos">108</span></a> <span class="n">number</span> <span class="o">=</span> <span class="s2">&quot;-&quot;</span> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">DASH</span><span class="p">)</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span> </span><span id="parse-108"><a href="#parse-108"><span class="linenos">108</span></a> <span class="n">start</span> <span class="o">=</span> <span class="n">_parse_literal</span><span class="p">()</span>
</span><span id="parse-109"><a href="#parse-109"><span class="linenos">109</span></a> </span><span id="parse-109"><a href="#parse-109"><span class="linenos">109</span></a> <span class="n">end</span> <span class="o">=</span> <span class="n">_parse_literal</span><span class="p">()</span> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COLON</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span>
</span><span id="parse-110"><a href="#parse-110"><span class="linenos">110</span></a> <span class="n">token</span> <span class="o">=</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">NUMBER</span><span class="p">)</span> </span><span id="parse-110"><a href="#parse-110"><span class="linenos">110</span></a> <span class="n">step</span> <span class="o">=</span> <span class="n">_parse_literal</span><span class="p">()</span> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COLON</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span>
</span><span id="parse-111"><a href="#parse-111"><span class="linenos">111</span></a> <span class="k">if</span> <span class="n">token</span><span class="p">:</span> </span><span id="parse-111"><a href="#parse-111"><span class="linenos">111</span></a>
</span><span id="parse-112"><a href="#parse-112"><span class="linenos">112</span></a> <span class="n">number</span> <span class="o">+=</span> <span class="n">token</span><span class="o">.</span><span class="n">text</span> </span><span id="parse-112"><a href="#parse-112"><span class="linenos">112</span></a> <span class="k">if</span> <span class="n">end</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">step</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="parse-113"><a href="#parse-113"><span class="linenos">113</span></a> </span><span id="parse-113"><a href="#parse-113"><span class="linenos">113</span></a> <span class="k">return</span> <span class="n">start</span>
</span><span id="parse-114"><a href="#parse-114"><span class="linenos">114</span></a> <span class="k">if</span> <span class="n">number</span><span class="p">:</span> </span><span id="parse-114"><a href="#parse-114"><span class="linenos">114</span></a>
</span><span id="parse-115"><a href="#parse-115"><span class="linenos">115</span></a> <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">number</span><span class="p">)</span> </span><span id="parse-115"><a href="#parse-115"><span class="linenos">115</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathSlice</span><span class="p">(</span><span class="n">start</span><span class="o">=</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="n">end</span><span class="p">,</span> <span class="n">step</span><span class="o">=</span><span class="n">step</span><span class="p">)</span>
</span><span id="parse-116"><a href="#parse-116"><span class="linenos">116</span></a> <span class="k">return</span> <span class="kc">False</span> </span><span id="parse-116"><a href="#parse-116"><span class="linenos">116</span></a>
</span><span id="parse-117"><a href="#parse-117"><span class="linenos">117</span></a> </span><span id="parse-117"><a href="#parse-117"><span class="linenos">117</span></a> <span class="k">def</span> <span class="nf">_parse_bracket</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathPart</span><span class="p">:</span>
</span><span id="parse-118"><a href="#parse-118"><span class="linenos">118</span></a> <span class="k">def</span> <span class="nf">_parse_slice</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">:</span> </span><span id="parse-118"><a href="#parse-118"><span class="linenos">118</span></a> <span class="n">literal</span> <span class="o">=</span> <span class="n">_parse_slice</span><span class="p">()</span>
</span><span id="parse-119"><a href="#parse-119"><span class="linenos">119</span></a> <span class="n">start</span> <span class="o">=</span> <span class="n">_parse_literal</span><span class="p">()</span> </span><span id="parse-119"><a href="#parse-119"><span class="linenos">119</span></a>
</span><span id="parse-120"><a href="#parse-120"><span class="linenos">120</span></a> <span class="n">end</span> <span class="o">=</span> <span class="n">_parse_literal</span><span class="p">()</span> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COLON</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span> </span><span id="parse-120"><a href="#parse-120"><span class="linenos">120</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">literal</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">or</span> <span class="n">literal</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">False</span><span class="p">:</span>
</span><span id="parse-121"><a href="#parse-121"><span class="linenos">121</span></a> <span class="n">step</span> <span class="o">=</span> <span class="n">_parse_literal</span><span class="p">()</span> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COLON</span><span class="p">)</span> <span class="k">else</span> <span class="kc">None</span> </span><span id="parse-121"><a href="#parse-121"><span class="linenos">121</span></a> <span class="n">indexes</span> <span class="o">=</span> <span class="p">[</span><span class="n">literal</span><span class="p">]</span>
</span><span id="parse-122"><a href="#parse-122"><span class="linenos">122</span></a> </span><span id="parse-122"><a href="#parse-122"><span class="linenos">122</span></a> <span class="k">while</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COMMA</span><span class="p">):</span>
</span><span id="parse-123"><a href="#parse-123"><span class="linenos">123</span></a> <span class="k">if</span> <span class="n">end</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">step</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> </span><span id="parse-123"><a href="#parse-123"><span class="linenos">123</span></a> <span class="n">literal</span> <span class="o">=</span> <span class="n">_parse_slice</span><span class="p">()</span>
</span><span id="parse-124"><a href="#parse-124"><span class="linenos">124</span></a> <span class="k">return</span> <span class="n">start</span> </span><span id="parse-124"><a href="#parse-124"><span class="linenos">124</span></a>
</span><span id="parse-125"><a href="#parse-125"><span class="linenos">125</span></a> <span class="k">return</span> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;slice&quot;</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="n">end</span><span class="p">,</span> <span class="n">step</span><span class="o">=</span><span class="n">step</span><span class="p">)</span> </span><span id="parse-125"><a href="#parse-125"><span class="linenos">125</span></a> <span class="k">if</span> <span class="n">literal</span><span class="p">:</span>
</span><span id="parse-126"><a href="#parse-126"><span class="linenos">126</span></a> </span><span id="parse-126"><a href="#parse-126"><span class="linenos">126</span></a> <span class="n">indexes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">literal</span><span class="p">)</span>
</span><span id="parse-127"><a href="#parse-127"><span class="linenos">127</span></a> <span class="k">def</span> <span class="nf">_parse_bracket</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">JSONPathNode</span><span class="p">:</span> </span><span id="parse-127"><a href="#parse-127"><span class="linenos">127</span></a>
</span><span id="parse-128"><a href="#parse-128"><span class="linenos">128</span></a> <span class="n">literal</span> <span class="o">=</span> <span class="n">_parse_slice</span><span class="p">()</span> </span><span id="parse-128"><a href="#parse-128"><span class="linenos">128</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">indexes</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
</span><span id="parse-129"><a href="#parse-129"><span class="linenos">129</span></a> </span><span id="parse-129"><a href="#parse-129"><span class="linenos">129</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">literal</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="parse-130"><a href="#parse-130"><span class="linenos">130</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">literal</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">or</span> <span class="n">literal</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">False</span><span class="p">:</span> </span><span id="parse-130"><a href="#parse-130"><span class="linenos">130</span></a> <span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathPart</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathKey</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">indexes</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</span><span id="parse-131"><a href="#parse-131"><span class="linenos">131</span></a> <span class="n">indexes</span> <span class="o">=</span> <span class="p">[</span><span class="n">literal</span><span class="p">]</span> </span><span id="parse-131"><a href="#parse-131"><span class="linenos">131</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">literal</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathPart</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span>
</span><span id="parse-132"><a href="#parse-132"><span class="linenos">132</span></a> <span class="k">while</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COMMA</span><span class="p">):</span> </span><span id="parse-132"><a href="#parse-132"><span class="linenos">132</span></a> <span class="n">literal</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathScript</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathFilter</span><span class="p">)</span>
</span><span id="parse-133"><a href="#parse-133"><span class="linenos">133</span></a> <span class="n">literal</span> <span class="o">=</span> <span class="n">_parse_slice</span><span class="p">()</span> </span><span id="parse-133"><a href="#parse-133"><span class="linenos">133</span></a> <span class="p">):</span>
</span><span id="parse-134"><a href="#parse-134"><span class="linenos">134</span></a> </span><span id="parse-134"><a href="#parse-134"><span class="linenos">134</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathSelector</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">indexes</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</span><span id="parse-135"><a href="#parse-135"><span class="linenos">135</span></a> <span class="k">if</span> <span class="n">literal</span><span class="p">:</span> </span><span id="parse-135"><a href="#parse-135"><span class="linenos">135</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="parse-136"><a href="#parse-136"><span class="linenos">136</span></a> <span class="n">indexes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">literal</span><span class="p">)</span> </span><span id="parse-136"><a href="#parse-136"><span class="linenos">136</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathSubscript</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">indexes</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</span><span id="parse-137"><a href="#parse-137"><span class="linenos">137</span></a> </span><span id="parse-137"><a href="#parse-137"><span class="linenos">137</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="parse-138"><a href="#parse-138"><span class="linenos">138</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">indexes</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span> </span><span id="parse-138"><a href="#parse-138"><span class="linenos">138</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathUnion</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="n">indexes</span><span class="p">)</span>
</span><span id="parse-139"><a href="#parse-139"><span class="linenos">139</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">literal</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span> </span><span id="parse-139"><a href="#parse-139"><span class="linenos">139</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="parse-140"><a href="#parse-140"><span class="linenos">140</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;key&quot;</span><span class="p">,</span> <span class="n">indexes</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> </span><span id="parse-140"><a href="#parse-140"><span class="linenos">140</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="s2">&quot;Cannot have empty segment&quot;</span><span class="p">))</span>
</span><span id="parse-141"><a href="#parse-141"><span class="linenos">141</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">literal</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)</span> <span class="ow">and</span> <span class="n">literal</span><span class="p">[</span><span class="s2">&quot;kind&quot;</span><span class="p">]</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;script&quot;</span><span class="p">,</span> <span class="s2">&quot;filter&quot;</span><span class="p">):</span> </span><span id="parse-141"><a href="#parse-141"><span class="linenos">141</span></a>
</span><span id="parse-142"><a href="#parse-142"><span class="linenos">142</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;selector&quot;</span><span class="p">,</span> <span class="n">indexes</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> </span><span id="parse-142"><a href="#parse-142"><span class="linenos">142</span></a> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">R_BRACKET</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="parse-143"><a href="#parse-143"><span class="linenos">143</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="parse-143"><a href="#parse-143"><span class="linenos">143</span></a>
</span><span id="parse-144"><a href="#parse-144"><span class="linenos">144</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;subscript&quot;</span><span class="p">,</span> <span class="n">indexes</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> </span><span id="parse-144"><a href="#parse-144"><span class="linenos">144</span></a> <span class="k">return</span> <span class="n">node</span>
</span><span id="parse-145"><a href="#parse-145"><span class="linenos">145</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="parse-145"><a href="#parse-145"><span class="linenos">145</span></a>
</span><span id="parse-146"><a href="#parse-146"><span class="linenos">146</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;union&quot;</span><span class="p">,</span> <span class="n">indexes</span><span class="p">)</span> </span><span id="parse-146"><a href="#parse-146"><span class="linenos">146</span></a> <span class="c1"># We canonicalize the JSON path AST so that it always starts with a</span>
</span><span id="parse-147"><a href="#parse-147"><span class="linenos">147</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="parse-147"><a href="#parse-147"><span class="linenos">147</span></a> <span class="c1"># &quot;root&quot; element, so paths like &quot;field&quot; will be generated as &quot;$.field&quot;</span>
</span><span id="parse-148"><a href="#parse-148"><span class="linenos">148</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="s2">&quot;Cannot have empty segment&quot;</span><span class="p">))</span> </span><span id="parse-148"><a href="#parse-148"><span class="linenos">148</span></a> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">DOLLAR</span><span class="p">)</span>
</span><span id="parse-149"><a href="#parse-149"><span class="linenos">149</span></a> </span><span id="parse-149"><a href="#parse-149"><span class="linenos">149</span></a> <span class="n">expressions</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathPart</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathRoot</span><span class="p">()]</span>
</span><span id="parse-150"><a href="#parse-150"><span class="linenos">150</span></a> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">R_BRACKET</span><span class="p">,</span> <span class="n">raise_unmatched</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> </span><span id="parse-150"><a href="#parse-150"><span class="linenos">150</span></a>
</span><span id="parse-151"><a href="#parse-151"><span class="linenos">151</span></a> </span><span id="parse-151"><a href="#parse-151"><span class="linenos">151</span></a> <span class="k">while</span> <span class="n">_curr</span><span class="p">():</span>
</span><span id="parse-152"><a href="#parse-152"><span class="linenos">152</span></a> <span class="k">return</span> <span class="n">node</span> </span><span id="parse-152"><a href="#parse-152"><span class="linenos">152</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">DOT</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">COLON</span><span class="p">):</span>
</span><span id="parse-153"><a href="#parse-153"><span class="linenos">153</span></a> </span><span id="parse-153"><a href="#parse-153"><span class="linenos">153</span></a> <span class="n">recursive</span> <span class="o">=</span> <span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span> <span class="o">==</span> <span class="s2">&quot;..&quot;</span>
</span><span id="parse-154"><a href="#parse-154"><span class="linenos">154</span></a> <span class="n">nodes</span> <span class="o">=</span> <span class="p">[]</span> </span><span id="parse-154"><a href="#parse-154"><span class="linenos">154</span></a>
</span><span id="parse-155"><a href="#parse-155"><span class="linenos">155</span></a> </span><span id="parse-155"><a href="#parse-155"><span class="linenos">155</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">VAR</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">IDENTIFIER</span><span class="p">):</span>
</span><span id="parse-156"><a href="#parse-156"><span class="linenos">156</span></a> <span class="k">while</span> <span class="n">_curr</span><span class="p">():</span> </span><span id="parse-156"><a href="#parse-156"><span class="linenos">156</span></a> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span> <span class="o">|</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathWildcard</span><span class="p">]</span> <span class="o">=</span> <span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span>
</span><span id="parse-157"><a href="#parse-157"><span class="linenos">157</span></a> <span class="k">if</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">DOLLAR</span><span class="p">):</span> </span><span id="parse-157"><a href="#parse-157"><span class="linenos">157</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STAR</span><span class="p">):</span>
</span><span id="parse-158"><a href="#parse-158"><span class="linenos">158</span></a> <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_node</span><span class="p">(</span><span class="s2">&quot;root&quot;</span><span class="p">))</span> </span><span id="parse-158"><a href="#parse-158"><span class="linenos">158</span></a> <span class="n">value</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPathWildcard</span><span class="p">()</span>
</span><span id="parse-159"><a href="#parse-159"><span class="linenos">159</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">DOT</span><span class="p">):</span> </span><span id="parse-159"><a href="#parse-159"><span class="linenos">159</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="parse-160"><a href="#parse-160"><span class="linenos">160</span></a> <span class="n">recursive</span> <span class="o">=</span> <span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span> <span class="o">==</span> <span class="s2">&quot;..&quot;</span> </span><span id="parse-160"><a href="#parse-160"><span class="linenos">160</span></a> <span class="n">value</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="parse-161"><a href="#parse-161"><span class="linenos">161</span></a> <span class="n">value</span> <span class="o">=</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">VAR</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STAR</span><span class="p">)</span> </span><span id="parse-161"><a href="#parse-161"><span class="linenos">161</span></a>
</span><span id="parse-162"><a href="#parse-162"><span class="linenos">162</span></a> <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span> </span><span id="parse-162"><a href="#parse-162"><span class="linenos">162</span></a> <span class="k">if</span> <span class="n">recursive</span><span class="p">:</span>
</span><span id="parse-163"><a href="#parse-163"><span class="linenos">163</span></a> <span class="n">_node</span><span class="p">(</span><span class="s2">&quot;recursive&quot;</span> <span class="k">if</span> <span class="n">recursive</span> <span class="k">else</span> <span class="s2">&quot;child&quot;</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="o">.</span><span class="n">text</span> <span class="k">if</span> <span class="n">value</span> <span class="k">else</span> <span class="kc">None</span><span class="p">)</span> </span><span id="parse-163"><a href="#parse-163"><span class="linenos">163</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathRecursive</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">value</span><span class="p">))</span>
</span><span id="parse-164"><a href="#parse-164"><span class="linenos">164</span></a> <span class="p">)</span> </span><span id="parse-164"><a href="#parse-164"><span class="linenos">164</span></a> <span class="k">elif</span> <span class="n">value</span><span class="p">:</span>
</span><span id="parse-165"><a href="#parse-165"><span class="linenos">165</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">L_BRACKET</span><span class="p">):</span> </span><span id="parse-165"><a href="#parse-165"><span class="linenos">165</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathKey</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">value</span><span class="p">))</span>
</span><span id="parse-166"><a href="#parse-166"><span class="linenos">166</span></a> <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_parse_bracket</span><span class="p">())</span> </span><span id="parse-166"><a href="#parse-166"><span class="linenos">166</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="parse-167"><a href="#parse-167"><span class="linenos">167</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">VAR</span><span class="p">):</span> </span><span id="parse-167"><a href="#parse-167"><span class="linenos">167</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="s2">&quot;Expected key name or * after DOT&quot;</span><span class="p">))</span>
</span><span id="parse-168"><a href="#parse-168"><span class="linenos">168</span></a> <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_node</span><span class="p">(</span><span class="s2">&quot;key&quot;</span><span class="p">,</span> <span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span><span class="p">))</span> </span><span id="parse-168"><a href="#parse-168"><span class="linenos">168</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">L_BRACKET</span><span class="p">):</span>
</span><span id="parse-169"><a href="#parse-169"><span class="linenos">169</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STAR</span><span class="p">):</span> </span><span id="parse-169"><a href="#parse-169"><span class="linenos">169</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_parse_bracket</span><span class="p">())</span>
</span><span id="parse-170"><a href="#parse-170"><span class="linenos">170</span></a> <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_node</span><span class="p">(</span><span class="s2">&quot;wildcard&quot;</span><span class="p">))</span> </span><span id="parse-170"><a href="#parse-170"><span class="linenos">170</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">VAR</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">IDENTIFIER</span><span class="p">):</span>
</span><span id="parse-171"><a href="#parse-171"><span class="linenos">171</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">PARAMETER</span><span class="p">):</span> </span><span id="parse-171"><a href="#parse-171"><span class="linenos">171</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathKey</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">_prev</span><span class="p">()</span><span class="o">.</span><span class="n">text</span><span class="p">))</span>
</span><span id="parse-172"><a href="#parse-172"><span class="linenos">172</span></a> <span class="n">nodes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_node</span><span class="p">(</span><span class="s2">&quot;current&quot;</span><span class="p">))</span> </span><span id="parse-172"><a href="#parse-172"><span class="linenos">172</span></a> <span class="k">elif</span> <span class="n">_match</span><span class="p">(</span><span class="n">TokenType</span><span class="o">.</span><span class="n">STAR</span><span class="p">):</span>
</span><span id="parse-173"><a href="#parse-173"><span class="linenos">173</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="parse-173"><a href="#parse-173"><span class="linenos">173</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">JSONPathWildcard</span><span class="p">())</span>
</span><span id="parse-174"><a href="#parse-174"><span class="linenos">174</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unexpected </span><span class="si">{</span><span class="n">tokens</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">token_type</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">))</span> </span><span id="parse-174"><a href="#parse-174"><span class="linenos">174</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="parse-175"><a href="#parse-175"><span class="linenos">175</span></a> </span><span id="parse-175"><a href="#parse-175"><span class="linenos">175</span></a> <span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="n">_error</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unexpected </span><span class="si">{</span><span class="n">tokens</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">token_type</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">))</span>
</span><span id="parse-176"><a href="#parse-176"><span class="linenos">176</span></a> <span class="k">return</span> <span class="n">nodes</span> </span><span id="parse-176"><a href="#parse-176"><span class="linenos">176</span></a>
</span><span id="parse-177"><a href="#parse-177"><span class="linenos">177</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">JSONPath</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="n">expressions</span><span class="p">)</span>
</span></pre></div> </span></pre></div>
<div class="docstring"><p>Takes in a JSONPath string and converts into a list of nodes.</p> <div class="docstring"><p>Takes in a JSON path string and parses it into a JSONPath expression.</p>
</div> </div>
</section> </section>
<section id="MAPPING"> <section id="JSON_PATH_PART_TRANSFORMS">
<div class="attr variable"> <div class="attr variable">
<span class="name">MAPPING</span> = <span class="name">JSON_PATH_PART_TRANSFORMS</span><span class="annotation">: Dict[Type[<a href="expressions.html#Expression">sqlglot.expressions.Expression</a>], Callable[..., str]]</span> =
<input id="MAPPING-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="JSON_PATH_PART_TRANSFORMS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="MAPPING-view-value"></label><span class="default_value">{&#39;child&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;filter&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;key&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;recursive&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;root&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;script&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;slice&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;selector&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;subscript&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;union&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;wildcard&#39;: &lt;function &lt;lambda&gt;&gt;}</span> <label class="view-value-button pdoc-button" for="JSON_PATH_PART_TRANSFORMS-view-value"></label><span class="default_value">{&lt;class &#39;<a href="expressions.html#JSONPathFilter">sqlglot.expressions.JSONPathFilter</a>&#39;&gt;: &lt;function &lt;lambda&gt;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathKey">sqlglot.expressions.JSONPathKey</a>&#39;&gt;: &lt;function &lt;lambda&gt;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathRecursive">sqlglot.expressions.JSONPathRecursive</a>&#39;&gt;: &lt;function &lt;lambda&gt;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathRoot">sqlglot.expressions.JSONPathRoot</a>&#39;&gt;: &lt;function &lt;lambda&gt;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathScript">sqlglot.expressions.JSONPathScript</a>&#39;&gt;: &lt;function &lt;lambda&gt;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSelector">sqlglot.expressions.JSONPathSelector</a>&#39;&gt;: &lt;function &lt;lambda&gt;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSlice">sqlglot.expressions.JSONPathSlice</a>&#39;&gt;: &lt;function &lt;lambda&gt;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSubscript">sqlglot.expressions.JSONPathSubscript</a>&#39;&gt;: &lt;function &lt;lambda&gt;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathUnion">sqlglot.expressions.JSONPathUnion</a>&#39;&gt;: &lt;function &lt;lambda&gt;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathWildcard">sqlglot.expressions.JSONPathWildcard</a>&#39;&gt;: &lt;function &lt;lambda&gt;&gt;}</span>
</div> </div>
<a class="headerlink" href="#MAPPING"></a> <a class="headerlink" href="#JSON_PATH_PART_TRANSFORMS"></a>
</section> </section>
<section id="generate"> <section id="ALL_JSON_PATH_PARTS">
<input id="generate-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <div class="attr variable">
<div class="attr function"> <span class="name">ALL_JSON_PATH_PARTS</span> =
<input id="ALL_JSON_PATH_PARTS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<span class="def">def</span> <label class="view-value-button pdoc-button" for="ALL_JSON_PATH_PARTS-view-value"></label><span class="default_value">{&lt;class &#39;<a href="expressions.html#JSONPathScript">sqlglot.expressions.JSONPathScript</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathRoot">sqlglot.expressions.JSONPathRoot</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathRecursive">sqlglot.expressions.JSONPathRecursive</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathKey">sqlglot.expressions.JSONPathKey</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathWildcard">sqlglot.expressions.JSONPathWildcard</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathFilter">sqlglot.expressions.JSONPathFilter</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathUnion">sqlglot.expressions.JSONPathUnion</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSubscript">sqlglot.expressions.JSONPathSubscript</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSelector">sqlglot.expressions.JSONPathSelector</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSlice">sqlglot.expressions.JSONPathSlice</a>&#39;&gt;}</span>
<span class="name">generate</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">nodes</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]]</span>,</span><span class="param"> <span class="n">mapping</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Callable</span><span class="p">[[</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]],</span> <span class="nb">str</span><span class="p">]]]</span> <span class="o">=</span> <span class="kc">None</span></span><span class="return-annotation">) -> <span class="nb">str</span>:</span></span>
<label class="view-source-button" for="generate-view-source"><span>View Source</span></label>
</div> </div>
<a class="headerlink" href="#generate"></a> <a class="headerlink" href="#ALL_JSON_PATH_PARTS"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="generate-200"><a href="#generate-200"><span class="linenos">200</span></a><span class="k">def</span> <span class="nf">generate</span><span class="p">(</span>
</span><span id="generate-201"><a href="#generate-201"><span class="linenos">201</span></a> <span class="n">nodes</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">JSONPathNode</span><span class="p">],</span>
</span><span id="generate-202"><a href="#generate-202"><span class="linenos">202</span></a> <span class="n">mapping</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[</span><span class="n">JSONPathNode</span><span class="p">],</span> <span class="nb">str</span><span class="p">]]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="generate-203"><a href="#generate-203"><span class="linenos">203</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="generate-204"><a href="#generate-204"><span class="linenos">204</span></a> <span class="n">mapping</span> <span class="o">=</span> <span class="n">MAPPING</span> <span class="k">if</span> <span class="n">mapping</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">mapping</span>
</span><span id="generate-205"><a href="#generate-205"><span class="linenos">205</span></a> <span class="n">path</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="generate-206"><a href="#generate-206"><span class="linenos">206</span></a>
</span><span id="generate-207"><a href="#generate-207"><span class="linenos">207</span></a> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">nodes</span><span class="p">:</span>
</span><span id="generate-208"><a href="#generate-208"><span class="linenos">208</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
</span><span id="generate-209"><a href="#generate-209"><span class="linenos">209</span></a> <span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">mapping</span><span class="p">[</span><span class="n">node</span><span class="p">[</span><span class="s2">&quot;kind&quot;</span><span class="p">]](</span><span class="n">node</span><span class="p">))</span>
</span><span id="generate-210"><a href="#generate-210"><span class="linenos">210</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="generate-211"><a href="#generate-211"><span class="linenos">211</span></a> <span class="n">escaped</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;&quot;&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&quot;&#39;</span><span class="p">)</span>
</span><span id="generate-212"><a href="#generate-212"><span class="linenos">212</span></a> <span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;&quot;</span><span class="si">{</span><span class="n">escaped</span><span class="si">}</span><span class="s1">&quot;&#39;</span><span class="p">)</span>
</span><span id="generate-213"><a href="#generate-213"><span class="linenos">213</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="generate-214"><a href="#generate-214"><span class="linenos">214</span></a> <span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">node</span><span class="p">))</span>
</span><span id="generate-215"><a href="#generate-215"><span class="linenos">215</span></a>
</span><span id="generate-216"><a href="#generate-216"><span class="linenos">216</span></a> <span class="k">return</span> <span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></pre></div>
</section> </section>

View file

@ -150,9 +150,9 @@
</span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a> <span class="n">label</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> </span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a> <span class="n">label</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a> <span class="n">source</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">source</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span> </span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a> <span class="n">source</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">source</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Tag</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">n</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;&lt;b&gt;&quot;</span><span class="p">,</span> <span class="n">postfix</span><span class="o">=</span><span class="s2">&quot;&lt;/b&gt;&quot;</span><span class="p">)</span> </span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="p">(</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a> <span class="k">if</span> <span class="n">n</span> <span class="ow">is</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span> </span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Tag</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">n</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;&lt;b&gt;&quot;</span><span class="p">,</span> <span class="n">postfix</span><span class="o">=</span><span class="s2">&quot;&lt;/b&gt;&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="n">n</span> <span class="ow">is</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span> <span class="k">else</span> <span class="n">n</span>
</span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a> <span class="k">else</span> <span class="n">n</span><span class="p">,</span> </span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a> <span class="p">),</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> </span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> <span class="p">)</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> </span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> <span class="p">)</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a> <span class="n">title</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;&lt;pre&gt;</span><span class="si">{</span><span class="n">source</span><span class="si">}</span><span class="s2">&lt;/pre&gt;&quot;</span> </span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a> <span class="n">title</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;&lt;pre&gt;</span><span class="si">{</span><span class="n">source</span><span class="si">}</span><span class="s2">&lt;/pre&gt;&quot;</span>
@ -453,9 +453,9 @@
</span><span id="Node-42"><a href="#Node-42"><span class="linenos">42</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="Node-42"><a href="#Node-42"><span class="linenos">42</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="Node-43"><a href="#Node-43"><span class="linenos">43</span></a> <span class="n">label</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> </span><span id="Node-43"><a href="#Node-43"><span class="linenos">43</span></a> <span class="n">label</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="Node-44"><a href="#Node-44"><span class="linenos">44</span></a> <span class="n">source</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">source</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span> </span><span id="Node-44"><a href="#Node-44"><span class="linenos">44</span></a> <span class="n">source</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">source</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span>
</span><span id="Node-45"><a href="#Node-45"><span class="linenos">45</span></a> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Tag</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">n</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;&lt;b&gt;&quot;</span><span class="p">,</span> <span class="n">postfix</span><span class="o">=</span><span class="s2">&quot;&lt;/b&gt;&quot;</span><span class="p">)</span> </span><span id="Node-45"><a href="#Node-45"><span class="linenos">45</span></a> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="p">(</span>
</span><span id="Node-46"><a href="#Node-46"><span class="linenos">46</span></a> <span class="k">if</span> <span class="n">n</span> <span class="ow">is</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span> </span><span id="Node-46"><a href="#Node-46"><span class="linenos">46</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Tag</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">n</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;&lt;b&gt;&quot;</span><span class="p">,</span> <span class="n">postfix</span><span class="o">=</span><span class="s2">&quot;&lt;/b&gt;&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="n">n</span> <span class="ow">is</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span> <span class="k">else</span> <span class="n">n</span>
</span><span id="Node-47"><a href="#Node-47"><span class="linenos">47</span></a> <span class="k">else</span> <span class="n">n</span><span class="p">,</span> </span><span id="Node-47"><a href="#Node-47"><span class="linenos">47</span></a> <span class="p">),</span>
</span><span id="Node-48"><a href="#Node-48"><span class="linenos">48</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> </span><span id="Node-48"><a href="#Node-48"><span class="linenos">48</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="Node-49"><a href="#Node-49"><span class="linenos">49</span></a> <span class="p">)</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> </span><span id="Node-49"><a href="#Node-49"><span class="linenos">49</span></a> <span class="p">)</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="Node-50"><a href="#Node-50"><span class="linenos">50</span></a> <span class="n">title</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;&lt;pre&gt;</span><span class="si">{</span><span class="n">source</span><span class="si">}</span><span class="s2">&lt;/pre&gt;&quot;</span> </span><span id="Node-50"><a href="#Node-50"><span class="linenos">50</span></a> <span class="n">title</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;&lt;pre&gt;</span><span class="si">{</span><span class="n">source</span><span class="si">}</span><span class="s2">&lt;/pre&gt;&quot;</span>
@ -594,9 +594,9 @@
</span><span id="Node.to_html-42"><a href="#Node.to_html-42"><span class="linenos">42</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="Node.to_html-42"><a href="#Node.to_html-42"><span class="linenos">42</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="Node.to_html-43"><a href="#Node.to_html-43"><span class="linenos">43</span></a> <span class="n">label</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> </span><span id="Node.to_html-43"><a href="#Node.to_html-43"><span class="linenos">43</span></a> <span class="n">label</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="Node.to_html-44"><a href="#Node.to_html-44"><span class="linenos">44</span></a> <span class="n">source</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">source</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span> </span><span id="Node.to_html-44"><a href="#Node.to_html-44"><span class="linenos">44</span></a> <span class="n">source</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">source</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span>
</span><span id="Node.to_html-45"><a href="#Node.to_html-45"><span class="linenos">45</span></a> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Tag</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">n</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;&lt;b&gt;&quot;</span><span class="p">,</span> <span class="n">postfix</span><span class="o">=</span><span class="s2">&quot;&lt;/b&gt;&quot;</span><span class="p">)</span> </span><span id="Node.to_html-45"><a href="#Node.to_html-45"><span class="linenos">45</span></a> <span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="p">(</span>
</span><span id="Node.to_html-46"><a href="#Node.to_html-46"><span class="linenos">46</span></a> <span class="k">if</span> <span class="n">n</span> <span class="ow">is</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span> </span><span id="Node.to_html-46"><a href="#Node.to_html-46"><span class="linenos">46</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Tag</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">n</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;&lt;b&gt;&quot;</span><span class="p">,</span> <span class="n">postfix</span><span class="o">=</span><span class="s2">&quot;&lt;/b&gt;&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="n">n</span> <span class="ow">is</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span> <span class="k">else</span> <span class="n">n</span>
</span><span id="Node.to_html-47"><a href="#Node.to_html-47"><span class="linenos">47</span></a> <span class="k">else</span> <span class="n">n</span><span class="p">,</span> </span><span id="Node.to_html-47"><a href="#Node.to_html-47"><span class="linenos">47</span></a> <span class="p">),</span>
</span><span id="Node.to_html-48"><a href="#Node.to_html-48"><span class="linenos">48</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> </span><span id="Node.to_html-48"><a href="#Node.to_html-48"><span class="linenos">48</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="Node.to_html-49"><a href="#Node.to_html-49"><span class="linenos">49</span></a> <span class="p">)</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> </span><span id="Node.to_html-49"><a href="#Node.to_html-49"><span class="linenos">49</span></a> <span class="p">)</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="n">pretty</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="Node.to_html-50"><a href="#Node.to_html-50"><span class="linenos">50</span></a> <span class="n">title</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;&lt;pre&gt;</span><span class="si">{</span><span class="n">source</span><span class="si">}</span><span class="s2">&lt;/pre&gt;&quot;</span> </span><span id="Node.to_html-50"><a href="#Node.to_html-50"><span class="linenos">50</span></a> <span class="n">title</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;&lt;pre&gt;</span><span class="si">{</span><span class="n">source</span><span class="si">}</span><span class="s2">&lt;/pre&gt;&quot;</span>

View file

@ -71,15 +71,17 @@
<label class="view-source-button" for="mod-optimizer-view-source"><span>View Source</span></label> <label class="view-source-button" for="mod-optimizer-view-source"><span>View Source</span></label>
<div class="pdoc-code codehilite"><pre><span></span><span id="L-1"><a href="#L-1"><span class="linenos">1</span></a><span class="kn">from</span> <span class="nn">sqlglot.optimizer.optimizer</span> <span class="kn">import</span> <span class="n">RULES</span><span class="p">,</span> <span class="n">optimize</span> <div class="pdoc-code codehilite"><pre><span></span><span id="L-1"><a href="#L-1"><span class="linenos"> 1</span></a><span class="c1"># ruff: noqa: F401</span>
</span><span id="L-2"><a href="#L-2"><span class="linenos">2</span></a><span class="kn">from</span> <span class="nn">sqlglot.optimizer.scope</span> <span class="kn">import</span> <span class="p">(</span> </span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a>
</span><span id="L-3"><a href="#L-3"><span class="linenos">3</span></a> <span class="n">Scope</span><span class="p">,</span> </span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="kn">from</span> <span class="nn">sqlglot.optimizer.optimizer</span> <span class="kn">import</span> <span class="n">RULES</span><span class="p">,</span> <span class="n">optimize</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos">4</span></a> <span class="n">build_scope</span><span class="p">,</span> </span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a><span class="kn">from</span> <span class="nn">sqlglot.optimizer.scope</span> <span class="kn">import</span> <span class="p">(</span>
</span><span id="L-5"><a href="#L-5"><span class="linenos">5</span></a> <span class="n">find_all_in_scope</span><span class="p">,</span> </span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a> <span class="n">Scope</span><span class="p">,</span>
</span><span id="L-6"><a href="#L-6"><span class="linenos">6</span></a> <span class="n">find_in_scope</span><span class="p">,</span> </span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a> <span class="n">build_scope</span><span class="p">,</span>
</span><span id="L-7"><a href="#L-7"><span class="linenos">7</span></a> <span class="n">traverse_scope</span><span class="p">,</span> </span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a> <span class="n">find_all_in_scope</span><span class="p">,</span>
</span><span id="L-8"><a href="#L-8"><span class="linenos">8</span></a> <span class="n">walk_in_scope</span><span class="p">,</span> </span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a> <span class="n">find_in_scope</span><span class="p">,</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos">9</span></a><span class="p">)</span> </span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a> <span class="n">traverse_scope</span><span class="p">,</span>
</span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a> <span class="n">walk_in_scope</span><span class="p">,</span>
</span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a><span class="p">)</span>
</span></pre></div> </span></pre></div>

File diff suppressed because one or more lines are too long

View file

@ -585,7 +585,7 @@ queries if it would result in multiple table selects in a single query:</p>
<div class="attr variable"> <div class="attr variable">
<span class="name">UNMERGABLE_ARGS</span> = <span class="name">UNMERGABLE_ARGS</span> =
<input id="UNMERGABLE_ARGS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="UNMERGABLE_ARGS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="UNMERGABLE_ARGS-view-value"></label><span class="default_value">{&#39;kind&#39;, &#39;qualify&#39;, &#39;offset&#39;, &#39;locks&#39;, &#39;group&#39;, &#39;with&#39;, &#39;limit&#39;, &#39;format&#39;, &#39;distinct&#39;, &#39;sample&#39;, &#39;laterals&#39;, &#39;cluster&#39;, &#39;settings&#39;, &#39;pivots&#39;, &#39;connect&#39;, &#39;distribute&#39;, &#39;match&#39;, &#39;having&#39;, &#39;into&#39;, &#39;windows&#39;, &#39;sort&#39;}</span> <label class="view-value-button pdoc-button" for="UNMERGABLE_ARGS-view-value"></label><span class="default_value">{&#39;distribute&#39;, &#39;settings&#39;, &#39;windows&#39;, &#39;format&#39;, &#39;group&#39;, &#39;having&#39;, &#39;limit&#39;, &#39;laterals&#39;, &#39;with&#39;, &#39;offset&#39;, &#39;into&#39;, &#39;cluster&#39;, &#39;locks&#39;, &#39;distinct&#39;, &#39;match&#39;, &#39;connect&#39;, &#39;kind&#39;, &#39;sample&#39;, &#39;qualify&#39;, &#39;sort&#39;, &#39;pivots&#39;}</span>
</div> </div>

View file

@ -61,63 +61,65 @@
</span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span> </span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a> </span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a>
</span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">exp</span> </span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">exp</span>
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a><span class="kn">from</span> <span class="nn">sqlglot._typing</span> <span class="kn">import</span> <span class="n">E</span> </span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.dialect</span> <span class="kn">import</span> <span class="n">Dialect</span><span class="p">,</span> <span class="n">DialectType</span>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.dialect</span> <span class="kn">import</span> <span class="n">Dialect</span><span class="p">,</span> <span class="n">DialectType</span> </span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a> </span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">TYPE_CHECKING</span><span class="p">:</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a> </span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a> <span class="kn">from</span> <span class="nn">sqlglot._typing</span> <span class="kn">import</span> <span class="n">E</span>
</span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a><span class="nd">@t</span><span class="o">.</span><span class="n">overload</span> </span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a>
</span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a><span class="k">def</span> <span class="nf">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">E</span><span class="p">,</span> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span> </span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a>
</span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a> <span class="o">...</span> </span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a><span class="nd">@t</span><span class="o">.</span><span class="n">overload</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a> </span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a><span class="k">def</span> <span class="nf">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">E</span><span class="p">,</span> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a> </span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a> <span class="o">...</span>
</span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a><span class="nd">@t</span><span class="o">.</span><span class="n">overload</span> </span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a>
</span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a><span class="k">def</span> <span class="nf">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">:</span> </span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a>
</span><span id="L-17"><a href="#L-17"><span class="linenos">17</span></a> <span class="o">...</span> </span><span id="L-17"><a href="#L-17"><span class="linenos">17</span></a><span class="nd">@t</span><span class="o">.</span><span class="n">overload</span>
</span><span id="L-18"><a href="#L-18"><span class="linenos">18</span></a> </span><span id="L-18"><a href="#L-18"><span class="linenos">18</span></a><span class="k">def</span> <span class="nf">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">:</span>
</span><span id="L-19"><a href="#L-19"><span class="linenos">19</span></a> </span><span id="L-19"><a href="#L-19"><span class="linenos">19</span></a> <span class="o">...</span>
</span><span id="L-20"><a href="#L-20"><span class="linenos">20</span></a><span class="k">def</span> <span class="nf">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> </span><span id="L-20"><a href="#L-20"><span class="linenos">20</span></a>
</span><span id="L-21"><a href="#L-21"><span class="linenos">21</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-21"><a href="#L-21"><span class="linenos">21</span></a>
</span><span id="L-22"><a href="#L-22"><span class="linenos">22</span></a><span class="sd"> Normalize all unquoted identifiers to either lower or upper case, depending</span> </span><span id="L-22"><a href="#L-22"><span class="linenos">22</span></a><span class="k">def</span> <span class="nf">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
</span><span id="L-23"><a href="#L-23"><span class="linenos">23</span></a><span class="sd"> on the dialect. This essentially makes those identifiers case-insensitive.</span> </span><span id="L-23"><a href="#L-23"><span class="linenos">23</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-24"><a href="#L-24"><span class="linenos">24</span></a> </span><span id="L-24"><a href="#L-24"><span class="linenos">24</span></a><span class="sd"> Normalize all unquoted identifiers to either lower or upper case, depending</span>
</span><span id="L-25"><a href="#L-25"><span class="linenos">25</span></a><span class="sd"> It&#39;s possible to make this a no-op by adding a special comment next to the</span> </span><span id="L-25"><a href="#L-25"><span class="linenos">25</span></a><span class="sd"> on the dialect. This essentially makes those identifiers case-insensitive.</span>
</span><span id="L-26"><a href="#L-26"><span class="linenos">26</span></a><span class="sd"> identifier of interest:</span> </span><span id="L-26"><a href="#L-26"><span class="linenos">26</span></a>
</span><span id="L-27"><a href="#L-27"><span class="linenos">27</span></a> </span><span id="L-27"><a href="#L-27"><span class="linenos">27</span></a><span class="sd"> It&#39;s possible to make this a no-op by adding a special comment next to the</span>
</span><span id="L-28"><a href="#L-28"><span class="linenos">28</span></a><span class="sd"> SELECT a /* sqlglot.meta case_sensitive */ FROM table</span> </span><span id="L-28"><a href="#L-28"><span class="linenos">28</span></a><span class="sd"> identifier of interest:</span>
</span><span id="L-29"><a href="#L-29"><span class="linenos">29</span></a> </span><span id="L-29"><a href="#L-29"><span class="linenos">29</span></a>
</span><span id="L-30"><a href="#L-30"><span class="linenos">30</span></a><span class="sd"> In this example, the identifier `a` will not be normalized.</span> </span><span id="L-30"><a href="#L-30"><span class="linenos">30</span></a><span class="sd"> SELECT a /* sqlglot.meta case_sensitive */ FROM table</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos">31</span></a> </span><span id="L-31"><a href="#L-31"><span class="linenos">31</span></a>
</span><span id="L-32"><a href="#L-32"><span class="linenos">32</span></a><span class="sd"> Note:</span> </span><span id="L-32"><a href="#L-32"><span class="linenos">32</span></a><span class="sd"> In this example, the identifier `a` will not be normalized.</span>
</span><span id="L-33"><a href="#L-33"><span class="linenos">33</span></a><span class="sd"> Some dialects (e.g. BigQuery) treat identifiers as case-insensitive even</span> </span><span id="L-33"><a href="#L-33"><span class="linenos">33</span></a>
</span><span id="L-34"><a href="#L-34"><span class="linenos">34</span></a><span class="sd"> when they&#39;re quoted, so in these cases all identifiers are normalized.</span> </span><span id="L-34"><a href="#L-34"><span class="linenos">34</span></a><span class="sd"> Note:</span>
</span><span id="L-35"><a href="#L-35"><span class="linenos">35</span></a> </span><span id="L-35"><a href="#L-35"><span class="linenos">35</span></a><span class="sd"> Some dialects (e.g. BigQuery) treat identifiers as case-insensitive even</span>
</span><span id="L-36"><a href="#L-36"><span class="linenos">36</span></a><span class="sd"> Example:</span> </span><span id="L-36"><a href="#L-36"><span class="linenos">36</span></a><span class="sd"> when they&#39;re quoted, so in these cases all identifiers are normalized.</span>
</span><span id="L-37"><a href="#L-37"><span class="linenos">37</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span> </span><span id="L-37"><a href="#L-37"><span class="linenos">37</span></a>
</span><span id="L-38"><a href="#L-38"><span class="linenos">38</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&#39;SELECT Bar.A AS A FROM &quot;Foo&quot;.Bar&#39;)</span> </span><span id="L-38"><a href="#L-38"><span class="linenos">38</span></a><span class="sd"> Example:</span>
</span><span id="L-39"><a href="#L-39"><span class="linenos">39</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(expression).sql()</span> </span><span id="L-39"><a href="#L-39"><span class="linenos">39</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="L-40"><a href="#L-40"><span class="linenos">40</span></a><span class="sd"> &#39;SELECT bar.a AS a FROM &quot;Foo&quot;.bar&#39;</span> </span><span id="L-40"><a href="#L-40"><span class="linenos">40</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&#39;SELECT Bar.A AS A FROM &quot;Foo&quot;.Bar&#39;)</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos">41</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(&quot;foo&quot;, dialect=&quot;snowflake&quot;).sql(dialect=&quot;snowflake&quot;)</span> </span><span id="L-41"><a href="#L-41"><span class="linenos">41</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(expression).sql()</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos">42</span></a><span class="sd"> &#39;FOO&#39;</span> </span><span id="L-42"><a href="#L-42"><span class="linenos">42</span></a><span class="sd"> &#39;SELECT bar.a AS a FROM &quot;Foo&quot;.bar&#39;</span>
</span><span id="L-43"><a href="#L-43"><span class="linenos">43</span></a> </span><span id="L-43"><a href="#L-43"><span class="linenos">43</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(&quot;foo&quot;, dialect=&quot;snowflake&quot;).sql(dialect=&quot;snowflake&quot;)</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos">44</span></a><span class="sd"> Args:</span> </span><span id="L-44"><a href="#L-44"><span class="linenos">44</span></a><span class="sd"> &#39;FOO&#39;</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos">45</span></a><span class="sd"> expression: The expression to transform.</span> </span><span id="L-45"><a href="#L-45"><span class="linenos">45</span></a>
</span><span id="L-46"><a href="#L-46"><span class="linenos">46</span></a><span class="sd"> dialect: The dialect to use in order to decide how to normalize identifiers.</span> </span><span id="L-46"><a href="#L-46"><span class="linenos">46</span></a><span class="sd"> Args:</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos">47</span></a> </span><span id="L-47"><a href="#L-47"><span class="linenos">47</span></a><span class="sd"> expression: The expression to transform.</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos">48</span></a><span class="sd"> Returns:</span> </span><span id="L-48"><a href="#L-48"><span class="linenos">48</span></a><span class="sd"> dialect: The dialect to use in order to decide how to normalize identifiers.</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos">49</span></a><span class="sd"> The transformed expression.</span> </span><span id="L-49"><a href="#L-49"><span class="linenos">49</span></a>
</span><span id="L-50"><a href="#L-50"><span class="linenos">50</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-50"><a href="#L-50"><span class="linenos">50</span></a><span class="sd"> Returns:</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos">51</span></a> <span class="n">dialect</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span> </span><span id="L-51"><a href="#L-51"><span class="linenos">51</span></a><span class="sd"> The transformed expression.</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos">52</span></a> </span><span id="L-52"><a href="#L-52"><span class="linenos">52</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-53"><a href="#L-53"><span class="linenos">53</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span> </span><span id="L-53"><a href="#L-53"><span class="linenos">53</span></a> <span class="n">dialect</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="L-54"><a href="#L-54"><span class="linenos">54</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">parse_identifier</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> </span><span id="L-54"><a href="#L-54"><span class="linenos">54</span></a>
</span><span id="L-55"><a href="#L-55"><span class="linenos">55</span></a> </span><span id="L-55"><a href="#L-55"><span class="linenos">55</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="L-56"><a href="#L-56"><span class="linenos">56</span></a> <span class="k">def</span> <span class="nf">_normalize</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">E</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span> </span><span id="L-56"><a href="#L-56"><span class="linenos">56</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">parse_identifier</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="L-57"><a href="#L-57"><span class="linenos">57</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;case_sensitive&quot;</span><span class="p">):</span> </span><span id="L-57"><a href="#L-57"><span class="linenos">57</span></a>
</span><span id="L-58"><a href="#L-58"><span class="linenos">58</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">replace_children</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">_normalize</span><span class="p">)</span> </span><span id="L-58"><a href="#L-58"><span class="linenos">58</span></a> <span class="k">def</span> <span class="nf">_normalize</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">E</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos">59</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">normalize_identifier</span><span class="p">(</span><span class="n">node</span><span class="p">)</span> </span><span id="L-59"><a href="#L-59"><span class="linenos">59</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;case_sensitive&quot;</span><span class="p">):</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos">60</span></a> <span class="k">return</span> <span class="n">node</span> </span><span id="L-60"><a href="#L-60"><span class="linenos">60</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">replace_children</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">_normalize</span><span class="p">)</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos">61</span></a> </span><span id="L-61"><a href="#L-61"><span class="linenos">61</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">normalize_identifier</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos">62</span></a> <span class="k">return</span> <span class="n">_normalize</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-62"><a href="#L-62"><span class="linenos">62</span></a> <span class="k">return</span> <span class="n">node</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos">63</span></a>
</span><span id="L-64"><a href="#L-64"><span class="linenos">64</span></a> <span class="k">return</span> <span class="n">_normalize</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span></pre></div> </span></pre></div>
@ -133,49 +135,49 @@
</div> </div>
<a class="headerlink" href="#normalize_identifiers"></a> <a class="headerlink" href="#normalize_identifiers"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="normalize_identifiers-21"><a href="#normalize_identifiers-21"><span class="linenos">21</span></a><span class="k">def</span> <span class="nf">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> <div class="pdoc-code codehilite"><pre><span></span><span id="normalize_identifiers-23"><a href="#normalize_identifiers-23"><span class="linenos">23</span></a><span class="k">def</span> <span class="nf">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
</span><span id="normalize_identifiers-22"><a href="#normalize_identifiers-22"><span class="linenos">22</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="normalize_identifiers-24"><a href="#normalize_identifiers-24"><span class="linenos">24</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="normalize_identifiers-23"><a href="#normalize_identifiers-23"><span class="linenos">23</span></a><span class="sd"> Normalize all unquoted identifiers to either lower or upper case, depending</span> </span><span id="normalize_identifiers-25"><a href="#normalize_identifiers-25"><span class="linenos">25</span></a><span class="sd"> Normalize all unquoted identifiers to either lower or upper case, depending</span>
</span><span id="normalize_identifiers-24"><a href="#normalize_identifiers-24"><span class="linenos">24</span></a><span class="sd"> on the dialect. This essentially makes those identifiers case-insensitive.</span> </span><span id="normalize_identifiers-26"><a href="#normalize_identifiers-26"><span class="linenos">26</span></a><span class="sd"> on the dialect. This essentially makes those identifiers case-insensitive.</span>
</span><span id="normalize_identifiers-25"><a href="#normalize_identifiers-25"><span class="linenos">25</span></a> </span><span id="normalize_identifiers-27"><a href="#normalize_identifiers-27"><span class="linenos">27</span></a>
</span><span id="normalize_identifiers-26"><a href="#normalize_identifiers-26"><span class="linenos">26</span></a><span class="sd"> It&#39;s possible to make this a no-op by adding a special comment next to the</span> </span><span id="normalize_identifiers-28"><a href="#normalize_identifiers-28"><span class="linenos">28</span></a><span class="sd"> It&#39;s possible to make this a no-op by adding a special comment next to the</span>
</span><span id="normalize_identifiers-27"><a href="#normalize_identifiers-27"><span class="linenos">27</span></a><span class="sd"> identifier of interest:</span> </span><span id="normalize_identifiers-29"><a href="#normalize_identifiers-29"><span class="linenos">29</span></a><span class="sd"> identifier of interest:</span>
</span><span id="normalize_identifiers-28"><a href="#normalize_identifiers-28"><span class="linenos">28</span></a>
</span><span id="normalize_identifiers-29"><a href="#normalize_identifiers-29"><span class="linenos">29</span></a><span class="sd"> SELECT a /* sqlglot.meta case_sensitive */ FROM table</span>
</span><span id="normalize_identifiers-30"><a href="#normalize_identifiers-30"><span class="linenos">30</span></a> </span><span id="normalize_identifiers-30"><a href="#normalize_identifiers-30"><span class="linenos">30</span></a>
</span><span id="normalize_identifiers-31"><a href="#normalize_identifiers-31"><span class="linenos">31</span></a><span class="sd"> In this example, the identifier `a` will not be normalized.</span> </span><span id="normalize_identifiers-31"><a href="#normalize_identifiers-31"><span class="linenos">31</span></a><span class="sd"> SELECT a /* sqlglot.meta case_sensitive */ FROM table</span>
</span><span id="normalize_identifiers-32"><a href="#normalize_identifiers-32"><span class="linenos">32</span></a> </span><span id="normalize_identifiers-32"><a href="#normalize_identifiers-32"><span class="linenos">32</span></a>
</span><span id="normalize_identifiers-33"><a href="#normalize_identifiers-33"><span class="linenos">33</span></a><span class="sd"> Note:</span> </span><span id="normalize_identifiers-33"><a href="#normalize_identifiers-33"><span class="linenos">33</span></a><span class="sd"> In this example, the identifier `a` will not be normalized.</span>
</span><span id="normalize_identifiers-34"><a href="#normalize_identifiers-34"><span class="linenos">34</span></a><span class="sd"> Some dialects (e.g. BigQuery) treat identifiers as case-insensitive even</span> </span><span id="normalize_identifiers-34"><a href="#normalize_identifiers-34"><span class="linenos">34</span></a>
</span><span id="normalize_identifiers-35"><a href="#normalize_identifiers-35"><span class="linenos">35</span></a><span class="sd"> when they&#39;re quoted, so in these cases all identifiers are normalized.</span> </span><span id="normalize_identifiers-35"><a href="#normalize_identifiers-35"><span class="linenos">35</span></a><span class="sd"> Note:</span>
</span><span id="normalize_identifiers-36"><a href="#normalize_identifiers-36"><span class="linenos">36</span></a> </span><span id="normalize_identifiers-36"><a href="#normalize_identifiers-36"><span class="linenos">36</span></a><span class="sd"> Some dialects (e.g. BigQuery) treat identifiers as case-insensitive even</span>
</span><span id="normalize_identifiers-37"><a href="#normalize_identifiers-37"><span class="linenos">37</span></a><span class="sd"> Example:</span> </span><span id="normalize_identifiers-37"><a href="#normalize_identifiers-37"><span class="linenos">37</span></a><span class="sd"> when they&#39;re quoted, so in these cases all identifiers are normalized.</span>
</span><span id="normalize_identifiers-38"><a href="#normalize_identifiers-38"><span class="linenos">38</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span> </span><span id="normalize_identifiers-38"><a href="#normalize_identifiers-38"><span class="linenos">38</span></a>
</span><span id="normalize_identifiers-39"><a href="#normalize_identifiers-39"><span class="linenos">39</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&#39;SELECT Bar.A AS A FROM &quot;Foo&quot;.Bar&#39;)</span> </span><span id="normalize_identifiers-39"><a href="#normalize_identifiers-39"><span class="linenos">39</span></a><span class="sd"> Example:</span>
</span><span id="normalize_identifiers-40"><a href="#normalize_identifiers-40"><span class="linenos">40</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(expression).sql()</span> </span><span id="normalize_identifiers-40"><a href="#normalize_identifiers-40"><span class="linenos">40</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="normalize_identifiers-41"><a href="#normalize_identifiers-41"><span class="linenos">41</span></a><span class="sd"> &#39;SELECT bar.a AS a FROM &quot;Foo&quot;.bar&#39;</span> </span><span id="normalize_identifiers-41"><a href="#normalize_identifiers-41"><span class="linenos">41</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&#39;SELECT Bar.A AS A FROM &quot;Foo&quot;.Bar&#39;)</span>
</span><span id="normalize_identifiers-42"><a href="#normalize_identifiers-42"><span class="linenos">42</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(&quot;foo&quot;, dialect=&quot;snowflake&quot;).sql(dialect=&quot;snowflake&quot;)</span> </span><span id="normalize_identifiers-42"><a href="#normalize_identifiers-42"><span class="linenos">42</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(expression).sql()</span>
</span><span id="normalize_identifiers-43"><a href="#normalize_identifiers-43"><span class="linenos">43</span></a><span class="sd"> &#39;FOO&#39;</span> </span><span id="normalize_identifiers-43"><a href="#normalize_identifiers-43"><span class="linenos">43</span></a><span class="sd"> &#39;SELECT bar.a AS a FROM &quot;Foo&quot;.bar&#39;</span>
</span><span id="normalize_identifiers-44"><a href="#normalize_identifiers-44"><span class="linenos">44</span></a> </span><span id="normalize_identifiers-44"><a href="#normalize_identifiers-44"><span class="linenos">44</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(&quot;foo&quot;, dialect=&quot;snowflake&quot;).sql(dialect=&quot;snowflake&quot;)</span>
</span><span id="normalize_identifiers-45"><a href="#normalize_identifiers-45"><span class="linenos">45</span></a><span class="sd"> Args:</span> </span><span id="normalize_identifiers-45"><a href="#normalize_identifiers-45"><span class="linenos">45</span></a><span class="sd"> &#39;FOO&#39;</span>
</span><span id="normalize_identifiers-46"><a href="#normalize_identifiers-46"><span class="linenos">46</span></a><span class="sd"> expression: The expression to transform.</span> </span><span id="normalize_identifiers-46"><a href="#normalize_identifiers-46"><span class="linenos">46</span></a>
</span><span id="normalize_identifiers-47"><a href="#normalize_identifiers-47"><span class="linenos">47</span></a><span class="sd"> dialect: The dialect to use in order to decide how to normalize identifiers.</span> </span><span id="normalize_identifiers-47"><a href="#normalize_identifiers-47"><span class="linenos">47</span></a><span class="sd"> Args:</span>
</span><span id="normalize_identifiers-48"><a href="#normalize_identifiers-48"><span class="linenos">48</span></a> </span><span id="normalize_identifiers-48"><a href="#normalize_identifiers-48"><span class="linenos">48</span></a><span class="sd"> expression: The expression to transform.</span>
</span><span id="normalize_identifiers-49"><a href="#normalize_identifiers-49"><span class="linenos">49</span></a><span class="sd"> Returns:</span> </span><span id="normalize_identifiers-49"><a href="#normalize_identifiers-49"><span class="linenos">49</span></a><span class="sd"> dialect: The dialect to use in order to decide how to normalize identifiers.</span>
</span><span id="normalize_identifiers-50"><a href="#normalize_identifiers-50"><span class="linenos">50</span></a><span class="sd"> The transformed expression.</span> </span><span id="normalize_identifiers-50"><a href="#normalize_identifiers-50"><span class="linenos">50</span></a>
</span><span id="normalize_identifiers-51"><a href="#normalize_identifiers-51"><span class="linenos">51</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="normalize_identifiers-51"><a href="#normalize_identifiers-51"><span class="linenos">51</span></a><span class="sd"> Returns:</span>
</span><span id="normalize_identifiers-52"><a href="#normalize_identifiers-52"><span class="linenos">52</span></a> <span class="n">dialect</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span> </span><span id="normalize_identifiers-52"><a href="#normalize_identifiers-52"><span class="linenos">52</span></a><span class="sd"> The transformed expression.</span>
</span><span id="normalize_identifiers-53"><a href="#normalize_identifiers-53"><span class="linenos">53</span></a> </span><span id="normalize_identifiers-53"><a href="#normalize_identifiers-53"><span class="linenos">53</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="normalize_identifiers-54"><a href="#normalize_identifiers-54"><span class="linenos">54</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span> </span><span id="normalize_identifiers-54"><a href="#normalize_identifiers-54"><span class="linenos">54</span></a> <span class="n">dialect</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="normalize_identifiers-55"><a href="#normalize_identifiers-55"><span class="linenos">55</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">parse_identifier</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> </span><span id="normalize_identifiers-55"><a href="#normalize_identifiers-55"><span class="linenos">55</span></a>
</span><span id="normalize_identifiers-56"><a href="#normalize_identifiers-56"><span class="linenos">56</span></a> </span><span id="normalize_identifiers-56"><a href="#normalize_identifiers-56"><span class="linenos">56</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="normalize_identifiers-57"><a href="#normalize_identifiers-57"><span class="linenos">57</span></a> <span class="k">def</span> <span class="nf">_normalize</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">E</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span> </span><span id="normalize_identifiers-57"><a href="#normalize_identifiers-57"><span class="linenos">57</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">parse_identifier</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="normalize_identifiers-58"><a href="#normalize_identifiers-58"><span class="linenos">58</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;case_sensitive&quot;</span><span class="p">):</span> </span><span id="normalize_identifiers-58"><a href="#normalize_identifiers-58"><span class="linenos">58</span></a>
</span><span id="normalize_identifiers-59"><a href="#normalize_identifiers-59"><span class="linenos">59</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">replace_children</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">_normalize</span><span class="p">)</span> </span><span id="normalize_identifiers-59"><a href="#normalize_identifiers-59"><span class="linenos">59</span></a> <span class="k">def</span> <span class="nf">_normalize</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">E</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span>
</span><span id="normalize_identifiers-60"><a href="#normalize_identifiers-60"><span class="linenos">60</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">normalize_identifier</span><span class="p">(</span><span class="n">node</span><span class="p">)</span> </span><span id="normalize_identifiers-60"><a href="#normalize_identifiers-60"><span class="linenos">60</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;case_sensitive&quot;</span><span class="p">):</span>
</span><span id="normalize_identifiers-61"><a href="#normalize_identifiers-61"><span class="linenos">61</span></a> <span class="k">return</span> <span class="n">node</span> </span><span id="normalize_identifiers-61"><a href="#normalize_identifiers-61"><span class="linenos">61</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">replace_children</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">_normalize</span><span class="p">)</span>
</span><span id="normalize_identifiers-62"><a href="#normalize_identifiers-62"><span class="linenos">62</span></a> </span><span id="normalize_identifiers-62"><a href="#normalize_identifiers-62"><span class="linenos">62</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">normalize_identifier</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
</span><span id="normalize_identifiers-63"><a href="#normalize_identifiers-63"><span class="linenos">63</span></a> <span class="k">return</span> <span class="n">_normalize</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="normalize_identifiers-63"><a href="#normalize_identifiers-63"><span class="linenos">63</span></a> <span class="k">return</span> <span class="n">node</span>
</span><span id="normalize_identifiers-64"><a href="#normalize_identifiers-64"><span class="linenos">64</span></a>
</span><span id="normalize_identifiers-65"><a href="#normalize_identifiers-65"><span class="linenos">65</span></a> <span class="k">return</span> <span class="n">_normalize</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span></pre></div> </span></pre></div>

View file

@ -34,7 +34,7 @@
<a class="variable" href="#SELECT_ALL">SELECT_ALL</a> <a class="variable" href="#SELECT_ALL">SELECT_ALL</a>
</li> </li>
<li> <li>
<a class="function" href="#DEFAULT_SELECTION">DEFAULT_SELECTION</a> <a class="function" href="#default_selection">default_selection</a>
</li> </li>
<li> <li>
<a class="function" href="#pushdown_projections">pushdown_projections</a> <a class="function" href="#pushdown_projections">pushdown_projections</a>
@ -72,10 +72,10 @@
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="c1"># Sentinel value that means an outer query selecting ALL columns</span> </span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="c1"># Sentinel value that means an outer query selecting ALL columns</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="n">SELECT_ALL</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span> </span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="n">SELECT_ALL</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span>
</span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a> </span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a>
</span><span id="L-11"><a href="#L-11"><span class="linenos"> 11</span></a><span class="c1"># Selection to use if selection list is empty</span> </span><span id="L-11"><a href="#L-11"><span class="linenos"> 11</span></a>
</span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a><span class="n">DEFAULT_SELECTION</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">is_agg</span><span class="p">:</span> <span class="n">alias</span><span class="p">(</span> </span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a><span class="c1"># Selection to use if selection list is empty</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos"> 13</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Max</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">number</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span> <span class="k">if</span> <span class="n">is_agg</span> <span class="k">else</span> <span class="s2">&quot;1&quot;</span><span class="p">,</span> <span class="s2">&quot;_&quot;</span> </span><span id="L-13"><a href="#L-13"><span class="linenos"> 13</span></a><span class="k">def</span> <span class="nf">default_selection</span><span class="p">(</span><span class="n">is_agg</span><span class="p">:</span> <span class="nb">bool</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Alias</span><span class="p">:</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos"> 14</span></a><span class="p">)</span> </span><span id="L-14"><a href="#L-14"><span class="linenos"> 14</span></a> <span class="k">return</span> <span class="n">alias</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Max</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">number</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span> <span class="k">if</span> <span class="n">is_agg</span> <span class="k">else</span> <span class="s2">&quot;1&quot;</span><span class="p">,</span> <span class="s2">&quot;_&quot;</span><span class="p">)</span>
</span><span id="L-15"><a href="#L-15"><span class="linenos"> 15</span></a> </span><span id="L-15"><a href="#L-15"><span class="linenos"> 15</span></a>
</span><span id="L-16"><a href="#L-16"><span class="linenos"> 16</span></a> </span><span id="L-16"><a href="#L-16"><span class="linenos"> 16</span></a>
</span><span id="L-17"><a href="#L-17"><span class="linenos"> 17</span></a><span class="k">def</span> <span class="nf">pushdown_projections</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">remove_unused_selections</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span> </span><span id="L-17"><a href="#L-17"><span class="linenos"> 17</span></a><span class="k">def</span> <span class="nf">pushdown_projections</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">remove_unused_selections</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
@ -193,7 +193,7 @@
</span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a> </span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a>
</span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a> <span class="c1"># If there are no remaining selections, just select a single constant</span> </span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a> <span class="c1"># If there are no remaining selections, just select a single constant</span>
</span><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">new_selections</span><span class="p">:</span> </span><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">new_selections</span><span class="p">:</span>
</span><span id="L-132"><a href="#L-132"><span class="linenos">132</span></a> <span class="n">new_selections</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">DEFAULT_SELECTION</span><span class="p">(</span><span class="n">is_agg</span><span class="p">))</span> </span><span id="L-132"><a href="#L-132"><span class="linenos">132</span></a> <span class="n">new_selections</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">default_selection</span><span class="p">(</span><span class="n">is_agg</span><span class="p">))</span>
</span><span id="L-133"><a href="#L-133"><span class="linenos">133</span></a> </span><span id="L-133"><a href="#L-133"><span class="linenos">133</span></a>
</span><span id="L-134"><a href="#L-134"><span class="linenos">134</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="o">*</span><span class="n">new_selections</span><span class="p">,</span> <span class="n">append</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> </span><span id="L-134"><a href="#L-134"><span class="linenos">134</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="o">*</span><span class="n">new_selections</span><span class="p">,</span> <span class="n">append</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a> </span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a>
@ -215,20 +215,19 @@
</section> </section>
<section id="DEFAULT_SELECTION"> <section id="default_selection">
<input id="DEFAULT_SELECTION-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="default_selection-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function"> <div class="attr function">
<span class="def">def</span> <span class="def">def</span>
<span class="name">DEFAULT_SELECTION</span><span class="signature pdoc-code condensed">(<span class="param"><span class="n">is_agg</span></span><span class="return-annotation">):</span></span> <span class="name">default_selection</span><span class="signature pdoc-code condensed">(<span class="param"><span class="n">is_agg</span><span class="p">:</span> <span class="nb">bool</span></span><span class="return-annotation">) -> <span class="n"><a href="../expressions.html#Alias">sqlglot.expressions.Alias</a></span>:</span></span>
<label class="view-source-button" for="DEFAULT_SELECTION-view-source"><span>View Source</span></label> <label class="view-source-button" for="default_selection-view-source"><span>View Source</span></label>
</div> </div>
<a class="headerlink" href="#DEFAULT_SELECTION"></a> <a class="headerlink" href="#default_selection"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="DEFAULT_SELECTION-13"><a href="#DEFAULT_SELECTION-13"><span class="linenos">13</span></a><span class="n">DEFAULT_SELECTION</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">is_agg</span><span class="p">:</span> <span class="n">alias</span><span class="p">(</span> <div class="pdoc-code codehilite"><pre><span></span><span id="default_selection-14"><a href="#default_selection-14"><span class="linenos">14</span></a><span class="k">def</span> <span class="nf">default_selection</span><span class="p">(</span><span class="n">is_agg</span><span class="p">:</span> <span class="nb">bool</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Alias</span><span class="p">:</span>
</span><span id="DEFAULT_SELECTION-14"><a href="#DEFAULT_SELECTION-14"><span class="linenos">14</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Max</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">number</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span> <span class="k">if</span> <span class="n">is_agg</span> <span class="k">else</span> <span class="s2">&quot;1&quot;</span><span class="p">,</span> <span class="s2">&quot;_&quot;</span> </span><span id="default_selection-15"><a href="#default_selection-15"><span class="linenos">15</span></a> <span class="k">return</span> <span class="n">alias</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Max</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">number</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span> <span class="k">if</span> <span class="n">is_agg</span> <span class="k">else</span> <span class="s2">&quot;1&quot;</span><span class="p">,</span> <span class="s2">&quot;_&quot;</span><span class="p">)</span>
</span><span id="DEFAULT_SELECTION-15"><a href="#DEFAULT_SELECTION-15"><span class="linenos">15</span></a><span class="p">)</span>
</span></pre></div> </span></pre></div>

File diff suppressed because it is too large Load diff

View file

@ -62,128 +62,130 @@
</span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span> </span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span>
</span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a> </span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a>
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a><span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">alias</span><span class="p">,</span> <span class="n">exp</span> </span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a><span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">alias</span><span class="p">,</span> <span class="n">exp</span>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="kn">from</span> <span class="nn">sqlglot._typing</span> <span class="kn">import</span> <span class="n">E</span> </span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.dialect</span> <span class="kn">import</span> <span class="n">DialectType</span>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="kn">from</span> <span class="nn">sqlglot.dialects.dialect</span> <span class="kn">import</span> <span class="n">DialectType</span> </span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="kn">from</span> <span class="nn">sqlglot.helper</span> <span class="kn">import</span> <span class="n">csv_reader</span><span class="p">,</span> <span class="n">name_sequence</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="kn">from</span> <span class="nn">sqlglot.helper</span> <span class="kn">import</span> <span class="n">csv_reader</span><span class="p">,</span> <span class="n">name_sequence</span> </span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="kn">from</span> <span class="nn">sqlglot.optimizer.scope</span> <span class="kn">import</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">traverse_scope</span>
</span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a><span class="kn">from</span> <span class="nn">sqlglot.optimizer.scope</span> <span class="kn">import</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">traverse_scope</span> </span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a><span class="kn">from</span> <span class="nn">sqlglot.schema</span> <span class="kn">import</span> <span class="n">Schema</span>
</span><span id="L-11"><a href="#L-11"><span class="linenos"> 11</span></a><span class="kn">from</span> <span class="nn">sqlglot.schema</span> <span class="kn">import</span> <span class="n">Schema</span> </span><span id="L-11"><a href="#L-11"><span class="linenos"> 11</span></a>
</span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a> </span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a><span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">TYPE_CHECKING</span><span class="p">:</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos"> 13</span></a> </span><span id="L-13"><a href="#L-13"><span class="linenos"> 13</span></a> <span class="kn">from</span> <span class="nn">sqlglot._typing</span> <span class="kn">import</span> <span class="n">E</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos"> 14</span></a><span class="k">def</span> <span class="nf">qualify_tables</span><span class="p">(</span> </span><span id="L-14"><a href="#L-14"><span class="linenos"> 14</span></a>
</span><span id="L-15"><a href="#L-15"><span class="linenos"> 15</span></a> <span class="n">expression</span><span class="p">:</span> <span class="n">E</span><span class="p">,</span> </span><span id="L-15"><a href="#L-15"><span class="linenos"> 15</span></a>
</span><span id="L-16"><a href="#L-16"><span class="linenos"> 16</span></a> <span class="n">db</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span> <span class="o">|</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="L-16"><a href="#L-16"><span class="linenos"> 16</span></a><span class="k">def</span> <span class="nf">qualify_tables</span><span class="p">(</span>
</span><span id="L-17"><a href="#L-17"><span class="linenos"> 17</span></a> <span class="n">catalog</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span> <span class="o">|</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="L-17"><a href="#L-17"><span class="linenos"> 17</span></a> <span class="n">expression</span><span class="p">:</span> <span class="n">E</span><span class="p">,</span>
</span><span id="L-18"><a href="#L-18"><span class="linenos"> 18</span></a> <span class="n">schema</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">Schema</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="L-18"><a href="#L-18"><span class="linenos"> 18</span></a> <span class="n">db</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span> <span class="o">|</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-19"><a href="#L-19"><span class="linenos"> 19</span></a> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="L-19"><a href="#L-19"><span class="linenos"> 19</span></a> <span class="n">catalog</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span> <span class="o">|</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-20"><a href="#L-20"><span class="linenos"> 20</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span> </span><span id="L-20"><a href="#L-20"><span class="linenos"> 20</span></a> <span class="n">schema</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">Schema</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-21"><a href="#L-21"><span class="linenos"> 21</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-21"><a href="#L-21"><span class="linenos"> 21</span></a> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-22"><a href="#L-22"><span class="linenos"> 22</span></a><span class="sd"> Rewrite sqlglot AST to have fully qualified tables. Join constructs such as</span> </span><span id="L-22"><a href="#L-22"><span class="linenos"> 22</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span>
</span><span id="L-23"><a href="#L-23"><span class="linenos"> 23</span></a><span class="sd"> (t1 JOIN t2) AS t will be expanded into (SELECT * FROM t1 AS t1, t2 AS t2) AS t.</span> </span><span id="L-23"><a href="#L-23"><span class="linenos"> 23</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-24"><a href="#L-24"><span class="linenos"> 24</span></a> </span><span id="L-24"><a href="#L-24"><span class="linenos"> 24</span></a><span class="sd"> Rewrite sqlglot AST to have fully qualified tables. Join constructs such as</span>
</span><span id="L-25"><a href="#L-25"><span class="linenos"> 25</span></a><span class="sd"> Examples:</span> </span><span id="L-25"><a href="#L-25"><span class="linenos"> 25</span></a><span class="sd"> (t1 JOIN t2) AS t will be expanded into (SELECT * FROM t1 AS t1, t2 AS t2) AS t.</span>
</span><span id="L-26"><a href="#L-26"><span class="linenos"> 26</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span> </span><span id="L-26"><a href="#L-26"><span class="linenos"> 26</span></a>
</span><span id="L-27"><a href="#L-27"><span class="linenos"> 27</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT 1 FROM tbl&quot;)</span> </span><span id="L-27"><a href="#L-27"><span class="linenos"> 27</span></a><span class="sd"> Examples:</span>
</span><span id="L-28"><a href="#L-28"><span class="linenos"> 28</span></a><span class="sd"> &gt;&gt;&gt; qualify_tables(expression, db=&quot;db&quot;).sql()</span> </span><span id="L-28"><a href="#L-28"><span class="linenos"> 28</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="L-29"><a href="#L-29"><span class="linenos"> 29</span></a><span class="sd"> &#39;SELECT 1 FROM db.tbl AS tbl&#39;</span> </span><span id="L-29"><a href="#L-29"><span class="linenos"> 29</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT 1 FROM tbl&quot;)</span>
</span><span id="L-30"><a href="#L-30"><span class="linenos"> 30</span></a><span class="sd"> &gt;&gt;&gt;</span> </span><span id="L-30"><a href="#L-30"><span class="linenos"> 30</span></a><span class="sd"> &gt;&gt;&gt; qualify_tables(expression, db=&quot;db&quot;).sql()</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos"> 31</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT 1 FROM (t1 JOIN t2) AS t&quot;)</span> </span><span id="L-31"><a href="#L-31"><span class="linenos"> 31</span></a><span class="sd"> &#39;SELECT 1 FROM db.tbl AS tbl&#39;</span>
</span><span id="L-32"><a href="#L-32"><span class="linenos"> 32</span></a><span class="sd"> &gt;&gt;&gt; qualify_tables(expression).sql()</span> </span><span id="L-32"><a href="#L-32"><span class="linenos"> 32</span></a><span class="sd"> &gt;&gt;&gt;</span>
</span><span id="L-33"><a href="#L-33"><span class="linenos"> 33</span></a><span class="sd"> &#39;SELECT 1 FROM (SELECT * FROM t1 AS t1, t2 AS t2) AS t&#39;</span> </span><span id="L-33"><a href="#L-33"><span class="linenos"> 33</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT 1 FROM (t1 JOIN t2) AS t&quot;)</span>
</span><span id="L-34"><a href="#L-34"><span class="linenos"> 34</span></a> </span><span id="L-34"><a href="#L-34"><span class="linenos"> 34</span></a><span class="sd"> &gt;&gt;&gt; qualify_tables(expression).sql()</span>
</span><span id="L-35"><a href="#L-35"><span class="linenos"> 35</span></a><span class="sd"> Args:</span> </span><span id="L-35"><a href="#L-35"><span class="linenos"> 35</span></a><span class="sd"> &#39;SELECT 1 FROM (SELECT * FROM t1 AS t1, t2 AS t2) AS t&#39;</span>
</span><span id="L-36"><a href="#L-36"><span class="linenos"> 36</span></a><span class="sd"> expression: Expression to qualify</span> </span><span id="L-36"><a href="#L-36"><span class="linenos"> 36</span></a>
</span><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a><span class="sd"> db: Database name</span> </span><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a><span class="sd"> Args:</span>
</span><span id="L-38"><a href="#L-38"><span class="linenos"> 38</span></a><span class="sd"> catalog: Catalog name</span> </span><span id="L-38"><a href="#L-38"><span class="linenos"> 38</span></a><span class="sd"> expression: Expression to qualify</span>
</span><span id="L-39"><a href="#L-39"><span class="linenos"> 39</span></a><span class="sd"> schema: A schema to populate</span> </span><span id="L-39"><a href="#L-39"><span class="linenos"> 39</span></a><span class="sd"> db: Database name</span>
</span><span id="L-40"><a href="#L-40"><span class="linenos"> 40</span></a><span class="sd"> dialect: The dialect to parse catalog and schema into.</span> </span><span id="L-40"><a href="#L-40"><span class="linenos"> 40</span></a><span class="sd"> catalog: Catalog name</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a> </span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a><span class="sd"> schema: A schema to populate</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a><span class="sd"> Returns:</span> </span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a><span class="sd"> dialect: The dialect to parse catalog and schema into.</span>
</span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a><span class="sd"> The qualified expression.</span> </span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a>
</span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a><span class="sd"> Returns:</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a> <span class="n">next_alias_name</span> <span class="o">=</span> <span class="n">name_sequence</span><span class="p">(</span><span class="s2">&quot;_q_&quot;</span><span class="p">)</span> </span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a><span class="sd"> The qualified expression.</span>
</span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a> <span class="n">db</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">parse_identifier</span><span class="p">(</span><span class="n">db</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> <span class="k">if</span> <span class="n">db</span> <span class="k">else</span> <span class="kc">None</span> </span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a> <span class="n">catalog</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">parse_identifier</span><span class="p">(</span><span class="n">catalog</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> <span class="k">if</span> <span class="n">catalog</span> <span class="k">else</span> <span class="kc">None</span> </span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a> <span class="n">next_alias_name</span> <span class="o">=</span> <span class="n">name_sequence</span><span class="p">(</span><span class="s2">&quot;_q_&quot;</span><span class="p">)</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> </span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> <span class="n">db</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">parse_identifier</span><span class="p">(</span><span class="n">db</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> <span class="k">if</span> <span class="n">db</span> <span class="k">else</span> <span class="kc">None</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a> <span class="k">def</span> <span class="nf">_qualify</span><span class="p">(</span><span class="n">table</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span> </span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a> <span class="n">catalog</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">parse_identifier</span><span class="p">(</span><span class="n">catalog</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> <span class="k">if</span> <span class="n">catalog</span> <span class="k">else</span> <span class="kc">None</span>
</span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">table</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">):</span> </span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a>
</span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;db&quot;</span><span class="p">):</span> </span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a> <span class="k">def</span> <span class="nf">_qualify</span><span class="p">(</span><span class="n">table</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a> <span class="n">table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;db&quot;</span><span class="p">,</span> <span class="n">db</span><span class="p">)</span> </span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">table</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">):</span>
</span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;catalog&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;db&quot;</span><span class="p">):</span> </span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;db&quot;</span><span class="p">):</span>
</span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a> <span class="n">table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;catalog&quot;</span><span class="p">,</span> <span class="n">catalog</span><span class="p">)</span> </span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a> <span class="n">table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;db&quot;</span><span class="p">,</span> <span class="n">db</span><span class="p">)</span>
</span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a> </span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;catalog&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;db&quot;</span><span class="p">):</span>
</span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Subqueryable</span><span class="p">):</span> </span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a> <span class="n">table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;catalog&quot;</span><span class="p">,</span> <span class="n">catalog</span><span class="p">)</span>
</span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">prune</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span><span class="p">:</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Unionable</span><span class="p">)):</span> </span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a>
</span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span> </span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Subqueryable</span><span class="p">):</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a> <span class="n">_qualify</span><span class="p">(</span><span class="n">node</span><span class="p">)</span> </span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">prune</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span><span class="p">:</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Unionable</span><span class="p">)):</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a> </span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">traverse_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span> </span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a> <span class="n">_qualify</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a> <span class="k">for</span> <span class="n">derived_table</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="n">scope</span><span class="o">.</span><span class="n">ctes</span><span class="p">,</span> <span class="n">scope</span><span class="o">.</span><span class="n">derived_tables</span><span class="p">):</span> </span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a>
</span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">derived_table</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Subquery</span><span class="p">):</span> </span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">traverse_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
</span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a> <span class="n">unnested</span> <span class="o">=</span> <span class="n">derived_table</span><span class="o">.</span><span class="n">unnest</span><span class="p">()</span> </span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a> <span class="k">for</span> <span class="n">derived_table</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="n">scope</span><span class="o">.</span><span class="n">ctes</span><span class="p">,</span> <span class="n">scope</span><span class="o">.</span><span class="n">derived_tables</span><span class="p">):</span>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">unnested</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span> </span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">derived_table</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Subquery</span><span class="p">):</span>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a> <span class="n">joins</span> <span class="o">=</span> <span class="n">unnested</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> </span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a> <span class="n">unnested</span> <span class="o">=</span> <span class="n">derived_table</span><span class="o">.</span><span class="n">unnest</span><span class="p">()</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a> <span class="n">derived_table</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="s2">&quot;*&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">unnested</span><span class="o">.</span><span class="n">copy</span><span class="p">(),</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">))</span> </span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">unnested</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span>
</span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a> <span class="n">derived_table</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="n">joins</span><span class="p">)</span> </span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a> <span class="n">joins</span> <span class="o">=</span> <span class="n">unnested</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> </span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> <span class="n">derived_table</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="s2">&quot;*&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">unnested</span><span class="o">.</span><span class="n">copy</span><span class="p">(),</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">))</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">derived_table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">):</span> </span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> <span class="n">derived_table</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="n">joins</span><span class="p">)</span>
</span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a> <span class="n">alias_</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span> </span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a>
</span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="n">derived_table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">alias_</span><span class="p">)))</span> </span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">derived_table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">):</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">rename_source</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">alias_</span><span class="p">)</span> </span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="n">alias_</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a> </span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a> <span class="n">derived_table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">alias_</span><span class="p">)))</span>
</span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a> <span class="n">pivots</span> <span class="o">=</span> <span class="n">derived_table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;pivots&quot;</span><span class="p">)</span> </span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">rename_source</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">alias_</span><span class="p">)</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a> <span class="k">if</span> <span class="n">pivots</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span> </span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a>
</span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">())))</span> </span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a> <span class="n">pivots</span> <span class="o">=</span> <span class="n">derived_table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;pivots&quot;</span><span class="p">)</span>
</span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a> </span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a> <span class="k">if</span> <span class="n">pivots</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">source</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> </span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">())))</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span> </span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a>
</span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a> <span class="n">_qualify</span><span class="p">(</span><span class="n">source</span><span class="p">)</span> </span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">source</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> </span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a> <span class="n">pivots</span> <span class="o">=</span> <span class="n">pivots</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;pivots&quot;</span><span class="p">)</span> </span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a> <span class="n">_qualify</span><span class="p">(</span><span class="n">source</span><span class="p">)</span>
</span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">source</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span> </span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a>
</span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a> <span class="c1"># Don&#39;t add the pivot&#39;s alias to the pivoted table, use the table&#39;s name instead</span> </span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a> <span class="n">pivots</span> <span class="o">=</span> <span class="n">pivots</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;pivots&quot;</span><span class="p">)</span>
</span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a> <span class="k">if</span> <span class="n">pivots</span> <span class="ow">and</span> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span> <span class="o">==</span> <span class="n">name</span><span class="p">:</span> </span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">source</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">name</span> </span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> <span class="c1"># Don&#39;t add the pivot&#39;s alias to the pivoted table, use the table&#39;s name instead</span>
</span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> </span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> <span class="k">if</span> <span class="n">pivots</span> <span class="ow">and</span> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span> <span class="o">==</span> <span class="n">name</span><span class="p">:</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="c1"># Mutates the source by attaching an alias to it</span> </span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">name</span>
</span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a> <span class="n">alias</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">name</span> <span class="ow">or</span> <span class="n">source</span><span class="o">.</span><span class="n">name</span> <span class="ow">or</span> <span class="n">next_alias_name</span><span class="p">(),</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">table</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> </span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a>
</span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a> </span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a> <span class="c1"># Mutates the source by attaching an alias to it</span>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="k">if</span> <span class="n">pivots</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span> </span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="n">alias</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">name</span> <span class="ow">or</span> <span class="n">source</span><span class="o">.</span><span class="n">name</span> <span class="ow">or</span> <span class="n">next_alias_name</span><span class="p">(),</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">table</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span> </span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a> <span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">()))</span> </span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a> <span class="k">if</span> <span class="n">pivots</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span>
</span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a> <span class="p">)</span> </span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span>
</span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a> </span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a> <span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">()))</span>
</span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a> <span class="k">if</span> <span class="n">schema</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">ReadCSV</span><span class="p">):</span> </span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a> <span class="p">)</span>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a> <span class="k">with</span> <span class="n">csv_reader</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">this</span><span class="p">)</span> <span class="k">as</span> <span class="n">reader</span><span class="p">:</span> </span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a>
</span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a> <span class="n">header</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">reader</span><span class="p">)</span> </span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a> <span class="k">if</span> <span class="n">schema</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">ReadCSV</span><span class="p">):</span>
</span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a> <span class="n">columns</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">reader</span><span class="p">)</span> </span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a> <span class="k">with</span> <span class="n">csv_reader</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">this</span><span class="p">)</span> <span class="k">as</span> <span class="n">reader</span><span class="p">:</span>
</span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a> <span class="n">schema</span><span class="o">.</span><span class="n">add_table</span><span class="p">(</span> </span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a> <span class="n">header</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">reader</span><span class="p">)</span>
</span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a> <span class="n">source</span><span class="p">,</span> </span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a> <span class="n">columns</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">reader</span><span class="p">)</span>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="nb">type</span><span class="p">(</span><span class="n">v</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">header</span><span class="p">,</span> <span class="n">columns</span><span class="p">)},</span> </span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a> <span class="n">schema</span><span class="o">.</span><span class="n">add_table</span><span class="p">(</span>
</span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a> <span class="n">match_depth</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> </span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a> <span class="n">source</span><span class="p">,</span>
</span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a> <span class="p">)</span> </span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="nb">type</span><span class="p">(</span><span class="n">v</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">header</span><span class="p">,</span> <span class="n">columns</span><span class="p">)},</span>
</span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">Scope</span><span class="p">)</span> <span class="ow">and</span> <span class="n">source</span><span class="o">.</span><span class="n">is_udtf</span><span class="p">:</span> </span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a> <span class="n">match_depth</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="L-107"><a href="#L-107"><span class="linenos">107</span></a> <span class="n">udtf</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">expression</span> </span><span id="L-107"><a href="#L-107"><span class="linenos">107</span></a> <span class="p">)</span>
</span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a> <span class="n">table_alias</span> <span class="o">=</span> <span class="n">udtf</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span> </span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">Scope</span><span class="p">)</span> <span class="ow">and</span> <span class="n">source</span><span class="o">.</span><span class="n">is_udtf</span><span class="p">:</span>
</span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a> <span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">())</span> </span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a> <span class="n">udtf</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">expression</span>
</span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a> <span class="p">)</span> </span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a> <span class="n">table_alias</span> <span class="o">=</span> <span class="n">udtf</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span>
</span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a> <span class="n">udtf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">table_alias</span><span class="p">)</span> </span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a> <span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">())</span>
</span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a> </span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a> <span class="p">)</span>
</span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">table_alias</span><span class="o">.</span><span class="n">name</span><span class="p">:</span> </span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a> <span class="n">udtf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a> <span class="n">table_alias</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;this&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">()))</span> </span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a>
</span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">udtf</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Values</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">table_alias</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span> </span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">table_alias</span><span class="o">.</span><span class="n">name</span><span class="p">:</span>
</span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">e</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">udtf</span><span class="o">.</span><span class="n">expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">expressions</span><span class="p">):</span> </span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a> <span class="n">table_alias</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;this&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">()))</span>
</span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a> <span class="n">table_alias</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;columns&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;_col_</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">))</span> </span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">udtf</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Values</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">table_alias</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="L-118"><a href="#L-118"><span class="linenos">118</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-118"><a href="#L-118"><span class="linenos">118</span></a> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">e</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">udtf</span><span class="o">.</span><span class="n">expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">expressions</span><span class="p">):</span>
</span><span id="L-119"><a href="#L-119"><span class="linenos">119</span></a> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="n">parent</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">walk</span><span class="p">():</span> </span><span id="L-119"><a href="#L-119"><span class="linenos">119</span></a> <span class="n">table_alias</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;columns&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;_col_</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">))</span>
</span><span id="L-120"><a href="#L-120"><span class="linenos">120</span></a> <span class="k">if</span> <span class="p">(</span> </span><span id="L-120"><a href="#L-120"><span class="linenos">120</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-121"><a href="#L-121"><span class="linenos">121</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">)</span> </span><span id="L-121"><a href="#L-121"><span class="linenos">121</span></a> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="n">parent</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">walk</span><span class="p">():</span>
</span><span id="L-122"><a href="#L-122"><span class="linenos">122</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">alias</span> </span><span id="L-122"><a href="#L-122"><span class="linenos">122</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-123"><a href="#L-123"><span class="linenos">123</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">From</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</span><span class="p">))</span> </span><span id="L-123"><a href="#L-123"><span class="linenos">123</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">)</span>
</span><span id="L-124"><a href="#L-124"><span class="linenos">124</span></a> <span class="p">):</span> </span><span id="L-124"><a href="#L-124"><span class="linenos">124</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">alias</span>
</span><span id="L-125"><a href="#L-125"><span class="linenos">125</span></a> <span class="c1"># Mutates the table by attaching an alias to it</span> </span><span id="L-125"><a href="#L-125"><span class="linenos">125</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">From</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</span><span class="p">))</span>
</span><span id="L-126"><a href="#L-126"><span class="linenos">126</span></a> <span class="n">alias</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">table</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> </span><span id="L-126"><a href="#L-126"><span class="linenos">126</span></a> <span class="p">):</span>
</span><span id="L-127"><a href="#L-127"><span class="linenos">127</span></a> </span><span id="L-127"><a href="#L-127"><span class="linenos">127</span></a> <span class="c1"># Mutates the table by attaching an alias to it</span>
</span><span id="L-128"><a href="#L-128"><span class="linenos">128</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="L-128"><a href="#L-128"><span class="linenos">128</span></a> <span class="n">alias</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">table</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a>
</span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div> </span></pre></div>
@ -199,121 +201,121 @@
</div> </div>
<a class="headerlink" href="#qualify_tables"></a> <a class="headerlink" href="#qualify_tables"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="qualify_tables-15"><a href="#qualify_tables-15"><span class="linenos"> 15</span></a><span class="k">def</span> <span class="nf">qualify_tables</span><span class="p">(</span> <div class="pdoc-code codehilite"><pre><span></span><span id="qualify_tables-17"><a href="#qualify_tables-17"><span class="linenos"> 17</span></a><span class="k">def</span> <span class="nf">qualify_tables</span><span class="p">(</span>
</span><span id="qualify_tables-16"><a href="#qualify_tables-16"><span class="linenos"> 16</span></a> <span class="n">expression</span><span class="p">:</span> <span class="n">E</span><span class="p">,</span> </span><span id="qualify_tables-18"><a href="#qualify_tables-18"><span class="linenos"> 18</span></a> <span class="n">expression</span><span class="p">:</span> <span class="n">E</span><span class="p">,</span>
</span><span id="qualify_tables-17"><a href="#qualify_tables-17"><span class="linenos"> 17</span></a> <span class="n">db</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span> <span class="o">|</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="qualify_tables-19"><a href="#qualify_tables-19"><span class="linenos"> 19</span></a> <span class="n">db</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span> <span class="o">|</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="qualify_tables-18"><a href="#qualify_tables-18"><span class="linenos"> 18</span></a> <span class="n">catalog</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span> <span class="o">|</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="qualify_tables-20"><a href="#qualify_tables-20"><span class="linenos"> 20</span></a> <span class="n">catalog</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span> <span class="o">|</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="qualify_tables-19"><a href="#qualify_tables-19"><span class="linenos"> 19</span></a> <span class="n">schema</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">Schema</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="qualify_tables-21"><a href="#qualify_tables-21"><span class="linenos"> 21</span></a> <span class="n">schema</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">Schema</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="qualify_tables-20"><a href="#qualify_tables-20"><span class="linenos"> 20</span></a> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> </span><span id="qualify_tables-22"><a href="#qualify_tables-22"><span class="linenos"> 22</span></a> <span class="n">dialect</span><span class="p">:</span> <span class="n">DialectType</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="qualify_tables-21"><a href="#qualify_tables-21"><span class="linenos"> 21</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span> </span><span id="qualify_tables-23"><a href="#qualify_tables-23"><span class="linenos"> 23</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span>
</span><span id="qualify_tables-22"><a href="#qualify_tables-22"><span class="linenos"> 22</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="qualify_tables-24"><a href="#qualify_tables-24"><span class="linenos"> 24</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="qualify_tables-23"><a href="#qualify_tables-23"><span class="linenos"> 23</span></a><span class="sd"> Rewrite sqlglot AST to have fully qualified tables. Join constructs such as</span> </span><span id="qualify_tables-25"><a href="#qualify_tables-25"><span class="linenos"> 25</span></a><span class="sd"> Rewrite sqlglot AST to have fully qualified tables. Join constructs such as</span>
</span><span id="qualify_tables-24"><a href="#qualify_tables-24"><span class="linenos"> 24</span></a><span class="sd"> (t1 JOIN t2) AS t will be expanded into (SELECT * FROM t1 AS t1, t2 AS t2) AS t.</span> </span><span id="qualify_tables-26"><a href="#qualify_tables-26"><span class="linenos"> 26</span></a><span class="sd"> (t1 JOIN t2) AS t will be expanded into (SELECT * FROM t1 AS t1, t2 AS t2) AS t.</span>
</span><span id="qualify_tables-25"><a href="#qualify_tables-25"><span class="linenos"> 25</span></a> </span><span id="qualify_tables-27"><a href="#qualify_tables-27"><span class="linenos"> 27</span></a>
</span><span id="qualify_tables-26"><a href="#qualify_tables-26"><span class="linenos"> 26</span></a><span class="sd"> Examples:</span> </span><span id="qualify_tables-28"><a href="#qualify_tables-28"><span class="linenos"> 28</span></a><span class="sd"> Examples:</span>
</span><span id="qualify_tables-27"><a href="#qualify_tables-27"><span class="linenos"> 27</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span> </span><span id="qualify_tables-29"><a href="#qualify_tables-29"><span class="linenos"> 29</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="qualify_tables-28"><a href="#qualify_tables-28"><span class="linenos"> 28</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT 1 FROM tbl&quot;)</span> </span><span id="qualify_tables-30"><a href="#qualify_tables-30"><span class="linenos"> 30</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT 1 FROM tbl&quot;)</span>
</span><span id="qualify_tables-29"><a href="#qualify_tables-29"><span class="linenos"> 29</span></a><span class="sd"> &gt;&gt;&gt; qualify_tables(expression, db=&quot;db&quot;).sql()</span> </span><span id="qualify_tables-31"><a href="#qualify_tables-31"><span class="linenos"> 31</span></a><span class="sd"> &gt;&gt;&gt; qualify_tables(expression, db=&quot;db&quot;).sql()</span>
</span><span id="qualify_tables-30"><a href="#qualify_tables-30"><span class="linenos"> 30</span></a><span class="sd"> &#39;SELECT 1 FROM db.tbl AS tbl&#39;</span> </span><span id="qualify_tables-32"><a href="#qualify_tables-32"><span class="linenos"> 32</span></a><span class="sd"> &#39;SELECT 1 FROM db.tbl AS tbl&#39;</span>
</span><span id="qualify_tables-31"><a href="#qualify_tables-31"><span class="linenos"> 31</span></a><span class="sd"> &gt;&gt;&gt;</span> </span><span id="qualify_tables-33"><a href="#qualify_tables-33"><span class="linenos"> 33</span></a><span class="sd"> &gt;&gt;&gt;</span>
</span><span id="qualify_tables-32"><a href="#qualify_tables-32"><span class="linenos"> 32</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT 1 FROM (t1 JOIN t2) AS t&quot;)</span> </span><span id="qualify_tables-34"><a href="#qualify_tables-34"><span class="linenos"> 34</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT 1 FROM (t1 JOIN t2) AS t&quot;)</span>
</span><span id="qualify_tables-33"><a href="#qualify_tables-33"><span class="linenos"> 33</span></a><span class="sd"> &gt;&gt;&gt; qualify_tables(expression).sql()</span> </span><span id="qualify_tables-35"><a href="#qualify_tables-35"><span class="linenos"> 35</span></a><span class="sd"> &gt;&gt;&gt; qualify_tables(expression).sql()</span>
</span><span id="qualify_tables-34"><a href="#qualify_tables-34"><span class="linenos"> 34</span></a><span class="sd"> &#39;SELECT 1 FROM (SELECT * FROM t1 AS t1, t2 AS t2) AS t&#39;</span> </span><span id="qualify_tables-36"><a href="#qualify_tables-36"><span class="linenos"> 36</span></a><span class="sd"> &#39;SELECT 1 FROM (SELECT * FROM t1 AS t1, t2 AS t2) AS t&#39;</span>
</span><span id="qualify_tables-35"><a href="#qualify_tables-35"><span class="linenos"> 35</span></a> </span><span id="qualify_tables-37"><a href="#qualify_tables-37"><span class="linenos"> 37</span></a>
</span><span id="qualify_tables-36"><a href="#qualify_tables-36"><span class="linenos"> 36</span></a><span class="sd"> Args:</span> </span><span id="qualify_tables-38"><a href="#qualify_tables-38"><span class="linenos"> 38</span></a><span class="sd"> Args:</span>
</span><span id="qualify_tables-37"><a href="#qualify_tables-37"><span class="linenos"> 37</span></a><span class="sd"> expression: Expression to qualify</span> </span><span id="qualify_tables-39"><a href="#qualify_tables-39"><span class="linenos"> 39</span></a><span class="sd"> expression: Expression to qualify</span>
</span><span id="qualify_tables-38"><a href="#qualify_tables-38"><span class="linenos"> 38</span></a><span class="sd"> db: Database name</span> </span><span id="qualify_tables-40"><a href="#qualify_tables-40"><span class="linenos"> 40</span></a><span class="sd"> db: Database name</span>
</span><span id="qualify_tables-39"><a href="#qualify_tables-39"><span class="linenos"> 39</span></a><span class="sd"> catalog: Catalog name</span> </span><span id="qualify_tables-41"><a href="#qualify_tables-41"><span class="linenos"> 41</span></a><span class="sd"> catalog: Catalog name</span>
</span><span id="qualify_tables-40"><a href="#qualify_tables-40"><span class="linenos"> 40</span></a><span class="sd"> schema: A schema to populate</span> </span><span id="qualify_tables-42"><a href="#qualify_tables-42"><span class="linenos"> 42</span></a><span class="sd"> schema: A schema to populate</span>
</span><span id="qualify_tables-41"><a href="#qualify_tables-41"><span class="linenos"> 41</span></a><span class="sd"> dialect: The dialect to parse catalog and schema into.</span> </span><span id="qualify_tables-43"><a href="#qualify_tables-43"><span class="linenos"> 43</span></a><span class="sd"> dialect: The dialect to parse catalog and schema into.</span>
</span><span id="qualify_tables-42"><a href="#qualify_tables-42"><span class="linenos"> 42</span></a> </span><span id="qualify_tables-44"><a href="#qualify_tables-44"><span class="linenos"> 44</span></a>
</span><span id="qualify_tables-43"><a href="#qualify_tables-43"><span class="linenos"> 43</span></a><span class="sd"> Returns:</span> </span><span id="qualify_tables-45"><a href="#qualify_tables-45"><span class="linenos"> 45</span></a><span class="sd"> Returns:</span>
</span><span id="qualify_tables-44"><a href="#qualify_tables-44"><span class="linenos"> 44</span></a><span class="sd"> The qualified expression.</span> </span><span id="qualify_tables-46"><a href="#qualify_tables-46"><span class="linenos"> 46</span></a><span class="sd"> The qualified expression.</span>
</span><span id="qualify_tables-45"><a href="#qualify_tables-45"><span class="linenos"> 45</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="qualify_tables-47"><a href="#qualify_tables-47"><span class="linenos"> 47</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="qualify_tables-46"><a href="#qualify_tables-46"><span class="linenos"> 46</span></a> <span class="n">next_alias_name</span> <span class="o">=</span> <span class="n">name_sequence</span><span class="p">(</span><span class="s2">&quot;_q_&quot;</span><span class="p">)</span> </span><span id="qualify_tables-48"><a href="#qualify_tables-48"><span class="linenos"> 48</span></a> <span class="n">next_alias_name</span> <span class="o">=</span> <span class="n">name_sequence</span><span class="p">(</span><span class="s2">&quot;_q_&quot;</span><span class="p">)</span>
</span><span id="qualify_tables-47"><a href="#qualify_tables-47"><span class="linenos"> 47</span></a> <span class="n">db</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">parse_identifier</span><span class="p">(</span><span class="n">db</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> <span class="k">if</span> <span class="n">db</span> <span class="k">else</span> <span class="kc">None</span> </span><span id="qualify_tables-49"><a href="#qualify_tables-49"><span class="linenos"> 49</span></a> <span class="n">db</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">parse_identifier</span><span class="p">(</span><span class="n">db</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> <span class="k">if</span> <span class="n">db</span> <span class="k">else</span> <span class="kc">None</span>
</span><span id="qualify_tables-48"><a href="#qualify_tables-48"><span class="linenos"> 48</span></a> <span class="n">catalog</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">parse_identifier</span><span class="p">(</span><span class="n">catalog</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> <span class="k">if</span> <span class="n">catalog</span> <span class="k">else</span> <span class="kc">None</span> </span><span id="qualify_tables-50"><a href="#qualify_tables-50"><span class="linenos"> 50</span></a> <span class="n">catalog</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">parse_identifier</span><span class="p">(</span><span class="n">catalog</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span> <span class="k">if</span> <span class="n">catalog</span> <span class="k">else</span> <span class="kc">None</span>
</span><span id="qualify_tables-49"><a href="#qualify_tables-49"><span class="linenos"> 49</span></a> </span><span id="qualify_tables-51"><a href="#qualify_tables-51"><span class="linenos"> 51</span></a>
</span><span id="qualify_tables-50"><a href="#qualify_tables-50"><span class="linenos"> 50</span></a> <span class="k">def</span> <span class="nf">_qualify</span><span class="p">(</span><span class="n">table</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span> </span><span id="qualify_tables-52"><a href="#qualify_tables-52"><span class="linenos"> 52</span></a> <span class="k">def</span> <span class="nf">_qualify</span><span class="p">(</span><span class="n">table</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="qualify_tables-51"><a href="#qualify_tables-51"><span class="linenos"> 51</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">table</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">):</span> </span><span id="qualify_tables-53"><a href="#qualify_tables-53"><span class="linenos"> 53</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">table</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Identifier</span><span class="p">):</span>
</span><span id="qualify_tables-52"><a href="#qualify_tables-52"><span class="linenos"> 52</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;db&quot;</span><span class="p">):</span> </span><span id="qualify_tables-54"><a href="#qualify_tables-54"><span class="linenos"> 54</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;db&quot;</span><span class="p">):</span>
</span><span id="qualify_tables-53"><a href="#qualify_tables-53"><span class="linenos"> 53</span></a> <span class="n">table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;db&quot;</span><span class="p">,</span> <span class="n">db</span><span class="p">)</span> </span><span id="qualify_tables-55"><a href="#qualify_tables-55"><span class="linenos"> 55</span></a> <span class="n">table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;db&quot;</span><span class="p">,</span> <span class="n">db</span><span class="p">)</span>
</span><span id="qualify_tables-54"><a href="#qualify_tables-54"><span class="linenos"> 54</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;catalog&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;db&quot;</span><span class="p">):</span> </span><span id="qualify_tables-56"><a href="#qualify_tables-56"><span class="linenos"> 56</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;catalog&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;db&quot;</span><span class="p">):</span>
</span><span id="qualify_tables-55"><a href="#qualify_tables-55"><span class="linenos"> 55</span></a> <span class="n">table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;catalog&quot;</span><span class="p">,</span> <span class="n">catalog</span><span class="p">)</span> </span><span id="qualify_tables-57"><a href="#qualify_tables-57"><span class="linenos"> 57</span></a> <span class="n">table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;catalog&quot;</span><span class="p">,</span> <span class="n">catalog</span><span class="p">)</span>
</span><span id="qualify_tables-56"><a href="#qualify_tables-56"><span class="linenos"> 56</span></a> </span><span id="qualify_tables-58"><a href="#qualify_tables-58"><span class="linenos"> 58</span></a>
</span><span id="qualify_tables-57"><a href="#qualify_tables-57"><span class="linenos"> 57</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Subqueryable</span><span class="p">):</span> </span><span id="qualify_tables-59"><a href="#qualify_tables-59"><span class="linenos"> 59</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Subqueryable</span><span class="p">):</span>
</span><span id="qualify_tables-58"><a href="#qualify_tables-58"><span class="linenos"> 58</span></a> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">prune</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span><span class="p">:</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Unionable</span><span class="p">)):</span> </span><span id="qualify_tables-60"><a href="#qualify_tables-60"><span class="linenos"> 60</span></a> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">prune</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span><span class="p">:</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Unionable</span><span class="p">)):</span>
</span><span id="qualify_tables-59"><a href="#qualify_tables-59"><span class="linenos"> 59</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span> </span><span id="qualify_tables-61"><a href="#qualify_tables-61"><span class="linenos"> 61</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span>
</span><span id="qualify_tables-60"><a href="#qualify_tables-60"><span class="linenos"> 60</span></a> <span class="n">_qualify</span><span class="p">(</span><span class="n">node</span><span class="p">)</span> </span><span id="qualify_tables-62"><a href="#qualify_tables-62"><span class="linenos"> 62</span></a> <span class="n">_qualify</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
</span><span id="qualify_tables-61"><a href="#qualify_tables-61"><span class="linenos"> 61</span></a> </span><span id="qualify_tables-63"><a href="#qualify_tables-63"><span class="linenos"> 63</span></a>
</span><span id="qualify_tables-62"><a href="#qualify_tables-62"><span class="linenos"> 62</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">traverse_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span> </span><span id="qualify_tables-64"><a href="#qualify_tables-64"><span class="linenos"> 64</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">traverse_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
</span><span id="qualify_tables-63"><a href="#qualify_tables-63"><span class="linenos"> 63</span></a> <span class="k">for</span> <span class="n">derived_table</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="n">scope</span><span class="o">.</span><span class="n">ctes</span><span class="p">,</span> <span class="n">scope</span><span class="o">.</span><span class="n">derived_tables</span><span class="p">):</span> </span><span id="qualify_tables-65"><a href="#qualify_tables-65"><span class="linenos"> 65</span></a> <span class="k">for</span> <span class="n">derived_table</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="n">scope</span><span class="o">.</span><span class="n">ctes</span><span class="p">,</span> <span class="n">scope</span><span class="o">.</span><span class="n">derived_tables</span><span class="p">):</span>
</span><span id="qualify_tables-64"><a href="#qualify_tables-64"><span class="linenos"> 64</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">derived_table</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Subquery</span><span class="p">):</span> </span><span id="qualify_tables-66"><a href="#qualify_tables-66"><span class="linenos"> 66</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">derived_table</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Subquery</span><span class="p">):</span>
</span><span id="qualify_tables-65"><a href="#qualify_tables-65"><span class="linenos"> 65</span></a> <span class="n">unnested</span> <span class="o">=</span> <span class="n">derived_table</span><span class="o">.</span><span class="n">unnest</span><span class="p">()</span> </span><span id="qualify_tables-67"><a href="#qualify_tables-67"><span class="linenos"> 67</span></a> <span class="n">unnested</span> <span class="o">=</span> <span class="n">derived_table</span><span class="o">.</span><span class="n">unnest</span><span class="p">()</span>
</span><span id="qualify_tables-66"><a href="#qualify_tables-66"><span class="linenos"> 66</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">unnested</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span> </span><span id="qualify_tables-68"><a href="#qualify_tables-68"><span class="linenos"> 68</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">unnested</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span>
</span><span id="qualify_tables-67"><a href="#qualify_tables-67"><span class="linenos"> 67</span></a> <span class="n">joins</span> <span class="o">=</span> <span class="n">unnested</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> </span><span id="qualify_tables-69"><a href="#qualify_tables-69"><span class="linenos"> 69</span></a> <span class="n">joins</span> <span class="o">=</span> <span class="n">unnested</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="qualify_tables-68"><a href="#qualify_tables-68"><span class="linenos"> 68</span></a> <span class="n">derived_table</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="s2">&quot;*&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">unnested</span><span class="o">.</span><span class="n">copy</span><span class="p">(),</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">))</span> </span><span id="qualify_tables-70"><a href="#qualify_tables-70"><span class="linenos"> 70</span></a> <span class="n">derived_table</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="s2">&quot;*&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">unnested</span><span class="o">.</span><span class="n">copy</span><span class="p">(),</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">))</span>
</span><span id="qualify_tables-69"><a href="#qualify_tables-69"><span class="linenos"> 69</span></a> <span class="n">derived_table</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="n">joins</span><span class="p">)</span> </span><span id="qualify_tables-71"><a href="#qualify_tables-71"><span class="linenos"> 71</span></a> <span class="n">derived_table</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="n">joins</span><span class="p">)</span>
</span><span id="qualify_tables-70"><a href="#qualify_tables-70"><span class="linenos"> 70</span></a> </span><span id="qualify_tables-72"><a href="#qualify_tables-72"><span class="linenos"> 72</span></a>
</span><span id="qualify_tables-71"><a href="#qualify_tables-71"><span class="linenos"> 71</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">derived_table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">):</span> </span><span id="qualify_tables-73"><a href="#qualify_tables-73"><span class="linenos"> 73</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">derived_table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">):</span>
</span><span id="qualify_tables-72"><a href="#qualify_tables-72"><span class="linenos"> 72</span></a> <span class="n">alias_</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span> </span><span id="qualify_tables-74"><a href="#qualify_tables-74"><span class="linenos"> 74</span></a> <span class="n">alias_</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span>
</span><span id="qualify_tables-73"><a href="#qualify_tables-73"><span class="linenos"> 73</span></a> <span class="n">derived_table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">alias_</span><span class="p">)))</span> </span><span id="qualify_tables-75"><a href="#qualify_tables-75"><span class="linenos"> 75</span></a> <span class="n">derived_table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">alias_</span><span class="p">)))</span>
</span><span id="qualify_tables-74"><a href="#qualify_tables-74"><span class="linenos"> 74</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">rename_source</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">alias_</span><span class="p">)</span> </span><span id="qualify_tables-76"><a href="#qualify_tables-76"><span class="linenos"> 76</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">rename_source</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">alias_</span><span class="p">)</span>
</span><span id="qualify_tables-75"><a href="#qualify_tables-75"><span class="linenos"> 75</span></a> </span><span id="qualify_tables-77"><a href="#qualify_tables-77"><span class="linenos"> 77</span></a>
</span><span id="qualify_tables-76"><a href="#qualify_tables-76"><span class="linenos"> 76</span></a> <span class="n">pivots</span> <span class="o">=</span> <span class="n">derived_table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;pivots&quot;</span><span class="p">)</span> </span><span id="qualify_tables-78"><a href="#qualify_tables-78"><span class="linenos"> 78</span></a> <span class="n">pivots</span> <span class="o">=</span> <span class="n">derived_table</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;pivots&quot;</span><span class="p">)</span>
</span><span id="qualify_tables-77"><a href="#qualify_tables-77"><span class="linenos"> 77</span></a> <span class="k">if</span> <span class="n">pivots</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span> </span><span id="qualify_tables-79"><a href="#qualify_tables-79"><span class="linenos"> 79</span></a> <span class="k">if</span> <span class="n">pivots</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span>
</span><span id="qualify_tables-78"><a href="#qualify_tables-78"><span class="linenos"> 78</span></a> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">())))</span> </span><span id="qualify_tables-80"><a href="#qualify_tables-80"><span class="linenos"> 80</span></a> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">())))</span>
</span><span id="qualify_tables-79"><a href="#qualify_tables-79"><span class="linenos"> 79</span></a> </span><span id="qualify_tables-81"><a href="#qualify_tables-81"><span class="linenos"> 81</span></a>
</span><span id="qualify_tables-80"><a href="#qualify_tables-80"><span class="linenos"> 80</span></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">source</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> </span><span id="qualify_tables-82"><a href="#qualify_tables-82"><span class="linenos"> 82</span></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">source</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span><span id="qualify_tables-81"><a href="#qualify_tables-81"><span class="linenos"> 81</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span> </span><span id="qualify_tables-83"><a href="#qualify_tables-83"><span class="linenos"> 83</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span>
</span><span id="qualify_tables-82"><a href="#qualify_tables-82"><span class="linenos"> 82</span></a> <span class="n">_qualify</span><span class="p">(</span><span class="n">source</span><span class="p">)</span> </span><span id="qualify_tables-84"><a href="#qualify_tables-84"><span class="linenos"> 84</span></a> <span class="n">_qualify</span><span class="p">(</span><span class="n">source</span><span class="p">)</span>
</span><span id="qualify_tables-83"><a href="#qualify_tables-83"><span class="linenos"> 83</span></a> </span><span id="qualify_tables-85"><a href="#qualify_tables-85"><span class="linenos"> 85</span></a>
</span><span id="qualify_tables-84"><a href="#qualify_tables-84"><span class="linenos"> 84</span></a> <span class="n">pivots</span> <span class="o">=</span> <span class="n">pivots</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;pivots&quot;</span><span class="p">)</span> </span><span id="qualify_tables-86"><a href="#qualify_tables-86"><span class="linenos"> 86</span></a> <span class="n">pivots</span> <span class="o">=</span> <span class="n">pivots</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;pivots&quot;</span><span class="p">)</span>
</span><span id="qualify_tables-85"><a href="#qualify_tables-85"><span class="linenos"> 85</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">source</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span> </span><span id="qualify_tables-87"><a href="#qualify_tables-87"><span class="linenos"> 87</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">source</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span>
</span><span id="qualify_tables-86"><a href="#qualify_tables-86"><span class="linenos"> 86</span></a> <span class="c1"># Don&#39;t add the pivot&#39;s alias to the pivoted table, use the table&#39;s name instead</span> </span><span id="qualify_tables-88"><a href="#qualify_tables-88"><span class="linenos"> 88</span></a> <span class="c1"># Don&#39;t add the pivot&#39;s alias to the pivoted table, use the table&#39;s name instead</span>
</span><span id="qualify_tables-87"><a href="#qualify_tables-87"><span class="linenos"> 87</span></a> <span class="k">if</span> <span class="n">pivots</span> <span class="ow">and</span> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span> <span class="o">==</span> <span class="n">name</span><span class="p">:</span> </span><span id="qualify_tables-89"><a href="#qualify_tables-89"><span class="linenos"> 89</span></a> <span class="k">if</span> <span class="n">pivots</span> <span class="ow">and</span> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span> <span class="o">==</span> <span class="n">name</span><span class="p">:</span>
</span><span id="qualify_tables-88"><a href="#qualify_tables-88"><span class="linenos"> 88</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">name</span> </span><span id="qualify_tables-90"><a href="#qualify_tables-90"><span class="linenos"> 90</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">name</span>
</span><span id="qualify_tables-89"><a href="#qualify_tables-89"><span class="linenos"> 89</span></a> </span><span id="qualify_tables-91"><a href="#qualify_tables-91"><span class="linenos"> 91</span></a>
</span><span id="qualify_tables-90"><a href="#qualify_tables-90"><span class="linenos"> 90</span></a> <span class="c1"># Mutates the source by attaching an alias to it</span> </span><span id="qualify_tables-92"><a href="#qualify_tables-92"><span class="linenos"> 92</span></a> <span class="c1"># Mutates the source by attaching an alias to it</span>
</span><span id="qualify_tables-91"><a href="#qualify_tables-91"><span class="linenos"> 91</span></a> <span class="n">alias</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">name</span> <span class="ow">or</span> <span class="n">source</span><span class="o">.</span><span class="n">name</span> <span class="ow">or</span> <span class="n">next_alias_name</span><span class="p">(),</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">table</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> </span><span id="qualify_tables-93"><a href="#qualify_tables-93"><span class="linenos"> 93</span></a> <span class="n">alias</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">name</span> <span class="ow">or</span> <span class="n">source</span><span class="o">.</span><span class="n">name</span> <span class="ow">or</span> <span class="n">next_alias_name</span><span class="p">(),</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">table</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="qualify_tables-92"><a href="#qualify_tables-92"><span class="linenos"> 92</span></a> </span><span id="qualify_tables-94"><a href="#qualify_tables-94"><span class="linenos"> 94</span></a>
</span><span id="qualify_tables-93"><a href="#qualify_tables-93"><span class="linenos"> 93</span></a> <span class="k">if</span> <span class="n">pivots</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span> </span><span id="qualify_tables-95"><a href="#qualify_tables-95"><span class="linenos"> 95</span></a> <span class="k">if</span> <span class="n">pivots</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span>
</span><span id="qualify_tables-94"><a href="#qualify_tables-94"><span class="linenos"> 94</span></a> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span> </span><span id="qualify_tables-96"><a href="#qualify_tables-96"><span class="linenos"> 96</span></a> <span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span>
</span><span id="qualify_tables-95"><a href="#qualify_tables-95"><span class="linenos"> 95</span></a> <span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">()))</span> </span><span id="qualify_tables-97"><a href="#qualify_tables-97"><span class="linenos"> 97</span></a> <span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">()))</span>
</span><span id="qualify_tables-96"><a href="#qualify_tables-96"><span class="linenos"> 96</span></a> <span class="p">)</span> </span><span id="qualify_tables-98"><a href="#qualify_tables-98"><span class="linenos"> 98</span></a> <span class="p">)</span>
</span><span id="qualify_tables-97"><a href="#qualify_tables-97"><span class="linenos"> 97</span></a> </span><span id="qualify_tables-99"><a href="#qualify_tables-99"><span class="linenos"> 99</span></a>
</span><span id="qualify_tables-98"><a href="#qualify_tables-98"><span class="linenos"> 98</span></a> <span class="k">if</span> <span class="n">schema</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">ReadCSV</span><span class="p">):</span> </span><span id="qualify_tables-100"><a href="#qualify_tables-100"><span class="linenos">100</span></a> <span class="k">if</span> <span class="n">schema</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">ReadCSV</span><span class="p">):</span>
</span><span id="qualify_tables-99"><a href="#qualify_tables-99"><span class="linenos"> 99</span></a> <span class="k">with</span> <span class="n">csv_reader</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">this</span><span class="p">)</span> <span class="k">as</span> <span class="n">reader</span><span class="p">:</span> </span><span id="qualify_tables-101"><a href="#qualify_tables-101"><span class="linenos">101</span></a> <span class="k">with</span> <span class="n">csv_reader</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">this</span><span class="p">)</span> <span class="k">as</span> <span class="n">reader</span><span class="p">:</span>
</span><span id="qualify_tables-100"><a href="#qualify_tables-100"><span class="linenos">100</span></a> <span class="n">header</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">reader</span><span class="p">)</span> </span><span id="qualify_tables-102"><a href="#qualify_tables-102"><span class="linenos">102</span></a> <span class="n">header</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">reader</span><span class="p">)</span>
</span><span id="qualify_tables-101"><a href="#qualify_tables-101"><span class="linenos">101</span></a> <span class="n">columns</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">reader</span><span class="p">)</span> </span><span id="qualify_tables-103"><a href="#qualify_tables-103"><span class="linenos">103</span></a> <span class="n">columns</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">reader</span><span class="p">)</span>
</span><span id="qualify_tables-102"><a href="#qualify_tables-102"><span class="linenos">102</span></a> <span class="n">schema</span><span class="o">.</span><span class="n">add_table</span><span class="p">(</span> </span><span id="qualify_tables-104"><a href="#qualify_tables-104"><span class="linenos">104</span></a> <span class="n">schema</span><span class="o">.</span><span class="n">add_table</span><span class="p">(</span>
</span><span id="qualify_tables-103"><a href="#qualify_tables-103"><span class="linenos">103</span></a> <span class="n">source</span><span class="p">,</span> </span><span id="qualify_tables-105"><a href="#qualify_tables-105"><span class="linenos">105</span></a> <span class="n">source</span><span class="p">,</span>
</span><span id="qualify_tables-104"><a href="#qualify_tables-104"><span class="linenos">104</span></a> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="nb">type</span><span class="p">(</span><span class="n">v</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">header</span><span class="p">,</span> <span class="n">columns</span><span class="p">)},</span> </span><span id="qualify_tables-106"><a href="#qualify_tables-106"><span class="linenos">106</span></a> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="nb">type</span><span class="p">(</span><span class="n">v</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">header</span><span class="p">,</span> <span class="n">columns</span><span class="p">)},</span>
</span><span id="qualify_tables-105"><a href="#qualify_tables-105"><span class="linenos">105</span></a> <span class="n">match_depth</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> </span><span id="qualify_tables-107"><a href="#qualify_tables-107"><span class="linenos">107</span></a> <span class="n">match_depth</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="qualify_tables-106"><a href="#qualify_tables-106"><span class="linenos">106</span></a> <span class="p">)</span> </span><span id="qualify_tables-108"><a href="#qualify_tables-108"><span class="linenos">108</span></a> <span class="p">)</span>
</span><span id="qualify_tables-107"><a href="#qualify_tables-107"><span class="linenos">107</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">Scope</span><span class="p">)</span> <span class="ow">and</span> <span class="n">source</span><span class="o">.</span><span class="n">is_udtf</span><span class="p">:</span> </span><span id="qualify_tables-109"><a href="#qualify_tables-109"><span class="linenos">109</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">Scope</span><span class="p">)</span> <span class="ow">and</span> <span class="n">source</span><span class="o">.</span><span class="n">is_udtf</span><span class="p">:</span>
</span><span id="qualify_tables-108"><a href="#qualify_tables-108"><span class="linenos">108</span></a> <span class="n">udtf</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">expression</span> </span><span id="qualify_tables-110"><a href="#qualify_tables-110"><span class="linenos">110</span></a> <span class="n">udtf</span> <span class="o">=</span> <span class="n">source</span><span class="o">.</span><span class="n">expression</span>
</span><span id="qualify_tables-109"><a href="#qualify_tables-109"><span class="linenos">109</span></a> <span class="n">table_alias</span> <span class="o">=</span> <span class="n">udtf</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span> </span><span id="qualify_tables-111"><a href="#qualify_tables-111"><span class="linenos">111</span></a> <span class="n">table_alias</span> <span class="o">=</span> <span class="n">udtf</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span>
</span><span id="qualify_tables-110"><a href="#qualify_tables-110"><span class="linenos">110</span></a> <span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">())</span> </span><span id="qualify_tables-112"><a href="#qualify_tables-112"><span class="linenos">112</span></a> <span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">())</span>
</span><span id="qualify_tables-111"><a href="#qualify_tables-111"><span class="linenos">111</span></a> <span class="p">)</span> </span><span id="qualify_tables-113"><a href="#qualify_tables-113"><span class="linenos">113</span></a> <span class="p">)</span>
</span><span id="qualify_tables-112"><a href="#qualify_tables-112"><span class="linenos">112</span></a> <span class="n">udtf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">table_alias</span><span class="p">)</span> </span><span id="qualify_tables-114"><a href="#qualify_tables-114"><span class="linenos">114</span></a> <span class="n">udtf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="qualify_tables-113"><a href="#qualify_tables-113"><span class="linenos">113</span></a> </span><span id="qualify_tables-115"><a href="#qualify_tables-115"><span class="linenos">115</span></a>
</span><span id="qualify_tables-114"><a href="#qualify_tables-114"><span class="linenos">114</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">table_alias</span><span class="o">.</span><span class="n">name</span><span class="p">:</span> </span><span id="qualify_tables-116"><a href="#qualify_tables-116"><span class="linenos">116</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">table_alias</span><span class="o">.</span><span class="n">name</span><span class="p">:</span>
</span><span id="qualify_tables-115"><a href="#qualify_tables-115"><span class="linenos">115</span></a> <span class="n">table_alias</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;this&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">()))</span> </span><span id="qualify_tables-117"><a href="#qualify_tables-117"><span class="linenos">117</span></a> <span class="n">table_alias</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;this&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">next_alias_name</span><span class="p">()))</span>
</span><span id="qualify_tables-116"><a href="#qualify_tables-116"><span class="linenos">116</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">udtf</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Values</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">table_alias</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span> </span><span id="qualify_tables-118"><a href="#qualify_tables-118"><span class="linenos">118</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">udtf</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Values</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">table_alias</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="qualify_tables-117"><a href="#qualify_tables-117"><span class="linenos">117</span></a> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">e</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">udtf</span><span class="o">.</span><span class="n">expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">expressions</span><span class="p">):</span> </span><span id="qualify_tables-119"><a href="#qualify_tables-119"><span class="linenos">119</span></a> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">e</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">udtf</span><span class="o">.</span><span class="n">expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">expressions</span><span class="p">):</span>
</span><span id="qualify_tables-118"><a href="#qualify_tables-118"><span class="linenos">118</span></a> <span class="n">table_alias</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;columns&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;_col_</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">))</span> </span><span id="qualify_tables-120"><a href="#qualify_tables-120"><span class="linenos">120</span></a> <span class="n">table_alias</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;columns&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;_col_</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">))</span>
</span><span id="qualify_tables-119"><a href="#qualify_tables-119"><span class="linenos">119</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="qualify_tables-121"><a href="#qualify_tables-121"><span class="linenos">121</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="qualify_tables-120"><a href="#qualify_tables-120"><span class="linenos">120</span></a> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="n">parent</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">walk</span><span class="p">():</span> </span><span id="qualify_tables-122"><a href="#qualify_tables-122"><span class="linenos">122</span></a> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="n">parent</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">walk</span><span class="p">():</span>
</span><span id="qualify_tables-121"><a href="#qualify_tables-121"><span class="linenos">121</span></a> <span class="k">if</span> <span class="p">(</span> </span><span id="qualify_tables-123"><a href="#qualify_tables-123"><span class="linenos">123</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="qualify_tables-122"><a href="#qualify_tables-122"><span class="linenos">122</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">)</span> </span><span id="qualify_tables-124"><a href="#qualify_tables-124"><span class="linenos">124</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">)</span>
</span><span id="qualify_tables-123"><a href="#qualify_tables-123"><span class="linenos">123</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">alias</span> </span><span id="qualify_tables-125"><a href="#qualify_tables-125"><span class="linenos">125</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">alias</span>
</span><span id="qualify_tables-124"><a href="#qualify_tables-124"><span class="linenos">124</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">From</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</span><span class="p">))</span> </span><span id="qualify_tables-126"><a href="#qualify_tables-126"><span class="linenos">126</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">From</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</span><span class="p">))</span>
</span><span id="qualify_tables-125"><a href="#qualify_tables-125"><span class="linenos">125</span></a> <span class="p">):</span> </span><span id="qualify_tables-127"><a href="#qualify_tables-127"><span class="linenos">127</span></a> <span class="p">):</span>
</span><span id="qualify_tables-126"><a href="#qualify_tables-126"><span class="linenos">126</span></a> <span class="c1"># Mutates the table by attaching an alias to it</span> </span><span id="qualify_tables-128"><a href="#qualify_tables-128"><span class="linenos">128</span></a> <span class="c1"># Mutates the table by attaching an alias to it</span>
</span><span id="qualify_tables-127"><a href="#qualify_tables-127"><span class="linenos">127</span></a> <span class="n">alias</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">table</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> </span><span id="qualify_tables-129"><a href="#qualify_tables-129"><span class="linenos">129</span></a> <span class="n">alias</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">table</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="qualify_tables-128"><a href="#qualify_tables-128"><span class="linenos">128</span></a> </span><span id="qualify_tables-130"><a href="#qualify_tables-130"><span class="linenos">130</span></a>
</span><span id="qualify_tables-129"><a href="#qualify_tables-129"><span class="linenos">129</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="qualify_tables-131"><a href="#qualify_tables-131"><span class="linenos">131</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div> </span></pre></div>

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -591,8 +591,8 @@
</span><span id="L-485"><a href="#L-485"><span class="linenos">485</span></a> <span class="n">expression_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-485"><a href="#L-485"><span class="linenos">485</span></a> <span class="n">expression_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-486"><a href="#L-486"><span class="linenos">486</span></a> </span><span id="L-486"><a href="#L-486"><span class="linenos">486</span></a>
</span><span id="L-487"><a href="#L-487"><span class="linenos">487</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-487"><a href="#L-487"><span class="linenos">487</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-488"><a href="#L-488"><span class="linenos">488</span></a> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span> </span><span id="L-488"><a href="#L-488"><span class="linenos">488</span></a> <span class="k">for</span> <span class="n">transform</span> <span class="ow">in</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
</span><span id="L-489"><a href="#L-489"><span class="linenos">489</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">t</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-489"><a href="#L-489"><span class="linenos">489</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-490"><a href="#L-490"><span class="linenos">490</span></a> </span><span id="L-490"><a href="#L-490"><span class="linenos">490</span></a>
</span><span id="L-491"><a href="#L-491"><span class="linenos">491</span></a> <span class="n">_sql_handler</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">key</span> <span class="o">+</span> <span class="s2">&quot;_sql&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> </span><span id="L-491"><a href="#L-491"><span class="linenos">491</span></a> <span class="n">_sql_handler</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">key</span> <span class="o">+</span> <span class="s2">&quot;_sql&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="L-492"><a href="#L-492"><span class="linenos">492</span></a> <span class="k">if</span> <span class="n">_sql_handler</span><span class="p">:</span> </span><span id="L-492"><a href="#L-492"><span class="linenos">492</span></a> <span class="k">if</span> <span class="n">_sql_handler</span><span class="p">:</span>
@ -1426,8 +1426,8 @@ moved to the top level so that the final SQL code is valid from a syntax standpo
</span><span id="preprocess-486"><a href="#preprocess-486"><span class="linenos">486</span></a> <span class="n">expression_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="preprocess-486"><a href="#preprocess-486"><span class="linenos">486</span></a> <span class="n">expression_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="preprocess-487"><a href="#preprocess-487"><span class="linenos">487</span></a> </span><span id="preprocess-487"><a href="#preprocess-487"><span class="linenos">487</span></a>
</span><span id="preprocess-488"><a href="#preprocess-488"><span class="linenos">488</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">expression</span><span class="p">)</span> </span><span id="preprocess-488"><a href="#preprocess-488"><span class="linenos">488</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">expression</span><span class="p">)</span>
</span><span id="preprocess-489"><a href="#preprocess-489"><span class="linenos">489</span></a> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span> </span><span id="preprocess-489"><a href="#preprocess-489"><span class="linenos">489</span></a> <span class="k">for</span> <span class="n">transform</span> <span class="ow">in</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
</span><span id="preprocess-490"><a href="#preprocess-490"><span class="linenos">490</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">t</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="preprocess-490"><a href="#preprocess-490"><span class="linenos">490</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">transform</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="preprocess-491"><a href="#preprocess-491"><span class="linenos">491</span></a> </span><span id="preprocess-491"><a href="#preprocess-491"><span class="linenos">491</span></a>
</span><span id="preprocess-492"><a href="#preprocess-492"><span class="linenos">492</span></a> <span class="n">_sql_handler</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">key</span> <span class="o">+</span> <span class="s2">&quot;_sql&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> </span><span id="preprocess-492"><a href="#preprocess-492"><span class="linenos">492</span></a> <span class="n">_sql_handler</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">key</span> <span class="o">+</span> <span class="s2">&quot;_sql&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="preprocess-493"><a href="#preprocess-493"><span class="linenos">493</span></a> <span class="k">if</span> <span class="n">_sql_handler</span><span class="p">:</span> </span><span id="preprocess-493"><a href="#preprocess-493"><span class="linenos">493</span></a> <span class="k">if</span> <span class="n">_sql_handler</span><span class="p">:</span>

View file

@ -7,7 +7,7 @@ from unittest import mock
from pdoc.__main__ import cli, parser from pdoc.__main__ import cli, parser
# Need this import or else import_module doesn't work # Need this import or else import_module doesn't work
import sqlglot import sqlglot # noqa
def mocked_import(*args, **kwargs): def mocked_import(*args, **kwargs):

View file

@ -29,16 +29,14 @@ setup(
python_requires=">=3.7", python_requires=">=3.7",
extras_require={ extras_require={
"dev": [ "dev": [
"autoflake",
"black",
"duckdb>=0.6", "duckdb>=0.6",
"isort", "mypy",
"mypy>=0.990",
"pandas", "pandas",
"pyspark", "pyspark",
"python-dateutil", "python-dateutil",
"pdoc", "pdoc",
"pre-commit", "pre-commit",
"ruff",
"types-python-dateutil", "types-python-dateutil",
"typing_extensions", "typing_extensions",
"maturin>=1.4,<2.0", "maturin>=1.4,<2.0",

View file

@ -1,3 +1,4 @@
# ruff: noqa: F401
""" """
.. include:: ../README.md .. include:: ../README.md
@ -87,11 +88,13 @@ def parse(
@t.overload @t.overload
def parse_one(sql: str, *, into: t.Type[E], **opts) -> E: ... def parse_one(sql: str, *, into: t.Type[E], **opts) -> E:
...
@t.overload @t.overload
def parse_one(sql: str, **opts) -> Expression: ... def parse_one(sql: str, **opts) -> Expression:
...
def parse_one( def parse_one(

View file

@ -13,4 +13,5 @@ if t.TYPE_CHECKING:
A = t.TypeVar("A", bound=t.Any) A = t.TypeVar("A", bound=t.Any)
B = t.TypeVar("B", bound="sqlglot.exp.Binary") B = t.TypeVar("B", bound="sqlglot.exp.Binary")
E = t.TypeVar("E", bound="sqlglot.exp.Expression") E = t.TypeVar("E", bound="sqlglot.exp.Expression")
F = t.TypeVar("F", bound="sqlglot.exp.Func")
T = t.TypeVar("T") T = t.TypeVar("T")

View file

@ -140,10 +140,12 @@ class DataFrame:
return cte, name return cte, name
@t.overload @t.overload
def _ensure_list_of_columns(self, cols: t.Collection[ColumnOrLiteral]) -> t.List[Column]: ... def _ensure_list_of_columns(self, cols: t.Collection[ColumnOrLiteral]) -> t.List[Column]:
...
@t.overload @t.overload
def _ensure_list_of_columns(self, cols: ColumnOrLiteral) -> t.List[Column]: ... def _ensure_list_of_columns(self, cols: ColumnOrLiteral) -> t.List[Column]:
...
def _ensure_list_of_columns(self, cols): def _ensure_list_of_columns(self, cols):
return Column.ensure_cols(ensure_list(cols)) return Column.ensure_cols(ensure_list(cols))

View file

@ -368,7 +368,10 @@ def covar_samp(col1: ColumnOrName, col2: ColumnOrName) -> Column:
def first(col: ColumnOrName, ignorenulls: t.Optional[bool] = None) -> Column: def first(col: ColumnOrName, ignorenulls: t.Optional[bool] = None) -> Column:
return Column.invoke_expression_over_column(col, expression.First, ignore_nulls=ignorenulls) this = Column.invoke_expression_over_column(col, expression.First)
if ignorenulls:
return Column.invoke_expression_over_column(this, expression.IgnoreNulls)
return this
def grouping_id(*cols: ColumnOrName) -> Column: def grouping_id(*cols: ColumnOrName) -> Column:
@ -392,7 +395,10 @@ def isnull(col: ColumnOrName) -> Column:
def last(col: ColumnOrName, ignorenulls: t.Optional[bool] = None) -> Column: def last(col: ColumnOrName, ignorenulls: t.Optional[bool] = None) -> Column:
return Column.invoke_expression_over_column(col, expression.Last, ignore_nulls=ignorenulls) this = Column.invoke_expression_over_column(col, expression.Last)
if ignorenulls:
return Column.invoke_expression_over_column(this, expression.IgnoreNulls)
return this
def monotonically_increasing_id() -> Column: def monotonically_increasing_id() -> Column:
@ -485,31 +491,28 @@ def factorial(col: ColumnOrName) -> Column:
def lag( def lag(
col: ColumnOrName, offset: t.Optional[int] = 1, default: t.Optional[ColumnOrLiteral] = None col: ColumnOrName, offset: t.Optional[int] = 1, default: t.Optional[ColumnOrLiteral] = None
) -> Column: ) -> Column:
if default is not None: return Column.invoke_expression_over_column(
return Column.invoke_anonymous_function(col, "LAG", offset, default) col, expression.Lag, offset=None if offset == 1 else offset, default=default
if offset != 1: )
return Column.invoke_anonymous_function(col, "LAG", offset)
return Column.invoke_anonymous_function(col, "LAG")
def lead( def lead(
col: ColumnOrName, offset: t.Optional[int] = 1, default: t.Optional[t.Any] = None col: ColumnOrName, offset: t.Optional[int] = 1, default: t.Optional[t.Any] = None
) -> Column: ) -> Column:
if default is not None: return Column.invoke_expression_over_column(
return Column.invoke_anonymous_function(col, "LEAD", offset, default) col, expression.Lead, offset=None if offset == 1 else offset, default=default
if offset != 1: )
return Column.invoke_anonymous_function(col, "LEAD", offset)
return Column.invoke_anonymous_function(col, "LEAD")
def nth_value( def nth_value(
col: ColumnOrName, offset: t.Optional[int] = 1, ignoreNulls: t.Optional[bool] = None col: ColumnOrName, offset: t.Optional[int] = 1, ignoreNulls: t.Optional[bool] = None
) -> Column: ) -> Column:
this = Column.invoke_expression_over_column(
col, expression.NthValue, offset=None if offset == 1 else offset
)
if ignoreNulls is not None: if ignoreNulls is not None:
raise NotImplementedError("There is currently not support for `ignoreNulls` parameter") return Column.invoke_expression_over_column(this, expression.IgnoreNulls)
if offset != 1: return this
return Column.invoke_anonymous_function(col, "NTH_VALUE", offset)
return Column.invoke_anonymous_function(col, "NTH_VALUE")
def ntile(n: int) -> Column: def ntile(n: int) -> Column:

View file

@ -1,9 +1,10 @@
# ruff: noqa: F401
""" """
## Dialects ## Dialects
While there is a SQL standard, most SQL engines support a variation of that standard. This makes it difficult While there is a SQL standard, most SQL engines support a variation of that standard. This makes it difficult
to write portable SQL code. SQLGlot bridges all the different variations, called "dialects", with an extensible to write portable SQL code. SQLGlot bridges all the different variations, called "dialects", with an extensible
SQL transpilation framework. SQL transpilation framework.
The base `sqlglot.dialects.dialect.Dialect` class implements a generic dialect that aims to be as universal as possible. The base `sqlglot.dialects.dialect.Dialect` class implements a generic dialect that aims to be as universal as possible.

View file

@ -19,7 +19,6 @@ from sqlglot.dialects.dialect import (
min_or_least, min_or_least,
no_ilike_sql, no_ilike_sql,
parse_date_delta_with_interval, parse_date_delta_with_interval,
path_to_jsonpath,
regexp_replace_sql, regexp_replace_sql,
rename_func, rename_func,
timestrtotime_sql, timestrtotime_sql,
@ -458,8 +457,10 @@ class BigQuery(Dialect):
return this return this
def _parse_table_parts(self, schema: bool = False) -> exp.Table: def _parse_table_parts(
table = super()._parse_table_parts(schema=schema) self, schema: bool = False, is_db_reference: bool = False
) -> exp.Table:
table = super()._parse_table_parts(schema=schema, is_db_reference=is_db_reference)
if isinstance(table.this, exp.Identifier) and "." in table.name: if isinstance(table.this, exp.Identifier) and "." in table.name:
catalog, db, this, *rest = ( catalog, db, this, *rest = (
t.cast(t.Optional[exp.Expression], exp.to_identifier(x)) t.cast(t.Optional[exp.Expression], exp.to_identifier(x))
@ -474,10 +475,12 @@ class BigQuery(Dialect):
return table return table
@t.overload @t.overload
def _parse_json_object(self, agg: Lit[False]) -> exp.JSONObject: ... def _parse_json_object(self, agg: Lit[False]) -> exp.JSONObject:
...
@t.overload @t.overload
def _parse_json_object(self, agg: Lit[True]) -> exp.JSONObjectAgg: ... def _parse_json_object(self, agg: Lit[True]) -> exp.JSONObjectAgg:
...
def _parse_json_object(self, agg=False): def _parse_json_object(self, agg=False):
json_object = super()._parse_json_object() json_object = super()._parse_json_object()
@ -536,6 +539,8 @@ class BigQuery(Dialect):
UNPIVOT_ALIASES_ARE_IDENTIFIERS = False UNPIVOT_ALIASES_ARE_IDENTIFIERS = False
JSON_KEY_VALUE_PAIR_SEP = "," JSON_KEY_VALUE_PAIR_SEP = ","
NULL_ORDERING_SUPPORTED = False NULL_ORDERING_SUPPORTED = False
IGNORE_NULLS_IN_FUNC = True
JSON_PATH_SINGLE_QUOTE_ESCAPE = True
TRANSFORMS = { TRANSFORMS = {
**generator.Generator.TRANSFORMS, **generator.Generator.TRANSFORMS,
@ -554,7 +559,8 @@ class BigQuery(Dialect):
exp.Create: _create_sql, exp.Create: _create_sql,
exp.CTE: transforms.preprocess([_pushdown_cte_column_names]), exp.CTE: transforms.preprocess([_pushdown_cte_column_names]),
exp.DateAdd: date_add_interval_sql("DATE", "ADD"), exp.DateAdd: date_add_interval_sql("DATE", "ADD"),
exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})", exp.DateDiff: lambda self,
e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})",
exp.DateFromParts: rename_func("DATE"), exp.DateFromParts: rename_func("DATE"),
exp.DateStrToDate: datestrtodate_sql, exp.DateStrToDate: datestrtodate_sql,
exp.DateSub: date_add_interval_sql("DATE", "SUB"), exp.DateSub: date_add_interval_sql("DATE", "SUB"),
@ -565,7 +571,6 @@ class BigQuery(Dialect):
"DATETIME", self.func("TIMESTAMP", e.this, e.args.get("zone")), "'UTC'" "DATETIME", self.func("TIMESTAMP", e.this, e.args.get("zone")), "'UTC'"
), ),
exp.GenerateSeries: rename_func("GENERATE_ARRAY"), exp.GenerateSeries: rename_func("GENERATE_ARRAY"),
exp.GetPath: path_to_jsonpath(),
exp.GroupConcat: rename_func("STRING_AGG"), exp.GroupConcat: rename_func("STRING_AGG"),
exp.Hex: rename_func("TO_HEX"), exp.Hex: rename_func("TO_HEX"),
exp.If: if_sql(false_value="NULL"), exp.If: if_sql(false_value="NULL"),
@ -597,12 +602,13 @@ class BigQuery(Dialect):
] ]
), ),
exp.SHA2: lambda self, e: self.func( exp.SHA2: lambda self, e: self.func(
f"SHA256" if e.text("length") == "256" else "SHA512", e.this "SHA256" if e.text("length") == "256" else "SHA512", e.this
), ),
exp.StabilityProperty: lambda self, e: ( exp.StabilityProperty: lambda self, e: (
f"DETERMINISTIC" if e.name == "IMMUTABLE" else "NOT DETERMINISTIC" "DETERMINISTIC" if e.name == "IMMUTABLE" else "NOT DETERMINISTIC"
), ),
exp.StrToDate: lambda self, e: f"PARSE_DATE({self.format_time(e)}, {self.sql(e, 'this')})", exp.StrToDate: lambda self,
e: f"PARSE_DATE({self.format_time(e)}, {self.sql(e, 'this')})",
exp.StrToTime: lambda self, e: self.func( exp.StrToTime: lambda self, e: self.func(
"PARSE_TIMESTAMP", self.format_time(e), e.this, e.args.get("zone") "PARSE_TIMESTAMP", self.format_time(e), e.this, e.args.get("zone")
), ),
@ -610,9 +616,10 @@ class BigQuery(Dialect):
exp.TimeFromParts: rename_func("TIME"), exp.TimeFromParts: rename_func("TIME"),
exp.TimeSub: date_add_interval_sql("TIME", "SUB"), exp.TimeSub: date_add_interval_sql("TIME", "SUB"),
exp.TimestampAdd: date_add_interval_sql("TIMESTAMP", "ADD"), exp.TimestampAdd: date_add_interval_sql("TIMESTAMP", "ADD"),
exp.TimestampDiff: rename_func("TIMESTAMP_DIFF"),
exp.TimestampSub: date_add_interval_sql("TIMESTAMP", "SUB"), exp.TimestampSub: date_add_interval_sql("TIMESTAMP", "SUB"),
exp.TimeStrToTime: timestrtotime_sql, exp.TimeStrToTime: timestrtotime_sql,
exp.Trim: lambda self, e: self.func(f"TRIM", e.this, e.expression), exp.Trim: lambda self, e: self.func("TRIM", e.this, e.expression),
exp.TsOrDsAdd: _ts_or_ds_add_sql, exp.TsOrDsAdd: _ts_or_ds_add_sql,
exp.TsOrDsDiff: _ts_or_ds_diff_sql, exp.TsOrDsDiff: _ts_or_ds_diff_sql,
exp.TsOrDsToTime: rename_func("TIME"), exp.TsOrDsToTime: rename_func("TIME"),
@ -623,6 +630,12 @@ class BigQuery(Dialect):
exp.VariancePop: rename_func("VAR_POP"), exp.VariancePop: rename_func("VAR_POP"),
} }
SUPPORTED_JSON_PATH_PARTS = {
exp.JSONPathKey,
exp.JSONPathRoot,
exp.JSONPathSubscript,
}
TYPE_MAPPING = { TYPE_MAPPING = {
**generator.Generator.TYPE_MAPPING, **generator.Generator.TYPE_MAPPING,
exp.DataType.Type.BIGDECIMAL: "BIGNUMERIC", exp.DataType.Type.BIGDECIMAL: "BIGNUMERIC",

View file

@ -8,12 +8,15 @@ from sqlglot.dialects.dialect import (
arg_max_or_min_no_count, arg_max_or_min_no_count,
date_delta_sql, date_delta_sql,
inline_array_sql, inline_array_sql,
json_extract_segments,
json_path_key_only_name,
no_pivot_sql, no_pivot_sql,
parse_json_extract_path,
rename_func, rename_func,
var_map_sql, var_map_sql,
) )
from sqlglot.errors import ParseError from sqlglot.errors import ParseError
from sqlglot.helper import seq_get from sqlglot.helper import is_int, seq_get
from sqlglot.parser import parse_var_map from sqlglot.parser import parse_var_map
from sqlglot.tokens import Token, TokenType from sqlglot.tokens import Token, TokenType
@ -120,6 +123,9 @@ class ClickHouse(Dialect):
"DATEDIFF": lambda args: exp.DateDiff( "DATEDIFF": lambda args: exp.DateDiff(
this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0) this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0)
), ),
"JSONEXTRACTSTRING": parse_json_extract_path(
exp.JSONExtractScalar, zero_based_indexing=False
),
"MAP": parse_var_map, "MAP": parse_var_map,
"MATCH": exp.RegexpLike.from_arg_list, "MATCH": exp.RegexpLike.from_arg_list,
"RANDCANONICAL": exp.Rand.from_arg_list, "RANDCANONICAL": exp.Rand.from_arg_list,
@ -354,9 +360,14 @@ class ClickHouse(Dialect):
joins: bool = False, joins: bool = False,
alias_tokens: t.Optional[t.Collection[TokenType]] = None, alias_tokens: t.Optional[t.Collection[TokenType]] = None,
parse_bracket: bool = False, parse_bracket: bool = False,
is_db_reference: bool = False,
) -> t.Optional[exp.Expression]: ) -> t.Optional[exp.Expression]:
this = super()._parse_table( this = super()._parse_table(
schema=schema, joins=joins, alias_tokens=alias_tokens, parse_bracket=parse_bracket schema=schema,
joins=joins,
alias_tokens=alias_tokens,
parse_bracket=parse_bracket,
is_db_reference=is_db_reference,
) )
if self._match(TokenType.FINAL): if self._match(TokenType.FINAL):
@ -518,6 +529,12 @@ class ClickHouse(Dialect):
exp.DataType.Type.VARCHAR: "String", exp.DataType.Type.VARCHAR: "String",
} }
SUPPORTED_JSON_PATH_PARTS = {
exp.JSONPathKey,
exp.JSONPathRoot,
exp.JSONPathSubscript,
}
TYPE_MAPPING = { TYPE_MAPPING = {
**generator.Generator.TYPE_MAPPING, **generator.Generator.TYPE_MAPPING,
**STRING_TYPE_MAPPING, **STRING_TYPE_MAPPING,
@ -570,6 +587,10 @@ class ClickHouse(Dialect):
exp.Explode: rename_func("arrayJoin"), exp.Explode: rename_func("arrayJoin"),
exp.Final: lambda self, e: f"{self.sql(e, 'this')} FINAL", exp.Final: lambda self, e: f"{self.sql(e, 'this')} FINAL",
exp.IsNan: rename_func("isNaN"), exp.IsNan: rename_func("isNaN"),
exp.JSONExtract: json_extract_segments("JSONExtractString", quoted_index=False),
exp.JSONExtractScalar: json_extract_segments("JSONExtractString", quoted_index=False),
exp.JSONPathKey: json_path_key_only_name,
exp.JSONPathRoot: lambda *_: "",
exp.Map: lambda self, e: _lower_func(var_map_sql(self, e)), exp.Map: lambda self, e: _lower_func(var_map_sql(self, e)),
exp.Nullif: rename_func("nullIf"), exp.Nullif: rename_func("nullIf"),
exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}", exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}",
@ -579,7 +600,8 @@ class ClickHouse(Dialect):
exp.Rand: rename_func("randCanonical"), exp.Rand: rename_func("randCanonical"),
exp.Select: transforms.preprocess([transforms.eliminate_qualify]), exp.Select: transforms.preprocess([transforms.eliminate_qualify]),
exp.StartsWith: rename_func("startsWith"), exp.StartsWith: rename_func("startsWith"),
exp.StrPosition: lambda self, e: f"position({self.format_args(e.this, e.args.get('substr'), e.args.get('position'))})", exp.StrPosition: lambda self,
e: f"position({self.format_args(e.this, e.args.get('substr'), e.args.get('position'))})",
exp.VarMap: lambda self, e: _lower_func(var_map_sql(self, e)), exp.VarMap: lambda self, e: _lower_func(var_map_sql(self, e)),
exp.Xor: lambda self, e: self.func("xor", e.this, e.expression, *e.expressions), exp.Xor: lambda self, e: self.func("xor", e.this, e.expression, *e.expressions),
} }
@ -608,6 +630,13 @@ class ClickHouse(Dialect):
"NAMED COLLECTION", "NAMED COLLECTION",
} }
def _jsonpathsubscript_sql(self, expression: exp.JSONPathSubscript) -> str:
this = self.json_path_part(expression.this)
return str(int(this) + 1) if is_int(this) else this
def likeproperty_sql(self, expression: exp.LikeProperty) -> str:
return f"AS {self.sql(expression, 'this')}"
def _any_to_has( def _any_to_has(
self, self,
expression: exp.EQ | exp.NEQ, expression: exp.EQ | exp.NEQ,

View file

@ -22,6 +22,7 @@ class Databricks(Spark):
"DATEADD": parse_date_delta(exp.DateAdd), "DATEADD": parse_date_delta(exp.DateAdd),
"DATE_ADD": parse_date_delta(exp.DateAdd), "DATE_ADD": parse_date_delta(exp.DateAdd),
"DATEDIFF": parse_date_delta(exp.DateDiff), "DATEDIFF": parse_date_delta(exp.DateDiff),
"TIMESTAMPDIFF": parse_date_delta(exp.TimestampDiff),
} }
FACTOR = { FACTOR = {
@ -48,6 +49,9 @@ class Databricks(Spark):
exp.DatetimeDiff: lambda self, e: self.func( exp.DatetimeDiff: lambda self, e: self.func(
"TIMESTAMPDIFF", e.text("unit"), e.expression, e.this "TIMESTAMPDIFF", e.text("unit"), e.expression, e.this
), ),
exp.TimestampDiff: lambda self, e: self.func(
"TIMESTAMPDIFF", e.text("unit"), e.expression, e.this
),
exp.DatetimeTrunc: timestamptrunc_sql, exp.DatetimeTrunc: timestamptrunc_sql,
exp.JSONExtract: lambda self, e: self.binary(e, ":"), exp.JSONExtract: lambda self, e: self.binary(e, ":"),
exp.Select: transforms.preprocess( exp.Select: transforms.preprocess(

View file

@ -1,5 +1,6 @@
from __future__ import annotations from __future__ import annotations
import logging
import typing as t import typing as t
from enum import Enum, auto from enum import Enum, auto
from functools import reduce from functools import reduce
@ -7,7 +8,8 @@ from functools import reduce
from sqlglot import exp from sqlglot import exp
from sqlglot.errors import ParseError from sqlglot.errors import ParseError
from sqlglot.generator import Generator from sqlglot.generator import Generator
from sqlglot.helper import AutoName, flatten, seq_get from sqlglot.helper import AutoName, flatten, is_int, seq_get
from sqlglot.jsonpath import parse as parse_json_path
from sqlglot.parser import Parser from sqlglot.parser import Parser
from sqlglot.time import TIMEZONES, format_time from sqlglot.time import TIMEZONES, format_time
from sqlglot.tokens import Token, Tokenizer, TokenType from sqlglot.tokens import Token, Tokenizer, TokenType
@ -17,7 +19,11 @@ DATE_ADD_OR_DIFF = t.Union[exp.DateAdd, exp.TsOrDsAdd, exp.DateDiff, exp.TsOrDsD
DATE_ADD_OR_SUB = t.Union[exp.DateAdd, exp.TsOrDsAdd, exp.DateSub] DATE_ADD_OR_SUB = t.Union[exp.DateAdd, exp.TsOrDsAdd, exp.DateSub]
if t.TYPE_CHECKING: if t.TYPE_CHECKING:
from sqlglot._typing import B, E from sqlglot._typing import B, E, F
JSON_EXTRACT_TYPE = t.Union[exp.JSONExtract, exp.JSONExtractScalar]
logger = logging.getLogger("sqlglot")
class Dialects(str, Enum): class Dialects(str, Enum):
@ -256,7 +262,7 @@ class Dialect(metaclass=_Dialect):
INVERSE_ESCAPE_SEQUENCES: t.Dict[str, str] = {} INVERSE_ESCAPE_SEQUENCES: t.Dict[str, str] = {}
# Delimiters for quotes, identifiers and the corresponding escape characters # Delimiters for string literals and identifiers
QUOTE_START = "'" QUOTE_START = "'"
QUOTE_END = "'" QUOTE_END = "'"
IDENTIFIER_START = '"' IDENTIFIER_START = '"'
@ -373,7 +379,7 @@ class Dialect(metaclass=_Dialect):
""" """
if ( if (
isinstance(expression, exp.Identifier) isinstance(expression, exp.Identifier)
and not self.normalization_strategy is NormalizationStrategy.CASE_SENSITIVE and self.normalization_strategy is not NormalizationStrategy.CASE_SENSITIVE
and ( and (
not expression.quoted not expression.quoted
or self.normalization_strategy is NormalizationStrategy.CASE_INSENSITIVE or self.normalization_strategy is NormalizationStrategy.CASE_INSENSITIVE
@ -440,6 +446,19 @@ class Dialect(metaclass=_Dialect):
return expression return expression
def to_json_path(self, path: t.Optional[exp.Expression]) -> t.Optional[exp.Expression]:
if isinstance(path, exp.Literal):
path_text = path.name
if path.is_number:
path_text = f"[{path_text}]"
try:
return parse_json_path(path_text)
except ParseError as e:
logger.warning(f"Invalid JSON path syntax. {str(e)}")
return path
def parse(self, sql: str, **opts) -> t.List[t.Optional[exp.Expression]]: def parse(self, sql: str, **opts) -> t.List[t.Optional[exp.Expression]]:
return self.parser(**opts).parse(self.tokenize(sql), sql) return self.parser(**opts).parse(self.tokenize(sql), sql)
@ -500,14 +519,12 @@ def if_sql(
return _if_sql return _if_sql
def arrow_json_extract_sql(self: Generator, expression: exp.JSONExtract | exp.JSONBExtract) -> str: def arrow_json_extract_sql(self: Generator, expression: JSON_EXTRACT_TYPE) -> str:
return self.binary(expression, "->") this = expression.this
if self.JSON_TYPE_REQUIRED_FOR_EXTRACTION and isinstance(this, exp.Literal) and this.is_string:
this.replace(exp.cast(this, "json"))
return self.binary(expression, "->" if isinstance(expression, exp.JSONExtract) else "->>")
def arrow_json_extract_scalar_sql(
self: Generator, expression: exp.JSONExtractScalar | exp.JSONBExtractScalar
) -> str:
return self.binary(expression, "->>")
def inline_array_sql(self: Generator, expression: exp.Array) -> str: def inline_array_sql(self: Generator, expression: exp.Array) -> str:
@ -552,11 +569,6 @@ def no_trycast_sql(self: Generator, expression: exp.TryCast) -> str:
return self.cast_sql(expression) return self.cast_sql(expression)
def no_properties_sql(self: Generator, expression: exp.Properties) -> str:
self.unsupported("Properties unsupported")
return ""
def no_comment_column_constraint_sql( def no_comment_column_constraint_sql(
self: Generator, expression: exp.CommentColumnConstraint self: Generator, expression: exp.CommentColumnConstraint
) -> str: ) -> str:
@ -965,32 +977,6 @@ def date_delta_sql(name: str, cast: bool = False) -> t.Callable[[Generator, DATE
return _delta_sql return _delta_sql
def prepend_dollar_to_path(expression: exp.GetPath) -> exp.GetPath:
from sqlglot.optimizer.simplify import simplify
# Makes sure the path will be evaluated correctly at runtime to include the path root.
# For example, `[0].foo` will become `$[0].foo`, and `foo` will become `$.foo`.
path = expression.expression
path = exp.func(
"if",
exp.func("startswith", path, "'['"),
exp.func("concat", "'$'", path),
exp.func("concat", "'$.'", path),
)
expression.expression.replace(simplify(path))
return expression
def path_to_jsonpath(
name: str = "JSON_EXTRACT",
) -> t.Callable[[Generator, exp.GetPath], str]:
def _transform(self: Generator, expression: exp.GetPath) -> str:
return rename_func(name)(self, prepend_dollar_to_path(expression))
return _transform
def no_last_day_sql(self: Generator, expression: exp.LastDay) -> str: def no_last_day_sql(self: Generator, expression: exp.LastDay) -> str:
trunc_curr_date = exp.func("date_trunc", "month", expression.this) trunc_curr_date = exp.func("date_trunc", "month", expression.this)
plus_one_month = exp.func("date_add", trunc_curr_date, 1, "month") plus_one_month = exp.func("date_add", trunc_curr_date, 1, "month")
@ -1003,9 +989,8 @@ def merge_without_target_sql(self: Generator, expression: exp.Merge) -> str:
"""Remove table refs from columns in when statements.""" """Remove table refs from columns in when statements."""
alias = expression.this.args.get("alias") alias = expression.this.args.get("alias")
normalize = lambda identifier: ( def normalize(identifier: t.Optional[exp.Identifier]) -> t.Optional[str]:
self.dialect.normalize_identifier(identifier).name if identifier else None return self.dialect.normalize_identifier(identifier).name if identifier else None
)
targets = {normalize(expression.this.this)} targets = {normalize(expression.this.this)}
@ -1023,3 +1008,60 @@ def merge_without_target_sql(self: Generator, expression: exp.Merge) -> str:
) )
return self.merge_sql(expression) return self.merge_sql(expression)
def parse_json_extract_path(
expr_type: t.Type[F], zero_based_indexing: bool = True
) -> t.Callable[[t.List], F]:
def _parse_json_extract_path(args: t.List) -> F:
segments: t.List[exp.JSONPathPart] = [exp.JSONPathRoot()]
for arg in args[1:]:
if not isinstance(arg, exp.Literal):
# We use the fallback parser because we can't really transpile non-literals safely
return expr_type.from_arg_list(args)
text = arg.name
if is_int(text):
index = int(text)
segments.append(
exp.JSONPathSubscript(this=index if zero_based_indexing else index - 1)
)
else:
segments.append(exp.JSONPathKey(this=text))
# This is done to avoid failing in the expression validator due to the arg count
del args[2:]
return expr_type(this=seq_get(args, 0), expression=exp.JSONPath(expressions=segments))
return _parse_json_extract_path
def json_extract_segments(
name: str, quoted_index: bool = True
) -> t.Callable[[Generator, JSON_EXTRACT_TYPE], str]:
def _json_extract_segments(self: Generator, expression: JSON_EXTRACT_TYPE) -> str:
path = expression.expression
if not isinstance(path, exp.JSONPath):
return rename_func(name)(self, expression)
segments = []
for segment in path.expressions:
path = self.sql(segment)
if path:
if isinstance(segment, exp.JSONPathPart) and (
quoted_index or not isinstance(segment, exp.JSONPathSubscript)
):
path = f"{self.dialect.QUOTE_START}{path}{self.dialect.QUOTE_END}"
segments.append(path)
return self.func(name, expression.this, *segments)
return _json_extract_segments
def json_path_key_only_name(self: Generator, expression: exp.JSONPathKey) -> str:
if isinstance(expression.this, exp.JSONPathWildcard):
self.unsupported("Unsupported wildcard in JSONPathKey expression")
return expression.name

View file

@ -55,11 +55,14 @@ class Doris(MySQL):
exp.Map: rename_func("ARRAY_MAP"), exp.Map: rename_func("ARRAY_MAP"),
exp.RegexpLike: rename_func("REGEXP"), exp.RegexpLike: rename_func("REGEXP"),
exp.RegexpSplit: rename_func("SPLIT_BY_STRING"), exp.RegexpSplit: rename_func("SPLIT_BY_STRING"),
exp.StrToUnix: lambda self, e: f"UNIX_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})", exp.StrToUnix: lambda self,
e: f"UNIX_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})",
exp.Split: rename_func("SPLIT_BY_STRING"), exp.Split: rename_func("SPLIT_BY_STRING"),
exp.TimeStrToDate: rename_func("TO_DATE"), exp.TimeStrToDate: rename_func("TO_DATE"),
exp.ToChar: lambda self, e: f"DATE_FORMAT({self.sql(e, 'this')}, {self.format_time(e)})", exp.ToChar: lambda self,
exp.TsOrDsAdd: lambda self, e: f"DATE_ADD({self.sql(e, 'this')}, {self.sql(e, 'expression')})", # Only for day level e: f"DATE_FORMAT({self.sql(e, 'this')}, {self.format_time(e)})",
exp.TsOrDsAdd: lambda self,
e: f"DATE_ADD({self.sql(e, 'this')}, {self.sql(e, 'expression')})", # Only for day level
exp.TsOrDsToDate: lambda self, e: self.func("TO_DATE", e.this), exp.TsOrDsToDate: lambda self, e: self.func("TO_DATE", e.this),
exp.TimeToUnix: rename_func("UNIX_TIMESTAMP"), exp.TimeToUnix: rename_func("UNIX_TIMESTAMP"),
exp.TimestampTrunc: lambda self, e: self.func( exp.TimestampTrunc: lambda self, e: self.func(

View file

@ -99,6 +99,7 @@ class Drill(Dialect):
QUERY_HINTS = False QUERY_HINTS = False
NVL2_SUPPORTED = False NVL2_SUPPORTED = False
LAST_DAY_SUPPORTS_DATE_PART = False LAST_DAY_SUPPORTS_DATE_PART = False
SUPPORTS_CREATE_TABLE_LIKE = False
TYPE_MAPPING = { TYPE_MAPPING = {
**generator.Generator.TYPE_MAPPING, **generator.Generator.TYPE_MAPPING,
@ -128,10 +129,14 @@ class Drill(Dialect):
exp.DateAdd: _date_add_sql("ADD"), exp.DateAdd: _date_add_sql("ADD"),
exp.DateStrToDate: datestrtodate_sql, exp.DateStrToDate: datestrtodate_sql,
exp.DateSub: _date_add_sql("SUB"), exp.DateSub: _date_add_sql("SUB"),
exp.DateToDi: lambda self, e: f"CAST(TO_DATE({self.sql(e, 'this')}, {Drill.DATEINT_FORMAT}) AS INT)", exp.DateToDi: lambda self,
exp.DiToDate: lambda self, e: f"TO_DATE(CAST({self.sql(e, 'this')} AS VARCHAR), {Drill.DATEINT_FORMAT})", e: f"CAST(TO_DATE({self.sql(e, 'this')}, {Drill.DATEINT_FORMAT}) AS INT)",
exp.If: lambda self, e: f"`IF`({self.format_args(e.this, e.args.get('true'), e.args.get('false'))})", exp.DiToDate: lambda self,
exp.ILike: lambda self, e: f" {self.sql(e, 'this')} `ILIKE` {self.sql(e, 'expression')}", e: f"TO_DATE(CAST({self.sql(e, 'this')} AS VARCHAR), {Drill.DATEINT_FORMAT})",
exp.If: lambda self,
e: f"`IF`({self.format_args(e.this, e.args.get('true'), e.args.get('false'))})",
exp.ILike: lambda self,
e: f" {self.sql(e, 'this')} `ILIKE` {self.sql(e, 'expression')}",
exp.Levenshtein: rename_func("LEVENSHTEIN_DISTANCE"), exp.Levenshtein: rename_func("LEVENSHTEIN_DISTANCE"),
exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}", exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}",
exp.RegexpLike: rename_func("REGEXP_MATCHES"), exp.RegexpLike: rename_func("REGEXP_MATCHES"),
@ -141,7 +146,8 @@ class Drill(Dialect):
exp.Select: transforms.preprocess( exp.Select: transforms.preprocess(
[transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins] [transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins]
), ),
exp.StrToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})", exp.StrToTime: lambda self,
e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})",
exp.TimeStrToDate: lambda self, e: f"CAST({self.sql(e, 'this')} AS DATE)", exp.TimeStrToDate: lambda self, e: f"CAST({self.sql(e, 'this')} AS DATE)",
exp.TimeStrToTime: timestrtotime_sql, exp.TimeStrToTime: timestrtotime_sql,
exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"),
@ -149,8 +155,10 @@ class Drill(Dialect):
exp.TimeToUnix: rename_func("UNIX_TIMESTAMP"), exp.TimeToUnix: rename_func("UNIX_TIMESTAMP"),
exp.ToChar: lambda self, e: self.function_fallback_sql(e), exp.ToChar: lambda self, e: self.function_fallback_sql(e),
exp.TryCast: no_trycast_sql, exp.TryCast: no_trycast_sql,
exp.TsOrDsAdd: lambda self, e: f"DATE_ADD(CAST({self.sql(e, 'this')} AS DATE), {self.sql(exp.Interval(this=e.expression, unit=exp.var('DAY')))})", exp.TsOrDsAdd: lambda self,
exp.TsOrDiToDi: lambda self, e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS VARCHAR), '-', ''), 1, 8) AS INT)", e: f"DATE_ADD(CAST({self.sql(e, 'this')} AS DATE), {self.sql(exp.Interval(this=e.expression, unit=exp.var('DAY')))})",
exp.TsOrDiToDi: lambda self,
e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS VARCHAR), '-', ''), 1, 8) AS INT)",
} }
def normalize_func(self, name: str) -> str: def normalize_func(self, name: str) -> str:

View file

@ -8,7 +8,6 @@ from sqlglot.dialects.dialect import (
NormalizationStrategy, NormalizationStrategy,
approx_count_distinct_sql, approx_count_distinct_sql,
arg_max_or_min_no_count, arg_max_or_min_no_count,
arrow_json_extract_scalar_sql,
arrow_json_extract_sql, arrow_json_extract_sql,
binary_from_function, binary_from_function,
bool_xor_sql, bool_xor_sql,
@ -18,11 +17,9 @@ from sqlglot.dialects.dialect import (
format_time_lambda, format_time_lambda,
inline_array_sql, inline_array_sql,
no_comment_column_constraint_sql, no_comment_column_constraint_sql,
no_properties_sql,
no_safe_divide_sql, no_safe_divide_sql,
no_timestamp_sql, no_timestamp_sql,
pivot_column_names, pivot_column_names,
prepend_dollar_to_path,
regexp_extract_sql, regexp_extract_sql,
rename_func, rename_func,
str_position_sql, str_position_sql,
@ -172,6 +169,18 @@ class DuckDB(Dialect):
# https://duckdb.org/docs/sql/introduction.html#creating-a-new-table # https://duckdb.org/docs/sql/introduction.html#creating-a-new-table
NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE
def to_json_path(self, path: t.Optional[exp.Expression]) -> t.Optional[exp.Expression]:
if isinstance(path, exp.Literal):
# DuckDB also supports the JSON pointer syntax, where every path starts with a `/`.
# Additionally, it allows accessing the back of lists using the `[#-i]` syntax.
# This check ensures we'll avoid trying to parse these as JSON paths, which can
# either result in a noisy warning or in an invalid representation of the path.
path_text = path.name
if path_text.startswith("/") or "[#" in path_text:
return path
return super().to_json_path(path)
class Tokenizer(tokens.Tokenizer): class Tokenizer(tokens.Tokenizer):
KEYWORDS = { KEYWORDS = {
**tokens.Tokenizer.KEYWORDS, **tokens.Tokenizer.KEYWORDS,
@ -229,6 +238,8 @@ class DuckDB(Dialect):
this=seq_get(args, 0), scale=exp.UnixToTime.MILLIS this=seq_get(args, 0), scale=exp.UnixToTime.MILLIS
), ),
"JSON": exp.ParseJSON.from_arg_list, "JSON": exp.ParseJSON.from_arg_list,
"JSON_EXTRACT_PATH": parser.parse_extract_json_with_path(exp.JSONExtract),
"JSON_EXTRACT_STRING": parser.parse_extract_json_with_path(exp.JSONExtractScalar),
"LIST_HAS": exp.ArrayContains.from_arg_list, "LIST_HAS": exp.ArrayContains.from_arg_list,
"LIST_REVERSE_SORT": _sort_array_reverse, "LIST_REVERSE_SORT": _sort_array_reverse,
"LIST_SORT": exp.SortArray.from_arg_list, "LIST_SORT": exp.SortArray.from_arg_list,
@ -319,6 +330,9 @@ class DuckDB(Dialect):
TABLESAMPLE_SEED_KEYWORD = "REPEATABLE" TABLESAMPLE_SEED_KEYWORD = "REPEATABLE"
LAST_DAY_SUPPORTS_DATE_PART = False LAST_DAY_SUPPORTS_DATE_PART = False
JSON_KEY_VALUE_PAIR_SEP = "," JSON_KEY_VALUE_PAIR_SEP = ","
IGNORE_NULLS_IN_FUNC = True
JSON_PATH_BRACKETED_KEY_SUPPORTED = False
SUPPORTS_CREATE_TABLE_LIKE = False
TRANSFORMS = { TRANSFORMS = {
**generator.Generator.TRANSFORMS, **generator.Generator.TRANSFORMS,
@ -350,18 +364,18 @@ class DuckDB(Dialect):
"DATE_DIFF", f"'{e.args.get('unit') or 'DAY'}'", e.expression, e.this "DATE_DIFF", f"'{e.args.get('unit') or 'DAY'}'", e.expression, e.this
), ),
exp.DateStrToDate: datestrtodate_sql, exp.DateStrToDate: datestrtodate_sql,
exp.DateToDi: lambda self, e: f"CAST(STRFTIME({self.sql(e, 'this')}, {DuckDB.DATEINT_FORMAT}) AS INT)", exp.DateToDi: lambda self,
e: f"CAST(STRFTIME({self.sql(e, 'this')}, {DuckDB.DATEINT_FORMAT}) AS INT)",
exp.Decode: lambda self, e: encode_decode_sql(self, e, "DECODE", replace=False), exp.Decode: lambda self, e: encode_decode_sql(self, e, "DECODE", replace=False),
exp.DiToDate: lambda self, e: f"CAST(STRPTIME(CAST({self.sql(e, 'this')} AS TEXT), {DuckDB.DATEINT_FORMAT}) AS DATE)", exp.DiToDate: lambda self,
e: f"CAST(STRPTIME(CAST({self.sql(e, 'this')} AS TEXT), {DuckDB.DATEINT_FORMAT}) AS DATE)",
exp.Encode: lambda self, e: encode_decode_sql(self, e, "ENCODE", replace=False), exp.Encode: lambda self, e: encode_decode_sql(self, e, "ENCODE", replace=False),
exp.Explode: rename_func("UNNEST"), exp.Explode: rename_func("UNNEST"),
exp.IntDiv: lambda self, e: self.binary(e, "//"), exp.IntDiv: lambda self, e: self.binary(e, "//"),
exp.IsInf: rename_func("ISINF"), exp.IsInf: rename_func("ISINF"),
exp.IsNan: rename_func("ISNAN"), exp.IsNan: rename_func("ISNAN"),
exp.JSONBExtract: arrow_json_extract_sql,
exp.JSONBExtractScalar: arrow_json_extract_scalar_sql,
exp.JSONExtract: arrow_json_extract_sql, exp.JSONExtract: arrow_json_extract_sql,
exp.JSONExtractScalar: arrow_json_extract_scalar_sql, exp.JSONExtractScalar: arrow_json_extract_sql,
exp.JSONFormat: _json_format_sql, exp.JSONFormat: _json_format_sql,
exp.LogicalOr: rename_func("BOOL_OR"), exp.LogicalOr: rename_func("BOOL_OR"),
exp.LogicalAnd: rename_func("BOOL_AND"), exp.LogicalAnd: rename_func("BOOL_AND"),
@ -377,7 +391,6 @@ class DuckDB(Dialect):
# DuckDB doesn't allow qualified columns inside of PIVOT expressions. # DuckDB doesn't allow qualified columns inside of PIVOT expressions.
# See: https://github.com/duckdb/duckdb/blob/671faf92411182f81dce42ac43de8bfb05d9909e/src/planner/binder/tableref/bind_pivot.cpp#L61-L62 # See: https://github.com/duckdb/duckdb/blob/671faf92411182f81dce42ac43de8bfb05d9909e/src/planner/binder/tableref/bind_pivot.cpp#L61-L62
exp.Pivot: transforms.preprocess([transforms.unqualify_columns]), exp.Pivot: transforms.preprocess([transforms.unqualify_columns]),
exp.Properties: no_properties_sql,
exp.RegexpExtract: regexp_extract_sql, exp.RegexpExtract: regexp_extract_sql,
exp.RegexpReplace: lambda self, e: self.func( exp.RegexpReplace: lambda self, e: self.func(
"REGEXP_REPLACE", "REGEXP_REPLACE",
@ -395,7 +408,8 @@ class DuckDB(Dialect):
exp.StrPosition: str_position_sql, exp.StrPosition: str_position_sql,
exp.StrToDate: lambda self, e: f"CAST({str_to_time_sql(self, e)} AS DATE)", exp.StrToDate: lambda self, e: f"CAST({str_to_time_sql(self, e)} AS DATE)",
exp.StrToTime: str_to_time_sql, exp.StrToTime: str_to_time_sql,
exp.StrToUnix: lambda self, e: f"EPOCH(STRPTIME({self.sql(e, 'this')}, {self.format_time(e)}))", exp.StrToUnix: lambda self,
e: f"EPOCH(STRPTIME({self.sql(e, 'this')}, {self.format_time(e)}))",
exp.Struct: _struct_sql, exp.Struct: _struct_sql,
exp.Timestamp: no_timestamp_sql, exp.Timestamp: no_timestamp_sql,
exp.TimestampDiff: lambda self, e: self.func( exp.TimestampDiff: lambda self, e: self.func(
@ -405,9 +419,11 @@ class DuckDB(Dialect):
exp.TimeStrToDate: lambda self, e: f"CAST({self.sql(e, 'this')} AS DATE)", exp.TimeStrToDate: lambda self, e: f"CAST({self.sql(e, 'this')} AS DATE)",
exp.TimeStrToTime: timestrtotime_sql, exp.TimeStrToTime: timestrtotime_sql,
exp.TimeStrToUnix: lambda self, e: f"EPOCH(CAST({self.sql(e, 'this')} AS TIMESTAMP))", exp.TimeStrToUnix: lambda self, e: f"EPOCH(CAST({self.sql(e, 'this')} AS TIMESTAMP))",
exp.TimeToStr: lambda self, e: f"STRFTIME({self.sql(e, 'this')}, {self.format_time(e)})", exp.TimeToStr: lambda self,
e: f"STRFTIME({self.sql(e, 'this')}, {self.format_time(e)})",
exp.TimeToUnix: rename_func("EPOCH"), exp.TimeToUnix: rename_func("EPOCH"),
exp.TsOrDiToDi: lambda self, e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS TEXT), '-', ''), 1, 8) AS INT)", exp.TsOrDiToDi: lambda self,
e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS TEXT), '-', ''), 1, 8) AS INT)",
exp.TsOrDsAdd: _ts_or_ds_add_sql, exp.TsOrDsAdd: _ts_or_ds_add_sql,
exp.TsOrDsDiff: lambda self, e: self.func( exp.TsOrDsDiff: lambda self, e: self.func(
"DATE_DIFF", "DATE_DIFF",
@ -415,7 +431,8 @@ class DuckDB(Dialect):
exp.cast(e.expression, "TIMESTAMP"), exp.cast(e.expression, "TIMESTAMP"),
exp.cast(e.this, "TIMESTAMP"), exp.cast(e.this, "TIMESTAMP"),
), ),
exp.UnixToStr: lambda self, e: f"STRFTIME(TO_TIMESTAMP({self.sql(e, 'this')}), {self.format_time(e)})", exp.UnixToStr: lambda self,
e: f"STRFTIME(TO_TIMESTAMP({self.sql(e, 'this')}), {self.format_time(e)})",
exp.UnixToTime: _unix_to_time_sql, exp.UnixToTime: _unix_to_time_sql,
exp.UnixToTimeStr: lambda self, e: f"CAST(TO_TIMESTAMP({self.sql(e, 'this')}) AS TEXT)", exp.UnixToTimeStr: lambda self, e: f"CAST(TO_TIMESTAMP({self.sql(e, 'this')}) AS TEXT)",
exp.VariancePop: rename_func("VAR_POP"), exp.VariancePop: rename_func("VAR_POP"),
@ -423,6 +440,13 @@ class DuckDB(Dialect):
exp.Xor: bool_xor_sql, exp.Xor: bool_xor_sql,
} }
SUPPORTED_JSON_PATH_PARTS = {
exp.JSONPathKey,
exp.JSONPathRoot,
exp.JSONPathSubscript,
exp.JSONPathWildcard,
}
TYPE_MAPPING = { TYPE_MAPPING = {
**generator.Generator.TYPE_MAPPING, **generator.Generator.TYPE_MAPPING,
exp.DataType.Type.BINARY: "BLOB", exp.DataType.Type.BINARY: "BLOB",
@ -442,11 +466,18 @@ class DuckDB(Dialect):
UNWRAPPED_INTERVAL_VALUES = (exp.Column, exp.Literal, exp.Paren) UNWRAPPED_INTERVAL_VALUES = (exp.Column, exp.Literal, exp.Paren)
# DuckDB doesn't generally support CREATE TABLE .. properties
# https://duckdb.org/docs/sql/statements/create_table.html
PROPERTIES_LOCATION = { PROPERTIES_LOCATION = {
**generator.Generator.PROPERTIES_LOCATION, prop: exp.Properties.Location.UNSUPPORTED
exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, for prop in generator.Generator.PROPERTIES_LOCATION
} }
# There are a few exceptions (e.g. temporary tables) which are supported or
# can be transpiled to DuckDB, so we explicitly override them accordingly
PROPERTIES_LOCATION[exp.LikeProperty] = exp.Properties.Location.POST_SCHEMA
PROPERTIES_LOCATION[exp.TemporaryProperty] = exp.Properties.Location.POST_CREATE
def timefromparts_sql(self, expression: exp.TimeFromParts) -> str: def timefromparts_sql(self, expression: exp.TimeFromParts) -> str:
nano = expression.args.get("nano") nano = expression.args.get("nano")
if nano is not None: if nano is not None:
@ -486,10 +517,6 @@ class DuckDB(Dialect):
expression, sep=sep, tablesample_keyword=tablesample_keyword expression, sep=sep, tablesample_keyword=tablesample_keyword
) )
def getpath_sql(self, expression: exp.GetPath) -> str:
expression = prepend_dollar_to_path(expression)
return f"{self.sql(expression, 'this')} -> {self.sql(expression, 'expression')}"
def interval_sql(self, expression: exp.Interval) -> str: def interval_sql(self, expression: exp.Interval) -> str:
multiplier: t.Optional[int] = None multiplier: t.Optional[int] = None
unit = expression.text("unit").lower() unit = expression.text("unit").lower()

View file

@ -192,6 +192,18 @@ def _to_date_sql(self: Hive.Generator, expression: exp.TsOrDsToDate) -> str:
return f"TO_DATE({this})" return f"TO_DATE({this})"
def _parse_ignore_nulls(
exp_class: t.Type[exp.Expression],
) -> t.Callable[[t.List[exp.Expression]], exp.Expression]:
def _parse(args: t.List[exp.Expression]) -> exp.Expression:
this = exp_class(this=seq_get(args, 0))
if seq_get(args, 1) == exp.true():
return exp.IgnoreNulls(this=this)
return this
return _parse
class Hive(Dialect): class Hive(Dialect):
ALIAS_POST_TABLESAMPLE = True ALIAS_POST_TABLESAMPLE = True
IDENTIFIERS_CAN_START_WITH_DIGIT = True IDENTIFIERS_CAN_START_WITH_DIGIT = True
@ -298,8 +310,12 @@ class Hive(Dialect):
expression=exp.TsOrDsToDate(this=seq_get(args, 1)), expression=exp.TsOrDsToDate(this=seq_get(args, 1)),
), ),
"DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
"FIRST": _parse_ignore_nulls(exp.First),
"FIRST_VALUE": _parse_ignore_nulls(exp.FirstValue),
"FROM_UNIXTIME": format_time_lambda(exp.UnixToStr, "hive", True), "FROM_UNIXTIME": format_time_lambda(exp.UnixToStr, "hive", True),
"GET_JSON_OBJECT": exp.JSONExtractScalar.from_arg_list, "GET_JSON_OBJECT": exp.JSONExtractScalar.from_arg_list,
"LAST": _parse_ignore_nulls(exp.Last),
"LAST_VALUE": _parse_ignore_nulls(exp.LastValue),
"LOCATE": locate_to_strposition, "LOCATE": locate_to_strposition,
"MAP": parse_var_map, "MAP": parse_var_map,
"MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate.from_arg_list(args)), "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate.from_arg_list(args)),
@ -429,6 +445,7 @@ class Hive(Dialect):
EXTRACT_ALLOWS_QUOTES = False EXTRACT_ALLOWS_QUOTES = False
NVL2_SUPPORTED = False NVL2_SUPPORTED = False
LAST_DAY_SUPPORTS_DATE_PART = False LAST_DAY_SUPPORTS_DATE_PART = False
JSON_PATH_SINGLE_QUOTE_ESCAPE = True
EXPRESSIONS_WITHOUT_NESTED_CTES = { EXPRESSIONS_WITHOUT_NESTED_CTES = {
exp.Insert, exp.Insert,
@ -437,6 +454,13 @@ class Hive(Dialect):
exp.Union, exp.Union,
} }
SUPPORTED_JSON_PATH_PARTS = {
exp.JSONPathKey,
exp.JSONPathRoot,
exp.JSONPathSubscript,
exp.JSONPathWildcard,
}
TYPE_MAPPING = { TYPE_MAPPING = {
**generator.Generator.TYPE_MAPPING, **generator.Generator.TYPE_MAPPING,
exp.DataType.Type.BIT: "BOOLEAN", exp.DataType.Type.BIT: "BOOLEAN",
@ -471,9 +495,12 @@ class Hive(Dialect):
exp.DateDiff: _date_diff_sql, exp.DateDiff: _date_diff_sql,
exp.DateStrToDate: datestrtodate_sql, exp.DateStrToDate: datestrtodate_sql,
exp.DateSub: _add_date_sql, exp.DateSub: _add_date_sql,
exp.DateToDi: lambda self, e: f"CAST(DATE_FORMAT({self.sql(e, 'this')}, {Hive.DATEINT_FORMAT}) AS INT)", exp.DateToDi: lambda self,
exp.DiToDate: lambda self, e: f"TO_DATE(CAST({self.sql(e, 'this')} AS STRING), {Hive.DATEINT_FORMAT})", e: f"CAST(DATE_FORMAT({self.sql(e, 'this')}, {Hive.DATEINT_FORMAT}) AS INT)",
exp.FileFormatProperty: lambda self, e: f"STORED AS {self.sql(e, 'this') if isinstance(e.this, exp.InputOutputFormat) else e.name.upper()}", exp.DiToDate: lambda self,
e: f"TO_DATE(CAST({self.sql(e, 'this')} AS STRING), {Hive.DATEINT_FORMAT})",
exp.FileFormatProperty: lambda self,
e: f"STORED AS {self.sql(e, 'this') if isinstance(e.this, exp.InputOutputFormat) else e.name.upper()}",
exp.FromBase64: rename_func("UNBASE64"), exp.FromBase64: rename_func("UNBASE64"),
exp.If: if_sql(), exp.If: if_sql(),
exp.ILike: no_ilike_sql, exp.ILike: no_ilike_sql,
@ -502,7 +529,8 @@ class Hive(Dialect):
exp.SafeDivide: no_safe_divide_sql, exp.SafeDivide: no_safe_divide_sql,
exp.SchemaCommentProperty: lambda self, e: self.naked_property(e), exp.SchemaCommentProperty: lambda self, e: self.naked_property(e),
exp.ArrayUniqueAgg: rename_func("COLLECT_SET"), exp.ArrayUniqueAgg: rename_func("COLLECT_SET"),
exp.Split: lambda self, e: f"SPLIT({self.sql(e, 'this')}, CONCAT('\\\\Q', {self.sql(e, 'expression')}))", exp.Split: lambda self,
e: f"SPLIT({self.sql(e, 'this')}, CONCAT('\\\\Q', {self.sql(e, 'expression')}))",
exp.StrPosition: strposition_to_locate_sql, exp.StrPosition: strposition_to_locate_sql,
exp.StrToDate: _str_to_date_sql, exp.StrToDate: _str_to_date_sql,
exp.StrToTime: _str_to_time_sql, exp.StrToTime: _str_to_time_sql,
@ -514,7 +542,8 @@ class Hive(Dialect):
exp.TimeToStr: _time_to_str, exp.TimeToStr: _time_to_str,
exp.TimeToUnix: rename_func("UNIX_TIMESTAMP"), exp.TimeToUnix: rename_func("UNIX_TIMESTAMP"),
exp.ToBase64: rename_func("BASE64"), exp.ToBase64: rename_func("BASE64"),
exp.TsOrDiToDi: lambda self, e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS STRING), '-', ''), 1, 8) AS INT)", exp.TsOrDiToDi: lambda self,
e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS STRING), '-', ''), 1, 8) AS INT)",
exp.TsOrDsAdd: _add_date_sql, exp.TsOrDsAdd: _add_date_sql,
exp.TsOrDsDiff: _date_diff_sql, exp.TsOrDsDiff: _date_diff_sql,
exp.TsOrDsToDate: _to_date_sql, exp.TsOrDsToDate: _to_date_sql,
@ -528,8 +557,10 @@ class Hive(Dialect):
exp.SerdeProperties: lambda self, e: self.properties(e, prefix="WITH SERDEPROPERTIES"), exp.SerdeProperties: lambda self, e: self.properties(e, prefix="WITH SERDEPROPERTIES"),
exp.NumberToStr: rename_func("FORMAT_NUMBER"), exp.NumberToStr: rename_func("FORMAT_NUMBER"),
exp.National: lambda self, e: self.national_sql(e, prefix=""), exp.National: lambda self, e: self.national_sql(e, prefix=""),
exp.ClusteredColumnConstraint: lambda self, e: f"({self.expressions(e, 'this', indent=False)})", exp.ClusteredColumnConstraint: lambda self,
exp.NonClusteredColumnConstraint: lambda self, e: f"({self.expressions(e, 'this', indent=False)})", e: f"({self.expressions(e, 'this', indent=False)})",
exp.NonClusteredColumnConstraint: lambda self,
e: f"({self.expressions(e, 'this', indent=False)})",
exp.NotForReplicationColumnConstraint: lambda self, e: "", exp.NotForReplicationColumnConstraint: lambda self, e: "",
exp.OnProperty: lambda self, e: "", exp.OnProperty: lambda self, e: "",
exp.PrimaryKeyColumnConstraint: lambda self, e: "PRIMARY KEY", exp.PrimaryKeyColumnConstraint: lambda self, e: "PRIMARY KEY",
@ -543,6 +574,13 @@ class Hive(Dialect):
exp.WithDataProperty: exp.Properties.Location.UNSUPPORTED, exp.WithDataProperty: exp.Properties.Location.UNSUPPORTED,
} }
def _jsonpathkey_sql(self, expression: exp.JSONPathKey) -> str:
if isinstance(expression.this, exp.JSONPathWildcard):
self.unsupported("Unsupported wildcard in JSONPathKey expression")
return ""
return super()._jsonpathkey_sql(expression)
def temporary_storage_provider(self, expression: exp.Create) -> exp.Create: def temporary_storage_provider(self, expression: exp.Create) -> exp.Create:
# Hive has no temporary storage provider (there are hive settings though) # Hive has no temporary storage provider (there are hive settings though)
return expression return expression

View file

@ -6,7 +6,7 @@ from sqlglot import exp, generator, parser, tokens, transforms
from sqlglot.dialects.dialect import ( from sqlglot.dialects.dialect import (
Dialect, Dialect,
NormalizationStrategy, NormalizationStrategy,
arrow_json_extract_scalar_sql, arrow_json_extract_sql,
date_add_interval_sql, date_add_interval_sql,
datestrtodate_sql, datestrtodate_sql,
format_time_lambda, format_time_lambda,
@ -19,8 +19,8 @@ from sqlglot.dialects.dialect import (
no_pivot_sql, no_pivot_sql,
no_tablesample_sql, no_tablesample_sql,
no_trycast_sql, no_trycast_sql,
parse_date_delta,
parse_date_delta_with_interval, parse_date_delta_with_interval,
path_to_jsonpath,
rename_func, rename_func,
strposition_to_locate_sql, strposition_to_locate_sql,
) )
@ -306,6 +306,7 @@ class MySQL(Dialect):
format=exp.Literal.string("%B"), format=exp.Literal.string("%B"),
), ),
"STR_TO_DATE": _str_to_date, "STR_TO_DATE": _str_to_date,
"TIMESTAMPDIFF": parse_date_delta(exp.TimestampDiff),
"TO_DAYS": lambda args: exp.paren( "TO_DAYS": lambda args: exp.paren(
exp.DateDiff( exp.DateDiff(
this=exp.TsOrDsToDate(this=seq_get(args, 0)), this=exp.TsOrDsToDate(this=seq_get(args, 0)),
@ -357,6 +358,7 @@ class MySQL(Dialect):
"CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True),
"CREATE VIEW": _show_parser("CREATE VIEW", target=True), "CREATE VIEW": _show_parser("CREATE VIEW", target=True),
"DATABASES": _show_parser("DATABASES"), "DATABASES": _show_parser("DATABASES"),
"SCHEMAS": _show_parser("DATABASES"),
"ENGINE": _show_parser("ENGINE", target=True), "ENGINE": _show_parser("ENGINE", target=True),
"STORAGE ENGINES": _show_parser("ENGINES"), "STORAGE ENGINES": _show_parser("ENGINES"),
"ENGINES": _show_parser("ENGINES"), "ENGINES": _show_parser("ENGINES"),
@ -630,6 +632,8 @@ class MySQL(Dialect):
VALUES_AS_TABLE = False VALUES_AS_TABLE = False
NVL2_SUPPORTED = False NVL2_SUPPORTED = False
LAST_DAY_SUPPORTS_DATE_PART = False LAST_DAY_SUPPORTS_DATE_PART = False
JSON_TYPE_REQUIRED_FOR_EXTRACTION = True
JSON_PATH_BRACKETED_KEY_SUPPORTED = False
JSON_KEY_VALUE_PAIR_SEP = "," JSON_KEY_VALUE_PAIR_SEP = ","
TRANSFORMS = { TRANSFORMS = {
@ -646,10 +650,10 @@ class MySQL(Dialect):
exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")),
exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")),
exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")),
exp.GetPath: path_to_jsonpath(), exp.GroupConcat: lambda self,
exp.GroupConcat: lambda self, e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""",
exp.ILike: no_ilike_sql, exp.ILike: no_ilike_sql,
exp.JSONExtractScalar: arrow_json_extract_scalar_sql, exp.JSONExtractScalar: arrow_json_extract_sql,
exp.Max: max_or_greatest, exp.Max: max_or_greatest,
exp.Min: min_or_least, exp.Min: min_or_least,
exp.Month: _remove_ts_or_ds_to_date(), exp.Month: _remove_ts_or_ds_to_date(),
@ -672,6 +676,9 @@ class MySQL(Dialect):
exp.TableSample: no_tablesample_sql, exp.TableSample: no_tablesample_sql,
exp.TimeFromParts: rename_func("MAKETIME"), exp.TimeFromParts: rename_func("MAKETIME"),
exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"),
exp.TimestampDiff: lambda self, e: self.func(
"TIMESTAMPDIFF", e.text("unit"), e.expression, e.this
),
exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), exp.TimestampSub: date_add_interval_sql("DATE", "SUB"),
exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"),
exp.TimeStrToTime: lambda self, e: self.sql(exp.cast(e.this, "datetime", copy=True)), exp.TimeStrToTime: lambda self, e: self.sql(exp.cast(e.this, "datetime", copy=True)),

View file

@ -199,7 +199,8 @@ class Oracle(Dialect):
transforms.eliminate_qualify, transforms.eliminate_qualify,
] ]
), ),
exp.StrToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})", exp.StrToTime: lambda self,
e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})",
exp.StrToDate: lambda self, e: f"TO_DATE({self.sql(e, 'this')}, {self.format_time(e)})", exp.StrToDate: lambda self, e: f"TO_DATE({self.sql(e, 'this')}, {self.format_time(e)})",
exp.Subquery: lambda self, e: self.subquery_sql(e, sep=" "), exp.Subquery: lambda self, e: self.subquery_sql(e, sep=" "),
exp.Substring: rename_func("SUBSTR"), exp.Substring: rename_func("SUBSTR"),
@ -208,7 +209,8 @@ class Oracle(Dialect):
exp.TimeToStr: lambda self, e: f"TO_CHAR({self.sql(e, 'this')}, {self.format_time(e)})", exp.TimeToStr: lambda self, e: f"TO_CHAR({self.sql(e, 'this')}, {self.format_time(e)})",
exp.ToChar: lambda self, e: self.function_fallback_sql(e), exp.ToChar: lambda self, e: self.function_fallback_sql(e),
exp.Trim: trim_sql, exp.Trim: trim_sql,
exp.UnixToTime: lambda self, e: f"TO_DATE('1970-01-01','YYYY-MM-DD') + ({self.sql(e, 'this')} / 86400)", exp.UnixToTime: lambda self,
e: f"TO_DATE('1970-01-01','YYYY-MM-DD') + ({self.sql(e, 'this')} / 86400)",
} }
PROPERTIES_LOCATION = { PROPERTIES_LOCATION = {

View file

@ -7,11 +7,11 @@ from sqlglot.dialects.dialect import (
DATE_ADD_OR_SUB, DATE_ADD_OR_SUB,
Dialect, Dialect,
any_value_to_max_sql, any_value_to_max_sql,
arrow_json_extract_scalar_sql,
arrow_json_extract_sql,
bool_xor_sql, bool_xor_sql,
datestrtodate_sql, datestrtodate_sql,
format_time_lambda, format_time_lambda,
json_extract_segments,
json_path_key_only_name,
max_or_greatest, max_or_greatest,
merge_without_target_sql, merge_without_target_sql,
min_or_least, min_or_least,
@ -20,6 +20,7 @@ from sqlglot.dialects.dialect import (
no_paren_current_date_sql, no_paren_current_date_sql,
no_pivot_sql, no_pivot_sql,
no_trycast_sql, no_trycast_sql,
parse_json_extract_path,
parse_timestamp_trunc, parse_timestamp_trunc,
rename_func, rename_func,
str_position_sql, str_position_sql,
@ -292,6 +293,8 @@ class Postgres(Dialect):
**parser.Parser.FUNCTIONS, **parser.Parser.FUNCTIONS,
"DATE_TRUNC": parse_timestamp_trunc, "DATE_TRUNC": parse_timestamp_trunc,
"GENERATE_SERIES": _generate_series, "GENERATE_SERIES": _generate_series,
"JSON_EXTRACT_PATH": parse_json_extract_path(exp.JSONExtract),
"JSON_EXTRACT_PATH_TEXT": parse_json_extract_path(exp.JSONExtractScalar),
"MAKE_TIME": exp.TimeFromParts.from_arg_list, "MAKE_TIME": exp.TimeFromParts.from_arg_list,
"MAKE_TIMESTAMP": exp.TimestampFromParts.from_arg_list, "MAKE_TIMESTAMP": exp.TimestampFromParts.from_arg_list,
"NOW": exp.CurrentTimestamp.from_arg_list, "NOW": exp.CurrentTimestamp.from_arg_list,
@ -375,8 +378,15 @@ class Postgres(Dialect):
TABLESAMPLE_SIZE_IS_ROWS = False TABLESAMPLE_SIZE_IS_ROWS = False
TABLESAMPLE_SEED_KEYWORD = "REPEATABLE" TABLESAMPLE_SEED_KEYWORD = "REPEATABLE"
SUPPORTS_SELECT_INTO = True SUPPORTS_SELECT_INTO = True
# https://www.postgresql.org/docs/current/sql-createtable.html JSON_TYPE_REQUIRED_FOR_EXTRACTION = True
SUPPORTS_UNLOGGED_TABLES = True SUPPORTS_UNLOGGED_TABLES = True
LIKE_PROPERTY_INSIDE_SCHEMA = True
SUPPORTED_JSON_PATH_PARTS = {
exp.JSONPathKey,
exp.JSONPathRoot,
exp.JSONPathSubscript,
}
TYPE_MAPPING = { TYPE_MAPPING = {
**generator.Generator.TYPE_MAPPING, **generator.Generator.TYPE_MAPPING,
@ -412,11 +422,14 @@ class Postgres(Dialect):
exp.DateSub: _date_add_sql("-"), exp.DateSub: _date_add_sql("-"),
exp.Explode: rename_func("UNNEST"), exp.Explode: rename_func("UNNEST"),
exp.GroupConcat: _string_agg_sql, exp.GroupConcat: _string_agg_sql,
exp.JSONExtract: arrow_json_extract_sql, exp.JSONExtract: json_extract_segments("JSON_EXTRACT_PATH"),
exp.JSONExtractScalar: arrow_json_extract_scalar_sql, exp.JSONExtractScalar: json_extract_segments("JSON_EXTRACT_PATH_TEXT"),
exp.JSONBExtract: lambda self, e: self.binary(e, "#>"), exp.JSONBExtract: lambda self, e: self.binary(e, "#>"),
exp.JSONBExtractScalar: lambda self, e: self.binary(e, "#>>"), exp.JSONBExtractScalar: lambda self, e: self.binary(e, "#>>"),
exp.JSONBContains: lambda self, e: self.binary(e, "?"), exp.JSONBContains: lambda self, e: self.binary(e, "?"),
exp.JSONPathKey: json_path_key_only_name,
exp.JSONPathRoot: lambda *_: "",
exp.JSONPathSubscript: lambda self, e: self.json_path_part(e.this),
exp.LastDay: no_last_day_sql, exp.LastDay: no_last_day_sql,
exp.LogicalOr: rename_func("BOOL_OR"), exp.LogicalOr: rename_func("BOOL_OR"),
exp.LogicalAnd: rename_func("BOOL_AND"), exp.LogicalAnd: rename_func("BOOL_AND"),
@ -443,7 +456,8 @@ class Postgres(Dialect):
] ]
), ),
exp.StrPosition: str_position_sql, exp.StrPosition: str_position_sql,
exp.StrToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})", exp.StrToTime: lambda self,
e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})",
exp.StructExtract: struct_extract_sql, exp.StructExtract: struct_extract_sql,
exp.Substring: _substring_sql, exp.Substring: _substring_sql,
exp.TimeFromParts: rename_func("MAKE_TIME"), exp.TimeFromParts: rename_func("MAKE_TIME"),

View file

@ -18,7 +18,6 @@ from sqlglot.dialects.dialect import (
no_pivot_sql, no_pivot_sql,
no_safe_divide_sql, no_safe_divide_sql,
no_timestamp_sql, no_timestamp_sql,
path_to_jsonpath,
regexp_extract_sql, regexp_extract_sql,
rename_func, rename_func,
right_to_substring_sql, right_to_substring_sql,
@ -150,7 +149,7 @@ def _unnest_sequence(expression: exp.Expression) -> exp.Expression:
return expression return expression
def _first_last_sql(self: Presto.Generator, expression: exp.First | exp.Last) -> str: def _first_last_sql(self: Presto.Generator, expression: exp.Func) -> str:
""" """
Trino doesn't support FIRST / LAST as functions, but they're valid in the context Trino doesn't support FIRST / LAST as functions, but they're valid in the context
of MATCH_RECOGNIZE, so we need to preserve them in that case. In all other cases of MATCH_RECOGNIZE, so we need to preserve them in that case. In all other cases
@ -292,6 +291,7 @@ class Presto(Dialect):
STRUCT_DELIMITER = ("(", ")") STRUCT_DELIMITER = ("(", ")")
LIMIT_ONLY_LITERALS = True LIMIT_ONLY_LITERALS = True
SUPPORTS_SINGLE_ARG_CONCAT = False SUPPORTS_SINGLE_ARG_CONCAT = False
LIKE_PROPERTY_INSIDE_SCHEMA = True
PROPERTIES_LOCATION = { PROPERTIES_LOCATION = {
**generator.Generator.PROPERTIES_LOCATION, **generator.Generator.PROPERTIES_LOCATION,
@ -324,12 +324,18 @@ class Presto(Dialect):
exp.ArrayContains: rename_func("CONTAINS"), exp.ArrayContains: rename_func("CONTAINS"),
exp.ArraySize: rename_func("CARDINALITY"), exp.ArraySize: rename_func("CARDINALITY"),
exp.ArrayUniqueAgg: rename_func("SET_AGG"), exp.ArrayUniqueAgg: rename_func("SET_AGG"),
exp.BitwiseAnd: lambda self, e: f"BITWISE_AND({self.sql(e, 'this')}, {self.sql(e, 'expression')})", exp.AtTimeZone: rename_func("AT_TIMEZONE"),
exp.BitwiseLeftShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_LEFT({self.sql(e, 'this')}, {self.sql(e, 'expression')})", exp.BitwiseAnd: lambda self,
e: f"BITWISE_AND({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
exp.BitwiseLeftShift: lambda self,
e: f"BITWISE_ARITHMETIC_SHIFT_LEFT({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
exp.BitwiseNot: lambda self, e: f"BITWISE_NOT({self.sql(e, 'this')})", exp.BitwiseNot: lambda self, e: f"BITWISE_NOT({self.sql(e, 'this')})",
exp.BitwiseOr: lambda self, e: f"BITWISE_OR({self.sql(e, 'this')}, {self.sql(e, 'expression')})", exp.BitwiseOr: lambda self,
exp.BitwiseRightShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_RIGHT({self.sql(e, 'this')}, {self.sql(e, 'expression')})", e: f"BITWISE_OR({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
exp.BitwiseXor: lambda self, e: f"BITWISE_XOR({self.sql(e, 'this')}, {self.sql(e, 'expression')})", exp.BitwiseRightShift: lambda self,
e: f"BITWISE_ARITHMETIC_SHIFT_RIGHT({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
exp.BitwiseXor: lambda self,
e: f"BITWISE_XOR({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
exp.Cast: transforms.preprocess([transforms.epoch_cast_to_ts]), exp.Cast: transforms.preprocess([transforms.epoch_cast_to_ts]),
exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP", exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP",
exp.DateAdd: lambda self, e: self.func( exp.DateAdd: lambda self, e: self.func(
@ -344,7 +350,8 @@ class Presto(Dialect):
"DATE_DIFF", exp.Literal.string(e.text("unit") or "DAY"), e.expression, e.this "DATE_DIFF", exp.Literal.string(e.text("unit") or "DAY"), e.expression, e.this
), ),
exp.DateStrToDate: datestrtodate_sql, exp.DateStrToDate: datestrtodate_sql,
exp.DateToDi: lambda self, e: f"CAST(DATE_FORMAT({self.sql(e, 'this')}, {Presto.DATEINT_FORMAT}) AS INT)", exp.DateToDi: lambda self,
e: f"CAST(DATE_FORMAT({self.sql(e, 'this')}, {Presto.DATEINT_FORMAT}) AS INT)",
exp.DateSub: lambda self, e: self.func( exp.DateSub: lambda self, e: self.func(
"DATE_ADD", "DATE_ADD",
exp.Literal.string(e.text("unit") or "DAY"), exp.Literal.string(e.text("unit") or "DAY"),
@ -352,12 +359,14 @@ class Presto(Dialect):
e.this, e.this,
), ),
exp.Decode: lambda self, e: encode_decode_sql(self, e, "FROM_UTF8"), exp.Decode: lambda self, e: encode_decode_sql(self, e, "FROM_UTF8"),
exp.DiToDate: lambda self, e: f"CAST(DATE_PARSE(CAST({self.sql(e, 'this')} AS VARCHAR), {Presto.DATEINT_FORMAT}) AS DATE)", exp.DiToDate: lambda self,
e: f"CAST(DATE_PARSE(CAST({self.sql(e, 'this')} AS VARCHAR), {Presto.DATEINT_FORMAT}) AS DATE)",
exp.Encode: lambda self, e: encode_decode_sql(self, e, "TO_UTF8"), exp.Encode: lambda self, e: encode_decode_sql(self, e, "TO_UTF8"),
exp.FileFormatProperty: lambda self, e: f"FORMAT='{e.name.upper()}'", exp.FileFormatProperty: lambda self, e: f"FORMAT='{e.name.upper()}'",
exp.First: _first_last_sql, exp.First: _first_last_sql,
exp.FromTimeZone: lambda self, e: f"WITH_TIMEZONE({self.sql(e, 'this')}, {self.sql(e, 'zone')}) AT TIME ZONE 'UTC'", exp.FirstValue: _first_last_sql,
exp.GetPath: path_to_jsonpath(), exp.FromTimeZone: lambda self,
e: f"WITH_TIMEZONE({self.sql(e, 'this')}, {self.sql(e, 'zone')}) AT TIME ZONE 'UTC'",
exp.Group: transforms.preprocess([transforms.unalias_group]), exp.Group: transforms.preprocess([transforms.unalias_group]),
exp.GroupConcat: lambda self, e: self.func( exp.GroupConcat: lambda self, e: self.func(
"ARRAY_JOIN", self.func("ARRAY_AGG", e.this), e.args.get("separator") "ARRAY_JOIN", self.func("ARRAY_AGG", e.this), e.args.get("separator")
@ -368,6 +377,7 @@ class Presto(Dialect):
exp.Initcap: _initcap_sql, exp.Initcap: _initcap_sql,
exp.ParseJSON: rename_func("JSON_PARSE"), exp.ParseJSON: rename_func("JSON_PARSE"),
exp.Last: _first_last_sql, exp.Last: _first_last_sql,
exp.LastValue: _first_last_sql,
exp.LastDay: lambda self, e: self.func("LAST_DAY_OF_MONTH", e.this), exp.LastDay: lambda self, e: self.func("LAST_DAY_OF_MONTH", e.this),
exp.Lateral: _explode_to_unnest_sql, exp.Lateral: _explode_to_unnest_sql,
exp.Left: left_to_substring_sql, exp.Left: left_to_substring_sql,
@ -394,26 +404,33 @@ class Presto(Dialect):
exp.StrToDate: lambda self, e: f"CAST({_str_to_time_sql(self, e)} AS DATE)", exp.StrToDate: lambda self, e: f"CAST({_str_to_time_sql(self, e)} AS DATE)",
exp.StrToMap: rename_func("SPLIT_TO_MAP"), exp.StrToMap: rename_func("SPLIT_TO_MAP"),
exp.StrToTime: _str_to_time_sql, exp.StrToTime: _str_to_time_sql,
exp.StrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {self.format_time(e)}))", exp.StrToUnix: lambda self,
e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {self.format_time(e)}))",
exp.StructExtract: struct_extract_sql, exp.StructExtract: struct_extract_sql,
exp.Table: transforms.preprocess([_unnest_sequence]), exp.Table: transforms.preprocess([_unnest_sequence]),
exp.Timestamp: no_timestamp_sql, exp.Timestamp: no_timestamp_sql,
exp.TimestampTrunc: timestamptrunc_sql, exp.TimestampTrunc: timestamptrunc_sql,
exp.TimeStrToDate: timestrtotime_sql, exp.TimeStrToDate: timestrtotime_sql,
exp.TimeStrToTime: timestrtotime_sql, exp.TimeStrToTime: timestrtotime_sql,
exp.TimeStrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {Presto.TIME_FORMAT}))", exp.TimeStrToUnix: lambda self,
exp.TimeToStr: lambda self, e: f"DATE_FORMAT({self.sql(e, 'this')}, {self.format_time(e)})", e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {Presto.TIME_FORMAT}))",
exp.TimeToStr: lambda self,
e: f"DATE_FORMAT({self.sql(e, 'this')}, {self.format_time(e)})",
exp.TimeToUnix: rename_func("TO_UNIXTIME"), exp.TimeToUnix: rename_func("TO_UNIXTIME"),
exp.ToChar: lambda self, e: f"DATE_FORMAT({self.sql(e, 'this')}, {self.format_time(e)})", exp.ToChar: lambda self,
e: f"DATE_FORMAT({self.sql(e, 'this')}, {self.format_time(e)})",
exp.TryCast: transforms.preprocess([transforms.epoch_cast_to_ts]), exp.TryCast: transforms.preprocess([transforms.epoch_cast_to_ts]),
exp.TsOrDiToDi: lambda self, e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS VARCHAR), '-', ''), 1, 8) AS INT)", exp.TsOrDiToDi: lambda self,
e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS VARCHAR), '-', ''), 1, 8) AS INT)",
exp.TsOrDsAdd: _ts_or_ds_add_sql, exp.TsOrDsAdd: _ts_or_ds_add_sql,
exp.TsOrDsDiff: _ts_or_ds_diff_sql, exp.TsOrDsDiff: _ts_or_ds_diff_sql,
exp.TsOrDsToDate: _ts_or_ds_to_date_sql, exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
exp.Unhex: rename_func("FROM_HEX"), exp.Unhex: rename_func("FROM_HEX"),
exp.UnixToStr: lambda self, e: f"DATE_FORMAT(FROM_UNIXTIME({self.sql(e, 'this')}), {self.format_time(e)})", exp.UnixToStr: lambda self,
e: f"DATE_FORMAT(FROM_UNIXTIME({self.sql(e, 'this')}), {self.format_time(e)})",
exp.UnixToTime: _unix_to_time_sql, exp.UnixToTime: _unix_to_time_sql,
exp.UnixToTimeStr: lambda self, e: f"CAST(FROM_UNIXTIME({self.sql(e, 'this')}) AS VARCHAR)", exp.UnixToTimeStr: lambda self,
e: f"CAST(FROM_UNIXTIME({self.sql(e, 'this')}) AS VARCHAR)",
exp.VariancePop: rename_func("VAR_POP"), exp.VariancePop: rename_func("VAR_POP"),
exp.With: transforms.preprocess([transforms.add_recursive_cte_column_names]), exp.With: transforms.preprocess([transforms.add_recursive_cte_column_names]),
exp.WithinGroup: transforms.preprocess( exp.WithinGroup: transforms.preprocess(

View file

@ -9,6 +9,7 @@ from sqlglot.dialects.dialect import (
concat_ws_to_dpipe_sql, concat_ws_to_dpipe_sql,
date_delta_sql, date_delta_sql,
generatedasidentitycolumnconstraint_sql, generatedasidentitycolumnconstraint_sql,
json_extract_segments,
no_tablesample_sql, no_tablesample_sql,
rename_func, rename_func,
) )
@ -20,10 +21,6 @@ if t.TYPE_CHECKING:
from sqlglot._typing import E from sqlglot._typing import E
def _json_sql(self: Redshift.Generator, expression: exp.JSONExtract | exp.JSONExtractScalar) -> str:
return f'{self.sql(expression, "this")}."{expression.expression.name}"'
def _parse_date_delta(expr_type: t.Type[E]) -> t.Callable[[t.List], E]: def _parse_date_delta(expr_type: t.Type[E]) -> t.Callable[[t.List], E]:
def _parse_delta(args: t.List) -> E: def _parse_delta(args: t.List) -> E:
expr = expr_type(this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0)) expr = expr_type(this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0))
@ -62,6 +59,7 @@ class Redshift(Postgres):
"DATE_ADD": _parse_date_delta(exp.TsOrDsAdd), "DATE_ADD": _parse_date_delta(exp.TsOrDsAdd),
"DATEDIFF": _parse_date_delta(exp.TsOrDsDiff), "DATEDIFF": _parse_date_delta(exp.TsOrDsDiff),
"DATE_DIFF": _parse_date_delta(exp.TsOrDsDiff), "DATE_DIFF": _parse_date_delta(exp.TsOrDsDiff),
"GETDATE": exp.CurrentTimestamp.from_arg_list,
"LISTAGG": exp.GroupConcat.from_arg_list, "LISTAGG": exp.GroupConcat.from_arg_list,
"STRTOL": exp.FromBase.from_arg_list, "STRTOL": exp.FromBase.from_arg_list,
} }
@ -69,6 +67,7 @@ class Redshift(Postgres):
NO_PAREN_FUNCTION_PARSERS = { NO_PAREN_FUNCTION_PARSERS = {
**Postgres.Parser.NO_PAREN_FUNCTION_PARSERS, **Postgres.Parser.NO_PAREN_FUNCTION_PARSERS,
"APPROXIMATE": lambda self: self._parse_approximate_count(), "APPROXIMATE": lambda self: self._parse_approximate_count(),
"SYSDATE": lambda self: self.expression(exp.CurrentTimestamp, transaction=True),
} }
def _parse_table( def _parse_table(
@ -77,6 +76,7 @@ class Redshift(Postgres):
joins: bool = False, joins: bool = False,
alias_tokens: t.Optional[t.Collection[TokenType]] = None, alias_tokens: t.Optional[t.Collection[TokenType]] = None,
parse_bracket: bool = False, parse_bracket: bool = False,
is_db_reference: bool = False,
) -> t.Optional[exp.Expression]: ) -> t.Optional[exp.Expression]:
# Redshift supports UNPIVOTing SUPER objects, e.g. `UNPIVOT foo.obj[0] AS val AT attr` # Redshift supports UNPIVOTing SUPER objects, e.g. `UNPIVOT foo.obj[0] AS val AT attr`
unpivot = self._match(TokenType.UNPIVOT) unpivot = self._match(TokenType.UNPIVOT)
@ -85,6 +85,7 @@ class Redshift(Postgres):
joins=joins, joins=joins,
alias_tokens=alias_tokens, alias_tokens=alias_tokens,
parse_bracket=parse_bracket, parse_bracket=parse_bracket,
is_db_reference=is_db_reference,
) )
return self.expression(exp.Pivot, this=table, unpivot=True) if unpivot else table return self.expression(exp.Pivot, this=table, unpivot=True) if unpivot else table
@ -153,7 +154,6 @@ class Redshift(Postgres):
**Postgres.Tokenizer.KEYWORDS, **Postgres.Tokenizer.KEYWORDS,
"HLLSKETCH": TokenType.HLLSKETCH, "HLLSKETCH": TokenType.HLLSKETCH,
"SUPER": TokenType.SUPER, "SUPER": TokenType.SUPER,
"SYSDATE": TokenType.CURRENT_TIMESTAMP,
"TOP": TokenType.TOP, "TOP": TokenType.TOP,
"UNLOAD": TokenType.COMMAND, "UNLOAD": TokenType.COMMAND,
"VARBYTE": TokenType.VARBINARY, "VARBYTE": TokenType.VARBINARY,
@ -180,31 +180,29 @@ class Redshift(Postgres):
exp.DataType.Type.VARBINARY: "VARBYTE", exp.DataType.Type.VARBINARY: "VARBYTE",
} }
PROPERTIES_LOCATION = {
**Postgres.Generator.PROPERTIES_LOCATION,
exp.LikeProperty: exp.Properties.Location.POST_WITH,
}
TRANSFORMS = { TRANSFORMS = {
**Postgres.Generator.TRANSFORMS, **Postgres.Generator.TRANSFORMS,
exp.Concat: concat_to_dpipe_sql, exp.Concat: concat_to_dpipe_sql,
exp.ConcatWs: concat_ws_to_dpipe_sql, exp.ConcatWs: concat_ws_to_dpipe_sql,
exp.ApproxDistinct: lambda self, e: f"APPROXIMATE COUNT(DISTINCT {self.sql(e, 'this')})", exp.ApproxDistinct: lambda self,
exp.CurrentTimestamp: lambda self, e: "SYSDATE", e: f"APPROXIMATE COUNT(DISTINCT {self.sql(e, 'this')})",
exp.CurrentTimestamp: lambda self, e: (
"SYSDATE" if e.args.get("transaction") else "GETDATE()"
),
exp.DateAdd: date_delta_sql("DATEADD"), exp.DateAdd: date_delta_sql("DATEADD"),
exp.DateDiff: date_delta_sql("DATEDIFF"), exp.DateDiff: date_delta_sql("DATEDIFF"),
exp.DistKeyProperty: lambda self, e: f"DISTKEY({e.name})", exp.DistKeyProperty: lambda self, e: f"DISTKEY({e.name})",
exp.DistStyleProperty: lambda self, e: self.naked_property(e), exp.DistStyleProperty: lambda self, e: self.naked_property(e),
exp.FromBase: rename_func("STRTOL"), exp.FromBase: rename_func("STRTOL"),
exp.GeneratedAsIdentityColumnConstraint: generatedasidentitycolumnconstraint_sql, exp.GeneratedAsIdentityColumnConstraint: generatedasidentitycolumnconstraint_sql,
exp.JSONExtract: _json_sql, exp.JSONExtract: json_extract_segments("JSON_EXTRACT_PATH_TEXT"),
exp.JSONExtractScalar: _json_sql,
exp.GroupConcat: rename_func("LISTAGG"), exp.GroupConcat: rename_func("LISTAGG"),
exp.ParseJSON: rename_func("JSON_PARSE"), exp.ParseJSON: rename_func("JSON_PARSE"),
exp.Select: transforms.preprocess( exp.Select: transforms.preprocess(
[transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins] [transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins]
), ),
exp.SortKeyProperty: lambda self, e: f"{'COMPOUND ' if e.args['compound'] else ''}SORTKEY({self.format_args(*e.this)})", exp.SortKeyProperty: lambda self,
e: f"{'COMPOUND ' if e.args['compound'] else ''}SORTKEY({self.format_args(*e.this)})",
exp.TableSample: no_tablesample_sql, exp.TableSample: no_tablesample_sql,
exp.TsOrDsAdd: date_delta_sql("DATEADD"), exp.TsOrDsAdd: date_delta_sql("DATEADD"),
exp.TsOrDsDiff: date_delta_sql("DATEDIFF"), exp.TsOrDsDiff: date_delta_sql("DATEDIFF"),
@ -228,6 +226,13 @@ class Redshift(Postgres):
"""Redshift doesn't have `WITH` as part of their with_properties so we remove it""" """Redshift doesn't have `WITH` as part of their with_properties so we remove it"""
return self.properties(properties, prefix=" ", suffix="") return self.properties(properties, prefix=" ", suffix="")
def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
if expression.is_type(exp.DataType.Type.JSON):
# Redshift doesn't support a JSON type, so casting to it is treated as a noop
return self.sql(expression, "this")
return super().cast_sql(expression, safe_prefix=safe_prefix)
def datatype_sql(self, expression: exp.DataType) -> str: def datatype_sql(self, expression: exp.DataType) -> str:
""" """
Redshift converts the `TEXT` data type to `VARCHAR(255)` by default when people more generally mean Redshift converts the `TEXT` data type to `VARCHAR(255)` by default when people more generally mean

View file

@ -21,19 +21,13 @@ from sqlglot.dialects.dialect import (
var_map_sql, var_map_sql,
) )
from sqlglot.expressions import Literal from sqlglot.expressions import Literal
from sqlglot.helper import seq_get from sqlglot.helper import is_int, seq_get
from sqlglot.tokens import TokenType from sqlglot.tokens import TokenType
if t.TYPE_CHECKING: if t.TYPE_CHECKING:
from sqlglot._typing import E from sqlglot._typing import E
def _check_int(s: str) -> bool:
if s[0] in ("-", "+"):
return s[1:].isdigit()
return s.isdigit()
# from https://docs.snowflake.com/en/sql-reference/functions/to_timestamp.html # from https://docs.snowflake.com/en/sql-reference/functions/to_timestamp.html
def _parse_to_timestamp(args: t.List) -> t.Union[exp.StrToTime, exp.UnixToTime, exp.TimeStrToTime]: def _parse_to_timestamp(args: t.List) -> t.Union[exp.StrToTime, exp.UnixToTime, exp.TimeStrToTime]:
if len(args) == 2: if len(args) == 2:
@ -53,7 +47,7 @@ def _parse_to_timestamp(args: t.List) -> t.Union[exp.StrToTime, exp.UnixToTime,
return exp.TimeStrToTime.from_arg_list(args) return exp.TimeStrToTime.from_arg_list(args)
if first_arg.is_string: if first_arg.is_string:
if _check_int(first_arg.this): if is_int(first_arg.this):
# case: <integer> # case: <integer>
return exp.UnixToTime.from_arg_list(args) return exp.UnixToTime.from_arg_list(args)
@ -241,7 +235,6 @@ DATE_PART_MAPPING = {
"NSECOND": "NANOSECOND", "NSECOND": "NANOSECOND",
"NSECONDS": "NANOSECOND", "NSECONDS": "NANOSECOND",
"NANOSECS": "NANOSECOND", "NANOSECS": "NANOSECOND",
"NSECONDS": "NANOSECOND",
"EPOCH": "EPOCH_SECOND", "EPOCH": "EPOCH_SECOND",
"EPOCH_SECONDS": "EPOCH_SECOND", "EPOCH_SECONDS": "EPOCH_SECOND",
"EPOCH_MILLISECONDS": "EPOCH_MILLISECOND", "EPOCH_MILLISECONDS": "EPOCH_MILLISECOND",
@ -291,7 +284,9 @@ def _parse_colon_get_path(
path = exp.Literal.string(path.sql(dialect="snowflake")) path = exp.Literal.string(path.sql(dialect="snowflake"))
# The extraction operator : is left-associative # The extraction operator : is left-associative
this = self.expression(exp.GetPath, this=this, expression=path) this = self.expression(
exp.JSONExtract, this=this, expression=self.dialect.to_json_path(path)
)
if target_type: if target_type:
this = exp.cast(this, target_type) this = exp.cast(this, target_type)
@ -411,6 +406,9 @@ class Snowflake(Dialect):
"DATEDIFF": _parse_datediff, "DATEDIFF": _parse_datediff,
"DIV0": _div0_to_if, "DIV0": _div0_to_if,
"FLATTEN": exp.Explode.from_arg_list, "FLATTEN": exp.Explode.from_arg_list,
"GET_PATH": lambda args, dialect: exp.JSONExtract(
this=seq_get(args, 0), expression=dialect.to_json_path(seq_get(args, 1))
),
"IFF": exp.If.from_arg_list, "IFF": exp.If.from_arg_list,
"LAST_DAY": lambda args: exp.LastDay( "LAST_DAY": lambda args: exp.LastDay(
this=seq_get(args, 0), unit=_map_date_part(seq_get(args, 1)) this=seq_get(args, 0), unit=_map_date_part(seq_get(args, 1))
@ -474,6 +472,8 @@ class Snowflake(Dialect):
"TERSE SCHEMAS": _show_parser("SCHEMAS"), "TERSE SCHEMAS": _show_parser("SCHEMAS"),
"OBJECTS": _show_parser("OBJECTS"), "OBJECTS": _show_parser("OBJECTS"),
"TERSE OBJECTS": _show_parser("OBJECTS"), "TERSE OBJECTS": _show_parser("OBJECTS"),
"TABLES": _show_parser("TABLES"),
"TERSE TABLES": _show_parser("TABLES"),
"PRIMARY KEYS": _show_parser("PRIMARY KEYS"), "PRIMARY KEYS": _show_parser("PRIMARY KEYS"),
"TERSE PRIMARY KEYS": _show_parser("PRIMARY KEYS"), "TERSE PRIMARY KEYS": _show_parser("PRIMARY KEYS"),
"COLUMNS": _show_parser("COLUMNS"), "COLUMNS": _show_parser("COLUMNS"),
@ -534,7 +534,9 @@ class Snowflake(Dialect):
return table return table
def _parse_table_parts(self, schema: bool = False) -> exp.Table: def _parse_table_parts(
self, schema: bool = False, is_db_reference: bool = False
) -> exp.Table:
# https://docs.snowflake.com/en/user-guide/querying-stage # https://docs.snowflake.com/en/user-guide/querying-stage
if self._match(TokenType.STRING, advance=False): if self._match(TokenType.STRING, advance=False):
table = self._parse_string() table = self._parse_string()
@ -550,7 +552,9 @@ class Snowflake(Dialect):
self._match(TokenType.L_PAREN) self._match(TokenType.L_PAREN)
while self._curr and not self._match(TokenType.R_PAREN): while self._curr and not self._match(TokenType.R_PAREN):
if self._match_text_seq("FILE_FORMAT", "=>"): if self._match_text_seq("FILE_FORMAT", "=>"):
file_format = self._parse_string() or super()._parse_table_parts() file_format = self._parse_string() or super()._parse_table_parts(
is_db_reference=is_db_reference
)
elif self._match_text_seq("PATTERN", "=>"): elif self._match_text_seq("PATTERN", "=>"):
pattern = self._parse_string() pattern = self._parse_string()
else: else:
@ -560,7 +564,7 @@ class Snowflake(Dialect):
table = self.expression(exp.Table, this=table, format=file_format, pattern=pattern) table = self.expression(exp.Table, this=table, format=file_format, pattern=pattern)
else: else:
table = super()._parse_table_parts(schema=schema) table = super()._parse_table_parts(schema=schema, is_db_reference=is_db_reference)
return self._parse_at_before(table) return self._parse_at_before(table)
@ -587,6 +591,8 @@ class Snowflake(Dialect):
# which is syntactically valid but has no effect on the output # which is syntactically valid but has no effect on the output
terse = self._tokens[self._index - 2].text.upper() == "TERSE" terse = self._tokens[self._index - 2].text.upper() == "TERSE"
history = self._match_text_seq("HISTORY")
like = self._parse_string() if self._match(TokenType.LIKE) else None like = self._parse_string() if self._match(TokenType.LIKE) else None
if self._match(TokenType.IN): if self._match(TokenType.IN):
@ -597,7 +603,7 @@ class Snowflake(Dialect):
if self._curr: if self._curr:
scope = self._parse_table_parts() scope = self._parse_table_parts()
elif self._curr: elif self._curr:
scope_kind = "SCHEMA" if this == "OBJECTS" else "TABLE" scope_kind = "SCHEMA" if this in ("OBJECTS", "TABLES") else "TABLE"
scope = self._parse_table_parts() scope = self._parse_table_parts()
return self.expression( return self.expression(
@ -605,6 +611,7 @@ class Snowflake(Dialect):
**{ **{
"terse": terse, "terse": terse,
"this": this, "this": this,
"history": history,
"like": like, "like": like,
"scope": scope, "scope": scope,
"scope_kind": scope_kind, "scope_kind": scope_kind,
@ -715,8 +722,10 @@ class Snowflake(Dialect):
), ),
exp.GroupConcat: rename_func("LISTAGG"), exp.GroupConcat: rename_func("LISTAGG"),
exp.If: if_sql(name="IFF", false_value="NULL"), exp.If: if_sql(name="IFF", false_value="NULL"),
exp.JSONExtract: lambda self, e: f"{self.sql(e, 'this')}[{self.sql(e, 'expression')}]", exp.JSONExtract: rename_func("GET_PATH"),
exp.JSONExtractScalar: rename_func("JSON_EXTRACT_PATH_TEXT"),
exp.JSONObject: lambda self, e: self.func("OBJECT_CONSTRUCT_KEEP_NULL", *e.expressions), exp.JSONObject: lambda self, e: self.func("OBJECT_CONSTRUCT_KEEP_NULL", *e.expressions),
exp.JSONPathRoot: lambda *_: "",
exp.LogicalAnd: rename_func("BOOLAND_AGG"), exp.LogicalAnd: rename_func("BOOLAND_AGG"),
exp.LogicalOr: rename_func("BOOLOR_AGG"), exp.LogicalOr: rename_func("BOOLOR_AGG"),
exp.Map: lambda self, e: var_map_sql(self, e, "OBJECT_CONSTRUCT"), exp.Map: lambda self, e: var_map_sql(self, e, "OBJECT_CONSTRUCT"),
@ -745,7 +754,8 @@ class Snowflake(Dialect):
exp.StrPosition: lambda self, e: self.func( exp.StrPosition: lambda self, e: self.func(
"POSITION", e.args.get("substr"), e.this, e.args.get("position") "POSITION", e.args.get("substr"), e.this, e.args.get("position")
), ),
exp.StrToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})", exp.StrToTime: lambda self,
e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})",
exp.Struct: lambda self, e: self.func( exp.Struct: lambda self, e: self.func(
"OBJECT_CONSTRUCT", "OBJECT_CONSTRUCT",
*(arg for expression in e.expressions for arg in expression.flatten()), *(arg for expression in e.expressions for arg in expression.flatten()),
@ -771,6 +781,12 @@ class Snowflake(Dialect):
exp.Xor: rename_func("BOOLXOR"), exp.Xor: rename_func("BOOLXOR"),
} }
SUPPORTED_JSON_PATH_PARTS = {
exp.JSONPathKey,
exp.JSONPathRoot,
exp.JSONPathSubscript,
}
TYPE_MAPPING = { TYPE_MAPPING = {
**generator.Generator.TYPE_MAPPING, **generator.Generator.TYPE_MAPPING,
exp.DataType.Type.TIMESTAMP: "TIMESTAMPNTZ", exp.DataType.Type.TIMESTAMP: "TIMESTAMPNTZ",
@ -841,6 +857,7 @@ class Snowflake(Dialect):
def show_sql(self, expression: exp.Show) -> str: def show_sql(self, expression: exp.Show) -> str:
terse = "TERSE " if expression.args.get("terse") else "" terse = "TERSE " if expression.args.get("terse") else ""
history = " HISTORY" if expression.args.get("history") else ""
like = self.sql(expression, "like") like = self.sql(expression, "like")
like = f" LIKE {like}" if like else "" like = f" LIKE {like}" if like else ""
@ -861,9 +878,7 @@ class Snowflake(Dialect):
if from_: if from_:
from_ = f" FROM {from_}" from_ = f" FROM {from_}"
return ( return f"SHOW {terse}{expression.name}{history}{like}{scope_kind}{scope}{starts_with}{limit}{from_}"
f"SHOW {terse}{expression.name}{like}{scope_kind}{scope}{starts_with}{limit}{from_}"
)
def regexpextract_sql(self, expression: exp.RegexpExtract) -> str: def regexpextract_sql(self, expression: exp.RegexpExtract) -> str:
# Other dialects don't support all of the following parameters, so we need to # Other dialects don't support all of the following parameters, so we need to

View file

@ -4,6 +4,7 @@ import typing as t
from sqlglot import exp from sqlglot import exp
from sqlglot.dialects.dialect import rename_func from sqlglot.dialects.dialect import rename_func
from sqlglot.dialects.hive import _parse_ignore_nulls
from sqlglot.dialects.spark2 import Spark2 from sqlglot.dialects.spark2 import Spark2
from sqlglot.helper import seq_get from sqlglot.helper import seq_get
@ -45,9 +46,7 @@ class Spark(Spark2):
class Parser(Spark2.Parser): class Parser(Spark2.Parser):
FUNCTIONS = { FUNCTIONS = {
**Spark2.Parser.FUNCTIONS, **Spark2.Parser.FUNCTIONS,
"ANY_VALUE": lambda args: exp.AnyValue( "ANY_VALUE": _parse_ignore_nulls(exp.AnyValue),
this=seq_get(args, 0), ignore_nulls=seq_get(args, 1)
),
"DATEDIFF": _parse_datediff, "DATEDIFF": _parse_datediff,
} }

View file

@ -187,8 +187,10 @@ class Spark2(Hive):
TRANSFORMS = { TRANSFORMS = {
**Hive.Generator.TRANSFORMS, **Hive.Generator.TRANSFORMS,
exp.ApproxDistinct: rename_func("APPROX_COUNT_DISTINCT"), exp.ApproxDistinct: rename_func("APPROX_COUNT_DISTINCT"),
exp.ArraySum: lambda self, e: f"AGGREGATE({self.sql(e, 'this')}, 0, (acc, x) -> acc + x, acc -> acc)", exp.ArraySum: lambda self,
exp.AtTimeZone: lambda self, e: f"FROM_UTC_TIMESTAMP({self.sql(e, 'this')}, {self.sql(e, 'zone')})", e: f"AGGREGATE({self.sql(e, 'this')}, 0, (acc, x) -> acc + x, acc -> acc)",
exp.AtTimeZone: lambda self,
e: f"FROM_UTC_TIMESTAMP({self.sql(e, 'this')}, {self.sql(e, 'zone')})",
exp.BitwiseLeftShift: rename_func("SHIFTLEFT"), exp.BitwiseLeftShift: rename_func("SHIFTLEFT"),
exp.BitwiseRightShift: rename_func("SHIFTRIGHT"), exp.BitwiseRightShift: rename_func("SHIFTRIGHT"),
exp.DateFromParts: rename_func("MAKE_DATE"), exp.DateFromParts: rename_func("MAKE_DATE"),
@ -198,7 +200,8 @@ class Spark2(Hive):
exp.DayOfYear: rename_func("DAYOFYEAR"), exp.DayOfYear: rename_func("DAYOFYEAR"),
exp.FileFormatProperty: lambda self, e: f"USING {e.name.upper()}", exp.FileFormatProperty: lambda self, e: f"USING {e.name.upper()}",
exp.From: transforms.preprocess([_unalias_pivot]), exp.From: transforms.preprocess([_unalias_pivot]),
exp.FromTimeZone: lambda self, e: f"TO_UTC_TIMESTAMP({self.sql(e, 'this')}, {self.sql(e, 'zone')})", exp.FromTimeZone: lambda self,
e: f"TO_UTC_TIMESTAMP({self.sql(e, 'this')}, {self.sql(e, 'zone')})",
exp.LogicalAnd: rename_func("BOOL_AND"), exp.LogicalAnd: rename_func("BOOL_AND"),
exp.LogicalOr: rename_func("BOOL_OR"), exp.LogicalOr: rename_func("BOOL_OR"),
exp.Map: _map_sql, exp.Map: _map_sql,
@ -212,7 +215,8 @@ class Spark2(Hive):
e.args.get("position"), e.args.get("position"),
), ),
exp.StrToDate: _str_to_date, exp.StrToDate: _str_to_date,
exp.StrToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})", exp.StrToTime: lambda self,
e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})",
exp.TimestampTrunc: lambda self, e: self.func( exp.TimestampTrunc: lambda self, e: self.func(
"DATE_TRUNC", exp.Literal.string(e.text("unit")), e.this "DATE_TRUNC", exp.Literal.string(e.text("unit")), e.this
), ),

View file

@ -7,7 +7,6 @@ from sqlglot.dialects.dialect import (
Dialect, Dialect,
NormalizationStrategy, NormalizationStrategy,
any_value_to_max_sql, any_value_to_max_sql,
arrow_json_extract_scalar_sql,
arrow_json_extract_sql, arrow_json_extract_sql,
concat_to_dpipe_sql, concat_to_dpipe_sql,
count_if_to_sum, count_if_to_sum,
@ -28,6 +27,12 @@ def _date_add_sql(self: SQLite.Generator, expression: exp.DateAdd) -> str:
return self.func("DATE", expression.this, modifier) return self.func("DATE", expression.this, modifier)
def _json_extract_sql(self: SQLite.Generator, expression: exp.JSONExtract) -> str:
if expression.expressions:
return self.function_fallback_sql(expression)
return arrow_json_extract_sql(self, expression)
def _transform_create(expression: exp.Expression) -> exp.Expression: def _transform_create(expression: exp.Expression) -> exp.Expression:
"""Move primary key to a column and enforce auto_increment on primary keys.""" """Move primary key to a column and enforce auto_increment on primary keys."""
schema = expression.this schema = expression.this
@ -85,6 +90,14 @@ class SQLite(Dialect):
TABLE_HINTS = False TABLE_HINTS = False
QUERY_HINTS = False QUERY_HINTS = False
NVL2_SUPPORTED = False NVL2_SUPPORTED = False
JSON_PATH_BRACKETED_KEY_SUPPORTED = False
SUPPORTS_CREATE_TABLE_LIKE = False
SUPPORTED_JSON_PATH_PARTS = {
exp.JSONPathKey,
exp.JSONPathRoot,
exp.JSONPathSubscript,
}
TYPE_MAPPING = { TYPE_MAPPING = {
**generator.Generator.TYPE_MAPPING, **generator.Generator.TYPE_MAPPING,
@ -120,10 +133,8 @@ class SQLite(Dialect):
exp.DateAdd: _date_add_sql, exp.DateAdd: _date_add_sql,
exp.DateStrToDate: lambda self, e: self.sql(e, "this"), exp.DateStrToDate: lambda self, e: self.sql(e, "this"),
exp.ILike: no_ilike_sql, exp.ILike: no_ilike_sql,
exp.JSONExtract: arrow_json_extract_sql, exp.JSONExtract: _json_extract_sql,
exp.JSONExtractScalar: arrow_json_extract_scalar_sql, exp.JSONExtractScalar: arrow_json_extract_sql,
exp.JSONBExtract: arrow_json_extract_sql,
exp.JSONBExtractScalar: arrow_json_extract_scalar_sql,
exp.Levenshtein: rename_func("EDITDIST3"), exp.Levenshtein: rename_func("EDITDIST3"),
exp.LogicalOr: rename_func("MAX"), exp.LogicalOr: rename_func("MAX"),
exp.LogicalAnd: rename_func("MIN"), exp.LogicalAnd: rename_func("MIN"),
@ -141,11 +152,18 @@ class SQLite(Dialect):
exp.TryCast: no_trycast_sql, exp.TryCast: no_trycast_sql,
} }
# SQLite doesn't generally support CREATE TABLE .. properties
# https://www.sqlite.org/lang_createtable.html
PROPERTIES_LOCATION = { PROPERTIES_LOCATION = {
k: exp.Properties.Location.UNSUPPORTED prop: exp.Properties.Location.UNSUPPORTED
for k, v in generator.Generator.PROPERTIES_LOCATION.items() for prop in generator.Generator.PROPERTIES_LOCATION
} }
# There are a few exceptions (e.g. temporary tables) which are supported or
# can be transpiled to SQLite, so we explicitly override them accordingly
PROPERTIES_LOCATION[exp.LikeProperty] = exp.Properties.Location.POST_SCHEMA
PROPERTIES_LOCATION[exp.TemporaryProperty] = exp.Properties.Location.POST_CREATE
LIMIT_FETCH = "LIMIT" LIMIT_FETCH = "LIMIT"
def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:

View file

@ -44,12 +44,14 @@ class StarRocks(MySQL):
exp.JSONExtractScalar: arrow_json_extract_sql, exp.JSONExtractScalar: arrow_json_extract_sql,
exp.JSONExtract: arrow_json_extract_sql, exp.JSONExtract: arrow_json_extract_sql,
exp.RegexpLike: rename_func("REGEXP"), exp.RegexpLike: rename_func("REGEXP"),
exp.StrToUnix: lambda self, e: f"UNIX_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})", exp.StrToUnix: lambda self,
e: f"UNIX_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})",
exp.TimestampTrunc: lambda self, e: self.func( exp.TimestampTrunc: lambda self, e: self.func(
"DATE_TRUNC", exp.Literal.string(e.text("unit")), e.this "DATE_TRUNC", exp.Literal.string(e.text("unit")), e.this
), ),
exp.TimeStrToDate: rename_func("TO_DATE"), exp.TimeStrToDate: rename_func("TO_DATE"),
exp.UnixToStr: lambda self, e: f"FROM_UNIXTIME({self.sql(e, 'this')}, {self.format_time(e)})", exp.UnixToStr: lambda self,
e: f"FROM_UNIXTIME({self.sql(e, 'this')}, {self.format_time(e)})",
exp.UnixToTime: rename_func("FROM_UNIXTIME"), exp.UnixToTime: rename_func("FROM_UNIXTIME"),
} }

View file

@ -200,7 +200,8 @@ class Teradata(Dialect):
exp.Select: transforms.preprocess( exp.Select: transforms.preprocess(
[transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins] [transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins]
), ),
exp.StrToDate: lambda self, e: f"CAST({self.sql(e, 'this')} AS DATE FORMAT {self.format_time(e)})", exp.StrToDate: lambda self,
e: f"CAST({self.sql(e, 'this')} AS DATE FORMAT {self.format_time(e)})",
exp.ToChar: lambda self, e: self.function_fallback_sql(e), exp.ToChar: lambda self, e: self.function_fallback_sql(e),
exp.Use: lambda self, e: f"DATABASE {self.sql(e, 'this')}", exp.Use: lambda self, e: f"DATABASE {self.sql(e, 'this')}",
} }

View file

@ -11,9 +11,16 @@ class Trino(Presto):
class Generator(Presto.Generator): class Generator(Presto.Generator):
TRANSFORMS = { TRANSFORMS = {
**Presto.Generator.TRANSFORMS, **Presto.Generator.TRANSFORMS,
exp.ArraySum: lambda self, e: f"REDUCE({self.sql(e, 'this')}, 0, (acc, x) -> acc + x, acc -> acc)", exp.ArraySum: lambda self,
e: f"REDUCE({self.sql(e, 'this')}, 0, (acc, x) -> acc + x, acc -> acc)",
exp.Merge: merge_without_target_sql, exp.Merge: merge_without_target_sql,
} }
SUPPORTED_JSON_PATH_PARTS = {
exp.JSONPathKey,
exp.JSONPathRoot,
exp.JSONPathSubscript,
}
class Tokenizer(Presto.Tokenizer): class Tokenizer(Presto.Tokenizer):
HEX_STRINGS = [("X'", "'")] HEX_STRINGS = [("X'", "'")]

View file

@ -14,7 +14,6 @@ from sqlglot.dialects.dialect import (
max_or_greatest, max_or_greatest,
min_or_least, min_or_least,
parse_date_delta, parse_date_delta,
path_to_jsonpath,
rename_func, rename_func,
timestrtotime_sql, timestrtotime_sql,
trim_sql, trim_sql,
@ -266,13 +265,32 @@ def _parse_timefromparts(args: t.List) -> exp.TimeFromParts:
) )
def _parse_len(args: t.List) -> exp.Length: def _parse_as_text(
this = seq_get(args, 0) klass: t.Type[exp.Expression],
) -> t.Callable[[t.List[exp.Expression]], exp.Expression]:
def _parse(args: t.List[exp.Expression]) -> exp.Expression:
this = seq_get(args, 0)
if this and not this.is_string: if this and not this.is_string:
this = exp.cast(this, exp.DataType.Type.TEXT) this = exp.cast(this, exp.DataType.Type.TEXT)
return exp.Length(this=this) expression = seq_get(args, 1)
kwargs = {"this": this}
if expression:
kwargs["expression"] = expression
return klass(**kwargs)
return _parse
def _json_extract_sql(
self: TSQL.Generator, expression: exp.JSONExtract | exp.JSONExtractScalar
) -> str:
json_query = rename_func("JSON_QUERY")(self, expression)
json_value = rename_func("JSON_VALUE")(self, expression)
return self.func("ISNULL", json_query, json_value)
class TSQL(Dialect): class TSQL(Dialect):
@ -441,8 +459,11 @@ class TSQL(Dialect):
"HASHBYTES": _parse_hashbytes, "HASHBYTES": _parse_hashbytes,
"IIF": exp.If.from_arg_list, "IIF": exp.If.from_arg_list,
"ISNULL": exp.Coalesce.from_arg_list, "ISNULL": exp.Coalesce.from_arg_list,
"JSON_VALUE": exp.JSONExtractScalar.from_arg_list, "JSON_QUERY": parser.parse_extract_json_with_path(exp.JSONExtract),
"LEN": _parse_len, "JSON_VALUE": parser.parse_extract_json_with_path(exp.JSONExtractScalar),
"LEN": _parse_as_text(exp.Length),
"LEFT": _parse_as_text(exp.Left),
"RIGHT": _parse_as_text(exp.Right),
"REPLICATE": exp.Repeat.from_arg_list, "REPLICATE": exp.Repeat.from_arg_list,
"SQUARE": lambda args: exp.Pow(this=seq_get(args, 0), expression=exp.Literal.number(2)), "SQUARE": lambda args: exp.Pow(this=seq_get(args, 0), expression=exp.Literal.number(2)),
"SYSDATETIME": exp.CurrentTimestamp.from_arg_list, "SYSDATETIME": exp.CurrentTimestamp.from_arg_list,
@ -677,6 +698,7 @@ class TSQL(Dialect):
SUPPORTS_SINGLE_ARG_CONCAT = False SUPPORTS_SINGLE_ARG_CONCAT = False
TABLESAMPLE_SEED_KEYWORD = "REPEATABLE" TABLESAMPLE_SEED_KEYWORD = "REPEATABLE"
SUPPORTS_SELECT_INTO = True SUPPORTS_SELECT_INTO = True
JSON_PATH_BRACKETED_KEY_SUPPORTED = False
EXPRESSIONS_WITHOUT_NESTED_CTES = { EXPRESSIONS_WITHOUT_NESTED_CTES = {
exp.Delete, exp.Delete,
@ -688,6 +710,12 @@ class TSQL(Dialect):
exp.Update, exp.Update,
} }
SUPPORTED_JSON_PATH_PARTS = {
exp.JSONPathKey,
exp.JSONPathRoot,
exp.JSONPathSubscript,
}
TYPE_MAPPING = { TYPE_MAPPING = {
**generator.Generator.TYPE_MAPPING, **generator.Generator.TYPE_MAPPING,
exp.DataType.Type.BOOLEAN: "BIT", exp.DataType.Type.BOOLEAN: "BIT",
@ -712,9 +740,10 @@ class TSQL(Dialect):
exp.CurrentTimestamp: rename_func("GETDATE"), exp.CurrentTimestamp: rename_func("GETDATE"),
exp.Extract: rename_func("DATEPART"), exp.Extract: rename_func("DATEPART"),
exp.GeneratedAsIdentityColumnConstraint: generatedasidentitycolumnconstraint_sql, exp.GeneratedAsIdentityColumnConstraint: generatedasidentitycolumnconstraint_sql,
exp.GetPath: path_to_jsonpath("JSON_VALUE"),
exp.GroupConcat: _string_agg_sql, exp.GroupConcat: _string_agg_sql,
exp.If: rename_func("IIF"), exp.If: rename_func("IIF"),
exp.JSONExtract: _json_extract_sql,
exp.JSONExtractScalar: _json_extract_sql,
exp.LastDay: lambda self, e: self.func("EOMONTH", e.this), exp.LastDay: lambda self, e: self.func("EOMONTH", e.this),
exp.Max: max_or_greatest, exp.Max: max_or_greatest,
exp.MD5: lambda self, e: self.func("HASHBYTES", exp.Literal.string("MD5"), e.this), exp.MD5: lambda self, e: self.func("HASHBYTES", exp.Literal.string("MD5"), e.this),
@ -831,15 +860,21 @@ class TSQL(Dialect):
exists = expression.args.pop("exists", None) exists = expression.args.pop("exists", None)
sql = super().create_sql(expression) sql = super().create_sql(expression)
like_property = expression.find(exp.LikeProperty)
if like_property:
ctas_expression = like_property.this
else:
ctas_expression = expression.expression
table = expression.find(exp.Table) table = expression.find(exp.Table)
# Convert CTAS statement to SELECT .. INTO .. # Convert CTAS statement to SELECT .. INTO ..
if kind == "TABLE" and expression.expression: if kind == "TABLE" and ctas_expression:
ctas_with = expression.expression.args.get("with") ctas_with = ctas_expression.args.get("with")
if ctas_with: if ctas_with:
ctas_with = ctas_with.pop() ctas_with = ctas_with.pop()
subquery = expression.expression subquery = ctas_expression
if isinstance(subquery, exp.Subqueryable): if isinstance(subquery, exp.Subqueryable):
subquery = subquery.subquery() subquery = subquery.subquery()
@ -847,6 +882,9 @@ class TSQL(Dialect):
select_into.set("into", exp.Into(this=table)) select_into.set("into", exp.Into(this=table))
select_into.set("with", ctas_with) select_into.set("with", ctas_with)
if like_property:
select_into.limit(0, copy=False)
sql = self.sql(select_into) sql = self.sql(select_into)
if exists: if exists:
@ -937,9 +975,19 @@ class TSQL(Dialect):
return f"CONSTRAINT {this} {expressions}" return f"CONSTRAINT {this} {expressions}"
def length_sql(self, expression: exp.Length) -> str: def length_sql(self, expression: exp.Length) -> str:
return self._uncast_text(expression, "LEN")
def right_sql(self, expression: exp.Right) -> str:
return self._uncast_text(expression, "RIGHT")
def left_sql(self, expression: exp.Left) -> str:
return self._uncast_text(expression, "LEFT")
def _uncast_text(self, expression: exp.Expression, name: str) -> str:
this = expression.this this = expression.this
if isinstance(this, exp.Cast) and this.is_type(exp.DataType.Type.TEXT): if isinstance(this, exp.Cast) and this.is_type(exp.DataType.Type.TEXT):
this_sql = self.sql(this, "this") this_sql = self.sql(this, "this")
else: else:
this_sql = self.sql(this) this_sql = self.sql(this)
return self.func("LEN", this_sql) expression_sql = self.sql(expression, "expression")
return self.func(name, this_sql, expression_sql if expression_sql else None)

View file

@ -10,7 +10,6 @@ import logging
import time import time
import typing as t import typing as t
from sqlglot import maybe_parse
from sqlglot.errors import ExecuteError from sqlglot.errors import ExecuteError
from sqlglot.executor.python import PythonExecutor from sqlglot.executor.python import PythonExecutor
from sqlglot.executor.table import Table, ensure_tables from sqlglot.executor.table import Table, ensure_tables
@ -23,7 +22,6 @@ logger = logging.getLogger("sqlglot")
if t.TYPE_CHECKING: if t.TYPE_CHECKING:
from sqlglot.dialects.dialect import DialectType from sqlglot.dialects.dialect import DialectType
from sqlglot.executor.table import Tables
from sqlglot.expressions import Expression from sqlglot.expressions import Expression
from sqlglot.schema import Schema from sqlglot.schema import Schema

View file

@ -44,9 +44,9 @@ class Context:
for other in self.tables.values(): for other in self.tables.values():
if self._table.columns != other.columns: if self._table.columns != other.columns:
raise Exception(f"Columns are different.") raise Exception("Columns are different.")
if len(self._table.rows) != len(other.rows): if len(self._table.rows) != len(other.rows):
raise Exception(f"Rows are different.") raise Exception("Rows are different.")
return self._table return self._table

View file

@ -6,7 +6,7 @@ from functools import wraps
from sqlglot import exp from sqlglot import exp
from sqlglot.generator import Generator from sqlglot.generator import Generator
from sqlglot.helper import PYTHON_VERSION from sqlglot.helper import PYTHON_VERSION, is_int, seq_get
class reverse_key: class reverse_key:
@ -143,6 +143,22 @@ def arrayjoin(this, expression, null=None):
return expression.join(x for x in (x if x is not None else null for x in this) if x is not None) return expression.join(x for x in (x if x is not None else null for x in this) if x is not None)
@null_if_any("this", "expression")
def jsonextract(this, expression):
for path_segment in expression:
if isinstance(this, dict):
this = this.get(path_segment)
elif isinstance(this, list) and is_int(path_segment):
this = seq_get(this, int(path_segment))
else:
raise NotImplementedError(f"Unable to extract value for {this} at {path_segment}.")
if this is None:
break
return this
ENV = { ENV = {
"exp": exp, "exp": exp,
# aggs # aggs
@ -175,12 +191,12 @@ ENV = {
"DOT": null_if_any(lambda e, this: e[this]), "DOT": null_if_any(lambda e, this: e[this]),
"EQ": null_if_any(lambda this, e: this == e), "EQ": null_if_any(lambda this, e: this == e),
"EXTRACT": null_if_any(lambda this, e: getattr(e, this)), "EXTRACT": null_if_any(lambda this, e: getattr(e, this)),
"GETPATH": null_if_any(lambda this, e: this.get(e)),
"GT": null_if_any(lambda this, e: this > e), "GT": null_if_any(lambda this, e: this > e),
"GTE": null_if_any(lambda this, e: this >= e), "GTE": null_if_any(lambda this, e: this >= e),
"IF": lambda predicate, true, false: true if predicate else false, "IF": lambda predicate, true, false: true if predicate else false,
"INTDIV": null_if_any(lambda e, this: e // this), "INTDIV": null_if_any(lambda e, this: e // this),
"INTERVAL": interval, "INTERVAL": interval,
"JSONEXTRACT": jsonextract,
"LEFT": null_if_any(lambda this, e: this[:e]), "LEFT": null_if_any(lambda this, e: this[:e]),
"LIKE": null_if_any( "LIKE": null_if_any(
lambda this, e: bool(re.match(e.replace("_", ".").replace("%", ".*"), this)) lambda this, e: bool(re.match(e.replace("_", ".").replace("%", ".*"), this))

View file

@ -9,7 +9,7 @@ from sqlglot.errors import ExecuteError
from sqlglot.executor.context import Context from sqlglot.executor.context import Context
from sqlglot.executor.env import ENV from sqlglot.executor.env import ENV
from sqlglot.executor.table import RowReader, Table from sqlglot.executor.table import RowReader, Table
from sqlglot.helper import csv_reader, subclasses from sqlglot.helper import csv_reader, ensure_list, subclasses
class PythonExecutor: class PythonExecutor:
@ -368,7 +368,7 @@ def _rename(self, e):
if isinstance(e, exp.Func) and e.is_var_len_args: if isinstance(e, exp.Func) and e.is_var_len_args:
*head, tail = values *head, tail = values
return self.func(e.key, *head, *tail) return self.func(e.key, *head, *ensure_list(tail))
return self.func(e.key, *values) return self.func(e.key, *values)
except Exception as ex: except Exception as ex:
@ -429,18 +429,24 @@ class Python(Dialect):
exp.Between: _rename, exp.Between: _rename,
exp.Boolean: lambda self, e: "True" if e.this else "False", exp.Boolean: lambda self, e: "True" if e.this else "False",
exp.Cast: lambda self, e: f"CAST({self.sql(e.this)}, exp.DataType.Type.{e.args['to']})", exp.Cast: lambda self, e: f"CAST({self.sql(e.this)}, exp.DataType.Type.{e.args['to']})",
exp.Column: lambda self, e: f"scope[{self.sql(e, 'table') or None}][{self.sql(e.this)}]", exp.Column: lambda self,
e: f"scope[{self.sql(e, 'table') or None}][{self.sql(e.this)}]",
exp.Concat: lambda self, e: self.func( exp.Concat: lambda self, e: self.func(
"SAFECONCAT" if e.args.get("safe") else "CONCAT", *e.expressions "SAFECONCAT" if e.args.get("safe") else "CONCAT", *e.expressions
), ),
exp.Distinct: lambda self, e: f"set({self.sql(e, 'this')})", exp.Distinct: lambda self, e: f"set({self.sql(e, 'this')})",
exp.Div: _div_sql, exp.Div: _div_sql,
exp.Extract: lambda self, e: f"EXTRACT('{e.name.lower()}', {self.sql(e, 'expression')})", exp.Extract: lambda self,
exp.In: lambda self, e: f"{self.sql(e, 'this')} in {{{self.expressions(e, flat=True)}}}", e: f"EXTRACT('{e.name.lower()}', {self.sql(e, 'expression')})",
exp.In: lambda self,
e: f"{self.sql(e, 'this')} in {{{self.expressions(e, flat=True)}}}",
exp.Interval: lambda self, e: f"INTERVAL({self.sql(e.this)}, '{self.sql(e.unit)}')", exp.Interval: lambda self, e: f"INTERVAL({self.sql(e.this)}, '{self.sql(e.unit)}')",
exp.Is: lambda self, e: ( exp.Is: lambda self, e: (
self.binary(e, "==") if isinstance(e.this, exp.Literal) else self.binary(e, "is") self.binary(e, "==") if isinstance(e.this, exp.Literal) else self.binary(e, "is")
), ),
exp.JSONPath: lambda self, e: f"[{','.join(self.sql(p) for p in e.expressions[1:])}]",
exp.JSONPathKey: lambda self, e: f"'{self.sql(e.this)}'",
exp.JSONPathSubscript: lambda self, e: f"'{e.this}'",
exp.Lambda: _lambda_sql, exp.Lambda: _lambda_sql,
exp.Not: lambda self, e: f"not {self.sql(e.this)}", exp.Not: lambda self, e: f"not {self.sql(e.this)}",
exp.Null: lambda *_: "None", exp.Null: lambda *_: "None",

View file

@ -29,6 +29,7 @@ from sqlglot.helper import (
camel_to_snake_case, camel_to_snake_case,
ensure_collection, ensure_collection,
ensure_list, ensure_list,
is_int,
seq_get, seq_get,
subclasses, subclasses,
) )
@ -175,13 +176,7 @@ class Expression(metaclass=_Expression):
""" """
Checks whether a Literal expression is an integer. Checks whether a Literal expression is an integer.
""" """
if self.is_number: return self.is_number and is_int(self.name)
try:
int(self.name)
return True
except ValueError:
pass
return False
@property @property
def is_star(self) -> bool: def is_star(self) -> bool:
@ -493,8 +488,8 @@ class Expression(metaclass=_Expression):
A AND B AND C -> [A, B, C] A AND B AND C -> [A, B, C]
""" """
for node, _, _ in self.dfs(prune=lambda n, p, *_: p and not type(n) is self.__class__): for node, _, _ in self.dfs(prune=lambda n, p, *_: p and type(n) is not self.__class__):
if not type(node) is self.__class__: if type(node) is not self.__class__:
yield node.unnest() if unnest and not isinstance(node, Subquery) else node yield node.unnest() if unnest and not isinstance(node, Subquery) else node
def __str__(self) -> str: def __str__(self) -> str:
@ -553,10 +548,12 @@ class Expression(metaclass=_Expression):
return new_node return new_node
@t.overload @t.overload
def replace(self, expression: E) -> E: ... def replace(self, expression: E) -> E:
...
@t.overload @t.overload
def replace(self, expression: None) -> None: ... def replace(self, expression: None) -> None:
...
def replace(self, expression): def replace(self, expression):
""" """
@ -610,7 +607,8 @@ class Expression(metaclass=_Expression):
>>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql() >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
'SELECT x, z FROM y' 'SELECT x, z FROM y'
""" """
assert isinstance(self, type_) if not isinstance(self, type_):
raise AssertionError(f"{self} is not {type_}.")
return self return self
def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]: def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
@ -1133,6 +1131,7 @@ class SetItem(Expression):
class Show(Expression): class Show(Expression):
arg_types = { arg_types = {
"this": True, "this": True,
"history": False,
"terse": False, "terse": False,
"target": False, "target": False,
"offset": False, "offset": False,
@ -1676,7 +1675,6 @@ class Index(Expression):
"amp": False, # teradata "amp": False, # teradata
"include": False, "include": False,
"partition_by": False, # teradata "partition_by": False, # teradata
"where": False, # postgres partial indexes
} }
@ -2573,7 +2571,7 @@ class HistoricalData(Expression):
class Table(Expression): class Table(Expression):
arg_types = { arg_types = {
"this": True, "this": False,
"alias": False, "alias": False,
"db": False, "db": False,
"catalog": False, "catalog": False,
@ -3664,6 +3662,7 @@ class DataType(Expression):
BINARY = auto() BINARY = auto()
BIT = auto() BIT = auto()
BOOLEAN = auto() BOOLEAN = auto()
BPCHAR = auto()
CHAR = auto() CHAR = auto()
DATE = auto() DATE = auto()
DATE32 = auto() DATE32 = auto()
@ -3805,6 +3804,7 @@ class DataType(Expression):
dtype: DATA_TYPE, dtype: DATA_TYPE,
dialect: DialectType = None, dialect: DialectType = None,
udt: bool = False, udt: bool = False,
copy: bool = True,
**kwargs, **kwargs,
) -> DataType: ) -> DataType:
""" """
@ -3815,7 +3815,8 @@ class DataType(Expression):
dialect: the dialect to use for parsing `dtype`, in case it's a string. dialect: the dialect to use for parsing `dtype`, in case it's a string.
udt: when set to True, `dtype` will be used as-is if it can't be parsed into a udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
DataType, thus creating a user-defined type. DataType, thus creating a user-defined type.
kawrgs: additional arguments to pass in the constructor of DataType. copy: whether or not to copy the data type.
kwargs: additional arguments to pass in the constructor of DataType.
Returns: Returns:
The constructed DataType object. The constructed DataType object.
@ -3837,7 +3838,7 @@ class DataType(Expression):
elif isinstance(dtype, DataType.Type): elif isinstance(dtype, DataType.Type):
data_type_exp = DataType(this=dtype) data_type_exp = DataType(this=dtype)
elif isinstance(dtype, DataType): elif isinstance(dtype, DataType):
return dtype return maybe_copy(dtype, copy)
else: else:
raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type") raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
@ -3855,7 +3856,7 @@ class DataType(Expression):
True, if and only if there is a type in `dtypes` which is equal to this DataType. True, if and only if there is a type in `dtypes` which is equal to this DataType.
""" """
for dtype in dtypes: for dtype in dtypes:
other = DataType.build(dtype, udt=True) other = DataType.build(dtype, copy=False, udt=True)
if ( if (
other.expressions other.expressions
@ -4001,7 +4002,7 @@ class Dot(Binary):
def build(self, expressions: t.Sequence[Expression]) -> Dot: def build(self, expressions: t.Sequence[Expression]) -> Dot:
"""Build a Dot object with a sequence of expressions.""" """Build a Dot object with a sequence of expressions."""
if len(expressions) < 2: if len(expressions) < 2:
raise ValueError(f"Dot requires >= 2 expressions.") raise ValueError("Dot requires >= 2 expressions.")
return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions)) return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
@ -4128,10 +4129,6 @@ class Sub(Binary):
pass pass
class ArrayOverlaps(Binary):
pass
# Unary Expressions # Unary Expressions
# (NOT a) # (NOT a)
class Unary(Condition): class Unary(Condition):
@ -4469,6 +4466,10 @@ class ArrayJoin(Func):
arg_types = {"this": True, "expression": True, "null": False} arg_types = {"this": True, "expression": True, "null": False}
class ArrayOverlaps(Binary, Func):
pass
class ArraySize(Func): class ArraySize(Func):
arg_types = {"this": True, "expression": False} arg_types = {"this": True, "expression": False}
@ -4490,15 +4491,37 @@ class Avg(AggFunc):
class AnyValue(AggFunc): class AnyValue(AggFunc):
arg_types = {"this": True, "having": False, "max": False, "ignore_nulls": False} arg_types = {"this": True, "having": False, "max": False}
class First(Func): class Lag(AggFunc):
arg_types = {"this": True, "ignore_nulls": False} arg_types = {"this": True, "offset": False, "default": False}
class Last(Func): class Lead(AggFunc):
arg_types = {"this": True, "ignore_nulls": False} arg_types = {"this": True, "offset": False, "default": False}
# some dialects have a distinction between first and first_value, usually first is an aggregate func
# and first_value is a window func
class First(AggFunc):
pass
class Last(AggFunc):
pass
class FirstValue(AggFunc):
pass
class LastValue(AggFunc):
pass
class NthValue(AggFunc):
arg_types = {"this": True, "offset": True}
class Case(Func): class Case(Func):
@ -4611,7 +4634,7 @@ class CurrentTime(Func):
class CurrentTimestamp(Func): class CurrentTimestamp(Func):
arg_types = {"this": False} arg_types = {"this": False, "transaction": False}
class CurrentUser(Func): class CurrentUser(Func):
@ -4712,6 +4735,7 @@ class TimestampSub(Func, TimeUnit):
class TimestampDiff(Func, TimeUnit): class TimestampDiff(Func, TimeUnit):
_sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
arg_types = {"this": True, "expression": True, "unit": False} arg_types = {"this": True, "expression": True, "unit": False}
@ -4857,6 +4881,59 @@ class IsInf(Func):
_sql_names = ["IS_INF", "ISINF"] _sql_names = ["IS_INF", "ISINF"]
class JSONPath(Expression):
arg_types = {"expressions": True}
@property
def output_name(self) -> str:
last_segment = self.expressions[-1].this
return last_segment if isinstance(last_segment, str) else ""
class JSONPathPart(Expression):
arg_types = {}
class JSONPathFilter(JSONPathPart):
arg_types = {"this": True}
class JSONPathKey(JSONPathPart):
arg_types = {"this": True}
class JSONPathRecursive(JSONPathPart):
arg_types = {"this": False}
class JSONPathRoot(JSONPathPart):
pass
class JSONPathScript(JSONPathPart):
arg_types = {"this": True}
class JSONPathSlice(JSONPathPart):
arg_types = {"start": False, "end": False, "step": False}
class JSONPathSelector(JSONPathPart):
arg_types = {"this": True}
class JSONPathSubscript(JSONPathPart):
arg_types = {"this": True}
class JSONPathUnion(JSONPathPart):
arg_types = {"expressions": True}
class JSONPathWildcard(JSONPathPart):
pass
class FormatJson(Expression): class FormatJson(Expression):
pass pass
@ -4940,18 +5017,30 @@ class JSONBContains(Binary):
class JSONExtract(Binary, Func): class JSONExtract(Binary, Func):
arg_types = {"this": True, "expression": True, "expressions": False}
_sql_names = ["JSON_EXTRACT"] _sql_names = ["JSON_EXTRACT"]
is_var_len_args = True
@property
def output_name(self) -> str:
return self.expression.output_name if not self.expressions else ""
class JSONExtractScalar(JSONExtract): class JSONExtractScalar(Binary, Func):
arg_types = {"this": True, "expression": True, "expressions": False}
_sql_names = ["JSON_EXTRACT_SCALAR"] _sql_names = ["JSON_EXTRACT_SCALAR"]
is_var_len_args = True
@property
def output_name(self) -> str:
return self.expression.output_name
class JSONBExtract(JSONExtract): class JSONBExtract(Binary, Func):
_sql_names = ["JSONB_EXTRACT"] _sql_names = ["JSONB_EXTRACT"]
class JSONBExtractScalar(JSONExtract): class JSONBExtractScalar(Binary, Func):
_sql_names = ["JSONB_EXTRACT_SCALAR"] _sql_names = ["JSONB_EXTRACT_SCALAR"]
@ -4972,15 +5061,6 @@ class ParseJSON(Func):
is_var_len_args = True is_var_len_args = True
# https://docs.snowflake.com/en/sql-reference/functions/get_path
class GetPath(Func):
arg_types = {"this": True, "expression": True}
@property
def output_name(self) -> str:
return self.expression.output_name
class Least(Func): class Least(Func):
arg_types = {"this": True, "expressions": False} arg_types = {"this": True, "expressions": False}
is_var_len_args = True is_var_len_args = True
@ -5476,6 +5556,8 @@ def _norm_arg(arg):
ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func)) ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()} FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
# Helpers # Helpers
@t.overload @t.overload
@ -5487,7 +5569,8 @@ def maybe_parse(
prefix: t.Optional[str] = None, prefix: t.Optional[str] = None,
copy: bool = False, copy: bool = False,
**opts, **opts,
) -> E: ... ) -> E:
...
@t.overload @t.overload
@ -5499,7 +5582,8 @@ def maybe_parse(
prefix: t.Optional[str] = None, prefix: t.Optional[str] = None,
copy: bool = False, copy: bool = False,
**opts, **opts,
) -> E: ... ) -> E:
...
def maybe_parse( def maybe_parse(
@ -5539,7 +5623,7 @@ def maybe_parse(
return sql_or_expression return sql_or_expression
if sql_or_expression is None: if sql_or_expression is None:
raise ParseError(f"SQL cannot be None") raise ParseError("SQL cannot be None")
import sqlglot import sqlglot
@ -5551,11 +5635,13 @@ def maybe_parse(
@t.overload @t.overload
def maybe_copy(instance: None, copy: bool = True) -> None: ... def maybe_copy(instance: None, copy: bool = True) -> None:
...
@t.overload @t.overload
def maybe_copy(instance: E, copy: bool = True) -> E: ... def maybe_copy(instance: E, copy: bool = True) -> E:
...
def maybe_copy(instance, copy=True): def maybe_copy(instance, copy=True):
@ -6174,17 +6260,19 @@ def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
return Paren(this=maybe_parse(expression, copy=copy)) return Paren(this=maybe_parse(expression, copy=copy))
SAFE_IDENTIFIER_RE = re.compile(r"^[_a-zA-Z][\w]*$") SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
@t.overload @t.overload
def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: ... def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None:
...
@t.overload @t.overload
def to_identifier( def to_identifier(
name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
) -> Identifier: ... ) -> Identifier:
...
def to_identifier(name, quoted=None, copy=True): def to_identifier(name, quoted=None, copy=True):
@ -6256,11 +6344,13 @@ def to_interval(interval: str | Literal) -> Interval:
@t.overload @t.overload
def to_table(sql_path: str | Table, **kwargs) -> Table: ... def to_table(sql_path: str | Table, **kwargs) -> Table:
...
@t.overload @t.overload
def to_table(sql_path: None, **kwargs) -> None: ... def to_table(sql_path: None, **kwargs) -> None:
...
def to_table( def to_table(
@ -6460,7 +6550,7 @@ def column(
return this return this
def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast: def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
"""Cast an expression to a data type. """Cast an expression to a data type.
Example: Example:
@ -6470,12 +6560,13 @@ def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast:
Args: Args:
expression: The expression to cast. expression: The expression to cast.
to: The datatype to cast to. to: The datatype to cast to.
copy: Whether or not to copy the supplied expressions.
Returns: Returns:
The new Cast instance. The new Cast instance.
""" """
expression = maybe_parse(expression, **opts) expression = maybe_parse(expression, copy=copy, **opts)
data_type = DataType.build(to, **opts) data_type = DataType.build(to, copy=copy, **opts)
expression = Cast(this=expression, to=data_type) expression = Cast(this=expression, to=data_type)
expression.type = data_type expression.type = data_type
return expression return expression

View file

@ -9,6 +9,7 @@ from functools import reduce
from sqlglot import exp from sqlglot import exp
from sqlglot.errors import ErrorLevel, UnsupportedError, concat_messages from sqlglot.errors import ErrorLevel, UnsupportedError, concat_messages
from sqlglot.helper import apply_index_offset, csv, seq_get from sqlglot.helper import apply_index_offset, csv, seq_get
from sqlglot.jsonpath import ALL_JSON_PATH_PARTS, JSON_PATH_PART_TRANSFORMS
from sqlglot.time import format_time from sqlglot.time import format_time
from sqlglot.tokens import TokenType from sqlglot.tokens import TokenType
@ -21,7 +22,18 @@ logger = logging.getLogger("sqlglot")
ESCAPED_UNICODE_RE = re.compile(r"\\(\d+)") ESCAPED_UNICODE_RE = re.compile(r"\\(\d+)")
class Generator: class _Generator(type):
def __new__(cls, clsname, bases, attrs):
klass = super().__new__(cls, clsname, bases, attrs)
# Remove transforms that correspond to unsupported JSONPathPart expressions
for part in ALL_JSON_PATH_PARTS - klass.SUPPORTED_JSON_PATH_PARTS:
klass.TRANSFORMS.pop(part, None)
return klass
class Generator(metaclass=_Generator):
""" """
Generator converts a given syntax tree to the corresponding SQL string. Generator converts a given syntax tree to the corresponding SQL string.
@ -58,19 +70,23 @@ class Generator:
Default: True Default: True
""" """
TRANSFORMS = { TRANSFORMS: t.Dict[t.Type[exp.Expression], t.Callable[..., str]] = {
**JSON_PATH_PART_TRANSFORMS,
exp.AutoRefreshProperty: lambda self, e: f"AUTO REFRESH {self.sql(e, 'this')}",
exp.CaseSpecificColumnConstraint: lambda self,
e: f"{'NOT ' if e.args.get('not_') else ''}CASESPECIFIC",
exp.CharacterSetColumnConstraint: lambda self, e: f"CHARACTER SET {self.sql(e, 'this')}",
exp.CharacterSetProperty: lambda self,
e: f"{'DEFAULT ' if e.args.get('default') else ''}CHARACTER SET={self.sql(e, 'this')}",
exp.CheckColumnConstraint: lambda self, e: f"CHECK ({self.sql(e, 'this')})",
exp.ClusteredColumnConstraint: lambda self,
e: f"CLUSTERED ({self.expressions(e, 'this', indent=False)})",
exp.CollateColumnConstraint: lambda self, e: f"COLLATE {self.sql(e, 'this')}",
exp.CommentColumnConstraint: lambda self, e: f"COMMENT {self.sql(e, 'this')}",
exp.CopyGrantsProperty: lambda self, e: "COPY GRANTS",
exp.DateAdd: lambda self, e: self.func( exp.DateAdd: lambda self, e: self.func(
"DATE_ADD", e.this, e.expression, exp.Literal.string(e.text("unit")) "DATE_ADD", e.this, e.expression, exp.Literal.string(e.text("unit"))
), ),
exp.CaseSpecificColumnConstraint: lambda self, e: f"{'NOT ' if e.args.get('not_') else ''}CASESPECIFIC",
exp.CharacterSetColumnConstraint: lambda self, e: f"CHARACTER SET {self.sql(e, 'this')}",
exp.CharacterSetProperty: lambda self, e: f"{'DEFAULT ' if e.args.get('default') else ''}CHARACTER SET={self.sql(e, 'this')}",
exp.CheckColumnConstraint: lambda self, e: f"CHECK ({self.sql(e, 'this')})",
exp.ClusteredColumnConstraint: lambda self, e: f"CLUSTERED ({self.expressions(e, 'this', indent=False)})",
exp.CollateColumnConstraint: lambda self, e: f"COLLATE {self.sql(e, 'this')}",
exp.AutoRefreshProperty: lambda self, e: f"AUTO REFRESH {self.sql(e, 'this')}",
exp.CopyGrantsProperty: lambda self, e: "COPY GRANTS",
exp.CommentColumnConstraint: lambda self, e: f"COMMENT {self.sql(e, 'this')}",
exp.DateFormatColumnConstraint: lambda self, e: f"FORMAT {self.sql(e, 'this')}", exp.DateFormatColumnConstraint: lambda self, e: f"FORMAT {self.sql(e, 'this')}",
exp.DefaultColumnConstraint: lambda self, e: f"DEFAULT {self.sql(e, 'this')}", exp.DefaultColumnConstraint: lambda self, e: f"DEFAULT {self.sql(e, 'this')}",
exp.EncodeColumnConstraint: lambda self, e: f"ENCODE {self.sql(e, 'this')}", exp.EncodeColumnConstraint: lambda self, e: f"ENCODE {self.sql(e, 'this')}",
@ -85,29 +101,33 @@ class Generator:
exp.LocationProperty: lambda self, e: self.naked_property(e), exp.LocationProperty: lambda self, e: self.naked_property(e),
exp.LogProperty: lambda self, e: f"{'NO ' if e.args.get('no') else ''}LOG", exp.LogProperty: lambda self, e: f"{'NO ' if e.args.get('no') else ''}LOG",
exp.MaterializedProperty: lambda self, e: "MATERIALIZED", exp.MaterializedProperty: lambda self, e: "MATERIALIZED",
exp.NonClusteredColumnConstraint: lambda self,
e: f"NONCLUSTERED ({self.expressions(e, 'this', indent=False)})",
exp.NoPrimaryIndexProperty: lambda self, e: "NO PRIMARY INDEX", exp.NoPrimaryIndexProperty: lambda self, e: "NO PRIMARY INDEX",
exp.NonClusteredColumnConstraint: lambda self, e: f"NONCLUSTERED ({self.expressions(e, 'this', indent=False)})",
exp.NotForReplicationColumnConstraint: lambda self, e: "NOT FOR REPLICATION", exp.NotForReplicationColumnConstraint: lambda self, e: "NOT FOR REPLICATION",
exp.OnCommitProperty: lambda self, e: f"ON COMMIT {'DELETE' if e.args.get('delete') else 'PRESERVE'} ROWS", exp.OnCommitProperty: lambda self,
e: f"ON COMMIT {'DELETE' if e.args.get('delete') else 'PRESERVE'} ROWS",
exp.OnProperty: lambda self, e: f"ON {self.sql(e, 'this')}", exp.OnProperty: lambda self, e: f"ON {self.sql(e, 'this')}",
exp.OnUpdateColumnConstraint: lambda self, e: f"ON UPDATE {self.sql(e, 'this')}", exp.OnUpdateColumnConstraint: lambda self, e: f"ON UPDATE {self.sql(e, 'this')}",
exp.OutputModelProperty: lambda self, e: f"OUTPUT{self.sql(e, 'this')}", exp.OutputModelProperty: lambda self, e: f"OUTPUT{self.sql(e, 'this')}",
exp.PathColumnConstraint: lambda self, e: f"PATH {self.sql(e, 'this')}", exp.PathColumnConstraint: lambda self, e: f"PATH {self.sql(e, 'this')}",
exp.RemoteWithConnectionModelProperty: lambda self, e: f"REMOTE WITH CONNECTION {self.sql(e, 'this')}", exp.RemoteWithConnectionModelProperty: lambda self,
e: f"REMOTE WITH CONNECTION {self.sql(e, 'this')}",
exp.ReturnsProperty: lambda self, e: self.naked_property(e), exp.ReturnsProperty: lambda self, e: self.naked_property(e),
exp.SampleProperty: lambda self, e: f"SAMPLE BY {self.sql(e, 'this')}", exp.SampleProperty: lambda self, e: f"SAMPLE BY {self.sql(e, 'this')}",
exp.SetProperty: lambda self, e: f"{'MULTI' if e.args.get('multi') else ''}SET",
exp.SetConfigProperty: lambda self, e: self.sql(e, "this"), exp.SetConfigProperty: lambda self, e: self.sql(e, "this"),
exp.SetProperty: lambda self, e: f"{'MULTI' if e.args.get('multi') else ''}SET",
exp.SettingsProperty: lambda self, e: f"SETTINGS{self.seg('')}{(self.expressions(e))}", exp.SettingsProperty: lambda self, e: f"SETTINGS{self.seg('')}{(self.expressions(e))}",
exp.SqlReadWriteProperty: lambda self, e: e.name, exp.SqlReadWriteProperty: lambda self, e: e.name,
exp.SqlSecurityProperty: lambda self, e: f"SQL SECURITY {'DEFINER' if e.args.get('definer') else 'INVOKER'}", exp.SqlSecurityProperty: lambda self,
e: f"SQL SECURITY {'DEFINER' if e.args.get('definer') else 'INVOKER'}",
exp.StabilityProperty: lambda self, e: e.name, exp.StabilityProperty: lambda self, e: e.name,
exp.TemporaryProperty: lambda self, e: f"TEMPORARY", exp.TemporaryProperty: lambda self, e: "TEMPORARY",
exp.ToTableProperty: lambda self, e: f"TO {self.sql(e.this)}",
exp.TransientProperty: lambda self, e: "TRANSIENT",
exp.TransformModelProperty: lambda self, e: self.func("TRANSFORM", *e.expressions),
exp.TitleColumnConstraint: lambda self, e: f"TITLE {self.sql(e, 'this')}", exp.TitleColumnConstraint: lambda self, e: f"TITLE {self.sql(e, 'this')}",
exp.UppercaseColumnConstraint: lambda self, e: f"UPPERCASE", exp.ToTableProperty: lambda self, e: f"TO {self.sql(e.this)}",
exp.TransformModelProperty: lambda self, e: self.func("TRANSFORM", *e.expressions),
exp.TransientProperty: lambda self, e: "TRANSIENT",
exp.UppercaseColumnConstraint: lambda self, e: "UPPERCASE",
exp.VarMap: lambda self, e: self.func("MAP", e.args["keys"], e.args["values"]), exp.VarMap: lambda self, e: self.func("MAP", e.args["keys"], e.args["values"]),
exp.VolatileProperty: lambda self, e: "VOLATILE", exp.VolatileProperty: lambda self, e: "VOLATILE",
exp.WithJournalTableProperty: lambda self, e: f"WITH JOURNAL TABLE={self.sql(e, 'this')}", exp.WithJournalTableProperty: lambda self, e: f"WITH JOURNAL TABLE={self.sql(e, 'this')}",
@ -117,6 +137,10 @@ class Generator:
# True: Full Support, None: No support, False: No support in window specifications # True: Full Support, None: No support, False: No support in window specifications
NULL_ORDERING_SUPPORTED: t.Optional[bool] = True NULL_ORDERING_SUPPORTED: t.Optional[bool] = True
# Whether or not ignore nulls is inside the agg or outside.
# FIRST(x IGNORE NULLS) OVER vs FIRST (x) IGNORE NULLS OVER
IGNORE_NULLS_IN_FUNC = False
# Whether or not locking reads (i.e. SELECT ... FOR UPDATE/SHARE) are supported # Whether or not locking reads (i.e. SELECT ... FOR UPDATE/SHARE) are supported
LOCKING_READS_SUPPORTED = False LOCKING_READS_SUPPORTED = False
@ -266,6 +290,24 @@ class Generator:
# Whether or not UNLOGGED tables can be created # Whether or not UNLOGGED tables can be created
SUPPORTS_UNLOGGED_TABLES = False SUPPORTS_UNLOGGED_TABLES = False
# Whether or not the CREATE TABLE LIKE statement is supported
SUPPORTS_CREATE_TABLE_LIKE = True
# Whether or not the LikeProperty needs to be specified inside of the schema clause
LIKE_PROPERTY_INSIDE_SCHEMA = False
# Whether or not the JSON extraction operators expect a value of type JSON
JSON_TYPE_REQUIRED_FOR_EXTRACTION = False
# Whether or not bracketed keys like ["foo"] are supported in JSON paths
JSON_PATH_BRACKETED_KEY_SUPPORTED = True
# Whether or not to escape keys using single quotes in JSON paths
JSON_PATH_SINGLE_QUOTE_ESCAPE = False
# The JSONPathPart expressions supported by this dialect
SUPPORTED_JSON_PATH_PARTS = ALL_JSON_PATH_PARTS.copy()
TYPE_MAPPING = { TYPE_MAPPING = {
exp.DataType.Type.NCHAR: "CHAR", exp.DataType.Type.NCHAR: "CHAR",
exp.DataType.Type.NVARCHAR: "VARCHAR", exp.DataType.Type.NVARCHAR: "VARCHAR",
@ -641,8 +683,6 @@ class Generator:
if callable(transform): if callable(transform):
sql = transform(self, expression) sql = transform(self, expression)
elif transform:
sql = transform
elif isinstance(expression, exp.Expression): elif isinstance(expression, exp.Expression):
exp_handler_name = f"{expression.key}_sql" exp_handler_name = f"{expression.key}_sql"
@ -802,7 +842,7 @@ class Generator:
desc = expression.args.get("desc") desc = expression.args.get("desc")
if desc is not None: if desc is not None:
return f"PRIMARY KEY{' DESC' if desc else ' ASC'}" return f"PRIMARY KEY{' DESC' if desc else ' ASC'}"
return f"PRIMARY KEY" return "PRIMARY KEY"
def uniquecolumnconstraint_sql(self, expression: exp.UniqueColumnConstraint) -> str: def uniquecolumnconstraint_sql(self, expression: exp.UniqueColumnConstraint) -> str:
this = self.sql(expression, "this") this = self.sql(expression, "this")
@ -1218,9 +1258,21 @@ class Generator:
return f"{property_name}={self.sql(expression, 'this')}" return f"{property_name}={self.sql(expression, 'this')}"
def likeproperty_sql(self, expression: exp.LikeProperty) -> str: def likeproperty_sql(self, expression: exp.LikeProperty) -> str:
options = " ".join(f"{e.name} {self.sql(e, 'value')}" for e in expression.expressions) if self.SUPPORTS_CREATE_TABLE_LIKE:
options = f" {options}" if options else "" options = " ".join(f"{e.name} {self.sql(e, 'value')}" for e in expression.expressions)
return f"LIKE {self.sql(expression, 'this')}{options}" options = f" {options}" if options else ""
like = f"LIKE {self.sql(expression, 'this')}{options}"
if self.LIKE_PROPERTY_INSIDE_SCHEMA and not isinstance(expression.parent, exp.Schema):
like = f"({like})"
return like
if expression.expressions:
self.unsupported("Transpilation of LIKE property options is unsupported")
select = exp.select("*").from_(expression.this).limit(0)
return f"AS {self.sql(select)}"
def fallbackproperty_sql(self, expression: exp.FallbackProperty) -> str: def fallbackproperty_sql(self, expression: exp.FallbackProperty) -> str:
no = "NO " if expression.args.get("no") else "" no = "NO " if expression.args.get("no") else ""
@ -2367,6 +2419,31 @@ class Generator:
def jsonkeyvalue_sql(self, expression: exp.JSONKeyValue) -> str: def jsonkeyvalue_sql(self, expression: exp.JSONKeyValue) -> str:
return f"{self.sql(expression, 'this')}{self.JSON_KEY_VALUE_PAIR_SEP} {self.sql(expression, 'expression')}" return f"{self.sql(expression, 'this')}{self.JSON_KEY_VALUE_PAIR_SEP} {self.sql(expression, 'expression')}"
def jsonpath_sql(self, expression: exp.JSONPath) -> str:
path = self.expressions(expression, sep="", flat=True).lstrip(".")
return f"{self.dialect.QUOTE_START}{path}{self.dialect.QUOTE_END}"
def json_path_part(self, expression: int | str | exp.JSONPathPart) -> str:
if isinstance(expression, exp.JSONPathPart):
transform = self.TRANSFORMS.get(expression.__class__)
if not callable(transform):
self.unsupported(f"Unsupported JSONPathPart type {expression.__class__.__name__}")
return ""
return transform(self, expression)
if isinstance(expression, int):
return str(expression)
if self.JSON_PATH_SINGLE_QUOTE_ESCAPE:
escaped = expression.replace("'", "\\'")
escaped = f"\\'{expression}\\'"
else:
escaped = expression.replace('"', '\\"')
escaped = f'"{escaped}"'
return escaped
def formatjson_sql(self, expression: exp.FormatJson) -> str: def formatjson_sql(self, expression: exp.FormatJson) -> str:
return f"{self.sql(expression, 'this')} FORMAT JSON" return f"{self.sql(expression, 'this')} FORMAT JSON"
@ -2620,6 +2697,9 @@ class Generator:
zone = self.sql(expression, "this") zone = self.sql(expression, "this")
return f"CURRENT_DATE({zone})" if zone else "CURRENT_DATE" return f"CURRENT_DATE({zone})" if zone else "CURRENT_DATE"
def currenttimestamp_sql(self, expression: exp.CurrentTimestamp) -> str:
return self.func("CURRENT_TIMESTAMP", expression.this)
def collate_sql(self, expression: exp.Collate) -> str: def collate_sql(self, expression: exp.Collate) -> str:
if self.COLLATE_IS_FUNC: if self.COLLATE_IS_FUNC:
return self.function_fallback_sql(expression) return self.function_fallback_sql(expression)
@ -2761,10 +2841,20 @@ class Generator:
return f"DISTINCT{this}{on}" return f"DISTINCT{this}{on}"
def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str: def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
return f"{self.sql(expression, 'this')} IGNORE NULLS" return self._embed_ignore_nulls(expression, "IGNORE NULLS")
def respectnulls_sql(self, expression: exp.RespectNulls) -> str: def respectnulls_sql(self, expression: exp.RespectNulls) -> str:
return f"{self.sql(expression, 'this')} RESPECT NULLS" return self._embed_ignore_nulls(expression, "RESPECT NULLS")
def _embed_ignore_nulls(self, expression: exp.IgnoreNulls | exp.RespectNulls, text: str) -> str:
if self.IGNORE_NULLS_IN_FUNC:
this = expression.find(exp.AggFunc)
if this:
sql = self.sql(this)
sql = sql[:-1] + f" {text})"
return sql
return f"{self.sql(expression, 'this')} {text}"
def intdiv_sql(self, expression: exp.IntDiv) -> str: def intdiv_sql(self, expression: exp.IntDiv) -> str:
return self.sql( return self.sql(
@ -2935,7 +3025,7 @@ class Generator:
def format_args(self, *args: t.Optional[str | exp.Expression]) -> str: def format_args(self, *args: t.Optional[str | exp.Expression]) -> str:
arg_sqls = tuple(self.sql(arg) for arg in args if arg is not None) arg_sqls = tuple(self.sql(arg) for arg in args if arg is not None)
if self.pretty and self.text_width(arg_sqls) > self.max_text_width: if self.pretty and self.text_width(arg_sqls) > self.max_text_width:
return self.indent("\n" + f",\n".join(arg_sqls) + "\n", skip_first=True, skip_last=True) return self.indent("\n" + ",\n".join(arg_sqls) + "\n", skip_first=True, skip_last=True)
return ", ".join(arg_sqls) return ", ".join(arg_sqls)
def text_width(self, args: t.Iterable) -> int: def text_width(self, args: t.Iterable) -> int:
@ -3279,6 +3369,22 @@ class Generator:
return self.func("LAST_DAY", expression.this) return self.func("LAST_DAY", expression.this)
def _jsonpathkey_sql(self, expression: exp.JSONPathKey) -> str:
this = expression.this
if isinstance(this, exp.JSONPathWildcard):
this = self.json_path_part(this)
return f".{this}" if this else ""
if exp.SAFE_IDENTIFIER_RE.match(this):
return f".{this}"
this = self.json_path_part(this)
return f"[{this}]" if self.JSON_PATH_BRACKETED_KEY_SUPPORTED else f".{this}"
def _jsonpathsubscript_sql(self, expression: exp.JSONPathSubscript) -> str:
this = self.json_path_part(expression.this)
return f"[{this}]" if this else ""
def _simplify_unless_literal(self, expression: E) -> E: def _simplify_unless_literal(self, expression: E) -> E:
if not isinstance(expression, exp.Literal): if not isinstance(expression, exp.Literal):
from sqlglot.optimizer.simplify import simplify from sqlglot.optimizer.simplify import simplify

View file

@ -53,11 +53,13 @@ def seq_get(seq: t.Sequence[T], index: int) -> t.Optional[T]:
@t.overload @t.overload
def ensure_list(value: t.Collection[T]) -> t.List[T]: ... def ensure_list(value: t.Collection[T]) -> t.List[T]:
...
@t.overload @t.overload
def ensure_list(value: T) -> t.List[T]: ... def ensure_list(value: T) -> t.List[T]:
...
def ensure_list(value): def ensure_list(value):
@ -79,11 +81,13 @@ def ensure_list(value):
@t.overload @t.overload
def ensure_collection(value: t.Collection[T]) -> t.Collection[T]: ... def ensure_collection(value: t.Collection[T]) -> t.Collection[T]:
...
@t.overload @t.overload
def ensure_collection(value: T) -> t.Collection[T]: ... def ensure_collection(value: T) -> t.Collection[T]:
...
def ensure_collection(value): def ensure_collection(value):
@ -232,7 +236,7 @@ def tsort(dag: t.Dict[T, t.Set[T]]) -> t.List[T]:
for node, deps in tuple(dag.items()): for node, deps in tuple(dag.items()):
for dep in deps: for dep in deps:
if not dep in dag: if dep not in dag:
dag[dep] = set() dag[dep] = set()
while dag: while dag:
@ -316,6 +320,14 @@ def find_new_name(taken: t.Collection[str], base: str) -> str:
return new return new
def is_int(text: str) -> bool:
try:
int(text)
return True
except ValueError:
return False
def name_sequence(prefix: str) -> t.Callable[[], str]: def name_sequence(prefix: str) -> t.Callable[[], str]:
"""Returns a name generator given a prefix (e.g. a0, a1, a2, ... if the prefix is "a").""" """Returns a name generator given a prefix (e.g. a0, a1, a2, ... if the prefix is "a")."""
sequence = count() sequence = count()

View file

@ -2,8 +2,8 @@ from __future__ import annotations
import typing as t import typing as t
import sqlglot.expressions as exp
from sqlglot.errors import ParseError from sqlglot.errors import ParseError
from sqlglot.expressions import SAFE_IDENTIFIER_RE
from sqlglot.tokens import Token, Tokenizer, TokenType from sqlglot.tokens import Token, Tokenizer, TokenType
if t.TYPE_CHECKING: if t.TYPE_CHECKING:
@ -36,20 +36,8 @@ class JSONPathTokenizer(Tokenizer):
STRING_ESCAPES = ["\\"] STRING_ESCAPES = ["\\"]
JSONPathNode = t.Dict[str, t.Any] def parse(path: str) -> exp.JSONPath:
"""Takes in a JSON path string and parses it into a JSONPath expression."""
def _node(kind: str, value: t.Any = None, **kwargs: t.Any) -> JSONPathNode:
node = {"kind": kind, **kwargs}
if value is not None:
node["value"] = value
return node
def parse(path: str) -> t.List[JSONPathNode]:
"""Takes in a JSONPath string and converts into a list of nodes."""
tokens = JSONPathTokenizer().tokenize(path) tokens = JSONPathTokenizer().tokenize(path)
size = len(tokens) size = len(tokens)
@ -89,7 +77,7 @@ def parse(path: str) -> t.List[JSONPathNode]:
if token: if token:
return token.text return token.text
if _match(TokenType.STAR): if _match(TokenType.STAR):
return _node("wildcard") return exp.JSONPathWildcard()
if _match(TokenType.PLACEHOLDER) or _match(TokenType.L_PAREN): if _match(TokenType.PLACEHOLDER) or _match(TokenType.L_PAREN):
script = _prev().text == "(" script = _prev().text == "("
start = i start = i
@ -100,9 +88,9 @@ def parse(path: str) -> t.List[JSONPathNode]:
if _curr() in (TokenType.R_BRACKET, None): if _curr() in (TokenType.R_BRACKET, None):
break break
_advance() _advance()
return _node(
"script" if script else "filter", path[tokens[start].start : tokens[i].end] expr_type = exp.JSONPathScript if script else exp.JSONPathFilter
) return expr_type(this=path[tokens[start].start : tokens[i].end])
number = "-" if _match(TokenType.DASH) else "" number = "-" if _match(TokenType.DASH) else ""
@ -112,6 +100,7 @@ def parse(path: str) -> t.List[JSONPathNode]:
if number: if number:
return int(number) return int(number)
return False return False
def _parse_slice() -> t.Any: def _parse_slice() -> t.Any:
@ -121,9 +110,10 @@ def parse(path: str) -> t.List[JSONPathNode]:
if end is None and step is None: if end is None and step is None:
return start return start
return _node("slice", start=start, end=end, step=step)
def _parse_bracket() -> JSONPathNode: return exp.JSONPathSlice(start=start, end=end, step=step)
def _parse_bracket() -> exp.JSONPathPart:
literal = _parse_slice() literal = _parse_slice()
if isinstance(literal, str) or literal is not False: if isinstance(literal, str) or literal is not False:
@ -136,13 +126,15 @@ def parse(path: str) -> t.List[JSONPathNode]:
if len(indexes) == 1: if len(indexes) == 1:
if isinstance(literal, str): if isinstance(literal, str):
node = _node("key", indexes[0]) node: exp.JSONPathPart = exp.JSONPathKey(this=indexes[0])
elif isinstance(literal, dict) and literal["kind"] in ("script", "filter"): elif isinstance(literal, exp.JSONPathPart) and isinstance(
node = _node("selector", indexes[0]) literal, (exp.JSONPathScript, exp.JSONPathFilter)
):
node = exp.JSONPathSelector(this=indexes[0])
else: else:
node = _node("subscript", indexes[0]) node = exp.JSONPathSubscript(this=indexes[0])
else: else:
node = _node("union", indexes) node = exp.JSONPathUnion(expressions=indexes)
else: else:
raise ParseError(_error("Cannot have empty segment")) raise ParseError(_error("Cannot have empty segment"))
@ -150,66 +142,56 @@ def parse(path: str) -> t.List[JSONPathNode]:
return node return node
nodes = [] # We canonicalize the JSON path AST so that it always starts with a
# "root" element, so paths like "field" will be generated as "$.field"
_match(TokenType.DOLLAR)
expressions: t.List[exp.JSONPathPart] = [exp.JSONPathRoot()]
while _curr(): while _curr():
if _match(TokenType.DOLLAR): if _match(TokenType.DOT) or _match(TokenType.COLON):
nodes.append(_node("root"))
elif _match(TokenType.DOT):
recursive = _prev().text == ".." recursive = _prev().text == ".."
value = _match(TokenType.VAR) or _match(TokenType.STAR)
nodes.append( if _match(TokenType.VAR) or _match(TokenType.IDENTIFIER):
_node("recursive" if recursive else "child", value=value.text if value else None) value: t.Optional[str | exp.JSONPathWildcard] = _prev().text
) elif _match(TokenType.STAR):
value = exp.JSONPathWildcard()
else:
value = None
if recursive:
expressions.append(exp.JSONPathRecursive(this=value))
elif value:
expressions.append(exp.JSONPathKey(this=value))
else:
raise ParseError(_error("Expected key name or * after DOT"))
elif _match(TokenType.L_BRACKET): elif _match(TokenType.L_BRACKET):
nodes.append(_parse_bracket()) expressions.append(_parse_bracket())
elif _match(TokenType.VAR): elif _match(TokenType.VAR) or _match(TokenType.IDENTIFIER):
nodes.append(_node("key", _prev().text)) expressions.append(exp.JSONPathKey(this=_prev().text))
elif _match(TokenType.STAR): elif _match(TokenType.STAR):
nodes.append(_node("wildcard")) expressions.append(exp.JSONPathWildcard())
elif _match(TokenType.PARAMETER):
nodes.append(_node("current"))
else: else:
raise ParseError(_error(f"Unexpected {tokens[i].token_type}")) raise ParseError(_error(f"Unexpected {tokens[i].token_type}"))
return nodes return exp.JSONPath(expressions=expressions)
MAPPING = { JSON_PATH_PART_TRANSFORMS: t.Dict[t.Type[exp.Expression], t.Callable[..., str]] = {
"child": lambda n: f".{n['value']}" if n.get("value") is not None else "", exp.JSONPathFilter: lambda _, e: f"?{e.this}",
"filter": lambda n: f"?{n['value']}", exp.JSONPathKey: lambda self, e: self._jsonpathkey_sql(e),
"key": lambda n: ( exp.JSONPathRecursive: lambda _, e: f"..{e.this or ''}",
f".{n['value']}" if SAFE_IDENTIFIER_RE.match(n["value"]) else f'[{generate([n["value"]])}]' exp.JSONPathRoot: lambda *_: "$",
), exp.JSONPathScript: lambda _, e: f"({e.this}",
"recursive": lambda n: f"..{n['value']}" if n.get("value") is not None else "..", exp.JSONPathSelector: lambda self, e: f"[{self.json_path_part(e.this)}]",
"root": lambda _: "$", exp.JSONPathSlice: lambda self, e: ":".join(
"script": lambda n: f"({n['value']}", "" if p is False else self.json_path_part(p)
"slice": lambda n: ":".join( for p in [e.args.get("start"), e.args.get("end"), e.args.get("step")]
"" if p is False else generate([p])
for p in [n["start"], n["end"], n["step"]]
if p is not None if p is not None
), ),
"selector": lambda n: f"[{generate([n['value']])}]", exp.JSONPathSubscript: lambda self, e: self._jsonpathsubscript_sql(e),
"subscript": lambda n: f"[{generate([n['value']])}]", exp.JSONPathUnion: lambda self,
"union": lambda n: f"[{','.join(generate([p]) for p in n['value'])}]", e: f"[{','.join(self.json_path_part(p) for p in e.expressions)}]",
"wildcard": lambda _: "*", exp.JSONPathWildcard: lambda *_: "*",
} }
ALL_JSON_PATH_PARTS = set(JSON_PATH_PART_TRANSFORMS)
def generate(
nodes: t.List[JSONPathNode],
mapping: t.Optional[t.Dict[str, t.Callable[[JSONPathNode], str]]] = None,
) -> str:
mapping = MAPPING if mapping is None else mapping
path = []
for node in nodes:
if isinstance(node, dict):
path.append(mapping[node["kind"]](node))
elif isinstance(node, str):
escaped = node.replace('"', '\\"')
path.append(f'"{escaped}"')
else:
path.append(str(node))
return "".join(path)

View file

@ -1,3 +1,5 @@
# ruff: noqa: F401
from sqlglot.optimizer.optimizer import RULES, optimize from sqlglot.optimizer.optimizer import RULES, optimize
from sqlglot.optimizer.scope import ( from sqlglot.optimizer.scope import (
Scope, Scope,

View file

@ -10,11 +10,13 @@ if t.TYPE_CHECKING:
@t.overload @t.overload
def normalize_identifiers(expression: E, dialect: DialectType = None) -> E: ... def normalize_identifiers(expression: E, dialect: DialectType = None) -> E:
...
@t.overload @t.overload
def normalize_identifiers(expression: str, dialect: DialectType = None) -> exp.Identifier: ... def normalize_identifiers(expression: str, dialect: DialectType = None) -> exp.Identifier:
...
def normalize_identifiers(expression, dialect=None): def normalize_identifiers(expression, dialect=None):

View file

@ -8,10 +8,10 @@ from sqlglot.schema import ensure_schema
# Sentinel value that means an outer query selecting ALL columns # Sentinel value that means an outer query selecting ALL columns
SELECT_ALL = object() SELECT_ALL = object()
# Selection to use if selection list is empty # Selection to use if selection list is empty
DEFAULT_SELECTION = lambda is_agg: alias( def default_selection(is_agg: bool) -> exp.Alias:
exp.Max(this=exp.Literal.number(1)) if is_agg else "1", "_" return alias(exp.Max(this=exp.Literal.number(1)) if is_agg else "1", "_")
)
def pushdown_projections(expression, schema=None, remove_unused_selections=True): def pushdown_projections(expression, schema=None, remove_unused_selections=True):
@ -129,7 +129,7 @@ def _remove_unused_selections(scope, parent_selections, schema, alias_count):
# If there are no remaining selections, just select a single constant # If there are no remaining selections, just select a single constant
if not new_selections: if not new_selections:
new_selections.append(DEFAULT_SELECTION(is_agg)) new_selections.append(default_selection(is_agg))
scope.expression.select(*new_selections, append=False, copy=False) scope.expression.select(*new_selections, append=False, copy=False)

View file

@ -104,7 +104,6 @@ def simplify(
if root: if root:
expression.replace(node) expression.replace(node)
return node return node
expression = while_changing(expression, _simplify) expression = while_changing(expression, _simplify)
@ -174,16 +173,20 @@ def simplify_not(expression):
if isinstance(this, exp.Paren): if isinstance(this, exp.Paren):
condition = this.unnest() condition = this.unnest()
if isinstance(condition, exp.And): if isinstance(condition, exp.And):
return exp.or_( return exp.paren(
exp.not_(condition.left, copy=False), exp.or_(
exp.not_(condition.right, copy=False), exp.not_(condition.left, copy=False),
copy=False, exp.not_(condition.right, copy=False),
copy=False,
)
) )
if isinstance(condition, exp.Or): if isinstance(condition, exp.Or):
return exp.and_( return exp.paren(
exp.not_(condition.left, copy=False), exp.and_(
exp.not_(condition.right, copy=False), exp.not_(condition.left, copy=False),
copy=False, exp.not_(condition.right, copy=False),
copy=False,
)
) )
if is_null(condition): if is_null(condition):
return exp.null() return exp.null()
@ -490,7 +493,7 @@ def simplify_equality(expression: exp.Expression) -> exp.Expression:
if isinstance(expression, COMPARISONS): if isinstance(expression, COMPARISONS):
l, r = expression.left, expression.right l, r = expression.left, expression.right
if not l.__class__ in INVERSE_OPS: if l.__class__ not in INVERSE_OPS:
return expression return expression
if r.is_number: if r.is_number:
@ -714,8 +717,7 @@ def simplify_concat(expression):
"""Reduces all groups that contain string literals by concatenating them.""" """Reduces all groups that contain string literals by concatenating them."""
if not isinstance(expression, CONCATS) or ( if not isinstance(expression, CONCATS) or (
# We can't reduce a CONCAT_WS call if we don't statically know the separator # We can't reduce a CONCAT_WS call if we don't statically know the separator
isinstance(expression, exp.ConcatWs) isinstance(expression, exp.ConcatWs) and not expression.expressions[0].is_string
and not expression.expressions[0].is_string
): ):
return expression return expression

View file

@ -60,6 +60,19 @@ def parse_logarithm(args: t.List, dialect: Dialect) -> exp.Func:
return (exp.Ln if dialect.parser_class.LOG_DEFAULTS_TO_LN else exp.Log)(this=this) return (exp.Ln if dialect.parser_class.LOG_DEFAULTS_TO_LN else exp.Log)(this=this)
def parse_extract_json_with_path(expr_type: t.Type[E]) -> t.Callable[[t.List, Dialect], E]:
def _parser(args: t.List, dialect: Dialect) -> E:
expression = expr_type(
this=seq_get(args, 0), expression=dialect.to_json_path(seq_get(args, 1))
)
if len(args) > 2 and expr_type is exp.JSONExtract:
expression.set("expressions", args[2:])
return expression
return _parser
class _Parser(type): class _Parser(type):
def __new__(cls, clsname, bases, attrs): def __new__(cls, clsname, bases, attrs):
klass = super().__new__(cls, clsname, bases, attrs) klass = super().__new__(cls, clsname, bases, attrs)
@ -102,6 +115,9 @@ class Parser(metaclass=_Parser):
to=exp.DataType(this=exp.DataType.Type.TEXT), to=exp.DataType(this=exp.DataType.Type.TEXT),
), ),
"GLOB": lambda args: exp.Glob(this=seq_get(args, 1), expression=seq_get(args, 0)), "GLOB": lambda args: exp.Glob(this=seq_get(args, 1), expression=seq_get(args, 0)),
"JSON_EXTRACT": parse_extract_json_with_path(exp.JSONExtract),
"JSON_EXTRACT_SCALAR": parse_extract_json_with_path(exp.JSONExtractScalar),
"JSON_EXTRACT_PATH_TEXT": parse_extract_json_with_path(exp.JSONExtractScalar),
"LIKE": parse_like, "LIKE": parse_like,
"LOG": parse_logarithm, "LOG": parse_logarithm,
"TIME_TO_TIME_STR": lambda args: exp.Cast( "TIME_TO_TIME_STR": lambda args: exp.Cast(
@ -175,6 +191,7 @@ class Parser(metaclass=_Parser):
TokenType.NCHAR, TokenType.NCHAR,
TokenType.VARCHAR, TokenType.VARCHAR,
TokenType.NVARCHAR, TokenType.NVARCHAR,
TokenType.BPCHAR,
TokenType.TEXT, TokenType.TEXT,
TokenType.MEDIUMTEXT, TokenType.MEDIUMTEXT,
TokenType.LONGTEXT, TokenType.LONGTEXT,
@ -295,6 +312,7 @@ class Parser(metaclass=_Parser):
TokenType.ASC, TokenType.ASC,
TokenType.AUTO_INCREMENT, TokenType.AUTO_INCREMENT,
TokenType.BEGIN, TokenType.BEGIN,
TokenType.BPCHAR,
TokenType.CACHE, TokenType.CACHE,
TokenType.CASE, TokenType.CASE,
TokenType.COLLATE, TokenType.COLLATE,
@ -531,12 +549,12 @@ class Parser(metaclass=_Parser):
TokenType.ARROW: lambda self, this, path: self.expression( TokenType.ARROW: lambda self, this, path: self.expression(
exp.JSONExtract, exp.JSONExtract,
this=this, this=this,
expression=path, expression=self.dialect.to_json_path(path),
), ),
TokenType.DARROW: lambda self, this, path: self.expression( TokenType.DARROW: lambda self, this, path: self.expression(
exp.JSONExtractScalar, exp.JSONExtractScalar,
this=this, this=this,
expression=path, expression=self.dialect.to_json_path(path),
), ),
TokenType.HASH_ARROW: lambda self, this, path: self.expression( TokenType.HASH_ARROW: lambda self, this, path: self.expression(
exp.JSONBExtract, exp.JSONBExtract,
@ -1334,7 +1352,9 @@ class Parser(metaclass=_Parser):
exp.Drop, exp.Drop,
comments=start.comments, comments=start.comments,
exists=exists or self._parse_exists(), exists=exists or self._parse_exists(),
this=self._parse_table(schema=True), this=self._parse_table(
schema=True, is_db_reference=self._prev.token_type == TokenType.SCHEMA
),
kind=kind, kind=kind,
temporary=temporary, temporary=temporary,
materialized=materialized, materialized=materialized,
@ -1422,7 +1442,9 @@ class Parser(metaclass=_Parser):
elif create_token.token_type == TokenType.INDEX: elif create_token.token_type == TokenType.INDEX:
this = self._parse_index(index=self._parse_id_var()) this = self._parse_index(index=self._parse_id_var())
elif create_token.token_type in self.DB_CREATABLES: elif create_token.token_type in self.DB_CREATABLES:
table_parts = self._parse_table_parts(schema=True) table_parts = self._parse_table_parts(
schema=True, is_db_reference=create_token.token_type == TokenType.SCHEMA
)
# exp.Properties.Location.POST_NAME # exp.Properties.Location.POST_NAME
self._match(TokenType.COMMA) self._match(TokenType.COMMA)
@ -2499,11 +2521,11 @@ class Parser(metaclass=_Parser):
elif self._match_text_seq("ALL", "ROWS", "PER", "MATCH"): elif self._match_text_seq("ALL", "ROWS", "PER", "MATCH"):
text = "ALL ROWS PER MATCH" text = "ALL ROWS PER MATCH"
if self._match_text_seq("SHOW", "EMPTY", "MATCHES"): if self._match_text_seq("SHOW", "EMPTY", "MATCHES"):
text += f" SHOW EMPTY MATCHES" text += " SHOW EMPTY MATCHES"
elif self._match_text_seq("OMIT", "EMPTY", "MATCHES"): elif self._match_text_seq("OMIT", "EMPTY", "MATCHES"):
text += f" OMIT EMPTY MATCHES" text += " OMIT EMPTY MATCHES"
elif self._match_text_seq("WITH", "UNMATCHED", "ROWS"): elif self._match_text_seq("WITH", "UNMATCHED", "ROWS"):
text += f" WITH UNMATCHED ROWS" text += " WITH UNMATCHED ROWS"
rows = exp.var(text) rows = exp.var(text)
else: else:
rows = None rows = None
@ -2511,9 +2533,9 @@ class Parser(metaclass=_Parser):
if self._match_text_seq("AFTER", "MATCH", "SKIP"): if self._match_text_seq("AFTER", "MATCH", "SKIP"):
text = "AFTER MATCH SKIP" text = "AFTER MATCH SKIP"
if self._match_text_seq("PAST", "LAST", "ROW"): if self._match_text_seq("PAST", "LAST", "ROW"):
text += f" PAST LAST ROW" text += " PAST LAST ROW"
elif self._match_text_seq("TO", "NEXT", "ROW"): elif self._match_text_seq("TO", "NEXT", "ROW"):
text += f" TO NEXT ROW" text += " TO NEXT ROW"
elif self._match_text_seq("TO", "FIRST"): elif self._match_text_seq("TO", "FIRST"):
text += f" TO FIRST {self._advance_any().text}" # type: ignore text += f" TO FIRST {self._advance_any().text}" # type: ignore
elif self._match_text_seq("TO", "LAST"): elif self._match_text_seq("TO", "LAST"):
@ -2772,7 +2794,7 @@ class Parser(metaclass=_Parser):
or self._parse_placeholder() or self._parse_placeholder()
) )
def _parse_table_parts(self, schema: bool = False) -> exp.Table: def _parse_table_parts(self, schema: bool = False, is_db_reference: bool = False) -> exp.Table:
catalog = None catalog = None
db = None db = None
table: t.Optional[exp.Expression | str] = self._parse_table_part(schema=schema) table: t.Optional[exp.Expression | str] = self._parse_table_part(schema=schema)
@ -2788,8 +2810,15 @@ class Parser(metaclass=_Parser):
db = table db = table
table = self._parse_table_part(schema=schema) or "" table = self._parse_table_part(schema=schema) or ""
if not table: if is_db_reference:
catalog = db
db = table
table = None
if not table and not is_db_reference:
self.raise_error(f"Expected table name but got {self._curr}") self.raise_error(f"Expected table name but got {self._curr}")
if not db and is_db_reference:
self.raise_error(f"Expected database name but got {self._curr}")
return self.expression( return self.expression(
exp.Table, this=table, db=db, catalog=catalog, pivots=self._parse_pivots() exp.Table, this=table, db=db, catalog=catalog, pivots=self._parse_pivots()
@ -2801,6 +2830,7 @@ class Parser(metaclass=_Parser):
joins: bool = False, joins: bool = False,
alias_tokens: t.Optional[t.Collection[TokenType]] = None, alias_tokens: t.Optional[t.Collection[TokenType]] = None,
parse_bracket: bool = False, parse_bracket: bool = False,
is_db_reference: bool = False,
) -> t.Optional[exp.Expression]: ) -> t.Optional[exp.Expression]:
lateral = self._parse_lateral() lateral = self._parse_lateral()
if lateral: if lateral:
@ -2823,7 +2853,11 @@ class Parser(metaclass=_Parser):
bracket = parse_bracket and self._parse_bracket(None) bracket = parse_bracket and self._parse_bracket(None)
bracket = self.expression(exp.Table, this=bracket) if bracket else None bracket = self.expression(exp.Table, this=bracket) if bracket else None
this = t.cast( this = t.cast(
exp.Expression, bracket or self._parse_bracket(self._parse_table_parts(schema=schema)) exp.Expression,
bracket
or self._parse_bracket(
self._parse_table_parts(schema=schema, is_db_reference=is_db_reference)
),
) )
if schema: if schema:
@ -3650,7 +3684,6 @@ class Parser(metaclass=_Parser):
identifier = allow_identifiers and self._parse_id_var( identifier = allow_identifiers and self._parse_id_var(
any_token=False, tokens=(TokenType.VAR,) any_token=False, tokens=(TokenType.VAR,)
) )
if identifier: if identifier:
tokens = self.dialect.tokenize(identifier.name) tokens = self.dialect.tokenize(identifier.name)
@ -3818,12 +3851,14 @@ class Parser(metaclass=_Parser):
return self.expression(exp.AtTimeZone, this=this, zone=self._parse_unary()) return self.expression(exp.AtTimeZone, this=this, zone=self._parse_unary())
def _parse_column(self) -> t.Optional[exp.Expression]: def _parse_column(self) -> t.Optional[exp.Expression]:
this = self._parse_column_reference()
return self._parse_column_ops(this) if this else self._parse_bracket(this)
def _parse_column_reference(self) -> t.Optional[exp.Expression]:
this = self._parse_field() this = self._parse_field()
if isinstance(this, exp.Identifier): if isinstance(this, exp.Identifier):
this = self.expression(exp.Column, this=this) this = self.expression(exp.Column, this=this)
elif not this: return this
return self._parse_bracket(this)
return self._parse_column_ops(this)
def _parse_column_ops(self, this: t.Optional[exp.Expression]) -> t.Optional[exp.Expression]: def _parse_column_ops(self, this: t.Optional[exp.Expression]) -> t.Optional[exp.Expression]:
this = self._parse_bracket(this) this = self._parse_bracket(this)
@ -3837,13 +3872,7 @@ class Parser(metaclass=_Parser):
if not field: if not field:
self.raise_error("Expected type") self.raise_error("Expected type")
elif op and self._curr: elif op and self._curr:
self._advance() field = self._parse_column_reference()
value = self._prev.text
field = (
exp.Literal.number(value)
if self._prev.token_type == TokenType.NUMBER
else exp.Literal.string(value)
)
else: else:
field = self._parse_field(anonymous_func=True, any_token=True) field = self._parse_field(anonymous_func=True, any_token=True)
@ -4375,7 +4404,10 @@ class Parser(metaclass=_Parser):
options[kind] = action options[kind] = action
return self.expression( return self.expression(
exp.ForeignKey, expressions=expressions, reference=reference, **options # type: ignore exp.ForeignKey,
expressions=expressions,
reference=reference,
**options, # type: ignore
) )
def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: def _parse_primary_key_part(self) -> t.Optional[exp.Expression]:
@ -4692,10 +4724,12 @@ class Parser(metaclass=_Parser):
return None return None
@t.overload @t.overload
def _parse_json_object(self, agg: Lit[False]) -> exp.JSONObject: ... def _parse_json_object(self, agg: Lit[False]) -> exp.JSONObject:
...
@t.overload @t.overload
def _parse_json_object(self, agg: Lit[True]) -> exp.JSONObjectAgg: ... def _parse_json_object(self, agg: Lit[True]) -> exp.JSONObjectAgg:
...
def _parse_json_object(self, agg=False): def _parse_json_object(self, agg=False):
star = self._parse_star() star = self._parse_star()
@ -4937,6 +4971,13 @@ class Parser(metaclass=_Parser):
# (https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/img_text/first_value.html) # (https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/img_text/first_value.html)
# and Snowflake chose to do the same for familiarity # and Snowflake chose to do the same for familiarity
# https://docs.snowflake.com/en/sql-reference/functions/first_value.html#usage-notes # https://docs.snowflake.com/en/sql-reference/functions/first_value.html#usage-notes
if isinstance(this, exp.AggFunc):
ignore_respect = this.find(exp.IgnoreNulls, exp.RespectNulls)
if ignore_respect and ignore_respect is not this:
ignore_respect.replace(ignore_respect.this)
this = self.expression(ignore_respect.__class__, this=this)
this = self._parse_respect_or_ignore_nulls(this) this = self._parse_respect_or_ignore_nulls(this)
# bigquery select from window x AS (partition by ...) # bigquery select from window x AS (partition by ...)
@ -5732,12 +5773,14 @@ class Parser(metaclass=_Parser):
return True return True
@t.overload @t.overload
def _replace_columns_with_dots(self, this: exp.Expression) -> exp.Expression: ... def _replace_columns_with_dots(self, this: exp.Expression) -> exp.Expression:
...
@t.overload @t.overload
def _replace_columns_with_dots( def _replace_columns_with_dots(
self, this: t.Optional[exp.Expression] self, this: t.Optional[exp.Expression]
) -> t.Optional[exp.Expression]: ... ) -> t.Optional[exp.Expression]:
...
def _replace_columns_with_dots(self, this): def _replace_columns_with_dots(self, this):
if isinstance(this, exp.Dot): if isinstance(this, exp.Dot):

View file

@ -125,6 +125,7 @@ class TokenType(AutoName):
NCHAR = auto() NCHAR = auto()
VARCHAR = auto() VARCHAR = auto()
NVARCHAR = auto() NVARCHAR = auto()
BPCHAR = auto()
TEXT = auto() TEXT = auto()
MEDIUMTEXT = auto() MEDIUMTEXT = auto()
LONGTEXT = auto() LONGTEXT = auto()
@ -801,6 +802,7 @@ class Tokenizer(metaclass=_Tokenizer):
"VARCHAR2": TokenType.VARCHAR, "VARCHAR2": TokenType.VARCHAR,
"NVARCHAR": TokenType.NVARCHAR, "NVARCHAR": TokenType.NVARCHAR,
"NVARCHAR2": TokenType.NVARCHAR, "NVARCHAR2": TokenType.NVARCHAR,
"BPCHAR": TokenType.BPCHAR,
"STR": TokenType.TEXT, "STR": TokenType.TEXT,
"STRING": TokenType.TEXT, "STRING": TokenType.TEXT,
"TEXT": TokenType.TEXT, "TEXT": TokenType.TEXT,
@ -1141,7 +1143,7 @@ class Tokenizer(metaclass=_Tokenizer):
self._comments.append(self._text[comment_start_size : -comment_end_size + 1]) self._comments.append(self._text[comment_start_size : -comment_end_size + 1])
self._advance(comment_end_size - 1) self._advance(comment_end_size - 1)
else: else:
while not self._end and not self.WHITE_SPACE.get(self._peek) is TokenType.BREAK: while not self._end and self.WHITE_SPACE.get(self._peek) is not TokenType.BREAK:
self._advance(alnum=True) self._advance(alnum=True)
self._comments.append(self._text[comment_start_size:]) self._comments.append(self._text[comment_start_size:])
@ -1259,7 +1261,7 @@ class Tokenizer(metaclass=_Tokenizer):
if base: if base:
try: try:
int(text, base) int(text, base)
except: except Exception:
raise TokenError( raise TokenError(
f"Numeric string contains invalid characters from {self._line}:{self._start}" f"Numeric string contains invalid characters from {self._line}:{self._start}"
) )

View file

@ -485,8 +485,8 @@ def preprocess(
expression_type = type(expression) expression_type = type(expression)
expression = transforms[0](expression) expression = transforms[0](expression)
for t in transforms[1:]: for transform in transforms[1:]:
expression = t(expression) expression = transform(expression)
_sql_handler = getattr(self, expression.key + "_sql", None) _sql_handler = getattr(self, expression.key + "_sql", None)
if _sql_handler: if _sql_handler:

View file

@ -528,7 +528,7 @@ class TestFunctions(unittest.TestCase):
col = SF.first(SF.col("cola")) col = SF.first(SF.col("cola"))
self.assertEqual("FIRST(cola)", col.sql()) self.assertEqual("FIRST(cola)", col.sql())
ignore_nulls = SF.first("cola", True) ignore_nulls = SF.first("cola", True)
self.assertEqual("FIRST(cola, TRUE)", ignore_nulls.sql()) self.assertEqual("FIRST(cola) IGNORE NULLS", ignore_nulls.sql())
def test_grouping_id(self): def test_grouping_id(self):
col_str = SF.grouping_id("cola", "colb") col_str = SF.grouping_id("cola", "colb")
@ -562,7 +562,7 @@ class TestFunctions(unittest.TestCase):
col = SF.last(SF.col("cola")) col = SF.last(SF.col("cola"))
self.assertEqual("LAST(cola)", col.sql()) self.assertEqual("LAST(cola)", col.sql())
ignore_nulls = SF.last("cola", True) ignore_nulls = SF.last("cola", True)
self.assertEqual("LAST(cola, TRUE)", ignore_nulls.sql()) self.assertEqual("LAST(cola) IGNORE NULLS", ignore_nulls.sql())
def test_monotonically_increasing_id(self): def test_monotonically_increasing_id(self):
col = SF.monotonically_increasing_id() col = SF.monotonically_increasing_id()
@ -713,8 +713,10 @@ class TestFunctions(unittest.TestCase):
self.assertEqual("NTH_VALUE(cola, 3)", col.sql()) self.assertEqual("NTH_VALUE(cola, 3)", col.sql())
col_no_offset = SF.nth_value("cola") col_no_offset = SF.nth_value("cola")
self.assertEqual("NTH_VALUE(cola)", col_no_offset.sql()) self.assertEqual("NTH_VALUE(cola)", col_no_offset.sql())
with self.assertRaises(NotImplementedError):
SF.nth_value("cola", ignoreNulls=True) self.assertEqual(
"NTH_VALUE(cola) IGNORE NULLS", SF.nth_value("cola", ignoreNulls=True).sql()
)
def test_ntile(self): def test_ntile(self):
col = SF.ntile(2) col = SF.ntile(2)

View file

@ -18,6 +18,64 @@ class TestBigQuery(Validator):
maxDiff = None maxDiff = None
def test_bigquery(self): def test_bigquery(self):
self.validate_all(
"SELECT SUM(x IGNORE NULLS) AS x",
read={
"bigquery": "SELECT SUM(x IGNORE NULLS) AS x",
"duckdb": "SELECT SUM(x IGNORE NULLS) AS x",
"postgres": "SELECT SUM(x) IGNORE NULLS AS x",
"spark": "SELECT SUM(x) IGNORE NULLS AS x",
"snowflake": "SELECT SUM(x) IGNORE NULLS AS x",
},
write={
"bigquery": "SELECT SUM(x IGNORE NULLS) AS x",
"duckdb": "SELECT SUM(x IGNORE NULLS) AS x",
"postgres": "SELECT SUM(x) IGNORE NULLS AS x",
"spark": "SELECT SUM(x) IGNORE NULLS AS x",
"snowflake": "SELECT SUM(x) IGNORE NULLS AS x",
},
)
self.validate_all(
"SELECT SUM(x RESPECT NULLS) AS x",
read={
"bigquery": "SELECT SUM(x RESPECT NULLS) AS x",
"duckdb": "SELECT SUM(x RESPECT NULLS) AS x",
"postgres": "SELECT SUM(x) RESPECT NULLS AS x",
"spark": "SELECT SUM(x) RESPECT NULLS AS x",
"snowflake": "SELECT SUM(x) RESPECT NULLS AS x",
},
write={
"bigquery": "SELECT SUM(x RESPECT NULLS) AS x",
"duckdb": "SELECT SUM(x RESPECT NULLS) AS x",
"postgres": "SELECT SUM(x) RESPECT NULLS AS x",
"spark": "SELECT SUM(x) RESPECT NULLS AS x",
"snowflake": "SELECT SUM(x) RESPECT NULLS AS x",
},
)
self.validate_all(
"SELECT PERCENTILE_CONT(x, 0.5 RESPECT NULLS) OVER ()",
write={
"duckdb": "SELECT QUANTILE_CONT(x, 0.5 RESPECT NULLS) OVER ()",
"spark": "SELECT PERCENTILE_CONT(x, 0.5) RESPECT NULLS OVER ()",
},
)
self.validate_all(
"SELECT ARRAY_AGG(DISTINCT x IGNORE NULLS ORDER BY a, b DESC LIMIT 10) AS x",
write={
"duckdb": "SELECT ARRAY_AGG(DISTINCT x ORDER BY a NULLS FIRST, b DESC LIMIT 10 IGNORE NULLS) AS x",
"spark": "SELECT COLLECT_LIST(DISTINCT x ORDER BY a, b DESC LIMIT 10) IGNORE NULLS AS x",
},
)
self.validate_all(
"SELECT ARRAY_AGG(DISTINCT x IGNORE NULLS ORDER BY a, b DESC LIMIT 1, 10) AS x",
write={
"duckdb": "SELECT ARRAY_AGG(DISTINCT x ORDER BY a NULLS FIRST, b DESC LIMIT 1, 10 IGNORE NULLS) AS x",
"spark": "SELECT COLLECT_LIST(DISTINCT x ORDER BY a, b DESC LIMIT 1, 10) IGNORE NULLS AS x",
},
)
self.validate_identity("SELECT COUNT(x RESPECT NULLS)")
self.validate_identity("SELECT LAST_VALUE(x IGNORE NULLS) OVER y AS x")
self.validate_identity( self.validate_identity(
"create or replace view test (tenant_id OPTIONS(description='Test description on table creation')) select 1 as tenant_id, 1 as customer_id;", "create or replace view test (tenant_id OPTIONS(description='Test description on table creation')) select 1 as tenant_id, 1 as customer_id;",
"CREATE OR REPLACE VIEW test (tenant_id OPTIONS (description='Test description on table creation')) AS SELECT 1 AS tenant_id, 1 AS customer_id", "CREATE OR REPLACE VIEW test (tenant_id OPTIONS (description='Test description on table creation')) AS SELECT 1 AS tenant_id, 1 AS customer_id",
@ -358,10 +416,25 @@ class TestBigQuery(Validator):
"SELECT TIMESTAMP_DIFF(TIMESTAMP_SECONDS(60), TIMESTAMP_SECONDS(0), minute)", "SELECT TIMESTAMP_DIFF(TIMESTAMP_SECONDS(60), TIMESTAMP_SECONDS(0), minute)",
write={ write={
"bigquery": "SELECT TIMESTAMP_DIFF(TIMESTAMP_SECONDS(60), TIMESTAMP_SECONDS(0), MINUTE)", "bigquery": "SELECT TIMESTAMP_DIFF(TIMESTAMP_SECONDS(60), TIMESTAMP_SECONDS(0), MINUTE)",
"databricks": "SELECT TIMESTAMPDIFF(MINUTE, CAST(FROM_UNIXTIME(0) AS TIMESTAMP), CAST(FROM_UNIXTIME(60) AS TIMESTAMP))",
"duckdb": "SELECT DATE_DIFF('MINUTE', TO_TIMESTAMP(0), TO_TIMESTAMP(60))", "duckdb": "SELECT DATE_DIFF('MINUTE', TO_TIMESTAMP(0), TO_TIMESTAMP(60))",
"snowflake": "SELECT TIMESTAMPDIFF(MINUTE, TO_TIMESTAMP(0), TO_TIMESTAMP(60))", "snowflake": "SELECT TIMESTAMPDIFF(MINUTE, TO_TIMESTAMP(0), TO_TIMESTAMP(60))",
}, },
) )
self.validate_all(
"TIMESTAMP_DIFF(a, b, MONTH)",
read={
"bigquery": "TIMESTAMP_DIFF(a, b, month)",
"databricks": "TIMESTAMPDIFF(month, b, a)",
"mysql": "TIMESTAMPDIFF(month, b, a)",
},
write={
"databricks": "TIMESTAMPDIFF(MONTH, b, a)",
"mysql": "TIMESTAMPDIFF(MONTH, b, a)",
"snowflake": "TIMESTAMPDIFF(MONTH, b, a)",
},
)
self.validate_all( self.validate_all(
"SELECT TIMESTAMP_MICROS(x)", "SELECT TIMESTAMP_MICROS(x)",
read={ read={
@ -419,34 +492,42 @@ class TestBigQuery(Validator):
"snowflake": "CREATE OR REPLACE TABLE a.b.c CLONE a.b.d", "snowflake": "CREATE OR REPLACE TABLE a.b.c CLONE a.b.d",
}, },
) )
self.validate_all( (
"SELECT DATETIME_DIFF('2023-01-01T00:00:00', '2023-01-01T05:00:00', MILLISECOND)", self.validate_all(
write={ "SELECT DATETIME_DIFF('2023-01-01T00:00:00', '2023-01-01T05:00:00', MILLISECOND)",
"bigquery": "SELECT DATETIME_DIFF('2023-01-01T00:00:00', '2023-01-01T05:00:00', MILLISECOND)", write={
"databricks": "SELECT TIMESTAMPDIFF(MILLISECOND, '2023-01-01T05:00:00', '2023-01-01T00:00:00')", "bigquery": "SELECT DATETIME_DIFF('2023-01-01T00:00:00', '2023-01-01T05:00:00', MILLISECOND)",
}, "databricks": "SELECT TIMESTAMPDIFF(MILLISECOND, '2023-01-01T05:00:00', '2023-01-01T00:00:00')",
), },
self.validate_all( ),
"SELECT DATETIME_ADD('2023-01-01T00:00:00', INTERVAL 1 MILLISECOND)", )
write={ (
"bigquery": "SELECT DATETIME_ADD('2023-01-01T00:00:00', INTERVAL 1 MILLISECOND)", self.validate_all(
"databricks": "SELECT TIMESTAMPADD(MILLISECOND, 1, '2023-01-01T00:00:00')", "SELECT DATETIME_ADD('2023-01-01T00:00:00', INTERVAL 1 MILLISECOND)",
}, write={
), "bigquery": "SELECT DATETIME_ADD('2023-01-01T00:00:00', INTERVAL 1 MILLISECOND)",
self.validate_all( "databricks": "SELECT TIMESTAMPADD(MILLISECOND, 1, '2023-01-01T00:00:00')",
"SELECT DATETIME_SUB('2023-01-01T00:00:00', INTERVAL 1 MILLISECOND)", },
write={ ),
"bigquery": "SELECT DATETIME_SUB('2023-01-01T00:00:00', INTERVAL 1 MILLISECOND)", )
"databricks": "SELECT TIMESTAMPADD(MILLISECOND, 1 * -1, '2023-01-01T00:00:00')", (
}, self.validate_all(
), "SELECT DATETIME_SUB('2023-01-01T00:00:00', INTERVAL 1 MILLISECOND)",
self.validate_all( write={
"SELECT DATETIME_TRUNC('2023-01-01T01:01:01', HOUR)", "bigquery": "SELECT DATETIME_SUB('2023-01-01T00:00:00', INTERVAL 1 MILLISECOND)",
write={ "databricks": "SELECT TIMESTAMPADD(MILLISECOND, 1 * -1, '2023-01-01T00:00:00')",
"bigquery": "SELECT DATETIME_TRUNC('2023-01-01T01:01:01', HOUR)", },
"databricks": "SELECT DATE_TRUNC('HOUR', '2023-01-01T01:01:01')", ),
}, )
), (
self.validate_all(
"SELECT DATETIME_TRUNC('2023-01-01T01:01:01', HOUR)",
write={
"bigquery": "SELECT DATETIME_TRUNC('2023-01-01T01:01:01', HOUR)",
"databricks": "SELECT DATE_TRUNC('HOUR', '2023-01-01T01:01:01')",
},
),
)
self.validate_all("LEAST(x, y)", read={"sqlite": "MIN(x, y)"}) self.validate_all("LEAST(x, y)", read={"sqlite": "MIN(x, y)"})
self.validate_all("CAST(x AS CHAR)", write={"bigquery": "CAST(x AS STRING)"}) self.validate_all("CAST(x AS CHAR)", write={"bigquery": "CAST(x AS STRING)"})
self.validate_all("CAST(x AS NCHAR)", write={"bigquery": "CAST(x AS STRING)"}) self.validate_all("CAST(x AS NCHAR)", write={"bigquery": "CAST(x AS STRING)"})

View file

@ -74,6 +74,10 @@ class TestClickhouse(Validator):
self.validate_identity("CAST(x AS DATETIME)") self.validate_identity("CAST(x AS DATETIME)")
self.validate_identity("CAST(x as MEDIUMINT)", "CAST(x AS Int32)") self.validate_identity("CAST(x as MEDIUMINT)", "CAST(x AS Int32)")
self.validate_identity("SELECT arrayJoin([1, 2, 3] AS src) AS dst, 'Hello', src") self.validate_identity("SELECT arrayJoin([1, 2, 3] AS src) AS dst, 'Hello', src")
self.validate_identity("""SELECT JSONExtractString('{"x": {"y": 1}}', 'x', 'y')""")
self.validate_identity(
"""SELECT JSONExtractString('{"a": "hello", "b": [-100, 200.0, 300]}', 'a')"""
)
self.validate_identity( self.validate_identity(
"ATTACH DATABASE DEFAULT ENGINE = ORDINARY", check_command_warning=True "ATTACH DATABASE DEFAULT ENGINE = ORDINARY", check_command_warning=True
) )

View file

@ -378,6 +378,31 @@ class TestDialect(Validator):
read={"postgres": "INET '127.0.0.1/32'"}, read={"postgres": "INET '127.0.0.1/32'"},
) )
def test_ddl(self):
self.validate_all(
"CREATE TABLE a LIKE b",
write={
"": "CREATE TABLE a LIKE b",
"bigquery": "CREATE TABLE a LIKE b",
"clickhouse": "CREATE TABLE a AS b",
"databricks": "CREATE TABLE a LIKE b",
"doris": "CREATE TABLE a LIKE b",
"drill": "CREATE TABLE a AS SELECT * FROM b LIMIT 0",
"duckdb": "CREATE TABLE a AS SELECT * FROM b LIMIT 0",
"hive": "CREATE TABLE a LIKE b",
"mysql": "CREATE TABLE a LIKE b",
"oracle": "CREATE TABLE a LIKE b",
"postgres": "CREATE TABLE a (LIKE b)",
"presto": "CREATE TABLE a (LIKE b)",
"redshift": "CREATE TABLE a (LIKE b)",
"snowflake": "CREATE TABLE a LIKE b",
"spark": "CREATE TABLE a LIKE b",
"sqlite": "CREATE TABLE a AS SELECT * FROM b LIMIT 0",
"trino": "CREATE TABLE a (LIKE b)",
"tsql": "SELECT TOP 0 * INTO a FROM b AS temp",
},
)
def test_heredoc_strings(self): def test_heredoc_strings(self):
for dialect in ("clickhouse", "postgres", "redshift"): for dialect in ("clickhouse", "postgres", "redshift"):
# Invalid matching tag # Invalid matching tag
@ -1097,61 +1122,173 @@ class TestDialect(Validator):
def test_json(self): def test_json(self):
self.validate_all( self.validate_all(
"JSON_EXTRACT(x, 'y')", """JSON_EXTRACT(x, '$["a b"]')""",
write={
"": """JSON_EXTRACT(x, '$["a b"]')""",
"bigquery": """JSON_EXTRACT(x, '$[\\'a b\\']')""",
"clickhouse": "JSONExtractString(x, 'a b')",
"duckdb": """x -> '$."a b"'""",
"mysql": """JSON_EXTRACT(x, '$."a b"')""",
"postgres": "JSON_EXTRACT_PATH(x, 'a b')",
"presto": """JSON_EXTRACT(x, '$["a b"]')""",
"redshift": "JSON_EXTRACT_PATH_TEXT(x, 'a b')",
"snowflake": """GET_PATH(x, '["a b"]')""",
"spark": """GET_JSON_OBJECT(x, '$[\\'a b\\']')""",
"sqlite": """x -> '$."a b"'""",
"trino": """JSON_EXTRACT(x, '$["a b"]')""",
"tsql": """ISNULL(JSON_QUERY(x, '$."a b"'), JSON_VALUE(x, '$."a b"'))""",
},
)
self.validate_all(
"JSON_EXTRACT(x, '$.y')",
read={ read={
"mysql": "JSON_EXTRACT(x, 'y')", "bigquery": "JSON_EXTRACT(x, '$.y')",
"duckdb": "x -> 'y'",
"doris": "x -> '$.y'",
"mysql": "JSON_EXTRACT(x, '$.y')",
"postgres": "x->'y'", "postgres": "x->'y'",
"presto": "JSON_EXTRACT(x, 'y')", "presto": "JSON_EXTRACT(x, '$.y')",
"starrocks": "x -> 'y'", "snowflake": "GET_PATH(x, 'y')",
"doris": "x -> 'y'", "sqlite": "x -> '$.y'",
"starrocks": "x -> '$.y'",
}, },
write={ write={
"mysql": "JSON_EXTRACT(x, 'y')", "bigquery": "JSON_EXTRACT(x, '$.y')",
"oracle": "JSON_EXTRACT(x, 'y')", "clickhouse": "JSONExtractString(x, 'y')",
"postgres": "x -> 'y'", "doris": "x -> '$.y'",
"presto": "JSON_EXTRACT(x, 'y')", "duckdb": "x -> '$.y'",
"starrocks": "x -> 'y'", "mysql": "JSON_EXTRACT(x, '$.y')",
"doris": "x -> 'y'", "oracle": "JSON_EXTRACT(x, '$.y')",
"postgres": "JSON_EXTRACT_PATH(x, 'y')",
"presto": "JSON_EXTRACT(x, '$.y')",
"snowflake": "GET_PATH(x, 'y')",
"spark": "GET_JSON_OBJECT(x, '$.y')",
"sqlite": "x -> '$.y'",
"starrocks": "x -> '$.y'",
"tsql": "ISNULL(JSON_QUERY(x, '$.y'), JSON_VALUE(x, '$.y'))",
}, },
) )
self.validate_all( self.validate_all(
"JSON_EXTRACT_SCALAR(x, 'y')", "JSON_EXTRACT_SCALAR(x, '$.y')",
read={ read={
"bigquery": "JSON_EXTRACT_SCALAR(x, '$.y')",
"clickhouse": "JSONExtractString(x, 'y')",
"duckdb": "x ->> 'y'",
"postgres": "x ->> 'y'", "postgres": "x ->> 'y'",
"presto": "JSON_EXTRACT_SCALAR(x, 'y')", "presto": "JSON_EXTRACT_SCALAR(x, '$.y')",
"redshift": "JSON_EXTRACT_PATH_TEXT(x, 'y')",
"spark": "GET_JSON_OBJECT(x, '$.y')",
"snowflake": "JSON_EXTRACT_PATH_TEXT(x, 'y')",
"sqlite": "x ->> '$.y'",
}, },
write={ write={
"postgres": "x ->> 'y'", "bigquery": "JSON_EXTRACT_SCALAR(x, '$.y')",
"presto": "JSON_EXTRACT_SCALAR(x, 'y')", "clickhouse": "JSONExtractString(x, 'y')",
"duckdb": "x ->> '$.y'",
"postgres": "JSON_EXTRACT_PATH_TEXT(x, 'y')",
"presto": "JSON_EXTRACT_SCALAR(x, '$.y')",
"redshift": "JSON_EXTRACT_PATH_TEXT(x, 'y')",
"snowflake": "JSON_EXTRACT_PATH_TEXT(x, 'y')",
"spark": "GET_JSON_OBJECT(x, '$.y')",
"sqlite": "x ->> '$.y'",
"tsql": "ISNULL(JSON_QUERY(x, '$.y'), JSON_VALUE(x, '$.y'))",
}, },
) )
self.validate_all( self.validate_all(
"JSON_EXTRACT_SCALAR(stream_data, '$.data.results')", "JSON_EXTRACT(x, '$.y[0].z')",
read={ read={
"hive": "GET_JSON_OBJECT(stream_data, '$.data.results')", "bigquery": "JSON_EXTRACT(x, '$.y[0].z')",
"mysql": "stream_data ->> '$.data.results'", "duckdb": "x -> '$.y[0].z'",
"doris": "x -> '$.y[0].z'",
"mysql": "JSON_EXTRACT(x, '$.y[0].z')",
"presto": "JSON_EXTRACT(x, '$.y[0].z')",
"snowflake": "GET_PATH(x, 'y[0].z')",
"sqlite": "x -> '$.y[0].z'",
"starrocks": "x -> '$.y[0].z'",
}, },
write={ write={
"hive": "GET_JSON_OBJECT(stream_data, '$.data.results')", "bigquery": "JSON_EXTRACT(x, '$.y[0].z')",
"mysql": "stream_data ->> '$.data.results'", "clickhouse": "JSONExtractString(x, 'y', 1, 'z')",
"doris": "x -> '$.y[0].z'",
"duckdb": "x -> '$.y[0].z'",
"mysql": "JSON_EXTRACT(x, '$.y[0].z')",
"oracle": "JSON_EXTRACT(x, '$.y[0].z')",
"postgres": "JSON_EXTRACT_PATH(x, 'y', '0', 'z')",
"presto": "JSON_EXTRACT(x, '$.y[0].z')",
"redshift": "JSON_EXTRACT_PATH_TEXT(x, 'y', '0', 'z')",
"snowflake": "GET_PATH(x, 'y[0].z')",
"spark": "GET_JSON_OBJECT(x, '$.y[0].z')",
"sqlite": "x -> '$.y[0].z'",
"starrocks": "x -> '$.y[0].z'",
"tsql": "ISNULL(JSON_QUERY(x, '$.y[0].z'), JSON_VALUE(x, '$.y[0].z'))",
}, },
) )
self.validate_all( self.validate_all(
"JSONB_EXTRACT(x, 'y')", "JSON_EXTRACT_SCALAR(x, '$.y[0].z')",
read={ read={
"postgres": "x#>'y'", "bigquery": "JSON_EXTRACT_SCALAR(x, '$.y[0].z')",
"clickhouse": "JSONExtractString(x, 'y', 1, 'z')",
"duckdb": "x ->> '$.y[0].z'",
"presto": "JSON_EXTRACT_SCALAR(x, '$.y[0].z')",
"snowflake": "JSON_EXTRACT_PATH_TEXT(x, 'y[0].z')",
"spark": 'GET_JSON_OBJECT(x, "$.y[0].z")',
"sqlite": "x ->> '$.y[0].z'",
}, },
write={ write={
"postgres": "x #> 'y'", "bigquery": "JSON_EXTRACT_SCALAR(x, '$.y[0].z')",
"clickhouse": "JSONExtractString(x, 'y', 1, 'z')",
"duckdb": "x ->> '$.y[0].z'",
"postgres": "JSON_EXTRACT_PATH_TEXT(x, 'y', '0', 'z')",
"presto": "JSON_EXTRACT_SCALAR(x, '$.y[0].z')",
"redshift": "JSON_EXTRACT_PATH_TEXT(x, 'y', '0', 'z')",
"snowflake": "JSON_EXTRACT_PATH_TEXT(x, 'y[0].z')",
"spark": "GET_JSON_OBJECT(x, '$.y[0].z')",
"sqlite": "x ->> '$.y[0].z'",
"tsql": "ISNULL(JSON_QUERY(x, '$.y[0].z'), JSON_VALUE(x, '$.y[0].z'))",
}, },
) )
self.validate_all( self.validate_all(
"JSONB_EXTRACT_SCALAR(x, 'y')", "JSON_EXTRACT(x, '$.y[*]')",
read={
"postgres": "x#>>'y'",
},
write={ write={
"postgres": "x #>> 'y'", "bigquery": UnsupportedError,
"clickhouse": UnsupportedError,
"duckdb": "x -> '$.y[*]'",
"mysql": "JSON_EXTRACT(x, '$.y[*]')",
"postgres": UnsupportedError,
"presto": "JSON_EXTRACT(x, '$.y[*]')",
"redshift": UnsupportedError,
"snowflake": UnsupportedError,
"spark": "GET_JSON_OBJECT(x, '$.y[*]')",
"sqlite": UnsupportedError,
"tsql": UnsupportedError,
},
)
self.validate_all(
"JSON_EXTRACT(x, '$.y[*]')",
write={
"bigquery": "JSON_EXTRACT(x, '$.y')",
"clickhouse": "JSONExtractString(x, 'y')",
"postgres": "JSON_EXTRACT_PATH(x, 'y')",
"redshift": "JSON_EXTRACT_PATH_TEXT(x, 'y')",
"snowflake": "GET_PATH(x, 'y')",
"sqlite": "x -> '$.y'",
"tsql": "ISNULL(JSON_QUERY(x, '$.y'), JSON_VALUE(x, '$.y'))",
},
)
self.validate_all(
"JSON_EXTRACT(x, '$.y.*')",
write={
"bigquery": UnsupportedError,
"clickhouse": UnsupportedError,
"duckdb": "x -> '$.y.*'",
"mysql": "JSON_EXTRACT(x, '$.y.*')",
"postgres": UnsupportedError,
"presto": "JSON_EXTRACT(x, '$.y.*')",
"redshift": UnsupportedError,
"snowflake": UnsupportedError,
"spark": UnsupportedError,
"sqlite": UnsupportedError,
"tsql": UnsupportedError,
}, },
) )

View file

@ -41,6 +41,7 @@ class TestDuckDB(Validator):
) )
self.validate_identity("SELECT 1 WHERE x > $1") self.validate_identity("SELECT 1 WHERE x > $1")
self.validate_identity("SELECT 1 WHERE x > $name") self.validate_identity("SELECT 1 WHERE x > $name")
self.validate_identity("""SELECT '{"x": 1}' -> c FROM t""")
self.assertEqual( self.assertEqual(
parse_one("select * from t limit (select 5)").sql(dialect="duckdb"), parse_one("select * from t limit (select 5)").sql(dialect="duckdb"),
@ -89,18 +90,26 @@ class TestDuckDB(Validator):
}, },
) )
self.validate_identity("""SELECT '{"duck": [1, 2, 3]}' -> '$.duck[#-1]'""")
self.validate_all(
"""SELECT JSON_EXTRACT('{"duck": [1, 2, 3]}', '/duck/0')""",
write={
"": """SELECT JSON_EXTRACT('{"duck": [1, 2, 3]}', '/duck/0')""",
"duckdb": """SELECT '{"duck": [1, 2, 3]}' -> '/duck/0'""",
},
)
self.validate_all( self.validate_all(
"""SELECT JSON('{"fruit":"banana"}') -> 'fruit'""", """SELECT JSON('{"fruit":"banana"}') -> 'fruit'""",
write={ write={
"duckdb": """SELECT JSON('{"fruit":"banana"}') -> 'fruit'""", "duckdb": """SELECT JSON('{"fruit":"banana"}') -> '$.fruit'""",
"snowflake": """SELECT PARSE_JSON('{"fruit":"banana"}')['fruit']""", "snowflake": """SELECT GET_PATH(PARSE_JSON('{"fruit":"banana"}'), 'fruit')""",
}, },
) )
self.validate_all( self.validate_all(
"""SELECT JSON('{"fruit": {"foo": "banana"}}') -> 'fruit' -> 'foo'""", """SELECT JSON('{"fruit": {"foo": "banana"}}') -> 'fruit' -> 'foo'""",
write={ write={
"duckdb": """SELECT JSON('{"fruit": {"foo": "banana"}}') -> 'fruit' -> 'foo'""", "duckdb": """SELECT JSON('{"fruit": {"foo": "banana"}}') -> '$.fruit' -> '$.foo'""",
"snowflake": """SELECT PARSE_JSON('{"fruit": {"foo": "banana"}}')['fruit']['foo']""", "snowflake": """SELECT GET_PATH(GET_PATH(PARSE_JSON('{"fruit": {"foo": "banana"}}'), 'fruit'), 'foo')""",
}, },
) )
self.validate_all( self.validate_all(
@ -199,6 +208,27 @@ class TestDuckDB(Validator):
self.validate_identity("FROM x SELECT x UNION SELECT 1", "SELECT x FROM x UNION SELECT 1") self.validate_identity("FROM x SELECT x UNION SELECT 1", "SELECT x FROM x UNION SELECT 1")
self.validate_identity("FROM (FROM tbl)", "SELECT * FROM (SELECT * FROM tbl)") self.validate_identity("FROM (FROM tbl)", "SELECT * FROM (SELECT * FROM tbl)")
self.validate_identity("FROM tbl", "SELECT * FROM tbl") self.validate_identity("FROM tbl", "SELECT * FROM tbl")
self.validate_identity("x -> '$.family'")
self.validate_identity(
"""SELECT '{"foo": [1, 2, 3]}' -> 'foo' -> 0""",
"""SELECT '{"foo": [1, 2, 3]}' -> '$.foo' -> '$[0]'""",
)
self.validate_identity(
"JSON_EXTRACT(x, '$.family')",
"x -> '$.family'",
)
self.validate_identity(
"JSON_EXTRACT_PATH(x, '$.family')",
"x -> '$.family'",
)
self.validate_identity(
"JSON_EXTRACT_STRING(x, '$.family')",
"x ->> '$.family'",
)
self.validate_identity(
"JSON_EXTRACT_PATH_TEXT(x, '$.family')",
"x ->> '$.family'",
)
self.validate_identity( self.validate_identity(
"ATTACH DATABASE ':memory:' AS new_database", check_command_warning=True "ATTACH DATABASE ':memory:' AS new_database", check_command_warning=True
) )

Some files were not shown because too many files have changed in this diff Show more