(
self, stmt, returning_cols, *, populate_result_map, **kw
)
| 2341 | return super().visit_binary(binary, **kwargs) |
| 2342 | |
| 2343 | def returning_clause( |
| 2344 | self, stmt, returning_cols, *, populate_result_map, **kw |
| 2345 | ): |
| 2346 | # SQL server returning clause requires that the columns refer to |
| 2347 | # the virtual table names "inserted" or "deleted". Here, we make |
| 2348 | # a simple alias of our table with that name, and then adapt the |
| 2349 | # columns we have from the list of RETURNING columns to that new name |
| 2350 | # so that they render as "inserted.<colname>" / "deleted.<colname>". |
| 2351 | |
| 2352 | if stmt.is_insert or stmt.is_update: |
| 2353 | target = stmt.table.alias("inserted") |
| 2354 | elif stmt.is_delete: |
| 2355 | target = stmt.table.alias("deleted") |
| 2356 | else: |
| 2357 | assert False, "expected Insert, Update or Delete statement" |
| 2358 | |
| 2359 | adapter = sql_util.ClauseAdapter(target) |
| 2360 | |
| 2361 | # adapter.traverse() takes a column from our target table and returns |
| 2362 | # the one that is linked to the "inserted" / "deleted" tables. So in |
| 2363 | # order to retrieve these values back from the result (e.g. like |
| 2364 | # row[column]), tell the compiler to also add the original unadapted |
| 2365 | # column to the result map. Before #4877, these were (unknowingly) |
| 2366 | # falling back using string name matching in the result set which |
| 2367 | # necessarily used an expensive KeyError in order to match. |
| 2368 | |
| 2369 | columns = [ |
| 2370 | self._label_returning_column( |
| 2371 | stmt, |
| 2372 | adapter.traverse(column), |
| 2373 | populate_result_map, |
| 2374 | {"result_map_targets": (column,)}, |
| 2375 | fallback_label_name=fallback_label_name, |
| 2376 | column_is_repeated=repeated, |
| 2377 | name=name, |
| 2378 | proxy_name=proxy_name, |
| 2379 | **kw, |
| 2380 | ) |
| 2381 | for ( |
| 2382 | name, |
| 2383 | proxy_name, |
| 2384 | fallback_label_name, |
| 2385 | column, |
| 2386 | repeated, |
| 2387 | ) in stmt._generate_columns_plus_names( |
| 2388 | True, cols=expression._select_iterables(returning_cols) |
| 2389 | ) |
| 2390 | ] |
| 2391 | |
| 2392 | return "OUTPUT " + ", ".join(columns) |
| 2393 | |
| 2394 | def get_cte_preamble(self, recursive): |
| 2395 | # SQL Server finds it too inconvenient to accept |
nothing calls this directly
no test coverage detected