void PythonOutputDataSet::RetrieveColumnFromDataFrame()

in language-extensions/python/src/PythonDataSet.cpp [939:1011]


void PythonOutputDataSet::RetrieveColumnFromDataFrame(
	string       columnName,
	SQLULEN      &columnSize,
	SQLSMALLINT  &decimalDigits,
	SQLSMALLINT  &nullable)
{
	LOG("PythonOutputDataSet::RetrieveColumnFromDataFrame");
	SQLType *columnData = nullptr;
	SQLINTEGER *nullMap = nullptr;
	NullType valueForNull = *(static_cast<const NullType*>(
		PythonExtensionUtils::sm_DataTypeToNullMap.at(DataType)));

	if (m_rowsNumber > 0)
	{
		columnData = new SQLType[m_rowsNumber];
		nullMap = new SQLINTEGER[m_rowsNumber];
	}

	columnSize = sizeof(SQLType);
	decimalDigits = 0;
	nullable = SQL_NO_NULLS;

	// Get the column of values, as the type we expect to extract
	//
	np::ndarray column = 
		ExtractArrayFromDataFrame(columnName).astype(np::dtype::get_builtin<SQLType>());

	for (SQLULEN row = 0; row < m_rowsNumber; ++row)
	{
		bool isNull = true;
		bp::object pyObj = column[row];

		// Make sure the object is not pointing at Python None,
		// or else it will crash on extract
		//
		if (!pyObj.is_none())
		{
			// Extract the data value from the iterator
			//
			bp::extract<SQLType> extractedData(pyObj);

			// Check to make sure the extracted data exists and is of the correct type
			//
			if (extractedData.check())
			{
				SQLType data = extractedData;

				// If the data is not NAN or INF, we set it to the extracted data.
				//
				if (!(is_same_v<NullType, float> && (isnan(data) || isinf(data))))
				{
					columnData[row] = data;
					nullMap[row] = sizeof(SQLType);
					isNull = false;
				}
			}
		}

		// If data is None, NAN, INF, or a bad type, we set it to NULL_DATA.
		//
		if(isNull)
		{
			// If there are any nulls, nullable is set to SQL_NULLABLE for the whole column
			//
			nullMap[row] = SQL_NULL_DATA;
			nullable = SQL_NULLABLE;
			columnData[row] = valueForNull;
		}
	}

	m_data.push_back(static_cast<SQLPOINTER>(columnData));
	m_columnNullMap.push_back(nullMap);
}