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