提交 3ab5f276 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 a49fa5aa
......@@ -21,7 +21,7 @@ import org.h2.value.ValueResultSet;
/**
* This class represents the statement
* CALL
* CALL.
*/
public class Call extends Prepared {
private Expression value;
......@@ -37,6 +37,23 @@ public class Call extends Prepared {
return result;
}
public int update() throws SQLException {
Value v = value.getValue(session);
int type = v.getType();
switch(type) {
case Value.RESULT_SET:
case Value.ARRAY:
// this will throw an exception
// methods returning a result set may not be called like this.
return super.update();
case Value.UNKNOWN:
case Value.NULL:
return 0;
default:
return v.getInt();
}
}
public LocalResult query(int maxrows) throws SQLException {
setCurrentRowNumber(1);
Value v = value.getValue(session);
......
......@@ -132,6 +132,10 @@ public class ScriptCommand extends ScriptBase {
ObjectArray settings = db.getAllSettings();
for (int i = 0; i < settings.size(); i++) {
Setting setting = (Setting) settings.get(i);
if (setting.getName().equals(SetTypes.getTypeName(SetTypes.CREATE_BUILD))) {
// don't add CREATE_BUILD to the script (it is only set when creating the database)
continue;
}
add(setting.getCreateSQL(), false);
}
}
......
......@@ -280,6 +280,16 @@ public class Set extends Prepared {
database.setExclusiveSession(value == 1 ? session : null);
break;
}
case SetTypes.CREATE_BUILD: {
session.getUser().checkAdmin();
if (database.isStarting()) {
// just ignore the command if not starting
// this avoids problems when running recovery scripts
int value = getIntValue();
addOrUpdateSetting(name, null, value);
}
break;
}
default:
throw Message.getInternalError("type="+type);
}
......
......@@ -21,6 +21,7 @@ public class SetTypes {
public static final int COMPRESS_LOB = 23, ALLOW_LITERALS = 24, MULTI_THREADED = 25, SCHEMA = 26;
public static final int OPTIMIZE_REUSE_RESULTS = 27, SCHEMA_SEARCH_PATH = 28, UNDO_LOG = 29;
public static final int REFERENTIAL_INTEGRITY = 30, MVCC = 31, MAX_OPERATION_MEMORY = 32, EXCLUSIVE = 33;
public static final int CREATE_BUILD = 34;
private static ObjectArray types = new ObjectArray();
......@@ -58,6 +59,7 @@ public class SetTypes {
setType(MVCC, "MVCC");
setType(MAX_OPERATION_MEMORY, "MAX_OPERATION_MEMORY");
setType(EXCLUSIVE, "EXCLUSIVE");
setType(CREATE_BUILD, "CREATE_BUILD");
}
private static void setType(int type, String name) {
......
......@@ -63,12 +63,12 @@ import org.h2.value.ValueInt;
/**
* There is one database object per open database.
*
* The format of the meta data table is:
* id int, headPos int (for indexes), objectType int, sql varchar
*
* @since 2004-04-15 22:49
*/
/*
* MetaData format: int id int headPos (for indexes) int objectType String sql
*/
public class Database implements DataHandler {
private final boolean persistent;
......@@ -539,6 +539,7 @@ public class Database implements DataHandler {
addDefaultSetting(systemSession, SetTypes.CACHE_SIZE, null, SysProperties.CACHE_SIZE_DEFAULT);
addDefaultSetting(systemSession, SetTypes.CLUSTER, Constants.CLUSTERING_DISABLED, 0);
addDefaultSetting(systemSession, SetTypes.WRITE_DELAY, null, Constants.DEFAULT_WRITE_DELAY);
addDefaultSetting(systemSession, SetTypes.CREATE_BUILD, null, Constants.BUILD_ID);
if (!readOnly) {
removeUnusedStorages(systemSession);
}
......
......@@ -172,6 +172,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
public long getCostRangeIndex(int[] masks, long rowCount) throws SQLException {
rowCount += Constants.COST_ROW_OFFSET;
long cost = rowCount;
long rows = rowCount;
int totalSelectivity = 0;
for (int i = 0; masks != null && i < columns.length; i++) {
Column column = columns[i];
......@@ -187,19 +188,16 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
if (distinctRows <= 0) {
distinctRows = 1;
}
long rowsSelected = rowCount / distinctRows;
if (rowsSelected < 1) {
rowsSelected = 1;
}
cost = getLookupCost(rowCount) + rowsSelected;
rows = Math.max(rowCount / distinctRows, 1);
cost = getLookupCost(rowCount) + rows;
} else if ((mask & IndexCondition.RANGE) == IndexCondition.RANGE) {
cost = getLookupCost(rowCount) + rowCount / 4;
cost = getLookupCost(rowCount) + rows / 4;
break;
} else if ((mask & IndexCondition.START) == IndexCondition.START) {
cost = getLookupCost(rowCount) + rowCount / 3;
cost = getLookupCost(rowCount) + rows / 3;
break;
} else if ((mask & IndexCondition.END) == IndexCondition.END) {
cost = rowCount / 3;
cost = rows / 3;
break;
} else {
break;
......
......@@ -75,7 +75,7 @@ public class NetUtils {
}
synchronized (NetUtils.class) {
if (bindAddress == null) {
bindAddress = InetAddress.getByName(host);
bindAddress = InetAddress.getByAddress(InetAddress.getByName(host).getAddress());
}
}
return bindAddress;
......
......@@ -150,29 +150,25 @@ java org.h2.test.TestAll timer
/*
h2CallableStatementBatchTest.zip
h2-2007-12-27_test.zip
Roadmap:
History:
Roadmap:
Automatically switch source code before compiling
staging.trace.db.gz
There is a problem with the h2.bindAddress build. When it is binding to 127.0.0.1,
the bind function works perfectly and I could confirm it no longer
listen to the ports of other IP addresses. However, when it is binding to normal IP
addresses, it always got the following exception.
Caused by: org.h2.jdbc.JdbcSQLException: Connection is broken [90067-64]
at org.h2.message.Message.getSQLException(Message.java:89)
Remarks: I build with JDK 1.6
drop table logs;
CREATE TABLE Logs(id INT PRIMARY KEY, procid INT);
CREATE unique INDEX procIdx ON Logs(procid, id);
@LOOP 1000 INSERT INTO Logs VALUES(?, MOD(?, 100000));
ANALYZE SAMPLE_SIZE 0;
script nodata;
EXPLAIN SELECT id FROM Logs WHERE procid=2 AND id<100;
Test Recovery with MAX_LOG_FILE_SIZE=1; test with various log file sizes
allow queries as well in batch updates
CALL syntax should probably work for regular executeUpdate as well.
http://java.sun.com/j2se/1.4.2/docs/guide/jdbc/getstart/callablestatement.html#1000220
Test H2 on OS X (result are here: h2-2007-12-27_test.zip)
write to the db file what version was used to create a database
Docs:
H2 can emulate PostgreSQL server.
Web site:
link to history page, bug page
......
......@@ -24,6 +24,7 @@ public class TestOptimizations extends TestBase {
if (config.networked) {
return;
}
testMultiColumnRangeQuery();
testDistinctOptimization();
testQueryCacheTimestamp();
testQueryCacheSpeed();
......@@ -34,6 +35,22 @@ public class TestOptimizations extends TestBase {
testMinMaxCountOptimization(false);
}
private void testMultiColumnRangeQuery() throws Exception {
deleteDb("optimizations");
Connection conn = getConnection("optimizations");
Statement stat = conn.createStatement();
stat.execute("CREATE TABLE Logs(id INT PRIMARY KEY, type INT)");
stat.execute("CREATE unique INDEX type_index ON Logs(type, id)");
stat.execute("INSERT INTO Logs SELECT X, MOD(X, 3) FROM SYSTEM_RANGE(1, 1000)");
stat.execute("ANALYZE SAMPLE_SIZE 0");
ResultSet rs;
rs = stat.executeQuery("EXPLAIN SELECT id FROM Logs WHERE id < 100 and type=2 AND id<100");
rs.next();
String plan = rs.getString(1);
check(plan.indexOf("TYPE_INDEX") > 0);
conn.close();
}
private void testDistinctOptimization() throws Exception {
deleteDb("optimizations");
Connection conn = getConnection("optimizations");
......
......@@ -7,6 +7,7 @@ package org.h2.test.jdbc;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.sql.BatchUpdateException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
......@@ -38,10 +39,36 @@ public class TestBatchUpdates extends TestBase {
PreparedStatement prep;
public void test() throws Exception {
testExecuteCall();
testException();
testCoffee();
}
private void testExecuteCall() throws Exception {
deleteDb("batchUpdates");
Connection conn = getConnection("batchUpdates");
Statement stat = conn.createStatement();
stat.execute("CREATE ALIAS updatePrices FOR \"" + getClass().getName() + ".updatePrices\"");
CallableStatement call = conn.prepareCall("{call updatePrices(?, ?)}");
call.setString(1, "Hello");
call.setFloat(2, 1.4f);
call.addBatch();
call.setString(1, "World");
call.setFloat(2, 3.2f);
call.addBatch();
int[] updateCounts = call.executeBatch();
int total = 0;
for (int i = 0; i < updateCounts.length; i++) {
total += updateCounts[i];
}
check(4, total);
conn.close();
}
public static int updatePrices(String s, double f) {
return (int) f;
}
private void testException() throws Exception {
deleteDb("batchUpdates");
Connection conn = getConnection("batchUpdates");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论