提交 26279c42 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 7d29e8e0
...@@ -13,6 +13,7 @@ import org.h2.engine.Session; ...@@ -13,6 +13,7 @@ import org.h2.engine.Session;
import org.h2.log.LogSystem; import org.h2.log.LogSystem;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.LocalResult; import org.h2.result.LocalResult;
import org.h2.util.TempFileDeleter;
/** /**
* Represents a transactional statement. * Represents a transactional statement.
...@@ -66,6 +67,7 @@ public class TransactionCommand extends Prepared { ...@@ -66,6 +67,7 @@ public class TransactionCommand extends Prepared {
case CHECKPOINT: case CHECKPOINT:
session.getUser().checkAdmin(); session.getUser().checkAdmin();
session.getDatabase().getLog().checkpoint(); session.getDatabase().getLog().checkpoint();
TempFileDeleter.deleteUnused();
break; break;
case SAVEPOINT: case SAVEPOINT:
session.addSavepoint(savepointName); session.addSavepoint(savepointName);
......
...@@ -217,7 +217,9 @@ public class SysProperties { ...@@ -217,7 +217,9 @@ public class SysProperties {
* more than this number of rows are in a result set, a temporary table is * more than this number of rows are in a result set, a temporary table is
* used. * used.
*/ */
public static final int MAX_MEMORY_ROWS_DISTINCT = getIntSetting("h2.maxMemoryRowsDistinct", Integer.MAX_VALUE); private int testing;
// public static final int MAX_MEMORY_ROWS_DISTINCT = getIntSetting("h2.maxMemoryRowsDistinct", Integer.MAX_VALUE);
public static final int MAX_MEMORY_ROWS_DISTINCT = getIntSetting("h2.maxMemoryRowsDistinct", 1);
/** /**
* System property <code>h2.maxQueryTimeout</code> (default: 0).<br /> * System property <code>h2.maxQueryTimeout</code> (default: 0).<br />
......
...@@ -68,7 +68,7 @@ public class Session implements SessionInterface { ...@@ -68,7 +68,7 @@ public class Session implements SessionInterface {
private String currentSchemaName; private String currentSchemaName;
private String[] schemaSearchPath; private String[] schemaSearchPath;
private String traceModuleName; private String traceModuleName;
private HashSet unlinkSet; private HashMap unlinkMap;
private int tempViewIndex; private int tempViewIndex;
private HashMap procedures; private HashMap procedures;
private static int nextSerialId; private static int nextSerialId;
...@@ -279,16 +279,16 @@ public class Session implements SessionInterface { ...@@ -279,16 +279,16 @@ public class Session implements SessionInterface {
autoCommitAtTransactionEnd = false; autoCommitAtTransactionEnd = false;
} }
} }
if (unlinkSet != null && unlinkSet.size() > 0) { if (unlinkMap != null && unlinkMap.size() > 0) {
// need to flush the log file, because we can't unlink lobs if the // need to flush the log file, because we can't unlink lobs if the
// commit record is not written // commit record is not written
logSystem.flush(); logSystem.flush();
Iterator it = unlinkSet.iterator(); Iterator it = unlinkMap.values().iterator();
while (it.hasNext()) { while (it.hasNext()) {
Value v = (Value) it.next(); Value v = (Value) it.next();
v.unlink(); v.unlink();
} }
unlinkSet = null; unlinkMap = null;
} }
unlockAll(); unlockAll();
} }
...@@ -635,15 +635,15 @@ public class Session implements SessionInterface { ...@@ -635,15 +635,15 @@ public class Session implements SessionInterface {
} }
public void unlinkAtCommit(Value v) { public void unlinkAtCommit(Value v) {
if (unlinkSet == null) { if (unlinkMap == null) {
unlinkSet = new HashSet(); unlinkMap = new HashMap();
} }
unlinkSet.add(v); unlinkMap.put(v.toString(), v);
} }
public void unlinkAtCommitStop(Value v) { public void unlinkAtCommitStop(Value v) {
if (unlinkSet != null) { if (unlinkMap != null) {
unlinkSet.remove(v); unlinkMap.remove(v.toString());
} }
} }
......
...@@ -104,7 +104,9 @@ public class ScanIndex extends BaseIndex { ...@@ -104,7 +104,9 @@ public class ScanIndex extends BaseIndex {
for (int i = 0; i < row.getColumnCount(); i++) { for (int i = 0; i < row.getColumnCount(); i++) {
Value v = row.getValue(i); Value v = row.getValue(i);
Value v2 = v.link(database, getId()); Value v2 = v.link(database, getId());
if (v2.isLinked()) {
session.unlinkAtCommitStop(v2); session.unlinkAtCommitStop(v2);
}
if (v != v2) { if (v != v2) {
row.setValue(i, v2); row.setValue(i, v2);
} }
......
...@@ -218,7 +218,7 @@ public class LocalResult implements ResultInterface { ...@@ -218,7 +218,7 @@ public class LocalResult implements ResultInterface {
distinctRows.put(array, values); distinctRows.put(array, values);
rowCount = distinctRows.size(); rowCount = distinctRows.size();
if (rowCount > SysProperties.MAX_MEMORY_ROWS_DISTINCT) { if (rowCount > SysProperties.MAX_MEMORY_ROWS_DISTINCT) {
disk = new ResultDiskBuffer(session, sort, values.length); disk = new ResultTempTable(session, sort, values.length);
disk.addRows(distinctRows.values()); disk.addRows(distinctRows.values());
distinctRows = null; distinctRows = null;
} }
...@@ -231,7 +231,7 @@ public class LocalResult implements ResultInterface { ...@@ -231,7 +231,7 @@ public class LocalResult implements ResultInterface {
rowCount++; rowCount++;
if (rows.size() > maxMemoryRows && session.getDatabase().isPersistent()) { if (rows.size() > maxMemoryRows && session.getDatabase().isPersistent()) {
if (disk == null) { if (disk == null) {
disk = new ResultTempTable(session, sort, values.length); disk = new ResultDiskBuffer(session, sort, values.length);
} }
addRowsToDisk(); addRowsToDisk();
} }
...@@ -251,6 +251,31 @@ public class LocalResult implements ResultInterface { ...@@ -251,6 +251,31 @@ public class LocalResult implements ResultInterface {
if (distinctRows != null) { if (distinctRows != null) {
rows = distinctRows.values(); rows = distinctRows.values();
distinctRows = null; distinctRows = null;
} else {
if (disk != null && sort != null) {
// external sort
ResultExternal temp = disk;
disk = null;
temp.reset();
rows = new ObjectArray();
// TODO use offset directly if possible
while (true) {
Value[] list = temp.next();
if (list == null) {
break;
}
if (disk == null) {
disk = new ResultDiskBuffer(session, sort, list.length);
}
rows.add(list);
if (rows.size() > maxMemoryRows) {
disk.addRows(rows);
rows.clear();
}
}
temp.close();
// the remaining data in rows is written in the following lines
}
} }
} }
if (disk != null) { if (disk != null) {
......
...@@ -9,9 +9,11 @@ import java.sql.SQLException; ...@@ -9,9 +9,11 @@ import java.sql.SQLException;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.index.BtreeIndex;
import org.h2.index.Cursor; import org.h2.index.Cursor;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.index.IndexType; import org.h2.index.IndexType;
import org.h2.message.Message;
import org.h2.schema.Schema; import org.h2.schema.Schema;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.IndexColumn; import org.h2.table.IndexColumn;
...@@ -19,7 +21,6 @@ import org.h2.table.TableData; ...@@ -19,7 +21,6 @@ import org.h2.table.TableData;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueArray; import org.h2.value.ValueArray;
import org.h2.value.ValueUuid;
/** /**
* This class implements the temp table buffer for the LocalResult class. * This class implements the temp table buffer for the LocalResult class.
...@@ -35,13 +36,13 @@ public class ResultTempTable implements ResultExternal { ...@@ -35,13 +36,13 @@ public class ResultTempTable implements ResultExternal {
public ResultTempTable(Session session, SortOrder sort, int columnCount) throws SQLException { public ResultTempTable(Session session, SortOrder sort, int columnCount) throws SQLException {
this.session = session; this.session = session;
this.sort = sort; this.sort = sort;
String tableName = "TEMP_" + ValueUuid.getNewRandom().toString();
Schema schema = session.getDatabase().getSchema(Constants.SCHEMA_MAIN); Schema schema = session.getDatabase().getSchema(Constants.SCHEMA_MAIN);
Column column = new Column(COLUMN_NAME, Value.ARRAY); Column column = new Column(COLUMN_NAME, Value.ARRAY);
column.setNullable(false); column.setNullable(false);
ObjectArray columns = new ObjectArray(); ObjectArray columns = new ObjectArray();
columns.add(column); columns.add(column);
int tableId = session.getDatabase().allocateObjectId(true, true); int tableId = session.getDatabase().allocateObjectId(true, true);
String tableName = "TEMP_RESULT_SET_" + tableId;
table = schema.createTable(tableName, tableId, columns, false, false); table = schema.createTable(tableName, tableId, columns, false, false);
int indexId = session.getDatabase().allocateObjectId(true, true); int indexId = session.getDatabase().allocateObjectId(true, true);
IndexColumn indexColumn = new IndexColumn(); IndexColumn indexColumn = new IndexColumn();
...@@ -50,27 +51,30 @@ public class ResultTempTable implements ResultExternal { ...@@ -50,27 +51,30 @@ public class ResultTempTable implements ResultExternal {
IndexType indexType; IndexType indexType;
indexType = IndexType.createPrimaryKey(true, false); indexType = IndexType.createPrimaryKey(true, false);
IndexColumn[] indexCols = new IndexColumn[]{indexColumn}; IndexColumn[] indexCols = new IndexColumn[]{indexColumn};
index = table.addIndex(session, tableName, indexId, indexCols, indexType, Index.EMPTY_HEAD, null); index = new BtreeIndex(session, table, indexId, tableName, indexCols, indexType, Index.EMPTY_HEAD);
table.getIndexes().add(index);
} }
public int removeRow(Value[] values) throws SQLException { public int removeRow(Value[] values) throws SQLException {
ValueArray data = ValueArray.get(values); Row row = convertToRow(values);
Row row = new Row(new Value[]{data}, data.getMemory()); Cursor cursor = find(row);
if (cursor != null) {
row = cursor.get();
table.removeRow(session, row); table.removeRow(session, row);
}
return (int) table.getRowCount(session); return (int) table.getRowCount(session);
} }
public boolean contains(Value[] values) throws SQLException { public boolean contains(Value[] values) throws SQLException {
ValueArray data = ValueArray.get(values); return find(convertToRow(values)) != null;
Row row = new Row(new Value[]{data}, data.getMemory());
Cursor cursor = index.find(session, row, row);
return cursor.next();
} }
public int addRow(Value[] values) throws SQLException { public int addRow(Value[] values) throws SQLException {
ValueArray data = ValueArray.get(values); Row row = convertToRow(values);
Row row = new Row(new Value[]{data}, data.getMemory()); Cursor cursor = find(row);
if (cursor == null) {
table.addRow(session, row); table.addRow(session, row);
}
return (int) table.getRowCount(session); return (int) table.getRowCount(session);
} }
...@@ -85,13 +89,17 @@ public class ResultTempTable implements ResultExternal { ...@@ -85,13 +89,17 @@ public class ResultTempTable implements ResultExternal {
} }
public void close() { public void close() {
int todo;
try { try {
if (table != null) {
index.remove(session); index.remove(session);
ObjectArray indexes = table.getIndexes();
indexes.remove(indexes.indexOf(index));
table.removeChildrenAndResources(session); table.removeChildrenAndResources(session);
}
} catch (SQLException e) { } catch (SQLException e) {
int test; throw Message.getInternalError();
e.printStackTrace(); } finally {
table = null;
} }
} }
...@@ -110,5 +118,23 @@ public class ResultTempTable implements ResultExternal { ...@@ -110,5 +118,23 @@ public class ResultTempTable implements ResultExternal {
public void reset() throws SQLException { public void reset() throws SQLException {
cursor = index.find(session, null, null); cursor = index.find(session, null, null);
} }
private Row convertToRow(Value[] values) {
ValueArray data = ValueArray.get(values);
return new Row(new Value[]{data}, data.getMemory());
}
private Cursor find(Row row) throws SQLException {
Cursor cursor = index.find(session, row, row);
while (cursor.next()) {
SearchRow found;
found = cursor.getSearchRow();
if (found.getValue(0).equals(row.getValue(0))) {
return cursor;
}
}
return null;
}
} }
...@@ -35,6 +35,7 @@ public class TempFileDeleter { ...@@ -35,6 +35,7 @@ public class TempFileDeleter {
if (SysProperties.CHECK && f2 != null && fileName != null && !f2.equals(fileName)) { if (SysProperties.CHECK && f2 != null && fileName != null && !f2.equals(fileName)) {
throw Message.getInternalError("f2:" + f2 + " f:" + fileName); throw Message.getInternalError("f2:" + f2 + " f:" + fileName);
} }
fileName = f2;
} }
if (fileName != null && FileUtils.exists(fileName)) { if (fileName != null && FileUtils.exists(fileName)) {
try { try {
...@@ -43,7 +44,6 @@ public class TempFileDeleter { ...@@ -43,7 +44,6 @@ public class TempFileDeleter {
} catch (Exception e) { } catch (Exception e) {
// TODO log such errors? // TODO log such errors?
} }
deleteUnused();
} }
} }
......
...@@ -519,7 +519,7 @@ public class ValueLob extends Value { ...@@ -519,7 +519,7 @@ public class ValueLob extends Value {
try { try {
hash = ByteUtils.getByteArrayHash(getBytes()); hash = ByteUtils.getByteArrayHash(getBytes());
} catch (SQLException e) { } catch (SQLException e) {
// TODO hash code for lob: should not ignore exception throw Message.convertToInternal(e);
} }
} }
return hash; return hash;
...@@ -607,7 +607,6 @@ public class ValueLob extends Value { ...@@ -607,7 +607,6 @@ public class ValueLob extends Value {
} }
public int getDisplaySize() { public int getDisplaySize() {
// TODO display size of lob?
return MathUtils.convertLongToInt(getPrecision()); return MathUtils.convertLongToInt(getPrecision());
} }
......
...@@ -159,6 +159,34 @@ java org.h2.test.TestAll timer ...@@ -159,6 +159,34 @@ java org.h2.test.TestAll timer
/* /*
disk based select distinct; order by:
DROP TABLE TEST;
CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255), VALUE DECIMAL(10,2));
INSERT INTO TEST VALUES(1,'Apples',1.20),
(2,'Oranges',2.05),
(3,'Cherries',5.10),
(4,'Apples',1.50),
(5,'Apples',1.10),
(6,'Oranges',1.80),
(7,'Bananas',2.50),
(8,NULL,3.10),
(9,NULL,-10.0);
SELECT DISTINCT NAME FROM TEST;
select distinct x from system_range(1, 200000);
CREATE TABLE p(d DATE);
INSERT INTO p VALUES('0000-01-01');
INSERT INTO p VALUES('0001-01-01');
check that test data in temp directories
add jdbcx to Javadocs
out of memory problem: out of memory problem:
java -XX:+HeapDumpOnOutOfMemoryError -Xmx1024m -cp bin/h2.jar org.h2.tools.Server -log true java -XX:+HeapDumpOnOutOfMemoryError -Xmx1024m -cp bin/h2.jar org.h2.tools.Server -log true
jdbc:h2:test;CACHE_SIZE=10000 jdbc:h2:test;CACHE_SIZE=10000
...@@ -169,17 +197,11 @@ CREATE TABLE secondtable (field1 number(10) not null, field2 number(8)); ...@@ -169,17 +197,11 @@ CREATE TABLE secondtable (field1 number(10) not null, field2 number(8));
create index idx_number1 on secondtable(field1); create index idx_number1 on secondtable(field1);
The table 'secondtable' contains a little over 100.000.000 records. The table 'secondtable' contains a little over 100.000.000 records.
disk based select distinct; order by Read HenPlus features
set max_memory_rows 10; http://henplus.sourceforge.net/
select distinct x from system_range(1, 200000);
set max_memory_rows 10000;
newsletter.sql newsletter.sql
BlobTestCase2
H2BlobWriteTester
add link to new in use, links add link to new in use, links
Add google site search to web page Add google site search to web page
...@@ -208,10 +230,13 @@ Can sometimes not delete log file? need test case ...@@ -208,10 +230,13 @@ Can sometimes not delete log file? need test case
Add where required // TODO: change in version 1.1 Add where required // TODO: change in version 1.1
History: History:
Very large SELECT DISTINCT and UNION EXCEPT queries are now supported.
Improved support for IKVM. Improved support for IKVM.
A error is now thrown when trying to call a method A error is now thrown when trying to call a method
inside a trigger that implicitly commits the current transaction, inside a trigger that implicitly commits the current transaction,
if an object is locked. if an object is locked.
Unused LOB files were deleted much too late.
Now they are deleted if no longer referenced in memory.
Roadmap: Roadmap:
......
...@@ -30,7 +30,11 @@ import org.h2.tools.DeleteDbFiles; ...@@ -30,7 +30,11 @@ import org.h2.tools.DeleteDbFiles;
*/ */
public abstract class TestBase { public abstract class TestBase {
protected static String baseDir = "data"; public static String getTestDir(String name) {
return System.getProperty("java.io.tmpdir") + "/dbtest-" + name;
}
protected static String baseDir = System.getProperty("java.io.tmpdir") + "/dbtest";
protected TestAll config; protected TestAll config;
private long start; private long start;
......
...@@ -19,9 +19,11 @@ import java.sql.ResultSet; ...@@ -19,9 +19,11 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Savepoint; import java.sql.Savepoint;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList;
import java.util.Random; import java.util.Random;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.store.FileLister;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
...@@ -35,6 +37,7 @@ public class TestLob extends TestBase { ...@@ -35,6 +37,7 @@ public class TestLob extends TestBase {
if (config.memory) { if (config.memory) {
return; return;
} }
testLobDelete();
testLobVariable(); testLobVariable();
testLobDrop(); testLobDrop();
testLobNoClose(); testLobNoClose();
...@@ -56,6 +59,37 @@ public class TestLob extends TestBase { ...@@ -56,6 +59,37 @@ public class TestLob extends TestBase {
testJavaObject(); testJavaObject();
} }
private void testLobDelete() throws Exception {
if (config.memory) {
return;
}
deleteDb("lob");
Connection conn = reconnect(null);
Statement stat = conn.createStatement();
stat.execute("CREATE TABLE TEST(ID INT, DATA CLOB)");
stat.execute("INSERT INTO TEST SELECT X, SPACE(10000) FROM SYSTEM_RANGE(1, 10)");
ArrayList list = FileLister.getDatabaseFiles(baseDir, "lob", true);
stat.execute("UPDATE TEST SET DATA = SPACE(5000)");
for (int i = 0; i < 3; i++) {
System.gc();
}
stat.execute("CHECKPOINT");
ArrayList list2 = FileLister.getDatabaseFiles(baseDir, "lob", true);
if (list2.size() >= list.size() + 2) {
error("Expected not many more files, got " + list2.size() + " was " + list.size());
}
stat.execute("DELETE FROM TEST");
for (int i = 0; i < 3; i++) {
System.gc();
}
stat.execute("CHECKPOINT");
ArrayList list3 = FileLister.getDatabaseFiles(baseDir, "lob", true);
if (list3.size() >= list.size()) {
error("Expected less files, got " + list2.size() + " was " + list.size());
}
conn.close();
}
private void testLobVariable() throws Exception { private void testLobVariable() throws Exception {
deleteDb("lob"); deleteDb("lob");
Connection conn = reconnect(null); Connection conn = reconnect(null);
......
...@@ -30,7 +30,7 @@ public class TestBtreeIndex extends TestBase { ...@@ -30,7 +30,7 @@ public class TestBtreeIndex extends TestBase {
} }
public void testCase(int seed) throws Exception { public void testCase(int seed) throws Exception {
baseDir = "dataIndex"; baseDir = TestBase.getTestDir("index");
testOne(seed); testOne(seed);
baseDir = "data"; baseDir = "data";
} }
......
...@@ -389,7 +389,7 @@ public class TestCrashAPI extends TestBase { ...@@ -389,7 +389,7 @@ public class TestCrashAPI extends TestBase {
if (config.mvcc || config.networked || config.logMode == 0) { if (config.mvcc || config.networked || config.logMode == 0) {
return this; return this;
} }
baseDir = "dataCrash"; baseDir = TestBase.getTestDir("crash");
startServerIfRequired(); startServerIfRequired();
TestScript script = new TestScript(); TestScript script = new TestScript();
ArrayList add = script.getAllStatements(config, "org/h2/test/test.in.txt"); ArrayList add = script.getAllStatements(config, "org/h2/test/test.in.txt");
......
...@@ -38,7 +38,7 @@ public abstract class TestHalt extends TestBase { ...@@ -38,7 +38,7 @@ public abstract class TestHalt extends TestBase {
private int errorId; private int errorId;
private int sequenceId; private int sequenceId;
private static final String DATABASE_NAME = "halt"; private static final String DATABASE_NAME = "halt";
static final String DIR = "dataHalt"; static final String DIR = TestBase.getTestDir("halt");
private static final String TRACE_FILE_NAME = "haltTrace.trace.db"; private static final String TRACE_FILE_NAME = "haltTrace.trace.db";
abstract void testInit() throws Exception; abstract void testInit() throws Exception;
......
...@@ -31,9 +31,10 @@ public class TestJoin extends TestBase { ...@@ -31,9 +31,10 @@ public class TestJoin extends TestBase {
private StringBuffer buff; private StringBuffer buff;
public void test() throws Exception { public void test() throws Exception {
baseDir = "dataJoin"; String old = baseDir;
baseDir = TestBase.getTestDir("join");
testJoin(); testJoin();
baseDir = "data"; baseDir = old;
} }
private void testJoin() throws Exception { private void testJoin() throws Exception {
......
...@@ -25,7 +25,7 @@ public class TestKill extends TestBase { ...@@ -25,7 +25,7 @@ public class TestKill extends TestBase {
Connection conn; Connection conn;
int accounts = 10; int accounts = 10;
Random random = new Random(1); Random random = new Random(1);
private static final String DIR = "synth"; private static final String DIR = TestBase.getTestDir("kill");
public void test() throws Exception { public void test() throws Exception {
String connect = ""; String connect = "";
......
...@@ -217,7 +217,7 @@ public class TestSynth extends TestBase { ...@@ -217,7 +217,7 @@ public class TestSynth extends TestBase {
public TestBase init(TestAll conf) throws Exception { public TestBase init(TestAll conf) throws Exception {
super.init(conf); super.init(conf);
baseDir = "dataSynth"; baseDir = TestBase.getTestDir("synth");
deleteDb("synth"); deleteDb("synth");
databases = new ArrayList(); databases = new ArrayList();
......
...@@ -6744,6 +6744,23 @@ SELECT DISTINCT NAME FROM TEST; ...@@ -6744,6 +6744,23 @@ SELECT DISTINCT NAME FROM TEST;
> null > null
> rows: 5 > rows: 5
SELECT DISTINCT NAME FROM TEST ORDER BY NAME DESC NULLS LAST;
> NAME
> --------
> Oranges
> Cherries
> Bananas
> Apples
> null
> rows (ordered): 5
SELECT DISTINCT NAME FROM TEST ORDER BY NAME DESC NULLS LAST LIMIT 2 OFFSET 1;
> NAME
> --------
> Cherries
> Bananas
> rows (ordered): 2
SELECT NAME, COUNT(*), SUM(VALUE), MAX(VALUE), MIN(VALUE), AVG(VALUE), COUNT(DISTINCT VALUE) FROM TEST GROUP BY NAME; SELECT NAME, COUNT(*), SUM(VALUE), MAX(VALUE), MIN(VALUE), AVG(VALUE), COUNT(DISTINCT VALUE) FROM TEST GROUP BY NAME;
> NAME COUNT(*) SUM(VALUE) MAX(VALUE) MIN(VALUE) AVG(VALUE) COUNT(DISTINCT VALUE) > NAME COUNT(*) SUM(VALUE) MAX(VALUE) MIN(VALUE) AVG(VALUE) COUNT(DISTINCT VALUE)
> -------- -------- ---------- ---------- ---------- ----------------------------- --------------------- > -------- -------- ---------- ---------- ---------- ----------------------------- ---------------------
......
...@@ -56,7 +56,7 @@ public class TestFileSystem extends TestBase { ...@@ -56,7 +56,7 @@ public class TestFileSystem extends TestBase {
stat.execute("backup to '" + baseDir + "/fsJar.zip'"); stat.execute("backup to '" + baseDir + "/fsJar.zip'");
conn.close(); conn.close();
deleteDb(baseDir + "/fsJar"); deleteDb("fsJar");
FileSystem fs = FileSystem.getInstance("zip:" + baseDir + "/fsJar.zip"); FileSystem fs = FileSystem.getInstance("zip:" + baseDir + "/fsJar.zip");
String[] files = fs.listFiles("zip:" + baseDir + "/fsJar.zip"); String[] files = fs.listFiles("zip:" + baseDir + "/fsJar.zip");
for (int i = 0; i < files.length; i++) { for (int i = 0; i < files.length; i++) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论