Repository: django/django
File: django/db/backends/oracle/operations.py (Python)

Code before:
            for sql in (
                ("OFFSET %d ROWS" % offset) if offset else None,
                ("FETCH FIRST %d ROWS ONLY" % fetch) if fetch else None,
            )
            if sql
        )

    def last_executed_query(self, cursor, sql, params):
        # https://python-oracledb.readthedocs.io/en/latest/api_manual/cursor.html#Cursor.statement
        # The DB API definition does not define this attribute.
        statement = cursor.statement
        # Unlike Psycopg's `query` and MySQLdb`'s `_executed`, oracledb's
        # `statement` doesn't contain the query parameters. Substitute
        # parameters manually.
        if statement and params:
            if isinstance(params, (tuple, list)):
                params = {
                    f":arg{i}": param for i, param in enumerate(dict.fromkeys(params))
                }
            elif isinstance(params, dict):
                params = {f":{key}": val for (key, val) in params.items()}
            for key in sorted(params, key=len, reverse=True):
                statement = statement.replace(
                    key, force_str(params[key], errors="replace")
                )
        return statement or super().last_executed_query(cursor, sql, params)

    def last_insert_id(self, cursor, table_name, pk_name):
        sq_name = self._get_sequence_name(cursor, strip_quotes(table_name), pk_name)
        cursor.execute('"%s".currval' % sq_name)
        return cursor.fetchone()[0]

    def lookup_cast(self, lookup_type, internal_type=None):
        if lookup_type in ("iexact", "icontains", "istartswith", "iendswith"):
            return "UPPER(%s)"
        if lookup_type != "isnull" and internal_type in (
            "BinaryField",
            "TextField",
        ):
            return "DBMS_LOB.SUBSTR(%s)"
        return "%s"

    def max_in_list_size(self):
        return 1000

    def max_name_length(self):
        return 30

    def pk_default_value(self):
        return "NULL"


Review comment (suggestion):
I think we should use `super().last_executed_query()` only when `statement` is None
```suggestion
        return super().last_executed_query(cursor, sql, params) if statement is None else statement 
```

Code after:
            for sql in (
                ("OFFSET %d ROWS" % offset) if offset else None,
                ("FETCH FIRST %d ROWS ONLY" % fetch) if fetch else None,
            )
            if sql
        )

    def last_executed_query(self, cursor, sql, params):
        # https://python-oracledb.readthedocs.io/en/latest/api_manual/cursor.html#Cursor.statement
        # The DB API definition does not define this attribute.
        statement = cursor.statement
        # Unlike Psycopg's `query` and MySQLdb`'s `_executed`, oracledb's
        # `statement` doesn't contain the query parameters. Substitute
        # parameters manually.
        if statement and params:
            if isinstance(params, (tuple, list)):
                params = {
                    f":arg{i}": param for i, param in enumerate(dict.fromkeys(params))
                }
            elif isinstance(params, dict):
                params = {f":{key}": val for (key, val) in params.items()}
            for key in sorted(params, key=len, reverse=True):
                statement = statement.replace(
                    key, force_str(params[key], errors="replace")
                )
        return (
            super().last_executed_query(cursor, sql, params)
            if statement is None
            else statement
        )

    def last_insert_id(self, cursor, table_name, pk_name):
        sq_name = self._get_sequence_name(cursor, strip_quotes(table_name), pk_name)
        cursor.execute('"%s".currval' % sq_name)
        return cursor.fetchone()[0]

    def lookup_cast(self, lookup_type, internal_type=None):
        if lookup_type in ("iexact", "icontains", "istartswith", "iendswith"):
            return "UPPER(%s)"
        if lookup_type != "isnull" and internal_type in (
            "BinaryField",
            "TextField",
        ):
            return "DBMS_LOB.SUBSTR(%s)"
        return "%s"

    def max_in_list_size(self):
        return 1000

    def max_name_length(self):
        return 30