From a122f7bbdbe09062295fc369637e19a2d9c0e7f3 Mon Sep 17 00:00:00 2001
From: Denis Smirnov <sd@picodata.io>
Date: Wed, 2 Nov 2022 16:47:34 +0700
Subject: [PATCH] feat: make explain use the oldest snapshot

Explain should show the same version of the selection clause as we
use to build SQL.
---
 sbroad-core/src/frontend/sql/ir/tests.rs        | 12 ++++++------
 sbroad-core/src/frontend/sql/ir/tests/params.rs |  4 ++--
 sbroad-core/src/ir/explain.rs                   |  3 ++-
 sbroad-core/src/ir/explain/tests.rs             | 12 ++++++------
 4 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/sbroad-core/src/frontend/sql/ir/tests.rs b/sbroad-core/src/frontend/sql/ir/tests.rs
index e907af5f71..ca9f87804d 100644
--- a/sbroad-core/src/frontend/sql/ir/tests.rs
+++ b/sbroad-core/src/frontend/sql/ir/tests.rs
@@ -28,7 +28,7 @@ fn front_sql2() {
 
     let expected_explain = String::from(
         r#"projection ("hash_testing"."identification_number" -> "identification_number", "hash_testing"."product_code" -> "product_code")
-    selection ROW("hash_testing"."identification_number", "hash_testing"."product_code") = ROW(1, '1') or ROW("hash_testing"."identification_number", "hash_testing"."product_code") = ROW(2, '2')
+    selection ROW("hash_testing"."identification_number") = ROW(1) and ROW("hash_testing"."product_code") = ROW('1') or ROW("hash_testing"."identification_number") = ROW(2) and ROW("hash_testing"."product_code") = ROW('2')
         scan "hash_testing"
 "#,
     );
@@ -87,7 +87,7 @@ fn front_sql4() {
 
     let expected_explain = String::from(
         r#"projection ("t3"."identification_number" -> "identification_number", "t3"."product_code" -> "product_code")
-    selection ROW("t3"."product_code", "t3"."identification_number") = ROW('1', 1) or ROW("t3"."product_code", "t3"."identification_number") = ROW('2', 1) or ROW("t3"."product_code", "t3"."identification_number") = ROW('1', 2) or ROW("t3"."product_code", "t3"."identification_number") = ROW('2', 2) or ROW("t3"."product_code", "t3"."identification_number") = ROW('1', 3) or ROW("t3"."product_code", "t3"."identification_number") = ROW('2', 3)
+    selection ROW("t3"."identification_number") = ROW(1) or ROW("t3"."identification_number") = ROW(2) or ROW("t3"."identification_number") = ROW(3) and ROW("t3"."product_code") = ROW('1') or ROW("t3"."product_code") = ROW('2')
         scan "t3"
             union all
                 projection ("hash_testing"."identification_number" -> "identification_number", "hash_testing"."product_code" -> "product_code")
@@ -137,7 +137,7 @@ fn front_sql6() {
 
     let expected_explain = String::from(
         r#"projection ("T"."id" -> "id", "hash_testing"."product_units" -> "product_units")
-    selection ROW("hash_testing"."identification_number", "hash_testing"."product_code") = ROW(5, '123')
+    selection ROW("hash_testing"."identification_number") = ROW(5) and ROW("hash_testing"."product_code") = ROW('123')
         join on ROW("hash_testing"."identification_number") = ROW("T"."id")
             scan "hash_testing"
                 projection ("hash_testing"."identification_number" -> "identification_number", "hash_testing"."product_code" -> "product_code", "hash_testing"."product_units" -> "product_units", "hash_testing"."sys_op" -> "sys_op")
@@ -196,12 +196,12 @@ fn front_sql9() {
 
     let expected_explain = String::from(
         r#"projection ("t3"."id" -> "id", "t3"."FIRST_NAME" -> "FIRST_NAME", "t8"."identification_number" -> "identification_number", "t8"."product_code" -> "product_code")
-    selection ROW("t3"."id", "t8"."product_code", "t3"."id", "t8"."identification_number") = ROW("t8"."identification_number", '123', 1, 1)
+    selection ROW("t3"."id") = ROW(1) and ROW("t8"."identification_number") = ROW(1) and ROW("t8"."product_code") = ROW('123')
         join on ROW("t3"."id") = ROW("t8"."identification_number")
             scan "t3"
                 union all
                     projection ("test_space"."id" -> "id", "test_space"."FIRST_NAME" -> "FIRST_NAME")
-                        selection ROW("test_space"."sysFrom") >= ROW(0) and ROW("test_space"."sys_op") < ROW(0)
+                        selection ROW("test_space"."sys_op") < ROW(0) and ROW("test_space"."sysFrom") >= ROW(0)
                             scan "test_space"
                     projection ("test_space_hist"."id" -> "id", "test_space_hist"."FIRST_NAME" -> "FIRST_NAME")
                         selection ROW("test_space_hist"."sysFrom") <= ROW(0)
@@ -316,7 +316,7 @@ fn front_sql18() {
 
     let expected_explain = String::from(
         r#"projection ("hash_testing"."product_code" -> "product_code")
-    selection ROW("hash_testing"."product_code") <= ROW(2) and ROW("hash_testing"."product_code") >= ROW(1)
+    selection ROW("hash_testing"."product_code") >= ROW(1) and ROW("hash_testing"."product_code") <= ROW(2)
         scan "hash_testing"
 "#,
     );
diff --git a/sbroad-core/src/frontend/sql/ir/tests/params.rs b/sbroad-core/src/frontend/sql/ir/tests/params.rs
index 7e51538b04..dfe3dc2696 100644
--- a/sbroad-core/src/frontend/sql/ir/tests/params.rs
+++ b/sbroad-core/src/frontend/sql/ir/tests/params.rs
@@ -27,7 +27,7 @@ fn front_params2() {
 
     let expected_explain = String::from(
         r#"projection ("test_space"."id" -> "id")
-    selection ROW("test_space"."sys_op", "test_space"."FIRST_NAME") = ROW(NULL, 'hello')
+    selection ROW("test_space"."sys_op") = ROW(NULL) and ROW("test_space"."FIRST_NAME") = ROW('hello')
         scan "test_space"
 "#,
     );
@@ -45,7 +45,7 @@ fn front_params3() {
 
     let expected_explain = String::from(
         r#"projection ("test_space"."id" -> "id")
-    selection ROW("test_space"."sys_op", "test_space"."FIRST_NAME") = ROW(NULL, 'кириллица')
+    selection ROW("test_space"."sys_op") = ROW(NULL) and ROW("test_space"."FIRST_NAME") = ROW('кириллица')
         scan "test_space"
 "#,
     );
diff --git a/sbroad-core/src/ir/explain.rs b/sbroad-core/src/ir/explain.rs
index aadc21f74c..48796039c2 100644
--- a/sbroad-core/src/ir/explain.rs
+++ b/sbroad-core/src/ir/explain.rs
@@ -729,7 +729,8 @@ impl FullExplain {
                             "Selection node doesn't have any children".into(),
                         ));
                     }
-                    let s = Selection::new(ir, *filter, &sq_ref_map)?;
+                    let filter_id = ir.undo.get_oldest(filter).map_or_else(|| *filter, |id| *id);
+                    let s = Selection::new(ir, filter_id, &sq_ref_map)?;
                     Some(ExplainNode::Selection(s))
                 }
                 Relational::UnionAll { .. } => {
diff --git a/sbroad-core/src/ir/explain/tests.rs b/sbroad-core/src/ir/explain/tests.rs
index 393d49c078..5c91f9aaf6 100644
--- a/sbroad-core/src/ir/explain/tests.rs
+++ b/sbroad-core/src/ir/explain/tests.rs
@@ -35,7 +35,7 @@ fn simple_query_with_cond_plan() {
     let mut actual_explain = String::new();
     actual_explain.push_str(
         r#"projection ("t"."identification_number" -> "c1", "t"."product_code" -> "product_code")
-    selection ROW("t"."identification_number", "t"."product_code") = ROW(1, '222')
+    selection ROW("t"."identification_number") = ROW(1) and ROW("t"."product_code") = ROW('222')
         scan "hash_testing" -> "t"
 "#,
     );
@@ -85,7 +85,7 @@ WHERE "id" = 1"#;
         scan "t"
             union all
                 projection ("test_space"."id" -> "id", "test_space"."FIRST_NAME" -> "FIRST_NAME")
-                    selection ROW("test_space"."sysFrom") < ROW(0) and ROW("test_space"."sys_op") > ROW(0)
+                    selection ROW("test_space"."sys_op") > ROW(0) and ROW("test_space"."sysFrom") < ROW(0)
                         scan "test_space"
                 projection ("test_space_hist"."id" -> "id", "test_space_hist"."FIRST_NAME" -> "FIRST_NAME")
                     selection ROW("test_space_hist"."sys_op") < ROW(0)
@@ -122,7 +122,7 @@ WHERE "id" IN (SELECT "id"
         scan "t"
             union all
                 projection ("test_space"."id" -> "id", "test_space"."FIRST_NAME" -> "FIRST_NAME")
-                    selection ROW("test_space"."sysFrom") < ROW(0) and ROW("test_space"."sys_op") > ROW(0)
+                    selection ROW("test_space"."sys_op") > ROW(0) and ROW("test_space"."sysFrom") < ROW(0)
                         scan "test_space"
                 projection ("test_space_hist"."id" -> "id", "test_space_hist"."FIRST_NAME" -> "FIRST_NAME")
                     selection ROW("test_space_hist"."sys_op") < ROW(0)
@@ -194,7 +194,7 @@ WHERE "id" IN (SELECT "id"
         scan "t"
             union all
                 projection ("test_space"."id" -> "id", "test_space"."FIRST_NAME" -> "FIRST_NAME")
-                    selection ROW("test_space"."sysFrom") < ROW(0) and ROW("test_space"."sys_op") > ROW(0)
+                    selection ROW("test_space"."sys_op") > ROW(0) and ROW("test_space"."sysFrom") < ROW(0)
                         scan "test_space"
                 projection ("test_space_hist"."id" -> "id", "test_space_hist"."FIRST_NAME" -> "FIRST_NAME")
                     selection ROW("test_space_hist"."sys_op") < ROW(0)
@@ -215,7 +215,7 @@ subquery $1:
 motion [policy: segment([ref("identification_number")]), generation: none]
             scan
                 projection ("hash_testing"."identification_number" -> "identification_number")
-                    selection ROW("hash_testing"."identification_number", "hash_testing"."product_code") = ROW(5, '123')
+                    selection ROW("hash_testing"."identification_number") = ROW(5) and ROW("hash_testing"."product_code") = ROW('123')
                         scan "hash_testing"
 "#);
 
@@ -295,7 +295,7 @@ fn unary_condition_plan() {
     let mut actual_explain = String::new();
     actual_explain.push_str(
         r#"projection ("test_space"."id" -> "id", "test_space"."FIRST_NAME" -> "FIRST_NAME")
-    selection ROW("test_space"."FIRST_NAME") is not null and ROW("test_space"."id") is null
+    selection ROW("test_space"."id") is null and ROW("test_space"."FIRST_NAME") is not null
         scan "test_space"
 "#,
     );
-- 
GitLab