Exemplo n.º 1
0
 /**
  * Undo all operations back to the log position of the given savepoint.
  *
  * @param name the savepoint name
  */
 public void rollbackToSavepoint(String name) {
   checkCommitRollback();
   if (savepoints == null) {
     throw DbException.get(ErrorCode.SAVEPOINT_IS_INVALID_1, name);
   }
   Integer savepointIndex = savepoints.get(name);
   if (savepointIndex == null) {
     throw DbException.get(ErrorCode.SAVEPOINT_IS_INVALID_1, name);
   }
   int i = savepointIndex.intValue();
   rollbackTo(i, false);
 }
Exemplo n.º 2
0
 /**
  * Automatically re-connect if necessary and if configured to do so.
  *
  * @param count the retry count index
  * @return true if reconnected
  */
 private boolean autoReconnect(int count) {
   if (!isClosed()) {
     return false;
   }
   if (!autoReconnect) {
     return false;
   }
   if (!cluster && !autoCommit) {
     return false;
   }
   if (count > SysProperties.MAX_RECONNECT) {
     return false;
   }
   lastReconnect++;
   while (true) {
     try {
       embedded = connectEmbeddedOrServer(false);
       break;
     } catch (DbException e) {
       if (e.getErrorCode() != ErrorCode.DATABASE_IS_IN_EXCLUSIVE_MODE) {
         throw e;
       }
       // exclusive mode: re-try endlessly
       try {
         Thread.sleep(500);
       } catch (Exception e2) {
         // ignore
       }
     }
   }
   if (embedded == this) {
     // connected to a server somewhere else
     embedded = null;
   } else {
     // opened an embedded connection now -
     // must connect to this database in server mode
     // unfortunately
     connectEmbeddedOrServer(true);
   }
   recreateSessionState();
   if (eventListener != null) {
     eventListener.setProgress(
         DatabaseEventListener.STATE_RECONNECTED,
         databaseName,
         count,
         SysProperties.MAX_RECONNECT);
   }
   return true;
 }
Exemplo n.º 3
0
  public synchronized void checkTransfers() {
    if (transferList != null) {
      for (int i = 0; i < transferList.size(); i++) {
        Transfer transfer = transferList.get(i);

        try {
          if (transfer.available() > 0)
            throw DbException.throwInternalError(
                "the transfer available bytes was " + transfer.available());
        } catch (IOException e) {
          throw DbException.convert(e);
        }
      }
    }
  }
Exemplo n.º 4
0
 /**
  * Get the local host address as a string. For performance, the result is cached for one second.
  *
  * @return the local host address
  */
 public static synchronized String getLocalAddress() {
   long now = System.currentTimeMillis();
   if (cachedLocalAddress != null) {
     if (cachedLocalAddressTime + CACHE_MILLIS > now) {
       return cachedLocalAddress;
     }
   }
   InetAddress bind = null;
   boolean useLocalhost = false;
   try {
     bind = getBindAddress();
     if (bind == null) {
       useLocalhost = true;
     }
   } catch (UnknownHostException e) {
     // ignore
   }
   if (useLocalhost) {
     try {
       bind = InetAddress.getLocalHost();
     } catch (UnknownHostException e) {
       throw DbException.convert(e);
     }
   }
   String address = bind == null ? "localhost" : getHostAddress(bind);
   if (address.equals("127.0.0.1")) {
     address = "localhost";
   }
   cachedLocalAddress = address;
   cachedLocalAddressTime = now;
   return address;
 }
Exemplo n.º 5
0
 private static ServerSocket createServerSocketTry(int port, boolean ssl) {
   try {
     InetAddress bindAddress = getBindAddress();
     if (ssl) {
       return CipherFactory.createServerSocket(port, bindAddress);
     }
     if (bindAddress == null) {
       return new ServerSocket(port);
     }
     return new ServerSocket(port, 0, bindAddress);
   } catch (BindException be) {
     throw DbException.get(ErrorCode.EXCEPTION_OPENING_PORT_2, be, "" + port, be.toString());
   } catch (IOException e) {
     throw DbException.convertIOException(e, "port: " + port + " ssl: " + ssl);
   }
 }
Exemplo n.º 6
0
 /**
  * Add an undo log entry to this session.
  *
  * @param table the table
  * @param operation the operation type (see {@link UndoLogRecord})
  * @param row the row
  */
 public void log(Table table, short operation, Row row) {
   if (undoLogEnabled) {
     UndoLogRecord log = new UndoLogRecord(table, operation, row);
     // called _after_ the row was inserted successfully into the table,
     // otherwise rollback will try to rollback a not-inserted row
     if (SysProperties.CHECK) {
       int lockMode = database.getLockMode();
       if (lockMode != Constants.LOCK_MODE_OFF && !database.isMultiVersion()) {
         String tableType = log.getTable().getTableType();
         if (locks.indexOf(log.getTable()) < 0
             && !Table.TABLE_LINK.equals(tableType)
             && !Table.EXTERNAL_TABLE_ENGINE.equals(tableType)) {
           DbException.throwInternalError();
         }
       }
     }
     undoLog.add(log);
   } else {
     if (database.isMultiVersion()) {
       // see also UndoLogRecord.commit
       ArrayList<Index> indexes = table.getIndexes();
       for (int i = 0, size = indexes.size(); i < size; i++) {
         Index index = indexes.get(i);
         index.commit(operation, row);
       }
       row.commit();
     }
   }
 }
Exemplo n.º 7
0
 /**
  * Commit or roll back the given transaction.
  *
  * @param transactionName the name of the transaction
  * @param commit true for commit, false for rollback
  */
 public void setPreparedTransaction(String transactionName, boolean commit) {
   if (currentTransactionName != null && currentTransactionName.equals(transactionName)) {
     if (commit) {
       commit(false);
     } else {
       rollback();
     }
   } else {
     ArrayList<InDoubtTransaction> list = database.getInDoubtTransactions();
     int state = commit ? InDoubtTransaction.COMMIT : InDoubtTransaction.ROLLBACK;
     boolean found = false;
     if (list != null) {
       for (InDoubtTransaction p : list) {
         if (p.getTransaction().equals(transactionName)) {
           p.setState(state);
           found = true;
           break;
         }
       }
     }
     if (!found) {
       throw DbException.get(ErrorCode.TRANSACTION_NOT_FOUND_1, transactionName);
     }
   }
 }
Exemplo n.º 8
0
 public synchronized Command prepareCommand(String sql) {
   if (closed) {
     throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "session closed");
   }
   Command command;
   if (queryCacheSize > 0) {
     if (queryCache == null) {
       queryCache = SmallLRUCache.newInstance(queryCacheSize);
     } else {
       command = queryCache.get(sql);
       if (command != null && command.canReuse()) {
         command.reuse();
         return command;
       }
     }
   }
   Parser parser = createParser();
   command = parser.prepareCommand(sql);
   if (queryCache != null) {
     if (command.isCacheable()) {
       queryCache.put(sql, command);
     }
   }
   return command;
 }
Exemplo n.º 9
0
 /**
  * Add a lock for the given table. The object is unlocked on commit or rollback.
  *
  * @param table the table that is locked
  */
 public void addLock(Table table) {
   if (SysProperties.CHECK) {
     if (locks.indexOf(table) >= 0) {
       DbException.throwInternalError();
     }
   }
   locks.add(table);
 }
Exemplo n.º 10
0
 public static void deletePgPortEphemeralNode(ServerName sn, int port, boolean isMaster) {
   try {
     ZKUtil.deleteNode(
         ZooKeeperAdmin.getZooKeeperWatcher(), getPgPortEphemeralNodePath(sn, port, isMaster));
   } catch (KeeperException e) {
     throw DbException.convert(e);
   }
 }
Exemplo n.º 11
0
  Value getMergedValue(Database database, boolean distinct) {
    if (distinct) {
      count = 0;
      groupDistinct(database);
    }
    Value v = null;
    switch (aggregateType) {
      case Aggregate.COUNT:
      case Aggregate.COUNT_ALL:
        v = ValueLong.get(count);
        break;
      case Aggregate.SUM:
      case Aggregate.MIN:
      case Aggregate.MAX:
      case Aggregate.BOOL_OR:
      case Aggregate.BOOL_AND:
        v = value;
        break;
      case Aggregate.AVG:
      case Aggregate.STDDEV_POP:
      case Aggregate.STDDEV_SAMP:
      case Aggregate.VAR_POP:
      case Aggregate.VAR_SAMP:
        return value == null ? ValueNull.INSTANCE : value;

      case Aggregate.SELECTIVITY:
        if (value != null) {
          v = divide(value, count);
        }
        break;
      case Aggregate.GROUP_CONCAT:
        return null;

      case Aggregate.HISTOGRAM:
        ValueArray[] values = new ValueArray[distinctValues.size()];
        int i = 0;
        for (Value dv : distinctValues.keys()) {
          AggregateData d = distinctValues.get(dv);
          values[i] = ValueArray.get(new Value[] {dv, ValueLong.get(d.count)});
          i++;
        }
        final CompareMode compareMode = database.getCompareMode();
        Arrays.sort(
            values,
            new Comparator<ValueArray>() {
              public int compare(ValueArray v1, ValueArray v2) {
                Value a1 = v1.getList()[0];
                Value a2 = v2.getList()[0];
                return a1.compareTo(a2, compareMode);
              }
            });
        v = ValueArray.get(values);
        break;
      default:
        DbException.throwInternalError("type=" + aggregateType);
    }
    return v == null ? ValueNull.INSTANCE : v.convertTo(dataType);
  }
Exemplo n.º 12
0
 /**
  * Remember that the given LOB value must be un-linked (disconnected from the table) at commit.
  *
  * @param v the value
  */
 public void unlinkAtCommit(Value v) {
   if (SysProperties.CHECK && !v.isLinked()) {
     DbException.throwInternalError();
   }
   if (unlinkLobMap == null) {
     unlinkLobMap = New.hashMap();
   }
   unlinkLobMap.put(v.toString(), v);
 }
Exemplo n.º 13
0
 /**
  * Add a local temporary index to this session.
  *
  * @param index the index to add
  * @throws DbException if a index with this name already exists
  */
 public void addLocalTempTableIndex(Index index) {
   if (localTempTableIndexes == null) {
     localTempTableIndexes = database.newStringMap();
   }
   if (localTempTableIndexes.get(index.getName()) != null) {
     throw DbException.get(ErrorCode.INDEX_ALREADY_EXISTS_1, index.getSQL());
   }
   localTempTableIndexes.put(index.getName(), index);
 }
Exemplo n.º 14
0
 /**
  * Add a local temporary constraint to this session.
  *
  * @param constraint the constraint to add
  * @throws DbException if a constraint with the same name already exists
  */
 public void addLocalTempTableConstraint(Constraint constraint) {
   if (localTempTableConstraints == null) {
     localTempTableConstraints = database.newStringMap();
   }
   String name = constraint.getName();
   if (localTempTableConstraints.get(name) != null) {
     throw DbException.get(ErrorCode.CONSTRAINT_ALREADY_EXISTS_1, constraint.getSQL());
   }
   localTempTableConstraints.put(name, constraint);
 }
Exemplo n.º 15
0
 /**
  * Add a local temporary table to this session.
  *
  * @param table the table to add
  * @throws DbException if a table with this name already exists
  */
 public void addLocalTempTable(Table table) {
   if (localTempTables == null) {
     localTempTables = database.newStringMap();
   }
   if (localTempTables.get(table.getName()) != null) {
     throw DbException.get(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1, table.getSQL());
   }
   modificationId++;
   localTempTables.put(table.getName(), table);
 }
Exemplo n.º 16
0
 public static void createPgPortEphemeralNode(ServerName sn, int port, boolean isMaster) {
   try {
     ZKUtil.createEphemeralNodeAndWatch(
         ZooKeeperAdmin.getZooKeeperWatcher(),
         getPgPortEphemeralNodePath(sn, port, isMaster),
         HConstants.EMPTY_BYTE_ARRAY);
   } catch (KeeperException e) {
     throw DbException.convert(e);
   }
 }
Exemplo n.º 17
0
 /**
  * Check if the current transaction is canceled by calling Statement.cancel() or because a session
  * timeout was set and expired.
  *
  * @throws DbException if the transaction is canceled
  */
 public void checkCanceled() {
   throttle();
   if (cancelAt == 0) {
     return;
   }
   long time = System.currentTimeMillis();
   if (time >= cancelAt) {
     cancelAt = 0;
     throw DbException.get(ErrorCode.STATEMENT_WAS_CANCELED);
   }
 }
  @Override
  public boolean next() {
    readBuffer.clear();
    searchRow = null;
    row = null;
    index++;
    if (result != null && index < result.length) {
      setSearchRow();
      return true;
    }

    Transaction transaction = session.getTransaction();
    List<KeyValue> kvs;
    KeyValue kv;
    Result r;
    long queryTimestamp;
    try {
      result = session.getRegionServer().next(scannerId, fetchSize);
      ArrayList<Result> list = new ArrayList<Result>(result.length);
      for (int i = 0; i < result.length; i++) {
        r = result[i];
        kvs = r.list();
        // 当Result.isEmpty=true时,r.list()也返回null,所以这里不用再判断kvs.isEmpty
        if (kvs != null) {
          kv = kvs.get(0);
          queryTimestamp = kv.getTimestamp();
          if (queryTimestamp < transaction.getStartTimestamp() & queryTimestamp % 2 == 0) {
            if (kv.getValueLength() != 0) // kv已删除,不需要再处理
            list.add(r);
            continue;
          }
        }

        // TODO Filter.filter很慢
        r = new Result(Filter.filter(session.getRegionServer(), regionName, transaction, kvs, 1));
        if (!r.isEmpty()) list.add(r);
      }

      result = list.toArray(new Result[0]);
    } catch (Exception e) {
      close();
      throw DbException.convert(e);
    }

    index = 0;

    if (result != null && result.length > 0) {
      setSearchRow();
      return true;
    }

    close();
    return false;
  }
Exemplo n.º 19
0
 /**
  * Open a new (remote or embedded) session.
  *
  * @param openNew whether to open a new session in any case
  * @return the session
  */
 public SessionInterface connectEmbeddedOrServer(boolean openNew) {
   ConnectionInfo ci = connectionInfo;
   if (ci.isRemote() || ci.isDynamic()) {
     connectServer(ci);
     return this;
   }
   // create the session using reflection,
   // so that the JDBC layer can be compiled without it
   boolean autoServerMode = Boolean.valueOf(ci.getProperty("AUTO_SERVER", "false")).booleanValue();
   ConnectionInfo backup = null;
   try {
     if (autoServerMode) {
       backup = (ConnectionInfo) ci.clone();
       connectionInfo = (ConnectionInfo) ci.clone();
     }
     if (openNew) {
       ci.setProperty("OPEN_NEW", "true");
     }
     if (sessionFactory == null) {
       sessionFactory = ci.getSessionFactory();
     }
     return sessionFactory.createSession(ci);
   } catch (Exception re) {
     DbException e = DbException.convert(re);
     if (e.getErrorCode() == ErrorCode.DATABASE_ALREADY_OPEN_1) {
       if (autoServerMode) {
         String serverKey = ((JdbcSQLException) e.getSQLException()).getSQL();
         if (serverKey != null) {
           backup.setServerKey(serverKey);
           // OPEN_NEW must be removed now, otherwise
           // opening a session with AUTO_SERVER fails
           // if another connection is already open
           backup.removeProperty("OPEN_NEW", null);
           connectServer(backup);
           return this;
         }
       }
     }
     throw e;
   }
 }
Exemplo n.º 20
0
  /**
   * Called to flush the output after data has been sent to the server and just before receiving
   * data. This method also reads the status code from the server and throws any exception the
   * server sent.
   *
   * @param transfer the transfer object
   * @throws DbException if the server sent an exception
   * @throws IOException if there is a communication problem between client and server
   */
  public void done(Transfer transfer) throws IOException {
    // 正常来讲不会出现这种情况,如果出现了,说明存在bug,找出为什么transfer的输入流没正常读完的原因
    if (transfer.available() > 0) {
      throw DbException.throwInternalError(
          "before transfer flush, the available bytes was " + transfer.available());
    }

    transfer.flush();
    int status = transfer.readInt();
    if (status == STATUS_ERROR) {
      parseError(transfer);
    } else if (status == STATUS_CLOSED) {
      transferList = null;
    } else if (status == STATUS_OK_STATE_CHANGED) {
      sessionStateChanged = true;
    } else if (status == STATUS_OK) {
      // ok
    } else {
      throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "unexpected status " + status);
    }
  }
Exemplo n.º 21
0
 private void initWrite() throws IOException {
   if (output == null) {
     try {
       OutputStream out = FileUtils.newOutputStream(fileName, false);
       out = new BufferedOutputStream(out, Constants.IO_BUFFER_SIZE);
       output = new BufferedWriter(new OutputStreamWriter(out, characterSet));
     } catch (Exception e) {
       close();
       throw DbException.convertToIOException(e);
     }
   }
 }
Exemplo n.º 22
0
 public void parseError(Transfer transfer) throws IOException {
   String sqlstate = transfer.readString();
   String message = transfer.readString();
   String sql = transfer.readString();
   int errorCode = transfer.readInt();
   String stackTrace = transfer.readString();
   JdbcSQLException s = new JdbcSQLException(message, sql, sqlstate, errorCode, null, stackTrace);
   if (errorCode == ErrorCode.CONNECTION_BROKEN_1) {
     // allow re-connect
     IOException e = new IOException(s.toString());
     e.initCause(s);
     throw e;
   }
   throw DbException.convert(s);
 }
Exemplo n.º 23
0
 private void sendErrorResponse(Exception re) throws IOException {
   SQLException e = DbException.toSQLException(re);
   server.traceError(e);
   startMessage('E');
   write('S');
   writeString("ERROR");
   write('C');
   writeString(e.getSQLState());
   write('M');
   writeString(e.getMessage());
   write('D');
   writeString(e.toString());
   write(0);
   sendMessage();
 }
Exemplo n.º 24
0
 private int writeResultSet(ResultSet rs) throws SQLException {
   try {
     int rows = 0;
     ResultSetMetaData meta = rs.getMetaData();
     int columnCount = meta.getColumnCount();
     String[] row = new String[columnCount];
     int[] sqlTypes = new int[columnCount];
     for (int i = 0; i < columnCount; i++) {
       row[i] = meta.getColumnLabel(i + 1);
       sqlTypes[i] = meta.getColumnType(i + 1);
     }
     if (writeColumnHeader) {
       writeRow(row);
     }
     while (rs.next()) {
       for (int i = 0; i < columnCount; i++) {
         Object o;
         switch (sqlTypes[i]) {
           case Types.DATE:
             o = rs.getDate(i + 1);
             break;
           case Types.TIME:
             o = rs.getTime(i + 1);
             break;
           case Types.TIMESTAMP:
             o = rs.getTimestamp(i + 1);
             break;
           default:
             o = rs.getString(i + 1);
         }
         row[i] = o == null ? null : o.toString();
       }
       writeRow(row);
       rows++;
     }
     output.close();
     return rows;
   } catch (IOException e) {
     throw DbException.convertIOException(e, null);
   } finally {
     close();
     JdbcUtils.closeSilently(rs);
   }
 }
Exemplo n.º 25
0
 private void unlockAll() {
   if (SysProperties.CHECK) {
     if (undoLog.size() > 0) {
       DbException.throwInternalError();
     }
   }
   if (locks.size() > 0) {
     synchronized (database) {
       // don't use the enhanced for loop to save memory
       for (int i = 0, size = locks.size(); i < size; i++) {
         Table t = locks.get(i);
         t.unlock(this);
       }
       locks.clear();
     }
   }
   savepoints = null;
   sessionStateChanged = true;
 }
Exemplo n.º 26
0
 public FileStore openFile(String name, String mode, boolean mustExist) {
   if (mustExist && !FileUtils.exists(name)) {
     throw DbException.get(ErrorCode.FILE_NOT_FOUND_1, name);
   }
   FileStore store;
   if (cipher == null) {
     store = FileStore.open(this, name, mode);
   } else {
     store = FileStore.open(this, name, mode, cipher, fileEncryptionKey, 0);
   }
   store.setCheckedWriting(false);
   try {
     store.init();
   } catch (DbException e) {
     store.closeSilently();
     throw e;
   }
   return store;
 }
 @Override
 public Row get() {
   if (row == null) {
     if (searchRow != null) {
       Result r;
       try {
         Get get = new Get(HBaseUtils.toBytes(searchRow.getRowKey()));
         get.setTimeStamp(searchTimestamp);
         if (columns != null) {
           for (Column c : columns) {
             if (c.isRowKeyColumn()) continue;
             else if (c.getColumnFamilyName() != null)
               get.addColumn(c.getColumnFamilyNameAsBytes(), c.getNameAsBytes());
             else get.addColumn(defaultColumnFamilyName, c.getNameAsBytes());
           }
         }
         r = secondaryIndex.dataTable.get(get);
       } catch (IOException e) {
         throw DbException.convert(e);
       }
       if (r != null) {
         Value[] data = new Value[columns.size()];
         Value rowKey = ValueString.get(Bytes.toString(r.getRow()));
         if (columns != null) {
           int i = 0;
           for (Column c : columns) {
             i = c.getColumnId();
             if (c.isRowKeyColumn()) data[i] = rowKey;
             else
               data[i] =
                   HBaseUtils.toValue( //
                       r.getValue(c.getColumnFamilyNameAsBytes(), c.getNameAsBytes()),
                       c.getType());
           }
         }
         row = new HBaseRow(null, rowKey, data, Row.MEMORY_CALCULATE, r);
       }
     }
   }
   return row;
 }
Exemplo n.º 28
0
 /**
  * INTERNAL. Parse and set the CSV options.
  *
  * @param options the the options
  * @return the character set
  */
 public String setOptions(String options) {
   String charset = null;
   String[] keyValuePairs = StringUtils.arraySplit(options, ' ', false);
   for (String pair : keyValuePairs) {
     if (pair.length() == 0) {
       continue;
     }
     int index = pair.indexOf('=');
     String key = StringUtils.trim(pair.substring(0, index), true, true, " ");
     String value = pair.substring(index + 1);
     char ch = value.length() == 0 ? 0 : value.charAt(0);
     if (isParam(key, "escape", "esc", "escapeCharacter")) {
       setEscapeCharacter(ch);
     } else if (isParam(key, "fieldDelimiter", "fieldDelim")) {
       setFieldDelimiter(ch);
     } else if (isParam(key, "fieldSeparator", "fieldSep")) {
       setFieldSeparatorRead(ch);
       setFieldSeparatorWrite(value);
     } else if (isParam(key, "lineComment", "lineCommentCharacter")) {
       setLineCommentCharacter(ch);
     } else if (isParam(key, "lineSeparator", "lineSep")) {
       setLineSeparator(value);
     } else if (isParam(key, "null", "nullString")) {
       setNullString(value);
     } else if (isParam(key, "rowSeparator", "rowSep")) {
       setRowSeparatorWrite(value);
     } else if (isParam(key, "charset", "characterSet")) {
       charset = value;
     } else if (isParam(key, "preserveWhitespace")) {
       setPreserveWhitespace(Boolean.parseBoolean(value));
     } else if (isParam(key, "writeColumnHeader")) {
       setWriteColumnHeader(Boolean.parseBoolean(value));
     } else if (isParam(key, "caseSensitiveColumnNames")) {
       setCaseSensitiveColumnNames(Boolean.parseBoolean(value));
     } else {
       throw DbException.get(ErrorCode.FEATURE_NOT_SUPPORTED_1, key);
     }
   }
   return charset;
 }
Exemplo n.º 29
0
 private static void installPgCatalog(Statement stat) throws SQLException {
   Reader r = null;
   try {
     r =
         new InputStreamReader(
             new ByteArrayInputStream(
                 Utils.getResource("/com/codefollower/lealone/server/pg/pg_catalog.sql")));
     ScriptReader reader = new ScriptReader(r);
     while (true) {
       String sql = reader.readStatement();
       if (sql == null) {
         break;
       }
       stat.execute(sql);
     }
     reader.close();
   } catch (IOException e) {
     throw DbException.convertIOException(e, "Can not read pg_catalog resource");
   } finally {
     IOUtils.closeSilently(r);
   }
 }
Exemplo n.º 30
0
 private void initDb() throws SQLException {
   Statement stat = null;
   ResultSet rs = null;
   try {
     synchronized (server) {
       // better would be: set the database to exclusive mode
       rs = conn.getMetaData().getTables(null, "PG_CATALOG", "PG_VERSION", null);
       boolean tableFound = rs.next();
       stat = conn.createStatement();
       if (!tableFound) {
         installPgCatalog(stat);
       }
       rs = stat.executeQuery("SELECT * FROM PG_CATALOG.PG_VERSION");
       if (!rs.next() || rs.getInt(1) < 2) {
         // installation incomplete, or old version
         installPgCatalog(stat);
       } else {
         // version 2 or newer: check the read version
         int versionRead = rs.getInt(2);
         if (versionRead > 2) {
           throw DbException.throwInternalError("Incompatible PG_VERSION");
         }
       }
     }
     stat.execute("set search_path = PUBLIC, pg_catalog");
     HashSet<Integer> typeSet = server.getTypeSet();
     if (typeSet.size() == 0) {
       rs = stat.executeQuery("SELECT OID FROM PG_CATALOG.PG_TYPE");
       while (rs.next()) {
         typeSet.add(rs.getInt(1));
       }
     }
   } finally {
     JdbcUtils.closeSilently(stat);
     JdbcUtils.closeSilently(rs);
   }
 }