snowflake-connector-python 3.16.0__cp313-cp313-win_amd64.whl

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 (246) hide show
  1. snowflake/connector/__init__.py +96 -0
  2. snowflake/connector/_query_context_cache.py +276 -0
  3. snowflake/connector/_sql_util.py +48 -0
  4. snowflake/connector/_utils.py +70 -0
  5. snowflake/connector/arrow_context.py +203 -0
  6. snowflake/connector/auth/__init__.py +53 -0
  7. snowflake/connector/auth/_auth.py +586 -0
  8. snowflake/connector/auth/_http_server.py +220 -0
  9. snowflake/connector/auth/_oauth_base.py +400 -0
  10. snowflake/connector/auth/by_plugin.py +219 -0
  11. snowflake/connector/auth/default.py +36 -0
  12. snowflake/connector/auth/idtoken.py +72 -0
  13. snowflake/connector/auth/keypair.py +222 -0
  14. snowflake/connector/auth/no_auth.py +39 -0
  15. snowflake/connector/auth/oauth.py +49 -0
  16. snowflake/connector/auth/oauth_code.py +479 -0
  17. snowflake/connector/auth/oauth_credentials.py +66 -0
  18. snowflake/connector/auth/okta.py +335 -0
  19. snowflake/connector/auth/pat.py +39 -0
  20. snowflake/connector/auth/usrpwdmfa.py +69 -0
  21. snowflake/connector/auth/webbrowser.py +502 -0
  22. snowflake/connector/auth/workload_identity.py +94 -0
  23. snowflake/connector/azure_storage_client.py +276 -0
  24. snowflake/connector/backoff_policies.py +141 -0
  25. snowflake/connector/bind_upload_agent.py +89 -0
  26. snowflake/connector/cache.py +696 -0
  27. snowflake/connector/compat.py +127 -0
  28. snowflake/connector/config_manager.py +496 -0
  29. snowflake/connector/connection.py +2273 -0
  30. snowflake/connector/connection_diagnostic.py +776 -0
  31. snowflake/connector/constants.py +442 -0
  32. snowflake/connector/converter.py +785 -0
  33. snowflake/connector/converter_issue23517.py +87 -0
  34. snowflake/connector/converter_null.py +14 -0
  35. snowflake/connector/converter_snowsql.py +205 -0
  36. snowflake/connector/cursor.py +1951 -0
  37. snowflake/connector/dbapi.py +53 -0
  38. snowflake/connector/description.py +19 -0
  39. snowflake/connector/direct_file_operation_utils.py +88 -0
  40. snowflake/connector/encryption_util.py +220 -0
  41. snowflake/connector/errorcode.py +91 -0
  42. snowflake/connector/errors.py +615 -0
  43. snowflake/connector/externals_utils/__init__.py +0 -0
  44. snowflake/connector/externals_utils/externals_setup.py +27 -0
  45. snowflake/connector/feature.py +4 -0
  46. snowflake/connector/file_compression_type.py +118 -0
  47. snowflake/connector/file_lock.py +72 -0
  48. snowflake/connector/file_transfer_agent.py +1215 -0
  49. snowflake/connector/file_util.py +153 -0
  50. snowflake/connector/gcs_storage_client.py +474 -0
  51. snowflake/connector/gzip_decoder.py +85 -0
  52. snowflake/connector/local_storage_client.py +90 -0
  53. snowflake/connector/log_configuration.py +60 -0
  54. snowflake/connector/logging_utils/__init__.py +0 -0
  55. snowflake/connector/logging_utils/filters.py +72 -0
  56. snowflake/connector/nanoarrow_arrow_iterator.cp313-win_amd64.pyd +0 -0
  57. snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +60 -0
  58. snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
  59. snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +19 -0
  60. snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
  61. snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
  62. snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
  63. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.cpp +557 -0
  64. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.hpp +98 -0
  65. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +125 -0
  66. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +115 -0
  67. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.cpp +1005 -0
  68. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.hpp +127 -0
  69. snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +47 -0
  70. snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
  71. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +83 -0
  72. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
  73. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +97 -0
  74. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +72 -0
  75. snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +73 -0
  76. snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
  77. snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +30 -0
  78. snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
  79. snowflake/connector/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
  80. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
  81. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +45 -0
  82. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +71 -0
  83. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +56 -0
  84. snowflake/connector/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
  85. snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +75 -0
  86. snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
  87. snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +46 -0
  88. snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
  89. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
  90. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +95 -0
  91. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +57 -0
  92. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +36 -0
  93. snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +34 -0
  94. snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
  95. snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +19 -0
  96. snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
  97. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +36 -0
  98. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
  99. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +346 -0
  100. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +145 -0
  101. snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
  102. snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.cpp +65 -0
  103. snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
  104. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +101 -0
  105. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +127 -0
  106. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
  107. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1908 -0
  108. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +215 -0
  109. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +125 -0
  110. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
  111. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +55 -0
  112. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +148 -0
  113. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
  114. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
  115. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
  116. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +162 -0
  117. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +97 -0
  118. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +239 -0
  119. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
  120. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +210 -0
  121. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +84 -0
  122. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +84 -0
  123. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
  124. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
  125. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +206 -0
  126. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +118 -0
  127. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
  128. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
  129. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
  130. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
  131. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
  132. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +162 -0
  133. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +898 -0
  134. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +190 -0
  135. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
  136. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
  137. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc.c +3204 -0
  138. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3217 -0
  139. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3618 -0
  140. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +379 -0
  141. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.pyx +256 -0
  142. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.c +512 -0
  143. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.h +350 -0
  144. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +33273 -0
  145. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +397 -0
  146. snowflake/connector/nanoarrow_cpp/Logging/logging.cpp +100 -0
  147. snowflake/connector/nanoarrow_cpp/Logging/logging.hpp +49 -0
  148. snowflake/connector/network.py +1297 -0
  149. snowflake/connector/ocsp_asn1crypto.py +447 -0
  150. snowflake/connector/ocsp_snowflake.py +1883 -0
  151. snowflake/connector/options.py +131 -0
  152. snowflake/connector/pandas_tools.py +732 -0
  153. snowflake/connector/proxy.py +43 -0
  154. snowflake/connector/py.typed +0 -0
  155. snowflake/connector/result_batch.py +786 -0
  156. snowflake/connector/result_set.py +319 -0
  157. snowflake/connector/s3_storage_client.py +605 -0
  158. snowflake/connector/secret_detector.py +181 -0
  159. snowflake/connector/sf_dirs.py +64 -0
  160. snowflake/connector/sfbinaryformat.py +35 -0
  161. snowflake/connector/sfdatetime.py +345 -0
  162. snowflake/connector/snow_logging.py +144 -0
  163. snowflake/connector/sqlstate.py +9 -0
  164. snowflake/connector/ssd_internal_keys.py +30 -0
  165. snowflake/connector/ssl_wrap_socket.py +134 -0
  166. snowflake/connector/storage_client.py +478 -0
  167. snowflake/connector/telemetry.py +249 -0
  168. snowflake/connector/telemetry_oob.py +543 -0
  169. snowflake/connector/test_util.py +30 -0
  170. snowflake/connector/time_util.py +159 -0
  171. snowflake/connector/token_cache.py +402 -0
  172. snowflake/connector/tool/__init__.py +0 -0
  173. snowflake/connector/tool/dump_certs.py +57 -0
  174. snowflake/connector/tool/dump_ocsp_response.py +139 -0
  175. snowflake/connector/tool/dump_ocsp_response_cache.py +194 -0
  176. snowflake/connector/tool/probe_connection.py +69 -0
  177. snowflake/connector/url_util.py +49 -0
  178. snowflake/connector/util_text.py +301 -0
  179. snowflake/connector/vendored/__init__.py +3 -0
  180. snowflake/connector/vendored/requests/LICENSE +175 -0
  181. snowflake/connector/vendored/requests/__init__.py +169 -0
  182. snowflake/connector/vendored/requests/__version__.py +14 -0
  183. snowflake/connector/vendored/requests/_internal_utils.py +50 -0
  184. snowflake/connector/vendored/requests/adapters.py +537 -0
  185. snowflake/connector/vendored/requests/api.py +157 -0
  186. snowflake/connector/vendored/requests/auth.py +315 -0
  187. snowflake/connector/vendored/requests/certs.py +17 -0
  188. snowflake/connector/vendored/requests/compat.py +79 -0
  189. snowflake/connector/vendored/requests/cookies.py +561 -0
  190. snowflake/connector/vendored/requests/exceptions.py +140 -0
  191. snowflake/connector/vendored/requests/help.py +134 -0
  192. snowflake/connector/vendored/requests/hooks.py +33 -0
  193. snowflake/connector/vendored/requests/models.py +1033 -0
  194. snowflake/connector/vendored/requests/sessions.py +833 -0
  195. snowflake/connector/vendored/requests/status_codes.py +128 -0
  196. snowflake/connector/vendored/requests/structures.py +99 -0
  197. snowflake/connector/vendored/requests/utils.py +1093 -0
  198. snowflake/connector/vendored/urllib3/LICENSE.txt +21 -0
  199. snowflake/connector/vendored/urllib3/__init__.py +85 -0
  200. snowflake/connector/vendored/urllib3/_collections.py +355 -0
  201. snowflake/connector/vendored/urllib3/_version.py +2 -0
  202. snowflake/connector/vendored/urllib3/connection.py +572 -0
  203. snowflake/connector/vendored/urllib3/connectionpool.py +1137 -0
  204. snowflake/connector/vendored/urllib3/contrib/__init__.py +0 -0
  205. snowflake/connector/vendored/urllib3/contrib/_appengine_environ.py +36 -0
  206. snowflake/connector/vendored/urllib3/contrib/_securetransport/__init__.py +0 -0
  207. snowflake/connector/vendored/urllib3/contrib/_securetransport/bindings.py +519 -0
  208. snowflake/connector/vendored/urllib3/contrib/_securetransport/low_level.py +397 -0
  209. snowflake/connector/vendored/urllib3/contrib/appengine.py +314 -0
  210. snowflake/connector/vendored/urllib3/contrib/ntlmpool.py +130 -0
  211. snowflake/connector/vendored/urllib3/contrib/pyopenssl.py +509 -0
  212. snowflake/connector/vendored/urllib3/contrib/securetransport.py +920 -0
  213. snowflake/connector/vendored/urllib3/contrib/socks.py +216 -0
  214. snowflake/connector/vendored/urllib3/exceptions.py +323 -0
  215. snowflake/connector/vendored/urllib3/fields.py +274 -0
  216. snowflake/connector/vendored/urllib3/filepost.py +98 -0
  217. snowflake/connector/vendored/urllib3/packages/__init__.py +0 -0
  218. snowflake/connector/vendored/urllib3/packages/backports/__init__.py +0 -0
  219. snowflake/connector/vendored/urllib3/packages/backports/makefile.py +51 -0
  220. snowflake/connector/vendored/urllib3/packages/backports/weakref_finalize.py +155 -0
  221. snowflake/connector/vendored/urllib3/packages/six.py +1076 -0
  222. snowflake/connector/vendored/urllib3/poolmanager.py +540 -0
  223. snowflake/connector/vendored/urllib3/request.py +191 -0
  224. snowflake/connector/vendored/urllib3/response.py +885 -0
  225. snowflake/connector/vendored/urllib3/util/__init__.py +49 -0
  226. snowflake/connector/vendored/urllib3/util/connection.py +156 -0
  227. snowflake/connector/vendored/urllib3/util/proxy.py +57 -0
  228. snowflake/connector/vendored/urllib3/util/queue.py +22 -0
  229. snowflake/connector/vendored/urllib3/util/request.py +146 -0
  230. snowflake/connector/vendored/urllib3/util/response.py +107 -0
  231. snowflake/connector/vendored/urllib3/util/retry.py +620 -0
  232. snowflake/connector/vendored/urllib3/util/ssl_.py +495 -0
  233. snowflake/connector/vendored/urllib3/util/ssl_match_hostname.py +159 -0
  234. snowflake/connector/vendored/urllib3/util/ssltransport.py +221 -0
  235. snowflake/connector/vendored/urllib3/util/timeout.py +271 -0
  236. snowflake/connector/vendored/urllib3/util/url.py +435 -0
  237. snowflake/connector/vendored/urllib3/util/wait.py +152 -0
  238. snowflake/connector/version.py +3 -0
  239. snowflake/connector/wif_util.py +407 -0
  240. snowflake_connector_python-3.16.0.dist-info/METADATA +1475 -0
  241. snowflake_connector_python-3.16.0.dist-info/RECORD +246 -0
  242. snowflake_connector_python-3.16.0.dist-info/WHEEL +5 -0
  243. snowflake_connector_python-3.16.0.dist-info/entry_points.txt +4 -0
  244. snowflake_connector_python-3.16.0.dist-info/licenses/LICENSE.txt +202 -0
  245. snowflake_connector_python-3.16.0.dist-info/licenses/NOTICE +8 -0
  246. snowflake_connector_python-3.16.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1005 @@
1
+ #include "CArrowTableIterator.hpp"
2
+
3
+ #include <cstring>
4
+ #include <iostream>
5
+ #include <string>
6
+ #include <vector>
7
+
8
+ #include "Python/Common.hpp"
9
+ #include "SnowflakeType.hpp"
10
+ #include "Util/time.hpp"
11
+
12
+ namespace sf {
13
+
14
+ void CArrowTableIterator::convertIfNeeded(ArrowSchema* columnSchema,
15
+ ArrowArrayView* columnArray) {
16
+ ArrowSchemaView columnSchemaView;
17
+ ArrowError error;
18
+ int returnCode;
19
+
20
+ returnCode = ArrowSchemaViewInit(&columnSchemaView, columnSchema, &error);
21
+ SF_CHECK_ARROW_RC(returnCode,
22
+ "[Snowflake Exception] error initializing "
23
+ "ArrowSchemaView : %s, error code: %d",
24
+ ArrowErrorMessage(&error), returnCode);
25
+
26
+ ArrowStringView snowflakeLogicalType;
27
+ const char* metadata = columnSchema->metadata;
28
+ returnCode = ArrowMetadataGetValue(metadata, ArrowCharView("logicalType"),
29
+ &snowflakeLogicalType);
30
+ SF_CHECK_ARROW_RC(returnCode,
31
+ "[Snowflake Exception] error getting 'logicalType' "
32
+ "from Arrow metadata, error code: %d",
33
+ returnCode);
34
+ SnowflakeType::Type st = SnowflakeType::snowflakeTypeFromString(
35
+ std::string(snowflakeLogicalType.data, snowflakeLogicalType.size_bytes));
36
+
37
+ // reconstruct columnArray in place
38
+ switch (st) {
39
+ case SnowflakeType::Type::FIXED: {
40
+ int scale = 0;
41
+ struct ArrowStringView scaleString = ArrowCharView(nullptr);
42
+ if (metadata != nullptr) {
43
+ returnCode = ArrowMetadataGetValue(metadata, ArrowCharView("scale"),
44
+ &scaleString);
45
+ SF_CHECK_ARROW_RC(returnCode,
46
+ "[Snowflake Exception] error getting 'scale' "
47
+ "from Arrow metadata, error code: %d",
48
+ returnCode);
49
+ scale =
50
+ std::stoi(std::string(scaleString.data, scaleString.size_bytes));
51
+ }
52
+ if (scale > 0 &&
53
+ columnSchemaView.type != ArrowType::NANOARROW_TYPE_DECIMAL128) {
54
+ logger->debug(__FILE__, __func__, __LINE__,
55
+ "Convert fixed number column to double column, "
56
+ "column scale %d, column type id: %d",
57
+ scale, columnSchemaView.type);
58
+ convertScaledFixedNumberColumn_nanoarrow(&columnSchemaView, columnArray,
59
+ scale);
60
+ }
61
+ break;
62
+ }
63
+
64
+ case SnowflakeType::Type::ANY:
65
+ case SnowflakeType::Type::BINARY:
66
+ case SnowflakeType::Type::BOOLEAN:
67
+ case SnowflakeType::Type::CHAR:
68
+ case SnowflakeType::Type::DATE:
69
+ case SnowflakeType::Type::REAL:
70
+ case SnowflakeType::Type::TEXT:
71
+ case SnowflakeType::Type::VARIANT:
72
+ case SnowflakeType::Type::VECTOR: {
73
+ // Do not need to convert
74
+ break;
75
+ }
76
+
77
+ case SnowflakeType::Type::ARRAY: {
78
+ switch (columnSchemaView.type) {
79
+ case NANOARROW_TYPE_STRING: {
80
+ // No need to convert json encoded array
81
+ break;
82
+ }
83
+ case NANOARROW_TYPE_LIST: {
84
+ if (columnSchemaView.schema->n_children != 1) {
85
+ std::string errorInfo = Logger::formatString(
86
+ "[Snowflake Exception] invalid arrow schema for array items "
87
+ "expected 1 "
88
+ "schema child, but got %d",
89
+ columnSchemaView.schema->n_children);
90
+ logger->error(__FILE__, __func__, __LINE__, errorInfo.c_str());
91
+ PyErr_SetString(PyExc_Exception, errorInfo.c_str());
92
+ break;
93
+ }
94
+
95
+ ArrowSchema* item_schema = columnSchemaView.schema->children[0];
96
+ ArrowArrayView* item_array = columnArray->children[0];
97
+ convertIfNeeded(item_schema, item_array);
98
+ break;
99
+ }
100
+ default: {
101
+ std::string errorInfo = Logger::formatString(
102
+ "[Snowflake Exception] unknown arrow internal data type(%s) "
103
+ "for ARRAY data in %s",
104
+ NANOARROW_TYPE_ENUM_STRING[columnSchemaView.type],
105
+ columnSchemaView.schema->name);
106
+ logger->error(__FILE__, __func__, __LINE__, errorInfo.c_str());
107
+ PyErr_SetString(PyExc_Exception, errorInfo.c_str());
108
+ break;
109
+ }
110
+ }
111
+ break;
112
+ }
113
+ case SnowflakeType::Type::MAP: {
114
+ if (columnSchemaView.schema->n_children != 1) {
115
+ std::string errorInfo = Logger::formatString(
116
+ "[Snowflake Exception] invalid arrow schema for map entries "
117
+ "expected 1 "
118
+ "schema child, but got %d",
119
+ columnSchemaView.schema->n_children);
120
+ logger->error(__FILE__, __func__, __LINE__, errorInfo.c_str());
121
+ PyErr_SetString(PyExc_Exception, errorInfo.c_str());
122
+ break;
123
+ }
124
+
125
+ ArrowSchema* entries = columnSchemaView.schema->children[0];
126
+ if (entries->n_children != 2) {
127
+ std::string errorInfo = Logger::formatString(
128
+ "[Snowflake Exception] invalid arrow schema for map key/value "
129
+ "pair "
130
+ "expected 2 entries, but got %d",
131
+ entries->n_children);
132
+ logger->error(__FILE__, __func__, __LINE__, errorInfo.c_str());
133
+ PyErr_SetString(PyExc_Exception, errorInfo.c_str());
134
+ break;
135
+ }
136
+
137
+ ArrowSchema* key_schema = entries->children[0];
138
+ ArrowArrayView* key_array = columnArray->children[0]->children[0];
139
+ convertIfNeeded(key_schema, key_array);
140
+
141
+ ArrowSchema* value_schema = entries->children[1];
142
+ ArrowArrayView* value_array = columnArray->children[0]->children[1];
143
+ convertIfNeeded(value_schema, value_array);
144
+ break;
145
+ }
146
+
147
+ case SnowflakeType::Type::OBJECT: {
148
+ switch (columnSchemaView.type) {
149
+ case NANOARROW_TYPE_STRING: {
150
+ // No need to convert json encoded data
151
+ break;
152
+ }
153
+ case NANOARROW_TYPE_STRUCT: {
154
+ // Object field names are strings that do not need conversion
155
+ // Child values values may need conversion.
156
+ for (int i = 0; i < columnSchemaView.schema->n_children; i++) {
157
+ ArrowSchema* property_schema = columnSchemaView.schema->children[i];
158
+ ArrowArrayView* child_array = columnArray->children[i];
159
+ convertIfNeeded(property_schema, child_array);
160
+ }
161
+ break;
162
+ }
163
+ default: {
164
+ std::string errorInfo = Logger::formatString(
165
+ "[Snowflake Exception] unknown arrow internal data type(%s) "
166
+ "for OBJECT data in %s",
167
+ NANOARROW_TYPE_ENUM_STRING[columnSchemaView.type],
168
+ columnSchemaView.schema->name);
169
+ logger->error(__FILE__, __func__, __LINE__, errorInfo.c_str());
170
+ PyErr_SetString(PyExc_Exception, errorInfo.c_str());
171
+ break;
172
+ }
173
+ }
174
+ break;
175
+ }
176
+
177
+ case SnowflakeType::Type::TIME: {
178
+ int scale = 9;
179
+ if (metadata != nullptr) {
180
+ struct ArrowStringView scaleString = ArrowCharView(nullptr);
181
+ returnCode = ArrowMetadataGetValue(metadata, ArrowCharView("scale"),
182
+ &scaleString);
183
+ SF_CHECK_ARROW_RC(returnCode,
184
+ "[Snowflake Exception] error getting 'scale' "
185
+ "from Arrow metadata, error code: %d",
186
+ returnCode);
187
+ scale =
188
+ std::stoi(std::string(scaleString.data, scaleString.size_bytes));
189
+ }
190
+
191
+ convertTimeColumn_nanoarrow(&columnSchemaView, columnArray, scale);
192
+ break;
193
+ }
194
+
195
+ case SnowflakeType::Type::TIMESTAMP_NTZ: {
196
+ int scale = 9;
197
+ if (metadata != nullptr) {
198
+ struct ArrowStringView scaleString = ArrowCharView(nullptr);
199
+ returnCode = ArrowMetadataGetValue(metadata, ArrowCharView("scale"),
200
+ &scaleString);
201
+ SF_CHECK_ARROW_RC(returnCode,
202
+ "[Snowflake Exception] error getting 'scale' "
203
+ "from Arrow metadata, error code: %d",
204
+ returnCode);
205
+ scale =
206
+ std::stoi(std::string(scaleString.data, scaleString.size_bytes));
207
+ }
208
+ convertTimestampColumn_nanoarrow(&columnSchemaView, columnArray, scale);
209
+ break;
210
+ }
211
+
212
+ case SnowflakeType::Type::TIMESTAMP_LTZ: {
213
+ int scale = 9;
214
+ if (metadata != nullptr) {
215
+ struct ArrowStringView scaleString = ArrowCharView(nullptr);
216
+ returnCode = ArrowMetadataGetValue(metadata, ArrowCharView("scale"),
217
+ &scaleString);
218
+ SF_CHECK_ARROW_RC(returnCode,
219
+ "[Snowflake Exception] error getting 'scale' "
220
+ "from Arrow metadata, error code: %d",
221
+ returnCode);
222
+ scale =
223
+ std::stoi(std::string(scaleString.data, scaleString.size_bytes));
224
+ }
225
+ convertTimestampColumn_nanoarrow(&columnSchemaView, columnArray, scale,
226
+ m_timezone);
227
+ break;
228
+ }
229
+
230
+ case SnowflakeType::Type::TIMESTAMP_TZ: {
231
+ struct ArrowStringView scaleString = ArrowCharView(nullptr);
232
+ struct ArrowStringView byteLengthString = ArrowCharView(nullptr);
233
+ int scale = 9;
234
+ int byteLength = 16;
235
+ if (metadata != nullptr) {
236
+ returnCode = ArrowMetadataGetValue(metadata, ArrowCharView("scale"),
237
+ &scaleString);
238
+ SF_CHECK_ARROW_RC(returnCode,
239
+ "[Snowflake Exception] error getting 'scale' "
240
+ "from Arrow metadata, error code: %d",
241
+ returnCode);
242
+ returnCode = ArrowMetadataGetValue(
243
+ metadata, ArrowCharView("byteLength"), &byteLengthString);
244
+ SF_CHECK_ARROW_RC(
245
+ returnCode,
246
+ "[Snowflake Exception] error getting 'byteLength' from Arrow "
247
+ "metadata, error code: %d",
248
+ returnCode);
249
+ scale =
250
+ std::stoi(std::string(scaleString.data, scaleString.size_bytes));
251
+ // Data inside a structured type may not have bytelength metadata.
252
+ // Use default in this case.
253
+ if (byteLengthString.data != nullptr) {
254
+ byteLength = std::stoi(
255
+ std::string(byteLengthString.data, byteLengthString.size_bytes));
256
+ }
257
+ }
258
+
259
+ convertTimestampTZColumn_nanoarrow(&columnSchemaView, columnArray, scale,
260
+ byteLength, m_timezone);
261
+ break;
262
+ }
263
+
264
+ default: {
265
+ std::string errorInfo = Logger::formatString(
266
+ "[Snowflake Exception] unknown snowflake data type : %s",
267
+ snowflakeLogicalType.data);
268
+ logger->error(__FILE__, __func__, __LINE__, errorInfo.c_str());
269
+ PyErr_SetString(PyExc_Exception, errorInfo.c_str());
270
+ return;
271
+ }
272
+ }
273
+ }
274
+
275
+ /**
276
+ * This function is to make sure the arrow table can be successfully converted
277
+ * to pandas dataframe using arrow's to_pandas method. Since some Snowflake
278
+ * arrow columns are not supported, this method can map those to supported ones.
279
+ * Specifically,
280
+ * All Snowflake fixed number with scale > 0 (expect decimal) will be
281
+ * converted to Arrow float64/double column All Snowflake time columns will be
282
+ * converted to Arrow Time column with unit = second, milli, or, micro. All
283
+ * Snowflake timestamp columns will be converted to Arrow timestamp columns
284
+ * Specifically,
285
+ * timestampntz will be converted to Arrow timestamp with UTC
286
+ * timestampltz will be converted to Arrow timestamp with session time zone
287
+ * timestamptz will be converted to Arrow timestamp with UTC
288
+ * Since Arrow timestamp use int64_t internally so it may be out of range for
289
+ * small and large timestamps
290
+ */
291
+ void CArrowTableIterator::reconstructRecordBatches_nanoarrow() {
292
+ int returnCode = 0;
293
+ // Type conversion, the code needs to be optimized
294
+ for (unsigned int batchIdx = 0; batchIdx < m_ipcArrowArrayViewVec.size();
295
+ batchIdx++) {
296
+ nanoarrow::UniqueSchema copiedSchema;
297
+ returnCode =
298
+ ArrowSchemaDeepCopy(m_ipcArrowSchema.get(), copiedSchema.get());
299
+ SF_CHECK_ARROW_RC(
300
+ returnCode,
301
+ "[Snowflake Exception] error copying arrow schema, error code: %d",
302
+ returnCode);
303
+ m_ipcSchemaArrayVec.push_back(std::move(copiedSchema));
304
+
305
+ for (int colIdx = 0; colIdx < m_ipcSchemaArrayVec[batchIdx]->n_children;
306
+ colIdx++) {
307
+ ArrowArrayView* columnArray =
308
+ m_ipcArrowArrayViewVec[batchIdx]->children[colIdx];
309
+ ArrowSchema* columnSchema =
310
+ m_ipcSchemaArrayVec[batchIdx]->children[colIdx];
311
+ convertIfNeeded(columnSchema, columnArray);
312
+ }
313
+ m_tableConverted = true;
314
+ }
315
+ }
316
+
317
+ CArrowTableIterator::CArrowTableIterator(PyObject* context, char* arrow_bytes,
318
+ int64_t arrow_bytes_size,
319
+ const bool number_to_decimal)
320
+ : CArrowIterator(arrow_bytes, arrow_bytes_size),
321
+ m_context(context),
322
+ m_convert_number_to_decimal(number_to_decimal) {
323
+ if (py::checkPyError()) {
324
+ return;
325
+ }
326
+ py::UniqueRef tz(PyObject_GetAttrString(m_context, "_timezone"));
327
+ PyArg_Parse(tz.get(), "s", &m_timezone);
328
+ }
329
+
330
+ ReturnVal CArrowTableIterator::next() {
331
+ bool firstDone = this->convertRecordBatchesToTable_nanoarrow();
332
+ if (firstDone && !m_ipcArrowArrayVec.empty()) {
333
+ return ReturnVal(Py_True, nullptr);
334
+ } else {
335
+ return ReturnVal(Py_None, nullptr);
336
+ }
337
+ }
338
+
339
+ template <typename T>
340
+ double CArrowTableIterator::convertScaledFixedNumberToDouble(
341
+ const unsigned int scale, T originalValue) {
342
+ if (scale < 9) {
343
+ // simply use divide to convert decimal value in double
344
+ return (double)originalValue / sf::internal::powTenSB4[scale];
345
+ } else {
346
+ // when scale is large, convert the value to string first and then convert
347
+ // it to double otherwise, it may loss precision
348
+ std::string valStr = std::to_string(originalValue);
349
+ int negative = valStr.at(0) == '-' ? 1 : 0;
350
+ unsigned int digits = valStr.length() - negative;
351
+ if (digits <= scale) {
352
+ int numOfZeroes = scale - digits + 1;
353
+ valStr.insert(negative, std::string(numOfZeroes, '0'));
354
+ }
355
+ valStr.insert(valStr.length() - scale, ".");
356
+ std::size_t offset = 0;
357
+ return std::stod(valStr, &offset);
358
+ }
359
+ }
360
+
361
+ void CArrowTableIterator::convertScaledFixedNumberColumn_nanoarrow(
362
+ ArrowSchemaView* field, ArrowArrayView* columnArray,
363
+ const unsigned int scale) {
364
+ // Convert scaled fixed number to either Double, or Decimal based on setting
365
+ if (m_convert_number_to_decimal) {
366
+ convertScaledFixedNumberColumnToDecimalColumn_nanoarrow(field, columnArray,
367
+ scale);
368
+ } else {
369
+ convertScaledFixedNumberColumnToDoubleColumn_nanoarrow(field, columnArray,
370
+ scale);
371
+ }
372
+ }
373
+
374
+ void CArrowTableIterator::
375
+ convertScaledFixedNumberColumnToDecimalColumn_nanoarrow(
376
+ ArrowSchemaView* field, ArrowArrayView* columnArray,
377
+ const unsigned int scale) {
378
+ int returnCode = 0;
379
+ // Convert to arrow double/float64 column
380
+ nanoarrow::UniqueSchema newUniqueField;
381
+ nanoarrow::UniqueArray newUniqueArray;
382
+ ArrowSchema* newSchema = newUniqueField.get();
383
+ ArrowArray* newArray = newUniqueArray.get();
384
+
385
+ // create new schema
386
+ ArrowSchemaInit(newSchema);
387
+ newSchema->flags &=
388
+ (field->schema->flags & ARROW_FLAG_NULLABLE); // map to nullable()
389
+ returnCode = ArrowSchemaSetTypeDecimal(newSchema, NANOARROW_TYPE_DECIMAL128,
390
+ 38, scale);
391
+ SF_CHECK_ARROW_RC(returnCode,
392
+ "[Snowflake Exception] error setting arrow schema type "
393
+ "decimal, error code: %d",
394
+ returnCode);
395
+ returnCode = ArrowSchemaSetName(newSchema, field->schema->name);
396
+ SF_CHECK_ARROW_RC(
397
+ returnCode,
398
+ "[Snowflake Exception] error setting schema name, error code: %d",
399
+ returnCode);
400
+
401
+ ArrowError error;
402
+ returnCode = ArrowArrayInitFromSchema(newArray, newSchema, &error);
403
+ SF_CHECK_ARROW_RC(returnCode,
404
+ "[Snowflake Exception] error initializing ArrowArrayView "
405
+ "from schema : %s, error code: %d",
406
+ ArrowErrorMessage(&error), returnCode);
407
+
408
+ returnCode = ArrowArrayStartAppending(newArray);
409
+ SF_CHECK_ARROW_RC(
410
+ returnCode,
411
+ "[Snowflake Exception] error appending arrow array, error code: %d",
412
+ returnCode);
413
+
414
+ for (int64_t rowIdx = 0; rowIdx < columnArray->array->length; rowIdx++) {
415
+ if (ArrowArrayViewIsNull(columnArray, rowIdx)) {
416
+ returnCode = ArrowArrayAppendNull(newArray, 1);
417
+ SF_CHECK_ARROW_RC(returnCode,
418
+ "[Snowflake Exception] error appending null to arrow "
419
+ "array, error code: %d",
420
+ returnCode);
421
+ } else {
422
+ auto originalVal = ArrowArrayViewGetIntUnsafe(columnArray, rowIdx);
423
+ ArrowDecimal arrowDecimal;
424
+ ArrowDecimalInit(&arrowDecimal, 128, 38, scale);
425
+ ArrowDecimalSetInt(&arrowDecimal, originalVal);
426
+ returnCode = ArrowArrayAppendDecimal(newArray, &arrowDecimal);
427
+ SF_CHECK_ARROW_RC(returnCode,
428
+ "[Snowflake Exception] error appending decimal to "
429
+ "arrow array, error code: %d",
430
+ returnCode);
431
+ }
432
+ }
433
+ returnCode = ArrowArrayFinishBuildingDefault(newArray, &error);
434
+ SF_CHECK_ARROW_RC(returnCode,
435
+ "[Snowflake Exception] error finishing building arrow "
436
+ "array: %s, error code: %d",
437
+ ArrowErrorMessage(&error), returnCode);
438
+ field->schema->release(field->schema);
439
+ ArrowSchemaMove(newSchema, field->schema);
440
+ columnArray->array->release(columnArray->array);
441
+ ArrowArrayMove(newArray, columnArray->array);
442
+ }
443
+
444
+ void CArrowTableIterator::
445
+ convertScaledFixedNumberColumnToDoubleColumn_nanoarrow(
446
+ ArrowSchemaView* field, ArrowArrayView* columnArray,
447
+ const unsigned int scale) {
448
+ int returnCode = 0;
449
+ // Convert to arrow double/float64 column
450
+ nanoarrow::UniqueSchema newUniqueField;
451
+ nanoarrow::UniqueArray newUniqueArray;
452
+ ArrowSchema* newSchema = newUniqueField.get();
453
+ ArrowArray* newArray = newUniqueArray.get();
454
+
455
+ // create new schema
456
+ ArrowSchemaInit(newSchema);
457
+ newSchema->flags &=
458
+ (field->schema->flags & ARROW_FLAG_NULLABLE); // map to nullable()
459
+ returnCode = ArrowSchemaSetType(
460
+ newSchema, NANOARROW_TYPE_DOUBLE); // map to arrow:float64()
461
+ SF_CHECK_ARROW_RC(returnCode,
462
+ "[Snowflake Exception] error setting arrow schema type "
463
+ "double, error code: %d",
464
+ returnCode);
465
+ returnCode = ArrowSchemaSetName(newSchema, field->schema->name);
466
+ SF_CHECK_ARROW_RC(
467
+ returnCode,
468
+ "[Snowflake Exception] error setting schema name, error code: %d",
469
+ returnCode);
470
+
471
+ ArrowError error;
472
+ returnCode = ArrowArrayInitFromSchema(newArray, newSchema, &error);
473
+ SF_CHECK_ARROW_RC(returnCode,
474
+ "[Snowflake Exception] error initializing ArrowArrayView "
475
+ "from schema : %s, error code: %d",
476
+ ArrowErrorMessage(&error), returnCode);
477
+
478
+ for (int64_t rowIdx = 0; rowIdx < columnArray->array->length; rowIdx++) {
479
+ if (ArrowArrayViewIsNull(columnArray, rowIdx)) {
480
+ returnCode = ArrowArrayAppendNull(newArray, 1);
481
+ SF_CHECK_ARROW_RC(returnCode,
482
+ "[Snowflake Exception] error appending null to arrow "
483
+ "array, error code: %d",
484
+ returnCode);
485
+ } else {
486
+ auto originalVal = ArrowArrayViewGetIntUnsafe(columnArray, rowIdx);
487
+ double val = convertScaledFixedNumberToDouble(scale, originalVal);
488
+ returnCode = ArrowArrayAppendDouble(newArray, val);
489
+ SF_CHECK_ARROW_RC(returnCode,
490
+ "[Snowflake Exception] error appending double to arrow "
491
+ "array, error code: %d",
492
+ returnCode);
493
+ }
494
+ }
495
+ returnCode = ArrowArrayFinishBuildingDefault(newArray, &error);
496
+ SF_CHECK_ARROW_RC(returnCode,
497
+ "[Snowflake Exception] error finishing building arrow "
498
+ "array: %s, error code: %d",
499
+ ArrowErrorMessage(&error), returnCode);
500
+ field->schema->release(field->schema);
501
+ ArrowSchemaMove(newSchema, field->schema);
502
+ columnArray->array->release(columnArray->array);
503
+ ArrowArrayMove(newArray, columnArray->array);
504
+ }
505
+
506
+ void CArrowTableIterator::convertTimeColumn_nanoarrow(
507
+ ArrowSchemaView* field, ArrowArrayView* columnArray, const int scale) {
508
+ int returnCode = 0;
509
+ nanoarrow::UniqueSchema newUniqueField;
510
+ nanoarrow::UniqueArray newUniqueArray;
511
+ ArrowSchema* newSchema = newUniqueField.get();
512
+ ArrowArray* newArray = newUniqueArray.get();
513
+ ArrowError error;
514
+
515
+ // create new schema
516
+ ArrowSchemaInit(newSchema);
517
+ int64_t powTenSB4Val = 1;
518
+ newSchema->flags &=
519
+ (field->schema->flags & ARROW_FLAG_NULLABLE); // map to nullable()
520
+ if (scale == 0) {
521
+ returnCode = ArrowSchemaSetTypeDateTime(newSchema, NANOARROW_TYPE_TIME32,
522
+ NANOARROW_TIME_UNIT_SECOND, NULL);
523
+ SF_CHECK_ARROW_RC(returnCode,
524
+ "[Snowflake Exception] error setting arrow schema type "
525
+ "DateTime, error code: %d",
526
+ returnCode);
527
+ } else if (scale <= 3) {
528
+ returnCode = ArrowSchemaSetTypeDateTime(newSchema, NANOARROW_TYPE_TIME32,
529
+ NANOARROW_TIME_UNIT_MILLI, NULL);
530
+ SF_CHECK_ARROW_RC(returnCode,
531
+ "[Snowflake Exception] error setting arrow schema type "
532
+ "DateTime, error code: %d",
533
+ returnCode);
534
+ powTenSB4Val = sf::internal::powTenSB4[3 - scale];
535
+ } else if (scale <= 6) {
536
+ returnCode = ArrowSchemaSetTypeDateTime(newSchema, NANOARROW_TYPE_TIME64,
537
+ NANOARROW_TIME_UNIT_MICRO, NULL);
538
+ SF_CHECK_ARROW_RC(returnCode,
539
+ "[Snowflake Exception] error setting arrow schema type "
540
+ "DateTime, error code: %d",
541
+ returnCode);
542
+ powTenSB4Val = sf::internal::powTenSB4[6 - scale];
543
+ } else {
544
+ returnCode = ArrowSchemaSetTypeDateTime(newSchema, NANOARROW_TYPE_TIME64,
545
+ NANOARROW_TIME_UNIT_MICRO, NULL);
546
+ SF_CHECK_ARROW_RC(returnCode,
547
+ "[Snowflake Exception] error setting arrow schema type "
548
+ "DateTime, error code: %d",
549
+ returnCode);
550
+ powTenSB4Val = sf::internal::powTenSB4[scale - 6];
551
+ }
552
+ returnCode = ArrowSchemaSetName(newSchema, field->schema->name);
553
+ SF_CHECK_ARROW_RC(
554
+ returnCode,
555
+ "[Snowflake Exception] error setting schema name, error code: %d",
556
+ returnCode);
557
+
558
+ returnCode = ArrowArrayInitFromSchema(newArray, newSchema, &error);
559
+ SF_CHECK_ARROW_RC(returnCode,
560
+ "[Snowflake Exception] error initializing ArrowArrayView "
561
+ "from schema : %s, error code: %d",
562
+ ArrowErrorMessage(&error), returnCode);
563
+
564
+ returnCode = ArrowArrayStartAppending(newArray);
565
+ SF_CHECK_ARROW_RC(
566
+ returnCode,
567
+ "[Snowflake Exception] error appending arrow array, error code: %d",
568
+ returnCode);
569
+
570
+ for (int64_t rowIdx = 0; rowIdx < columnArray->array->length; rowIdx++) {
571
+ if (ArrowArrayViewIsNull(columnArray, rowIdx)) {
572
+ returnCode = ArrowArrayAppendNull(newArray, 1);
573
+ SF_CHECK_ARROW_RC(returnCode,
574
+ "[Snowflake Exception] error appending null to arrow "
575
+ "array, error code: %d",
576
+ returnCode);
577
+ } else {
578
+ auto originalVal = ArrowArrayViewGetIntUnsafe(columnArray, rowIdx);
579
+ if (scale <= 6) {
580
+ originalVal *= powTenSB4Val;
581
+ } else {
582
+ originalVal /= powTenSB4Val;
583
+ }
584
+ returnCode = ArrowArrayAppendInt(newArray, originalVal);
585
+ SF_CHECK_ARROW_RC(returnCode,
586
+ "[Snowflake Exception] error appending int to arrow "
587
+ "array, error code: %d",
588
+ returnCode);
589
+ }
590
+ }
591
+
592
+ returnCode = ArrowArrayFinishBuildingDefault(newArray, &error);
593
+ SF_CHECK_ARROW_RC(returnCode,
594
+ "[Snowflake Exception] error finishing building arrow "
595
+ "array: %s, error code: %d",
596
+ ArrowErrorMessage(&error), returnCode);
597
+ field->schema->release(field->schema);
598
+ ArrowSchemaMove(newSchema, field->schema);
599
+ columnArray->array->release(columnArray->array);
600
+ ArrowArrayMove(newArray, columnArray->array);
601
+ }
602
+
603
+ void CArrowTableIterator::convertTimestampColumn_nanoarrow(
604
+ ArrowSchemaView* field, ArrowArrayView* columnArray, const int scale,
605
+ const std::string timezone) {
606
+ int returnCode = 0;
607
+ nanoarrow::UniqueSchema newUniqueField;
608
+ nanoarrow::UniqueArray newUniqueArray;
609
+ ArrowSchema* newSchema = newUniqueField.get();
610
+ ArrowArray* newArray = newUniqueArray.get();
611
+ ArrowError error;
612
+
613
+ ArrowSchemaInit(newSchema);
614
+ newSchema->flags &=
615
+ (field->schema->flags & ARROW_FLAG_NULLABLE); // map to nullable()
616
+
617
+ // calculate has_overflow_to_downscale
618
+ bool has_overflow_to_downscale = false;
619
+ if (scale > 6 && field->type == NANOARROW_TYPE_STRUCT) {
620
+ ArrowArrayView* epochArray;
621
+ ArrowArrayView* fractionArray;
622
+ for (int64_t i = 0; i < field->schema->n_children; i++) {
623
+ ArrowSchema* c_schema = field->schema->children[i];
624
+ if (std::strcmp(c_schema->name, internal::FIELD_NAME_EPOCH.c_str()) ==
625
+ 0) {
626
+ epochArray = columnArray->children[i];
627
+ } else if (std::strcmp(c_schema->name,
628
+ internal::FIELD_NAME_FRACTION.c_str()) == 0) {
629
+ fractionArray = columnArray->children[i];
630
+ } else {
631
+ // do nothing
632
+ }
633
+ }
634
+
635
+ int powTenSB4 = sf::internal::powTenSB4[9];
636
+ for (int64_t rowIdx = 0; rowIdx < columnArray->array->length; rowIdx++) {
637
+ if (!ArrowArrayViewIsNull(columnArray, rowIdx)) {
638
+ int64_t epoch = ArrowArrayViewGetIntUnsafe(epochArray, rowIdx);
639
+ int64_t fraction = ArrowArrayViewGetIntUnsafe(fractionArray, rowIdx);
640
+ if (epoch > (INT64_MAX / powTenSB4) ||
641
+ epoch < (INT64_MIN / powTenSB4)) {
642
+ if (fraction % 1000 != 0) {
643
+ std::string errorInfo = Logger::formatString(
644
+ "The total number of nanoseconds %d%d overflows int64 range. "
645
+ "If you use a timestamp with "
646
+ "the nanosecond part over 6-digits in the Snowflake database, "
647
+ "the timestamp must be "
648
+ "between '1677-09-21 00:12:43.145224192' and '2262-04-11 "
649
+ "23:47:16.854775807' to not overflow.",
650
+ epoch, fraction);
651
+ throw std::overflow_error(errorInfo.c_str());
652
+ } else {
653
+ has_overflow_to_downscale = true;
654
+ }
655
+ }
656
+ }
657
+ }
658
+ }
659
+
660
+ if (scale <= 6) {
661
+ int64_t powTenSB4Val = 1;
662
+ auto timeunit = NANOARROW_TIME_UNIT_SECOND;
663
+ if (scale == 0) {
664
+ timeunit = NANOARROW_TIME_UNIT_SECOND;
665
+ powTenSB4Val = 1;
666
+ } else if (scale <= 3) {
667
+ timeunit = NANOARROW_TIME_UNIT_MILLI;
668
+ powTenSB4Val = sf::internal::powTenSB4[3 - scale];
669
+ } else if (scale <= 6) {
670
+ timeunit = NANOARROW_TIME_UNIT_MICRO;
671
+ powTenSB4Val = sf::internal::powTenSB4[6 - scale];
672
+ }
673
+ if (!timezone.empty()) {
674
+ returnCode = ArrowSchemaSetTypeDateTime(
675
+ newSchema, NANOARROW_TYPE_TIMESTAMP, timeunit, timezone.c_str());
676
+ SF_CHECK_ARROW_RC(returnCode,
677
+ "[Snowflake Exception] error setting arrow schema type "
678
+ "DateTime, error code: %d",
679
+ returnCode);
680
+ } else {
681
+ returnCode = ArrowSchemaSetTypeDateTime(
682
+ newSchema, NANOARROW_TYPE_TIMESTAMP, timeunit, NULL);
683
+ SF_CHECK_ARROW_RC(returnCode,
684
+ "[Snowflake Exception] error setting arrow schema type "
685
+ "DateTime, error code: %d",
686
+ returnCode);
687
+ }
688
+ returnCode = ArrowSchemaSetName(newSchema, field->schema->name);
689
+ SF_CHECK_ARROW_RC(
690
+ returnCode,
691
+ "[Snowflake Exception] error setting schema name, error code: %d",
692
+ returnCode);
693
+ returnCode = ArrowArrayInitFromSchema(newArray, newSchema, &error);
694
+ SF_CHECK_ARROW_RC(returnCode,
695
+ "[Snowflake Exception] error initializing ArrowArrayView "
696
+ "from schema : %s, error code: %d",
697
+ ArrowErrorMessage(&error), returnCode);
698
+
699
+ for (int64_t rowIdx = 0; rowIdx < columnArray->array->length; rowIdx++) {
700
+ if (ArrowArrayViewIsNull(columnArray, rowIdx)) {
701
+ returnCode = ArrowArrayAppendNull(newArray, 1);
702
+ SF_CHECK_ARROW_RC(returnCode,
703
+ "[Snowflake Exception] error appending null to arrow "
704
+ "array, error code: %d",
705
+ returnCode);
706
+ } else {
707
+ int64_t val = ArrowArrayViewGetIntUnsafe(columnArray, rowIdx);
708
+ val *= powTenSB4Val;
709
+ returnCode = ArrowArrayAppendInt(newArray, val);
710
+ SF_CHECK_ARROW_RC(returnCode,
711
+ "[Snowflake Exception] error appending int to arrow "
712
+ "array, error code: %d",
713
+ returnCode);
714
+ }
715
+ }
716
+ } else {
717
+ int64_t val;
718
+ if (field->type == NANOARROW_TYPE_STRUCT) {
719
+ ArrowArrayView* epochArray;
720
+ ArrowArrayView* fractionArray;
721
+ for (int64_t i = 0; i < field->schema->n_children; i++) {
722
+ ArrowSchema* c_schema = field->schema->children[i];
723
+ if (std::strcmp(c_schema->name, internal::FIELD_NAME_EPOCH.c_str()) ==
724
+ 0) {
725
+ epochArray = columnArray->children[i];
726
+ } else if (std::strcmp(c_schema->name,
727
+ internal::FIELD_NAME_FRACTION.c_str()) == 0) {
728
+ fractionArray = columnArray->children[i];
729
+ } else {
730
+ // do nothing
731
+ }
732
+ }
733
+
734
+ auto timeunit = has_overflow_to_downscale ? NANOARROW_TIME_UNIT_MICRO
735
+ : NANOARROW_TIME_UNIT_NANO;
736
+ if (!timezone.empty()) {
737
+ returnCode = ArrowSchemaSetTypeDateTime(
738
+ newSchema, NANOARROW_TYPE_TIMESTAMP, timeunit, timezone.c_str());
739
+ SF_CHECK_ARROW_RC(returnCode,
740
+ "[Snowflake Exception] error setting arrow schema "
741
+ "type DateTime, error code: %d",
742
+ returnCode);
743
+ } else {
744
+ returnCode = ArrowSchemaSetTypeDateTime(
745
+ newSchema, NANOARROW_TYPE_TIMESTAMP, timeunit, NULL);
746
+ SF_CHECK_ARROW_RC(returnCode,
747
+ "[Snowflake Exception] error setting arrow schema "
748
+ "type DateTime, error code: %d",
749
+ returnCode);
750
+ }
751
+ returnCode = ArrowSchemaSetName(newSchema, field->schema->name);
752
+ SF_CHECK_ARROW_RC(
753
+ returnCode,
754
+ "[Snowflake Exception] error setting schema name, error code: %d",
755
+ returnCode);
756
+
757
+ returnCode = ArrowArrayInitFromSchema(newArray, newSchema, &error);
758
+ SF_CHECK_ARROW_RC(returnCode,
759
+ "[Snowflake Exception] error initializing "
760
+ "ArrowArrayView from schema : %s, error code: %d",
761
+ ArrowErrorMessage(&error), returnCode);
762
+
763
+ for (int64_t rowIdx = 0; rowIdx < columnArray->array->length; rowIdx++) {
764
+ if (!ArrowArrayViewIsNull(columnArray, rowIdx)) {
765
+ int64_t epoch = ArrowArrayViewGetIntUnsafe(epochArray, rowIdx);
766
+ int64_t fraction = ArrowArrayViewGetIntUnsafe(fractionArray, rowIdx);
767
+ if (has_overflow_to_downscale) {
768
+ val = epoch * sf::internal::powTenSB4[6] + fraction / 1000;
769
+ } else {
770
+ val = epoch * sf::internal::powTenSB4[9] + fraction;
771
+ }
772
+ returnCode = ArrowArrayAppendInt(newArray, val);
773
+ SF_CHECK_ARROW_RC(returnCode,
774
+ "[Snowflake Exception] error appending int to "
775
+ "arrow array, error code: %d",
776
+ returnCode);
777
+ } else {
778
+ returnCode = ArrowArrayAppendNull(newArray, 1);
779
+ SF_CHECK_ARROW_RC(returnCode,
780
+ "[Snowflake Exception] error appending null to "
781
+ "arrow array, error code: %d",
782
+ returnCode);
783
+ }
784
+ }
785
+ } else if (field->type == NANOARROW_TYPE_INT64) {
786
+ auto timeunit = has_overflow_to_downscale ? NANOARROW_TIME_UNIT_MICRO
787
+ : NANOARROW_TIME_UNIT_NANO;
788
+ if (!timezone.empty()) {
789
+ returnCode = ArrowSchemaSetTypeDateTime(
790
+ newSchema, NANOARROW_TYPE_TIMESTAMP, timeunit, timezone.c_str());
791
+ SF_CHECK_ARROW_RC(returnCode,
792
+ "[Snowflake Exception] error setting arrow schema "
793
+ "type DateTime, error code: %d",
794
+ returnCode);
795
+ } else {
796
+ returnCode = ArrowSchemaSetTypeDateTime(
797
+ newSchema, NANOARROW_TYPE_TIMESTAMP, timeunit, NULL);
798
+ SF_CHECK_ARROW_RC(returnCode,
799
+ "[Snowflake Exception] error setting arrow schema "
800
+ "type DateTime, error code: %d",
801
+ returnCode);
802
+ }
803
+ returnCode = ArrowSchemaSetName(newSchema, field->schema->name);
804
+ SF_CHECK_ARROW_RC(
805
+ returnCode,
806
+ "[Snowflake Exception] error setting schema name, error code: %d",
807
+ returnCode);
808
+
809
+ returnCode = ArrowArrayInitFromSchema(newArray, newSchema, &error);
810
+ SF_CHECK_ARROW_RC(returnCode,
811
+ "[Snowflake Exception] error initializing "
812
+ "ArrowArrayView from schema : %s, error code: %d",
813
+ ArrowErrorMessage(&error), returnCode);
814
+
815
+ for (int64_t rowIdx = 0; rowIdx < columnArray->array->length; rowIdx++) {
816
+ if (!ArrowArrayViewIsNull(columnArray, rowIdx)) {
817
+ val = ArrowArrayViewGetIntUnsafe(columnArray, rowIdx);
818
+ val *= sf::internal::powTenSB4[9 - scale];
819
+ returnCode = ArrowArrayAppendInt(newArray, val);
820
+ SF_CHECK_ARROW_RC(returnCode,
821
+ "[Snowflake Exception] error appending int to "
822
+ "arrow array, error code: %d",
823
+ returnCode);
824
+ } else {
825
+ returnCode = ArrowArrayAppendNull(newArray, 1);
826
+ SF_CHECK_ARROW_RC(returnCode,
827
+ "[Snowflake Exception] error appending null to "
828
+ "arrow array, error code: %d",
829
+ returnCode);
830
+ }
831
+ }
832
+ }
833
+ }
834
+
835
+ returnCode = ArrowArrayFinishBuildingDefault(newArray, &error);
836
+ SF_CHECK_ARROW_RC(returnCode,
837
+ "[Snowflake Exception] error finishing building arrow "
838
+ "array: %s, error code: %d",
839
+ ArrowErrorMessage(&error), returnCode);
840
+ field->schema->release(field->schema);
841
+ ArrowSchemaMove(newSchema, field->schema);
842
+ columnArray->array->release(columnArray->array);
843
+ ArrowArrayMove(newArray, columnArray->array);
844
+ }
845
+
846
+ void CArrowTableIterator::convertTimestampTZColumn_nanoarrow(
847
+ ArrowSchemaView* field, ArrowArrayView* columnArray, const int scale,
848
+ const int byteLength, const std::string timezone) {
849
+ int returnCode = 0;
850
+ nanoarrow::UniqueSchema newUniqueField;
851
+ nanoarrow::UniqueArray newUniqueArray;
852
+ ArrowSchema* newSchema = newUniqueField.get();
853
+ ArrowArray* newArray = newUniqueArray.get();
854
+ ArrowError error;
855
+ ArrowSchemaInit(newSchema);
856
+ newSchema->flags &=
857
+ (field->schema->flags & ARROW_FLAG_NULLABLE); // map to nullable()
858
+ auto timeunit = NANOARROW_TIME_UNIT_SECOND;
859
+ if (scale == 0) {
860
+ timeunit = NANOARROW_TIME_UNIT_SECOND;
861
+ } else if (scale <= 3) {
862
+ timeunit = NANOARROW_TIME_UNIT_MILLI;
863
+ } else if (scale <= 6) {
864
+ timeunit = NANOARROW_TIME_UNIT_MICRO;
865
+ } else {
866
+ timeunit = NANOARROW_TIME_UNIT_NANO;
867
+ }
868
+
869
+ if (!timezone.empty()) {
870
+ returnCode = ArrowSchemaSetTypeDateTime(newSchema, NANOARROW_TYPE_TIMESTAMP,
871
+ timeunit, timezone.c_str());
872
+ SF_CHECK_ARROW_RC(returnCode,
873
+ "[Snowflake Exception] error setting arrow schema type "
874
+ "DateTime, error code: %d",
875
+ returnCode);
876
+ } else {
877
+ returnCode = ArrowSchemaSetTypeDateTime(newSchema, NANOARROW_TYPE_TIMESTAMP,
878
+ timeunit, NULL);
879
+ SF_CHECK_ARROW_RC(returnCode,
880
+ "[Snowflake Exception] error setting arrow schema type "
881
+ "DateTime, error code: %d",
882
+ returnCode);
883
+ }
884
+ returnCode = ArrowSchemaSetName(newSchema, field->schema->name);
885
+ SF_CHECK_ARROW_RC(
886
+ returnCode,
887
+ "[Snowflake Exception] error setting schema name, error code: %d",
888
+ returnCode);
889
+
890
+ returnCode = ArrowArrayInitFromSchema(newArray, newSchema, &error);
891
+ SF_CHECK_ARROW_RC(returnCode,
892
+ "[Snowflake Exception] error initializing ArrowArrayView "
893
+ "from schema : %s, error code: %d",
894
+ ArrowErrorMessage(&error), returnCode);
895
+
896
+ ArrowArrayView* epochArray;
897
+ ArrowArrayView* fractionArray;
898
+ for (int64_t i = 0; i < field->schema->n_children; i++) {
899
+ ArrowSchema* c_schema = field->schema->children[i];
900
+ if (std::strcmp(c_schema->name, internal::FIELD_NAME_EPOCH.c_str()) == 0) {
901
+ epochArray = columnArray->children[i];
902
+ } else if (std::strcmp(c_schema->name,
903
+ internal::FIELD_NAME_FRACTION.c_str()) == 0) {
904
+ fractionArray = columnArray->children[i];
905
+ } else {
906
+ // do nothing
907
+ }
908
+ }
909
+
910
+ for (int64_t rowIdx = 0; rowIdx < columnArray->array->length; rowIdx++) {
911
+ if (!ArrowArrayViewIsNull(columnArray, rowIdx)) {
912
+ if (byteLength == 8) {
913
+ int64_t epoch = ArrowArrayViewGetIntUnsafe(epochArray, rowIdx);
914
+ if (scale == 0) {
915
+ returnCode = ArrowArrayAppendInt(newArray, epoch);
916
+ } else if (scale <= 3) {
917
+ returnCode = ArrowArrayAppendInt(
918
+ newArray, epoch * sf::internal::powTenSB4[3 - scale]);
919
+ } else if (scale <= 6) {
920
+ returnCode = ArrowArrayAppendInt(
921
+ newArray, epoch * sf::internal::powTenSB4[6 - scale]);
922
+ } else {
923
+ returnCode = ArrowArrayAppendInt(
924
+ newArray, epoch * sf::internal::powTenSB4[9 - scale]);
925
+ }
926
+ SF_CHECK_ARROW_RC(returnCode,
927
+ "[Snowflake Exception] error appending int to "
928
+ "arrow array, error code: %d",
929
+ returnCode);
930
+ } else if (byteLength == 16) {
931
+ int64_t epoch = ArrowArrayViewGetIntUnsafe(epochArray, rowIdx);
932
+ int64_t fraction = ArrowArrayViewGetIntUnsafe(fractionArray, rowIdx);
933
+ if (scale == 0) {
934
+ returnCode = ArrowArrayAppendInt(newArray, epoch);
935
+ } else if (scale <= 3) {
936
+ returnCode = ArrowArrayAppendInt(
937
+ newArray, epoch * sf::internal::powTenSB4[3 - scale] +
938
+ fraction / sf::internal::powTenSB4[6]);
939
+ } else if (scale <= 6) {
940
+ returnCode = ArrowArrayAppendInt(
941
+ newArray, epoch * sf::internal::powTenSB4[6] +
942
+ fraction / sf::internal::powTenSB4[3]);
943
+ } else {
944
+ returnCode = ArrowArrayAppendInt(
945
+ newArray, epoch * sf::internal::powTenSB4[9] + fraction);
946
+ }
947
+ SF_CHECK_ARROW_RC(returnCode,
948
+ "[Snowflake Exception] error appending int to "
949
+ "arrow array, error code: %d",
950
+ returnCode);
951
+ } else {
952
+ std::string errorInfo = Logger::formatString(
953
+ "[Snowflake Exception] unknown arrow internal data type(%d) "
954
+ "for TIMESTAMP_TZ data",
955
+ NANOARROW_TYPE_ENUM_STRING[field->type]);
956
+ logger->error(__FILE__, __func__, __LINE__, errorInfo.c_str());
957
+ PyErr_SetString(PyExc_Exception, errorInfo.c_str());
958
+ return;
959
+ }
960
+ } else {
961
+ returnCode = ArrowArrayAppendNull(newArray, 1);
962
+ SF_CHECK_ARROW_RC(returnCode,
963
+ "[Snowflake Exception] error appending null to arrow "
964
+ "array, error code: %d",
965
+ returnCode);
966
+ }
967
+ }
968
+
969
+ returnCode = ArrowArrayFinishBuildingDefault(newArray, &error);
970
+ SF_CHECK_ARROW_RC(returnCode,
971
+ "[Snowflake Exception] error finishing building arrow "
972
+ "array: %s, error code: %d",
973
+ ArrowErrorMessage(&error), returnCode);
974
+ field->schema->release(field->schema);
975
+ ArrowSchemaMove(newSchema, field->schema);
976
+ columnArray->array->release(columnArray->array);
977
+ ArrowArrayMove(newArray, columnArray->array);
978
+ }
979
+
980
+ bool CArrowTableIterator::convertRecordBatchesToTable_nanoarrow() {
981
+ // only do conversion once and there exist some record batches
982
+ if (!m_tableConverted && m_ipcArrowArrayViewVec.size() > 0) {
983
+ reconstructRecordBatches_nanoarrow();
984
+ return true;
985
+ }
986
+ return false;
987
+ }
988
+
989
+ std::vector<uintptr_t> CArrowTableIterator::getArrowArrayPtrs() {
990
+ std::vector<uintptr_t> ret;
991
+ for (size_t i = 0; i < m_ipcArrowArrayVec.size(); i++) {
992
+ ret.push_back((uintptr_t)(void*)(m_ipcArrowArrayVec[i].get()));
993
+ }
994
+ return ret;
995
+ }
996
+
997
+ std::vector<uintptr_t> CArrowTableIterator::getArrowSchemaPtrs() {
998
+ std::vector<uintptr_t> ret;
999
+ for (size_t i = 0; i < m_ipcSchemaArrayVec.size(); i++) {
1000
+ ret.push_back((uintptr_t)(void*)(m_ipcSchemaArrayVec[i].get()));
1001
+ }
1002
+ return ret;
1003
+ }
1004
+
1005
+ } // namespace sf