supertable 2.3.8__tar.gz → 2.3.9__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 (194) hide show
  1. {supertable-2.3.8/supertable.egg-info → supertable-2.3.9}/PKG-INFO +1 -1
  2. {supertable-2.3.8 → supertable-2.3.9}/pyproject.toml +1 -1
  3. {supertable-2.3.8 → supertable-2.3.9}/setup.py +1 -1
  4. {supertable-2.3.8 → supertable-2.3.9}/supertable/__init__.py +1 -1
  5. {supertable-2.3.8 → supertable-2.3.9}/supertable/config/settings.py +9 -0
  6. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/engine_common.py +45 -3
  7. {supertable-2.3.8 → supertable-2.3.9/supertable.egg-info}/PKG-INFO +1 -1
  8. {supertable-2.3.8 → supertable-2.3.9}/LICENSE +0 -0
  9. {supertable-2.3.8 → supertable-2.3.9}/README.md +0 -0
  10. {supertable-2.3.8 → supertable-2.3.9}/requirements.txt +0 -0
  11. {supertable-2.3.8 → supertable-2.3.9}/setup.cfg +0 -0
  12. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/__init__.py +0 -0
  13. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/admin.py +0 -0
  14. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/chain.py +0 -0
  15. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/consumers.py +0 -0
  16. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/crypto.py +0 -0
  17. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/events.py +0 -0
  18. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/export.py +0 -0
  19. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/logger.py +0 -0
  20. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/middleware.py +0 -0
  21. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/reader.py +0 -0
  22. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/retention.py +0 -0
  23. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/tests/__init__.py +0 -0
  24. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/tests/test_chain.py +0 -0
  25. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/tests/test_crypto.py +0 -0
  26. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/tests/test_emit.py +0 -0
  27. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/tests/test_events.py +0 -0
  28. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/tests/test_retention.py +0 -0
  29. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/writer_parquet.py +0 -0
  30. {supertable-2.3.8 → supertable-2.3.9}/supertable/audit/writer_redis.py +0 -0
  31. {supertable-2.3.8 → supertable-2.3.9}/supertable/config/__init__.py +0 -0
  32. {supertable-2.3.8 → supertable-2.3.9}/supertable/config/defaults.py +0 -0
  33. {supertable-2.3.8 → supertable-2.3.9}/supertable/config/homedir.py +0 -0
  34. {supertable-2.3.8 → supertable-2.3.9}/supertable/config/tests/__init__.py +0 -0
  35. {supertable-2.3.8 → supertable-2.3.9}/supertable/config/tests/test_defaults.py +0 -0
  36. {supertable-2.3.8 → supertable-2.3.9}/supertable/config/tests/test_homedir.py +0 -0
  37. {supertable-2.3.8 → supertable-2.3.9}/supertable/config/tests/test_settings.py +0 -0
  38. {supertable-2.3.8 → supertable-2.3.9}/supertable/data_classes.py +0 -0
  39. {supertable-2.3.8 → supertable-2.3.9}/supertable/data_reader.py +0 -0
  40. {supertable-2.3.8 → supertable-2.3.9}/supertable/data_writer.py +0 -0
  41. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/__init__.py +0 -0
  42. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/__init__.py +0 -0
  43. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/__main__.py +0 -0
  44. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/check_filter_builder.py +0 -0
  45. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/controller.py +0 -0
  46. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/data_writer_helpers.py +0 -0
  47. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/defaults.py +0 -0
  48. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/dummy_data.py +0 -0
  49. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/read_parquet_header.py +0 -0
  50. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s01_01_01_create_super_table.py +0 -0
  51. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s01_01_02_enable_mirroring_formats.py +0 -0
  52. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s01_02_create_roles.py +0 -0
  53. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s01_03_create_users.py +0 -0
  54. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s02_01_write_dummy_data.py +0 -0
  55. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s02_02_write_single_data.py +0 -0
  56. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s02_03_01_write_staging.py +0 -0
  57. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s02_03_02_create_pipe.py +0 -0
  58. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s02_04_01_write_monitoring_simple.py +0 -0
  59. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s02_04_02_write_monitoring_parallel.py +0 -0
  60. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s02_05_write_tombstone.py +0 -0
  61. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s03_01_read_data_error.py +0 -0
  62. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s03_02_01_read_super_data_ok.py +0 -0
  63. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s03_02_02_read_table_data_ok.py +0 -0
  64. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s03_03_read_meta.py +0 -0
  65. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s03_04_read_staging.py +0 -0
  66. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s03_06_01_read_roles.py +0 -0
  67. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s03_06_02_read_user.py +0 -0
  68. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s03_07_01_estimate_read.py +0 -0
  69. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s03_07_02_estimate_files.py +0 -0
  70. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s03_08_read_snapshot_history.py +0 -0
  71. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s04_01_03_delete_pipe.py +0 -0
  72. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s05_01_delete_table.py +0 -0
  73. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/quickstart/s05_02_delete_super_table.py +0 -0
  74. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/webshop/__init__.py +0 -0
  75. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/webshop/core.py +0 -0
  76. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/webshop/defaults.py +0 -0
  77. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/webshop/generate.py +0 -0
  78. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/webshop/load.py +0 -0
  79. {supertable-2.3.8 → supertable-2.3.9}/supertable/demo/webshop/topup.py +0 -0
  80. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/__init__.py +0 -0
  81. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/data_estimator.py +0 -0
  82. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/duckdb_lite.py +0 -0
  83. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/duckdb_pro.py +0 -0
  84. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/engine_config.py +0 -0
  85. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/engine_enum.py +0 -0
  86. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/executor.py +0 -0
  87. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/plan_stats.py +0 -0
  88. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/spark_thrift.py +0 -0
  89. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/tests/__init__.py +0 -0
  90. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/tests/conftest.py +0 -0
  91. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/tests/test_engine.py +0 -0
  92. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/tests/test_engine_config.py +0 -0
  93. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/tests/test_engine_routing.py +0 -0
  94. {supertable-2.3.8 → supertable-2.3.9}/supertable/engine/tests/test_engine_spill.py +0 -0
  95. {supertable-2.3.8 → supertable-2.3.9}/supertable/errors.py +0 -0
  96. {supertable-2.3.8 → supertable-2.3.9}/supertable/locking/__init__.py +0 -0
  97. {supertable-2.3.8 → supertable-2.3.9}/supertable/locking/benchmarks/__init__.py +0 -0
  98. {supertable-2.3.8 → supertable-2.3.9}/supertable/locking/benchmarks/benchmark_locking.py +0 -0
  99. {supertable-2.3.8 → supertable-2.3.9}/supertable/locking/benchmarks/measure_lock_speed.py +0 -0
  100. {supertable-2.3.8 → supertable-2.3.9}/supertable/locking/benchmarks/measure_lock_time.py +0 -0
  101. {supertable-2.3.8 → supertable-2.3.9}/supertable/locking/file_lock.py +0 -0
  102. {supertable-2.3.8 → supertable-2.3.9}/supertable/locking/redis_lock.py +0 -0
  103. {supertable-2.3.8 → supertable-2.3.9}/supertable/locking/tests/__init__.py +0 -0
  104. {supertable-2.3.8 → supertable-2.3.9}/supertable/locking/tests/test_file_lock.py +0 -0
  105. {supertable-2.3.8 → supertable-2.3.9}/supertable/locking/tests/test_redis_lock.py +0 -0
  106. {supertable-2.3.8 → supertable-2.3.9}/supertable/logging.py +0 -0
  107. {supertable-2.3.8 → supertable-2.3.9}/supertable/meta_reader.py +0 -0
  108. {supertable-2.3.8 → supertable-2.3.9}/supertable/mirroring/__init__.py +0 -0
  109. {supertable-2.3.8 → supertable-2.3.9}/supertable/mirroring/mirror_delta.py +0 -0
  110. {supertable-2.3.8 → supertable-2.3.9}/supertable/mirroring/mirror_formats.py +0 -0
  111. {supertable-2.3.8 → supertable-2.3.9}/supertable/mirroring/mirror_iceberg.py +0 -0
  112. {supertable-2.3.8 → supertable-2.3.9}/supertable/mirroring/mirror_parquet.py +0 -0
  113. {supertable-2.3.8 → supertable-2.3.9}/supertable/monitoring/__init__.py +0 -0
  114. {supertable-2.3.8 → supertable-2.3.9}/supertable/monitoring/partitions.py +0 -0
  115. {supertable-2.3.8 → supertable-2.3.9}/supertable/monitoring_writer.py +0 -0
  116. {supertable-2.3.8 → supertable-2.3.9}/supertable/plan_extender.py +0 -0
  117. {supertable-2.3.8 → supertable-2.3.9}/supertable/processing.py +0 -0
  118. {supertable-2.3.8 → supertable-2.3.9}/supertable/quality/__init__.py +0 -0
  119. {supertable-2.3.8 → supertable-2.3.9}/supertable/quality/anomaly.py +0 -0
  120. {supertable-2.3.8 → supertable-2.3.9}/supertable/quality/checker.py +0 -0
  121. {supertable-2.3.8 → supertable-2.3.9}/supertable/quality/config.py +0 -0
  122. {supertable-2.3.8 → supertable-2.3.9}/supertable/quality/history.py +0 -0
  123. {supertable-2.3.8 → supertable-2.3.9}/supertable/quality/scheduler.py +0 -0
  124. {supertable-2.3.8 → supertable-2.3.9}/supertable/query_plan_manager.py +0 -0
  125. {supertable-2.3.8 → supertable-2.3.9}/supertable/rbac/__init__.py +0 -0
  126. {supertable-2.3.8 → supertable-2.3.9}/supertable/rbac/access_control.py +0 -0
  127. {supertable-2.3.8 → supertable-2.3.9}/supertable/rbac/filter_builder.py +0 -0
  128. {supertable-2.3.8 → supertable-2.3.9}/supertable/rbac/permissions.py +0 -0
  129. {supertable-2.3.8 → supertable-2.3.9}/supertable/rbac/role_manager.py +0 -0
  130. {supertable-2.3.8 → supertable-2.3.9}/supertable/rbac/row_column_security.py +0 -0
  131. {supertable-2.3.8 → supertable-2.3.9}/supertable/rbac/tests/test_filter_builder.py +0 -0
  132. {supertable-2.3.8 → supertable-2.3.9}/supertable/rbac/tests/test_rbac.py +0 -0
  133. {supertable-2.3.8 → supertable-2.3.9}/supertable/rbac/tests/test_rbac_per_table.py +0 -0
  134. {supertable-2.3.8 → supertable-2.3.9}/supertable/rbac/user_manager.py +0 -0
  135. {supertable-2.3.8 → supertable-2.3.9}/supertable/redis_catalog.py +0 -0
  136. {supertable-2.3.8 → supertable-2.3.9}/supertable/redis_connector.py +0 -0
  137. {supertable-2.3.8 → supertable-2.3.9}/supertable/redis_infra.py +0 -0
  138. {supertable-2.3.8 → supertable-2.3.9}/supertable/redis_keys.py +0 -0
  139. {supertable-2.3.8 → supertable-2.3.9}/supertable/simple_table.py +0 -0
  140. {supertable-2.3.8 → supertable-2.3.9}/supertable/staging_area.py +0 -0
  141. {supertable-2.3.8 → supertable-2.3.9}/supertable/storage/__init__.py +0 -0
  142. {supertable-2.3.8 → supertable-2.3.9}/supertable/storage/azure_storage.py +0 -0
  143. {supertable-2.3.8 → supertable-2.3.9}/supertable/storage/gcp_storage.py +0 -0
  144. {supertable-2.3.8 → supertable-2.3.9}/supertable/storage/local_storage.py +0 -0
  145. {supertable-2.3.8 → supertable-2.3.9}/supertable/storage/minio_storage.py +0 -0
  146. {supertable-2.3.8 → supertable-2.3.9}/supertable/storage/s3_storage.py +0 -0
  147. {supertable-2.3.8 → supertable-2.3.9}/supertable/storage/storage_factory.py +0 -0
  148. {supertable-2.3.8 → supertable-2.3.9}/supertable/storage/storage_interface.py +0 -0
  149. {supertable-2.3.8 → supertable-2.3.9}/supertable/storage/tests/test_storage.py +0 -0
  150. {supertable-2.3.8 → supertable-2.3.9}/supertable/super_pipe.py +0 -0
  151. {supertable-2.3.8 → supertable-2.3.9}/supertable/super_table.py +0 -0
  152. {supertable-2.3.8 → supertable-2.3.9}/supertable/system_query.py +0 -0
  153. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/__init__.py +0 -0
  154. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_align_to_schema_fix.py +0 -0
  155. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_compaction_selection.py +0 -0
  156. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_create_if_missing.py +0 -0
  157. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_data_reader.py +0 -0
  158. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_data_reader_preflight.py +0 -0
  159. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_data_writer.py +0 -0
  160. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_data_writer_compact.py +0 -0
  161. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_data_writer_comprehensive.py +0 -0
  162. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_errors.py +0 -0
  163. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_meta_reader.py +0 -0
  164. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_monitoring_partitions.py +0 -0
  165. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_monitoring_sink_guard.py +0 -0
  166. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_newer_than.py +0 -0
  167. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_parquet_statistics.py +0 -0
  168. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_processing.py +0 -0
  169. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_processing_compact_resources.py +0 -0
  170. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_processing_stats.py +0 -0
  171. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_query_sql.py +0 -0
  172. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_read_pruning_differential.py +0 -0
  173. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_read_pruning_integration.py +0 -0
  174. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_redis_key_prefix.py +0 -0
  175. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_resolve_overwrite_writes.py +0 -0
  176. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_simple_table.py +0 -0
  177. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_stats_cache.py +0 -0
  178. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_stats_pruning.py +0 -0
  179. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_stats_schema_snapshot.py +0 -0
  180. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_super_table.py +0 -0
  181. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_supertable_all.py +0 -0
  182. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_system_query.py +0 -0
  183. {supertable-2.3.8 → supertable-2.3.9}/supertable/tests/test_write_probe_gate.py +0 -0
  184. {supertable-2.3.8 → supertable-2.3.9}/supertable/utils/__init__.py +0 -0
  185. {supertable-2.3.8 → supertable-2.3.9}/supertable/utils/helper.py +0 -0
  186. {supertable-2.3.8 → supertable-2.3.9}/supertable/utils/profiler.py +0 -0
  187. {supertable-2.3.8 → supertable-2.3.9}/supertable/utils/sql_parser.py +0 -0
  188. {supertable-2.3.8 → supertable-2.3.9}/supertable/utils/tests/test_sql_parser_columns.py +0 -0
  189. {supertable-2.3.8 → supertable-2.3.9}/supertable/utils/timer.py +0 -0
  190. {supertable-2.3.8 → supertable-2.3.9}/supertable.egg-info/SOURCES.txt +0 -0
  191. {supertable-2.3.8 → supertable-2.3.9}/supertable.egg-info/dependency_links.txt +0 -0
  192. {supertable-2.3.8 → supertable-2.3.9}/supertable.egg-info/entry_points.txt +0 -0
  193. {supertable-2.3.8 → supertable-2.3.9}/supertable.egg-info/requires.txt +0 -0
  194. {supertable-2.3.8 → supertable-2.3.9}/supertable.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: supertable
3
- Version: 2.3.8
3
+ Version: 2.3.9
4
4
  Summary: SuperTable — versioned data lake library for SQL analytics on Parquet + Redis.
5
5
  Author: Levente Kupas
6
6
  Author-email: Levente Kupas <lkupas@kladnasoft.com>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "supertable"
7
- version = "2.3.8"
7
+ version = "2.3.9"
8
8
  description = "SuperTable — versioned data lake library for SQL analytics on Parquet + Redis."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -19,7 +19,7 @@ long_description = readme.read_text(encoding="utf-8") if readme.exists() else ""
19
19
 
20
20
  setup(
21
21
  name="supertable",
22
- version="2.3.8",
22
+ version="2.3.9",
23
23
  description="SuperTable — versioned data lake library for SQL analytics on Parquet + Redis.",
24
24
  long_description=long_description,
25
25
  long_description_content_type="text/markdown",
@@ -25,7 +25,7 @@ See the ``supertable.demo`` package for runnable end-to-end demos and the
25
25
  project documentation for the full API surface.
26
26
  """
27
27
 
28
- __version__ = "2.3.8"
28
+ __version__ = "2.3.9"
29
29
 
30
30
  # Re-export the core public surface so users can do ``from supertable import …``
31
31
  # instead of remembering submodule paths.
@@ -157,6 +157,14 @@ class Settings:
157
157
  SUPERTABLE_DUCKDB_MATERIALIZE: str = "view" # SUPERTABLE_DUCKDB_MATERIALIZE
158
158
  SUPERTABLE_DUCKDB_PRESIGNED: bool = False # SUPERTABLE_DUCKDB_PRESIGNED
159
159
  SUPERTABLE_DUCKDB_USE_HTTPFS: bool = False # SUPERTABLE_DUCKDB_USE_HTTPFS
160
+ # Allow DuckDB to DOWNLOAD a missing extension (httpfs) from
161
+ # extensions.duckdb.org at query time. Default OFF: httpfs is baked into
162
+ # the image and seeded into the extension dir, and an implicit network
163
+ # install on an offline/firewalled node can hang for minutes instead of
164
+ # failing. When OFF, a genuinely missing extension raises immediately with
165
+ # an actionable message; set ON only on a networked box that must
166
+ # self-install.
167
+ SUPERTABLE_DUCKDB_ALLOW_EXTENSION_DOWNLOAD: bool = False # SUPERTABLE_DUCKDB_ALLOW_EXTENSION_DOWNLOAD
160
168
  # Write-path overwrite/delete resolution via the DuckDB pushdown probe.
161
169
  # Disabled by default: the polars fallback reads only the projected key
162
170
  # columns through the storage SDK and needs no httpfs extension, so it works
@@ -444,6 +452,7 @@ def _build_settings() -> Settings:
444
452
  SUPERTABLE_DUCKDB_MATERIALIZE=_env_str("SUPERTABLE_DUCKDB_MATERIALIZE", "view"),
445
453
  SUPERTABLE_DUCKDB_PRESIGNED=_env_bool("SUPERTABLE_DUCKDB_PRESIGNED", False),
446
454
  SUPERTABLE_DUCKDB_USE_HTTPFS=_env_bool("SUPERTABLE_DUCKDB_USE_HTTPFS", False),
455
+ SUPERTABLE_DUCKDB_ALLOW_EXTENSION_DOWNLOAD=_env_bool("SUPERTABLE_DUCKDB_ALLOW_EXTENSION_DOWNLOAD", False),
447
456
  SUPERTABLE_DUCKDB_WRITE_PROBE=_env_bool("SUPERTABLE_DUCKDB_WRITE_PROBE", False),
448
457
  SUPERTABLE_DUCKDB_TOMBSTONE_CACHE_MAX_PER_TABLE=_env_int("SUPERTABLE_DUCKDB_TOMBSTONE_CACHE_MAX_PER_TABLE", 8),
449
458
  SUPERTABLE_DUCKDB_TOMBSTONE_CACHE_TTL_SEC=_env_int("SUPERTABLE_DUCKDB_TOMBSTONE_CACHE_TTL_SEC", 300),
@@ -215,12 +215,43 @@ def configure_httpfs_and_s3(
215
215
  if not for_paths:
216
216
  return
217
217
 
218
- # Load httpfs; install only when not already available.
218
+ # Load httpfs. It is baked into the image and seeded into the DuckDB
219
+ # extension dir (see the container entrypoint), so LOAD normally succeeds
220
+ # with no network access.
221
+ #
222
+ # Why this is NOT a blind ``INSTALL`` fallback: ``INSTALL httpfs`` performs
223
+ # an HTTP GET to extensions.duckdb.org. On an offline / firewalled node
224
+ # that socket can stall for minutes — or hang indefinitely on a blackholed
225
+ # route — turning a should-be-instant failure into an unbounded query hang.
226
+ # So we fail fast instead:
227
+ # * SET autoinstall_known_extensions=false makes LOAD raise immediately
228
+ # when the extension is absent, rather than silently downloading it;
229
+ # * a network INSTALL is attempted ONLY when explicitly opted in via
230
+ # SUPERTABLE_DUCKDB_ALLOW_EXTENSION_DOWNLOAD;
231
+ # * otherwise we raise a clear, actionable error the caller returns.
219
232
  try:
220
- con.execute("LOAD httpfs;")
233
+ con.execute("SET autoinstall_known_extensions=false;")
221
234
  except Exception:
222
- con.execute("INSTALL httpfs;")
235
+ pass
236
+
237
+ try:
223
238
  con.execute("LOAD httpfs;")
239
+ except Exception as load_err:
240
+ if settings.SUPERTABLE_DUCKDB_ALLOW_EXTENSION_DOWNLOAD:
241
+ # Operator explicitly allowed reaching the network for a one-off
242
+ # install (e.g. an online dev box without a baked extension).
243
+ con.execute("INSTALL httpfs;")
244
+ con.execute("LOAD httpfs;")
245
+ else:
246
+ raise RuntimeError(
247
+ "DuckDB 'httpfs' extension is not available locally and network "
248
+ "auto-download is disabled, so this query cannot run. Bake/seed "
249
+ "httpfs into "
250
+ f"'{get_app_home()}/.duckdb/extensions/v<duckdb_version>/<platform>/' "
251
+ "(the container entrypoint restores it from /opt/duckdb-extensions), "
252
+ "or set SUPERTABLE_DUCKDB_ALLOW_EXTENSION_DOWNLOAD=true to permit a "
253
+ f"one-time online install. Underlying DuckDB error: {load_err}"
254
+ ) from load_err
224
255
 
225
256
  any_s3 = any(str(p).lower().startswith("s3://") for p in for_paths)
226
257
  any_http = any(str(p).lower().startswith(("http://", "https://")) for p in for_paths)
@@ -634,6 +665,17 @@ def init_connection(
634
665
  except Exception as e:
635
666
  logger.warning(f"[duckdb.init] home_directory pin failed: {e}")
636
667
 
668
+ # Never let DuckDB auto-DOWNLOAD an extension. Everything we need (httpfs)
669
+ # is baked/seeded into the local extension dir; an implicit network install
670
+ # would reach out to extensions.duckdb.org and can hang for minutes on an
671
+ # offline/firewalled node — turning a should-be-instant error into an
672
+ # unbounded query hang. configure_httpfs_and_s3() owns the explicit,
673
+ # opt-in install path (SUPERTABLE_DUCKDB_ALLOW_EXTENSION_DOWNLOAD).
674
+ try:
675
+ con.execute("SET autoinstall_known_extensions=false;")
676
+ except Exception as e:
677
+ logger.debug(f"[duckdb.init] disabling extension auto-install failed: {e}")
678
+
637
679
  # Resolve memory limit.
638
680
  # Single env var SUPERTABLE_DUCKDB_MEMORY_LIMIT controls both executors.
639
681
  # The `memory_limit` argument is the caller's fallback when the env var is absent.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: supertable
3
- Version: 2.3.8
3
+ Version: 2.3.9
4
4
  Summary: SuperTable — versioned data lake library for SQL analytics on Parquet + Redis.
5
5
  Author: Levente Kupas
6
6
  Author-email: Levente Kupas <lkupas@kladnasoft.com>
File without changes
File without changes
File without changes
File without changes