Ticket #14091: 14091.3.patch

File 14091.3.patch, 6.6 KB (added by aaugustin, 4 years ago)
  • AUTHORS

     
    6060    atlithorn <atlithorn@gmail.com>
    6161    Jökull Sólberg Auðunsson <jokullsolberg@gmail.com>
    6262    Arthur <avandorp@gmail.com>
     63    Aymeric Augustin <aymeric.augustin@m4x.org>
    6364    av0000@mail.ru
    6465    David Avsajanishvili <avsd05@gmail.com>
    6566    Mike Axiak <axiak@mit.edu>
  • docs/faq/models.txt

     
    2222
    2323``connection.queries`` includes all SQL statements -- INSERTs, UPDATES,
    2424SELECTs, etc. Each time your app hits the database, the query will be recorded.
    25 Note that the raw SQL logged in ``connection.queries`` may not include
    26 parameter quoting.  Parameter quoting is performed by the database-specific
    27 backend, and not all backends provide a way to retrieve the SQL after quoting.
     25Note that the raw SQL is :ref:`unreliable with SQLite <sqlite-connection-queries>`.
    2826
    2927.. versionadded:: 1.2
    3028
  • docs/ref/databases.txt

     
    465465binary distribution, if needed.
    466466
    467467"Database is locked" errors
    468 -----------------------------------------------
     468---------------------------
    469469
    470470SQLite is meant to be a lightweight database, and thus can't support a high
    471471level of concurrency. ``OperationalError: database is locked`` errors indicate
     
    506506SQLite does not support the ``SELECT ... FOR UPDATE`` syntax. Calling it will
    507507have no effect.
    508508
     509.. _sqlite-connection-queries:
     510
     511Parameters not quoted in ``connection.queries``
     512-----------------------------------------------
     513
     514``sqlite3`` does not provide a way to retrieve the SQL after quoting and
     515substituting the parameters. Instead, the SQL in ``connection.queries`` is
     516rebuilt with a simple string interpolation. It may be incorrect. Make sure
     517you add quotes where necessary before copying a query into a SQLite shell.
     518
    509519.. _oracle-notes:
    510520
    511521Oracle notes
  • django/db/backends/mysql/base.py

     
    191191    def fulltext_search_sql(self, field_name):
    192192        return 'MATCH (%s) AGAINST (%%s IN BOOLEAN MODE)' % field_name
    193193
     194    def last_executed_query(self, cursor, sql, params):
     195        # With MySQLdb, cursor objects have an (undocumented) "_last_executed"
     196        # attribute where the exact query sent to the database is saved.
     197        # See MySQLdb/cursors.py in the source distribution.
     198        return cursor._last_executed
     199
    194200    def no_limit_value(self):
    195201        # 2**64 - 1, as recommended by the MySQL documentation
    196202        return 18446744073709551615L
  • django/db/backends/oracle/base.py

     
    210210        else:
    211211            return "%s"
    212212
     213    def last_executed_query(self, cursor, sql, params):
     214        # http://cx-oracle.sourceforge.net/html/cursor.html#Cursor.statement
     215        # The DB API definition does not define this attribute.
     216        return cursor.statement
     217
    213218    def last_insert_id(self, cursor, table_name, pk_name):
    214219        sq_name = self._get_sequence_name(table_name)
    215220        cursor.execute('SELECT "%s".currval FROM dual' % sq_name)
  • django/db/backends/postgresql_psycopg2/operations.py

     
    202202        return 63
    203203
    204204    def last_executed_query(self, cursor, sql, params):
    205         # With psycopg2, cursor objects have a "query" attribute that is the
    206         # exact query sent to the database. See docs here:
    207         # http://www.initd.org/tracker/psycopg/wiki/psycopg2_documentation#postgresql-status-message-and-executed-query
     205        # http://initd.org/psycopg/docs/cursor.html#cursor.query
     206        # The query attribute is a Psycopg extension to the DB API 2.0.
    208207        return cursor.query
    209208
    210209    def return_insert_id(self):
  • tests/regressiontests/backends/tests.py

     
    22# Unit and doctests for specific database backends.
    33import datetime
    44
     5from django.conf import settings
    56from django.core.management.color import no_style
    67from django.db import backend, connection, connections, DEFAULT_DB_ALIAS, IntegrityError
    78from django.db.backends.signals import connection_created
     
    8586        classes = models.SchoolClass.objects.filter(last_updated__day=20)
    8687        self.assertEqual(len(classes), 1)
    8788
     89class LastExecutedQueryTest(TestCase):
    8890
     91    def setUp(self):
     92        # connection.queries will not be filled in without this
     93        settings.DEBUG = True
     94
     95    def tearDown(self):
     96        settings.DEBUG = False
     97
     98    # There are no tests for the sqlite backend because it does not
     99    # implement paramater escaping. See #14091.
     100
     101    @unittest.skipUnless(connection.vendor in ('oracle', 'postgresql'),
     102                         "These backends use the standard parameter escaping rules")
     103    def test_parameter_escaping(self):
     104        # check that both numbers and string are properly quoted
     105        list(models.Tag.objects.filter(name="special:\\\"':", object_id=12))
     106        sql = connection.queries[-1]['sql']
     107        self.assertTrue("= 'special:\\\"'':' " in sql)
     108        self.assertTrue("= 12 " in sql)
     109
     110    @unittest.skipUnless(connection.vendor == 'mysql',
     111                         "MySQL uses backslashes to escape parameters.")
     112    def test_parameter_escaping(self):
     113        list(models.Tag.objects.filter(name="special:\\\"':", object_id=12))
     114        sql = connection.queries[-1]['sql']
     115        # only this line is different from the test above
     116        self.assertTrue("= 'special:\\\\\\\"\\':' " in sql)
     117        self.assertTrue("= 12 " in sql)
     118
    89119class ParameterHandlingTest(TestCase):
    90120    def test_bad_parameter_count(self):
    91121        "An executemany call with too many/not enough parameters will raise an exception (Refs #12612)"
Back to Top