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,275 @@
|
|
|
1
|
+
#include "CArrowStreamTableIterator.hpp"
|
|
2
|
+
|
|
3
|
+
#include <exception>
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <string>
|
|
6
|
+
|
|
7
|
+
#include "Python/Common.hpp"
|
|
8
|
+
|
|
9
|
+
namespace sf {
|
|
10
|
+
|
|
11
|
+
Logger* CArrowStreamTableIterator::logger =
|
|
12
|
+
new Logger("snowflake.connector.CArrowStreamTableIterator");
|
|
13
|
+
|
|
14
|
+
namespace {
|
|
15
|
+
void releaseStream(ArrowArrayStream* s) {
|
|
16
|
+
if (s && s->release) s->release(s);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Invokes @p convert, translating any C++ exception into a Python
|
|
21
|
+
* exception. The Cython declarations of the methods below carry no
|
|
22
|
+
* `except +`, so an escaping C++ exception reaches a caller that cannot
|
|
23
|
+
* handle it and terminates the process. py::setPyError() acquires the GIL
|
|
24
|
+
* on its own, so this is usable inside a Py_BEGIN_ALLOW_THREADS block.
|
|
25
|
+
*/
|
|
26
|
+
template <typename Fn>
|
|
27
|
+
void runTranslatingCxxExceptions(Fn&& convert) {
|
|
28
|
+
try {
|
|
29
|
+
convert();
|
|
30
|
+
} catch (const std::exception& e) {
|
|
31
|
+
py::setPyError(PyExc_Exception, e.what());
|
|
32
|
+
} catch (...) {
|
|
33
|
+
py::setPyError(PyExc_Exception,
|
|
34
|
+
"[Snowflake Exception] unknown error while converting Arrow columns");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
} // namespace
|
|
38
|
+
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Factory / constructor
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
std::unique_ptr<CArrowStreamTableIterator> CArrowStreamTableIterator::from_stream(int64_t stream_ptr, PyObject* context, bool number_to_decimal, bool force_microsecond_precision) {
|
|
44
|
+
auto* stream = reinterpret_cast<ArrowArrayStream*>(stream_ptr);
|
|
45
|
+
if (!stream || !stream->release) {
|
|
46
|
+
PyErr_SetString(PyExc_Exception, "[Snowflake Exception] Invalid ArrowArrayStream pointer");
|
|
47
|
+
return nullptr;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
ArrowSchema schema{};
|
|
51
|
+
int rc = stream->get_schema(stream, &schema);
|
|
52
|
+
if (rc != 0) {
|
|
53
|
+
const char* msg = stream->get_last_error(stream);
|
|
54
|
+
std::string err = Logger::formatString(
|
|
55
|
+
"[Snowflake Exception] error getting schema: %s, error code: %d", msg ? msg : "unknown", rc);
|
|
56
|
+
logger->error(__FILE__, __func__, __LINE__, err.c_str());
|
|
57
|
+
PyErr_SetString(PyExc_Exception, err.c_str());
|
|
58
|
+
return nullptr;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return std::unique_ptr<CArrowStreamTableIterator>(
|
|
62
|
+
new CArrowStreamTableIterator(stream, &schema, context, number_to_decimal, force_microsecond_precision));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
CArrowStreamTableIterator::CArrowStreamTableIterator(ArrowArrayStream* stream, ArrowSchema* schema, PyObject* context, bool number_to_decimal, bool force_microsecond_precision)
|
|
66
|
+
: m_stream(stream, releaseStream),
|
|
67
|
+
m_columnCount(schema->n_children),
|
|
68
|
+
m_context(context) {
|
|
69
|
+
ArrowSchemaMove(schema, m_schema.get());
|
|
70
|
+
|
|
71
|
+
char* timezone = nullptr;
|
|
72
|
+
py::UniqueRef tz(PyObject_GetAttrString(m_context, "_timezone"));
|
|
73
|
+
PyArg_Parse(tz.get(), "z", &timezone);
|
|
74
|
+
|
|
75
|
+
m_converter = std::unique_ptr<ArrowTableConverter>(
|
|
76
|
+
new ArrowTableConverter(number_to_decimal, force_microsecond_precision, timezone ? std::string(timezone) : std::string()));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
// Export accessors
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
|
|
83
|
+
uintptr_t CArrowStreamTableIterator::getArrowArrayPtr() {
|
|
84
|
+
return reinterpret_cast<uintptr_t>(m_exportArray.get());
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
uintptr_t CArrowStreamTableIterator::getArrowSchemaPtr() {
|
|
88
|
+
return reinterpret_cast<uintptr_t>(m_exportSchema.get());
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
uintptr_t CArrowStreamTableIterator::getConvertedSchemaPtr() {
|
|
92
|
+
m_streamSchemaExport.reset();
|
|
93
|
+
int rc = ArrowSchemaDeepCopy(m_schema.get(), m_streamSchemaExport.get());
|
|
94
|
+
if (rc != NANOARROW_OK) {
|
|
95
|
+
std::string err = Logger::formatString(
|
|
96
|
+
"[Snowflake Exception] error deep-copying stream schema, error code: %d", rc);
|
|
97
|
+
logger->error(__FILE__, __func__, __LINE__, err.c_str());
|
|
98
|
+
PyErr_SetString(PyExc_RuntimeError, err.c_str());
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
ArrowError error;
|
|
103
|
+
|
|
104
|
+
nanoarrow::UniqueArray emptyArray;
|
|
105
|
+
rc = ArrowArrayInitFromSchema(emptyArray.get(), m_schema.get(), &error);
|
|
106
|
+
if (rc != NANOARROW_OK) {
|
|
107
|
+
std::string err = Logger::formatString(
|
|
108
|
+
"[Snowflake Exception] error initializing empty array for schema conversion: %s, error code: %d",
|
|
109
|
+
ArrowErrorMessage(&error), rc);
|
|
110
|
+
logger->error(__FILE__, __func__, __LINE__, err.c_str());
|
|
111
|
+
PyErr_SetString(PyExc_RuntimeError, err.c_str());
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
rc = ArrowArrayFinishBuildingDefault(emptyArray.get(), &error);
|
|
115
|
+
if (rc != NANOARROW_OK) {
|
|
116
|
+
std::string err = Logger::formatString(
|
|
117
|
+
"[Snowflake Exception] error finishing empty array: %s, error code: %d",
|
|
118
|
+
ArrowErrorMessage(&error), rc);
|
|
119
|
+
logger->error(__FILE__, __func__, __LINE__, err.c_str());
|
|
120
|
+
PyErr_SetString(PyExc_RuntimeError, err.c_str());
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
nanoarrow::UniqueArrayView emptyView;
|
|
125
|
+
rc = ArrowArrayViewInitFromSchema(emptyView.get(), m_schema.get(), &error);
|
|
126
|
+
if (rc != NANOARROW_OK) {
|
|
127
|
+
std::string err = Logger::formatString(
|
|
128
|
+
"[Snowflake Exception] error initializing empty array view: %s, error code: %d",
|
|
129
|
+
ArrowErrorMessage(&error), rc);
|
|
130
|
+
logger->error(__FILE__, __func__, __LINE__, err.c_str());
|
|
131
|
+
PyErr_SetString(PyExc_RuntimeError, err.c_str());
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
rc = ArrowArrayViewSetArray(emptyView.get(), emptyArray.get(), &error);
|
|
135
|
+
if (rc != NANOARROW_OK) {
|
|
136
|
+
std::string err = Logger::formatString(
|
|
137
|
+
"[Snowflake Exception] error setting empty array view: %s, error code: %d",
|
|
138
|
+
ArrowErrorMessage(&error), rc);
|
|
139
|
+
logger->error(__FILE__, __func__, __LINE__, err.c_str());
|
|
140
|
+
PyErr_SetString(PyExc_RuntimeError, err.c_str());
|
|
141
|
+
return 0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
runTranslatingCxxExceptions([this, &emptyView] {
|
|
145
|
+
for (int64_t col = 0; col < m_columnCount; col++) {
|
|
146
|
+
m_converter->convertIfNeeded(m_streamSchemaExport->children[col], emptyView->children[col]);
|
|
147
|
+
if (py::checkPyError()) return;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
if (py::checkPyError()) return 0;
|
|
151
|
+
|
|
152
|
+
return reinterpret_cast<uintptr_t>(m_streamSchemaExport.get());
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
// Stream loading
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
|
|
159
|
+
bool CArrowStreamTableIterator::loadNextBatch() {
|
|
160
|
+
if (m_streamExhausted) return false;
|
|
161
|
+
|
|
162
|
+
m_currentArray.reset();
|
|
163
|
+
m_currentArrayView.reset();
|
|
164
|
+
|
|
165
|
+
int returnCode;
|
|
166
|
+
ArrowArrayStream* stream = m_stream.get();
|
|
167
|
+
{
|
|
168
|
+
Py_BEGIN_ALLOW_THREADS
|
|
169
|
+
returnCode = stream->get_next(stream, m_currentArray.get());
|
|
170
|
+
Py_END_ALLOW_THREADS
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (returnCode != NANOARROW_OK) {
|
|
174
|
+
const char* msg = stream->get_last_error(stream);
|
|
175
|
+
std::string err = Logger::formatString(
|
|
176
|
+
"[Snowflake Exception] error getting next batch: %s, error code: %d", msg ? msg : "unknown", returnCode);
|
|
177
|
+
logger->error(__FILE__, __func__, __LINE__, err.c_str());
|
|
178
|
+
PyErr_SetString(PyExc_Exception, err.c_str());
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (m_currentArray->release == nullptr) {
|
|
183
|
+
m_streamExhausted = true;
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (m_currentArray->length == 0) {
|
|
188
|
+
return loadNextBatch();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
ArrowError error;
|
|
192
|
+
returnCode = ArrowArrayViewInitFromSchema(m_currentArrayView.get(), m_schema.get(), &error);
|
|
193
|
+
if (returnCode != NANOARROW_OK) {
|
|
194
|
+
std::string err = Logger::formatString(
|
|
195
|
+
"[Snowflake Exception] error initializing ArrowArrayView: %s, error code: %d",
|
|
196
|
+
ArrowErrorMessage(&error), returnCode);
|
|
197
|
+
logger->error(__FILE__, __func__, __LINE__, err.c_str());
|
|
198
|
+
PyErr_SetString(PyExc_Exception, err.c_str());
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
returnCode = ArrowArrayViewSetArray(m_currentArrayView.get(), m_currentArray.get(), &error);
|
|
203
|
+
if (returnCode != NANOARROW_OK) {
|
|
204
|
+
std::string err = Logger::formatString(
|
|
205
|
+
"[Snowflake Exception] error setting ArrowArrayView: %s, error code: %d",
|
|
206
|
+
ArrowErrorMessage(&error), returnCode);
|
|
207
|
+
logger->error(__FILE__, __func__, __LINE__, err.c_str());
|
|
208
|
+
PyErr_SetString(PyExc_Exception, err.c_str());
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
// convertBatch()
|
|
217
|
+
// ---------------------------------------------------------------------------
|
|
218
|
+
|
|
219
|
+
void CArrowStreamTableIterator::convertBatch() {
|
|
220
|
+
m_exportArray.reset();
|
|
221
|
+
m_exportSchema.reset();
|
|
222
|
+
|
|
223
|
+
int rc = ArrowSchemaDeepCopy(m_schema.get(), m_exportSchema.get());
|
|
224
|
+
SF_CHECK_ARROW_RC(rc, "[Snowflake Exception] error deep-copying schema, error code: %d", rc);
|
|
225
|
+
|
|
226
|
+
{
|
|
227
|
+
Py_BEGIN_ALLOW_THREADS
|
|
228
|
+
runTranslatingCxxExceptions([this] {
|
|
229
|
+
for (int64_t col = 0; col < m_columnCount; col++) {
|
|
230
|
+
m_converter->convertIfNeeded(m_exportSchema->children[col],
|
|
231
|
+
m_currentArrayView->children[col]);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
Py_END_ALLOW_THREADS
|
|
235
|
+
}
|
|
236
|
+
// GIL is held again - surface any error set via py::setPyError
|
|
237
|
+
if (py::checkPyError()) return;
|
|
238
|
+
|
|
239
|
+
ArrowArrayMove(m_currentArray.get(), m_exportArray.get());
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// ---------------------------------------------------------------------------
|
|
243
|
+
// next()
|
|
244
|
+
// ---------------------------------------------------------------------------
|
|
245
|
+
|
|
246
|
+
ReturnVal CArrowStreamTableIterator::next() {
|
|
247
|
+
if (!loadNextBatch()) {
|
|
248
|
+
if (py::checkPyError()) {
|
|
249
|
+
PyObject *type, *val, *traceback;
|
|
250
|
+
PyErr_Fetch(&type, &val, &traceback);
|
|
251
|
+
PyErr_Clear();
|
|
252
|
+
m_currentPyException.reset(val);
|
|
253
|
+
Py_XDECREF(type);
|
|
254
|
+
Py_XDECREF(traceback);
|
|
255
|
+
return ReturnVal(nullptr, m_currentPyException.get());
|
|
256
|
+
}
|
|
257
|
+
return ReturnVal(Py_None, nullptr);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
convertBatch();
|
|
261
|
+
|
|
262
|
+
if (py::checkPyError()) {
|
|
263
|
+
PyObject *type, *val, *traceback;
|
|
264
|
+
PyErr_Fetch(&type, &val, &traceback);
|
|
265
|
+
PyErr_Clear();
|
|
266
|
+
m_currentPyException.reset(val);
|
|
267
|
+
Py_XDECREF(type);
|
|
268
|
+
Py_XDECREF(traceback);
|
|
269
|
+
return ReturnVal(nullptr, m_currentPyException.get());
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return ReturnVal(Py_True, nullptr);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
} // namespace sf
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#ifndef PC_CARROWSTREAMTABLEITERATOR_HPP
|
|
2
|
+
#define PC_CARROWSTREAMTABLEITERATOR_HPP
|
|
3
|
+
|
|
4
|
+
#include <memory>
|
|
5
|
+
|
|
6
|
+
#include "ArrowTableConverter.hpp"
|
|
7
|
+
#include "CArrowIterator.hpp"
|
|
8
|
+
#include "Python/Common.hpp"
|
|
9
|
+
#include "logging.hpp"
|
|
10
|
+
#include "nanoarrow.h"
|
|
11
|
+
#include "nanoarrow.hpp"
|
|
12
|
+
|
|
13
|
+
namespace sf {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Stream-based Arrow iterator that reads batches from an ArrowArrayStream
|
|
17
|
+
* and exposes each batch as a (ArrowArray, ArrowSchema) pair suitable for
|
|
18
|
+
* import into PyArrow via RecordBatch._import_from_c().
|
|
19
|
+
*
|
|
20
|
+
* Snowflake-specific type conversions (e.g. scaled NUMBER -> float64,
|
|
21
|
+
* struct-encoded TIMESTAMP -> Arrow timestamp) are applied to every batch
|
|
22
|
+
* through the shared ArrowTableConverter.
|
|
23
|
+
*
|
|
24
|
+
* Lifecycle (driven from the Cython wrapper ArrowDummyIterator):
|
|
25
|
+
* 1. from_stream() – validate stream, read schema, construct instance
|
|
26
|
+
* 2. next() – load next batch, convert, expose via export slots
|
|
27
|
+
* 3. getArrowArrayPtr() / getArrowSchemaPtr()
|
|
28
|
+
* – caller passes these to _import_from_c() which
|
|
29
|
+
* consumes them (sets release to nullptr)
|
|
30
|
+
* 4. repeat 2-3 until next() signals exhaustion (Py_None)
|
|
31
|
+
*/
|
|
32
|
+
class CArrowStreamTableIterator {
|
|
33
|
+
public:
|
|
34
|
+
/**
|
|
35
|
+
* Factory method. Validates the stream pointer, reads the schema, and
|
|
36
|
+
* returns a ready-to-iterate instance.
|
|
37
|
+
*
|
|
38
|
+
* @param stream_ptr Pointer to ArrowArrayStream as int64 (FFI from Python)
|
|
39
|
+
* @param context Python ArrowConverterContext carrying session timezone
|
|
40
|
+
* @param number_to_decimal
|
|
41
|
+
* If true, scaled FIXED columns become Decimal128; otherwise float64
|
|
42
|
+
* @param force_microsecond_precision
|
|
43
|
+
* If true, all TIMESTAMP columns are forced to microsecond precision,
|
|
44
|
+
* ensuring consistent schema across batches whose data may span
|
|
45
|
+
* outside the nanosecond-representable range (1677-2262)
|
|
46
|
+
* @return Unique pointer to the iterator, or nullptr with a Python
|
|
47
|
+
* exception set on failure
|
|
48
|
+
*/
|
|
49
|
+
static std::unique_ptr<CArrowStreamTableIterator> from_stream(
|
|
50
|
+
int64_t stream_ptr, PyObject* context, bool number_to_decimal,
|
|
51
|
+
bool force_microsecond_precision);
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Advance to the next batch.
|
|
55
|
+
*
|
|
56
|
+
* @return ReturnVal with:
|
|
57
|
+
* - successObj = Py_True, exception = nullptr → batch ready; call
|
|
58
|
+
* getArrowArrayPtr() / getArrowSchemaPtr() to retrieve it
|
|
59
|
+
* - successObj = Py_None, exception = nullptr → stream exhausted
|
|
60
|
+
* - successObj = nullptr, exception != nullptr → error occurred
|
|
61
|
+
*/
|
|
62
|
+
ReturnVal next();
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Raw pointer (as uintptr_t) to the converted ArrowArray for the
|
|
66
|
+
* current batch. Valid only immediately after next() returns Py_True.
|
|
67
|
+
* Ownership transfers to the caller via _import_from_c().
|
|
68
|
+
*/
|
|
69
|
+
uintptr_t getArrowArrayPtr();
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Raw pointer (as uintptr_t) to the deep-copied ArrowSchema for the
|
|
73
|
+
* current batch. Same ownership semantics as getArrowArrayPtr().
|
|
74
|
+
*/
|
|
75
|
+
uintptr_t getArrowSchemaPtr();
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Raw pointer (as uintptr_t) to the stream schema after applying
|
|
79
|
+
* Snowflake type conversions (e.g. struct → timestamp, int → float64).
|
|
80
|
+
* Unlike getArrowSchemaPtr(), this is always valid—even when no batch
|
|
81
|
+
* has been loaded—making it safe to call for empty result sets
|
|
82
|
+
* (e.g. to build an empty PyArrow table with the correct column types).
|
|
83
|
+
*
|
|
84
|
+
* Internally synthesises a zero-row batch and runs it through
|
|
85
|
+
* ArrowTableConverter so the schema matches what non-empty results
|
|
86
|
+
* would produce.
|
|
87
|
+
*
|
|
88
|
+
* Ownership transfers to the caller via _import_from_c().
|
|
89
|
+
*/
|
|
90
|
+
uintptr_t getConvertedSchemaPtr();
|
|
91
|
+
|
|
92
|
+
private:
|
|
93
|
+
CArrowStreamTableIterator(ArrowArrayStream* stream, ArrowSchema* schema,
|
|
94
|
+
PyObject* context, bool number_to_decimal,
|
|
95
|
+
bool force_microsecond_precision);
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Pull the next non-empty batch from the stream into m_currentArray.
|
|
99
|
+
* Releases the GIL during stream->get_next() so concurrent chunk
|
|
100
|
+
* downloads (e.g. from S3) are not blocked by the Python interpreter.
|
|
101
|
+
* Also initialises m_currentArrayView for the conversion step.
|
|
102
|
+
*
|
|
103
|
+
* @return true if a batch was loaded; false if exhausted or error
|
|
104
|
+
*/
|
|
105
|
+
bool loadNextBatch();
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Apply Snowflake type conversions to the current batch via
|
|
109
|
+
* m_converter, then move the result into the export slots
|
|
110
|
+
* (m_exportArray / m_exportSchema).
|
|
111
|
+
* Releases the GIL during the per-column conversion loop, since it is
|
|
112
|
+
* pure nanoarrow buffer work; any Python exception raised inside the
|
|
113
|
+
* loop is signalled through py::setPyError(), which re-acquires the GIL
|
|
114
|
+
* only for the duration of the call. Errors are checked once after the
|
|
115
|
+
* loop when the GIL is held again.
|
|
116
|
+
* Sets a Python exception on failure (check py::checkPyError()).
|
|
117
|
+
*/
|
|
118
|
+
void convertBatch();
|
|
119
|
+
|
|
120
|
+
/** Owned handle to the ArrowArrayStream; released on destruction. */
|
|
121
|
+
std::unique_ptr<ArrowArrayStream, void (*)(ArrowArrayStream*)> m_stream;
|
|
122
|
+
|
|
123
|
+
/** Stream schema, read once at construction; immutable across batches. */
|
|
124
|
+
nanoarrow::UniqueSchema m_schema;
|
|
125
|
+
|
|
126
|
+
/** Raw batch from the most recent stream->get_next() call. */
|
|
127
|
+
nanoarrow::UniqueArray m_currentArray;
|
|
128
|
+
|
|
129
|
+
/** View over m_currentArray; rebuilt each loadNextBatch() for the
|
|
130
|
+
* converter to read column data through. */
|
|
131
|
+
nanoarrow::UniqueArrayView m_currentArrayView;
|
|
132
|
+
|
|
133
|
+
/** Converted batch ready for PyArrow import. Populated by
|
|
134
|
+
* convertBatch(); consumed by _import_from_c() via getArrowArrayPtr(). */
|
|
135
|
+
nanoarrow::UniqueArray m_exportArray;
|
|
136
|
+
|
|
137
|
+
/** Deep-copied and possibly rewritten schema for the current batch.
|
|
138
|
+
* Each batch gets its own copy because conversion may alter child
|
|
139
|
+
* schemas (e.g. struct → timestamp). Consumed via getArrowSchemaPtr(). */
|
|
140
|
+
nanoarrow::UniqueSchema m_exportSchema;
|
|
141
|
+
|
|
142
|
+
/** Deep copy of m_schema used by getStreamSchemaPtr(). Separate from
|
|
143
|
+
* m_exportSchema so it can be produced independently of batch iteration. */
|
|
144
|
+
nanoarrow::UniqueSchema m_streamSchemaExport;
|
|
145
|
+
|
|
146
|
+
/** Set to true once stream->get_next() returns an empty release sentinel. */
|
|
147
|
+
bool m_streamExhausted = false;
|
|
148
|
+
|
|
149
|
+
/** Number of top-level columns, cached from schema.n_children. */
|
|
150
|
+
int64_t m_columnCount = 0;
|
|
151
|
+
|
|
152
|
+
/** Python ArrowConverterContext; borrowed reference kept alive by the
|
|
153
|
+
* Cython wrapper which stores it as `self.arrow_context`. */
|
|
154
|
+
PyObject* m_context;
|
|
155
|
+
|
|
156
|
+
/** Applies Snowflake-specific type conversions per column. */
|
|
157
|
+
std::unique_ptr<ArrowTableConverter> m_converter;
|
|
158
|
+
|
|
159
|
+
/** Holds the most recent Python exception so the pointer remains valid
|
|
160
|
+
* until the next call into the iterator. */
|
|
161
|
+
py::UniqueRef m_currentPyException;
|
|
162
|
+
|
|
163
|
+
static Logger* logger;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
} // namespace sf
|
|
167
|
+
|
|
168
|
+
#endif // PC_CARROWSTREAMTABLEITERATOR_HPP
|