sqlframe 1.14.0__tar.gz → 2.1.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 (227) hide show
  1. {sqlframe-1.14.0 → sqlframe-2.1.0}/Makefile +3 -0
  2. {sqlframe-1.14.0 → sqlframe-2.1.0}/PKG-INFO +6 -2
  3. {sqlframe-1.14.0 → sqlframe-2.1.0}/README.md +5 -1
  4. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/configuration.md +30 -2
  5. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/duckdb.md +3 -0
  6. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/postgres.md +2 -0
  7. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/snowflake.md +3 -1
  8. {sqlframe-1.14.0 → sqlframe-2.1.0}/setup.py +8 -8
  9. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/_version.py +2 -2
  10. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/_typing.py +1 -0
  11. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/catalog.py +36 -13
  12. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/column.py +11 -9
  13. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/dataframe.py +72 -79
  14. sqlframe-2.1.0/sqlframe/base/decorators.py +15 -0
  15. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/function_alternatives.py +36 -25
  16. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/functions.py +88 -28
  17. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/mixins/catalog_mixins.py +156 -45
  18. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/mixins/dataframe_mixins.py +1 -1
  19. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/readerwriter.py +12 -14
  20. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/session.py +157 -84
  21. sqlframe-2.1.0/sqlframe/base/udf.py +36 -0
  22. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/util.py +71 -20
  23. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/bigquery/catalog.py +79 -28
  24. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/bigquery/functions.py +5 -8
  25. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/bigquery/session.py +4 -2
  26. sqlframe-2.1.0/sqlframe/bigquery/udf.py +11 -0
  27. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/duckdb/catalog.py +30 -13
  28. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/duckdb/dataframe.py +5 -0
  29. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/duckdb/functions.py +2 -0
  30. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/duckdb/readwriter.py +7 -6
  31. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/duckdb/session.py +8 -2
  32. sqlframe-2.1.0/sqlframe/duckdb/udf.py +19 -0
  33. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/postgres/catalog.py +30 -18
  34. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/postgres/functions.py +2 -0
  35. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/postgres/session.py +16 -5
  36. sqlframe-2.1.0/sqlframe/postgres/udf.py +11 -0
  37. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/redshift/catalog.py +28 -13
  38. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/redshift/session.py +4 -2
  39. sqlframe-2.1.0/sqlframe/redshift/udf.py +11 -0
  40. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/snowflake/catalog.py +64 -24
  41. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/snowflake/dataframe.py +9 -5
  42. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/snowflake/functions.py +1 -0
  43. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/snowflake/session.py +5 -2
  44. sqlframe-2.1.0/sqlframe/snowflake/udf.py +11 -0
  45. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/spark/catalog.py +180 -10
  46. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/spark/session.py +46 -14
  47. sqlframe-2.1.0/sqlframe/spark/udf.py +34 -0
  48. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/standalone/session.py +3 -0
  49. sqlframe-2.1.0/sqlframe/standalone/udf.py +11 -0
  50. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe.egg-info/PKG-INFO +6 -2
  51. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe.egg-info/SOURCES.txt +9 -0
  52. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe.egg-info/requires.txt +8 -8
  53. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/bigquery/test_bigquery_catalog.py +2 -2
  54. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/bigquery/test_bigquery_dataframe.py +15 -15
  55. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/bigquery/test_bigquery_session.py +1 -1
  56. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/duck/test_duckdb_catalog.py +12 -11
  57. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/duck/test_duckdb_dataframe.py +50 -14
  58. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/duck/test_duckdb_session.py +1 -1
  59. sqlframe-2.1.0/tests/integration/engines/duck/test_duckdb_udf.py +12 -0
  60. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/postgres/test_postgres_catalog.py +4 -4
  61. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/postgres/test_postgres_dataframe.py +7 -7
  62. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/postgres/test_postgres_session.py +2 -2
  63. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/redshift/test_redshift_catalog.py +4 -4
  64. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/redshift/test_redshift_session.py +2 -2
  65. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/snowflake/test_snowflake_catalog.py +50 -50
  66. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/snowflake/test_snowflake_dataframe.py +44 -44
  67. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/snowflake/test_snowflake_session.py +2 -2
  68. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/spark/test_spark_catalog.py +4 -4
  69. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/test_engine_dataframe.py +8 -33
  70. sqlframe-2.1.0/tests/integration/engines/test_engine_session.py +41 -0
  71. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/test_int_functions.py +77 -42
  72. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/test_int_dataframe.py +68 -0
  73. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/unit/standalone/fixtures.py +5 -1
  74. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/unit/standalone/test_dataframe.py +9 -9
  75. sqlframe-2.1.0/tests/unit/standalone/test_dataframe_writer.py +107 -0
  76. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/unit/standalone/test_functions.py +14 -5
  77. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/unit/standalone/test_session.py +1 -1
  78. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/unit/test_util.py +1 -0
  79. sqlframe-1.14.0/sqlframe/base/decorators.py +0 -53
  80. sqlframe-1.14.0/tests/integration/engines/test_engine_session.py +0 -47
  81. sqlframe-1.14.0/tests/unit/standalone/test_dataframe_writer.py +0 -107
  82. {sqlframe-1.14.0 → sqlframe-2.1.0}/.github/CODEOWNERS +0 -0
  83. {sqlframe-1.14.0 → sqlframe-2.1.0}/.github/workflows/main.workflow.yaml +0 -0
  84. {sqlframe-1.14.0 → sqlframe-2.1.0}/.github/workflows/publish.workflow.yaml +0 -0
  85. {sqlframe-1.14.0 → sqlframe-2.1.0}/.gitignore +0 -0
  86. {sqlframe-1.14.0 → sqlframe-2.1.0}/.pre-commit-config.yaml +0 -0
  87. {sqlframe-1.14.0 → sqlframe-2.1.0}/.readthedocs.yaml +0 -0
  88. {sqlframe-1.14.0 → sqlframe-2.1.0}/LICENSE +0 -0
  89. {sqlframe-1.14.0 → sqlframe-2.1.0}/blogs/add_chatgpt_support.md +0 -0
  90. {sqlframe-1.14.0 → sqlframe-2.1.0}/blogs/images/add_chatgpt_support/adding_ai_to_meal.jpeg +0 -0
  91. {sqlframe-1.14.0 → sqlframe-2.1.0}/blogs/images/add_chatgpt_support/hype_train.gif +0 -0
  92. {sqlframe-1.14.0 → sqlframe-2.1.0}/blogs/images/add_chatgpt_support/marvin_paranoid_robot.gif +0 -0
  93. {sqlframe-1.14.0 → sqlframe-2.1.0}/blogs/images/add_chatgpt_support/nonsense_sql.png +0 -0
  94. {sqlframe-1.14.0 → sqlframe-2.1.0}/blogs/images/add_chatgpt_support/openai_full_rewrite.png +0 -0
  95. {sqlframe-1.14.0 → sqlframe-2.1.0}/blogs/images/add_chatgpt_support/openai_replacing_cte_names.png +0 -0
  96. {sqlframe-1.14.0 → sqlframe-2.1.0}/blogs/images/add_chatgpt_support/sqlglot_optimized_code.png +0 -0
  97. {sqlframe-1.14.0 → sqlframe-2.1.0}/blogs/images/add_chatgpt_support/sunny_shake_head_no.gif +0 -0
  98. {sqlframe-1.14.0 → sqlframe-2.1.0}/blogs/images/but_wait_theres_more.gif +0 -0
  99. {sqlframe-1.14.0 → sqlframe-2.1.0}/blogs/images/cake.gif +0 -0
  100. {sqlframe-1.14.0 → sqlframe-2.1.0}/blogs/images/you_get_pyspark_api.gif +0 -0
  101. {sqlframe-1.14.0 → sqlframe-2.1.0}/blogs/sqlframe_universal_dataframe_api.md +0 -0
  102. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/bigquery.md +0 -0
  103. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/docs/bigquery.md +0 -0
  104. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/docs/duckdb.md +0 -0
  105. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/docs/images/SF.png +0 -0
  106. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/docs/images/favicon.png +0 -0
  107. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/docs/images/favicon_old.png +0 -0
  108. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/docs/images/sqlframe_diagram.png +0 -0
  109. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/docs/images/sqlframe_logo.png +0 -0
  110. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/docs/postgres.md +0 -0
  111. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/images/SF.png +0 -0
  112. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/images/favicon.png +0 -0
  113. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/images/favicon_old.png +0 -0
  114. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/images/sqlframe_diagram.png +0 -0
  115. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/images/sqlframe_logo.png +0 -0
  116. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/index.md +0 -0
  117. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/requirements.txt +0 -0
  118. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/spark.md +0 -0
  119. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/standalone.md +0 -0
  120. {sqlframe-1.14.0 → sqlframe-2.1.0}/docs/stylesheets/extra.css +0 -0
  121. {sqlframe-1.14.0 → sqlframe-2.1.0}/mkdocs.yml +0 -0
  122. {sqlframe-1.14.0 → sqlframe-2.1.0}/pytest.ini +0 -0
  123. {sqlframe-1.14.0 → sqlframe-2.1.0}/renovate.json +0 -0
  124. {sqlframe-1.14.0 → sqlframe-2.1.0}/setup.cfg +0 -0
  125. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/LICENSE +0 -0
  126. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/__init__.py +0 -0
  127. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/__init__.py +0 -0
  128. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/exceptions.py +0 -0
  129. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/group.py +0 -0
  130. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/mixins/__init__.py +0 -0
  131. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/mixins/readwriter_mixins.py +0 -0
  132. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/normalize.py +0 -0
  133. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/operations.py +0 -0
  134. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/transforms.py +0 -0
  135. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/types.py +0 -0
  136. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/base/window.py +0 -0
  137. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/bigquery/__init__.py +0 -0
  138. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/bigquery/column.py +0 -0
  139. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/bigquery/dataframe.py +0 -0
  140. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/bigquery/functions.pyi +0 -0
  141. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/bigquery/group.py +0 -0
  142. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/bigquery/readwriter.py +0 -0
  143. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/bigquery/types.py +0 -0
  144. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/bigquery/window.py +0 -0
  145. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/duckdb/__init__.py +0 -0
  146. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/duckdb/column.py +0 -0
  147. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/duckdb/functions.pyi +0 -0
  148. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/duckdb/group.py +0 -0
  149. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/duckdb/types.py +0 -0
  150. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/duckdb/window.py +0 -0
  151. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/postgres/__init__.py +0 -0
  152. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/postgres/column.py +0 -0
  153. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/postgres/dataframe.py +0 -0
  154. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/postgres/functions.pyi +0 -0
  155. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/postgres/group.py +0 -0
  156. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/postgres/readwriter.py +0 -0
  157. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/postgres/types.py +0 -0
  158. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/postgres/window.py +0 -0
  159. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/redshift/__init__.py +0 -0
  160. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/redshift/column.py +0 -0
  161. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/redshift/dataframe.py +0 -0
  162. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/redshift/functions.py +0 -0
  163. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/redshift/group.py +0 -0
  164. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/redshift/readwriter.py +0 -0
  165. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/redshift/types.py +0 -0
  166. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/redshift/window.py +0 -0
  167. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/snowflake/__init__.py +0 -0
  168. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/snowflake/column.py +0 -0
  169. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/snowflake/functions.pyi +0 -0
  170. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/snowflake/group.py +0 -0
  171. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/snowflake/readwriter.py +0 -0
  172. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/snowflake/types.py +0 -0
  173. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/snowflake/window.py +0 -0
  174. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/spark/__init__.py +0 -0
  175. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/spark/column.py +0 -0
  176. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/spark/dataframe.py +0 -0
  177. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/spark/functions.py +0 -0
  178. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/spark/functions.pyi +0 -0
  179. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/spark/group.py +0 -0
  180. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/spark/readwriter.py +0 -0
  181. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/spark/types.py +0 -0
  182. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/spark/window.py +0 -0
  183. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/standalone/__init__.py +0 -0
  184. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/standalone/catalog.py +0 -0
  185. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/standalone/column.py +0 -0
  186. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/standalone/dataframe.py +0 -0
  187. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/standalone/functions.py +0 -0
  188. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/standalone/group.py +0 -0
  189. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/standalone/readwriter.py +0 -0
  190. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/standalone/types.py +0 -0
  191. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/standalone/window.py +0 -0
  192. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/testing/__init__.py +0 -0
  193. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe/testing/utils.py +0 -0
  194. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe.egg-info/dependency_links.txt +0 -0
  195. {sqlframe-1.14.0 → sqlframe-2.1.0}/sqlframe.egg-info/top_level.txt +0 -0
  196. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/__init__.py +0 -0
  197. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/common_fixtures.py +0 -0
  198. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/conftest.py +0 -0
  199. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/fixtures/employee.csv +0 -0
  200. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/fixtures/employee.json +0 -0
  201. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/fixtures/employee.parquet +0 -0
  202. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/fixtures/employee_extra_line.csv +0 -0
  203. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/__init__.py +0 -0
  204. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/__init__.py +0 -0
  205. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/bigquery/__init__.py +0 -0
  206. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/duck/__init__.py +0 -0
  207. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/duck/test_duckdb_reader.py +0 -0
  208. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/postgres/__init__.py +0 -0
  209. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/redshift/__init__.py +0 -0
  210. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/snowflake/__init__.py +0 -0
  211. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/spark/__init__.py +0 -0
  212. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/spark/test_spark_dataframe.py +0 -0
  213. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/test_engine_column.py +0 -0
  214. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/test_engine_reader.py +0 -0
  215. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/test_engine_writer.py +0 -0
  216. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/engines/test_int_testing.py +0 -0
  217. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/fixtures.py +0 -0
  218. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/test_int_dataframe_stats.py +0 -0
  219. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/test_int_grouped_data.py +0 -0
  220. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/integration/test_int_session.py +0 -0
  221. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/types.py +0 -0
  222. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/unit/__init__.py +0 -0
  223. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/unit/standalone/__init__.py +0 -0
  224. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/unit/standalone/test_column.py +0 -0
  225. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/unit/standalone/test_session_case_sensitivity.py +0 -0
  226. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/unit/standalone/test_types.py +0 -0
  227. {sqlframe-1.14.0 → sqlframe-2.1.0}/tests/unit/standalone/test_window.py +0 -0
@@ -19,6 +19,9 @@ bigquery-test:
19
19
  duckdb-test:
20
20
  pytest -n auto -m "duckdb"
21
21
 
22
+ snowflake-test:
23
+ pytest -n auto -m "snowflake"
24
+
22
25
  style:
23
26
  pre-commit run --all-files
24
27
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sqlframe
3
- Version: 1.14.0
3
+ Version: 2.1.0
4
4
  Summary: Turning PySpark Into a Universal DataFrame API
5
5
  Home-page: https://github.com/eakmanrq/sqlframe
6
6
  Author: Ryan Eakman
@@ -78,6 +78,10 @@ SQLFrame generates consistently accurate yet complex SQL for engine execution.
78
78
  However, when using df.sql(), it produces more human-readable SQL.
79
79
  For details on how to configure this output and leverage OpenAI to enhance the SQL, see [Generated SQL Configuration](https://sqlframe.readthedocs.io/en/stable/configuration/#generated-sql).
80
80
 
81
+ SQLFrame by default uses the Spark dialect for input and output.
82
+ This can be changed to make SQLFrame feel more like a native DataFrame API for the engine you are using.
83
+ See [Input and Output Dialect Configuration](https://sqlframe.readthedocs.io/en/stable/configuration/#input-and-output-dialect).
84
+
81
85
  ## Example Usage
82
86
 
83
87
  ```python
@@ -112,7 +116,7 @@ df = (
112
116
  )
113
117
  ```
114
118
  ```python
115
- >>> df.sql()
119
+ >>> df.sql(optimize=True)
116
120
  WITH `t94228` AS (
117
121
  SELECT
118
122
  `natality`.`year` AS `year`,
@@ -48,6 +48,10 @@ SQLFrame generates consistently accurate yet complex SQL for engine execution.
48
48
  However, when using df.sql(), it produces more human-readable SQL.
49
49
  For details on how to configure this output and leverage OpenAI to enhance the SQL, see [Generated SQL Configuration](https://sqlframe.readthedocs.io/en/stable/configuration/#generated-sql).
50
50
 
51
+ SQLFrame by default uses the Spark dialect for input and output.
52
+ This can be changed to make SQLFrame feel more like a native DataFrame API for the engine you are using.
53
+ See [Input and Output Dialect Configuration](https://sqlframe.readthedocs.io/en/stable/configuration/#input-and-output-dialect).
54
+
51
55
  ## Example Usage
52
56
 
53
57
  ```python
@@ -82,7 +86,7 @@ df = (
82
86
  )
83
87
  ```
84
88
  ```python
85
- >>> df.sql()
89
+ >>> df.sql(optimize=True)
86
90
  WITH `t94228` AS (
87
91
  SELECT
88
92
  `natality`.`year` AS `year`,
@@ -1,5 +1,29 @@
1
1
  # General Configuration
2
2
 
3
+ ## Input and Output Dialect
4
+
5
+ By default, SQLFrame processes all string inputs using the Spark dialect (e.g., date format strings, SQL) and generates outputs in the Spark dialect (e.g., column names, data types).
6
+ This configuration is ideal if you aim to use the PySpark DataFrame API as if running on Spark while actually executing on another engine.
7
+
8
+ This configuration can be changed to make SQLFrame feel more like a native DataFrame API for the engine you are using.
9
+
10
+ Example: Using BigQuery to Change Default Behavior
11
+
12
+ ```python
13
+ from sqlframe.bigquery import BigQuerySession
14
+
15
+ session = BigQuerySession.builder.config(
16
+ map={
17
+ "sqlframe.input.dialect": "bigquery",
18
+ "sqlframe.output.dialect": "bigquery",
19
+ }
20
+ ).getOrCreate()
21
+ ```
22
+
23
+ In this configuration, you can use BigQuery syntax for elements such as date format strings and will receive BigQuery column names and data types in the output.
24
+
25
+ SQLFrame supports multiple dialects, all of which can be specific as the `input_dialect` and `output_dialect`.
26
+
3
27
  ## Generated SQL
4
28
 
5
29
  ### Pretty
@@ -28,7 +52,9 @@ SELECT CAST(`a3`.`a` AS BIGINT) AS `a`, CAST(`a3`.`b` AS BIGINT) AS `b` FROM VAL
28
52
 
29
53
  ### Optimized
30
54
 
31
- Optimized SQL is SQL that has been processed by SQLGlot's optimizer. For complex queries this will significantly reduce the number of CTEs produced and remove extra unused columns. Defaults to `True`.
55
+ Optimized SQL is SQL that has been processed by SQLGlot's optimizer.
56
+ For complex queries this will significantly reduce the number of CTEs produced and remove extra unused columns.
57
+ Defaults to `False`.
32
58
 
33
59
  ```python
34
60
  from sqlframe.bigquery import BigQuerySession
@@ -177,7 +203,9 @@ LIMIT 5
177
203
 
178
204
  ### Override Dialect
179
205
 
180
- The dialect of the generated SQL will be based on the session's dialect. However, you can override the dialect by passing a string to the `dialect` parameter. This is useful when you want to generate SQL for a different database.
206
+ The dialect of the generated SQL will be based on the session's output dialect.
207
+ However, you can override the dialect by passing a string to the `dialect` parameter.
208
+ This is useful when you want to generate SQL for a different database.
181
209
 
182
210
  ```python
183
211
  # create session and `df` like normal
@@ -258,6 +258,7 @@ See something that you would like to see supported? [Open an issue](https://gith
258
258
  * [concat](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.concat.html)
259
259
  * Only works on strings (does not work on arrays)
260
260
  * [concat_ws](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.concat_ws.html)
261
+ * [convert_timezone](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.convert_timezone.html)
261
262
  * [corr](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.corr.html)
262
263
  * [cos](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.cos.html)
263
264
  * [cot](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.cot.html)
@@ -293,6 +294,7 @@ See something that you would like to see supported? [Open an issue](https://gith
293
294
  * [element_at](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.element_at.html)
294
295
  * Only works on strings (does not work on arrays)
295
296
  * [encode](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.encode.html)
297
+ * [endswith](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.Column.endswith.html)
296
298
  * [exp](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.exp.html)
297
299
  * [explode](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.explode.html)
298
300
  * [expm1](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.expm1.html)
@@ -320,6 +322,7 @@ See something that you would like to see supported? [Open an issue](https://gith
320
322
  * [kurtosis](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.kurtosis.html)
321
323
  * [lag](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.lag.html)
322
324
  * [last](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.last.html)
325
+ * [last_day](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.last_day.html)
323
326
  * [lcase](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.lcase.html)
324
327
  * [lead](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.lead.html)
325
328
  * [least](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.least.html)
@@ -300,6 +300,7 @@ See something that you would like to see supported? [Open an issue](https://gith
300
300
  * [element_at](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.element_at.html)
301
301
  * Only works on strings (does not work on arrays)
302
302
  * [encode](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.encode.html)
303
+ * [endswith](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.Column.endswith.html)
303
304
  * [exp](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.exp.html)
304
305
  * [explode](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.explode.html)
305
306
  * Doesn't support exploding maps
@@ -320,6 +321,7 @@ See something that you would like to see supported? [Open an issue](https://gith
320
321
  * [isnan](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.isnan.html)
321
322
  * [isnull](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.isnull.html)
322
323
  * [lag](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.lag.html)
324
+ * [last_day](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.last_day.html)
323
325
  * [lcase](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.lcase.html)
324
326
  * [lead](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.lead.html)
325
327
  * [least](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.least.html)
@@ -1,4 +1,4 @@
1
- # BigQuery
1
+ # Snowflake
2
2
 
3
3
  ## Installation
4
4
 
@@ -286,6 +286,7 @@ See something that you would like to see supported? [Open an issue](https://gith
286
286
  * [concat](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.concat.html)
287
287
  * Can only concat strings not arrays
288
288
  * [concat_ws](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.concat_ws.html)
289
+ * [convert_timezone](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.convert_timezone.html)
289
290
  * [corr](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.corr.html)
290
291
  * [cos](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.cos.html)
291
292
  * [cosh](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.cosh.html)
@@ -319,6 +320,7 @@ See something that you would like to see supported? [Open an issue](https://gith
319
320
  * [desc_nulls_last](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.desc_nulls_last.html)
320
321
  * [e](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.e.html)
321
322
  * [element_at](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.element_at.html)
323
+ * [endswith](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.Column.endswith.html)
322
324
  * [exp](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.exp.html)
323
325
  * [explode](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.explode.html)
324
326
  * [expm1](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.expm1.html)
@@ -20,7 +20,7 @@ setup(
20
20
  python_requires=">=3.8",
21
21
  install_requires=[
22
22
  "prettytable<3.11.0",
23
- "sqlglot>=24.0.0,<25.5",
23
+ "sqlglot>=24.0.0,<25.11",
24
24
  "typing_extensions>=4.8,<5",
25
25
  ],
26
26
  extras_require={
@@ -30,18 +30,18 @@ setup(
30
30
  ],
31
31
  "dev": [
32
32
  "duckdb>=0.9,<1.1",
33
- "mypy>=1.10.0,<1.11",
34
- "openai>=1.30,<1.36",
33
+ "mypy>=1.10.0,<1.12",
34
+ "openai>=1.30,<1.41",
35
35
  "pandas>=2,<3",
36
36
  "pandas-stubs>=2,<3",
37
37
  "psycopg>=3.1,<4",
38
- "pyarrow>=10,<17",
38
+ "pyarrow>=10,<18",
39
39
  "pyspark>=2,<3.6",
40
- "pytest>=8.2.0,<8.3",
40
+ "pytest>=8.2.0,<8.4",
41
41
  "pytest-postgresql>=6,<7",
42
42
  "pytest-xdist>=3.6,<3.7",
43
43
  "pre-commit>=3.5;python_version=='3.8'",
44
- "pre-commit>=3.7,<3.8;python_version>='3.9'",
44
+ "pre-commit>=3.7,<3.9;python_version>='3.9'",
45
45
  "ruff>=0.4.4,<0.6",
46
46
  "types-psycopg2>=2.9,<3",
47
47
  ],
@@ -57,7 +57,7 @@ setup(
57
57
  "pandas>=2,<3",
58
58
  ],
59
59
  "openai": [
60
- "openai>=1.30,<1.36",
60
+ "openai>=1.30,<1.41",
61
61
  ],
62
62
  "pandas": [
63
63
  "pandas>=2,<3",
@@ -69,7 +69,7 @@ setup(
69
69
  "redshift_connector>=2.1.1,<2.2.0",
70
70
  ],
71
71
  "snowflake": [
72
- "snowflake-connector-python[secure-local-storage]>=3.10.0,<3.12",
72
+ "snowflake-connector-python[secure-local-storage]>=3.10.0,<3.13",
73
73
  ],
74
74
  "spark": [
75
75
  "pyspark>=2,<3.6",
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.14.0'
16
- __version_tuple__ = version_tuple = (1, 14, 0)
15
+ __version__ = version = '2.1.0'
16
+ __version_tuple__ = version_tuple = (2, 1, 0)
@@ -24,6 +24,7 @@ OutputExpressionContainer = t.Union[exp.Select, exp.Create, exp.Insert]
24
24
  StorageLevel = str
25
25
  PathOrPaths = t.Union[str, t.List[str]]
26
26
  OptionalPrimitiveType = t.Optional[PrimitiveType]
27
+ DataTypeOrString = t.Union[DataType, str]
27
28
 
28
29
 
29
30
  class UserDefinedFunctionLike(t.Protocol):
@@ -3,12 +3,12 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import typing as t
6
+ from collections import defaultdict
6
7
 
7
8
  from sqlglot import MappingSchema, exp
8
9
 
9
- from sqlframe.base.decorators import normalize
10
10
  from sqlframe.base.exceptions import TableSchemaError
11
- from sqlframe.base.util import ensure_column_mapping, to_schema
11
+ from sqlframe.base.util import ensure_column_mapping, normalize_string, to_schema
12
12
 
13
13
  if t.TYPE_CHECKING:
14
14
  from sqlglot.schema import ColumnMapping
@@ -33,6 +33,7 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
33
33
  """Create a new Catalog that wraps the underlying JVM object."""
34
34
  self.session = sparkSession
35
35
  self._schema = schema or MappingSchema()
36
+ self._quoted_columns: t.Dict[exp.Table, t.List[str]] = defaultdict(list)
36
37
 
37
38
  @property
38
39
  def spark(self) -> SESSION:
@@ -52,7 +53,7 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
52
53
  def get_columns_from_schema(self, table: exp.Table | str) -> t.Dict[str, exp.DataType]:
53
54
  table = self.ensure_table(table)
54
55
  return {
55
- exp.column(name, quoted=True).sql(
56
+ exp.column(name, quoted=name in self._quoted_columns[table]).sql(
56
57
  dialect=self.session.input_dialect
57
58
  ): exp.DataType.build(dtype, dialect=self.session.input_dialect)
58
59
  for name, dtype in self._schema.find(table, raise_on_missing=True).items() # type: ignore
@@ -64,9 +65,7 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
64
65
  if not columns:
65
66
  return {}
66
67
  return {
67
- exp.column(c.name, quoted=True).sql(
68
- dialect=self.session.input_dialect
69
- ): exp.DataType.build(c.dataType, dialect=self.session.input_dialect)
68
+ c.name: exp.DataType.build(c.dataType, dialect=self.session.output_dialect)
70
69
  for c in columns
71
70
  }
72
71
 
@@ -79,16 +78,30 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
79
78
  return
80
79
  if not column_mapping:
81
80
  try:
82
- column_mapping = self.get_columns(table)
81
+ column_mapping = {
82
+ normalize_string(
83
+ k, from_dialect="output", to_dialect="input", is_column=True
84
+ ): normalize_string(
85
+ v.sql(dialect=self.session.output_dialect),
86
+ from_dialect="output",
87
+ to_dialect="input",
88
+ is_datatype=True,
89
+ )
90
+ for k, v in self.get_columns(table).items()
91
+ }
83
92
  except NotImplementedError:
84
93
  # TODO: Add doc link
85
94
  raise TableSchemaError(
86
95
  "This session does not have access to a catalog that can lookup column information. See docs for explicitly defining columns or using a session that can automatically determine this."
87
96
  )
88
97
  column_mapping = ensure_column_mapping(column_mapping) # type: ignore
98
+ for column_name in column_mapping:
99
+ column = exp.to_column(column_name, dialect=self.session.input_dialect)
100
+ if column.this.quoted:
101
+ self._quoted_columns[table].append(column.this.name)
102
+
89
103
  self._schema.add_table(table, column_mapping, dialect=self.session.input_dialect)
90
104
 
91
- @normalize(["dbName"])
92
105
  def getDatabase(self, dbName: str) -> Database:
93
106
  """Get the database with the specified name.
94
107
  This throws an :class:`AnalysisException` when the database cannot be found.
@@ -115,6 +128,7 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
115
128
  >>> spark.catalog.getDatabase("spark_catalog.default")
116
129
  Database(name='default', catalog='spark_catalog', description='default database', ...
117
130
  """
131
+ dbName = normalize_string(dbName, from_dialect="input", is_schema=True)
118
132
  schema = to_schema(dbName, dialect=self.session.input_dialect)
119
133
  database_name = schema.db
120
134
  databases = self.listDatabases(pattern=database_name)
@@ -122,12 +136,16 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
122
136
  raise ValueError(f"Database '{dbName}' not found")
123
137
  if len(databases) > 1:
124
138
  if schema.catalog is not None:
125
- filtered_databases = [db for db in databases if db.catalog == schema.catalog]
139
+ filtered_databases = [
140
+ db
141
+ for db in databases
142
+ if normalize_string(db.catalog, from_dialect="output", to_dialect="input") # type: ignore
143
+ == schema.catalog
144
+ ]
126
145
  if filtered_databases:
127
146
  return filtered_databases[0]
128
147
  return databases[0]
129
148
 
130
- @normalize(["dbName"])
131
149
  def databaseExists(self, dbName: str) -> bool:
132
150
  """Check if the database with the specified name exists.
133
151
 
@@ -168,7 +186,6 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
168
186
  except ValueError:
169
187
  return False
170
188
 
171
- @normalize(["tableName"])
172
189
  def getTable(self, tableName: str) -> Table:
173
190
  """Get the table or view with the specified name. This table can be a temporary view or a
174
191
  table/view. This throws an :class:`AnalysisException` when no Table can be found.
@@ -210,13 +227,18 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
210
227
  ...
211
228
  AnalysisException: ...
212
229
  """
230
+ tableName = normalize_string(tableName, from_dialect="input", is_table=True)
213
231
  table = exp.to_table(tableName, dialect=self.session.input_dialect)
214
232
  schema = table.copy()
215
233
  schema.set("this", None)
216
234
  tables = self.listTables(
217
235
  schema.sql(dialect=self.session.input_dialect) if schema.db else None
218
236
  )
219
- matching_tables = [t for t in tables if t.name == table.name]
237
+ matching_tables = [
238
+ t
239
+ for t in tables
240
+ if normalize_string(t.name, from_dialect="output", to_dialect="input") == table.name
241
+ ]
220
242
  if not matching_tables:
221
243
  raise ValueError(f"Table '{tableName}' not found")
222
244
  return matching_tables[0]
@@ -315,7 +337,6 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
315
337
  raise ValueError(f"Function '{functionName}' not found")
316
338
  return matching_functions[0]
317
339
 
318
- @normalize(["tableName", "dbName"])
319
340
  def tableExists(self, tableName: str, dbName: t.Optional[str] = None) -> bool:
320
341
  """Check if the table or view with the specified name exists.
321
342
  This can either be a temporary view or a table/view.
@@ -389,6 +410,8 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
389
410
  >>> spark.catalog.tableExists("view1")
390
411
  False
391
412
  """
413
+ tableName = normalize_string(tableName, from_dialect="input", is_table=True)
414
+ dbName = normalize_string(dbName, from_dialect="input", is_schema=True) if dbName else None
392
415
  table = exp.to_table(tableName, dialect=self.session.input_dialect)
393
416
  schema_arg = to_schema(dbName, dialect=self.session.input_dialect) if dbName else None
394
417
  if not table.db:
@@ -7,11 +7,11 @@ import math
7
7
  import typing as t
8
8
 
9
9
  import sqlglot
10
+ from sqlglot import Dialect
10
11
  from sqlglot import expressions as exp
11
12
  from sqlglot.helper import flatten, is_iterable
12
13
  from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
13
14
 
14
- from sqlframe.base.decorators import normalize
15
15
  from sqlframe.base.exceptions import UnsupportedOperationError
16
16
  from sqlframe.base.types import DataType
17
17
  from sqlframe.base.util import get_func_from_session, quote_preserving_alias_or_name
@@ -211,9 +211,8 @@ class Column:
211
211
  def binary_op(
212
212
  self, klass: t.Callable, other: ColumnOrLiteral, paren: bool = False, **kwargs
213
213
  ) -> Column:
214
- op = klass(
215
- this=self.column_expression, expression=Column(other).column_expression, **kwargs
216
- )
214
+ other = self._lit(other) if isinstance(other, str) else Column(other)
215
+ op = klass(this=self.column_expression, expression=other.column_expression, **kwargs)
217
216
  if paren:
218
217
  return Column(exp.Paren(this=op))
219
218
  return Column(op)
@@ -221,9 +220,8 @@ class Column:
221
220
  def inverse_binary_op(
222
221
  self, klass: t.Callable, other: ColumnOrLiteral, paren: bool = False, **kwargs
223
222
  ) -> Column:
224
- op = klass(
225
- this=Column(other).column_expression, expression=self.column_expression, **kwargs
226
- )
223
+ other = self._lit(other) if isinstance(other, str) else Column(other)
224
+ op = klass(this=other.column_expression, expression=self.column_expression, **kwargs)
227
225
  if paren:
228
226
  return Column(exp.Paren(this=op))
229
227
  return Column(op)
@@ -340,13 +338,17 @@ class Column:
340
338
  new_expression = exp.Not(this=exp.Is(this=self.column_expression, expression=exp.Null()))
341
339
  return Column(new_expression)
342
340
 
343
- def cast(self, dataType: t.Union[str, DataType]) -> Column:
341
+ def cast(
342
+ self, dataType: t.Union[str, DataType], dialect: t.Optional[t.Union[str, Dialect]] = None
343
+ ) -> Column:
344
344
  from sqlframe.base.session import _BaseSession
345
345
 
346
346
  if isinstance(dataType, DataType):
347
347
  dataType = dataType.simpleString()
348
348
  return Column(
349
- exp.cast(self.column_expression, dataType, dialect=_BaseSession().input_dialect)
349
+ exp.cast(
350
+ self.column_expression, dataType, dialect=dialect or _BaseSession().input_dialect
351
+ )
350
352
  )
351
353
 
352
354
  def startswith(self, value: t.Union[str, Column]) -> Column: