python-sql 1.5.0__tar.gz → 1.5.1__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.
Files changed (46) hide show
  1. {python_sql-1.5.0 → python_sql-1.5.1}/.hgtags +1 -0
  2. {python_sql-1.5.0 → python_sql-1.5.1}/CHANGELOG +4 -0
  3. {python_sql-1.5.0 → python_sql-1.5.1}/PKG-INFO +1 -1
  4. {python_sql-1.5.0 → python_sql-1.5.1}/python_sql.egg-info/PKG-INFO +1 -1
  5. {python_sql-1.5.0 → python_sql-1.5.1}/sql/__init__.py +30 -7
  6. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_select.py +10 -10
  7. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_window.py +6 -6
  8. {python_sql-1.5.0 → python_sql-1.5.1}/.flake8 +0 -0
  9. {python_sql-1.5.0 → python_sql-1.5.1}/.gitlab-ci.yml +0 -0
  10. {python_sql-1.5.0 → python_sql-1.5.1}/.isort.cfg +0 -0
  11. {python_sql-1.5.0 → python_sql-1.5.1}/COPYRIGHT +0 -0
  12. {python_sql-1.5.0 → python_sql-1.5.1}/MANIFEST.in +0 -0
  13. {python_sql-1.5.0 → python_sql-1.5.1}/README.rst +0 -0
  14. {python_sql-1.5.0 → python_sql-1.5.1}/python_sql.egg-info/SOURCES.txt +0 -0
  15. {python_sql-1.5.0 → python_sql-1.5.1}/python_sql.egg-info/dependency_links.txt +0 -0
  16. {python_sql-1.5.0 → python_sql-1.5.1}/python_sql.egg-info/top_level.txt +0 -0
  17. {python_sql-1.5.0 → python_sql-1.5.1}/setup.cfg +0 -0
  18. {python_sql-1.5.0 → python_sql-1.5.1}/setup.py +0 -0
  19. {python_sql-1.5.0 → python_sql-1.5.1}/sql/aggregate.py +0 -0
  20. {python_sql-1.5.0 → python_sql-1.5.1}/sql/conditionals.py +0 -0
  21. {python_sql-1.5.0 → python_sql-1.5.1}/sql/functions.py +0 -0
  22. {python_sql-1.5.0 → python_sql-1.5.1}/sql/operators.py +0 -0
  23. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/__init__.py +0 -0
  24. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_aggregate.py +0 -0
  25. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_alias.py +0 -0
  26. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_as.py +0 -0
  27. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_cast.py +0 -0
  28. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_collate.py +0 -0
  29. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_column.py +0 -0
  30. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_combining_query.py +0 -0
  31. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_conditionals.py +0 -0
  32. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_delete.py +0 -0
  33. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_for.py +0 -0
  34. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_functions.py +0 -0
  35. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_insert.py +0 -0
  36. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_join.py +0 -0
  37. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_lateral.py +0 -0
  38. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_literal.py +0 -0
  39. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_merge.py +0 -0
  40. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_operators.py +0 -0
  41. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_order.py +0 -0
  42. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_table.py +0 -0
  43. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_update.py +0 -0
  44. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_values.py +0 -0
  45. {python_sql-1.5.0 → python_sql-1.5.1}/sql/tests/test_with.py +0 -0
  46. {python_sql-1.5.0 → python_sql-1.5.1}/tox.ini +0 -0
@@ -18,3 +18,4 @@ e71bbae3398cb6a0e72f97a0cada9fcdee2bddea 1.4.1
18
18
  fcb64787b51db2068061eb4aa13825abc1134916 1.4.2
19
19
  111e3e86865360f83a65c04fa48c55f3d2957ee3 1.4.3
20
20
  6f9066b83fe3a8c4699a8555ad1bc406f18974ff 1.5.0
21
+ 79a69b0bbbd35a8d95e1b754ed3feb03df23fb70 1.5.1
@@ -1,3 +1,7 @@
1
+ Version 1.5.1 - 2024-05-28
2
+ * Use parameter for start and end of WINDOW FRAME
3
+ * Use parameter for limit and offset
4
+
1
5
  Version 1.5.0 - 2024-05-13
2
6
  * Skip alias on INSERT without ON CONFLICT or RETURNING
3
7
  * Add MERGE
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-sql
3
- Version: 1.5.0
3
+ Version: 1.5.1
4
4
  Summary: Library to write SQL queries
5
5
  Home-page: https://pypi.org/project/python-sql/
6
6
  Download-URL: https://downloads.tryton.org/python-sql/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-sql
3
- Version: 1.5.0
3
+ Version: 1.5.1
4
4
  Summary: Library to write SQL queries
5
5
  Home-page: https://pypi.org/project/python-sql/
6
6
  Download-URL: https://downloads.tryton.org/python-sql/
@@ -7,7 +7,7 @@ from collections import defaultdict
7
7
  from itertools import chain
8
8
  from threading import current_thread, local
9
9
 
10
- __version__ = '1.5.0'
10
+ __version__ = '1.5.1'
11
11
  __all__ = [
12
12
  'Flavor', 'Table', 'Values', 'Literal', 'Column', 'Grouping', 'Conflict',
13
13
  'Matched', 'MatchedUpdate', 'MatchedDelete',
@@ -380,13 +380,14 @@ class SelectQuery(WithQuery):
380
380
 
381
381
  @property
382
382
  def _limit_offset_str(self):
383
+ param = Flavor.get().param
383
384
  if Flavor.get().limitstyle == 'limit':
384
385
  offset = ''
385
386
  if self.offset:
386
- offset = ' OFFSET %s' % self.offset
387
+ offset = ' OFFSET %s' % param
387
388
  limit = ''
388
389
  if self.limit is not None:
389
- limit = ' LIMIT %s' % self.limit
390
+ limit = ' LIMIT %s' % param
390
391
  elif self.offset:
391
392
  max_limit = Flavor.get().max_limit
392
393
  if max_limit:
@@ -395,12 +396,27 @@ class SelectQuery(WithQuery):
395
396
  else:
396
397
  offset = ''
397
398
  if self.offset:
398
- offset = ' OFFSET (%s) ROWS' % self.offset
399
+ offset = ' OFFSET (%s) ROWS' % param
399
400
  fetch = ''
400
401
  if self.limit is not None:
401
- fetch = ' FETCH FIRST (%s) ROWS ONLY' % self.limit
402
+ fetch = ' FETCH FIRST (%s) ROWS ONLY' % param
402
403
  return offset + fetch
403
404
 
405
+ @property
406
+ def _limit_offset_params(self):
407
+ p = []
408
+ if Flavor.get().limitstyle == 'limit':
409
+ if self.limit is not None:
410
+ p.append(self.limit)
411
+ if self.offset:
412
+ p.append(self.offset)
413
+ else:
414
+ if self.offset:
415
+ p.append(self.offset)
416
+ if self.limit is not None:
417
+ p.append(self.limit)
418
+ return tuple(p)
419
+
404
420
  def as_(self, output_name):
405
421
  return As(self, output_name)
406
422
 
@@ -663,6 +679,7 @@ class Select(FromItem, SelectQuery):
663
679
  p.extend(self.having.params)
664
680
  for window in self.windows:
665
681
  p.extend(window.params)
682
+ p.extend(self._limit_offset_params)
666
683
  return tuple(p)
667
684
 
668
685
 
@@ -1992,6 +2009,7 @@ class Window(object):
1992
2009
  return AliasManager.contains(self)
1993
2010
 
1994
2011
  def __str__(self):
2012
+ param = Flavor.get().param
1995
2013
  partition = ''
1996
2014
  if self.partition:
1997
2015
  partition = 'PARTITION BY ' + ', '.join(map(str, self.partition))
@@ -2005,9 +2023,9 @@ class Window(object):
2005
2023
  elif not frame:
2006
2024
  return 'CURRENT ROW'
2007
2025
  elif frame < 0:
2008
- return '%s PRECEDING' % -frame
2026
+ return '%s PRECEDING' % param
2009
2027
  elif frame > 0:
2010
- return '%s FOLLOWING' % frame
2028
+ return '%s FOLLOWING' % param
2011
2029
 
2012
2030
  frame = ''
2013
2031
  if self.frame:
@@ -2028,6 +2046,11 @@ class Window(object):
2028
2046
  if self.order_by:
2029
2047
  for expression in self.order_by:
2030
2048
  p.extend(expression.params)
2049
+ if self.frame:
2050
+ if self.start:
2051
+ p.append(abs(self.start))
2052
+ if self.end:
2053
+ p.append(abs(self.end))
2031
2054
  return tuple(p)
2032
2055
 
2033
2056
 
@@ -253,13 +253,13 @@ class TestSelect(unittest.TestCase):
253
253
  Flavor.set(Flavor(limitstyle='limit'))
254
254
  query = self.table.select(limit=50, offset=10)
255
255
  self.assertEqual(str(query),
256
- 'SELECT * FROM "t" AS "a" LIMIT 50 OFFSET 10')
257
- self.assertEqual(tuple(query.params), ())
256
+ 'SELECT * FROM "t" AS "a" LIMIT %s OFFSET %s')
257
+ self.assertEqual(tuple(query.params), (50, 10))
258
258
 
259
259
  query.limit = None
260
260
  self.assertEqual(str(query),
261
- 'SELECT * FROM "t" AS "a" OFFSET 10')
262
- self.assertEqual(tuple(query.params), ())
261
+ 'SELECT * FROM "t" AS "a" OFFSET %s')
262
+ self.assertEqual(tuple(query.params), (10,))
263
263
 
264
264
  query.offset = 0
265
265
  self.assertEqual(str(query),
@@ -280,8 +280,8 @@ class TestSelect(unittest.TestCase):
280
280
 
281
281
  query.offset = 10
282
282
  self.assertEqual(str(query),
283
- 'SELECT * FROM "t" AS "a" LIMIT -1 OFFSET 10')
284
- self.assertEqual(tuple(query.params), ())
283
+ 'SELECT * FROM "t" AS "a" LIMIT -1 OFFSET %s')
284
+ self.assertEqual(tuple(query.params), (10,))
285
285
  finally:
286
286
  Flavor.set(Flavor())
287
287
 
@@ -291,13 +291,13 @@ class TestSelect(unittest.TestCase):
291
291
  query = self.table.select(limit=50, offset=10)
292
292
  self.assertEqual(str(query),
293
293
  'SELECT * FROM "t" AS "a" '
294
- 'OFFSET (10) ROWS FETCH FIRST (50) ROWS ONLY')
295
- self.assertEqual(tuple(query.params), ())
294
+ 'OFFSET (%s) ROWS FETCH FIRST (%s) ROWS ONLY')
295
+ self.assertEqual(tuple(query.params), (10, 50))
296
296
 
297
297
  query.limit = None
298
298
  self.assertEqual(str(query),
299
- 'SELECT * FROM "t" AS "a" OFFSET (10) ROWS')
300
- self.assertEqual(tuple(query.params), ())
299
+ 'SELECT * FROM "t" AS "a" OFFSET (%s) ROWS')
300
+ self.assertEqual(tuple(query.params), (10,))
301
301
 
302
302
  query.offset = 0
303
303
  self.assertEqual(str(query),
@@ -33,22 +33,22 @@ class TestWindow(unittest.TestCase):
33
33
  window.start = -1
34
34
  self.assertEqual(str(window),
35
35
  'PARTITION BY "c" RANGE '
36
- 'BETWEEN 1 PRECEDING AND CURRENT ROW')
37
- self.assertEqual(window.params, ())
36
+ 'BETWEEN %s PRECEDING AND CURRENT ROW')
37
+ self.assertEqual(window.params, (1,))
38
38
 
39
39
  window.start = 0
40
40
  window.end = 1
41
41
  self.assertEqual(str(window),
42
42
  'PARTITION BY "c" RANGE '
43
- 'BETWEEN CURRENT ROW AND 1 FOLLOWING')
44
- self.assertEqual(window.params, ())
43
+ 'BETWEEN CURRENT ROW AND %s FOLLOWING')
44
+ self.assertEqual(window.params, (1,))
45
45
 
46
46
  window.start = 1
47
47
  window.end = None
48
48
  self.assertEqual(str(window),
49
49
  'PARTITION BY "c" RANGE '
50
- 'BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING')
51
- self.assertEqual(window.params, ())
50
+ 'BETWEEN %s FOLLOWING AND UNBOUNDED FOLLOWING')
51
+ self.assertEqual(window.params, (1,))
52
52
 
53
53
  def test_window_exclude(self):
54
54
  t = Table('t')
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes