This makes to require a cast on pretty much any placeholder that might
receive a None, which is really asking too much.
Exploratory commit to test what can be done with PG 9.6. The result
shows that in PG 9.6 it's pretty much impossible to use prepared
statements: neither for executemany nor for preparation. Tests failing:
- tests/test_cursor.py::test_executemany_null_first
- tests/test_cursor_async.py::test_executemany_null_first
- tests/test_prepared.py::test_different_types
- tests/test_prepared_async.py::test_different_types
all with: psycopg3.errors.IndeterminateDatatype: could not determine
data type of parameter $x
self, params: Sequence[Any], formats: Sequence[Format]
) -> Tuple[List[Any], Tuple[int, ...]]:
ps: List[Optional[bytes]] = [None] * len(params)
- ts = [self._unknown_oid] * len(params)
+ ts = [INVALID_OID] * len(params)
dumpers = self._row_dumpers
if not dumpers:
<PyObject *>param, NULL)
else:
dumped = None
- oid = self._unknown_oid
+ oid = oids.INVALID_OID
Py_INCREF(dumped)
PyList_SET_ITEM(ps, i, dumped)
def test_none_type_argument(conn, fmt_in):
cur = conn.cursor()
cur.execute("create table none_args (id serial primary key, num integer)")
- cast = "" if conn.pgconn.server_version >= 100000 else "::int"
cur.execute(
- f"insert into none_args (num) values (%s{cast}) returning id",
- (None,),
+ "insert into none_args (num) values (%s) returning id", (None,)
)
assert cur.fetchone()[0]