Skip to content

Commit

Permalink
#798 Add backing index names to getImportedKeys, getExportedKeys and …
Browse files Browse the repository at this point in the history
…getCrossReference of DatabaseMetaData
  • Loading branch information
mrotteveel committed Apr 3, 2024
1 parent 8fc9dc1 commit 1295753
Show file tree
Hide file tree
Showing 11 changed files with 562 additions and 19 deletions.
3 changes: 3 additions & 0 deletions src/docs/asciidoc/release_notes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,9 @@ This feature was backported to Jaybird 5.0.5.
Disabling extended metadata may improve performance of these `ResultSetMetaData` methods in exchange for estimated precision information of `NUMERIC` and `DECIMAL` columns, and not being able to determine the auto-increment status of `INTEGER`, `BIGINT` or `SMALLINT` columns.
+
This feature was backported to Jaybird 5.0.5.
* Improvement: Added column `JB_PK_INDEX_NAME` and `JB_FK_INDEX_NAME` to the result set of to `getImportedKeys`, `getExportedKeys` and `getCrossReference` of `DatabaseMetaData` with the names of the index backing the primary key and foreign key (https://github.com/FirebirdSQL/jaybird/issues/798[#798])
+
Given this is a non-standard extension, it is advisable to retrieve these columns by name, not by position.
[#potentially-breaking-changes]
=== Potentially breaking changes
Expand Down
30 changes: 30 additions & 0 deletions src/main/org/firebirdsql/jdbc/FBDatabaseMetaData.java
Original file line number Diff line number Diff line change
Expand Up @@ -1409,16 +1409,46 @@ public ResultSet getPrimaryKeys(String catalog, String schema, String table) thr
return GetPrimaryKeys.create(getDbMetadataMediator()).getPrimaryKeys(table);
}

/**
* {@inheritDoc}
* <p>
* Jaybird defines these additional columns:
* <ol start="15">
* <li><b>JB_FK_INDEX_NAME</b> String =&gt; Index backing the foreign key</li>
* <li><b>JB_PK_INDEX_NAME</b> String =&gt; Index backing the primary key</li>
* </ol>
* </p>
*/
@Override
public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException {
return GetImportedKeys.create(getDbMetadataMediator()).getImportedKeys(table);
}

/**
* {@inheritDoc}
* <p>
* Jaybird defines these additional columns:
* <ol start="15">
* <li><b>JB_FK_INDEX_NAME</b> String =&gt; Index backing the foreign key</li>
* <li><b>JB_PK_INDEX_NAME</b> String =&gt; Index backing the primary key</li>
* </ol>
* </p>
*/
@Override
public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException {
return GetExportedKeys.create(getDbMetadataMediator()).getExportedKeys(table);
}

/**
* {@inheritDoc}
* <p>
* Jaybird defines these additional columns:
* <ol start="15">
* <li><b>JB_FK_INDEX_NAME</b> String =&gt; Index backing the foreign key</li>
* <li><b>JB_PK_INDEX_NAME</b> String =&gt; Index backing the primary key</li>
* </ol>
* </p>
*/
@Override
public ResultSet getCrossReference(
String primaryCatalog, String primarySchema, String primaryTable,
Expand Down
10 changes: 7 additions & 3 deletions src/main/org/firebirdsql/jdbc/metadata/AbstractKeysMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ abstract class AbstractKeysMethod extends AbstractMetadataMethod {

private static final String COLUMNINFO = "COLUMNINFO";

private static final RowDescriptor ROW_DESCRIPTOR = DbMetadataMediator.newRowDescriptorBuilder(14)
private static final RowDescriptor ROW_DESCRIPTOR = DbMetadataMediator.newRowDescriptorBuilder(16)
.at(0).simple(SQL_VARYING | 1, OBJECT_NAME_LENGTH, "PKTABLE_CAT", COLUMNINFO).addField()
.at(1).simple(SQL_VARYING | 1, OBJECT_NAME_LENGTH, "PKTABLE_SCHEM", COLUMNINFO).addField()
.at(2).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "PKTABLE_NAME", COLUMNINFO).addField()
Expand All @@ -55,6 +55,8 @@ abstract class AbstractKeysMethod extends AbstractMetadataMethod {
.at(11).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "FK_NAME", COLUMNINFO).addField()
.at(12).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "PK_NAME", COLUMNINFO).addField()
.at(13).simple(SQL_SHORT, 0, "DEFERRABILITY", COLUMNINFO).addField()
.at(14).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "JB_FK_INDEX_NAME", COLUMNINFO).addField()
.at(15).simple(SQL_VARYING, OBJECT_NAME_LENGTH, "JB_PK_INDEX_NAME", COLUMNINFO).addField()
.toRowDescriptor();

AbstractKeysMethod(DbMetadataMediator mediator) {
Expand All @@ -74,6 +76,8 @@ final RowValue createMetadataRow(ResultSet rs, RowValueBuilder valueBuilder) thr
.at(11).setString(rs.getString("FK_NAME"))
.at(12).setString(rs.getString("PK_NAME"))
.at(13).setShort(DatabaseMetaData.importedKeyNotDeferrable)
.at(14).setString(rs.getString("JB_FK_INDEX_NAME"))
.at(15).setString(rs.getString("JB_PK_INDEX_NAME"))
.toRowValue(true);
}

Expand All @@ -86,8 +90,8 @@ final RowValue createMetadataRow(ResultSet rs, RowValueBuilder valueBuilder) thr
*/
private static Integer mapAction(String firebirdActionName) {
return switch (firebirdActionName) {
// NOTE: Firebird has no "RESTRICT", however this mapping (to importedKeyNoAction) was also present in
// the previous implementation, so preserving it just in case.
// NOTE: Firebird has no ON UPDATE/DELETE option RESTRICT, but absence of a ON UPDATE/DELETE clause stores
// "RESTRICT", which behaves the same as NO ACTION.
case "RESTRICT", "NO ACTION" -> DatabaseMetaData.importedKeyNoAction;
case "CASCADE" -> DatabaseMetaData.importedKeyCascade;
case "SET NULL" -> DatabaseMetaData.importedKeySetNull;
Expand Down
8 changes: 6 additions & 2 deletions src/main/org/firebirdsql/jdbc/metadata/GetCrossReference.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import java.sql.ResultSet;
import java.sql.SQLException;

import static org.firebirdsql.jaybird.util.StringUtils.isNullOrEmpty;

/**
* Provides the implementation for {@link java.sql.DatabaseMetaData#getCrossReference(String, String, String, String, String, String)}.
*
Expand All @@ -42,7 +44,9 @@ public final class GetCrossReference extends AbstractKeysMethod {
RC.RDB$UPDATE_RULE as UPDATE_RULE,
RC.RDB$DELETE_RULE as DELETE_RULE,
PK.RDB$CONSTRAINT_NAME as PK_NAME,
FK.RDB$CONSTRAINT_NAME as FK_NAME
FK.RDB$CONSTRAINT_NAME as FK_NAME,
PK.RDB$INDEX_NAME as JB_PK_INDEX_NAME,
FK.RDB$INDEX_NAME as JB_FK_INDEX_NAME
from RDB$RELATION_CONSTRAINTS PK
inner join RDB$REF_CONSTRAINTS RC
on PK.RDB$CONSTRAINT_NAME = RC.RDB$CONST_NAME_UQ
Expand All @@ -61,7 +65,7 @@ private GetCrossReference(DbMetadataMediator mediator) {
}

public ResultSet getCrossReference(String primaryTable, String foreignTable) throws SQLException {
if (primaryTable == null || primaryTable.isEmpty() || foreignTable == null || foreignTable.isEmpty()) {
if (isNullOrEmpty(primaryTable) || isNullOrEmpty(foreignTable)) {
return createEmpty();
}

Expand Down
8 changes: 6 additions & 2 deletions src/main/org/firebirdsql/jdbc/metadata/GetExportedKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import java.sql.ResultSet;
import java.sql.SQLException;

import static org.firebirdsql.jaybird.util.StringUtils.isNullOrEmpty;

/**
* Provides the implementation for {@link java.sql.DatabaseMetaData#getExportedKeys(String, String, String)}.
*
Expand All @@ -42,7 +44,9 @@ public final class GetExportedKeys extends AbstractKeysMethod {
RC.RDB$UPDATE_RULE as UPDATE_RULE,
RC.RDB$DELETE_RULE as DELETE_RULE,
PK.RDB$CONSTRAINT_NAME as PK_NAME,
FK.RDB$CONSTRAINT_NAME as FK_NAME
FK.RDB$CONSTRAINT_NAME as FK_NAME,
PK.RDB$INDEX_NAME as JB_PK_INDEX_NAME,
FK.RDB$INDEX_NAME as JB_FK_INDEX_NAME
from RDB$RELATION_CONSTRAINTS PK
inner join RDB$REF_CONSTRAINTS RC
on PK.RDB$CONSTRAINT_NAME = RC.RDB$CONST_NAME_UQ
Expand All @@ -61,7 +65,7 @@ private GetExportedKeys(DbMetadataMediator mediator) {
}

public ResultSet getExportedKeys(String table) throws SQLException {
if (table == null || "".equals(table)) {
if (isNullOrEmpty(table)) {
return createEmpty();
}

Expand Down
8 changes: 6 additions & 2 deletions src/main/org/firebirdsql/jdbc/metadata/GetImportedKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import java.sql.ResultSet;
import java.sql.SQLException;

import static org.firebirdsql.jaybird.util.StringUtils.isNullOrEmpty;

/**
* Provides the implementation for {@link java.sql.DatabaseMetaData#getImportedKeys(String, String, String)}.
*
Expand All @@ -42,7 +44,9 @@ public final class GetImportedKeys extends AbstractKeysMethod {
RC.RDB$UPDATE_RULE as UPDATE_RULE,
RC.RDB$DELETE_RULE as DELETE_RULE,
PK.RDB$CONSTRAINT_NAME as PK_NAME,
FK.RDB$CONSTRAINT_NAME as FK_NAME
FK.RDB$CONSTRAINT_NAME as FK_NAME,
PK.RDB$INDEX_NAME as JB_PK_INDEX_NAME,
FK.RDB$INDEX_NAME as JB_FK_INDEX_NAME
from RDB$RELATION_CONSTRAINTS PK
inner join RDB$REF_CONSTRAINTS RC
on PK.RDB$CONSTRAINT_NAME = RC.RDB$CONST_NAME_UQ
Expand All @@ -61,7 +65,7 @@ private GetImportedKeys(DbMetadataMediator mediator) {
}

public ResultSet getImportedKeys(String table) throws SQLException {
if (table == null || "".equals(table)) {
if (isNullOrEmpty(table)) {
return createEmpty();
}

Expand Down
Loading

0 comments on commit 1295753

Please sign in to comment.