добавленные пикодата опции перетирают пользовательские опции
в рамках #64 (closed) были введены дополнительные опции для соединений (см STMT_INVALIDATION_OPTION)
несмотря на то, что опция добавляется в server_settings, расширяя, а не заменяя -- тут затесался баг. дело в том, что asyncpg при конфликте опций в DSN и в connect_kwargs, разрешает их в сторону connect_kwargs. таким образом, если в DSN указать options, то они затрутся (т.к. общий ключ option)
в рамках починки мы также не можем перенести специальные опции пикодата в DSN, т.к. если пользователь задаст опции в connect_kwargs -- уже они перетрут опции пикодата
таким образом, нам нужно учитывать DSN на этапе обогащения опций. необходимо проверять, есть ли в DSN опции и если есть -- добавлять их тоже, при этом оставить опции connect_kwargs в приоритете
репро:
import asyncio
import os
from picopyn.asynchronous.connection import Connection
BASE = os.environ.get("PICODATA_TEST_CONN", "postgresql://admin:T0psecret@localhost:5433")
DSN = f"{BASE}?options=sql_vdbe_opcode_max%3D1"
QUERY = "SELECT 1"
async def main():
print(f"option asked for in DSN {DSN}")
conn = Connection(DSN)
try:
await conn.connect()
except RuntimeError as e:
print(f"cannot connect: {e}")
return
try:
rows = await conn.fetch(QUERY)
except Exception as e:
text = str(e).lower()
if "vdbe" in text or "opcode" in text:
print(f"query `{QUERY}` failed on the limit: {e}")
print("the option from DSN reached Picodata")
return
print(f"query failed for an unrelated reason, so possibly the DSN option never Picodata: {e!r}")
return
else:
print(f"query succeeded, returned {len(rows)} row(s)")
print("the DSN option never reached Picodata")
return
finally:
await conn.close()
asyncio.run(main())