Пример #1
0
 /**
  * Get the increment.
  *
  * @param session the session
  * @return the increment (1 by default)
  */
 public long getStep(Session session) {
   optimize(session);
   if (step == null) {
     return 1;
   }
   return step.getValue(session).getLong();
 }
Пример #2
0
 private int insertRows() {
   session.getUser().checkRight(table, Right.INSERT);
   setCurrentRowNumber(0);
   table.fire(session, Trigger.INSERT, true);
   rowNumber = 0;
   int listSize = list.size();
   if (listSize > 0) {
     int columnLen = columns.length;
     for (int x = 0; x < listSize; x++) {
       Row newRow = table.getTemplateRow(); // newRow的长度是全表字段的个数是,会>=columns的长度
       Expression[] expr = list.get(x);
       setCurrentRowNumber(x + 1);
       for (int i = 0; i < columnLen; i++) {
         Column c = columns[i];
         int index = c.getColumnId(); // 从0开始
         Expression e = expr[i];
         if (e != null) {
           // e can be null (DEFAULT)
           e = e.optimize(session);
           try {
             Value v = c.convert(e.getValue(session));
             newRow.setValue(index, v);
           } catch (DbException ex) {
             throw setRow(ex, x, getSQL(expr));
           }
         }
       }
       rowNumber++;
       table.validateConvertUpdateSequence(session, newRow);
       boolean done = table.fireBeforeRow(session, null, newRow); // INSTEAD OF触发器会返回true
       if (!done) {
         // 直到事务commit或rollback时才解琐,见org.h2.engine.Session.unlockAll()
         table.lock(session, true, false);
         table.addRow(session, newRow);
         // 在org.h2.index.PageDataIndex.addTry(Session, Row)中事先记了一次PageLog
         // 也就是org.h2.store.PageStore.logAddOrRemoveRow(Session, int, Row, boolean)
         // 这里又记了一次UndoLog
         // UndoLog在org.h2.engine.Session.commit(boolean)时就清除了
         session.log(table, UndoLogRecord.INSERT, newRow);
         table.fireAfterRow(session, null, newRow, false);
       }
     }
   } else {
     table.lock(session, true, false);
     // 这种方式主要是避免循环两次,因为query内部己循环一次了,得到记录后像else中的非insertFromSelect一样,还要循环一次
     if (insertFromSelect) {
       query.query(0, this); // 每遍历一行会回调下面的addRow方法
     } else {
       ResultInterface rows = query.query(0);
       while (rows.next()) {
         Value[] r = rows.currentRow();
         addRow(r);
       }
       rows.close();
     }
   }
   table.fire(session, Trigger.INSERT, false);
   return rowNumber;
 }
Пример #3
0
 private void queryQuick(int columnCount, ResultTarget result) {
   Value[] row = new Value[columnCount];
   for (int i = 0; i < columnCount; i++) {
     Expression expr = expressions.get(i);
     row[i] = expr.getValue(session);
   }
   result.addRow(row);
 }
Пример #4
0
 private void addGroupSortedRow(Value[] keyValues, int columnCount, ResultTarget result) {
   Value[] row = new Value[columnCount];
   for (int j = 0; groupIndex != null && j < groupIndex.length; j++) {
     row[groupIndex[j]] = keyValues[j];
   }
   for (int j = 0; j < columnCount; j++) {
     if (groupByExpression != null && groupByExpression[j]) {
       continue;
     }
     Expression expr = expressions.get(j);
     row[j] = expr.getValue(session);
   }
   if (isHavingNullOrFalse(row)) {
     return;
   }
   row = keepOnlyDistinct(row, columnCount);
   result.addRow(row);
 }
Пример #5
0
 public int update() throws SQLException {
   session.commit(true);
   session.getUser().checkAdmin();
   Database db = session.getDatabase();
   if (getSchema().findConstant(constantName) != null) {
     if (ifNotExists) {
       return 0;
     }
     throw Message.getSQLException(ErrorCode.CONSTANT_ALREADY_EXISTS_1, constantName);
   }
   int id = getObjectId(false, true);
   Constant constant = new Constant(getSchema(), id, constantName);
   expression = expression.optimize(session);
   Value value = expression.getValue(session);
   constant.setValue(value);
   db.addSchemaObject(session, constant);
   return 0;
 }
Пример #6
0
 private void queryFlat(int columnCount, ResultTarget result, long limitRows) {
   // limitRows must be long, otherwise we get an int overflow
   // if limitRows is at or near Integer.MAX_VALUE
   // limitRows is never 0 here
   if (limitRows > 0 && offsetExpr != null) {
     int offset = offsetExpr.getValue(session).getInt();
     if (offset > 0) {
       limitRows += offset;
     }
   }
   int rowNumber = 0;
   setCurrentRowNumber(0);
   ArrayList<Row> forUpdateRows = null;
   if (isForUpdateMvcc) {
     forUpdateRows = New.arrayList();
   }
   while (topTableFilter.next()) {
     setCurrentRowNumber(rowNumber + 1);
     if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) {
       Value[] row = new Value[columnCount];
       for (int i = 0; i < columnCount; i++) {
         Expression expr = expressions.get(i);
         row[i] = expr.getValue(session);
       }
       if (isForUpdateMvcc) {
         topTableFilter.lockRowAdd(forUpdateRows);
       }
       result.addRow(row);
       rowNumber++;
       if ((sort == null || sortUsingIndex)
           && limitRows > 0
           && result.getRowCount() >= limitRows) {
         break;
       }
       if (sampleSize > 0 && rowNumber >= sampleSize) {
         break;
       }
     }
   }
   if (isForUpdateMvcc) {
     topTableFilter.lockRows(forUpdateRows);
   }
 }
Пример #7
0
 /**
  * Create a {@link SortOrder} object given the list of {@link SelectOrderBy} objects. The
  * expression list is extended if necessary.
  *
  * @param orderList a list of {@link SelectOrderBy} elements
  * @param expressionCount the number of columns in the query
  * @return the {@link SortOrder} object
  */
 public SortOrder prepareOrder(ArrayList<SelectOrderBy> orderList, int expressionCount) {
   int size = orderList.size();
   int[] index = new int[size];
   int[] sortType = new int[size];
   for (int i = 0; i < size; i++) {
     SelectOrderBy o = orderList.get(i);
     int idx;
     boolean reverse = false;
     Expression expr = o.columnIndexExpr;
     Value v = expr.getValue(null);
     if (v == ValueNull.INSTANCE) {
       // parameter not yet set - order by first column
       idx = 0;
     } else {
       idx = v.getInt();
       if (idx < 0) {
         reverse = true;
         idx = -idx;
       }
       idx -= 1;
       if (idx < 0 || idx >= expressionCount) {
         throw DbException.get(ErrorCode.ORDER_BY_NOT_IN_RESULT, "" + (idx + 1));
       }
     }
     index[i] = idx;
     boolean desc = o.descending;
     if (reverse) {
       desc = !desc;
     }
     int type = desc ? SortOrder.DESCENDING : SortOrder.ASCENDING;
     if (o.nullsFirst) {
       type += SortOrder.NULLS_FIRST;
     } else if (o.nullsLast) {
       type += SortOrder.NULLS_LAST;
     }
     sortType[i] = type;
   }
   return new SortOrder(session.getDatabase(), index, sortType, orderList);
 }
Пример #8
0
  private void queryGroupSorted(int columnCount, ResultTarget result) {
    int rowNumber = 0;
    setCurrentRowNumber(0);
    Value[] previousKeyValues = null;
    while (topTableFilter.next()) {
      setCurrentRowNumber(rowNumber + 1);
      if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) {
        rowNumber++;
        Value[] keyValues = new Value[groupIndex.length];
        // update group
        for (int i = 0; i < groupIndex.length; i++) {
          int idx = groupIndex[i];
          Expression expr = expressions.get(idx);
          keyValues[i] = expr.getValue(session);
        }

        if (previousKeyValues == null) {
          previousKeyValues = keyValues;
          currentGroup = New.hashMap();
        } else if (!Arrays.equals(previousKeyValues, keyValues)) {
          addGroupSortedRow(previousKeyValues, columnCount, result);
          previousKeyValues = keyValues;
          currentGroup = New.hashMap();
        }
        currentGroupRowId++;

        for (int i = 0; i < columnCount; i++) {
          if (groupByExpression == null || !groupByExpression[i]) {
            Expression expr = expressions.get(i);
            expr.updateAggregate(session);
          }
        }
      }
    }
    if (previousKeyValues != null) {
      addGroupSortedRow(previousKeyValues, columnCount, result);
    }
  }
Пример #9
0
 @Override
 public int update() {
   tableFilter.startQuery(session);
   tableFilter.reset();
   Table table = tableFilter.getTable();
   session.getUser().checkRight(table, Right.DELETE);
   table.fire(session, Trigger.DELETE, true);
   // 直到事务commit或rollback时才解琐,见org.h2.engine.Session.unlockAll()
   table.lock(session, true, false);
   RowList rows = new RowList(session);
   int limitRows = -1;
   if (limitExpr != null) {
     Value v = limitExpr.getValue(session);
     if (v != ValueNull.INSTANCE) {
       limitRows = v.getInt();
     }
   }
   try {
     setCurrentRowNumber(0);
     int count = 0;
     // 比如delete from DeleteTest limit 0,
     // 此时limitRows为0,不删除任何行
     while (limitRows != 0 && tableFilter.next()) {
       setCurrentRowNumber(rows.size() + 1);
       // condition.getBooleanValue(session)内部会取当前行与之比较,
       // 比如,如果是ExpressionColumn,那么就由它对应的列,取得列id,
       // 然后在从当前行中按列id取当前行value数组中对应元素
       if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) {
         Row row = tableFilter.get();
         boolean done = false;
         if (table.fireRow()) {
           done = table.fireBeforeRow(session, row, null);
         }
         if (!done) {
           rows.add(row);
         }
         count++;
         if (limitRows >= 0 && count >= limitRows) {
           break;
         }
       }
     }
     int rowScanCount = 0;
     for (rows.reset(); rows.hasNext(); ) {
       if ((++rowScanCount & 127) == 0) {
         checkCanceled();
       }
       Row row = rows.next();
       table.removeRow(session, row);
       session.log(table, UndoLogRecord.DELETE, row);
     }
     if (table.fireRow()) {
       for (rows.reset(); rows.hasNext(); ) {
         Row row = rows.next();
         table.fireAfterRow(session, row, null, false);
       }
     }
     table.fire(session, Trigger.DELETE, false);
     return count;
   } finally {
     rows.close();
   }
 }
Пример #10
0
 /**
  * Calculate and get the end value of this range.
  *
  * @param session the session
  * @return the end value
  */
 public long getMax(Session session) {
   optimize(session);
   return max.getValue(session).getLong();
 }
Пример #11
0
 /**
  * Calculate and get the start value of this range.
  *
  * @param session the session
  * @return the start value
  */
 public long getMin(Session session) {
   optimize(session);
   return min.getValue(session).getLong();
 }
Пример #12
0
 private void queryGroup(int columnCount, LocalResult result) {
   ValueHashMap<HashMap<Expression, Object>> groups = ValueHashMap.newInstance();
   int rowNumber = 0;
   setCurrentRowNumber(0);
   ValueArray defaultGroup = ValueArray.get(new Value[0]);
   while (topTableFilter.next()) {
     setCurrentRowNumber(rowNumber + 1);
     if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) {
       Value key;
       rowNumber++;
       if (groupIndex == null) {
         key = defaultGroup;
       } else {
         Value[] keyValues = new Value[groupIndex.length];
         // update group
         for (int i = 0; i < groupIndex.length; i++) {
           int idx = groupIndex[i];
           Expression expr = expressions.get(idx);
           keyValues[i] = expr.getValue(session);
         }
         key = ValueArray.get(keyValues);
       }
       HashMap<Expression, Object> values = groups.get(key);
       if (values == null) {
         values = new HashMap<Expression, Object>();
         groups.put(key, values);
       }
       currentGroup = values;
       currentGroupRowId++;
       int len = columnCount;
       for (int i = 0; i < len; i++) {
         if (groupByExpression == null || !groupByExpression[i]) {
           Expression expr = expressions.get(i);
           expr.updateAggregate(session);
         }
       }
       if (sampleSize > 0 && rowNumber >= sampleSize) {
         break;
       }
     }
   }
   if (groupIndex == null && groups.size() == 0) {
     groups.put(defaultGroup, new HashMap<Expression, Object>());
   }
   ArrayList<Value> keys = groups.keys();
   for (Value v : keys) {
     ValueArray key = (ValueArray) v;
     currentGroup = groups.get(key);
     Value[] keyValues = key.getList();
     Value[] row = new Value[columnCount];
     for (int j = 0; groupIndex != null && j < groupIndex.length; j++) {
       row[groupIndex[j]] = keyValues[j];
     }
     for (int j = 0; j < columnCount; j++) {
       if (groupByExpression != null && groupByExpression[j]) {
         continue;
       }
       Expression expr = expressions.get(j);
       row[j] = expr.getValue(session);
     }
     if (isHavingNullOrFalse(row)) {
       continue;
     }
     row = keepOnlyDistinct(row, columnCount);
     result.addRow(row);
   }
 }