/** * 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(); }
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; }
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); }
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); }
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; }
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); } }
/** * 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); }
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); } }
@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(); } }
/** * 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(); }
/** * 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(); }
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); } }