@@ -366,6 +366,51 @@ void checkSQLColAttributesNumeric(SQLHSTMT stmt, const std::wstring& wsql,
366366 EXPECT_EQ (numVal, expectedAttrNumeric);
367367}
368368
369+ TYPED_TEST (FlightSQLODBCTestBase, SQLColumnsTestInputData) {
370+ this ->connect ();
371+
372+ SQLWCHAR catalogName[] = L" " ;
373+ SQLWCHAR schemaName[] = L" " ;
374+ SQLWCHAR tableName[] = L" " ;
375+ SQLWCHAR columnName[] = L" " ;
376+
377+ // All values populated
378+ SQLRETURN ret = SQLColumns (this ->stmt , catalogName, sizeof (catalogName), schemaName,
379+ sizeof (schemaName), tableName, sizeof (tableName), columnName,
380+ sizeof (columnName));
381+
382+ EXPECT_EQ (ret, SQL_SUCCESS);
383+
384+ ValidateFetch (this ->stmt , SQL_NO_DATA);
385+
386+ // Sizes are nulls
387+ ret =
388+ SQLColumns (this ->stmt , catalogName, 0 , schemaName, 0 , tableName, 0 , columnName, 0 );
389+
390+ EXPECT_EQ (ret, SQL_SUCCESS);
391+
392+ ValidateFetch (this ->stmt , SQL_NO_DATA);
393+
394+ // Values are nulls
395+ ret = SQLColumns (this ->stmt , 0 , sizeof (catalogName), 0 , sizeof (schemaName), 0 ,
396+ sizeof (tableName), 0 , sizeof (columnName));
397+
398+ EXPECT_EQ (ret, SQL_SUCCESS);
399+
400+ ValidateFetch (this ->stmt , SQL_SUCCESS);
401+ // Close statement cursor to avoid leaving in an invalid state
402+ SQLFreeStmt (this ->stmt , SQL_CLOSE);
403+
404+ // All values and sizes are nulls
405+ ret = SQLColumns (this ->stmt , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 );
406+
407+ EXPECT_EQ (ret, SQL_SUCCESS);
408+
409+ ValidateFetch (this ->stmt , SQL_SUCCESS);
410+
411+ this ->disconnect ();
412+ }
413+
369414TEST_F (FlightSQLODBCMockTestBase, TestSQLColumnsAllColumns) {
370415 // Check table pattern and column pattern returns all columns
371416 this ->connect ();
@@ -1245,6 +1290,125 @@ TEST_F(FlightSQLODBCMockTestBase, TestSQLColumnsInvalidTablePattern) {
12451290 this ->disconnect ();
12461291}
12471292
1293+ TYPED_TEST (FlightSQLODBCTestBase, SQLColAttributeTestInputData) {
1294+ this ->connect ();
1295+
1296+ std::wstring wsql = L" SELECT 1 as col1;" ;
1297+ std::vector<SQLWCHAR> sql0 (wsql.begin (), wsql.end ());
1298+
1299+ SQLRETURN ret =
1300+ SQLExecDirect (this ->stmt , &sql0[0 ], static_cast <SQLINTEGER>(sql0.size ()));
1301+ EXPECT_EQ (ret, SQL_SUCCESS);
1302+
1303+ ret = SQLFetch (this ->stmt );
1304+ EXPECT_EQ (ret, SQL_SUCCESS);
1305+
1306+ SQLUSMALLINT idx = 1 ;
1307+ std::vector<SQLWCHAR> characterAttr (ODBC_BUFFER_SIZE);
1308+ SQLSMALLINT characterAttrLen = 0 ;
1309+ SQLLEN numericAttr = 0 ;
1310+
1311+ // All character values populated
1312+ ret = SQLColAttribute (this ->stmt , idx, SQL_DESC_NAME, &characterAttr[0 ],
1313+ (SQLSMALLINT)characterAttr.size (), &characterAttrLen, 0 );
1314+ EXPECT_EQ (ret, SQL_SUCCESS);
1315+
1316+ // All numeric values populated
1317+ ret = SQLColAttribute (this ->stmt , idx, SQL_DESC_COUNT, 0 , 0 , 0 , &numericAttr);
1318+
1319+ EXPECT_EQ (ret, SQL_SUCCESS);
1320+
1321+ // Pass null values, driver should not throw error
1322+ ret = SQLColAttribute (this ->stmt , idx, SQL_COLUMN_TABLE_NAME, 0 , 0 , 0 , 0 );
1323+ EXPECT_EQ (ret, SQL_SUCCESS);
1324+
1325+ ret = SQLColAttribute (this ->stmt , idx, SQL_DESC_COUNT, 0 , 0 , 0 , 0 );
1326+ EXPECT_EQ (ret, SQL_SUCCESS);
1327+
1328+ this ->disconnect ();
1329+ }
1330+
1331+ TYPED_TEST (FlightSQLODBCTestBase, SQLColAttributeGetCharacterLen) {
1332+ this ->connect ();
1333+
1334+ std::wstring wsql = L" SELECT 1 as col1;" ;
1335+ std::vector<SQLWCHAR> sql0 (wsql.begin (), wsql.end ());
1336+
1337+ SQLRETURN ret =
1338+ SQLExecDirect (this ->stmt , &sql0[0 ], static_cast <SQLINTEGER>(sql0.size ()));
1339+ EXPECT_EQ (ret, SQL_SUCCESS);
1340+
1341+ ret = SQLFetch (this ->stmt );
1342+ EXPECT_EQ (ret, SQL_SUCCESS);
1343+
1344+ SQLSMALLINT characterAttrLen = 0 ;
1345+
1346+ // Check length of character attribute
1347+ ret = SQLColAttribute (this ->stmt , 1 , SQL_DESC_BASE_COLUMN_NAME, 0 , 0 , &characterAttrLen,
1348+ 0 );
1349+ EXPECT_EQ (ret, SQL_SUCCESS);
1350+
1351+ EXPECT_EQ (characterAttrLen, 4 * ODBC::GetSqlWCharSize ());
1352+
1353+ this ->disconnect ();
1354+ }
1355+
1356+ TYPED_TEST (FlightSQLODBCTestBase, SQLColAttributeInvalidFieldId) {
1357+ this ->connect ();
1358+
1359+ std::wstring wsql = L" SELECT 1 as col1;" ;
1360+ std::vector<SQLWCHAR> sql0 (wsql.begin (), wsql.end ());
1361+
1362+ SQLRETURN ret =
1363+ SQLExecDirect (this ->stmt , &sql0[0 ], static_cast <SQLINTEGER>(sql0.size ()));
1364+ EXPECT_EQ (ret, SQL_SUCCESS);
1365+
1366+ ret = SQLFetch (this ->stmt );
1367+ EXPECT_EQ (ret, SQL_SUCCESS);
1368+
1369+ SQLUSMALLINT invalidFieldId = -100 ;
1370+ SQLUSMALLINT idx = 1 ;
1371+ std::vector<SQLWCHAR> characterAttr (ODBC_BUFFER_SIZE);
1372+ SQLSMALLINT characterAttrLen = 0 ;
1373+ SQLLEN numericAttr = 0 ;
1374+
1375+ ret = SQLColAttribute (this ->stmt , idx, invalidFieldId, &characterAttr[0 ],
1376+ (SQLSMALLINT)characterAttr.size (), &characterAttrLen, 0 );
1377+ EXPECT_EQ (ret, SQL_ERROR);
1378+ // Verify invalid descriptor field identifier error state is returned
1379+ VerifyOdbcErrorState (SQL_HANDLE_STMT, this ->stmt , error_state_HY091);
1380+
1381+ this ->disconnect ();
1382+ }
1383+
1384+ TYPED_TEST (FlightSQLODBCTestBase, SQLColAttributeInvalidColId) {
1385+ this ->connect ();
1386+
1387+ std::wstring wsql = L" SELECT 1 as col1;" ;
1388+ std::vector<SQLWCHAR> sql0 (wsql.begin (), wsql.end ());
1389+
1390+ SQLRETURN ret =
1391+ SQLExecDirect (this ->stmt , &sql0[0 ], static_cast <SQLINTEGER>(sql0.size ()));
1392+ EXPECT_EQ (ret, SQL_SUCCESS);
1393+
1394+ ret = SQLFetch (this ->stmt );
1395+ EXPECT_EQ (ret, SQL_SUCCESS);
1396+
1397+ SQLUSMALLINT invalidColId = 2 ;
1398+ std::vector<SQLWCHAR> characterAttr (ODBC_BUFFER_SIZE);
1399+ SQLSMALLINT characterAttrLen = 0 ;
1400+ SQLLEN numericAttr = 0 ;
1401+
1402+ ret = SQLColAttribute (this ->stmt , invalidColId, SQL_DESC_BASE_COLUMN_NAME,
1403+ &characterAttr[0 ], (SQLSMALLINT)characterAttr.size (),
1404+ &characterAttrLen, 0 );
1405+ EXPECT_EQ (ret, SQL_ERROR);
1406+ // Verify invalid descriptor index error state is returned
1407+ VerifyOdbcErrorState (SQL_HANDLE_STMT, this ->stmt , error_state_07009);
1408+
1409+ this ->disconnect ();
1410+ }
1411+
12481412TEST_F (FlightSQLODBCMockTestBase, TestSQLColAttributeAllTypes) {
12491413 this ->connect ();
12501414 this ->CreateTableAllDataType ();
0 commit comments