fakesnow 0.9.38__py3-none-any.whl → 0.9.40__py3-none-any.whl
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.
- fakesnow/checks.py +2 -2
- fakesnow/copy_into.py +194 -29
- fakesnow/cursor.py +37 -10
- fakesnow/info_schema.py +45 -0
- fakesnow/macros.py +11 -0
- fakesnow/server.py +15 -0
- fakesnow/transforms/__init__.py +7 -3
- fakesnow/transforms/show.py +263 -173
- fakesnow/transforms/stage.py +163 -0
- fakesnow/transforms/transforms.py +31 -42
- fakesnow/variables.py +3 -1
- {fakesnow-0.9.38.dist-info → fakesnow-0.9.40.dist-info}/METADATA +2 -2
- {fakesnow-0.9.38.dist-info → fakesnow-0.9.40.dist-info}/RECORD +17 -16
- {fakesnow-0.9.38.dist-info → fakesnow-0.9.40.dist-info}/WHEEL +1 -1
- {fakesnow-0.9.38.dist-info → fakesnow-0.9.40.dist-info}/entry_points.txt +0 -0
- {fakesnow-0.9.38.dist-info → fakesnow-0.9.40.dist-info}/licenses/LICENSE +0 -0
- {fakesnow-0.9.38.dist-info → fakesnow-0.9.40.dist-info}/top_level.txt +0 -0
fakesnow/transforms/show.py
CHANGED
@@ -11,11 +11,52 @@ def fs_global_creation_sql() -> str:
|
|
11
11
|
{SQL_CREATE_VIEW_SHOW_OBJECTS};
|
12
12
|
{SQL_CREATE_VIEW_SHOW_TABLES};
|
13
13
|
{SQL_CREATE_VIEW_SHOW_VIEWS};
|
14
|
+
{SQL_CREATE_VIEW_SHOW_COLUMNS};
|
15
|
+
{SQL_CREATE_VIEW_SHOW_DATABASES};
|
16
|
+
{SQL_CREATE_VIEW_SHOW_FUNCTIONS};
|
17
|
+
{SQL_CREATE_VIEW_SHOW_SCHEMAS};
|
18
|
+
{SQL_CREATE_VIEW_SHOW_PROCEDURES};
|
14
19
|
"""
|
15
20
|
|
16
21
|
|
22
|
+
# see https://docs.snowflake.com/en/sql-reference/sql/show-columns
|
23
|
+
SQL_CREATE_VIEW_SHOW_COLUMNS = """
|
24
|
+
create view if not exists _fs_global._fs_information_schema._fs_show_columns as
|
25
|
+
SELECT
|
26
|
+
table_name,
|
27
|
+
table_schema as "schema_name",
|
28
|
+
column_name,
|
29
|
+
CASE
|
30
|
+
WHEN data_type = 'NUMBER' THEN
|
31
|
+
'{"type":"FIXED","precision":' || numeric_precision || ',"scale":' || numeric_scale || ',"nullable":true}'
|
32
|
+
WHEN data_type = 'TEXT' THEN
|
33
|
+
'{"type":"TEXT","length":' || coalesce(character_maximum_length,16777216) || ',"byteLength":' ||
|
34
|
+
CASE
|
35
|
+
WHEN character_maximum_length = 16777216 THEN 16777216
|
36
|
+
ELSE coalesce(character_maximum_length*4,16777216)
|
37
|
+
END || ',"nullable":true,"fixed":false}'
|
38
|
+
WHEN data_type in ('TIMESTAMP_NTZ','TIMESTAMP_TZ','TIME') THEN
|
39
|
+
'{"type":"' || data_type || '","precision":0,"scale":9,"nullable":true}'
|
40
|
+
WHEN data_type = 'FLOAT' THEN '{"type":"REAL","nullable":true}'
|
41
|
+
WHEN data_type = 'BINARY' THEN
|
42
|
+
'{"type":"BINARY","length":8388608,"byteLength":8388608,"nullable":true,"fixed":true}'
|
43
|
+
ELSE '{"type":"' || data_type || '","nullable":true}'
|
44
|
+
END as "data_type",
|
45
|
+
CASE WHEN is_nullable = 'YES' THEN 'true' ELSE 'false' END as "null?",
|
46
|
+
COALESCE(column_default, '') as "default",
|
47
|
+
'COLUMN' as "kind",
|
48
|
+
'' as "expression",
|
49
|
+
COALESCE(comment, '') as "comment",
|
50
|
+
table_catalog as "database_name",
|
51
|
+
'' as "autoincrement",
|
52
|
+
NULL as "schema_evolution_record"
|
53
|
+
FROM _fs_global._fs_information_schema._fs_columns
|
54
|
+
ORDER BY table_catalog, table_schema, table_name, ordinal_position
|
55
|
+
"""
|
56
|
+
|
57
|
+
|
17
58
|
def show_columns(
|
18
|
-
expression: exp.Expression, current_database: str | None
|
59
|
+
expression: exp.Expression, current_database: str | None, current_schema: str | None
|
19
60
|
) -> exp.Expression:
|
20
61
|
"""Transform SHOW COLUMNS to a query against the fs global information_schema columns table.
|
21
62
|
|
@@ -29,12 +70,7 @@ def show_columns(
|
|
29
70
|
scope_kind = expression.args.get("scope_kind")
|
30
71
|
table = expression.find(exp.Table)
|
31
72
|
|
32
|
-
if scope_kind == "
|
33
|
-
# all columns
|
34
|
-
catalog = None
|
35
|
-
schema = None
|
36
|
-
table = None
|
37
|
-
elif scope_kind == "DATABASE" and table:
|
73
|
+
if scope_kind == "DATABASE" and table:
|
38
74
|
catalog = table.name
|
39
75
|
schema = None
|
40
76
|
table = None
|
@@ -46,42 +82,39 @@ def show_columns(
|
|
46
82
|
catalog = table.catalog or current_database
|
47
83
|
schema = table.db or current_schema
|
48
84
|
table = table.name
|
85
|
+
elif scope_kind == "ACCOUNT":
|
86
|
+
# all columns
|
87
|
+
catalog = None
|
88
|
+
schema = None
|
89
|
+
table = None
|
90
|
+
elif not scope_kind:
|
91
|
+
# no explicit scope - show current database and schema only
|
92
|
+
catalog = current_database
|
93
|
+
schema = current_schema
|
94
|
+
table = None
|
49
95
|
else:
|
50
96
|
raise NotImplementedError(f"show_object_columns: {expression.sql(dialect='snowflake')}")
|
51
97
|
|
98
|
+
where = ["1=1"]
|
99
|
+
if catalog:
|
100
|
+
where.append(f"database_name = '{catalog}'")
|
101
|
+
if schema:
|
102
|
+
where.append(f"schema_name = '{schema}'")
|
103
|
+
if table:
|
104
|
+
where.append(f"table_name = '{table}'")
|
105
|
+
where_clause = " AND ".join(where)
|
106
|
+
|
52
107
|
query = f"""
|
53
|
-
SELECT
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
CASE
|
58
|
-
WHEN data_type = 'NUMBER' THEN '{{"type":"FIXED","precision":'|| numeric_precision || ',"scale":' || numeric_scale || ',"nullable":true}}'
|
59
|
-
WHEN data_type = 'TEXT' THEN '{{"type":"TEXT","length":' || coalesce(character_maximum_length,16777216) || ',"byteLength":' || CASE WHEN character_maximum_length = 16777216 THEN 16777216 ELSE coalesce(character_maximum_length*4,16777216) END || ',"nullable":true,"fixed":false}}'
|
60
|
-
WHEN data_type in ('TIMESTAMP_NTZ','TIMESTAMP_TZ','TIME') THEN '{{"type":"' || data_type || '","precision":0,"scale":9,"nullable":true}}'
|
61
|
-
WHEN data_type = 'FLOAT' THEN '{{"type":"REAL","nullable":true}}'
|
62
|
-
WHEN data_type = 'BINARY' THEN '{{"type":"BINARY","length":8388608,"byteLength":8388608,"nullable":true,"fixed":true}}'
|
63
|
-
ELSE '{{"type":"' || data_type || '","nullable":true}}'
|
64
|
-
END as "data_type",
|
65
|
-
CASE WHEN is_nullable = 'YES' THEN 'true' ELSE 'false' END as "null?",
|
66
|
-
COALESCE(column_default, '') as "default",
|
67
|
-
'COLUMN' as "kind",
|
68
|
-
'' as "expression",
|
69
|
-
COALESCE(comment, '') as "comment",
|
70
|
-
table_catalog as "database_name",
|
71
|
-
'' as "autoincrement",
|
72
|
-
NULL as "schema_evolution_record"
|
73
|
-
FROM _fs_global._fs_information_schema._fs_columns c
|
74
|
-
WHERE 1=1
|
75
|
-
{f"AND table_catalog = '{catalog}'" if catalog else ""}
|
76
|
-
{f"AND table_schema = '{schema}'" if schema else ""}
|
77
|
-
{f"AND table_name = '{table}'" if table else ""}
|
78
|
-
ORDER BY table_name, ordinal_position
|
79
|
-
""" # noqa: E501
|
108
|
+
SELECT *
|
109
|
+
FROM _fs_global._fs_information_schema._fs_show_columns
|
110
|
+
WHERE {where_clause}
|
111
|
+
"""
|
80
112
|
|
81
113
|
return sqlglot.parse_one(query, read="duckdb")
|
82
114
|
|
83
115
|
|
84
|
-
|
116
|
+
SQL_CREATE_VIEW_SHOW_DATABASES = """
|
117
|
+
create view if not exists _fs_global._fs_information_schema._fs_show_databases as
|
85
118
|
SELECT
|
86
119
|
to_timestamp(0)::timestamptz as 'created_on',
|
87
120
|
database_name as 'name',
|
@@ -102,18 +135,18 @@ WHERE database_name NOT IN ('memory', '_fs_global')
|
|
102
135
|
|
103
136
|
|
104
137
|
def show_databases(expression: exp.Expression) -> exp.Expression:
|
105
|
-
"""Transform SHOW DATABASES to a query against
|
138
|
+
"""Transform SHOW DATABASES to a query against _fs_show_databases.
|
106
139
|
|
107
140
|
See https://docs.snowflake.com/en/sql-reference/sql/show-databases
|
108
141
|
"""
|
109
142
|
if isinstance(expression, exp.Show) and isinstance(expression.this, str) and expression.this.upper() == "DATABASES":
|
110
|
-
return sqlglot.parse_one(
|
143
|
+
return sqlglot.parse_one("SELECT * FROM _fs_global._fs_information_schema._fs_show_databases", read="duckdb")
|
111
144
|
|
112
145
|
return expression
|
113
146
|
|
114
147
|
|
115
|
-
|
116
|
-
|
148
|
+
SQL_CREATE_VIEW_SHOW_FUNCTIONS = """
|
149
|
+
create view if not exists _fs_global._fs_information_schema._fs_show_functions as
|
117
150
|
SELECT
|
118
151
|
'1970-01-01 00:00:00 UTC'::timestamptz as created_on,
|
119
152
|
'SYSTIMESTAMP' as name,
|
@@ -145,73 +178,14 @@ def show_functions(expression: exp.Expression) -> exp.Expression:
|
|
145
178
|
See https://docs.snowflake.com/en/sql-reference/sql/show-functions
|
146
179
|
"""
|
147
180
|
if isinstance(expression, exp.Show) and isinstance(expression.this, str) and expression.this.upper() == "FUNCTIONS":
|
148
|
-
return sqlglot.parse_one(
|
149
|
-
|
150
|
-
return expression
|
151
|
-
|
152
|
-
|
153
|
-
# returns zero rows
|
154
|
-
SQL_SHOW_WAREHOUSES = """
|
155
|
-
SELECT
|
156
|
-
'FAKESNOW_WAREHOUSE' as name,
|
157
|
-
'STARTED' as state,
|
158
|
-
'STANDARD' as type,
|
159
|
-
'X-Small' as size,
|
160
|
-
1 as min_cluster_count,
|
161
|
-
1 as max_cluster_count,
|
162
|
-
1 as started_clusters,
|
163
|
-
0 as running,
|
164
|
-
0 as queued,
|
165
|
-
'N' as is_default,
|
166
|
-
'N' as is_current,
|
167
|
-
600 as auto_suspend,
|
168
|
-
'true' as auto_resume,
|
169
|
-
-- nb: deliberate space before '100' to match Snowflake's output
|
170
|
-
' 100' as available,
|
171
|
-
'0' as provisioning,
|
172
|
-
'0' as quiescing,
|
173
|
-
'0' as other,
|
174
|
-
'1970-01-01 00:00:00.000000 UTC'::timestamptz as created_on,
|
175
|
-
'1970-01-01 00:00:00.000000 UTC'::timestamptz as resumed_on,
|
176
|
-
'1970-01-01 00:00:00.000000 UTC'::timestamptz as updated_on,
|
177
|
-
'SYSADMIN' as owner,
|
178
|
-
'' as comment,
|
179
|
-
'false' as enable_query_acceleration,
|
180
|
-
8 as query_acceleration_max_scale_factor,
|
181
|
-
'null' as resource_monitor,
|
182
|
-
|
183
|
-
-- deprecated - these 5 cols are for internal use
|
184
|
-
0 as actives,
|
185
|
-
0 as pendings,
|
186
|
-
0 as failed,
|
187
|
-
0 as suspended,
|
188
|
-
'123456789012' as uuid,
|
189
|
-
|
190
|
-
'STANDARD' as scaling_policy,
|
191
|
-
NULL as budget,
|
192
|
-
'ROLE' as owner_role_type,
|
193
|
-
NULL as resource_constraint;
|
194
|
-
"""
|
195
|
-
|
196
|
-
|
197
|
-
def show_warehouses(expression: exp.Expression) -> exp.Expression:
|
198
|
-
"""Transform SHOW WAREHOUSES.
|
199
|
-
|
200
|
-
See https://docs.snowflake.com/en/sql-reference/sql/show-warehouses
|
201
|
-
"""
|
202
|
-
if (
|
203
|
-
isinstance(expression, exp.Show)
|
204
|
-
and isinstance(expression.this, str)
|
205
|
-
and expression.this.upper() == "WAREHOUSES"
|
206
|
-
):
|
207
|
-
return sqlglot.parse_one(SQL_SHOW_WAREHOUSES, read="duckdb")
|
181
|
+
return sqlglot.parse_one("SELECT * FROM _fs_global._fs_information_schema._fs_show_functions", read="duckdb")
|
208
182
|
|
209
183
|
return expression
|
210
184
|
|
211
185
|
|
212
186
|
def show_keys(
|
213
187
|
expression: exp.Expression,
|
214
|
-
current_database: str | None
|
188
|
+
current_database: str | None,
|
215
189
|
*,
|
216
190
|
kind: Literal["PRIMARY", "UNIQUE", "FOREIGN"],
|
217
191
|
) -> exp.Expression:
|
@@ -296,15 +270,138 @@ def show_keys(
|
|
296
270
|
return expression
|
297
271
|
|
298
272
|
|
273
|
+
SQL_CREATE_VIEW_SHOW_PROCEDURES = """
|
274
|
+
create view if not exists _fs_global._fs_information_schema._fs_show_procedures as
|
275
|
+
SELECT
|
276
|
+
'2012-08-01 07:00:00 UTC'::timestamptz as 'created_on',
|
277
|
+
'SYSTEM$CLASSIFY' as 'name',
|
278
|
+
'' as 'schema_name',
|
279
|
+
'Y' as 'is_builtin',
|
280
|
+
'N' as 'is_aggregate',
|
281
|
+
'N' as 'is_ansi',
|
282
|
+
2 as 'min_num_arguments',
|
283
|
+
2 as 'max_num_arguments',
|
284
|
+
'SYSTEM$CLASSIFY(VARCHAR, OBJECT) RETURN OBJECT' as 'arguments',
|
285
|
+
'classify stored proc' as 'description',
|
286
|
+
'' as 'catalog_name',
|
287
|
+
'N' as 'is_table_function',
|
288
|
+
'N' as 'valid_for_clustering',
|
289
|
+
NULL as 'is_secure',
|
290
|
+
'' as 'secrets',
|
291
|
+
'' as 'external_access_integrations',
|
292
|
+
WHERE 0 = 1;
|
293
|
+
"""
|
294
|
+
|
295
|
+
|
296
|
+
def show_procedures(expression: exp.Expression) -> exp.Expression:
|
297
|
+
"""Transform SHOW PROCEDURES.
|
298
|
+
|
299
|
+
See https://docs.snowflake.com/en/sql-reference/sql/show-procedures
|
300
|
+
"""
|
301
|
+
if (
|
302
|
+
isinstance(expression, exp.Show)
|
303
|
+
and isinstance(expression.this, str)
|
304
|
+
and expression.this.upper() == "PROCEDURES"
|
305
|
+
):
|
306
|
+
return sqlglot.parse_one(
|
307
|
+
"SELECT * FROM _fs_global._fs_information_schema._fs_show_procedures",
|
308
|
+
read="duckdb",
|
309
|
+
)
|
310
|
+
|
311
|
+
return expression
|
312
|
+
|
313
|
+
|
314
|
+
SQL_CREATE_VIEW_SHOW_SCHEMAS = """
|
315
|
+
create view if not exists _fs_global._fs_information_schema._fs_show_schemas as
|
316
|
+
select
|
317
|
+
to_timestamp(0)::timestamptz as 'created_on',
|
318
|
+
case
|
319
|
+
when schema_name = '_fs_information_schema' then 'information_schema'
|
320
|
+
else schema_name
|
321
|
+
end as 'name',
|
322
|
+
NULL as 'kind',
|
323
|
+
catalog_name as 'database_name',
|
324
|
+
NULL as 'schema_name'
|
325
|
+
from information_schema.schemata
|
326
|
+
where not catalog_name in ('memory', 'system', 'temp', '_fs_global')
|
327
|
+
and not schema_name in ('main', 'pg_catalog')
|
328
|
+
"""
|
329
|
+
|
330
|
+
|
331
|
+
def show_schemas(expression: exp.Expression, current_database: str | None) -> exp.Expression:
|
332
|
+
"""Transform SHOW SCHEMAS to a query against the _fs_show_schemas view.
|
333
|
+
|
334
|
+
See https://docs.snowflake.com/en/sql-reference/sql/show-schemas
|
335
|
+
"""
|
336
|
+
if isinstance(expression, exp.Show) and isinstance(expression.this, str) and expression.this.upper() == "SCHEMAS":
|
337
|
+
if (ident := expression.find(exp.Identifier)) and isinstance(ident.this, str):
|
338
|
+
database = ident.this
|
339
|
+
else:
|
340
|
+
database = current_database
|
341
|
+
|
342
|
+
query = "SELECT * FROM _fs_global._fs_information_schema._fs_show_schemas"
|
343
|
+
|
344
|
+
if database:
|
345
|
+
query += f" WHERE database_name = '{database}'"
|
346
|
+
return sqlglot.parse_one(query, read="duckdb")
|
347
|
+
|
348
|
+
return expression
|
349
|
+
|
350
|
+
|
351
|
+
def show_stages(expression: exp.Expression, current_database: str | None, current_schema: str | None) -> exp.Expression:
|
352
|
+
"""Transform SHOW STAGES to a select from the fake _fs_stages table."""
|
353
|
+
if not (
|
354
|
+
isinstance(expression, exp.Show) and isinstance(expression.this, str) and expression.this.upper() == "STAGES"
|
355
|
+
):
|
356
|
+
return expression
|
357
|
+
|
358
|
+
scope_kind = expression.args.get("scope_kind")
|
359
|
+
table = expression.find(exp.Table)
|
360
|
+
|
361
|
+
if scope_kind == "DATABASE":
|
362
|
+
catalog = (table and table.name) or current_database
|
363
|
+
schema = None
|
364
|
+
elif scope_kind == "SCHEMA" and table:
|
365
|
+
catalog = table.db or current_database
|
366
|
+
schema = table.name
|
367
|
+
elif scope_kind == "TABLE" and table:
|
368
|
+
catalog = table.db or current_database
|
369
|
+
assert isinstance(table.this, exp.Identifier)
|
370
|
+
schema = table.this.this
|
371
|
+
elif scope_kind == "ACCOUNT":
|
372
|
+
# show all objects / tables in the account
|
373
|
+
catalog = None
|
374
|
+
schema = None
|
375
|
+
else:
|
376
|
+
# no explicit scope - show current database and schema only
|
377
|
+
catalog = current_database
|
378
|
+
schema = current_schema
|
379
|
+
|
380
|
+
where = ["1=1"]
|
381
|
+
if catalog:
|
382
|
+
where.append(f"database_name = '{catalog}'")
|
383
|
+
if schema:
|
384
|
+
where.append(f"schema_name = '{schema}'")
|
385
|
+
where_clause = " AND ".join(where)
|
386
|
+
|
387
|
+
query = f"""
|
388
|
+
SELECT *
|
389
|
+
from _fs_global._fs_information_schema._fs_stages
|
390
|
+
where {where_clause}
|
391
|
+
"""
|
392
|
+
|
393
|
+
return sqlglot.parse_one(query, read="duckdb")
|
394
|
+
|
395
|
+
|
299
396
|
# see https://docs.snowflake.com/en/sql-reference/sql/show-objects
|
300
397
|
SQL_CREATE_VIEW_SHOW_OBJECTS = """
|
301
398
|
create view if not exists _fs_global._fs_information_schema._fs_show_objects as
|
302
399
|
select
|
303
400
|
to_timestamp(0)::timestamptz as created_on,
|
304
401
|
table_name as name,
|
305
|
-
case when table_type='BASE TABLE' then 'TABLE' else table_type end as 'kind',
|
306
402
|
table_catalog as database_name,
|
307
403
|
table_schema as schema_name,
|
404
|
+
case when table_type='BASE TABLE' then 'TABLE' else table_type end as 'kind',
|
308
405
|
'' as comment,
|
309
406
|
'' as cluster_by,
|
310
407
|
-- TODO: implement rows and bytes as rows * 1024
|
@@ -313,9 +410,9 @@ select
|
|
313
410
|
'SYSADMIN' as owner,
|
314
411
|
1 as retention_time,
|
315
412
|
'ROLE' as owner_role_type,
|
316
|
-
null as budget,
|
317
413
|
'N' as is_hybrid,
|
318
|
-
'N' as is_dynamic
|
414
|
+
'N' as is_dynamic,
|
415
|
+
'N' as is_iceberg
|
319
416
|
from information_schema.tables
|
320
417
|
where not (table_schema == '_fs_information_schema')
|
321
418
|
"""
|
@@ -377,7 +474,9 @@ where not table_catalog in ('system')
|
|
377
474
|
"""
|
378
475
|
|
379
476
|
|
380
|
-
def show_tables_etc(
|
477
|
+
def show_tables_etc(
|
478
|
+
expression: exp.Expression, current_database: str | None, current_schema: str | None
|
479
|
+
) -> exp.Expression:
|
381
480
|
"""Transform SHOW OBJECTS/TABLES/VIEWS to a query against the _fs_information_schema views."""
|
382
481
|
if not (
|
383
482
|
isinstance(expression, exp.Show)
|
@@ -396,10 +495,14 @@ def show_tables_etc(expression: exp.Expression, current_database: str | None = N
|
|
396
495
|
elif scope_kind == "SCHEMA" and table:
|
397
496
|
catalog = table.db or current_database
|
398
497
|
schema = table.name
|
399
|
-
|
400
|
-
# all objects / tables
|
498
|
+
elif scope_kind == "ACCOUNT":
|
499
|
+
# show all objects / tables in the account
|
401
500
|
catalog = None
|
402
501
|
schema = None
|
502
|
+
else:
|
503
|
+
# no explicit scope - show current database and schema only
|
504
|
+
catalog = current_database
|
505
|
+
schema = current_schema
|
403
506
|
|
404
507
|
if expression.args["terse"] and show == "VIEWS":
|
405
508
|
columns = ["created_on, name, 'VIEW' as kind, database_name, schema_name"]
|
@@ -430,84 +533,71 @@ def show_tables_etc(expression: exp.Expression, current_database: str | None = N
|
|
430
533
|
return sqlglot.parse_one(query, read="duckdb")
|
431
534
|
|
432
535
|
|
433
|
-
|
434
|
-
|
435
|
-
SELECT
|
436
|
-
'2012-08-01 07:00:00 UTC'::timestamptz as 'created_on',
|
437
|
-
'SYSTEM$CLASSIFY' as 'name',
|
438
|
-
'' as 'schema_name',
|
439
|
-
'Y' as 'is_builtin',
|
440
|
-
'N' as 'is_aggregate',
|
441
|
-
'N' as 'is_ansi',
|
442
|
-
2 as 'min_num_arguments',
|
443
|
-
2 as 'max_num_arguments',
|
444
|
-
'SYSTEM$CLASSIFY(VARCHAR, OBJECT) RETURN OBJECT' as 'arguments',
|
445
|
-
'classify stored proc' as 'description',
|
446
|
-
'' as 'catalog_name',
|
447
|
-
'N' as 'is_table_function',
|
448
|
-
'N' as 'valid_for_clustering',
|
449
|
-
NULL as 'is_secure',
|
450
|
-
'' as 'secrets',
|
451
|
-
'' as 'external_access_integrations',
|
452
|
-
WHERE 0 = 1;
|
453
|
-
"""
|
454
|
-
|
455
|
-
|
456
|
-
def show_procedures(expression: exp.Expression) -> exp.Expression:
|
457
|
-
"""Transform SHOW PROCEDURES.
|
536
|
+
def show_users(expression: exp.Expression) -> exp.Expression:
|
537
|
+
"""Transform SHOW USERS to a query against the global database's information_schema._fs_users table.
|
458
538
|
|
459
|
-
|
539
|
+
https://docs.snowflake.com/en/sql-reference/sql/show-users
|
460
540
|
"""
|
461
|
-
if (
|
462
|
-
|
463
|
-
and isinstance(expression.this, str)
|
464
|
-
and expression.this.upper() == "PROCEDURES"
|
465
|
-
):
|
466
|
-
return sqlglot.parse_one(SQL_SHOW_PROCEDURES, read="duckdb")
|
541
|
+
if isinstance(expression, exp.Show) and isinstance(expression.this, str) and expression.this.upper() == "USERS":
|
542
|
+
return sqlglot.parse_one("SELECT * FROM _fs_global._fs_information_schema._fs_users", read="duckdb")
|
467
543
|
|
468
544
|
return expression
|
469
545
|
|
470
546
|
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
547
|
+
# returns zero rows
|
548
|
+
SQL_SHOW_WAREHOUSES = """
|
549
|
+
SELECT
|
550
|
+
'FAKESNOW_WAREHOUSE' as name,
|
551
|
+
'STARTED' as state,
|
552
|
+
'STANDARD' as type,
|
553
|
+
'X-Small' as size,
|
554
|
+
1 as min_cluster_count,
|
555
|
+
1 as max_cluster_count,
|
556
|
+
1 as started_clusters,
|
557
|
+
0 as running,
|
558
|
+
0 as queued,
|
559
|
+
'N' as is_default,
|
560
|
+
'N' as is_current,
|
561
|
+
600 as auto_suspend,
|
562
|
+
'true' as auto_resume,
|
563
|
+
-- nb: deliberate space before '100' to match Snowflake's output
|
564
|
+
' 100' as available,
|
565
|
+
'0' as provisioning,
|
566
|
+
'0' as quiescing,
|
567
|
+
'0' as other,
|
568
|
+
'1970-01-01 00:00:00.000000 UTC'::timestamptz as created_on,
|
569
|
+
'1970-01-01 00:00:00.000000 UTC'::timestamptz as resumed_on,
|
570
|
+
'1970-01-01 00:00:00.000000 UTC'::timestamptz as updated_on,
|
571
|
+
'SYSADMIN' as owner,
|
572
|
+
'' as comment,
|
573
|
+
'false' as enable_query_acceleration,
|
574
|
+
8 as query_acceleration_max_scale_factor,
|
575
|
+
'null' as resource_monitor,
|
497
576
|
|
498
|
-
|
499
|
-
|
500
|
-
|
577
|
+
-- deprecated - these 5 cols are for internal use
|
578
|
+
0 as actives,
|
579
|
+
0 as pendings,
|
580
|
+
0 as failed,
|
581
|
+
0 as suspended,
|
582
|
+
'123456789012' as uuid,
|
501
583
|
|
502
|
-
|
584
|
+
'STANDARD' as scaling_policy,
|
585
|
+
NULL as budget,
|
586
|
+
'ROLE' as owner_role_type,
|
587
|
+
NULL as resource_constraint;
|
588
|
+
"""
|
503
589
|
|
504
590
|
|
505
|
-
def
|
506
|
-
"""Transform SHOW
|
591
|
+
def show_warehouses(expression: exp.Expression) -> exp.Expression:
|
592
|
+
"""Transform SHOW WAREHOUSES.
|
507
593
|
|
508
|
-
https://docs.snowflake.com/en/sql-reference/sql/show-
|
594
|
+
See https://docs.snowflake.com/en/sql-reference/sql/show-warehouses
|
509
595
|
"""
|
510
|
-
if
|
511
|
-
|
596
|
+
if (
|
597
|
+
isinstance(expression, exp.Show)
|
598
|
+
and isinstance(expression.this, str)
|
599
|
+
and expression.this.upper() == "WAREHOUSES"
|
600
|
+
):
|
601
|
+
return sqlglot.parse_one(SQL_SHOW_WAREHOUSES, read="duckdb")
|
512
602
|
|
513
603
|
return expression
|