/** * 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); }
/** * Set the value of the given variable for this session. * * @param name the name of the variable (may not be null) * @param value the new value (may not be null) */ public void setVariable(String name, Value value) { initVariables(); modificationId++; Value old; if (value == ValueNull.INSTANCE) { old = variables.remove(name); } else { old = variables.put(name, value); } if (old != null) { // close the old value (in case it is a lob) old.close(); } }
@Override public void updateAggregate(Session session) { // TODO aggregates: check nested MIN(MAX(ID)) and so on // if (on != null) { // on.updateAggregate(); // } HashMap<Expression, Object> group = select.getCurrentGroup(); if (group == null) { // this is a different level (the enclosing query) return; } int groupRowId = select.getCurrentGroupRowId(); if (lastGroupRowId == groupRowId) { // already visited return; } lastGroupRowId = groupRowId; AggregateData data = (AggregateData) group.get(this); if (data == null) { data = AggregateData.create(type); group.put(this, data); } Value v = on == null ? null : on.getValue(session); if (type == GROUP_CONCAT) { if (v != ValueNull.INSTANCE) { v = v.convertTo(Value.STRING); if (groupConcatOrderList != null) { int size = groupConcatOrderList.size(); Value[] array = new Value[1 + size]; array[0] = v; for (int i = 0; i < size; i++) { SelectOrderBy o = groupConcatOrderList.get(i); array[i + 1] = o.expression.getValue(session); } v = ValueArray.get(array); } } } data.add(session.getDatabase(), dataType, distinct, v); }
/** * Do not unlink this LOB value at commit any longer. * * @param v the value */ public void unlinkAtCommitStop(Value v) { if (unlinkLobMap != null) { unlinkLobMap.remove(v.toString()); } }
/** * Commit the current transaction. If the statement was not a data definition statement, and if * there are temporary tables that should be dropped or truncated at commit, this is done as well. * * @param ddl if the statement was a data definition statement */ public void commit(boolean ddl) { checkCommitRollback(); currentTransactionName = null; transactionStart = 0; if (containsUncommitted()) { // need to commit even if rollback is not possible // (create/drop table and so on) database.commit(this); } if (temporaryLobs != null) { for (Value v : temporaryLobs) { if (!v.isLinked()) { v.close(); } } temporaryLobs.clear(); } if (!ddl) { // do not clean the temp tables if the last command was a // create/drop cleanTempTables(false); if (autoCommitAtTransactionEnd) { autoCommit = true; autoCommitAtTransactionEnd = false; } } endTransaction(); boolean commit = true; List<SQLException> commitExceptions = New.arrayList(); StringBuilder buf = new StringBuilder(); for (Map.Entry<String, Connection> entry : connectionHolder.entrySet()) { if (commit) { try { entry.getValue().commit(); buf.append("\ncommit shard " + entry.getKey() + " transaction succeed."); } catch (SQLException ex) { commit = false; commitExceptions.add(ex); buf.append("\ncommit shard " + entry.getKey() + " transaction failure."); } } else { // after unsucessfull commit we must try to rollback // remaining connections try { entry.getValue().rollback(); buf.append("\nrollback shard " + entry.getKey() + " transaction succeed."); } catch (SQLException ex) { buf.append("\nrollback shard " + entry.getKey() + " transaction failure."); } } } if (commitExceptions.isEmpty()) { trace.debug("commit multiple group transaction succeed. commit track list:{0}", buf); } else { trace.error( commitExceptions.get(0), "fail to commit multiple group transaction. commit track list:{0}", buf); DbException.convert(commitExceptions.get(0)); } }
@Override public Value getValue(Session session) { if (select.isQuickAggregateQuery()) { switch (type) { case COUNT: case COUNT_ALL: Table table = select.getTopTableFilter().getTable(); return ValueLong.get(table.getRowCount(session)); case MIN: case MAX: boolean first = type == MIN; Index index = getColumnIndex(); int sortType = index.getIndexColumns()[0].sortType; if ((sortType & SortOrder.DESCENDING) != 0) { first = !first; } Cursor cursor = index.findFirstOrLast(session, first); SearchRow row = cursor.getSearchRow(); Value v; if (row == null) { v = ValueNull.INSTANCE; } else { v = row.getValue(index.getColumns()[0].getColumnId()); } return v; default: DbException.throwInternalError("type=" + type); } } HashMap<Expression, Object> group = select.getCurrentGroup(); if (group == null) { throw DbException.get(ErrorCode.INVALID_USE_OF_AGGREGATE_FUNCTION_1, getSQL()); } AggregateData data = (AggregateData) group.get(this); if (data == null) { data = AggregateData.create(type); } Value v = data.getValue(session.getDatabase(), dataType, distinct); if (type == GROUP_CONCAT) { ArrayList<Value> list = ((AggregateDataGroupConcat) data).getList(); if (list == null || list.size() == 0) { return ValueNull.INSTANCE; } if (groupConcatOrderList != null) { final SortOrder sortOrder = groupConcatSort; Collections.sort( list, new Comparator<Value>() { @Override public int compare(Value v1, Value v2) { Value[] a1 = ((ValueArray) v1).getList(); Value[] a2 = ((ValueArray) v2).getList(); return sortOrder.compare(a1, a2); } }); } StatementBuilder buff = new StatementBuilder(); String sep = groupConcatSeparator == null ? "," : groupConcatSeparator.getValue(session).getString(); for (Value val : list) { String s; if (val.getType() == Value.ARRAY) { s = ((ValueArray) val).getList()[0].getString(); } else { s = val.getString(); } if (s == null) { continue; } if (sep != null) { buff.appendExceptFirst(sep); } buff.append(s); } v = ValueString.get(buff.toString()); } return v; }