in src/main/user-impl/java/com/mysql/cj/jdbc/result/UpdatableResultSet.java [221:400]
public void checkUpdatability() throws SQLException {
try {
if (getMetadata() == null) {
// we've been created to be populated with cached metadata, and we don't have the metadata yet, we'll be called again by
// Connection.initializeResultsMetadataFromCache() when the metadata has been made available
return;
}
String singleTableName = null;
String dbName = null;
int primaryKeyCount = 0;
Field[] fields = getMetadata().getFields();
// We can only do this if we know that there is a currently selected database, or if we're talking to a > 4.1 version of MySQL server (as it returns
// database names in field info)
if (this.db == null || this.db.length() == 0) {
this.db = fields[0].getDatabaseName();
if (this.db == null || this.db.length() == 0) {
throw SQLError.createSQLException(Messages.getString("UpdatableResultSet.43"), MysqlErrorNumbers.SQLSTATE_CONNJ_ILLEGAL_ARGUMENT,
getExceptionInterceptor());
}
}
if (fields.length > 0) {
singleTableName = fields[0].getOriginalTableName();
dbName = fields[0].getDatabaseName();
if (singleTableName == null) {
singleTableName = fields[0].getTableName();
dbName = this.db;
}
if (singleTableName == null) {
this.isUpdatable = false;
this.notUpdatableReason = Messages.getString("NotUpdatableReason.3");
return;
}
if (fields[0].isPrimaryKey()) {
primaryKeyCount++;
}
//
// References only one table?
//
for (int i = 1; i < fields.length; i++) {
String otherTableName = fields[i].getOriginalTableName();
String otherDbName = fields[i].getDatabaseName();
if (otherTableName == null) {
otherTableName = fields[i].getTableName();
otherDbName = this.db;
}
if (otherTableName == null) {
this.isUpdatable = false;
this.notUpdatableReason = Messages.getString("NotUpdatableReason.3");
return;
}
if (!otherTableName.equals(singleTableName)) {
this.isUpdatable = false;
this.notUpdatableReason = Messages.getString("NotUpdatableReason.0");
return;
}
// Can't reference more than one database
if (dbName == null || !dbName.equals(otherDbName)) {
this.isUpdatable = false;
this.notUpdatableReason = Messages.getString("NotUpdatableReason.1");
return;
}
if (fields[i].isPrimaryKey()) {
primaryKeyCount++;
}
}
} else {
this.isUpdatable = false;
this.notUpdatableReason = Messages.getString("NotUpdatableReason.3");
return;
}
if (getSession().getPropertySet().getBooleanProperty(PropertyKey.strictUpdates).getValue()) {
java.sql.DatabaseMetaData dbmd = getConnection().getMetaData();
java.sql.ResultSet rs = null;
HashMap<String, String> primaryKeyNames = new HashMap<>();
try {
rs = this.session.getPropertySet().<DatabaseTerm>getEnumProperty(PropertyKey.databaseTerm).getValue() == DatabaseTerm.SCHEMA
? dbmd.getPrimaryKeys(null, dbName, singleTableName)
: dbmd.getPrimaryKeys(dbName, null, singleTableName);
while (rs.next()) {
String keyName = rs.getString(4);
keyName = keyName.toUpperCase();
primaryKeyNames.put(keyName, keyName);
}
} finally {
if (rs != null) {
try {
rs.close();
} catch (Exception ex) {
AssertionFailedException.shouldNotHappen(ex);
}
rs = null;
}
}
int existingPrimaryKeysCount = primaryKeyNames.size();
if (existingPrimaryKeysCount == 0) {
this.isUpdatable = false;
this.notUpdatableReason = Messages.getString("NotUpdatableReason.5");
return; // we can't update tables w/o keys
}
//
// Contains all primary keys?
//
for (int i = 0; i < fields.length; i++) {
if (fields[i].isPrimaryKey()) {
String columnNameUC = fields[i].getName().toUpperCase();
if (primaryKeyNames.remove(columnNameUC) == null) {
// try original name
String originalName = fields[i].getOriginalName();
if (originalName != null) {
if (primaryKeyNames.remove(originalName.toUpperCase()) == null) {
// we don't know about this key, so give up :(
this.isUpdatable = false;
this.notUpdatableReason = Messages.getString("NotUpdatableReason.6", new Object[] { originalName });
return;
}
}
}
}
}
this.isUpdatable = primaryKeyNames.isEmpty();
if (!this.isUpdatable) {
this.notUpdatableReason = existingPrimaryKeysCount > 1 ? Messages.getString("NotUpdatableReason.7")
: Messages.getString("NotUpdatableReason.4");
return;
}
}
//
// Must have at least one primary key
//
if (primaryKeyCount == 0) {
this.isUpdatable = false;
this.notUpdatableReason = Messages.getString("NotUpdatableReason.4");
return;
}
this.isUpdatable = true;
this.notUpdatableReason = null;
return;
} catch (SQLException sqlEx) {
this.isUpdatable = false;
this.notUpdatableReason = sqlEx.getMessage();
}
}