Skip to content

Commit 4ec2e27

Browse files
authored
fix H2 materialized view bug (#357)
* fix H2 materialized view bug * reproducing test * refactor test
1 parent 3dd0e26 commit 4ec2e27

3 files changed

Lines changed: 83 additions & 54 deletions

File tree

celesta-sql/src/main/java/ru/curs/celesta/dbutils/h2/AbstractMaterializeViewTrigger.java

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -61,36 +61,27 @@ public void init(Connection connection, String schemaName, String triggerName, S
6161
.map(v -> "\"" + v + "\"")
6262
.collect(Collectors.joining(", "));
6363

64-
keySearchTerm = mv.getColumns().keySet().stream()
65-
.filter(alias -> mv.isGroupByColumn(alias))
66-
.map((String alias) -> {
67-
try {
68-
return String.format("(\"%s\" = %s)",
69-
alias,
70-
DateTimeColumn.CELESTA_TYPE.equals(
71-
mv.getColumn(alias).getCelestaType()) ? "TRUNC(?)" : "?");
72-
} catch (ParseException e) {
73-
throw new RuntimeException(e);
74-
}
75-
})
76-
.collect(Collectors.joining(" and "));
77-
64+
List<String> keySearchTerms = new ArrayList<>();
7865
List<String> columnRefNames = mv.getColumnRefNames();
79-
8066
int curIndex = 0;
8167
for (String tCol : t.getColumns().keySet()) {
82-
boolean isGroupBy = mv.getColumns().keySet().stream()
83-
.anyMatch(v -> mv.isGroupByColumn(v) && tCol.equals(mv.getColumnRef(v).getName()));
84-
85-
if (isGroupBy) {
86-
tGroupByColumnIndices.put(curIndex, tCol);
68+
for (Map.Entry<String, Column<?>> col : mv.getColumns().entrySet()) {
69+
if (mv.isGroupByColumn(col.getKey()) && tCol.equals(mv.getColumnRef(col.getKey()).getName())) {
70+
tGroupByColumnIndices.put(curIndex, tCol);
71+
keySearchTerms.add(String.format("(\"%s\" = %s)",
72+
col.getKey(),
73+
DateTimeColumn.CELESTA_TYPE.equals(
74+
col.getValue().getCelestaType()) ? "TRUNC(?)" : "?"));
75+
break;
76+
}
8777
}
8878

8979
if (columnRefNames.contains(tCol)) {
9080
mvColumnRefs.put(curIndex, tCol);
9181
}
9282
++curIndex;
9383
}
84+
keySearchTerm = String.join(" and ", keySearchTerms);
9485
}
9586

9687

celesta-test/score/mView/_mView.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ create materialized view mView5 AS
6161
from table4
6262
group by var1, vvv;
6363

64+
create materialized view mViewReverseOrder AS
65+
select var2, var1, sum(numb) as s
66+
from table4
67+
group by var2, var1;
68+
69+
6470
CREATE SEQUENCE table5Num;
6571

6672
create table table5 (

celesta-test/src/test/java/ru/curs/celesta/script/TestMaterializedView.java

Lines changed: 66 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
package ru.curs.celesta.script;
22

3-
import mView.*;
3+
import mView.MView1Cursor;
4+
import mView.MView2Cursor;
5+
import mView.MView3Cursor;
6+
import mView.MView4Cursor;
7+
import mView.MView5Cursor;
8+
import mView.MView6Cursor;
9+
import mView.MViewReverseOrderCursor;
10+
import mView.Table1Cursor;
11+
import mView.Table2Cursor;
12+
import mView.Table3Cursor;
13+
import mView.Table4Cursor;
14+
import mView.Table5Cursor;
415
import org.junit.jupiter.api.TestTemplate;
516
import ru.curs.celesta.CallContext;
617

@@ -64,21 +75,24 @@ void test_mat_view_two_columns(CallContext context) {
6475
Table4Cursor tableCursor = new Table4Cursor(context);
6576
MView5Cursor mViewCursor = new MView5Cursor(context);
6677
assertEquals(0, mViewCursor.count());
67-
tableCursor.setVar1("A");
68-
tableCursor.setVar2("B");
69-
tableCursor.setNumb(3);
70-
tableCursor.insert();
71-
tableCursor.setId(null);
72-
tableCursor.setNumb(2);
73-
tableCursor.insert();
78+
tableCursor
79+
.setVar1("A")
80+
.setVar2("B")
81+
.setNumb(3)
82+
.insert();
83+
tableCursor
84+
.setId(null)
85+
.setNumb(2)
86+
.insert();
7487
assertEquals(1, mViewCursor.count());
7588
mViewCursor.get("A", "B");
7689
assertEquals(5, mViewCursor.getS().intValue());
7790

78-
tableCursor.setId(null);
79-
tableCursor.setVar2("C");
80-
tableCursor.setNumb(4);
81-
tableCursor.insert();
91+
tableCursor
92+
.setId(null)
93+
.setVar2("C")
94+
.setNumb(4)
95+
.insert();
8296
mViewCursor.get("A", "C");
8397
assertEquals(4, mViewCursor.getS().intValue());
8498
mViewCursor.tryGetCurrent();
@@ -96,40 +110,45 @@ void test_mat_view_update_when_count_is_unknown(CallContext context) {
96110
tableCursor.deleteAll();
97111
assertEquals(0, mViewCursor.count());
98112

99-
tableCursor.setNumb(5);
100-
tableCursor.setVar("A");
101-
tableCursor.insert();
113+
tableCursor
114+
.setNumb(5)
115+
.setVar("A")
116+
.insert();
102117
Integer id1 = tableCursor.getId();
103118
tableCursor.clear();
104119

105-
tableCursor.setNumb(2);
106-
tableCursor.setVar("A");
107-
tableCursor.insert();
120+
tableCursor
121+
.setNumb(2)
122+
.setVar("A")
123+
.insert();
108124
tableCursor.clear();
109125

110126
mViewCursor.get("A");
111127
assertEquals(7, mViewCursor.getS().intValue());
112128

113129
tableCursor.setRange(tableCursor.COLUMNS.numb(), 2);
114130
tableCursor.first();
115-
tableCursor.setNumb(-5);
116-
tableCursor.update();
131+
tableCursor
132+
.setNumb(-5)
133+
.update();
117134
tableCursor.clear();
118135

119136
mViewCursor.get("A");
120137
assertEquals(0, mViewCursor.getS().intValue());
121138

122-
tableCursor.setNumb(5);
123-
tableCursor.setVar("A");
124-
tableCursor.insert();
139+
tableCursor
140+
.setNumb(5)
141+
.setVar("A")
142+
.insert();
125143
tableCursor.clear();
126144

127145
mViewCursor.get("A");
128146
assertEquals(5, mViewCursor.getS().intValue());
129147

130148
tableCursor.get(id1);
131-
tableCursor.setVar("B");
132-
tableCursor.update();
149+
tableCursor
150+
.setVar("B")
151+
.update();
133152
tableCursor.clear();
134153

135154
mViewCursor.get("A");
@@ -149,22 +168,25 @@ void test_mat_view_date_rounding(CallContext context) {
149168
LocalDateTime datetime1 = LocalDateTime.of(2000, Month.AUGUST, 5, 10, 5, 32);
150169
LocalDateTime date1 = datetime1.truncatedTo(ChronoUnit.DAYS);
151170

152-
tableCursor.setNumb(5);
153-
tableCursor.setDate(Timestamp.valueOf(datetime1));
154-
tableCursor.insert();
171+
tableCursor
172+
.setNumb(5)
173+
.setDate(Timestamp.valueOf(datetime1))
174+
.insert();
155175
tableCursor.clear();
156176

157177
LocalDateTime datetime2 = LocalDateTime.of(2000, Month.AUGUST, 5, 22, 5, 32);
158-
tableCursor.setNumb(2);
159-
tableCursor.setDate(Timestamp.valueOf(datetime2));
160-
tableCursor.insert();
178+
tableCursor
179+
.setNumb(2)
180+
.setDate(Timestamp.valueOf(datetime2))
181+
.insert();
161182
tableCursor.clear();
162183

163184
LocalDateTime datetime3 = LocalDateTime.of(2000, Month.AUGUST, 6, 10, 5, 32);
164185
LocalDateTime date2 = datetime3.truncatedTo(ChronoUnit.DAYS);
165-
tableCursor.setNumb(5);
166-
tableCursor.setDate(Timestamp.valueOf(datetime3));
167-
tableCursor.insert();
186+
tableCursor
187+
.setNumb(5)
188+
.setDate(Timestamp.valueOf(datetime3))
189+
.insert();
168190
tableCursor.clear();
169191

170192
assertEquals(2, mViewCursor.count());
@@ -414,4 +436,14 @@ void _test_mat_view_delete(Cursor tableCursor, MaterializedViewCursor mViewCurso
414436
assertEquals(1, mViewCursor.count());
415437
}
416438

439+
@TestTemplate
440+
void test_mat_view_reverse_order_of_columns(CallContext ctx) {
441+
Table4Cursor t4 = new Table4Cursor(ctx);
442+
t4.setVar1("v1").setVar2("v2").setNumb(1).insert();
443+
t4.clear();
444+
t4.setVar1("v1").setVar2("v2").setNumb(2).insert();
445+
MViewReverseOrderCursor reverseOrderCursor = new MViewReverseOrderCursor(ctx);
446+
reverseOrderCursor.get("v2", "v1");
447+
assertEquals(3, reverseOrderCursor.getS());
448+
}
417449
}

0 commit comments

Comments
 (0)