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

Fix ENUM data type in external results

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