]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
fix(c): massage the queries module until it compiles and passes tests fix-456
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 5 Feb 2023 18:34:47 +0000 (19:34 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 6 Feb 2023 21:03:36 +0000 (21:03 +0000)
psycopg/psycopg/_queries.py
psycopg_c/psycopg_c/_psycopg/_queries.pyx

index a386a711904634feec0ec4258928094e962af436..e8bdd8408ec769bf1cc82de7d63f998ca65b9fac 100644 (file)
@@ -9,14 +9,21 @@ This module exports the requested implementation to the rest of the package.
 from typing import Type
 from . import abc
 
-from . import _queries_py
+from ._cmodule import _psycopg
 
 PostgresQuery: Type[abc.PostgresQuery]
 PostgresClientQuery: Type[abc.PostgresQuery]
 
+if _psycopg:
+    PostgresQuery = _psycopg.PostgresQuery
+    PostgresClientQuery = _psycopg.PostgresClientQuery
+    _split_query = _psycopg._split_query
 
-PostgresQuery = _queries_py.PostgresQuery
-PostgresClientQuery = _queries_py.PostgresClientQuery
+else:
+    from . import _queries_py
 
-# Exposed only for testing purposes
-_split_query = _queries_py._split_query
+    PostgresQuery = _queries_py.PostgresQuery
+    PostgresClientQuery = _queries_py.PostgresClientQuery
+
+    # Exposed only for testing purposes
+    _split_query = _queries_py._split_query
index 15a61bf6d931ffebe260e47e7cf0d8c363463d6f..697aa446073df899487819df0dc71460459e8b2e 100644 (file)
@@ -4,6 +4,9 @@ Utility module to manipulate queries
 
 # Copyright (C) 2020 The Psycopg Team
 
+from cpython.ref cimport Py_INCREF
+from cpython.tuple cimport PyTuple_New, PyTuple_SET_ITEM
+
 import re
 from typing import Any, Dict, List, Mapping, Match, NamedTuple, Optional
 from typing import Sequence, Tuple, Union, TYPE_CHECKING
@@ -12,7 +15,7 @@ from functools import lru_cache
 from psycopg import pq
 from psycopg import errors as e
 # from psycopg.sql import Composable
-from psycopg.abc import Buffer, Query, Params
+from psycopg.abc import Buffer
 from psycopg._enums import PyFormat
 from psycopg._encodings import conn_encoding
 
@@ -24,17 +27,18 @@ class QueryPart(NamedTuple):
     item: Union[int, str]
     format: PyFormat
 
+
 cdef class PostgresQuery:
     """
     Helper to convert a Python query and parameters into Postgres format.
     """
 
-    cdef bytes query
-    cdef object params
+    cdef readonly bytes query
+    cdef readonly object params
+    cdef readonly tuple types
+    cdef readonly list formats
     cdef Transformer _tx
-    cdef tuple types
     cdef list _want_formats
-    cdef list formats
     cdef list _parts
     cdef object _encoding
     cdef list _order
@@ -55,7 +59,7 @@ cdef class PostgresQuery:
         self.query = b""
         self._order: Optional[List[str]] = None
 
-    cpdef convert(self, query: Query, vars: Optional[Params]):
+    cpdef convert(self, query, vars):
         """
         Set up the query and parameters to convert.
 
@@ -86,7 +90,7 @@ cdef class PostgresQuery:
 
         self.dump(vars)
 
-    def dump(self, vars: Optional[Params]):
+    cpdef dump(self, vars):
         """
         Process a new set of variables on the query processed by `convert()`.
 
@@ -111,7 +115,7 @@ cdef class PostgresClientQuery(PostgresQuery):
 
     cdef bytes template;
 
-    cpdef convert(self, query: Query, vars: Optional[Params]):
+    cpdef convert(self, query, vars):
         """
         Set up the query and parameters to convert.
 
@@ -135,16 +139,27 @@ cdef class PostgresClientQuery(PostgresQuery):
 
         self.dump(vars)
 
-    def dump(self, vars: Optional[Params]):
+    cpdef dump(self, vars):
         """
         Process a new set of variables on the query processed by `convert()`.
 
         This method updates `params` and `types`.
         """
+        cdef Py_ssize_t nparams
+
         if vars is not None:
             params = _validate_and_reorder_params(self._parts, vars, self._order)
-            self.params = tuple(
-                self._tx.as_literal(p) if p is not None else b"NULL" for p in params)
+            nparams = len(params)
+            self.params = p = PyTuple_New(nparams)
+            for i in range(nparams):
+                item = params[i]
+                if item is not None:
+                    val = self._tx.as_literal(item)
+                else:
+                    val = b"NULL"
+                Py_INCREF(val)
+                PyTuple_SET_ITEM(p, i, val)
+
             self.query = self.template % self.params
         else:
             self.params = None
@@ -241,9 +256,7 @@ cdef _query2pg_client(
     return b"".join(chunks), order, parts
 
 #Returns Sequence[Any]
-cdef _validate_and_reorder_params(
-    parts: List[QueryPart], vars: Params, order: Optional[List[str]]
-):
+cdef _validate_and_reorder_params(parts, vars, order):
     """
     Verify the compatibility between a query and a set of params.
     """
@@ -303,8 +316,8 @@ _re_placeholder = re.compile(
 
 
 #Returns List[QueryPart]
-cdef list _split_query(
-    query: bytes, encoding: str = "ascii", collapse_double_percent: bool = True
+cpdef list _split_query(
+    query, encoding = "ascii", collapse_double_percent = True
 ):
     parts: List[Tuple[bytes, Optional[Match[bytes]]]] = []
     cur = 0