ydb-sqlglot-plugin 0.2.3__tar.gz → 0.2.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ydb-sqlglot-plugin
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Summary: YDB dialect plugin for sqlglot
5
5
  Author: YDB Team
6
6
  License: Apache-2.0
@@ -53,6 +53,94 @@ result = sqlglot.transpile("$t = (SELECT id FROM users); SELECT * FROM $t AS t",
53
53
 
54
54
  ## What the plugin does
55
55
 
56
+ ### YDB syntax documentation conformance
57
+
58
+ Source index: https://ydb.tech/docs/en/yql/reference/syntax/
59
+
60
+ This is a working checklist for doc-conformance work against YDB syntax
61
+ documentation. A checked item means `tests/unit/test_ydb.py` has focused tests
62
+ derived from that page's snippets, syntax variants, or documented negative
63
+ cases. An unchecked item is a backlog item.
64
+
65
+ - [x] [Lexical structure](https://ydb.tech/docs/en/yql/reference/syntax/lexer) - `test_lexer_doc_*`
66
+ - [x] [Expressions](https://ydb.tech/docs/en/yql/reference/syntax/expressions) - `test_expressions_doc_*`
67
+ - [x] [SELECT](https://ydb.tech/docs/en/yql/reference/syntax/select/) - all tracked SELECT subpages below
68
+ - [x] [Overview](https://ydb.tech/docs/en/yql/reference/syntax/select/) - `test_select_overview_doc_*`
69
+ - [x] [FROM](https://ydb.tech/docs/en/yql/reference/syntax/select/from) - `test_from_doc_snippets`
70
+ - [x] [FROM AS_TABLE](https://ydb.tech/docs/en/yql/reference/syntax/select/from_as_table) - `test_from_as_table_doc_snippet`
71
+ - [x] [FROM SELECT](https://ydb.tech/docs/en/yql/reference/syntax/select/from_select) - `test_from_select_doc_snippets`
72
+ - [x] [FLATTEN](https://ydb.tech/docs/en/yql/reference/syntax/select/flatten) - `test_flatten_*_page_snippet_roundtrip_stable`
73
+ - [x] [GROUP BY](https://ydb.tech/docs/en/yql/reference/syntax/select/group_by) - `test_group_by_doc_*`
74
+ - [x] [JOIN](https://ydb.tech/docs/en/yql/reference/syntax/select/join) - `test_join_doc_*`
75
+ - [x] [WINDOW](https://ydb.tech/docs/en/yql/reference/syntax/select/window) - `test_window_functions`, `test_window_doc_partition_compact_hint`
76
+ - [x] [DISTINCT](https://ydb.tech/docs/en/yql/reference/syntax/select/distinct) - `test_distinct_doc_*`
77
+ - [x] [UNIQUE DISTINCT](https://ydb.tech/docs/en/yql/reference/syntax/select/unique_distinct_hints) - `test_unique_distinct_hints`
78
+ - [x] [UNION](https://ydb.tech/docs/en/yql/reference/syntax/select/union) - `test_union_doc_*`
79
+ - [x] [VIEW secondary_index](https://ydb.tech/docs/en/yql/reference/syntax/select/secondary_index) - `test_secondary_index_doc_*`
80
+ - [x] [VIEW vector_index](https://ydb.tech/docs/en/yql/reference/syntax/select/vector_index) - `test_vector_index_doc_*`
81
+ - [x] [WITH](https://ydb.tech/docs/en/yql/reference/syntax/select/with) - `test_with_doc_*`
82
+ - [x] [WITHOUT](https://ydb.tech/docs/en/yql/reference/syntax/select/without) - `test_without_doc_*`
83
+ - [x] [WHERE](https://ydb.tech/docs/en/yql/reference/syntax/select/where) - `test_where_doc_filter_snippet`
84
+ - [x] [ORDER BY](https://ydb.tech/docs/en/yql/reference/syntax/select/order_by) - `test_order_by_doc_*`
85
+ - [x] [ASSUME ORDER BY](https://ydb.tech/docs/en/yql/reference/syntax/select/assume_order_by) - `test_assume_order_by_doc_*`
86
+ - [x] [LIMIT OFFSET](https://ydb.tech/docs/en/yql/reference/syntax/select/limit_offset) - `test_limit_offset_doc_*`
87
+ - [x] [SAMPLE / TABLESAMPLE](https://ydb.tech/docs/en/yql/reference/syntax/select/sample) - `test_sample_doc_*`
88
+ - [x] [MATCH_RECOGNIZE](https://ydb.tech/docs/en/yql/reference/syntax/select/match_recognize) - `test_match_recognize_doc_*`
89
+ - [ ] [VALUES](https://ydb.tech/docs/en/yql/reference/syntax/values)
90
+ - [x] [CREATE TABLE](https://ydb.tech/docs/en/yql/reference/syntax/create_table/) - `test_create_table_doc_*`, `test_create_table_secondary_index_doc_*`, `test_create_table_family_doc_*`, TTL tests
91
+ - [ ] [DROP TABLE](https://ydb.tech/docs/en/yql/reference/syntax/drop_table)
92
+ - [x] [INSERT](https://ydb.tech/docs/en/yql/reference/syntax/insert_into) - `test_insert_into_doc_snippets`, `test_insert_into_external_file_doc_snippet` (skipped: external sources), pg→ydb DML coverage
93
+ - [ ] [ALTER TABLE](https://ydb.tech/docs/en/yql/reference/syntax/alter_table/)
94
+ - [x] [UPDATE](https://ydb.tech/docs/en/yql/reference/syntax/update) - `test_update_doc_*`, `test_update_on_doc_snippet`
95
+ - [ ] [DELETE](https://ydb.tech/docs/en/yql/reference/syntax/delete)
96
+ - [ ] [REPLACE](https://ydb.tech/docs/en/yql/reference/syntax/replace_into)
97
+ - [x] [UPSERT](https://ydb.tech/docs/en/yql/reference/syntax/upsert_into) - `test_upsert_into_doc_*`
98
+ - [ ] [ACTION](https://ydb.tech/docs/en/yql/reference/syntax/action)
99
+ - [ ] [INTO RESULT](https://ydb.tech/docs/en/yql/reference/syntax/into_result)
100
+ - [ ] [PRAGMA](https://ydb.tech/docs/en/yql/reference/syntax/pragma)
101
+ - [ ] [DECLARE](https://ydb.tech/docs/en/yql/reference/syntax/declare)
102
+ - [ ] [CREATE TOPIC](https://ydb.tech/docs/en/yql/reference/syntax/create-topic)
103
+ - [ ] [ALTER TOPIC](https://ydb.tech/docs/en/yql/reference/syntax/alter-topic)
104
+ - [ ] [DROP TOPIC](https://ydb.tech/docs/en/yql/reference/syntax/drop-topic)
105
+ - [ ] [CREATE ASYNC REPLICATION](https://ydb.tech/docs/en/yql/reference/syntax/create-async-replication)
106
+ - [ ] [ALTER ASYNC REPLICATION](https://ydb.tech/docs/en/yql/reference/syntax/alter-async-replication)
107
+ - [ ] [DROP ASYNC REPLICATION](https://ydb.tech/docs/en/yql/reference/syntax/drop-async-replication)
108
+ - [ ] [CREATE TRANSFER](https://ydb.tech/docs/en/yql/reference/syntax/create-transfer)
109
+ - [ ] [ALTER TRANSFER](https://ydb.tech/docs/en/yql/reference/syntax/alter-transfer)
110
+ - [ ] [DROP TRANSFER](https://ydb.tech/docs/en/yql/reference/syntax/drop-transfer)
111
+ - [ ] [COMMIT](https://ydb.tech/docs/en/yql/reference/syntax/commit)
112
+ - [ ] [CREATE VIEW](https://ydb.tech/docs/en/yql/reference/syntax/create-view)
113
+ - [ ] [ALTER VIEW](https://ydb.tech/docs/en/yql/reference/syntax/alter-view)
114
+ - [ ] [DROP VIEW](https://ydb.tech/docs/en/yql/reference/syntax/drop-view)
115
+ - [ ] [CREATE EXTERNAL DATA SOURCE](https://ydb.tech/docs/en/yql/reference/syntax/create-external-data-source)
116
+ - [ ] [CREATE EXTERNAL TABLE](https://ydb.tech/docs/en/yql/reference/syntax/create-external-table)
117
+ - [ ] [DROP EXTERNAL DATA SOURCE](https://ydb.tech/docs/en/yql/reference/syntax/drop-external-data-source)
118
+ - [ ] [DROP EXTERNAL TABLE](https://ydb.tech/docs/en/yql/reference/syntax/drop-external-table)
119
+ - [ ] [CREATE OBJECT (TYPE SECRET)](https://ydb.tech/docs/en/yql/reference/syntax/create-object-type-secret)
120
+ - [ ] [CREATE OBJECT (TYPE SECRET_ACCESS)](https://ydb.tech/docs/en/yql/reference/syntax/create-object-type-secret-access)
121
+ - [ ] [DROP OBJECT (TYPE SECRET)](https://ydb.tech/docs/en/yql/reference/syntax/drop-object-type-secret)
122
+ - [ ] [DROP OBJECT (TYPE SECRET_ACCESS)](https://ydb.tech/docs/en/yql/reference/syntax/drop-object-type-secret-access)
123
+ - [ ] [UPSERT OBJECT (TYPE SECRET)](https://ydb.tech/docs/en/yql/reference/syntax/upsert-object-type-secret)
124
+ - [ ] [CREATE RESOURCE POOL](https://ydb.tech/docs/en/yql/reference/syntax/create-resource-pool)
125
+ - [ ] [ALTER RESOURCE POOL](https://ydb.tech/docs/en/yql/reference/syntax/alter-resource-pool)
126
+ - [ ] [DROP RESOURCE POOL](https://ydb.tech/docs/en/yql/reference/syntax/drop-resource-pool)
127
+ - [ ] [CREATE RESOURCE POOL CLASSIFIER](https://ydb.tech/docs/en/yql/reference/syntax/create-resource-pool-classifier)
128
+ - [ ] [ALTER RESOURCE POOL CLASSIFIER](https://ydb.tech/docs/en/yql/reference/syntax/alter-resource-pool-classifier)
129
+ - [ ] [DROP RESOURCE POOL CLASSIFIER](https://ydb.tech/docs/en/yql/reference/syntax/drop-resource-pool-classifier)
130
+ - [ ] [CREATE USER](https://ydb.tech/docs/en/yql/reference/syntax/create-user)
131
+ - [ ] [ALTER USER](https://ydb.tech/docs/en/yql/reference/syntax/alter-user)
132
+ - [ ] [DROP USER](https://ydb.tech/docs/en/yql/reference/syntax/drop-user)
133
+ - [ ] [CREATE GROUP](https://ydb.tech/docs/en/yql/reference/syntax/create-group)
134
+ - [ ] [ALTER GROUP](https://ydb.tech/docs/en/yql/reference/syntax/alter-group)
135
+ - [ ] [DROP GROUP](https://ydb.tech/docs/en/yql/reference/syntax/drop-group)
136
+ - [ ] [GRANT](https://ydb.tech/docs/en/yql/reference/syntax/grant)
137
+ - [ ] [REVOKE](https://ydb.tech/docs/en/yql/reference/syntax/revoke)
138
+ - [ ] [Unsupported syntax](https://ydb.tech/docs/en/yql/reference/syntax/unsupported)
139
+
140
+ Unchecked pages may already have incidental parser support. They remain
141
+ unchecked until their specific documentation page has been used as the normative
142
+ source and focused tests have been added or corrected.
143
+
56
144
  ### Any SQL → YDB
57
145
 
58
146
  #### Table names
@@ -140,18 +228,27 @@ The plugin parses YDB/YQL back into sqlglot's AST, enabling round-trips, YDB-to-
140
228
  | `$variable` references | `SELECT * FROM $t AS t` |
141
229
  | `Module::Function()` | `DateTime::GetYear(ts)` |
142
230
  | `DECLARE $p AS Type` | `DECLARE $p AS Int32` |
143
- | `FLATTEN [LIST\|DICT] BY col` | `FROM t FLATTEN LIST BY col` |
231
+ | `FLATTEN [LIST\|DICT\|OPTIONAL] BY ...` / `FLATTEN COLUMNS` | `FROM t FLATTEN LIST BY col AS item`, `FROM t FLATTEN BY (a, b)`, `FROM t FLATTEN COLUMNS` |
144
232
  | `Optional<T>` / `T?` | `CAST(x AS Optional<Utf8>)` |
145
233
  | Container types | `CAST(x AS List<Int32>)`, `Dict<Utf8, Int64>`, `Set<Utf8>`, `Tuple<Int32, Utf8>` |
146
234
  | `ASSUME ORDER BY` | `SELECT * FROM t ASSUME ORDER BY id` |
147
- | `GROUP BY expr AS alias` | `SELECT v, COUNT(*) FROM t GROUP BY v AS v` |
235
+ | `GROUP BY expr AS alias` / `GROUP COMPACT BY` | `SELECT v, COUNT(*) FROM t GROUP BY v AS v` |
236
+ | `LEFT ONLY JOIN` | `SELECT * FROM a LEFT ONLY JOIN b USING (id)` |
237
+ | `* WITHOUT (...)` projections | `SELECT b.* WITHOUT (b.id) FROM t AS b` |
148
238
  | Named expressions | `$t = (SELECT 1 AS x)` |
149
239
  | Lambda expressions | `($x, $y?) -> ($x + COALESCE($y, 0))`, `($y) -> { $p = "x"; RETURN $p \|\| $y }` |
240
+ | YQL struct literals | `AsList(<|user_id: "u1", description: NULL|>)` |
150
241
  | `IN COMPACT` | `WHERE key IN COMPACT $values` |
151
242
  | `PRAGMA` | `PRAGMA AnsiImplicitCrossJoin` |
243
+ | Table-valued functions | `SELECT * FROM AS_TABLE($Input) AS k` |
244
+ | Table source options and index views | ``FROM `t` WITH TabletId='...'``, ``FROM `t` VIEW PRIMARY KEY v`` |
245
+ | Function-valued expressions | `$grep(x)`, `DateTime::Format("%Y-%m-%d")(ts)`, `Interval("P7D")` |
152
246
 
153
247
  Table names without backticks are accepted on input; the generator always produces backtick-quoted output.
154
248
 
249
+ The parser also tolerates case variants that appear in real YQL dumps, such as
250
+ `set<Utf8>`, `Tuple<Int32, Utf8>?`, and lowercase `return` in lambda blocks.
251
+
155
252
  #### CTEs reassembly
156
253
 
157
254
  YDB-style named expressions are automatically reassembled into standard `WITH` CTEs when targeting other dialects:
@@ -207,6 +304,7 @@ Functions below are recognized by sqlglot as standard SQL expressions and transl
207
304
  | `INTERVAL n HOUR` (literal) | `DateTime::IntervalFromHours(n)` |
208
305
  | `INTERVAL n MINUTE` (literal) | `DateTime::IntervalFromMinutes(n)` |
209
306
  | `INTERVAL n SECOND` (literal) | `DateTime::IntervalFromSeconds(n)` |
307
+ | `Interval("P7D")` (YQL input) | passed through unchanged |
210
308
  | `dateDiff('minute', a, b)` | `(CAST(b AS Int64) - CAST(a AS Int64)) / 60000000` |
211
309
  | `dateDiff('hour', a, b)` | `(CAST(b AS Int64) - CAST(a AS Int64)) / 3600000000` |
212
310
  | `dateDiff('day', a, b)` | `(CAST(b AS Int64) - CAST(a AS Int64)) / 86400000000` |
@@ -256,6 +354,10 @@ arguments and block bodies with local named expressions:
256
354
  ($y) -> { $prefix = "x"; RETURN $prefix || $y; };
257
355
  ```
258
356
 
357
+ ClickHouse `ARRAY JOIN` and simple `arrayJoin(...)` projections, and PostgreSQL
358
+ `LATERAL unnest(...)`, are converted to YDB `FLATTEN BY` when the operation is
359
+ directly tied to the source table.
360
+
259
361
  ### Conditional / math
260
362
 
261
363
  | Input | YQL output |
@@ -270,6 +372,18 @@ arguments and block bodies with local named expressions:
270
372
  |---|---|
271
373
  | `jsonb_col @> value` (PostgreSQL) | `Yson::Contains(jsonb_col, value)` |
272
374
 
375
+ YDB JSON functions are parsed and round-tripped, including `PASSING`,
376
+ `RETURNING`, wrapper modes, and `ON EMPTY` / `ON ERROR` clauses:
377
+
378
+ ```sql
379
+ JSON_VALUE(payload, '$.value + $delta' PASSING 1 AS delta RETURNING Int64 DEFAULT 0 ON EMPTY ERROR ON ERROR)
380
+ JSON_QUERY(payload, '$.items' WITH CONDITIONAL ARRAY WRAPPER NULL ON EMPTY ERROR ON ERROR)
381
+ JSON_EXISTS(payload, '$.items[$Index]' PASSING 0 AS "Index" FALSE ON ERROR)
382
+ ```
383
+
384
+ JSON paths can contain quoted keys, for example
385
+ `JSON_EXISTS(item_result, "$.'P_008 device playback test'")`.
386
+
273
387
  ---
274
388
 
275
389
  ## Type mapping
@@ -26,6 +26,94 @@ result = sqlglot.transpile("$t = (SELECT id FROM users); SELECT * FROM $t AS t",
26
26
 
27
27
  ## What the plugin does
28
28
 
29
+ ### YDB syntax documentation conformance
30
+
31
+ Source index: https://ydb.tech/docs/en/yql/reference/syntax/
32
+
33
+ This is a working checklist for doc-conformance work against YDB syntax
34
+ documentation. A checked item means `tests/unit/test_ydb.py` has focused tests
35
+ derived from that page's snippets, syntax variants, or documented negative
36
+ cases. An unchecked item is a backlog item.
37
+
38
+ - [x] [Lexical structure](https://ydb.tech/docs/en/yql/reference/syntax/lexer) - `test_lexer_doc_*`
39
+ - [x] [Expressions](https://ydb.tech/docs/en/yql/reference/syntax/expressions) - `test_expressions_doc_*`
40
+ - [x] [SELECT](https://ydb.tech/docs/en/yql/reference/syntax/select/) - all tracked SELECT subpages below
41
+ - [x] [Overview](https://ydb.tech/docs/en/yql/reference/syntax/select/) - `test_select_overview_doc_*`
42
+ - [x] [FROM](https://ydb.tech/docs/en/yql/reference/syntax/select/from) - `test_from_doc_snippets`
43
+ - [x] [FROM AS_TABLE](https://ydb.tech/docs/en/yql/reference/syntax/select/from_as_table) - `test_from_as_table_doc_snippet`
44
+ - [x] [FROM SELECT](https://ydb.tech/docs/en/yql/reference/syntax/select/from_select) - `test_from_select_doc_snippets`
45
+ - [x] [FLATTEN](https://ydb.tech/docs/en/yql/reference/syntax/select/flatten) - `test_flatten_*_page_snippet_roundtrip_stable`
46
+ - [x] [GROUP BY](https://ydb.tech/docs/en/yql/reference/syntax/select/group_by) - `test_group_by_doc_*`
47
+ - [x] [JOIN](https://ydb.tech/docs/en/yql/reference/syntax/select/join) - `test_join_doc_*`
48
+ - [x] [WINDOW](https://ydb.tech/docs/en/yql/reference/syntax/select/window) - `test_window_functions`, `test_window_doc_partition_compact_hint`
49
+ - [x] [DISTINCT](https://ydb.tech/docs/en/yql/reference/syntax/select/distinct) - `test_distinct_doc_*`
50
+ - [x] [UNIQUE DISTINCT](https://ydb.tech/docs/en/yql/reference/syntax/select/unique_distinct_hints) - `test_unique_distinct_hints`
51
+ - [x] [UNION](https://ydb.tech/docs/en/yql/reference/syntax/select/union) - `test_union_doc_*`
52
+ - [x] [VIEW secondary_index](https://ydb.tech/docs/en/yql/reference/syntax/select/secondary_index) - `test_secondary_index_doc_*`
53
+ - [x] [VIEW vector_index](https://ydb.tech/docs/en/yql/reference/syntax/select/vector_index) - `test_vector_index_doc_*`
54
+ - [x] [WITH](https://ydb.tech/docs/en/yql/reference/syntax/select/with) - `test_with_doc_*`
55
+ - [x] [WITHOUT](https://ydb.tech/docs/en/yql/reference/syntax/select/without) - `test_without_doc_*`
56
+ - [x] [WHERE](https://ydb.tech/docs/en/yql/reference/syntax/select/where) - `test_where_doc_filter_snippet`
57
+ - [x] [ORDER BY](https://ydb.tech/docs/en/yql/reference/syntax/select/order_by) - `test_order_by_doc_*`
58
+ - [x] [ASSUME ORDER BY](https://ydb.tech/docs/en/yql/reference/syntax/select/assume_order_by) - `test_assume_order_by_doc_*`
59
+ - [x] [LIMIT OFFSET](https://ydb.tech/docs/en/yql/reference/syntax/select/limit_offset) - `test_limit_offset_doc_*`
60
+ - [x] [SAMPLE / TABLESAMPLE](https://ydb.tech/docs/en/yql/reference/syntax/select/sample) - `test_sample_doc_*`
61
+ - [x] [MATCH_RECOGNIZE](https://ydb.tech/docs/en/yql/reference/syntax/select/match_recognize) - `test_match_recognize_doc_*`
62
+ - [ ] [VALUES](https://ydb.tech/docs/en/yql/reference/syntax/values)
63
+ - [x] [CREATE TABLE](https://ydb.tech/docs/en/yql/reference/syntax/create_table/) - `test_create_table_doc_*`, `test_create_table_secondary_index_doc_*`, `test_create_table_family_doc_*`, TTL tests
64
+ - [ ] [DROP TABLE](https://ydb.tech/docs/en/yql/reference/syntax/drop_table)
65
+ - [x] [INSERT](https://ydb.tech/docs/en/yql/reference/syntax/insert_into) - `test_insert_into_doc_snippets`, `test_insert_into_external_file_doc_snippet` (skipped: external sources), pg→ydb DML coverage
66
+ - [ ] [ALTER TABLE](https://ydb.tech/docs/en/yql/reference/syntax/alter_table/)
67
+ - [x] [UPDATE](https://ydb.tech/docs/en/yql/reference/syntax/update) - `test_update_doc_*`, `test_update_on_doc_snippet`
68
+ - [ ] [DELETE](https://ydb.tech/docs/en/yql/reference/syntax/delete)
69
+ - [ ] [REPLACE](https://ydb.tech/docs/en/yql/reference/syntax/replace_into)
70
+ - [x] [UPSERT](https://ydb.tech/docs/en/yql/reference/syntax/upsert_into) - `test_upsert_into_doc_*`
71
+ - [ ] [ACTION](https://ydb.tech/docs/en/yql/reference/syntax/action)
72
+ - [ ] [INTO RESULT](https://ydb.tech/docs/en/yql/reference/syntax/into_result)
73
+ - [ ] [PRAGMA](https://ydb.tech/docs/en/yql/reference/syntax/pragma)
74
+ - [ ] [DECLARE](https://ydb.tech/docs/en/yql/reference/syntax/declare)
75
+ - [ ] [CREATE TOPIC](https://ydb.tech/docs/en/yql/reference/syntax/create-topic)
76
+ - [ ] [ALTER TOPIC](https://ydb.tech/docs/en/yql/reference/syntax/alter-topic)
77
+ - [ ] [DROP TOPIC](https://ydb.tech/docs/en/yql/reference/syntax/drop-topic)
78
+ - [ ] [CREATE ASYNC REPLICATION](https://ydb.tech/docs/en/yql/reference/syntax/create-async-replication)
79
+ - [ ] [ALTER ASYNC REPLICATION](https://ydb.tech/docs/en/yql/reference/syntax/alter-async-replication)
80
+ - [ ] [DROP ASYNC REPLICATION](https://ydb.tech/docs/en/yql/reference/syntax/drop-async-replication)
81
+ - [ ] [CREATE TRANSFER](https://ydb.tech/docs/en/yql/reference/syntax/create-transfer)
82
+ - [ ] [ALTER TRANSFER](https://ydb.tech/docs/en/yql/reference/syntax/alter-transfer)
83
+ - [ ] [DROP TRANSFER](https://ydb.tech/docs/en/yql/reference/syntax/drop-transfer)
84
+ - [ ] [COMMIT](https://ydb.tech/docs/en/yql/reference/syntax/commit)
85
+ - [ ] [CREATE VIEW](https://ydb.tech/docs/en/yql/reference/syntax/create-view)
86
+ - [ ] [ALTER VIEW](https://ydb.tech/docs/en/yql/reference/syntax/alter-view)
87
+ - [ ] [DROP VIEW](https://ydb.tech/docs/en/yql/reference/syntax/drop-view)
88
+ - [ ] [CREATE EXTERNAL DATA SOURCE](https://ydb.tech/docs/en/yql/reference/syntax/create-external-data-source)
89
+ - [ ] [CREATE EXTERNAL TABLE](https://ydb.tech/docs/en/yql/reference/syntax/create-external-table)
90
+ - [ ] [DROP EXTERNAL DATA SOURCE](https://ydb.tech/docs/en/yql/reference/syntax/drop-external-data-source)
91
+ - [ ] [DROP EXTERNAL TABLE](https://ydb.tech/docs/en/yql/reference/syntax/drop-external-table)
92
+ - [ ] [CREATE OBJECT (TYPE SECRET)](https://ydb.tech/docs/en/yql/reference/syntax/create-object-type-secret)
93
+ - [ ] [CREATE OBJECT (TYPE SECRET_ACCESS)](https://ydb.tech/docs/en/yql/reference/syntax/create-object-type-secret-access)
94
+ - [ ] [DROP OBJECT (TYPE SECRET)](https://ydb.tech/docs/en/yql/reference/syntax/drop-object-type-secret)
95
+ - [ ] [DROP OBJECT (TYPE SECRET_ACCESS)](https://ydb.tech/docs/en/yql/reference/syntax/drop-object-type-secret-access)
96
+ - [ ] [UPSERT OBJECT (TYPE SECRET)](https://ydb.tech/docs/en/yql/reference/syntax/upsert-object-type-secret)
97
+ - [ ] [CREATE RESOURCE POOL](https://ydb.tech/docs/en/yql/reference/syntax/create-resource-pool)
98
+ - [ ] [ALTER RESOURCE POOL](https://ydb.tech/docs/en/yql/reference/syntax/alter-resource-pool)
99
+ - [ ] [DROP RESOURCE POOL](https://ydb.tech/docs/en/yql/reference/syntax/drop-resource-pool)
100
+ - [ ] [CREATE RESOURCE POOL CLASSIFIER](https://ydb.tech/docs/en/yql/reference/syntax/create-resource-pool-classifier)
101
+ - [ ] [ALTER RESOURCE POOL CLASSIFIER](https://ydb.tech/docs/en/yql/reference/syntax/alter-resource-pool-classifier)
102
+ - [ ] [DROP RESOURCE POOL CLASSIFIER](https://ydb.tech/docs/en/yql/reference/syntax/drop-resource-pool-classifier)
103
+ - [ ] [CREATE USER](https://ydb.tech/docs/en/yql/reference/syntax/create-user)
104
+ - [ ] [ALTER USER](https://ydb.tech/docs/en/yql/reference/syntax/alter-user)
105
+ - [ ] [DROP USER](https://ydb.tech/docs/en/yql/reference/syntax/drop-user)
106
+ - [ ] [CREATE GROUP](https://ydb.tech/docs/en/yql/reference/syntax/create-group)
107
+ - [ ] [ALTER GROUP](https://ydb.tech/docs/en/yql/reference/syntax/alter-group)
108
+ - [ ] [DROP GROUP](https://ydb.tech/docs/en/yql/reference/syntax/drop-group)
109
+ - [ ] [GRANT](https://ydb.tech/docs/en/yql/reference/syntax/grant)
110
+ - [ ] [REVOKE](https://ydb.tech/docs/en/yql/reference/syntax/revoke)
111
+ - [ ] [Unsupported syntax](https://ydb.tech/docs/en/yql/reference/syntax/unsupported)
112
+
113
+ Unchecked pages may already have incidental parser support. They remain
114
+ unchecked until their specific documentation page has been used as the normative
115
+ source and focused tests have been added or corrected.
116
+
29
117
  ### Any SQL → YDB
30
118
 
31
119
  #### Table names
@@ -113,18 +201,27 @@ The plugin parses YDB/YQL back into sqlglot's AST, enabling round-trips, YDB-to-
113
201
  | `$variable` references | `SELECT * FROM $t AS t` |
114
202
  | `Module::Function()` | `DateTime::GetYear(ts)` |
115
203
  | `DECLARE $p AS Type` | `DECLARE $p AS Int32` |
116
- | `FLATTEN [LIST\|DICT] BY col` | `FROM t FLATTEN LIST BY col` |
204
+ | `FLATTEN [LIST\|DICT\|OPTIONAL] BY ...` / `FLATTEN COLUMNS` | `FROM t FLATTEN LIST BY col AS item`, `FROM t FLATTEN BY (a, b)`, `FROM t FLATTEN COLUMNS` |
117
205
  | `Optional<T>` / `T?` | `CAST(x AS Optional<Utf8>)` |
118
206
  | Container types | `CAST(x AS List<Int32>)`, `Dict<Utf8, Int64>`, `Set<Utf8>`, `Tuple<Int32, Utf8>` |
119
207
  | `ASSUME ORDER BY` | `SELECT * FROM t ASSUME ORDER BY id` |
120
- | `GROUP BY expr AS alias` | `SELECT v, COUNT(*) FROM t GROUP BY v AS v` |
208
+ | `GROUP BY expr AS alias` / `GROUP COMPACT BY` | `SELECT v, COUNT(*) FROM t GROUP BY v AS v` |
209
+ | `LEFT ONLY JOIN` | `SELECT * FROM a LEFT ONLY JOIN b USING (id)` |
210
+ | `* WITHOUT (...)` projections | `SELECT b.* WITHOUT (b.id) FROM t AS b` |
121
211
  | Named expressions | `$t = (SELECT 1 AS x)` |
122
212
  | Lambda expressions | `($x, $y?) -> ($x + COALESCE($y, 0))`, `($y) -> { $p = "x"; RETURN $p \|\| $y }` |
213
+ | YQL struct literals | `AsList(<|user_id: "u1", description: NULL|>)` |
123
214
  | `IN COMPACT` | `WHERE key IN COMPACT $values` |
124
215
  | `PRAGMA` | `PRAGMA AnsiImplicitCrossJoin` |
216
+ | Table-valued functions | `SELECT * FROM AS_TABLE($Input) AS k` |
217
+ | Table source options and index views | ``FROM `t` WITH TabletId='...'``, ``FROM `t` VIEW PRIMARY KEY v`` |
218
+ | Function-valued expressions | `$grep(x)`, `DateTime::Format("%Y-%m-%d")(ts)`, `Interval("P7D")` |
125
219
 
126
220
  Table names without backticks are accepted on input; the generator always produces backtick-quoted output.
127
221
 
222
+ The parser also tolerates case variants that appear in real YQL dumps, such as
223
+ `set<Utf8>`, `Tuple<Int32, Utf8>?`, and lowercase `return` in lambda blocks.
224
+
128
225
  #### CTEs reassembly
129
226
 
130
227
  YDB-style named expressions are automatically reassembled into standard `WITH` CTEs when targeting other dialects:
@@ -180,6 +277,7 @@ Functions below are recognized by sqlglot as standard SQL expressions and transl
180
277
  | `INTERVAL n HOUR` (literal) | `DateTime::IntervalFromHours(n)` |
181
278
  | `INTERVAL n MINUTE` (literal) | `DateTime::IntervalFromMinutes(n)` |
182
279
  | `INTERVAL n SECOND` (literal) | `DateTime::IntervalFromSeconds(n)` |
280
+ | `Interval("P7D")` (YQL input) | passed through unchanged |
183
281
  | `dateDiff('minute', a, b)` | `(CAST(b AS Int64) - CAST(a AS Int64)) / 60000000` |
184
282
  | `dateDiff('hour', a, b)` | `(CAST(b AS Int64) - CAST(a AS Int64)) / 3600000000` |
185
283
  | `dateDiff('day', a, b)` | `(CAST(b AS Int64) - CAST(a AS Int64)) / 86400000000` |
@@ -229,6 +327,10 @@ arguments and block bodies with local named expressions:
229
327
  ($y) -> { $prefix = "x"; RETURN $prefix || $y; };
230
328
  ```
231
329
 
330
+ ClickHouse `ARRAY JOIN` and simple `arrayJoin(...)` projections, and PostgreSQL
331
+ `LATERAL unnest(...)`, are converted to YDB `FLATTEN BY` when the operation is
332
+ directly tied to the source table.
333
+
232
334
  ### Conditional / math
233
335
 
234
336
  | Input | YQL output |
@@ -243,6 +345,18 @@ arguments and block bodies with local named expressions:
243
345
  |---|---|
244
346
  | `jsonb_col @> value` (PostgreSQL) | `Yson::Contains(jsonb_col, value)` |
245
347
 
348
+ YDB JSON functions are parsed and round-tripped, including `PASSING`,
349
+ `RETURNING`, wrapper modes, and `ON EMPTY` / `ON ERROR` clauses:
350
+
351
+ ```sql
352
+ JSON_VALUE(payload, '$.value + $delta' PASSING 1 AS delta RETURNING Int64 DEFAULT 0 ON EMPTY ERROR ON ERROR)
353
+ JSON_QUERY(payload, '$.items' WITH CONDITIONAL ARRAY WRAPPER NULL ON EMPTY ERROR ON ERROR)
354
+ JSON_EXISTS(payload, '$.items[$Index]' PASSING 0 AS "Index" FALSE ON ERROR)
355
+ ```
356
+
357
+ JSON paths can contain quoted keys, for example
358
+ `JSON_EXISTS(item_result, "$.'P_008 device playback test'")`.
359
+
246
360
  ---
247
361
 
248
362
  ## Type mapping
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ydb-sqlglot-plugin"
7
- version = "0.2.3" # AUTOVERSION
7
+ version = "0.2.5" # AUTOVERSION
8
8
  description = "YDB dialect plugin for sqlglot"
9
9
  readme = "README.md"
10
10
  license = {text = "Apache-2.0"}
@@ -0,0 +1 @@
1
+ VERSION = "0.2.5"