Commit dad8434d authored by Caio Ariede's avatar Caio Ariede Committed by Tim Graham
Browse files

Fixed #25180 -- Prevented varchar_patterns_ops and text_patterns_ops indexes for ArrayField.

parent 7a40fef1
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -29,6 +29,11 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
                # a second index that specifies their operator class, which is
                # needed when performing correct LIKE queries outside the
                # C locale. See #12234.
                #
                # The same doesn't apply to array fields such as varchar[size]
                # and text[size], so skip them.
                if '[' in db_type:
                    continue
                if db_type.startswith('varchar'):
                    output.append(self._create_index_sql(
                        model, [field], suffix='_like', sql=self.sql_create_varchar_index))
+3 −0
Original line number Diff line number Diff line
@@ -31,3 +31,6 @@ Bugfixes
* Moved the :ref:`unsaved model instance assignment data loss check
  <unsaved-model-instance-check-18>` to ``Model.save()`` to allow easier usage
  of in-memory models (:ticket:`25160`).

* Prevented ``varchar_patterns_ops`` and ``text_patterns_ops`` indexes for
  ``ArrayField`` (:ticket:`25180`).
+26 −0
Original line number Diff line number Diff line
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import django.contrib.postgres.fields
from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='CharTextArrayIndexModel',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('char', django.contrib.postgres.fields.ArrayField(models.CharField(max_length=10), db_index=True, size=100)),
                ('char2', models.CharField(max_length=11, db_index=True)),
                ('text', django.contrib.postgres.fields.ArrayField(models.TextField(), db_index=True)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
    ]
+0 −0

Empty file added.

+27 −0
Original line number Diff line number Diff line
@@ -312,6 +312,33 @@ class TestMigrations(TransactionTestCase):
        with connection.cursor() as cursor:
            self.assertNotIn(table_name, connection.introspection.table_names(cursor))

    @override_settings(MIGRATION_MODULES={
        "postgres_tests": "postgres_tests.array_index_migrations",
    })
    def test_adding_arrayfield_with_index(self):
        """
        ArrayField shouldn't have varchar_patterns_ops or text_patterns_ops indexes.
        """
        table_name = 'postgres_tests_chartextarrayindexmodel'
        call_command('migrate', 'postgres_tests', verbosity=0)
        with connection.cursor() as cursor:
            like_constraint_field_names = [
                c.rsplit('_', 2)[0][len(table_name) + 1:]
                for c in connection.introspection.get_constraints(cursor, table_name)
                if c.endswith('_like')
            ]
        # Only the CharField should have a LIKE index.
        self.assertEqual(like_constraint_field_names, ['char2'])
        with connection.cursor() as cursor:
            indexes = connection.introspection.get_indexes(cursor, table_name)
        # All fields should have regular indexes.
        self.assertIn('char', indexes)
        self.assertIn('char2', indexes)
        self.assertIn('text', indexes)
        call_command('migrate', 'postgres_tests', 'zero', verbosity=0)
        with connection.cursor() as cursor:
            self.assertNotIn(table_name, connection.introspection.table_names(cursor))


class TestSerialization(PostgreSQLTestCase):
    test_data = '[{"fields": {"field": "[\\"1\\", \\"2\\"]"}, "model": "postgres_tests.integerarraymodel", "pk": null}]'