private MetaRecord getMetaRecord(Result r) { Value[] data = new Value[4]; // id // data[0] = ValueInt.get(Bytes.toInt(r.getValue(FAMILY, ID))); data[0] = ValueInt.get(Bytes.toInt(r.getRow())); // head 未使用 // data[1] = null; // type data[2] = ValueInt.get(Bytes.toInt(r.getValue(FAMILY, OBJECT_TYPE))); // sql data[3] = ValueString.get(Bytes.toString(r.getValue(FAMILY, SQL))); return new MetaRecord(new SimpleRow(data)); }
/** * Changes the current transaction isolation level. Calling this method will commit an open * transaction, even if the new level is the same as the old one, except if the level is not * supported. Internally, this method calls SET LOCK_MODE. The following isolation levels are * supported: * * <ul> * <li>Connection.TRANSACTION_READ_UNCOMMITTED = SET LOCK_MODE 0: no locking (should only be * used for testing). * <li>Connection.TRANSACTION_SERIALIZABLE = SET LOCK_MODE 1: table level locking. * <li>Connection.TRANSACTION_READ_COMMITTED = SET LOCK_MODE 3: table level locking, but read * locks are released immediately (default). * </ul> * * This setting is not persistent. Please note that using TRANSACTION_READ_UNCOMMITTED while at * the same time using multiple connections may result in inconsistent transactions. * * @param level the new transaction isolation level: Connection.TRANSACTION_READ_UNCOMMITTED, * Connection.TRANSACTION_READ_COMMITTED, or Connection.TRANSACTION_SERIALIZABLE * @throws SQLException if the connection is closed or the isolation level is not supported */ public void setTransactionIsolation(int level) throws SQLException { try { debugCodeCall("setTransactionIsolation", level); checkClosed(); int lockMode; switch (level) { case Connection.TRANSACTION_READ_UNCOMMITTED: lockMode = Constants.LOCK_MODE_OFF; break; case Connection.TRANSACTION_READ_COMMITTED: lockMode = Constants.LOCK_MODE_READ_COMMITTED; break; case Connection.TRANSACTION_REPEATABLE_READ: case Connection.TRANSACTION_SERIALIZABLE: lockMode = Constants.LOCK_MODE_TABLE; break; default: throw DbException.getInvalidValueException("" + level, "level"); } commit(); setLockMode = prepareCommand("SET LOCK_MODE ?", setLockMode); setLockMode.getParameters().get(0).setValue(ValueInt.get(lockMode), false); setLockMode.executeUpdate(); } catch (Exception e) { throw logAndConvert(e); } }
/** INTERNAL */ public void setQueryTimeout(int seconds) throws SQLException { try { debugCodeCall("setQueryTimeout", seconds); checkClosed(); setQueryTimeout = prepareCommand("SET QUERY_TIMEOUT ?", setQueryTimeout); setQueryTimeout.getParameters().get(0).setValue(ValueInt.get(seconds * 1000), false); setQueryTimeout.executeUpdate(); } catch (Exception e) { throw logAndConvert(e); } }
/** * Initialize the order by list. This call may extend the expressions list. * * @param session the session * @param expressions the select list expressions * @param expressionSQL the select list SQL snippets * @param orderList the order by list * @param visible the number of visible columns in the select list * @param mustBeInResult all order by expressions must be in the select list * @param filters the table filters */ static void initOrder( Session session, ArrayList<Expression> expressions, ArrayList<String> expressionSQL, ArrayList<SelectOrderBy> orderList, int visible, boolean mustBeInResult, ArrayList<TableFilter> filters) { Database db = session.getDatabase(); for (SelectOrderBy o : orderList) { Expression e = o.expression; if (e == null) { continue; } // special case: SELECT 1 AS A FROM DUAL ORDER BY A // (oracle supports it, but only in order by, not in group by and // not in having): // SELECT 1 AS A FROM DUAL ORDER BY -A boolean isAlias = false; int idx = expressions.size(); if (e instanceof ExpressionColumn) { // order by expression ExpressionColumn exprCol = (ExpressionColumn) e; String tableAlias = exprCol.getOriginalTableAliasName(); String col = exprCol.getOriginalColumnName(); for (int j = 0; j < visible; j++) { boolean found = false; Expression ec = expressions.get(j); if (ec instanceof ExpressionColumn) { // select expression ExpressionColumn c = (ExpressionColumn) ec; found = db.equalsIdentifiers(col, c.getColumnName()); if (found && tableAlias != null) { String ca = c.getOriginalTableAliasName(); if (ca == null) { found = false; if (filters != null) { // select id from test order by test.id for (int i = 0, size = filters.size(); i < size; i++) { TableFilter f = filters.get(i); if (db.equalsIdentifiers(f.getTableAlias(), tableAlias)) { found = true; break; } } } } else { found = db.equalsIdentifiers(ca, tableAlias); } } } else if (!(ec instanceof Alias)) { continue; } else if (tableAlias == null && db.equalsIdentifiers(col, ec.getAlias())) { found = true; } else { Expression ec2 = ec.getNonAliasExpression(); if (ec2 instanceof ExpressionColumn) { ExpressionColumn c2 = (ExpressionColumn) ec2; String ta = exprCol.getSQL(); String tb = c2.getSQL(); String s2 = c2.getColumnName(); found = db.equalsIdentifiers(col, s2); if (!db.equalsIdentifiers(ta, tb)) { found = false; } } } if (found) { idx = j; isAlias = true; break; } } } else { String s = e.getSQL(); if (expressionSQL != null) { for (int j = 0, size = expressionSQL.size(); j < size; j++) { String s2 = expressionSQL.get(j); if (db.equalsIdentifiers(s2, s)) { idx = j; isAlias = true; break; } } } } if (!isAlias) { if (mustBeInResult) { throw DbException.get(ErrorCode.ORDER_BY_NOT_IN_RESULT, e.getSQL()); } expressions.add(e); String sql = e.getSQL(); expressionSQL.add(sql); } o.columnIndexExpr = ValueExpression.get(ValueInt.get(idx + 1)); Expression expr = expressions.get(idx).getNonAliasExpression(); o.expression = expr; } }
/** * Read a value. * * @return the value */ public Value readValue() { int type = data[pos++] & 255; switch (type) { case Value.NULL: return ValueNull.INSTANCE; case BOOLEAN_TRUE: return ValueBoolean.get(true); case BOOLEAN_FALSE: return ValueBoolean.get(false); case INT_NEG: return ValueInt.get(-readVarInt()); case Value.INT: return ValueInt.get(readVarInt()); case LONG_NEG: return ValueLong.get(-readVarLong()); case Value.LONG: return ValueLong.get(readVarLong()); case Value.BYTE: return ValueByte.get(readByte()); case Value.SHORT: return ValueShort.get(readShortInt()); case DECIMAL_0_1: return (ValueDecimal) ValueDecimal.ZERO; case DECIMAL_0_1 + 1: return (ValueDecimal) ValueDecimal.ONE; case DECIMAL_SMALL_0: return ValueDecimal.get(BigDecimal.valueOf(readVarLong())); case DECIMAL_SMALL: { int scale = readVarInt(); return ValueDecimal.get(BigDecimal.valueOf(readVarLong(), scale)); } case Value.DECIMAL: { int scale = readVarInt(); int len = readVarInt(); byte[] buff = DataUtils.newBytes(len); read(buff, 0, len); BigInteger b = new BigInteger(buff); return ValueDecimal.get(new BigDecimal(b, scale)); } case LOCAL_DATE: { return ValueDate.fromDateValue(readVarLong()); } case Value.DATE: { long x = readVarLong() * MILLIS_PER_MINUTE; return ValueDate.get(new Date(DateTimeUtils.getTimeUTCWithoutDst(x))); } case LOCAL_TIME: { long nanos = readVarLong() * 1000000 + readVarLong(); return ValueTime.fromNanos(nanos); } case Value.TIME: // need to normalize the year, month and day return ValueTime.get(new Time(DateTimeUtils.getTimeUTCWithoutDst(readVarLong()))); case LOCAL_TIMESTAMP: { long dateValue = readVarLong(); long nanos = readVarLong() * 1000000 + readVarLong(); return ValueTimestamp.fromDateValueAndNanos(dateValue, nanos); } case Value.TIMESTAMP: { Timestamp ts = new Timestamp(DateTimeUtils.getTimeUTCWithoutDst(readVarLong())); ts.setNanos(readVarInt()); return ValueTimestamp.get(ts); } case Value.BYTES: { int len = readVarInt(); byte[] b = DataUtils.newBytes(len); read(b, 0, len); return ValueBytes.getNoCopy(b); } case Value.GEOMETRY: { int len = readVarInt(); byte[] b = DataUtils.newBytes(len); read(b, 0, len); return ValueGeometry.get(b); } case Value.JAVA_OBJECT: { int len = readVarInt(); byte[] b = DataUtils.newBytes(len); read(b, 0, len); return ValueJavaObject.getNoCopy(null, b, handler); } case Value.UUID: return ValueUuid.get(readLong(), readLong()); case Value.STRING: return ValueString.get(readString()); case Value.STRING_IGNORECASE: return ValueStringIgnoreCase.get(readString()); case Value.STRING_FIXED: return ValueStringFixed.get(readString()); case FLOAT_0_1: return ValueFloat.get(0); case FLOAT_0_1 + 1: return ValueFloat.get(1); case DOUBLE_0_1: return ValueDouble.get(0); case DOUBLE_0_1 + 1: return ValueDouble.get(1); case Value.DOUBLE: return ValueDouble.get(Double.longBitsToDouble(Long.reverse(readVarLong()))); case Value.FLOAT: return ValueFloat.get(Float.intBitsToFloat(Integer.reverse(readVarInt()))); case Value.BLOB: case Value.CLOB: { int smallLen = readVarInt(); if (smallLen >= 0) { byte[] small = DataUtils.newBytes(smallLen); read(small, 0, smallLen); return ValueLobDb.createSmallLob(type, small); } else if (smallLen == -3) { int tableId = readVarInt(); long lobId = readVarLong(); long precision = readVarLong(); ValueLobDb lob = ValueLobDb.create(type, handler, tableId, lobId, null, precision); return lob; } else { int tableId = readVarInt(); int objectId = readVarInt(); long precision = 0; boolean compression = false; // -1: regular; -2: regular, but not linked (in this case: // including file name) if (smallLen == -1 || smallLen == -2) { precision = readVarLong(); compression = readByte() == 1; } if (smallLen == -2) { String filename = readString(); return ValueLob.openUnlinked( type, handler, tableId, objectId, precision, compression, filename); } return ValueLob.openLinked(type, handler, tableId, objectId, precision, compression); } } case Value.ARRAY: { int len = readVarInt(); Value[] list = new Value[len]; for (int i = 0; i < len; i++) { list[i] = readValue(); } return ValueArray.get(list); } case Value.RESULT_SET: { SimpleResultSet rs = new SimpleResultSet(); rs.setAutoClose(false); int columns = readVarInt(); for (int i = 0; i < columns; i++) { rs.addColumn(readString(), readVarInt(), readVarInt(), readVarInt()); } while (true) { if (readByte() == 0) { break; } Object[] o = new Object[columns]; for (int i = 0; i < columns; i++) { o[i] = readValue().getObject(); } rs.addRow(o); } return ValueResultSet.get(rs); } default: if (type >= INT_0_15 && type < INT_0_15 + 16) { return ValueInt.get(type - INT_0_15); } else if (type >= LONG_0_7 && type < LONG_0_7 + 8) { return ValueLong.get(type - LONG_0_7); } else if (type >= BYTES_0_31 && type < BYTES_0_31 + 32) { int len = type - BYTES_0_31; byte[] b = DataUtils.newBytes(len); read(b, 0, len); return ValueBytes.getNoCopy(b); } else if (type >= STRING_0_31 && type < STRING_0_31 + 32) { return ValueString.get(readString(type - STRING_0_31)); } throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "type: " + type); } }
@Override protected LocalResult queryWithoutCache(int maxRows, ResultTarget target) { if (maxRows != 0) { // maxRows is set (maxRows 0 means no limit) int l; if (limitExpr == null) { l = -1; } else { Value v = limitExpr.getValue(session); l = v == ValueNull.INSTANCE ? -1 : v.getInt(); } if (l < 0) { // for limitExpr, 0 means no rows, and -1 means no limit l = maxRows; } else { l = Math.min(l, maxRows); } limitExpr = ValueExpression.get(ValueInt.get(l)); } if (session.getDatabase().getSettings().optimizeInsertFromSelect) { if (unionType == UNION_ALL && target != null) { if (sort == null && !distinct && maxRows == 0 && offsetExpr == null && limitExpr == null) { left.query(0, target); right.query(0, target); return null; } } } int columnCount = left.getColumnCount(); LocalResult result = new LocalResult(session, expressionArray, columnCount); if (sort != null) { result.setSortOrder(sort); } if (distinct) { left.setDistinct(true); right.setDistinct(true); result.setDistinct(); } if (randomAccessResult) { result.setRandomAccess(); } switch (unionType) { case UNION: case EXCEPT: left.setDistinct(true); right.setDistinct(true); result.setDistinct(); break; case UNION_ALL: break; case INTERSECT: left.setDistinct(true); right.setDistinct(true); break; default: DbException.throwInternalError("type=" + unionType); } ResultInterface l = left.query(0); ResultInterface r = right.query(0); l.reset(); r.reset(); switch (unionType) { case UNION_ALL: case UNION: { while (l.next()) { result.addRow(convert(l.currentRow(), columnCount)); } while (r.next()) { result.addRow(convert(r.currentRow(), columnCount)); } break; } case EXCEPT: { while (l.next()) { result.addRow(convert(l.currentRow(), columnCount)); } while (r.next()) { result.removeDistinct(convert(r.currentRow(), columnCount)); } break; } case INTERSECT: { LocalResult temp = new LocalResult(session, expressionArray, columnCount); temp.setDistinct(); temp.setRandomAccess(); while (l.next()) { temp.addRow(convert(l.currentRow(), columnCount)); } while (r.next()) { Value[] values = convert(r.currentRow(), columnCount); if (temp.containsDistinct(values)) { result.addRow(values); } } break; } default: DbException.throwInternalError("type=" + unionType); } if (offsetExpr != null) { result.setOffset(offsetExpr.getValue(session).getInt()); } if (limitExpr != null) { Value v = limitExpr.getValue(session); if (v != ValueNull.INSTANCE) { result.setLimit(v.getInt()); } } result.done(); if (target != null) { while (result.next()) { target.addRow(result.currentRow()); } result.close(); return null; } return result; }