snowflake-snowpark-python 1.51.1__tar.gz → 1.53.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 (243) hide show
  1. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/CHANGELOG.md +47 -0
  2. {snowflake_snowpark_python-1.51.1/src/snowflake_snowpark_python.egg-info → snowflake_snowpark_python-1.53.0}/PKG-INFO +9 -6
  3. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/README.md +2 -2
  4. snowflake_snowpark_python-1.53.0/pyproject.toml +13 -0
  5. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/setup.py +9 -4
  6. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/analyzer_utils.py +159 -37
  7. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/select_statement.py +32 -13
  8. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/snowflake_plan.py +16 -10
  9. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/snowflake_plan_node.py +4 -10
  10. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/table_function.py +1 -9
  11. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/code_generation.py +1 -7
  12. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/compiler/cte_utils.py +6 -1
  13. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/compiler/repeated_subquery_elimination.py +38 -10
  14. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/base_dialect.py +8 -4
  15. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/databricks_dialect.py +8 -8
  16. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/mysql_dialect.py +8 -8
  17. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/oracledb_dialect.py +8 -8
  18. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/postgresql_dialect.py +16 -11
  19. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/sqlserver_dialect.py +4 -4
  20. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/debug_utils.py +1 -1
  21. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/type_utils.py +121 -10
  22. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/udf_utils.py +2 -8
  23. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/utils.py +227 -9
  24. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/xml_schema_inference.py +1 -1
  25. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/column.py +1 -8
  26. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/dataframe.py +17 -10
  27. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/dataframe_ai_functions.py +4 -4
  28. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/dataframe_na_functions.py +1 -9
  29. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/dataframe_reader.py +192 -13
  30. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/dataframe_stat_functions.py +1 -9
  31. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/dataframe_writer.py +1 -9
  32. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/files.py +1 -8
  33. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/functions.py +134 -30
  34. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/lineage.py +9 -2
  35. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/__init__.py +2 -2
  36. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/ordered_dataframe.py +1 -8
  37. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/indexing_overrides.py +1 -1
  38. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/pd_extensions.py +1 -1
  39. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/utils.py +2 -2
  40. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/row.py +1 -9
  41. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/secrets.py +39 -0
  42. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/session.py +24 -8
  43. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/stored_procedure.py +1 -7
  44. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/table.py +46 -8
  45. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/types.py +3 -9
  46. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/udaf.py +1 -7
  47. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/udf.py +1 -7
  48. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/udtf.py +1 -7
  49. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/version.py +1 -1
  50. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/window.py +1 -7
  51. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0/src/snowflake_snowpark_python.egg-info}/PKG-INFO +9 -6
  52. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake_snowpark_python.egg-info/requires.txt +9 -1
  53. snowflake_snowpark_python-1.51.1/pyproject.toml +0 -7
  54. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/LICENSE.txt +0 -0
  55. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/MANIFEST.in +0 -0
  56. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/setup.cfg +0 -0
  57. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/__init__.py +0 -0
  58. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_functions/__init__.py +0 -0
  59. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_functions/general_functions.py +0 -0
  60. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_functions/scalar_functions.py +0 -0
  61. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/__init__.py +0 -0
  62. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/__init__.py +0 -0
  63. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/analyzer.py +0 -0
  64. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/binary_expression.py +0 -0
  65. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/binary_plan_node.py +0 -0
  66. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/datatype_mapper.py +0 -0
  67. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/expression.py +0 -0
  68. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/grouping_set.py +0 -0
  69. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/metadata_utils.py +0 -0
  70. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/query_plan_analysis_utils.py +0 -0
  71. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/schema_utils.py +0 -0
  72. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/sort_expression.py +0 -0
  73. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/table_merge_expression.py +0 -0
  74. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/unary_expression.py +0 -0
  75. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/unary_plan_node.py +0 -0
  76. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/analyzer/window_expression.py +0 -0
  77. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/ast/__init__.py +0 -0
  78. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/ast/batch.py +0 -0
  79. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/ast/builder.py +0 -0
  80. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/ast/utils.py +0 -0
  81. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/compiler/__init__.py +0 -0
  82. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/compiler/large_query_breakdown.py +0 -0
  83. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/compiler/plan_compiler.py +0 -0
  84. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/compiler/query_generator.py +0 -0
  85. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/compiler/telemetry_constants.py +0 -0
  86. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/compiler/utils.py +0 -0
  87. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/__init__.py +0 -0
  88. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/datasource_partitioner.py +0 -0
  89. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/datasource_reader.py +0 -0
  90. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/datasource_typing.py +0 -0
  91. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/__init__.py +0 -0
  92. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/dbms_dialects/sqlite3_dialect.py +0 -0
  93. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/drivers/__init__.py +0 -0
  94. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/drivers/base_driver.py +0 -0
  95. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/drivers/databricks_driver.py +0 -0
  96. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/drivers/oracledb_driver.py +0 -0
  97. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/drivers/psycopg2_driver.py +0 -0
  98. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/drivers/pymsql_driver.py +0 -0
  99. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/drivers/pyodbc_driver.py +0 -0
  100. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/drivers/sqlite_driver.py +0 -0
  101. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/jdbc.py +0 -0
  102. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/data_source/utils.py +0 -0
  103. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/error_message.py +0 -0
  104. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/event_table_telemetry.py +0 -0
  105. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/open_telemetry.py +0 -0
  106. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/packaging_utils.py +0 -0
  107. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/proto/generated/__init__.py +0 -0
  108. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/proto/generated/ast_pb2.py +0 -0
  109. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/proto/generated/ast_pb2.pyi +0 -0
  110. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/select_projection_complexity_utils.py +0 -0
  111. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/server_connection.py +0 -0
  112. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/snowpark_profiler.py +0 -0
  113. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/telemetry.py +0 -0
  114. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/temp_table_auto_cleaner.py +0 -0
  115. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/xml_reader.py +0 -0
  116. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/_internal/xpath_handlers.py +0 -0
  117. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/async_job.py +0 -0
  118. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/catalog.py +0 -0
  119. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/context.py +0 -0
  120. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/dataframe_analytics_functions.py +0 -0
  121. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/dataframe_profiler.py +0 -0
  122. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/exceptions.py +0 -0
  123. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/file_operation.py +0 -0
  124. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/__init__.py +0 -0
  125. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_analyzer.py +0 -0
  126. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_connection.py +0 -0
  127. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_constants.py +0 -0
  128. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_functions.py +0 -0
  129. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_nop_analyzer.py +0 -0
  130. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_nop_connection.py +0 -0
  131. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_nop_plan.py +0 -0
  132. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_options.py +0 -0
  133. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_pandas_util.py +0 -0
  134. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_plan.py +0 -0
  135. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_plan_builder.py +0 -0
  136. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_select_statement.py +0 -0
  137. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_snowflake_data_type.py +0 -0
  138. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_snowflake_to_pandas_converter.py +0 -0
  139. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_stage_registry.py +0 -0
  140. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_stored_procedure.py +0 -0
  141. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_telemetry.py +0 -0
  142. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_udaf.py +0 -0
  143. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_udf.py +0 -0
  144. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_udf_utils.py +0 -0
  145. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_udtf.py +0 -0
  146. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_util.py +0 -0
  147. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/_window_utils.py +0 -0
  148. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/mock/exceptions.py +0 -0
  149. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/__init__.py +0 -0
  150. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/config/__init__.py +0 -0
  151. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/config/__main__.py +0 -0
  152. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/config/envvars.py +0 -0
  153. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/config/pubsub.py +0 -0
  154. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/conftest.py +0 -0
  155. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/__init__.py +0 -0
  156. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/aggregation_utils.py +0 -0
  157. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/align_utils.py +0 -0
  158. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/apply_utils.py +0 -0
  159. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/binary_op_utils.py +0 -0
  160. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/concat_utils.py +0 -0
  161. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/cumulative_utils.py +0 -0
  162. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/cut_utils.py +0 -0
  163. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/frame.py +0 -0
  164. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/generator_utils.py +0 -0
  165. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/get_dummies_utils.py +0 -0
  166. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/groupby_utils.py +0 -0
  167. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/indexing_utils.py +0 -0
  168. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/io_utils.py +0 -0
  169. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/isin_utils.py +0 -0
  170. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/join_utils.py +0 -0
  171. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/pivot_utils.py +0 -0
  172. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/resample_utils.py +0 -0
  173. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/row_count_estimation.py +0 -0
  174. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/session.py +0 -0
  175. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/snowpark_pandas_types.py +0 -0
  176. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/statement_params_constants.py +0 -0
  177. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/telemetry.py +0 -0
  178. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/timestamp_utils.py +0 -0
  179. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/transpose_utils.py +0 -0
  180. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/type_utils.py +0 -0
  181. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/unpivot_utils.py +0 -0
  182. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/utils.py +0 -0
  183. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/where_utils.py +0 -0
  184. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_internal/window_utils.py +0 -0
  185. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/_typing.py +0 -0
  186. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/compiler/__init__.py +0 -0
  187. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/compiler/doc_utils.py +0 -0
  188. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/compiler/ray_utils.py +0 -0
  189. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/compiler/snowflake_query_compiler.py +0 -0
  190. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/__init__.py +0 -0
  191. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/base.py +0 -0
  192. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/dataframe.py +0 -0
  193. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/datetime_index.py +0 -0
  194. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/general.py +0 -0
  195. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/groupby.py +0 -0
  196. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/index.py +0 -0
  197. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/io.py +0 -0
  198. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/resample.py +0 -0
  199. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/series.py +0 -0
  200. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/series_utils.py +0 -0
  201. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/shared_docs.py +0 -0
  202. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/timedelta_index.py +0 -0
  203. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/docstrings/window.py +0 -0
  204. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/__init__.py +0 -0
  205. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/base_overrides.py +0 -0
  206. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/dataframe_extensions.py +0 -0
  207. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/dataframe_groupby_overrides.py +0 -0
  208. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/dataframe_overrides.py +0 -0
  209. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/datetime_index.py +0 -0
  210. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/general_overrides.py +0 -0
  211. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/index.py +0 -0
  212. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/io_overrides.py +0 -0
  213. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/resample_overrides.py +0 -0
  214. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/resampler_groupby_overrides.py +0 -0
  215. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/rolling_groupby_overrides.py +0 -0
  216. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/series_extensions.py +0 -0
  217. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/series_groupby_overrides.py +0 -0
  218. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/series_overrides.py +0 -0
  219. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/snow_partition_iterator.py +0 -0
  220. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/timedelta_index.py +0 -0
  221. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/extensions/window_overrides.py +0 -0
  222. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/io/__init__.py +0 -0
  223. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/io/factories.py +0 -0
  224. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/io/snow_io.py +0 -0
  225. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/utils/__init__.py +0 -0
  226. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/utils/error_message.py +0 -0
  227. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/utils/exceptions.py +0 -0
  228. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/utils/frontend_constants.py +0 -0
  229. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/utils/numpy_to_pandas.py +0 -0
  230. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/plugin/utils/warning_message.py +0 -0
  231. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/modin/utils.py +0 -0
  232. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/py.typed +0 -0
  233. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/query_history.py +0 -0
  234. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/relational_grouped_dataframe.py +0 -0
  235. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/stored_procedure_profiler.py +0 -0
  236. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/table_function.py +0 -0
  237. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/testing.py +0 -0
  238. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake/snowpark/udf_profiler.py +0 -0
  239. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake_snowpark_python.egg-info/SOURCES.txt +0 -0
  240. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake_snowpark_python.egg-info/dependency_links.txt +0 -0
  241. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake_snowpark_python.egg-info/namespace_packages.txt +0 -0
  242. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake_snowpark_python.egg-info/not-zip-safe +0 -0
  243. {snowflake_snowpark_python-1.51.1 → snowflake_snowpark_python-1.53.0}/src/snowflake_snowpark_python.egg-info/top_level.txt +0 -0
@@ -1,5 +1,52 @@
1
1
  # Release History
2
2
 
3
+ ## 1.53.0 (2026-07-09)
4
+
5
+ ### Snowpark Python API Updates
6
+
7
+ #### New Features
8
+
9
+ - Added the `udf_init_once` decorator in `snowflake.snowpark.functions` for marking functions to be executed once during pre-fork initialization on Snowflake workers, matching the server-side `_snowflake.udf_init_once` API.
10
+
11
+ #### Bug Fixes
12
+
13
+ - Fixed a bug where stage paths and file format names that contain single quotes were not consistently escaped when generating SQL, which could produce malformed statements. This affects `INFER_SCHEMA` (used by `DataFrameReader.csv`/`json`/`parquet`/`orc`/`avro`) and `COPY FILES` (used by `FileOperation.copy_files`).
14
+ - Fixed a bug where single quotes and backslashes in stage/file paths were not correctly escaped when generating `COPY INTO` / `PUT` / `GET` SQL, which could produce malformed statements. This affects `DataFrame.write.csv`/`copy_into_location` and the Snowpark-pandas `DataFrame.to_csv` stage path.
15
+ - Fixed a bug where column names containing quote characters returned by an external database were not correctly escaped when generating the `SELECT` query for `DataFrameReader.dbapi`, which could produce malformed SQL. Embedded quote characters in identifiers are now doubled (backticks for Databricks/MySQL, double quotes for Oracle/PostgreSQL/SQL Server).
16
+ - Fixed a bug where the destination passed to `DataFrameWriter.copy_into_location` (and `csv`/`json`/`parquet`/`save`) was embedded into the generated `COPY INTO` statement without quoting, which could produce malformed SQL for locations containing single quotes. The location is now consistently quoted and escaped, and a string that merely starts and ends with a single quote but contains unescaped interior quotes is no longer treated as an already-quoted literal; it is fully escaped so it stays a single SQL string literal.
17
+ - Fixed a bug where UDF default argument values reconstructed from a source file in `register_from_file` were evaluated with `eval()`; they are now evaluated only against the documented set of supported default-value types, and unsupported expressions are ignored.
18
+ - Fixed a bug where `object_name`, `object_domain`, or `object_version` values containing single quotes or backslashes in `session.lineage.trace()` caused incorrect SQL generation. These values are now properly escaped before being embedded in the `SYSTEM$DGQL` call.
19
+ - 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.
20
+ - 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).
21
+
22
+ #### Dependency Updates
23
+
24
+ - Lifted `protobuf` restriction for Python 3.14 from `==5.29.3` to `>=5.29.3,<6.34`.
25
+ - Capped `pandas` to `<3.0.0` for the `[pandas]` install extra, as Snowpark Python pandas-related features may not be fully compatible with pandas 3.0 or later.
26
+
27
+ ## 1.52.0 (2026-06-10)
28
+
29
+ ### Snowpark Python API Updates
30
+
31
+ #### New Features
32
+
33
+ - Added `get_wif_token` to `snowflake.snowpark.secrets` for workload identity federation tokens on the Snowflake server (not available in SPCS file-based secret environments).
34
+
35
+ #### Bug Fixes
36
+
37
+ - Fixed a bug where copying a `DataFrame` via `copy.copy()` lost post-aggregate state, causing subsequent `.limit()` or `.sort()` to generate incorrect SQL.
38
+ - Fixed a bug where calling `DataFrame.alias()` twice on the same DataFrame (e.g. for a self-join) caused both aliases to share the same internal column-mapping dictionary. This made `col("R", "col")` resolve to the same column as `col("L", "col")`, producing incorrect join conditions and filter expressions.
39
+ - Fixed a bug where `cloudpickle` could not be resolved when registering a Python stored procedure or UDF with `runtime_version='3.13'`.
40
+
41
+ #### Improvements
42
+
43
+ - Improved CTE optimization to deduplicate identical subtrees in self-joins, which were previously emitted as repeated subqueries.
44
+ - Reduced the size of generated query text for repeated join operations.
45
+
46
+ #### Deprecations
47
+
48
+ - Removed support for Python 3.9.
49
+
3
50
  ## 1.51.1 (2026-05-28)
4
51
 
5
52
  #### Documentation
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: snowflake-snowpark-python
3
- Version: 1.51.1
3
+ Version: 1.53.0
4
4
  Summary: Snowflake Snowpark for Python
5
5
  Home-page: https://www.snowflake.com/
6
6
  Author: Snowflake, Inc
@@ -22,7 +22,6 @@ Classifier: License :: OSI Approved :: Apache Software License
22
22
  Classifier: Operating System :: OS Independent
23
23
  Classifier: Programming Language :: SQL
24
24
  Classifier: Programming Language :: Python :: 3 :: Only
25
- Classifier: Programming Language :: Python :: 3.9
26
25
  Classifier: Programming Language :: Python :: 3.10
27
26
  Classifier: Programming Language :: Python :: 3.11
28
27
  Classifier: Programming Language :: Python :: 3.12
@@ -33,7 +32,7 @@ Classifier: Topic :: Software Development :: Libraries
33
32
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
34
33
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
35
34
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
36
- Requires-Python: >=3.9, <3.15
35
+ Requires-Python: >=3.10, <3.15
37
36
  Description-Content-Type: text/markdown
38
37
  License-File: LICENSE.txt
39
38
  Requires-Dist: setuptools>=40.6.0
@@ -42,13 +41,16 @@ Requires-Dist: snowflake-connector-python<5.0.0,>=3.17.0
42
41
  Requires-Dist: typing-extensions<5.0.0,>=4.1.0
43
42
  Requires-Dist: pyyaml
44
43
  Requires-Dist: cloudpickle!=2.1.0,!=2.2.0,<=3.1.1,>=1.6.0
45
- Requires-Dist: protobuf<6.34,>=3.20
44
+ Requires-Dist: protobuf<6.34,>=3.20; python_version < "3.14"
45
+ Requires-Dist: protobuf<6.34,>=5.29.0; python_version >= "3.14"
46
46
  Requires-Dist: python-dateutil
47
47
  Requires-Dist: tzlocal
48
48
  Provides-Extra: pandas
49
49
  Requires-Dist: snowflake-connector-python[pandas]<5.0.0,>=3.17.0; extra == "pandas"
50
+ Requires-Dist: pandas<3.0.0; extra == "pandas"
50
51
  Provides-Extra: modin
51
52
  Requires-Dist: snowflake-connector-python[pandas]<5.0.0,>=3.17.0; extra == "modin"
53
+ Requires-Dist: pandas<3.0.0; extra == "modin"
52
54
  Requires-Dist: modin<0.38.0,>=0.36.0; extra == "modin"
53
55
  Requires-Dist: pandas<=2.4; extra == "modin"
54
56
  Requires-Dist: tqdm; extra == "modin"
@@ -77,6 +79,7 @@ Requires-Dist: lxml; extra == "development"
77
79
  Requires-Dist: pyarrow; extra == "development"
78
80
  Provides-Extra: modin-development
79
81
  Requires-Dist: snowflake-connector-python[pandas]<5.0.0,>=3.17.0; extra == "modin-development"
82
+ Requires-Dist: pandas<3.0.0; extra == "modin-development"
80
83
  Requires-Dist: modin<0.38.0,>=0.36.0; extra == "modin-development"
81
84
  Requires-Dist: pandas<=2.4; extra == "modin-development"
82
85
  Requires-Dist: tqdm; extra == "modin-development"
@@ -149,9 +152,9 @@ If you don't have a Snowflake account yet, you can [sign up for a 30-day free tr
149
152
 
150
153
  ### Create a Python virtual environment
151
154
  You can use [miniconda][miniconda], [anaconda][anaconda], or [virtualenv][virtualenv]
152
- to create a Python 3.9, 3.10, 3.11, 3.12 or 3.13 virtual environment.
155
+ to create a Python 3.10, 3.11, 3.12 or 3.13 virtual environment.
153
156
 
154
- For Snowpark pandas, only Python 3.9, 3.10, or 3.11 is supported.
157
+ For Snowpark pandas, only Python 3.10 or 3.11 is supported.
155
158
 
156
159
  To have the best experience when using it with UDFs, [creating a local conda environment with the Snowflake channel][use snowflake channel] is recommended.
157
160
 
@@ -18,9 +18,9 @@ If you don't have a Snowflake account yet, you can [sign up for a 30-day free tr
18
18
 
19
19
  ### Create a Python virtual environment
20
20
  You can use [miniconda][miniconda], [anaconda][anaconda], or [virtualenv][virtualenv]
21
- to create a Python 3.9, 3.10, 3.11, 3.12 or 3.13 virtual environment.
21
+ to create a Python 3.10, 3.11, 3.12 or 3.13 virtual environment.
22
22
 
23
- For Snowpark pandas, only Python 3.9, 3.10, or 3.11 is supported.
23
+ For Snowpark pandas, only Python 3.10 or 3.11 is supported.
24
24
 
25
25
  To have the best experience when using it with UDFs, [creating a local conda environment with the Snowflake channel][use snowflake channel] is recommended.
26
26
 
@@ -0,0 +1,13 @@
1
+ [build-system]
2
+ requires = [
3
+ "setuptools",
4
+ # py>=3.14: protoc-wheel-0 has no cp314 wheel on PyPI, so it cannot be installed
5
+ # in pip's build isolation venv. setup.py falls back to shutil.which("protoc").
6
+ "protoc-wheel-0==21.1; python_version < '3.14'", # Protocol buffer compiler for Snowpark IR
7
+ # py>=3.14: pin <=3.6.0 so the build isolation venv does not install mypy-protobuf 5.x,
8
+ # whose extensions_pb2.py was generated with protobuf 6.x gencode and fails at import
9
+ # time when the isolated venv resolves protobuf 5.x (Snowflake internal channel).
10
+ "mypy-protobuf<=3.6.0; python_version >= '3.14'",
11
+ "mypy-protobuf; python_version < '3.14'", # used in generating typed Python code from protobuf for Snowpark IR
12
+ ]
13
+ build-backend = "setuptools.build_meta"
@@ -28,17 +28,23 @@ INSTALL_REQ_LIST = [
28
28
  "pyyaml",
29
29
  "cloudpickle>=1.6.0,<=3.1.1,!=2.1.0,!=2.2.0",
30
30
  # `protoc` < 3.20 is not able to generate protobuf code compatible with protobuf >= 3.20.
31
- "protobuf>=3.20, <6.34", # Snowpark IR
31
+ "protobuf>=3.20, <6.34; python_version < '3.14'", # Snowpark IR
32
+ # py314: protoc-wheel-0 has no cp314 wheel; setup.py uses libprotobuf's protoc from PATH.
33
+ # The pre-generated ast_pb2.py in the tarball has no ValidateProtobufRuntimeVersion call
34
+ # (built with protoc 3.21), so 5.29.0+ is sufficient. Conda recipes may regenerate with
35
+ # a different protoc version and override this constraint via their run deps.
36
+ "protobuf>=5.29.0,<6.34; python_version >= '3.14'", # Snowpark IR
32
37
  "python-dateutil", # Snowpark IR
33
38
  "tzlocal", # Snowpark IR
34
39
  ]
35
- REQUIRED_PYTHON_VERSION = ">=3.9, <3.15"
40
+ REQUIRED_PYTHON_VERSION = ">=3.10, <3.15"
36
41
 
37
42
  if os.getenv("SNOWFLAKE_IS_PYTHON_RUNTIME_TEST", False):
38
- REQUIRED_PYTHON_VERSION = ">=3.9"
43
+ REQUIRED_PYTHON_VERSION = ">=3.10"
39
44
 
40
45
  PANDAS_REQUIREMENTS = [
41
46
  f"snowflake-connector-python[pandas]{CONNECTOR_DEPENDENCY_VERSION}",
47
+ "pandas<3.0.0",
42
48
  ]
43
49
  MODIN_REQUIREMENTS = [
44
50
  *PANDAS_REQUIREMENTS,
@@ -246,7 +252,6 @@ setup(
246
252
  "Operating System :: OS Independent",
247
253
  "Programming Language :: SQL",
248
254
  "Programming Language :: Python :: 3 :: Only",
249
- "Programming Language :: Python :: 3.9",
250
255
  "Programming Language :: Python :: 3.10",
251
256
  "Programming Language :: Python :: 3.11",
252
257
  "Programming Language :: Python :: 3.12",
@@ -6,7 +6,7 @@
6
6
  import json
7
7
  import math
8
8
  import os
9
- import sys
9
+ import re
10
10
  import tempfile
11
11
  from typing import Any, Dict, List, Optional, Tuple, Union, Literal, Sequence
12
12
 
@@ -41,7 +41,8 @@ from snowflake.snowpark._internal.utils import (
41
41
  EMPTY_STRING,
42
42
  TempObjectType,
43
43
  escape_quotes,
44
- escape_single_quotes,
44
+ escape_quotes_and_backslashes,
45
+ escape_subfield_key,
45
46
  get_temp_type_for_object,
46
47
  is_single_quoted,
47
48
  is_sql_select_statement,
@@ -52,13 +53,7 @@ from snowflake.snowpark._internal.utils import (
52
53
  from snowflake.snowpark.row import Row
53
54
  from snowflake.snowpark.types import DataType
54
55
 
55
- # Python 3.8 needs to use typing.Iterable because collections.abc.Iterable is not subscriptable
56
- # Python 3.9 can use both
57
- # Python 3.10 needs to use collections.abc.Iterable because typing.Iterable is removed
58
- if sys.version_info <= (3, 9):
59
- from typing import Iterable
60
- else:
61
- from collections.abc import Iterable
56
+ from collections.abc import Iterable
62
57
 
63
58
  LEFT_PARENTHESIS = "("
64
59
  RIGHT_PARENTHESIS = ")"
@@ -409,7 +404,26 @@ def regexp_expression(expr: str, pattern: str, parameters: Optional[str] = None)
409
404
 
410
405
 
411
406
  def collate_expression(expr: str, collation_spec: str) -> str:
412
- return expr + COLLATE + single_quote(collation_spec)
407
+ # Escape the collation spec so a value containing single quotes or
408
+ # backslashes does not terminate the single-quoted literal early and produce
409
+ # invalid SQL.
410
+ #
411
+ # Preserve the historical behavior of single_quote(): a spec that is already
412
+ # wrapped in single quotes (e.g. "'en_US'") is treated as pre-quoted, so we
413
+ # strip the outer quotes, escape the interior, and re-wrap. An unquoted spec
414
+ # is escaped and wrapped. Specs (quoted or unquoted) with no interior quotes
415
+ # or backslashes therefore produce identical SQL to before.
416
+ if is_single_quoted(collation_spec):
417
+ inner = collation_spec[1:-1]
418
+ else:
419
+ inner = collation_spec
420
+ return (
421
+ expr
422
+ + COLLATE
423
+ + SINGLE_QUOTE
424
+ + escape_quotes_and_backslashes(inner)
425
+ + SINGLE_QUOTE
426
+ )
413
427
 
414
428
 
415
429
  def subfield_expression(expr: str, field: Union[str, int]) -> str:
@@ -417,7 +431,12 @@ def subfield_expression(expr: str, field: Union[str, int]) -> str:
417
431
  expr
418
432
  + LEFT_BRACKET
419
433
  + (
420
- SINGLE_QUOTE + field + SINGLE_QUOTE
434
+ # Escape the field so a VARIANT/OBJECT key containing single quotes
435
+ # or backslashes does not terminate the literal early. A key whose
436
+ # single quotes are already doubled is preserved unchanged (minus
437
+ # backslash normalization) to keep the historical "double your own
438
+ # quotes" contract non-breaking.
439
+ SINGLE_QUOTE + escape_subfield_key(field) + SINGLE_QUOTE
421
440
  if isinstance(field, str)
422
441
  else str(field)
423
442
  )
@@ -438,7 +457,10 @@ def flatten_expression(
438
457
  + PATH
439
458
  + RIGHT_ARROW
440
459
  + SINGLE_QUOTE
441
- + (path or EMPTY_STRING)
460
+ # Escape the JSON path so a value containing single quotes or
461
+ # backslashes does not terminate the literal early and produce invalid
462
+ # SQL in the FLATTEN argument list.
463
+ + (escape_quotes_and_backslashes(path) if path else EMPTY_STRING)
442
464
  + SINGLE_QUOTE
443
465
  + COMMA
444
466
  + OUTER
@@ -968,6 +990,33 @@ def lateral_join_statement(
968
990
  )
969
991
 
970
992
 
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
+
971
1020
  def snowflake_supported_join_statement(
972
1021
  left: str,
973
1022
  right: str,
@@ -978,17 +1027,30 @@ def snowflake_supported_join_statement(
978
1027
  left_uuid: Optional[str] = None,
979
1028
  right_uuid: Optional[str] = None,
980
1029
  directed: bool = False,
1030
+ left_is_join: bool = False,
981
1031
  ) -> str:
982
1032
  LEFT_UUID = format_uuid(left_uuid)
983
1033
  RIGHT_UUID = format_uuid(right_uuid)
984
- left_alias = (
985
- "SNOWPARK_LEFT"
986
- if use_constant_subquery_alias
987
- else random_name_for_temp_object(TempObjectType.TABLE)
988
- )
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
989
1049
  right_alias = (
990
1050
  "SNOWPARK_RIGHT"
991
- if use_constant_subquery_alias
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.
992
1054
  else random_name_for_temp_object(TempObjectType.TABLE)
993
1055
  )
994
1056
 
@@ -1024,18 +1086,31 @@ def snowflake_supported_join_statement(
1024
1086
 
1025
1087
  maybe_directed_sql = DIRECTED_JOIN if directed else JOIN
1026
1088
 
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
+ )
1027
1112
  source = (
1028
- LEFT_PARENTHESIS
1029
- + NEW_LINE
1030
- + LEFT_UUID
1031
- + left
1032
- + NEW_LINE
1033
- + LEFT_UUID
1034
- + RIGHT_PARENTHESIS
1035
- + AS
1036
- + left_alias
1037
- + SPACE
1038
- + NEW_LINE
1113
+ left_expr
1039
1114
  + join_sql
1040
1115
  + maybe_directed_sql
1041
1116
  + NEW_LINE
@@ -1067,6 +1142,7 @@ def join_statement(
1067
1142
  left_uuid: Optional[str] = None,
1068
1143
  right_uuid: Optional[str] = None,
1069
1144
  directed: bool = False,
1145
+ left_is_join: bool = False,
1070
1146
  ) -> str:
1071
1147
  if isinstance(join_type, (LeftSemi, LeftAnti)):
1072
1148
  return left_semi_or_anti_join_statement(
@@ -1094,12 +1170,18 @@ def join_statement(
1094
1170
  left_uuid=left_uuid,
1095
1171
  right_uuid=right_uuid,
1096
1172
  directed=directed,
1173
+ left_is_join=left_is_join,
1097
1174
  )
1098
1175
 
1099
1176
 
1100
1177
  def get_comment_sql(comment: Optional[str]) -> str:
1101
1178
  return (
1102
- COMMENT + EQUALS + SINGLE_QUOTE + escape_single_quotes(comment) + SINGLE_QUOTE
1179
+ COMMENT + EQUALS + SINGLE_QUOTE
1180
+ # Escape backslashes and single quotes so a comment containing those
1181
+ # characters does not terminate the single-quoted literal early and
1182
+ # produce invalid SQL. A comment with no backslash/quote is emitted
1183
+ # unchanged.
1184
+ + escape_quotes_and_backslashes(comment) + SINGLE_QUOTE
1103
1185
  if comment
1104
1186
  else EMPTY_STRING
1105
1187
  )
@@ -1323,13 +1405,11 @@ def infer_schema_statement(
1323
1405
  + LEFT_PARENTHESIS
1324
1406
  + LOCATION
1325
1407
  + RIGHT_ARROW
1326
- + (path if is_single_quoted(path) else SINGLE_QUOTE + path + SINGLE_QUOTE)
1408
+ + single_quote(path)
1327
1409
  + COMMA
1328
1410
  + FILE_FORMAT
1329
1411
  + RIGHT_ARROW
1330
- + SINGLE_QUOTE
1331
- + file_format_name
1332
- + SINGLE_QUOTE
1412
+ + single_quote(file_format_name)
1333
1413
  + (
1334
1414
  ", "
1335
1415
  + ", ".join(
@@ -1358,7 +1438,14 @@ def file_operation_statement(
1358
1438
  return f"{REMOVE}{stage_location}{get_options_statement(options)}"
1359
1439
  if command.lower() == "copy_files":
1360
1440
  # For COPY FILES, file_name stores the value of the source stage location or subquery (from a DataFrame)
1361
- return f"{COPY_FILES}{INTO}{stage_location}{FROM}{file_name}{get_options_statement(options)}"
1441
+ # Quote stage_location; file_name may be a subquery that must not be quoted
1442
+ quoted_target = single_quote(stage_location)
1443
+ # If file_name is a subquery (starts with '('), don't quote it
1444
+ if file_name.strip().startswith("("):
1445
+ source = file_name
1446
+ else:
1447
+ source = single_quote(file_name)
1448
+ return f"{COPY_FILES}{INTO}{quoted_target}{FROM}{source}{get_options_statement(options)}"
1362
1449
  raise ValueError(f"Unsupported file operation type {command}")
1363
1450
 
1364
1451
 
@@ -1878,7 +1965,7 @@ def copy_into_location(
1878
1965
  return (
1879
1966
  COPY
1880
1967
  + INTO
1881
- + stage_location
1968
+ + escape_location_literal(stage_location)
1882
1969
  + FROM
1883
1970
  + LEFT_PARENTHESIS
1884
1971
  + query
@@ -2086,12 +2173,47 @@ def table(content: str) -> str:
2086
2173
 
2087
2174
 
2088
2175
  def single_quote(value: str) -> str:
2089
- if value.startswith(SINGLE_QUOTE) and value.endswith(SINGLE_QUOTE):
2176
+ if is_single_quoted(value):
2090
2177
  return value
2091
2178
  else:
2179
+ # Double any embedded single quotes so the value stays a single literal
2180
+ value = value.replace("'", "''")
2092
2181
  return SINGLE_QUOTE + value + SINGLE_QUOTE
2093
2182
 
2094
2183
 
2184
+ # Matches a complete, well-formed single-quoted SQL literal. The three body
2185
+ # alternatives each start with a different character (non-quote/non-backslash,
2186
+ # ', \), so every input character fits exactly one branch -- the engine never
2187
+ # backtracks, giving linear-time matching even on adversarial input.
2188
+ # Matches: "'@stage/o''clock/'" (interior quote is doubled -> one literal)
2189
+ # No match: "'@x' UNION SELECT --'" (bare interior quote ends the literal early)
2190
+ _WELL_FORMED_SINGLE_QUOTED_LITERAL = re.compile(
2191
+ r"""
2192
+ ' # opening single quote
2193
+ ( # body: zero or more of...
2194
+ [^'\\] # any char that is neither a quote nor a backslash
2195
+ | '' # or a doubled (escaped) quote
2196
+ | \\. # or a backslash followed by any char (backslash escape)
2197
+ )*
2198
+ ' # closing single quote
2199
+ """,
2200
+ re.VERBOSE | re.DOTALL,
2201
+ )
2202
+
2203
+
2204
+ def escape_location_literal(value: str) -> str:
2205
+ """Return ``value`` as a single, well-formed single-quoted SQL literal.
2206
+
2207
+ Unlike :func:`single_quote`, a value that merely starts and ends with a
2208
+ single quote but contains unescaped interior quotes is treated as unquoted
2209
+ and fully escaped. This prevents a caller-controlled location from breaking
2210
+ out of the string literal in the generated ``COPY INTO`` statement.
2211
+ """
2212
+ if _WELL_FORMED_SINGLE_QUOTED_LITERAL.fullmatch(value):
2213
+ return value
2214
+ return SINGLE_QUOTE + value.replace("'", "''") + SINGLE_QUOTE
2215
+
2216
+
2095
2217
  def quote_name_without_upper_casing(name: str) -> str:
2096
2218
  return DOUBLE_QUOTE + escape_quotes(name) + DOUBLE_QUOTE
2097
2219
 
@@ -2,7 +2,6 @@
2
2
  # Copyright (c) 2012-2025 Snowflake Computing Inc. All rights reserved.
3
3
  #
4
4
 
5
- import sys
6
5
  import uuid
7
6
  import re
8
7
  from abc import ABC, abstractmethod
@@ -90,13 +89,7 @@ from snowflake.snowpark._internal.utils import (
90
89
  )
91
90
  import snowflake.snowpark.context as context
92
91
 
93
- # Python 3.8 needs to use typing.Iterable because collections.abc.Iterable is not subscriptable
94
- # Python 3.9 can use both
95
- # Python 3.10 needs to use collections.abc.Iterable because typing.Iterable is removed
96
- if sys.version_info <= (3, 9):
97
- from typing import Iterable
98
- else:
99
- from collections.abc import Iterable
92
+ from collections.abc import Iterable
100
93
 
101
94
  SET_UNION = analyzer_utils.UNION
102
95
  SET_UNION_ALL = analyzer_utils.UNION_ALL
@@ -276,6 +269,7 @@ class Selectable(LogicalPlan, ABC):
276
269
  self.pre_actions: Optional[List["Query"]] = None
277
270
  self.post_actions: Optional[List["Query"]] = None
278
271
  self.flatten_disabled: bool = False
272
+ self.protect_dropped_new_columns: bool = False
279
273
  self._column_states: Optional[ColumnStateDict] = None
280
274
  self._snowflake_plan: Optional[SnowflakePlan] = None
281
275
  self.expr_to_alias = (
@@ -451,6 +445,19 @@ class Selectable(LogicalPlan, ABC):
451
445
  # Add the last df ast id to the snowflake plan as the most recent
452
446
  # dataframe operation to create this plan.
453
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
+ )
454
461
  return self._snowflake_plan
455
462
 
456
463
  @property
@@ -597,7 +604,11 @@ class SelectableEntity(Selectable):
597
604
  # Metadata/Attributes for the plan
598
605
  self._attributes: Optional[List[Attribute]] = None
599
606
  self.table_reference = self.entity.name
600
- if self.entity.time_travel_config is not None:
607
+ if self.entity.iceberg_changes_config is not None:
608
+ self.table_reference += (
609
+ self.entity.iceberg_changes_config.generate_sql_clause()
610
+ )
611
+ elif self.entity.time_travel_config is not None:
601
612
  self.table_reference += self.entity.time_travel_config.generate_sql_clause()
602
613
 
603
614
  def __deepcopy__(self, memodict={}) -> "SelectableEntity": # noqa: B006
@@ -963,7 +974,7 @@ class SelectStatement(Selectable):
963
974
  new._snowflake_plan = None
964
975
  new.flatten_disabled = False # by default a SelectStatement can be flattened.
965
976
  new._api_calls = self._api_calls.copy() if self._api_calls is not None else None
966
- new.df_aliased_col_name_to_real_col_name = (
977
+ new.df_aliased_col_name_to_real_col_name = deepcopy(
967
978
  self.df_aliased_col_name_to_real_col_name
968
979
  )
969
980
  new._merge_projection_complexity_with_subquery = (
@@ -1493,7 +1504,7 @@ class SelectStatement(Selectable):
1493
1504
  can_be_flattened = False
1494
1505
  else:
1495
1506
  can_be_flattened = can_select_statement_be_flattened(
1496
- self.column_states, new_column_states
1507
+ self.column_states, new_column_states, self.protect_dropped_new_columns
1497
1508
  )
1498
1509
 
1499
1510
  if can_be_flattened:
@@ -2190,7 +2201,9 @@ def parse_column_name(
2190
2201
 
2191
2202
 
2192
2203
  def can_select_statement_be_flattened(
2193
- subquery_column_states: ColumnStateDict, new_column_states: ColumnStateDict
2204
+ subquery_column_states: ColumnStateDict,
2205
+ new_column_states: ColumnStateDict,
2206
+ protect_dropped_new_columns: bool = False,
2194
2207
  ) -> bool:
2195
2208
  for col, state in new_column_states.items():
2196
2209
  dependent_columns = state.dependent_columns
@@ -2213,7 +2226,13 @@ def can_select_statement_be_flattened(
2213
2226
  state.change_state == ColumnChangeState.DROPPED
2214
2227
  and (subquery_state := subquery_column_states.get(col))
2215
2228
  and subquery_state.change_state == ColumnChangeState.NEW
2216
- and subquery_state.is_referenced_by_same_level_column
2229
+ and (
2230
+ subquery_state.is_referenced_by_same_level_column
2231
+ # If the subquery was explicitly marked (e.g. by the SCOS withColumn
2232
+ # path), preserve it so that future filter/sort clauses can still
2233
+ # reference the dropped NEW column.
2234
+ or protect_dropped_new_columns
2235
+ )
2217
2236
  ):
2218
2237
  return False
2219
2238
  return True