diff --git a/django/db/backends/ddl_references.py b/django/db/backends/ddl_references.py
index c06386a2fa..f798fd648b 100644
--- a/django/db/backends/ddl_references.py
+++ b/django/db/backends/ddl_references.py
@@ -212,11 +212,7 @@ class Expressions(TableColumns):
     def rename_table_references(self, old_table, new_table):
         if self.table != old_table:
             return
-        expressions = deepcopy(self.expressions)
-        self.columns = []
-        for col in self.compiler.query._gen_cols([expressions]):
-            col.alias = new_table
-        self.expressions = expressions
+        self.expressions = self.expressions.relabeled_clone({old_table: new_table})
         super().rename_table_references(old_table, new_table)
 
     def rename_column_references(self, table, old_column, new_column):
diff --git a/docs/releases/3.2.9.txt b/docs/releases/3.2.9.txt
index 56cbd1d223..a03542c0b6 100644
--- a/docs/releases/3.2.9.txt
+++ b/docs/releases/3.2.9.txt
@@ -10,4 +10,5 @@ Django 3.2.9 fixes several bugs in 3.2.8 and adds compatibility with Python
 Bugfixes
 ========
 
-* ...
+* Fixed a bug in Django 3.2 that caused a migration crash on SQLite when
+  altering a field with a functional index (:ticket:`33194`).
diff --git a/tests/backends/test_ddl_references.py b/tests/backends/test_ddl_references.py
index bd4036ee33..ab3ba6ccd2 100644
--- a/tests/backends/test_ddl_references.py
+++ b/tests/backends/test_ddl_references.py
@@ -5,6 +5,7 @@ from django.db.backends.ddl_references import (
 from django.db.models import ExpressionList, F
 from django.db.models.functions import Upper
 from django.db.models.indexes import IndexExpression
+from django.db.models.sql import Query
 from django.test import SimpleTestCase, TransactionTestCase
 
 from .models import Person
@@ -229,6 +230,27 @@ class ExpressionsTests(TransactionTestCase):
             str(self.expressions),
         )
 
+    def test_rename_table_references_without_alias(self):
+        compiler = Query(Person, alias_cols=False).get_compiler(connection=connection)
+        table = Person._meta.db_table
+        expressions = Expressions(
+            table=table,
+            expressions=ExpressionList(
+                IndexExpression(Upper('last_name')),
+                IndexExpression(F('first_name')),
+            ).resolve_expression(compiler.query),
+            compiler=compiler,
+            quote_value=self.editor.quote_value,
+        )
+        expressions.rename_table_references(table, 'other')
+        self.assertIs(expressions.references_table(table), False)
+        self.assertIs(expressions.references_table('other'), True)
+        expected_str = '(UPPER(%s)), %s' % (
+            self.editor.quote_name('last_name'),
+            self.editor.quote_name('first_name'),
+        )
+        self.assertEqual(str(expressions), expected_str)
+
     def test_rename_column_references(self):
         table = Person._meta.db_table
         self.expressions.rename_column_references(table, 'first_name', 'other')
diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py
index 5ae75a477b..11961a1f40 100644
--- a/tests/migrations/test_operations.py
+++ b/tests/migrations/test_operations.py
@@ -2106,6 +2106,25 @@ class OperationTests(OperationTestBase):
         self.assertEqual(definition[1], [])
         self.assertEqual(definition[2], {'model_name': 'Pony', 'name': index_name})
 
+    @skipUnlessDBFeature('supports_expression_indexes')
+    def test_alter_field_with_func_index(self):
+        app_label = 'test_alfuncin'
+        index_name = f'{app_label}_pony_idx'
+        table_name = f'{app_label}_pony'
+        project_state = self.set_up_test_model(
+            app_label,
+            indexes=[models.Index(Abs('pink'), name=index_name)],
+        )
+        operation = migrations.AlterField('Pony', 'pink', models.IntegerField(null=True))
+        new_state = project_state.clone()
+        operation.state_forwards(app_label, new_state)
+        with connection.schema_editor() as editor:
+            operation.database_forwards(app_label, editor, project_state, new_state)
+        self.assertIndexNameExists(table_name, index_name)
+        with connection.schema_editor() as editor:
+            operation.database_backwards(app_label, editor, new_state, project_state)
+        self.assertIndexNameExists(table_name, index_name)
+
     def test_alter_field_with_index(self):
         """
         Test AlterField operation with an index to ensure indexes created via
@@ -2664,6 +2683,26 @@ class OperationTests(OperationTestBase):
             'name': 'covering_pink_constraint_rm',
         })
 
+    def test_alter_field_with_func_unique_constraint(self):
+        app_label = 'test_alfuncuc'
+        constraint_name = f'{app_label}_pony_uq'
+        table_name = f'{app_label}_pony'
+        project_state = self.set_up_test_model(
+            app_label,
+            constraints=[models.UniqueConstraint('pink', 'weight', name=constraint_name)]
+        )
+        operation = migrations.AlterField('Pony', 'pink', models.IntegerField(null=True))
+        new_state = project_state.clone()
+        operation.state_forwards(app_label, new_state)
+        with connection.schema_editor() as editor:
+            operation.database_forwards(app_label, editor, project_state, new_state)
+        if connection.features.supports_expression_indexes:
+            self.assertIndexNameExists(table_name, constraint_name)
+        with connection.schema_editor() as editor:
+            operation.database_backwards(app_label, editor, new_state, project_state)
+        if connection.features.supports_expression_indexes:
+            self.assertIndexNameExists(table_name, constraint_name)
+
     def test_add_func_unique_constraint(self):
         app_label = 'test_adfuncuc'
         constraint_name = f'{app_label}_pony_abs_uq'