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,1021 @@
1
+ """SQL statement splitter with caching and dialect support.
2
+
3
+ This module provides SQL script statement splitting functionality
4
+ with support for multiple SQL dialects and caching for performance.
5
+
6
+ Components:
7
+ StatementSplitter: Main SQL script splitter with caching
8
+ DialectConfig: Base class for dialect-specific configurations
9
+ Token/TokenType: Token representation and classification
10
+ Caching: Pattern and result caching for performance
11
+
12
+ Supported dialects include Oracle PL/SQL, T-SQL, PostgreSQL,
13
+ MySQL, SQLite, DuckDB, and BigQuery.
14
+ """
15
+
16
+ import logging
17
+ import re
18
+ import threading
19
+ from abc import ABC, abstractmethod
20
+ from collections.abc import Callable, Generator
21
+ from enum import Enum
22
+ from re import Pattern
23
+ from typing import Any, Final, TypeAlias, cast
24
+
25
+ from mypy_extensions import mypyc_attr
26
+
27
+ from sqlspec.core.cache import CacheKey, LRUCache
28
+ from sqlspec.utils.logging import get_logger
29
+
30
+ __all__ = (
31
+ "DialectConfig",
32
+ "OracleDialectConfig",
33
+ "PostgreSQLDialectConfig",
34
+ "StatementSplitter",
35
+ "TSQLDialectConfig",
36
+ "Token",
37
+ "TokenType",
38
+ "split_sql_script",
39
+ )
40
+
41
+ logger = get_logger("sqlspec.core.splitter")
42
+
43
+ _TOKENIZE_DEBUG_SAMPLE_LIMIT: Final[int] = 3
44
+ _TOKENIZE_SNIPPET_LENGTH: Final[int] = 20
45
+
46
+ DEFAULT_PATTERN_CACHE_SIZE: Final = 1000
47
+ DEFAULT_RESULT_CACHE_SIZE: Final = 5000
48
+ DEFAULT_CACHE_TTL: Final = 3600
49
+
50
+ DIALECT_CONFIG_SLOTS: Final = (
51
+ "_block_starters",
52
+ "_block_enders",
53
+ "_statement_terminators",
54
+ "_batch_separators",
55
+ "_special_terminators",
56
+ "_max_nesting_depth",
57
+ "_name",
58
+ )
59
+
60
+ TOKEN_SLOTS: Final = ("type", "value", "line", "column", "position")
61
+
62
+ SPLITTER_SLOTS: Final = (
63
+ "_dialect",
64
+ "_strip_trailing_semicolon",
65
+ "_token_patterns",
66
+ "_compiled_patterns",
67
+ "_pattern_cache_key",
68
+ "_result_cache",
69
+ "_pattern_cache",
70
+ )
71
+
72
+
73
+ def _special_terminator_true(_tokens: "list[Token]", _pos: int) -> bool:
74
+ return True
75
+
76
+
77
+ _STRING_WRITER_TYPE: "type[Any] | None" = None
78
+ _STRING_WRITER_RESOLVED = False
79
+
80
+
81
+ def _get_librt_string_writer() -> "type[Any] | None":
82
+ """Return librt's StringWriter when the optional performance helper exists."""
83
+ global _STRING_WRITER_RESOLVED, _STRING_WRITER_TYPE
84
+ if _STRING_WRITER_RESOLVED:
85
+ return _STRING_WRITER_TYPE
86
+ try:
87
+ from librt.strings import StringWriter
88
+ except ImportError:
89
+ _STRING_WRITER_TYPE = None
90
+ else:
91
+ _STRING_WRITER_TYPE = StringWriter
92
+ _STRING_WRITER_RESOLVED = True
93
+ return _STRING_WRITER_TYPE
94
+
95
+
96
+ def _join_string_fragments(fragments: "list[str]") -> str:
97
+ """Join fragments with the standard list-join path."""
98
+ return "".join(fragments)
99
+
100
+
101
+ class TokenType(Enum):
102
+ """Types of tokens recognized by the SQL lexer."""
103
+
104
+ COMMENT_LINE = "COMMENT_LINE"
105
+ COMMENT_BLOCK = "COMMENT_BLOCK"
106
+ STRING_LITERAL = "STRING_LITERAL"
107
+ QUOTED_IDENTIFIER = "QUOTED_IDENTIFIER"
108
+ KEYWORD = "KEYWORD"
109
+ TERMINATOR = "TERMINATOR"
110
+ BATCH_SEPARATOR = "BATCH_SEPARATOR"
111
+ WHITESPACE = "WHITESPACE"
112
+ OTHER = "OTHER"
113
+
114
+
115
+ @mypyc_attr(allow_interpreted_subclasses=False)
116
+ class Token:
117
+ """SQL token with metadata."""
118
+
119
+ __slots__ = TOKEN_SLOTS
120
+
121
+ def __init__(self, type: TokenType, value: str, line: int, column: int, position: int) -> None:
122
+ self.type = type
123
+ self.value = value
124
+ self.line = line
125
+ self.column = column
126
+ self.position = position
127
+
128
+ def __repr__(self) -> str:
129
+ return f"Token({self.type.value}, {self.value!r}, {self.line}:{self.column})"
130
+
131
+
132
+ TokenHandler: TypeAlias = Callable[[str, int, int, int], Token | None]
133
+ TokenPattern: TypeAlias = str | TokenHandler
134
+ CompiledTokenPattern: TypeAlias = Pattern[str] | TokenHandler
135
+
136
+
137
+ @mypyc_attr(allow_interpreted_subclasses=False)
138
+ class DialectConfig(ABC):
139
+ """Abstract base class for SQL dialect configurations."""
140
+
141
+ __slots__ = DIALECT_CONFIG_SLOTS
142
+
143
+ def __init__(self) -> None:
144
+ """Initialize dialect configuration."""
145
+ self._name: str | None = None
146
+ self._block_starters: set[str] | None = None
147
+ self._block_enders: set[str] | None = None
148
+ self._statement_terminators: set[str] | None = None
149
+ self._batch_separators: set[str] | None = None
150
+ self._special_terminators: dict[str, Callable[[list[Token], int], bool]] | None = None
151
+ self._max_nesting_depth: int | None = None
152
+
153
+ @property
154
+ @abstractmethod
155
+ def name(self) -> str:
156
+ """Name of the dialect (e.g., 'oracle', 'tsql')."""
157
+
158
+ @property
159
+ @abstractmethod
160
+ def block_starters(self) -> "set[str]":
161
+ """Keywords that start a block (e.g., BEGIN, DECLARE)."""
162
+
163
+ @property
164
+ @abstractmethod
165
+ def block_enders(self) -> "set[str]":
166
+ """Keywords that end a block (e.g., END)."""
167
+
168
+ @property
169
+ @abstractmethod
170
+ def statement_terminators(self) -> "set[str]":
171
+ """Characters that terminate statements (e.g., ;)."""
172
+
173
+ @property
174
+ def batch_separators(self) -> "set[str]":
175
+ """Keywords that separate batches (e.g., GO for T-SQL)."""
176
+ if self._batch_separators is None:
177
+ self._batch_separators = set()
178
+ return self._batch_separators
179
+
180
+ @property
181
+ def special_terminators(self) -> "dict[str, Callable[[list[Token], int], bool]]":
182
+ """Special terminators that need custom handling."""
183
+ if self._special_terminators is None:
184
+ self._special_terminators = {}
185
+ return self._special_terminators
186
+
187
+ @property
188
+ def max_nesting_depth(self) -> int:
189
+ """Maximum allowed nesting depth for blocks."""
190
+ if self._max_nesting_depth is None:
191
+ self._max_nesting_depth = 256
192
+ return self._max_nesting_depth
193
+
194
+ def get_all_token_patterns(self) -> "list[tuple[TokenType, TokenPattern]]":
195
+ """Get the complete ordered list of token patterns for this dialect.
196
+
197
+ Returns:
198
+ List of tuples containing token types and their regex patterns
199
+ """
200
+ patterns: list[tuple[TokenType, TokenPattern]] = [
201
+ (TokenType.COMMENT_LINE, r"--[^\n]*"),
202
+ (TokenType.COMMENT_BLOCK, r"/\*[\s\S]*?\*/"),
203
+ (TokenType.STRING_LITERAL, r"'(?:[^']|'')*'"),
204
+ (TokenType.QUOTED_IDENTIFIER, r'"[^"]*"|\[[^\]]*\]'),
205
+ ]
206
+
207
+ patterns.extend(self._get_dialect_specific_patterns())
208
+
209
+ all_keywords = self.block_starters | self.block_enders | self.batch_separators
210
+ if all_keywords:
211
+ sorted_keywords = sorted(all_keywords, key=len, reverse=True)
212
+ patterns.append((TokenType.KEYWORD, r"\b(" + "|".join(re.escape(kw) for kw in sorted_keywords) + r")\b"))
213
+
214
+ all_terminators = self.statement_terminators | set(self.special_terminators.keys())
215
+ if all_terminators:
216
+ patterns.append((TokenType.TERMINATOR, "|".join(re.escape(t) for t in all_terminators)))
217
+
218
+ patterns.extend([(TokenType.WHITESPACE, r"\s+"), (TokenType.OTHER, r".")])
219
+
220
+ return patterns
221
+
222
+ def _get_dialect_specific_patterns(self) -> "list[tuple[TokenType, TokenPattern]]":
223
+ """Get dialect-specific token patterns.
224
+
225
+ Returns:
226
+ List of dialect-specific token patterns
227
+ """
228
+ return []
229
+
230
+ @staticmethod
231
+ def is_real_block_ender(tokens: "list[Token]", current_pos: int) -> bool: # noqa: ARG004
232
+ """Check if END keyword represents an actual block terminator.
233
+
234
+ Args:
235
+ tokens: List of all tokens
236
+ current_pos: Position of END token
237
+
238
+ Returns:
239
+ True if END represents a block terminator, False otherwise
240
+ """
241
+ return True
242
+
243
+ def should_delay_semicolon_termination(self, tokens: "list[Token]", current_pos: int) -> bool:
244
+ """Check if semicolon termination should be delayed.
245
+
246
+ Args:
247
+ tokens: List of all tokens
248
+ current_pos: Current position in token list
249
+
250
+ Returns:
251
+ True if termination should be delayed, False otherwise
252
+ """
253
+ return False
254
+
255
+
256
+ class OracleDialectConfig(DialectConfig):
257
+ """Configuration for Oracle PL/SQL dialect."""
258
+
259
+ @property
260
+ def name(self) -> str:
261
+ if self._name is None:
262
+ self._name = "oracle"
263
+ return self._name
264
+
265
+ @property
266
+ def block_starters(self) -> "set[str]":
267
+ if self._block_starters is None:
268
+ self._block_starters = {"BEGIN", "DECLARE", "CASE"}
269
+ return self._block_starters
270
+
271
+ @property
272
+ def block_enders(self) -> "set[str]":
273
+ if self._block_enders is None:
274
+ self._block_enders = {"END"}
275
+ return self._block_enders
276
+
277
+ @property
278
+ def statement_terminators(self) -> "set[str]":
279
+ if self._statement_terminators is None:
280
+ self._statement_terminators = {";"}
281
+ return self._statement_terminators
282
+
283
+ @property
284
+ def special_terminators(self) -> "dict[str, Callable[[list[Token], int], bool]]":
285
+ if self._special_terminators is None:
286
+ self._special_terminators = {"/": self._handle_slash_terminator}
287
+ return self._special_terminators
288
+
289
+ def should_delay_semicolon_termination(self, tokens: "list[Token]", current_pos: int) -> bool:
290
+ """Check if semicolon termination should be delayed for Oracle slash terminators.
291
+
292
+ Args:
293
+ tokens: List of all tokens
294
+ current_pos: Current position in token list
295
+
296
+ Returns:
297
+ True if termination should be delayed, False otherwise
298
+ """
299
+ pos = current_pos - 1
300
+ while pos >= 0:
301
+ token = tokens[pos]
302
+ if token.type == TokenType.WHITESPACE:
303
+ pos -= 1
304
+ continue
305
+ if token.type == TokenType.KEYWORD and token.value.upper() == "END":
306
+ return self._has_upcoming_slash(tokens, current_pos)
307
+ break
308
+
309
+ return False
310
+
311
+ def _has_upcoming_slash(self, tokens: "list[Token]", current_pos: int) -> bool:
312
+ """Check if there's a slash terminator on its own line ahead.
313
+
314
+ Args:
315
+ tokens: List of all tokens
316
+ current_pos: Current position in token list
317
+
318
+ Returns:
319
+ True if slash terminator found on its own line, False otherwise
320
+ """
321
+ pos = current_pos + 1
322
+ found_newline = False
323
+
324
+ while pos < len(tokens):
325
+ token = tokens[pos]
326
+ if token.type == TokenType.WHITESPACE:
327
+ if "\n" in token.value:
328
+ found_newline = True
329
+ pos += 1
330
+ continue
331
+ if token.type == TokenType.TERMINATOR and token.value == "/":
332
+ return found_newline and self._handle_slash_terminator(tokens, pos)
333
+ if token.type in {TokenType.COMMENT_LINE, TokenType.COMMENT_BLOCK}:
334
+ pos += 1
335
+ continue
336
+ break
337
+
338
+ return False
339
+
340
+ @staticmethod
341
+ def is_real_block_ender(tokens: "list[Token]", current_pos: int) -> bool:
342
+ """Check if END keyword represents a block terminator in Oracle PL/SQL.
343
+
344
+ Args:
345
+ tokens: List of all tokens
346
+ current_pos: Position of END token
347
+
348
+ Returns:
349
+ True if END represents a block terminator, False otherwise
350
+ """
351
+ pos = current_pos + 1
352
+ while pos < len(tokens):
353
+ next_token = tokens[pos]
354
+
355
+ if next_token.type == TokenType.WHITESPACE:
356
+ pos += 1
357
+ continue
358
+ if next_token.type == TokenType.OTHER:
359
+ word_chars = []
360
+ word_pos = pos
361
+ while word_pos < len(tokens) and tokens[word_pos].type == TokenType.OTHER:
362
+ word_chars.append(tokens[word_pos].value)
363
+ word_pos += 1
364
+
365
+ word = "".join(word_chars).upper()
366
+ if word in {"IF", "LOOP", "CASE", "WHILE"}:
367
+ return False
368
+ break
369
+ return True
370
+
371
+ @staticmethod
372
+ def _handle_slash_terminator(tokens: "list[Token]", current_pos: int) -> bool:
373
+ """Check if Oracle slash terminator is properly positioned.
374
+
375
+ Oracle slash terminators must be on their own line with only
376
+ whitespace or comments preceding them on the same line.
377
+
378
+ Args:
379
+ tokens: List of all tokens
380
+ current_pos: Position of slash token
381
+
382
+ Returns:
383
+ True if slash is properly positioned, False otherwise
384
+ """
385
+ if current_pos == 0:
386
+ return True
387
+
388
+ pos = current_pos - 1
389
+ while pos >= 0:
390
+ token = tokens[pos]
391
+ if "\n" in token.value:
392
+ break
393
+ if token.type not in {TokenType.WHITESPACE, TokenType.COMMENT_LINE}:
394
+ return False
395
+ pos -= 1
396
+
397
+ return True
398
+
399
+
400
+ class TSQLDialectConfig(DialectConfig):
401
+ """Configuration for T-SQL (SQL Server) dialect."""
402
+
403
+ @property
404
+ def name(self) -> str:
405
+ if self._name is None:
406
+ self._name = "tsql"
407
+ return self._name
408
+
409
+ @property
410
+ def block_starters(self) -> "set[str]":
411
+ if self._block_starters is None:
412
+ self._block_starters = {"BEGIN", "TRY"}
413
+ return self._block_starters
414
+
415
+ @property
416
+ def block_enders(self) -> "set[str]":
417
+ if self._block_enders is None:
418
+ self._block_enders = {"END", "CATCH"}
419
+ return self._block_enders
420
+
421
+ @property
422
+ def statement_terminators(self) -> "set[str]":
423
+ if self._statement_terminators is None:
424
+ self._statement_terminators = {";"}
425
+ return self._statement_terminators
426
+
427
+ @property
428
+ def batch_separators(self) -> "set[str]":
429
+ if self._batch_separators is None:
430
+ self._batch_separators = {"GO"}
431
+ return self._batch_separators
432
+
433
+
434
+ class PostgreSQLDialectConfig(DialectConfig):
435
+ """Configuration for PostgreSQL dialect with dollar-quoted strings."""
436
+
437
+ @property
438
+ def name(self) -> str:
439
+ if self._name is None:
440
+ self._name = "postgresql"
441
+ return self._name
442
+
443
+ @property
444
+ def block_starters(self) -> "set[str]":
445
+ if self._block_starters is None:
446
+ self._block_starters = {"DECLARE", "CASE", "DO"}
447
+ return self._block_starters
448
+
449
+ @property
450
+ def block_enders(self) -> "set[str]":
451
+ if self._block_enders is None:
452
+ self._block_enders = {"END"}
453
+ return self._block_enders
454
+
455
+ @property
456
+ def statement_terminators(self) -> "set[str]":
457
+ if self._statement_terminators is None:
458
+ self._statement_terminators = {";"}
459
+ return self._statement_terminators
460
+
461
+ def _get_dialect_specific_patterns(self) -> "list[tuple[TokenType, TokenPattern]]":
462
+ """Get PostgreSQL-specific token patterns.
463
+
464
+ Returns:
465
+ List of dialect-specific token patterns
466
+ """
467
+ return [(TokenType.STRING_LITERAL, self._handle_dollar_quoted_string)]
468
+
469
+ @staticmethod
470
+ def _handle_dollar_quoted_string(text: str, position: int, line: int, column: int) -> Token | None:
471
+ """Handle PostgreSQL dollar-quoted string literals.
472
+
473
+ Parses dollar-quoted strings in the format $tag$content$tag$
474
+ where tag is optional.
475
+
476
+ Args:
477
+ text: The full SQL text being tokenized
478
+ position: Current position in the text
479
+ line: Current line number
480
+ column: Current column number
481
+
482
+ Returns:
483
+ Token representing the dollar-quoted string, or None if no match
484
+ """
485
+ start_match = re.match(r"\$([a-zA-Z_][a-zA-Z0-9_]*)?\$", text[position:])
486
+ if not start_match:
487
+ return None
488
+
489
+ tag = start_match.group(0)
490
+ content_start = position + len(tag)
491
+
492
+ try:
493
+ content_end = text.index(tag, content_start)
494
+ full_value = text[position : content_end + len(tag)]
495
+
496
+ return Token(type=TokenType.STRING_LITERAL, value=full_value, line=line, column=column, position=position)
497
+ except ValueError:
498
+ return None
499
+
500
+
501
+ class GenericDialectConfig(DialectConfig):
502
+ """Generic SQL dialect configuration for standard SQL."""
503
+
504
+ @property
505
+ def name(self) -> str:
506
+ if self._name is None:
507
+ self._name = "generic"
508
+ return self._name
509
+
510
+ @property
511
+ def block_starters(self) -> "set[str]":
512
+ if self._block_starters is None:
513
+ self._block_starters = {"BEGIN", "DECLARE", "CASE"}
514
+ return self._block_starters
515
+
516
+ @property
517
+ def block_enders(self) -> "set[str]":
518
+ if self._block_enders is None:
519
+ self._block_enders = {"END"}
520
+ return self._block_enders
521
+
522
+ @property
523
+ def statement_terminators(self) -> "set[str]":
524
+ if self._statement_terminators is None:
525
+ self._statement_terminators = {";"}
526
+ return self._statement_terminators
527
+
528
+
529
+ class MySQLDialectConfig(DialectConfig):
530
+ """Configuration for MySQL dialect."""
531
+
532
+ @property
533
+ def name(self) -> str:
534
+ if self._name is None:
535
+ self._name = "mysql"
536
+ return self._name
537
+
538
+ @property
539
+ def block_starters(self) -> "set[str]":
540
+ if self._block_starters is None:
541
+ self._block_starters = {"BEGIN", "DECLARE", "CASE"}
542
+ return self._block_starters
543
+
544
+ @property
545
+ def block_enders(self) -> "set[str]":
546
+ if self._block_enders is None:
547
+ self._block_enders = {"END"}
548
+ return self._block_enders
549
+
550
+ @property
551
+ def statement_terminators(self) -> "set[str]":
552
+ if self._statement_terminators is None:
553
+ self._statement_terminators = {";"}
554
+ return self._statement_terminators
555
+
556
+ @property
557
+ def special_terminators(self) -> "dict[str, Callable[[list[Token], int], bool]]":
558
+ if self._special_terminators is None:
559
+ self._special_terminators = {"\\g": _special_terminator_true, "\\G": _special_terminator_true}
560
+ return self._special_terminators
561
+
562
+
563
+ class SQLiteDialectConfig(DialectConfig):
564
+ """Configuration for SQLite dialect."""
565
+
566
+ @property
567
+ def name(self) -> str:
568
+ if self._name is None:
569
+ self._name = "sqlite"
570
+ return self._name
571
+
572
+ @property
573
+ def block_starters(self) -> "set[str]":
574
+ if self._block_starters is None:
575
+ self._block_starters = {"BEGIN", "CASE"}
576
+ return self._block_starters
577
+
578
+ @property
579
+ def block_enders(self) -> "set[str]":
580
+ if self._block_enders is None:
581
+ self._block_enders = {"END"}
582
+ return self._block_enders
583
+
584
+ @property
585
+ def statement_terminators(self) -> "set[str]":
586
+ if self._statement_terminators is None:
587
+ self._statement_terminators = {";"}
588
+ return self._statement_terminators
589
+
590
+
591
+ class DuckDBDialectConfig(DialectConfig):
592
+ """Configuration for DuckDB dialect."""
593
+
594
+ @property
595
+ def name(self) -> str:
596
+ if self._name is None:
597
+ self._name = "duckdb"
598
+ return self._name
599
+
600
+ @property
601
+ def block_starters(self) -> "set[str]":
602
+ if self._block_starters is None:
603
+ self._block_starters = {"BEGIN", "CASE"}
604
+ return self._block_starters
605
+
606
+ @property
607
+ def block_enders(self) -> "set[str]":
608
+ if self._block_enders is None:
609
+ self._block_enders = {"END"}
610
+ return self._block_enders
611
+
612
+ @property
613
+ def statement_terminators(self) -> "set[str]":
614
+ if self._statement_terminators is None:
615
+ self._statement_terminators = {";"}
616
+ return self._statement_terminators
617
+
618
+
619
+ class BigQueryDialectConfig(DialectConfig):
620
+ """Configuration for BigQuery dialect."""
621
+
622
+ @property
623
+ def name(self) -> str:
624
+ if self._name is None:
625
+ self._name = "bigquery"
626
+ return self._name
627
+
628
+ @property
629
+ def block_starters(self) -> "set[str]":
630
+ if self._block_starters is None:
631
+ self._block_starters = {"BEGIN", "CASE"}
632
+ return self._block_starters
633
+
634
+ @property
635
+ def block_enders(self) -> "set[str]":
636
+ if self._block_enders is None:
637
+ self._block_enders = {"END"}
638
+ return self._block_enders
639
+
640
+ @property
641
+ def statement_terminators(self) -> "set[str]":
642
+ if self._statement_terminators is None:
643
+ self._statement_terminators = {";"}
644
+ return self._statement_terminators
645
+
646
+
647
+ _pattern_cache: LRUCache | None = None
648
+ _result_cache: LRUCache | None = None
649
+ _cache_lock = threading.Lock()
650
+ _unknown_dialect_warning_lock = threading.Lock()
651
+ _warned_unknown_dialects: set[str] = set()
652
+
653
+
654
+ def _get_pattern_cache() -> LRUCache:
655
+ """Get or create the global pattern compilation cache.
656
+
657
+ Returns:
658
+ The pattern cache instance
659
+ """
660
+ global _pattern_cache
661
+ if _pattern_cache is None:
662
+ with _cache_lock:
663
+ if _pattern_cache is None:
664
+ _pattern_cache = LRUCache(max_size=DEFAULT_PATTERN_CACHE_SIZE, ttl_seconds=DEFAULT_CACHE_TTL)
665
+ return _pattern_cache
666
+
667
+
668
+ def _get_result_cache() -> LRUCache:
669
+ """Get or create the global result cache.
670
+
671
+ Returns:
672
+ The result cache instance
673
+ """
674
+ global _result_cache
675
+ if _result_cache is None:
676
+ with _cache_lock:
677
+ if _result_cache is None:
678
+ _result_cache = LRUCache(max_size=DEFAULT_RESULT_CACHE_SIZE, ttl_seconds=DEFAULT_CACHE_TTL)
679
+ return _result_cache
680
+
681
+
682
+ def _warn_unknown_dialect_once(dialect: "str | None") -> None:
683
+ """Emit the generic splitter fallback warning once per dialect."""
684
+ key = "<none>" if dialect is None else dialect.lower()
685
+ with _unknown_dialect_warning_lock:
686
+ if key in _warned_unknown_dialects:
687
+ return
688
+ _warned_unknown_dialects.add(key)
689
+ logger.warning("Unknown dialect '%s', using generic SQL splitter", dialect)
690
+
691
+
692
+ @mypyc_attr(allow_interpreted_subclasses=False)
693
+ class StatementSplitter:
694
+ """SQL script splitter with caching and dialect support."""
695
+
696
+ __slots__ = SPLITTER_SLOTS
697
+
698
+ def __init__(self, dialect: DialectConfig, strip_trailing_semicolon: bool = False) -> None:
699
+ """Initialize the statement splitter.
700
+
701
+ Args:
702
+ dialect: The SQL dialect configuration to use
703
+ strip_trailing_semicolon: Whether to remove trailing semicolons from statements
704
+ """
705
+ self._dialect = dialect
706
+ self._strip_trailing_semicolon = strip_trailing_semicolon
707
+ self._token_patterns = dialect.get_all_token_patterns()
708
+
709
+ self._pattern_cache_key = f"{dialect.name}:{hash(tuple(str(p) for _, p in self._token_patterns))}"
710
+
711
+ self._pattern_cache = _get_pattern_cache()
712
+ self._result_cache = _get_result_cache()
713
+
714
+ self._compiled_patterns = self._get_or_compile_patterns()
715
+
716
+ def _get_or_compile_patterns(self) -> "list[tuple[TokenType, CompiledTokenPattern]]":
717
+ """Get compiled regex patterns from cache or compile and cache them.
718
+
719
+ Returns:
720
+ List of compiled token patterns with their types
721
+ """
722
+ cache_key = CacheKey(("pattern", self._pattern_cache_key))
723
+
724
+ cached_patterns = self._pattern_cache.get(cache_key)
725
+ if cached_patterns is not None:
726
+ return cast("list[tuple[TokenType, CompiledTokenPattern]]", cached_patterns)
727
+
728
+ compiled: list[tuple[TokenType, CompiledTokenPattern]] = []
729
+ for token_type, pattern in self._token_patterns:
730
+ if isinstance(pattern, str):
731
+ compiled.append((token_type, re.compile(pattern, re.IGNORECASE | re.DOTALL)))
732
+ else:
733
+ compiled.append((token_type, pattern))
734
+
735
+ self._pattern_cache.put(cache_key, compiled)
736
+ return compiled
737
+
738
+ def _tokenize(self, sql: str) -> Generator[Token, None, None]:
739
+ """Tokenize SQL string into Token objects.
740
+
741
+ Args:
742
+ sql: The SQL string to tokenize
743
+
744
+ Yields:
745
+ Token objects representing the lexical elements
746
+ """
747
+ pos = 0
748
+ line = 1
749
+ line_start = 0
750
+ unmatched_count = 0
751
+ first_unmatched_pos: int | None = None
752
+ first_unmatched_snippet: str | None = None
753
+
754
+ while pos < len(sql):
755
+ matched = False
756
+
757
+ for token_type, pattern in self._compiled_patterns:
758
+ if callable(pattern):
759
+ column = pos - line_start + 1
760
+ token = pattern(sql, pos, line, column)
761
+ if token:
762
+ newlines = token.value.count("\n")
763
+ if newlines > 0:
764
+ line += newlines
765
+ last_newline = token.value.rfind("\n")
766
+ line_start = pos + last_newline + 1
767
+
768
+ yield token
769
+ pos += len(token.value)
770
+ matched = True
771
+ break
772
+ else:
773
+ match = pattern.match(sql, pos)
774
+ if match:
775
+ value = match.group(0)
776
+ column = pos - line_start + 1
777
+
778
+ newlines = value.count("\n")
779
+ if newlines > 0:
780
+ line += newlines
781
+ last_newline = value.rfind("\n")
782
+ line_start = pos + last_newline + 1
783
+
784
+ yield Token(type=token_type, value=value, line=line, column=column, position=pos)
785
+ pos = match.end()
786
+ matched = True
787
+ break
788
+
789
+ if not matched:
790
+ if unmatched_count == 0:
791
+ first_unmatched_pos = pos
792
+ first_unmatched_snippet = sql[pos : pos + _TOKENIZE_SNIPPET_LENGTH]
793
+ unmatched_count += 1
794
+ if unmatched_count <= _TOKENIZE_DEBUG_SAMPLE_LIMIT and logger.isEnabledFor(logging.DEBUG):
795
+ logger.debug(
796
+ "Failed to tokenize at position %d: %s", pos, sql[pos : pos + _TOKENIZE_SNIPPET_LENGTH]
797
+ )
798
+ pos += 1
799
+
800
+ if unmatched_count and logger.isEnabledFor(logging.DEBUG):
801
+ logger.debug(
802
+ "Tokenization skipped %d unmatched characters (first at %s: %s)",
803
+ unmatched_count,
804
+ first_unmatched_pos,
805
+ first_unmatched_snippet,
806
+ )
807
+
808
+ def split(self, sql: str) -> "list[str]":
809
+ """Split SQL script into individual statements.
810
+
811
+ Args:
812
+ sql: The SQL script to split
813
+
814
+ Returns:
815
+ List of individual SQL statements
816
+ """
817
+ script_hash = hash(sql)
818
+ cache_key = CacheKey(("split", self._dialect.name, script_hash, self._strip_trailing_semicolon))
819
+
820
+ cached_result = self._result_cache.get(cache_key)
821
+ if cached_result is not None:
822
+ return cast("list[str]", cached_result)
823
+
824
+ statements = self._do_split(sql)
825
+
826
+ self._result_cache.put(cache_key, statements)
827
+ return statements
828
+
829
+ def _do_split(self, sql: str) -> "list[str]":
830
+ """Perform the actual SQL script splitting logic.
831
+
832
+ Args:
833
+ sql: The SQL script to split
834
+
835
+ Returns:
836
+ List of individual SQL statements
837
+ """
838
+ statements = []
839
+ current_statement_tokens = []
840
+ string_writer_type = _get_librt_string_writer()
841
+ current_statement_writer = string_writer_type() if string_writer_type is not None else None
842
+ current_statement_chars: list[str] = []
843
+ current_statement_fragment_count = 0
844
+ block_stack = []
845
+
846
+ all_tokens = list(self._tokenize(sql))
847
+
848
+ for token_idx, token in enumerate(all_tokens):
849
+ current_statement_fragment_count += 1
850
+ if current_statement_writer is None:
851
+ current_statement_chars.append(token.value)
852
+ else:
853
+ current_statement_writer.write(token.value)
854
+
855
+ if token.type in {TokenType.WHITESPACE, TokenType.COMMENT_LINE, TokenType.COMMENT_BLOCK}:
856
+ current_statement_tokens.append(token)
857
+ continue
858
+
859
+ current_statement_tokens.append(token)
860
+ token_upper = token.value.upper()
861
+
862
+ if token.type == TokenType.KEYWORD:
863
+ if token_upper in self._dialect.block_starters:
864
+ block_stack.append(token_upper)
865
+ if len(block_stack) > self._dialect.max_nesting_depth:
866
+ msg = f"Maximum nesting depth ({self._dialect.max_nesting_depth}) exceeded"
867
+ raise ValueError(msg)
868
+ elif token_upper in self._dialect.block_enders:
869
+ if block_stack and self._dialect.is_real_block_ender(all_tokens, token_idx):
870
+ block_stack.pop()
871
+
872
+ is_terminator = False
873
+ if not block_stack:
874
+ if token.type == TokenType.TERMINATOR:
875
+ if token.value in self._dialect.statement_terminators:
876
+ should_delay = self._dialect.should_delay_semicolon_termination(all_tokens, token_idx)
877
+
878
+ if not should_delay and token.value == ";" and self._dialect.batch_separators:
879
+ should_delay = True
880
+
881
+ if not should_delay:
882
+ is_terminator = True
883
+ elif token.value in self._dialect.special_terminators:
884
+ handler = self._dialect.special_terminators[token.value]
885
+ if handler(all_tokens, token_idx):
886
+ is_terminator = True
887
+
888
+ elif token.type == TokenType.KEYWORD and token_upper in self._dialect.batch_separators:
889
+ is_terminator = True
890
+
891
+ if is_terminator:
892
+ if current_statement_writer is None:
893
+ statement = _join_string_fragments(current_statement_chars).strip()
894
+ else:
895
+ statement = cast("str", current_statement_writer.getvalue()).strip()
896
+
897
+ is_plsql_block = self._is_plsql_block(current_statement_tokens)
898
+
899
+ if (
900
+ self._strip_trailing_semicolon
901
+ and token.type == TokenType.TERMINATOR
902
+ and statement.endswith(token.value)
903
+ and not is_plsql_block
904
+ ):
905
+ statement = statement[: -len(token.value)].rstrip()
906
+
907
+ if statement and self._contains_executable_content(statement):
908
+ statements.append(statement)
909
+ current_statement_tokens = []
910
+ current_statement_writer = string_writer_type() if string_writer_type is not None else None
911
+ current_statement_chars = []
912
+ current_statement_fragment_count = 0
913
+
914
+ if current_statement_fragment_count:
915
+ if current_statement_writer is None:
916
+ statement = _join_string_fragments(current_statement_chars).strip()
917
+ else:
918
+ statement = cast("str", current_statement_writer.getvalue()).strip()
919
+ if statement and self._contains_executable_content(statement):
920
+ statements.append(statement)
921
+
922
+ return statements
923
+
924
+ @staticmethod
925
+ def _is_plsql_block(tokens: "list[Token]") -> bool:
926
+ """Check if the token list represents a PL/SQL block.
927
+
928
+ Args:
929
+ tokens: List of tokens to examine
930
+
931
+ Returns:
932
+ True if tokens represent a PL/SQL block, False otherwise
933
+ """
934
+ for token in tokens:
935
+ if token.type == TokenType.KEYWORD:
936
+ return token.value.upper() in {"BEGIN", "DECLARE"}
937
+ return False
938
+
939
+ def _contains_executable_content(self, statement: str) -> bool:
940
+ """Check if a statement contains executable content.
941
+
942
+ Args:
943
+ statement: The SQL statement to check
944
+
945
+ Returns:
946
+ True if statement contains non-whitespace/non-comment content
947
+ """
948
+ tokens = list(self._tokenize(statement))
949
+
950
+ for token in tokens:
951
+ if token.type not in {TokenType.WHITESPACE, TokenType.COMMENT_LINE, TokenType.COMMENT_BLOCK}:
952
+ return True
953
+
954
+ return False
955
+
956
+
957
+ def split_sql_script(script: str, dialect: str | None = None, strip_trailing_terminator: bool = False) -> "list[str]":
958
+ """Split SQL script into individual statements.
959
+
960
+ Args:
961
+ script: The SQL script to split
962
+ dialect: The SQL dialect name
963
+ strip_trailing_terminator: If True, remove trailing terminators from statements
964
+
965
+ Returns:
966
+ List of individual SQL statements
967
+ """
968
+ if dialect is None:
969
+ dialect = "generic"
970
+
971
+ dialect_configs = {
972
+ "generic": GenericDialectConfig(),
973
+ "oracle": OracleDialectConfig(),
974
+ "tsql": TSQLDialectConfig(),
975
+ "mssql": TSQLDialectConfig(),
976
+ "sqlserver": TSQLDialectConfig(),
977
+ "postgresql": PostgreSQLDialectConfig(),
978
+ "postgres": PostgreSQLDialectConfig(),
979
+ "paradedb": PostgreSQLDialectConfig(),
980
+ "pgvector": PostgreSQLDialectConfig(),
981
+ "mysql": MySQLDialectConfig(),
982
+ "sqlite": SQLiteDialectConfig(),
983
+ "duckdb": DuckDBDialectConfig(),
984
+ "bigquery": BigQueryDialectConfig(),
985
+ }
986
+
987
+ config = dialect_configs.get(dialect.lower())
988
+ if not config:
989
+ _warn_unknown_dialect_once(dialect)
990
+ config = GenericDialectConfig()
991
+
992
+ splitter = StatementSplitter(config, strip_trailing_semicolon=strip_trailing_terminator)
993
+ return splitter.split(script)
994
+
995
+
996
+ def clear_splitter_caches() -> None:
997
+ """Clear all splitter caches.
998
+
999
+ Clears both pattern and result caches to free memory.
1000
+ """
1001
+ pattern_cache = _get_pattern_cache()
1002
+ result_cache = _get_result_cache()
1003
+ pattern_cache.clear()
1004
+ result_cache.clear()
1005
+ with _unknown_dialect_warning_lock:
1006
+ _warned_unknown_dialects.clear()
1007
+
1008
+
1009
+ def get_splitter_cache_stats() -> "dict[str, Any]":
1010
+ """Get statistics from splitter caches.
1011
+
1012
+ Returns:
1013
+ Dictionary containing cache statistics
1014
+ """
1015
+ pattern_cache = _get_pattern_cache()
1016
+ result_cache = _get_result_cache()
1017
+
1018
+ return {
1019
+ "pattern_cache": {"size": pattern_cache.size(), "stats": pattern_cache.get_stats()},
1020
+ "result_cache": {"size": result_cache.size(), "stats": result_cache.get_stats()},
1021
+ }