@@ -40,7 +40,7 @@ class QueryCacheTest : public PelotonCodeGenTest {
40
40
oid_t TestTableId () { return test_table_oids[0 ]; }
41
41
oid_t RightTableId () { return test_table_oids[1 ]; }
42
42
43
- // SELECT b FROM table where a >= 40;
43
+ // SELECT a FROM table where a >= 40;
44
44
std::shared_ptr<planner::SeqScanPlan> GetSeqScanPlan () {
45
45
auto *a_col_exp =
46
46
new expression::TupleValueExpression (type::TypeId::INTEGER, 0 , 0 );
@@ -51,6 +51,38 @@ class QueryCacheTest : public PelotonCodeGenTest {
51
51
&GetTestTable (TestTableId ()), a_gt_40, {0 , 1 }));
52
52
}
53
53
54
+ /* SELECT a FROM table where a >= 40;
55
+ bind_tve: flag for binding the tuple value expression
56
+ */
57
+ std::shared_ptr<planner::SeqScanPlan> GetSeqScanPlanA (bool bind_tve) {
58
+ auto *a_col_exp =
59
+ new expression::TupleValueExpression (type::TypeId::INTEGER, 0 , 0 );
60
+ if (bind_tve) {
61
+ a_col_exp->SetBoundOid (GetDatabase ().GetOid (), TestTableId (), 0 );
62
+ }
63
+ auto *const_40_exp = PelotonCodeGenTest::ConstIntExpr (40 ).release ();
64
+ auto *a_eq_40 = new expression::ComparisonExpression (
65
+ ExpressionType::COMPARE_EQUAL, a_col_exp, const_40_exp);
66
+ return std::shared_ptr<planner::SeqScanPlan>(new planner::SeqScanPlan (
67
+ &GetTestTable (TestTableId ()), a_eq_40, {0 , 1 }));
68
+ }
69
+
70
+ /* SELECT b FROM table where b >= 41;
71
+ bind_tve: flag for binding the tuple value expression
72
+ */
73
+ std::shared_ptr<planner::SeqScanPlan> GetSeqScanPlanB (bool bind_tve) {
74
+ auto *b_col_exp =
75
+ new expression::TupleValueExpression (type::TypeId::INTEGER, 0 , 1 );
76
+ if (bind_tve) {
77
+ b_col_exp->SetBoundOid (GetDatabase ().GetOid (), TestTableId (), 1 );
78
+ }
79
+ auto *const_41_exp = PelotonCodeGenTest::ConstIntExpr (41 ).release ();
80
+ auto *b_eq_41 = new expression::ComparisonExpression (
81
+ ExpressionType::COMPARE_EQUAL, b_col_exp, const_41_exp);
82
+ return std::shared_ptr<planner::SeqScanPlan>(new planner::SeqScanPlan (
83
+ &GetTestTable (TestTableId ()), b_eq_41, {0 , 1 }));
84
+ }
85
+
54
86
// SELECT a, b, c FROM table where a >= 20 and b = 21;
55
87
std::shared_ptr<planner::SeqScanPlan> GetSeqScanPlanWithPredicate () {
56
88
auto *a_col_exp =
@@ -207,6 +239,7 @@ class QueryCacheTest : public PelotonCodeGenTest {
207
239
uint32_t num_rows_to_insert = 64 ;
208
240
};
209
241
242
+
210
243
TEST_F (QueryCacheTest, SimpleCache) {
211
244
int CACHE_USED_BY_CATALOG = codegen::QueryCache::Instance ().GetCount ();
212
245
@@ -253,6 +286,80 @@ TEST_F(QueryCacheTest, SimpleCache) {
253
286
EXPECT_EQ (0 , codegen::QueryCache::Instance ().GetCount ());
254
287
}
255
288
289
+ TEST_F (QueryCacheTest, SimpleCacheWithDiffPredicate) {
290
+ std::shared_ptr<planner::SeqScanPlan> scan_a = GetSeqScanPlanA (false );
291
+
292
+ std::shared_ptr<planner::SeqScanPlan> scan_b = GetSeqScanPlanB (false );
293
+ // Do binding
294
+ planner::BindingContext context_1;
295
+ scan_a->PerformBinding (context_1);
296
+ planner::BindingContext context_2;
297
+ scan_b->PerformBinding (context_2);
298
+
299
+ // Check if the two plans are the same
300
+ // Since they are not bound, the two plans are the same
301
+ auto hash_equal = (scan_a->Hash () == scan_b->Hash ());
302
+ EXPECT_TRUE (hash_equal);
303
+
304
+ auto is_equal = (*scan_a.get () == *scan_b.get ());
305
+ EXPECT_TRUE (is_equal);
306
+
307
+ // Create two plans with bound tuple value expression
308
+ std::shared_ptr<planner::SeqScanPlan> plan_a = GetSeqScanPlanA (true );
309
+
310
+ std::shared_ptr<planner::SeqScanPlan> plan_b = GetSeqScanPlanB (true );
311
+
312
+ auto hash_equal_2 = (plan_a->Hash () == plan_b->Hash ());
313
+ EXPECT_FALSE (hash_equal_2);
314
+
315
+ auto is_equal_2 = (*plan_a.get () == *plan_b.get ());
316
+ EXPECT_FALSE (is_equal_2);
317
+
318
+ // Do binding
319
+ planner::BindingContext context_a;
320
+ plan_a->PerformBinding (context_a);
321
+ planner::BindingContext context_b;
322
+ plan_b->PerformBinding (context_b);
323
+
324
+ // execute SELECT a FROM table where a == 40;
325
+ codegen::BufferingConsumer buffer_1{{0 , 1 }, context_a};
326
+ bool cached;
327
+ CompileAndExecuteCache (plan_a, buffer_1, cached);
328
+ auto &results_1 = buffer_1.GetOutputTuples ();
329
+ EXPECT_EQ (1 , results_1.size ());
330
+ EXPECT_EQ (40 , results_1[0 ].GetValue (0 ).GetAs <int32_t >());
331
+ EXPECT_FALSE (cached);
332
+
333
+ // clear the cache
334
+ codegen::QueryCache::Instance ().Clear ();
335
+ EXPECT_EQ (0 , codegen::QueryCache::Instance ().GetCount ());
336
+
337
+ // execute SELECT b FROM table where b == 41;
338
+ codegen::BufferingConsumer buffer_2{{0 , 1 }, context_b};
339
+ CompileAndExecuteCache (plan_b, buffer_2, cached);
340
+
341
+ const auto &results_2 = buffer_2.GetOutputTuples ();
342
+ EXPECT_EQ (1 , results_2.size ());
343
+ EXPECT_EQ (41 , results_2[0 ].GetValue (1 ).GetAs <int32_t >());
344
+ EXPECT_FALSE (cached);
345
+
346
+ // cache has plan_b
347
+ EXPECT_EQ (1 , codegen::QueryCache::Instance ().GetCount ());
348
+
349
+ // re-execute SELECT a FROM table where a == 40;
350
+ codegen::BufferingConsumer buffer_3{{0 , 1 }, context_a};
351
+ CompileAndExecuteCache (plan_a, buffer_3, cached);
352
+
353
+ // cache should not hit
354
+ EXPECT_FALSE (cached);
355
+ const auto &results_3 = buffer_3.GetOutputTuples ();
356
+ EXPECT_EQ (1 , results_3.size ());
357
+ EXPECT_EQ (40 , results_1[0 ].GetValue (0 ).GetAs <int32_t >());
358
+
359
+ codegen::QueryCache::Instance ().Clear ();
360
+ EXPECT_EQ (0 , codegen::QueryCache::Instance ().GetCount ());
361
+ }
362
+
256
363
TEST_F (QueryCacheTest, CacheSeqScanPlan) {
257
364
int CACHE_USED_BY_CATALOG = codegen::QueryCache::Instance ().GetCount ();
258
365
0 commit comments