iris-pgwire 1.2.32__tar.gz → 1.2.33__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 (111) hide show
  1. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/PKG-INFO +1 -1
  2. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/__init__.py +1 -1
  3. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/dbapi_executor.py +38 -3
  4. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/iris_executor.py +35 -1
  5. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/.gitignore +0 -0
  6. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/CHANGELOG.md +0 -0
  7. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/LICENSE +0 -0
  8. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/README.md +0 -0
  9. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/docs/VECTOR_PARAMETER_BINDING.md +0 -0
  10. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/examples/BI_TOOLS_SETUP.md +0 -0
  11. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/examples/async_sqlalchemy_demo.py +0 -0
  12. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/examples/bi_tools_demo.py +0 -0
  13. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/examples/client_demonstrations.py +0 -0
  14. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/examples/client_demos.py +0 -0
  15. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/examples/translation_api_demo.py +0 -0
  16. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/pyproject.toml +0 -0
  17. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/auth/__init__.py +0 -0
  18. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/auth/auth_selector.py +0 -0
  19. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/auth/gssapi_auth.py +0 -0
  20. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/auth/oauth_bridge.py +0 -0
  21. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/auth/scram.py +0 -0
  22. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/auth/wallet_credentials.py +0 -0
  23. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/backend_selector.py +0 -0
  24. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/bulk_executor.py +0 -0
  25. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/catalog/__init__.py +0 -0
  26. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/catalog/catalog_functions.py +0 -0
  27. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/catalog/catalog_router.py +0 -0
  28. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/catalog/oid_generator.py +0 -0
  29. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/catalog/pg_attrdef.py +0 -0
  30. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/catalog/pg_attribute.py +0 -0
  31. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/catalog/pg_class.py +0 -0
  32. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/catalog/pg_constraint.py +0 -0
  33. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/catalog/pg_index.py +0 -0
  34. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/catalog/pg_namespace.py +0 -0
  35. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/catalog/pg_type.py +0 -0
  36. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/column_validator.py +0 -0
  37. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/config_schema.py +0 -0
  38. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/constitutional.py +0 -0
  39. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/conversions/__init__.py +0 -0
  40. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/conversions/bulk_insert.py +0 -0
  41. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/conversions/date_horolog.py +0 -0
  42. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/conversions/ddl_idempotency.py +0 -0
  43. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/conversions/ddl_splitter.py +0 -0
  44. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/conversions/json_path.py +0 -0
  45. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/conversions/vector_syntax.py +0 -0
  46. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/copy_handler.py +0 -0
  47. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/csv_processor.py +0 -0
  48. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/dbapi_connection_pool.py +0 -0
  49. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/debug_tracer.py +0 -0
  50. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/health_checker.py +0 -0
  51. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/integratedml.py +0 -0
  52. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/iris_constructs.py +0 -0
  53. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/iris_log_handler.py +0 -0
  54. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/iris_user_management.py +0 -0
  55. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/models/__init__.py +0 -0
  56. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/models/backend_config.py +0 -0
  57. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/models/connection_pool_state.py +0 -0
  58. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/models/dbapi_connection.py +0 -0
  59. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/models/ipm_metadata.py +0 -0
  60. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/models/vector_query_request.py +0 -0
  61. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/observability.py +0 -0
  62. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/performance_monitor.py +0 -0
  63. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/protocol.py +0 -0
  64. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/quality/__init__.py +0 -0
  65. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/quality/__main__.py +0 -0
  66. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/quality/code_quality_validator.py +0 -0
  67. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/quality/documentation_validator.py +0 -0
  68. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/quality/package_metadata_validator.py +0 -0
  69. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/quality/security_validator.py +0 -0
  70. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/quality/validator.py +0 -0
  71. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/schema_mapper.py +0 -0
  72. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/server.py +0 -0
  73. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/__init__.py +0 -0
  74. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/alias_extractor.py +0 -0
  75. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/api.py +0 -0
  76. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/boolean_translator.py +0 -0
  77. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/cache.py +0 -0
  78. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/confidence_analyzer.py +0 -0
  79. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/config.py +0 -0
  80. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/copy_parser.py +0 -0
  81. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/date_translator.py +0 -0
  82. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/debug.py +0 -0
  83. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/default_values.py +0 -0
  84. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/enum_registry.py +0 -0
  85. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/enum_translator.py +0 -0
  86. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/error_handler.py +0 -0
  87. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/identifier_normalizer.py +0 -0
  88. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/interceptor.py +0 -0
  89. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/logging_config.py +0 -0
  90. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/mappings/__init__.py +0 -0
  91. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/mappings/constructs.py +0 -0
  92. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/mappings/datatypes.py +0 -0
  93. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/mappings/document_filters.py +0 -0
  94. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/mappings/functions.py +0 -0
  95. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/metrics.py +0 -0
  96. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/models.py +0 -0
  97. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/normalizer.py +0 -0
  98. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/parser.py +0 -0
  99. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/performance_monitor.py +0 -0
  100. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/pipeline.py +0 -0
  101. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/refiner.py +0 -0
  102. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/skipped_table_set.py +0 -0
  103. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/statement_filter.py +0 -0
  104. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/transaction_translator.py +0 -0
  105. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/translator.py +0 -0
  106. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/sql_translator/validator.py +0 -0
  107. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/testing/__init__.py +0 -0
  108. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/testing/base_fixture_builder.py +0 -0
  109. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/type_mapping.py +0 -0
  110. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/src/iris_pgwire/vector_metrics.py +0 -0
  111. {iris_pgwire-1.2.32 → iris_pgwire-1.2.33}/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.2.32
3
+ Version: 1.2.33
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.2.32"
9
+ __version__ = "1.2.33"
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
@@ -87,6 +87,35 @@ class DBAPIExecutor:
87
87
  """
88
88
  return re.sub(r"\$\d+", "?", sql)
89
89
 
90
+ def _convert_params_for_iris(self, params: Any) -> Any:
91
+ """
92
+ Convert parameters to IRIS-compatible formats.
93
+ Specifically handles ISO 8601 timestamps.
94
+ """
95
+ if params is None:
96
+ return None
97
+
98
+ if isinstance(params, (list, tuple)):
99
+ return [self._convert_value_for_iris(v) for v in params]
100
+
101
+ return self._convert_value_for_iris(params)
102
+
103
+ def _convert_value_for_iris(self, value: Any) -> Any:
104
+ """Helper to convert a single value."""
105
+ if isinstance(value, str):
106
+ # FR-004: Normalize ISO 8601 timestamp strings for IRIS
107
+ # Handles: YYYY-MM-DD[T ]HH:MM:SS[.fff][Z|[+-]HH:MM]
108
+ # IRIS rejects the 'T' and 'Z' or offset in %PosixTime/TIMESTAMP
109
+ import re
110
+
111
+ ts_match = re.match(
112
+ r"^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2}:\d{2}(?:\.\d+)?)(?:Z|[+-]\d{2}:?(\d{2})?)?$",
113
+ value,
114
+ )
115
+ if ts_match:
116
+ return f"{ts_match.group(1)} {ts_match.group(2)}"
117
+ return value
118
+
90
119
  async def execute_query(
91
120
  self, sql: str, params: tuple | None = None, session_id: str | None = None, **kwargs
92
121
  ) -> dict[str, Any]:
@@ -116,6 +145,9 @@ class DBAPIExecutor:
116
145
  # Translate placeholders ($1 -> ?)
117
146
  sql = self._translate_placeholders(sql)
118
147
 
148
+ # Convert parameters for IRIS (e.g., ISO 8601 timestamps)
149
+ converted_params = self._convert_params_for_iris(params)
150
+
119
151
  # Acquire connection from pool
120
152
  conn_wrapper = await self.pool.acquire()
121
153
 
@@ -134,8 +166,8 @@ class DBAPIExecutor:
134
166
  # For now, we log it.
135
167
  logger.debug(f"Session {session_id} using namespace {ns}")
136
168
 
137
- if params:
138
- cursor.execute(clean_sql, params)
169
+ if converted_params:
170
+ cursor.execute(clean_sql, converted_params)
139
171
  else:
140
172
  cursor.execute(clean_sql)
141
173
 
@@ -256,9 +288,12 @@ class DBAPIExecutor:
256
288
  # Pre-process parameters (e.g. convert lists to IRIS vector strings)
257
289
  final_params_list = []
258
290
  for p_set in params_list:
291
+ # Convert ISO 8601 timestamps and other formats
292
+ converted_p_set = self._convert_params_for_iris(p_set)
293
+
259
294
  processed_params = [
260
295
  "[" + ",".join(map(str, p)) + "]" if isinstance(p, list) else p
261
- for p in p_set
296
+ for p in converted_p_set
262
297
  ]
263
298
  final_params_list.append(tuple(processed_params))
264
299
 
@@ -1211,11 +1211,14 @@ class IRISExecutor:
1211
1211
 
1212
1212
  rows_affected = 0
1213
1213
  for row_params in params_list:
1214
+ # Normalize parameters for IRIS (e.g. ISO timestamps)
1215
+ normalized_row_params = self._normalize_parameters(row_params)
1216
+
1214
1217
  inline_sql = "N/A"
1215
1218
  try:
1216
1219
  # Build inline SQL by replacing ? placeholders with actual values
1217
1220
  inline_sql = normalized_sql
1218
- for param_value in row_params:
1221
+ for param_value in normalized_row_params:
1219
1222
  # Convert value to SQL literal
1220
1223
  if param_value is None:
1221
1224
  sql_literal = "NULL"
@@ -4384,3 +4387,34 @@ class IRISExecutor:
4384
4387
  except Exception as e:
4385
4388
  logger.warning("Vector query translation failed", error=str(e), sql=sql[:100])
4386
4389
  return sql # Return original if translation fails
4390
+
4391
+ def _convert_params_for_iris(self, params: Any) -> Any:
4392
+ """
4393
+ Convert parameters to IRIS-compatible formats.
4394
+ Specifically handles ISO 8601 timestamps.
4395
+ """
4396
+ if params is None:
4397
+ return None
4398
+
4399
+ if isinstance(params, (list, tuple)):
4400
+ return [self._convert_value_for_iris(v) for v in params]
4401
+
4402
+ return self._convert_value_for_iris(params)
4403
+
4404
+ def _convert_value_for_iris(self, value: Any) -> Any:
4405
+ """Helper to convert a single value."""
4406
+ if isinstance(value, str):
4407
+ # Check for ISO 8601 timestamp: 2026-01-29T21:27:38.111Z
4408
+ # or 2026-01-29T21:27:38.111+00:00
4409
+ # IRIS rejects the 'T' and 'Z' or offset in %PosixTime/TIMESTAMP
4410
+ if len(value) >= 19 and value[10] == "T":
4411
+ # Replace 'T' with space
4412
+ converted = value.replace("T", " ")
4413
+ # Remove 'Z' if present
4414
+ if converted.endswith("Z"):
4415
+ converted = converted[:-1]
4416
+ # Remove timezone offset if present (e.g., +00:00)
4417
+ if "+" in converted:
4418
+ converted = converted.split("+")[0]
4419
+ return converted
4420
+ return value
File without changes
File without changes
File without changes
File without changes