snowflake-connector-python 5.2.0__cp315-cp315-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 (204) hide show
  1. snowflake/connector/__init__.py +148 -0
  2. snowflake/connector/_common/__init__.py +0 -0
  3. snowflake/connector/_common/extras.py +134 -0
  4. snowflake/connector/_common/telemetry.py +221 -0
  5. snowflake/connector/_common/wif_util.py +92 -0
  6. snowflake/connector/_core/sf_core_python.cp315-win_amd64.pyd +0 -0
  7. snowflake/connector/_core/sf_core_python.pyi +79 -0
  8. snowflake/connector/_internal/__init__.py +6 -0
  9. snowflake/connector/_internal/_private_key_helper.py +31 -0
  10. snowflake/connector/_internal/api_client/__init__.py +93 -0
  11. snowflake/connector/_internal/api_client/bridge.py +41 -0
  12. snowflake/connector/_internal/api_client/client_api.py +976 -0
  13. snowflake/connector/_internal/arrow.py +47 -0
  14. snowflake/connector/_internal/arrow_context.py +240 -0
  15. snowflake/connector/_internal/arrow_stream_async.py +266 -0
  16. snowflake/connector/_internal/arrow_stream_iterator.cp311-win_amd64.pyd +0 -0
  17. snowflake/connector/_internal/arrow_stream_iterator.cp312-win_amd64.pyd +0 -0
  18. snowflake/connector/_internal/arrow_stream_iterator.cp313-win_amd64.pyd +0 -0
  19. snowflake/connector/_internal/arrow_stream_iterator.cp314-win_amd64.pyd +0 -0
  20. snowflake/connector/_internal/arrow_stream_iterator.cp314t-win_amd64.pyd +0 -0
  21. snowflake/connector/_internal/arrow_stream_iterator.cp315-win_amd64.pyd +0 -0
  22. snowflake/connector/_internal/arrow_stream_iterator.pyi +42 -0
  23. snowflake/connector/_internal/arrow_stream_utils.py +171 -0
  24. snowflake/connector/_internal/authenticator_type.py +53 -0
  25. snowflake/connector/_internal/backward_compatibility.py +245 -0
  26. snowflake/connector/_internal/binding_converters.py +741 -0
  27. snowflake/connector/_internal/config_utils.py +71 -0
  28. snowflake/connector/_internal/connection/__init__.py +39 -0
  29. snowflake/connector/_internal/connection/connection.py +616 -0
  30. snowflake/connector/_internal/connection/connection_types.py +13 -0
  31. snowflake/connector/_internal/connection/constants.py +25 -0
  32. snowflake/connector/_internal/connection/decorators.py +31 -0
  33. snowflake/connector/_internal/connection/freezable_proxy.py +104 -0
  34. snowflake/connector/_internal/connection/queries.py +10 -0
  35. snowflake/connector/_internal/connection_config_mixin.py +755 -0
  36. snowflake/connector/_internal/cursor/__init__.py +25 -0
  37. snowflake/connector/_internal/cursor/base.py +732 -0
  38. snowflake/connector/_internal/cursor/cursor_types.py +13 -0
  39. snowflake/connector/_internal/cursor/decorators.py +56 -0
  40. snowflake/connector/_internal/cursor/query_result.py +202 -0
  41. snowflake/connector/_internal/cursor/query_result_waiter.py +98 -0
  42. snowflake/connector/_internal/cursor/result_metadata.py +255 -0
  43. snowflake/connector/_internal/cursor/result_set_wrapper.py +66 -0
  44. snowflake/connector/_internal/decorators.py +539 -0
  45. snowflake/connector/_internal/error_kinds.py +111 -0
  46. snowflake/connector/_internal/errorcode.py +35 -0
  47. snowflake/connector/_internal/errorhandler.py +278 -0
  48. snowflake/connector/_internal/fips.py +28 -0
  49. snowflake/connector/_internal/logging/__init__.py +52 -0
  50. snowflake/connector/_internal/logging/config.py +134 -0
  51. snowflake/connector/_internal/logging/core_logger.py +218 -0
  52. snowflake/connector/_internal/logging/native_extension_logger.py +144 -0
  53. snowflake/connector/_internal/logout_config_mapping.py +187 -0
  54. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +57 -0
  55. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
  56. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrowTableConverter.cpp +943 -0
  57. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrowTableConverter.hpp +63 -0
  58. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +18 -0
  59. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
  60. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
  61. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
  62. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +118 -0
  63. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +116 -0
  64. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamIterator.cpp +323 -0
  65. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamIterator.hpp +133 -0
  66. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamTableIterator.cpp +275 -0
  67. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamTableIterator.hpp +168 -0
  68. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ConverterUtil.cpp +439 -0
  69. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ConverterUtil.hpp +30 -0
  70. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +48 -0
  71. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
  72. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +76 -0
  73. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
  74. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +90 -0
  75. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +63 -0
  76. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +62 -0
  77. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
  78. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +29 -0
  79. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
  80. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
  81. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
  82. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +41 -0
  83. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +65 -0
  84. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +54 -0
  85. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
  86. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +79 -0
  87. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
  88. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +52 -0
  89. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
  90. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
  91. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +117 -0
  92. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +54 -0
  93. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +34 -0
  94. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +33 -0
  95. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
  96. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +18 -0
  97. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
  98. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +39 -0
  99. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
  100. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +326 -0
  101. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +138 -0
  102. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
  103. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/time.cpp +65 -0
  104. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
  105. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/arrow_stream_iterator.cpp +13278 -0
  106. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/arrow_stream_iterator.pyx +204 -0
  107. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +109 -0
  108. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +125 -0
  109. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
  110. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1914 -0
  111. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +208 -0
  112. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +128 -0
  113. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
  114. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +58 -0
  115. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +144 -0
  116. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
  117. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
  118. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
  119. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +160 -0
  120. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +98 -0
  121. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +243 -0
  122. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
  123. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +207 -0
  124. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +80 -0
  125. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +83 -0
  126. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
  127. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
  128. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +201 -0
  129. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +108 -0
  130. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
  131. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
  132. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
  133. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
  134. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
  135. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +164 -0
  136. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +926 -0
  137. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +182 -0
  138. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
  139. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
  140. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc.c +3052 -0
  141. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3019 -0
  142. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3354 -0
  143. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +344 -0
  144. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +29305 -0
  145. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +381 -0
  146. snowflake/connector/_internal/nanoarrow_cpp/Logging/logging.cpp +108 -0
  147. snowflake/connector/_internal/nanoarrow_cpp/Logging/logging.hpp +47 -0
  148. snowflake/connector/_internal/nanoarrow_cpp/scripts/.clang-format +8 -0
  149. snowflake/connector/_internal/nanoarrow_cpp/scripts/format.sh +8 -0
  150. snowflake/connector/_internal/protobuf_gen/__init__.py +0 -0
  151. snowflake/connector/_internal/protobuf_gen/database_driver_v1_pb2.py +408 -0
  152. snowflake/connector/_internal/protobuf_gen/database_driver_v1_pb2.pyi +4487 -0
  153. snowflake/connector/_internal/protobuf_gen/database_driver_v1_services.py +2088 -0
  154. snowflake/connector/_internal/protobuf_gen/proto_exception.py +17 -0
  155. snowflake/connector/_internal/result_batch.py +150 -0
  156. snowflake/connector/_internal/snowflake_restful.py +222 -0
  157. snowflake/connector/_internal/snowpark_backcompat_helpers.py +31 -0
  158. snowflake/connector/_internal/sqlstate.py +11 -0
  159. snowflake/connector/_internal/statement_utils.py +207 -0
  160. snowflake/connector/_internal/text_utils.py +112 -0
  161. snowflake/connector/_internal/type_codes.py +139 -0
  162. snowflake/connector/_internal/utils.py +65 -0
  163. snowflake/connector/_internal/write_pandas_operation.py +657 -0
  164. snowflake/connector/aio/README.md +168 -0
  165. snowflake/connector/aio/__init__.py +37 -0
  166. snowflake/connector/aio/connection/__init__.py +17 -0
  167. snowflake/connector/aio/connection/_connection.py +506 -0
  168. snowflake/connector/aio/cursor/__init__.py +35 -0
  169. snowflake/connector/aio/cursor/_base.py +1034 -0
  170. snowflake/connector/aio/cursor/_dict_cursor.py +78 -0
  171. snowflake/connector/aio/cursor/_result_set_wrapper.py +35 -0
  172. snowflake/connector/aio/cursor/_snowflake_cursor.py +72 -0
  173. snowflake/connector/aio/pandas_tools.py +279 -0
  174. snowflake/connector/aio/result_batch.py +165 -0
  175. snowflake/connector/auth/__init__.py +0 -0
  176. snowflake/connector/auth/workload_identity.py +5 -0
  177. snowflake/connector/compat.py +22 -0
  178. snowflake/connector/config_manager.py +392 -0
  179. snowflake/connector/connection/__init__.py +30 -0
  180. snowflake/connector/connection/_connection.py +641 -0
  181. snowflake/connector/connection_config.py +517 -0
  182. snowflake/connector/constants.py +52 -0
  183. snowflake/connector/cursor/__init__.py +37 -0
  184. snowflake/connector/cursor/_base.py +1169 -0
  185. snowflake/connector/cursor/_chunked_download_reader.py +75 -0
  186. snowflake/connector/cursor/_dict_cursor.py +78 -0
  187. snowflake/connector/cursor/_result_set_wrapper.py +35 -0
  188. snowflake/connector/cursor/_snowflake_cursor.py +72 -0
  189. snowflake/connector/description.py +7 -0
  190. snowflake/connector/errors.py +492 -0
  191. snowflake/connector/network.py +71 -0
  192. snowflake/connector/pandas_tools.py +191 -0
  193. snowflake/connector/py.typed +0 -0
  194. snowflake/connector/result_batch.py +216 -0
  195. snowflake/connector/telemetry.py +40 -0
  196. snowflake/connector/time_util.py +11 -0
  197. snowflake/connector/types.py +134 -0
  198. snowflake/connector/util_text.py +3 -0
  199. snowflake/connector/version.py +23 -0
  200. snowflake_connector_python-5.2.0.dist-info/DELVEWHEEL +2 -0
  201. snowflake_connector_python-5.2.0.dist-info/METADATA +190 -0
  202. snowflake_connector_python-5.2.0.dist-info/RECORD +204 -0
  203. snowflake_connector_python-5.2.0.dist-info/WHEEL +4 -0
  204. snowflake_connector_python.libs/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll +0 -0
@@ -0,0 +1,323 @@
1
+ #include "CArrowStreamIterator.hpp"
2
+
3
+ #include <memory>
4
+ #include <string>
5
+ #include <vector>
6
+
7
+ namespace sf {
8
+
9
+
10
+
11
+ Logger* CArrowStreamIterator::logger = new Logger("snowflake.connector.CArrowStreamIterator");
12
+
13
+ std::unique_ptr<CArrowStreamIterator> CArrowStreamIterator::from_stream(int64_t stream_ptr,
14
+ PyObject* context,
15
+ bool use_numpy,
16
+ bool use_dict_result) {
17
+ auto* stream = reinterpret_cast<ArrowArrayStream*>(stream_ptr);
18
+
19
+ // Validate stream pointer
20
+ if (stream == nullptr || stream->release == nullptr) {
21
+ std::string errorInfo = "[Snowflake Exception] Invalid ArrowArrayStream pointer";
22
+ logger->error(__FILE__, __func__, __LINE__, errorInfo.c_str());
23
+ PyErr_SetString(PyExc_Exception, errorInfo.c_str());
24
+ return nullptr;
25
+ }
26
+
27
+ // Get schema from stream before creating the iterator
28
+ ArrowSchema schema = {};
29
+ int returnCode = stream->get_schema(stream, &schema);
30
+ if (returnCode != 0) {
31
+ const char* error_msg = stream->get_last_error(stream);
32
+ std::string errorInfo = Logger::formatString(
33
+ "[Snowflake Exception] error getting schema from stream: %s, error code: %d",
34
+ error_msg ? error_msg : "unknown", returnCode);
35
+ logger->error(__FILE__, __func__, __LINE__, errorInfo.c_str());
36
+ PyErr_SetString(PyExc_Exception, errorInfo.c_str());
37
+ return nullptr;
38
+ }
39
+
40
+ logger->debug(__FILE__, __func__, __LINE__, "CArrowStreamIterator initialized with %lld columns",
41
+ schema.n_children);
42
+
43
+ // Create the iterator with all data
44
+ return std::unique_ptr<CArrowStreamIterator>(
45
+ new CArrowStreamIterator(stream, &schema, context, use_numpy, use_dict_result));
46
+ }
47
+
48
+ namespace {
49
+ void releaseArrowArrayStream(ArrowArrayStream* stream) {
50
+ if (stream != nullptr && stream->release != nullptr) {
51
+ stream->release(stream);
52
+ }
53
+ }
54
+ } // namespace
55
+
56
+ CArrowStreamIterator::CArrowStreamIterator(ArrowArrayStream* stream, ArrowSchema* schema,
57
+ PyObject* context, bool use_numpy, bool use_dict_result)
58
+ : m_stream(stream, releaseArrowArrayStream),
59
+ m_currentRowIndex(0),
60
+ m_rowCount(0),
61
+ m_columnCount(schema->n_children),
62
+ m_context(context),
63
+ m_useNumpy(use_numpy),
64
+ m_useDictResult(use_dict_result),
65
+ m_streamExhausted(false),
66
+ m_totalRowsReturned(0) {
67
+ // Move schema data into our UniqueSchema (transfers ownership)
68
+ ArrowSchemaMove(schema, m_schema.get());
69
+ }
70
+
71
+ bool CArrowStreamIterator::loadNextBatch() {
72
+ if (m_streamExhausted) {
73
+ return false;
74
+ }
75
+
76
+ // Reset current batch state
77
+ m_currentRowIndex = 0;
78
+ m_rowCount = 0;
79
+ m_columnConverters.clear();
80
+
81
+ // Create new array for next batch
82
+ m_currentArray.reset();
83
+ m_currentArrayView.reset();
84
+
85
+ // Get next batch from stream
86
+ // IMPORTANT: Release the GIL during get_next() to avoid deadlocks.
87
+ // Similar practice happens in pyarrow.
88
+ int returnCode;
89
+ ArrowArrayStream* stream = m_stream.get();
90
+ {
91
+ Py_BEGIN_ALLOW_THREADS
92
+ returnCode = stream->get_next(stream, m_currentArray.get());
93
+ Py_END_ALLOW_THREADS
94
+ }
95
+
96
+ if (returnCode != 0) {
97
+ const char* error_msg = stream->get_last_error(stream);
98
+ std::string errorInfo = Logger::formatString(
99
+ "[Snowflake Exception] error getting next batch from stream: %s, error code: %d",
100
+ error_msg ? error_msg : "unknown", returnCode);
101
+ logger->error(__FILE__, __func__, __LINE__, errorInfo.c_str());
102
+ PyErr_SetString(PyExc_Exception, errorInfo.c_str());
103
+ return false;
104
+ }
105
+
106
+ // Check if stream is exhausted (release is null means no more data)
107
+ if (m_currentArray->release == nullptr) {
108
+ m_streamExhausted = true;
109
+ logger->debug(__FILE__, __func__, __LINE__, "Stream exhausted");
110
+ return false;
111
+ }
112
+
113
+ m_rowCount = m_currentArray->length;
114
+ logger->debug(__FILE__, __func__, __LINE__, "Loaded batch with %lld rows", m_rowCount);
115
+
116
+ // Handle empty batches
117
+ if (m_rowCount == 0) {
118
+ return loadNextBatch(); // Try next batch
119
+ }
120
+
121
+ // Initialize array view
122
+ ArrowError error;
123
+ returnCode = ArrowArrayViewInitFromSchema(m_currentArrayView.get(), m_schema.get(), &error);
124
+ if (returnCode != NANOARROW_OK) {
125
+ std::string errorInfo = Logger::formatString(
126
+ "[Snowflake Exception] error initializing ArrowArrayView: %s, error code: %d",
127
+ ArrowErrorMessage(&error), returnCode);
128
+ logger->error(__FILE__, __func__, __LINE__, errorInfo.c_str());
129
+ PyErr_SetString(PyExc_Exception, errorInfo.c_str());
130
+ return false;
131
+ }
132
+
133
+ returnCode = ArrowArrayViewSetArray(m_currentArrayView.get(), m_currentArray.get(), &error);
134
+ if (returnCode != NANOARROW_OK) {
135
+ std::string errorInfo = Logger::formatString(
136
+ "[Snowflake Exception] error setting ArrowArrayView: %s, error code: %d",
137
+ ArrowErrorMessage(&error), returnCode);
138
+ logger->error(__FILE__, __func__, __LINE__, errorInfo.c_str());
139
+ PyErr_SetString(PyExc_Exception, errorInfo.c_str());
140
+ return false;
141
+ }
142
+
143
+ // Initialize column converters for this batch
144
+ initColumnConverters();
145
+
146
+ return true;
147
+ }
148
+
149
+ void CArrowStreamIterator::initColumnConverters() {
150
+ m_columnConverters.clear();
151
+ m_columnConverters.reserve(m_columnCount);
152
+
153
+ for (int64_t i = 0; i < m_columnCount; ++i) {
154
+ ArrowSchema* columnSchema = m_schema->children[i];
155
+ ArrowArrayView* columnArrayView = m_currentArrayView->children[i];
156
+
157
+ auto converter =
158
+ getConverterFromSchema(columnSchema, columnArrayView, m_context, m_useNumpy, logger);
159
+ if (converter == nullptr) {
160
+ std::string errorInfo =
161
+ Logger::formatString("[Snowflake Exception] Failed to create converter for column %lld", i);
162
+ logger->error(__FILE__, __func__, __LINE__, errorInfo.c_str());
163
+ PyErr_SetString(PyExc_Exception, errorInfo.c_str());
164
+ return;
165
+ }
166
+ m_columnConverters.push_back(converter);
167
+ }
168
+
169
+ logger->debug(__FILE__, __func__, __LINE__, "Initialized %zu column converters",
170
+ m_columnConverters.size());
171
+ }
172
+
173
+ ReturnVal CArrowStreamIterator::next() {
174
+ while (m_currentRowIndex >= m_rowCount) {
175
+ if (!loadNextBatch()) {
176
+ return ReturnVal(nullptr, nullptr);
177
+ }
178
+ }
179
+
180
+ PyObject* row = buildRowObject();
181
+ if (row == nullptr) {
182
+ if (py::checkPyError()) {
183
+ PyObject *type, *val, *traceback;
184
+ PyErr_Fetch(&type, &val, &traceback);
185
+ PyErr_Clear();
186
+ m_currentPyException.reset(val);
187
+ Py_XDECREF(type);
188
+ Py_XDECREF(traceback);
189
+ return ReturnVal(nullptr, m_currentPyException.get());
190
+ }
191
+ return ReturnVal(nullptr, nullptr);
192
+ }
193
+
194
+ m_latestReturnedRow.reset(row);
195
+ m_currentRowIndex++;
196
+ m_totalRowsReturned++;
197
+ return ReturnVal(m_latestReturnedRow.get(), nullptr);
198
+ }
199
+
200
+ PyObject* CArrowStreamIterator::nextN(int64_t size) {
201
+ PyObject* pylist = PyList_New(size);
202
+ if (pylist == nullptr) {
203
+ return nullptr;
204
+ }
205
+
206
+ int64_t collected = 0;
207
+ while (collected < size) {
208
+ while (m_currentRowIndex >= m_rowCount) {
209
+ if (!loadNextBatch()) {
210
+ if (py::checkPyError()) {
211
+ PyList_SetSlice(pylist, collected, size, nullptr);
212
+ Py_DECREF(pylist);
213
+ return nullptr;
214
+ }
215
+ if (PyList_SetSlice(pylist, collected, size, nullptr) != 0) {
216
+ Py_DECREF(pylist);
217
+ return nullptr;
218
+ }
219
+ return pylist;
220
+ }
221
+ }
222
+
223
+ PyObject* row = buildRowObject();
224
+ if (row == nullptr) {
225
+ PyList_SetSlice(pylist, collected, size, nullptr);
226
+ Py_DECREF(pylist);
227
+ return nullptr;
228
+ }
229
+
230
+ PyList_SET_ITEM(pylist, collected, row); // steals reference
231
+ m_currentRowIndex++;
232
+ m_totalRowsReturned++;
233
+ collected++;
234
+ }
235
+
236
+ return pylist;
237
+ }
238
+
239
+ PyObject* CArrowStreamIterator::nextAll() {
240
+ PyObject* pylist = PyList_New(0);
241
+ if (pylist == nullptr) {
242
+ return nullptr;
243
+ }
244
+
245
+ for (;;) {
246
+ while (m_currentRowIndex >= m_rowCount) {
247
+ if (!loadNextBatch()) {
248
+ if (py::checkPyError()) {
249
+ Py_DECREF(pylist);
250
+ return nullptr;
251
+ }
252
+ return pylist;
253
+ }
254
+ }
255
+
256
+ PyObject* row = buildRowObject();
257
+ if (row == nullptr) {
258
+ Py_DECREF(pylist);
259
+ return nullptr;
260
+ }
261
+
262
+ if (PyList_Append(pylist, row) != 0) {
263
+ Py_DECREF(row);
264
+ Py_DECREF(pylist);
265
+ return nullptr;
266
+ }
267
+ Py_DECREF(row);
268
+
269
+ m_currentRowIndex++;
270
+ m_totalRowsReturned++;
271
+ }
272
+ }
273
+
274
+ PyObject* CArrowStreamIterator::buildRowObject() {
275
+ if (m_columnCount == 0) {
276
+ return m_useDictResult ? PyDict_New() : PyTuple_New(0);
277
+ }
278
+
279
+ if (m_useDictResult) {
280
+ PyObject* pydict = PyDict_New();
281
+ if (pydict == nullptr) {
282
+ return nullptr;
283
+ }
284
+
285
+ for (int64_t colIdx = 0; colIdx < m_columnCount; ++colIdx) {
286
+ const char* colName = m_schema->children[colIdx]->name;
287
+ PyObject* val = m_columnConverters[colIdx]->toPyObject(m_currentRowIndex);
288
+
289
+ if (py::checkPyError()) {
290
+ Py_DECREF(pydict);
291
+ return nullptr;
292
+ }
293
+
294
+ if (PyDict_SetItemString(pydict, colName, val) != 0) {
295
+ Py_DECREF(val);
296
+ Py_DECREF(pydict);
297
+ return nullptr;
298
+ }
299
+ Py_DECREF(val);
300
+ }
301
+ return pydict;
302
+ }
303
+
304
+ PyObject* pytuple = PyTuple_New(m_columnCount);
305
+ if (pytuple == nullptr) {
306
+ return nullptr;
307
+ }
308
+
309
+ for (int64_t colIdx = 0; colIdx < m_columnCount; ++colIdx) {
310
+ PyObject* val = m_columnConverters[colIdx]->toPyObject(m_currentRowIndex);
311
+
312
+ if (py::checkPyError()) {
313
+ Py_DECREF(pytuple);
314
+ return nullptr;
315
+ }
316
+
317
+ PyTuple_SET_ITEM(pytuple, colIdx, val); // steals reference
318
+ }
319
+ return pytuple;
320
+ }
321
+
322
+ } // namespace sf
323
+
@@ -0,0 +1,133 @@
1
+ #ifndef PC_ARROWSTREAMITERATOR_HPP
2
+ #define PC_ARROWSTREAMITERATOR_HPP
3
+
4
+ #include <memory>
5
+ #include <vector>
6
+
7
+ #include "CArrowIterator.hpp" // For ReturnVal definition
8
+ #include "ConverterUtil.hpp"
9
+ #include "IColumnConverter.hpp"
10
+ #include "Python/Common.hpp"
11
+ #include "logging.hpp"
12
+ #include "nanoarrow.h"
13
+ #include "nanoarrow.hpp"
14
+
15
+ namespace sf {
16
+
17
+ /**
18
+ * Arrow stream iterator that reads directly from an ArrowArrayStream pointer.
19
+ * This eliminates the need for PyArrow to read batches - C++ reads directly from the stream.
20
+ */
21
+ class CArrowStreamIterator {
22
+ public:
23
+ /**
24
+ * Factory method to create a CArrowStreamIterator from a stream pointer.
25
+ * Validates the stream and reads the schema.
26
+ * @param stream_ptr Pointer to ArrowArrayStream (as integer from Python)
27
+ * @param context Python context object for conversions
28
+ * @param use_numpy Whether to use numpy types
29
+ * @param use_dict_result Whether to return dicts instead of tuples
30
+ * @return Unique pointer to the iterator, or nullptr on error (with Python exception set)
31
+ */
32
+ static std::unique_ptr<CArrowStreamIterator> from_stream(int64_t stream_ptr, PyObject* context,
33
+ bool use_numpy, bool use_dict_result);
34
+
35
+ /**
36
+ * Get the next row as a Python tuple or dict
37
+ * @return ReturnVal with Python object or nullptr if exhausted
38
+ */
39
+ ReturnVal next();
40
+
41
+ /**
42
+ * Fetch up to `size` rows as a Python list in a single C++ call.
43
+ * @param size Number of rows to fetch (must be >= 0).
44
+ * @return New reference to a Python list, or nullptr with Python exception set on error.
45
+ */
46
+ PyObject* nextN(int64_t size);
47
+
48
+ /**
49
+ * Fetch all remaining rows as a Python list in a single C++ call.
50
+ * @return New reference to a Python list, or nullptr with Python exception set on error.
51
+ */
52
+ PyObject* nextAll();
53
+
54
+ private:
55
+ /**
56
+ * Private constructor - use from_stream() factory method instead.
57
+ * Takes ownership of stream and schema.
58
+ */
59
+ CArrowStreamIterator(ArrowArrayStream* stream, ArrowSchema* schema, PyObject* context,
60
+ bool use_numpy, bool use_dict_result);
61
+
62
+ protected:
63
+ /**
64
+ * Load the next batch from the stream
65
+ * @return true if a batch was loaded, false if stream exhausted
66
+ */
67
+ bool loadNextBatch();
68
+
69
+ /**
70
+ * Initialize column converters for the current batch
71
+ */
72
+ void initColumnConverters();
73
+
74
+ /**
75
+ * Build a Python tuple or dict for the current row, returning a new reference.
76
+ * Callers decide whether to store the result in m_latestReturnedRow or use it directly.
77
+ * @return New reference to the row object, or nullptr with Python exception set on error.
78
+ */
79
+ PyObject* buildRowObject();
80
+
81
+ /** The Arrow stream we're reading from (owned by this iterator) */
82
+ std::unique_ptr<ArrowArrayStream, void (*)(ArrowArrayStream*)> m_stream;
83
+
84
+ /** Schema read from stream */
85
+ nanoarrow::UniqueSchema m_schema;
86
+
87
+ /** Current batch array */
88
+ nanoarrow::UniqueArray m_currentArray;
89
+
90
+ /** Current batch array view */
91
+ nanoarrow::UniqueArrayView m_currentArrayView;
92
+
93
+ /** Pointer to the latest returned Python row result */
94
+ py::UniqueRef m_latestReturnedRow;
95
+
96
+ /** List of column converters for current batch */
97
+ std::vector<std::shared_ptr<sf::IColumnConverter>> m_columnConverters;
98
+
99
+ /** Current row index in current batch (0-based) */
100
+ int64_t m_currentRowIndex;
101
+
102
+ /** Total number of rows in current batch */
103
+ int64_t m_rowCount;
104
+
105
+ /** Number of columns */
106
+ int64_t m_columnCount;
107
+
108
+ /** Arrow format convert context for the current session */
109
+ PyObject* m_context;
110
+
111
+ /** Whether to use numpy int64/float64/datetime */
112
+ bool m_useNumpy;
113
+
114
+ /** Whether to return dicts instead of tuples */
115
+ bool m_useDictResult;
116
+
117
+ /** Logger instance */
118
+ static Logger* logger;
119
+
120
+ /** Current Python exception if any */
121
+ py::UniqueRef m_currentPyException;
122
+
123
+ /** Whether stream is exhausted */
124
+ bool m_streamExhausted;
125
+
126
+ /** Total rows returned so far (for debugging) */
127
+ int64_t m_totalRowsReturned;
128
+ };
129
+
130
+ } // namespace sf
131
+
132
+ #endif // PC_ARROWSTREAMITERATOR_HPP
133
+