sqlframe 3.36.2__py3-none-any.whl → 3.37.0__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.
sqlframe/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '3.36.2'
21
- __version_tuple__ = version_tuple = (3, 36, 2)
20
+ __version__ = version = '3.37.0'
21
+ __version_tuple__ = version_tuple = (3, 37, 0)
@@ -1475,6 +1475,32 @@ def timestamp_seconds(col: ColumnOrName) -> Column:
1475
1475
  return Column.invoke_expression_over_column(col, expression.UnixToTime)
1476
1476
 
1477
1477
 
1478
+ @meta()
1479
+ def timestamp_add(unit: str, quantity: ColumnOrName, ts: ColumnOrName) -> Column:
1480
+ session = _get_session()
1481
+
1482
+ if session._is_duckdb or session._is_postgres:
1483
+ quantity = lit(quantity) if isinstance(quantity, int) else quantity
1484
+ if (
1485
+ isinstance(quantity, Column)
1486
+ and isinstance(quantity.expression, expression.Literal)
1487
+ and quantity.expression.is_number
1488
+ and int(quantity.expression.this) < 0
1489
+ ):
1490
+ # If quantity is a negative literal, we use DateSub
1491
+ expr = expression.DateSub
1492
+ quantity.expression.set("this", str(-int(quantity.expression.this)))
1493
+ else:
1494
+ expr = expression.DateAdd # type: ignore
1495
+ return Column.invoke_expression_over_column(
1496
+ ts, expr, expression=quantity, unit=expression.Var(this=unit.upper())
1497
+ )
1498
+
1499
+ return Column.invoke_expression_over_column(
1500
+ ts, expression.TimestampAdd, expression=quantity, unit=expression.Var(this=unit.upper())
1501
+ )
1502
+
1503
+
1478
1504
  @meta(unsupported_engines=["*", "spark"])
1479
1505
  def window(
1480
1506
  timeColumn: ColumnOrName,
@@ -2084,24 +2110,24 @@ def array_size(col: ColumnOrName) -> Column:
2084
2110
  return Column.invoke_expression_over_column(col, expression.ArraySize)
2085
2111
 
2086
2112
 
2087
- @meta(unsupported_engines="*")
2113
+ @meta(unsupported_engines="snowflake")
2088
2114
  def bit_and(col: ColumnOrName) -> Column:
2089
- return Column.invoke_anonymous_function(col, "BIT_AND")
2115
+ return Column.invoke_expression_over_column(col, expression.BitwiseAndAgg)
2090
2116
 
2091
2117
 
2092
- @meta(unsupported_engines="*")
2118
+ @meta(unsupported_engines="snowflake")
2093
2119
  def bit_or(col: ColumnOrName) -> Column:
2094
- return Column.invoke_anonymous_function(col, "BIT_OR")
2120
+ return Column.invoke_expression_over_column(col, expression.BitwiseOrAgg)
2095
2121
 
2096
2122
 
2097
- @meta(unsupported_engines="*")
2123
+ @meta(unsupported_engines="snowflake")
2098
2124
  def bit_xor(col: ColumnOrName) -> Column:
2099
- return Column.invoke_anonymous_function(col, "BIT_XOR")
2125
+ return Column.invoke_expression_over_column(col, expression.BitwiseXorAgg)
2100
2126
 
2101
2127
 
2102
- @meta(unsupported_engines="*")
2128
+ @meta(unsupported_engines=["postgres", "snowflake"])
2103
2129
  def bit_count(col: ColumnOrName) -> Column:
2104
- return Column.invoke_anonymous_function(col, "BIT_COUNT")
2130
+ return Column.invoke_expression_over_column(col, expression.BitwiseCountAgg)
2105
2131
 
2106
2132
 
2107
2133
  @meta(unsupported_engines="*")
@@ -3267,7 +3293,7 @@ def find_in_set(str: ColumnOrName, str_array: ColumnOrName) -> Column:
3267
3293
  return Column.invoke_anonymous_function(str, "find_in_set", str_array)
3268
3294
 
3269
3295
 
3270
- @meta(unsupported_engines=["bigquery", "postgres", "snowflake"])
3296
+ @meta(unsupported_engines=["bigquery", "postgres"])
3271
3297
  def first_value(col: ColumnOrName, ignoreNulls: t.Optional[t.Union[bool, Column]] = None) -> Column:
3272
3298
  """Returns the first value of `col` for a group of rows. It will return the first non-null
3273
3299
  value it sees when `ignoreNulls` is set to true. If all values are null, then null is returned.
@@ -3933,7 +3959,7 @@ def json_object_keys(col: ColumnOrName) -> Column:
3933
3959
  return Column.invoke_anonymous_function(col, "json_object_keys")
3934
3960
 
3935
3961
 
3936
- @meta(unsupported_engines=["bigquery", "postgres", "snowflake"])
3962
+ @meta(unsupported_engines="postgres")
3937
3963
  def last_value(col: ColumnOrName, ignoreNulls: t.Optional[t.Union[bool, Column]] = None) -> Column:
3938
3964
  """Returns the last value of `col` for a group of rows. It will return the last non-null
3939
3965
  value it sees when `ignoreNulls` is set to true. If all values are null, then null is returned.
sqlframe/base/types.py CHANGED
@@ -42,7 +42,7 @@ class DataTypeWithLength(DataType):
42
42
  def __repr__(self) -> str:
43
43
  return f"{self.__class__.__name__}({self.length})"
44
44
 
45
- def __str__(self) -> str:
45
+ def simpleString(self) -> str:
46
46
  return f"{self.typeName()}({self.length})"
47
47
 
48
48
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sqlframe
3
- Version: 3.36.2
3
+ Version: 3.37.0
4
4
  Summary: Turning PySpark Into a Universal DataFrame API
5
5
  Home-page: https://github.com/eakmanrq/sqlframe
6
6
  Author: Ryan Eakman
@@ -17,7 +17,7 @@ Requires-Python: >=3.9
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
19
  Requires-Dist: prettytable <4
20
- Requires-Dist: sqlglot <26.34,>=24.0.0
20
+ Requires-Dist: sqlglot <27.2,>=24.0.0
21
21
  Requires-Dist: typing-extensions
22
22
  Provides-Extra: bigquery
23
23
  Requires-Dist: google-cloud-bigquery-storage <3,>=2 ; extra == 'bigquery'
@@ -27,16 +27,17 @@ Requires-Dist: databricks-sql-connector[pyarrow] <5,>=3.6 ; extra == 'databricks
27
27
  Provides-Extra: dev
28
28
  Requires-Dist: duckdb <1.4,>=1.2 ; extra == 'dev'
29
29
  Requires-Dist: findspark <3,>=2 ; extra == 'dev'
30
- Requires-Dist: mypy <1.17,>=1.10.0 ; extra == 'dev'
30
+ Requires-Dist: mypy <1.18,>=1.10.0 ; extra == 'dev'
31
31
  Requires-Dist: openai <2,>=1.30 ; extra == 'dev'
32
32
  Requires-Dist: pandas-stubs <3,>=2 ; extra == 'dev'
33
33
  Requires-Dist: pandas <3,>=2 ; extra == 'dev'
34
34
  Requires-Dist: pre-commit <5,>=3.7 ; extra == 'dev'
35
35
  Requires-Dist: psycopg <4,>=3.1 ; extra == 'dev'
36
- Requires-Dist: pyarrow <21,>=10 ; extra == 'dev'
36
+ Requires-Dist: pyarrow <22,>=10 ; extra == 'dev'
37
37
  Requires-Dist: pyspark <3.6,>=2 ; extra == 'dev'
38
38
  Requires-Dist: pytest-forked ; extra == 'dev'
39
39
  Requires-Dist: pytest-postgresql <8,>=6 ; extra == 'dev'
40
+ Requires-Dist: pytest-rerunfailures ; extra == 'dev'
40
41
  Requires-Dist: pytest-xdist <3.9,>=3.6 ; extra == 'dev'
41
42
  Requires-Dist: pytest <8.5,>=8.2.0 ; extra == 'dev'
42
43
  Requires-Dist: ruff <0.13,>=0.4.4 ; extra == 'dev'
@@ -1,5 +1,5 @@
1
1
  sqlframe/__init__.py,sha256=SB80yLTITBXHI2GCDS6n6bN5ObHqgPjfpRPAUwxaots,3403
2
- sqlframe/_version.py,sha256=8n9kfLZeiKlOVTLEVFfs0B2MLJQ8xc2SyKauUUuFT3s,513
2
+ sqlframe/_version.py,sha256=OHLx0CdNTm07UdNGtUV9adqYt8IYPToP_wYMErxuyAQ,513
3
3
  sqlframe/py.typed,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
4
4
  sqlframe/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  sqlframe/base/_typing.py,sha256=b2clI5HI1zEZKB_3Msx3FeAJQyft44ubUifJwQRVXyQ,1298
@@ -9,7 +9,7 @@ sqlframe/base/dataframe.py,sha256=0diYONDlet8iZt49LC3vcmfXHAAZ2MovPL2pTXYHj2U,85
9
9
  sqlframe/base/decorators.py,sha256=IhE5xNQDkwJHacCvulq5WpUKyKmXm7dL2A3o5WuKGP4,2131
10
10
  sqlframe/base/exceptions.py,sha256=9Uwvqn2eAkDpqm4BrRgbL61qM-GMCbJEMAW8otxO46s,370
11
11
  sqlframe/base/function_alternatives.py,sha256=aTu3nQhIAkZoxrI1IpjpaHEAMxBNms0AnhS0EMR-TwY,51727
12
- sqlframe/base/functions.py,sha256=n1MsfJt2WWUk7-YwbfByWG065g0W45AwJVIME5H-QJU,225875
12
+ sqlframe/base/functions.py,sha256=OxoeI2cEoQY79hdOnvpw0pRiaUHkU55MMpfx7_v5l70,226984
13
13
  sqlframe/base/group.py,sha256=fBm8EUve7W7xz11nybTXr09ih-yZxL_vvEiZVE1eb_0,12025
14
14
  sqlframe/base/normalize.py,sha256=nXAJ5CwxVf4DV0GsH-q1w0p8gmjSMlv96k_ez1eVul8,3880
15
15
  sqlframe/base/operations.py,sha256=g-YNcbvNKTOBbYm23GKfB3fmydlR7ZZDAuZUtXIHtzw,4438
@@ -17,7 +17,7 @@ sqlframe/base/readerwriter.py,sha256=Nb2VJ_HBmLQp5mK8JhnFooZh2ydAaboCAFVPb-4MNX4
17
17
  sqlframe/base/session.py,sha256=djXPmuW0cIQYuoE7hegfyvZuKC2D3ABZCjvw-fa1C24,27260
18
18
  sqlframe/base/table.py,sha256=rCeh1W5SWbtEVfkLAUiexzrZwNgmZeptLEmLcM1ABkE,6961
19
19
  sqlframe/base/transforms.py,sha256=y0j3SGDz3XCmNGrvassk1S-owllUWfkHyMgZlY6SFO4,467
20
- sqlframe/base/types.py,sha256=0gebYkJUtaijaqBis2uqE3CRr3PfVTriwyUJ9-7ly_0,12300
20
+ sqlframe/base/types.py,sha256=OktuJ5f7tEogOW0oupI0RBlHfzZMmKh7zGLke9cwllo,12305
21
21
  sqlframe/base/udf.py,sha256=O6hMhBUy9NVv-mhJRtfFhXTIa_-Z8Y_FkmmuOHu0l90,1117
22
22
  sqlframe/base/util.py,sha256=gv_kRc3LxCuQy3t4dHFldV7elB8RU5PMqIN5-xSkWSo,19107
23
23
  sqlframe/base/window.py,sha256=7NaKDTlhun-95LEghukBCjFBwq0RHrPaajWQNCsLxok,4818
@@ -130,8 +130,8 @@ sqlframe/standalone/udf.py,sha256=azmgtUjHNIPs0WMVNId05SHwiYn41MKVBhKXsQJ5dmY,27
130
130
  sqlframe/standalone/window.py,sha256=6GKPzuxeSapJakBaKBeT9VpED1ACdjggDv9JRILDyV0,35
131
131
  sqlframe/testing/__init__.py,sha256=VVCosQhitU74A3NnE52O4mNtGZONapuEXcc20QmSlnQ,132
132
132
  sqlframe/testing/utils.py,sha256=PFsGZpwNUE_4-g_f43_vstTqsK0AQ2lBneb5Eb6NkFo,13008
133
- sqlframe-3.36.2.dist-info/LICENSE,sha256=VZu79YgW780qxaFJMr0t5ZgbOYEh04xWoxaWOaqIGWk,1068
134
- sqlframe-3.36.2.dist-info/METADATA,sha256=G40goRUAdQg115DFuLq6-RYZ_6OSyBJ0zRsPHu7mhMQ,8987
135
- sqlframe-3.36.2.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
136
- sqlframe-3.36.2.dist-info/top_level.txt,sha256=T0_RpoygaZSF6heeWwIDQgaP0varUdSK1pzjeJZRjM8,9
137
- sqlframe-3.36.2.dist-info/RECORD,,
133
+ sqlframe-3.37.0.dist-info/LICENSE,sha256=VZu79YgW780qxaFJMr0t5ZgbOYEh04xWoxaWOaqIGWk,1068
134
+ sqlframe-3.37.0.dist-info/METADATA,sha256=dr_LT2MGEsiXj-1rwsTtx31DtQxM6_Fo9zsJ24ghD30,9039
135
+ sqlframe-3.37.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
136
+ sqlframe-3.37.0.dist-info/top_level.txt,sha256=T0_RpoygaZSF6heeWwIDQgaP0varUdSK1pzjeJZRjM8,9
137
+ sqlframe-3.37.0.dist-info/RECORD,,