soda-sqlserver 4.7.0__tar.gz → 4.14.0__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.
- {soda_sqlserver-4.7.0 → soda_sqlserver-4.14.0}/PKG-INFO +2 -2
- {soda_sqlserver-4.7.0 → soda_sqlserver-4.14.0}/pyproject.toml +2 -2
- {soda_sqlserver-4.7.0 → soda_sqlserver-4.14.0}/src/soda_sqlserver/common/data_sources/sqlserver_data_source.py +22 -0
- {soda_sqlserver-4.7.0 → soda_sqlserver-4.14.0}/src/soda_sqlserver/common/data_sources/sqlserver_data_source_connection.py +24 -1
- {soda_sqlserver-4.7.0 → soda_sqlserver-4.14.0}/src/soda_sqlserver.egg-info/PKG-INFO +2 -2
- soda_sqlserver-4.14.0/src/soda_sqlserver.egg-info/requires.txt +2 -0
- soda_sqlserver-4.7.0/src/soda_sqlserver.egg-info/requires.txt +0 -2
- {soda_sqlserver-4.7.0 → soda_sqlserver-4.14.0}/setup.cfg +0 -0
- {soda_sqlserver-4.7.0 → soda_sqlserver-4.14.0}/src/soda_sqlserver/test_helpers/sqlserver_data_source_test_helper.py +0 -0
- {soda_sqlserver-4.7.0 → soda_sqlserver-4.14.0}/src/soda_sqlserver.egg-info/SOURCES.txt +0 -0
- {soda_sqlserver-4.7.0 → soda_sqlserver-4.14.0}/src/soda_sqlserver.egg-info/dependency_links.txt +0 -0
- {soda_sqlserver-4.7.0 → soda_sqlserver-4.14.0}/src/soda_sqlserver.egg-info/entry_points.txt +0 -0
- {soda_sqlserver-4.7.0 → soda_sqlserver-4.14.0}/src/soda_sqlserver.egg-info/top_level.txt +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: soda-sqlserver
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.14.0
|
|
4
4
|
Summary: Soda SQL Server V4
|
|
5
5
|
Author-email: "Soda Data N.V." <info@soda.io>
|
|
6
6
|
License: Proprietary
|
|
7
7
|
Requires-Python: >=3.10
|
|
8
|
-
Requires-Dist: soda-core==4.
|
|
8
|
+
Requires-Dist: soda-core==4.14.0
|
|
9
9
|
Requires-Dist: pyodbc
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "soda-sqlserver"
|
|
3
|
-
version = "4.
|
|
3
|
+
version = "4.14.0"
|
|
4
4
|
description = "Soda SQL Server V4"
|
|
5
5
|
requires-python = ">=3.10"
|
|
6
6
|
license = {text = "Proprietary"}
|
|
@@ -8,7 +8,7 @@ authors = [
|
|
|
8
8
|
{name = "Soda Data N.V.", email = "info@soda.io"}
|
|
9
9
|
]
|
|
10
10
|
dependencies = [
|
|
11
|
-
"soda-core==4.
|
|
11
|
+
"soda-core==4.14.0",
|
|
12
12
|
"pyodbc",
|
|
13
13
|
]
|
|
14
14
|
|
|
@@ -14,6 +14,7 @@ from soda_core.common.sql_ast import (
|
|
|
14
14
|
COUNT,
|
|
15
15
|
CREATE_TABLE,
|
|
16
16
|
CREATE_TABLE_AS_SELECT,
|
|
17
|
+
CREATE_TABLE_COLUMN,
|
|
17
18
|
CREATE_TABLE_IF_NOT_EXISTS,
|
|
18
19
|
CREATE_VIEW,
|
|
19
20
|
DISTINCT,
|
|
@@ -162,6 +163,11 @@ class SqlServerSqlDialect(SqlDialect, sqlglot_dialect="tsql"):
|
|
|
162
163
|
def _build_length_sql(self, length: LENGTH) -> str:
|
|
163
164
|
return f"LEN({self.build_expression_sql(length.expression)})"
|
|
164
165
|
|
|
166
|
+
def _build_count_sql(self, count: COUNT) -> str:
|
|
167
|
+
# T-SQL COUNT returns INT and overflows above 2,147,483,647 rows. COUNT_BIG is the
|
|
168
|
+
# BIGINT-returning equivalent with identical null/distinct semantics.
|
|
169
|
+
return f"COUNT_BIG({self.build_expression_sql(count.expression)})"
|
|
170
|
+
|
|
165
171
|
def sql_expr_timestamp_literal(self, datetime_in_iso8601: str) -> str:
|
|
166
172
|
return f"'{datetime_in_iso8601}'"
|
|
167
173
|
|
|
@@ -324,6 +330,22 @@ class SqlServerSqlDialect(SqlDialect, sqlglot_dialect="tsql"):
|
|
|
324
330
|
"datetimeoffset",
|
|
325
331
|
]
|
|
326
332
|
|
|
333
|
+
# SQL Server's datetime2 / datetimeoffset / time accept a fractional-seconds
|
|
334
|
+
# precision of 0..7. Any higher value is rejected at CREATE TABLE time.
|
|
335
|
+
_MAX_DATETIME_PRECISION = 7
|
|
336
|
+
|
|
337
|
+
def _build_create_table_column_type(self, create_table_column: CREATE_TABLE_COLUMN) -> str:
|
|
338
|
+
# Clamp datetime precision to SQL Server's max. Cross-source flows from sources
|
|
339
|
+
# with higher native precision (e.g. Snowflake's TIMESTAMP_NTZ defaults to 9)
|
|
340
|
+
# would otherwise produce e.g. `datetime2(9)` and fail CREATE TABLE.
|
|
341
|
+
if create_table_column.type.name.lower() in ("datetime2", "datetimeoffset", "time"):
|
|
342
|
+
if (
|
|
343
|
+
create_table_column.type.datetime_precision is not None
|
|
344
|
+
and create_table_column.type.datetime_precision > self._MAX_DATETIME_PRECISION
|
|
345
|
+
):
|
|
346
|
+
create_table_column.type.datetime_precision = self._MAX_DATETIME_PRECISION
|
|
347
|
+
return super()._build_create_table_column_type(create_table_column)
|
|
348
|
+
|
|
327
349
|
def default_varchar_length(self) -> Optional[int]:
|
|
328
350
|
return 255
|
|
329
351
|
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import logging
|
|
4
4
|
import struct
|
|
5
5
|
from abc import ABC
|
|
6
|
-
from datetime import datetime, timedelta, timezone
|
|
6
|
+
from datetime import datetime, timedelta, timezone, tzinfo
|
|
7
7
|
from typing import Any, Literal, Optional, Union
|
|
8
8
|
|
|
9
9
|
import pyodbc
|
|
@@ -196,5 +196,28 @@ class SqlServerDataSourceConnection(DataSourceConnection):
|
|
|
196
196
|
def _execute_query_get_result_row_column_name(self, column) -> str:
|
|
197
197
|
return column[0]
|
|
198
198
|
|
|
199
|
+
def _fetch_session_timezone(self) -> tzinfo:
|
|
200
|
+
# Use SYSDATETIMEOFFSET() instead of CURRENT_TIMEZONE_ID() so the same query works
|
|
201
|
+
# across the whole SQL Server family: SQL Server proper, Microsoft Fabric DW, Azure
|
|
202
|
+
# Synapse Dedicated/Serverless. CURRENT_TIMEZONE_ID is unsupported in Fabric and
|
|
203
|
+
# Synapse Dedicated; SYSDATETIMEOFFSET is universally supported.
|
|
204
|
+
# The connection registers ``handle_datetimeoffset`` as a pyodbc output converter for
|
|
205
|
+
# SQL_TYPE -155, so the returned value is a tz-aware ``datetime`` whose tzinfo is the
|
|
206
|
+
# exact offset reported by the server.
|
|
207
|
+
with self.connection.cursor() as cursor:
|
|
208
|
+
cursor.execute("SELECT SYSDATETIMEOFFSET()")
|
|
209
|
+
row = cursor.fetchone()
|
|
210
|
+
if not row or not isinstance(row[0], datetime) or row[0].tzinfo is None:
|
|
211
|
+
return timezone.utc
|
|
212
|
+
offset = row[0].tzinfo.utcoffset(row[0])
|
|
213
|
+
# Normalize zero offset to ``timezone.utc`` (the singleton) so that adapters
|
|
214
|
+
# routed through ``parse_session_timezone`` and SQL Server agree on the UTC
|
|
215
|
+
# representation — adapters that report ``UTC`` / ``Etc/UTC`` resolve to the
|
|
216
|
+
# same ``timezone.utc`` instance, while a raw ``timezone(timedelta(0))`` would
|
|
217
|
+
# be ``==`` but not ``is`` equivalent.
|
|
218
|
+
if offset == timedelta(0):
|
|
219
|
+
return timezone.utc
|
|
220
|
+
return timezone(offset)
|
|
221
|
+
|
|
199
222
|
def _get_autocommit_setting(self) -> bool:
|
|
200
223
|
return False # No need to set autocommit, as it is set to False by default.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: soda-sqlserver
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.14.0
|
|
4
4
|
Summary: Soda SQL Server V4
|
|
5
5
|
Author-email: "Soda Data N.V." <info@soda.io>
|
|
6
6
|
License: Proprietary
|
|
7
7
|
Requires-Python: >=3.10
|
|
8
|
-
Requires-Dist: soda-core==4.
|
|
8
|
+
Requires-Dist: soda-core==4.14.0
|
|
9
9
|
Requires-Dist: pyodbc
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{soda_sqlserver-4.7.0 → soda_sqlserver-4.14.0}/src/soda_sqlserver.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|