__slots__ = """
params types formats
- _tx _unknown_oid _parts query _encoding _order
+ _tx _want_formats _parts query _encoding _order
""".split()
def __init__(self, transformer: "Transformer"):
self.params: Optional[List[Optional[bytes]]] = None
# these are tuples so they can be used as keys e.g. in prepared stmts
self.types: Tuple[int, ...] = ()
- self.formats: Optional[List[Format]] = None
+
+ # The format requested by the user and the ones to really pass Postgres
+ self._want_formats: Optional[List[Format]] = None
+ self.formats: Optional[Sequence[Format]] = None
self._parts: List[QueryPart]
self.query = b""
query = query.as_bytes(self._tx)
if vars is not None:
- self.query, self.formats, self._order, self._parts = _query2pg(
- query, self._encoding
- )
+ (
+ self.query,
+ self._want_formats,
+ self._order,
+ self._parts,
+ ) = _query2pg(query, self._encoding)
else:
if isinstance(query, str):
query = query.encode(self._encoding)
self.query = query
- self.formats = self._order = None
+ self._want_formats = self._order = None
self.dump(vars)
def dump(self, vars: Optional[Params]) -> None:
"""
- Process a new set of variables on the same query as before.
+ Process a new set of variables on the query processed by `convert()`.
This method updates `params` and `types`.
"""
params = _validate_and_reorder_params(
self._parts, vars, self._order
)
- assert self.formats is not None
- self.params, self.types = self._tx.dump_sequence(
- params, self.formats
+ assert self._want_formats is not None
+ self.params, self.types, self.formats = self._tx.dump_sequence(
+ params, self._want_formats
)
else:
self.params = None
self.types = ()
+ self.formats = None
@lru_cache()
def dump_sequence(
self, params: Sequence[Any], formats: Sequence[Format]
- ) -> Tuple[List[Any], Tuple[int, ...]]:
+ ) -> Tuple[List[Any], Tuple[int, ...], Sequence[Format]]:
ps: List[Optional[bytes]] = [None] * len(params)
ts = [INVALID_OID] * len(params)
ps[i] = dumper.dump(param)
ts[i] = dumper.oid
- return ps, tuple(ts)
+ return ps, tuple(ts), formats
def get_dumper(self, obj: Any, format: Format) -> "Dumper":
# Fast path: return a Dumper class already instantiated from the same type
def dump_sequence(
self, params: Sequence[Any], formats: Sequence[Format]
- ) -> Tuple[List[Any], Tuple[int, ...]]:
+ ) -> Tuple[List[Any], Tuple[int, ...], Sequence[Format]]:
...
def get_dumper(self, obj: Any, format: Format) -> "Dumper":
) -> None: ...
def dump_sequence(
self, params: Sequence[Any], formats: Sequence[Format]
- ) -> Tuple[List[Any], Tuple[int, ...]]: ...
+ ) -> Tuple[List[Any], Tuple[int, ...], Sequence[Format]]: ...
def get_dumper(self, obj: Any, format: Format) -> Dumper: ...
def load_rows(self, row0: int, row1: int) -> List[Tuple[Any, ...]]: ...
def load_row(self, row: int) -> Optional[Tuple[Any, ...]]: ...