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.
- snowflake/connector/__init__.py +148 -0
- snowflake/connector/_common/__init__.py +0 -0
- snowflake/connector/_common/extras.py +134 -0
- snowflake/connector/_common/telemetry.py +221 -0
- snowflake/connector/_common/wif_util.py +92 -0
- snowflake/connector/_core/sf_core_python.cp315-win_amd64.pyd +0 -0
- snowflake/connector/_core/sf_core_python.pyi +79 -0
- snowflake/connector/_internal/__init__.py +6 -0
- snowflake/connector/_internal/_private_key_helper.py +31 -0
- snowflake/connector/_internal/api_client/__init__.py +93 -0
- snowflake/connector/_internal/api_client/bridge.py +41 -0
- snowflake/connector/_internal/api_client/client_api.py +976 -0
- snowflake/connector/_internal/arrow.py +47 -0
- snowflake/connector/_internal/arrow_context.py +240 -0
- snowflake/connector/_internal/arrow_stream_async.py +266 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp311-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp312-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp313-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp314-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp314t-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp315-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.pyi +42 -0
- snowflake/connector/_internal/arrow_stream_utils.py +171 -0
- snowflake/connector/_internal/authenticator_type.py +53 -0
- snowflake/connector/_internal/backward_compatibility.py +245 -0
- snowflake/connector/_internal/binding_converters.py +741 -0
- snowflake/connector/_internal/config_utils.py +71 -0
- snowflake/connector/_internal/connection/__init__.py +39 -0
- snowflake/connector/_internal/connection/connection.py +616 -0
- snowflake/connector/_internal/connection/connection_types.py +13 -0
- snowflake/connector/_internal/connection/constants.py +25 -0
- snowflake/connector/_internal/connection/decorators.py +31 -0
- snowflake/connector/_internal/connection/freezable_proxy.py +104 -0
- snowflake/connector/_internal/connection/queries.py +10 -0
- snowflake/connector/_internal/connection_config_mixin.py +755 -0
- snowflake/connector/_internal/cursor/__init__.py +25 -0
- snowflake/connector/_internal/cursor/base.py +732 -0
- snowflake/connector/_internal/cursor/cursor_types.py +13 -0
- snowflake/connector/_internal/cursor/decorators.py +56 -0
- snowflake/connector/_internal/cursor/query_result.py +202 -0
- snowflake/connector/_internal/cursor/query_result_waiter.py +98 -0
- snowflake/connector/_internal/cursor/result_metadata.py +255 -0
- snowflake/connector/_internal/cursor/result_set_wrapper.py +66 -0
- snowflake/connector/_internal/decorators.py +539 -0
- snowflake/connector/_internal/error_kinds.py +111 -0
- snowflake/connector/_internal/errorcode.py +35 -0
- snowflake/connector/_internal/errorhandler.py +278 -0
- snowflake/connector/_internal/fips.py +28 -0
- snowflake/connector/_internal/logging/__init__.py +52 -0
- snowflake/connector/_internal/logging/config.py +134 -0
- snowflake/connector/_internal/logging/core_logger.py +218 -0
- snowflake/connector/_internal/logging/native_extension_logger.py +144 -0
- snowflake/connector/_internal/logout_config_mapping.py +187 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +57 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrowTableConverter.cpp +943 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrowTableConverter.hpp +63 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +18 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +118 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +116 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamIterator.cpp +323 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamIterator.hpp +133 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamTableIterator.cpp +275 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamTableIterator.hpp +168 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ConverterUtil.cpp +439 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ConverterUtil.hpp +30 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +48 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +76 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +90 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +63 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +62 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +29 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +41 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +65 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +54 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +79 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +52 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +117 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +54 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +34 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +33 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +18 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +39 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +326 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +138 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/time.cpp +65 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/arrow_stream_iterator.cpp +13278 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/arrow_stream_iterator.pyx +204 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +109 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +125 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1914 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +208 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +128 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +58 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +144 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +160 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +98 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +243 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +207 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +80 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +83 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +201 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +108 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +164 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +926 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +182 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc.c +3052 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3019 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3354 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +344 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +29305 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +381 -0
- snowflake/connector/_internal/nanoarrow_cpp/Logging/logging.cpp +108 -0
- snowflake/connector/_internal/nanoarrow_cpp/Logging/logging.hpp +47 -0
- snowflake/connector/_internal/nanoarrow_cpp/scripts/.clang-format +8 -0
- snowflake/connector/_internal/nanoarrow_cpp/scripts/format.sh +8 -0
- snowflake/connector/_internal/protobuf_gen/__init__.py +0 -0
- snowflake/connector/_internal/protobuf_gen/database_driver_v1_pb2.py +408 -0
- snowflake/connector/_internal/protobuf_gen/database_driver_v1_pb2.pyi +4487 -0
- snowflake/connector/_internal/protobuf_gen/database_driver_v1_services.py +2088 -0
- snowflake/connector/_internal/protobuf_gen/proto_exception.py +17 -0
- snowflake/connector/_internal/result_batch.py +150 -0
- snowflake/connector/_internal/snowflake_restful.py +222 -0
- snowflake/connector/_internal/snowpark_backcompat_helpers.py +31 -0
- snowflake/connector/_internal/sqlstate.py +11 -0
- snowflake/connector/_internal/statement_utils.py +207 -0
- snowflake/connector/_internal/text_utils.py +112 -0
- snowflake/connector/_internal/type_codes.py +139 -0
- snowflake/connector/_internal/utils.py +65 -0
- snowflake/connector/_internal/write_pandas_operation.py +657 -0
- snowflake/connector/aio/README.md +168 -0
- snowflake/connector/aio/__init__.py +37 -0
- snowflake/connector/aio/connection/__init__.py +17 -0
- snowflake/connector/aio/connection/_connection.py +506 -0
- snowflake/connector/aio/cursor/__init__.py +35 -0
- snowflake/connector/aio/cursor/_base.py +1034 -0
- snowflake/connector/aio/cursor/_dict_cursor.py +78 -0
- snowflake/connector/aio/cursor/_result_set_wrapper.py +35 -0
- snowflake/connector/aio/cursor/_snowflake_cursor.py +72 -0
- snowflake/connector/aio/pandas_tools.py +279 -0
- snowflake/connector/aio/result_batch.py +165 -0
- snowflake/connector/auth/__init__.py +0 -0
- snowflake/connector/auth/workload_identity.py +5 -0
- snowflake/connector/compat.py +22 -0
- snowflake/connector/config_manager.py +392 -0
- snowflake/connector/connection/__init__.py +30 -0
- snowflake/connector/connection/_connection.py +641 -0
- snowflake/connector/connection_config.py +517 -0
- snowflake/connector/constants.py +52 -0
- snowflake/connector/cursor/__init__.py +37 -0
- snowflake/connector/cursor/_base.py +1169 -0
- snowflake/connector/cursor/_chunked_download_reader.py +75 -0
- snowflake/connector/cursor/_dict_cursor.py +78 -0
- snowflake/connector/cursor/_result_set_wrapper.py +35 -0
- snowflake/connector/cursor/_snowflake_cursor.py +72 -0
- snowflake/connector/description.py +7 -0
- snowflake/connector/errors.py +492 -0
- snowflake/connector/network.py +71 -0
- snowflake/connector/pandas_tools.py +191 -0
- snowflake/connector/py.typed +0 -0
- snowflake/connector/result_batch.py +216 -0
- snowflake/connector/telemetry.py +40 -0
- snowflake/connector/time_util.py +11 -0
- snowflake/connector/types.py +134 -0
- snowflake/connector/util_text.py +3 -0
- snowflake/connector/version.py +23 -0
- snowflake_connector_python-5.2.0.dist-info/DELVEWHEEL +2 -0
- snowflake_connector_python-5.2.0.dist-info/METADATA +190 -0
- snowflake_connector_python-5.2.0.dist-info/RECORD +204 -0
- snowflake_connector_python-5.2.0.dist-info/WHEEL +4 -0
- 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
|
+
|