Skip to content

Commit 72dcf5b

Browse files
committed
some fixes for different tests
1 parent 591986c commit 72dcf5b

File tree

6 files changed

+221
-57
lines changed

6 files changed

+221
-57
lines changed

django_iris/__init__.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22
from django.db.models.functions.datetime import Now
33
from django.db.models.expressions import Exists, Func, Value, Col, OrderBy
44
from django.db.models.functions.text import Chr, ConcatPair, StrIndex
5+
from django.db.models.functions import Cast
56
from django.db.models.fields import TextField, CharField
7+
from django.db.models.lookups import BuiltinLookup
8+
from django.db.models.fields.json import (
9+
KeyTransform,
10+
KeyTransformExact,
11+
compile_json_path,
12+
)
613

714
from django_iris.compiler import SQLCompiler
815

@@ -65,7 +72,8 @@ def convert_streams(expressions):
6572

6673
@as_intersystems(Exists)
6774
def exists_as_intersystems(self, compiler, connection, template=None, **extra_context):
68-
template = "(SELECT COUNT(*) FROM (%(subquery)s))"
75+
# template = "(SELECT COUNT(*) FROM (%(subquery)s))"
76+
template = "EXISTS %(subquery)s"
6977
return self.as_sql(compiler, connection, template, **extra_context)
7078

7179

@@ -151,3 +159,37 @@ def orderby_as_intersystems(self, compiler, connection, **extra_context):
151159
# IRIS does not support order NULL
152160
copy.nulls_first = copy.nulls_last = False
153161
return copy.as_sql(compiler, connection, **extra_context)
162+
163+
164+
@as_intersystems(KeyTransformExact)
165+
def json_KeyTransformExact_as_intersystems(self, compiler, connection):
166+
return self.as_sql(compiler, connection)
167+
168+
169+
@as_intersystems(KeyTransform)
170+
def json_KeyTransform_as_intersystems(self, compiler, connection):
171+
# breakpoint()
172+
# json_path = compile_json_path(key_transforms)
173+
return f"{self.field.name}__{self.key_name}", []
174+
175+
176+
@as_intersystems(BuiltinLookup)
177+
def BuiltinLookup_as_intersystems(self, compiler, connection):
178+
sql, params = self.as_sql(compiler, connection)
179+
if compiler.in_get_order_by:
180+
return "CASE WHEN %s THEN 1 ELSE 0 END" % (sql,), params
181+
# if not compiler.in_get_select and not compiler.in_get_order_by:
182+
return sql, params
183+
184+
185+
@as_intersystems(Cast)
186+
def cast_as_intersystems(self, compiler, connection, **extra_context):
187+
if hasattr(self.source_expressions[0], "lookup_name"):
188+
if self.source_expressions[0].lookup_name in ["gt", "gte", "lt", "lte"]:
189+
return self.as_sql(
190+
compiler,
191+
connection,
192+
template="CASE WHEN %(expressions)s THEN 1 ELSE 0 END",
193+
**extra_context,
194+
)
195+
return self.as_sql(compiler, connection, **extra_context)

django_iris/compiler.py

Lines changed: 93 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,81 @@
1+
import itertools
2+
13
from django.core.exceptions import EmptyResultSet, FullResultSet
2-
from django.db.models.expressions import Col, Value
4+
from django.db.models.expressions import RawSQL
5+
from django.db.models.sql.where import AND
36
from django.db.models.sql import compiler
7+
from django.db.models.fields.json import KeyTransform
8+
from django.db.models.expressions import DatabaseDefault
9+
10+
11+
class Flag:
12+
value = False
13+
14+
def __init__(self, value):
15+
self.value = value
16+
17+
def __enter__(self):
18+
self.value = True
19+
return True
20+
21+
def __exit__(self, *args):
22+
self.value = False
23+
24+
def __bool__(self):
25+
return self.value
26+
427

528
class SQLCompiler(compiler.SQLCompiler):
29+
in_get_select = Flag(False)
30+
in_get_order_by = Flag(False)
31+
# def get_from_clause(self):
32+
# result, params = super().get_from_clause()
33+
# jsoncolumns = {}
34+
# for column in self.query.select + tuple(
35+
# [column for column in (col.lhs for col in self.query.where.children)]
36+
# ):
37+
# if isinstance(column, KeyTransform):
38+
# if column.field.name not in jsoncolumns:
39+
# jsoncolumns[column.field.name] = {}
40+
# jsoncolumns[column.field.name][
41+
# column.key_name
42+
# ] = f"{column.field.name}__{column.key_name}"
43+
# []
44+
# for field in jsoncolumns:
45+
# self.query.where.add(RawSQL("%s is not null" % (field,), []), AND)
46+
# cols = ", ".join(
47+
# [
48+
# f"{jsoncolumns[field][col_name]} VARCHAR PATH '$.{col_name}'"
49+
# for col_name in jsoncolumns[field]
50+
# ]
51+
# )
52+
# result.append(
53+
# f"""
54+
# , JSON_TABLE("{column.field.name}", '$' COLUMNS(
55+
# {cols}
56+
# ))
57+
# """
58+
# )
59+
60+
# if "model_fields_nullablejsonmodel" in self.query.alias_map:
61+
# breakpoint()
62+
# return result, params
63+
64+
def get_select(self, with_col_aliases=False):
65+
with self.in_get_select:
66+
return super().get_select(with_col_aliases)
67+
68+
def get_order_by(self):
69+
with self.in_get_order_by:
70+
return super().get_order_by()
671

772
def as_sql(self, with_limits=True, with_col_aliases=False):
873
with_limit_offset = (with_limits or self.query.is_sliced) and (
974
self.query.high_mark is not None or self.query.low_mark > 0
1075
)
1176
if self.query.select_for_update or not with_limit_offset:
12-
return super().as_sql(with_limits, with_col_aliases)
77+
query, params = super().as_sql(with_limits, with_col_aliases)
78+
return query, params
1379
try:
1480
extra_select, order_by, group_by = self.pre_sql_setup()
1581

@@ -79,7 +145,10 @@ def as_sql(self, with_limits=True, with_col_aliases=False):
79145
order_by_result = "ORDER BY %s" % first_col
80146

81147
if offset:
82-
out_cols.append("ROW_NUMBER() %s AS row_number" % ("OVER (%s)" % order_by_result if order_by_result else ""))
148+
out_cols.append(
149+
"ROW_NUMBER() %s AS row_number"
150+
% ("OVER (%s)" % order_by_result if order_by_result else "")
151+
)
83152

84153
result += [", ".join(out_cols), "FROM", *from_]
85154
params.extend(f_params)
@@ -154,19 +223,32 @@ def as_sql(self, with_limits=True, with_col_aliases=False):
154223
), tuple(sub_params + params)
155224

156225
if offset:
157-
query = "SELECT * FROM (%s) WHERE row_number between %d AND %d ORDER BY row_number" % (
158-
query,
159-
offset,
160-
limit,
226+
query = (
227+
"SELECT * FROM (%s) WHERE row_number between %d AND %d ORDER BY row_number"
228+
% (
229+
query,
230+
offset,
231+
limit,
232+
)
161233
)
162234
return query, tuple(params)
163-
except:
164-
return super().as_sql(with_limits, with_col_aliases)
235+
except Exception:
236+
query, params = super().as_sql(with_limits, with_col_aliases)
237+
return query, params
165238

166239

167240
class SQLInsertCompiler(compiler.SQLInsertCompiler, SQLCompiler):
168-
241+
169242
def as_sql(self):
243+
244+
if self.query.fields:
245+
fields = self.query.fields
246+
self.query.fields = [
247+
field
248+
for field in fields
249+
if not isinstance(self.pre_save_val(field, self.query.objs[0]), DatabaseDefault)
250+
]
251+
170252
if self.query.fields:
171253
return super().as_sql()
172254

@@ -195,7 +277,7 @@ def as_sql(self):
195277
if self.connection._disable_constraint_checking:
196278
sql = "UPDATE %%NOCHECK" + sql[6:]
197279
return sql, params
198-
280+
199281

200282
class SQLAggregateCompiler(compiler.SQLAggregateCompiler, SQLCompiler):
201283
pass

django_iris/features.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
8484
only_supports_unbounded_with_preceding_and_following = False
8585

8686
# Does the backend support JSONField?
87-
supports_json_field = False
87+
supports_json_field = True
8888
# Can the backend introspect a JSONField?
8989
can_introspect_json_field = False
9090
# Does the backend support primitives in JSONField?
@@ -106,13 +106,15 @@ class DatabaseFeatures(BaseDatabaseFeatures):
106106
supports_collation_on_charfield = True
107107
supports_collation_on_textfield = False
108108

109+
supports_boolean_expr_in_select_clause = False
110+
109111
# Collation names for use by the Django test suite.
110112
test_collations = {
111113
# "ci": None, # Case-insensitive.
112114
"cs": "EXACT", # Case-sensitive.
113115
# "non_default": None, # Non-default.
114116
# "swedish_ci": None, # Swedish case-insensitive.
115-
"virtual": None
117+
"virtual": None,
116118
}
117119

118120
@cached_property
@@ -162,12 +164,23 @@ def django_test_skips(self):
162164
# "datetimes.tests.DateTimesTests.test_datetimes_ambiguous_and_invalid_times",
163165
# },
164166
"IRIS does not have check contsraints": {
167+
"model_fields.test_jsonfield.JSONFieldTests.test_db_check_constraints",
165168
"constraints.tests.CheckConstraintTests.test_validate",
166169
"constraints.tests.CheckConstraintTests.test_validate_boolean_expressions",
167170
"constraints.tests.UniqueConstraintTests.test_validate_expression_condition",
168171
},
172+
"Does not support expressions in default": {
173+
"field_defaults.tests.DefaultTests.test_full_clean",
174+
"basic.tests.ModelInstanceCreationTests.test_save_primary_with_db_default",
175+
},
176+
"Regex not supported": {
177+
"lookup.tests.LookupTests.test_regex",
178+
"lookup.tests.LookupTests.test_regex_backreferencing",
179+
"lookup.tests.LookupTests.test_regex_non_ascii",
180+
"lookup.tests.LookupTests.test_regex_non_string",
181+
"lookup.tests.LookupTests.test_regex_null",
182+
},
169183
}
170-
171184
)
172185
return skips
173186

@@ -186,6 +199,19 @@ def django_test_skips(self):
186199
"schema.tests.SchemaTests.test_alter_text_field_to_time_field",
187200
"schema.tests.SchemaTests.test_alter_text_field_to_datetime_field",
188201
"schema.tests.SchemaTests.test_alter_text_field_to_date_field",
202+
#
203+
"lookup.tests.LookupQueryingTests.test_filter_exists_lhs",
204+
"lookup.tests.LookupQueryingTests.test_filter_lookup_lhs",
205+
"lookup.tests.LookupQueryingTests.test_filter_subquery_lhs",
206+
"lookup.tests.LookupQueryingTests.test_filter_wrapped_lookup_lhs",
207+
"lookup.tests.LookupTests.test_lookup_rhs",
208+
209+
"lookup.tests.LookupTests.test_regex",
210+
"lookup.tests.LookupTests.test_regex_backreferencing",
211+
"lookup.tests.LookupTests.test_regex_non_ascii",
212+
"lookup.tests.LookupTests.test_regex_non_string",
213+
"lookup.tests.LookupTests.test_regex_null",
214+
189215
}
190216

191217
# django_test_skips["IRIS Bugs"] = django_test_expected_failures

0 commit comments

Comments
 (0)