iris-pgwire 1.5.4__tar.gz → 1.5.6__tar.gz

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 (119) hide show
  1. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/PKG-INFO +1 -1
  2. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/__init__.py +1 -1
  3. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/iris_executor.py +32 -7
  4. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/protocol.py +18 -3
  5. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/.gitignore +0 -0
  6. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/LICENSE +0 -0
  7. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/README.md +0 -0
  8. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/pyproject.toml +0 -0
  9. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/_column_naming.py +0 -0
  10. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/_noop_cursor.py +0 -0
  11. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/_result_processing.py +0 -0
  12. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/_type_mapping.py +0 -0
  13. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/auth/__init__.py +0 -0
  14. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/auth/auth_selector.py +0 -0
  15. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/auth/gssapi_auth.py +0 -0
  16. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/auth/oauth_bridge.py +0 -0
  17. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/auth/scram.py +0 -0
  18. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/auth/wallet_credentials.py +0 -0
  19. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/backend_selector.py +0 -0
  20. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/bulk_executor.py +0 -0
  21. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/catalog/__init__.py +0 -0
  22. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/catalog/catalog_functions.py +0 -0
  23. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/catalog/catalog_router.py +0 -0
  24. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/catalog/oid_generator.py +0 -0
  25. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/catalog/pg_attrdef.py +0 -0
  26. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/catalog/pg_attribute.py +0 -0
  27. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/catalog/pg_class.py +0 -0
  28. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/catalog/pg_constraint.py +0 -0
  29. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/catalog/pg_index.py +0 -0
  30. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/catalog/pg_namespace.py +0 -0
  31. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/catalog/pg_type.py +0 -0
  32. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/column_validator.py +0 -0
  33. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/config.py +0 -0
  34. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/config_schema.py +0 -0
  35. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/constitutional.py +0 -0
  36. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/conversions/__init__.py +0 -0
  37. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/conversions/bulk_insert.py +0 -0
  38. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/conversions/date_horolog.py +0 -0
  39. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/conversions/ddl_idempotency.py +0 -0
  40. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/conversions/ddl_splitter.py +0 -0
  41. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/conversions/json_path.py +0 -0
  42. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/conversions/vector_syntax.py +0 -0
  43. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/copy_handler.py +0 -0
  44. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/csv_processor.py +0 -0
  45. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/dbapi_connection_pool.py +0 -0
  46. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/dbapi_executor.py +0 -0
  47. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/debug_tracer.py +0 -0
  48. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/health_checker.py +0 -0
  49. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/integratedml.py +0 -0
  50. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/iris_constructs.py +0 -0
  51. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/iris_log_handler.py +0 -0
  52. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/iris_user_management.py +0 -0
  53. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/migrations/__init__.py +0 -0
  54. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/migrations/__main__.py +0 -0
  55. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/migrations/executor.py +0 -0
  56. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/models/__init__.py +0 -0
  57. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/models/backend_config.py +0 -0
  58. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/models/connection_pool_state.py +0 -0
  59. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/models/dbapi_connection.py +0 -0
  60. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/models/ipm_metadata.py +0 -0
  61. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/models/vector_query_request.py +0 -0
  62. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/observability.py +0 -0
  63. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/performance_monitor.py +0 -0
  64. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/quality/__init__.py +0 -0
  65. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/quality/__main__.py +0 -0
  66. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/quality/code_quality_validator.py +0 -0
  67. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/quality/documentation_validator.py +0 -0
  68. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/quality/package_metadata_validator.py +0 -0
  69. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/quality/security_validator.py +0 -0
  70. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/quality/validator.py +0 -0
  71. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/schema_mapper.py +0 -0
  72. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/server.py +0 -0
  73. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/__init__.py +0 -0
  74. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/alias_extractor.py +0 -0
  75. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/api.py +0 -0
  76. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/boolean_translator.py +0 -0
  77. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/cache.py +0 -0
  78. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/confidence_analyzer.py +0 -0
  79. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/config.py +0 -0
  80. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/constraint_translator.py +0 -0
  81. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/copy_parser.py +0 -0
  82. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/date_translator.py +0 -0
  83. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/ddl_parser.py +0 -0
  84. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/ddl_translator.py +0 -0
  85. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/debug.py +0 -0
  86. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/default_values.py +0 -0
  87. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/enum_registry.py +0 -0
  88. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/enum_translator.py +0 -0
  89. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/error_handler.py +0 -0
  90. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/identifier_normalizer.py +0 -0
  91. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/index_validator.py +0 -0
  92. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/interceptor.py +0 -0
  93. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/logging_config.py +0 -0
  94. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/mappings/__init__.py +0 -0
  95. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/mappings/constructs.py +0 -0
  96. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/mappings/datatypes.py +0 -0
  97. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/mappings/document_filters.py +0 -0
  98. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/mappings/functions.py +0 -0
  99. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/metadata_cache.py +0 -0
  100. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/metrics.py +0 -0
  101. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/models.py +0 -0
  102. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/normalizer.py +0 -0
  103. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/parser.py +0 -0
  104. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/performance_monitor.py +0 -0
  105. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/pipeline.py +0 -0
  106. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/refiner.py +0 -0
  107. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/reserved_words.py +0 -0
  108. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/returning_plan.py +0 -0
  109. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/skipped_table_set.py +0 -0
  110. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/statement_filter.py +0 -0
  111. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/transaction_translator.py +0 -0
  112. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/translator.py +0 -0
  113. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/type_translator.py +0 -0
  114. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/sql_translator/validator.py +0 -0
  115. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/testing/__init__.py +0 -0
  116. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/testing/base_fixture_builder.py +0 -0
  117. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/type_mapping.py +0 -0
  118. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/vector_metrics.py +0 -0
  119. {iris_pgwire-1.5.4 → iris_pgwire-1.5.6}/src/iris_pgwire/vector_optimizer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iris-pgwire
3
- Version: 1.5.4
3
+ Version: 1.5.6
4
4
  Summary: PostgreSQL Wire Protocol Server for InterSystems IRIS - Connect BI tools, Python frameworks, and PostgreSQL clients to IRIS databases
5
5
  Project-URL: Homepage, https://github.com/intersystems-community/iris-pgwire
6
6
  Project-URL: Documentation, https://github.com/intersystems-community/iris-pgwire#readme
@@ -6,7 +6,7 @@ Based on the specification from docs/iris_pgwire_plan.md and proven patterns fro
6
6
  caretdev/sqlalchemy-iris.
7
7
  """
8
8
 
9
- __version__ = "1.5.4"
9
+ __version__ = "1.5.6"
10
10
  __author__ = "Thomas Dyar <thomas.dyar@intersystems.com>"
11
11
 
12
12
  # Don't import server/protocol in __init__ to avoid sys.modules conflicts
@@ -627,6 +627,7 @@ class IRISExecutor:
627
627
  params: list | None,
628
628
  execution_path: str,
629
629
  session_id: str | None = None,
630
+ original_sql: str | None = None,
630
631
  ) -> tuple[str, list | None, "ReturningPlan", float]:
631
632
  """
632
633
  Shared pre-execution pipeline (steps 1–7) used by both embedded and external paths.
@@ -678,8 +679,12 @@ class IRISExecutor:
678
679
  t_opt_elapsed = (time.perf_counter() - t_opt_start) * 1000
679
680
 
680
681
  # 5. RETURNING / ON CONFLICT parsing
682
+ # Use original_sql (pre-translation) for RETURNING detection when available.
683
+ # translated sql (optimized_sql) has the RETURNING clause stripped because IRIS
684
+ # doesn't support it natively — so ReturningPlan must inspect the original.
685
+ _sql_for_plan = original_sql if original_sql else optimized_sql
681
686
  plan = ReturningPlan.from_sql(
682
- optimized_sql,
687
+ _sql_for_plan,
683
688
  metadata_cache=self.metadata_cache,
684
689
  executor=self,
685
690
  )
@@ -998,10 +1003,14 @@ class IRISExecutor:
998
1003
  )
999
1004
  if self.embedded_mode:
1000
1005
  logger.warning("🔍 DEBUG: Taking EMBEDDED path → _execute_embedded_async()")
1001
- result = await self._execute_embedded_async(sql, params, session_id)
1006
+ result = await self._execute_embedded_async(
1007
+ sql, params, session_id, original_sql=kwargs.get("original_sql")
1008
+ )
1002
1009
  else:
1003
1010
  logger.warning("🔍 DEBUG: Taking EXTERNAL path → _execute_external_async()")
1004
- result = await self._execute_external_async(sql, params, session_id)
1011
+ result = await self._execute_external_async(
1012
+ sql, params, session_id, original_sql=kwargs.get("original_sql")
1013
+ )
1005
1014
 
1006
1015
  # Feature 026: Handle DDL idempotency (IF NOT EXISTS)
1007
1016
  # Check both for raised exceptions and for success=False results
@@ -2292,7 +2301,11 @@ class IRISExecutor:
2292
2301
  return rows, columns
2293
2302
 
2294
2303
  async def _execute_embedded_async(
2295
- self, sql: str, params: list | None = None, session_id: str | None = None
2304
+ self,
2305
+ sql: str,
2306
+ params: list | None = None,
2307
+ session_id: str | None = None,
2308
+ original_sql: str | None = None,
2296
2309
  ) -> dict[str, Any]:
2297
2310
  """Execute query in IRIS embedded Python environment (async wrapper)"""
2298
2311
 
@@ -2354,7 +2367,11 @@ class IRISExecutor:
2354
2367
 
2355
2368
  # Steps 1-7: Shared pre-execution pipeline
2356
2369
  optimized_sql, optimized_params, plan, t_opt_elapsed = self._prepare_sql(
2357
- sql, params, execution_path="direct", session_id=session_id
2370
+ sql,
2371
+ params,
2372
+ execution_path="direct",
2373
+ session_id=session_id,
2374
+ original_sql=original_sql,
2358
2375
  )
2359
2376
  optimized_sql_upper = optimized_sql.upper()
2360
2377
  returning_operation = plan.operation
@@ -2883,7 +2900,11 @@ class IRISExecutor:
2883
2900
  return rows, columns
2884
2901
 
2885
2902
  async def _execute_external_async(
2886
- self, sql: str, params: list | None = None, session_id: str | None = None
2903
+ self,
2904
+ sql: str,
2905
+ params: list | None = None,
2906
+ session_id: str | None = None,
2907
+ original_sql: str | None = None,
2887
2908
  ) -> dict[str, Any]:
2888
2909
  """
2889
2910
  Execute SQL using external IRIS connection with proper async threading
@@ -2910,7 +2931,11 @@ class IRISExecutor:
2910
2931
 
2911
2932
  # Steps 1-7: Shared pre-execution pipeline
2912
2933
  optimized_sql, optimized_params, plan, t_opt_elapsed = self._prepare_sql(
2913
- sql, params, execution_path="external", session_id=session_id
2934
+ sql,
2935
+ params,
2936
+ execution_path="external",
2937
+ session_id=session_id,
2938
+ original_sql=original_sql,
2914
2939
  )
2915
2940
  optimized_sql_upper = optimized_sql.upper()
2916
2941
 
@@ -2930,10 +2930,14 @@ class PGWireProtocol:
2930
2930
  # For SELECT/SHOW statements, send RowDescription with column metadata
2931
2931
  # For DDL/DML statements, send NoData
2932
2932
  query = stmt.get("translated_query", stmt.get("query", ""))
2933
+ # Use original_query for RETURNING detection: the translation pipeline
2934
+ # strips RETURNING before storing translated_query (IRIS doesn't support it
2935
+ # natively), so has_returning would always be False if we use translated_query.
2936
+ original_query = stmt.get("original_query", query)
2933
2937
  query_upper = query.strip().upper()
2934
2938
 
2935
2939
  plan = ReturningPlan.from_sql(
2936
- query,
2940
+ original_query,
2937
2941
  metadata_cache=self.iris_executor.metadata_cache,
2938
2942
  executor=self.iris_executor,
2939
2943
  )
@@ -3081,10 +3085,13 @@ class PGWireProtocol:
3081
3085
 
3082
3086
  stmt = self.prepared_statements[statement_name]
3083
3087
  query = stmt.get("translated_query", stmt.get("query", ""))
3088
+ # Use original_query for RETURNING detection: translated_query has the
3089
+ # RETURNING clause stripped (IRIS doesn't support it natively).
3090
+ original_query = stmt.get("original_query", query)
3084
3091
  query_upper = query.strip().upper()
3085
3092
 
3086
3093
  plan = ReturningPlan.from_sql(
3087
- query,
3094
+ original_query,
3088
3095
  metadata_cache=self.iris_executor.metadata_cache,
3089
3096
  executor=self.iris_executor,
3090
3097
  )
@@ -3305,6 +3312,9 @@ class PGWireProtocol:
3305
3312
 
3306
3313
  # Use translated query for execution
3307
3314
  query = stmt.get("translated_query", stmt.get("query", stmt.get("original_query", "")))
3315
+ # Use original_query for RETURNING detection: translated_query has RETURNING stripped.
3316
+ # has_returning check below decides whether to fast-batch (DML without RETURNING).
3317
+ original_query = stmt.get("original_query", query)
3308
3318
 
3309
3319
  # Log execution of prepared statement with translation metadata
3310
3320
  translation_metadata = stmt.get("translation_metadata", {})
@@ -3387,7 +3397,11 @@ class PGWireProtocol:
3387
3397
  # Standard PostgreSQL clients (psycopg3) send Sync every 5 rows, which is slow.
3388
3398
  # We buffer parameters and send synthetic CommandComplete to keep client pipe full.
3389
3399
  is_dml = self.iris_executor.sql_parser.is_dml_statement(query)
3390
- has_returning = self.iris_executor.sql_parser.has_returning_clause(query)
3400
+ # Use original_query for RETURNING detection: translated_query has RETURNING stripped.
3401
+ # If we used query (translated) here, INSERT...RETURNING would be fast-batched
3402
+ # (because has_returning=False on translated_query), INSERT would execute but
3403
+ # zero DataRows would be returned to the client.
3404
+ has_returning = self.iris_executor.sql_parser.has_returning_clause(original_query)
3391
3405
 
3392
3406
  if is_dml and not has_returning:
3393
3407
  # Store SQL if first row in batch
@@ -3425,6 +3439,7 @@ class PGWireProtocol:
3425
3439
  session_id=self.connection_id,
3426
3440
  in_transaction=in_txn,
3427
3441
  autocommit=autocommit,
3442
+ original_sql=original_query,
3428
3443
  )
3429
3444
 
3430
3445
  if result["success"]:
File without changes
File without changes
File without changes
File without changes