Merging upstream version 26.24.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
c78999c8c9
commit
2b9f8478b0
53 changed files with 3642 additions and 3447 deletions
27
CHANGELOG.md
27
CHANGELOG.md
|
@ -1,6 +1,31 @@
|
|||
Changelog
|
||||
=========
|
||||
|
||||
## [v26.23.0] - 2025-05-29
|
||||
### :boom: BREAKING CHANGES
|
||||
- due to [`6910744`](https://github.com/tobymao/sqlglot/commit/6910744e6260793b3f9190782cf60fbbd9adcd38) - update py03 version *(PR [#5136](https://github.com/tobymao/sqlglot/pull/5136) by [@benfdking](https://github.com/benfdking))*:
|
||||
|
||||
update py03 version (#5136)
|
||||
|
||||
- due to [`a56deab`](https://github.com/tobymao/sqlglot/commit/a56deabc2b9543209fb5e41f19c3bef89177a577) - bump sqlglotrs to 0.5.0 *(commit by [@georgesittas](https://github.com/georgesittas))*:
|
||||
|
||||
bump sqlglotrs to 0.5.0
|
||||
|
||||
|
||||
### :bug: Bug Fixes
|
||||
- [`e9b3156`](https://github.com/tobymao/sqlglot/commit/e9b3156aa1ed95fdee4c6b419134d8ca746964b6) - **athena**: Handle transpilation of FileFormatProperty from dialects that treat it as a variable and not a string literal *(PR [#5133](https://github.com/tobymao/sqlglot/pull/5133) by [@erindru](https://github.com/erindru))*
|
||||
|
||||
### :wrench: Chores
|
||||
- [`6910744`](https://github.com/tobymao/sqlglot/commit/6910744e6260793b3f9190782cf60fbbd9adcd38) - update py03 version *(PR [#5136](https://github.com/tobymao/sqlglot/pull/5136) by [@benfdking](https://github.com/benfdking))*
|
||||
- :arrow_lower_right: *addresses issue [#5134](https://github.com/tobymao/sqlglot/issues/5134) opened by [@mgorny](https://github.com/mgorny)*
|
||||
- [`a56deab`](https://github.com/tobymao/sqlglot/commit/a56deabc2b9543209fb5e41f19c3bef89177a577) - bump sqlglotrs to 0.5.0 *(commit by [@georgesittas](https://github.com/georgesittas))*
|
||||
|
||||
|
||||
## [v26.22.1] - 2025-05-28
|
||||
### :bug: Bug Fixes
|
||||
- [`f7401fd`](https://github.com/tobymao/sqlglot/commit/f7401fdc29a35738eb23f424ceba03463a4d8af9) - **bigquery**: avoid getting stuck in infinite loop when parsing tables *(PR [#5130](https://github.com/tobymao/sqlglot/pull/5130) by [@georgesittas](https://github.com/georgesittas))*
|
||||
|
||||
|
||||
## [v26.22.0] - 2025-05-27
|
||||
### :boom: BREAKING CHANGES
|
||||
- due to [`f2bf000`](https://github.com/tobymao/sqlglot/commit/f2bf000a410fb18531bb90ef1d767baf0e8bce7a) - avoid creating new alias for qualifying unpivot *(PR [#5121](https://github.com/tobymao/sqlglot/pull/5121) by [@geooo109](https://github.com/geooo109))*:
|
||||
|
@ -6838,3 +6863,5 @@ Changelog
|
|||
[v26.20.0]: https://github.com/tobymao/sqlglot/compare/v26.19.0...v26.20.0
|
||||
[v26.21.0]: https://github.com/tobymao/sqlglot/compare/v26.20.0...v26.21.0
|
||||
[v26.22.0]: https://github.com/tobymao/sqlglot/compare/v26.21.0...v26.22.0
|
||||
[v26.22.1]: https://github.com/tobymao/sqlglot/compare/v26.22.0...v26.22.1
|
||||
[v26.23.0]: https://github.com/tobymao/sqlglot/compare/v26.22.1...v26.23.0
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -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">'26.22.0'</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">22</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||||
</span><span id="L-20"><a href="#L-20"><span class="linenos">20</span></a><span class="n">__version__</span> <span class="o">=</span> <span class="n">version</span> <span class="o">=</span> <span class="s1">'26.23.0'</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">23</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||||
</span></pre></div>
|
||||
|
||||
|
||||
|
@ -93,7 +93,7 @@
|
|||
<section id="__version__">
|
||||
<div class="attr variable">
|
||||
<span class="name">__version__</span><span class="annotation">: str</span> =
|
||||
<span class="default_value">'26.22.0'</span>
|
||||
<span class="default_value">'26.23.0'</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, 22, 0)</span>
|
||||
<span class="default_value">(26, 23, 0)</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -117,7 +117,7 @@
|
|||
<section id="version">
|
||||
<div class="attr variable">
|
||||
<span class="name">version</span><span class="annotation">: str</span> =
|
||||
<span class="default_value">'26.22.0'</span>
|
||||
<span class="default_value">'26.23.0'</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, 22, 0)</span>
|
||||
<span class="default_value">(26, 23, 0)</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
|
@ -359,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"><MagicMock id='140578035606928'></span>
|
||||
<span class="default_value"><MagicMock id='139904393074608'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -371,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"><MagicMock id='140578037633456'></span>
|
||||
<span class="default_value"><MagicMock id='139904406061312'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -383,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"><MagicMock id='140578050343264'></span>
|
||||
<span class="default_value"><MagicMock id='139904391016128'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -395,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"><MagicMock id='140578040723824'></span>
|
||||
<span class="default_value"><MagicMock id='139904405693408'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -407,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"><MagicMock id='140578040724592'></span>
|
||||
<span class="default_value"><MagicMock id='139904405691728'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -419,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"><MagicMock id='140578045917168'></span>
|
||||
<span class="default_value"><MagicMock id='139904402062592'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -431,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"><MagicMock id='140578033549760'></span>
|
||||
<span class="default_value"><MagicMock id='139904389006720'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -443,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"><MagicMock id='140578033556816'></span>
|
||||
<span class="default_value"><MagicMock id='139904389011808'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -455,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"><MagicMock id='140578041121664'></span>
|
||||
<span class="default_value"><MagicMock id='139904405826688'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -467,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"><MagicMock id='140578050255568'></span>
|
||||
<span class="default_value"><MagicMock id='139904397287840'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -479,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"><MagicMock id='140578050246112'></span>
|
||||
<span class="default_value"><MagicMock id='139904407772256'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -491,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"><MagicMock id='140578034280160'></span>
|
||||
<span class="default_value"><MagicMock id='139904405858928'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -503,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"><MagicMock id='140578035976464'></span>
|
||||
<span class="default_value"><MagicMock id='139904401435536'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -515,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"><MagicMock id='140578049605696'></span>
|
||||
<span class="default_value"><MagicMock id='139904406312352'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -527,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"><MagicMock id='140578048875568'></span>
|
||||
<span class="default_value"><MagicMock id='139904406604816'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -539,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"><MagicMock id='140578048873360'></span>
|
||||
<span class="default_value"><MagicMock id='139904406615424'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -551,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"><MagicMock id='140578050264320'></span>
|
||||
<span class="default_value"><MagicMock id='139904401186272'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -563,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"><MagicMock id='140578045958160'></span>
|
||||
<span class="default_value"><MagicMock id='139904401188912'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -575,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"><MagicMock id='140578045962528'></span>
|
||||
<span class="default_value"><MagicMock id='139904405754480'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -587,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"><MagicMock id='140578046116480'></span>
|
||||
<span class="default_value"><MagicMock id='139904405919904'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -599,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"><MagicMock id='140578041801088'></span>
|
||||
<span class="default_value"><MagicMock id='139904406383936'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -611,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"><MagicMock id='140578048618512'></span>
|
||||
<span class="default_value"><MagicMock id='139904406386960'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -623,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"><MagicMock id='140578048434304'></span>
|
||||
<span class="default_value"><MagicMock id='139904391390896'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -635,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"><MagicMock id='140578048437088'></span>
|
||||
<span class="default_value"><MagicMock id='139904396179488'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -647,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"><MagicMock id='140578033862064'></span>
|
||||
<span class="default_value"><MagicMock id='139904389318016'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -659,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"><MagicMock id='140578033869936'></span>
|
||||
<span class="default_value"><MagicMock id='139904389325888'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -671,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"><MagicMock id='140578033877920'></span>
|
||||
<span class="default_value"><MagicMock id='139904389333872'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -683,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"><MagicMock id='140578033885840'></span>
|
||||
<span class="default_value"><MagicMock id='139904389341792'></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -695,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"><MagicMock id='140578033910208'></span>
|
||||
<span class="default_value"><MagicMock id='139904389366160'></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
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
|
@ -63285,7 +63285,7 @@ Otherwise, this resets the expressions.</li>
|
|||
<div id="DataType.STRUCT_TYPES" class="classattr">
|
||||
<div class="attr variable">
|
||||
<span class="name">STRUCT_TYPES</span> =
|
||||
<span class="default_value">{<Type.OBJECT: 'OBJECT'>, <Type.UNION: 'UNION'>, <Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>}</span>
|
||||
<span class="default_value">{<Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>, <Type.UNION: 'UNION'>}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -63310,7 +63310,7 @@ Otherwise, this resets the expressions.</li>
|
|||
<div class="attr variable">
|
||||
<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">
|
||||
<label class="view-value-button pdoc-button" for="DataType.NESTED_TYPES-view-value"></label><span class="default_value">{<Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>, <Type.UNION: 'UNION'>, <Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>, <Type.MAP: 'MAP'>}</span>
|
||||
<label class="view-value-button pdoc-button" for="DataType.NESTED_TYPES-view-value"></label><span class="default_value">{<Type.LIST: 'LIST'>, <Type.NESTED: 'NESTED'>, <Type.UNION: 'UNION'>, <Type.STRUCT: 'STRUCT'>, <Type.ARRAY: 'ARRAY'>, <Type.OBJECT: 'OBJECT'>, <Type.MAP: 'MAP'>}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -63323,7 +63323,7 @@ Otherwise, this resets the expressions.</li>
|
|||
<div class="attr variable">
|
||||
<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">
|
||||
<label class="view-value-button pdoc-button" for="DataType.TEXT_TYPES-view-value"></label><span class="default_value">{<Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NAME: 'NAME'>, <Type.NCHAR: 'NCHAR'>, <Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>}</span>
|
||||
<label class="view-value-button pdoc-button" for="DataType.TEXT_TYPES-view-value"></label><span class="default_value">{<Type.NCHAR: 'NCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NAME: 'NAME'>, <Type.TEXT: 'TEXT'>}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -63336,7 +63336,7 @@ Otherwise, this resets the expressions.</li>
|
|||
<div class="attr variable">
|
||||
<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">
|
||||
<label class="view-value-button pdoc-button" for="DataType.SIGNED_INTEGER_TYPES-view-value"></label><span class="default_value">{<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>}</span>
|
||||
<label class="view-value-button pdoc-button" for="DataType.SIGNED_INTEGER_TYPES-view-value"></label><span class="default_value">{<Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>, <Type.INT128: 'INT128'>, <Type.INT256: 'INT256'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -63349,7 +63349,7 @@ Otherwise, this resets the expressions.</li>
|
|||
<div class="attr variable">
|
||||
<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">
|
||||
<label class="view-value-button pdoc-button" for="DataType.UNSIGNED_INTEGER_TYPES-view-value"></label><span class="default_value">{<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.UINT256: 'UINT256'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT: 'UINT'>, <Type.USMALLINT: 'USMALLINT'>}</span>
|
||||
<label class="view-value-button pdoc-button" for="DataType.UNSIGNED_INTEGER_TYPES-view-value"></label><span class="default_value">{<Type.UTINYINT: 'UTINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT: 'UINT'>, <Type.UINT128: 'UINT128'>}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -63362,7 +63362,7 @@ Otherwise, this resets the expressions.</li>
|
|||
<div class="attr variable">
|
||||
<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">
|
||||
<label class="view-value-button pdoc-button" for="DataType.INTEGER_TYPES-view-value"></label><span class="default_value">{<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIT: 'BIT'>, <Type.TINYINT: 'TINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.UINT256: 'UINT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT: 'INT'>, <Type.UINT: 'UINT'>, <Type.BIGINT: 'BIGINT'>, <Type.USMALLINT: 'USMALLINT'>}</span>
|
||||
<label class="view-value-button pdoc-button" for="DataType.INTEGER_TYPES-view-value"></label><span class="default_value">{<Type.UTINYINT: 'UTINYINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.INT128: 'INT128'>, <Type.INT256: 'INT256'>, <Type.UINT256: 'UINT256'>, <Type.BIT: 'BIT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UINT: 'UINT'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT128: 'UINT128'>}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -63374,7 +63374,7 @@ Otherwise, this resets the expressions.</li>
|
|||
<div id="DataType.FLOAT_TYPES" class="classattr">
|
||||
<div class="attr variable">
|
||||
<span class="name">FLOAT_TYPES</span> =
|
||||
<span class="default_value">{<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}</span>
|
||||
<span class="default_value">{<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -63387,7 +63387,7 @@ Otherwise, this resets the expressions.</li>
|
|||
<div class="attr variable">
|
||||
<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">
|
||||
<label class="view-value-button pdoc-button" for="DataType.REAL_TYPES-view-value"></label><span class="default_value">{<Type.DECIMAL256: 'DECIMAL256'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.MONEY: 'MONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>}</span>
|
||||
<label class="view-value-button pdoc-button" for="DataType.REAL_TYPES-view-value"></label><span class="default_value">{<Type.MONEY: 'MONEY'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DECIMAL128: 'DECIMAL128'>}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -63400,7 +63400,7 @@ Otherwise, this resets the expressions.</li>
|
|||
<div class="attr variable">
|
||||
<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">
|
||||
<label class="view-value-button pdoc-button" for="DataType.NUMERIC_TYPES-view-value"></label><span class="default_value">{<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.BIT: 'BIT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT256: 'UINT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT: 'INT'>, <Type.UINT: 'UINT'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.FLOAT: 'FLOAT'>, <Type.UINT128: 'UINT128'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.BIGINT: 'BIGINT'>, <Type.MONEY: 'MONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>}</span>
|
||||
<label class="view-value-button pdoc-button" for="DataType.NUMERIC_TYPES-view-value"></label><span class="default_value">{<Type.UDECIMAL: 'UDECIMAL'>, <Type.INT: 'INT'>, <Type.BIT: 'BIT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT256: 'UINT256'>, <Type.INT128: 'INT128'>, <Type.INT256: 'INT256'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.TINYINT: 'TINYINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.MONEY: 'MONEY'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UINT: 'UINT'>, <Type.BIGINT: 'BIGINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UINT128: 'UINT128'>}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -63413,7 +63413,7 @@ Otherwise, this resets the expressions.</li>
|
|||
<div class="attr variable">
|
||||
<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">
|
||||
<label class="view-value-button pdoc-button" for="DataType.TEMPORAL_TYPES-view-value"></label><span class="default_value">{<Type.DATE32: 'DATE32'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATETIME2: 'DATETIME2'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.TIME: 'TIME'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATE: 'DATE'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>}</span>
|
||||
<label class="view-value-button pdoc-button" for="DataType.TEMPORAL_TYPES-view-value"></label><span class="default_value">{<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATETIME2: 'DATETIME2'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIME: 'TIME'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATE32: 'DATE32'>}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
|
@ -12767,7 +12767,7 @@ Default: True</li>
|
|||
<div id="Generator.PARAMETERIZABLE_TEXT_TYPES" class="classattr">
|
||||
<div class="attr variable">
|
||||
<span class="name">PARAMETERIZABLE_TEXT_TYPES</span> =
|
||||
<span class="default_value">{<Type.CHAR: 'CHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>}</span>
|
||||
<span class="default_value">{<Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NCHAR: 'NCHAR'>}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
|
@ -2003,7 +2003,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">{'year', 'month', 'day', 'quarter', 'year_month', 'week'}</span>
|
||||
<span class="default_value">{'quarter', 'year_month', 'week', 'year', 'month', 'day'}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -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">{'settings', 'offset', 'cluster', 'match', 'with', 'distinct', 'operation_modifiers', 'pivots', 'kind', 'qualify', 'prewhere', 'having', 'sort', 'format', 'sample', 'connect', 'options', 'laterals', 'into', 'distribute', 'locks', 'limit', 'group', 'windows'}</span>
|
||||
<label class="view-value-button pdoc-button" for="UNMERGABLE_ARGS-view-value"></label><span class="default_value">{'settings', 'connect', 'pivots', 'options', 'qualify', 'windows', 'into', 'with', 'prewhere', 'having', 'distribute', 'limit', 'sample', 'operation_modifiers', 'offset', 'distinct', 'format', 'locks', 'cluster', 'match', 'laterals', 'kind', 'group', 'sort'}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
|
@ -3285,7 +3285,7 @@ prefix are statically known.</p>
|
|||
<section id="JOINS">
|
||||
<div class="attr variable">
|
||||
<span class="name">JOINS</span> =
|
||||
<span class="default_value">{('', 'INNER'), ('RIGHT', ''), ('RIGHT', 'OUTER'), ('', '')}</span>
|
||||
<span class="default_value">{('RIGHT', ''), ('RIGHT', 'OUTER'), ('', 'INNER'), ('', '')}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -9489,7 +9489,7 @@
|
|||
<div class="attr variable">
|
||||
<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">
|
||||
<label class="view-value-button pdoc-button" for="Tokenizer.TOKENS_PRECEDING_HINT-view-value"></label><span class="default_value">{<<a href="#TokenType.SELECT">TokenType.SELECT</a>: 'SELECT'>, <<a href="#TokenType.DELETE">TokenType.DELETE</a>: 'DELETE'>, <<a href="#TokenType.UPDATE">TokenType.UPDATE</a>: 'UPDATE'>, <<a href="#TokenType.INSERT">TokenType.INSERT</a>: 'INSERT'>}</span>
|
||||
<label class="view-value-button pdoc-button" for="Tokenizer.TOKENS_PRECEDING_HINT-view-value"></label><span class="default_value">{<<a href="#TokenType.INSERT">TokenType.INSERT</a>: 'INSERT'>, <<a href="#TokenType.UPDATE">TokenType.UPDATE</a>: 'UPDATE'>, <<a href="#TokenType.SELECT">TokenType.SELECT</a>: 'SELECT'>, <<a href="#TokenType.DELETE">TokenType.DELETE</a>: 'DELETE'>}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -9528,7 +9528,7 @@
|
|||
<div class="attr variable">
|
||||
<span class="name">COMMANDS</span> =
|
||||
<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">{<<a href="#TokenType.EXECUTE">TokenType.EXECUTE</a>: 'EXECUTE'>, <<a href="#TokenType.FETCH">TokenType.FETCH</a>: 'FETCH'>, <<a href="#TokenType.SHOW">TokenType.SHOW</a>: 'SHOW'>, <<a href="#TokenType.RENAME">TokenType.RENAME</a>: 'RENAME'>, <<a href="#TokenType.COMMAND">TokenType.COMMAND</a>: 'COMMAND'>}</span>
|
||||
<label class="view-value-button pdoc-button" for="Tokenizer.COMMANDS-view-value"></label><span class="default_value">{<<a href="#TokenType.COMMAND">TokenType.COMMAND</a>: 'COMMAND'>, <<a href="#TokenType.EXECUTE">TokenType.EXECUTE</a>: 'EXECUTE'>, <<a href="#TokenType.RENAME">TokenType.RENAME</a>: 'RENAME'>, <<a href="#TokenType.FETCH">TokenType.FETCH</a>: 'FETCH'>, <<a href="#TokenType.SHOW">TokenType.SHOW</a>: 'SHOW'>}</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
|
@ -148,7 +148,6 @@ class Athena(Trino):
|
|||
|
||||
TRANSFORMS = {
|
||||
**Trino.Generator.TRANSFORMS,
|
||||
exp.FileFormatProperty: lambda self, e: f"format={self.sql(e, 'this')}",
|
||||
exp.PartitionedByProperty: _partitioned_by_property_sql,
|
||||
exp.LocationProperty: _location_property_sql,
|
||||
}
|
||||
|
|
|
@ -461,7 +461,8 @@ class Presto(Dialect):
|
|||
exp.DiToDate: lambda self,
|
||||
e: f"CAST(DATE_PARSE(CAST({self.sql(e, 'this')} AS VARCHAR), {Presto.DATEINT_FORMAT}) AS DATE)",
|
||||
exp.Encode: lambda self, e: encode_decode_sql(self, e, "TO_UTF8"),
|
||||
exp.FileFormatProperty: lambda self, e: f"FORMAT='{e.name.upper()}'",
|
||||
exp.FileFormatProperty: lambda self,
|
||||
e: f"format={self.sql(exp.Literal.string(e.name))}",
|
||||
exp.First: _first_last_sql,
|
||||
exp.FromTimeZone: lambda self,
|
||||
e: f"WITH_TIMEZONE({self.sql(e, 'this')}, {self.sql(e, 'zone')}) AT TIME ZONE 'UTC'",
|
||||
|
|
|
@ -372,6 +372,11 @@ class Snowflake(Dialect):
|
|||
"ff6": "%f",
|
||||
}
|
||||
|
||||
DATE_PART_MAPPING = {
|
||||
**Dialect.DATE_PART_MAPPING,
|
||||
"ISOWEEK": "WEEKISO",
|
||||
}
|
||||
|
||||
def quote_identifier(self, expression: E, identify: bool = True) -> E:
|
||||
# This disables quoting DUAL in SELECT ... FROM DUAL, because Snowflake treats an
|
||||
# unquoted DUAL keyword in a special way and does not map it to a user-defined table
|
||||
|
@ -1012,7 +1017,6 @@ class Snowflake(Dialect):
|
|||
exp.ApproxDistinct: rename_func("APPROX_COUNT_DISTINCT"),
|
||||
exp.ArgMax: rename_func("MAX_BY"),
|
||||
exp.ArgMin: rename_func("MIN_BY"),
|
||||
exp.Array: inline_array_sql,
|
||||
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.AtTimeZone: lambda self, e: self.func(
|
||||
|
@ -1033,7 +1037,9 @@ class Snowflake(Dialect):
|
|||
exp.DayOfWeekIso: rename_func("DAYOFWEEKISO"),
|
||||
exp.DayOfYear: rename_func("DAYOFYEAR"),
|
||||
exp.Explode: rename_func("FLATTEN"),
|
||||
exp.Extract: rename_func("DATE_PART"),
|
||||
exp.Extract: lambda self, e: self.func(
|
||||
"DATE_PART", map_date_part(e.this, self.dialect), e.expression
|
||||
),
|
||||
exp.FileFormatProperty: lambda self,
|
||||
e: f"FILE_FORMAT=({self.expressions(e, 'expressions', sep=' ')})",
|
||||
exp.FromTimeZone: lambda self, e: self.func(
|
||||
|
@ -1154,6 +1160,8 @@ class Snowflake(Dialect):
|
|||
exp.VarMap,
|
||||
}
|
||||
|
||||
RESPECT_IGNORE_NULLS_UNSUPPORTED_EXPRESSIONS = (exp.ArrayAgg,)
|
||||
|
||||
def with_properties(self, properties: exp.Properties) -> str:
|
||||
return self.properties(properties, wrapped=False, prefix=self.sep(""), sep=" ")
|
||||
|
||||
|
@ -1224,13 +1232,15 @@ class Snowflake(Dialect):
|
|||
unnest_alias = expression.args.get("alias")
|
||||
offset = expression.args.get("offset")
|
||||
|
||||
unnest_alias_columns = unnest_alias.columns if unnest_alias else []
|
||||
value = seq_get(unnest_alias_columns, 0) or exp.to_identifier("value")
|
||||
|
||||
columns = [
|
||||
exp.to_identifier("seq"),
|
||||
exp.to_identifier("key"),
|
||||
exp.to_identifier("path"),
|
||||
offset.pop() if isinstance(offset, exp.Expression) else exp.to_identifier("index"),
|
||||
seq_get(unnest_alias.columns if unnest_alias else [], 0)
|
||||
or exp.to_identifier("value"),
|
||||
value,
|
||||
exp.to_identifier("this"),
|
||||
]
|
||||
|
||||
|
@ -1246,7 +1256,9 @@ class Snowflake(Dialect):
|
|||
explode = f"TABLE(FLATTEN({table_input}))"
|
||||
alias = self.sql(unnest_alias)
|
||||
alias = f" AS {alias}" if alias else ""
|
||||
return f"{explode}{alias}"
|
||||
value = "" if isinstance(expression.parent, (exp.From, exp.Join)) else f"{value} FROM "
|
||||
|
||||
return f"{value}{explode}{alias}"
|
||||
|
||||
def show_sql(self, expression: exp.Show) -> str:
|
||||
terse = "TERSE " if expression.args.get("terse") else ""
|
||||
|
@ -1398,3 +1410,45 @@ class Snowflake(Dialect):
|
|||
return f"{this_name}{self.sep()}{copy_grants}{this_schema}"
|
||||
|
||||
return super().createable_sql(expression, locations)
|
||||
|
||||
def arrayagg_sql(self, expression: exp.ArrayAgg) -> str:
|
||||
this = expression.this
|
||||
|
||||
# If an ORDER BY clause is present, we need to remove it from ARRAY_AGG
|
||||
# and add it later as part of the WITHIN GROUP clause
|
||||
order = this if isinstance(this, exp.Order) else None
|
||||
if order:
|
||||
expression.set("this", order.this.pop())
|
||||
|
||||
expr_sql = super().arrayagg_sql(expression)
|
||||
|
||||
if order:
|
||||
expr_sql = self.sql(exp.WithinGroup(this=expr_sql, expression=order))
|
||||
|
||||
return expr_sql
|
||||
|
||||
def array_sql(self, expression: exp.Array) -> str:
|
||||
expressions = expression.expressions
|
||||
|
||||
first_expr = seq_get(expressions, 0)
|
||||
if isinstance(first_expr, exp.Select):
|
||||
# SELECT AS STRUCT foo AS alias_foo -> ARRAY_AGG(OBJECT_CONSTRUCT('alias_foo', foo))
|
||||
if first_expr.text("kind").upper() == "STRUCT":
|
||||
object_construct_args = []
|
||||
for expr in first_expr.expressions:
|
||||
# Alias case: SELECT AS STRUCT foo AS alias_foo -> OBJECT_CONSTRUCT('alias_foo', foo)
|
||||
# Column case: SELECT AS STRUCT foo -> OBJECT_CONSTRUCT('foo', foo)
|
||||
name = expr.this if isinstance(expr, exp.Alias) else expr
|
||||
|
||||
object_construct_args.extend([exp.Literal.string(expr.alias_or_name), name])
|
||||
|
||||
array_agg = exp.ArrayAgg(
|
||||
this=_build_object_construct(args=object_construct_args)
|
||||
)
|
||||
|
||||
first_expr.set("kind", None)
|
||||
first_expr.set("expressions", [array_agg])
|
||||
|
||||
return self.sql(first_expr.subquery())
|
||||
|
||||
return inline_array_sql(self, expression)
|
||||
|
|
|
@ -5539,6 +5539,10 @@ class ArrayConcat(Func):
|
|||
is_var_len_args = True
|
||||
|
||||
|
||||
class ArrayConcatAgg(AggFunc):
|
||||
pass
|
||||
|
||||
|
||||
class ArrayConstructCompact(Func):
|
||||
arg_types = {"expressions": True}
|
||||
is_var_len_args = True
|
||||
|
|
|
@ -667,6 +667,8 @@ class Generator(metaclass=_Generator):
|
|||
# Expressions that need to have all CTEs under them bubbled up to them
|
||||
EXPRESSIONS_WITHOUT_NESTED_CTES: t.Set[t.Type[exp.Expression]] = set()
|
||||
|
||||
RESPECT_IGNORE_NULLS_UNSUPPORTED_EXPRESSIONS: t.Tuple[t.Type[exp.Expression], ...] = ()
|
||||
|
||||
SENTINEL_LINE_BREAK = "__SQLGLOT__LB__"
|
||||
|
||||
__slots__ = (
|
||||
|
@ -4268,6 +4270,13 @@ class Generator(metaclass=_Generator):
|
|||
return expression
|
||||
|
||||
def _embed_ignore_nulls(self, expression: exp.IgnoreNulls | exp.RespectNulls, text: str) -> str:
|
||||
this = expression.this
|
||||
if isinstance(this, self.RESPECT_IGNORE_NULLS_UNSUPPORTED_EXPRESSIONS):
|
||||
self.unsupported(
|
||||
f"RESPECT/IGNORE NULLS is not supported for {type(this).key} in {self.dialect.__class__.__name__}"
|
||||
)
|
||||
return self.sql(this)
|
||||
|
||||
if self.IGNORE_NULLS_IN_FUNC and not expression.meta.get("inline"):
|
||||
# The first modifier here will be the one closest to the AggFunc's arg
|
||||
mods = sorted(
|
||||
|
|
|
@ -6234,7 +6234,12 @@ class Parser(metaclass=_Parser):
|
|||
expressions = apply_index_offset(
|
||||
this, expressions, -self.dialect.INDEX_OFFSET, dialect=self.dialect
|
||||
)
|
||||
this = self.expression(exp.Bracket, this=this, expressions=expressions)
|
||||
this = self.expression(
|
||||
exp.Bracket,
|
||||
this=this,
|
||||
expressions=expressions,
|
||||
comments=this.pop_comments(),
|
||||
)
|
||||
|
||||
self._add_comments(this)
|
||||
return self._parse_bracket(this)
|
||||
|
|
27
sqlglotrs/Cargo.lock
generated
27
sqlglotrs/Cargo.lock
generated
|
@ -329,11 +329,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pyo3"
|
||||
version = "0.22.6"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884"
|
||||
checksum = "f239d656363bcee73afef85277f1b281e8ac6212a1d42aa90e55b90ed43c47a4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"indoc",
|
||||
"libc",
|
||||
"memoffset",
|
||||
|
@ -347,9 +346,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pyo3-build-config"
|
||||
version = "0.22.6"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38"
|
||||
checksum = "755ea671a1c34044fa165247aaf6f419ca39caa6003aee791a0df2713d8f1b6d"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"target-lexicon",
|
||||
|
@ -357,9 +356,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pyo3-ffi"
|
||||
version = "0.22.6"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636"
|
||||
checksum = "fc95a2e67091e44791d4ea300ff744be5293f394f1bafd9f78c080814d35956e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pyo3-build-config",
|
||||
|
@ -367,9 +366,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pyo3-macros"
|
||||
version = "0.22.6"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453"
|
||||
checksum = "a179641d1b93920829a62f15e87c0ed791b6c8db2271ba0fd7c2686090510214"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"pyo3-macros-backend",
|
||||
|
@ -379,9 +378,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pyo3-macros-backend"
|
||||
version = "0.22.6"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe"
|
||||
checksum = "9dff85ebcaab8c441b0e3f7ae40a6963ecea8a9f5e74f647e33fcf5ec9a1e89e"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
|
@ -503,7 +502,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sqlglotrs"
|
||||
version = "0.4.2"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"criterion",
|
||||
"pyo3",
|
||||
|
@ -526,9 +525,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.12.16"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||
checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a"
|
||||
|
||||
[[package]]
|
||||
name = "tinytemplate"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "sqlglotrs"
|
||||
version = "0.4.2"
|
||||
version = "0.5.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
|
@ -19,7 +19,7 @@ default = []
|
|||
profiling = ["serde", "serde_json"]
|
||||
|
||||
[dependencies]
|
||||
pyo3 = {version ="0.22.6", features = ["auto-initialize"]}
|
||||
pyo3 = {version ="0.25"}
|
||||
rustc-hash = { version = "2.1" }
|
||||
|
||||
# Optional dependencies used for profiling
|
||||
|
@ -31,3 +31,4 @@ criterion = "0.5"
|
|||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = { version = "1" }
|
||||
sqlglotrs = { path = "." , features = ["profiling"] }
|
||||
pyo3 = { version = "0.25", features = ["auto-initialize"] }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::settings::TokenType;
|
||||
use pyo3::prelude::PyListMethods;
|
||||
use pyo3::types::{PyList, PyNone, PyString};
|
||||
use pyo3::{pyclass, IntoPy, Py, PyObject, Python};
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::{PyList, PyString};
|
||||
use pyo3::{pyclass, Py, PyObject, Python};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[pyclass]
|
||||
|
@ -36,13 +36,13 @@ impl Token {
|
|||
) -> Token {
|
||||
Python::with_gil(|py| Token {
|
||||
token_type,
|
||||
token_type_py: PyNone::get_bound(py).into_py(py),
|
||||
text: PyString::new_bound(py, &text).into_py(py),
|
||||
token_type_py: py.None(),
|
||||
text: PyString::new(py, &text).unbind(),
|
||||
line,
|
||||
col,
|
||||
start,
|
||||
end,
|
||||
comments: PyList::new_bound(py, &comments).into(),
|
||||
comments: PyList::new(py, &comments).unwrap().unbind(),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,10 @@ class TestBigQuery(Validator):
|
|||
select_with_quoted_udf = self.validate_identity("SELECT `p.d.UdF`(data) FROM `p.d.t`")
|
||||
self.assertEqual(select_with_quoted_udf.selects[0].name, "p.d.UdF")
|
||||
|
||||
self.validate_identity("ARRAY_CONCAT_AGG(x ORDER BY ARRAY_LENGTH(x) LIMIT 2)")
|
||||
self.validate_identity("ARRAY_CONCAT_AGG(x LIMIT 2)")
|
||||
self.validate_identity("ARRAY_CONCAT_AGG(x ORDER BY ARRAY_LENGTH(x))")
|
||||
self.validate_identity("ARRAY_CONCAT_AGG(x)")
|
||||
self.validate_identity("PARSE_TIMESTAMP('%Y-%m-%dT%H:%M:%E*S%z', x)")
|
||||
self.validate_identity("SELECT ARRAY_CONCAT([1])")
|
||||
self.validate_identity("SELECT * FROM READ_CSV('bla.csv')")
|
||||
|
@ -2560,3 +2564,55 @@ OPTIONS (
|
|||
self.assertEqual(qualified.sql("bigquery"), "SELECT * FROM `P`.`D`.`T` AS `T`")
|
||||
finally:
|
||||
BigQuery.NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE
|
||||
|
||||
def test_array_agg(self):
|
||||
for distinct in ("", "DISTINCT "):
|
||||
self.validate_all(
|
||||
f"SELECT ARRAY_AGG({distinct}x ORDER BY x)",
|
||||
write={
|
||||
"bigquery": f"SELECT ARRAY_AGG({distinct}x ORDER BY x)",
|
||||
"snowflake": f"SELECT ARRAY_AGG({distinct}x) WITHIN GROUP (ORDER BY x NULLS FIRST)",
|
||||
},
|
||||
)
|
||||
|
||||
for nulls in ("", " IGNORE NULLS", " RESPECT NULLS"):
|
||||
self.validate_all(
|
||||
f"SELECT ARRAY_AGG(x{nulls} ORDER BY col1 ASC, col2 DESC)",
|
||||
write={
|
||||
"bigquery": f"SELECT ARRAY_AGG(x{nulls} ORDER BY col1 ASC, col2 DESC)",
|
||||
"snowflake": "SELECT ARRAY_AGG(x) WITHIN GROUP (ORDER BY col1 ASC NULLS FIRST, col2 DESC NULLS LAST)",
|
||||
},
|
||||
)
|
||||
|
||||
def test_select_as_struct(self):
|
||||
self.validate_all(
|
||||
"SELECT ARRAY(SELECT AS STRUCT x1 AS x1, x2 AS x2 FROM t) AS array_col",
|
||||
write={
|
||||
"bigquery": "SELECT ARRAY(SELECT AS STRUCT x1 AS x1, x2 AS x2 FROM t) AS array_col",
|
||||
"snowflake": "SELECT (SELECT ARRAY_AGG(OBJECT_CONSTRUCT('x1', x1, 'x2', x2)) FROM t) AS array_col",
|
||||
},
|
||||
)
|
||||
|
||||
self.validate_all(
|
||||
"WITH t1 AS (SELECT ARRAY(SELECT AS STRUCT x1 AS alias_x1, x2 /* test */ FROM t2) AS array_col) SELECT array_col[0].alias_x1, array_col[0].x2 FROM t1",
|
||||
write={
|
||||
"bigquery": "WITH t1 AS (SELECT ARRAY(SELECT AS STRUCT x1 AS alias_x1, x2 /* test */ FROM t2) AS array_col) SELECT array_col[0].alias_x1, array_col[0].x2 FROM t1",
|
||||
"snowflake": "WITH t1 AS (SELECT (SELECT ARRAY_AGG(OBJECT_CONSTRUCT('alias_x1', x1, 'x2', x2 /* test */)) FROM t2) AS array_col) SELECT array_col[0].alias_x1, array_col[0].x2 FROM t1",
|
||||
},
|
||||
)
|
||||
|
||||
self.validate_all(
|
||||
"WITH t1 AS (SELECT ARRAY(SELECT AS STRUCT 1 AS a, 2 AS b) AS array_col) SELECT array_col[0].a, array_col[0].b FROM t1",
|
||||
write={
|
||||
"bigquery": "WITH t1 AS (SELECT ARRAY(SELECT AS STRUCT 1 AS a, 2 AS b) AS array_col) SELECT array_col[0].a, array_col[0].b FROM t1",
|
||||
"snowflake": "WITH t1 AS (SELECT (SELECT ARRAY_AGG(OBJECT_CONSTRUCT('a', 1, 'b', 2))) AS array_col) SELECT array_col[0].a, array_col[0].b FROM t1",
|
||||
},
|
||||
)
|
||||
|
||||
self.validate_all(
|
||||
"WITH t1 AS (SELECT ARRAY(SELECT AS STRUCT x1 AS alias_x1, x2 /* test */ FROM t2 WHERE x2 = 4) AS array_col) SELECT array_col[0].alias_x1, array_col[0].x2 FROM t1",
|
||||
write={
|
||||
"bigquery": "WITH t1 AS (SELECT ARRAY(SELECT AS STRUCT x1 AS alias_x1, x2 /* test */ FROM t2 WHERE x2 = 4) AS array_col) SELECT array_col[0].alias_x1, array_col[0].x2 FROM t1",
|
||||
"snowflake": "WITH t1 AS (SELECT (SELECT ARRAY_AGG(OBJECT_CONSTRUCT('alias_x1', x1, 'x2', x2 /* test */)) FROM t2 WHERE x2 = 4) AS array_col) SELECT array_col[0].alias_x1, array_col[0].x2 FROM t1",
|
||||
},
|
||||
)
|
||||
|
|
|
@ -161,7 +161,7 @@ class TestHive(Validator):
|
|||
"CREATE TABLE test STORED AS parquet TBLPROPERTIES ('x'='1', 'Z'='2') AS SELECT 1",
|
||||
write={
|
||||
"duckdb": "CREATE TABLE test AS SELECT 1",
|
||||
"presto": "CREATE TABLE test WITH (FORMAT='PARQUET', x='1', Z='2') AS SELECT 1",
|
||||
"presto": "CREATE TABLE test WITH (format='parquet', x='1', Z='2') AS SELECT 1",
|
||||
"hive": "CREATE TABLE test STORED AS PARQUET TBLPROPERTIES ('x'='1', 'Z'='2') AS SELECT 1",
|
||||
"spark": "CREATE TABLE test USING PARQUET TBLPROPERTIES ('x'='1', 'Z'='2') AS SELECT 1",
|
||||
},
|
||||
|
|
|
@ -465,7 +465,7 @@ class TestPresto(Validator):
|
|||
"CREATE TABLE test WITH (FORMAT = 'PARQUET') AS SELECT 1",
|
||||
write={
|
||||
"duckdb": "CREATE TABLE test AS SELECT 1",
|
||||
"presto": "CREATE TABLE test WITH (FORMAT='PARQUET') AS SELECT 1",
|
||||
"presto": "CREATE TABLE test WITH (format='PARQUET') AS SELECT 1",
|
||||
"hive": "CREATE TABLE test STORED AS PARQUET AS SELECT 1",
|
||||
"spark": "CREATE TABLE test USING PARQUET AS SELECT 1",
|
||||
},
|
||||
|
@ -474,7 +474,7 @@ class TestPresto(Validator):
|
|||
"CREATE TABLE test STORED AS 'PARQUET' AS SELECT 1",
|
||||
write={
|
||||
"duckdb": "CREATE TABLE test AS SELECT 1",
|
||||
"presto": "CREATE TABLE test WITH (FORMAT='PARQUET') AS SELECT 1",
|
||||
"presto": "CREATE TABLE test WITH (format='PARQUET') AS SELECT 1",
|
||||
"hive": "CREATE TABLE test STORED AS PARQUET AS SELECT 1",
|
||||
"spark": "CREATE TABLE test USING PARQUET AS SELECT 1",
|
||||
},
|
||||
|
@ -483,7 +483,7 @@ class TestPresto(Validator):
|
|||
"CREATE TABLE test WITH (FORMAT = 'PARQUET', X = '1', Z = '2') AS SELECT 1",
|
||||
write={
|
||||
"duckdb": "CREATE TABLE test AS SELECT 1",
|
||||
"presto": "CREATE TABLE test WITH (FORMAT='PARQUET', X='1', Z='2') AS SELECT 1",
|
||||
"presto": "CREATE TABLE test WITH (format='PARQUET', X='1', Z='2') AS SELECT 1",
|
||||
"hive": "CREATE TABLE test STORED AS PARQUET TBLPROPERTIES ('X'='1', 'Z'='2') AS SELECT 1",
|
||||
"spark": "CREATE TABLE test USING PARQUET TBLPROPERTIES ('X'='1', 'Z'='2') AS SELECT 1",
|
||||
},
|
||||
|
|
|
@ -1071,6 +1071,14 @@ class TestSnowflake(Validator):
|
|||
},
|
||||
)
|
||||
|
||||
self.validate_all(
|
||||
"SELECT DATE_PART(WEEKISO, CAST('2013-12-25' AS DATE))",
|
||||
read={
|
||||
"bigquery": "SELECT EXTRACT(ISOWEEK FROM CAST('2013-12-25' AS DATE))",
|
||||
"snowflake": "SELECT DATE_PART(WEEKISO, CAST('2013-12-25' AS DATE))",
|
||||
},
|
||||
)
|
||||
|
||||
def test_null_treatment(self):
|
||||
self.validate_all(
|
||||
r"SELECT FIRST_VALUE(TABLE1.COLUMN1) OVER (PARTITION BY RANDOM_COLUMN1, RANDOM_COLUMN2 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS MY_ALIAS FROM TABLE1",
|
||||
|
@ -1102,6 +1110,15 @@ class TestSnowflake(Validator):
|
|||
"snowflake": r"SELECT FIRST_VALUE(TABLE1.COLUMN1) IGNORE NULLS OVER (PARTITION BY RANDOM_COLUMN1, RANDOM_COLUMN2 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS MY_ALIAS FROM TABLE1"
|
||||
},
|
||||
)
|
||||
self.validate_all(
|
||||
"SELECT * FROM foo WHERE 'str' IN (SELECT value FROM TABLE(FLATTEN(INPUT => vals)) AS _u(seq, key, path, index, value, this))",
|
||||
read={
|
||||
"bigquery": "SELECT * FROM foo WHERE 'str' IN UNNEST(vals)",
|
||||
},
|
||||
write={
|
||||
"snowflake": "SELECT * FROM foo WHERE 'str' IN (SELECT value FROM TABLE(FLATTEN(INPUT => vals)) AS _u(seq, key, path, index, value, this))",
|
||||
},
|
||||
)
|
||||
|
||||
def test_staged_files(self):
|
||||
# Ensure we don't treat staged file paths as identifiers (i.e. they're not normalized)
|
||||
|
|
|
@ -56,7 +56,7 @@ class TestSpark(Validator):
|
|||
"CREATE TABLE x USING ICEBERG PARTITIONED BY (MONTHS(y)) LOCATION 's3://z'",
|
||||
write={
|
||||
"duckdb": "CREATE TABLE x",
|
||||
"presto": "CREATE TABLE x WITH (FORMAT='ICEBERG', PARTITIONED_BY=ARRAY['MONTHS(y)'])",
|
||||
"presto": "CREATE TABLE x WITH (format='ICEBERG', PARTITIONED_BY=ARRAY['MONTHS(y)'])",
|
||||
"hive": "CREATE TABLE x STORED AS ICEBERG PARTITIONED BY (MONTHS(y)) LOCATION 's3://z'",
|
||||
"spark": "CREATE TABLE x USING ICEBERG PARTITIONED BY (MONTHS(y)) LOCATION 's3://z'",
|
||||
},
|
||||
|
@ -65,7 +65,9 @@ class TestSpark(Validator):
|
|||
"CREATE TABLE test STORED AS PARQUET AS SELECT 1",
|
||||
write={
|
||||
"duckdb": "CREATE TABLE test AS SELECT 1",
|
||||
"presto": "CREATE TABLE test WITH (FORMAT='PARQUET') AS SELECT 1",
|
||||
"presto": "CREATE TABLE test WITH (format='PARQUET') AS SELECT 1",
|
||||
"trino": "CREATE TABLE test WITH (format='PARQUET') AS SELECT 1",
|
||||
"athena": "CREATE TABLE test WITH (format='PARQUET') AS SELECT 1", # note: lowercase format property is important for Athena
|
||||
"hive": "CREATE TABLE test STORED AS PARQUET AS SELECT 1",
|
||||
"spark": "CREATE TABLE test USING PARQUET AS SELECT 1",
|
||||
},
|
||||
|
@ -83,7 +85,7 @@ class TestSpark(Validator):
|
|||
COMMENT 'Test comment: blah'
|
||||
WITH (
|
||||
PARTITIONED_BY=ARRAY['date'],
|
||||
FORMAT='ICEBERG',
|
||||
format='ICEBERG',
|
||||
x='1'
|
||||
)""",
|
||||
"hive": """CREATE TABLE blah (
|
||||
|
|
12
tests/fixtures/pretty.sql
vendored
12
tests/fixtures/pretty.sql
vendored
|
@ -457,3 +457,15 @@ ON t.id = s.id
|
|||
WHEN MATCHED THEN UPDATE SET
|
||||
status = s.status,
|
||||
amount = s.amount;
|
||||
|
||||
SELECT
|
||||
id,
|
||||
-- SUM(total) as all_that,
|
||||
ARRAY_AGG(foo)[0][0] AS first_foo,
|
||||
FROM facts
|
||||
GROUP BY all;
|
||||
SELECT
|
||||
id,
|
||||
ARRAY_AGG(foo)[0][0] AS first_foo /* SUM(total) as all_that, */
|
||||
FROM facts
|
||||
GROUP BY ALL;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue