diff --git a/django_spanner/lookups.py b/django_spanner/lookups.py index c2e642d26a..d9a54982f2 100644 --- a/django_spanner/lookups.py +++ b/django_spanner/lookups.py @@ -100,7 +100,10 @@ def iexact(self, compiler, connection): # lhs_sql is the expression/column to use as the regular expression. # Use concat to make the value case-insensitive. lhs_sql = "CONCAT('^(?i)', " + lhs_sql + ", '$')" - rhs_sql = rhs_sql.replace("%%s", "%s") + if not self.rhs_is_direct_value() and not params: + # If rhs is not a direct value and parameter is not present we want + # to have only 1 formatable argument in rhs_sql else we need 2. + rhs_sql = rhs_sql.replace("%%s", "%s") # rhs_sql is REGEXP_CONTAINS(%s, %%s), and lhs_sql is the column name. return rhs_sql % lhs_sql, params diff --git a/tests/unit/django_spanner/test_lookups.py b/tests/unit/django_spanner/test_lookups.py index 1931d255aa..53604691cc 100644 --- a/tests/unit/django_spanner/test_lookups.py +++ b/tests/unit/django_spanner/test_lookups.py @@ -283,3 +283,17 @@ def test_iexact_sql_query_case_insensitive_function_transform(self): + "CONCAT('^(?i)', CAST(UPPER(tests_author.name) AS STRING), '$'))", ) self.assertEqual(params, ()) + + def test_iexact_sql_query_case_insensitive_value_match(self): + + qs1 = Author.objects.filter(name__upper__iexact="abc").values("name") + compiler = SQLCompiler(qs1.query, self.connection, "default") + sql_compiled, params = compiler.as_sql() + + self.assertEqual( + sql_compiled, + "SELECT tests_author.name FROM tests_author WHERE " + + "REGEXP_CONTAINS((UPPER(CONCAT('^(?i)', " + + "CAST(UPPER(tests_author.name) AS STRING), '$'))), %s)", + ) + self.assertEqual(params, ("abc",))