]
PQsendQueryPrepared.restype = c_int
-# TODO: PQsendDescribePrepared PQsendDescribePortal
+PQsendDescribePrepared = pq.PQsendDescribePrepared
+PQsendDescribePrepared.argtypes = [PGconn_ptr, c_char_p]
+PQsendDescribePrepared.restype = c_int
+
+PQsendDescribePortal = pq.PQsendDescribePortal
+PQsendDescribePortal.argtypes = [PGconn_ptr, c_char_p]
+PQsendDescribePortal.restype = c_int
PQgetResult = pq.PQgetResult
PQgetResult.argtypes = [PGconn_ptr]
def PQunescapeBytea(arg1: bytes, arg2: pointer[c_ulong]) -> pointer[c_ubyte]: ...
def PQsendQuery(arg1: Optional[PGconn_struct], arg2: bytes) -> int: ...
def PQsendQueryParams(arg1: Optional[PGconn_struct], arg2: bytes, arg3: int, arg4: pointer[c_uint], arg5: pointer[c_char_p], arg6: pointer[c_int], arg7: pointer[c_int], arg8: int) -> int: ...
+def PQsendDescribePrepared(arg1: Optional[PGconn_struct], arg2: bytes) -> int: ...
+def PQsendDescribePortal(arg1: Optional[PGconn_struct], arg2: bytes) -> int: ...
def PQgetResult(arg1: Optional[PGconn_struct]) -> PGresult_struct: ...
def PQconsumeInput(arg1: Optional[PGconn_struct]) -> int: ...
def PQisBusy(arg1: Optional[PGconn_struct]) -> int: ...
raise MemoryError("couldn't allocate PGresult")
return PGresult(rv)
+ def send_describe_prepared(self, name: bytes) -> None:
+ if not isinstance(name, bytes):
+ raise TypeError(f"bytes expected, got {type(name)} instead")
+ self._ensure_pgconn()
+ if not impl.PQsendDescribePrepared(self.pgconn_ptr, name):
+ raise PQerror(
+ f"sending describe prepared failed: {error_message(self)}"
+ )
+
def describe_portal(self, name: bytes) -> "PGresult":
if not isinstance(name, bytes):
raise TypeError(f"'name' must be bytes, got {type(name)} instead")
raise MemoryError("couldn't allocate PGresult")
return PGresult(rv)
+ def send_describe_portal(self, name: bytes) -> None:
+ if not isinstance(name, bytes):
+ raise TypeError(f"bytes expected, got {type(name)} instead")
+ self._ensure_pgconn()
+ if not impl.PQsendDescribePortal(self.pgconn_ptr, name):
+ raise PQerror(
+ f"sending describe portal failed: {error_message(self)}"
+ )
+
def get_result(self) -> Optional["PGresult"]:
rv = impl.PQgetResult(self.pgconn_ptr)
return PGresult(rv) if rv else None
raise MemoryError("couldn't allocate PGresult")
return PGresult._from_ptr(rv)
+ def send_describe_prepared(self, const char *name) -> None:
+ _ensure_pgconn(self)
+ cdef int rv = libpq.PQsendDescribePrepared(self.pgconn_ptr, name)
+ if not rv:
+ raise PQerror(
+ f"sending describe prepared failed: {error_message(self)}"
+ )
+
def describe_portal(self, const char *name) -> PGresult:
_ensure_pgconn(self)
cdef libpq.PGresult *rv = libpq.PQdescribePortal(self.pgconn_ptr, name)
raise MemoryError("couldn't allocate PGresult")
return PGresult._from_ptr(rv)
+ def send_describe_portal(self, const char *name) -> None:
+ _ensure_pgconn(self)
+ cdef int rv = libpq.PQsendDescribePortal(self.pgconn_ptr, name)
+ if not rv:
+ raise PQerror(
+ f"sending describe prepared failed: {error_message(self)}"
+ )
+
def get_result(self) -> Optional["PGresult"]:
cdef libpq.PGresult *pgresult = libpq.PQgetResult(self.pgconn_ptr)
if pgresult is NULL:
(res,) = execute_wait(pgconn)
assert res.status == pq.ExecStatus.TUPLES_OK
assert res.get_value(0, 0) == out
+
+
+def test_send_describe_prepared(pgconn):
+ pgconn.send_prepare(b"prep", b"select $1::int + $2::int as fld")
+ (res,) = execute_wait(pgconn)
+ assert res.status == pq.ExecStatus.COMMAND_OK, res.error_message
+
+ pgconn.send_describe_prepared(b"prep")
+ (res,) = execute_wait(pgconn)
+ assert res.nfields == 1
+ assert res.ntuples == 0
+ assert res.fname(0) == b"fld"
+ assert res.ftype(0) == 23
+
+ pgconn.finish()
+ with pytest.raises(psycopg3.OperationalError):
+ pgconn.send_describe_prepared(b"prep")
+
+
+def test_send_describe_portal(pgconn):
+ res = pgconn.exec_(
+ b"""
+ begin;
+ declare cur cursor for select * from generate_series(1,10) foo;
+ """
+ )
+ assert res.status == pq.ExecStatus.COMMAND_OK, res.error_message
+
+ pgconn.send_describe_portal(b"cur")
+ (res,) = execute_wait(pgconn)
+ assert res.status == pq.ExecStatus.COMMAND_OK, res.error_message
+ assert res.nfields == 1
+ assert res.fname(0) == b"foo"
+
+ pgconn.finish()
+ with pytest.raises(psycopg3.OperationalError):
+ pgconn.send_describe_portal(b"cur")