Fixed #19058 -- Fixed Oracle GIS crash
The problem is the same as in #10888 which was reintroduced when bulk_insert was added. Thanks to Jani Tiainen for report, patch and also testing the final patch on Oracle GIS.
This commit is contained in:
parent
2dbfa66f4d
commit
92d7f541da
|
@ -7,29 +7,7 @@ class GeoSQLCompiler(BaseGeoSQLCompiler, SQLCompiler):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class SQLInsertCompiler(compiler.SQLInsertCompiler, GeoSQLCompiler):
|
class SQLInsertCompiler(compiler.SQLInsertCompiler, GeoSQLCompiler):
|
||||||
def placeholder(self, field, val):
|
pass
|
||||||
if field is None:
|
|
||||||
# A field value of None means the value is raw.
|
|
||||||
return val
|
|
||||||
elif hasattr(field, 'get_placeholder'):
|
|
||||||
# Some fields (e.g. geo fields) need special munging before
|
|
||||||
# they can be inserted.
|
|
||||||
ph = field.get_placeholder(val, self.connection)
|
|
||||||
if ph == 'NULL':
|
|
||||||
# If the placeholder returned is 'NULL', then we need to
|
|
||||||
# to remove None from the Query parameters. Specifically,
|
|
||||||
# cx_Oracle will assume a CHAR type when a placeholder ('%s')
|
|
||||||
# is used for columns of MDSYS.SDO_GEOMETRY. Thus, we use
|
|
||||||
# 'NULL' for the value, and remove None from the query params.
|
|
||||||
# See also #10888.
|
|
||||||
param_idx = self.query.columns.index(field.column)
|
|
||||||
params = list(self.query.params)
|
|
||||||
params.pop(param_idx)
|
|
||||||
self.query.params = tuple(params)
|
|
||||||
return ph
|
|
||||||
else:
|
|
||||||
# Return the common case for the placeholder
|
|
||||||
return '%s'
|
|
||||||
|
|
||||||
class SQLDeleteCompiler(compiler.SQLDeleteCompiler, GeoSQLCompiler):
|
class SQLDeleteCompiler(compiler.SQLDeleteCompiler, GeoSQLCompiler):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -288,3 +288,12 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
def spatial_ref_sys(self):
|
def spatial_ref_sys(self):
|
||||||
from django.contrib.gis.db.backends.oracle.models import SpatialRefSys
|
from django.contrib.gis.db.backends.oracle.models import SpatialRefSys
|
||||||
return SpatialRefSys
|
return SpatialRefSys
|
||||||
|
|
||||||
|
def modify_insert_params(self, placeholders, params):
|
||||||
|
"""Drop out insert parameters for NULL placeholder. Needed for Oracle Spatial
|
||||||
|
backend due to #10888
|
||||||
|
"""
|
||||||
|
# This code doesn't work for bulk insert cases.
|
||||||
|
assert len(placeholders) == 1
|
||||||
|
return [[param for pholder,param
|
||||||
|
in six.moves.zip(placeholders[0], params[0]) if pholder != 'NULL'], ]
|
||||||
|
|
|
@ -916,6 +916,11 @@ class BaseDatabaseOperations(object):
|
||||||
conn = ' %s ' % connector
|
conn = ' %s ' % connector
|
||||||
return conn.join(sub_expressions)
|
return conn.join(sub_expressions)
|
||||||
|
|
||||||
|
def modify_insert_params(self, placeholders, params):
|
||||||
|
"""Allow modification of insert parameters. Needed for Oracle Spatial
|
||||||
|
backend due to #10888.
|
||||||
|
"""
|
||||||
|
return params
|
||||||
|
|
||||||
class BaseDatabaseIntrospection(object):
|
class BaseDatabaseIntrospection(object):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -856,6 +856,8 @@ class SQLInsertCompiler(SQLCompiler):
|
||||||
[self.placeholder(field, v) for field, v in zip(fields, val)]
|
[self.placeholder(field, v) for field, v in zip(fields, val)]
|
||||||
for val in values
|
for val in values
|
||||||
]
|
]
|
||||||
|
# Oracle Spatial needs to remove some values due to #10888
|
||||||
|
params = self.connection.ops.modify_insert_params(placeholders, params)
|
||||||
if self.return_id and self.connection.features.can_return_id_from_insert:
|
if self.return_id and self.connection.features.can_return_id_from_insert:
|
||||||
params = params[0]
|
params = params[0]
|
||||||
col = "%s.%s" % (qn(opts.db_table), qn(opts.pk.column))
|
col = "%s.%s" % (qn(opts.db_table), qn(opts.pk.column))
|
||||||
|
|
Loading…
Reference in New Issue