sqlspec 0.47.0__cp314-cp314-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (621) hide show
  1. f68e0789eb443ecb1c2c__mypyc.cp314-win_amd64.pyd +0 -0
  2. sqlspec/__init__.py +167 -0
  3. sqlspec/__main__.py +12 -0
  4. sqlspec/__metadata__.py +14 -0
  5. sqlspec/_typing.py +714 -0
  6. sqlspec/adapters/__init__.py +0 -0
  7. sqlspec/adapters/adbc/__init__.py +13 -0
  8. sqlspec/adapters/adbc/_typing.py +106 -0
  9. sqlspec/adapters/adbc/adk/__init__.py +5 -0
  10. sqlspec/adapters/adbc/adk/store.py +1280 -0
  11. sqlspec/adapters/adbc/config.py +378 -0
  12. sqlspec/adapters/adbc/core.cp314-win_amd64.pyd +0 -0
  13. sqlspec/adapters/adbc/core.py +922 -0
  14. sqlspec/adapters/adbc/data_dictionary.py +339 -0
  15. sqlspec/adapters/adbc/driver.py +534 -0
  16. sqlspec/adapters/adbc/events/__init__.py +5 -0
  17. sqlspec/adapters/adbc/events/store.py +285 -0
  18. sqlspec/adapters/adbc/litestar/__init__.py +5 -0
  19. sqlspec/adapters/adbc/litestar/store.py +534 -0
  20. sqlspec/adapters/adbc/type_converter.cp314-win_amd64.pyd +0 -0
  21. sqlspec/adapters/adbc/type_converter.py +142 -0
  22. sqlspec/adapters/aiomysql/__init__.py +21 -0
  23. sqlspec/adapters/aiomysql/_typing.py +137 -0
  24. sqlspec/adapters/aiomysql/adk/__init__.py +5 -0
  25. sqlspec/adapters/aiomysql/adk/store.py +678 -0
  26. sqlspec/adapters/aiomysql/config.py +305 -0
  27. sqlspec/adapters/aiomysql/core.cp314-win_amd64.pyd +0 -0
  28. sqlspec/adapters/aiomysql/core.py +536 -0
  29. sqlspec/adapters/aiomysql/data_dictionary.py +121 -0
  30. sqlspec/adapters/aiomysql/driver.py +386 -0
  31. sqlspec/adapters/aiomysql/events/__init__.py +5 -0
  32. sqlspec/adapters/aiomysql/events/store.py +104 -0
  33. sqlspec/adapters/aiomysql/litestar/__init__.py +5 -0
  34. sqlspec/adapters/aiomysql/litestar/store.py +314 -0
  35. sqlspec/adapters/aiosqlite/__init__.py +26 -0
  36. sqlspec/adapters/aiosqlite/_typing.py +109 -0
  37. sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
  38. sqlspec/adapters/aiosqlite/adk/store.py +829 -0
  39. sqlspec/adapters/aiosqlite/config.py +315 -0
  40. sqlspec/adapters/aiosqlite/core.cp314-win_amd64.pyd +0 -0
  41. sqlspec/adapters/aiosqlite/core.py +315 -0
  42. sqlspec/adapters/aiosqlite/data_dictionary.py +202 -0
  43. sqlspec/adapters/aiosqlite/driver.py +311 -0
  44. sqlspec/adapters/aiosqlite/events/__init__.py +5 -0
  45. sqlspec/adapters/aiosqlite/events/store.py +20 -0
  46. sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
  47. sqlspec/adapters/aiosqlite/litestar/store.py +279 -0
  48. sqlspec/adapters/aiosqlite/pool.cp314-win_amd64.pyd +0 -0
  49. sqlspec/adapters/aiosqlite/pool.py +734 -0
  50. sqlspec/adapters/asyncmy/__init__.py +21 -0
  51. sqlspec/adapters/asyncmy/_typing.py +113 -0
  52. sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
  53. sqlspec/adapters/asyncmy/adk/store.py +644 -0
  54. sqlspec/adapters/asyncmy/config.py +307 -0
  55. sqlspec/adapters/asyncmy/core.cp314-win_amd64.pyd +0 -0
  56. sqlspec/adapters/asyncmy/core.py +538 -0
  57. sqlspec/adapters/asyncmy/data_dictionary.py +122 -0
  58. sqlspec/adapters/asyncmy/driver.py +391 -0
  59. sqlspec/adapters/asyncmy/events/__init__.py +5 -0
  60. sqlspec/adapters/asyncmy/events/store.py +104 -0
  61. sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
  62. sqlspec/adapters/asyncmy/litestar/store.py +296 -0
  63. sqlspec/adapters/asyncpg/__init__.py +26 -0
  64. sqlspec/adapters/asyncpg/_typing.py +103 -0
  65. sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
  66. sqlspec/adapters/asyncpg/adk/store.py +483 -0
  67. sqlspec/adapters/asyncpg/config.py +575 -0
  68. sqlspec/adapters/asyncpg/core.cp314-win_amd64.pyd +0 -0
  69. sqlspec/adapters/asyncpg/core.py +480 -0
  70. sqlspec/adapters/asyncpg/data_dictionary.py +157 -0
  71. sqlspec/adapters/asyncpg/driver.py +487 -0
  72. sqlspec/adapters/asyncpg/events/__init__.py +6 -0
  73. sqlspec/adapters/asyncpg/events/_hub.py +181 -0
  74. sqlspec/adapters/asyncpg/events/backend.py +210 -0
  75. sqlspec/adapters/asyncpg/events/store.py +40 -0
  76. sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
  77. sqlspec/adapters/asyncpg/litestar/store.py +251 -0
  78. sqlspec/adapters/bigquery/__init__.py +15 -0
  79. sqlspec/adapters/bigquery/_typing.py +108 -0
  80. sqlspec/adapters/bigquery/config.py +362 -0
  81. sqlspec/adapters/bigquery/core.cp314-win_amd64.pyd +0 -0
  82. sqlspec/adapters/bigquery/core.py +768 -0
  83. sqlspec/adapters/bigquery/data_dictionary.py +120 -0
  84. sqlspec/adapters/bigquery/driver.py +542 -0
  85. sqlspec/adapters/bigquery/events/__init__.py +5 -0
  86. sqlspec/adapters/bigquery/events/store.py +139 -0
  87. sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
  88. sqlspec/adapters/bigquery/litestar/store.py +325 -0
  89. sqlspec/adapters/bigquery/type_converter.cp314-win_amd64.pyd +0 -0
  90. sqlspec/adapters/bigquery/type_converter.py +107 -0
  91. sqlspec/adapters/cockroach_asyncpg/__init__.py +26 -0
  92. sqlspec/adapters/cockroach_asyncpg/_typing.py +73 -0
  93. sqlspec/adapters/cockroach_asyncpg/adk/__init__.py +3 -0
  94. sqlspec/adapters/cockroach_asyncpg/adk/store.py +465 -0
  95. sqlspec/adapters/cockroach_asyncpg/config.py +248 -0
  96. sqlspec/adapters/cockroach_asyncpg/core.cp314-win_amd64.pyd +0 -0
  97. sqlspec/adapters/cockroach_asyncpg/core.py +55 -0
  98. sqlspec/adapters/cockroach_asyncpg/data_dictionary.py +110 -0
  99. sqlspec/adapters/cockroach_asyncpg/driver.py +142 -0
  100. sqlspec/adapters/cockroach_asyncpg/events/__init__.py +3 -0
  101. sqlspec/adapters/cockroach_asyncpg/events/store.py +20 -0
  102. sqlspec/adapters/cockroach_asyncpg/litestar/__init__.py +3 -0
  103. sqlspec/adapters/cockroach_asyncpg/litestar/store.py +142 -0
  104. sqlspec/adapters/cockroach_psycopg/__init__.py +39 -0
  105. sqlspec/adapters/cockroach_psycopg/_typing.py +137 -0
  106. sqlspec/adapters/cockroach_psycopg/adk/__init__.py +13 -0
  107. sqlspec/adapters/cockroach_psycopg/adk/store.py +1039 -0
  108. sqlspec/adapters/cockroach_psycopg/config.py +511 -0
  109. sqlspec/adapters/cockroach_psycopg/core.cp314-win_amd64.pyd +0 -0
  110. sqlspec/adapters/cockroach_psycopg/core.py +63 -0
  111. sqlspec/adapters/cockroach_psycopg/data_dictionary.py +220 -0
  112. sqlspec/adapters/cockroach_psycopg/driver.py +273 -0
  113. sqlspec/adapters/cockroach_psycopg/events/__init__.py +6 -0
  114. sqlspec/adapters/cockroach_psycopg/events/store.py +34 -0
  115. sqlspec/adapters/cockroach_psycopg/litestar/__init__.py +3 -0
  116. sqlspec/adapters/cockroach_psycopg/litestar/store.py +327 -0
  117. sqlspec/adapters/duckdb/__init__.py +29 -0
  118. sqlspec/adapters/duckdb/_typing.py +104 -0
  119. sqlspec/adapters/duckdb/adk/__init__.py +14 -0
  120. sqlspec/adapters/duckdb/adk/store.py +935 -0
  121. sqlspec/adapters/duckdb/config.py +386 -0
  122. sqlspec/adapters/duckdb/core.cp314-win_amd64.pyd +0 -0
  123. sqlspec/adapters/duckdb/core.py +332 -0
  124. sqlspec/adapters/duckdb/data_dictionary.py +140 -0
  125. sqlspec/adapters/duckdb/driver.py +426 -0
  126. sqlspec/adapters/duckdb/events/__init__.py +5 -0
  127. sqlspec/adapters/duckdb/events/store.py +57 -0
  128. sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
  129. sqlspec/adapters/duckdb/litestar/store.py +330 -0
  130. sqlspec/adapters/duckdb/pool.cp314-win_amd64.pyd +0 -0
  131. sqlspec/adapters/duckdb/pool.py +350 -0
  132. sqlspec/adapters/duckdb/type_converter.cp314-win_amd64.pyd +0 -0
  133. sqlspec/adapters/duckdb/type_converter.py +118 -0
  134. sqlspec/adapters/mysqlconnector/__init__.py +39 -0
  135. sqlspec/adapters/mysqlconnector/_typing.py +186 -0
  136. sqlspec/adapters/mysqlconnector/adk/__init__.py +15 -0
  137. sqlspec/adapters/mysqlconnector/adk/store.py +1183 -0
  138. sqlspec/adapters/mysqlconnector/config.py +421 -0
  139. sqlspec/adapters/mysqlconnector/core.cp314-win_amd64.pyd +0 -0
  140. sqlspec/adapters/mysqlconnector/core.py +472 -0
  141. sqlspec/adapters/mysqlconnector/data_dictionary.py +230 -0
  142. sqlspec/adapters/mysqlconnector/driver.py +516 -0
  143. sqlspec/adapters/mysqlconnector/events/__init__.py +8 -0
  144. sqlspec/adapters/mysqlconnector/events/store.py +98 -0
  145. sqlspec/adapters/mysqlconnector/litestar/__init__.py +5 -0
  146. sqlspec/adapters/mysqlconnector/litestar/store.py +426 -0
  147. sqlspec/adapters/oracledb/__init__.py +39 -0
  148. sqlspec/adapters/oracledb/_json_handlers.cp314-win_amd64.pyd +0 -0
  149. sqlspec/adapters/oracledb/_json_handlers.py +196 -0
  150. sqlspec/adapters/oracledb/_param_types.cp314-win_amd64.pyd +0 -0
  151. sqlspec/adapters/oracledb/_param_types.py +46 -0
  152. sqlspec/adapters/oracledb/_typing.py +258 -0
  153. sqlspec/adapters/oracledb/_uuid_handlers.cp314-win_amd64.pyd +0 -0
  154. sqlspec/adapters/oracledb/_uuid_handlers.py +163 -0
  155. sqlspec/adapters/oracledb/_vector_handlers.cp314-win_amd64.pyd +0 -0
  156. sqlspec/adapters/oracledb/_vector_handlers.py +228 -0
  157. sqlspec/adapters/oracledb/adk/__init__.py +21 -0
  158. sqlspec/adapters/oracledb/adk/store.py +2453 -0
  159. sqlspec/adapters/oracledb/config.py +575 -0
  160. sqlspec/adapters/oracledb/core.cp314-win_amd64.pyd +0 -0
  161. sqlspec/adapters/oracledb/core.py +820 -0
  162. sqlspec/adapters/oracledb/data_dictionary.py +404 -0
  163. sqlspec/adapters/oracledb/driver.py +1277 -0
  164. sqlspec/adapters/oracledb/events/__init__.py +16 -0
  165. sqlspec/adapters/oracledb/events/_hub.py +345 -0
  166. sqlspec/adapters/oracledb/events/backend.py +300 -0
  167. sqlspec/adapters/oracledb/events/store.py +420 -0
  168. sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
  169. sqlspec/adapters/oracledb/litestar/store.py +781 -0
  170. sqlspec/adapters/oracledb/migrations.py +539 -0
  171. sqlspec/adapters/oracledb/type_converter.cp314-win_amd64.pyd +0 -0
  172. sqlspec/adapters/oracledb/type_converter.py +211 -0
  173. sqlspec/adapters/psqlpy/__init__.py +18 -0
  174. sqlspec/adapters/psqlpy/_typing.py +121 -0
  175. sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
  176. sqlspec/adapters/psqlpy/adk/store.py +591 -0
  177. sqlspec/adapters/psqlpy/config.py +376 -0
  178. sqlspec/adapters/psqlpy/core.cp314-win_amd64.pyd +0 -0
  179. sqlspec/adapters/psqlpy/core.py +694 -0
  180. sqlspec/adapters/psqlpy/data_dictionary.py +121 -0
  181. sqlspec/adapters/psqlpy/driver.py +411 -0
  182. sqlspec/adapters/psqlpy/events/__init__.py +6 -0
  183. sqlspec/adapters/psqlpy/events/_hub.py +204 -0
  184. sqlspec/adapters/psqlpy/events/backend.py +210 -0
  185. sqlspec/adapters/psqlpy/events/store.py +20 -0
  186. sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
  187. sqlspec/adapters/psqlpy/litestar/store.py +270 -0
  188. sqlspec/adapters/psqlpy/type_converter.cp314-win_amd64.pyd +0 -0
  189. sqlspec/adapters/psqlpy/type_converter.py +113 -0
  190. sqlspec/adapters/psycopg/__init__.py +38 -0
  191. sqlspec/adapters/psycopg/_typing.py +218 -0
  192. sqlspec/adapters/psycopg/adk/__init__.py +10 -0
  193. sqlspec/adapters/psycopg/adk/store.py +1106 -0
  194. sqlspec/adapters/psycopg/config.py +695 -0
  195. sqlspec/adapters/psycopg/core.cp314-win_amd64.pyd +0 -0
  196. sqlspec/adapters/psycopg/core.py +520 -0
  197. sqlspec/adapters/psycopg/data_dictionary.py +278 -0
  198. sqlspec/adapters/psycopg/driver.py +1033 -0
  199. sqlspec/adapters/psycopg/events/__init__.py +20 -0
  200. sqlspec/adapters/psycopg/events/_hub.py +388 -0
  201. sqlspec/adapters/psycopg/events/backend.py +398 -0
  202. sqlspec/adapters/psycopg/events/store.py +42 -0
  203. sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
  204. sqlspec/adapters/psycopg/litestar/store.py +554 -0
  205. sqlspec/adapters/psycopg/type_converter.cp314-win_amd64.pyd +0 -0
  206. sqlspec/adapters/psycopg/type_converter.py +93 -0
  207. sqlspec/adapters/pymysql/__init__.py +21 -0
  208. sqlspec/adapters/pymysql/_typing.py +92 -0
  209. sqlspec/adapters/pymysql/adk/__init__.py +5 -0
  210. sqlspec/adapters/pymysql/adk/store.py +657 -0
  211. sqlspec/adapters/pymysql/config.py +176 -0
  212. sqlspec/adapters/pymysql/core.cp314-win_amd64.pyd +0 -0
  213. sqlspec/adapters/pymysql/core.py +469 -0
  214. sqlspec/adapters/pymysql/data_dictionary.py +120 -0
  215. sqlspec/adapters/pymysql/driver.py +271 -0
  216. sqlspec/adapters/pymysql/events/__init__.py +5 -0
  217. sqlspec/adapters/pymysql/events/store.py +50 -0
  218. sqlspec/adapters/pymysql/litestar/__init__.py +5 -0
  219. sqlspec/adapters/pymysql/litestar/store.py +232 -0
  220. sqlspec/adapters/pymysql/pool.cp314-win_amd64.pyd +0 -0
  221. sqlspec/adapters/pymysql/pool.py +184 -0
  222. sqlspec/adapters/spanner/__init__.py +33 -0
  223. sqlspec/adapters/spanner/_typing.py +102 -0
  224. sqlspec/adapters/spanner/adk/__init__.py +5 -0
  225. sqlspec/adapters/spanner/adk/store.py +758 -0
  226. sqlspec/adapters/spanner/config.py +355 -0
  227. sqlspec/adapters/spanner/core.cp314-win_amd64.pyd +0 -0
  228. sqlspec/adapters/spanner/core.py +263 -0
  229. sqlspec/adapters/spanner/data_dictionary.py +120 -0
  230. sqlspec/adapters/spanner/driver.py +407 -0
  231. sqlspec/adapters/spanner/events/__init__.py +5 -0
  232. sqlspec/adapters/spanner/events/store.py +187 -0
  233. sqlspec/adapters/spanner/litestar/__init__.py +5 -0
  234. sqlspec/adapters/spanner/litestar/store.py +291 -0
  235. sqlspec/adapters/spanner/type_converter.cp314-win_amd64.pyd +0 -0
  236. sqlspec/adapters/spanner/type_converter.py +342 -0
  237. sqlspec/adapters/sqlite/__init__.py +19 -0
  238. sqlspec/adapters/sqlite/_typing.py +123 -0
  239. sqlspec/adapters/sqlite/adk/__init__.py +5 -0
  240. sqlspec/adapters/sqlite/adk/store.py +992 -0
  241. sqlspec/adapters/sqlite/config.py +240 -0
  242. sqlspec/adapters/sqlite/core.cp314-win_amd64.pyd +0 -0
  243. sqlspec/adapters/sqlite/core.py +357 -0
  244. sqlspec/adapters/sqlite/data_dictionary.py +198 -0
  245. sqlspec/adapters/sqlite/driver.py +527 -0
  246. sqlspec/adapters/sqlite/events/__init__.py +5 -0
  247. sqlspec/adapters/sqlite/events/store.py +20 -0
  248. sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
  249. sqlspec/adapters/sqlite/litestar/store.py +316 -0
  250. sqlspec/adapters/sqlite/pool.cp314-win_amd64.pyd +0 -0
  251. sqlspec/adapters/sqlite/pool.py +237 -0
  252. sqlspec/adapters/sqlite/type_converter.cp314-win_amd64.pyd +0 -0
  253. sqlspec/adapters/sqlite/type_converter.py +114 -0
  254. sqlspec/base.py +832 -0
  255. sqlspec/builder/__init__.py +181 -0
  256. sqlspec/builder/_base.cp314-win_amd64.pyd +0 -0
  257. sqlspec/builder/_base.py +1071 -0
  258. sqlspec/builder/_column.cp314-win_amd64.pyd +0 -0
  259. sqlspec/builder/_column.py +521 -0
  260. sqlspec/builder/_ddl.cp314-win_amd64.pyd +0 -0
  261. sqlspec/builder/_ddl.py +1691 -0
  262. sqlspec/builder/_delete.cp314-win_amd64.pyd +0 -0
  263. sqlspec/builder/_delete.py +95 -0
  264. sqlspec/builder/_dml.cp314-win_amd64.pyd +0 -0
  265. sqlspec/builder/_dml.py +386 -0
  266. sqlspec/builder/_explain.cp314-win_amd64.pyd +0 -0
  267. sqlspec/builder/_explain.py +579 -0
  268. sqlspec/builder/_expression_wrappers.cp314-win_amd64.pyd +0 -0
  269. sqlspec/builder/_expression_wrappers.py +46 -0
  270. sqlspec/builder/_factory.cp314-win_amd64.pyd +0 -0
  271. sqlspec/builder/_factory.py +1884 -0
  272. sqlspec/builder/_insert.cp314-win_amd64.pyd +0 -0
  273. sqlspec/builder/_insert.py +405 -0
  274. sqlspec/builder/_join.cp314-win_amd64.pyd +0 -0
  275. sqlspec/builder/_join.py +489 -0
  276. sqlspec/builder/_merge.cp314-win_amd64.pyd +0 -0
  277. sqlspec/builder/_merge.py +823 -0
  278. sqlspec/builder/_parsing_utils.cp314-win_amd64.pyd +0 -0
  279. sqlspec/builder/_parsing_utils.py +295 -0
  280. sqlspec/builder/_select.cp314-win_amd64.pyd +0 -0
  281. sqlspec/builder/_select.py +1666 -0
  282. sqlspec/builder/_temporal.cp314-win_amd64.pyd +0 -0
  283. sqlspec/builder/_temporal.py +167 -0
  284. sqlspec/builder/_update.cp314-win_amd64.pyd +0 -0
  285. sqlspec/builder/_update.py +173 -0
  286. sqlspec/builder/_vector_distance.cp314-win_amd64.pyd +0 -0
  287. sqlspec/builder/_vector_distance.py +330 -0
  288. sqlspec/cli.py +1095 -0
  289. sqlspec/config.py +2383 -0
  290. sqlspec/core/__init__.py +372 -0
  291. sqlspec/core/_correlation.cp314-win_amd64.pyd +0 -0
  292. sqlspec/core/_correlation.py +176 -0
  293. sqlspec/core/_pagination.py +42 -0
  294. sqlspec/core/_pool.cp314-win_amd64.pyd +0 -0
  295. sqlspec/core/_pool.py +76 -0
  296. sqlspec/core/cache.cp314-win_amd64.pyd +0 -0
  297. sqlspec/core/cache.py +1085 -0
  298. sqlspec/core/compiler.cp314-win_amd64.pyd +0 -0
  299. sqlspec/core/compiler.py +1090 -0
  300. sqlspec/core/config_runtime.cp314-win_amd64.pyd +0 -0
  301. sqlspec/core/config_runtime.py +174 -0
  302. sqlspec/core/explain.cp314-win_amd64.pyd +0 -0
  303. sqlspec/core/explain.py +275 -0
  304. sqlspec/core/filters.cp314-win_amd64.pyd +0 -0
  305. sqlspec/core/filters.py +969 -0
  306. sqlspec/core/hashing.cp314-win_amd64.pyd +0 -0
  307. sqlspec/core/hashing.py +266 -0
  308. sqlspec/core/metrics.cp314-win_amd64.pyd +0 -0
  309. sqlspec/core/metrics.py +83 -0
  310. sqlspec/core/parameters/__init__.py +72 -0
  311. sqlspec/core/parameters/_alignment.cp314-win_amd64.pyd +0 -0
  312. sqlspec/core/parameters/_alignment.py +283 -0
  313. sqlspec/core/parameters/_converter.cp314-win_amd64.pyd +0 -0
  314. sqlspec/core/parameters/_converter.py +554 -0
  315. sqlspec/core/parameters/_processor.cp314-win_amd64.pyd +0 -0
  316. sqlspec/core/parameters/_processor.py +1182 -0
  317. sqlspec/core/parameters/_registry.cp314-win_amd64.pyd +0 -0
  318. sqlspec/core/parameters/_registry.py +206 -0
  319. sqlspec/core/parameters/_transformers.cp314-win_amd64.pyd +0 -0
  320. sqlspec/core/parameters/_transformers.py +324 -0
  321. sqlspec/core/parameters/_types.cp314-win_amd64.pyd +0 -0
  322. sqlspec/core/parameters/_types.py +536 -0
  323. sqlspec/core/parameters/_validator.cp314-win_amd64.pyd +0 -0
  324. sqlspec/core/parameters/_validator.py +171 -0
  325. sqlspec/core/pipeline.cp314-win_amd64.pyd +0 -0
  326. sqlspec/core/pipeline.py +333 -0
  327. sqlspec/core/query_modifiers.cp314-win_amd64.pyd +0 -0
  328. sqlspec/core/query_modifiers.py +508 -0
  329. sqlspec/core/result/__init__.py +25 -0
  330. sqlspec/core/result/_base.cp314-win_amd64.pyd +0 -0
  331. sqlspec/core/result/_base.py +1232 -0
  332. sqlspec/core/result/_io.cp314-win_amd64.pyd +0 -0
  333. sqlspec/core/result/_io.py +28 -0
  334. sqlspec/core/splitter.cp314-win_amd64.pyd +0 -0
  335. sqlspec/core/splitter.py +1021 -0
  336. sqlspec/core/sqlcommenter.cp314-win_amd64.pyd +0 -0
  337. sqlspec/core/sqlcommenter.py +249 -0
  338. sqlspec/core/stack.cp314-win_amd64.pyd +0 -0
  339. sqlspec/core/stack.py +163 -0
  340. sqlspec/core/statement.cp314-win_amd64.pyd +0 -0
  341. sqlspec/core/statement.py +1865 -0
  342. sqlspec/core/type_converter.cp314-win_amd64.pyd +0 -0
  343. sqlspec/core/type_converter.py +340 -0
  344. sqlspec/data_dictionary/__init__.py +22 -0
  345. sqlspec/data_dictionary/_loader.cp314-win_amd64.pyd +0 -0
  346. sqlspec/data_dictionary/_loader.py +138 -0
  347. sqlspec/data_dictionary/_registry.cp314-win_amd64.pyd +0 -0
  348. sqlspec/data_dictionary/_registry.py +74 -0
  349. sqlspec/data_dictionary/_types.cp314-win_amd64.pyd +0 -0
  350. sqlspec/data_dictionary/_types.py +121 -0
  351. sqlspec/data_dictionary/dialects/__init__.py +21 -0
  352. sqlspec/data_dictionary/dialects/bigquery.cp314-win_amd64.pyd +0 -0
  353. sqlspec/data_dictionary/dialects/bigquery.py +81 -0
  354. sqlspec/data_dictionary/dialects/cockroachdb.cp314-win_amd64.pyd +0 -0
  355. sqlspec/data_dictionary/dialects/cockroachdb.py +54 -0
  356. sqlspec/data_dictionary/dialects/duckdb.cp314-win_amd64.pyd +0 -0
  357. sqlspec/data_dictionary/dialects/duckdb.py +47 -0
  358. sqlspec/data_dictionary/dialects/mysql.cp314-win_amd64.pyd +0 -0
  359. sqlspec/data_dictionary/dialects/mysql.py +53 -0
  360. sqlspec/data_dictionary/dialects/oracle.cp314-win_amd64.pyd +0 -0
  361. sqlspec/data_dictionary/dialects/oracle.py +197 -0
  362. sqlspec/data_dictionary/dialects/postgres.cp314-win_amd64.pyd +0 -0
  363. sqlspec/data_dictionary/dialects/postgres.py +69 -0
  364. sqlspec/data_dictionary/dialects/spanner.cp314-win_amd64.pyd +0 -0
  365. sqlspec/data_dictionary/dialects/spanner.py +37 -0
  366. sqlspec/data_dictionary/dialects/sqlite.cp314-win_amd64.pyd +0 -0
  367. sqlspec/data_dictionary/dialects/sqlite.py +59 -0
  368. sqlspec/data_dictionary/sql/.gitkeep +0 -0
  369. sqlspec/data_dictionary/sql/bigquery/columns.sql +23 -0
  370. sqlspec/data_dictionary/sql/bigquery/foreign_keys.sql +34 -0
  371. sqlspec/data_dictionary/sql/bigquery/indexes.sql +19 -0
  372. sqlspec/data_dictionary/sql/bigquery/tables.sql +33 -0
  373. sqlspec/data_dictionary/sql/bigquery/version.sql +3 -0
  374. sqlspec/data_dictionary/sql/cockroachdb/columns.sql +34 -0
  375. sqlspec/data_dictionary/sql/cockroachdb/foreign_keys.sql +40 -0
  376. sqlspec/data_dictionary/sql/cockroachdb/indexes.sql +32 -0
  377. sqlspec/data_dictionary/sql/cockroachdb/tables.sql +44 -0
  378. sqlspec/data_dictionary/sql/cockroachdb/version.sql +3 -0
  379. sqlspec/data_dictionary/sql/duckdb/columns.sql +23 -0
  380. sqlspec/data_dictionary/sql/duckdb/foreign_keys.sql +36 -0
  381. sqlspec/data_dictionary/sql/duckdb/indexes.sql +19 -0
  382. sqlspec/data_dictionary/sql/duckdb/tables.sql +38 -0
  383. sqlspec/data_dictionary/sql/duckdb/version.sql +3 -0
  384. sqlspec/data_dictionary/sql/mysql/columns.sql +23 -0
  385. sqlspec/data_dictionary/sql/mysql/foreign_keys.sql +28 -0
  386. sqlspec/data_dictionary/sql/mysql/indexes.sql +26 -0
  387. sqlspec/data_dictionary/sql/mysql/tables.sql +33 -0
  388. sqlspec/data_dictionary/sql/mysql/version.sql +3 -0
  389. sqlspec/data_dictionary/sql/oracle/columns.sql +23 -0
  390. sqlspec/data_dictionary/sql/oracle/foreign_keys.sql +48 -0
  391. sqlspec/data_dictionary/sql/oracle/indexes.sql +44 -0
  392. sqlspec/data_dictionary/sql/oracle/tables.sql +25 -0
  393. sqlspec/data_dictionary/sql/oracle/version.sql +20 -0
  394. sqlspec/data_dictionary/sql/postgres/columns.sql +34 -0
  395. sqlspec/data_dictionary/sql/postgres/foreign_keys.sql +40 -0
  396. sqlspec/data_dictionary/sql/postgres/indexes.sql +56 -0
  397. sqlspec/data_dictionary/sql/postgres/tables.sql +44 -0
  398. sqlspec/data_dictionary/sql/postgres/version.sql +3 -0
  399. sqlspec/data_dictionary/sql/spanner/columns.sql +23 -0
  400. sqlspec/data_dictionary/sql/spanner/foreign_keys.sql +70 -0
  401. sqlspec/data_dictionary/sql/spanner/indexes.sql +30 -0
  402. sqlspec/data_dictionary/sql/spanner/tables.sql +9 -0
  403. sqlspec/data_dictionary/sql/spanner/version.sql +3 -0
  404. sqlspec/data_dictionary/sql/sqlite/columns.sql +23 -0
  405. sqlspec/data_dictionary/sql/sqlite/foreign_keys.sql +22 -0
  406. sqlspec/data_dictionary/sql/sqlite/indexes.sql +7 -0
  407. sqlspec/data_dictionary/sql/sqlite/tables.sql +28 -0
  408. sqlspec/data_dictionary/sql/sqlite/version.sql +3 -0
  409. sqlspec/dialects/__init__.py +22 -0
  410. sqlspec/dialects/_compat.cp314-win_amd64.pyd +0 -0
  411. sqlspec/dialects/_compat.py +14 -0
  412. sqlspec/dialects/postgres/__init__.py +9 -0
  413. sqlspec/dialects/postgres/_generators.cp314-win_amd64.pyd +0 -0
  414. sqlspec/dialects/postgres/_generators.py +57 -0
  415. sqlspec/dialects/postgres/_operators.cp314-win_amd64.pyd +0 -0
  416. sqlspec/dialects/postgres/_operators.py +81 -0
  417. sqlspec/dialects/postgres/_paradedb.py +50 -0
  418. sqlspec/dialects/postgres/_pgvector.py +36 -0
  419. sqlspec/dialects/spanner/__init__.py +6 -0
  420. sqlspec/dialects/spanner/_generators.cp314-win_amd64.pyd +0 -0
  421. sqlspec/dialects/spanner/_generators.py +206 -0
  422. sqlspec/dialects/spanner/_spangres.py +77 -0
  423. sqlspec/dialects/spanner/_spanner.py +179 -0
  424. sqlspec/driver/__init__.py +49 -0
  425. sqlspec/driver/_async.cp314-win_amd64.pyd +0 -0
  426. sqlspec/driver/_async.py +1830 -0
  427. sqlspec/driver/_common.cp314-win_amd64.pyd +0 -0
  428. sqlspec/driver/_common.py +2292 -0
  429. sqlspec/driver/_exception_handler.cp314-win_amd64.pyd +0 -0
  430. sqlspec/driver/_exception_handler.py +108 -0
  431. sqlspec/driver/_query_cache.cp314-win_amd64.pyd +0 -0
  432. sqlspec/driver/_query_cache.py +96 -0
  433. sqlspec/driver/_sql_helpers.cp314-win_amd64.pyd +0 -0
  434. sqlspec/driver/_sql_helpers.py +139 -0
  435. sqlspec/driver/_storage_helpers.cp314-win_amd64.pyd +0 -0
  436. sqlspec/driver/_storage_helpers.py +153 -0
  437. sqlspec/driver/_sync.cp314-win_amd64.pyd +0 -0
  438. sqlspec/driver/_sync.py +1817 -0
  439. sqlspec/exceptions.cp314-win_amd64.pyd +0 -0
  440. sqlspec/exceptions.py +480 -0
  441. sqlspec/extensions/__init__.py +0 -0
  442. sqlspec/extensions/adk/__init__.py +84 -0
  443. sqlspec/extensions/adk/_config_utils.py +199 -0
  444. sqlspec/extensions/adk/_types.cp314-win_amd64.pyd +0 -0
  445. sqlspec/extensions/adk/_types.py +41 -0
  446. sqlspec/extensions/adk/artifact/__init__.py +57 -0
  447. sqlspec/extensions/adk/artifact/_types.cp314-win_amd64.pyd +0 -0
  448. sqlspec/extensions/adk/artifact/_types.py +32 -0
  449. sqlspec/extensions/adk/artifact/service.py +508 -0
  450. sqlspec/extensions/adk/artifact/store.py +361 -0
  451. sqlspec/extensions/adk/converters.py +212 -0
  452. sqlspec/extensions/adk/memory/__init__.py +69 -0
  453. sqlspec/extensions/adk/memory/_types.cp314-win_amd64.pyd +0 -0
  454. sqlspec/extensions/adk/memory/_types.py +30 -0
  455. sqlspec/extensions/adk/memory/converters.py +225 -0
  456. sqlspec/extensions/adk/memory/service.py +316 -0
  457. sqlspec/extensions/adk/memory/store.py +525 -0
  458. sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +184 -0
  459. sqlspec/extensions/adk/migrations/__init__.py +0 -0
  460. sqlspec/extensions/adk/service.py +279 -0
  461. sqlspec/extensions/adk/store.py +590 -0
  462. sqlspec/extensions/events/__init__.py +51 -0
  463. sqlspec/extensions/events/_channel.py +703 -0
  464. sqlspec/extensions/events/_hints.cp314-win_amd64.pyd +0 -0
  465. sqlspec/extensions/events/_hints.py +45 -0
  466. sqlspec/extensions/events/_models.py +23 -0
  467. sqlspec/extensions/events/_payload.cp314-win_amd64.pyd +0 -0
  468. sqlspec/extensions/events/_payload.py +69 -0
  469. sqlspec/extensions/events/_protocols.py +134 -0
  470. sqlspec/extensions/events/_queue.py +462 -0
  471. sqlspec/extensions/events/_store.py +209 -0
  472. sqlspec/extensions/events/migrations/0001_create_event_queue.py +59 -0
  473. sqlspec/extensions/events/migrations/__init__.py +3 -0
  474. sqlspec/extensions/fastapi/__init__.py +22 -0
  475. sqlspec/extensions/fastapi/extension.py +391 -0
  476. sqlspec/extensions/fastapi/providers.cp314-win_amd64.pyd +0 -0
  477. sqlspec/extensions/fastapi/providers.py +712 -0
  478. sqlspec/extensions/flask/__init__.py +38 -0
  479. sqlspec/extensions/flask/_state.py +87 -0
  480. sqlspec/extensions/flask/_utils.py +71 -0
  481. sqlspec/extensions/flask/extension.py +539 -0
  482. sqlspec/extensions/litestar/__init__.py +31 -0
  483. sqlspec/extensions/litestar/_utils.py +52 -0
  484. sqlspec/extensions/litestar/channels.py +165 -0
  485. sqlspec/extensions/litestar/cli.py +102 -0
  486. sqlspec/extensions/litestar/config.py +90 -0
  487. sqlspec/extensions/litestar/handlers.py +316 -0
  488. sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
  489. sqlspec/extensions/litestar/migrations/__init__.py +3 -0
  490. sqlspec/extensions/litestar/plugin.py +1066 -0
  491. sqlspec/extensions/litestar/providers.cp314-win_amd64.pyd +0 -0
  492. sqlspec/extensions/litestar/providers.py +784 -0
  493. sqlspec/extensions/litestar/store.py +298 -0
  494. sqlspec/extensions/otel/__init__.py +58 -0
  495. sqlspec/extensions/prometheus/__init__.py +113 -0
  496. sqlspec/extensions/sanic/__init__.py +19 -0
  497. sqlspec/extensions/sanic/_state.py +43 -0
  498. sqlspec/extensions/sanic/_utils.py +127 -0
  499. sqlspec/extensions/sanic/extension.py +647 -0
  500. sqlspec/extensions/starlette/__init__.py +22 -0
  501. sqlspec/extensions/starlette/_state.py +42 -0
  502. sqlspec/extensions/starlette/_utils.py +96 -0
  503. sqlspec/extensions/starlette/extension.py +374 -0
  504. sqlspec/extensions/starlette/middleware.py +281 -0
  505. sqlspec/loader.cp314-win_amd64.pyd +0 -0
  506. sqlspec/loader.py +727 -0
  507. sqlspec/migrations/__init__.py +39 -0
  508. sqlspec/migrations/base.cp314-win_amd64.pyd +0 -0
  509. sqlspec/migrations/base.py +862 -0
  510. sqlspec/migrations/commands.py +2151 -0
  511. sqlspec/migrations/context.cp314-win_amd64.pyd +0 -0
  512. sqlspec/migrations/context.py +157 -0
  513. sqlspec/migrations/fix.cp314-win_amd64.pyd +0 -0
  514. sqlspec/migrations/fix.py +204 -0
  515. sqlspec/migrations/loaders.cp314-win_amd64.pyd +0 -0
  516. sqlspec/migrations/loaders.py +443 -0
  517. sqlspec/migrations/runner.cp314-win_amd64.pyd +0 -0
  518. sqlspec/migrations/runner.py +1195 -0
  519. sqlspec/migrations/squash.cp314-win_amd64.pyd +0 -0
  520. sqlspec/migrations/squash.py +490 -0
  521. sqlspec/migrations/templates.cp314-win_amd64.pyd +0 -0
  522. sqlspec/migrations/templates.py +234 -0
  523. sqlspec/migrations/tracker.cp314-win_amd64.pyd +0 -0
  524. sqlspec/migrations/tracker.py +792 -0
  525. sqlspec/migrations/utils.cp314-win_amd64.pyd +0 -0
  526. sqlspec/migrations/utils.py +256 -0
  527. sqlspec/migrations/validation.cp314-win_amd64.pyd +0 -0
  528. sqlspec/migrations/validation.py +359 -0
  529. sqlspec/migrations/version.cp314-win_amd64.pyd +0 -0
  530. sqlspec/migrations/version.py +446 -0
  531. sqlspec/observability/__init__.py +57 -0
  532. sqlspec/observability/_common.cp314-win_amd64.pyd +0 -0
  533. sqlspec/observability/_common.py +77 -0
  534. sqlspec/observability/_config.cp314-win_amd64.pyd +0 -0
  535. sqlspec/observability/_config.py +364 -0
  536. sqlspec/observability/_diagnostics.cp314-win_amd64.pyd +0 -0
  537. sqlspec/observability/_diagnostics.py +74 -0
  538. sqlspec/observability/_dispatcher.cp314-win_amd64.pyd +0 -0
  539. sqlspec/observability/_dispatcher.py +200 -0
  540. sqlspec/observability/_formatters/__init__.py +13 -0
  541. sqlspec/observability/_formatters/_aws.cp314-win_amd64.pyd +0 -0
  542. sqlspec/observability/_formatters/_aws.py +102 -0
  543. sqlspec/observability/_formatters/_azure.cp314-win_amd64.pyd +0 -0
  544. sqlspec/observability/_formatters/_azure.py +96 -0
  545. sqlspec/observability/_formatters/_base.cp314-win_amd64.pyd +0 -0
  546. sqlspec/observability/_formatters/_base.py +57 -0
  547. sqlspec/observability/_formatters/_gcp.cp314-win_amd64.pyd +0 -0
  548. sqlspec/observability/_formatters/_gcp.py +131 -0
  549. sqlspec/observability/_formatting.py +58 -0
  550. sqlspec/observability/_observer.cp314-win_amd64.pyd +0 -0
  551. sqlspec/observability/_observer.py +361 -0
  552. sqlspec/observability/_runtime.cp314-win_amd64.pyd +0 -0
  553. sqlspec/observability/_runtime.py +461 -0
  554. sqlspec/observability/_sampling.cp314-win_amd64.pyd +0 -0
  555. sqlspec/observability/_sampling.py +188 -0
  556. sqlspec/observability/_spans.cp314-win_amd64.pyd +0 -0
  557. sqlspec/observability/_spans.py +161 -0
  558. sqlspec/protocols.py +955 -0
  559. sqlspec/py.typed +0 -0
  560. sqlspec/service.py +433 -0
  561. sqlspec/storage/__init__.py +48 -0
  562. sqlspec/storage/_arrow_payload.py +68 -0
  563. sqlspec/storage/_paths.cp314-win_amd64.pyd +0 -0
  564. sqlspec/storage/_paths.py +58 -0
  565. sqlspec/storage/_utils.py +46 -0
  566. sqlspec/storage/backends/__init__.py +1 -0
  567. sqlspec/storage/backends/base.cp314-win_amd64.pyd +0 -0
  568. sqlspec/storage/backends/base.py +374 -0
  569. sqlspec/storage/backends/fsspec.py +574 -0
  570. sqlspec/storage/backends/local.py +468 -0
  571. sqlspec/storage/backends/obstore.py +956 -0
  572. sqlspec/storage/errors.cp314-win_amd64.pyd +0 -0
  573. sqlspec/storage/errors.py +102 -0
  574. sqlspec/storage/pipeline.cp314-win_amd64.pyd +0 -0
  575. sqlspec/storage/pipeline.py +628 -0
  576. sqlspec/storage/registry.cp314-win_amd64.pyd +0 -0
  577. sqlspec/storage/registry.py +329 -0
  578. sqlspec/typing.py +405 -0
  579. sqlspec/utils/__init__.py +7 -0
  580. sqlspec/utils/arrow_helpers.py +384 -0
  581. sqlspec/utils/config_tools.cp314-win_amd64.pyd +0 -0
  582. sqlspec/utils/config_tools.py +314 -0
  583. sqlspec/utils/correlation.cp314-win_amd64.pyd +0 -0
  584. sqlspec/utils/correlation.py +134 -0
  585. sqlspec/utils/deprecation.cp314-win_amd64.pyd +0 -0
  586. sqlspec/utils/deprecation.py +157 -0
  587. sqlspec/utils/dispatch.cp314-win_amd64.pyd +0 -0
  588. sqlspec/utils/dispatch.py +101 -0
  589. sqlspec/utils/fixtures.cp314-win_amd64.pyd +0 -0
  590. sqlspec/utils/fixtures.py +260 -0
  591. sqlspec/utils/logging.cp314-win_amd64.pyd +0 -0
  592. sqlspec/utils/logging.py +251 -0
  593. sqlspec/utils/module_loader.py +306 -0
  594. sqlspec/utils/portal.cp314-win_amd64.pyd +0 -0
  595. sqlspec/utils/portal.py +377 -0
  596. sqlspec/utils/schema.cp314-win_amd64.pyd +0 -0
  597. sqlspec/utils/schema.py +1040 -0
  598. sqlspec/utils/serializers/__init__.py +30 -0
  599. sqlspec/utils/serializers/_json.cp314-win_amd64.pyd +0 -0
  600. sqlspec/utils/serializers/_json.py +415 -0
  601. sqlspec/utils/serializers/_numpy.cp314-win_amd64.pyd +0 -0
  602. sqlspec/utils/serializers/_numpy.py +65 -0
  603. sqlspec/utils/serializers/_schema.cp314-win_amd64.pyd +0 -0
  604. sqlspec/utils/serializers/_schema.py +285 -0
  605. sqlspec/utils/singleton.cp314-win_amd64.pyd +0 -0
  606. sqlspec/utils/singleton.py +41 -0
  607. sqlspec/utils/sync_tools.cp314-win_amd64.pyd +0 -0
  608. sqlspec/utils/sync_tools.py +316 -0
  609. sqlspec/utils/text.cp314-win_amd64.pyd +0 -0
  610. sqlspec/utils/text.py +109 -0
  611. sqlspec/utils/type_converters.cp314-win_amd64.pyd +0 -0
  612. sqlspec/utils/type_converters.py +216 -0
  613. sqlspec/utils/type_guards.cp314-win_amd64.pyd +0 -0
  614. sqlspec/utils/type_guards.py +1508 -0
  615. sqlspec/utils/uuids.cp314-win_amd64.pyd +0 -0
  616. sqlspec/utils/uuids.py +241 -0
  617. sqlspec-0.47.0.dist-info/METADATA +202 -0
  618. sqlspec-0.47.0.dist-info/RECORD +621 -0
  619. sqlspec-0.47.0.dist-info/WHEEL +4 -0
  620. sqlspec-0.47.0.dist-info/entry_points.txt +6 -0
  621. sqlspec-0.47.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,820 @@
1
+ """OracleDB adapter compiled helpers."""
2
+
3
+ import re
4
+ from collections.abc import Sized
5
+ from typing import TYPE_CHECKING, Any, cast
6
+
7
+ from sqlspec.adapters.oracledb._param_types import OracleBlob, OracleClob, OracleJson
8
+ from sqlspec.adapters.oracledb.type_converter import OracleOutputConverter
9
+ from sqlspec.core import (
10
+ DriverParameterProfile,
11
+ ParameterStyle,
12
+ StackResult,
13
+ StatementConfig,
14
+ build_statement_config_from_profile,
15
+ create_sql_result,
16
+ )
17
+ from sqlspec.exceptions import (
18
+ CheckViolationError,
19
+ ConnectionTimeoutError,
20
+ DatabaseConnectionError,
21
+ DataError,
22
+ DeadlockError,
23
+ ForeignKeyViolationError,
24
+ IntegrityError,
25
+ NotNullViolationError,
26
+ OperationalError,
27
+ PermissionDeniedError,
28
+ QueryTimeoutError,
29
+ SQLParsingError,
30
+ SQLSpecError,
31
+ TransactionError,
32
+ UniqueViolationError,
33
+ )
34
+ from sqlspec.typing import NUMPY_INSTALLED
35
+ from sqlspec.utils.serializers import to_json
36
+ from sqlspec.utils.type_converters import build_uuid_coercions
37
+ from sqlspec.utils.type_guards import has_rowcount, is_readable
38
+
39
+ if TYPE_CHECKING:
40
+ from collections.abc import Callable, Mapping
41
+
42
+ from sqlspec.core import SQL
43
+
44
+ __all__ = (
45
+ "apply_driver_features",
46
+ "build_insert_statement",
47
+ "build_pipeline_stack_result",
48
+ "build_profile",
49
+ "build_statement_config",
50
+ "build_truncate_statement",
51
+ "coerce_large_parameters_async",
52
+ "coerce_large_parameters_sync",
53
+ "collect_async_rows",
54
+ "collect_sync_rows",
55
+ "create_mapped_exception",
56
+ "default_statement_config",
57
+ "driver_profile",
58
+ "normalize_column_names",
59
+ "normalize_execute_many_parameters_async",
60
+ "normalize_execute_many_parameters_sync",
61
+ "requires_session_callback",
62
+ "resolve_row_metadata",
63
+ "resolve_rowcount",
64
+ )
65
+
66
+
67
+ IMPLICIT_UPPER_COLUMN_PATTERN: "re.Pattern[str]" = re.compile(r"^(?!\d)(?:[A-Z0-9_]+)$")
68
+ _VERSION_COMPONENTS: int = 3
69
+ TYPE_CONVERTER = OracleOutputConverter()
70
+ _LOB_TYPE_NAME_MARKERS: "tuple[str, ...]" = ("LOB", "BFILE")
71
+ _SCALAR_PASSTHROUGH_TYPES: "tuple[type[Any], ...]" = (bool, int, float, str, bytes, bytearray, type(None))
72
+ ROW_CACHE_MAX_SIZE: int = 256
73
+
74
+ # Oracle ORA error code ranges for category detection
75
+ ORA_CHECK_CONSTRAINT = 2290
76
+ ORA_INTEGRITY_RANGE_START = 2200
77
+ ORA_INTEGRITY_RANGE_END = 2300
78
+ ORA_PARSING_RANGE_START = 900
79
+ ORA_PARSING_RANGE_END = 1000
80
+ ORA_TABLESPACE_FULL = 1652
81
+
82
+ # Oracle error codes for specific exception mappings
83
+ _ERROR_CODE_MAPPING: "dict[int, tuple[type[SQLSpecError], str]]" = {
84
+ # Integrity constraint violations
85
+ 1: (UniqueViolationError, "unique constraint violation"),
86
+ 2291: (ForeignKeyViolationError, "foreign key constraint violation"),
87
+ 2292: (ForeignKeyViolationError, "foreign key constraint violation"),
88
+ ORA_CHECK_CONSTRAINT: (CheckViolationError, "check constraint violation"),
89
+ 1400: (NotNullViolationError, "not-null constraint violation"),
90
+ 1407: (NotNullViolationError, "not-null constraint violation"),
91
+ # Permission/access errors
92
+ 1017: (PermissionDeniedError, "invalid username/password"),
93
+ 1031: (PermissionDeniedError, "insufficient privileges"),
94
+ 942: (PermissionDeniedError, "table or view does not exist"),
95
+ # Connection errors
96
+ 12154: (DatabaseConnectionError, "TNS resolution failed"),
97
+ 12541: (ConnectionTimeoutError, "no listener"),
98
+ 12545: (ConnectionTimeoutError, "connect failed"),
99
+ 12514: (DatabaseConnectionError, "service not known"),
100
+ 12505: (DatabaseConnectionError, "listener rejected"),
101
+ 12170: (ConnectionTimeoutError, "connect timeout"),
102
+ # Transaction errors
103
+ 60: (DeadlockError, "deadlock detected"),
104
+ 8176: (TransactionError, "consistent read failure"),
105
+ # Query timeout/cancellation
106
+ 1013: (QueryTimeoutError, "user requested cancel"),
107
+ # Data errors
108
+ 1722: (DataError, "invalid number"),
109
+ 1858: (DataError, "invalid character"),
110
+ 1840: (DataError, "data conversion error"),
111
+ # Operational errors
112
+ ORA_TABLESPACE_FULL: (OperationalError, "tablespace full"),
113
+ }
114
+
115
+
116
+ def _parse_version_tuple(version: str) -> "tuple[int, int, int]":
117
+ parts = [int(part) for part in version.split(".") if part.isdigit()]
118
+ while len(parts) < _VERSION_COMPONENTS:
119
+ parts.append(0)
120
+ return parts[0], parts[1], parts[2]
121
+
122
+
123
+ def _resolve_oracledb_version() -> "tuple[int, int, int]":
124
+ try:
125
+ import oracledb
126
+ except ImportError:
127
+ return (0, 0, 0)
128
+ try:
129
+ version = oracledb.__version__
130
+ except AttributeError:
131
+ version = "0.0.0"
132
+ return _parse_version_tuple(version)
133
+
134
+
135
+ ORACLEDB_VERSION: "tuple[int, int, int]" = _resolve_oracledb_version()
136
+
137
+
138
+ def normalize_column_names(column_names: "list[str]", driver_features: "dict[str, Any]") -> "list[str]":
139
+ should_lowercase = driver_features.get("enable_lowercase_column_names", False)
140
+ if not should_lowercase:
141
+ return column_names
142
+ normalized: list[str] = []
143
+ for name in column_names:
144
+ if name and IMPLICIT_UPPER_COLUMN_PATTERN.fullmatch(name):
145
+ normalized.append(name.lower())
146
+ else:
147
+ normalized.append(name)
148
+ return normalized
149
+
150
+
151
+ def normalize_execute_many_parameters_sync(parameters: Any) -> Any:
152
+ """Normalize parameters for Oracle executemany calls.
153
+
154
+ Args:
155
+ parameters: Prepared parameters payload.
156
+
157
+ Returns:
158
+ Normalized parameters payload.
159
+
160
+ Raises:
161
+ ValueError: When parameters are missing for executemany.
162
+ """
163
+ if not parameters:
164
+ msg = "execute_many requires parameters"
165
+ raise ValueError(msg)
166
+ if isinstance(parameters, tuple):
167
+ return list(parameters)
168
+ return parameters
169
+
170
+
171
+ def normalize_execute_many_parameters_async(parameters: Any) -> Any:
172
+ """Normalize parameters for Oracle async executemany calls.
173
+
174
+ Args:
175
+ parameters: Prepared parameters payload.
176
+
177
+ Returns:
178
+ Normalized parameters payload.
179
+
180
+ Raises:
181
+ ValueError: When parameters are missing for executemany.
182
+ """
183
+ if not parameters:
184
+ msg = "execute_many requires parameters"
185
+ raise ValueError(msg)
186
+ return parameters
187
+
188
+
189
+ def _coerce_value_sync(
190
+ connection: Any, value: Any, *, clob_type: Any, blob_type: Any, varchar2_byte_limit: int, raw_byte_limit: int
191
+ ) -> Any:
192
+ """Route a single parameter value through wrapper-aware coercion (sync)."""
193
+ if isinstance(value, OracleClob):
194
+ inner = value.value
195
+ if isinstance(inner, bytes):
196
+ inner = inner.decode("utf-8")
197
+ return connection.createlob(clob_type, inner)
198
+ if isinstance(value, OracleBlob):
199
+ inner = value.value
200
+ if isinstance(inner, str):
201
+ inner = inner.encode("utf-8")
202
+ return connection.createlob(blob_type, inner)
203
+ if isinstance(value, OracleJson):
204
+ return value.value
205
+ if isinstance(value, str) and len(value.encode("utf-8")) > varchar2_byte_limit:
206
+ return connection.createlob(clob_type, value)
207
+ if isinstance(value, (bytes, bytearray)) and len(value) > raw_byte_limit:
208
+ return connection.createlob(blob_type, bytes(value))
209
+ return value
210
+
211
+
212
+ async def _coerce_value_async(
213
+ connection: Any, value: Any, *, clob_type: Any, blob_type: Any, varchar2_byte_limit: int, raw_byte_limit: int
214
+ ) -> Any:
215
+ """Async mirror of :func:`_coerce_value_sync`."""
216
+ if isinstance(value, OracleClob):
217
+ inner = value.value
218
+ if isinstance(inner, bytes):
219
+ inner = inner.decode("utf-8")
220
+ return await connection.createlob(clob_type, inner)
221
+ if isinstance(value, OracleBlob):
222
+ inner = value.value
223
+ if isinstance(inner, str):
224
+ inner = inner.encode("utf-8")
225
+ return await connection.createlob(blob_type, inner)
226
+ if isinstance(value, OracleJson):
227
+ return value.value
228
+ if isinstance(value, str) and len(value.encode("utf-8")) > varchar2_byte_limit:
229
+ return await connection.createlob(clob_type, value)
230
+ if isinstance(value, (bytes, bytearray)) and len(value) > raw_byte_limit:
231
+ return await connection.createlob(blob_type, bytes(value))
232
+ return value
233
+
234
+
235
+ def coerce_large_parameters_sync(
236
+ connection: Any, parameters: Any, *, clob_type: Any, blob_type: Any, varchar2_byte_limit: int, raw_byte_limit: int
237
+ ) -> Any:
238
+ """Coerce large string/bytes parameters into CLOBs/BLOBs with wrapper-aware routing.
239
+
240
+ Routing order:
241
+ 1. ``OracleClob`` / ``OracleBlob`` / ``OracleJson`` wrappers — explicit user
242
+ intent, length-thresholds bypassed.
243
+ 2. Plain ``str`` whose UTF-8 encoding exceeds ``varchar2_byte_limit`` → CLOB.
244
+ 3. Plain ``bytes``/``bytearray`` longer than ``raw_byte_limit`` → BLOB.
245
+
246
+ Handles ``dict`` (named binds), ``tuple`` and ``list`` (positional binds).
247
+ Tuples are returned as new lists when any value is rewritten so the driver's
248
+ ``cast(... | tuple | list | dict)`` contract is preserved.
249
+
250
+ Args:
251
+ connection: Oracle database connection.
252
+ parameters: Prepared parameters payload.
253
+ clob_type: Oracle CLOB DB type (``oracledb.DB_TYPE_CLOB``).
254
+ blob_type: Oracle BLOB DB type (``oracledb.DB_TYPE_BLOB``).
255
+ varchar2_byte_limit: Byte-length threshold for implicit CLOB conversion.
256
+ raw_byte_limit: Byte-length threshold for implicit BLOB conversion.
257
+
258
+ Returns:
259
+ Parameters payload with values routed to the correct LOB / native type.
260
+ """
261
+ if not parameters:
262
+ return parameters
263
+ if isinstance(parameters, dict):
264
+ for param_name, param_value in parameters.items():
265
+ parameters[param_name] = _coerce_value_sync(
266
+ connection,
267
+ param_value,
268
+ clob_type=clob_type,
269
+ blob_type=blob_type,
270
+ varchar2_byte_limit=varchar2_byte_limit,
271
+ raw_byte_limit=raw_byte_limit,
272
+ )
273
+ return parameters
274
+ if isinstance(parameters, (list, tuple)):
275
+ return [
276
+ _coerce_value_sync(
277
+ connection,
278
+ value,
279
+ clob_type=clob_type,
280
+ blob_type=blob_type,
281
+ varchar2_byte_limit=varchar2_byte_limit,
282
+ raw_byte_limit=raw_byte_limit,
283
+ )
284
+ for value in parameters
285
+ ]
286
+ return parameters
287
+
288
+
289
+ async def coerce_large_parameters_async(
290
+ connection: Any, parameters: Any, *, clob_type: Any, blob_type: Any, varchar2_byte_limit: int, raw_byte_limit: int
291
+ ) -> Any:
292
+ """Async mirror of :func:`coerce_large_parameters_sync`.
293
+
294
+ Identical routing order; ``connection.createlob`` is awaited for the async
295
+ Oracle driver.
296
+ """
297
+ if not parameters:
298
+ return parameters
299
+ if isinstance(parameters, dict):
300
+ for param_name, param_value in parameters.items():
301
+ parameters[param_name] = await _coerce_value_async(
302
+ connection,
303
+ param_value,
304
+ clob_type=clob_type,
305
+ blob_type=blob_type,
306
+ varchar2_byte_limit=varchar2_byte_limit,
307
+ raw_byte_limit=raw_byte_limit,
308
+ )
309
+ return parameters
310
+ if isinstance(parameters, (list, tuple)):
311
+ return [
312
+ await _coerce_value_async(
313
+ connection,
314
+ value,
315
+ clob_type=clob_type,
316
+ blob_type=blob_type,
317
+ varchar2_byte_limit=varchar2_byte_limit,
318
+ raw_byte_limit=raw_byte_limit,
319
+ )
320
+ for value in parameters
321
+ ]
322
+ return parameters
323
+
324
+
325
+ def build_insert_statement(table: str, columns: "list[str]") -> str:
326
+ column_list = ", ".join(columns)
327
+ placeholders = ", ".join(f":{idx + 1}" for idx in range(len(columns)))
328
+ return f"INSERT INTO {table} ({column_list}) VALUES ({placeholders})"
329
+
330
+
331
+ def build_truncate_statement(table: str) -> str:
332
+ return f"TRUNCATE TABLE {table}"
333
+
334
+
335
+ def build_pipeline_stack_result(
336
+ statement: "SQL",
337
+ method: str,
338
+ returns_rows: bool,
339
+ parameters: Any,
340
+ pipeline_result: Any,
341
+ driver_features: "dict[str, Any]",
342
+ ) -> "StackResult":
343
+ """Build StackResult from Oracle pipeline output.
344
+
345
+ Args:
346
+ statement: Statement executed in the pipeline.
347
+ method: Pipeline execution method name.
348
+ returns_rows: Whether the operation returns rows.
349
+ parameters: Prepared parameters used for execution.
350
+ pipeline_result: Raw pipeline execution result.
351
+ driver_features: Driver feature configuration for normalization.
352
+
353
+ Returns:
354
+ StackResult for the pipeline operation.
355
+ """
356
+ try:
357
+ rows = pipeline_result.rows
358
+ except AttributeError:
359
+ rows = None
360
+ try:
361
+ columns = pipeline_result.columns
362
+ except AttributeError:
363
+ columns = None
364
+
365
+ data: list[dict[str, Any]] | None = None
366
+ if returns_rows:
367
+ if not rows:
368
+ data = []
369
+ else:
370
+ if columns:
371
+ names = []
372
+ for index, column in enumerate(columns):
373
+ try:
374
+ name = column.name
375
+ except AttributeError:
376
+ name = f"column_{index}"
377
+ names.append(name)
378
+ else:
379
+ first = rows[0]
380
+ names = [f"column_{index}" for index in range(len(first) if isinstance(first, Sized) else 0)]
381
+ names = normalize_column_names(names, driver_features)
382
+ normalized_rows: list[dict[str, Any]] = []
383
+ for row in rows:
384
+ if isinstance(row, dict):
385
+ normalized_rows.append(row)
386
+ else:
387
+ normalized_rows.append(dict(zip(names, row, strict=False)))
388
+ data = normalized_rows
389
+
390
+ metadata: dict[str, Any] = {"pipeline_operation": method}
391
+ try:
392
+ warning = pipeline_result.warning
393
+ except AttributeError:
394
+ warning = None
395
+ if warning is not None:
396
+ metadata["warning"] = warning
397
+
398
+ try:
399
+ return_value = pipeline_result.return_value
400
+ except AttributeError:
401
+ return_value = None
402
+ if return_value is not None:
403
+ metadata["return_value"] = return_value
404
+
405
+ try:
406
+ rowcount = pipeline_result.rowcount
407
+ except AttributeError:
408
+ rowcount = None
409
+
410
+ if isinstance(rowcount, int) and rowcount >= 0:
411
+ rows_affected = rowcount
412
+ elif method == "execute_many":
413
+ try:
414
+ rows_affected = len(parameters or ())
415
+ except TypeError:
416
+ rows_affected = 0
417
+ elif method == "execute" and not returns_rows:
418
+ rows_affected = 1
419
+ elif returns_rows:
420
+ rows_affected = len(data or [])
421
+ else:
422
+ rows_affected = 0
423
+
424
+ sql_result = create_sql_result(statement, data=data, rows_affected=rows_affected, metadata=metadata)
425
+ return StackResult.from_sql_result(sql_result)
426
+
427
+
428
+ def resolve_rowcount(cursor: Any) -> int:
429
+ """Resolve rowcount from an Oracle cursor.
430
+
431
+ Args:
432
+ cursor: Oracle cursor with optional rowcount metadata.
433
+
434
+ Returns:
435
+ Rowcount value or 0 when unavailable.
436
+ """
437
+ if not has_rowcount(cursor):
438
+ return 0
439
+ rowcount = cursor.rowcount
440
+ if isinstance(rowcount, int):
441
+ return rowcount
442
+ return 0
443
+
444
+
445
+ def apply_driver_features(driver_features: "Mapping[str, Any] | None") -> "dict[str, Any]":
446
+ """Apply OracleDB driver feature defaults."""
447
+ features: dict[str, Any] = dict(driver_features) if driver_features else {}
448
+ features.setdefault("enable_numpy_vectors", NUMPY_INSTALLED)
449
+ features.setdefault("enable_lowercase_column_names", True)
450
+ features.setdefault("enable_uuid_binary", True)
451
+ if "vector_return_format" not in features:
452
+ if not NUMPY_INSTALLED:
453
+ features["vector_return_format"] = "list"
454
+ elif features["enable_numpy_vectors"]:
455
+ features["vector_return_format"] = "numpy"
456
+ else:
457
+ features["vector_return_format"] = "array"
458
+ features.setdefault("oracle_varchar2_byte_limit", 4000)
459
+ features.setdefault("oracle_raw_byte_limit", 2000)
460
+ return features
461
+
462
+
463
+ def requires_session_callback(driver_features: "dict[str, Any]") -> bool:
464
+ """Return True when the session callback should be installed.
465
+
466
+ The JSON input/output handlers are always-on (no driver-feature flag), so
467
+ the session callback is always required for an Oracle pool to bind ``dict``
468
+ / ``list`` parameters via the native ``DB_TYPE_JSON`` / OSON-encoded BLOB /
469
+ JSON-string CLOB paths and to cache ``connection._sqlspec_oracle_major``.
470
+ """
471
+ del driver_features # always-on; preserved for signature compatibility
472
+ return True
473
+
474
+
475
+ def _description_requires_lob_coercion(description: "list[Any]") -> bool:
476
+ """Return True when cursor metadata indicates LOB-compatible columns."""
477
+ for column in description:
478
+ try:
479
+ type_code = column[1]
480
+ except (TypeError, IndexError, KeyError):
481
+ type_code = getattr(column, "type_code", None)
482
+ if type_code is None:
483
+ # Unknown metadata shape: keep conservative behavior.
484
+ return True
485
+
486
+ type_name = getattr(type_code, "name", None)
487
+ if isinstance(type_name, str):
488
+ upper_name = type_name.upper()
489
+ if any(marker in upper_name for marker in _LOB_TYPE_NAME_MARKERS):
490
+ return True
491
+ continue
492
+
493
+ type_text = str(type_code).upper()
494
+ if any(marker in type_text for marker in _LOB_TYPE_NAME_MARKERS):
495
+ return True
496
+ return False
497
+
498
+
499
+ def resolve_row_metadata(
500
+ description: "list[Any] | None", driver_features: "dict[str, Any]", cache: "dict[int, tuple[Any, list[str], bool]]"
501
+ ) -> "tuple[list[str], bool]":
502
+ """Resolve and cache Oracle row metadata for hot row materialization paths.
503
+
504
+ Args:
505
+ description: Cursor description metadata.
506
+ driver_features: Driver feature configuration.
507
+ cache: Driver-local metadata cache keyed by ``id(description)``.
508
+
509
+ Returns:
510
+ Tuple of (normalized column names, requires_lob_coercion).
511
+ """
512
+ if not description:
513
+ return [], False
514
+
515
+ cache_key = id(description)
516
+ cached = cache.get(cache_key)
517
+ if cached is not None and cached[0] is description:
518
+ return cached[1], cached[2]
519
+
520
+ column_names = [col[0] for col in description]
521
+ normalized_column_names = normalize_column_names(column_names, driver_features)
522
+ requires_lob_coercion = _description_requires_lob_coercion(description)
523
+
524
+ if len(cache) >= ROW_CACHE_MAX_SIZE:
525
+ cache.pop(next(iter(cache)))
526
+ cache[cache_key] = (description, normalized_column_names, requires_lob_coercion)
527
+ return normalized_column_names, requires_lob_coercion
528
+
529
+
530
+ def _row_requires_lob_coercion(row: "tuple[Any, ...]") -> bool:
531
+ """Return True when a row contains readable values that need LOB coercion."""
532
+ for value in row:
533
+ value_type = type(value)
534
+ if value_type in _SCALAR_PASSTHROUGH_TYPES:
535
+ continue
536
+ if is_readable(value):
537
+ return True
538
+ return False
539
+
540
+
541
+ def _coerce_sync_row_values(row: "tuple[Any, ...]") -> "tuple[Any, ...]":
542
+ """Coerce LOB handles to concrete values for synchronous execution.
543
+
544
+ Processes each value in the row, reading LOB objects and applying
545
+ type detection for JSON values stored in CLOBs.
546
+
547
+ Args:
548
+ row: Tuple of column values from database fetch.
549
+
550
+ Returns:
551
+ Tuple of coerced values with LOBs read to strings/bytes.
552
+
553
+ """
554
+ coerced_values: list[Any] | None = None
555
+ for index, value in enumerate(row):
556
+ value_type = type(value)
557
+ if value_type in _SCALAR_PASSTHROUGH_TYPES:
558
+ if coerced_values is not None:
559
+ coerced_values.append(value)
560
+ continue
561
+
562
+ if is_readable(value):
563
+ try:
564
+ processed_value = value.read()
565
+ except Exception:
566
+ if coerced_values is not None:
567
+ coerced_values.append(value)
568
+ continue
569
+ if isinstance(processed_value, str):
570
+ processed_value = TYPE_CONVERTER.convert_if_detected(processed_value)
571
+
572
+ if coerced_values is None:
573
+ if processed_value is value:
574
+ continue
575
+ coerced_values = list(row[:index])
576
+ coerced_values.append(processed_value)
577
+ continue
578
+
579
+ if coerced_values is not None:
580
+ coerced_values.append(value)
581
+
582
+ if coerced_values is None:
583
+ return row
584
+ return tuple(coerced_values)
585
+
586
+
587
+ async def _coerce_async_row_values(row: "tuple[Any, ...]") -> "tuple[Any, ...]":
588
+ """Coerce LOB handles to concrete values for asynchronous execution.
589
+
590
+ Processes each value in the row, reading LOB objects asynchronously
591
+ and applying type detection for JSON values stored in CLOBs.
592
+
593
+ Args:
594
+ row: Tuple of column values from database fetch.
595
+
596
+ Returns:
597
+ Tuple of coerced values with LOBs read to strings/bytes.
598
+
599
+ """
600
+ coerced_values: list[Any] | None = None
601
+ for index, value in enumerate(row):
602
+ value_type = type(value)
603
+ if value_type in _SCALAR_PASSTHROUGH_TYPES:
604
+ if coerced_values is not None:
605
+ coerced_values.append(value)
606
+ continue
607
+
608
+ if is_readable(value):
609
+ try:
610
+ processed_value = await TYPE_CONVERTER.process_lob(value)
611
+ except Exception:
612
+ if coerced_values is not None:
613
+ coerced_values.append(value)
614
+ continue
615
+ if isinstance(processed_value, str):
616
+ processed_value = TYPE_CONVERTER.convert_if_detected(processed_value)
617
+
618
+ if coerced_values is None:
619
+ if processed_value is value:
620
+ continue
621
+ coerced_values = list(row[:index])
622
+ coerced_values.append(processed_value)
623
+ continue
624
+
625
+ if coerced_values is not None:
626
+ coerced_values.append(value)
627
+
628
+ if coerced_values is None:
629
+ return row
630
+ return tuple(coerced_values)
631
+
632
+
633
+ def collect_sync_rows(
634
+ fetched_data: "list[Any] | None",
635
+ description: "list[Any] | None",
636
+ driver_features: "dict[str, Any]",
637
+ *,
638
+ column_names: "list[str] | None" = None,
639
+ requires_lob_coercion: "bool | None" = None,
640
+ ) -> "tuple[list[tuple[Any, ...]], list[str]]":
641
+ """Collect OracleDB sync rows as tuples with normalized column names.
642
+
643
+ LOB coercion is still applied to each row. The raw coerced tuples are
644
+ returned instead of dicts so that ``SQLResult`` can handle lazy dict
645
+ materialization based on ``row_format``.
646
+
647
+ Args:
648
+ fetched_data: Rows returned from cursor.fetchall().
649
+ description: Cursor description metadata.
650
+ driver_features: Driver feature configuration.
651
+ column_names: Optional precomputed normalized column names.
652
+ requires_lob_coercion: Optional precomputed LOB-coercion flag.
653
+
654
+ Returns:
655
+ Tuple of (rows, column_names).
656
+ """
657
+ if not description:
658
+ return [], []
659
+ resolved_column_names = (
660
+ normalize_column_names([col[0] for col in description], driver_features)
661
+ if column_names is None
662
+ else column_names
663
+ )
664
+ if not fetched_data:
665
+ return [], resolved_column_names
666
+
667
+ if requires_lob_coercion is None:
668
+ requires_lob_coercion = _description_requires_lob_coercion(description)
669
+ if not requires_lob_coercion:
670
+ first_row = fetched_data[0]
671
+ first_row_tuple = first_row if isinstance(first_row, tuple) else tuple(first_row)
672
+ if not _row_requires_lob_coercion(first_row_tuple):
673
+ return cast("list[tuple[Any, ...]]", fetched_data), resolved_column_names
674
+
675
+ data: list[tuple[Any, ...]] = []
676
+ for row in fetched_data:
677
+ row_tuple = row if isinstance(row, tuple) else tuple(row)
678
+ data.append(_coerce_sync_row_values(row_tuple))
679
+ return data, resolved_column_names
680
+
681
+
682
+ async def collect_async_rows(
683
+ fetched_data: "list[Any] | None",
684
+ description: "list[Any] | None",
685
+ driver_features: "dict[str, Any]",
686
+ *,
687
+ column_names: "list[str] | None" = None,
688
+ requires_lob_coercion: "bool | None" = None,
689
+ ) -> "tuple[list[tuple[Any, ...]], list[str]]":
690
+ """Collect OracleDB async rows as tuples with normalized column names.
691
+
692
+ LOB coercion is still applied to each row. The raw coerced tuples are
693
+ returned instead of dicts so that ``SQLResult`` can handle lazy dict
694
+ materialization based on ``row_format``.
695
+
696
+ Args:
697
+ fetched_data: Rows returned from cursor.fetchall().
698
+ description: Cursor description metadata.
699
+ driver_features: Driver feature configuration.
700
+ column_names: Optional precomputed normalized column names.
701
+ requires_lob_coercion: Optional precomputed LOB-coercion flag.
702
+
703
+ Returns:
704
+ Tuple of (rows, column_names).
705
+ """
706
+ if not description:
707
+ return [], []
708
+ resolved_column_names = (
709
+ normalize_column_names([col[0] for col in description], driver_features)
710
+ if column_names is None
711
+ else column_names
712
+ )
713
+ if not fetched_data:
714
+ return [], resolved_column_names
715
+
716
+ if requires_lob_coercion is None:
717
+ requires_lob_coercion = _description_requires_lob_coercion(description)
718
+ if not requires_lob_coercion:
719
+ first_row = fetched_data[0]
720
+ first_row_tuple = first_row if isinstance(first_row, tuple) else tuple(first_row)
721
+ if not _row_requires_lob_coercion(first_row_tuple):
722
+ return cast("list[tuple[Any, ...]]", fetched_data), resolved_column_names
723
+
724
+ data: list[tuple[Any, ...]] = []
725
+ for row in fetched_data:
726
+ row_tuple = row if isinstance(row, tuple) else tuple(row)
727
+ data.append(await _coerce_async_row_values(row_tuple))
728
+ return data, resolved_column_names
729
+
730
+
731
+ def _create_oracle_error(
732
+ error: Any, code: "int | None", error_class: type[SQLSpecError], description: str
733
+ ) -> SQLSpecError:
734
+ """Create a SQLSpec exception from an Oracle error.
735
+
736
+ Args:
737
+ error: The original Oracle exception
738
+ code: Oracle error code
739
+ error_class: The SQLSpec exception class to instantiate
740
+ description: Human-readable description of the error type
741
+
742
+ Returns:
743
+ A new SQLSpec exception instance with the original as its cause
744
+ """
745
+ msg = f"Oracle {description} [ORA-{code:05d}]: {error}" if code else f"Oracle {description}: {error}"
746
+ exc = error_class(msg)
747
+ exc.__cause__ = error
748
+ return exc
749
+
750
+
751
+ def create_mapped_exception(error: Any) -> SQLSpecError:
752
+ """Map Oracle exceptions to SQLSpec exceptions.
753
+
754
+ This is a factory function that returns an exception instance rather than
755
+ raising. This pattern is more robust for use in __exit__ handlers and
756
+ avoids issues with exception control flow in different Python versions.
757
+
758
+ Args:
759
+ error: The Oracle exception to map
760
+
761
+ Returns:
762
+ A SQLSpec exception that wraps the original error
763
+ """
764
+ error_obj = error.args[0] if getattr(error, "args", None) else None
765
+ if not error_obj:
766
+ return _create_oracle_error(error, None, SQLSpecError, "database error")
767
+
768
+ try:
769
+ error_code = error_obj.code
770
+ except AttributeError:
771
+ error_code = None
772
+ if not error_code:
773
+ return _create_oracle_error(error, None, SQLSpecError, "database error")
774
+
775
+ mapping = _ERROR_CODE_MAPPING.get(error_code)
776
+ if mapping:
777
+ error_class, error_desc = mapping
778
+ return _create_oracle_error(error, error_code, error_class, error_desc)
779
+
780
+ if ORA_INTEGRITY_RANGE_START <= error_code < ORA_INTEGRITY_RANGE_END:
781
+ return _create_oracle_error(error, error_code, IntegrityError, "integrity constraint violation")
782
+
783
+ if ORA_PARSING_RANGE_START <= error_code < ORA_PARSING_RANGE_END:
784
+ return _create_oracle_error(error, error_code, SQLParsingError, "SQL syntax error")
785
+
786
+ return _create_oracle_error(error, error_code, SQLSpecError, "database error")
787
+
788
+
789
+ def build_profile() -> "DriverParameterProfile":
790
+ """Create the OracleDB driver parameter profile."""
791
+ return DriverParameterProfile(
792
+ name="OracleDB",
793
+ default_style=ParameterStyle.NAMED_COLON,
794
+ supported_styles={ParameterStyle.NAMED_COLON, ParameterStyle.NUMERIC, ParameterStyle.QMARK},
795
+ default_execution_style=ParameterStyle.NAMED_COLON,
796
+ supported_execution_styles={ParameterStyle.NAMED_COLON, ParameterStyle.POSITIONAL_COLON},
797
+ has_native_list_expansion=False,
798
+ preserve_parameter_format=True,
799
+ needs_static_script_compilation=False,
800
+ allow_mixed_parameter_styles=False,
801
+ preserve_original_params_for_many=False,
802
+ json_serializer_strategy="driver",
803
+ custom_type_coercions={**build_uuid_coercions(native=True)},
804
+ default_dialect="oracle",
805
+ )
806
+
807
+
808
+ driver_profile = build_profile()
809
+
810
+
811
+ def build_statement_config(*, json_serializer: "Callable[[Any], str] | None" = None) -> StatementConfig:
812
+ """Construct the OracleDB statement configuration with optional JSON serializer."""
813
+ serializer = json_serializer or to_json
814
+ profile = driver_profile
815
+ return build_statement_config_from_profile(
816
+ profile, statement_overrides={"dialect": "oracle"}, json_serializer=serializer
817
+ )
818
+
819
+
820
+ default_statement_config = build_statement_config()