提交 e273bff1 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Fix ENUM data type in external results

上级 fa946672
......@@ -59,8 +59,8 @@ class MVPlainTempResult extends MVTempResult {
* count of visible columns
*/
MVPlainTempResult(Database database, Expression[] expressions, int visibleColumnCount) {
super(database, expressions.length, visibleColumnCount);
ValueDataType valueType = new ValueDataType(database, new int[columnCount]);
super(database, expressions, visibleColumnCount);
ValueDataType valueType = new ValueDataType(database, new int[expressions.length]);
Builder<Long, ValueRow> builder = new MVMap.Builder<Long, ValueRow>()
.valueType(valueType).singleWriter();
map = store.openMap("tmp", builder);
......@@ -99,7 +99,11 @@ class MVPlainTempResult extends MVTempResult {
return null;
}
cursor.next();
return cursor.getValue().getList();
Value[] currentRow = cursor.getValue().getList();
if (hasEnum) {
fixEnum(currentRow);
}
return currentRow;
}
@Override
......
......@@ -109,10 +109,10 @@ class MVSortedTempResult extends MVTempResult {
*/
MVSortedTempResult(Database database, Expression[] expressions, boolean distinct, int[] distinctIndexes,
int visibleColumnCount, SortOrder sort) {
super(database, expressions.length, visibleColumnCount);
super(database, expressions, visibleColumnCount);
this.distinct = distinct;
this.distinctIndexes = distinctIndexes;
int length = columnCount;
int length = expressions.length;
int[] sortTypes = new int[length];
int[] indexes;
if (sort != null) {
......@@ -192,7 +192,7 @@ class MVSortedTempResult extends MVTempResult {
if (index.putIfAbsent(distinctRow, true) != null) {
return rowCount;
}
} else if (columnCount != visibleColumnCount) {
} else if (expressions.length != visibleColumnCount) {
ValueRow distinctRow = ValueRow.get(Arrays.copyOf(values, visibleColumnCount));
if (index.putIfAbsent(distinctRow, true) != null) {
return rowCount;
......@@ -221,7 +221,7 @@ class MVSortedTempResult extends MVTempResult {
return parent.contains(values);
}
assert distinct;
if (columnCount != visibleColumnCount) {
if (expressions.length != visibleColumnCount) {
return index.containsKey(ValueRow.get(values));
}
return map.containsKey(getKey(values));
......@@ -297,6 +297,9 @@ class MVSortedTempResult extends MVTempResult {
}
// Read the next row
current = getValue(cursor.next().getList());
if (hasEnum) {
fixEnum(current);
}
/*
* If valueCount is greater than 1 that is possible for non-distinct results the
* following invocations of next() will use this.current and this.valueCount.
......@@ -308,7 +311,7 @@ class MVSortedTempResult extends MVTempResult {
@Override
public int removeRow(Value[] values) {
assert parent == null && distinct;
if (columnCount != visibleColumnCount) {
if (expressions.length != visibleColumnCount) {
throw DbException.getUnsupportedException("removeRow()");
}
// If an entry was removed decrement the counter
......
......@@ -19,6 +19,7 @@ import org.h2.result.ResultExternal;
import org.h2.result.SortOrder;
import org.h2.store.fs.FileUtils;
import org.h2.util.TempFileDeleter;
import org.h2.value.TypeInfo;
import org.h2.value.Value;
/**
......@@ -87,15 +88,17 @@ public abstract class MVTempResult implements ResultExternal {
final MVStore store;
/**
* Count of columns.
* Column expressions.
*/
final int columnCount;
final Expression[] expressions;
/**
* Count of visible columns.
*/
final int visibleColumnCount;
final boolean hasEnum;
/**
* Count of rows. Used only in a root results, copies always have 0 value.
*/
......@@ -140,8 +143,9 @@ public abstract class MVTempResult implements ResultExternal {
MVTempResult(MVTempResult parent) {
this.parent = parent;
this.store = parent.store;
this.columnCount = parent.columnCount;
this.expressions = parent.expressions;
this.visibleColumnCount = parent.visibleColumnCount;
this.hasEnum = parent.hasEnum;
this.tempFileDeleter = null;
this.closeable = null;
this.fileRef = null;
......@@ -152,12 +156,12 @@ public abstract class MVTempResult implements ResultExternal {
*
* @param database
* database
* @param columnCount
* count of columns
* @param expressions
* column expressions
* @param visibleColumnCount
* count of visible columns
*/
MVTempResult(Database database, int columnCount, int visibleColumnCount) {
MVTempResult(Database database, Expression[] expressions, int visibleColumnCount) {
try {
String fileName = FileUtils.createTempFile("h2tmp", Constants.SUFFIX_TEMP_FILE, true);
Builder builder = new MVStore.Builder().fileName(fileName).cacheSize(0).autoCommitDisabled();
......@@ -166,8 +170,16 @@ public abstract class MVTempResult implements ResultExternal {
builder.encryptionKey(MVTableEngine.decodePassword(key));
}
store = builder.open();
this.columnCount = columnCount;
this.expressions = expressions;
this.visibleColumnCount = visibleColumnCount;
boolean hasEnum = false;
for (Expression e : expressions) {
if (e.getType().getValueType() == Value.ENUM) {
hasEnum = true;
break;
}
}
this.hasEnum = hasEnum;
tempFileDeleter = database.getTempFileDeleter();
closeable = new CloseImpl(store, fileName);
fileRef = tempFileDeleter.addFile(closeable, this);
......@@ -210,4 +222,13 @@ public abstract class MVTempResult implements ResultExternal {
tempFileDeleter.deleteFile(fileRef, closeable);
}
final void fixEnum(Value[] row) {
for (int i = 0, l = expressions.length; i < l; i++) {
TypeInfo type = expressions[i].getType();
if (type.getValueType() == Value.ENUM) {
row[i] = type.getExtTypeInfo().cast(row[i]);
}
}
}
}
......@@ -11,6 +11,7 @@ import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.BitSet;
import org.h2.test.TestBase;
import org.h2.tools.DeleteDbFiles;
......@@ -53,16 +54,25 @@ public class TestMVTempResult extends TestBase {
DeleteDbFiles.execute(dir, name, true);
try (Connection c = DriverManager.getConnection("jdbc:h2:" + dir + '/' + name)) {
Statement s = c.createStatement();
try (ResultSet rs = s.executeQuery("SELECT X, RAND() R FROM SYSTEM_RANGE(1, " + ROWS + ") ORDER BY R")) {
for (int i = 1; i <= ROWS; i++) {
s.execute("CREATE TABLE TEST(I BIGINT, E ENUM('a', 'b'))" //
+ " AS SELECT X, 'a' FROM SYSTEM_RANGE(1, " + ROWS + ')');
try (ResultSet rs = s.executeQuery("SELECT I, E FROM TEST ORDER BY I DESC")) {
for (int i = ROWS; i > 0; i--) {
assertTrue(rs.next());
assertEquals(i, rs.getLong(1));
assertEquals("a", rs.getString(2));
}
assertFalse(rs.next());
}
try (ResultSet rs = s.executeQuery("SELECT X, RAND() FROM SYSTEM_RANGE(1, " + ROWS + ')')) {
BitSet set = new BitSet(ROWS);
try (ResultSet rs = s.executeQuery("SELECT I, E FROM TEST")) {
for (int i = 1; i <= ROWS; i++) {
assertTrue(rs.next());
assertEquals(i, rs.getLong(1));
set.set((int) rs.getLong(1));
assertEquals("a", rs.getString(2));
}
assertFalse(rs.next());
assertEquals(ROWS, set.cardinality());
}
}
DeleteDbFiles.execute(dir, name, true);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论