public void checkUpdatability()

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();
        }
    }