Skip to content

Commit 763f32f

Browse files
committed
pipeline fix
1 parent 74c6296 commit 763f32f

File tree

2 files changed

+44
-40
lines changed

2 files changed

+44
-40
lines changed

mssql_python/cursor.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -465,15 +465,6 @@ def _map_sql_type(self, param, parameters_list, i, min_val=None, max_val=None):
465465
0,
466466
False
467467
)
468-
469-
if isinstance(param, uuid.UUID):
470-
return (
471-
ddbc_sql_const.SQL_GUID.value,
472-
ddbc_sql_const.SQL_C_GUID.value,
473-
16,
474-
0,
475-
False,
476-
)
477468

478469
if isinstance(param, datetime.datetime):
479470
if param.tzinfo is not None:
@@ -1689,7 +1680,6 @@ def executemany(self, operation: str, seq_of_parameters: list) -> None:
16891680
sample_value = sample_row[col_index]
16901681
else:
16911682
sample_value = self._select_best_sample_value(column)
1692-
16931683
dummy_row = list(sample_row)
16941684
paraminfo = self._create_parameter_types_list(
16951685
sample_value, param_info, dummy_row, col_index, min_val=min_val, max_val=max_val

mssql_python/pybind/ddbc_bindings.cpp

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1967,36 +1967,41 @@ SQLRETURN BindParameterArray(SQLHANDLE hStmt,
19671967
SQLGUID* guidArray = AllocateParamBufferArray<SQLGUID>(tempBuffers, paramSetSize);
19681968
strLenOrIndArray = AllocateParamBufferArray<SQLLEN>(tempBuffers, paramSetSize);
19691969

1970-
py::object uuid_type = py::module_::import("uuid").attr("UUID");
1971-
1970+
py::module_ uuid_mod = py::module_::import("uuid");
1971+
py::object uuid_class = uuid_mod.attr("UUID");
19721972
for (size_t i = 0; i < paramSetSize; ++i) {
1973-
if (columnValues[i].is_none()) {
1973+
const py::handle& element = columnValues[i];
1974+
std::array<unsigned char, 16> uuid_bytes;
1975+
if (element.is_none()) {
19741976
std::memset(&guidArray[i], 0, sizeof(SQLGUID));
19751977
strLenOrIndArray[i] = SQL_NULL_DATA;
1976-
} else if (py::isinstance(columnValues[i], uuid_type)) {
1977-
py::bytes uuid_bytes = columnValues[i].attr("bytes");
1978-
const unsigned char* uuid_data = reinterpret_cast<const unsigned char*>(PyBytes_AS_STRING(uuid_bytes.ptr()));
1979-
1980-
if (PyBytes_GET_SIZE(uuid_bytes.ptr()) != 16) {
1978+
continue;
1979+
}
1980+
else if (py::isinstance<py::bytes>(element)) {
1981+
py::bytes b = element.cast<py::bytes>();
1982+
if (PyBytes_GET_SIZE(b.ptr()) != 16) {
19811983
ThrowStdException("UUID binary data must be exactly 16 bytes long.");
19821984
}
1983-
1984-
guidArray[i].Data1 = (static_cast<uint32_t>(uuid_data[3]) << 24) |
1985-
(static_cast<uint32_t>(uuid_data[2]) << 16) |
1986-
(static_cast<uint32_t>(uuid_data[1]) << 8) |
1987-
(static_cast<uint32_t>(uuid_data[0]));
1988-
guidArray[i].Data2 = (static_cast<uint16_t>(uuid_data[5]) << 8) |
1989-
(static_cast<uint16_t>(uuid_data[4]));
1990-
guidArray[i].Data3 = (static_cast<uint16_t>(uuid_data[7]) << 8) |
1991-
(static_cast<uint16_t>(uuid_data[6]));
1992-
std::memcpy(guidArray[i].Data4, &uuid_data[8], 8);
1993-
1994-
strLenOrIndArray[i] = sizeof(SQLGUID);
1995-
} else {
1985+
std::memcpy(uuid_bytes.data(), PyBytes_AS_STRING(b.ptr()), 16);
1986+
}
1987+
else if (py::isinstance(element, uuid_class)) {
1988+
py::bytes b = element.attr("bytes_le").cast<py::bytes>();
1989+
std::memcpy(uuid_bytes.data(), PyBytes_AS_STRING(b.ptr()), 16);
1990+
}
1991+
else {
19961992
ThrowStdException(MakeParamMismatchErrorStr(info.paramCType, paramIndex));
19971993
}
1994+
guidArray[i].Data1 = (static_cast<uint32_t>(uuid_bytes[3]) << 24) |
1995+
(static_cast<uint32_t>(uuid_bytes[2]) << 16) |
1996+
(static_cast<uint32_t>(uuid_bytes[1]) << 8) |
1997+
(static_cast<uint32_t>(uuid_bytes[0]));
1998+
guidArray[i].Data2 = (static_cast<uint16_t>(uuid_bytes[5]) << 8) |
1999+
(static_cast<uint16_t>(uuid_bytes[4]));
2000+
guidArray[i].Data3 = (static_cast<uint16_t>(uuid_bytes[7]) << 8) |
2001+
(static_cast<uint16_t>(uuid_bytes[6]));
2002+
std::memcpy(guidArray[i].Data4, uuid_bytes.data() + 8, 8);
2003+
strLenOrIndArray[i] = sizeof(SQLGUID);
19982004
}
1999-
20002005
dataPtr = guidArray;
20012006
bufferLength = sizeof(SQLGUID);
20022007
break;
@@ -3133,15 +3138,24 @@ SQLRETURN FetchBatchData(SQLHSTMT hStmt, ColumnBuffers& buffers, py::list& colum
31333138
break;
31343139
}
31353140
case SQL_GUID: {
3141+
SQLLEN indicator = buffers.indicators[col - 1][i];
3142+
if (indicator == SQL_NULL_DATA) {
3143+
row.append(py::none());
3144+
break;
3145+
}
31363146
SQLGUID* guidValue = &buffers.guidBuffers[col - 1][i];
3137-
// We already have the raw bytes from SQL Server in the SQLGUID struct.
3138-
// We do not need to perform any additional reordering here, as the C++
3139-
// SQLGUID struct is already laid out in the non-standard SQL Server byte order.
3140-
std::vector<char> guid_bytes(16);
3141-
std::memcpy(guid_bytes.data(), guidValue, sizeof(SQLGUID));
3142-
3143-
// Convert the raw C++ byte vector to a Python bytes object
3144-
py::bytes py_guid_bytes(guid_bytes.data(), guid_bytes.size());
3147+
uint8_t reordered[16];
3148+
reordered[0] = ((char*)&guidValue->Data1)[3];
3149+
reordered[1] = ((char*)&guidValue->Data1)[2];
3150+
reordered[2] = ((char*)&guidValue->Data1)[1];
3151+
reordered[3] = ((char*)&guidValue->Data1)[0];
3152+
reordered[4] = ((char*)&guidValue->Data2)[1];
3153+
reordered[5] = ((char*)&guidValue->Data2)[0];
3154+
reordered[6] = ((char*)&guidValue->Data3)[1];
3155+
reordered[7] = ((char*)&guidValue->Data3)[0];
3156+
std::memcpy(reordered + 8, guidValue->Data4, 8);
3157+
3158+
py::bytes py_guid_bytes(reinterpret_cast<char*>(reordered), 16);
31453159
py::dict kwargs;
31463160
kwargs["bytes"] = py_guid_bytes;
31473161
py::object uuid_obj = py::module_::import("uuid").attr("UUID")(**kwargs);

0 commit comments

Comments
 (0)