python-sql 1.5.1__py3-none-any.whl → 1.6.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.
sql/__init__.py CHANGED
@@ -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.1'
10
+ __version__ = '1.6.0'
11
11
  __all__ = [
12
12
  'Flavor', 'Table', 'Values', 'Literal', 'Column', 'Grouping', 'Conflict',
13
13
  'Matched', 'MatchedUpdate', 'MatchedDelete',
@@ -62,17 +62,23 @@ class Flavor(object):
62
62
  def __init__(self, limitstyle='limit', max_limit=None, paramstyle='format',
63
63
  ilike=False, no_as=False, no_boolean=False, null_ordering=True,
64
64
  function_mapping=None, filter_=False, escape_empty=False):
65
- assert limitstyle in ['fetch', 'limit', 'rownum']
65
+ if limitstyle not in {'fetch', 'limit', 'rownum'}:
66
+ raise ValueError("unsupported limitstyle: %r" % limitstyle)
66
67
  self.limitstyle = limitstyle
68
+ if (max_limit is not None
69
+ and not isinstance(max_limit, numbers.Integral)):
70
+ raise ValueError("unsupported max_limit: %r" % max_limit)
67
71
  self.max_limit = max_limit
72
+ if paramstyle not in {'format', 'qmark'}:
73
+ raise ValueError("unsupported paramstyle: %r" % paramstyle)
68
74
  self.paramstyle = paramstyle
69
- self.ilike = ilike
70
- self.no_as = no_as
71
- self.no_boolean = no_boolean
72
- self.null_ordering = null_ordering
73
- self.function_mapping = function_mapping or {}
74
- self.filter_ = filter_
75
- self.escape_empty = escape_empty
75
+ self.ilike = bool(ilike)
76
+ self.no_as = bool(no_as)
77
+ self.no_boolean = bool(no_boolean)
78
+ self.null_ordering = bool(null_ordering)
79
+ self.function_mapping = dict(function_mapping or {})
80
+ self.filter_ = bool(filter_)
81
+ self.escape_empty = bool(escape_empty)
76
82
 
77
83
  @property
78
84
  def param(self):
@@ -176,7 +182,7 @@ def format2numeric(query, params):
176
182
 
177
183
 
178
184
  class Query(object):
179
- __slots__ = ()
185
+ __slots__ = ('__weakref__',)
180
186
 
181
187
  @property
182
188
  def params(self):
@@ -213,7 +219,8 @@ class WithQuery(Query):
213
219
  if value is not None:
214
220
  if isinstance(value, With):
215
221
  value = [value]
216
- assert all(isinstance(w, With) for w in value)
222
+ if any(not isinstance(w, With) for w in value):
223
+ raise ValueError("invalid with: %r" % value)
217
224
  self._with = value
218
225
 
219
226
  def _with_str(self):
@@ -236,7 +243,7 @@ class WithQuery(Query):
236
243
 
237
244
 
238
245
  class FromItem(object):
239
- __slots__ = ()
246
+ __slots__ = ('__weakref__',)
240
247
 
241
248
  @property
242
249
  def alias(self):
@@ -252,7 +259,8 @@ class FromItem(object):
252
259
  return Column(self, name)
253
260
 
254
261
  def __add__(self, other):
255
- assert isinstance(other, FromItem)
262
+ if not isinstance(other, FromItem):
263
+ return NotImplemented
256
264
  return From((self, other))
257
265
 
258
266
  def select(self, *args, **kwargs):
@@ -348,7 +356,8 @@ class SelectQuery(WithQuery):
348
356
  if value is not None:
349
357
  if isinstance(value, Expression):
350
358
  value = [value]
351
- assert all(isinstance(col, Expression) for col in value)
359
+ if any(not isinstance(col, Expression) for col in value):
360
+ raise ValueError("invalid order by: %r" % value)
352
361
  self._order_by = value
353
362
 
354
363
  @property
@@ -365,7 +374,8 @@ class SelectQuery(WithQuery):
365
374
  @limit.setter
366
375
  def limit(self, value):
367
376
  if value is not None:
368
- assert isinstance(value, numbers.Integral)
377
+ if not isinstance(value, numbers.Integral):
378
+ raise ValueError("invalid limit: %r" % value)
369
379
  self._limit = value
370
380
 
371
381
  @property
@@ -375,7 +385,8 @@ class SelectQuery(WithQuery):
375
385
  @offset.setter
376
386
  def offset(self, value):
377
387
  if value is not None:
378
- assert isinstance(value, numbers.Integral)
388
+ if not isinstance(value, numbers.Integral):
389
+ raise ValueError("invalid offset: %r" % value)
379
390
  self._offset = value
380
391
 
381
392
  @property
@@ -464,7 +475,8 @@ class Select(FromItem, SelectQuery):
464
475
  if value is not None:
465
476
  if isinstance(value, Expression):
466
477
  value = [value]
467
- assert all(isinstance(col, Expression) for col in value)
478
+ if any(not isinstance(col, Expression) for col in value):
479
+ raise ValueError("invalid distinct on: %r" % value)
468
480
  self._distinct_on = value
469
481
 
470
482
  @property
@@ -473,7 +485,10 @@ class Select(FromItem, SelectQuery):
473
485
 
474
486
  @columns.setter
475
487
  def columns(self, value):
476
- assert all(isinstance(col, (Expression, SelectQuery)) for col in value)
488
+ if any(
489
+ not isinstance(col, (Expression, SelectQuery))
490
+ for col in value):
491
+ raise ValueError("invalid columns: %r" % value)
477
492
  self._columns = tuple(value)
478
493
 
479
494
  @property
@@ -484,7 +499,8 @@ class Select(FromItem, SelectQuery):
484
499
  def where(self, value):
485
500
  from sql.operators import And, Or
486
501
  if value is not None:
487
- assert isinstance(value, (Expression, And, Or))
502
+ if not isinstance(value, (Expression, And, Or)):
503
+ raise ValueError("invalid where: %r" % value)
488
504
  self._where = value
489
505
 
490
506
  @property
@@ -496,7 +512,8 @@ class Select(FromItem, SelectQuery):
496
512
  if value is not None:
497
513
  if isinstance(value, Expression):
498
514
  value = [value]
499
- assert all(isinstance(col, Expression) for col in value)
515
+ if any(not isinstance(col, Expression) for col in value):
516
+ raise ValueError("invalid group by: %r" % value)
500
517
  self._group_by = value
501
518
 
502
519
  @property
@@ -507,7 +524,8 @@ class Select(FromItem, SelectQuery):
507
524
  def having(self, value):
508
525
  from sql.operators import And, Or
509
526
  if value is not None:
510
- assert isinstance(value, (Expression, And, Or))
527
+ if not isinstance(value, (Expression, And, Or)):
528
+ raise ValueError("invalid having: %r" % value)
511
529
  self._having = value
512
530
 
513
531
  @property
@@ -519,7 +537,8 @@ class Select(FromItem, SelectQuery):
519
537
  if value is not None:
520
538
  if isinstance(value, For):
521
539
  value = [value]
522
- assert all(isinstance(f, For) for f in value)
540
+ if any(not isinstance(f, For) for f in value):
541
+ raise ValueError("invalid for: %r" % value)
523
542
  self._for_ = value
524
543
 
525
544
  @property
@@ -547,7 +566,8 @@ class Select(FromItem, SelectQuery):
547
566
  @windows.setter
548
567
  def windows(self, value):
549
568
  if value is not None:
550
- assert all(isinstance(w, Window) for w in value)
569
+ if any(not isinstance(w, Window) for w in value):
570
+ raise ValueError("invalid windows: %r" % value)
551
571
  self._windows = value
552
572
 
553
573
  @staticmethod
@@ -672,13 +692,13 @@ class Select(FromItem, SelectQuery):
672
692
  if self.group_by:
673
693
  for expression in self.group_by:
674
694
  p.extend(expression.params)
675
- if self.order_by:
676
- for expression in self.order_by:
677
- p.extend(expression.params)
678
695
  if self.having:
679
696
  p.extend(self.having.params)
680
697
  for window in self.windows:
681
698
  p.extend(window.params)
699
+ if self.order_by:
700
+ for expression in self.order_by:
701
+ p.extend(expression.params)
682
702
  p.extend(self._limit_offset_params)
683
703
  return tuple(p)
684
704
 
@@ -707,7 +727,8 @@ class Insert(WithQuery):
707
727
 
708
728
  @table.setter
709
729
  def table(self, value):
710
- assert isinstance(value, Table)
730
+ if not isinstance(value, Table):
731
+ raise ValueError("invalid table: %r" % value)
711
732
  self._table = value
712
733
 
713
734
  @property
@@ -717,8 +738,10 @@ class Insert(WithQuery):
717
738
  @columns.setter
718
739
  def columns(self, value):
719
740
  if value is not None:
720
- assert all(isinstance(col, Column) for col in value)
721
- assert all(col.table == self.table for col in value)
741
+ if any(
742
+ not isinstance(col, Column) or col.table != self.table
743
+ for col in value):
744
+ raise ValueError("invalid columns: %r" % value)
722
745
  self._columns = value
723
746
 
724
747
  @property
@@ -728,7 +751,8 @@ class Insert(WithQuery):
728
751
  @values.setter
729
752
  def values(self, value):
730
753
  if value is not None:
731
- assert isinstance(value, (list, Select))
754
+ if not isinstance(value, (list, Select)):
755
+ raise ValueError("invalid values: %r" % value)
732
756
  if isinstance(value, list):
733
757
  value = Values(value)
734
758
  self._values = value
@@ -740,8 +764,8 @@ class Insert(WithQuery):
740
764
  @on_conflict.setter
741
765
  def on_conflict(self, value):
742
766
  if value is not None:
743
- assert isinstance(value, Conflict)
744
- assert value.table == self.table
767
+ if not isinstance(value, Conflict) or value.table != self.table:
768
+ raise ValueError("invalid on conflict: %r" % value)
745
769
  self._on_conflict = value
746
770
 
747
771
  @property
@@ -751,7 +775,8 @@ class Insert(WithQuery):
751
775
  @returning.setter
752
776
  def returning(self, value):
753
777
  if value is not None:
754
- assert isinstance(value, list)
778
+ if not isinstance(value, list):
779
+ raise ValueError("invalid returning: %r" % value)
755
780
  self._returning = value
756
781
 
757
782
  @staticmethod
@@ -834,7 +859,8 @@ class Conflict(object):
834
859
 
835
860
  @table.setter
836
861
  def table(self, value):
837
- assert isinstance(value, Table)
862
+ if not isinstance(value, Table):
863
+ raise ValueError("invalid table: %r" % value)
838
864
  self._table = value
839
865
 
840
866
  @property
@@ -844,8 +870,10 @@ class Conflict(object):
844
870
  @indexed_columns.setter
845
871
  def indexed_columns(self, value):
846
872
  if value is not None:
847
- assert all(isinstance(col, Column) for col in value)
848
- assert all(col.table == self.table for col in value)
873
+ if any(
874
+ not isinstance(col, Column) or col.table != self.table
875
+ for col in value):
876
+ raise ValueError("invalid indexed columns: %r" % value)
849
877
  self._indexed_columns = value
850
878
 
851
879
  @property
@@ -856,7 +884,8 @@ class Conflict(object):
856
884
  def index_where(self, value):
857
885
  from sql.operators import And, Or
858
886
  if value is not None:
859
- assert isinstance(value, (Expression, And, Or))
887
+ if not isinstance(value, (Expression, And, Or)):
888
+ raise ValueError("invalid index where: %r" % value)
860
889
  self._index_where = value
861
890
 
862
891
  @property
@@ -866,8 +895,10 @@ class Conflict(object):
866
895
  @columns.setter
867
896
  def columns(self, value):
868
897
  if value is not None:
869
- assert all(isinstance(col, Column) for col in value)
870
- assert all(col.table == self.table for col in value)
898
+ if any(
899
+ not isinstance(col, Column) or col.table != self.table
900
+ for col in value):
901
+ raise ValueError("invalid columns: %r" % value)
871
902
  self._columns = value
872
903
 
873
904
  @property
@@ -877,7 +908,8 @@ class Conflict(object):
877
908
  @values.setter
878
909
  def values(self, value):
879
910
  if value is not None:
880
- assert isinstance(value, (list, Select))
911
+ if not isinstance(value, (list, Select)):
912
+ raise ValueError("invalid values: %r" % value)
881
913
  if isinstance(value, list):
882
914
  value = Values([value])
883
915
  self._values = value
@@ -890,7 +922,8 @@ class Conflict(object):
890
922
  def where(self, value):
891
923
  from sql.operators import And, Or
892
924
  if value is not None:
893
- assert isinstance(value, (Expression, And, Or))
925
+ if not isinstance(value, (Expression, And, Or)):
926
+ raise ValueError("invalid where: %r" % value)
894
927
  self._where = value
895
928
 
896
929
  def __str__(self):
@@ -961,7 +994,8 @@ class Update(Insert):
961
994
  def values(self, value):
962
995
  if isinstance(value, Select):
963
996
  value = [value]
964
- assert isinstance(value, list)
997
+ if not isinstance(value, list):
998
+ raise ValueError("invalid values: %r" % value)
965
999
  self._values = value
966
1000
 
967
1001
  @property
@@ -972,9 +1006,14 @@ class Update(Insert):
972
1006
  def where(self, value):
973
1007
  from sql.operators import And, Or
974
1008
  if value is not None:
975
- assert isinstance(value, (Expression, And, Or))
1009
+ if not isinstance(value, (Expression, And, Or)):
1010
+ raise ValueError("invalid where: %r" % value)
976
1011
  self._where = value
977
1012
 
1013
+ @staticmethod
1014
+ def _format_column(value):
1015
+ return Select._format_column(value)
1016
+
978
1017
  def __str__(self):
979
1018
  assert all(col.table == self.table for col in self.columns)
980
1019
  # Get columns without alias
@@ -992,7 +1031,7 @@ class Update(Insert):
992
1031
  returning = ''
993
1032
  if self.returning:
994
1033
  returning = ' RETURNING ' + ', '.join(
995
- map(self._format, self.returning))
1034
+ map(self._format_column, self.returning))
996
1035
  return (self._with_str()
997
1036
  + 'UPDATE %s AS "%s" SET ' % (self.table, self.table.alias)
998
1037
  + values + from_ + where + returning)
@@ -1037,7 +1076,8 @@ class Delete(WithQuery):
1037
1076
 
1038
1077
  @table.setter
1039
1078
  def table(self, value):
1040
- assert isinstance(value, Table)
1079
+ if not isinstance(value, Table):
1080
+ raise ValueError("invalid table: %r" % value)
1041
1081
  self._table = value
1042
1082
 
1043
1083
  @property
@@ -1048,7 +1088,8 @@ class Delete(WithQuery):
1048
1088
  def where(self, value):
1049
1089
  from sql.operators import And, Or
1050
1090
  if value is not None:
1051
- assert isinstance(value, (Expression, And, Or))
1091
+ if not isinstance(value, (Expression, And, Or)):
1092
+ raise ValueError("invalid where: %r" % value)
1052
1093
  self._where = value
1053
1094
 
1054
1095
  @property
@@ -1058,19 +1099,15 @@ class Delete(WithQuery):
1058
1099
  @returning.setter
1059
1100
  def returning(self, value):
1060
1101
  if value is not None:
1061
- assert isinstance(value, list)
1102
+ if any(
1103
+ not isinstance(col, (Expression, SelectQuery))
1104
+ for col in value):
1105
+ raise ValueError("invalid returning: %r" % value)
1062
1106
  self._returning = value
1063
1107
 
1064
1108
  @staticmethod
1065
- def _format(value, param=None):
1066
- if param is None:
1067
- param = Flavor.get().param
1068
- if isinstance(value, Expression):
1069
- return str(value)
1070
- elif isinstance(value, Select):
1071
- return '(%s)' % value
1072
- else:
1073
- return param
1109
+ def _format(value):
1110
+ return Select._format_column(value)
1074
1111
 
1075
1112
  def __str__(self):
1076
1113
  with AliasManager(exclude=[self.table]):
@@ -1118,7 +1155,8 @@ class Merge(WithQuery):
1118
1155
 
1119
1156
  @target.setter
1120
1157
  def target(self, value):
1121
- assert isinstance(value, Table)
1158
+ if not isinstance(value, Table):
1159
+ raise ValueError("invalid target: %r" % value)
1122
1160
  self._target = value
1123
1161
 
1124
1162
  @property
@@ -1127,7 +1165,8 @@ class Merge(WithQuery):
1127
1165
 
1128
1166
  @source.setter
1129
1167
  def source(self, value):
1130
- assert isinstance(value, (Table, SelectQuery, Values))
1168
+ if not isinstance(value, (Table, SelectQuery, Values)):
1169
+ raise ValueError("invalid source: %r" % value)
1131
1170
  self._source = value
1132
1171
 
1133
1172
  @property
@@ -1136,7 +1175,8 @@ class Merge(WithQuery):
1136
1175
 
1137
1176
  @condition.setter
1138
1177
  def condition(self, value):
1139
- assert isinstance(value, Expression)
1178
+ if not isinstance(value, Expression):
1179
+ raise ValueError("invalid condition: %r" % value)
1140
1180
  self._condition = value
1141
1181
 
1142
1182
  @property
@@ -1145,7 +1185,8 @@ class Merge(WithQuery):
1145
1185
 
1146
1186
  @whens.setter
1147
1187
  def whens(self, value):
1148
- assert all(isinstance(w, Matched) for w in value)
1188
+ if any(not isinstance(w, Matched) for w in value):
1189
+ raise ValueError("invalid whens: %r" % value)
1149
1190
  self._whens = tuple(value)
1150
1191
 
1151
1192
  def __str__(self):
@@ -1154,10 +1195,7 @@ class Merge(WithQuery):
1154
1195
  source = '(%s)' % self.source
1155
1196
  else:
1156
1197
  source = self.source
1157
- if self.condition:
1158
- condition = 'ON %s' % self.condition
1159
- else:
1160
- condition = ''
1198
+ condition = 'ON %s' % self.condition
1161
1199
  return (self._with_str()
1162
1200
  + 'MERGE INTO %s AS "%s" ' % (self.target, self.target.alias)
1163
1201
  + 'USING %s AS "%s" ' % (source, self.source.alias)
@@ -1191,7 +1229,8 @@ class Matched(object):
1191
1229
  @condition.setter
1192
1230
  def condition(self, value):
1193
1231
  if value is not None:
1194
- assert isinstance(value, Expression)
1232
+ if not isinstance(value, Expression):
1233
+ raise ValueError("invalid condition: %r" % value)
1195
1234
  self._condition = value
1196
1235
 
1197
1236
  def _then_str(self):
@@ -1228,7 +1267,8 @@ class _MatchedValues(Matched):
1228
1267
 
1229
1268
  @columns.setter
1230
1269
  def columns(self, value):
1231
- assert all(isinstance(col, Column) for col in value)
1270
+ if any(not isinstance(col, Column) for col in value):
1271
+ raise ValueError("invalid columns: %r" % value)
1232
1272
  self._columns = value
1233
1273
 
1234
1274
 
@@ -1281,13 +1321,15 @@ class NotMatchedInsert(_MatchedValues, NotMatched):
1281
1321
 
1282
1322
  @values.setter
1283
1323
  def values(self, value):
1284
- self._values = Values([value])
1324
+ if value is not None:
1325
+ value = Values([value])
1326
+ self._values = value
1285
1327
 
1286
1328
  def _then_str(self):
1287
1329
  columns = ', '.join(c.column_name for c in self.columns)
1288
1330
  columns = '(' + columns + ')'
1289
1331
  if self.values is None:
1290
- values = ' DEFAULT VALUES '
1332
+ values = ' DEFAULT VALUES'
1291
1333
  else:
1292
1334
  values = ' ' + str(self.values)
1293
1335
  return 'INSERT ' + columns + values
@@ -1295,7 +1337,8 @@ class NotMatchedInsert(_MatchedValues, NotMatched):
1295
1337
  @property
1296
1338
  def params(self):
1297
1339
  p = list(super().params)
1298
- p.extend(self.values.params)
1340
+ if self.values:
1341
+ p.extend(self.values.params)
1299
1342
  return tuple(p)
1300
1343
 
1301
1344
 
@@ -1304,7 +1347,8 @@ class CombiningQuery(FromItem, SelectQuery):
1304
1347
  _operator = ''
1305
1348
 
1306
1349
  def __init__(self, *queries, **kwargs):
1307
- assert all(isinstance(q, Query) for q in queries)
1350
+ if any(not isinstance(q, Query) for q in queries):
1351
+ raise ValueError("invalid queries: %r" % (queries,))
1308
1352
  self.queries = queries
1309
1353
  self.all_ = kwargs.pop('all_', False)
1310
1354
  super(CombiningQuery, self).__init__(**kwargs)
@@ -1424,7 +1468,8 @@ class Join(FromItem):
1424
1468
 
1425
1469
  @left.setter
1426
1470
  def left(self, value):
1427
- assert isinstance(value, FromItem)
1471
+ if not isinstance(value, FromItem):
1472
+ raise ValueError("invalid left: %r" % value)
1428
1473
  self._left = value
1429
1474
 
1430
1475
  @property
@@ -1433,7 +1478,8 @@ class Join(FromItem):
1433
1478
 
1434
1479
  @right.setter
1435
1480
  def right(self, value):
1436
- assert isinstance(value, FromItem)
1481
+ if not isinstance(value, FromItem):
1482
+ raise ValueError("invalid right: %r" % value)
1437
1483
  self._right = value
1438
1484
 
1439
1485
  @property
@@ -1444,7 +1490,8 @@ class Join(FromItem):
1444
1490
  def condition(self, value):
1445
1491
  from sql.operators import And, Or
1446
1492
  if value is not None:
1447
- assert isinstance(value, (Expression, And, Or))
1493
+ if not isinstance(value, (Expression, And, Or)):
1494
+ raise ValueError("invalid condition: %r" % value)
1448
1495
  self._condition = value
1449
1496
 
1450
1497
  @property
@@ -1454,8 +1501,10 @@ class Join(FromItem):
1454
1501
  @type_.setter
1455
1502
  def type_(self, value):
1456
1503
  value = value.upper()
1457
- assert value in ('INNER', 'LEFT', 'LEFT OUTER',
1458
- 'RIGHT', 'RIGHT OUTER', 'FULL', 'FULL OUTER', 'CROSS')
1504
+ if value not in {
1505
+ 'INNER', 'LEFT', 'LEFT OUTER', 'RIGHT', 'RIGHT OUTER', 'FULL',
1506
+ 'FULL OUTER', 'CROSS'}:
1507
+ raise ValueError("invalid type: %r" % value)
1459
1508
  self._type_ = value
1460
1509
 
1461
1510
  def __str__(self):
@@ -1471,14 +1520,9 @@ class Join(FromItem):
1471
1520
  def params(self):
1472
1521
  p = []
1473
1522
  for item in (self.left, self.right):
1474
- try:
1475
- p.extend(item.params)
1476
- except AttributeError:
1477
- pass
1478
- try:
1523
+ p.extend(item.params)
1524
+ if self.condition:
1479
1525
  p.extend(self.condition.params)
1480
- except AttributeError:
1481
- pass
1482
1526
  return tuple(p)
1483
1527
 
1484
1528
  @property
@@ -1534,8 +1578,10 @@ class From(list):
1534
1578
  return tuple(p)
1535
1579
 
1536
1580
  def __add__(self, other):
1537
- assert isinstance(other, FromItem)
1538
- assert not isinstance(other, CombiningQuery)
1581
+ if not isinstance(other, FromItem):
1582
+ return NotImplemented
1583
+ elif isinstance(other, CombiningQuery):
1584
+ return NotImplemented
1539
1585
  return From(super(From, self).__add__([other]))
1540
1586
 
1541
1587
 
@@ -1558,7 +1604,7 @@ class Values(list, Query, FromItem):
1558
1604
 
1559
1605
  @property
1560
1606
  def params(self):
1561
- p = []
1607
+ p = list(super().params)
1562
1608
  for values in self:
1563
1609
  for value in values:
1564
1610
  if isinstance(value, Expression):
@@ -1569,7 +1615,7 @@ class Values(list, Query, FromItem):
1569
1615
 
1570
1616
 
1571
1617
  class Expression(object):
1572
- __slots__ = ()
1618
+ __slots__ = ('__weakref__',)
1573
1619
 
1574
1620
  def __str__(self):
1575
1621
  raise NotImplementedError
@@ -1823,21 +1869,35 @@ class Cast(Expression):
1823
1869
 
1824
1870
 
1825
1871
  class Collate(Expression):
1826
- __slots__ = ('expression', 'collation')
1872
+ __slots__ = ('_expression', '_collation')
1827
1873
 
1828
1874
  def __init__(self, expression, collation):
1829
1875
  super(Collate, self).__init__()
1830
1876
  self.expression = expression
1831
1877
  self.collation = collation
1832
1878
 
1879
+ @property
1880
+ def expression(self):
1881
+ return self._expression
1882
+
1883
+ @expression.setter
1884
+ def expression(self, value):
1885
+ self._expression = value
1886
+
1887
+ @property
1888
+ def collation(self):
1889
+ return self._collation
1890
+
1891
+ @collation.setter
1892
+ def collation(self, value):
1893
+ self._collation = value
1894
+
1833
1895
  def __str__(self):
1834
1896
  if isinstance(self.expression, Expression):
1835
1897
  value = self.expression
1836
1898
  else:
1837
1899
  value = Flavor.get().param
1838
- if '"' in self.collation:
1839
- raise ValueError("Wrong collation %s" % self.collation)
1840
- return '%s COLLATE "%s"' % (value, self.collation)
1900
+ return '%s COLLATE %s' % (value, _escape_identifier(self.collation))
1841
1901
 
1842
1902
  @property
1843
1903
  def params(self):
@@ -1860,8 +1920,11 @@ class Grouping(Expression):
1860
1920
 
1861
1921
  @sets.setter
1862
1922
  def sets(self, value):
1863
- assert all(
1864
- isinstance(col, Expression) for cols in value for col in cols)
1923
+ if any(
1924
+ not isinstance(col, Expression)
1925
+ for cols in value
1926
+ for col in cols):
1927
+ raise ValueError("invalid sets: %r" % value)
1865
1928
  self._sets = tuple(tuple(cols) for cols in value)
1866
1929
 
1867
1930
  def __str__(self):
@@ -1888,10 +1951,11 @@ class Rollup(Expression):
1888
1951
 
1889
1952
  @expressions.setter
1890
1953
  def expressions(self, value):
1891
- assert all(
1892
- isinstance(col, Expression)
1893
- or all(isinstance(c, Expression) for c in col)
1894
- for col in value)
1954
+ if not all(
1955
+ isinstance(col, Expression)
1956
+ or all(isinstance(c, Expression) for c in col)
1957
+ for col in value):
1958
+ raise ValueError("invalid expressions: %r" % value)
1895
1959
  self._expressions = tuple(value)
1896
1960
 
1897
1961
  def __str__(self):
@@ -1922,7 +1986,8 @@ class Cube(Rollup):
1922
1986
 
1923
1987
  class Window(object):
1924
1988
  __slots__ = (
1925
- '_partition', '_order_by', '_frame', '_start', '_end', '_exclude')
1989
+ '_partition', '_order_by', '_frame', '_start', '_end', '_exclude',
1990
+ '__weakref__')
1926
1991
 
1927
1992
  def __init__(self, partition, order_by=None,
1928
1993
  frame=None, start=None, end=0, exclude=None):
@@ -1945,7 +2010,8 @@ class Window(object):
1945
2010
 
1946
2011
  @partition.setter
1947
2012
  def partition(self, value):
1948
- assert all(isinstance(e, Expression) for e in value)
2013
+ if any(not isinstance(e, Expression) for e in value):
2014
+ raise ValueError("invalid partition: %r" % value)
1949
2015
  self._partition = value
1950
2016
 
1951
2017
  @property
@@ -1957,7 +2023,8 @@ class Window(object):
1957
2023
  if value is not None:
1958
2024
  if isinstance(value, Expression):
1959
2025
  value = [value]
1960
- assert all(isinstance(col, Expression) for col in value)
2026
+ if any(not isinstance(col, Expression) for col in value):
2027
+ raise ValueError("invalid order by: %r" % value)
1961
2028
  self._order_by = value
1962
2029
 
1963
2030
  @property
@@ -1967,7 +2034,8 @@ class Window(object):
1967
2034
  @frame.setter
1968
2035
  def frame(self, value):
1969
2036
  if value:
1970
- assert value in ['RANGE', 'ROWS', 'GROUPS']
2037
+ if value not in {'RANGE', 'ROWS', 'GROUPS'}:
2038
+ raise ValueError("invalid frame: %r" % value)
1971
2039
  self._frame = value
1972
2040
 
1973
2041
  @property
@@ -1977,7 +2045,8 @@ class Window(object):
1977
2045
  @start.setter
1978
2046
  def start(self, value):
1979
2047
  if value:
1980
- assert isinstance(value, numbers.Integral)
2048
+ if not isinstance(value, numbers.Integral):
2049
+ raise ValueError("invalid start: %r" % value)
1981
2050
  self._start = value
1982
2051
 
1983
2052
  @property
@@ -1987,7 +2056,8 @@ class Window(object):
1987
2056
  @end.setter
1988
2057
  def end(self, value):
1989
2058
  if value:
1990
- assert isinstance(value, numbers.Integral)
2059
+ if not isinstance(value, numbers.Integral):
2060
+ raise ValueError("invalid end: %r" % value)
1991
2061
  self._end = value
1992
2062
 
1993
2063
  @property
@@ -1997,7 +2067,8 @@ class Window(object):
1997
2067
  @exclude.setter
1998
2068
  def exclude(self, value):
1999
2069
  if value:
2000
- assert value in ['CURRENT ROW', 'GROUP', 'TIES']
2070
+ if value not in {'CURRENT ROW', 'GROUP', 'TIES'}:
2071
+ raise ValueError("invalid exclude: %r" % value)
2001
2072
  self._exclude = value
2002
2073
 
2003
2074
  @property
@@ -2070,7 +2141,8 @@ class Order(Expression):
2070
2141
 
2071
2142
  @expression.setter
2072
2143
  def expression(self, value):
2073
- assert isinstance(value, (Expression, SelectQuery))
2144
+ if not isinstance(value, (Expression, SelectQuery)):
2145
+ raise ValueError("invalid expression: %r" % value)
2074
2146
  self._expression = value
2075
2147
 
2076
2148
  def __str__(self):
@@ -2173,7 +2245,8 @@ class For(object):
2173
2245
  @type_.setter
2174
2246
  def type_(self, value):
2175
2247
  value = value.upper()
2176
- assert value in ('UPDATE', 'SHARE')
2248
+ if value not in {'UPDATE', 'SHARE'}:
2249
+ raise ValueError("invalid type: %r" % value)
2177
2250
  self._type_ = value
2178
2251
 
2179
2252
  def __str__(self):