/**
  * Get the value of the given property.
  *
  * @param key the property key
  * @param defaultValue the default value
  * @return the value as a String
  */
 public String getProperty(String key, String defaultValue) {
   if (SysProperties.CHECK && !isKnownSetting(key)) {
     DbException.throwInternalError(key);
   }
   String s = getProperty(key);
   return s == null ? defaultValue : s;
 }
 static {
   ArrayList<String> list = SetTypes.getTypes();
   HashSet<String> set = KNOWN_SETTINGS;
   set.addAll(list);
   String[] connectionTime = {
     "ACCESS_MODE_DATA",
     "AUTOCOMMIT",
     "CIPHER",
     "CREATE",
     "CACHE_TYPE",
     "FILE_LOCK",
     "IGNORE_UNKNOWN_SETTINGS",
     "IFEXISTS",
     "INIT",
     "PASSWORD",
     "RECOVER",
     "RECOVER_TEST",
     "USER",
     "AUTO_SERVER",
     "AUTO_SERVER_PORT",
     "NO_UPGRADE",
     "AUTO_RECONNECT",
     "OPEN_NEW",
     "PAGE_SIZE",
     "PASSWORD_HASH",
     "JMX"
   };
   for (String key : connectionTime) {
     if (SysProperties.CHECK && set.contains(key)) {
       DbException.throwInternalError(key);
     }
     set.add(key);
   }
 }
 /**
  * Remove a String property if it is set and return the value.
  *
  * @param key the property name
  * @param defaultValue the default value
  * @return the value
  */
 String removeProperty(String key, String defaultValue) {
   if (SysProperties.CHECK && !isKnownSetting(key)) {
     DbException.throwInternalError(key);
   }
   Object x = prop.remove(key);
   return x == null ? defaultValue : x.toString();
 }
 /**
  * Get the value of the given property.
  *
  * @param key the property key
  * @param defaultValue the default value
  * @return the value as a String
  */
 int getProperty(String key, int defaultValue) {
   if (SysProperties.CHECK && !isKnownSetting(key)) {
     DbException.throwInternalError(key);
   }
   String s = getProperty(key);
   return s == null ? defaultValue : Integer.parseInt(s);
 }
示例#5
0
 /**
  * Returns the current transaction isolation level.
  *
  * @return the isolation level.
  * @throws SQLException if the connection is closed
  */
 public int getTransactionIsolation() throws SQLException {
   try {
     debugCodeCall("getTransactionIsolation");
     checkClosed();
     getLockMode = prepareCommand("CALL LOCK_MODE()", getLockMode);
     ResultInterface result = getLockMode.executeQuery(0, false);
     result.next();
     int lockMode = result.currentRow()[0].getInt();
     result.close();
     int transactionIsolationLevel;
     switch (lockMode) {
       case Constants.LOCK_MODE_OFF:
         transactionIsolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED;
         break;
       case Constants.LOCK_MODE_READ_COMMITTED:
         transactionIsolationLevel = Connection.TRANSACTION_READ_COMMITTED;
         break;
       case Constants.LOCK_MODE_TABLE:
       case Constants.LOCK_MODE_TABLE_GC:
         transactionIsolationLevel = Connection.TRANSACTION_SERIALIZABLE;
         break;
       default:
         throw DbException.throwInternalError("lockMode:" + lockMode);
     }
     return transactionIsolationLevel;
   } catch (Exception e) {
     throw logAndConvert(e);
   }
 }
 /**
  * Add or update a key value pair.
  *
  * @param key the key
  * @param value the new value
  */
 public void put(Value key, V value) {
   checkSizePut();
   int index = getIndex(key);
   int plus = 1;
   int deleted = -1;
   do {
     Value k = keys[index];
     if (k == null) {
       // found an empty record
       if (deleted >= 0) {
         index = deleted;
         deletedCount--;
       }
       size++;
       keys[index] = key;
       values[index] = value;
       return;
     } else if (k == ValueNull.DELETED) {
       // found a deleted record
       if (deleted < 0) {
         deleted = index;
       }
     } else if (k.equals(key)) {
       // update existing
       values[index] = value;
       return;
     }
     index = (index + plus++) & mask;
   } while (plus <= len);
   // no space
   DbException.throwInternalError("hashmap is full");
 }
示例#7
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 (table.isMVStore()) {
     return;
   }
   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();
     }
   }
 }
示例#8
0
 @Override
 public int update() {
   session.getUser().checkAdmin();
   session.commit(true);
   Database db = session.getDatabase();
   if (db.findRole(userName) != null) {
     throw DbException.get(ErrorCode.ROLE_ALREADY_EXISTS_1, userName);
   }
   if (db.findUser(userName) != null) {
     if (ifNotExists) {
       return 0;
     }
     throw DbException.get(ErrorCode.USER_ALREADY_EXISTS_1, userName);
   }
   int id = getObjectId();
   User user = new User(db, id, userName, false);
   user.setAdmin(admin);
   user.setComment(comment);
   if (hash != null && salt != null) {
     user.setSaltAndHash(getByteArray(salt), getByteArray(hash));
   } else if (password != null) {
     char[] passwordChars = getCharArray(password);
     byte[] userPasswordHash;
     if (userName.length() == 0 && passwordChars.length == 0) {
       userPasswordHash = new byte[0];
     } else {
       userPasswordHash = SHA256.getKeyPasswordHash(userName, passwordChars);
     }
     user.setUserPasswordHash(userPasswordHash);
   } else {
     throw DbException.throwInternalError();
   }
   db.addDatabaseObject(session, user);
   return 0;
 }
示例#9
0
 @Override
 public void add(Session session, Row row) {
   if (closed) {
     throw DbException.throwInternalError();
   }
   TreeNode i = new TreeNode(row);
   TreeNode n = root, x = n;
   boolean isLeft = true;
   while (true) {
     if (n == null) {
       if (x == null) {
         root = i;
         rowCount++;
         return;
       }
       set(x, isLeft, i);
       break;
     }
     Row r = n.row;
     int compare = compareRows(row, r);
     if (compare == 0) {
       if (indexType.isUnique()) {
         if (!containsNullAndAllowMultipleNull(row)) {
           throw getDuplicateKeyException(row.toString());
         }
       }
       compare = compareKeys(row, r);
     }
     isLeft = compare < 0;
     x = n;
     n = child(x, isLeft);
   }
   balance(x, isLeft);
   rowCount++;
 }
示例#10
0
 /**
  * Remove all pages until the given data page.
  *
  * @param trunkPage the first trunk page
  * @param firstDataPageToKeep the first data page to keep
  * @return the trunk page of the data page to keep
  */
 private int removeUntil(int trunkPage, int firstDataPageToKeep) {
   trace.debug("log.removeUntil " + trunkPage + " " + firstDataPageToKeep);
   int last = trunkPage;
   while (true) {
     Page p = store.getPage(trunkPage);
     PageStreamTrunk t = (PageStreamTrunk) p;
     if (t == null) {
       throw DbException.throwInternalError(
           "log.removeUntil not found: " + firstDataPageToKeep + " last " + last);
     }
     logKey = t.getLogKey();
     last = t.getPos();
     if (t.contains(firstDataPageToKeep)) {
       return last;
     }
     trunkPage = t.getNextTrunk();
     IntArray list = new IntArray();
     list.add(t.getPos());
     for (int i = 0; ; i++) {
       int next = t.getPageData(i);
       if (next == -1) {
         break;
       }
       list.add(next);
     }
     freeLogPages(list);
     pageOut.free(t);
   }
 }
示例#11
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.contains(table)) {
       DbException.throwInternalError();
     }
   }
   locks.add(table);
 }
示例#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);
 }
示例#13
0
 public void decrypt(byte[] bytes, int off, int len) {
   if (SysProperties.CHECK) {
     if (len % ALIGN != 0) {
       DbException.throwInternalError("unaligned len " + len);
     }
   }
   for (int i = off; i < off + len; i += 8) {
     decryptBlock(bytes, bytes, i);
   }
 }
示例#14
0
 public MVDelegateIndex(
     MVTable table, int id, String name, MVPrimaryIndex mainIndex, IndexType indexType) {
   IndexColumn[] cols =
       IndexColumn.wrap(new Column[] {table.getColumn(mainIndex.getMainIndexColumn())});
   this.initBaseIndex(table, id, name, cols, indexType);
   this.mainIndex = mainIndex;
   if (id < 0) {
     throw DbException.throwInternalError("" + name);
   }
 }
示例#15
0
 PageData split(int splitPoint) {
   int newPageId = index.getPageStore().allocatePage();
   PageDataLeaf p2 = PageDataLeaf.create(index, newPageId, parentPageId);
   for (int i = splitPoint; i < entryCount; ) {
     int split = p2.addRowTry(getRowAt(splitPoint));
     if (split != -1) {
       DbException.throwInternalError("split " + split);
     }
     removeRow(splitPoint);
   }
   return p2;
 }
示例#16
0
 /**
  * Get the key from the row.
  *
  * @param row the row
  * @param ifEmpty the value to use if the row is empty
  * @param ifNull the value to use if the column is NULL
  * @return the key
  */
 long getKey(SearchRow row, long ifEmpty, long ifNull) {
   if (row == null) {
     return ifEmpty;
   }
   Value v = row.getValue(mainIndexColumn);
   if (v == null) {
     throw DbException.throwInternalError(row.toString());
   } else if (v == ValueNull.INSTANCE) {
     return ifNull;
   }
   return v.getLong();
 }
示例#17
0
 /**
  * Set the overflow page id.
  *
  * @param old the old overflow page id
  * @param overflow the new overflow page id
  */
 void setOverflow(int old, int overflow) {
   if (SysProperties.CHECK && old != firstOverflowPageId) {
     DbException.throwInternalError("move " + this + " " + firstOverflowPageId);
   }
   index.getPageStore().logUndo(this, data);
   firstOverflowPageId = overflow;
   if (written) {
     changeCount = index.getPageStore().getChangeCount();
     writeHead();
     data.writeInt(firstOverflowPageId);
   }
   index.getPageStore().update(this);
 }
示例#18
0
 @Override
 public InputStream getInputStream(ValueLobDb lob, byte[] hmac, long byteCount)
     throws IOException {
   init();
   Object[] value = lobMap.get(lob.getLobId());
   if (value == null) {
     if (lob.getTableId() == LobStorageFrontend.TABLE_RESULT
         || lob.getTableId() == LobStorageFrontend.TABLE_ID_SESSION_VARIABLE) {
       throw DbException.get(
           ErrorCode.LOB_CLOSED_ON_TIMEOUT_1, "" + lob.getLobId() + "/" + lob.getTableId());
     }
     throw DbException.throwInternalError(
         "Lob not found: " + lob.getLobId() + "/" + lob.getTableId());
   }
   byte[] streamStoreId = (byte[]) value[0];
   return streamStore.get(streamStoreId);
 }
示例#19
0
  private Permutations(T[] in, T[] out, int m) {
    this.n = in.length;
    this.m = m;
    if (n < m || m < 0) {
      DbException.throwInternalError("n < m or m < 0");
    }
    this.in = in;
    this.out = out;
    index = new int[n];
    for (int i = 0; i < n; i++) {
      index[i] = i;
    }

    // The elements from m to n are always kept ascending right to left.
    // This keeps the dip in the interesting region.
    reverseAfter(m - 1);
  }
示例#20
0
 private void unlockAll() {
   if (SysProperties.CHECK) {
     if (undoLog.size() > 0) {
       DbException.throwInternalError();
     }
   }
   if (locks.size() > 0) {
     // 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;
 }
 /**
  * Split the file name into size and base file name.
  *
  * @param fileName the file name
  * @return an array with size and file name
  */
 private String[] parse(String fileName) {
   if (!fileName.startsWith(getScheme())) {
     DbException.throwInternalError(fileName + " doesn't start with " + getScheme());
   }
   fileName = fileName.substring(getScheme().length() + 1);
   String size;
   if (fileName.length() > 0 && Character.isDigit(fileName.charAt(0))) {
     int idx = fileName.indexOf(':');
     size = fileName.substring(0, idx);
     try {
       fileName = fileName.substring(idx + 1);
     } catch (NumberFormatException e) {
       // ignore
     }
   } else {
     size = Long.toString(SysProperties.SPLIT_FILE_SIZE_SHIFT);
   }
   return new String[] {size, fileName};
 }
 public boolean isEverything(ExpressionVisitor visitor) {
   if (!this.left.isEverything(visitor)) {
     return false;
   }
   switch (visitor.getType()) {
     case 0:
     case 1:
     case 2:
     case 3:
     case 4:
     case 5:
     case 6:
     case 7:
     case 8:
     case 9:
       return true;
   }
   throw DbException.throwInternalError("type=" + visitor.getType());
 }
示例#23
0
 @Override
 public Cursor findFirstOrLast(Session session, boolean first) {
   if (closed) {
     throw DbException.throwInternalError();
   }
   if (first) {
     // TODO optimization: this loops through NULL
     Cursor cursor = find(session, null, null);
     while (cursor.next()) {
       SearchRow row = cursor.getSearchRow();
       Value v = row.getValue(columnIds[0]);
       if (v != ValueNull.INSTANCE) {
         return cursor;
       }
     }
     return cursor;
   }
   TreeNode x = root, n;
   while (x != null) {
     n = x.right;
     if (n == null) {
       break;
     }
     x = n;
   }
   TreeCursor cursor = new TreeCursor(this, x, null, null);
   if (x == null) {
     return cursor;
   }
   // TODO optimization: this loops through NULL elements
   do {
     SearchRow row = cursor.getSearchRow();
     if (row == null) {
       break;
     }
     Value v = row.getValue(columnIds[0]);
     if (v != ValueNull.INSTANCE) {
       return cursor;
     }
   } while (cursor.previous());
   return cursor;
 }
示例#24
0
 private void removeRow(int i) {
   index.getPageStore().logUndo(this, data);
   written = false;
   changeCount = index.getPageStore().getChangeCount();
   if (!optimizeUpdate) {
     readAllRows();
   }
   Row r = getRowAt(i);
   if (r != null) {
     memoryChange(false, r);
   }
   entryCount--;
   if (entryCount < 0) {
     DbException.throwInternalError();
   }
   if (firstOverflowPageId != 0) {
     start -= 4;
     freeOverflow();
     firstOverflowPageId = 0;
     overflowRowSize = 0;
     rowRef = null;
   }
   int keyOffsetPairLen = 2 + Data.getVarLongLen(keys[i]);
   int startNext = i > 0 ? offsets[i - 1] : index.getPageStore().getPageSize();
   int rowLength = startNext - offsets[i];
   if (optimizeUpdate) {
     if (writtenData) {
       byte[] d = data.getBytes();
       int dataStart = offsets[entryCount];
       System.arraycopy(d, dataStart, d, dataStart + rowLength, offsets[i] - dataStart);
       Arrays.fill(d, dataStart, dataStart + rowLength, (byte) 0);
     }
   } else {
     int clearStart = offsets[entryCount];
     Arrays.fill(data.getBytes(), clearStart, clearStart + rowLength, (byte) 0);
   }
   start -= keyOffsetPairLen;
   offsets = remove(offsets, entryCount + 1, i);
   add(offsets, i, entryCount, rowLength);
   keys = remove(keys, entryCount + 1, i);
   rows = remove(rows, entryCount + 1, i);
 }
示例#25
0
 private void writeHead() {
   data.reset();
   int type;
   if (firstOverflowPageId == 0) {
     type = Page.TYPE_DATA_LEAF | Page.FLAG_LAST;
   } else {
     type = Page.TYPE_DATA_LEAF;
   }
   data.writeByte((byte) type);
   data.writeShortInt(0);
   if (SysProperties.CHECK2) {
     if (data.length() != START_PARENT) {
       DbException.throwInternalError();
     }
   }
   data.writeInt(parentPageId);
   data.writeVarInt(index.getId());
   data.writeVarInt(columnCount);
   data.writeShortInt(entryCount);
 }
示例#26
0
 private void balance(TreeNode x, boolean isLeft) {
   while (true) {
     int sign = isLeft ? 1 : -1;
     switch (x.balance * sign) {
       case 1:
         x.balance = 0;
         return;
       case 0:
         x.balance = -sign;
         break;
       case -1:
         TreeNode l = child(x, isLeft);
         if (l.balance == -sign) {
           replace(x, l);
           set(x, isLeft, child(l, !isLeft));
           set(l, !isLeft, x);
           x.balance = 0;
           l.balance = 0;
         } else {
           TreeNode r = child(l, !isLeft);
           replace(x, r);
           set(l, !isLeft, child(r, isLeft));
           set(r, isLeft, l);
           set(x, isLeft, child(r, !isLeft));
           set(r, !isLeft, x);
           int rb = r.balance;
           x.balance = (rb == -sign) ? sign : 0;
           l.balance = (rb == sign) ? -sign : 0;
           r.balance = 0;
         }
         return;
       default:
         DbException.throwInternalError("b:" + x.balance * sign);
     }
     if (x == root) {
       return;
     }
     isLeft = x.isFromLeft();
     x = x.parent;
   }
 }
示例#27
0
 @Override
 public void addGlobalCondition(Parameter param, int columnId, int comparisonType) {
   addParameter(param);
   switch (unionType) {
     case UNION_ALL:
     case UNION:
     case INTERSECT:
       {
         left.addGlobalCondition(param, columnId, comparisonType);
         right.addGlobalCondition(param, columnId, comparisonType);
         break;
       }
     case EXCEPT:
       {
         left.addGlobalCondition(param, columnId, comparisonType);
         break;
       }
     default:
       DbException.throwInternalError("type=" + unionType);
   }
 }
示例#28
0
 @Override
 public void init() {
   if (SysProperties.CHECK && checkInit) {
     DbException.throwInternalError();
   }
   checkInit = true;
   left.init();
   right.init();
   int len = left.getColumnCount();
   if (len != right.getColumnCount()) {
     throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
   }
   ArrayList<Expression> le = left.getExpressions();
   // set the expressions to get the right column count and names,
   // but can't validate at this time
   expressions = New.arrayList();
   for (int i = 0; i < len; i++) {
     Expression l = le.get(i);
     expressions.add(l);
   }
 }
示例#29
0
 /**
  * Add an undo entry to the log. The page data is only written once until the next checkpoint.
  *
  * @param pageId the page id
  * @param page the old page data
  */
 void addUndo(int pageId, Data page) {
   if (undo.get(pageId) || freeing) {
     return;
   }
   if (trace.isDebugEnabled()) {
     trace.debug("log undo " + pageId);
   }
   if (SysProperties.CHECK) {
     if (page == null) {
       DbException.throwInternalError("Undo entry not written");
     }
   }
   undo.set(pageId);
   undoAll.set(pageId);
   Data buffer = getBuffer();
   buffer.writeByte((byte) UNDO);
   buffer.writeVarInt(pageId);
   if (page.getBytes()[0] == 0) {
     buffer.writeVarInt(1);
   } else {
     int pageSize = store.getPageSize();
     if (COMPRESS_UNDO) {
       int size = compress.compress(page.getBytes(), pageSize, compressBuffer, 0);
       if (size < pageSize) {
         buffer.writeVarInt(size);
         buffer.checkCapacity(size);
         buffer.write(compressBuffer, 0, size);
       } else {
         buffer.writeVarInt(0);
         buffer.checkCapacity(pageSize);
         buffer.write(page.getBytes(), 0, pageSize);
       }
     } else {
       buffer.writeVarInt(0);
       buffer.checkCapacity(pageSize);
       buffer.write(page.getBytes(), 0, pageSize);
     }
   }
   write(buffer);
 }
示例#30
0
 @Override
 public String getPlanSQL() {
   StringBuilder buff = new StringBuilder();
   buff.append('(').append(left.getPlanSQL()).append(')');
   switch (unionType) {
     case UNION_ALL:
       buff.append("\nUNION ALL\n");
       break;
     case UNION:
       buff.append("\nUNION\n");
       break;
     case INTERSECT:
       buff.append("\nINTERSECT\n");
       break;
     case EXCEPT:
       buff.append("\nEXCEPT\n");
       break;
     default:
       DbException.throwInternalError("type=" + unionType);
   }
   buff.append('(').append(right.getPlanSQL()).append(')');
   Expression[] exprList = expressions.toArray(new Expression[expressions.size()]);
   if (sort != null) {
     buff.append("\nORDER BY ").append(sort.getSQL(exprList, exprList.length));
   }
   if (limitExpr != null) {
     buff.append("\nLIMIT ").append(StringUtils.unEnclose(limitExpr.getSQL()));
     if (offsetExpr != null) {
       buff.append("\nOFFSET ").append(StringUtils.unEnclose(offsetExpr.getSQL()));
     }
   }
   if (sampleSizeExpr != null) {
     buff.append("\nSAMPLE_SIZE ").append(StringUtils.unEnclose(sampleSizeExpr.getSQL()));
   }
   if (isForUpdate) {
     buff.append("\nFOR UPDATE");
   }
   return buff.toString();
 }