1
0
Fork 0

Merging upstream version 26.10.1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-03-17 07:38:58 +01:00
parent f2e3d707cd
commit 273cfbc19c
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
66 changed files with 79349 additions and 76628 deletions

View file

@ -10,13 +10,14 @@ jobs:
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
cache: pip
- name: Create a virtual environment
run: |
python -m venv .venv
@ -28,8 +29,4 @@ jobs:
- name: Run checks (linter, code style, tests)
run: |
source ./.venv/bin/activate
if [[ ${{ matrix.python-version }} == "3.7" ]]; then
make test test-rs
else
make check
fi
make check

View file

@ -55,13 +55,13 @@ jobs:
- uses: actions/setup-python@v5
if: matrix.os == 'windows'
with:
python-version: '3.7'
python-version: '3.8'
architecture: ${{ matrix.python-architecture || 'x64' }}
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --out dist --interpreter 3.7 3.8 3.9 3.10 3.11 3.12 3.13
args: --release --out dist --interpreter 3.8 3.9 3.10 3.11 3.12 3.13
sccache: 'true'
manylinux: auto
working-directory: ./sqlglotrs
@ -122,7 +122,7 @@ jobs:
python -m venv .venv
source ./.venv/bin/activate
python -m pip install --upgrade pip
pip install setuptools wheel twine
pip install build twine
make install-dev
- name: Build and publish
env:
@ -130,7 +130,7 @@ jobs:
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
source ./.venv/bin/activate
python setup.py sdist bdist_wheel
python -m build
twine upload dist/*
- name: Update API docs
run: |

1
.gitignore vendored
View file

@ -106,6 +106,7 @@ celerybeat.pid
.venv
env/
venv/
venv*/
ENV/
env.bak/
venv.bak/

View file

@ -1,6 +1,110 @@
Changelog
=========
## [v26.10.0] - 2025-03-13
### :boom: BREAKING CHANGES
- due to [`c0bfcc6`](https://github.com/tobymao/sqlglot/commit/c0bfcc66b97ce667a1ead608c4fbbee69db633fa) - postgres case insesitive formats closes [#4860](https://github.com/tobymao/sqlglot/pull/4860) *(commit by [@tobymao](https://github.com/tobymao))*:
postgres case insesitive formats closes #4860
- due to [`6914684`](https://github.com/tobymao/sqlglot/commit/69146842d005ae0edecbd7f6f842f648ae0622e7) - duckdb defaults timestampntz closes [#4859](https://github.com/tobymao/sqlglot/pull/4859) *(commit by [@tobymao](https://github.com/tobymao))*:
duckdb defaults timestampntz closes #4859
- due to [`ceb1f02`](https://github.com/tobymao/sqlglot/commit/ceb1f026dd04926a6a210de9d16da4dffef4717c) - support TO_CHAR to duckdb STRFTIME *(PR [#4866](https://github.com/tobymao/sqlglot/pull/4866) by [@geooo109](https://github.com/geooo109))*:
support TO_CHAR to duckdb STRFTIME (#4866)
- due to [`d748e53`](https://github.com/tobymao/sqlglot/commit/d748e53f6a77196bef6550b6d9fddf41076c01fa) - Introduce pyproject.toml and switch to packaging via build *(PR [#4865](https://github.com/tobymao/sqlglot/pull/4865) by [@erindru](https://github.com/erindru))*:
Introduce pyproject.toml and switch to packaging via build (#4865)
- due to [`038da09`](https://github.com/tobymao/sqlglot/commit/038da09f620cf057e4576b719c4e2f6712cbb804) - treat TABLE(...) as a UDTF *(PR [#4875](https://github.com/tobymao/sqlglot/pull/4875) by [@georgesittas](https://github.com/georgesittas))*:
treat TABLE(...) as a UDTF (#4875)
- due to [`92e479e`](https://github.com/tobymao/sqlglot/commit/92e479ea7d70efc4bdccd17cb12b719aec603830) - support STRUCT(*) and MAP(*) *(PR [#4876](https://github.com/tobymao/sqlglot/pull/4876) by [@geooo109](https://github.com/geooo109))*:
support STRUCT(*) and MAP(*) (#4876)
- due to [`87c94fe`](https://github.com/tobymao/sqlglot/commit/87c94fe91aa2a4bc2c255191d92aed450f3c7998) - turn off multi-arg coalesce simplification *(PR [#4877](https://github.com/tobymao/sqlglot/pull/4877) by [@georgesittas](https://github.com/georgesittas))*:
turn off multi-arg coalesce simplification (#4877)
### :sparkles: New Features
- [`54be278`](https://github.com/tobymao/sqlglot/commit/54be278361496367fb2f7d380634d3390879e58d) - **snowflake**: add support for HEX_DECODE_BINARY *(PR [#4855](https://github.com/tobymao/sqlglot/pull/4855) by [@sk-](https://github.com/sk-))*
- :arrow_lower_right: *addresses issue [#4852](https://github.com/tobymao/sqlglot/issues/4852) opened by [@sk-](https://github.com/sk-)*
- [`47959a9`](https://github.com/tobymao/sqlglot/commit/47959a94a4693cb904cfb2e50ce8cc8ca5c2e22f) - **duckdb**: add support for prefix aliases *(PR [#4869](https://github.com/tobymao/sqlglot/pull/4869) by [@georgesittas](https://github.com/georgesittas))*
### :bug: Bug Fixes
- [`e942391`](https://github.com/tobymao/sqlglot/commit/e942391edcefb40f927887450765b4365b0e980d) - spark zone offset closes [#4858](https://github.com/tobymao/sqlglot/pull/4858) *(commit by [@tobymao](https://github.com/tobymao))*
- [`c0bfcc6`](https://github.com/tobymao/sqlglot/commit/c0bfcc66b97ce667a1ead608c4fbbee69db633fa) - postgres case insesitive formats closes [#4860](https://github.com/tobymao/sqlglot/pull/4860) *(commit by [@tobymao](https://github.com/tobymao))*
- [`6914684`](https://github.com/tobymao/sqlglot/commit/69146842d005ae0edecbd7f6f842f648ae0622e7) - duckdb defaults timestampntz closes [#4859](https://github.com/tobymao/sqlglot/pull/4859) *(commit by [@tobymao](https://github.com/tobymao))*
- [`ceb1f02`](https://github.com/tobymao/sqlglot/commit/ceb1f026dd04926a6a210de9d16da4dffef4717c) - **snowflake**: support TO_CHAR to duckdb STRFTIME *(PR [#4866](https://github.com/tobymao/sqlglot/pull/4866) by [@geooo109](https://github.com/geooo109))*
- :arrow_lower_right: *fixes issue [#4857](https://github.com/tobymao/sqlglot/issues/4857) opened by [@asarama](https://github.com/asarama)*
- [`80466f1`](https://github.com/tobymao/sqlglot/commit/80466f16aa081860bc9e65f425924a0620840cdf) - expand util - align normalization behaviour with lazy and non-lazy source providers. *(PR [#4874](https://github.com/tobymao/sqlglot/pull/4874) by [@omerhadari](https://github.com/omerhadari))*
- [`038da09`](https://github.com/tobymao/sqlglot/commit/038da09f620cf057e4576b719c4e2f6712cbb804) - **snowflake**: treat TABLE(...) as a UDTF *(PR [#4875](https://github.com/tobymao/sqlglot/pull/4875) by [@georgesittas](https://github.com/georgesittas))*
- :arrow_lower_right: *fixes issue [#4861](https://github.com/tobymao/sqlglot/issues/4861) opened by [@mattijsdp](https://github.com/mattijsdp)*
- [`92e479e`](https://github.com/tobymao/sqlglot/commit/92e479ea7d70efc4bdccd17cb12b719aec603830) - **hive**: support STRUCT(*) and MAP(*) *(PR [#4876](https://github.com/tobymao/sqlglot/pull/4876) by [@geooo109](https://github.com/geooo109))*
- :arrow_lower_right: *fixes issue [#4871](https://github.com/tobymao/sqlglot/issues/4871) opened by [@btyuhas](https://github.com/btyuhas)*
- [`87c94fe`](https://github.com/tobymao/sqlglot/commit/87c94fe91aa2a4bc2c255191d92aed450f3c7998) - **redshift**: turn off multi-arg coalesce simplification *(PR [#4877](https://github.com/tobymao/sqlglot/pull/4877) by [@georgesittas](https://github.com/georgesittas))*
### :wrench: Chores
- [`d748e53`](https://github.com/tobymao/sqlglot/commit/d748e53f6a77196bef6550b6d9fddf41076c01fa) - Introduce pyproject.toml and switch to packaging via build *(PR [#4865](https://github.com/tobymao/sqlglot/pull/4865) by [@erindru](https://github.com/erindru))*
## [v26.9.0] - 2025-03-07
### :boom: BREAKING CHANGES
- due to [`6a3973b`](https://github.com/tobymao/sqlglot/commit/6a3973b7da639a19634bc352ea76f75735114c38) - Refactor exp.GroupConcat generation *(PR [#4823](https://github.com/tobymao/sqlglot/pull/4823) by [@VaggelisD](https://github.com/VaggelisD))*:
Refactor exp.GroupConcat generation (#4823)
- due to [`813d2ad`](https://github.com/tobymao/sqlglot/commit/813d2ada7afd653b2aaff75cbddd7f011750f861) - use _parse_table_parts for udf parsing *(PR [#4829](https://github.com/tobymao/sqlglot/pull/4829) by [@geooo109](https://github.com/geooo109))*:
use _parse_table_parts for udf parsing (#4829)
- due to [`7cdbad6`](https://github.com/tobymao/sqlglot/commit/7cdbad688cad7e7ce40df99802e93deb6a4d7abf) - add initial support for PUT statements *(PR [#4818](https://github.com/tobymao/sqlglot/pull/4818) by [@whummer](https://github.com/whummer))*:
add initial support for PUT statements (#4818)
- due to [`8c0a6be`](https://github.com/tobymao/sqlglot/commit/8c0a6bec6e38f3f6ce9a90b6a9b6457de70c7228) - BLOB transpilation *(PR [#4844](https://github.com/tobymao/sqlglot/pull/4844) by [@geooo109](https://github.com/geooo109))*:
BLOB transpilation (#4844)
### :sparkles: New Features
- [`7e8975e`](https://github.com/tobymao/sqlglot/commit/7e8975efce0af350142f8fb437cf46dd46f2b8d9) - **oracle**: add FORCE property *(PR [#4828](https://github.com/tobymao/sqlglot/pull/4828) by [@geooo109](https://github.com/geooo109))*
- :arrow_lower_right: *addresses issue [#4826](https://github.com/tobymao/sqlglot/issues/4826) opened by [@Duchyna1](https://github.com/Duchyna1)*
- [`7cdbad6`](https://github.com/tobymao/sqlglot/commit/7cdbad688cad7e7ce40df99802e93deb6a4d7abf) - **snowflake**: add initial support for PUT statements *(PR [#4818](https://github.com/tobymao/sqlglot/pull/4818) by [@whummer](https://github.com/whummer))*
- :arrow_lower_right: *addresses issue [#4813](https://github.com/tobymao/sqlglot/issues/4813) opened by [@whummer](https://github.com/whummer)*
- [`f4d1a1f`](https://github.com/tobymao/sqlglot/commit/f4d1a1f4d8104b2efd56f568ca99c7e768466d19) - **hive**: add support for STORED BY syntax for storage handlers *(PR [#4832](https://github.com/tobymao/sqlglot/pull/4832) by [@tsamaras](https://github.com/tsamaras))*
- [`b7a0df1`](https://github.com/tobymao/sqlglot/commit/b7a0df1b9a9cff2cd57db77ac0095c189b9d67ab) - **parser**: Support trailing commas after from *(PR [#4854](https://github.com/tobymao/sqlglot/pull/4854) by [@omerhadari](https://github.com/omerhadari))*
### :bug: Bug Fixes
- [`6a3973b`](https://github.com/tobymao/sqlglot/commit/6a3973b7da639a19634bc352ea76f75735114c38) - **duckdb, snowflake**: Refactor exp.GroupConcat generation *(PR [#4823](https://github.com/tobymao/sqlglot/pull/4823) by [@VaggelisD](https://github.com/VaggelisD))*
- :arrow_lower_right: *fixes issue [#4821](https://github.com/tobymao/sqlglot/issues/4821) opened by [@asarama](https://github.com/asarama)*
- [`08eb7f2`](https://github.com/tobymao/sqlglot/commit/08eb7f2032957c2fe3119963f344538b90d8f631) - **snowflake**: clean up PUT implementation *(PR [#4830](https://github.com/tobymao/sqlglot/pull/4830) by [@georgesittas](https://github.com/georgesittas))*
- [`adf2fef`](https://github.com/tobymao/sqlglot/commit/adf2fef27dc341508c3b9c710da0f835277094a1) - **mysql**: Support for USING BTREE/HASH in PK *(PR [#4837](https://github.com/tobymao/sqlglot/pull/4837) by [@VaggelisD](https://github.com/VaggelisD))*
- :arrow_lower_right: *fixes issue [#4833](https://github.com/tobymao/sqlglot/issues/4833) opened by [@Gohoy](https://github.com/Gohoy)*
- [`8c0a6be`](https://github.com/tobymao/sqlglot/commit/8c0a6bec6e38f3f6ce9a90b6a9b6457de70c7228) - **mysql**: BLOB transpilation *(PR [#4844](https://github.com/tobymao/sqlglot/pull/4844) by [@geooo109](https://github.com/geooo109))*
- :arrow_lower_right: *fixes issue [#4839](https://github.com/tobymao/sqlglot/issues/4839) opened by [@Gohoy](https://github.com/Gohoy)*
- [`0cb7a71`](https://github.com/tobymao/sqlglot/commit/0cb7a719de33ab1f6cfedf0833df7c79324b21f9) - **postgres**: Fix arrow extraction for string keys representing numbers *(PR [#4842](https://github.com/tobymao/sqlglot/pull/4842) by [@VaggelisD](https://github.com/VaggelisD))*
- :arrow_lower_right: *fixes issue [#4840](https://github.com/tobymao/sqlglot/issues/4840) opened by [@superkashyap](https://github.com/superkashyap)*
- [`2e223cb`](https://github.com/tobymao/sqlglot/commit/2e223cb3e0bc946b8aa97e115e4c0dc02e58d1c9) - **parser**: properly parse qualified columns when parsing "columns ops" *(PR [#4847](https://github.com/tobymao/sqlglot/pull/4847) by [@georgesittas](https://github.com/georgesittas))*
- :arrow_lower_right: *fixes issue [#4845](https://github.com/tobymao/sqlglot/issues/4845) opened by [@maudlel](https://github.com/maudlel)*
### :recycle: Refactors
- [`813d2ad`](https://github.com/tobymao/sqlglot/commit/813d2ada7afd653b2aaff75cbddd7f011750f861) - use _parse_table_parts for udf parsing *(PR [#4829](https://github.com/tobymao/sqlglot/pull/4829) by [@geooo109](https://github.com/geooo109))*
### :wrench: Chores
- [`e4fd354`](https://github.com/tobymao/sqlglot/commit/e4fd354c8fb55752cb883eb3912950c17020a1df) - Simplify Hive's STORED BY property *(PR [#4838](https://github.com/tobymao/sqlglot/pull/4838) by [@VaggelisD](https://github.com/VaggelisD))*
- [`8115b58`](https://github.com/tobymao/sqlglot/commit/8115b5853e621423eb2697b7253b17ef709dbdf0) - (duckdb): treat auto-increment DDL property as unsupported *(PR [#4849](https://github.com/tobymao/sqlglot/pull/4849) by [@georgesittas](https://github.com/georgesittas))*
- :arrow_lower_right: *addresses issue [#4841](https://github.com/tobymao/sqlglot/issues/4841) opened by [@sk-](https://github.com/sk-)*
- [`b05dddb`](https://github.com/tobymao/sqlglot/commit/b05dddbe5a7d45dfebefc3e04cb95d8c4d9802e9) - fix pdoc deployment *(PR [#4856](https://github.com/tobymao/sqlglot/pull/4856) by [@georgesittas](https://github.com/georgesittas))*
- :arrow_lower_right: *addresses issue [#4853](https://github.com/tobymao/sqlglot/issues/4853) opened by [@tsamaras](https://github.com/tsamaras)*
## [v26.8.0] - 2025-03-03
### :boom: BREAKING CHANGES
- due to [`596b66f`](https://github.com/tobymao/sqlglot/commit/596b66fc289140109db8f689c6e84264d643a47a) - add support for and/2 and or/2 functions *(PR [#4806](https://github.com/tobymao/sqlglot/pull/4806) by [@georgesittas](https://github.com/georgesittas))*:
@ -6039,3 +6143,5 @@ Changelog
[v26.6.0]: https://github.com/tobymao/sqlglot/compare/v26.5.0...v26.6.0
[v26.7.0]: https://github.com/tobymao/sqlglot/compare/v26.6.0...v26.7.0
[v26.8.0]: https://github.com/tobymao/sqlglot/compare/v26.7.0...v26.8.0
[v26.9.0]: https://github.com/tobymao/sqlglot/compare/v26.8.0...v26.9.0
[v26.10.0]: https://github.com/tobymao/sqlglot/compare/v26.9.0...v26.10.0

File diff suppressed because one or more lines are too long

View file

@ -84,8 +84,8 @@
</span><span id="L-17"><a href="#L-17"><span class="linenos">17</span></a><span class="n">__version_tuple__</span><span class="p">:</span> <span class="n">VERSION_TUPLE</span>
</span><span id="L-18"><a href="#L-18"><span class="linenos">18</span></a><span class="n">version_tuple</span><span class="p">:</span> <span class="n">VERSION_TUPLE</span>
</span><span id="L-19"><a href="#L-19"><span class="linenos">19</span></a>
</span><span id="L-20"><a href="#L-20"><span class="linenos">20</span></a><span class="n">__version__</span> <span class="o">=</span> <span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;26.8.0&#39;</span>
</span><span id="L-21"><a href="#L-21"><span class="linenos">21</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">26</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</span><span id="L-20"><a href="#L-20"><span class="linenos">20</span></a><span class="n">__version__</span> <span class="o">=</span> <span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;26.10.0&#39;</span>
</span><span id="L-21"><a href="#L-21"><span class="linenos">21</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">26</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</span></pre></div>
@ -93,7 +93,7 @@
<section id="__version__">
<div class="attr variable">
<span class="name">__version__</span><span class="annotation">: str</span> =
<span class="default_value">&#39;26.8.0&#39;</span>
<span class="default_value">&#39;26.10.0&#39;</span>
</div>
@ -105,7 +105,7 @@
<section id="__version_tuple__">
<div class="attr variable">
<span class="name">__version_tuple__</span><span class="annotation">: object</span> =
<span class="default_value">(26, 8, 0)</span>
<span class="default_value">(26, 10, 0)</span>
</div>
@ -117,7 +117,7 @@
<section id="version">
<div class="attr variable">
<span class="name">version</span><span class="annotation">: str</span> =
<span class="default_value">&#39;26.8.0&#39;</span>
<span class="default_value">&#39;26.10.0&#39;</span>
</div>
@ -129,7 +129,7 @@
<section id="version_tuple">
<div class="attr variable">
<span class="name">version_tuple</span><span class="annotation">: object</span> =
<span class="default_value">(26, 8, 0)</span>
<span class="default_value">(26, 10, 0)</span>
</div>

View file

@ -32,6 +32,36 @@
</ul>
<h2>Submodules</h2>
<ul>
<li><a href="dialects/athena.html">athena</a></li>
<li><a href="dialects/bigquery.html">bigquery</a></li>
<li><a href="dialects/clickhouse.html">clickhouse</a></li>
<li><a href="dialects/databricks.html">databricks</a></li>
<li><a href="dialects/doris.html">doris</a></li>
<li><a href="dialects/drill.html">drill</a></li>
<li><a href="dialects/druid.html">druid</a></li>
<li><a href="dialects/duckdb.html">duckdb</a></li>
<li><a href="dialects/dune.html">dune</a></li>
<li><a href="dialects/hive.html">hive</a></li>
<li><a href="dialects/materialize.html">materialize</a></li>
<li><a href="dialects/mysql.html">mysql</a></li>
<li><a href="dialects/oracle.html">oracle</a></li>
<li><a href="dialects/postgres.html">postgres</a></li>
<li><a href="dialects/presto.html">presto</a></li>
<li><a href="dialects/prql.html">prql</a></li>
<li><a href="dialects/redshift.html">redshift</a></li>
<li><a href="dialects/risingwave.html">risingwave</a></li>
<li><a href="dialects/snowflake.html">snowflake</a></li>
<li><a href="dialects/spark.html">spark</a></li>
<li><a href="dialects/spark2.html">spark2</a></li>
<li><a href="dialects/sqlite.html">sqlite</a></li>
<li><a href="dialects/starrocks.html">starrocks</a></li>
<li><a href="dialects/tableau.html">tableau</a></li>
<li><a href="dialects/teradata.html">teradata</a></li>
<li><a href="dialects/trino.html">trino</a></li>
<li><a href="dialects/tsql.html">tsql</a></li>
</ul>
<h2>API Documentation</h2>
<ul class="memberlist">
@ -325,7 +355,7 @@ dialect implementations in order to understand how their various components can
<section id="Athena">
<div class="attr variable">
<span class="name">Athena</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234444173472&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374168101040&#39;&gt;</span>
</div>
@ -337,7 +367,7 @@ dialect implementations in order to understand how their various components can
<section id="BigQuery">
<div class="attr variable">
<span class="name">BigQuery</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234434573840&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374175098928&#39;&gt;</span>
</div>
@ -349,7 +379,7 @@ dialect implementations in order to understand how their various components can
<section id="ClickHouse">
<div class="attr variable">
<span class="name">ClickHouse</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234434570672&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374175096432&#39;&gt;</span>
</div>
@ -361,7 +391,7 @@ dialect implementations in order to understand how their various components can
<section id="Databricks">
<div class="attr variable">
<span class="name">Databricks</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234428888496&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374171297936&#39;&gt;</span>
</div>
@ -373,7 +403,7 @@ dialect implementations in order to understand how their various components can
<section id="Doris">
<div class="attr variable">
<span class="name">Doris</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234427959280&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374165470464&#39;&gt;</span>
</div>
@ -385,7 +415,7 @@ dialect implementations in order to understand how their various components can
<section id="Drill">
<div class="attr variable">
<span class="name">Drill</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234427969360&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374165462544&#39;&gt;</span>
</div>
@ -397,7 +427,7 @@ dialect implementations in order to understand how their various components can
<section id="Druid">
<div class="attr variable">
<span class="name">Druid</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234428366560&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374177410560&#39;&gt;</span>
</div>
@ -409,7 +439,7 @@ dialect implementations in order to understand how their various components can
<section id="DuckDB">
<div class="attr variable">
<span class="name">DuckDB</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234428356288&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374178503920&#39;&gt;</span>
</div>
@ -421,7 +451,7 @@ dialect implementations in order to understand how their various components can
<section id="Dune">
<div class="attr variable">
<span class="name">Dune</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234443818320&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374178278336&#39;&gt;</span>
</div>
@ -433,7 +463,7 @@ dialect implementations in order to understand how their various components can
<section id="Hive">
<div class="attr variable">
<span class="name">Hive</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234443819328&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374178270944&#39;&gt;</span>
</div>
@ -445,7 +475,7 @@ dialect implementations in order to understand how their various components can
<section id="Materialize">
<div class="attr variable">
<span class="name">Materialize</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234443765840&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374170434768&#39;&gt;</span>
</div>
@ -457,7 +487,7 @@ dialect implementations in order to understand how their various components can
<section id="MySQL">
<div class="attr variable">
<span class="name">MySQL</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234443756864&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374171265744&#39;&gt;</span>
</div>
@ -469,7 +499,7 @@ dialect implementations in order to understand how their various components can
<section id="Oracle">
<div class="attr variable">
<span class="name">Oracle</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234443761904&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374174224432&#39;&gt;</span>
</div>
@ -481,7 +511,7 @@ dialect implementations in order to understand how their various components can
<section id="Postgres">
<div class="attr variable">
<span class="name">Postgres</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234443680944&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374178654640&#39;&gt;</span>
</div>
@ -493,7 +523,7 @@ dialect implementations in order to understand how their various components can
<section id="Presto">
<div class="attr variable">
<span class="name">Presto</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234443675808&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374178120560&#39;&gt;</span>
</div>
@ -505,7 +535,7 @@ dialect implementations in order to understand how their various components can
<section id="PRQL">
<div class="attr variable">
<span class="name">PRQL</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234442518112&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374178123344&#39;&gt;</span>
</div>
@ -517,7 +547,7 @@ dialect implementations in order to understand how their various components can
<section id="Redshift">
<div class="attr variable">
<span class="name">Redshift</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234442511824&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374174402832&#39;&gt;</span>
</div>
@ -529,7 +559,7 @@ dialect implementations in order to understand how their various components can
<section id="RisingWave">
<div class="attr variable">
<span class="name">RisingWave</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234434918768&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374178167248&#39;&gt;</span>
</div>
@ -541,7 +571,7 @@ dialect implementations in order to understand how their various components can
<section id="Snowflake">
<div class="attr variable">
<span class="name">Snowflake</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234443372672&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374166107808&#39;&gt;</span>
</div>
@ -553,7 +583,7 @@ dialect implementations in order to understand how their various components can
<section id="Spark">
<div class="attr variable">
<span class="name">Spark</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234443373296&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374166109728&#39;&gt;</span>
</div>
@ -565,7 +595,7 @@ dialect implementations in order to understand how their various components can
<section id="Spark2">
<div class="attr variable">
<span class="name">Spark2</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234430652496&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374175510016&#39;&gt;</span>
</div>
@ -577,7 +607,7 @@ dialect implementations in order to understand how their various components can
<section id="SQLite">
<div class="attr variable">
<span class="name">SQLite</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234445453776&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374175508432&#39;&gt;</span>
</div>
@ -589,7 +619,7 @@ dialect implementations in order to understand how their various components can
<section id="StarRocks">
<div class="attr variable">
<span class="name">StarRocks</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234443357104&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374167923072&#39;&gt;</span>
</div>
@ -601,7 +631,7 @@ dialect implementations in order to understand how their various components can
<section id="Tableau">
<div class="attr variable">
<span class="name">Tableau</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234443351056&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374167915392&#39;&gt;</span>
</div>
@ -613,7 +643,7 @@ dialect implementations in order to understand how their various components can
<section id="Teradata">
<div class="attr variable">
<span class="name">Teradata</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234428938992&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374163754768&#39;&gt;</span>
</div>
@ -625,7 +655,7 @@ dialect implementations in order to understand how their various components can
<section id="Trino">
<div class="attr variable">
<span class="name">Trino</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234443896096&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374163762640&#39;&gt;</span>
</div>
@ -637,7 +667,7 @@ dialect implementations in order to understand how their various components can
<section id="TSQL">
<div class="attr variable">
<span class="name">TSQL</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234443893456&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374163787008&#39;&gt;</span>
</div>
@ -649,7 +679,7 @@ dialect implementations in order to understand how their various components can
<section id="Dialect">
<div class="attr variable">
<span class="name">Dialect</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234426619200&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374163794928&#39;&gt;</span>
</div>
@ -661,7 +691,7 @@ dialect implementations in order to understand how their various components can
<section id="Dialects">
<div class="attr variable">
<span class="name">Dialects</span> =
<span class="default_value">&lt;MagicMock id=&#39;140234426627120&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140374163802912&#39;&gt;</span>
</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 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

@ -178,7 +178,7 @@
<div class="attr class">
<span class="def">class</span>
<span class="name">Druid</span><wbr>(<span class="base"><a href="dialect.html#Dialect">sqlglot.dialects.dialect.Dialect</a></span>):
<span class="name">Druid</span><wbr>(<span class="base">sqlglot.dialects.dialect.Dialect</span>):
<label class="view-source-button" for="Druid-view-source"><span>View Source</span></label>
@ -500,77 +500,6 @@
</div>
<div class="inherited">
<h5>Inherited Members</h5>
<dl>
<div><dt><a href="dialect.html#Dialect">sqlglot.dialects.dialect.Dialect</a></dt>
<dd id="Druid.__init__" class="function"><a href="dialect.html#Dialect.__init__">Dialect</a></dd>
<dd id="Druid.INDEX_OFFSET" class="variable"><a href="dialect.html#Dialect.INDEX_OFFSET">INDEX_OFFSET</a></dd>
<dd id="Druid.WEEK_OFFSET" class="variable"><a href="dialect.html#Dialect.WEEK_OFFSET">WEEK_OFFSET</a></dd>
<dd id="Druid.UNNEST_COLUMN_ONLY" class="variable"><a href="dialect.html#Dialect.UNNEST_COLUMN_ONLY">UNNEST_COLUMN_ONLY</a></dd>
<dd id="Druid.ALIAS_POST_TABLESAMPLE" class="variable"><a href="dialect.html#Dialect.ALIAS_POST_TABLESAMPLE">ALIAS_POST_TABLESAMPLE</a></dd>
<dd id="Druid.TABLESAMPLE_SIZE_IS_PERCENT" class="variable"><a href="dialect.html#Dialect.TABLESAMPLE_SIZE_IS_PERCENT">TABLESAMPLE_SIZE_IS_PERCENT</a></dd>
<dd id="Druid.NORMALIZATION_STRATEGY" class="variable"><a href="dialect.html#Dialect.NORMALIZATION_STRATEGY">NORMALIZATION_STRATEGY</a></dd>
<dd id="Druid.IDENTIFIERS_CAN_START_WITH_DIGIT" class="variable"><a href="dialect.html#Dialect.IDENTIFIERS_CAN_START_WITH_DIGIT">IDENTIFIERS_CAN_START_WITH_DIGIT</a></dd>
<dd id="Druid.DPIPE_IS_STRING_CONCAT" class="variable"><a href="dialect.html#Dialect.DPIPE_IS_STRING_CONCAT">DPIPE_IS_STRING_CONCAT</a></dd>
<dd id="Druid.STRICT_STRING_CONCAT" class="variable"><a href="dialect.html#Dialect.STRICT_STRING_CONCAT">STRICT_STRING_CONCAT</a></dd>
<dd id="Druid.SUPPORTS_USER_DEFINED_TYPES" class="variable"><a href="dialect.html#Dialect.SUPPORTS_USER_DEFINED_TYPES">SUPPORTS_USER_DEFINED_TYPES</a></dd>
<dd id="Druid.SUPPORTS_SEMI_ANTI_JOIN" class="variable"><a href="dialect.html#Dialect.SUPPORTS_SEMI_ANTI_JOIN">SUPPORTS_SEMI_ANTI_JOIN</a></dd>
<dd id="Druid.COPY_PARAMS_ARE_CSV" class="variable"><a href="dialect.html#Dialect.COPY_PARAMS_ARE_CSV">COPY_PARAMS_ARE_CSV</a></dd>
<dd id="Druid.NORMALIZE_FUNCTIONS" class="variable"><a href="dialect.html#Dialect.NORMALIZE_FUNCTIONS">NORMALIZE_FUNCTIONS</a></dd>
<dd id="Druid.PRESERVE_ORIGINAL_NAMES" class="variable"><a href="dialect.html#Dialect.PRESERVE_ORIGINAL_NAMES">PRESERVE_ORIGINAL_NAMES</a></dd>
<dd id="Druid.LOG_BASE_FIRST" class="variable"><a href="dialect.html#Dialect.LOG_BASE_FIRST">LOG_BASE_FIRST</a></dd>
<dd id="Druid.NULL_ORDERING" class="variable"><a href="dialect.html#Dialect.NULL_ORDERING">NULL_ORDERING</a></dd>
<dd id="Druid.TYPED_DIVISION" class="variable"><a href="dialect.html#Dialect.TYPED_DIVISION">TYPED_DIVISION</a></dd>
<dd id="Druid.SAFE_DIVISION" class="variable"><a href="dialect.html#Dialect.SAFE_DIVISION">SAFE_DIVISION</a></dd>
<dd id="Druid.CONCAT_COALESCE" class="variable"><a href="dialect.html#Dialect.CONCAT_COALESCE">CONCAT_COALESCE</a></dd>
<dd id="Druid.HEX_LOWERCASE" class="variable"><a href="dialect.html#Dialect.HEX_LOWERCASE">HEX_LOWERCASE</a></dd>
<dd id="Druid.DATE_FORMAT" class="variable"><a href="dialect.html#Dialect.DATE_FORMAT">DATE_FORMAT</a></dd>
<dd id="Druid.DATEINT_FORMAT" class="variable"><a href="dialect.html#Dialect.DATEINT_FORMAT">DATEINT_FORMAT</a></dd>
<dd id="Druid.TIME_FORMAT" class="variable"><a href="dialect.html#Dialect.TIME_FORMAT">TIME_FORMAT</a></dd>
<dd id="Druid.TIME_MAPPING" class="variable"><a href="dialect.html#Dialect.TIME_MAPPING">TIME_MAPPING</a></dd>
<dd id="Druid.FORMAT_MAPPING" class="variable"><a href="dialect.html#Dialect.FORMAT_MAPPING">FORMAT_MAPPING</a></dd>
<dd id="Druid.UNESCAPED_SEQUENCES" class="variable"><a href="dialect.html#Dialect.UNESCAPED_SEQUENCES">UNESCAPED_SEQUENCES</a></dd>
<dd id="Druid.PSEUDOCOLUMNS" class="variable"><a href="dialect.html#Dialect.PSEUDOCOLUMNS">PSEUDOCOLUMNS</a></dd>
<dd id="Druid.PREFER_CTE_ALIAS_COLUMN" class="variable"><a href="dialect.html#Dialect.PREFER_CTE_ALIAS_COLUMN">PREFER_CTE_ALIAS_COLUMN</a></dd>
<dd id="Druid.FORCE_EARLY_ALIAS_REF_EXPANSION" class="variable"><a href="dialect.html#Dialect.FORCE_EARLY_ALIAS_REF_EXPANSION">FORCE_EARLY_ALIAS_REF_EXPANSION</a></dd>
<dd id="Druid.EXPAND_ALIAS_REFS_EARLY_ONLY_IN_GROUP_BY" class="variable"><a href="dialect.html#Dialect.EXPAND_ALIAS_REFS_EARLY_ONLY_IN_GROUP_BY">EXPAND_ALIAS_REFS_EARLY_ONLY_IN_GROUP_BY</a></dd>
<dd id="Druid.SUPPORTS_ORDER_BY_ALL" class="variable"><a href="dialect.html#Dialect.SUPPORTS_ORDER_BY_ALL">SUPPORTS_ORDER_BY_ALL</a></dd>
<dd id="Druid.HAS_DISTINCT_ARRAY_CONSTRUCTORS" class="variable"><a href="dialect.html#Dialect.HAS_DISTINCT_ARRAY_CONSTRUCTORS">HAS_DISTINCT_ARRAY_CONSTRUCTORS</a></dd>
<dd id="Druid.SUPPORTS_FIXED_SIZE_ARRAYS" class="variable"><a href="dialect.html#Dialect.SUPPORTS_FIXED_SIZE_ARRAYS">SUPPORTS_FIXED_SIZE_ARRAYS</a></dd>
<dd id="Druid.STRICT_JSON_PATH_SYNTAX" class="variable"><a href="dialect.html#Dialect.STRICT_JSON_PATH_SYNTAX">STRICT_JSON_PATH_SYNTAX</a></dd>
<dd id="Druid.ON_CONDITION_EMPTY_BEFORE_ERROR" class="variable"><a href="dialect.html#Dialect.ON_CONDITION_EMPTY_BEFORE_ERROR">ON_CONDITION_EMPTY_BEFORE_ERROR</a></dd>
<dd id="Druid.ARRAY_AGG_INCLUDES_NULLS" class="variable"><a href="dialect.html#Dialect.ARRAY_AGG_INCLUDES_NULLS">ARRAY_AGG_INCLUDES_NULLS</a></dd>
<dd id="Druid.PROMOTE_TO_INFERRED_DATETIME_TYPE" class="variable"><a href="dialect.html#Dialect.PROMOTE_TO_INFERRED_DATETIME_TYPE">PROMOTE_TO_INFERRED_DATETIME_TYPE</a></dd>
<dd id="Druid.SUPPORTS_VALUES_DEFAULT" class="variable"><a href="dialect.html#Dialect.SUPPORTS_VALUES_DEFAULT">SUPPORTS_VALUES_DEFAULT</a></dd>
<dd id="Druid.NUMBERS_CAN_BE_UNDERSCORE_SEPARATED" class="variable"><a href="dialect.html#Dialect.NUMBERS_CAN_BE_UNDERSCORE_SEPARATED">NUMBERS_CAN_BE_UNDERSCORE_SEPARATED</a></dd>
<dd id="Druid.REGEXP_EXTRACT_DEFAULT_GROUP" class="variable"><a href="dialect.html#Dialect.REGEXP_EXTRACT_DEFAULT_GROUP">REGEXP_EXTRACT_DEFAULT_GROUP</a></dd>
<dd id="Druid.SET_OP_DISTINCT_BY_DEFAULT" class="variable"><a href="dialect.html#Dialect.SET_OP_DISTINCT_BY_DEFAULT">SET_OP_DISTINCT_BY_DEFAULT</a></dd>
<dd id="Druid.CREATABLE_KIND_MAPPING" class="variable"><a href="dialect.html#Dialect.CREATABLE_KIND_MAPPING">CREATABLE_KIND_MAPPING</a></dd>
<dd id="Druid.DATE_PART_MAPPING" class="variable"><a href="dialect.html#Dialect.DATE_PART_MAPPING">DATE_PART_MAPPING</a></dd>
<dd id="Druid.TYPE_TO_EXPRESSIONS" class="variable"><a href="dialect.html#Dialect.TYPE_TO_EXPRESSIONS">TYPE_TO_EXPRESSIONS</a></dd>
<dd id="Druid.ANNOTATORS" class="variable"><a href="dialect.html#Dialect.ANNOTATORS">ANNOTATORS</a></dd>
<dd id="Druid.get_or_raise" class="function"><a href="dialect.html#Dialect.get_or_raise">get_or_raise</a></dd>
<dd id="Druid.format_time" class="function"><a href="dialect.html#Dialect.format_time">format_time</a></dd>
<dd id="Druid.settings" class="variable"><a href="dialect.html#Dialect.settings">settings</a></dd>
<dd id="Druid.normalize_identifier" class="function"><a href="dialect.html#Dialect.normalize_identifier">normalize_identifier</a></dd>
<dd id="Druid.case_sensitive" class="function"><a href="dialect.html#Dialect.case_sensitive">case_sensitive</a></dd>
<dd id="Druid.can_identify" class="function"><a href="dialect.html#Dialect.can_identify">can_identify</a></dd>
<dd id="Druid.quote_identifier" class="function"><a href="dialect.html#Dialect.quote_identifier">quote_identifier</a></dd>
<dd id="Druid.to_json_path" class="function"><a href="dialect.html#Dialect.to_json_path">to_json_path</a></dd>
<dd id="Druid.parse" class="function"><a href="dialect.html#Dialect.parse">parse</a></dd>
<dd id="Druid.parse_into" class="function"><a href="dialect.html#Dialect.parse_into">parse_into</a></dd>
<dd id="Druid.generate" class="function"><a href="dialect.html#Dialect.generate">generate</a></dd>
<dd id="Druid.transpile" class="function"><a href="dialect.html#Dialect.transpile">transpile</a></dd>
<dd id="Druid.tokenize" class="function"><a href="dialect.html#Dialect.tokenize">tokenize</a></dd>
<dd id="Druid.tokenizer" class="variable"><a href="dialect.html#Dialect.tokenizer">tokenizer</a></dd>
<dd id="Druid.jsonpath_tokenizer" class="variable"><a href="dialect.html#Dialect.jsonpath_tokenizer">jsonpath_tokenizer</a></dd>
<dd id="Druid.parser" class="function"><a href="dialect.html#Dialect.parser">parser</a></dd>
<dd id="Druid.generator" class="function"><a href="dialect.html#Dialect.generator">generator</a></dd>
</div>
</dl>
</div>
</section>
<section id="Druid.Generator">
@ -641,7 +570,7 @@ Default: True</li>
<div class="attr variable">
<span class="name">TYPE_MAPPING</span> =
<input id="Druid.Generator.TYPE_MAPPING-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="Druid.Generator.TYPE_MAPPING-view-value"></label><span class="default_value">{&lt;Type.DATETIME2: &#39;DATETIME2&#39;&gt;: &#39;TIMESTAMP&#39;, &lt;Type.NCHAR: &#39;NCHAR&#39;&gt;: &#39;STRING&#39;, &lt;Type.NVARCHAR: &#39;NVARCHAR&#39;&gt;: &#39;STRING&#39;, &lt;Type.MEDIUMTEXT: &#39;MEDIUMTEXT&#39;&gt;: &#39;TEXT&#39;, &lt;Type.LONGTEXT: &#39;LONGTEXT&#39;&gt;: &#39;TEXT&#39;, &lt;Type.TINYTEXT: &#39;TINYTEXT&#39;&gt;: &#39;TEXT&#39;, &lt;Type.MEDIUMBLOB: &#39;MEDIUMBLOB&#39;&gt;: &#39;BLOB&#39;, &lt;Type.LONGBLOB: &#39;LONGBLOB&#39;&gt;: &#39;BLOB&#39;, &lt;Type.TINYBLOB: &#39;TINYBLOB&#39;&gt;: &#39;BLOB&#39;, &lt;Type.INET: &#39;INET&#39;&gt;: &#39;INET&#39;, &lt;Type.ROWVERSION: &#39;ROWVERSION&#39;&gt;: &#39;VARBINARY&#39;, &lt;Type.SMALLDATETIME: &#39;SMALLDATETIME&#39;&gt;: &#39;TIMESTAMP&#39;, &lt;Type.TEXT: &#39;TEXT&#39;&gt;: &#39;STRING&#39;, &lt;Type.UUID: &#39;UUID&#39;&gt;: &#39;STRING&#39;}</span>
<label class="view-value-button pdoc-button" for="Druid.Generator.TYPE_MAPPING-view-value"></label><span class="default_value">{&lt;Type.DATETIME2: &#39;DATETIME2&#39;&gt;: &#39;TIMESTAMP&#39;, &lt;Type.NCHAR: &#39;NCHAR&#39;&gt;: &#39;STRING&#39;, &lt;Type.NVARCHAR: &#39;NVARCHAR&#39;&gt;: &#39;STRING&#39;, &lt;Type.MEDIUMTEXT: &#39;MEDIUMTEXT&#39;&gt;: &#39;TEXT&#39;, &lt;Type.LONGTEXT: &#39;LONGTEXT&#39;&gt;: &#39;TEXT&#39;, &lt;Type.TINYTEXT: &#39;TINYTEXT&#39;&gt;: &#39;TEXT&#39;, &lt;Type.BLOB: &#39;BLOB&#39;&gt;: &#39;VARBINARY&#39;, &lt;Type.MEDIUMBLOB: &#39;MEDIUMBLOB&#39;&gt;: &#39;BLOB&#39;, &lt;Type.LONGBLOB: &#39;LONGBLOB&#39;&gt;: &#39;BLOB&#39;, &lt;Type.TINYBLOB: &#39;TINYBLOB&#39;&gt;: &#39;BLOB&#39;, &lt;Type.INET: &#39;INET&#39;&gt;: &#39;INET&#39;, &lt;Type.ROWVERSION: &#39;ROWVERSION&#39;&gt;: &#39;VARBINARY&#39;, &lt;Type.SMALLDATETIME: &#39;SMALLDATETIME&#39;&gt;: &#39;TIMESTAMP&#39;, &lt;Type.TEXT: &#39;TEXT&#39;&gt;: &#39;STRING&#39;, &lt;Type.UUID: &#39;UUID&#39;&gt;: &#39;STRING&#39;}</span>
</div>
@ -778,6 +707,7 @@ Default: True</li>
<dd id="Druid.Generator.SUPPORTS_UNIX_SECONDS" class="variable"><a href="../generator.html#Generator.SUPPORTS_UNIX_SECONDS">SUPPORTS_UNIX_SECONDS</a></dd>
<dd id="Druid.Generator.PARSE_JSON_NAME" class="variable"><a href="../generator.html#Generator.PARSE_JSON_NAME">PARSE_JSON_NAME</a></dd>
<dd id="Druid.Generator.ARRAY_SIZE_NAME" class="variable"><a href="../generator.html#Generator.ARRAY_SIZE_NAME">ARRAY_SIZE_NAME</a></dd>
<dd id="Druid.Generator.ALTER_SET_TYPE" class="variable"><a href="../generator.html#Generator.ALTER_SET_TYPE">ALTER_SET_TYPE</a></dd>
<dd id="Druid.Generator.ARRAY_SIZE_DIM_REQUIRED" class="variable"><a href="../generator.html#Generator.ARRAY_SIZE_DIM_REQUIRED">ARRAY_SIZE_DIM_REQUIRED</a></dd>
<dd id="Druid.Generator.TIME_PART_SINGULARS" class="variable"><a href="../generator.html#Generator.TIME_PART_SINGULARS">TIME_PART_SINGULARS</a></dd>
<dd id="Druid.Generator.TOKEN_MAPPING" class="variable"><a href="../generator.html#Generator.TOKEN_MAPPING">TOKEN_MAPPING</a></dd>
@ -858,6 +788,7 @@ Default: True</li>
<dd id="Druid.Generator.set_operation" class="function"><a href="../generator.html#Generator.set_operation">set_operation</a></dd>
<dd id="Druid.Generator.set_operations" class="function"><a href="../generator.html#Generator.set_operations">set_operations</a></dd>
<dd id="Druid.Generator.fetch_sql" class="function"><a href="../generator.html#Generator.fetch_sql">fetch_sql</a></dd>
<dd id="Druid.Generator.limitoptions_sql" class="function"><a href="../generator.html#Generator.limitoptions_sql">limitoptions_sql</a></dd>
<dd id="Druid.Generator.filter_sql" class="function"><a href="../generator.html#Generator.filter_sql">filter_sql</a></dd>
<dd id="Druid.Generator.hint_sql" class="function"><a href="../generator.html#Generator.hint_sql">hint_sql</a></dd>
<dd id="Druid.Generator.indexparameters_sql" class="function"><a href="../generator.html#Generator.indexparameters_sql">indexparameters_sql</a></dd>
@ -902,6 +833,7 @@ Default: True</li>
<dd id="Druid.Generator.historicaldata_sql" class="function"><a href="../generator.html#Generator.historicaldata_sql">historicaldata_sql</a></dd>
<dd id="Druid.Generator.table_parts" class="function"><a href="../generator.html#Generator.table_parts">table_parts</a></dd>
<dd id="Druid.Generator.table_sql" class="function"><a href="../generator.html#Generator.table_sql">table_sql</a></dd>
<dd id="Druid.Generator.tablefromrows_sql" class="function"><a href="../generator.html#Generator.tablefromrows_sql">tablefromrows_sql</a></dd>
<dd id="Druid.Generator.tablesample_sql" class="function"><a href="../generator.html#Generator.tablesample_sql">tablesample_sql</a></dd>
<dd id="Druid.Generator.pivot_sql" class="function"><a href="../generator.html#Generator.pivot_sql">pivot_sql</a></dd>
<dd id="Druid.Generator.version_sql" class="function"><a href="../generator.html#Generator.version_sql">version_sql</a></dd>
@ -1031,6 +963,7 @@ Default: True</li>
<dd id="Druid.Generator.commit_sql" class="function"><a href="../generator.html#Generator.commit_sql">commit_sql</a></dd>
<dd id="Druid.Generator.rollback_sql" class="function"><a href="../generator.html#Generator.rollback_sql">rollback_sql</a></dd>
<dd id="Druid.Generator.altercolumn_sql" class="function"><a href="../generator.html#Generator.altercolumn_sql">altercolumn_sql</a></dd>
<dd id="Druid.Generator.alterindex_sql" class="function"><a href="../generator.html#Generator.alterindex_sql">alterindex_sql</a></dd>
<dd id="Druid.Generator.alterdiststyle_sql" class="function"><a href="../generator.html#Generator.alterdiststyle_sql">alterdiststyle_sql</a></dd>
<dd id="Druid.Generator.altersortkey_sql" class="function"><a href="../generator.html#Generator.altersortkey_sql">altersortkey_sql</a></dd>
<dd id="Druid.Generator.alterrename_sql" class="function"><a href="../generator.html#Generator.alterrename_sql">alterrename_sql</a></dd>
@ -1073,6 +1006,7 @@ Default: True</li>
<dd id="Druid.Generator.slice_sql" class="function"><a href="../generator.html#Generator.slice_sql">slice_sql</a></dd>
<dd id="Druid.Generator.sub_sql" class="function"><a href="../generator.html#Generator.sub_sql">sub_sql</a></dd>
<dd id="Druid.Generator.trycast_sql" class="function"><a href="../generator.html#Generator.trycast_sql">trycast_sql</a></dd>
<dd id="Druid.Generator.jsoncast_sql" class="function"><a href="../generator.html#Generator.jsoncast_sql">jsoncast_sql</a></dd>
<dd id="Druid.Generator.try_sql" class="function"><a href="../generator.html#Generator.try_sql">try_sql</a></dd>
<dd id="Druid.Generator.log_sql" class="function"><a href="../generator.html#Generator.log_sql">log_sql</a></dd>
<dd id="Druid.Generator.use_sql" class="function"><a href="../generator.html#Generator.use_sql">use_sql</a></dd>
@ -1186,6 +1120,16 @@ Default: True</li>
<dd id="Druid.Generator.analyze_sql" class="function"><a href="../generator.html#Generator.analyze_sql">analyze_sql</a></dd>
<dd id="Druid.Generator.xmltable_sql" class="function"><a href="../generator.html#Generator.xmltable_sql">xmltable_sql</a></dd>
<dd id="Druid.Generator.xmlnamespace_sql" class="function"><a href="../generator.html#Generator.xmlnamespace_sql">xmlnamespace_sql</a></dd>
<dd id="Druid.Generator.export_sql" class="function"><a href="../generator.html#Generator.export_sql">export_sql</a></dd>
<dd id="Druid.Generator.declare_sql" class="function"><a href="../generator.html#Generator.declare_sql">declare_sql</a></dd>
<dd id="Druid.Generator.declareitem_sql" class="function"><a href="../generator.html#Generator.declareitem_sql">declareitem_sql</a></dd>
<dd id="Druid.Generator.recursivewithsearch_sql" class="function"><a href="../generator.html#Generator.recursivewithsearch_sql">recursivewithsearch_sql</a></dd>
<dd id="Druid.Generator.parameterizedagg_sql" class="function"><a href="../generator.html#Generator.parameterizedagg_sql">parameterizedagg_sql</a></dd>
<dd id="Druid.Generator.anonymousaggfunc_sql" class="function"><a href="../generator.html#Generator.anonymousaggfunc_sql">anonymousaggfunc_sql</a></dd>
<dd id="Druid.Generator.combinedaggfunc_sql" class="function"><a href="../generator.html#Generator.combinedaggfunc_sql">combinedaggfunc_sql</a></dd>
<dd id="Druid.Generator.combinedparameterizedagg_sql" class="function"><a href="../generator.html#Generator.combinedparameterizedagg_sql">combinedparameterizedagg_sql</a></dd>
<dd id="Druid.Generator.show_sql" class="function"><a href="../generator.html#Generator.show_sql">show_sql</a></dd>
<dd id="Druid.Generator.put_sql" class="function"><a href="../generator.html#Generator.put_sql">put_sql</a></dd>
</div>
</dl>

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -2467,6 +2467,7 @@ Default: True</li>
<dd id="Python.Generator.historicaldata_sql" class="function"><a href="../generator.html#Generator.historicaldata_sql">historicaldata_sql</a></dd>
<dd id="Python.Generator.table_parts" class="function"><a href="../generator.html#Generator.table_parts">table_parts</a></dd>
<dd id="Python.Generator.table_sql" class="function"><a href="../generator.html#Generator.table_sql">table_sql</a></dd>
<dd id="Python.Generator.tablefromrows_sql" class="function"><a href="../generator.html#Generator.tablefromrows_sql">tablefromrows_sql</a></dd>
<dd id="Python.Generator.tablesample_sql" class="function"><a href="../generator.html#Generator.tablesample_sql">tablesample_sql</a></dd>
<dd id="Python.Generator.pivot_sql" class="function"><a href="../generator.html#Generator.pivot_sql">pivot_sql</a></dd>
<dd id="Python.Generator.version_sql" class="function"><a href="../generator.html#Generator.version_sql">version_sql</a></dd>
@ -2762,6 +2763,7 @@ Default: True</li>
<dd id="Python.Generator.combinedaggfunc_sql" class="function"><a href="../generator.html#Generator.combinedaggfunc_sql">combinedaggfunc_sql</a></dd>
<dd id="Python.Generator.combinedparameterizedagg_sql" class="function"><a href="../generator.html#Generator.combinedparameterizedagg_sql">combinedparameterizedagg_sql</a></dd>
<dd id="Python.Generator.show_sql" class="function"><a href="../generator.html#Generator.show_sql">show_sql</a></dd>
<dd id="Python.Generator.put_sql" class="function"><a href="../generator.html#Generator.put_sql">put_sql</a></dd>
</div>
</dl>

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -1920,7 +1920,7 @@ belong to some totally-ordered set.</p>
<section id="DATE_UNITS">
<div class="attr variable">
<span class="name">DATE_UNITS</span> =
<span class="default_value">{&#39;day&#39;, &#39;month&#39;, &#39;week&#39;, &#39;quarter&#39;, &#39;year_month&#39;, &#39;year&#39;}</span>
<span class="default_value">{&#39;year_month&#39;, &#39;year&#39;, &#39;quarter&#39;, &#39;day&#39;, &#39;week&#39;, &#39;month&#39;}</span>
</div>

View file

@ -641,7 +641,7 @@
<div class="attr variable">
<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">
<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#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;, &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;}</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#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;, &lt;class &#39;<a href="expressions.html#JSONPathScript">sqlglot.expressions.JSONPathScript</a>&#39;&gt;}</span>
</div>

File diff suppressed because one or more lines are too long

View file

@ -581,7 +581,7 @@ queries if it would result in multiple table selects in a single query:</p>
<div class="attr variable">
<span class="name">UNMERGABLE_ARGS</span> =
<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;operation_modifiers&#39;, &#39;qualify&#39;, &#39;distinct&#39;, &#39;sort&#39;, &#39;cluster&#39;, &#39;limit&#39;, &#39;having&#39;, &#39;connect&#39;, &#39;prewhere&#39;, &#39;match&#39;, &#39;sample&#39;, &#39;into&#39;, &#39;offset&#39;, &#39;settings&#39;, &#39;distribute&#39;, &#39;group&#39;, &#39;pivots&#39;, &#39;options&#39;, &#39;format&#39;, &#39;laterals&#39;, &#39;with&#39;, &#39;windows&#39;, &#39;kind&#39;, &#39;locks&#39;}</span>
<label class="view-value-button pdoc-button" for="UNMERGABLE_ARGS-view-value"></label><span class="default_value">{&#39;operation_modifiers&#39;, &#39;sample&#39;, &#39;windows&#39;, &#39;pivots&#39;, &#39;offset&#39;, &#39;format&#39;, &#39;kind&#39;, &#39;match&#39;, &#39;distinct&#39;, &#39;prewhere&#39;, &#39;having&#39;, &#39;limit&#39;, &#39;into&#39;, &#39;connect&#39;, &#39;settings&#39;, &#39;qualify&#39;, &#39;group&#39;, &#39;with&#39;, &#39;options&#39;, &#39;cluster&#39;, &#39;distribute&#39;, &#39;locks&#39;, &#39;sort&#39;, &#39;laterals&#39;}</span>
</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 it is too large Load diff

41
pyproject.toml Normal file
View file

@ -0,0 +1,41 @@
[project]
name = "sqlglot"
dynamic = ["version", "optional-dependencies"]
description = "An easily customizable SQL parser and transpiler"
readme = "README.md"
authors = [{ name = "Toby Mao", email = "toby.mao@gmail.com" }]
license = { file = "LICENSE" }
requires-python = ">= 3.8"
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: SQL",
"Programming Language :: Python :: 3 :: Only",
]
[project.urls]
Homepage = "https://sqlglot.com/"
Documentation = "https://sqlglot.com/sqlglot.html"
Repository = "https://github.com/tobymao/sqlglot"
Issues = "https://github.com/tobymao/sqlglot/issues"
[build-system]
requires = ["setuptools >= 61.0", "setuptools_scm"]
build-backend = "setuptools.build_meta"
[tool.setuptools]
include-package-data = false
[tool.setuptools_scm]
version_file = "sqlglot/_version.py"
fallback_version = "0.0.0"
local_scheme = "no-local-version"
[tool.setuptools.packages.find]
include=["sqlglot", "sqlglot.*"]
[tool.setuptools.package-data]
"*" = ["py.typed"]

View file

@ -1,4 +1,4 @@
from setuptools import find_packages, setup
from setuptools import setup
def sqlglotrs_version():
@ -9,24 +9,11 @@ def sqlglotrs_version():
raise ValueError("Could not find version in Cargo.toml")
# Everything is defined in pyproject.toml except the extras because for the [rs] extra we need to dynamically
# read the sqlglotrs version. [dev] has to be specified here as well because you cant specify some extras groups
# dynamically and others statically, it has to be either all dynamic or all static
# ref: https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html#dynamic-metadata
setup(
name="sqlglot",
description="An easily customizable SQL parser and transpiler",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
url="https://github.com/tobymao/sqlglot",
author="Toby Mao",
author_email="toby.mao@gmail.com",
license="MIT",
packages=find_packages(include=["sqlglot", "sqlglot.*"]),
package_data={"sqlglot": ["py.typed"]},
use_scm_version={
"write_to": "sqlglot/_version.py",
"fallback_version": "0.0.0",
"local_scheme": "no-local-version",
},
setup_requires=["setuptools_scm"],
python_requires=">=3.7",
extras_require={
"dev": [
"duckdb>=0.6",
@ -45,13 +32,4 @@ setup(
],
"rs": [f"sqlglotrs=={sqlglotrs_version()}"],
},
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: SQL",
"Programming Language :: Python :: 3 :: Only",
],
)

View file

@ -1856,3 +1856,17 @@ def groupconcat_sql(
listagg.set("expressions", [f"{args}{self.sql(expression=expression.this)}"])
return self.sql(listagg)
def build_timetostr_or_tochar(args: t.List, dialect: Dialect) -> exp.TimeToStr | exp.ToChar:
this = seq_get(args, 0)
if this and not this.type:
from sqlglot.optimizer.annotate_types import annotate_types
annotate_types(this)
if this.is_type(*exp.DataType.TEMPORAL_TYPES):
dialect_name = dialect.__class__.__name__.lower()
return build_formatted_time(exp.TimeToStr, dialect_name, default=True)(args)
return exp.ToChar.from_arg_list(args)

View file

@ -468,6 +468,58 @@ class DuckDB(Dialect):
TokenType.DETACH: lambda self: self._parse_attach_detach(is_attach=False),
}
def _parse_expression(self) -> t.Optional[exp.Expression]:
# DuckDB supports prefix aliases, e.g. foo: 1
if self._next and self._next.token_type == TokenType.COLON:
alias = self._parse_id_var(tokens=self.ALIAS_TOKENS)
self._match(TokenType.COLON)
comments = self._prev_comments or []
this = self._parse_assignment()
if isinstance(this, exp.Expression):
# Moves the comment next to the alias in `alias: expr /* comment */`
comments += this.pop_comments() or []
return self.expression(exp.Alias, comments=comments, this=this, alias=alias)
return super()._parse_expression()
def _parse_table(
self,
schema: bool = False,
joins: bool = False,
alias_tokens: t.Optional[t.Collection[TokenType]] = None,
parse_bracket: bool = False,
is_db_reference: bool = False,
parse_partition: bool = False,
) -> t.Optional[exp.Expression]:
# DuckDB supports prefix aliases, e.g. FROM foo: bar
if self._next and self._next.token_type == TokenType.COLON:
alias = self._parse_table_alias(
alias_tokens=alias_tokens or self.TABLE_ALIAS_TOKENS
)
self._match(TokenType.COLON)
comments = self._prev_comments or []
else:
alias = None
comments = []
table = super()._parse_table(
schema=schema,
joins=joins,
alias_tokens=alias_tokens,
parse_bracket=parse_bracket,
is_db_reference=is_db_reference,
parse_partition=parse_partition,
)
if isinstance(table, exp.Expression) and isinstance(alias, exp.TableAlias):
# Moves the comment next to the alias in `alias: table /* comment */`
comments += table.pop_comments() or []
alias.comments = alias.pop_comments() + comments
table.set("alias", alias)
return table
def _parse_table_sample(self, as_modifier: bool = False) -> t.Optional[exp.TableSample]:
# https://duckdb.org/docs/sql/samples.html
sample = super()._parse_table_sample(as_modifier=as_modifier)

View file

@ -233,6 +233,8 @@ class Hive(Dialect):
"EE": "%a",
"EEE": "%a",
"EEEE": "%A",
"z": "%Z",
"Z": "%z",
}
DATE_FORMAT = "'yyyy-MM-dd'"
@ -444,6 +446,9 @@ class Hive(Dialect):
return self.expression(exp.Parameter, this=this, expression=expression)
def _to_prop_eq(self, expression: exp.Expression, index: int) -> exp.Expression:
if expression.is_star:
return expression
if isinstance(expression, exp.Column):
key = expression.this
else:
@ -575,6 +580,7 @@ class Hive(Dialect):
exp.StrToTime: _str_to_time_sql,
exp.StrToUnix: _str_to_unix_sql,
exp.StructExtract: struct_extract_sql,
exp.StarMap: rename_func("MAP"),
exp.Table: transforms.preprocess([transforms.unnest_generate_series]),
exp.TimeStrToDate: rename_func("TO_DATE"),
exp.TimeStrToTime: timestrtotime_sql,

View file

@ -6,6 +6,7 @@ from sqlglot import exp, generator, parser, tokens, transforms
from sqlglot.dialects.dialect import (
Dialect,
NormalizationStrategy,
build_timetostr_or_tochar,
build_formatted_time,
no_ilike_sql,
rename_func,
@ -21,19 +22,6 @@ if t.TYPE_CHECKING:
from sqlglot._typing import E
def _build_timetostr_or_tochar(args: t.List) -> exp.TimeToStr | exp.ToChar:
this = seq_get(args, 0)
if this and not this.type:
from sqlglot.optimizer.annotate_types import annotate_types
annotate_types(this)
if this.is_type(*exp.DataType.TEMPORAL_TYPES):
return build_formatted_time(exp.TimeToStr, "oracle", default=True)(args)
return exp.ToChar.from_arg_list(args)
def _trim_sql(self: Oracle.Generator, expression: exp.Trim) -> str:
position = expression.args.get("position")
@ -117,7 +105,7 @@ class Oracle(Dialect):
**parser.Parser.FUNCTIONS,
"NVL": lambda args: build_coalesce(args, is_nvl=True),
"SQUARE": lambda args: exp.Pow(this=seq_get(args, 0), expression=exp.Literal.number(2)),
"TO_CHAR": _build_timetostr_or_tochar,
"TO_CHAR": build_timetostr_or_tochar,
"TO_TIMESTAMP": build_formatted_time(exp.StrToTime, "oracle"),
"TO_DATE": build_formatted_time(exp.StrToDate, "oracle"),
"TRUNC": lambda args: exp.DateTrunc(

View file

@ -262,8 +262,11 @@ class Postgres(Dialect):
TIME_MAPPING = {
"AM": "%p",
"PM": "%p",
"d": "%u", # 1-based day of week
"D": "%u", # 1-based day of week
"dd": "%d", # day of month
"DD": "%d", # day of month
"ddd": "%j", # zero padded day of year
"DDD": "%j", # zero padded day of year
"FMDD": "%-d", # - is no leading zero for Python; same for FM in postgres
"FMDDD": "%-j", # day of year
@ -274,9 +277,12 @@ class Postgres(Dialect):
"FMSS": "%-S", # Second
"HH12": "%I", # 09
"HH24": "%H", # 09
"mi": "%M", # zero padded minute
"MI": "%M", # zero padded minute
"mm": "%m", # 01
"MM": "%m", # 01
"OF": "%z", # utc offset
"ss": "%S", # zero padded second
"SS": "%S", # zero padded second
"TMDay": "%A", # TM is locale dependent
"TMDy": "%a",
@ -284,8 +290,11 @@ class Postgres(Dialect):
"TMMonth": "%B", # September
"TZ": "%Z", # uppercase timezone name
"US": "%f", # zero padded microsecond
"ww": "%U", # 1-based week of year
"WW": "%U", # 1-based week of year
"yy": "%y", # 15
"YY": "%y", # 15
"yyyy": "%Y", # 2015
"YYYY": "%Y", # 2015
}

View file

@ -6,6 +6,7 @@ from sqlglot import exp, generator, jsonpath, parser, tokens, transforms
from sqlglot.dialects.dialect import (
Dialect,
NormalizationStrategy,
build_timetostr_or_tochar,
binary_from_function,
build_default_decimal_type,
build_timestamp_from_parts,
@ -434,6 +435,7 @@ class Snowflake(Dialect):
"GET_PATH": lambda args, dialect: exp.JSONExtract(
this=seq_get(args, 0), expression=dialect.to_json_path(seq_get(args, 1))
),
"HEX_DECODE_BINARY": exp.Unhex.from_arg_list,
"IFF": exp.If.from_arg_list,
"LAST_DAY": lambda args: exp.LastDay(
this=seq_get(args, 0), unit=map_date_part(seq_get(args, 1))
@ -448,6 +450,7 @@ class Snowflake(Dialect):
"REGEXP_SUBSTR_ALL": _build_regexp_extract(exp.RegexpExtractAll),
"RLIKE": exp.RegexpLike.from_arg_list,
"SQUARE": lambda args: exp.Pow(this=seq_get(args, 0), expression=exp.Literal.number(2)),
"TABLE": lambda args: exp.TableFromRows(this=seq_get(args, 0)),
"TIMEADD": _build_date_time_add(exp.TimeAdd),
"TIMEDIFF": _build_datediff,
"TIMESTAMPADD": _build_date_time_add(exp.DateAdd),
@ -462,6 +465,7 @@ class Snowflake(Dialect):
"TRY_TO_TIMESTAMP": _build_datetime(
"TRY_TO_TIMESTAMP", exp.DataType.Type.TIMESTAMP, safe=True
),
"TO_CHAR": build_timetostr_or_tochar,
"TO_DATE": _build_datetime("TO_DATE", exp.DataType.Type.DATE),
"TO_NUMBER": lambda args: exp.ToNumber(
this=seq_get(args, 0),
@ -744,6 +748,33 @@ class Snowflake(Dialect):
return table
def _parse_table(
self,
schema: bool = False,
joins: bool = False,
alias_tokens: t.Optional[t.Collection[TokenType]] = None,
parse_bracket: bool = False,
is_db_reference: bool = False,
parse_partition: bool = False,
) -> t.Optional[exp.Expression]:
table = super()._parse_table(
schema=schema,
joins=joins,
alias_tokens=alias_tokens,
parse_bracket=parse_bracket,
is_db_reference=is_db_reference,
parse_partition=parse_partition,
)
if isinstance(table, exp.Table) and isinstance(table.this, exp.TableFromRows):
table_from_rows = table.this
for arg in exp.TableFromRows.arg_types:
if arg != "this":
table_from_rows.set(arg, table.args.get(arg))
table = table_from_rows
return table
def _parse_id_var(
self,
any_token: bool = True,
@ -1030,6 +1061,7 @@ class Snowflake(Dialect):
exp.TsOrDsToTime: lambda self, e: self.func(
"TRY_TO_TIME" if e.args.get("safe") else "TO_TIME", e.this, self.format_time(e)
),
exp.Unhex: rename_func("HEX_DECODE_BINARY"),
exp.UnixToTime: rename_func("TO_TIMESTAMP"),
exp.Uuid: rename_func("UUID_STRING"),
exp.VarMap: lambda self, e: var_map_sql(self, e, "OBJECT_CONSTRUCT"),

View file

@ -11,6 +11,7 @@ SQL expressions, such as `sqlglot.expressions.select`.
"""
from __future__ import annotations
import datetime
import math
import numbers
@ -37,6 +38,7 @@ from sqlglot.tokens import Token, TokenError
if t.TYPE_CHECKING:
from typing_extensions import Self
from sqlglot._typing import E, Lit
from sqlglot.dialects.dialect import DialectType
@ -410,8 +412,7 @@ class Expression(metaclass=_Expression):
def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
"""Yields the key and expression for all arguments, exploding list args."""
# remove tuple when python 3.7 is deprecated
for vs in reversed(tuple(self.args.values())) if reverse else self.args.values(): # type: ignore
for vs in reversed(self.args.values()) if reverse else self.args.values(): # type: ignore
if type(vs) is list:
for v in reversed(vs) if reverse else vs: # type: ignore
if hasattr(v, "parent"):
@ -2586,6 +2587,18 @@ class Lateral(UDTF):
}
# https://docs.snowflake.com/sql-reference/literals-table
# https://docs.snowflake.com/en/sql-reference/functions-table#using-a-table-function
class TableFromRows(UDTF):
arg_types = {
"this": True,
"alias": False,
"joins": False,
"pivots": False,
"sample": False,
}
class MatchRecognizeMeasure(Expression):
arg_types = {
"this": True,
@ -8495,7 +8508,7 @@ def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
def expand(
expression: Expression,
sources: t.Dict[str, Query],
sources: t.Dict[str, Query | t.Callable[[], Query]],
dialect: DialectType = None,
copy: bool = True,
) -> Expression:
@ -8511,23 +8524,29 @@ def expand(
Args:
expression: The expression to expand.
sources: A dictionary of name to Queries.
dialect: The dialect of the sources dict.
sources: A dict of name to query or a callable that provides a query on demand.
dialect: The dialect of the sources dict or the callable.
copy: Whether to copy the expression during transformation. Defaults to True.
Returns:
The transformed expression.
"""
sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
def _expand(node: Expression):
if isinstance(node, Table):
name = normalize_table_name(node, dialect=dialect)
source = sources.get(name)
source = normalized_sources.get(name)
if source:
subquery = source.subquery(node.alias or name)
# Create a subquery with the same alias (or table name if no alias)
parsed_source = source() if callable(source) else source
subquery = parsed_source.subquery(node.alias or name)
subquery.comments = [f"source: {name}"]
# Continue expanding within the subquery
return subquery.transform(_expand, copy=False)
return node
return expression.transform(_expand, copy=copy)

View file

@ -191,8 +191,8 @@ class Generator(metaclass=_Generator):
exp.StreamingTableProperty: lambda *_: "STREAMING",
exp.StrictProperty: lambda *_: "STRICT",
exp.SwapTable: lambda self, e: f"SWAP WITH {self.sql(e, 'this')}",
exp.TemporaryProperty: lambda *_: "TEMPORARY",
exp.Tags: lambda self, e: f"TAG ({self.expressions(e, flat=True)})",
exp.TemporaryProperty: lambda *_: "TEMPORARY",
exp.TitleColumnConstraint: lambda self, e: f"TITLE {self.sql(e, 'this')}",
exp.ToMap: lambda self, e: f"MAP {self.sql(e, 'this')}",
exp.ToTableProperty: lambda self, e: f"TO {self.sql(e.this)}",
@ -1999,6 +1999,17 @@ class Generator(metaclass=_Generator):
return f"{only}{table}{changes}{partition}{version}{file_format}{sample_pre_alias}{alias}{hints}{pivots}{sample_post_alias}{joins}{laterals}{ordinality}"
def tablefromrows_sql(self, expression: exp.TableFromRows) -> str:
table = self.func("TABLE", expression.this)
alias = self.sql(expression, "alias")
alias = f" AS {alias}" if alias else ""
sample = self.sql(expression, "sample")
pivots = self.expressions(expression, key="pivots", sep="", flat=True)
joins = self.indent(
self.expressions(expression, key="joins", sep="", flat=True), skip_first=True
)
return f"{table}{alias}{pivots}{sample}{joins}"
def tablesample_sql(
self,
expression: exp.TableSample,

View file

@ -117,7 +117,7 @@ def simplify(
node = flatten(node)
node = simplify_connectors(node, root)
node = remove_complements(node, root)
node = simplify_coalesce(node)
node = simplify_coalesce(node, dialect)
node.parent = expression.parent
node = simplify_literals(node, root)
node = simplify_equality(node)
@ -775,7 +775,7 @@ def _is_constant(expression: exp.Expression) -> bool:
return isinstance(expression, exp.CONSTANTS) or _is_date_literal(expression)
def simplify_coalesce(expression):
def simplify_coalesce(expression: exp.Expression, dialect: DialectType) -> exp.Expression:
# COALESCE(x) -> x
if (
isinstance(expression, exp.Coalesce)
@ -785,6 +785,12 @@ def simplify_coalesce(expression):
):
return expression.this
# We can't convert `COALESCE(x, 1) = 2` into `NOT x IS NULL AND x = 2` for redshift,
# because they are not always equivalent. For example, if `x` is `NULL` and it comes
# from a table, then the result is `NULL`, despite `FALSE AND NULL` evaluating to `FALSE`
if dialect == "redshift":
return expression
if not isinstance(expression, COMPARISONS):
return expression

View file

@ -685,6 +685,7 @@ class Parser(metaclass=_Parser):
TIMESTAMPS = {
TokenType.TIMESTAMP,
TokenType.TIMESTAMPNTZ,
TokenType.TIMESTAMPTZ,
TokenType.TIMESTAMPLTZ,
*TIMES,
@ -1386,6 +1387,8 @@ class Parser(metaclass=_Parser):
RECURSIVE_CTE_SEARCH_KIND = {"BREADTH", "DEPTH", "CYCLE"}
MODIFIABLES = (exp.Query, exp.Table, exp.TableFromRows)
STRICT_CAST = True
PREFIXED_PIVOT_COLUMNS = False
@ -3350,7 +3353,7 @@ class Parser(metaclass=_Parser):
def _parse_query_modifiers(
self, this: t.Optional[exp.Expression]
) -> t.Optional[exp.Expression]:
if isinstance(this, (exp.Query, exp.Table)):
if isinstance(this, self.MODIFIABLES):
for join in self._parse_joins():
this.append("joins", join)
for lateral in iter(self._parse_lateral, None):

View file

@ -5,7 +5,7 @@ build-backend = "maturin"
[project]
name = "sqlglotrs"
description = "An easily customizable SQL parser and transpiler"
requires-python = ">=3.7"
requires-python = ">=3.8"
classifiers = [
"Programming Language :: Rust",
"Programming Language :: Python :: Implementation :: CPython",

View file

@ -8,6 +8,10 @@ class TestDuckDB(Validator):
dialect = "duckdb"
def test_duckdb(self):
self.validate_identity("x::timestamp", "CAST(x AS TIMESTAMP)")
self.validate_identity("x::timestamp without time zone", "CAST(x AS TIMESTAMP)")
self.validate_identity("x::timestamp with time zone", "CAST(x AS TIMESTAMPTZ)")
with self.assertRaises(ParseError):
parse_one("1 //", read="duckdb")
@ -1482,3 +1486,86 @@ class TestDuckDB(Validator):
def test_analyze(self):
self.validate_identity("ANALYZE")
def test_prefix_aliases(self):
# https://duckdb.org/2025/02/25/prefix-aliases-in-sql.html
self.validate_identity(
"SELECT foo: 1",
"SELECT 1 AS foo",
)
self.validate_identity(
"SELECT foo: bar",
"SELECT bar AS foo",
)
self.validate_identity(
"SELECT foo: t.col FROM t",
"SELECT t.col AS foo FROM t",
)
self.validate_identity(
'SELECT "foo" /* bla */: 1',
'SELECT 1 AS "foo" /* bla */',
)
self.validate_identity(
'SELECT "foo": 1 /* bla */',
'SELECT 1 AS "foo" /* bla */',
)
self.validate_identity(
'SELECT "foo": /* bla */ 1',
'SELECT 1 AS "foo" /* bla */',
)
self.validate_identity(
'SELECT "foo": /* bla */ 1 /* foo */',
'SELECT 1 AS "foo" /* bla */ /* foo */',
)
self.validate_identity(
'SELECT "foo": 1',
'SELECT 1 AS "foo"',
)
self.validate_identity(
"SELECT foo: 1, bar: 2, baz: 3",
"SELECT 1 AS foo, 2 AS bar, 3 AS baz",
)
self.validate_identity(
"SELECT e: 1 + 2, f: len('asdf'), s: (SELECT 42)",
"SELECT 1 + 2 AS e, LENGTH('asdf') AS f, (SELECT 42) AS s",
)
self.validate_identity(
"SELECT * FROM foo: bar",
"SELECT * FROM bar AS foo",
)
self.validate_identity(
"SELECT * FROM foo: c.db.tbl",
"SELECT * FROM c.db.tbl AS foo",
)
self.validate_identity(
"SELECT * FROM foo /* bla */: bar",
"SELECT * FROM bar AS foo /* bla */",
)
self.validate_identity(
"SELECT * FROM foo /* bla */: bar /* baz */",
"SELECT * FROM bar AS foo /* bla */ /* baz */",
)
self.validate_identity(
"SELECT * FROM foo /* bla */: /* baz */ bar /* boo */",
"SELECT * FROM bar AS foo /* bla */ /* baz */ /* boo */",
)
self.validate_identity(
"SELECT * FROM r: range(10), v: (VALUES (42)), s: (FROM range(10))",
"SELECT * FROM RANGE(0, 10) AS r, (VALUES (42)) AS v, (SELECT * FROM RANGE(0, 10)) AS s",
)
self.validate_identity(
"""
SELECT
l_returnflag,
l_linestatus,
sum_qty: sum(l_quantity),
sum_base_price: sum(l_extendedprice),
sum_disc_price: sum(l_extendedprice * (1-l_discount)),
sum_charge: sum(l_extendedprice * (1-l_discount) * (1+l_tax)),
avg_qty: avg(l_quantity),
avg_price: avg(l_extendedprice),
avg_disc: avg(l_discount),
count_order: count(*)
""",
"SELECT l_returnflag, l_linestatus, SUM(l_quantity) AS sum_qty, SUM(l_extendedprice) AS sum_base_price, SUM(l_extendedprice * (1 - l_discount)) AS sum_disc_price, SUM(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge, AVG(l_quantity) AS avg_qty, AVG(l_extendedprice) AS avg_price, AVG(l_discount) AS avg_disc, COUNT(*) AS count_order",
)

View file

@ -810,6 +810,21 @@ class TestHive(Validator):
self.validate_identity("SELECT 1_2")
self.validate_all(
"SELECT MAP(*), STRUCT(*) FROM t",
read={
"hive": "SELECT MAP(*), STRUCT(*) FROM t",
"spark2": "SELECT MAP(*), STRUCT(*) FROM t",
"spark": "SELECT MAP(*), STRUCT(*) FROM t",
"databricks": "SELECT MAP(*), STRUCT(*) FROM t",
},
write={
"spark2": "SELECT MAP(*), STRUCT(*) FROM t",
"spark": "SELECT MAP(*), STRUCT(*) FROM t",
"databricks": "SELECT MAP(*), STRUCT(*) FROM t",
},
)
def test_escapes(self) -> None:
self.validate_identity("'\n'", "'\\n'")
self.validate_identity("'\\n'")

View file

@ -143,13 +143,13 @@ class TestOracle(Validator):
},
)
self.validate_all(
"CURRENT_TIMESTAMP BETWEEN TO_DATE(f.C_SDATE, 'yyyy/mm/dd') AND TO_DATE(f.C_EDATE, 'yyyy/mm/dd')",
"CURRENT_TIMESTAMP BETWEEN TO_DATE(f.C_SDATE, 'YYYY/MM/DD') AND TO_DATE(f.C_EDATE, 'YYYY/MM/DD')",
read={
"postgres": "CURRENT_TIMESTAMP BETWEEN TO_DATE(f.C_SDATE, 'yyyy/mm/dd') AND TO_DATE(f.C_EDATE, 'yyyy/mm/dd')",
},
write={
"oracle": "CURRENT_TIMESTAMP BETWEEN TO_DATE(f.C_SDATE, 'yyyy/mm/dd') AND TO_DATE(f.C_EDATE, 'yyyy/mm/dd')",
"postgres": "CURRENT_TIMESTAMP BETWEEN TO_DATE(f.C_SDATE, 'yyyy/mm/dd') AND TO_DATE(f.C_EDATE, 'yyyy/mm/dd')",
"oracle": "CURRENT_TIMESTAMP BETWEEN TO_DATE(f.C_SDATE, 'YYYY/MM/DD') AND TO_DATE(f.C_EDATE, 'YYYY/MM/DD')",
"postgres": "CURRENT_TIMESTAMP BETWEEN TO_DATE(f.C_SDATE, 'YYYY/MM/DD') AND TO_DATE(f.C_EDATE, 'YYYY/MM/DD')",
},
)
self.validate_all(

View file

@ -588,6 +588,16 @@ class TestSnowflake(Validator):
"teradata": "TO_CHAR(x, y)",
},
)
self.validate_identity(
"TO_CHAR(foo::DATE, 'yyyy')", "TO_CHAR(CAST(CAST(foo AS DATE) AS TIMESTAMP), 'yyyy')"
)
self.validate_all(
"TO_CHAR(foo::TIMESTAMP, 'YYYY-MM')",
write={
"snowflake": "TO_CHAR(CAST(foo AS TIMESTAMP), 'yyyy-mm')",
"duckdb": "STRFTIME(CAST(foo AS TIMESTAMP), '%Y-%m')",
},
)
self.validate_all(
"SQUARE(x)",
write={
@ -998,6 +1008,15 @@ class TestSnowflake(Validator):
self.validate_identity("CREATE TABLE t (id INT PRIMARY KEY AUTOINCREMENT)")
self.validate_all(
"SELECT HEX_DECODE_BINARY('65')",
write={
"bigquery": "SELECT FROM_HEX('65')",
"duckdb": "SELECT UNHEX('65')",
"snowflake": "SELECT HEX_DECODE_BINARY('65')",
},
)
def test_null_treatment(self):
self.validate_all(
r"SELECT FIRST_VALUE(TABLE1.COLUMN1) OVER (PARTITION BY RANDOM_COLUMN1, RANDOM_COLUMN2 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS MY_ALIAS FROM TABLE1",
@ -1608,44 +1627,21 @@ class TestSnowflake(Validator):
"CREATE PROCEDURE a.b.c(x INT, y VARIANT) RETURNS OBJECT EXECUTE AS CALLER AS 'BEGIN SELECT 1; END;'"
)
def test_table_literal(self):
# All examples from https://docs.snowflake.com/en/sql-reference/literals-table.html
self.validate_all(
r"""SELECT * FROM TABLE('MYTABLE')""",
write={"snowflake": r"""SELECT * FROM TABLE('MYTABLE')"""},
)
self.validate_all(
r"""SELECT * FROM TABLE('MYDB."MYSCHEMA"."MYTABLE"')""",
write={"snowflake": r"""SELECT * FROM TABLE('MYDB."MYSCHEMA"."MYTABLE"')"""},
)
# Per Snowflake documentation at https://docs.snowflake.com/en/sql-reference/literals-table.html
# one can use either a " ' " or " $$ " to enclose the object identifier.
# Capturing the single tokens seems like lot of work. Hence adjusting tests to use these interchangeably,
self.validate_all(
r"""SELECT * FROM TABLE($$MYDB. "MYSCHEMA"."MYTABLE"$$)""",
write={"snowflake": r"""SELECT * FROM TABLE('MYDB. "MYSCHEMA"."MYTABLE"')"""},
)
self.validate_all(
r"""SELECT * FROM TABLE($MYVAR)""",
write={"snowflake": r"""SELECT * FROM TABLE($MYVAR)"""},
)
self.validate_all(
r"""SELECT * FROM TABLE(?)""",
write={"snowflake": r"""SELECT * FROM TABLE(?)"""},
)
self.validate_all(
r"""SELECT * FROM TABLE(:BINDING)""",
write={"snowflake": r"""SELECT * FROM TABLE(:BINDING)"""},
)
self.validate_all(
r"""SELECT * FROM TABLE($MYVAR) WHERE COL1 = 10""",
write={"snowflake": r"""SELECT * FROM TABLE($MYVAR) WHERE COL1 = 10"""},
def test_table_function(self):
self.validate_identity("SELECT * FROM TABLE('MYTABLE')")
self.validate_identity("SELECT * FROM TABLE($MYVAR)")
self.validate_identity("SELECT * FROM TABLE(?)")
self.validate_identity("SELECT * FROM TABLE(:BINDING)")
self.validate_identity("SELECT * FROM TABLE($MYVAR) WHERE COL1 = 10")
self.validate_identity("SELECT * FROM TABLE('t1') AS f")
self.validate_identity("SELECT * FROM (TABLE('t1') CROSS JOIN TABLE('t2'))")
self.validate_identity("SELECT * FROM TABLE('t1'), LATERAL (SELECT * FROM t2)")
self.validate_identity("SELECT * FROM TABLE('t1') UNION ALL SELECT * FROM TABLE('t2')")
self.validate_identity("SELECT * FROM TABLE('t1') TABLESAMPLE BERNOULLI (20.3)")
self.validate_identity("""SELECT * FROM TABLE('MYDB."MYSCHEMA"."MYTABLE"')""")
self.validate_identity(
'SELECT * FROM TABLE($$MYDB. "MYSCHEMA"."MYTABLE"$$)',
"""SELECT * FROM TABLE('MYDB. "MYSCHEMA"."MYTABLE"')""",
)
def test_flatten(self):

View file

@ -445,7 +445,7 @@ TBLPROPERTIES (
self.validate_all(
"SELECT DATEDIFF(MONTH, CAST('1996-10-30' AS TIMESTAMP), CAST('1997-02-28 10:30:00' AS TIMESTAMP))",
read={
"duckdb": "SELECT DATEDIFF('month', CAST('1996-10-30' AS TIMESTAMP), CAST('1997-02-28 10:30:00' AS TIMESTAMP))",
"duckdb": "SELECT DATEDIFF('month', CAST('1996-10-30' AS TIMESTAMPTZ), CAST('1997-02-28 10:30:00' AS TIMESTAMPTZ))",
},
write={
"spark": "SELECT DATEDIFF(MONTH, TO_DATE(CAST('1996-10-30' AS TIMESTAMP)), TO_DATE(CAST('1997-02-28 10:30:00' AS TIMESTAMP)))",
@ -488,6 +488,13 @@ TBLPROPERTIES (
"spark": "SELECT CAST('2016-12-31 00:12:00' AS TIMESTAMP)",
},
)
self.validate_all(
"SELECT TO_TIMESTAMP(x, 'zZ')",
write={
"": "SELECT STR_TO_TIME(x, '%Z%z')",
"duckdb": "SELECT STRPTIME(x, '%Z%z')",
},
)
self.validate_all(
"SELECT TO_TIMESTAMP('2016-12-31', 'yyyy-MM-dd')",
read={

View file

@ -843,6 +843,10 @@ x;
COALESCE(x, 1) = 2;
NOT x IS NULL AND x = 2;
# dialect: redshift
COALESCE(x, 1) = 2;
COALESCE(x, 1) = 2;
2 = COALESCE(x, 1);
NOT x IS NULL AND x = 2;

View file

@ -1,6 +1,6 @@
import sys
import datetime
import math
import sys
import unittest
from sqlglot import ParseError, alias, exp, parse_one
@ -277,6 +277,16 @@ class TestExpressions(unittest.TestCase):
"SELECT * FROM (SELECT 1) AS a /* source: a-b.c */",
)
def test_expand_with_lazy_source_provider(self):
self.assertEqual(
exp.expand(
parse_one('select * from "a-b"."C" AS a'),
{"`a-b`.c": lambda: parse_one("select 1", dialect="spark")},
dialect="spark",
).sql(),
"SELECT * FROM (SELECT 1) AS a /* source: a-b.c */",
)
def test_replace_placeholders(self):
self.assertEqual(
exp.replace_placeholders(
@ -838,6 +848,7 @@ class TestExpressions(unittest.TestCase):
def test_convert(self):
from collections import namedtuple
import pytz
PointTuple = namedtuple("Point", ["x", "y"])

View file

@ -576,3 +576,48 @@ class TestLineage(unittest.TestCase):
self.assertEqual(node.downstream[0].name, "t.empid")
self.assertEqual(node.downstream[0].reference_node_name, "t")
self.assertEqual(node.downstream[0].downstream[0].name, "quarterly_sales.empid")
def test_table_udtf_snowflake(self) -> None:
lateral_flatten = """
SELECT f.value:external_id::string AS external_id
FROM database_name.schema_name.table_name AS raw,
LATERAL FLATTEN(events) AS f
"""
table_flatten = """
SELECT f.value:external_id::string AS external_id
FROM database_name.schema_name.table_name AS raw
JOIN TABLE(FLATTEN(events)) AS f
"""
lateral_node = lineage("external_id", lateral_flatten, dialect="snowflake")
table_node = lineage("external_id", table_flatten, dialect="snowflake")
self.assertEqual(lateral_node.name, "EXTERNAL_ID")
self.assertEqual(table_node.name, "EXTERNAL_ID")
lateral_node = lateral_node.downstream[0]
table_node = table_node.downstream[0]
self.assertEqual(lateral_node.name, "F.VALUE")
self.assertEqual(
lateral_node.source.sql("snowflake"),
"LATERAL FLATTEN(RAW.EVENTS) AS F(SEQ, KEY, PATH, INDEX, VALUE, THIS)",
)
self.assertEqual(table_node.name, "F.VALUE")
self.assertEqual(table_node.source.sql("snowflake"), "TABLE(FLATTEN(RAW.EVENTS)) AS F")
lateral_node = lateral_node.downstream[0]
table_node = table_node.downstream[0]
self.assertEqual(lateral_node.name, "RAW.EVENTS")
self.assertEqual(
lateral_node.source.sql("snowflake"),
"DATABASE_NAME.SCHEMA_NAME.TABLE_NAME AS RAW",
)
self.assertEqual(table_node.name, "RAW.EVENTS")
self.assertEqual(
table_node.source.sql("snowflake"),
"DATABASE_NAME.SCHEMA_NAME.TABLE_NAME AS RAW",
)