snowflake-snowpark-python 1.53.1__tar.gz → 1.55.0__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 (244) hide show
  1. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/CHANGELOG.md +55 -1
  2. {snowflake_snowpark_python-1.53.1/src/snowflake_snowpark_python.egg-info → snowflake_snowpark_python-1.55.0}/PKG-INFO +3 -1
  3. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/setup.py +1 -0
  4. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/analyzer_utils.py +46 -74
  5. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/datatype_mapper.py +44 -0
  6. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/expression.py +11 -2
  7. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/select_statement.py +4 -15
  8. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/snowflake_plan.py +7 -10
  9. snowflake_snowpark_python-1.55.0/src/snowflake/snowpark/_internal/polars_backend.py +135 -0
  10. snowflake_snowpark_python-1.55.0/src/snowflake/snowpark/_internal/proto/generated/ast_pb2.py +609 -0
  11. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/proto/generated/ast_pb2.pyi +218 -22
  12. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/type_utils.py +6 -0
  13. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/udf_utils.py +15 -3
  14. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/utils.py +23 -15
  15. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/column.py +11 -2
  16. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/dataframe.py +115 -1
  17. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/dataframe_ai_functions.py +438 -39
  18. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/dataframe_writer.py +10 -9
  19. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/functions.py +623 -122
  20. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_functions.py +6 -0
  21. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/compiler/snowflake_query_compiler.py +10 -3
  22. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/relational_grouped_dataframe.py +0 -2
  23. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/session.py +0 -1
  24. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/types.py +2 -2
  25. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/version.py +1 -1
  26. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0/src/snowflake_snowpark_python.egg-info}/PKG-INFO +3 -1
  27. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake_snowpark_python.egg-info/SOURCES.txt +1 -0
  28. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake_snowpark_python.egg-info/requires.txt +2 -0
  29. snowflake_snowpark_python-1.53.1/src/snowflake/snowpark/_internal/proto/generated/ast_pb2.py +0 -603
  30. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/LICENSE.txt +0 -0
  31. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/MANIFEST.in +0 -0
  32. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/README.md +0 -0
  33. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/pyproject.toml +0 -0
  34. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/setup.cfg +0 -0
  35. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/__init__.py +0 -0
  36. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_functions/__init__.py +0 -0
  37. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_functions/general_functions.py +0 -0
  38. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_functions/scalar_functions.py +0 -0
  39. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/__init__.py +0 -0
  40. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/__init__.py +0 -0
  41. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/analyzer.py +0 -0
  42. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/binary_expression.py +0 -0
  43. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/binary_plan_node.py +0 -0
  44. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/grouping_set.py +0 -0
  45. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/metadata_utils.py +0 -0
  46. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/query_plan_analysis_utils.py +0 -0
  47. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/schema_utils.py +0 -0
  48. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/snowflake_plan_node.py +0 -0
  49. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/sort_expression.py +0 -0
  50. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/table_function.py +0 -0
  51. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/table_merge_expression.py +0 -0
  52. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/unary_expression.py +0 -0
  53. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/unary_plan_node.py +0 -0
  54. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/analyzer/window_expression.py +0 -0
  55. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/ast/__init__.py +0 -0
  56. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/ast/batch.py +0 -0
  57. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/ast/builder.py +0 -0
  58. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/ast/utils.py +0 -0
  59. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/code_generation.py +0 -0
  60. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/compiler/__init__.py +0 -0
  61. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/compiler/cte_utils.py +0 -0
  62. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/compiler/large_query_breakdown.py +0 -0
  63. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/compiler/plan_compiler.py +0 -0
  64. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/compiler/query_generator.py +0 -0
  65. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/compiler/repeated_subquery_elimination.py +0 -0
  66. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/compiler/telemetry_constants.py +0 -0
  67. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/compiler/utils.py +0 -0
  68. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/__init__.py +0 -0
  69. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/datasource_partitioner.py +0 -0
  70. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/datasource_reader.py +0 -0
  71. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/datasource_typing.py +0 -0
  72. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/__init__.py +0 -0
  73. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/base_dialect.py +0 -0
  74. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/databricks_dialect.py +0 -0
  75. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/mysql_dialect.py +0 -0
  76. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/oracledb_dialect.py +0 -0
  77. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/postgresql_dialect.py +0 -0
  78. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/sqlite3_dialect.py +0 -0
  79. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/sqlserver_dialect.py +0 -0
  80. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/drivers/__init__.py +0 -0
  81. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/drivers/base_driver.py +0 -0
  82. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/drivers/databricks_driver.py +0 -0
  83. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/drivers/oracledb_driver.py +0 -0
  84. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/drivers/psycopg2_driver.py +0 -0
  85. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/drivers/pymsql_driver.py +0 -0
  86. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/drivers/pyodbc_driver.py +0 -0
  87. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/drivers/sqlite_driver.py +0 -0
  88. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/jdbc.py +0 -0
  89. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/data_source/utils.py +0 -0
  90. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/debug_utils.py +0 -0
  91. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/error_message.py +0 -0
  92. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/event_table_telemetry.py +0 -0
  93. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/open_telemetry.py +0 -0
  94. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/packaging_utils.py +0 -0
  95. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/proto/generated/__init__.py +0 -0
  96. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/select_projection_complexity_utils.py +0 -0
  97. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/server_connection.py +0 -0
  98. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/snowpark_profiler.py +0 -0
  99. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/telemetry.py +0 -0
  100. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/temp_table_auto_cleaner.py +0 -0
  101. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/xml_reader.py +0 -0
  102. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/xml_schema_inference.py +0 -0
  103. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/_internal/xpath_handlers.py +0 -0
  104. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/async_job.py +0 -0
  105. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/catalog.py +0 -0
  106. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/context.py +0 -0
  107. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/dataframe_analytics_functions.py +0 -0
  108. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/dataframe_na_functions.py +0 -0
  109. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/dataframe_profiler.py +0 -0
  110. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/dataframe_reader.py +0 -0
  111. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/dataframe_stat_functions.py +0 -0
  112. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/exceptions.py +0 -0
  113. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/file_operation.py +0 -0
  114. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/files.py +0 -0
  115. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/lineage.py +0 -0
  116. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/__init__.py +0 -0
  117. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_analyzer.py +0 -0
  118. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_connection.py +0 -0
  119. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_constants.py +0 -0
  120. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_nop_analyzer.py +0 -0
  121. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_nop_connection.py +0 -0
  122. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_nop_plan.py +0 -0
  123. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_options.py +0 -0
  124. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_pandas_util.py +0 -0
  125. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_plan.py +0 -0
  126. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_plan_builder.py +0 -0
  127. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_select_statement.py +0 -0
  128. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_snowflake_data_type.py +0 -0
  129. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_snowflake_to_pandas_converter.py +0 -0
  130. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_stage_registry.py +0 -0
  131. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_stored_procedure.py +0 -0
  132. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_telemetry.py +0 -0
  133. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_udaf.py +0 -0
  134. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_udf.py +0 -0
  135. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_udf_utils.py +0 -0
  136. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_udtf.py +0 -0
  137. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_util.py +0 -0
  138. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/_window_utils.py +0 -0
  139. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/mock/exceptions.py +0 -0
  140. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/__init__.py +0 -0
  141. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/config/__init__.py +0 -0
  142. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/config/__main__.py +0 -0
  143. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/config/envvars.py +0 -0
  144. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/config/pubsub.py +0 -0
  145. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/conftest.py +0 -0
  146. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/__init__.py +0 -0
  147. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/__init__.py +0 -0
  148. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/aggregation_utils.py +0 -0
  149. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/align_utils.py +0 -0
  150. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/apply_utils.py +0 -0
  151. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/binary_op_utils.py +0 -0
  152. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/concat_utils.py +0 -0
  153. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/cumulative_utils.py +0 -0
  154. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/cut_utils.py +0 -0
  155. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/frame.py +0 -0
  156. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/generator_utils.py +0 -0
  157. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/get_dummies_utils.py +0 -0
  158. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/groupby_utils.py +0 -0
  159. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/indexing_utils.py +0 -0
  160. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/io_utils.py +0 -0
  161. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/isin_utils.py +0 -0
  162. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/join_utils.py +0 -0
  163. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/ordered_dataframe.py +0 -0
  164. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/pivot_utils.py +0 -0
  165. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/resample_utils.py +0 -0
  166. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/row_count_estimation.py +0 -0
  167. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/session.py +0 -0
  168. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/snowpark_pandas_types.py +0 -0
  169. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/statement_params_constants.py +0 -0
  170. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/telemetry.py +0 -0
  171. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/timestamp_utils.py +0 -0
  172. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/transpose_utils.py +0 -0
  173. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/type_utils.py +0 -0
  174. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/unpivot_utils.py +0 -0
  175. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/utils.py +0 -0
  176. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/where_utils.py +0 -0
  177. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_internal/window_utils.py +0 -0
  178. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/_typing.py +0 -0
  179. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/compiler/__init__.py +0 -0
  180. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/compiler/doc_utils.py +0 -0
  181. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/compiler/ray_utils.py +0 -0
  182. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/__init__.py +0 -0
  183. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/base.py +0 -0
  184. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/dataframe.py +0 -0
  185. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/datetime_index.py +0 -0
  186. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/general.py +0 -0
  187. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/groupby.py +0 -0
  188. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/index.py +0 -0
  189. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/io.py +0 -0
  190. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/resample.py +0 -0
  191. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/series.py +0 -0
  192. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/series_utils.py +0 -0
  193. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/shared_docs.py +0 -0
  194. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/timedelta_index.py +0 -0
  195. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/docstrings/window.py +0 -0
  196. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/__init__.py +0 -0
  197. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/base_overrides.py +0 -0
  198. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/dataframe_extensions.py +0 -0
  199. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/dataframe_groupby_overrides.py +0 -0
  200. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/dataframe_overrides.py +0 -0
  201. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/datetime_index.py +0 -0
  202. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/general_overrides.py +0 -0
  203. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/index.py +0 -0
  204. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/indexing_overrides.py +0 -0
  205. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/io_overrides.py +0 -0
  206. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/pd_extensions.py +0 -0
  207. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/resample_overrides.py +0 -0
  208. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/resampler_groupby_overrides.py +0 -0
  209. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/rolling_groupby_overrides.py +0 -0
  210. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/series_extensions.py +0 -0
  211. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/series_groupby_overrides.py +0 -0
  212. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/series_overrides.py +0 -0
  213. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/snow_partition_iterator.py +0 -0
  214. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/timedelta_index.py +0 -0
  215. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/utils.py +0 -0
  216. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/extensions/window_overrides.py +0 -0
  217. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/io/__init__.py +0 -0
  218. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/io/factories.py +0 -0
  219. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/io/snow_io.py +0 -0
  220. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/utils/__init__.py +0 -0
  221. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/utils/error_message.py +0 -0
  222. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/utils/exceptions.py +0 -0
  223. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/utils/frontend_constants.py +0 -0
  224. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/utils/numpy_to_pandas.py +0 -0
  225. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/plugin/utils/warning_message.py +0 -0
  226. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/modin/utils.py +0 -0
  227. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/py.typed +0 -0
  228. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/query_history.py +0 -0
  229. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/row.py +0 -0
  230. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/secrets.py +0 -0
  231. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/stored_procedure.py +0 -0
  232. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/stored_procedure_profiler.py +0 -0
  233. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/table.py +0 -0
  234. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/table_function.py +0 -0
  235. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/testing.py +0 -0
  236. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/udaf.py +0 -0
  237. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/udf.py +0 -0
  238. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/udf_profiler.py +0 -0
  239. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/udtf.py +0 -0
  240. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake/snowpark/window.py +0 -0
  241. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake_snowpark_python.egg-info/dependency_links.txt +0 -0
  242. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake_snowpark_python.egg-info/namespace_packages.txt +0 -0
  243. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake_snowpark_python.egg-info/not-zip-safe +0 -0
  244. {snowflake_snowpark_python-1.53.1 → snowflake_snowpark_python-1.55.0}/src/snowflake_snowpark_python.egg-info/top_level.txt +0 -0
@@ -1,5 +1,56 @@
1
1
  # Release History
2
2
 
3
+ ## 1.55.0 (2026-09-10)
4
+
5
+ ### Snowpark Python API Updates
6
+
7
+ #### New Features
8
+
9
+ - Added `DataFrame.to_polars()` to convert a Snowpark DataFrame to a Polars DataFrame. Supports an optional `transport="parquet"` mode for large data-transfer-dominated workloads.
10
+ - Added interval type support for Python UDFs and stored procedures. Use `datetime.timedelta` as the type annotation for day-time interval (`DayTimeIntervalType`) parameters and return values, and `YearMonthInterval` (a type annotation sentinel from `snowflake.snowpark.types`) for year-month interval (`YearMonthIntervalType`) parameters and return values.
11
+ - Added support for a `table_properties` key in the `iceberg_config` dictionary of `DataFrameWriter.save_as_table`, which emits a `TABLE_PROPERTIES = ('k'='v', ...)` clause on Iceberg table creation (CREATE / CTAS).
12
+
13
+ #### Bug Fixes
14
+
15
+ - Fixed registering a UDF, UDTF, or stored procedure with an integer optional argument failing with `SQL compilation error: invalid default argument expression`. Integer defaults were emitted as `DEFAULT <value> :: INT`, and a parameter default only accepts a constant expression. The redundant cast is no longer generated.
16
+
17
+ #### Documentation
18
+
19
+ - Documented the JSON Schema `response_format` shape for `ai_extract` and `DataFrame.ai.extract`.
20
+
21
+ #### Other Changes
22
+
23
+ - Test-only: fixed `test_generator_table_function` failing as `assert 0 < 0` on the `seq2(0)` + `generator(timelimit => 1)` case. `seq2(0)` passes sign=0, so it continues at 0 after 32767, and a one-second generator run usually emits far more than one 32768-value cycle, making `ORDER BY seq2(0) LIMIT 3` return `0, 0, 0`. That assertion now allows equal values; the `seq1(1)` + `rowcount` assertions stay strictly increasing.
24
+
25
+ ### Snowpark pandas API Updates
26
+
27
+ #### Bug Fixes
28
+
29
+ - Fixed a bug where referencing `modin.pandas` inside a Snowpark pandas `apply()` function raised a `ModuleNotFoundError`.
30
+
31
+ ## 1.54.0 (2026-07-29)
32
+
33
+ ### Snowpark Python API updates
34
+
35
+ #### New Features
36
+
37
+ - Added `ai_count_tokens` function to `snowflake.snowpark.functions` to estimate token counts for AI function calls.
38
+ - Added `ai_multi_embed` function to `snowflake.snowpark.functions` to generate multimodal embeddings from text, images, audio, or video files.
39
+ - Added `ai_redact` function to `snowflake.snowpark.functions` to detect and redact personally identifiable information (PII) from text.
40
+ - Added `DataFrame.ai.multi_embed` method to generate multimodal embeddings via the DataFrame API.
41
+ - Added `DataFrame.ai.redact` method to detect and redact PII from text columns via the DataFrame API.
42
+ - Added `DataFrame.ai.translate` method to translate text columns between languages via the DataFrame API.
43
+
44
+ #### Improvements
45
+
46
+ - Removed the `experimental` tag from all AI SQL functions in `DataFrameAIFunctions` (`complete`, `filter`, `agg`, `classify`, `similarity`, `sentiment`, `embed`, `summarize_agg`, `transcribe`, `parse_document`, `extract`, `count_tokens`, `split_text_markdown_header`, `split_text_recursive_character`) and `RelationalGroupedDataFrame.ai_agg`.
47
+ - Updated `DataFrame.ai.count_tokens` to match the standalone `ai_count_tokens` function: `function_name` is now the required first parameter, and `model` is optional. Also added `options` and `return_error_details` parameters.
48
+
49
+ #### Bug Fixes
50
+
51
+ - Fixed `DataFrame.ai.count_tokens` to call the `AI_COUNT_TOKENS` SQL function instead of the deprecated `SNOWFLAKE.CORTEX.COUNT_TOKENS`. Token counts may differ slightly due to the updated tokenizer.
52
+ - Reverted the change introduced in 1.53.0 to eliminate unnecessary `SELECT *` from joins, which was causing performance regressions. This has no functional impact.
53
+
3
54
  ## 1.53.1 (2026-07-14)
4
55
 
5
56
  No user-facing changes in this release.
@@ -23,6 +74,10 @@ No user-facing changes in this release.
23
74
  - Fixed a bug where single quotes and backslashes in `comment` (`create_or_replace_view` / dynamic table / `save_as_table`), collation specs (`Column.collate`), VARIANT/OBJECT subfield keys (`Column[...]`), and `DataFrame`/`Session.flatten` paths were not correctly escaped when generating SQL, which could produce malformed statements. Backslash sequences (e.g. `\t`, `\n`) in these values are now applied literally rather than interpreted.
24
75
  - Fixed a bug where string values in the AI functions (`ai_extract`, `ai_classify`, `ai_similarity`, `ai_parse_document`, `ai_transcribe`, `ai_complete`) configuration and `response_format` were not correctly escaped when generating the SQL object literal, which could produce malformed statements when a value contained single quotes or backslashes (for example, an apostrophe in a natural-language question).
25
76
 
77
+ #### Improvements
78
+
79
+ - Reduced the size of generated query text for repeated join operations.
80
+
26
81
  #### Dependency Updates
27
82
 
28
83
  - Lifted `protobuf` restriction for Python 3.14 from `==5.29.3` to `>=5.29.3,<6.34`.
@@ -45,7 +100,6 @@ No user-facing changes in this release.
45
100
  #### Improvements
46
101
 
47
102
  - Improved CTE optimization to deduplicate identical subtrees in self-joins, which were previously emitted as repeated subqueries.
48
- - Reduced the size of generated query text for repeated join operations.
49
103
 
50
104
  #### Deprecations
51
105
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: snowflake-snowpark-python
3
- Version: 1.53.1
3
+ Version: 1.55.0
4
4
  Summary: Snowflake Snowpark for Python
5
5
  Home-page: https://www.snowflake.com/
6
6
  Author: Snowflake, Inc
@@ -77,6 +77,7 @@ Requires-Dist: snowflake.core<2,>=1.0.0; extra == "development"
77
77
  Requires-Dist: psutil; extra == "development"
78
78
  Requires-Dist: lxml; extra == "development"
79
79
  Requires-Dist: pyarrow; extra == "development"
80
+ Requires-Dist: polars>=1.0; extra == "development"
80
81
  Provides-Extra: modin-development
81
82
  Requires-Dist: snowflake-connector-python[pandas]<5.0.0,>=3.17.0; extra == "modin-development"
82
83
  Requires-Dist: pandas<3.0.0; extra == "modin-development"
@@ -103,6 +104,7 @@ Requires-Dist: snowflake.core<2,>=1.0.0; extra == "modin-development"
103
104
  Requires-Dist: psutil; extra == "modin-development"
104
105
  Requires-Dist: lxml; extra == "modin-development"
105
106
  Requires-Dist: pyarrow; extra == "modin-development"
107
+ Requires-Dist: polars>=1.0; extra == "modin-development"
106
108
  Requires-Dist: scipy<=1.16.3; extra == "modin-development"
107
109
  Requires-Dist: statsmodels; extra == "modin-development"
108
110
  Requires-Dist: scikit-learn; extra == "modin-development"
@@ -73,6 +73,7 @@ DEVELOPMENT_REQUIREMENTS = [
73
73
  "psutil", # testing for telemetry
74
74
  "lxml", # used in XML reader unit tests
75
75
  "pyarrow", # used in dataframe reader tests
76
+ "polars>=1.0", # used in test_df_to_polars integration tests
76
77
  ]
77
78
  MODIN_DEVELOPMENT_REQUIREMENTS = [
78
79
  # Snowpark pandas 3rd party library testing. Cap the scipy version because
@@ -150,6 +150,7 @@ BASE_LOCATION = " BASE_LOCATION "
150
150
  TARGET_FILE_SIZE = " TARGET_FILE_SIZE "
151
151
  CATALOG_SYNC = " CATALOG_SYNC "
152
152
  STORAGE_SERIALIZATION_POLICY = " STORAGE_SERIALIZATION_POLICY "
153
+ TABLE_PROPERTIES = " TABLE_PROPERTIES"
153
154
  REG_EXP = " REGEXP "
154
155
  COLLATE = " COLLATE "
155
156
  RESULT_SCAN = " RESULT_SCAN"
@@ -334,6 +335,30 @@ def iceberg_partition_clause(partition_exprs: List[str]) -> str:
334
335
  )
335
336
 
336
337
 
338
+ def iceberg_table_properties_clause(iceberg_config: Optional[dict]) -> str:
339
+ """Emit ``TABLE_PROPERTIES = ('k'='v', ...)`` from an ``iceberg_config``'s
340
+ ``table_properties`` map (keys kept verbatim, keys/values escaped); empty
341
+ when absent."""
342
+ if not iceberg_config:
343
+ return EMPTY_STRING
344
+ normalized = {k.lower(): v for k, v in iceberg_config.items()}
345
+ table_properties = normalized.get("table_properties")
346
+ if not table_properties:
347
+ return EMPTY_STRING
348
+
349
+ # Escape via ``escape_quotes_and_backslashes`` (not ``single_quote``): it
350
+ # escapes backslashes as well as quotes and never skips escaping, so a
351
+ # crafted key/value cannot break out of its literal and inject extra SQL
352
+ # (e.g. "'x', 'injected'='surprise'" or "x\\') COPY GRANTS --").
353
+ def _quote(value: object) -> str:
354
+ return SINGLE_QUOTE + escape_quotes_and_backslashes(str(value)) + SINGLE_QUOTE
355
+
356
+ pairs = COMMA.join(f"{_quote(k)}={_quote(v)}" for k, v in table_properties.items())
357
+ return (
358
+ SPACE + TABLE_PROPERTIES + EQUALS + LEFT_PARENTHESIS + pairs + RIGHT_PARENTHESIS
359
+ )
360
+
361
+
337
362
  def order_by_spec(col_exprs: List[str]) -> str:
338
363
  if not col_exprs:
339
364
  return EMPTY_STRING
@@ -990,33 +1015,6 @@ def lateral_join_statement(
990
1015
  )
991
1016
 
992
1017
 
993
- _SELECT_STAR_FROM_PREFIX = SELECT + STAR + NEW_LINE + FROM + LEFT_PARENTHESIS + NEW_LINE
994
- _SELECT_STAR_FROM_SUFFIX = NEW_LINE + RIGHT_PARENTHESIS
995
-
996
-
997
- def _unwrap_select_star_from(sql: str) -> Optional[str]:
998
- """If sql is a join-produced `SELECT * FROM (\n<join_source>\n)` (the
999
- output of project_statement([], join_source)), return <join_source>.
1000
- Only unwraps when the inner content starts with '(' (possibly preceded
1001
- by UUID trace comments) which indicates a parenthesized join operand
1002
- rather than a wrapped SELECT statement."""
1003
- if sql.startswith(_SELECT_STAR_FROM_PREFIX) and sql.endswith(
1004
- _SELECT_STAR_FROM_SUFFIX
1005
- ):
1006
- inner = sql[len(_SELECT_STAR_FROM_PREFIX) : -len(_SELECT_STAR_FROM_SUFFIX)]
1007
- # In trace-SQL mode, UUID comments (\n-- <uuid>\n) may precede the
1008
- # opening parenthesis. Strip them before checking.
1009
- check = inner.lstrip("\n")
1010
- if check.startswith("--"):
1011
- # Skip the comment line and any trailing newline
1012
- newline_pos = check.find("\n")
1013
- if newline_pos != -1:
1014
- check = check[newline_pos + 1 :]
1015
- if check.startswith(LEFT_PARENTHESIS) or inner.startswith(LEFT_PARENTHESIS):
1016
- return inner
1017
- return None
1018
-
1019
-
1020
1018
  def snowflake_supported_join_statement(
1021
1019
  left: str,
1022
1020
  right: str,
@@ -1027,30 +1025,17 @@ def snowflake_supported_join_statement(
1027
1025
  left_uuid: Optional[str] = None,
1028
1026
  right_uuid: Optional[str] = None,
1029
1027
  directed: bool = False,
1030
- left_is_join: bool = False,
1031
1028
  ) -> str:
1032
1029
  LEFT_UUID = format_uuid(left_uuid)
1033
1030
  RIGHT_UUID = format_uuid(right_uuid)
1034
-
1035
- # If left is the output of a previous join, flatten into a multi-way join
1036
- # by unwrapping the SELECT * FROM (...) envelope and appending the new
1037
- # right operand directly to the existing join source. This avoids nested
1038
- # SELECT * layers that inflate query text without changing semantics.
1039
- #
1040
- # Though it is technically less efficient than constructing the join sub-queries
1041
- # without the SELECT in the first place, the structure of our SQL processing code
1042
- # needs top-level projections to be wrapped by a select to be well-formed, so we
1043
- # must strip it here instead.
1044
- #
1045
- # We only unwrap the left side because it is simpler to deal with than unwrapping
1046
- # both left and right, and left-deep chains are more common, as they're produced
1047
- # by calls like df1.join(df2).join(df3) etc.
1048
- unwrapped_left = _unwrap_select_star_from(left) if left_is_join else None
1031
+ left_alias = (
1032
+ "SNOWPARK_LEFT"
1033
+ if use_constant_subquery_alias
1034
+ else random_name_for_temp_object(TempObjectType.TABLE)
1035
+ )
1049
1036
  right_alias = (
1050
1037
  "SNOWPARK_RIGHT"
1051
- if use_constant_subquery_alias and unwrapped_left is None
1052
- # Multi-way join: right alias must be unique to avoid collisions
1053
- # with aliases already present in the flattened join source.
1038
+ if use_constant_subquery_alias
1054
1039
  else random_name_for_temp_object(TempObjectType.TABLE)
1055
1040
  )
1056
1041
 
@@ -1086,31 +1071,18 @@ def snowflake_supported_join_statement(
1086
1071
 
1087
1072
  maybe_directed_sql = DIRECTED_JOIN if directed else JOIN
1088
1073
 
1089
- if unwrapped_left is not None:
1090
- # No need for additional parentheses around the left expression here, since it
1091
- # should already be parenthesized
1092
- left_expr = LEFT_UUID + unwrapped_left + NEW_LINE + LEFT_UUID
1093
- else:
1094
- left_alias = (
1095
- "SNOWPARK_LEFT"
1096
- if use_constant_subquery_alias
1097
- else random_name_for_temp_object(TempObjectType.TABLE)
1098
- )
1099
- left_expr = (
1100
- LEFT_PARENTHESIS
1101
- + NEW_LINE
1102
- + LEFT_UUID
1103
- + left
1104
- + NEW_LINE
1105
- + LEFT_UUID
1106
- + RIGHT_PARENTHESIS
1107
- + AS
1108
- + left_alias
1109
- + SPACE
1110
- + NEW_LINE
1111
- )
1112
1074
  source = (
1113
- left_expr
1075
+ LEFT_PARENTHESIS
1076
+ + NEW_LINE
1077
+ + LEFT_UUID
1078
+ + left
1079
+ + NEW_LINE
1080
+ + LEFT_UUID
1081
+ + RIGHT_PARENTHESIS
1082
+ + AS
1083
+ + left_alias
1084
+ + SPACE
1085
+ + NEW_LINE
1114
1086
  + join_sql
1115
1087
  + maybe_directed_sql
1116
1088
  + NEW_LINE
@@ -1142,7 +1114,6 @@ def join_statement(
1142
1114
  left_uuid: Optional[str] = None,
1143
1115
  right_uuid: Optional[str] = None,
1144
1116
  directed: bool = False,
1145
- left_is_join: bool = False,
1146
1117
  ) -> str:
1147
1118
  if isinstance(join_type, (LeftSemi, LeftAnti)):
1148
1119
  return left_semi_or_anti_join_statement(
@@ -1170,7 +1141,6 @@ def join_statement(
1170
1141
  left_uuid=left_uuid,
1171
1142
  right_uuid=right_uuid,
1172
1143
  directed=directed,
1173
- left_is_join=left_is_join,
1174
1144
  )
1175
1145
 
1176
1146
 
@@ -1223,13 +1193,14 @@ def create_table_statement(
1223
1193
  options_statement = get_options_statement(options)
1224
1194
 
1225
1195
  partition_by_clause = iceberg_partition_clause(partition_exprs)
1196
+ table_properties_clause = iceberg_table_properties_clause(iceberg_config)
1226
1197
 
1227
1198
  return (
1228
1199
  f"{CREATE}{(OR + REPLACE) if replace else EMPTY_STRING}"
1229
1200
  f" {(get_temp_type_for_object(use_scoped_temp_objects, is_generated) if table_type.lower() in TEMPORARY_STRING_SET else table_type).upper()} "
1230
1201
  f"{ICEBERG if iceberg_options else EMPTY_STRING}{TABLE}{table_name}{(IF + NOT + EXISTS) if not replace and not error else EMPTY_STRING}"
1231
1202
  f"{LEFT_PARENTHESIS}{schema}{RIGHT_PARENTHESIS}{partition_by_clause}{cluster_by_clause}"
1232
- f"{options_statement}{COPY_GRANTS if copy_grants else EMPTY_STRING}{comment_sql}"
1203
+ f"{options_statement}{table_properties_clause}{COPY_GRANTS if copy_grants else EMPTY_STRING}{comment_sql}"
1233
1204
  )
1234
1205
 
1235
1206
 
@@ -1314,13 +1285,14 @@ def create_table_as_select_statement(
1314
1285
  options_statement = get_options_statement(options)
1315
1286
 
1316
1287
  partition_by_clause = iceberg_partition_clause(partition_exprs)
1288
+ table_properties_clause = iceberg_table_properties_clause(iceberg_config)
1317
1289
 
1318
1290
  return (
1319
1291
  f"{CREATE}{OR + REPLACE if replace else EMPTY_STRING}"
1320
1292
  f" {(get_temp_type_for_object(use_scoped_temp_objects, is_generated) if table_type.lower() in TEMPORARY_STRING_SET else table_type).upper()} "
1321
1293
  f"{ICEBERG if iceberg_options else EMPTY_STRING}{TABLE}"
1322
1294
  f"{IF + NOT + EXISTS if not replace and not error else EMPTY_STRING} "
1323
- f"{table_name}{column_definition_sql}{partition_by_clause}{cluster_by_clause}{options_statement}"
1295
+ f"{table_name}{column_definition_sql}{partition_by_clause}{cluster_by_clause}{options_statement}{table_properties_clause}"
1324
1296
  f"{COPY_GRANTS if copy_grants else EMPTY_STRING}{comment_sql} {AS}{project_statement([], child)}"
1325
1297
  )
1326
1298
 
@@ -331,6 +331,25 @@ def to_sql_no_cast(
331
331
  return f"{value}"
332
332
 
333
333
 
334
+ def to_sql_for_default_arg(value: Any, datatype: DataType) -> str:
335
+ """Convert a value with DataType to SQL usable as a parameter's DEFAULT.
336
+
337
+ Identical to :func:`to_sql` except that integral values are emitted as bare
338
+ literals rather than ``<value> :: INT``. A DEFAULT only accepts a constant
339
+ expression, and the parameter already declares its own type, so the cast is
340
+ redundant. Snowflake rejects it outright on some server versions with
341
+ ``invalid default argument expression`` (SNOW-4013704).
342
+ """
343
+ if isinstance(datatype, _IntegralType):
344
+ if value is None:
345
+ return "NULL"
346
+ if isinstance(value, int):
347
+ # bool is a subclass of int, so normalize it to 0/1 for an
348
+ # integral parameter rather than emitting True/False.
349
+ return str(int(value))
350
+ return to_sql(value, datatype)
351
+
352
+
334
353
  def to_sql(
335
354
  value: Any,
336
355
  datatype: DataType,
@@ -501,6 +520,31 @@ def to_sql(
501
520
  if isinstance(value, str) and isinstance(datatype, DayTimeIntervalType):
502
521
  return f"{str_to_sql_for_day_time_interval(value, datatype)} :: {convert_sp_to_sf_type(datatype)}"
503
522
 
523
+ if isinstance(value, timedelta) and isinstance(datatype, DayTimeIntervalType):
524
+ # Serialize timedelta as an INTERVAL DAY TO SECOND literal.
525
+ # timedelta stores (days, seconds, microseconds) all non-negative after normalization.
526
+ sign = "-" if value < timedelta(0) else "+"
527
+ abs_val = abs(value)
528
+ d = abs_val.days
529
+ total_us = abs_val.seconds * 1_000_000 + abs_val.microseconds
530
+ h = total_us // 3_600_000_000
531
+ total_us %= 3_600_000_000
532
+ m = total_us // 60_000_000
533
+ total_us %= 60_000_000
534
+ s = total_us // 1_000_000
535
+ us = total_us % 1_000_000
536
+ interval_str = f"{sign}{d} {h:02d}:{m:02d}:{s:02d}.{us:06d}"
537
+ return f"INTERVAL '{interval_str}' DAY TO SECOND :: {convert_sp_to_sf_type(datatype)}"
538
+
539
+ if isinstance(value, int) and isinstance(datatype, YearMonthIntervalType):
540
+ # Serialize int (total months) as an INTERVAL YEAR TO MONTH literal.
541
+ sign = "-" if value < 0 else "+"
542
+ abs_months = abs(value)
543
+ years = abs_months // 12
544
+ months = abs_months % 12
545
+ interval_str = f"{sign}{years}-{months:02d}"
546
+ return f"INTERVAL '{interval_str}' YEAR TO MONTH :: {convert_sp_to_sf_type(datatype)}"
547
+
504
548
  raise TypeError(f"Unsupported datatype {datatype}, value {value} by to_sql()")
505
549
 
506
550
 
@@ -295,13 +295,22 @@ class Star(Expression):
295
295
 
296
296
  class UnresolvedAttribute(Expression, NamedExpression):
297
297
  def __init__(
298
- self, name: str, is_sql_text: bool = False, df_alias: Optional[str] = None
298
+ self,
299
+ name: str,
300
+ is_sql_text: bool = False,
301
+ df_alias: Optional[str] = None,
302
+ is_constant: bool = False,
299
303
  ) -> None:
300
304
  super().__init__()
301
305
  self.df_alias = df_alias
302
306
  self.name = name
303
307
  self.is_sql_text = is_sql_text
304
- if "$" in name:
308
+ self.is_constant = is_constant
309
+ if is_constant:
310
+ # Constant SQL text (e.g. object/array literals) does not reference
311
+ # any columns from the input relation.
312
+ self._dependent_column_names = COLUMN_DEPENDENCY_EMPTY
313
+ elif "$" in name:
305
314
  # $n refers to a column by index. We don't consider column index yet.
306
315
  # even though "$" isn't necessarily used to refer to a column by index. We're conservative here.
307
316
  self._dependent_column_names = COLUMN_DEPENDENCY_DOLLAR
@@ -445,19 +445,6 @@ class Selectable(LogicalPlan, ABC):
445
445
  # Add the last df ast id to the snowflake plan as the most recent
446
446
  # dataframe operation to create this plan.
447
447
  self._snowflake_plan.df_ast_ids = self.df_ast_ids
448
- # Propagate join output flag through passthrough SelectStatements
449
- # so chained joins can flatten into multi-way joins.
450
- # Only SelectStatement has has_clause/has_projection; other
451
- # Selectable subclasses (SelectSQL, SetStatement, etc.) skip this.
452
- if (
453
- isinstance(self, SelectStatement)
454
- and not self.has_clause
455
- and not self.has_projection
456
- and isinstance(self.from_, SelectSnowflakePlan)
457
- ):
458
- self._snowflake_plan._is_join_output = (
459
- self.from_._snowflake_plan._is_join_output
460
- )
461
448
  return self._snowflake_plan
462
449
 
463
450
  @property
@@ -605,8 +592,10 @@ class SelectableEntity(Selectable):
605
592
  self._attributes: Optional[List[Attribute]] = None
606
593
  self.table_reference = self.entity.name
607
594
  if self.entity.iceberg_changes_config is not None:
608
- self.table_reference += (
609
- self.entity.iceberg_changes_config.generate_sql_clause()
595
+ self.table_reference = (
596
+ self.entity.iceberg_changes_config.generate_table_reference(
597
+ self.entity.name
598
+ )
610
599
  )
611
600
  elif self.entity.time_travel_config is not None:
612
601
  self.table_reference += self.entity.time_travel_config.generate_sql_clause()
@@ -458,7 +458,6 @@ class SnowflakePlan(LogicalPlan):
458
458
  self.session = session
459
459
  self.source_plan = source_plan
460
460
  self.is_ddl_on_temp_object = is_ddl_on_temp_object
461
- self._is_join_output = False
462
461
  # We need to copy this list since we don't want to change it for the
463
462
  # previous SnowflakePlan objects
464
463
  self.api_calls = api_calls.copy() if api_calls else []
@@ -770,7 +769,6 @@ class SnowflakePlan(LogicalPlan):
770
769
  referenced_ctes=self.referenced_ctes,
771
770
  )
772
771
  plan.df_ast_ids = self.df_ast_ids
773
- plan._is_join_output = self._is_join_output
774
772
  return plan
775
773
 
776
774
  def __deepcopy__(self, memodict={}) -> "SnowflakePlan": # noqa: B006
@@ -810,7 +808,6 @@ class SnowflakePlan(LogicalPlan):
810
808
  if copied_source_plan:
811
809
  copied_source_plan._is_valid_for_replacement = True
812
810
  copied_plan.df_ast_ids = self.df_ast_ids
813
- copied_plan._is_join_output = self._is_join_output
814
811
 
815
812
  return copied_plan
816
813
 
@@ -1070,8 +1067,10 @@ class SnowflakePlanBuilder:
1070
1067
  table_reference = table_name
1071
1068
  if isinstance(source_plan, SnowflakeTable):
1072
1069
  if source_plan.iceberg_changes_config:
1073
- table_reference += (
1074
- source_plan.iceberg_changes_config.generate_sql_clause()
1070
+ table_reference = (
1071
+ source_plan.iceberg_changes_config.generate_table_reference(
1072
+ table_name
1073
+ )
1075
1074
  )
1076
1075
  elif source_plan.time_travel_config:
1077
1076
  table_reference += source_plan.time_travel_config.generate_sql_clause()
@@ -1239,8 +1238,7 @@ class SnowflakePlanBuilder:
1239
1238
  use_constant_subquery_alias: bool,
1240
1239
  directed: bool = False,
1241
1240
  ):
1242
- left_is_join = left._is_join_output
1243
- result = self.build_binary(
1241
+ return self.build_binary(
1244
1242
  lambda x, y: join_statement(
1245
1243
  x,
1246
1244
  y,
@@ -1257,14 +1255,11 @@ class SnowflakePlanBuilder:
1257
1255
  else None
1258
1256
  ),
1259
1257
  directed=directed,
1260
- left_is_join=left_is_join,
1261
1258
  ),
1262
1259
  left,
1263
1260
  right,
1264
1261
  source_plan,
1265
1262
  )
1266
- result._is_join_output = True
1267
- return result
1268
1263
 
1269
1264
  def save_as_table(
1270
1265
  self,
@@ -1323,6 +1318,8 @@ class SnowflakePlanBuilder:
1323
1318
  catalog_sync: optionally sets the catalog integration configured for Polaris Catalog
1324
1319
  storage_serialization_policy: specifies the storage serialization policy for the table
1325
1320
  iceberg_version: Overrides the version of iceberg to use. Defaults to 2 when unset.
1321
+ table_properties: optional mapping of Iceberg property names to values, emitted
1322
+ verbatim as a ``TABLE_PROPERTIES = ('k'='v', ...)`` clause on CREATE / CTAS.
1326
1323
  table_exists: whether the table already exists in the database.
1327
1324
  Only used for APPEND and TRUNCATE mode.
1328
1325
  """
@@ -0,0 +1,135 @@
1
+ #
2
+ # Copyright (c) 2012-2025 Snowflake Computing Inc. All rights reserved.
3
+ #
4
+ from __future__ import annotations
5
+
6
+ import uuid
7
+ from concurrent.futures import ThreadPoolExecutor
8
+ from typing import TYPE_CHECKING
9
+
10
+ if TYPE_CHECKING:
11
+ import polars as pl
12
+ from snowflake.snowpark.dataframe import DataFrame
13
+
14
+
15
+ def _empty_frame_from_schema(
16
+ df: DataFrame, statement_params: dict[str, str] | None
17
+ ) -> pl.DataFrame:
18
+ """Return an empty polars DataFrame with the DataFrame's schema."""
19
+ import polars as pl
20
+
21
+ return pl.from_arrow(
22
+ df.limit(0).to_arrow(
23
+ statement_params=statement_params,
24
+ _emit_ast=False,
25
+ )
26
+ )
27
+
28
+
29
+ def _open_stage_files_parallel(
30
+ session,
31
+ paths: list[str],
32
+ is_sproc: bool,
33
+ max_workers: int | None = None,
34
+ ) -> list:
35
+ """Open stage files concurrently, reading each with ``pl.read_parquet``
36
+ and returning the resulting ``pl.DataFrame`` (``with`` closes the handle
37
+ after read).
38
+
39
+ Uses ``SnowflakeFile.open`` inside a stored procedure and
40
+ ``session.file.get_stream`` on the client.
41
+ """
42
+ if not paths:
43
+ return []
44
+
45
+ import polars as pl
46
+
47
+ if is_sproc:
48
+ from snowflake.snowpark.files import SnowflakeFile
49
+
50
+ def opener(p: str):
51
+ return SnowflakeFile.open(p, "rb", require_scoped_url=False)
52
+
53
+ else:
54
+ opener = session.file.get_stream
55
+
56
+ def _work(p: str):
57
+ with opener(p) as f:
58
+ return pl.read_parquet(f)
59
+
60
+ with ThreadPoolExecutor(max_workers=max_workers) as ex:
61
+ return list(ex.map(_work, paths))
62
+
63
+
64
+ def _copy_df_to_stage(
65
+ df: DataFrame,
66
+ sub_prefix: str,
67
+ statement_params: dict[str, str] | None = None,
68
+ ) -> list[str]:
69
+ """COPY INTO the session stage as Parquet and return the staged file paths.
70
+
71
+ Uses ``DataFrame.write.copy_into_location`` so plan compilation and
72
+ statement params go through the same path as other write actions. No
73
+ pre-sort is applied — callers wanting row-group elimination should
74
+ ``.sort(...)`` before ``to_polars``.
75
+ """
76
+ rid = uuid.uuid4().hex[:12]
77
+ stage = df._session.get_session_stage().rstrip("/")
78
+ sub = f"{stage}/{sub_prefix}/{rid}/"
79
+ df.write.copy_into_location(
80
+ sub,
81
+ file_format_type="parquet",
82
+ format_type_options={"COMPRESSION": "SNAPPY"},
83
+ header=True,
84
+ overwrite=True,
85
+ statement_params=statement_params,
86
+ )
87
+ rows = df._session.sql(f"LIST '{sub}'").collect(statement_params=statement_params)
88
+ # `sub` is fully qualified; LIST returns stage-relative names. Construct fully-qualified paths.
89
+ return [sub + row["name"].rsplit("/", 1)[-1] for row in rows]
90
+
91
+
92
+ def arrow_eager(
93
+ df: DataFrame,
94
+ statement_params: dict[str, str] | None = None,
95
+ ) -> pl.DataFrame:
96
+ """Fetch the result as Arrow batches and return a polars DataFrame.
97
+
98
+ Backs the default ``to_polars()`` path (``transport="arrow"``).
99
+ Preserves full Snowflake type fidelity.
100
+ """
101
+ import polars as pl
102
+
103
+ parts = [
104
+ pl.from_arrow(batch)
105
+ for batch in df.to_arrow_batches(
106
+ statement_params=statement_params, _emit_ast=False
107
+ )
108
+ ]
109
+ if not parts:
110
+ return _empty_frame_from_schema(df, statement_params)
111
+ return pl.concat(parts) if len(parts) > 1 else parts[0]
112
+
113
+
114
+ def parquet_eager(
115
+ df: DataFrame,
116
+ is_sproc: bool = False,
117
+ statement_params: dict[str, str] | None = None,
118
+ max_workers: int | None = None,
119
+ ) -> pl.DataFrame:
120
+ """COPY INTO Parquet, read the staged files in parallel, return a polars DataFrame.
121
+
122
+ Backs ``to_polars(transport="parquet")``. Subject to the Parquet type-fidelity
123
+ caveats documented on ``DataFrame.to_polars``.
124
+ """
125
+ import polars as pl
126
+
127
+ paths = _copy_df_to_stage(df, "to_polars_parquet_eager", statement_params)
128
+ if not paths:
129
+ return _empty_frame_from_schema(df, statement_params)
130
+ frames = _open_stage_files_parallel(
131
+ df._session, paths, is_sproc, max_workers=max_workers
132
+ )
133
+ if not frames:
134
+ return _empty_frame_from_schema(df, statement_params)
135
+ return pl.concat(frames) if len(frames) > 1 else frames[0]