ransacklib 1.1.0.dev5__tar.gz → 1.1.0.dev6__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.
- {ransacklib-1.1.0.dev5/ransacklib.egg-info → ransacklib-1.1.0.dev6}/PKG-INFO +1 -1
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/pyproject.toml +1 -1
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/ransack/operator.py +55 -47
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/ransack/transformer.py +28 -27
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6/ransacklib.egg-info}/PKG-INFO +1 -1
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/tests/test_transformer.py +106 -3
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/LICENSE +0 -0
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/README.rst +0 -0
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/ransack/__init__.py +0 -0
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/ransack/exceptions.py +0 -0
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/ransack/function.py +0 -0
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/ransack/parser.py +0 -0
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/ransack/py.typed +0 -0
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/ransacklib.egg-info/SOURCES.txt +0 -0
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/ransacklib.egg-info/dependency_links.txt +0 -0
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/ransacklib.egg-info/requires.txt +0 -0
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/ransacklib.egg-info/top_level.txt +0 -0
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/setup.cfg +0 -0
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/tests/test_operator.py +0 -0
- {ransacklib-1.1.0.dev5 → ransacklib-1.1.0.dev6}/tests/test_parser.py +0 -0
|
@@ -500,63 +500,65 @@ def binary_operation(operator: str, left: Any, right: Any) -> Any:
|
|
|
500
500
|
raise OperatorNotFoundError(operator, (t1, t2), (left, right)) from None
|
|
501
501
|
|
|
502
502
|
|
|
503
|
-
def _operator_map_sql(op, l_sql, r_sql, t1, t2) -> tuple[str, Any]:
|
|
504
|
-
def _get_comp_dict_sql(
|
|
503
|
+
def _operator_map_sql(op, l_sql, r_sql, t1, t2) -> tuple[str, Any, bool]:
|
|
504
|
+
def _get_comp_dict_sql(
|
|
505
|
+
op: str, tuple_repr_f
|
|
506
|
+
) -> dict[tuple[Operand, Operand], tuple[str, bool]]:
|
|
505
507
|
return {
|
|
506
|
-
(Number, Number): f"{l_sql} {op} {r_sql}",
|
|
507
|
-
(Number, list): f"{l_sql} {op} ANY({r_sql})",
|
|
508
|
-
(Number, tuple): f"{l_sql} {op} {tuple_repr_f}({r_sql})",
|
|
509
|
-
(datetime, datetime): f"{l_sql} {op} {r_sql}",
|
|
510
|
-
(datetime, list): f"{l_sql} {op} ANY({r_sql})",
|
|
511
|
-
(datetime, tuple): f"{r_sql} {op} {tuple_repr_f}({l_sql})",
|
|
512
|
-
(timedelta, timedelta): f"{l_sql} {op} {r_sql}",
|
|
513
|
-
(timedelta, list): f"{l_sql} {op} ANY({r_sql})",
|
|
514
|
-
("ip", "ip"): f"{l_sql} {op} {r_sql}",
|
|
515
|
-
("ip", list): f"{l_sql} {op} ANY({r_sql})",
|
|
508
|
+
(Number, Number): (f"{l_sql} {op} {r_sql}", False),
|
|
509
|
+
(Number, list): (f"{l_sql} {op} ANY({r_sql})", False),
|
|
510
|
+
(Number, tuple): (f"{l_sql} {op} {tuple_repr_f}({r_sql})", False),
|
|
511
|
+
(datetime, datetime): (f"{l_sql} {op} {r_sql}", False),
|
|
512
|
+
(datetime, list): (f"{l_sql} {op} ANY({r_sql})", False),
|
|
513
|
+
(datetime, tuple): (f"{r_sql} {op} {tuple_repr_f}({l_sql})", True),
|
|
514
|
+
(timedelta, timedelta): (f"{l_sql} {op} {r_sql}", False),
|
|
515
|
+
(timedelta, list): (f"{l_sql} {op} ANY({r_sql})", False),
|
|
516
|
+
("ip", "ip"): (f"{l_sql} {op} {r_sql}", False),
|
|
517
|
+
("ip", list): (f"{l_sql} {op} ANY({r_sql})", False),
|
|
516
518
|
# (list, list): f"{l_sql} && {r_sql}",
|
|
517
519
|
# (tuple, tuple): f"upper({l_sql}) > lower({r_sql})",
|
|
518
520
|
}
|
|
519
521
|
|
|
520
522
|
d: dict[str, dict] = {
|
|
521
523
|
"=": {
|
|
522
|
-
(Number, Number): f"{l_sql} = {r_sql}",
|
|
523
|
-
(Number, list): f"{l_sql} = ANY({r_sql})",
|
|
524
|
-
(Number, tuple): f"{r_sql} @> {l_sql}",
|
|
525
|
-
(datetime, datetime): f"{l_sql} = {r_sql}",
|
|
526
|
-
(datetime, list): f"{l_sql} = ANY({r_sql})",
|
|
527
|
-
(datetime, tuple): f"{r_sql} @> {l_sql}",
|
|
528
|
-
(timedelta, timedelta): f"{l_sql} = {r_sql}",
|
|
529
|
-
(timedelta, list): f"{l_sql} = ANY({r_sql})",
|
|
530
|
-
(str, str): f"{l_sql} = {r_sql}",
|
|
531
|
-
(str, list): f"{l_sql} = ANY({r_sql})",
|
|
532
|
-
("ip", "ip"): f"{l_sql} && {r_sql}",
|
|
533
|
-
("ip", list): f"{l_sql} && ANY({r_sql})",
|
|
534
|
-
(list, list): f"{l_sql} && {r_sql}",
|
|
535
|
-
(tuple, tuple): f"{l_sql} && {r_sql}",
|
|
524
|
+
(Number, Number): (f"{l_sql} = {r_sql}", False),
|
|
525
|
+
(Number, list): (f"{l_sql} = ANY({r_sql})", False),
|
|
526
|
+
(Number, tuple): (f"{r_sql} @> {l_sql}", True),
|
|
527
|
+
(datetime, datetime): (f"{l_sql} = {r_sql}", False),
|
|
528
|
+
(datetime, list): (f"{l_sql} = ANY({r_sql})", False),
|
|
529
|
+
(datetime, tuple): (f"{r_sql} @> {l_sql}", True),
|
|
530
|
+
(timedelta, timedelta): (f"{l_sql} = {r_sql}", False),
|
|
531
|
+
(timedelta, list): (f"{l_sql} = ANY({r_sql})", False),
|
|
532
|
+
(str, str): (f"{l_sql} = {r_sql}", False),
|
|
533
|
+
(str, list): (f"{l_sql} = ANY({r_sql})", False),
|
|
534
|
+
("ip", "ip"): (f"{l_sql} && {r_sql}", False),
|
|
535
|
+
("ip", list): (f"{l_sql} && ANY({r_sql})", False),
|
|
536
|
+
(list, list): (f"{l_sql} && {r_sql}", False),
|
|
537
|
+
(tuple, tuple): (f"{l_sql} && {r_sql}", False),
|
|
536
538
|
},
|
|
537
539
|
">": _get_comp_dict_sql(">", "lower")
|
|
538
|
-
| {(tuple, tuple): f"upper({l_sql}) > lower({r_sql})"},
|
|
540
|
+
| {(tuple, tuple): (f"upper({l_sql}) > lower({r_sql})", False)},
|
|
539
541
|
">=": _get_comp_dict_sql(">=", "lower")
|
|
540
|
-
| {(tuple, tuple): f"upper({l_sql}) >= lower({r_sql})"},
|
|
542
|
+
| {(tuple, tuple): (f"upper({l_sql}) >= lower({r_sql})", False)},
|
|
541
543
|
"<": _get_comp_dict_sql("<", "upper")
|
|
542
|
-
| {(tuple, tuple): f"lower({l_sql}) < upper({r_sql})"},
|
|
544
|
+
| {(tuple, tuple): (f"lower({l_sql}) < upper({r_sql})", False)},
|
|
543
545
|
"<=": _get_comp_dict_sql("<=", "upper")
|
|
544
|
-
| {(tuple, tuple): f"lower({l_sql}) <= upper({r_sql})"},
|
|
545
|
-
"and": {(bool, bool): f"{l_sql} AND {r_sql}"},
|
|
546
|
-
"or": {(bool, bool): f"{l_sql} OR {r_sql}"},
|
|
547
|
-
"contains": {(str, str): f"position({r_sql} in {l_sql})>0"},
|
|
546
|
+
| {(tuple, tuple): (f"lower({l_sql}) <= upper({r_sql})", False)},
|
|
547
|
+
"and": {(bool, bool): (f"{l_sql} AND {r_sql}", False)},
|
|
548
|
+
"or": {(bool, bool): (f"({l_sql} OR {r_sql})", False)},
|
|
549
|
+
"contains": {(str, str): (f"position({r_sql} in {l_sql})>0", True)},
|
|
548
550
|
}
|
|
549
551
|
d2: dict[str, dict] = {
|
|
550
552
|
"+": {
|
|
551
|
-
(Number, Number): (f"{l_sql} + {r_sql}", Number),
|
|
552
|
-
(datetime, timedelta): (f"{l_sql} + {r_sql}", datetime),
|
|
553
|
-
(timedelta, timedelta): (f"{l_sql} + {r_sql}", timedelta),
|
|
553
|
+
(Number, Number): (f"({l_sql} + {r_sql})", Number),
|
|
554
|
+
(datetime, timedelta): (f"({l_sql} + {r_sql})", datetime),
|
|
555
|
+
(timedelta, timedelta): (f"({l_sql} + {r_sql})", timedelta),
|
|
554
556
|
},
|
|
555
557
|
"-": {
|
|
556
|
-
(Number, Number): (f"{l_sql} - {r_sql}", Number),
|
|
557
|
-
(datetime, timedelta): (f"{l_sql} - {r_sql}", datetime),
|
|
558
|
-
(timedelta, timedelta): (f"{l_sql} - {r_sql}", timedelta),
|
|
559
|
-
(datetime, datetime): (f"{l_sql} - {r_sql}", timedelta),
|
|
558
|
+
(Number, Number): (f"({l_sql} - {r_sql})", Number),
|
|
559
|
+
(datetime, timedelta): (f"({l_sql} - {r_sql})", datetime),
|
|
560
|
+
(timedelta, timedelta): (f"({l_sql} - {r_sql})", timedelta),
|
|
561
|
+
(datetime, datetime): (f"({l_sql} - {r_sql})", timedelta),
|
|
560
562
|
},
|
|
561
563
|
"*": {
|
|
562
564
|
(timedelta, Number): (f"{l_sql} * {r_sql}", timedelta),
|
|
@@ -567,21 +569,24 @@ def _operator_map_sql(op, l_sql, r_sql, t1, t2) -> tuple[str, Any]:
|
|
|
567
569
|
(Number, Number): (f"{l_sql} / {r_sql}", Number),
|
|
568
570
|
},
|
|
569
571
|
"%": {
|
|
570
|
-
(Number, Number): (f"{l_sql} % {r_sql}", Number),
|
|
572
|
+
(Number, Number): (f"({l_sql} % {r_sql})", Number),
|
|
571
573
|
},
|
|
572
574
|
}
|
|
573
575
|
if op == "==":
|
|
574
|
-
return (f"{l_sql} = {r_sql}", bool)
|
|
576
|
+
return (f"{l_sql} = {r_sql}", bool, False)
|
|
575
577
|
if op == "in":
|
|
576
|
-
|
|
578
|
+
sql, switch = d["="][(t1, t2)]
|
|
579
|
+
return sql, bool, switch
|
|
577
580
|
if op in d2:
|
|
578
|
-
|
|
579
|
-
|
|
581
|
+
sql, type_ = d2[op][(t1, t2)]
|
|
582
|
+
return sql, type_, False
|
|
583
|
+
sql, switch = d[op][(t1, t2)]
|
|
584
|
+
return sql, bool, switch
|
|
580
585
|
|
|
581
586
|
|
|
582
587
|
def binary_operation_sql(
|
|
583
588
|
operator: str, left: str, right: str, l_type: Any, r_type: Any
|
|
584
|
-
) -> tuple[str, Any]:
|
|
589
|
+
) -> tuple[str, bool, Any]:
|
|
585
590
|
# Normalize numeric types
|
|
586
591
|
l_type = Number if l_type in (int, float) else l_type
|
|
587
592
|
r_type = Number if r_type in (int, float) else r_type
|
|
@@ -595,7 +600,10 @@ def binary_operation_sql(
|
|
|
595
600
|
return _operator_map_sql(operator, left, right, l_type, r_type)
|
|
596
601
|
except KeyError:
|
|
597
602
|
try:
|
|
598
|
-
|
|
603
|
+
sql, type_, switch = _operator_map_sql(
|
|
604
|
+
operator, right, left, r_type, l_type
|
|
605
|
+
)
|
|
606
|
+
return sql, type_, not switch
|
|
599
607
|
except KeyError:
|
|
600
608
|
pass
|
|
601
609
|
raise OperatorNotFoundError(operator, (l_type, r_type), (left, right)) from None
|
|
@@ -852,13 +852,13 @@ class SQLInterpreter(Interpreter):
|
|
|
852
852
|
cast = "iprange"
|
|
853
853
|
return (f"%s::{cast}", [token.real_value], type(token.real_value))
|
|
854
854
|
|
|
855
|
-
def neg(self, tree: Tree) -> tuple[str, list
|
|
855
|
+
def neg(self, tree: Tree) -> tuple[str, list, Any]:
|
|
856
856
|
sql, params, type_ = self.visit(tree)
|
|
857
|
-
return (f"-{sql}", params, type_)
|
|
857
|
+
return (f"(-{sql})", params, type_)
|
|
858
858
|
|
|
859
859
|
def range_op(
|
|
860
860
|
self, l_tree: Tree, r_tree: Tree
|
|
861
|
-
) -> tuple[str, list
|
|
861
|
+
) -> tuple[str, list, type[tuple] | type[IP]]:
|
|
862
862
|
l_sql, l_params, l_type = self.visit(l_tree)
|
|
863
863
|
r_sql, r_params, r_type = self.visit(r_tree)
|
|
864
864
|
|
|
@@ -898,7 +898,7 @@ class SQLInterpreter(Interpreter):
|
|
|
898
898
|
tuple,
|
|
899
899
|
)
|
|
900
900
|
|
|
901
|
-
def var_from_data(self, var: TokenWrapper) -> tuple[str, list
|
|
901
|
+
def var_from_data(self, var: TokenWrapper) -> tuple[str, list, Any]:
|
|
902
902
|
if var.real_value in self.data:
|
|
903
903
|
column, type_ = self.data[var.real_value]
|
|
904
904
|
return (f'"{column}"', [], type_)
|
|
@@ -912,68 +912,69 @@ class SQLInterpreter(Interpreter):
|
|
|
912
912
|
end_pos=var.end_pos,
|
|
913
913
|
)
|
|
914
914
|
|
|
915
|
-
def _binary_operation(self, operator, l_tree, r_tree) -> tuple[str, list
|
|
915
|
+
def _binary_operation(self, operator, l_tree, r_tree) -> tuple[str, list, Any]:
|
|
916
916
|
l_sql, l_params, l_type = self.visit(l_tree)
|
|
917
917
|
r_sql, r_params, r_type = self.visit(r_tree)
|
|
918
918
|
|
|
919
|
-
sql, type_ = binary_operation_sql(
|
|
919
|
+
sql, type_, switch = binary_operation_sql(
|
|
920
|
+
operator, l_sql, r_sql, l_type, r_type
|
|
921
|
+
)
|
|
922
|
+
params = l_params + r_params if not switch else r_params + l_params
|
|
920
923
|
|
|
921
|
-
return sql,
|
|
924
|
+
return sql, params, type_
|
|
922
925
|
|
|
923
|
-
def add(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
926
|
+
def add(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, Any]:
|
|
924
927
|
return self._binary_operation("+", l_tree, r_tree)
|
|
925
928
|
|
|
926
|
-
def sub(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
929
|
+
def sub(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, Any]:
|
|
927
930
|
return self._binary_operation("-", l_tree, r_tree)
|
|
928
931
|
|
|
929
|
-
def mul(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
932
|
+
def mul(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, Any]:
|
|
930
933
|
return self._binary_operation("*", l_tree, r_tree)
|
|
931
934
|
|
|
932
|
-
def div(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
935
|
+
def div(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, Any]:
|
|
933
936
|
return self._binary_operation("/", l_tree, r_tree)
|
|
934
937
|
|
|
935
|
-
def mod(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
938
|
+
def mod(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, Any]:
|
|
936
939
|
return self._binary_operation("%", l_tree, r_tree)
|
|
937
940
|
|
|
938
|
-
def eq(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
941
|
+
def eq(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, type[bool]]:
|
|
939
942
|
return self._binary_operation("==", l_tree, r_tree)
|
|
940
943
|
|
|
941
|
-
def in_op(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
944
|
+
def in_op(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, type[bool]]:
|
|
942
945
|
return self._binary_operation("in", l_tree, r_tree)
|
|
943
946
|
|
|
944
|
-
def any_eq(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
947
|
+
def any_eq(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, type[bool]]:
|
|
945
948
|
return self._binary_operation("=", l_tree, r_tree)
|
|
946
949
|
|
|
947
|
-
def gt(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
950
|
+
def gt(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, type[bool]]:
|
|
948
951
|
return self._binary_operation(">", l_tree, r_tree)
|
|
949
952
|
|
|
950
|
-
def gte(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
953
|
+
def gte(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, type[bool]]:
|
|
951
954
|
return self._binary_operation(">=", l_tree, r_tree)
|
|
952
955
|
|
|
953
|
-
def lt(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
956
|
+
def lt(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, type[bool]]:
|
|
954
957
|
return self._binary_operation("<", l_tree, r_tree)
|
|
955
958
|
|
|
956
|
-
def lte(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
959
|
+
def lte(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, type[bool]]:
|
|
957
960
|
return self._binary_operation("<=", l_tree, r_tree)
|
|
958
961
|
|
|
959
|
-
def or_op(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
962
|
+
def or_op(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, type[bool]]:
|
|
960
963
|
return self._binary_operation("or", l_tree, r_tree)
|
|
961
964
|
|
|
962
|
-
def and_op(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list
|
|
965
|
+
def and_op(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, type[bool]]:
|
|
963
966
|
return self._binary_operation("and", l_tree, r_tree)
|
|
964
967
|
|
|
965
|
-
def not_op(self, tree: Tree) -> tuple[str, list
|
|
968
|
+
def not_op(self, tree: Tree) -> tuple[str, list, type[bool]]:
|
|
966
969
|
sql, params, type_ = self.visit(tree)
|
|
967
970
|
return f"NOT {sql}", params, type_
|
|
968
971
|
|
|
969
|
-
def contains_op(
|
|
970
|
-
self, l_tree: Tree, r_tree: Tree
|
|
971
|
-
) -> tuple[str, list[Any], type[bool]]:
|
|
972
|
+
def contains_op(self, l_tree: Tree, r_tree: Tree) -> tuple[str, list, type[bool]]:
|
|
972
973
|
return self._binary_operation("contains", l_tree, r_tree)
|
|
973
974
|
|
|
974
|
-
def exists_op(self, path: Token) -> tuple[str, list
|
|
975
|
+
def exists_op(self, path: Token) -> tuple[str, list, type[bool]]:
|
|
975
976
|
var_sql, _, _ = self.var_from_data(TokenWrapper(path, path))
|
|
976
|
-
return f"{var_sql}
|
|
977
|
+
return f"{var_sql} IS NOT NULL", [], bool
|
|
977
978
|
|
|
978
979
|
def exists_with_default(self, path: Token, default: Any) -> Any:
|
|
979
980
|
var_sql, _, _ = self.var_from_data(TokenWrapper(path, path))
|
|
@@ -530,9 +530,9 @@ class TestSQLInterpreter:
|
|
|
530
530
|
[
|
|
531
531
|
# Numbers.
|
|
532
532
|
("5", "%s", [5]),
|
|
533
|
-
("-12", "-%s", [12]),
|
|
533
|
+
("-12", "(-%s)", [12]),
|
|
534
534
|
("23.22", "%s", [23.22]),
|
|
535
|
-
("-0.224", "-%s", [0.224]),
|
|
535
|
+
("-0.224", "(-%s)", [0.224]),
|
|
536
536
|
("13e19", "%s", [1.3e20]),
|
|
537
537
|
# Datetime.
|
|
538
538
|
("2025-01-01", "%s::TIMESTAMP", [datetime(2025, 1, 1, 0, 0)]),
|
|
@@ -554,7 +554,7 @@ class TestSQLInterpreter:
|
|
|
554
554
|
),
|
|
555
555
|
# Timedelta.
|
|
556
556
|
("01:23:34", "%s", [timedelta(seconds=5014)]),
|
|
557
|
-
("-10D23:59:59", "-%s", [timedelta(days=10, seconds=86399)]),
|
|
557
|
+
("-10D23:59:59", "(-%s)", [timedelta(days=10, seconds=86399)]),
|
|
558
558
|
("99:59:59", "%s", [timedelta(days=4, seconds=14399)]),
|
|
559
559
|
# Strings.
|
|
560
560
|
("''", "%s", [""]),
|
|
@@ -659,6 +659,109 @@ class TestSQLInterpreter:
|
|
|
659
659
|
),
|
|
660
660
|
[],
|
|
661
661
|
),
|
|
662
|
+
# Test arithmetic operations.
|
|
663
|
+
(
|
|
664
|
+
"(10 + 12 - 7) * (15 / (8 % 3)) - (-5)",
|
|
665
|
+
"(((%s + %s) - %s) * %s / (%s % %s) - (-%s))",
|
|
666
|
+
[10, 12, 7, 15, 8, 3, 5],
|
|
667
|
+
),
|
|
668
|
+
# Test comparisons.
|
|
669
|
+
(
|
|
670
|
+
"10 > 12 and 12 < 20 and (17 >= 12 or 12 <= 1) and not 53 == 13",
|
|
671
|
+
"%s > %s AND %s < %s AND (%s >= %s OR %s <= %s) AND NOT %s = %s",
|
|
672
|
+
[10, 12, 12, 20, 17, 12, 12, 1, 53, 13],
|
|
673
|
+
),
|
|
674
|
+
# Test exists operators.
|
|
675
|
+
("a_int??", '"a" IS NOT NULL', []),
|
|
676
|
+
("a_int??14", 'COALESCE("a", %s)', [14]),
|
|
677
|
+
# Test contains operator.
|
|
678
|
+
("'abcdfg' contains 'bcd'", "position(%s in %s)>0", ["bcd", "abcdfg"]),
|
|
679
|
+
# Test = operator.
|
|
680
|
+
("1 = 1", "%s = %s", [1, 1]),
|
|
681
|
+
("1 = [1, 2, 3]", "%s = ANY(ARRAY[%s, %s, %s])", [1, 1, 2, 3]),
|
|
682
|
+
("[1, 2, 3] = 1", "%s = ANY(ARRAY[%s, %s, %s])", [1, 1, 2, 3]),
|
|
683
|
+
("[1, 2] = [3, 4]", "ARRAY[%s, %s] && ARRAY[%s, %s]", [1, 2, 3, 4]),
|
|
684
|
+
(
|
|
685
|
+
"2 = 1..10",
|
|
686
|
+
(
|
|
687
|
+
"CASE WHEN %s < %s "
|
|
688
|
+
"THEN int4range(%s, %s, '[]') "
|
|
689
|
+
"ELSE int4range(%s, %s, '[]') END @> %s"
|
|
690
|
+
),
|
|
691
|
+
[1, 10, 1, 10, 10, 1, 2],
|
|
692
|
+
),
|
|
693
|
+
(
|
|
694
|
+
"1..10 = 2",
|
|
695
|
+
(
|
|
696
|
+
"CASE WHEN %s < %s "
|
|
697
|
+
"THEN int4range(%s, %s, '[]') "
|
|
698
|
+
"ELSE int4range(%s, %s, '[]') END @> %s"
|
|
699
|
+
),
|
|
700
|
+
[1, 10, 1, 10, 10, 1, 2],
|
|
701
|
+
),
|
|
702
|
+
(
|
|
703
|
+
"a_int..b_int = c_int..d_int",
|
|
704
|
+
(
|
|
705
|
+
'CASE WHEN "a" < "b" '
|
|
706
|
+
'THEN int4range("a", "b", \'[]\') '
|
|
707
|
+
'ELSE int4range("b", "a", \'[]\') END '
|
|
708
|
+
'&& CASE WHEN "c" < "d" '
|
|
709
|
+
'THEN int4range("c", "d", \'[]\') '
|
|
710
|
+
'ELSE int4range("d", "c", \'[]\') END'
|
|
711
|
+
),
|
|
712
|
+
[],
|
|
713
|
+
),
|
|
714
|
+
(
|
|
715
|
+
"10.10.10.10 = 10.10.10.10",
|
|
716
|
+
"%s::ipaddress && %s::ipaddress",
|
|
717
|
+
[from_str("10.10.10.10"), from_str("10.10.10.10")],
|
|
718
|
+
),
|
|
719
|
+
(
|
|
720
|
+
"10.10.10.10 = 10.10.10.0 .. 10.10.10.20",
|
|
721
|
+
"%s::ipaddress && iprange(%s::ipaddress, %s::ipaddress)",
|
|
722
|
+
[
|
|
723
|
+
from_str("10.10.10.10"),
|
|
724
|
+
from_str("10.10.10.0"),
|
|
725
|
+
from_str("10.10.10.20"),
|
|
726
|
+
],
|
|
727
|
+
),
|
|
728
|
+
(
|
|
729
|
+
"192.168.0.5 = 192.168.0.0-192.168.0.255",
|
|
730
|
+
"%s::ipaddress && %s::iprange",
|
|
731
|
+
[from_str("192.168.0.5"), from_str("192.168.0.0-192.168.0.255")],
|
|
732
|
+
),
|
|
733
|
+
(
|
|
734
|
+
"192.168.0.12 = 192.168.1.0/24",
|
|
735
|
+
"%s::ipaddress && %s::iprange",
|
|
736
|
+
[from_str("192.168.0.12"), from_str("192.168.1.0/24")],
|
|
737
|
+
),
|
|
738
|
+
(
|
|
739
|
+
"10.10.10.10-10.10.10.20 = 10.10.10.15-10.10.10.25",
|
|
740
|
+
"%s::iprange && %s::iprange",
|
|
741
|
+
[
|
|
742
|
+
from_str("10.10.10.10-10.10.10.20"),
|
|
743
|
+
from_str("10.10.10.15-10.10.10.25"),
|
|
744
|
+
],
|
|
745
|
+
),
|
|
746
|
+
(
|
|
747
|
+
"10.10.10.10-10.10.10.20 = 192.168.0.0/16",
|
|
748
|
+
"%s::iprange && %s::iprange",
|
|
749
|
+
[from_str("10.10.10.10-10.10.10.20"), from_str("192.168.0.0/16")],
|
|
750
|
+
),
|
|
751
|
+
(
|
|
752
|
+
"192.168.1.0/24 = 192.168.0.0/16",
|
|
753
|
+
"%s::iprange && %s::iprange",
|
|
754
|
+
[from_str("192.168.1.0/24"), from_str("192.168.0.0/16")],
|
|
755
|
+
),
|
|
756
|
+
(
|
|
757
|
+
"192.168.1.10 = [192.168.0.0/24, 192.168.0.0/16]",
|
|
758
|
+
("%s::ipaddress && ANY(ARRAY[%s::iprange, %s::iprange])"),
|
|
759
|
+
[
|
|
760
|
+
from_str("192.168.1.10"),
|
|
761
|
+
from_str("192.168.0.0/24"),
|
|
762
|
+
from_str("192.168.0.0/16"),
|
|
763
|
+
],
|
|
764
|
+
),
|
|
662
765
|
],
|
|
663
766
|
)
|
|
664
767
|
def test_parse_sql(self, parser, sql, expr, expected_sql, expected_params):
|
|
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
|
|
File without changes
|
|
File without changes
|