| 261 | |
| 262 | |
| 263 | class DialectSQL(CompiledSQL): |
| 264 | def _compile_dialect(self, execute_observed): |
| 265 | return execute_observed.context.dialect |
| 266 | |
| 267 | def _compare_no_space(self, real_stmt, received_stmt): |
| 268 | stmt = re.sub(r"[\n\t]", "", real_stmt) |
| 269 | return received_stmt == stmt |
| 270 | |
| 271 | def _received_statement(self, execute_observed): |
| 272 | received_stmt, received_params = super()._received_statement( |
| 273 | execute_observed |
| 274 | ) |
| 275 | |
| 276 | # TODO: why do we need this part? |
| 277 | for real_stmt in execute_observed.statements: |
| 278 | if self._compare_no_space( |
| 279 | real_stmt.context.statement, received_stmt |
| 280 | ): |
| 281 | break |
| 282 | else: |
| 283 | raise AssertionError( |
| 284 | "Can't locate compiled statement %r in list of " |
| 285 | "statements actually invoked" % received_stmt |
| 286 | ) |
| 287 | |
| 288 | return received_stmt, execute_observed.context.compiled_parameters |
| 289 | |
| 290 | def _dialect_adjusted_statement(self, dialect): |
| 291 | paramstyle = dialect.paramstyle |
| 292 | stmt = re.sub(r"[\n\t]", "", self.statement) |
| 293 | |
| 294 | # temporarily escape out PG double colons |
| 295 | stmt = stmt.replace("::", "!!") |
| 296 | |
| 297 | if paramstyle == "pyformat": |
| 298 | stmt = re.sub(r":([\w_]+)", r"%(\1)s", stmt) |
| 299 | else: |
| 300 | # positional params |
| 301 | repl = None |
| 302 | if paramstyle == "qmark": |
| 303 | repl = "?" |
| 304 | elif paramstyle == "format": |
| 305 | repl = r"%s" |
| 306 | elif paramstyle.startswith("numeric"): |
| 307 | counter = itertools.count(1) |
| 308 | |
| 309 | num_identifier = "$" if paramstyle == "numeric_dollar" else ":" |
| 310 | |
| 311 | def repl(m): |
| 312 | return f"{num_identifier}{next(counter)}" |
| 313 | |
| 314 | stmt = re.sub(r":([\w_]+)", repl, stmt) |
| 315 | |
| 316 | # put them back |
| 317 | stmt = stmt.replace("!!", "::") |
| 318 | |
| 319 | return stmt |
| 320 |
no outgoing calls