Commit 92d7f541 authored by Anssi Kääriäinen's avatar Anssi Kääriäinen
Browse files

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.
parent 2dbfa66f
Loading
Loading
Loading
Loading
+1 −23
Original line number Diff line number Diff line
@@ -7,29 +7,7 @@ class GeoSQLCompiler(BaseGeoSQLCompiler, SQLCompiler):
    pass

class SQLInsertCompiler(compiler.SQLInsertCompiler, GeoSQLCompiler):
    def placeholder(self, field, val):
        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'
    pass

class SQLDeleteCompiler(compiler.SQLDeleteCompiler, GeoSQLCompiler):
    pass
+9 −0
Original line number Diff line number Diff line
@@ -288,3 +288,12 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
    def spatial_ref_sys(self):
        from django.contrib.gis.db.backends.oracle.models import 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'], ]
+5 −0
Original line number Diff line number Diff line
@@ -916,6 +916,11 @@ class BaseDatabaseOperations(object):
        conn = ' %s ' % connector
        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):
    """
+2 −0
Original line number Diff line number Diff line
@@ -856,6 +856,8 @@ class SQLInsertCompiler(SQLCompiler):
                [self.placeholder(field, v) for field, v in zip(fields, val)]
                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:
            params = params[0]
            col = "%s.%s" % (qn(opts.db_table), qn(opts.pk.column))