@@ -964,4 +964,125 @@ void testListSchemasWithMultipleCatalogSupportDisabled() throws SQLException {
964964 assertEquals (METADATA_STATEMENT_ID , actualResult .getStatementId ());
965965 assertEquals (2 , ((DatabricksResultSetMetaData ) actualResult .getMetaData ()).getTotalRows ());
966966 }
967+
968+ /**
969+ * Test that listTables handles SQLException with null SQL state without NPE. This tests the fix
970+ * for the issue where e.getSQLState() could return null, causing NullPointerException when
971+ * calling .equals() on it.
972+ */
973+ @ Test
974+ void testListTables_handlesNullSqlStateWithoutNPE () throws Exception {
975+ // Create exception with null SQL state (simulating server response without structured SQL
976+ // state)
977+ DatabricksSQLException exception =
978+ new DatabricksSQLException (
979+ "[SCHEMA_NOT_FOUND] The schema cannot be found. SQLSTATE: 42704" ,
980+ (String ) null ); // null SQL state
981+
982+ when (session .getComputeResource ()).thenReturn (WAREHOUSE_COMPUTE );
983+ IDatabricksConnectionContext mockContext = mock (IDatabricksConnectionContext .class );
984+ when (mockContext .getEnableMultipleCatalogSupport ()).thenReturn (true );
985+ when (mockClient .getConnectionContext ()).thenReturn (mockContext );
986+
987+ DatabricksMetadataSdkClient metadataClient = new DatabricksMetadataSdkClient (mockClient );
988+ when (mockClient .executeStatement (
989+ "SHOW TABLES IN CATALOG " ,
990+ WAREHOUSE_COMPUTE ,
991+ new HashMap <>(),
992+ StatementType .METADATA ,
993+ session ,
994+ null ))
995+ .thenThrow (exception );
996+
997+ // This should throw the original exception, not NPE
998+ assertThrows (
999+ DatabricksSQLException .class ,
1000+ () -> metadataClient .listTables (session , "" , null , null , null ));
1001+ }
1002+
1003+ @ Test
1004+ void testListSchemas_handlesNullSqlStateWithoutNPE () throws Exception {
1005+ DatabricksSQLException exception =
1006+ new DatabricksSQLException (
1007+ "syntax error at or near \" ALL CATALOGS\" " , (String ) null ); // null SQL state
1008+
1009+ when (session .getComputeResource ()).thenReturn (WAREHOUSE_COMPUTE );
1010+ IDatabricksConnectionContext mockContext = mock (IDatabricksConnectionContext .class );
1011+ when (mockContext .getEnableMultipleCatalogSupport ()).thenReturn (true );
1012+ when (mockClient .getConnectionContext ()).thenReturn (mockContext );
1013+
1014+ DatabricksMetadataSdkClient metadataClient = new DatabricksMetadataSdkClient (mockClient );
1015+ when (mockClient .executeStatement (
1016+ "SHOW SCHEMAS IN ALL CATALOGS" ,
1017+ WAREHOUSE_COMPUTE ,
1018+ new HashMap <>(),
1019+ StatementType .METADATA ,
1020+ session ,
1021+ null ))
1022+ .thenThrow (exception );
1023+
1024+ // This should throw the original exception, not NPE
1025+ assertThrows (
1026+ DatabricksSQLException .class , () -> metadataClient .listSchemas (session , null , null ));
1027+ }
1028+
1029+ @ Test
1030+ void testListImportedKeys_handlesNullSqlStateWithoutNPE () throws Exception {
1031+ DatabricksSQLException exception =
1032+ new DatabricksSQLException (
1033+ "syntax error at or near \" foreign\" " , (String ) null ); // null SQL state
1034+
1035+ when (session .getComputeResource ()).thenReturn (WAREHOUSE_COMPUTE );
1036+ IDatabricksConnectionContext mockContext = mock (IDatabricksConnectionContext .class );
1037+ when (mockContext .getEnableMultipleCatalogSupport ()).thenReturn (true );
1038+ when (mockClient .getConnectionContext ()).thenReturn (mockContext );
1039+
1040+ DatabricksMetadataSdkClient metadataClient = new DatabricksMetadataSdkClient (mockClient );
1041+ when (mockClient .executeStatement (
1042+ "SHOW FOREIGN KEYS IN CATALOG catalog1 IN SCHEMA testSchema IN TABLE testTable" ,
1043+ WAREHOUSE_COMPUTE ,
1044+ new HashMap <>(),
1045+ StatementType .METADATA ,
1046+ session ,
1047+ null ))
1048+ .thenThrow (exception );
1049+
1050+ // This should throw the original exception, not NPE
1051+ assertThrows (
1052+ DatabricksSQLException .class ,
1053+ () -> metadataClient .listImportedKeys (session , TEST_CATALOG , TEST_SCHEMA , TEST_TABLE ));
1054+ }
1055+
1056+ @ Test
1057+ void testListCrossReferences_handlesNullSqlStateWithoutNPE () throws Exception {
1058+ DatabricksSQLException exception =
1059+ new DatabricksSQLException (
1060+ "syntax error at or near \" foreign\" " , (String ) null ); // null SQL state
1061+
1062+ when (session .getComputeResource ()).thenReturn (WAREHOUSE_COMPUTE );
1063+ when (mockClient .getConnectionContext ()).thenReturn (mock (IDatabricksConnectionContext .class ));
1064+
1065+ DatabricksMetadataSdkClient metadataClient = new DatabricksMetadataSdkClient (mockClient );
1066+ when (mockClient .executeStatement (
1067+ "SHOW FOREIGN KEYS IN CATALOG catalog1 IN SCHEMA testSchema IN TABLE testTable" ,
1068+ WAREHOUSE_COMPUTE ,
1069+ new HashMap <>(),
1070+ StatementType .METADATA ,
1071+ session ,
1072+ null ))
1073+ .thenThrow (exception );
1074+
1075+ // This should throw the original exception, not NPE
1076+ assertThrows (
1077+ DatabricksSQLException .class ,
1078+ () ->
1079+ metadataClient .listCrossReferences (
1080+ session ,
1081+ "parentCatalog" ,
1082+ "parentSchema" ,
1083+ "parentTable" ,
1084+ TEST_CATALOG ,
1085+ TEST_SCHEMA ,
1086+ TEST_TABLE ));
1087+ }
9671088}
0 commit comments