1
0
Fork 0

Merging upstream version 26.16.4.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-04 09:27:42 +02:00
parent c0dccc98e9
commit 542c175872
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
57 changed files with 54950 additions and 53265 deletions

View file

@ -1,6 +1,35 @@
Changelog
=========
## [v26.16.3] - 2025-05-01
### :boom: BREAKING CHANGES
- due to [`f5358d8`](https://github.com/tobymao/sqlglot/commit/f5358d8a3e2743b5ac0d540f10502d333ad4e082) - add support for GET statements *(PR [#5019](https://github.com/tobymao/sqlglot/pull/5019) by [@eruditmorina](https://github.com/eruditmorina))*:
add support for GET statements (#5019)
### :sparkles: New Features
- [`6010302`](https://github.com/tobymao/sqlglot/commit/60103020879db5f23a6c4a1775848e31cce13415) - **postgres**: transpile QUARTER interval unit *(PR [#5015](https://github.com/tobymao/sqlglot/pull/5015) by [@georgesittas](https://github.com/georgesittas))*
- :arrow_lower_right: *addresses issue [#5013](https://github.com/tobymao/sqlglot/issues/5013) opened by [@Wiill007](https://github.com/Wiill007)*
- [`f5358d8`](https://github.com/tobymao/sqlglot/commit/f5358d8a3e2743b5ac0d540f10502d333ad4e082) - **snowflake**: add support for GET statements *(PR [#5019](https://github.com/tobymao/sqlglot/pull/5019) by [@eruditmorina](https://github.com/eruditmorina))*
- [`df5ecdb`](https://github.com/tobymao/sqlglot/commit/df5ecdbebcdce491031538f6baa0f87ec7eefee8) - Include token refereces in the meta of identifier expressions *(PR [#5022](https://github.com/tobymao/sqlglot/pull/5022) by [@izeigerman](https://github.com/izeigerman))*
### :bug: Bug Fixes
- [`c594b63`](https://github.com/tobymao/sqlglot/commit/c594b630c1c940e9a47abfce1633b435a2607f13) - Add MAX_BY & MIN_BY to FUNCTION_PARSER *(PR [#5021](https://github.com/tobymao/sqlglot/pull/5021) by [@VaggelisD](https://github.com/VaggelisD))*
- :arrow_lower_right: *fixes issue [#5020](https://github.com/tobymao/sqlglot/issues/5020) opened by [@omerhadari](https://github.com/omerhadari)*
- [`c1c892c`](https://github.com/tobymao/sqlglot/commit/c1c892cebb89ddf29369ff3c7647f96d217acb71) - **parser**: parse column ops after no-paren type casting *(PR [#5025](https://github.com/tobymao/sqlglot/pull/5025) by [@georgesittas](https://github.com/georgesittas))*
- :arrow_lower_right: *fixes issue [#5024](https://github.com/tobymao/sqlglot/issues/5024) opened by [@MagdaSousa](https://github.com/MagdaSousa)*
## [v26.16.2] - 2025-04-24
### :sparkles: New Features
- [`5feae00`](https://github.com/tobymao/sqlglot/commit/5feae00ec7a4826285e7fd0be85d377cc0de09b5) - **databricks**: add support for the VOID type *(PR [#5012](https://github.com/tobymao/sqlglot/pull/5012) by [@georgesittas](https://github.com/georgesittas))*
### :wrench: Chores
- [`da90228`](https://github.com/tobymao/sqlglot/commit/da90228f1550715646106dd6f9a170d0973f138f) - put a lock around the lazy dialect module loading call *(PR [#5011](https://github.com/tobymao/sqlglot/pull/5011) by [@georgesittas](https://github.com/georgesittas))*
- :arrow_lower_right: *addresses issue [#5010](https://github.com/tobymao/sqlglot/issues/5010) opened by [@NickCrews](https://github.com/NickCrews)*
## [v26.16.1] - 2025-04-24
### :sparkles: New Features
- [`27a9fb2`](https://github.com/tobymao/sqlglot/commit/27a9fb26a1936512a09b8b09ed2656e22918f2c6) - **clickhouse**: Support parsing CTAS with alias *(PR [#5003](https://github.com/tobymao/sqlglot/pull/5003) by [@dorranh](https://github.com/dorranh))*
@ -6456,3 +6485,5 @@ Changelog
[v26.15.0]: https://github.com/tobymao/sqlglot/compare/v26.14.0...v26.15.0
[v26.16.0]: https://github.com/tobymao/sqlglot/compare/v26.15.0...v26.16.0
[v26.16.1]: https://github.com/tobymao/sqlglot/compare/v26.16.0...v26.16.1
[v26.16.2]: https://github.com/tobymao/sqlglot/compare/v26.16.1...v26.16.2
[v26.16.3]: https://github.com/tobymao/sqlglot/compare/v26.16.2...v26.16.3

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.16.1&#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">16</span><span class="p">,</span> <span class="mi">1</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.16.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">16</span><span class="p">,</span> <span class="mi">3</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.16.1&#39;</span>
<span class="default_value">&#39;26.16.3&#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, 16, 1)</span>
<span class="default_value">(26, 16, 3)</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.16.1&#39;</span>
<span class="default_value">&#39;26.16.3&#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, 16, 1)</span>
<span class="default_value">(26, 16, 3)</span>
</div>

View file

@ -298,56 +298,60 @@ dialect implementations in order to understand how their various components can
</span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a>
</span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a><span class="kn">import</span><span class="w"> </span><span class="nn">importlib</span>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a><span class="n">DIALECTS</span> <span class="o">=</span> <span class="p">[</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a> <span class="s2">&quot;Athena&quot;</span><span class="p">,</span>
</span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a> <span class="s2">&quot;BigQuery&quot;</span><span class="p">,</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> <span class="s2">&quot;ClickHouse&quot;</span><span class="p">,</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> <span class="s2">&quot;Databricks&quot;</span><span class="p">,</span>
</span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a> <span class="s2">&quot;Doris&quot;</span><span class="p">,</span>
</span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="s2">&quot;Drill&quot;</span><span class="p">,</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="s2">&quot;Druid&quot;</span><span class="p">,</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a> <span class="s2">&quot;DuckDB&quot;</span><span class="p">,</span>
</span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a> <span class="s2">&quot;Dune&quot;</span><span class="p">,</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a> <span class="s2">&quot;Hive&quot;</span><span class="p">,</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a> <span class="s2">&quot;Materialize&quot;</span><span class="p">,</span>
</span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a> <span class="s2">&quot;MySQL&quot;</span><span class="p">,</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> <span class="s2">&quot;Oracle&quot;</span><span class="p">,</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a> <span class="s2">&quot;Postgres&quot;</span><span class="p">,</span>
</span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a> <span class="s2">&quot;Presto&quot;</span><span class="p">,</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> <span class="s2">&quot;PRQL&quot;</span><span class="p">,</span>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a> <span class="s2">&quot;Redshift&quot;</span><span class="p">,</span>
</span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a> <span class="s2">&quot;RisingWave&quot;</span><span class="p">,</span>
</span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a> <span class="s2">&quot;Snowflake&quot;</span><span class="p">,</span>
</span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a> <span class="s2">&quot;Spark&quot;</span><span class="p">,</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> <span class="s2">&quot;Spark2&quot;</span><span class="p">,</span>
</span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> <span class="s2">&quot;SQLite&quot;</span><span class="p">,</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="s2">&quot;StarRocks&quot;</span><span class="p">,</span>
</span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a> <span class="s2">&quot;Tableau&quot;</span><span class="p">,</span>
</span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a> <span class="s2">&quot;Teradata&quot;</span><span class="p">,</span>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="s2">&quot;Trino&quot;</span><span class="p">,</span>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a> <span class="s2">&quot;TSQL&quot;</span><span class="p">,</span>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a><span class="p">]</span>
</span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a>
</span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a><span class="n">MODULE_BY_DIALECT</span> <span class="o">=</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">DIALECTS</span><span class="p">}</span>
</span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a><span class="n">DIALECT_MODULE_NAMES</span> <span class="o">=</span> <span class="n">MODULE_BY_DIALECT</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a>
</span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a><span class="n">MODULE_BY_ATTRIBUTE</span> <span class="o">=</span> <span class="p">{</span>
</span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a> <span class="o">**</span><span class="n">MODULE_BY_DIALECT</span><span class="p">,</span>
</span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a> <span class="s2">&quot;Dialect&quot;</span><span class="p">:</span> <span class="s2">&quot;dialect&quot;</span><span class="p">,</span>
</span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a> <span class="s2">&quot;Dialects&quot;</span><span class="p">:</span> <span class="s2">&quot;dialect&quot;</span><span class="p">,</span>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a><span class="p">}</span>
</span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a>
</span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a><span class="n">__all__</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">MODULE_BY_ATTRIBUTE</span><span class="p">)</span>
</span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a><span class="kn">import</span><span class="w"> </span><span class="nn">threading</span>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a>
</span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a><span class="n">DIALECTS</span> <span class="o">=</span> <span class="p">[</span>
</span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a> <span class="s2">&quot;Athena&quot;</span><span class="p">,</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> <span class="s2">&quot;BigQuery&quot;</span><span class="p">,</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> <span class="s2">&quot;ClickHouse&quot;</span><span class="p">,</span>
</span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a> <span class="s2">&quot;Databricks&quot;</span><span class="p">,</span>
</span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="s2">&quot;Doris&quot;</span><span class="p">,</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="s2">&quot;Drill&quot;</span><span class="p">,</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a> <span class="s2">&quot;Druid&quot;</span><span class="p">,</span>
</span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a> <span class="s2">&quot;DuckDB&quot;</span><span class="p">,</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a> <span class="s2">&quot;Dune&quot;</span><span class="p">,</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a> <span class="s2">&quot;Hive&quot;</span><span class="p">,</span>
</span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a> <span class="s2">&quot;Materialize&quot;</span><span class="p">,</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> <span class="s2">&quot;MySQL&quot;</span><span class="p">,</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a> <span class="s2">&quot;Oracle&quot;</span><span class="p">,</span>
</span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a> <span class="s2">&quot;Postgres&quot;</span><span class="p">,</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> <span class="s2">&quot;Presto&quot;</span><span class="p">,</span>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a> <span class="s2">&quot;PRQL&quot;</span><span class="p">,</span>
</span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a> <span class="s2">&quot;Redshift&quot;</span><span class="p">,</span>
</span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a> <span class="s2">&quot;RisingWave&quot;</span><span class="p">,</span>
</span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a> <span class="s2">&quot;Snowflake&quot;</span><span class="p">,</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> <span class="s2">&quot;Spark&quot;</span><span class="p">,</span>
</span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> <span class="s2">&quot;Spark2&quot;</span><span class="p">,</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="s2">&quot;SQLite&quot;</span><span class="p">,</span>
</span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a> <span class="s2">&quot;StarRocks&quot;</span><span class="p">,</span>
</span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a> <span class="s2">&quot;Tableau&quot;</span><span class="p">,</span>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="s2">&quot;Teradata&quot;</span><span class="p">,</span>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a> <span class="s2">&quot;Trino&quot;</span><span class="p">,</span>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a> <span class="s2">&quot;TSQL&quot;</span><span class="p">,</span>
</span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a><span class="p">]</span>
</span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a>
</span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a><span class="n">MODULE_BY_DIALECT</span> <span class="o">=</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">DIALECTS</span><span class="p">}</span>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a><span class="n">DIALECT_MODULE_NAMES</span> <span class="o">=</span> <span class="n">MODULE_BY_DIALECT</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
</span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a>
</span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a><span class="n">MODULE_BY_ATTRIBUTE</span> <span class="o">=</span> <span class="p">{</span>
</span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a> <span class="o">**</span><span class="n">MODULE_BY_DIALECT</span><span class="p">,</span>
</span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a> <span class="s2">&quot;Dialect&quot;</span><span class="p">:</span> <span class="s2">&quot;dialect&quot;</span><span class="p">,</span>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a> <span class="s2">&quot;Dialects&quot;</span><span class="p">:</span> <span class="s2">&quot;dialect&quot;</span><span class="p">,</span>
</span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a><span class="p">}</span>
</span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a>
</span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a><span class="n">__all__</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">MODULE_BY_ATTRIBUTE</span><span class="p">)</span>
</span><span id="L-107"><a href="#L-107"><span class="linenos">107</span></a>
</span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a><span class="k">def</span><span class="w"> </span><span class="fm">__getattr__</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
</span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a> <span class="n">module_name</span> <span class="o">=</span> <span class="n">MODULE_BY_ATTRIBUTE</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
</span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a> <span class="k">if</span> <span class="n">module_name</span><span class="p">:</span>
</span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a> <span class="n">module</span> <span class="o">=</span> <span class="n">importlib</span><span class="o">.</span><span class="n">import_module</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;sqlglot.dialects.</span><span class="si">{</span><span class="n">module_name</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a> <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
</span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a>
</span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a> <span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;module </span><span class="si">{</span><span class="vm">__name__</span><span class="si">}</span><span class="s2"> has no attribute </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a><span class="n">_import_lock</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Lock</span><span class="p">()</span>
</span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a>
</span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a>
</span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a><span class="k">def</span><span class="w"> </span><span class="fm">__getattr__</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
</span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a> <span class="n">module_name</span> <span class="o">=</span> <span class="n">MODULE_BY_ATTRIBUTE</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
</span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a> <span class="k">if</span> <span class="n">module_name</span><span class="p">:</span>
</span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a> <span class="k">with</span> <span class="n">_import_lock</span><span class="p">:</span>
</span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a> <span class="n">module</span> <span class="o">=</span> <span class="n">importlib</span><span class="o">.</span><span class="n">import_module</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;sqlglot.dialects.</span><span class="si">{</span><span class="n">module_name</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a> <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
</span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a>
</span><span id="L-118"><a href="#L-118"><span class="linenos">118</span></a> <span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;module </span><span class="si">{</span><span class="vm">__name__</span><span class="si">}</span><span class="s2"> has no attribute </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</span></pre></div>
@ -355,7 +359,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;139957621941120&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223654967424&#39;&gt;</span>
</div>
@ -367,7 +371,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;139957636579392&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223656927360&#39;&gt;</span>
</div>
@ -379,7 +383,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;139957636585248&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223660767264&#39;&gt;</span>
</div>
@ -391,7 +395,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;139957633660240&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223662982864&#39;&gt;</span>
</div>
@ -403,7 +407,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;139957637267712&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223660478944&#39;&gt;</span>
</div>
@ -415,7 +419,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;139957633690128&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223666653216&#39;&gt;</span>
</div>
@ -427,7 +431,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;139957633689072&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223666655952&#39;&gt;</span>
</div>
@ -439,7 +443,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;139957633610848&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223670315872&#39;&gt;</span>
</div>
@ -451,7 +455,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;139957624244448&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223670305216&#39;&gt;</span>
</div>
@ -463,7 +467,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;139957624250736&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223657243648&#39;&gt;</span>
</div>
@ -475,7 +479,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;139957624397856&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223657238608&#39;&gt;</span>
</div>
@ -487,7 +491,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;139957624395264&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223665565472&#39;&gt;</span>
</div>
@ -499,7 +503,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;139957624004256&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223662411296&#39;&gt;</span>
</div>
@ -511,7 +515,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;139957636826496&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223661003184&#39;&gt;</span>
</div>
@ -523,7 +527,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;139957629147248&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223666522720&#39;&gt;</span>
</div>
@ -535,7 +539,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;139957629148544&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223666526416&#39;&gt;</span>
</div>
@ -547,7 +551,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;139957626264144&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223669060368&#39;&gt;</span>
</div>
@ -559,7 +563,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;139957629643808&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223669070016&#39;&gt;</span>
</div>
@ -571,7 +575,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;139957629645296&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223661514208&#39;&gt;</span>
</div>
@ -583,7 +587,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;139957637172528&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223668511184&#39;&gt;</span>
</div>
@ -595,7 +599,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;139957637175264&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223668508640&#39;&gt;</span>
</div>
@ -607,7 +611,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;139957626373072&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223670717072&#39;&gt;</span>
</div>
@ -619,7 +623,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;139957629590240&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223665043152&#39;&gt;</span>
</div>
@ -631,7 +635,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;139957629591056&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223670678480&#39;&gt;</span>
</div>
@ -643,7 +647,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;139957624072336&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223661583152&#39;&gt;</span>
</div>
@ -655,7 +659,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;139957637093248&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223661585888&#39;&gt;</span>
</div>
@ -667,7 +671,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;139957637096128&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223666222752&#39;&gt;</span>
</div>
@ -679,7 +683,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;139957628556272&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223657831024&#39;&gt;</span>
</div>
@ -691,7 +695,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;139957633832832&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140223657831648&#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

@ -1129,7 +1129,7 @@ Default: True</li>
<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>
<dd id="Druid.Generator.get_put_sql" class="function"><a href="../generator.html#Generator.get_put_sql">get_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

@ -2763,7 +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>
<dd id="Python.Generator.get_put_sql" class="function"><a href="../generator.html#Generator.get_put_sql">get_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

@ -1956,7 +1956,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;quarter&#39;, &#39;day&#39;, &#39;month&#39;, &#39;week&#39;, &#39;year&#39;, &#39;year_month&#39;}</span>
<span class="default_value">{&#39;year&#39;, &#39;week&#39;, &#39;year_month&#39;, &#39;day&#39;, &#39;month&#39;, &#39;quarter&#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#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#JSONPathWildcard">sqlglot.expressions.JSONPathWildcard</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;}</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#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;, &lt;class &#39;<a href="expressions.html#JSONPathRoot">sqlglot.expressions.JSONPathRoot</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;format&#39;, &#39;laterals&#39;, &#39;match&#39;, &#39;options&#39;, &#39;sample&#39;, &#39;prewhere&#39;, &#39;group&#39;, &#39;offset&#39;, &#39;qualify&#39;, &#39;distribute&#39;, &#39;sort&#39;, &#39;operation_modifiers&#39;, &#39;cluster&#39;, &#39;distinct&#39;, &#39;having&#39;, &#39;with&#39;, &#39;connect&#39;, &#39;limit&#39;, &#39;pivots&#39;, &#39;windows&#39;, &#39;into&#39;, &#39;settings&#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;match&#39;, &#39;pivots&#39;, &#39;distinct&#39;, &#39;with&#39;, &#39;limit&#39;, &#39;into&#39;, &#39;connect&#39;, &#39;operation_modifiers&#39;, &#39;offset&#39;, &#39;having&#39;, &#39;distribute&#39;, &#39;sort&#39;, &#39;format&#39;, &#39;laterals&#39;, &#39;prewhere&#39;, &#39;locks&#39;, &#39;cluster&#39;, &#39;group&#39;, &#39;windows&#39;, &#39;kind&#39;, &#39;options&#39;, &#39;qualify&#39;, &#39;settings&#39;, &#39;sample&#39;}</span>
</div>

View file

@ -3186,7 +3186,7 @@ prefix are statically known.</p>
<div class="attr variable">
<span class="name">DATETRUNC_COMPARISONS</span> =
<input id="DATETRUNC_COMPARISONS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DATETRUNC_COMPARISONS-view-value"></label><span class="default_value">{&lt;class &#39;<a href="../expressions.html#NEQ">sqlglot.expressions.NEQ</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#GTE">sqlglot.expressions.GTE</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#EQ">sqlglot.expressions.EQ</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#LTE">sqlglot.expressions.LTE</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#GT">sqlglot.expressions.GT</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#In">sqlglot.expressions.In</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#LT">sqlglot.expressions.LT</a>&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="DATETRUNC_COMPARISONS-view-value"></label><span class="default_value">{&lt;class &#39;<a href="../expressions.html#EQ">sqlglot.expressions.EQ</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#LTE">sqlglot.expressions.LTE</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#GT">sqlglot.expressions.GT</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#In">sqlglot.expressions.In</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#LT">sqlglot.expressions.LT</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#NEQ">sqlglot.expressions.NEQ</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#GTE">sqlglot.expressions.GTE</a>&#39;&gt;}</span>
</div>
@ -3270,7 +3270,7 @@ prefix are statically known.</p>
<section id="JOINS">
<div class="attr variable">
<span class="name">JOINS</span> =
<span class="default_value">{(&#39;&#39;, &#39;INNER&#39;), (&#39;RIGHT&#39;, &#39;OUTER&#39;), (&#39;RIGHT&#39;, &#39;&#39;), (&#39;&#39;, &#39;&#39;)}</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>
</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 it is too large Load diff

View file

@ -645,14 +645,16 @@ class BigQuery(Dialect):
table_name += self._find_sql(start, self._prev)
this = exp.Identifier(this=table_name, quoted=this.args.get("quoted"))
this = exp.Identifier(
this=table_name, quoted=this.args.get("quoted")
).update_positions(this)
elif isinstance(this, exp.Literal):
table_name = this.name
if self._is_connected() and self._parse_var(any_token=True):
table_name += self._prev.text
this = exp.Identifier(this=table_name, quoted=True)
this = exp.Identifier(this=table_name, quoted=True).update_positions(this)
return this
@ -666,15 +668,23 @@ class BigQuery(Dialect):
# proj-1.db.tbl -- `1.` is tokenized as a float so we need to unravel it here
if not table.catalog:
if table.db:
previous_db = table.args["db"]
parts = table.db.split(".")
if len(parts) == 2 and not table.args["db"].quoted:
table.set("catalog", exp.Identifier(this=parts[0]))
table.set("db", exp.Identifier(this=parts[1]))
table.set(
"catalog", exp.Identifier(this=parts[0]).update_positions(previous_db)
)
table.set("db", exp.Identifier(this=parts[1]).update_positions(previous_db))
else:
previous_this = table.this
parts = table.name.split(".")
if len(parts) == 2 and not table.this.quoted:
table.set("db", exp.Identifier(this=parts[0]))
table.set("this", exp.Identifier(this=parts[1]))
table.set(
"db", exp.Identifier(this=parts[0]).update_positions(previous_this)
)
table.set(
"this", exp.Identifier(this=parts[1]).update_positions(previous_this)
)
if isinstance(table.this, exp.Identifier) and any("." in p.name for p in table.parts):
alias = table.this
@ -683,6 +693,10 @@ class BigQuery(Dialect):
for p in split_num_words(".".join(p.name for p in table.parts), ".", 3)
)
for part in (catalog, db, this):
if part:
part.update_positions(table.this)
if rest and this:
this = exp.Dot.build([this, *rest]) # type: ignore
@ -717,7 +731,13 @@ class BigQuery(Dialect):
)
info_schema_view = f"{table_parts[-2].name}.{table_parts[-1].name}"
table.set("this", exp.Identifier(this=info_schema_view, quoted=True))
new_this = exp.Identifier(this=info_schema_view, quoted=True).update_positions(
line=table_parts[-2].meta.get("line"),
col=table_parts[-1].meta.get("col"),
start=table_parts[-2].meta.get("start"),
end=table_parts[-1].meta.get("end"),
)
table.set("this", new_this)
table.set("db", seq_get(table_parts, -3))
table.set("catalog", seq_get(table_parts, -4))

View file

@ -742,3 +742,12 @@ class Postgres(Dialect):
@unsupported_args("this")
def currentschema_sql(self, expression: exp.CurrentSchema) -> str:
return "CURRENT_SCHEMA"
def interval_sql(self, expression: exp.Interval) -> str:
unit = expression.text("unit").lower()
if unit.startswith("quarter") and isinstance(expression.this, exp.Literal):
expression.this.replace(exp.Literal.number(int(expression.this.to_py()) * 3))
expression.args["unit"].replace(exp.var("MONTH"))
return super().interval_sql(expression)

View file

@ -512,6 +512,7 @@ class Snowflake(Dialect):
STATEMENT_PARSERS = {
**parser.Parser.STATEMENT_PARSERS,
TokenType.GET: lambda self: self._parse_get(),
TokenType.PUT: lambda self: self._parse_put(),
TokenType.SHOW: lambda self: self._parse_show(),
}
@ -857,6 +858,21 @@ class Snowflake(Dialect):
properties=self._parse_properties(),
)
def _parse_get(self) -> exp.Get | exp.Command:
start = self._prev
target = self._parse_location_path()
# Parse as command if unquoted file path
if self._curr.token_type == TokenType.URI_START:
return self._parse_as_command(start)
return self.expression(
exp.Get,
this=self._parse_string(),
target=target,
properties=self._parse_properties(),
)
def _parse_location_property(self) -> exp.LocationProperty:
self._match(TokenType.EQ)
return self.expression(exp.LocationProperty, this=self._parse_location_path())
@ -937,6 +953,7 @@ class Snowflake(Dialect):
"CHARACTER VARYING": TokenType.VARCHAR,
"EXCLUDE": TokenType.EXCEPT,
"FILE FORMAT": TokenType.FILE_FORMAT,
"GET": TokenType.GET,
"ILIKE ANY": TokenType.ILIKE_ANY,
"LIKE ANY": TokenType.LIKE_ANY,
"MATCH_CONDITION": TokenType.MATCH_CONDITION,

View file

@ -334,7 +334,9 @@ class Spark2(Hive):
def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
arg = expression.this
is_json_extract = isinstance(arg, (exp.JSONExtract, exp.JSONExtractScalar))
is_json_extract = isinstance(
arg, (exp.JSONExtract, exp.JSONExtractScalar)
) and not arg.args.get("variant_extract")
# We can't use a non-nested type (eg. STRING) as a schema
if expression.to.args.get("nested") and (is_parse_json(arg) or is_json_extract):

View file

@ -64,6 +64,7 @@ SQLGLOT_META = "sqlglot.meta"
SQLGLOT_ANONYMOUS = "sqlglot.anonymous"
TABLE_PARTS = ("this", "db", "catalog")
COLUMN_PARTS = ("this", "table", "db", "catalog")
POSITION_META_KEYS = ("line", "col", "start", "end")
class Expression(metaclass=_Expression):
@ -846,6 +847,32 @@ class Expression(metaclass=_Expression):
"""
return not_(self, copy=copy)
def update_positions(
self: E, other: t.Optional[Token | Expression] = None, **kwargs: t.Any
) -> E:
"""
Update this expression with positions from a token or other expression.
Args:
other: a token or expression to update this expression with.
Returns:
The updated expression.
"""
if isinstance(other, Expression):
self.meta.update({k: v for k, v in other.meta.items() if k in POSITION_META_KEYS})
elif other is not None:
self.meta.update(
{
"line": other.line,
"col": other.col,
"start": other.start,
"end": other.end,
}
)
self.meta.update({k: v for k, v in kwargs.items() if k in POSITION_META_KEYS})
return self
def as_(
self,
alias: str | Identifier,
@ -3307,6 +3334,11 @@ class Put(Expression):
arg_types = {"this": True, "target": True, "properties": False}
# https://docs.snowflake.com/en/sql-reference/sql/get
class Get(Expression):
arg_types = {"this": True, "target": True, "properties": False}
class Table(Expression):
arg_types = {
"this": False,

View file

@ -146,6 +146,7 @@ class Generator(metaclass=_Generator):
exp.Except: lambda self, e: self.set_operations(e),
exp.ExternalProperty: lambda *_: "EXTERNAL",
exp.Floor: lambda self, e: self.ceil_floor(e),
exp.Get: lambda self, e: self.get_put_sql(e),
exp.GlobalProperty: lambda *_: "GLOBAL",
exp.HeapProperty: lambda *_: "HEAP",
exp.IcebergProperty: lambda *_: "ICEBERG",
@ -175,6 +176,7 @@ class Generator(metaclass=_Generator):
exp.PivotAny: lambda self, e: f"ANY{self.sql(e, 'this')}",
exp.ProjectionPolicyColumnConstraint: lambda self,
e: f"PROJECTION POLICY {self.sql(e, 'this')}",
exp.Put: lambda self, e: self.get_put_sql(e),
exp.RemoteWithConnectionModelProperty: lambda self,
e: f"REMOTE WITH CONNECTION {self.sql(e, 'this')}",
exp.ReturnsProperty: lambda self, e: (
@ -4903,9 +4905,16 @@ class Generator(metaclass=_Generator):
self.unsupported("Unsupported SHOW statement")
return ""
def put_sql(self, expression: exp.Put) -> str:
def get_put_sql(self, expression: exp.Put | exp.Get) -> str:
# Snowflake GET/PUT statements:
# PUT <file> <internalStage> <properties>
# GET <internalStage> <file> <properties>
props = expression.args.get("properties")
props_sql = self.properties(props, prefix=" ", sep=" ", wrapped=False) if props else ""
this = self.sql(expression, "this")
target = self.sql(expression, "target")
if isinstance(expression, exp.Put):
return f"PUT {this} {target}{props_sql}"
else:
return f"GET {target} {this}{props_sql}"

View file

@ -512,6 +512,7 @@ class Parser(metaclass=_Parser):
TokenType.FINAL,
TokenType.FORMAT,
TokenType.FULL,
TokenType.GET,
TokenType.IDENTIFIER,
TokenType.IS,
TokenType.ISNULL,
@ -606,6 +607,7 @@ class Parser(metaclass=_Parser):
TokenType.FILTER,
TokenType.FIRST,
TokenType.FORMAT,
TokenType.GET,
TokenType.GLOB,
TokenType.IDENTIFIER,
TokenType.INDEX,
@ -1184,6 +1186,12 @@ class Parser(metaclass=_Parser):
KEY_VALUE_DEFINITIONS = (exp.Alias, exp.EQ, exp.PropertyEQ, exp.Slice)
FUNCTION_PARSERS = {
**{
name: lambda self: self._parse_max_min_by(exp.ArgMax) for name in exp.ArgMax.sql_names()
},
**{
name: lambda self: self._parse_max_min_by(exp.ArgMin) for name in exp.ArgMin.sql_names()
},
"CAST": lambda self: self._parse_cast(self.STRICT_CAST),
"CEIL": lambda self: self._parse_ceil_floor(exp.Ceil),
"CONVERT": lambda self: self._parse_convert(self.STRICT_CAST),
@ -4718,7 +4726,7 @@ class Parser(metaclass=_Parser):
)
def _parse_set_operations(self, this: t.Optional[exp.Expression]) -> t.Optional[exp.Expression]:
while True:
while this:
setop = self.parse_set_operation(this)
if not setop:
break
@ -5034,6 +5042,8 @@ class Parser(metaclass=_Parser):
this = self._parse_primary()
if isinstance(this, exp.Literal):
this = self._parse_column_ops(this)
parser = self.TYPE_LITERAL_PARSERS.get(data_type.this)
if parser:
return parser(self, this, data_type)
@ -5609,6 +5619,7 @@ class Parser(metaclass=_Parser):
return None
comments = self._curr.comments
token = self._curr
token_type = self._curr.token_type
this = self._curr.text
upper = this.upper()
@ -5683,7 +5694,7 @@ class Parser(metaclass=_Parser):
this = func
else:
if token_type == TokenType.IDENTIFIER:
this = exp.Identifier(this=this, quoted=True)
this = exp.Identifier(this=this, quoted=True).update_positions(token)
this = self.expression(exp.Anonymous, this=this, expressions=args)
if isinstance(this, exp.Expression):
@ -5742,7 +5753,7 @@ class Parser(metaclass=_Parser):
if literal:
return self.expression(exp.Introducer, this=token.text, expression=literal)
return self.expression(exp.Identifier, this=token.text)
return self._identifier_expression(token)
def _parse_session_parameter(self) -> exp.SessionParameter:
kind = None
@ -6972,7 +6983,7 @@ class Parser(metaclass=_Parser):
(any_token and self._advance_any()) or self._match_set(tokens or self.ID_VAR_TOKENS)
):
quoted = self._prev.token_type == TokenType.STRING
expression = self.expression(exp.Identifier, this=self._prev.text, quoted=quoted)
expression = self._identifier_expression(quoted=quoted)
return expression
@ -6982,7 +6993,10 @@ class Parser(metaclass=_Parser):
return self._parse_placeholder()
def _parse_string_as_identifier(self) -> t.Optional[exp.Identifier]:
return exp.to_identifier(self._match(TokenType.STRING) and self._prev.text, quoted=True)
output = exp.to_identifier(self._match(TokenType.STRING) and self._prev.text, quoted=True)
if output:
output.update_positions(self._prev)
return output
def _parse_number(self) -> t.Optional[exp.Expression]:
if self._match_set(self.NUMERIC_PARSERS):
@ -6991,7 +7005,7 @@ class Parser(metaclass=_Parser):
def _parse_identifier(self) -> t.Optional[exp.Expression]:
if self._match(TokenType.IDENTIFIER):
return self.expression(exp.Identifier, this=self._prev.text, quoted=True)
return self._identifier_expression(quoted=True)
return self._parse_placeholder()
def _parse_var(
@ -8224,3 +8238,24 @@ class Parser(metaclass=_Parser):
this=exp.var("FORMAT_NAME"),
value=self._parse_string() or self._parse_table_parts(),
)
def _parse_max_min_by(self, expr_type: t.Type[exp.AggFunc]) -> exp.AggFunc:
args: t.List[exp.Expression] = []
if self._match(TokenType.DISTINCT):
args.append(self.expression(exp.Distinct, expressions=[self._parse_assignment()]))
self._match(TokenType.COMMA)
args.extend(self._parse_csv(self._parse_assignment))
return self.expression(
expr_type, this=seq_get(args, 0), expression=seq_get(args, 1), count=seq_get(args, 2)
)
def _identifier_expression(
self, token: t.Optional[Token] = None, **kwargs: t.Any
) -> exp.Identifier:
token = token or self._prev
expression = self.expression(exp.Identifier, this=token.text, **kwargs)
expression.update_positions(token)
return expression

View file

@ -290,6 +290,7 @@ class TokenType(AutoName):
FROM = auto()
FULL = auto()
FUNCTION = auto()
GET = auto()
GLOB = auto()
GLOBAL = auto()
GRANT = auto()

View file

@ -2432,3 +2432,56 @@ OPTIONS (
f"SELECT * FROM t1, UNNEST([1, 2]) AS hit WITH OFFSET {join_ops} JOIN foo",
f"SELECT * FROM t1, UNNEST([1, 2]) AS hit WITH OFFSET AS offset {join_ops} JOIN foo",
)
def test_identifier_meta(self):
ast = parse_one(
"SELECT a, b FROM test_schema.test_table_a UNION ALL SELECT c, d FROM test_catalog.test_schema.test_table_b",
dialect="bigquery",
)
for identifier in ast.find_all(exp.Identifier):
self.assertEqual(set(identifier.meta), {"line", "col", "start", "end"})
self.assertEqual(
ast.this.args["from"].this.args["this"].meta,
{"line": 1, "col": 41, "start": 29, "end": 40},
)
self.assertEqual(
ast.this.args["from"].this.args["db"].meta,
{"line": 1, "col": 28, "start": 17, "end": 27},
)
self.assertEqual(
ast.expression.args["from"].this.args["this"].meta,
{"line": 1, "col": 106, "start": 94, "end": 105},
)
self.assertEqual(
ast.expression.args["from"].this.args["db"].meta,
{"line": 1, "col": 93, "start": 82, "end": 92},
)
self.assertEqual(
ast.expression.args["from"].this.args["catalog"].meta,
{"line": 1, "col": 81, "start": 69, "end": 80},
)
information_schema_sql = "SELECT a, b FROM region.INFORMATION_SCHEMA.COLUMNS"
ast = parse_one(information_schema_sql, dialect="bigquery")
meta = ast.args["from"].this.this.meta
self.assertEqual(meta, {"line": 1, "col": 50, "start": 24, "end": 49})
assert (
information_schema_sql[meta["start"] : meta["end"] + 1] == "INFORMATION_SCHEMA.COLUMNS"
)
def test_quoted_identifier_meta(self):
sql = "SELECT `a` FROM `test_schema`.`test_table_a`"
ast = parse_one(sql, dialect="bigquery")
db_meta = ast.args["from"].this.args["db"].meta
self.assertEqual(sql[db_meta["start"] : db_meta["end"] + 1], "`test_schema`")
table_meta = ast.args["from"].this.this.meta
self.assertEqual(sql[table_meta["start"] : table_meta["end"] + 1], "`test_table_a`")
information_schema_sql = "SELECT a, b FROM `region.INFORMATION_SCHEMA.COLUMNS`"
ast = parse_one(information_schema_sql, dialect="bigquery")
table_meta = ast.args["from"].this.this.meta
assert (
information_schema_sql[table_meta["start"] : table_meta["end"] + 1]
== "`region.INFORMATION_SCHEMA.COLUMNS`"
)

View file

@ -35,6 +35,7 @@ class TestDatabricks(Validator):
self.validate_identity("SELECT ${x} FROM ${y} WHERE ${z} > 1")
self.validate_identity("CREATE TABLE foo (x DATE GENERATED ALWAYS AS (CAST(y AS DATE)))")
self.validate_identity("TRUNCATE TABLE t1 PARTITION(age = 10, name = 'test', address)")
self.validate_identity("SELECT PARSE_JSON('{}')")
self.validate_identity(
"CREATE TABLE IF NOT EXISTS db.table (a TIMESTAMP, b BOOLEAN GENERATED ALWAYS AS (NOT a IS NULL)) USING DELTA"
)
@ -56,7 +57,10 @@ class TestDatabricks(Validator):
self.validate_identity(
"COPY INTO target FROM `s3://link` FILEFORMAT = AVRO VALIDATE = ALL FILES = ('file1', 'file2') FORMAT_OPTIONS ('opt1'='true', 'opt2'='test') COPY_OPTIONS ('mergeSchema'='true')"
)
self.validate_identity("SELECT PARSE_JSON('{}')")
self.validate_identity(
"SELECT TIMESTAMP '2025-04-29 18.47.18'::DATE",
"SELECT CAST(CAST('2025-04-29 18.47.18' AS DATE) AS TIMESTAMP)",
)
self.validate_identity(
"SELECT DATE_FORMAT(CAST(FROM_UTC_TIMESTAMP(foo, 'America/Los_Angeles') AS TIMESTAMP), 'yyyy-MM-dd HH:mm:ss') AS foo FROM t",
"SELECT DATE_FORMAT(CAST(FROM_UTC_TIMESTAMP(CAST(foo AS TIMESTAMP), 'America/Los_Angeles') AS TIMESTAMP), 'yyyy-MM-dd HH:mm:ss') AS foo FROM t",
@ -161,6 +165,8 @@ class TestDatabricks(Validator):
# https://docs.databricks.com/sql/language-manual/functions/colonsign.html
def test_json(self):
self.validate_identity("SELECT c1:price, c1:price.foo, c1:price.bar[1]")
self.validate_identity("SELECT TRY_CAST(c1:price AS ARRAY<VARIANT>)")
self.validate_identity("""SELECT TRY_CAST(c1:["foo bar"]["baz qux"] AS ARRAY<VARIANT>)""")
self.validate_identity(
"""SELECT c1:item[1].price FROM VALUES ('{ "item": [ { "model" : "basic", "price" : 6.12 }, { "model" : "medium", "price" : 9.24 } ] }') AS T(c1)"""
)

View file

@ -298,6 +298,7 @@ class TestDuckDB(Validator):
self.validate_identity("SUMMARIZE tbl").assert_is(exp.Summarize)
self.validate_identity("SUMMARIZE SELECT * FROM tbl").assert_is(exp.Summarize)
self.validate_identity("CREATE TABLE tbl_summary AS SELECT * FROM (SUMMARIZE tbl)")
self.validate_identity("SELECT STAR(tbl, exclude := [foo])")
self.validate_identity("UNION_VALUE(k1 := 1)").find(exp.PropertyEQ).this.assert_is(
exp.Identifier
)

View file

@ -31,6 +31,8 @@ class TestPostgres(Validator):
self.assertIsInstance(expr, exp.Alter)
self.assertEqual(expr.sql(dialect="postgres"), alter_table_only)
self.validate_identity("SELECT EXTRACT(QUARTER FROM CAST('2025-04-26' AS DATE))")
self.validate_identity("SELECT DATE_TRUNC('QUARTER', CAST('2025-04-26' AS DATE))")
self.validate_identity("STRING_TO_ARRAY('xx~^~yy~^~zz', '~^~', 'yy')")
self.validate_identity("SELECT x FROM t WHERE CAST($1 AS TEXT) = 'ok'")
self.validate_identity("SELECT * FROM t TABLESAMPLE SYSTEM (50) REPEATABLE (55)")
@ -372,6 +374,14 @@ FROM json_data, field_ids""",
pretty=True,
)
self.validate_all(
"SELECT CURRENT_TIMESTAMP + INTERVAL '-3 MONTH'",
read={
"mysql": "SELECT DATE_ADD(CURRENT_TIMESTAMP, INTERVAL -1 QUARTER)",
"postgres": "SELECT CURRENT_TIMESTAMP + INTERVAL '-3 MONTH'",
"tsql": "SELECT DATEADD(QUARTER, -1, GETDATE())",
},
)
self.validate_all(
"SELECT ARRAY[]::INT[] AS foo",
write={

View file

@ -11,6 +11,7 @@ class TestSnowflake(Validator):
dialect = "snowflake"
def test_snowflake(self):
self.validate_identity("SELECT GET(a, b)")
self.assertEqual(
# Ensures we don't fail when generating ParseJSON with the `safe` arg set to `True`
self.validate_identity("""SELECT TRY_PARSE_JSON('{"x: 1}')""").sql(),
@ -22,7 +23,7 @@ class TestSnowflake(Validator):
self.assertEqual(expr.sql(dialect="snowflake"), "SELECT APPROX_TOP_K(C4, 3, 5) FROM t")
self.validate_identity("INSERT INTO test VALUES (x'48FAF43B0AFCEF9B63EE3A93EE2AC2')")
self.validate_identity("exclude := [foo]")
self.validate_identity("SELECT STAR(tbl, exclude := [foo])")
self.validate_identity("SELECT CAST([1, 2, 3] AS VECTOR(FLOAT, 3))")
self.validate_identity("SELECT CONNECT_BY_ROOT test AS test_column_alias")
self.validate_identity("SELECT number").selects[0].assert_is(exp.Column)
@ -110,6 +111,10 @@ class TestSnowflake(Validator):
"SELECT 1 put",
"SELECT 1 AS put",
)
self.validate_identity(
"SELECT 1 get",
"SELECT 1 AS get",
)
self.validate_identity(
"WITH t (SELECT 1 AS c) SELECT c FROM t",
"WITH t AS (SELECT 1 AS c) SELECT c FROM t",
@ -2465,6 +2470,33 @@ SINGLE = TRUE""",
check_command_warning=True,
)
def test_get_from_stage(self):
self.validate_identity('GET @"my_DB"."schEMA1"."MYstage" \'file:///dir/tmp.csv\'')
self.validate_identity("GET @s1/test 'file:///dir/tmp.csv'")
# GET with file path and stage ref containing spaces (wrapped in single quotes)
ast = parse_one("GET '@s1/my folder' 'file://my file.txt'", read="snowflake")
self.assertIsInstance(ast, exp.Get)
self.assertEqual(ast.args["target"], exp.Var(this="'@s1/my folder'"))
self.assertEqual(ast.this, exp.Literal(this="file://my file.txt", is_string=True))
self.assertEqual(ast.sql("snowflake"), "GET '@s1/my folder' 'file://my file.txt'")
# expression with additional properties
ast = parse_one("GET @stage1/folder 'file:///tmp/my.txt' PARALLEL = 1", read="snowflake")
self.assertIsInstance(ast, exp.Get)
self.assertEqual(ast.args["target"], exp.Var(this="@stage1/folder"))
self.assertEqual(ast.this, exp.Literal(this="file:///tmp/my.txt", is_string=True))
properties = ast.args.get("properties")
props_dict = {prop.this.this: prop.args["value"].this for prop in properties.expressions}
self.assertEqual(props_dict, {"PARALLEL": "1"})
# the unquoted URI variant is not fully supported yet
self.validate_identity("GET @%table file:///dir/tmp.csv", check_command_warning=True)
self.validate_identity(
"GET @s1/test file:///dir/tmp.csv PARALLEL=1",
check_command_warning=True,
)
def test_querying_semi_structured_data(self):
self.validate_identity("SELECT $1")
self.validate_identity("SELECT $1.elem")
@ -2578,3 +2610,11 @@ SINGLE = TRUE""",
self.assertEqual(expr.find(exp.Placeholder), exp.Placeholder(this="1"))
self.validate_identity("SELECT :1, :2")
self.validate_identity("SELECT :1 + :2")
def test_max_by_min_by(self):
max_by = self.validate_identity("MAX_BY(DISTINCT selected_col, filtered_col)")
min_by = self.validate_identity("MIN_BY(DISTINCT selected_col, filtered_col)")
for node in (max_by, min_by):
self.assertEqual(len(node.this.expressions), 1)
self.assertIsInstance(node.expression, exp.Column)

View file

@ -889,3 +889,5 @@ CAST(x AS INT128)
CAST(x AS UINT128)
CAST(x AS UINT256)
SELECT export
SELECT ARG_MAX(DISTINCT selected_col, filtered_col) FROM table
SELECT ARG_MIN(DISTINCT selected_col, filtered_col) FROM table

View file

@ -956,3 +956,41 @@ class TestParser(unittest.TestCase):
# Incomplete or incorrect anonymous meta comments are not registered
ast = parse_one("YEAR(a) /* sqlglot.anon */")
self.assertIsInstance(ast, exp.Year)
def test_identifier_meta(self):
ast = parse_one(
"SELECT a, b FROM test_schema.test_table_a UNION ALL SELECT c, d FROM test_catalog.test_schema.test_table_b"
)
for identifier in ast.find_all(exp.Identifier):
self.assertEqual(set(identifier.meta), {"line", "col", "start", "end"})
self.assertEqual(
ast.this.args["from"].this.args["this"].meta,
{"line": 1, "col": 41, "start": 29, "end": 40},
)
self.assertEqual(
ast.this.args["from"].this.args["db"].meta,
{"line": 1, "col": 28, "start": 17, "end": 27},
)
self.assertEqual(
ast.expression.args["from"].this.args["this"].meta,
{"line": 1, "col": 106, "start": 94, "end": 105},
)
self.assertEqual(
ast.expression.args["from"].this.args["db"].meta,
{"line": 1, "col": 93, "start": 82, "end": 92},
)
self.assertEqual(
ast.expression.args["from"].this.args["catalog"].meta,
{"line": 1, "col": 81, "start": 69, "end": 80},
)
def test_quoted_identifier_meta(self):
sql = 'SELECT "a" FROM "test_schema"."test_table_a"'
ast = parse_one(sql)
db_meta = ast.args["from"].this.args["db"].meta
self.assertEqual(sql[db_meta["start"] : db_meta["end"] + 1], '"test_schema"')
table_meta = ast.args["from"].this.this.meta
self.assertEqual(sql[table_meta["start"] : table_meta["end"] + 1], '"test_table_a"')