/**
   * @param excludeIndirectColumns
   * @param excludeColumns
   * @throws SQLException
   */
  private void initColumns(Pattern excludeIndirectColumns, Pattern excludeColumns)
      throws SQLException {
    ResultSet rs = null;

    synchronized (Table.class) {
      try {
        rs = db.getMetaData().getColumns(null, getSchema(), getName(), "%");

        while (rs.next()) addColumn(rs, excludeIndirectColumns, excludeColumns);
      } catch (SQLException exc) {
        class ColumnInitializationFailure extends SQLException {
          private static final long serialVersionUID = 1L;

          public ColumnInitializationFailure(SQLException failure) {
            super(
                "Failed to collect column details for "
                    + (isView() ? "view" : "table")
                    + " '"
                    + getName()
                    + "' in schema '"
                    + getSchema()
                    + "'");
            initCause(failure);
          }
        }

        throw new ColumnInitializationFailure(exc);
      } finally {
        if (rs != null) rs.close();
      }
    }

    if (!isView() && !isRemote()) initColumnAutoUpdate(false);
  }
  /**
   * @param forceQuotes
   * @throws SQLException
   */
  private void initColumnAutoUpdate(boolean forceQuotes) throws SQLException {
    ResultSet rs = null;
    PreparedStatement stmt = null;

    // we've got to get a result set with all the columns in it
    // so we can ask if the columns are auto updated
    // Ugh!!!  Should have been in DatabaseMetaData instead!!!
    StringBuilder sql = new StringBuilder("select * from ");
    if (getSchema() != null) {
      sql.append(getSchema());
      sql.append('.');
    }

    if (forceQuotes) {
      String quote = db.getMetaData().getIdentifierQuoteString().trim();
      sql.append(quote + getName() + quote);
    } else sql.append(db.getQuotedIdentifier(getName()));

    sql.append(" where 0 = 1");

    try {
      stmt = db.getMetaData().getConnection().prepareStatement(sql.toString());
      rs = stmt.executeQuery();

      ResultSetMetaData rsMeta = rs.getMetaData();
      for (int i = rsMeta.getColumnCount(); i > 0; --i) {
        TableColumn column = getColumn(rsMeta.getColumnName(i));
        column.setIsAutoUpdated(rsMeta.isAutoIncrement(i));
      }
    } catch (SQLException exc) {
      if (forceQuotes) {
        // don't completely choke just because we couldn't do this....
        logger.warning("Failed to determine auto increment status: " + exc);
        logger.warning("SQL: " + sql.toString());
      } else {
        initColumnAutoUpdate(true);
      }
    } finally {
      if (rs != null) rs.close();
      if (stmt != null) stmt.close();
    }
  }