@@ -950,21 +950,158 @@ public ResultSet getPrimaryKeys(String catalog, String schema, String table) thr
950950 return ps .executeQuery ();
951951 }
952952
953+ private void appendAndQual (StringBuilder sb , boolean needed ) {
954+ if (needed ) {
955+ sb .append (" AND " );
956+ } else {
957+ sb .append (" " );
958+ }
959+ }
960+
953961 @ Override
954962 public ResultSet getImportedKeys (String catalog , String schema , String table ) throws SQLException {
955- throw new SQLFeatureNotSupportedException ( "getImportedKeys" );
963+ return getCrossReference ( null , null , null , catalog , schema , table );
956964 }
957965
958966 @ Override
959967 public ResultSet getExportedKeys (String catalog , String schema , String table ) throws SQLException {
960- throw new SQLFeatureNotSupportedException ( "getExportedKeys" );
968+ return getCrossReference ( catalog , schema , table , null , null , null );
961969 }
962970
963971 @ Override
964972 public ResultSet getCrossReference (String parentCatalog , String parentSchema , String parentTable ,
965973 String foreignCatalog , String foreignSchema , String foreignTable )
966974 throws SQLException {
967- throw new SQLFeatureNotSupportedException ("getCrossReference" );
975+ StringBuilder sb = new StringBuilder (QUERY_SB_DEFAULT_CAPACITY );
976+ sb .append ("SELECT" ).append (lineSeparator ());
977+ sb .append (" pk_tc.table_catalog AS PKTABLE_CAT" ).append (TRAILING_COMMA ).append (lineSeparator ());
978+ sb .append (" pk_tc.table_schema AS PKTABLE_SCHEM" ).append (TRAILING_COMMA ).append (lineSeparator ());
979+ sb .append (" pk_tc.table_name AS PKTABLE_NAME" ).append (TRAILING_COMMA ).append (lineSeparator ());
980+ sb .append (" pk_kcu.column_name AS PKCOLUMN_NAME" ).append (TRAILING_COMMA ).append (lineSeparator ());
981+ sb .append (" fk_tc.table_catalog AS FKTABLE_CAT" ).append (TRAILING_COMMA ).append (lineSeparator ());
982+ sb .append (" fk_tc.table_schema AS FKTABLE_SCHEM" ).append (TRAILING_COMMA ).append (lineSeparator ());
983+ sb .append (" fk_tc.table_name AS FKTABLE_NAME" ).append (TRAILING_COMMA ).append (lineSeparator ());
984+ sb .append (" fk_kcu.column_name AS FKCOLUMN_NAME" ).append (TRAILING_COMMA ).append (lineSeparator ());
985+ sb .append (" fk_kcu.ordinal_position AS KEY_SEQ" ).append (TRAILING_COMMA ).append (lineSeparator ());
986+ sb .append (" CASE rc.update_rule " ).append (lineSeparator ());
987+ sb .append (" WHEN 'CASCADE' THEN 0" ).append (lineSeparator ());
988+ sb .append (" WHEN 'RESTRICT' THEN 1" ).append (lineSeparator ());
989+ sb .append (" WHEN 'SET NULL' THEN 2" ).append (lineSeparator ());
990+ sb .append (" WHEN 'SET DEFAULT' THEN 4" ).append (lineSeparator ());
991+ sb .append (" ELSE 3" ).append (lineSeparator ());
992+ sb .append (" END AS UPDATE_RULE," ).append (lineSeparator ());
993+ sb .append (" CASE rc.delete_rule" ).append (lineSeparator ());
994+ sb .append (" WHEN 'CASCADE' THEN 0" ).append (lineSeparator ());
995+ sb .append (" WHEN 'RESTRICT' THEN 1" ).append (lineSeparator ());
996+ sb .append (" WHEN 'SET NULL' THEN 2" ).append (lineSeparator ());
997+ sb .append (" WHEN 'SET DEFAULT' THEN 4" ).append (lineSeparator ());
998+ sb .append (" ELSE 3" ).append (lineSeparator ());
999+ sb .append (" END AS DELETE_RULE," ).append (lineSeparator ());
1000+ sb .append (" rc.constraint_name AS FK_NAME," ).append (lineSeparator ());
1001+ sb .append (" rc.unique_constraint_name AS PK_NAME," ).append (lineSeparator ());
1002+ sb .append (" CASE " ).append (lineSeparator ());
1003+ sb .append (" WHEN fk_tc.is_deferrable = 'YES' AND fk_tc.initially_deferred = 'YES' THEN 5" )
1004+ .append (lineSeparator ());
1005+ sb .append (" WHEN fk_tc.is_deferrable = 'YES' AND fk_tc.initially_deferred = 'NO' THEN 6" )
1006+ .append (lineSeparator ());
1007+ sb .append (" ELSE 7" ).append (lineSeparator ());
1008+ sb .append (" END AS DEFERRABILITY" ).append (lineSeparator ());
1009+ sb .append ("FROM information_schema.referential_constraints rc" ).append (lineSeparator ());
1010+ sb .append (" JOIN information_schema.table_constraints fk_tc" ).append (lineSeparator ());
1011+ sb .append (" ON fk_tc.constraint_catalog = rc.constraint_catalog" ).append (lineSeparator ());
1012+ sb .append (" AND fk_tc.constraint_schema = rc.constraint_schema" ).append (lineSeparator ());
1013+ sb .append (" AND fk_tc.constraint_name = rc.constraint_name" ).append (lineSeparator ());
1014+ sb .append (" JOIN information_schema.key_column_usage fk_kcu" ).append (lineSeparator ());
1015+ sb .append (" ON fk_kcu.constraint_catalog = rc.constraint_catalog" ).append (lineSeparator ());
1016+ sb .append (" AND fk_kcu.constraint_schema = rc.constraint_schema" ).append (lineSeparator ());
1017+ sb .append (" AND fk_kcu.constraint_name = rc.constraint_name" ).append (lineSeparator ());
1018+ sb .append (" JOIN information_schema.table_constraints pk_tc" ).append (lineSeparator ());
1019+ sb .append (" ON pk_tc.constraint_catalog = rc.unique_constraint_catalog" ).append (lineSeparator ());
1020+ sb .append (" AND pk_tc.constraint_schema = rc.unique_constraint_schema" ).append (lineSeparator ());
1021+ sb .append (" AND pk_tc.constraint_name = rc.unique_constraint_name" ).append (lineSeparator ());
1022+ sb .append (" JOIN information_schema.key_column_usage pk_kcu" ).append (lineSeparator ());
1023+ sb .append (" ON pk_kcu.constraint_catalog = pk_tc.constraint_catalog" ).append (lineSeparator ());
1024+ sb .append (" AND pk_kcu.constraint_schema = pk_tc.constraint_schema" ).append (lineSeparator ());
1025+ sb .append (" AND pk_kcu.constraint_name = pk_tc.constraint_name" ).append (lineSeparator ());
1026+ sb .append (" AND pk_kcu.ordinal_position = fk_kcu.ordinal_position" ).append (lineSeparator ());
1027+ sb .append (" -- AND pk_kcu.ordinal_position = fk_kcu.position_in_unique_constraint" ).append (lineSeparator ());
1028+ if (null != parentCatalog || null != parentSchema || null != parentTable || null != foreignCatalog ||
1029+ null != foreignSchema || null != foreignTable ) {
1030+ sb .append ("WHERE" );
1031+ }
1032+ boolean andQualNeeded = false ;
1033+ if (null != parentCatalog ) {
1034+ appendAndQual (sb , andQualNeeded );
1035+ sb .append ("pk_tc.table_catalog = ?" ).append (lineSeparator ());
1036+ andQualNeeded = true ;
1037+ }
1038+ if (null != parentSchema ) {
1039+ appendAndQual (sb , andQualNeeded );
1040+ sb .append ("pk_tc.table_schema = ?" ).append (lineSeparator ());
1041+ andQualNeeded = true ;
1042+ }
1043+ if (null != parentTable ) {
1044+ appendAndQual (sb , andQualNeeded );
1045+ sb .append ("pk_tc.table_name = ?" ).append (lineSeparator ());
1046+ andQualNeeded = true ;
1047+ }
1048+ if (null != foreignCatalog ) {
1049+ appendAndQual (sb , andQualNeeded );
1050+ sb .append ("fk_tc.table_catalog = ?" ).append (lineSeparator ());
1051+ andQualNeeded = true ;
1052+ }
1053+ if (null != foreignSchema ) {
1054+ appendAndQual (sb , andQualNeeded );
1055+ sb .append ("fk_tc.table_schema = ?" ).append (lineSeparator ());
1056+ andQualNeeded = true ;
1057+ }
1058+ if (null != foreignTable ) {
1059+ appendAndQual (sb , andQualNeeded );
1060+ sb .append ("fk_tc.table_name = ?" ).append (lineSeparator ());
1061+ andQualNeeded = true ;
1062+ }
1063+ sb .append ("ORDER BY " ).append (lineSeparator ());
1064+ if (null != foreignTable ) { // imported keys
1065+ sb .append (" PKTABLE_CAT" ).append (TRAILING_COMMA ).append (lineSeparator ());
1066+ sb .append (" PKTABLE_SCHEM" ).append (TRAILING_COMMA ).append (lineSeparator ());
1067+ sb .append (" PKTABLE_NAME" ).append (TRAILING_COMMA ).append (lineSeparator ());
1068+ sb .append (" KEY_SEQ" ).append (TRAILING_COMMA ).append (lineSeparator ());
1069+ sb .append (" FKTABLE_CAT" ).append (TRAILING_COMMA ).append (lineSeparator ());
1070+ sb .append (" FKTABLE_SCHEM" ).append (TRAILING_COMMA ).append (lineSeparator ());
1071+ sb .append (" FKTABLE_NAME" );
1072+ } else { // exported keys or cross-reference
1073+ sb .append (" FKTABLE_CAT" ).append (TRAILING_COMMA ).append (lineSeparator ());
1074+ sb .append (" FKTABLE_SCHEM" ).append (TRAILING_COMMA ).append (lineSeparator ());
1075+ sb .append (" FKTABLE_NAME" ).append (TRAILING_COMMA ).append (lineSeparator ());
1076+ sb .append (" KEY_SEQ" ).append (TRAILING_COMMA ).append (lineSeparator ());
1077+ sb .append (" PKTABLE_CAT" ).append (TRAILING_COMMA ).append (lineSeparator ());
1078+ sb .append (" PKTABLE_SCHEM" ).append (TRAILING_COMMA ).append (lineSeparator ());
1079+ sb .append (" PKTABLE_NAME" );
1080+ }
1081+
1082+ PreparedStatement ps = conn .prepareStatement (sb .toString ());
1083+ int paramIdx = 1 ;
1084+ if (null != parentCatalog ) {
1085+ ps .setString (paramIdx ++, parentCatalog );
1086+ }
1087+ if (null != parentSchema ) {
1088+ ps .setString (paramIdx ++, parentSchema );
1089+ }
1090+ if (null != parentTable ) {
1091+ ps .setString (paramIdx ++, parentTable );
1092+ }
1093+ if (null != foreignCatalog ) {
1094+ ps .setString (paramIdx ++, foreignCatalog );
1095+ }
1096+ if (null != foreignSchema ) {
1097+ ps .setString (paramIdx ++, foreignSchema );
1098+ }
1099+ if (null != foreignTable ) {
1100+ ps .setString (paramIdx ++, foreignTable );
1101+ }
1102+
1103+ ps .closeOnCompletion ();
1104+ return ps .executeQuery ();
9681105 }
9691106
9701107 @ Override
0 commit comments