提交 774b1795 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 dae44578
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
<!--
Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>H2 データベース エンジン</title>
<script type="text/javascript" src="navigation.js"></script>
<link rel="stylesheet" type="text/css" href="stylesheet.css" />
<link rel="alternate" type="application/atom+xml" title="H2 Newsfeed" href="http://www.h2database.com/html/newsfeed-atom.xml" />
<link rel="alternate" type="application/rss+xml" title="H2 Newsfeed" href="http://www.h2database.com/html/newsfeed-rss.xml" />
</head>
<frameset cols="180,*" rows="*" frameborder="2" framespacing="4" border="4" onLoad="loadFrameset()">
<frame frameborder="0" marginheight="0" marginwidth="0" src="search_ja.html" name="menu" />
<frame frameborder="0" marginheight="0" marginwidth="0" src="main_ja.html" name="main" />
</frameset>
<noframes>
<body>
<p>
H2 (for 'Hypersonic 2') is free a Java SQL DBMS.
Clustering, embedded and server mode, transactions, referential integrity,
views, subqueries, triggers, encryption, and disk based or in-memory operation
are supported. A browser based console application is included.
If you see this page your browser does not support frames.
Please click here to view the <a href="search_ja.html">index</a>.
</p>
</body>
</noframes>
</html>
......@@ -1125,6 +1125,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
</li><li>In MySQL mode, for AUTO_INCREMENT columns, don't set the primary key
</li><li>Use JDK 1.4 file locking to create the lock file (but not yet by default); writing a system property to detect concurrent access from the same VM (different classloaders).
</li><li>Read-only sessions (Connection.setReadOnly)
</li><li>Support compatibility for jdbc:hsqldb:res:
</li></ul>
<h3>Not Planned</h3>
......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="ja">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Installation
</title><link rel="stylesheet" type="text/css" href="stylesheet.css" />
<script type="text/javascript" src="navigation.js"></script>
</head><body onload="frameMe();">
<table class="content"><tr class="content"><td class="content"><div class="contentDiv">
<h1>インストール</h1>
<a href="#requirements">
必要条件</a><br />
<a href="#supported_platforms">
サポートされているプラットフォーム</a><br />
<a href="#installing">
ソフトウェアのインストール </a><br />
<a href="#directory_structure">
ディレクトリ構成</a><br />
<br /><a name="requirements"></a>
<h2>必要条件</h2>
<p>
データベースを実行するために、以下のソフトウェアが動作することを確認します。 互換性のあるソフトウェアでも動作しますが、テストはされていません。
</p>
<ul>
<li>Windows XP, MacOS, or Linux
</li><li>Recommended Windows file system: NTFS (FAT32 supports files up to 4 GB)
</li><li>Sun JDK 1.4 or newer
</li><li>Mozilla Firefox 1.5 or newer
</li></ul>
<br /><a name="supported_platforms"></a>
<h2>サポートされているプラットフォーム</h2>
<p>
このデータベースはJavaで書かれているため、多くの異なったプラットフォームで実行することができます。 Java 1.4 と 1.5でテストされましたが、GCJを使用することでネイティブコードにコンパイルすることもできます。 ソースコードはJava 1.5の特徴は使われていません。現在、データベースはWindows XPでSun JDKを使用して開発、テストされていますが、 おそらく、他の多くのOSと他のJava Runtime Environmentを使用しても動作するでしょう。
</p>
<br /><a name="installing"></a>
<h2>ソフトウェアのインストール</h2>
<p>
ソフトウェアをインストールするために、インストーラーを実行するか 選択したディレクトリにソフトウェアを解凍します。
</p>
<br /><a name="directory_structure"></a>
<h2>ディレクトリ構成</h2>
<p>
インストール後、下記のディレクトリ構成が作られます:
</p>
<table>
<tr>
<th>ディレクトリ</th>
<th>コンテンツ</th>
</tr>
<tr>
<td>bin</td>
<td>JAR and batch files</td>
</tr>
<tr>
<td>docs</td>
<td>Documentation</td>
</tr>
<tr>
<td>docs/html</td>
<td>HTML pages</td>
</tr>
<tr>
<td>docs/javadoc</td>
<td>Javadoc files</td>
</tr>
<tr>
<td>odbc</td>
<td>ODBC drivers and tools</td>
</tr>
<tr>
<td>service</td>
<td>Tools to run the database as a Windows Service</td>
</tr>
<tr>
<td>src</td>
<td>Source files</td>
</tr>
</table>
</div></td></tr></table></body></html>
差异被折叠。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
H2 Database Engine
</title><link rel="stylesheet" type="text/css" href="stylesheet.css" />
<script type="text/javascript" src="navigation.js"></script>
</head><body onload="frameMe();">
<table class="content"><tr class="content"><td class="content"><div class="contentDiv">
<h1>H2 データベース エンジン</h1>
<p>
ようこそ、無料のSQLデータベース、H2へ
</p>
<br />
<p>
<a href="quickstartText_ja.html" style="font-size: 16px; font-weight: bold">クイックスタート</a>
<br />
Click here to get a fast overview.
</p>
<p>
<a href="tutorial_ja.html" style="font-size: 16px; font-weight: bold">チュートリアル</a>
<br />
Go through the samples.
</p>
<p>
<a href="features.html" style="font-size: 16px; font-weight: bold">特徴</a>
<br />
See what this database can do and how to use these features.
</p>
</div></td></tr></table></body></html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="ja">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>
Quickstart
</title><link rel="stylesheet" type="text/css" href="stylesheet.css" />
<script type="text/javascript" src="navigation.js"></script>
</head><body onload="frameMe();">
<table class="content"><tr class="content"><td class="content"><div class="contentDiv">
<h1>クイックスタート</h1>
<a href="#embedding">
Embedding H2 in an Application</a><br />
<a href="#h2_console">
H2 コンソール アプリケーション</a><br />
<br /><a name="embedding"></a>
<h2>Embedding H2 in an Application</h2>
<p>
This database can be used in embedded mode, or in server mode. To use it in embedded mode, you need to:
</p>
<ul>
<li>Add <code>h2.jar</code> to the classpath
</li><li>Use the JDBC driver class: <code>org.h2.Driver</code>
</li><li>The database URL <code>jdbc:h2:~/test</code> opens the database 'test' in your user home directory
</li></ul>
<br /><a name="h2_console"></a>
<h2>H2 コンソール アプリケーション</h2>
<p>
このコンソールはブラウザインターフェースを使ってSQL データベースにアクセスします。
<br />
<img src="images/console.png" alt="Web Browser - H2 Console Server - H2 Database" />
<br />
Windows XPをご使用でなかったり、 期待通りに機能しない場合は、 <a href="tutorial.html">チュートリアル</a> 内の 詳細説明をご覧下さい。
</p>
<h3>手順</h3>
<h4>インストール</h4>
<p>
Windows インストーラーを使用してソフトウェアをインストールしましょう (まだインストールされていない場合)。
</p>
<h4>コンソールを起動する</h4>
<p>
<span class="button">スタート</span>
<span class="button">すべてのプログラム</span>
<span class="button">H2</span>
<span class="button">H2 Console (Command Line)</span>をクリックします:<br />
<img class="screenshot" src="images/quickstart-1.png" alt="screenshot: start H2 Console" /><br />
コンソールウィンドウが 開きます:<br />
<img class="screenshot" src="images/quickstart-2.png" alt="screenshot: H2 Running" /><br />
新しいブラウザで URL http://localhost:8082/ にアクセスして下さい。 ファイアーウォールによるセキュリティ警告を設定することができます。
外部ネットワークから あなたのマシンのデータベースにアクセスされたくないのであれば、ファイアーウォールが他の接続を遮断します。 ローカル接続のみ必要です。
</p>
<h4>ログイン</h4>
<p>
<span class="button">Generic H2</span>を選び、<span class="button">Connect</span>をクリックします:<br />
<img class="screenshot" src="images/quickstart-3.png" alt="screenshot: Login screen" /><br />
ログインされました。
</p>
<h4>サンプル</h4>
<p>
<span class="button">Sample SQL Script</span>をクリックします。: <br />
<img class="screenshot" src="images/quickstart-4.png" alt="screenshot: click on the sample SQL script" /><br />
SQLコマンドがコマンドエリアに表示されます。<br />
</p>
<h4>実行する</h4>
<p>
<span class="button">Run</span>をクリックします:<br />
<img class="screenshot" src="images/quickstart-5.png" alt="screenshot: click Run" /><br />
左側のデータベースアイコンの下に、 新しいテーブル TEST が追加されます。動作とステートメントの結果は、スクリプトの下に表示されます。<br />
<img class="screenshot" src="images/quickstart-6.png" alt="screenshot: see the result" /><br />
</p>
<h4>切断</h4>
<p>
<span class="button">Disconnect</span>をクリックします:<br />
<img src="images/icon_disconnect.gif" alt="Disconnect icon" /><br />
データベースを閉じます。
</p>
<h4>終了</h4>
<p>
コンソールウィンドウを閉じます。詳細は<a href="tutorial.html">チュートリアル</a>をご覧下さい。
</p>
</div></td></tr></table></body></html>
......@@ -44,7 +44,6 @@ Initial Developer: H2 Group
<tr class="search">
<td class="search" colspan="2">
<table id="result" style="border: 0px;">
<tr><td /></tr>
</table>
</td>
</tr>
......
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--
Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<html><head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Search</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" />
<script type="text/javascript" src="index.js"></script>
<script type="text/javascript" src="search.js"></script>
<script type="text/javascript" src="navigation.js"></script>
</head>
<body style="margin: 10px 0px 0px 0px;" onload="frameMe('menu');">
<div class="menu">
<img border="0" src="images/h2-logo.png" alt="H2 Logo" onclick="document.location='main.html'" />
</div>
<form name="searchForm" action="submit" onsubmit="return goFirst();">
<table width="100%" class="search">
<tr class="search">
<td class="search" colspan="2">
<a href="frame.html" target="_top"><img border="0" src="images/language_en.gif" alt="English" /></a>
<a href="frame_ja.html" target="_top"><img border="0" src="images/language_ja.gif" alt="Japanese" /></a>
</td>
</tr>
<tr class="search">
<td class="search" colspan="2">
<b>検索:</b>
</td>
</tr>
<tr class="search">
<td class="search" colspan="2">
<input id="search" name="search" type="text" size="21" maxlength="100" onKeyup="listWords(this.value, '')" /><br />
<input type="reset" id="clear" style="display:none;" value="Clear" onclick="listWords('', '');" />
</td>
</tr>
<tr class="search" style="display:none;" >
<td width="1%" class="search" style="vertical-align: middle;"><input id="highlight" type="checkbox" checked="checked" onclick="highlightCurrent(this.checked, search.value)" /></td>
<td width="99%" class="search" style="padding: 0px; vertical-align: middle;">Highlight keyword(s)</td>
</tr>
<tr class="search">
<td class="search" colspan="2">
<table id="result" style="border: 0px;">
</table>
</td>
</tr>
</table>
</form>
<div class="menu">
<b><a href="main_ja.html" target="main">ホーム</a></b><br />
<a href="quickstartText_ja.html" target="main">クイックスタート</a><br />
<a href="installation_ja.html" target="main">インストール</a><br />
<a href="tutorial_ja.html" target="main">チュートリアル</a><br />
<a href="features.html" target="main">特徴</a><br />
<a href="performance.html" target="main">パフォーマンス</a><br />
<a href="advanced.html" target="main">Advanced Topics</a><br />
<br />
<b>参照</b><br />
<a href="grammar.html" target="main">SQL文</a><br />
<a href="functions.html" target="main">関数</a><br />
<a href="datatypes.html" target="main">データ型</a><br />
<a href="../javadoc/index.html" target="main">Javadoc JDBC API</a><br />
<a href="../h2.pdf" target="_blank">PDFドキュメント</a><br />
<br />
<b>付録</b><br />
<a href="build.html" target="main">構築</a><br />
<a href="history.html" target="main">歴史とロードマップ</a><br />
<a href="faq.html" target="main">Q&A</a><br />
<a href="license.html" target="main">ライセンス</a><br />
<br />
</div>
</body></html>
差异被折叠。
......@@ -205,7 +205,7 @@ public class ScriptCommand extends ScriptBase {
add(sql, false);
if(Table.TABLE.equals(tableType)) {
if(table.canGetRowCount()) {
String rowcount = "-- " + table.getRowCount() + " = SELECT COUNT(*) FROM " + table.getSQL();
String rowcount = "-- " + table.getRowCount(session) + " = SELECT COUNT(*) FROM " + table.getSQL();
add(rowcount, false);
}
if(data) {
......
......@@ -735,7 +735,7 @@ public class Database implements DataHandler {
}
public synchronized Session createSession(User user) {
Session session = new Session(this, user, nextSessionId++);
Session session = new Session(this, user, ++nextSessionId);
sessions.add(session);
traceSystem.getTrace(Trace.SESSION).info("connecting #" + session.getId() + " to " + databaseName);
if(delayedCloser != null) {
......
......@@ -155,7 +155,7 @@ public class Aggregate extends Expression {
switch(type) {
case COUNT_ALL:
Table table = select.getTopTableFilter().getTable();
return ValueLong.get(table.getRowCount());
return ValueLong.get(table.getRowCount(session));
case MIN:
case MAX:
boolean first = type == MIN;
......
......@@ -58,7 +58,7 @@ public class BtreeIndex extends Index implements RecordReader {
if(head != null && head.getConsistent()) {
setRoot((BtreePage) storage.getRecord(session, head.getRootPosition()));
needRebuild = false;
rowCount = table.getRowCount();
rowCount = table.getRowCount(session);
} else {
truncate(session);
needRebuild = true;
......@@ -164,12 +164,17 @@ public class BtreeIndex extends Index implements RecordReader {
public void remove(Session session, Row row) throws SQLException {
setChanged(session);
if(rowCount == 1) {
// TODO performance: maybe improve truncate performance in this case
truncate(session);
} else {
if(SysProperties.MVCC) {
root.remove(session, row, 0);
rowCount--;
} else {
if(rowCount == 1) {
// TODO performance: maybe improve truncate performance in this case
truncate(session);
} else {
root.remove(session, row, 0);
rowCount--;
}
}
}
......@@ -199,8 +204,8 @@ public class BtreeIndex extends Index implements RecordReader {
}
}
public long getCost(int[] masks) throws SQLException {
return 10 * getCostRangeIndex(masks, tableData.getRowCount());
public double getCost(Session session, int[] masks) throws SQLException {
return 10 * getCostRangeIndex(masks, tableData.getRowCount(session));
}
public Record read(Session session, DataPage s) throws SQLException {
......
......@@ -30,7 +30,7 @@ public class BtreeLeaf extends BtreePage {
private boolean writePos;
private int cachedRealByteCount;
BtreeLeaf(BtreeIndex index, Session session,DataPage s) throws SQLException {
BtreeLeaf(BtreeIndex index, Session session, DataPage s) throws SQLException {
super(index);
writePos = s.readByte() == 'P';
if(writePos) {
......@@ -60,7 +60,18 @@ public class BtreeLeaf extends BtreePage {
if (comp == 0) {
if(index.indexType.isUnique()) {
if(!index.isNull(newRow)) {
throw index.getDuplicateKeyException();
if(SysProperties.MVCC) {
int todoMVCC;
// currently, throw a duplicate row exception even if another transaction
// updated or deleted the same row and did not yet commit - PostgreSQL waits but in most cases transactions are committed
if(row.getDeleted() && row.getSessionId() == session.getId()) {
// ignore: deleted
} else {
throw index.getDuplicateKeyException();
}
} else {
throw index.getDuplicateKeyException();
}
}
}
comp = index.compareKeys(row, newRow);
......@@ -251,7 +262,9 @@ public class BtreeLeaf extends BtreePage {
int size = 2 + dummy.getIntLen() * (len+1);
for (int i = 0; i < len; i++) {
SearchRow row = (SearchRow) pageData.get(i);
size += getRowSize(dummy, row);
if(!row.getDeleted()) {
size += getRowSize(dummy, row);
}
}
size += index.getRecordOverhead();
cachedRealByteCount = size;
......
......@@ -56,10 +56,12 @@ public class BtreeNode extends BtreePage {
this.pageData = pageData;
}
protected SearchRow getData(Session session, int i) throws SQLException {
protected SearchRow getData(int i) throws SQLException {
SearchRow r = (SearchRow) pageData.get(i);
if(r == null) {
int p = pageChildren.get(i+1);
// MVCC: get the committed data
Session session = index.getDatabase().getSystemSession();
BtreePage page = index.getPage(session, p);
r = page.getFirst(session);
pageData.set(i, r);
......
......@@ -46,7 +46,7 @@ public class FunctionIndex extends Index {
return new FunctionCursor(result);
}
public long getCost(int[] masks) throws SQLException {
public double getCost(Session session, int[] masks) throws SQLException {
if(masks != null) {
throw Message.getUnsupportedException();
}
......
......@@ -121,7 +121,7 @@ public class HashIndex extends Index {
return new HashCursor(result);
}
public long getCost(int[] masks) {
public double getCost(Session session, int[] masks) {
for (int i = 0; i < columns.length; i++) {
Column column = columns[i];
int index = column.getColumnId();
......
......@@ -75,7 +75,7 @@ public abstract class Index extends SchemaObject {
public abstract void add(Session session, Row row) throws SQLException;
public abstract void remove(Session session, Row row) throws SQLException;
public abstract Cursor find(Session session, SearchRow first, SearchRow last) throws SQLException;
public abstract long getCost(int[] masks) throws SQLException;
public abstract double getCost(Session session, int[] masks) throws SQLException;
public abstract void remove(Session session) throws SQLException;
public abstract void truncate(Session session) throws SQLException;
public abstract boolean canGetFirstOrLast(boolean first);
......
......@@ -59,7 +59,7 @@ public class LinearHashIndex extends Index implements RecordReader {
firstBucketBlock = 4;
storage = database.getStorage(id, diskFile);
storage.setReader(this);
rowCount = table.getRowCount();
rowCount = table.getRowCount(session);
int pos = storage.getNext(null);
if(pos == -1) {
truncate(session);
......@@ -489,7 +489,7 @@ public class LinearHashIndex extends Index implements RecordReader {
return new LinearHashCursor(tableData.getRow(session, key));
}
public long getCost(int[] masks) throws SQLException {
public double getCost(Session session, int[] masks) throws SQLException {
for (int i = 0; i < columns.length; i++) {
Column column = columns[i];
int index = column.getColumnId();
......
......@@ -139,7 +139,7 @@ public class LinkedIndex extends Index {
}
}
public long getCost(int[] masks) throws SQLException {
public double getCost(Session session, int[] masks) throws SQLException {
return 100 + getCostRangeIndex(masks, rowCount + Constants.COST_ROW_OFFSET);
}
......
......@@ -48,7 +48,7 @@ public class MetaIndex extends Index {
return new MetaCursor(rows);
}
public long getCost(int[] masks) throws SQLException {
public double getCost(Session session, int[] masks) throws SQLException {
if(scan) {
return 10000;
}
......
......@@ -42,7 +42,7 @@ public class RangeIndex extends Index {
return new RangeCursor(start, end);
}
public long getCost(int[] masks) throws SQLException {
public double getCost(Session session, int[] masks) throws SQLException {
return 1;
}
......
......@@ -6,6 +6,7 @@ package org.h2.index;
import java.sql.SQLException;
import org.h2.constant.SysProperties;
import org.h2.engine.Session;
import org.h2.result.Row;
import org.h2.result.SearchRow;
......@@ -42,6 +43,18 @@ public class ScanCursor implements Cursor {
}
public boolean next() throws SQLException {
if(SysProperties.MVCC) {
while(true) {
row = scan.getNextRow(session, row);
if(row == null) {
break;
}
if(row.getSessionId() == 0 || row.getSessionId() == session.getId()) {
break;
}
}
return row != null;
}
row = scan.getNextRow(session, row);
return row != null;
}
......
......@@ -142,8 +142,8 @@ public class ScanIndex extends Index {
return new ScanCursor(session, this);
}
public long getCost(int[] masks) throws SQLException {
long cost = tableData.getRowCount() + Constants.COST_ROW_OFFSET;
public double getCost(Session session, int[] masks) throws SQLException {
long cost = tableData.getRowCount(session) + Constants.COST_ROW_OFFSET;
if(storage != null) {
cost *= 10;
}
......
......@@ -293,8 +293,8 @@ public class TreeIndex extends Index {
}
}
public long getCost(int[] masks) throws SQLException {
return getCostRangeIndex(masks, tableData.getRowCount());
public double getCost(Session session, int[] masks) throws SQLException {
return getCostRangeIndex(masks, tableData.getRowCount(session));
}
public void remove(Session session) throws SQLException {
......
......@@ -212,13 +212,6 @@ public class ViewIndex extends Index {
return query;
}
public long getCost(int[] masks) throws SQLException {
if(masks != null) {
throw Message.getUnsupportedException();
}
return Long.MAX_VALUE;
}
public void remove(Session session) throws SQLException {
throw Message.getUnsupportedException();
}
......
......@@ -872,11 +872,11 @@ SET MAX_LENGTH_INPLACE_LOB int
Sets the maximum size of an in-place LOB object. LOB objects larger
that this size are stored in a separate file, otherwise stored
directly in the database (in-place).
The default max size is 128.
The default max size is 1024.
This setting is persistent.
Admin rights are required to execute this command.
","
SET MAX_LENGTH_INPLACE_LOB 512
SET MAX_LENGTH_INPLACE_LOB 128
"
"Commands (Other)","SET MAX_LOG_SIZE","
......
......@@ -4,6 +4,7 @@
*/
package org.h2.result;
import org.h2.engine.Session;
import org.h2.value.Value;
public interface SearchRow {
......@@ -13,5 +14,8 @@ public interface SearchRow {
int getColumnCount();
void setValue(int idx, Value v);
void setPos(int pos);
void setDeleted(Session session, boolean deleted);
int getSessionId();
boolean getDeleted();
}
......@@ -4,12 +4,15 @@
*/
package org.h2.result;
import org.h2.engine.Session;
import org.h2.value.Value;
public class SimpleRow implements SearchRow {
private int pos;
private Value[] data;
private int sessionId;
private boolean deleted;
public SimpleRow(Value[] data) {
this.data = data;
......@@ -35,4 +38,18 @@ public class SimpleRow implements SearchRow {
return data[i];
}
public boolean getDeleted() {
return deleted;
}
public void setDeleted(Session session, boolean deleted) {
this.sessionId = session.getId();
this.deleted = deleted;
}
public int getSessionId() {
int testing;
return sessionId;
}
}
......@@ -4,6 +4,7 @@
*/
package org.h2.result;
import org.h2.engine.Session;
import org.h2.value.Value;
public class SimpleRowValue implements SearchRow {
......@@ -12,6 +13,8 @@ public class SimpleRowValue implements SearchRow {
private int index;
private int virtualColumnCount;
private Value data;
private int sessionId;
private boolean deleted;
public SimpleRowValue(int columnCount) {
this.virtualColumnCount = columnCount;
......@@ -35,4 +38,18 @@ public class SimpleRowValue implements SearchRow {
data = v;
}
public boolean getDeleted() {
return deleted;
}
public void setDeleted(Session session, boolean deleted) {
this.sessionId = session.getId();
this.deleted = deleted;
}
public int getSessionId() {
int testing;
return sessionId;
}
}
......@@ -10,6 +10,7 @@ import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.expression.Expression;
import org.h2.util.ObjectArray;
import org.h2.util.RandomUtils;
import org.h2.util.StringUtils;
import org.h2.value.Value;
import org.h2.value.ValueNull;
......@@ -110,9 +111,11 @@ public class SortOrder {
}
private void sort(ObjectArray rows, int l, int r) throws SQLException {
// quicksort
int i, j;
while (r - l > 10) {
i = (r + l) >> 1;
// randomized pivot to avoid worst case
i = RandomUtils.nextInt(r - l - 4) + l + 2;
if (compare((Value[]) rows.get(l), (Value[]) rows.get(r)) > 0) {
swap(rows, l, r);
}
......
......@@ -6,6 +6,7 @@ package org.h2.store;
import java.sql.SQLException;
import org.h2.constant.SysProperties;
import org.h2.engine.Session;
import org.h2.util.CacheObject;
......@@ -81,6 +82,12 @@ public abstract class Record extends CacheObject {
if((isChanged() && !isLogWritten()) || isPinned()) {
return false;
}
if(SysProperties.MVCC) {
// TODO not required if we write the log only when committed
if(sessionId != 0) {
return false;
}
}
return true;
}
......
......@@ -113,7 +113,7 @@ public class FunctionTable extends Table {
return false;
}
public long getRowCount() throws SQLException {
public long getRowCount(Session session) throws SQLException {
throw Message.getInternalError();
}
......
......@@ -1272,7 +1272,7 @@ public class MetaTable extends Table {
throw Message.getUnsupportedException();
}
public long getRowCount() {
public long getRowCount(Session session) {
throw Message.getInternalError();
}
......
......@@ -84,7 +84,7 @@ public class RangeTable extends Table {
return false;
}
public long getRowCount() throws SQLException {
public long getRowCount(Session session) throws SQLException {
return max - min;
}
......
......@@ -252,11 +252,11 @@ public abstract class Table extends SchemaObject {
public PlanItem getBestPlanItem(Session session, int[] masks) throws SQLException {
PlanItem item = new PlanItem();
item.setIndex(getScanIndex(session));
item.cost = item.getIndex().getCost(null);
item.cost = item.getIndex().getCost(session, null);
ObjectArray indexes = getIndexes();
for (int i = 1; indexes != null && masks != null && i < indexes.size(); i++) {
Index index = (Index) indexes.get(i);
long cost = index.getCost(masks);
double cost = index.getCost(session, masks);
if (cost < item.cost) {
item.cost = cost;
item.setIndex(index);
......@@ -440,7 +440,7 @@ public abstract class Table extends SchemaObject {
public abstract boolean canGetRowCount();
public abstract boolean canDrop();
public abstract long getRowCount() throws SQLException;
public abstract long getRowCount(Session session) throws SQLException;
public boolean getGlobalTemporary() {
return false;
......
......@@ -243,7 +243,7 @@ public class TableData extends Table implements RecordReader {
return true;
}
public long getRowCount() {
public long getRowCount(Session session) {
return rowCount;
}
......
......@@ -96,7 +96,7 @@ public class TableFilter implements ColumnResolver {
if (indexConditions.size() == 0) {
item = new PlanItem();
item.setIndex(table.getScanIndex(session));
item.cost = item.getIndex().getCost(null);
item.cost = item.getIndex().getCost(session, null);
} else {
int len = table.getColumns().length;
int[] masks = new int[len];
......
......@@ -242,7 +242,7 @@ public class TableLink extends Table {
}
}
public long getRowCount() throws SQLException {
public long getRowCount(Session session) throws SQLException {
PreparedStatement prep = getPreparedStatement("SELECT COUNT(*) FROM "+originalTable);
ResultSet rs = prep.executeQuery();
rs.next();
......
......@@ -175,7 +175,7 @@ public class TableView extends Table {
throw Message.getUnsupportedException();
}
public long getRowCount() {
public long getRowCount(Session session) {
throw Message.getInternalError();
}
......
......@@ -17,4 +17,8 @@ public class CacheHead extends CacheObject {
public void write(DataPage buff) throws SQLException {
}
public boolean canRemove() {
return false;
}
}
......@@ -58,9 +58,7 @@ public abstract class CacheObject {
return false;
}
public boolean canRemove() {
return true;
}
abstract public boolean canRemove();
/*
* Get the estimated memory size.
......
package org.h2.samples;
import java.io.*;
import java.sql.*;
import org.h2.tools.RunScript;
public class InitDatabaseFromJar {
public static void main(String[] args) throws Exception {
new InitDatabaseFromJar().createScript();
new InitDatabaseFromJar().initDb();
}
private void createScript() throws Exception {
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:mem:test");
Statement stat = conn.createStatement();
stat.execute("CREATE TABLE TEST(NAME VARCHAR)");
stat.execute("INSERT INTO TEST VALUES('Hello World')");
stat.execute("SCRIPT TO 'script.sql'");
conn.close();
}
void initDb() throws Exception {
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:mem:test");
InputStream in = getClass().getResourceAsStream("script.sql");
if(in == null) {
System.out.println("Please add the file script.sql to the classpath, package " + getClass().getPackage().getName());
} else {
RunScript.execute(conn, new InputStreamReader(in));
ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM TEST");
while(rs.next()) {
System.out.println(rs.getString(1));
}
conn.close();
}
}
}
......@@ -94,6 +94,16 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
/*
table with constraint
alter the table
add data
-> object is closed
CREATE TABLE TEST(ID INT, PARENT INT, CONSTRAINT A FOREIGN KEY(PARENT) REFERENCES(ID));
ALTER TABLE TEST ALTER COLUMN PARENT BIGINT;
INSERT INTO TEST VALUES(1, 1, 1);
add MVCC
test and document fulltext search
......
package org.h2.test.mvcc;
import java.sql.*;
import org.h2.tools.DeleteDbFiles;
public class TestMVCC {
Connection c1, c2;
Statement s1, s2;
public static void main(String[] args) throws Exception {
TestMVCC app = new TestMVCC();
app.test();
}
void test() throws Exception {
// TODO Prio 1: don't store records before they are committed (otherwise re-reading from a different session may return the wrong value)
// TODO Prio 1: getRowCount: different row count for different sessions: TableData
// TODO Prio 2: getRowCount: different row count for different sessions: TableLink (use different connections?)
System.setProperty("h2.mvcc", "true");
DeleteDbFiles.execute(null, "test", true);
Class.forName("org.h2.Driver");
c1 = DriverManager.getConnection("jdbc:h2:test");
s1 = c1.createStatement();
c2 = DriverManager.getConnection("jdbc:h2:test");
s2 = c2.createStatement();
c1.setAutoCommit(false);
c2.setAutoCommit(false);
s1.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR)");
// s1.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
s1.execute("INSERT INTO TEST VALUES(1, 'Hello')");
test(s2, "SELECT COUNT(*) FROM TEST WHERE NAME!='X'", "0");
c1.commit();
// TODO support snapshot isolation
// test(s2, "SELECT COUNT(*) FROM TEST WHERE NAME!='X'", "0");
test(s2, "SELECT COUNT(*) FROM TEST WHERE NAME!='X'", "1");
c1.close();
c2.close();
}
private void test(Statement stat, String sql, String expected) throws Exception {
ResultSet rs = stat.executeQuery(sql);
if(rs.next()) {
String s = rs.getString(1);
if(expected == null) {
throw new Error("expected: no rows, got: " + s);
} else if(!expected.equals(s)) {
throw new Error("expected: " + expected + ", got: " + s);
}
} else {
if(expected != null) {
throw new Error("expected: " + expected + ", got: no rows");
}
}
// TODO Auto-generated method stub
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论