Repository: googleapis/python-spanner-django

Issue:
django: Greatest/Least Coalesce workaround crashes
```
======================================================================
ERROR: test_coalesce_workaround (db_functions.comparison.test_greatest.GreatestTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/google/api_core/grpc_helpers.py", line 79, in next
    return six.next(self._wrapped)
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/grpc/_channel.py", line 392, in __next__
    return self._next()
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/grpc/_channel.py", line 561, in _next
    raise self
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
	status = StatusCode.INVALID_ARGUMENT
	details = "Unable to infer type for parameter: a1. Provide the parameter type in the parameter binding."
	debug_error_string = "{"created":"@1577641722.833796151","description":"Error received from peer ipv4:172.217.6.202:443","file":"src/core/lib/surface/call.cc","file_line":1055,"grpc_message":"Unable to infer type for parameter: a1. Provide the parameter type in the parameter binding.","grpc_status":3}"
>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tim/code/spanner-orm/spanner/dbapi/cursor.py", line 91, in execute
    self.__handle_DQL(sql, args or None)
  File "/home/tim/code/spanner-orm/spanner/dbapi/cursor.py", line 183, in __handle_DQL
    self.__itr = PeekIterator(self.__res)
  File "/home/tim/code/spanner-orm/spanner/dbapi/cursor.py", line 322, in __init__
    head = next(itr_src)
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/google/cloud/spanner_v1/streamed.py", line 143, in __iter__
    self._consume_next()
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/google/cloud/spanner_v1/streamed.py", line 116, in _consume_next
    response = six.next(self._response_iterator)
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/google/cloud/spanner_v1/snapshot.py", line 45, in _restart_on_unavailable
    for item in iterator:
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/google/api_core/grpc_helpers.py", line 81, in next
    six.raise_from(exceptions.from_grpc_error(exc), exc)
  File "<string>", line 3, in raise_from
google.api_core.exceptions.InvalidArgument: 400 Unable to infer type for parameter: a1. Provide the parameter type in the parameter binding.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/tim/code/spanner-orm/spanner/dbapi/cursor.py", line 99, in execute
    raise ProgrammingError(e.details if hasattr(e, 'details') else e)
spanner.dbapi.exceptions.ProgrammingError: 400 Unable to infer type for parameter: a1. Provide the parameter type in the parameter binding.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tim/code/django/tests/db_functions/comparison/test_greatest.py", line 47, in test_coalesce_workaround
    self.assertEqual(articles.first().last_updated, now)
  File "/home/tim/code/django/django/db/models/query.py", line 653, in first
    for obj in (self if self.ordered else self.order_by('pk'))[:1]:
  File "/home/tim/code/django/django/db/models/query.py", line 274, in __iter__
    self._fetch_all()
  File "/home/tim/code/django/django/db/models/query.py", line 1242, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/home/tim/code/django/django/db/models/query.py", line 55, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/home/tim/code/django/django/db/models/sql/compiler.py", line 1133, in execute_sql
    cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/tim/code/django/django/db/backends/utils.py", line 76, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/tim/code/spanner-orm/spanner/dbapi/cursor.py", line 99, in execute
    raise ProgrammingError(e.details if hasattr(e, 'details') else e)
django.db.utils.ProgrammingError: 400 Unable to infer type for parameter: a1. Provide the parameter type in the parameter binding.

======================================================================
ERROR: test_coalesce_workaround (db_functions.comparison.test_least.LeastTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/google/api_core/grpc_helpers.py", line 79, in next
    return six.next(self._wrapped)
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/grpc/_channel.py", line 392, in __next__
    return self._next()
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/grpc/_channel.py", line 561, in _next
    raise self
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
	status = StatusCode.INVALID_ARGUMENT
	details = "Unable to infer type for parameter: a1. Provide the parameter type in the parameter binding."
	debug_error_string = "{"created":"@1577641846.309472188","description":"Error received from peer ipv4:172.217.6.234:443","file":"src/core/lib/surface/call.cc","file_line":1055,"grpc_message":"Unable to infer type for parameter: a1. Provide the parameter type in the parameter binding.","grpc_status":3}"
>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tim/code/spanner-orm/spanner/dbapi/cursor.py", line 91, in execute
    self.__handle_DQL(sql, args or None)
  File "/home/tim/code/spanner-orm/spanner/dbapi/cursor.py", line 183, in __handle_DQL
    self.__itr = PeekIterator(self.__res)
  File "/home/tim/code/spanner-orm/spanner/dbapi/cursor.py", line 322, in __init__
    head = next(itr_src)
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/google/cloud/spanner_v1/streamed.py", line 143, in __iter__
    self._consume_next()
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/google/cloud/spanner_v1/streamed.py", line 116, in _consume_next
    response = six.next(self._response_iterator)
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/google/cloud/spanner_v1/snapshot.py", line 45, in _restart_on_unavailable
    for item in iterator:
  File "/home/tim/.virtualenvs/django37/lib/python3.7/site-packages/google/api_core/grpc_helpers.py", line 81, in next
    six.raise_from(exceptions.from_grpc_error(exc), exc)
  File "<string>", line 3, in raise_from
google.api_core.exceptions.InvalidArgument: 400 Unable to infer type for parameter: a1. Provide the parameter type in the parameter binding.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/tim/code/spanner-orm/spanner/dbapi/cursor.py", line 99, in execute
    raise ProgrammingError(e.details if hasattr(e, 'details') else e)
spanner.dbapi.exceptions.ProgrammingError: 400 Unable to infer type for parameter: a1. Provide the parameter type in the parameter binding.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tim/code/django/tests/db_functions/comparison/test_least.py", line 49, in test_coalesce_workaround
    self.assertEqual(articles.first().last_updated, now)
  File "/home/tim/code/django/django/db/models/query.py", line 653, in first
    for obj in (self if self.ordered else self.order_by('pk'))[:1]:
  File "/home/tim/code/django/django/db/models/query.py", line 274, in __iter__
    self._fetch_all()
  File "/home/tim/code/django/django/db/models/query.py", line 1242, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/home/tim/code/django/django/db/models/query.py", line 55, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/home/tim/code/django/django/db/models/sql/compiler.py", line 1133, in execute_sql
    cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/tim/code/django/django/db/backends/utils.py", line 76, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/tim/code/django/django/db/utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/tim/code/django/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/tim/code/spanner-orm/spanner/dbapi/cursor.py", line 99, in execute
    raise ProgrammingError(e.details if hasattr(e, 'details') else e)
django.db.utils.ProgrammingError: 400 Unable to infer type for parameter: a1. Provide the parameter type in the parameter binding.
```


Discussion:

Resolving patch:
diff --git a/spanner/django/features.py b/spanner/django/features.py
--- a/spanner/django/features.py
+++ b/spanner/django/features.py
@@ -103,10 +103,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
         # USE_TZ = True: https://github.com/orijtech/spanner-orm/issues/193
         'datetimes.tests.DateTimesTests.test_21432',
         'db_functions.datetime.test_extract_trunc.DateFunctionWithTimeZoneTests.test_trunc_timezone_applied_before_truncation',  # noqa
-        # Unable to infer type for parameter:
-        # https://github.com/orijtech/spanner-orm/issues/185
-        'timezones.tests.LegacyDatabaseTests.test_cursor_execute_returns_naive_datetime',
-        'timezones.tests.NewDatabaseTests.test_cursor_execute_returns_naive_datetime',
         # extract() with timezone not working as expected:
         # https://github.com/orijtech/spanner-orm/issues/191
         'timezones.tests.NewDatabaseTests.test_query_datetimes',
@@ -202,14 +198,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
         # implement SchemaEditor.quote_value():
         # https://github.com/orijtech/spanner-orm/issues/227
         'indexes.tests.PartialIndexConditionIgnoredTests.test_condition_ignored',
-        # Cast from Python date or datetime crashes:
-        # https://github.com/orijtech/spanner-orm/issues/257
-        'db_functions.comparison.test_cast.CastTests.test_cast_from_python_to_date',
-        'db_functions.comparison.test_cast.CastTests.test_cast_from_python_to_datetime',
-        # Greatest/Least Coalesce workaround crashes:
-        # https://github.com/orijtech/spanner-orm/issues/259
-        'db_functions.comparison.test_greatest.GreatestTests.test_coalesce_workaround',
-        'db_functions.comparison.test_least.LeastTests.test_coalesce_workaround',
         # Cast to CharField with max_length doesn't work:
         # https://github.com/orijtech/spanner-orm/issues/258
         'db_functions.comparison.test_cast.CastTests.test_cast_to_char_field_with_max_length',


Test patch: