1
0
Fork 0

Merging upstream version 26.26.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-06-11 08:06:17 +02:00
parent 768f936511
commit 1ac9fca060
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
62 changed files with 938 additions and 453 deletions

81
.github/scripts/format_benchmark.py vendored Executable file
View file

@ -0,0 +1,81 @@
#!/usr/bin/env python3
"""Format benchmark comparison output with visual indicators for GitHub markdown."""
import re
import sys
def format_benchmark_output(content):
"""Add visual formatting to benchmark comparison output."""
lines = content.split("\n")
formatted_lines = []
for line in lines:
# Skip empty lines and headers
if not line.strip() or line.startswith("|") and "---" in line:
formatted_lines.append(line)
continue
# Process benchmark result lines
if "|" in line and ("faster" in line or "slower" in line):
# Extract the speed factor (e.g., "1.23x faster" or "1.10x slower")
speed_match = re.search(r"(\d+\.\d+)x\s+(faster|slower)", line)
if speed_match:
factor = float(speed_match.group(1))
direction = speed_match.group(2)
# Add visual indicators based on performance
if direction == "faster":
# Green indicator for faster
if factor >= 2.0:
indicator = "🟢🟢" # Double green for 2x+ faster
elif factor >= 1.1:
indicator = "🟢" # Single green for 1.1x+ faster
else:
indicator = "" # White for marginal improvement
formatted_text = f"{indicator} **{speed_match.group(0)}**"
else:
# Red indicator for slower
if factor >= 2.0:
indicator = "🔴🔴" # Double red for 2x+ slower
elif factor >= 1.1:
indicator = "🔴" # Single red for 1.1x+ slower
else:
indicator = "" # White for marginal slowdown
formatted_text = f"{indicator} **{speed_match.group(0)}**"
# Replace the original text with formatted version
line = line.replace(speed_match.group(0), formatted_text)
elif "not significant" in line:
# Add neutral indicator for non-significant changes
line = re.sub(r"not significant", "⚪ not significant", line)
formatted_lines.append(line)
return "\n".join(formatted_lines)
def main():
if len(sys.argv) != 2:
print("Usage: python format_benchmark.py <input_file>")
sys.exit(1)
input_file = sys.argv[1]
try:
with open(input_file, "r") as f:
content = f.read()
formatted = format_benchmark_output(content)
print(formatted)
except FileNotFoundError:
print(f"Error: File '{input_file}' not found")
sys.exit(1)
except Exception as e:
print(f"Error: {e}")
sys.exit(1)
if __name__ == "__main__":
main()

View file

@ -61,14 +61,27 @@ jobs:
- name: Compare benchmarks and save results - name: Compare benchmarks and save results
run: | run: |
source ./.venv/bin/activate source ./.venv/bin/activate
python -m pyperf compare_to bench_parse_pr.json bench_parse_main.json --table --table-format=md > bench_parse_comparison.txt python -m pyperf compare_to bench_parse_main.json bench_parse_pr.json --table --table-format=md > bench_parse_comparison_raw.txt
python -m pyperf compare_to bench_optimize_pr.json bench_optimize_main.json --table --table-format=md > bench_optimize_comparison.txt python -m pyperf compare_to bench_optimize_main.json bench_optimize_pr.json --table --table-format=md > bench_optimize_comparison_raw.txt
# Format with colors
python .github/scripts/format_benchmark.py bench_parse_comparison_raw.txt > bench_parse_comparison.txt
python .github/scripts/format_benchmark.py bench_optimize_comparison_raw.txt > bench_optimize_comparison.txt
- name: Combine benchmark outputs - name: Combine benchmark outputs
run: | run: |
echo "## Parsing Benchmark" > combined_benchmarks.md echo "## Benchmark Results" > combined_benchmarks.md
echo "" >> combined_benchmarks.md
echo "**Legend:**" >> combined_benchmarks.md
echo "- 🟢🟢 = 2x+ faster" >> combined_benchmarks.md
echo "- 🟢 = 1.1x - 2x faster" >> combined_benchmarks.md
echo "- ⚪ = No significant change (< 1.1x)" >> combined_benchmarks.md
echo "- 🔴 = 1.1x - 2x slower" >> combined_benchmarks.md
echo "- 🔴🔴 = 2x+ slower" >> combined_benchmarks.md
echo "" >> combined_benchmarks.md
echo "### Parsing Benchmark" >> combined_benchmarks.md
cat bench_parse_comparison.txt >> combined_benchmarks.md cat bench_parse_comparison.txt >> combined_benchmarks.md
echo -e "\n---\n" >> combined_benchmarks.md echo -e "\n---\n" >> combined_benchmarks.md
echo "## Optimization Benchmark" >> combined_benchmarks.md echo "### Optimization Benchmark" >> combined_benchmarks.md
cat bench_optimize_comparison.txt >> combined_benchmarks.md cat bench_optimize_comparison.txt >> combined_benchmarks.md
- name: Comment on PR for parse benchmark results - name: Comment on PR for parse benchmark results
uses: peter-evans/create-or-update-comment@v4 uses: peter-evans/create-or-update-comment@v4

View file

@ -1,6 +1,11 @@
Changelog Changelog
========= =========
## [v26.25.3] - 2025-06-04
### :sparkles: New Features
- [`964b4a1`](https://github.com/tobymao/sqlglot/commit/964b4a1e367e00e243b80edf677cd48d453ed31e) - add line/col position for Star *(commit by [@georgesittas](https://github.com/georgesittas))*
## [v26.25.2] - 2025-06-04 ## [v26.25.2] - 2025-06-04
### :sparkles: New Features ### :sparkles: New Features
- [`8b5129f`](https://github.com/tobymao/sqlglot/commit/8b5129f288880032f0bf9d649984d82314039af1) - **postgres**: improve pretty-formatting of ARRAY[...] *(commit by [@georgesittas](https://github.com/georgesittas))* - [`8b5129f`](https://github.com/tobymao/sqlglot/commit/8b5129f288880032f0bf9d649984d82314039af1) - **postgres**: improve pretty-formatting of ARRAY[...] *(commit by [@georgesittas](https://github.com/georgesittas))*
@ -4788,3 +4793,4 @@ Changelog
[v26.25.0]: https://github.com/tobymao/sqlglot/compare/v26.24.0...v26.25.0 [v26.25.0]: https://github.com/tobymao/sqlglot/compare/v26.24.0...v26.25.0
[v26.25.1]: https://github.com/tobymao/sqlglot/compare/v26.25.0...v26.25.1 [v26.25.1]: https://github.com/tobymao/sqlglot/compare/v26.25.0...v26.25.1
[v26.25.2]: https://github.com/tobymao/sqlglot/compare/v26.25.1...v26.25.2 [v26.25.2]: https://github.com/tobymao/sqlglot/compare/v26.25.1...v26.25.2
[v26.25.3]: https://github.com/tobymao/sqlglot/compare/v26.25.2...v26.25.3

View file

@ -497,6 +497,7 @@ See also: [Writing a Python SQL engine from scratch](https://github.com/tobymao/
* [Dagster](https://github.com/dagster-io/dagster) * [Dagster](https://github.com/dagster-io/dagster)
* [Fugue](https://github.com/fugue-project/fugue) * [Fugue](https://github.com/fugue-project/fugue)
* [Ibis](https://github.com/ibis-project/ibis) * [Ibis](https://github.com/ibis-project/ibis)
* [dlt](https://github.com/dlt-hub/dlt)
* [mysql-mimic](https://github.com/kelsin/mysql-mimic) * [mysql-mimic](https://github.com/kelsin/mysql-mimic)
* [Querybook](https://github.com/pinterest/querybook) * [Querybook](https://github.com/pinterest/querybook)
* [Quokka](https://github.com/marsupialtail/quokka) * [Quokka](https://github.com/marsupialtail/quokka)

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-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-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-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.25.2&#39;</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.25.3&#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">25</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</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">25</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
</span></pre></div> </span></pre></div>
@ -93,7 +93,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;26.25.2&#39;</span> <span class="default_value">&#39;26.25.3&#39;</span>
</div> </div>
@ -105,7 +105,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">(26, 25, 2)</span> <span class="default_value">(26, 25, 3)</span>
</div> </div>
@ -117,7 +117,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;26.25.2&#39;</span> <span class="default_value">&#39;26.25.3&#39;</span>
</div> </div>
@ -129,7 +129,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">(26, 25, 2)</span> <span class="default_value">(26, 25, 3)</span>
</div> </div>

View file

@ -359,7 +359,7 @@ dialect implementations in order to understand how their various components can
<section id="Athena"> <section id="Athena">
<div class="attr variable"> <div class="attr variable">
<span class="name">Athena</span> = <span class="name">Athena</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634507837104&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571796728384&#39;&gt;</span>
</div> </div>
@ -371,7 +371,7 @@ dialect implementations in order to understand how their various components can
<section id="BigQuery"> <section id="BigQuery">
<div class="attr variable"> <div class="attr variable">
<span class="name">BigQuery</span> = <span class="name">BigQuery</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634507824912&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571796081632&#39;&gt;</span>
</div> </div>
@ -383,7 +383,7 @@ dialect implementations in order to understand how their various components can
<section id="ClickHouse"> <section id="ClickHouse">
<div class="attr variable"> <div class="attr variable">
<span class="name">ClickHouse</span> = <span class="name">ClickHouse</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634506710896&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571798395520&#39;&gt;</span>
</div> </div>
@ -395,7 +395,7 @@ dialect implementations in order to understand how their various components can
<section id="Databricks"> <section id="Databricks">
<div class="attr variable"> <div class="attr variable">
<span class="name">Databricks</span> = <span class="name">Databricks</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634506014208&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571786944400&#39;&gt;</span>
</div> </div>
@ -407,7 +407,7 @@ dialect implementations in order to understand how their various components can
<section id="Doris"> <section id="Doris">
<div class="attr variable"> <div class="attr variable">
<span class="name">Doris</span> = <span class="name">Doris</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634502703680&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571799701632&#39;&gt;</span>
</div> </div>
@ -419,7 +419,7 @@ dialect implementations in order to understand how their various components can
<section id="Drill"> <section id="Drill">
<div class="attr variable"> <div class="attr variable">
<span class="name">Drill</span> = <span class="name">Drill</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634506225040&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571798507328&#39;&gt;</span>
</div> </div>
@ -431,7 +431,7 @@ dialect implementations in order to understand how their various components can
<section id="Druid"> <section id="Druid">
<div class="attr variable"> <div class="attr variable">
<span class="name">Druid</span> = <span class="name">Druid</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634506216304&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571784920080&#39;&gt;</span>
</div> </div>
@ -443,7 +443,7 @@ dialect implementations in order to understand how their various components can
<section id="DuckDB"> <section id="DuckDB">
<div class="attr variable"> <div class="attr variable">
<span class="name">DuckDB</span> = <span class="name">DuckDB</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634494301136&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571784909808&#39;&gt;</span>
</div> </div>
@ -455,7 +455,7 @@ dialect implementations in order to understand how their various components can
<section id="Dune"> <section id="Dune">
<div class="attr variable"> <div class="attr variable">
<span class="name">Dune</span> = <span class="name">Dune</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634505383792&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571785635072&#39;&gt;</span>
</div> </div>
@ -467,7 +467,7 @@ dialect implementations in order to understand how their various components can
<section id="Hive"> <section id="Hive">
<div class="attr variable"> <div class="attr variable">
<span class="name">Hive</span> = <span class="name">Hive</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634502237920&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571796939552&#39;&gt;</span>
</div> </div>
@ -479,7 +479,7 @@ dialect implementations in order to understand how their various components can
<section id="Materialize"> <section id="Materialize">
<div class="attr variable"> <div class="attr variable">
<span class="name">Materialize</span> = <span class="name">Materialize</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634509349440&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571796933216&#39;&gt;</span>
</div> </div>
@ -491,7 +491,7 @@ dialect implementations in order to understand how their various components can
<section id="MySQL"> <section id="MySQL">
<div class="attr variable"> <div class="attr variable">
<span class="name">MySQL</span> = <span class="name">MySQL</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634507150432&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571802007920&#39;&gt;</span>
</div> </div>
@ -503,7 +503,7 @@ dialect implementations in order to understand how their various components can
<section id="Oracle"> <section id="Oracle">
<div class="attr variable"> <div class="attr variable">
<span class="name">Oracle</span> = <span class="name">Oracle</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634496723616&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571798015520&#39;&gt;</span>
</div> </div>
@ -515,7 +515,7 @@ dialect implementations in order to understand how their various components can
<section id="Postgres"> <section id="Postgres">
<div class="attr variable"> <div class="attr variable">
<span class="name">Postgres</span> = <span class="name">Postgres</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634496715216&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571787331280&#39;&gt;</span>
</div> </div>
@ -527,7 +527,7 @@ dialect implementations in order to understand how their various components can
<section id="Presto"> <section id="Presto">
<div class="attr variable"> <div class="attr variable">
<span class="name">Presto</span> = <span class="name">Presto</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634508955024&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571792711184&#39;&gt;</span>
</div> </div>
@ -539,7 +539,7 @@ dialect implementations in order to understand how their various components can
<section id="PRQL"> <section id="PRQL">
<div class="attr variable"> <div class="attr variable">
<span class="name">PRQL</span> = <span class="name">PRQL</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634507747792&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571790276352&#39;&gt;</span>
</div> </div>
@ -551,7 +551,7 @@ dialect implementations in order to understand how their various components can
<section id="Redshift"> <section id="Redshift">
<div class="attr variable"> <div class="attr variable">
<span class="name">Redshift</span> = <span class="name">Redshift</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634504908416&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571796486896&#39;&gt;</span>
</div> </div>
@ -563,7 +563,7 @@ dialect implementations in order to understand how their various components can
<section id="RisingWave"> <section id="RisingWave">
<div class="attr variable"> <div class="attr variable">
<span class="name">RisingWave</span> = <span class="name">RisingWave</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634504916624&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571796480032&#39;&gt;</span>
</div> </div>
@ -575,7 +575,7 @@ dialect implementations in order to understand how their various components can
<section id="Snowflake"> <section id="Snowflake">
<div class="attr variable"> <div class="attr variable">
<span class="name">Snowflake</span> = <span class="name">Snowflake</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634507238688&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571798302544&#39;&gt;</span>
</div> </div>
@ -587,7 +587,7 @@ dialect implementations in order to understand how their various components can
<section id="Spark"> <section id="Spark">
<div class="attr variable"> <div class="attr variable">
<span class="name">Spark</span> = <span class="name">Spark</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634507369712&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571798306144&#39;&gt;</span>
</div> </div>
@ -599,7 +599,7 @@ dialect implementations in order to understand how their various components can
<section id="Spark2"> <section id="Spark2">
<div class="attr variable"> <div class="attr variable">
<span class="name">Spark2</span> = <span class="name">Spark2</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634506022528&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571795407632&#39;&gt;</span>
</div> </div>
@ -611,7 +611,7 @@ dialect implementations in order to understand how their various components can
<section id="SQLite"> <section id="SQLite">
<div class="attr variable"> <div class="attr variable">
<span class="name">SQLite</span> = <span class="name">SQLite</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634506023632&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571791304560&#39;&gt;</span>
</div> </div>
@ -623,7 +623,7 @@ dialect implementations in order to understand how their various components can
<section id="StarRocks"> <section id="StarRocks">
<div class="attr variable"> <div class="attr variable">
<span class="name">StarRocks</span> = <span class="name">StarRocks</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634509005568&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571795611968&#39;&gt;</span>
</div> </div>
@ -635,7 +635,7 @@ dialect implementations in order to understand how their various components can
<section id="Tableau"> <section id="Tableau">
<div class="attr variable"> <div class="attr variable">
<span class="name">Tableau</span> = <span class="name">Tableau</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634508366016&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571793529520&#39;&gt;</span>
</div> </div>
@ -647,7 +647,7 @@ dialect implementations in order to understand how their various components can
<section id="Teradata"> <section id="Teradata">
<div class="attr variable"> <div class="attr variable">
<span class="name">Teradata</span> = <span class="name">Teradata</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634494650928&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571785251376&#39;&gt;</span>
</div> </div>
@ -659,7 +659,7 @@ dialect implementations in order to understand how their various components can
<section id="Trino"> <section id="Trino">
<div class="attr variable"> <div class="attr variable">
<span class="name">Trino</span> = <span class="name">Trino</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634494658800&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571785259248&#39;&gt;</span>
</div> </div>
@ -671,7 +671,7 @@ dialect implementations in order to understand how their various components can
<section id="TSQL"> <section id="TSQL">
<div class="attr variable"> <div class="attr variable">
<span class="name">TSQL</span> = <span class="name">TSQL</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634494683168&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571785300000&#39;&gt;</span>
</div> </div>
@ -683,7 +683,7 @@ dialect implementations in order to understand how their various components can
<section id="Dialect"> <section id="Dialect">
<div class="attr variable"> <div class="attr variable">
<span class="name">Dialect</span> = <span class="name">Dialect</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634494691088&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571785307920&#39;&gt;</span>
</div> </div>
@ -695,7 +695,7 @@ dialect implementations in order to understand how their various components can
<section id="Dialects"> <section id="Dialects">
<div class="attr variable"> <div class="attr variable">
<span class="name">Dialects</span> = <span class="name">Dialects</span> =
<span class="default_value">&lt;MagicMock id=&#39;140634494715456&#39;&gt;</span> <span class="default_value">&lt;MagicMock id=&#39;140571785332288&#39;&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

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -63337,7 +63337,7 @@ Otherwise, this resets the expressions.</li>
<div id="DataType.STRUCT_TYPES" class="classattr"> <div id="DataType.STRUCT_TYPES" class="classattr">
<div class="attr variable"> <div class="attr variable">
<span class="name">STRUCT_TYPES</span> = <span class="name">STRUCT_TYPES</span> =
<span class="default_value">{&lt;Type.UNION: &#39;UNION&#39;&gt;, &lt;Type.OBJECT: &#39;OBJECT&#39;&gt;, &lt;Type.NESTED: &#39;NESTED&#39;&gt;, &lt;Type.STRUCT: &#39;STRUCT&#39;&gt;}</span> <span class="default_value">{&lt;Type.NESTED: &#39;NESTED&#39;&gt;, &lt;Type.UNION: &#39;UNION&#39;&gt;, &lt;Type.STRUCT: &#39;STRUCT&#39;&gt;, &lt;Type.OBJECT: &#39;OBJECT&#39;&gt;}</span>
</div> </div>
@ -63349,7 +63349,7 @@ Otherwise, this resets the expressions.</li>
<div id="DataType.ARRAY_TYPES" class="classattr"> <div id="DataType.ARRAY_TYPES" class="classattr">
<div class="attr variable"> <div class="attr variable">
<span class="name">ARRAY_TYPES</span> = <span class="name">ARRAY_TYPES</span> =
<span class="default_value">{&lt;Type.LIST: &#39;LIST&#39;&gt;, &lt;Type.ARRAY: &#39;ARRAY&#39;&gt;}</span> <span class="default_value">{&lt;Type.ARRAY: &#39;ARRAY&#39;&gt;, &lt;Type.LIST: &#39;LIST&#39;&gt;}</span>
</div> </div>
@ -63362,7 +63362,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable"> <div class="attr variable">
<span class="name">NESTED_TYPES</span> = <span class="name">NESTED_TYPES</span> =
<input id="DataType.NESTED_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="DataType.NESTED_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.NESTED_TYPES-view-value"></label><span class="default_value">{&lt;Type.MAP: &#39;MAP&#39;&gt;, &lt;Type.STRUCT: &#39;STRUCT&#39;&gt;, &lt;Type.LIST: &#39;LIST&#39;&gt;, &lt;Type.UNION: &#39;UNION&#39;&gt;, &lt;Type.OBJECT: &#39;OBJECT&#39;&gt;, &lt;Type.NESTED: &#39;NESTED&#39;&gt;, &lt;Type.ARRAY: &#39;ARRAY&#39;&gt;}</span> <label class="view-value-button pdoc-button" for="DataType.NESTED_TYPES-view-value"></label><span class="default_value">{&lt;Type.OBJECT: &#39;OBJECT&#39;&gt;, &lt;Type.MAP: &#39;MAP&#39;&gt;, &lt;Type.LIST: &#39;LIST&#39;&gt;, &lt;Type.NESTED: &#39;NESTED&#39;&gt;, &lt;Type.UNION: &#39;UNION&#39;&gt;, &lt;Type.ARRAY: &#39;ARRAY&#39;&gt;, &lt;Type.STRUCT: &#39;STRUCT&#39;&gt;}</span>
</div> </div>
@ -63375,7 +63375,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable"> <div class="attr variable">
<span class="name">TEXT_TYPES</span> = <span class="name">TEXT_TYPES</span> =
<input id="DataType.TEXT_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="DataType.TEXT_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.TEXT_TYPES-view-value"></label><span class="default_value">{&lt;Type.NAME: &#39;NAME&#39;&gt;, &lt;Type.VARCHAR: &#39;VARCHAR&#39;&gt;, &lt;Type.TEXT: &#39;TEXT&#39;&gt;, &lt;Type.NVARCHAR: &#39;NVARCHAR&#39;&gt;, &lt;Type.CHAR: &#39;CHAR&#39;&gt;, &lt;Type.NCHAR: &#39;NCHAR&#39;&gt;}</span> <label class="view-value-button pdoc-button" for="DataType.TEXT_TYPES-view-value"></label><span class="default_value">{&lt;Type.NAME: &#39;NAME&#39;&gt;, &lt;Type.NVARCHAR: &#39;NVARCHAR&#39;&gt;, &lt;Type.VARCHAR: &#39;VARCHAR&#39;&gt;, &lt;Type.CHAR: &#39;CHAR&#39;&gt;, &lt;Type.NCHAR: &#39;NCHAR&#39;&gt;, &lt;Type.TEXT: &#39;TEXT&#39;&gt;}</span>
</div> </div>
@ -63388,7 +63388,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable"> <div class="attr variable">
<span class="name">SIGNED_INTEGER_TYPES</span> = <span class="name">SIGNED_INTEGER_TYPES</span> =
<input id="DataType.SIGNED_INTEGER_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="DataType.SIGNED_INTEGER_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.SIGNED_INTEGER_TYPES-view-value"></label><span class="default_value">{&lt;Type.MEDIUMINT: &#39;MEDIUMINT&#39;&gt;, &lt;Type.INT128: &#39;INT128&#39;&gt;, &lt;Type.INT: &#39;INT&#39;&gt;, &lt;Type.INT256: &#39;INT256&#39;&gt;, &lt;Type.BIGINT: &#39;BIGINT&#39;&gt;, &lt;Type.SMALLINT: &#39;SMALLINT&#39;&gt;, &lt;Type.TINYINT: &#39;TINYINT&#39;&gt;}</span> <label class="view-value-button pdoc-button" for="DataType.SIGNED_INTEGER_TYPES-view-value"></label><span class="default_value">{&lt;Type.MEDIUMINT: &#39;MEDIUMINT&#39;&gt;, &lt;Type.INT128: &#39;INT128&#39;&gt;, &lt;Type.BIGINT: &#39;BIGINT&#39;&gt;, &lt;Type.INT256: &#39;INT256&#39;&gt;, &lt;Type.SMALLINT: &#39;SMALLINT&#39;&gt;, &lt;Type.INT: &#39;INT&#39;&gt;, &lt;Type.TINYINT: &#39;TINYINT&#39;&gt;}</span>
</div> </div>
@ -63401,7 +63401,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable"> <div class="attr variable">
<span class="name">UNSIGNED_INTEGER_TYPES</span> = <span class="name">UNSIGNED_INTEGER_TYPES</span> =
<input id="DataType.UNSIGNED_INTEGER_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="DataType.UNSIGNED_INTEGER_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.UNSIGNED_INTEGER_TYPES-view-value"></label><span class="default_value">{&lt;Type.UMEDIUMINT: &#39;UMEDIUMINT&#39;&gt;, &lt;Type.USMALLINT: &#39;USMALLINT&#39;&gt;, &lt;Type.UINT256: &#39;UINT256&#39;&gt;, &lt;Type.UINT: &#39;UINT&#39;&gt;, &lt;Type.UINT128: &#39;UINT128&#39;&gt;, &lt;Type.UTINYINT: &#39;UTINYINT&#39;&gt;, &lt;Type.UBIGINT: &#39;UBIGINT&#39;&gt;}</span> <label class="view-value-button pdoc-button" for="DataType.UNSIGNED_INTEGER_TYPES-view-value"></label><span class="default_value">{&lt;Type.UMEDIUMINT: &#39;UMEDIUMINT&#39;&gt;, &lt;Type.UINT256: &#39;UINT256&#39;&gt;, &lt;Type.UINT128: &#39;UINT128&#39;&gt;, &lt;Type.USMALLINT: &#39;USMALLINT&#39;&gt;, &lt;Type.UTINYINT: &#39;UTINYINT&#39;&gt;, &lt;Type.UINT: &#39;UINT&#39;&gt;, &lt;Type.UBIGINT: &#39;UBIGINT&#39;&gt;}</span>
</div> </div>
@ -63414,7 +63414,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable"> <div class="attr variable">
<span class="name">INTEGER_TYPES</span> = <span class="name">INTEGER_TYPES</span> =
<input id="DataType.INTEGER_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="DataType.INTEGER_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.INTEGER_TYPES-view-value"></label><span class="default_value">{&lt;Type.UMEDIUMINT: &#39;UMEDIUMINT&#39;&gt;, &lt;Type.BIT: &#39;BIT&#39;&gt;, &lt;Type.INT128: &#39;INT128&#39;&gt;, &lt;Type.MEDIUMINT: &#39;MEDIUMINT&#39;&gt;, &lt;Type.UBIGINT: &#39;UBIGINT&#39;&gt;, &lt;Type.USMALLINT: &#39;USMALLINT&#39;&gt;, &lt;Type.INT: &#39;INT&#39;&gt;, &lt;Type.UINT256: &#39;UINT256&#39;&gt;, &lt;Type.INT256: &#39;INT256&#39;&gt;, &lt;Type.BIGINT: &#39;BIGINT&#39;&gt;, &lt;Type.UINT: &#39;UINT&#39;&gt;, &lt;Type.UINT128: &#39;UINT128&#39;&gt;, &lt;Type.UTINYINT: &#39;UTINYINT&#39;&gt;, &lt;Type.SMALLINT: &#39;SMALLINT&#39;&gt;, &lt;Type.TINYINT: &#39;TINYINT&#39;&gt;}</span> <label class="view-value-button pdoc-button" for="DataType.INTEGER_TYPES-view-value"></label><span class="default_value">{&lt;Type.UINT: &#39;UINT&#39;&gt;, &lt;Type.MEDIUMINT: &#39;MEDIUMINT&#39;&gt;, &lt;Type.INT128: &#39;INT128&#39;&gt;, &lt;Type.BIT: &#39;BIT&#39;&gt;, &lt;Type.BIGINT: &#39;BIGINT&#39;&gt;, &lt;Type.INT256: &#39;INT256&#39;&gt;, &lt;Type.SMALLINT: &#39;SMALLINT&#39;&gt;, &lt;Type.UMEDIUMINT: &#39;UMEDIUMINT&#39;&gt;, &lt;Type.UINT256: &#39;UINT256&#39;&gt;, &lt;Type.UINT128: &#39;UINT128&#39;&gt;, &lt;Type.USMALLINT: &#39;USMALLINT&#39;&gt;, &lt;Type.UTINYINT: &#39;UTINYINT&#39;&gt;, &lt;Type.INT: &#39;INT&#39;&gt;, &lt;Type.UBIGINT: &#39;UBIGINT&#39;&gt;, &lt;Type.TINYINT: &#39;TINYINT&#39;&gt;}</span>
</div> </div>
@ -63439,7 +63439,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable"> <div class="attr variable">
<span class="name">REAL_TYPES</span> = <span class="name">REAL_TYPES</span> =
<input id="DataType.REAL_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="DataType.REAL_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.REAL_TYPES-view-value"></label><span class="default_value">{&lt;Type.DOUBLE: &#39;DOUBLE&#39;&gt;, &lt;Type.DECIMAL128: &#39;DECIMAL128&#39;&gt;, &lt;Type.UDOUBLE: &#39;UDOUBLE&#39;&gt;, &lt;Type.FLOAT: &#39;FLOAT&#39;&gt;, &lt;Type.BIGDECIMAL: &#39;BIGDECIMAL&#39;&gt;, &lt;Type.DECIMAL: &#39;DECIMAL&#39;&gt;, &lt;Type.DECIMAL64: &#39;DECIMAL64&#39;&gt;, &lt;Type.UDECIMAL: &#39;UDECIMAL&#39;&gt;, &lt;Type.SMALLMONEY: &#39;SMALLMONEY&#39;&gt;, &lt;Type.DECIMAL256: &#39;DECIMAL256&#39;&gt;, &lt;Type.MONEY: &#39;MONEY&#39;&gt;, &lt;Type.DECIMAL32: &#39;DECIMAL32&#39;&gt;}</span> <label class="view-value-button pdoc-button" for="DataType.REAL_TYPES-view-value"></label><span class="default_value">{&lt;Type.DECIMAL256: &#39;DECIMAL256&#39;&gt;, &lt;Type.MONEY: &#39;MONEY&#39;&gt;, &lt;Type.DECIMAL32: &#39;DECIMAL32&#39;&gt;, &lt;Type.DOUBLE: &#39;DOUBLE&#39;&gt;, &lt;Type.DECIMAL: &#39;DECIMAL&#39;&gt;, &lt;Type.DECIMAL64: &#39;DECIMAL64&#39;&gt;, &lt;Type.UDECIMAL: &#39;UDECIMAL&#39;&gt;, &lt;Type.UDOUBLE: &#39;UDOUBLE&#39;&gt;, &lt;Type.BIGDECIMAL: &#39;BIGDECIMAL&#39;&gt;, &lt;Type.SMALLMONEY: &#39;SMALLMONEY&#39;&gt;, &lt;Type.FLOAT: &#39;FLOAT&#39;&gt;, &lt;Type.DECIMAL128: &#39;DECIMAL128&#39;&gt;}</span>
</div> </div>
@ -63452,7 +63452,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable"> <div class="attr variable">
<span class="name">NUMERIC_TYPES</span> = <span class="name">NUMERIC_TYPES</span> =
<input id="DataType.NUMERIC_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="DataType.NUMERIC_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.NUMERIC_TYPES-view-value"></label><span class="default_value">{&lt;Type.DOUBLE: &#39;DOUBLE&#39;&gt;, &lt;Type.UMEDIUMINT: &#39;UMEDIUMINT&#39;&gt;, &lt;Type.BIT: &#39;BIT&#39;&gt;, &lt;Type.DECIMAL64: &#39;DECIMAL64&#39;&gt;, &lt;Type.UDECIMAL: &#39;UDECIMAL&#39;&gt;, &lt;Type.INT: &#39;INT&#39;&gt;, &lt;Type.SMALLMONEY: &#39;SMALLMONEY&#39;&gt;, &lt;Type.INT256: &#39;INT256&#39;&gt;, &lt;Type.UINT: &#39;UINT&#39;&gt;, &lt;Type.UINT128: &#39;UINT128&#39;&gt;, &lt;Type.MONEY: &#39;MONEY&#39;&gt;, &lt;Type.UTINYINT: &#39;UTINYINT&#39;&gt;, &lt;Type.UBIGINT: &#39;UBIGINT&#39;&gt;, &lt;Type.SMALLINT: &#39;SMALLINT&#39;&gt;, &lt;Type.TINYINT: &#39;TINYINT&#39;&gt;, &lt;Type.DECIMAL32: &#39;DECIMAL32&#39;&gt;, &lt;Type.DECIMAL128: &#39;DECIMAL128&#39;&gt;, &lt;Type.UDOUBLE: &#39;UDOUBLE&#39;&gt;, &lt;Type.FLOAT: &#39;FLOAT&#39;&gt;, &lt;Type.INT128: &#39;INT128&#39;&gt;, &lt;Type.MEDIUMINT: &#39;MEDIUMINT&#39;&gt;, &lt;Type.BIGDECIMAL: &#39;BIGDECIMAL&#39;&gt;, &lt;Type.USMALLINT: &#39;USMALLINT&#39;&gt;, &lt;Type.UINT256: &#39;UINT256&#39;&gt;, &lt;Type.DECIMAL: &#39;DECIMAL&#39;&gt;, &lt;Type.DECIMAL256: &#39;DECIMAL256&#39;&gt;, &lt;Type.BIGINT: &#39;BIGINT&#39;&gt;}</span> <label class="view-value-button pdoc-button" for="DataType.NUMERIC_TYPES-view-value"></label><span class="default_value">{&lt;Type.INT128: &#39;INT128&#39;&gt;, &lt;Type.BIT: &#39;BIT&#39;&gt;, &lt;Type.BIGINT: &#39;BIGINT&#39;&gt;, &lt;Type.DECIMAL32: &#39;DECIMAL32&#39;&gt;, &lt;Type.UDOUBLE: &#39;UDOUBLE&#39;&gt;, &lt;Type.UINT: &#39;UINT&#39;&gt;, &lt;Type.UBIGINT: &#39;UBIGINT&#39;&gt;, &lt;Type.UDECIMAL: &#39;UDECIMAL&#39;&gt;, &lt;Type.DECIMAL128: &#39;DECIMAL128&#39;&gt;, &lt;Type.DECIMAL256: &#39;DECIMAL256&#39;&gt;, &lt;Type.MEDIUMINT: &#39;MEDIUMINT&#39;&gt;, &lt;Type.MONEY: &#39;MONEY&#39;&gt;, &lt;Type.INT256: &#39;INT256&#39;&gt;, &lt;Type.DOUBLE: &#39;DOUBLE&#39;&gt;, &lt;Type.SMALLINT: &#39;SMALLINT&#39;&gt;, &lt;Type.DECIMAL: &#39;DECIMAL&#39;&gt;, &lt;Type.UMEDIUMINT: &#39;UMEDIUMINT&#39;&gt;, &lt;Type.UINT256: &#39;UINT256&#39;&gt;, &lt;Type.DECIMAL64: &#39;DECIMAL64&#39;&gt;, &lt;Type.FLOAT: &#39;FLOAT&#39;&gt;, &lt;Type.UINT128: &#39;UINT128&#39;&gt;, &lt;Type.USMALLINT: &#39;USMALLINT&#39;&gt;, &lt;Type.UTINYINT: &#39;UTINYINT&#39;&gt;, &lt;Type.BIGDECIMAL: &#39;BIGDECIMAL&#39;&gt;, &lt;Type.SMALLMONEY: &#39;SMALLMONEY&#39;&gt;, &lt;Type.INT: &#39;INT&#39;&gt;, &lt;Type.TINYINT: &#39;TINYINT&#39;&gt;}</span>
</div> </div>
@ -63465,7 +63465,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable"> <div class="attr variable">
<span class="name">TEMPORAL_TYPES</span> = <span class="name">TEMPORAL_TYPES</span> =
<input id="DataType.TEMPORAL_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="DataType.TEMPORAL_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.TEMPORAL_TYPES-view-value"></label><span class="default_value">{&lt;Type.DATETIME2: &#39;DATETIME2&#39;&gt;, &lt;Type.TIME: &#39;TIME&#39;&gt;, &lt;Type.TIMETZ: &#39;TIMETZ&#39;&gt;, &lt;Type.DATE: &#39;DATE&#39;&gt;, &lt;Type.DATE32: &#39;DATE32&#39;&gt;, &lt;Type.TIMESTAMPNTZ: &#39;TIMESTAMPNTZ&#39;&gt;, &lt;Type.TIMESTAMP_MS: &#39;TIMESTAMP_MS&#39;&gt;, &lt;Type.TIMESTAMP: &#39;TIMESTAMP&#39;&gt;, &lt;Type.TIMESTAMP_NS: &#39;TIMESTAMP_NS&#39;&gt;, &lt;Type.DATETIME: &#39;DATETIME&#39;&gt;, &lt;Type.TIMESTAMPLTZ: &#39;TIMESTAMPLTZ&#39;&gt;, &lt;Type.TIMESTAMP_S: &#39;TIMESTAMP_S&#39;&gt;, &lt;Type.DATETIME64: &#39;DATETIME64&#39;&gt;, &lt;Type.TIMESTAMPTZ: &#39;TIMESTAMPTZ&#39;&gt;, &lt;Type.SMALLDATETIME: &#39;SMALLDATETIME&#39;&gt;}</span> <label class="view-value-button pdoc-button" for="DataType.TEMPORAL_TYPES-view-value"></label><span class="default_value">{&lt;Type.DATETIME: &#39;DATETIME&#39;&gt;, &lt;Type.DATETIME2: &#39;DATETIME2&#39;&gt;, &lt;Type.DATE: &#39;DATE&#39;&gt;, &lt;Type.DATE32: &#39;DATE32&#39;&gt;, &lt;Type.TIMESTAMPLTZ: &#39;TIMESTAMPLTZ&#39;&gt;, &lt;Type.DATETIME64: &#39;DATETIME64&#39;&gt;, &lt;Type.SMALLDATETIME: &#39;SMALLDATETIME&#39;&gt;, &lt;Type.TIMESTAMP: &#39;TIMESTAMP&#39;&gt;, &lt;Type.TIMESTAMPNTZ: &#39;TIMESTAMPNTZ&#39;&gt;, &lt;Type.TIMESTAMP_NS: &#39;TIMESTAMP_NS&#39;&gt;, &lt;Type.TIMESTAMPTZ: &#39;TIMESTAMPTZ&#39;&gt;, &lt;Type.TIMETZ: &#39;TIMETZ&#39;&gt;, &lt;Type.TIMESTAMP_MS: &#39;TIMESTAMP_MS&#39;&gt;, &lt;Type.TIMESTAMP_S: &#39;TIMESTAMP_S&#39;&gt;, &lt;Type.TIME: &#39;TIME&#39;&gt;}</span>
</div> </div>

View file

@ -12871,7 +12871,7 @@ Default: True</li>
<div id="Generator.PARAMETERIZABLE_TEXT_TYPES" class="classattr"> <div id="Generator.PARAMETERIZABLE_TEXT_TYPES" class="classattr">
<div class="attr variable"> <div class="attr variable">
<span class="name">PARAMETERIZABLE_TEXT_TYPES</span> = <span class="name">PARAMETERIZABLE_TEXT_TYPES</span> =
<span class="default_value">{&lt;Type.NVARCHAR: &#39;NVARCHAR&#39;&gt;, &lt;Type.CHAR: &#39;CHAR&#39;&gt;, &lt;Type.VARCHAR: &#39;VARCHAR&#39;&gt;, &lt;Type.NCHAR: &#39;NCHAR&#39;&gt;}</span> <span class="default_value">{&lt;Type.VARCHAR: &#39;VARCHAR&#39;&gt;, &lt;Type.NCHAR: &#39;NCHAR&#39;&gt;, &lt;Type.NVARCHAR: &#39;NVARCHAR&#39;&gt;, &lt;Type.CHAR: &#39;CHAR&#39;&gt;}</span>
</div> </div>

View file

@ -2003,7 +2003,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;year&#39;, &#39;day&#39;, &#39;month&#39;, &#39;quarter&#39;, &#39;week&#39;}</span> <span class="default_value">{&#39;day&#39;, &#39;year&#39;, &#39;year_month&#39;, &#39;quarter&#39;, &#39;week&#39;, &#39;month&#39;}</span>
</div> </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"> <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;laterals&#39;, &#39;locks&#39;, &#39;sort&#39;, &#39;limit&#39;, &#39;settings&#39;, &#39;qualify&#39;, &#39;distinct&#39;, &#39;with&#39;, &#39;match&#39;, &#39;pivots&#39;, &#39;having&#39;, &#39;sample&#39;, &#39;windows&#39;, &#39;operation_modifiers&#39;, &#39;offset&#39;, &#39;format&#39;, &#39;cluster&#39;, &#39;connect&#39;, &#39;into&#39;, &#39;options&#39;, &#39;prewhere&#39;, &#39;group&#39;, &#39;distribute&#39;}</span> <label class="view-value-button pdoc-button" for="UNMERGABLE_ARGS-view-value"></label><span class="default_value">{&#39;options&#39;, &#39;qualify&#39;, &#39;group&#39;, &#39;locks&#39;, &#39;having&#39;, &#39;prewhere&#39;, &#39;kind&#39;, &#39;offset&#39;, &#39;cluster&#39;, &#39;distinct&#39;, &#39;operation_modifiers&#39;, &#39;settings&#39;, &#39;windows&#39;, &#39;limit&#39;, &#39;match&#39;, &#39;into&#39;, &#39;laterals&#39;, &#39;distribute&#39;, &#39;format&#39;, &#39;sample&#39;, &#39;connect&#39;, &#39;with&#39;, &#39;sort&#39;, &#39;pivots&#39;}</span>
</div> </div>

View file

@ -3285,7 +3285,7 @@ prefix are statically known.</p>
<section id="JOINS"> <section id="JOINS">
<div class="attr variable"> <div class="attr variable">
<span class="name">JOINS</span> = <span class="name">JOINS</span> =
<span class="default_value">{(&#39;RIGHT&#39;, &#39;&#39;), (&#39;&#39;, &#39;INNER&#39;), (&#39;RIGHT&#39;, &#39;OUTER&#39;), (&#39;&#39;, &#39;&#39;)}</span> <span class="default_value">{(&#39;&#39;, &#39;&#39;), (&#39;RIGHT&#39;, &#39;OUTER&#39;), (&#39;RIGHT&#39;, &#39;&#39;), (&#39;&#39;, &#39;INNER&#39;)}</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

View file

@ -9516,7 +9516,7 @@
<div class="attr variable"> <div class="attr variable">
<span class="name">TOKENS_PRECEDING_HINT</span> = <span class="name">TOKENS_PRECEDING_HINT</span> =
<input id="Tokenizer.TOKENS_PRECEDING_HINT-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="Tokenizer.TOKENS_PRECEDING_HINT-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="Tokenizer.TOKENS_PRECEDING_HINT-view-value"></label><span class="default_value">{&lt;<a href="#TokenType.INSERT">TokenType.INSERT</a>: &#39;INSERT&#39;&gt;, &lt;<a href="#TokenType.DELETE">TokenType.DELETE</a>: &#39;DELETE&#39;&gt;, &lt;<a href="#TokenType.UPDATE">TokenType.UPDATE</a>: &#39;UPDATE&#39;&gt;, &lt;<a href="#TokenType.SELECT">TokenType.SELECT</a>: &#39;SELECT&#39;&gt;}</span> <label class="view-value-button pdoc-button" for="Tokenizer.TOKENS_PRECEDING_HINT-view-value"></label><span class="default_value">{&lt;<a href="#TokenType.SELECT">TokenType.SELECT</a>: &#39;SELECT&#39;&gt;, &lt;<a href="#TokenType.INSERT">TokenType.INSERT</a>: &#39;INSERT&#39;&gt;, &lt;<a href="#TokenType.UPDATE">TokenType.UPDATE</a>: &#39;UPDATE&#39;&gt;, &lt;<a href="#TokenType.DELETE">TokenType.DELETE</a>: &#39;DELETE&#39;&gt;}</span>
</div> </div>
@ -9555,7 +9555,7 @@
<div class="attr variable"> <div class="attr variable">
<span class="name">COMMANDS</span> = <span class="name">COMMANDS</span> =
<input id="Tokenizer.COMMANDS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="Tokenizer.COMMANDS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="Tokenizer.COMMANDS-view-value"></label><span class="default_value">{&lt;<a href="#TokenType.FETCH">TokenType.FETCH</a>: &#39;FETCH&#39;&gt;, &lt;<a href="#TokenType.COMMAND">TokenType.COMMAND</a>: &#39;COMMAND&#39;&gt;, &lt;<a href="#TokenType.SHOW">TokenType.SHOW</a>: &#39;SHOW&#39;&gt;, &lt;<a href="#TokenType.EXECUTE">TokenType.EXECUTE</a>: &#39;EXECUTE&#39;&gt;, &lt;<a href="#TokenType.RENAME">TokenType.RENAME</a>: &#39;RENAME&#39;&gt;}</span> <label class="view-value-button pdoc-button" for="Tokenizer.COMMANDS-view-value"></label><span class="default_value">{&lt;<a href="#TokenType.EXECUTE">TokenType.EXECUTE</a>: &#39;EXECUTE&#39;&gt;, &lt;<a href="#TokenType.SHOW">TokenType.SHOW</a>: &#39;SHOW&#39;&gt;, &lt;<a href="#TokenType.RENAME">TokenType.RENAME</a>: &#39;RENAME&#39;&gt;, &lt;<a href="#TokenType.COMMAND">TokenType.COMMAND</a>: &#39;COMMAND&#39;&gt;, &lt;<a href="#TokenType.FETCH">TokenType.FETCH</a>: &#39;FETCH&#39;&gt;}</span>
</div> </div>

View file

@ -525,6 +525,16 @@ class BigQuery(Dialect):
LOG_DEFAULTS_TO_LN = True LOG_DEFAULTS_TO_LN = True
SUPPORTS_IMPLICIT_UNNEST = True SUPPORTS_IMPLICIT_UNNEST = True
# BigQuery does not allow ASC/DESC to be used as an identifier
ID_VAR_TOKENS = parser.Parser.ID_VAR_TOKENS - {TokenType.ASC, TokenType.DESC}
ALIAS_TOKENS = parser.Parser.ALIAS_TOKENS - {TokenType.ASC, TokenType.DESC}
TABLE_ALIAS_TOKENS = parser.Parser.TABLE_ALIAS_TOKENS - {TokenType.ASC, TokenType.DESC}
COMMENT_TABLE_ALIAS_TOKENS = parser.Parser.COMMENT_TABLE_ALIAS_TOKENS - {
TokenType.ASC,
TokenType.DESC,
}
UPDATE_ALIAS_TOKENS = parser.Parser.UPDATE_ALIAS_TOKENS - {TokenType.ASC, TokenType.DESC}
FUNCTIONS = { FUNCTIONS = {
**parser.Parser.FUNCTIONS, **parser.Parser.FUNCTIONS,
"CONTAINS_SUBSTR": _build_contains_substring, "CONTAINS_SUBSTR": _build_contains_substring,

View file

@ -1096,6 +1096,7 @@ class ClickHouse(Dialect):
exp.RegexpLike: lambda self, e: self.func("match", e.this, e.expression), exp.RegexpLike: lambda self, e: self.func("match", e.this, e.expression),
exp.Rand: rename_func("randCanonical"), exp.Rand: rename_func("randCanonical"),
exp.StartsWith: rename_func("startsWith"), exp.StartsWith: rename_func("startsWith"),
exp.EndsWith: rename_func("endsWith"),
exp.StrPosition: lambda self, e: strposition_sql( exp.StrPosition: lambda self, e: strposition_sql(
self, self,
e, e,

View file

@ -36,6 +36,7 @@ from sqlglot.dialects.dialect import (
strposition_sql, strposition_sql,
count_if_to_sum, count_if_to_sum,
groupconcat_sql, groupconcat_sql,
Version,
) )
from sqlglot.generator import unsupported_args from sqlglot.generator import unsupported_args
from sqlglot.helper import is_int, seq_get from sqlglot.helper import is_int, seq_get
@ -255,6 +256,15 @@ def _levenshtein_sql(self: Postgres.Generator, expression: exp.Levenshtein) -> s
return rename_func(name)(self, expression) return rename_func(name)(self, expression)
def _versioned_anyvalue_sql(self: Postgres.Generator, expression: exp.AnyValue) -> str:
# https://www.postgresql.org/docs/16/functions-aggregate.html
# https://www.postgresql.org/about/featurematrix/
if self.dialect.version < Version("16.0"):
return any_value_to_max_sql(self, expression)
return rename_func("ANY_VALUE")(self, expression)
class Postgres(Dialect): class Postgres(Dialect):
INDEX_OFFSET = 1 INDEX_OFFSET = 1
TYPED_DIVISION = True TYPED_DIVISION = True
@ -546,7 +556,7 @@ class Postgres(Dialect):
TRANSFORMS = { TRANSFORMS = {
**generator.Generator.TRANSFORMS, **generator.Generator.TRANSFORMS,
exp.AnyValue: any_value_to_max_sql, exp.AnyValue: _versioned_anyvalue_sql,
exp.ArrayConcat: lambda self, e: self.arrayconcat_sql(e, name="ARRAY_CAT"), exp.ArrayConcat: lambda self, e: self.arrayconcat_sql(e, name="ARRAY_CAT"),
exp.ArrayFilter: filter_array_using_unnest, exp.ArrayFilter: filter_array_using_unnest,
exp.BitwiseXor: lambda self, e: self.binary(e, "#"), exp.BitwiseXor: lambda self, e: self.binary(e, "#"),

View file

@ -1,5 +1,6 @@
from __future__ import annotations from __future__ import annotations
from sqlglot.dialects.postgres import Postgres from sqlglot.dialects.postgres import Postgres
from sqlglot.generator import Generator
from sqlglot.tokens import TokenType from sqlglot.tokens import TokenType
import typing as t import typing as t
@ -72,3 +73,6 @@ class RisingWave(Postgres):
} }
EXPRESSION_PRECEDES_PROPERTIES_CREATABLES = {"SINK"} EXPRESSION_PRECEDES_PROPERTIES_CREATABLES = {"SINK"}
def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str:
return Generator.computedcolumnconstraint_sql(self, expression)

View file

@ -1019,6 +1019,7 @@ class Snowflake(Dialect):
exp.ArgMin: rename_func("MIN_BY"), exp.ArgMin: rename_func("MIN_BY"),
exp.ArrayConcat: lambda self, e: self.arrayconcat_sql(e, name="ARRAY_CAT"), exp.ArrayConcat: lambda self, e: self.arrayconcat_sql(e, name="ARRAY_CAT"),
exp.ArrayContains: lambda self, e: self.func("ARRAY_CONTAINS", e.expression, e.this), exp.ArrayContains: lambda self, e: self.func("ARRAY_CONTAINS", e.expression, e.this),
exp.ArrayIntersect: rename_func("ARRAY_INTERSECTION"),
exp.AtTimeZone: lambda self, e: self.func( exp.AtTimeZone: lambda self, e: self.func(
"CONVERT_TIMEZONE", e.args.get("zone"), e.this "CONVERT_TIMEZONE", e.args.get("zone"), e.this
), ),
@ -1094,11 +1095,13 @@ class Snowflake(Dialect):
exp.SHA: rename_func("SHA1"), exp.SHA: rename_func("SHA1"),
exp.StarMap: rename_func("OBJECT_CONSTRUCT"), exp.StarMap: rename_func("OBJECT_CONSTRUCT"),
exp.StartsWith: rename_func("STARTSWITH"), exp.StartsWith: rename_func("STARTSWITH"),
exp.EndsWith: rename_func("ENDSWITH"),
exp.StrPosition: lambda self, e: strposition_sql( exp.StrPosition: lambda self, e: strposition_sql(
self, e, func_name="CHARINDEX", supports_position=True self, e, func_name="CHARINDEX", supports_position=True
), ),
exp.StrToDate: lambda self, e: self.func("DATE", e.this, self.format_time(e)), exp.StrToDate: lambda self, e: self.func("DATE", e.this, self.format_time(e)),
exp.Stuff: rename_func("INSERT"), exp.Stuff: rename_func("INSERT"),
exp.StPoint: rename_func("ST_MAKEPOINT"),
exp.TimeAdd: date_delta_sql("TIMEADD"), exp.TimeAdd: date_delta_sql("TIMEADD"),
exp.Timestamp: no_timestamp_sql, exp.Timestamp: no_timestamp_sql,
exp.TimestampAdd: date_delta_sql("TIMESTAMPADD"), exp.TimestampAdd: date_delta_sql("TIMESTAMPADD"),

View file

@ -163,6 +163,7 @@ class Spark(Spark2):
move_partitioned_by_to_schema_columns, move_partitioned_by_to_schema_columns,
] ]
), ),
exp.EndsWith: rename_func("ENDSWITH"),
exp.PartitionedByProperty: lambda self, exp.PartitionedByProperty: lambda self,
e: f"PARTITIONED BY {self.wrap(self.expressions(sqls=[_normalize_partition(e) for e in e.this.expressions], skip_first=True))}", e: f"PARTITIONED BY {self.wrap(self.expressions(sqls=[_normalize_partition(e) for e in e.this.expressions], skip_first=True))}",
exp.StartsWith: rename_func("STARTSWITH"), exp.StartsWith: rename_func("STARTSWITH"),

View file

@ -99,6 +99,8 @@ class SQLite(Dialect):
KEYWORDS = tokens.Tokenizer.KEYWORDS.copy() KEYWORDS = tokens.Tokenizer.KEYWORDS.copy()
KEYWORDS.pop("/*+") KEYWORDS.pop("/*+")
COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE}
class Parser(parser.Parser): class Parser(parser.Parser):
FUNCTIONS = { FUNCTIONS = {
**parser.Parser.FUNCTIONS, **parser.Parser.FUNCTIONS,
@ -307,3 +309,10 @@ class SQLite(Dialect):
@unsupported_args("this") @unsupported_args("this")
def currentschema_sql(self, expression: exp.CurrentSchema) -> str: def currentschema_sql(self, expression: exp.CurrentSchema) -> str:
return "'main'" return "'main'"
def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
self.unsupported("SQLite does not support IGNORE NULLS.")
return self.sql(expression.this)
def respectnulls_sql(self, expression: exp.RespectNulls) -> str:
return self.sql(expression.this)

View file

@ -17,6 +17,19 @@ from sqlglot.helper import seq_get
from sqlglot.tokens import TokenType from sqlglot.tokens import TokenType
# https://docs.starrocks.io/docs/sql-reference/sql-functions/spatial-functions/st_distance_sphere/
def st_distance_sphere(self, expression: exp.StDistance) -> str:
point1 = expression.this
point2 = expression.expression
point1_x = self.func("ST_X", point1)
point1_y = self.func("ST_Y", point1)
point2_x = self.func("ST_X", point2)
point2_y = self.func("ST_Y", point2)
return self.func("ST_Distance_Sphere", point1_x, point1_y, point2_x, point2_y)
class StarRocks(MySQL): class StarRocks(MySQL):
STRICT_JSON_PATH_SYNTAX = False STRICT_JSON_PATH_SYNTAX = False
@ -132,6 +145,8 @@ class StarRocks(MySQL):
TRANSFORMS = { TRANSFORMS = {
**MySQL.Generator.TRANSFORMS, **MySQL.Generator.TRANSFORMS,
exp.Array: inline_array_sql, exp.Array: inline_array_sql,
exp.ArrayAgg: rename_func("ARRAY_AGG"),
exp.ArrayFilter: rename_func("ARRAY_FILTER"),
exp.ArrayToString: rename_func("ARRAY_JOIN"), exp.ArrayToString: rename_func("ARRAY_JOIN"),
exp.ApproxDistinct: approx_count_distinct_sql, exp.ApproxDistinct: approx_count_distinct_sql,
exp.DateDiff: lambda self, e: self.func( exp.DateDiff: lambda self, e: self.func(
@ -141,12 +156,12 @@ class StarRocks(MySQL):
exp.JSONExtract: arrow_json_extract_sql, exp.JSONExtract: arrow_json_extract_sql,
exp.Property: property_sql, exp.Property: property_sql,
exp.RegexpLike: rename_func("REGEXP"), exp.RegexpLike: rename_func("REGEXP"),
exp.StDistance: st_distance_sphere,
exp.StrToUnix: lambda self, e: self.func("UNIX_TIMESTAMP", e.this, self.format_time(e)), exp.StrToUnix: lambda self, e: self.func("UNIX_TIMESTAMP", e.this, self.format_time(e)),
exp.TimestampTrunc: lambda self, e: self.func("DATE_TRUNC", unit_to_str(e), e.this), exp.TimestampTrunc: lambda self, e: self.func("DATE_TRUNC", unit_to_str(e), e.this),
exp.TimeStrToDate: rename_func("TO_DATE"), exp.TimeStrToDate: rename_func("TO_DATE"),
exp.UnixToStr: lambda self, e: self.func("FROM_UNIXTIME", e.this, self.format_time(e)), exp.UnixToStr: lambda self, e: self.func("FROM_UNIXTIME", e.this, self.format_time(e)),
exp.UnixToTime: rename_func("FROM_UNIXTIME"), exp.UnixToTime: rename_func("FROM_UNIXTIME"),
exp.ArrayFilter: rename_func("ARRAY_FILTER"),
} }
TRANSFORMS.pop(exp.DateTrunc) TRANSFORMS.pop(exp.DateTrunc)

View file

@ -31,6 +31,7 @@ from sqlglot.helper import (
ensure_collection, ensure_collection,
ensure_list, ensure_list,
seq_get, seq_get,
split_num_words,
subclasses, subclasses,
to_bool, to_bool,
) )
@ -1993,11 +1994,6 @@ class OnUpdateColumnConstraint(ColumnConstraintKind):
pass pass
# https://docs.snowflake.com/en/sql-reference/sql/create-external-table#optional-parameters
class TransformColumnConstraint(ColumnConstraintKind):
pass
class PrimaryKeyColumnConstraint(ColumnConstraintKind): class PrimaryKeyColumnConstraint(ColumnConstraintKind):
arg_types = {"desc": False, "options": False} arg_types = {"desc": False, "options": False}
@ -5570,6 +5566,21 @@ class ArrayToString(Func):
_sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"] _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
class ArrayIntersect(Func):
arg_types = {"expressions": True}
is_var_len_args = True
_sql_names = ["ARRAY_INTERSECT", "ARRAY_INTERSECTION"]
class StPoint(Func):
arg_types = {"this": True, "expression": True, "null": False}
_sql_names = ["ST_POINT", "ST_MAKEPOINT"]
class StDistance(Func):
arg_types = {"this": True, "expression": True, "use_spheroid": False}
# https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#string # https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#string
class String(Func): class String(Func):
arg_types = {"this": True, "zone": False} arg_types = {"this": True, "zone": False}
@ -6706,6 +6717,11 @@ class StartsWith(Func):
arg_types = {"this": True, "expression": True} arg_types = {"this": True, "expression": True}
class EndsWith(Func):
_sql_names = ["ENDS_WITH", "ENDSWITH"]
arg_types = {"this": True, "expression": True}
class StrPosition(Func): class StrPosition(Func):
arg_types = { arg_types = {
"this": True, "this": True,
@ -7366,7 +7382,7 @@ def _apply_set_operation(
**opts, **opts,
) -> S: ) -> S:
return reduce( return reduce(
lambda x, y: set_operation(this=x, expression=y, distinct=distinct), lambda x, y: set_operation(this=x, expression=y, distinct=distinct, **opts),
(maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in expressions), (maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in expressions),
) )
@ -7962,7 +7978,15 @@ def to_table(
if isinstance(sql_path, Table): if isinstance(sql_path, Table):
return maybe_copy(sql_path, copy=copy) return maybe_copy(sql_path, copy=copy)
table = maybe_parse(sql_path, into=Table, dialect=dialect) try:
table = maybe_parse(sql_path, into=Table, dialect=dialect)
except ParseError:
catalog, db, this = split_num_words(sql_path, ".", 3)
if not this:
raise
table = table_(this, db=db, catalog=catalog)
for k, v in kwargs.items(): for k, v in kwargs.items():
table.set(k, v) table.set(k, v)
@ -8110,7 +8134,7 @@ def column(
@t.overload @t.overload
def column( def column(
col: str | Identifier, col: str | Identifier | Star,
table: t.Optional[str | Identifier] = None, table: t.Optional[str | Identifier] = None,
db: t.Optional[str | Identifier] = None, db: t.Optional[str | Identifier] = None,
catalog: t.Optional[str | Identifier] = None, catalog: t.Optional[str | Identifier] = None,
@ -8147,8 +8171,11 @@ def column(
Returns: Returns:
The new Column instance. The new Column instance.
""" """
if not isinstance(col, Star):
col = to_identifier(col, quoted=quoted, copy=copy)
this = Column( this = Column(
this=to_identifier(col, quoted=quoted, copy=copy), this=col,
table=to_identifier(table, quoted=quoted, copy=copy), table=to_identifier(table, quoted=quoted, copy=copy),
db=to_identifier(db, quoted=quoted, copy=copy), db=to_identifier(db, quoted=quoted, copy=copy),
catalog=to_identifier(catalog, quoted=quoted, copy=copy), catalog=to_identifier(catalog, quoted=quoted, copy=copy),

View file

@ -1018,6 +1018,7 @@ class Generator(metaclass=_Generator):
persisted = " PERSISTED" persisted = " PERSISTED"
else: else:
persisted = "" persisted = ""
return f"AS {this}{persisted}" return f"AS {this}{persisted}"
def autoincrementcolumnconstraint_sql(self, _) -> str: def autoincrementcolumnconstraint_sql(self, _) -> str:
@ -1079,9 +1080,6 @@ class Generator(metaclass=_Generator):
def notnullcolumnconstraint_sql(self, expression: exp.NotNullColumnConstraint) -> str: def notnullcolumnconstraint_sql(self, expression: exp.NotNullColumnConstraint) -> str:
return f"{'' if expression.args.get('allow_null') else 'NOT '}NULL" return f"{'' if expression.args.get('allow_null') else 'NOT '}NULL"
def transformcolumnconstraint_sql(self, expression: exp.TransformColumnConstraint) -> str:
return f"AS {self.sql(expression, 'this')}"
def primarykeycolumnconstraint_sql(self, expression: exp.PrimaryKeyColumnConstraint) -> str: def primarykeycolumnconstraint_sql(self, expression: exp.PrimaryKeyColumnConstraint) -> str:
desc = expression.args.get("desc") desc = expression.args.get("desc")
if desc is not None: if desc is not None:

View file

@ -936,6 +936,7 @@ class Parser(metaclass=_Parser):
"ORDER BY": lambda self, query: query.order_by(self._parse_order(), copy=False), "ORDER BY": lambda self, query: query.order_by(self._parse_order(), copy=False),
"LIMIT": lambda self, query: self._parse_pipe_syntax_limit(query), "LIMIT": lambda self, query: self._parse_pipe_syntax_limit(query),
"OFFSET": lambda self, query: query.offset(self._parse_offset(), copy=False), "OFFSET": lambda self, query: query.offset(self._parse_offset(), copy=False),
"AGGREGATE": lambda self, query: self._parse_pipe_syntax_aggregate(query),
} }
PROPERTY_PARSERS: t.Dict[str, t.Callable] = { PROPERTY_PARSERS: t.Dict[str, t.Callable] = {
@ -1143,6 +1144,78 @@ class Parser(metaclass=_Parser):
query.offset(offset, copy=False) query.offset(offset, copy=False)
return query return query
def _parse_pipe_syntax_aggregate_fields(self) -> t.Optional[exp.Expression]:
this = self._parse_assignment()
if self._match_text_seq("GROUP", "AND", advance=False):
return this
this = self._parse_alias(this)
if self._match_set((TokenType.ASC, TokenType.DESC), advance=False):
return self._parse_ordered(lambda: this)
return this
def _parse_pipe_syntax_aggregate_group_order_by(
self, query: exp.Query, group_by_exists: bool = True
) -> exp.Query:
expr = self._parse_csv(self._parse_pipe_syntax_aggregate_fields)
aggregates_or_groups, orders = [], []
for element in expr:
if isinstance(element, exp.Ordered):
this = element.this
if isinstance(this, exp.Alias):
element.set("this", this.args["alias"])
orders.append(element)
else:
this = element
aggregates_or_groups.append(this)
if group_by_exists and isinstance(query, exp.Select):
query = query.select(*aggregates_or_groups, copy=False).group_by(
*[element.args.get("alias", element) for element in aggregates_or_groups],
copy=False,
)
else:
query = exp.select(*aggregates_or_groups, copy=False).from_(
query.subquery(copy=False), copy=False
)
if orders:
return query.order_by(*orders, copy=False)
return query
def _parse_pipe_syntax_aggregate(self, query: exp.Query) -> exp.Query:
self._match_text_seq("AGGREGATE")
query = self._parse_pipe_syntax_aggregate_group_order_by(query, group_by_exists=False)
if self._match(TokenType.GROUP_BY) or (
self._match_text_seq("GROUP", "AND") and self._match(TokenType.ORDER_BY)
):
return self._parse_pipe_syntax_aggregate_group_order_by(query)
return query
def _parse_pipe_syntax_set_operator(
self, query: t.Optional[exp.Query]
) -> t.Optional[exp.Query]:
first_setop = self.parse_set_operation(this=query)
if not first_setop or not query:
return None
first_setop.this.pop()
distinct = first_setop.args.pop("distinct")
setops = [first_setop.expression.pop(), *self._parse_expressions()]
if isinstance(first_setop, exp.Union):
return query.union(*setops, distinct=distinct, **first_setop.args)
if isinstance(first_setop, exp.Except):
return query.except_(*setops, distinct=distinct, **first_setop.args)
return query.intersect(*setops, distinct=distinct, **first_setop.args)
def _parse_partitioned_by_bucket_or_truncate(self) -> exp.Expression: def _parse_partitioned_by_bucket_or_truncate(self) -> exp.Expression:
klass = ( klass = (
exp.PartitionedByBucket exp.PartitionedByBucket
@ -5900,7 +5973,7 @@ class Parser(metaclass=_Parser):
constraints.append( constraints.append(
self.expression( self.expression(
exp.ColumnConstraint, exp.ColumnConstraint,
kind=exp.TransformColumnConstraint(this=self._parse_disjunction()), kind=exp.ComputedColumnConstraint(this=self._parse_disjunction()),
) )
) )
@ -7163,11 +7236,18 @@ class Parser(metaclass=_Parser):
return this return this
def _parse_pipe_syntax_query(self, query: exp.Select) -> exp.Query: def _parse_pipe_syntax_query(self, query: exp.Query) -> t.Optional[exp.Query]:
while self._match(TokenType.PIPE_GT): while self._match(TokenType.PIPE_GT):
start = self._curr
parser = self.PIPE_SYNTAX_TRANSFORM_PARSERS.get(self._curr.text.upper()) parser = self.PIPE_SYNTAX_TRANSFORM_PARSERS.get(self._curr.text.upper())
if not parser: if not parser:
self.raise_error(f"Unsupported pipe syntax operator: '{self._curr.text.upper()}'.") set_op_query = self._parse_pipe_syntax_set_operator(query)
if not set_op_query:
self._retreat(start)
self.raise_error(f"Unsupported pipe syntax operator: '{start.text.upper()}'.")
break
query = set_op_query
else: else:
query = parser(self, query) query = parser(self, query)

View file

@ -1,7 +1,7 @@
use crate::settings::TokenType; use crate::settings::TokenType;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::{PyList, PyString}; use pyo3::types::{PyList, PyString};
use pyo3::{pyclass, Py, PyObject, Python}; use pyo3::{pyclass, pymethods, Py, PyObject, Python};
#[derive(Debug)] #[derive(Debug)]
#[pyclass] #[pyclass]
@ -57,3 +57,25 @@ impl Token {
}); });
} }
} }
#[pymethods]
impl Token {
fn __repr__(&self, py: Python) -> PyResult<String> {
let text = self.text.bind(py).to_str()?;
let comments = self.comments.bind(py);
let token_type_str = self.token_type_py.bind(py).str()?;
let comments_repr = comments.repr()?;
let comments_str = comments_repr.to_str()?;
Ok(format!(
"<Token token_type: {}, text: {}, line: {}, col: {}, start: {}, end: {}, comments: {}>",
token_type_str,
text,
self.line,
self.col,
self.start,
self.end,
comments_str
))
}
}

View file

@ -462,6 +462,16 @@ class TestDialect(Validator):
"CAST('127.0.0.1/32' AS INET)", "CAST('127.0.0.1/32' AS INET)",
read={"postgres": "INET '127.0.0.1/32'"}, read={"postgres": "INET '127.0.0.1/32'"},
) )
self.assertIsNotNone(
self.validate_identity("CREATE TABLE foo (bar INT AS (foo))").find(
exp.ComputedColumnConstraint
)
)
self.assertIsNotNone(
self.validate_identity(
"CREATE TABLE foo (t1 INT, t2 INT, bar INT AS (t1 * t2 * 2))"
).find(exp.ComputedColumnConstraint)
)
def test_ddl(self): def test_ddl(self):
self.validate_all( self.validate_all(
@ -1304,6 +1314,32 @@ class TestDialect(Validator):
}, },
) )
self.validate_all(
"ARRAY_INTERSECT(x, y)",
read={
"hive": "ARRAY_INTERSECT(x, y)",
"spark2": "ARRAY_INTERSECT(x, y)",
"spark": "ARRAY_INTERSECT(x, y)",
"databricks": "ARRAY_INTERSECT(x, y)",
"presto": "ARRAY_INTERSECT(x, y)",
"trino": "ARRAY_INTERSECT(x, y)",
"snowflake": "ARRAY_INTERSECTION(x, y)",
"starrocks": "ARRAY_INTERSECT(x, y)",
},
write={
"hive": "ARRAY_INTERSECT(x, y)",
"spark2": "ARRAY_INTERSECT(x, y)",
"spark": "ARRAY_INTERSECT(x, y)",
"databricks": "ARRAY_INTERSECT(x, y)",
"presto": "ARRAY_INTERSECT(x, y)",
"trino": "ARRAY_INTERSECT(x, y)",
"snowflake": "ARRAY_INTERSECTION(x, y)",
"starrocks": "ARRAY_INTERSECT(x, y)",
},
)
self.validate_identity("SELECT ARRAY_INTERSECT(x, y, z)")
def test_order_by(self): def test_order_by(self):
self.validate_identity( self.validate_identity(
"SELECT c FROM t ORDER BY a, b,", "SELECT c FROM t ORDER BY a, b,",
@ -3528,3 +3564,81 @@ FROM subquery2""",
f"FROM x |> SELECT x1, x2 |> WHERE x1 > 0 |> WHERE x2 > 0 |> ORDER BY x1, x2 |> {option}", f"FROM x |> SELECT x1, x2 |> WHERE x1 > 0 |> WHERE x2 > 0 |> ORDER BY x1, x2 |> {option}",
f"SELECT x1, x2 FROM (SELECT * FROM x) WHERE x1 > 0 AND x2 > 0 ORDER BY x1, x2 {option}", f"SELECT x1, x2 FROM (SELECT * FROM x) WHERE x1 > 0 AND x2 > 0 ORDER BY x1, x2 {option}",
) )
self.validate_identity(
"FROM x |> AGGREGATE SUM(x1), MAX(x2), MIN(x3)",
"SELECT SUM(x1), MAX(x2), MIN(x3) FROM (SELECT * FROM x)",
)
self.validate_identity(
"FROM x |> AGGREGATE SUM(x1) AS s_x1 |> SELECT s_x1",
"SELECT s_x1 FROM (SELECT SUM(x1) AS s_x1 FROM (SELECT * FROM x))",
)
self.validate_identity(
"FROM x |> AGGREGATE SUM(x1), MAX(x2), MIN(x3) GROUP BY x4, x5",
"SELECT SUM(x1), MAX(x2), MIN(x3), x4, x5 FROM (SELECT * FROM x) GROUP BY x4, x5",
)
self.validate_identity(
"FROM x |> AGGREGATE SUM(x1), MAX(x2), MIN(x3) GROUP BY x4 AS a_x4, x5 AS a_x5",
"SELECT SUM(x1), MAX(x2), MIN(x3), x4 AS a_x4, x5 AS a_x5 FROM (SELECT * FROM x) GROUP BY a_x4, a_x5",
)
self.validate_identity(
"FROM x |> AGGREGATE SUM(x1) as s_x1 GROUP BY x1 |> SELECT s_x1, x1 as ss_x1",
"SELECT s_x1, x1 AS ss_x1 FROM (SELECT SUM(x1) AS s_x1, x1 FROM (SELECT * FROM x) GROUP BY x1)",
)
self.validate_identity(
"FROM x |> AGGREGATE SUM(x1) GROUP", "SELECT SUM(x1) AS GROUP FROM (SELECT * FROM x)"
)
for order_option in ("ASC", "DESC", "ASC NULLS LAST", "DESC NULLS FIRST"):
with self.subTest(f"Testing pipe syntax AGGREGATE for order option: {order_option}"):
self.validate_all(
f"SELECT SUM(x1) AS x_s FROM (SELECT * FROM x) ORDER BY x_s {order_option}",
read={
"bigquery": f"FROM x |> AGGREGATE SUM(x1) AS x_s {order_option}",
},
)
self.validate_all(
f"SELECT SUM(x1) AS x_s, x1 AS g_x1 FROM (SELECT * FROM x) GROUP BY g_x1 ORDER BY x_s {order_option}",
read={
"bigquery": f"FROM x |> AGGREGATE SUM(x1) AS x_s {order_option} GROUP BY x1 AS g_x1",
},
)
with self.subTest(
f"Testing pipe syntax AGGREGATE with GROUP AND ORDER BY for order option: {order_option}"
):
self.validate_all(
f"SELECT g_x1, x_s FROM (SELECT SUM(x1) AS x_s, x1 AS g_x1 FROM (SELECT * FROM x) GROUP BY g_x1 ORDER BY g_x1 {order_option})",
read={
"bigquery": f"FROM x |> AGGREGATE SUM(x1) AS x_s GROUP AND ORDER BY x1 AS g_x1 {order_option} |> SELECT g_x1, x_s",
},
)
for op_operator in (
"UNION ALL",
"UNION DISTINCT",
"INTERSECT DISTINCT",
"EXCEPT DISTINCT",
):
with self.subTest(f"Testing pipe syntax SET OPERATORS: {op_operator}"):
self.validate_all(
f"FROM x|> {op_operator} (SELECT y1 FROM y), (SELECT z1 FROM z)",
write={
"bigquery": f"SELECT * FROM x {op_operator} (SELECT y1 FROM y) {op_operator} (SELECT z1 FROM z)",
},
)
for op_prefix in ("LEFT OUTER", "FULL OUTER"):
for op_operator in (
"UNION ALL",
"UNION DISTINCT",
"INTERSECT DISTINCT",
"EXCEPT DISTINCT",
):
for suffix_operator in ("BY NAME", "CORRESPONDING"):
with self.subTest(
f"Testing pipe syntax SET OPERATORS: {op_prefix} {op_operator} {suffix_operator}"
):
self.validate_all(
f"FROM x|> SELECT x1, x2 FROM x |> {op_prefix} {op_operator} {suffix_operator} (SELECT y1, y2 FROM y), (SELECT z1, z2 FROM z)",
write={
"bigquery": f"SELECT x1, x2 FROM (SELECT * FROM x) {op_prefix} {op_operator} BY NAME (SELECT y1, y2 FROM y) {op_prefix} {op_operator} BY NAME (SELECT z1, z2 FROM z)",
},
)

View file

@ -9,13 +9,6 @@ class TestDuckDB(Validator):
dialect = "duckdb" dialect = "duckdb"
def test_duckdb(self): def test_duckdb(self):
self.validate_identity("SELECT * FROM my_ducklake.demo AT (VERSION => 2)")
self.validate_identity("SELECT UUIDV7()")
self.validate_identity("SELECT TRY(LOG(0))")
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): with self.assertRaises(ParseError):
parse_one("1 //", read="duckdb") parse_one("1 //", read="duckdb")
@ -36,6 +29,20 @@ class TestDuckDB(Validator):
"STRUCT(k TEXT, v STRUCT(v_str TEXT, v_int INT, v_int_arr INT[]))[]", "STRUCT(k TEXT, v STRUCT(v_str TEXT, v_int INT, v_int_arr INT[]))[]",
) )
self.validate_all(
"SELECT FIRST_VALUE(c IGNORE NULLS) OVER (PARTITION BY gb ORDER BY ob) FROM t",
write={
"duckdb": "SELECT FIRST_VALUE(c IGNORE NULLS) OVER (PARTITION BY gb ORDER BY ob) FROM t",
"sqlite": UnsupportedError,
},
)
self.validate_all(
"SELECT FIRST_VALUE(c RESPECT NULLS) OVER (PARTITION BY gb ORDER BY ob) FROM t",
write={
"duckdb": "SELECT FIRST_VALUE(c RESPECT NULLS) OVER (PARTITION BY gb ORDER BY ob) FROM t",
"sqlite": "SELECT FIRST_VALUE(c) OVER (PARTITION BY gb ORDER BY ob NULLS LAST) FROM t",
},
)
self.validate_all( self.validate_all(
"CAST(x AS UUID)", "CAST(x AS UUID)",
write={ write={
@ -264,6 +271,12 @@ class TestDuckDB(Validator):
parse_one("a // b", read="duckdb").assert_is(exp.IntDiv).sql(dialect="duckdb"), "a // b" parse_one("a // b", read="duckdb").assert_is(exp.IntDiv).sql(dialect="duckdb"), "a // b"
) )
self.validate_identity("SELECT * FROM my_ducklake.demo AT (VERSION => 2)")
self.validate_identity("SELECT UUIDV7()")
self.validate_identity("SELECT TRY(LOG(0))")
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)")
self.validate_identity("CAST(x AS FOO)") self.validate_identity("CAST(x AS FOO)")
self.validate_identity("SELECT UNNEST([1, 2])").selects[0].assert_is(exp.UDTF) self.validate_identity("SELECT UNNEST([1, 2])").selects[0].assert_is(exp.UDTF)
self.validate_identity("'red' IN flags").args["field"].assert_is(exp.Column) self.validate_identity("'red' IN flags").args["field"].assert_is(exp.Column)

View file

@ -22,6 +22,7 @@ class TestPostgres(Validator):
expected_sql = "ARRAY[\n x" + (",\n x" * 27) + "\n]" expected_sql = "ARRAY[\n x" + (",\n x" * 27) + "\n]"
self.validate_identity(sql, expected_sql, pretty=True) self.validate_identity(sql, expected_sql, pretty=True)
self.validate_identity("SELECT ST_DISTANCE(gg1, gg2, FALSE) AS sphere_dist")
self.validate_identity("SHA384(x)") self.validate_identity("SHA384(x)")
self.validate_identity("1.x", "1. AS x") self.validate_identity("1.x", "1. AS x")
self.validate_identity("|/ x", "SQRT(x)") self.validate_identity("|/ x", "SQRT(x)")
@ -908,6 +909,18 @@ FROM json_data, field_ids""",
}, },
) )
# Postgres introduced ANY_VALUE in version 16
self.validate_all(
"SELECT ANY_VALUE(1) AS col",
write={
"postgres": "SELECT ANY_VALUE(1) AS col",
"postgres, version=16": "SELECT ANY_VALUE(1) AS col",
"postgres, version=17.5": "SELECT ANY_VALUE(1) AS col",
"postgres, version=15": "SELECT MAX(1) AS col",
"postgres, version=13.9": "SELECT MAX(1) AS col",
},
)
def test_ddl(self): def test_ddl(self):
# Checks that user-defined types are parsed into DataType instead of Identifier # Checks that user-defined types are parsed into DataType instead of Identifier
self.parse_one("CREATE TABLE t (a udt)").this.expressions[0].args["kind"].assert_is( self.parse_one("CREATE TABLE t (a udt)").this.expressions[0].args["kind"].assert_is(

View file

@ -778,7 +778,7 @@ class TestPresto(Validator):
"hive": "FIRST(x)", "hive": "FIRST(x)",
"mysql": "ANY_VALUE(x)", "mysql": "ANY_VALUE(x)",
"oracle": "ANY_VALUE(x)", "oracle": "ANY_VALUE(x)",
"postgres": "MAX(x)", "postgres": "ANY_VALUE(x)",
"presto": "ARBITRARY(x)", "presto": "ARBITRARY(x)",
"redshift": "ANY_VALUE(x)", "redshift": "ANY_VALUE(x)",
"snowflake": "ANY_VALUE(x)", "snowflake": "ANY_VALUE(x)",

View file

@ -318,6 +318,13 @@ class TestSnowflake(Validator):
"SELECT * FROM xxx, yyy, zzz", "SELECT * FROM xxx, yyy, zzz",
) )
self.validate_all(
"SELECT ARRAY_INTERSECTION([1, 2], [2, 3])",
write={
"starrocks": "SELECT ARRAY_INTERSECT([1, 2], [2, 3])",
},
)
self.validate_all( self.validate_all(
"CREATE TABLE test_table (id NUMERIC NOT NULL AUTOINCREMENT)", "CREATE TABLE test_table (id NUMERIC NOT NULL AUTOINCREMENT)",
write={ write={
@ -1079,6 +1086,22 @@ class TestSnowflake(Validator):
}, },
) )
self.validate_all(
"SELECT ST_MAKEPOINT(10, 20)",
write={
"snowflake": "SELECT ST_MAKEPOINT(10, 20)",
"starrocks": "SELECT ST_POINT(10, 20)",
},
)
self.validate_all(
"SELECT ST_DISTANCE(a, b)",
write={
"snowflake": "SELECT ST_DISTANCE(a, b)",
"starrocks": "SELECT ST_DISTANCE_SPHERE(ST_X(a), ST_Y(a), ST_X(b), ST_Y(b))",
},
)
def test_null_treatment(self): def test_null_treatment(self):
self.validate_all( 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", 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",
@ -1687,12 +1710,6 @@ class TestSnowflake(Validator):
}, },
) )
self.assertIsNotNone(
self.validate_identity("CREATE TABLE foo (bar INT AS (foo))").find(
exp.TransformColumnConstraint
)
)
def test_user_defined_functions(self): def test_user_defined_functions(self):
self.validate_all( self.validate_all(
"CREATE FUNCTION a(x DATE, y BIGINT) RETURNS ARRAY LANGUAGE JAVASCRIPT AS $$ SELECT 1 $$", "CREATE FUNCTION a(x DATE, y BIGINT) RETURNS ARRAY LANGUAGE JAVASCRIPT AS $$ SELECT 1 $$",
@ -2013,6 +2030,26 @@ FROM persons AS p, LATERAL FLATTEN(input => p.c, path => 'contact') AS _flattene
"spark": "DESCRIBE db.table", "spark": "DESCRIBE db.table",
}, },
) )
self.validate_all(
"ENDSWITH('abc', 'c')",
read={
"bigquery": "ENDS_WITH('abc', 'c')",
"clickhouse": "endsWith('abc', 'c')",
"databricks": "ENDSWITH('abc', 'c')",
"duckdb": "ENDS_WITH('abc', 'c')",
"presto": "ENDS_WITH('abc', 'c')",
"spark": "ENDSWITH('abc', 'c')",
},
write={
"bigquery": "ENDS_WITH('abc', 'c')",
"clickhouse": "endsWith('abc', 'c')",
"databricks": "ENDSWITH('abc', 'c')",
"duckdb": "ENDS_WITH('abc', 'c')",
"presto": "ENDS_WITH('abc', 'c')",
"snowflake": "ENDSWITH('abc', 'c')",
"spark": "ENDSWITH('abc', 'c')",
},
)
def test_parse_like_any(self): def test_parse_like_any(self):
like = parse_one("a LIKE ANY fun('foo')", read="snowflake") like = parse_one("a LIKE ANY fun('foo')", read="snowflake")

View file

@ -113,6 +113,7 @@ class TestSQLite(Validator):
'CREATE TABLE "foo t" ("foo t id" TEXT NOT NULL, PRIMARY KEY ("foo t id"))', 'CREATE TABLE "foo t" ("foo t id" TEXT NOT NULL, PRIMARY KEY ("foo t id"))',
'CREATE TABLE "foo t" ("foo t id" TEXT NOT NULL PRIMARY KEY)', 'CREATE TABLE "foo t" ("foo t id" TEXT NOT NULL PRIMARY KEY)',
) )
self.validate_identity("REPLACE INTO foo (x, y) VALUES (1, 2)", check_command_warning=True)
def test_strftime(self): def test_strftime(self):
self.validate_identity("SELECT STRFTIME('%Y/%m/%d', 'now')") self.validate_identity("SELECT STRFTIME('%Y/%m/%d', 'now')")

View file

@ -9,6 +9,9 @@ class TestStarrocks(Validator):
self.validate_identity("SELECT ARRAY_JOIN([1, 3, 5, NULL], '_', 'NULL')") self.validate_identity("SELECT ARRAY_JOIN([1, 3, 5, NULL], '_', 'NULL')")
self.validate_identity("SELECT ARRAY_JOIN([1, 3, 5, NULL], '_')") self.validate_identity("SELECT ARRAY_JOIN([1, 3, 5, NULL], '_')")
self.validate_identity("ALTER TABLE a SWAP WITH b") self.validate_identity("ALTER TABLE a SWAP WITH b")
self.validate_identity("SELECT ARRAY_AGG(a) FROM x")
self.validate_identity("SELECT ST_POINT(10, 20)")
self.validate_identity("SELECT ST_DISTANCE_SPHERE(10.1, 20.2, 30.3, 40.4)")
def test_ddl(self): def test_ddl(self):
ddl_sqls = [ ddl_sqls = [

View file

@ -669,6 +669,8 @@ class TestExpressions(unittest.TestCase):
self.assertIsInstance(parse_one("ARRAY_AGG(a)"), exp.ArrayAgg) self.assertIsInstance(parse_one("ARRAY_AGG(a)"), exp.ArrayAgg)
self.assertIsInstance(parse_one("ARRAY_CONTAINS(a, 'a')"), exp.ArrayContains) self.assertIsInstance(parse_one("ARRAY_CONTAINS(a, 'a')"), exp.ArrayContains)
self.assertIsInstance(parse_one("ARRAY_SIZE(a)"), exp.ArraySize) self.assertIsInstance(parse_one("ARRAY_SIZE(a)"), exp.ArraySize)
self.assertIsInstance(parse_one("ARRAY_INTERSECTION([1, 2], [2, 3])"), exp.ArrayIntersect)
self.assertIsInstance(parse_one("ARRAY_INTERSECT([1, 2], [2, 3])"), exp.ArrayIntersect)
self.assertIsInstance(parse_one("AVG(a)"), exp.Avg) self.assertIsInstance(parse_one("AVG(a)"), exp.Avg)
self.assertIsInstance(parse_one("BEGIN DEFERRED TRANSACTION"), exp.Transaction) self.assertIsInstance(parse_one("BEGIN DEFERRED TRANSACTION"), exp.Transaction)
self.assertIsInstance(parse_one("CEIL(a)"), exp.Ceil) self.assertIsInstance(parse_one("CEIL(a)"), exp.Ceil)
@ -710,6 +712,8 @@ class TestExpressions(unittest.TestCase):
self.assertIsInstance(parse_one("ROUND(a)"), exp.Round) self.assertIsInstance(parse_one("ROUND(a)"), exp.Round)
self.assertIsInstance(parse_one("ROUND(a, 2)"), exp.Round) self.assertIsInstance(parse_one("ROUND(a, 2)"), exp.Round)
self.assertIsInstance(parse_one("SPLIT(a, 'test')"), exp.Split) self.assertIsInstance(parse_one("SPLIT(a, 'test')"), exp.Split)
self.assertIsInstance(parse_one("ST_POINT(10, 20)"), exp.StPoint)
self.assertIsInstance(parse_one("ST_DISTANCE(a, b)"), exp.StDistance)
self.assertIsInstance(parse_one("STR_POSITION(a, 'test')"), exp.StrPosition) self.assertIsInstance(parse_one("STR_POSITION(a, 'test')"), exp.StrPosition)
self.assertIsInstance(parse_one("STR_TO_UNIX(a, 'format')"), exp.StrToUnix) self.assertIsInstance(parse_one("STR_TO_UNIX(a, 'format')"), exp.StrToUnix)
self.assertIsInstance(parse_one("STRUCT_EXTRACT(a, 'test')"), exp.StructExtract) self.assertIsInstance(parse_one("STRUCT_EXTRACT(a, 'test')"), exp.StructExtract)
@ -752,6 +756,9 @@ class TestExpressions(unittest.TestCase):
self.assertIsInstance(parse_one("ADD_MONTHS(a, b)"), exp.AddMonths) self.assertIsInstance(parse_one("ADD_MONTHS(a, b)"), exp.AddMonths)
def test_column(self): def test_column(self):
column = exp.column(exp.Star(), table="t")
self.assertEqual(column.sql(), "t.*")
column = parse_one("a.b.c.d") column = parse_one("a.b.c.d")
self.assertEqual(column.catalog, "a") self.assertEqual(column.catalog, "a")
self.assertEqual(column.db, "b") self.assertEqual(column.db, "b")
@ -987,15 +994,20 @@ FROM foo""",
self.assertEqual(table_only.name, "table_name") self.assertEqual(table_only.name, "table_name")
self.assertIsNone(table_only.args.get("db")) self.assertIsNone(table_only.args.get("db"))
self.assertIsNone(table_only.args.get("catalog")) self.assertIsNone(table_only.args.get("catalog"))
db_and_table = exp.to_table("db.table_name") db_and_table = exp.to_table("db.table_name")
self.assertEqual(db_and_table.name, "table_name") self.assertEqual(db_and_table.name, "table_name")
self.assertEqual(db_and_table.args.get("db"), exp.to_identifier("db")) self.assertEqual(db_and_table.args.get("db"), exp.to_identifier("db"))
self.assertIsNone(db_and_table.args.get("catalog")) self.assertIsNone(db_and_table.args.get("catalog"))
catalog_db_and_table = exp.to_table("catalog.db.table_name") catalog_db_and_table = exp.to_table("catalog.db.table_name")
self.assertEqual(catalog_db_and_table.name, "table_name") self.assertEqual(catalog_db_and_table.name, "table_name")
self.assertEqual(catalog_db_and_table.args.get("db"), exp.to_identifier("db")) self.assertEqual(catalog_db_and_table.args.get("db"), exp.to_identifier("db"))
self.assertEqual(catalog_db_and_table.args.get("catalog"), exp.to_identifier("catalog")) self.assertEqual(catalog_db_and_table.args.get("catalog"), exp.to_identifier("catalog"))
table_only_unsafe_identifier = exp.to_table("3e")
self.assertEqual(table_only_unsafe_identifier.sql(), '"3e"')
def test_to_column(self): def test_to_column(self):
column_only = exp.to_column("column_name") column_only = exp.to_column("column_name")
self.assertEqual(column_only.name, "column_name") self.assertEqual(column_only.name, "column_name")

View file

@ -201,3 +201,10 @@ x"""
self.assertEqual(len(partial_tokens), 1) self.assertEqual(len(partial_tokens), 1)
self.assertEqual(partial_tokens[0].token_type, TokenType.VAR) self.assertEqual(partial_tokens[0].token_type, TokenType.VAR)
self.assertEqual(partial_tokens[0].text, "foo") self.assertEqual(partial_tokens[0].text, "foo")
def test_token_repr(self):
# Ensures both the Python and the Rust tokenizer produce a human-friendly representation
self.assertEqual(
repr(Tokenizer().tokenize("foo")),
"[<Token token_type: TokenType.VAR, text: foo, line: 1, col: 3, start: 0, end: 2, comments: []>]",
)