private void checkIfUpdatable()

in src/main/java/org/mariadb/jdbc/internal/com/read/resultset/UpdatableResultSet.java [126:276]


  private void checkIfUpdatable(Results results) throws SQLException {

    database = null;
    table = null;
    canBeUpdate = true;
    canBeInserted = true;
    canBeRefresh = false;

    // check that resultSet concern one table and database exactly
    for (ColumnDefinition columnDefinition : columnsInformation) {

      if (columnDefinition.getDatabase() == null || columnDefinition.getDatabase().isEmpty()) {

        cannotUpdateInsertRow(
            "The result-set contains fields without without any database information");
        return;

      } else {

        if (database != null && !database.equals(columnDefinition.getDatabase())) {
          cannotUpdateInsertRow("The result-set contains more than one database");
          return;
        }

        database = columnDefinition.getDatabase();
      }

      if (columnDefinition.getOriginalTable() == null
          || columnDefinition.getOriginalTable().isEmpty()) {

        cannotUpdateInsertRow(
            "The result-set contains fields without without any table information");
        return;

      } else {

        if (table != null && !table.equals(columnDefinition.getOriginalTable())) {
          cannotUpdateInsertRow("The result-set contains fields on different tables");
          return;
        }

        table = columnDefinition.getOriginalTable();
      }
    }

    if (database == null) {
      cannotUpdateInsertRow("The result-set does not contain any table information");
      return;
    }

    if (table == null) {
      cannotUpdateInsertRow("The result-set does not contain any table information");
      return;
    }

    // read table metadata
    if (canBeUpdate) {
      if (results.getStatement() != null && results.getStatement().getConnection() != null) {

        connection = results.getStatement().getConnection();
        Statement stmt =
            connection.createStatement(
                ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
        ResultSet rs = stmt.executeQuery("SHOW COLUMNS FROM `" + database + "`.`" + table + "`");

        UpdatableColumnDefinition[] updatableColumns =
            new UpdatableColumnDefinition[columnInformationLength];

        boolean primaryFound = false;
        while (rs.next()) {
          // read SHOW COLUMNS informations
          String fieldName = rs.getString("Field");
          boolean canBeNull = "YES".equals(rs.getString("Null"));
          boolean hasDefault = rs.getString("Default") != null;
          String extra = rs.getString("Extra");
          boolean generated = extra != null && !extra.isEmpty();
          boolean autoIncrement = extra != null && "auto_increment".equals(extra);
          boolean primary = "PRI".equals(rs.getString("Key"));

          boolean found = false;

          // update column information with SHOW COLUMNS additional informations
          for (int index = 0; index < columnInformationLength; index++) {
            ColumnDefinition columnDefinition = columnsInformation[index];
            if (fieldName.equals(columnDefinition.getOriginalName())) {
              updatableColumns[index] =
                  new UpdatableColumnDefinition(
                      columnDefinition, canBeNull, hasDefault, generated, primary, autoIncrement);
              found = true;
            }
          }

          if (primary) {
            primaryFound = true;
          }

          if (!found) {
            if (primary) {
              // without primary key in resultSet, update/delete cannot be done, since query need
              // to be updated/deleted for this unknown identifier
              //
              // For insert, key is not mandatory in resultSet if automatically generated, but data
              // cannot be added to rows in adequate format
              cannotUpdateInsertRow("Primary key field `" + fieldName + "` is not in result-set");
              return;
            }

            // check that missing field can be null / have default values / are generated
            // automatically
            if (!canBeNull && !hasDefault && !generated) {
              cannotInsertRow(
                  "Field `"
                      + fieldName
                      + "` is not present in query returning "
                      + "fields and cannot be null");
            }
          }
        }

        if (!primaryFound) {
          // if there is no primary key (UNIQUE key are considered as primary by SHOW COLUMNS),
          // rows cannot be updated.
          cannotUpdateInsertRow("Table `" + database + "`.`" + table + "` has no primary key");
          return;
        } else {
          canBeRefresh = true;
        }

        boolean ensureAllColumnHaveMeta = true;
        for (int index = 0; index < columnInformationLength; index++) {
          if (updatableColumns[index] == null) {
            // abnormal error : some field in META are not listed in SHOW COLUMNS
            cannotUpdateInsertRow(
                "Metadata information not available for table `"
                    + database
                    + "`.`"
                    + table
                    + "`, field `"
                    + columnsInformation[index].getOriginalName()
                    + "`");
            ensureAllColumnHaveMeta = false;
          }
        }
        if (ensureAllColumnHaveMeta) {
          columnsInformation = updatableColumns;
        }
      } else {
        throw new SQLException("abnormal error : connection is null");
      }
    }
  }