From cc33caf7a0128a69f9f8abf8db71ddada3af20fc Mon Sep 17 00:00:00 2001
From: Igor Kuznetsov <kuznetsovin@gmail.com>
Date: Mon, 13 Dec 2021 15:30:52 +0300
Subject: [PATCH] feat: sync column info with tarantool box.execute format

---
 Cargo.toml                                    |  3 +-
 src/ir/relation.rs                            | 28 ++++++-
 src/ir/relation/tests.rs                      | 76 ++++++++++++++++++-
 .../ir/relation/table_seg_serialized.yaml     |  4 +
 4 files changed, 106 insertions(+), 5 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index c081e92bf1..ffb7f00933 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,13 +12,14 @@ fasthash = "0.4.0"
 serde = { version = "1.0", features = ["derive"] }
 serde_yaml = "0.8"
 sqlparser = "0.11.0"
-tarantool = { git = "https://sbroad-cargo-token:t-nZyqJVVuhGQv17BX6v@gitlab.com/picodata/picodata/tarantool-module.git", rev="8e388030"}
+tarantool = { git = "https://sbroad-cargo-token:t-nZyqJVVuhGQv17BX6v@gitlab.com/picodata/picodata/tarantool-module.git", rev="6f6bc329"}
 traversal = "0.1.2"
 yaml-rust = "0.4.1"
 
 [dev-dependencies]
 pretty_assertions = "1.0.0"
 itertools = "0.8.2"
+rmp-serde = "0.14"
 
 [lib]
 crate-type = ["cdylib"]
diff --git a/src/ir/relation.rs b/src/ir/relation.rs
index 6c49266a64..9bb5afdb31 100644
--- a/src/ir/relation.rs
+++ b/src/ir/relation.rs
@@ -2,22 +2,26 @@
 
 use std::collections::{HashMap, HashSet};
 
+use serde::ser::{Serialize as SerSerialize, SerializeMap, Serializer};
 use serde::{Deserialize, Serialize};
+use tarantool::hlua::{self, LuaRead};
 
 use crate::errors::QueryPlannerError;
 
 use super::value::Value;
 
 /// Supported column types.
-#[derive(Serialize, Deserialize, PartialEq, Debug)]
+#[derive(LuaRead, Serialize, Deserialize, PartialEq, Debug, Eq)]
 pub enum Type {
     Boolean,
     Number,
     String,
+    Integer,
+    Unsigned,
 }
 
 /// Relation column.
-#[derive(Serialize, Deserialize, PartialEq, Debug)]
+#[derive(LuaRead, Deserialize, PartialEq, Debug, Eq)]
 pub struct Column {
     /// Column name.
     pub name: String,
@@ -25,6 +29,26 @@ pub struct Column {
     pub r#type: Type,
 }
 
+/// Msgpack serializer for column
+impl SerSerialize for Column {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        let mut map = serializer.serialize_map(Some(2))?;
+        map.serialize_entry("name", &self.name)?;
+        match &self.r#type {
+            Type::Boolean => map.serialize_entry("type", "boolean")?,
+            Type::Number => map.serialize_entry("type", "number")?,
+            Type::Integer => map.serialize_entry("type", "integer")?,
+            Type::Unsigned => map.serialize_entry("type", "unsigned")?,
+            Type::String => map.serialize_entry("type", "string")?,
+        }
+
+        map.end()
+    }
+}
+
 #[allow(dead_code)]
 impl Column {
     /// Column constructor.
diff --git a/src/ir/relation/tests.rs b/src/ir/relation/tests.rs
index 7499949749..8619ba57b8 100644
--- a/src/ir/relation/tests.rs
+++ b/src/ir/relation/tests.rs
@@ -1,8 +1,10 @@
-use super::*;
-use pretty_assertions::{assert_eq, assert_ne};
 use std::fs;
 use std::path::Path;
 
+use pretty_assertions::{assert_eq, assert_ne};
+
+use super::*;
+
 #[test]
 fn column() {
     let a = Column {
@@ -85,6 +87,8 @@ fn table_seg_serialized() {
             Column::new("b", Type::Number),
             Column::new("c", Type::String),
             Column::new("d", Type::String),
+            Column::new("e", Type::Integer),
+            Column::new("f", Type::Unsigned),
         ],
         &["a", "d"],
     )
@@ -157,3 +161,71 @@ fn table_seg_serialized_no_columns() {
         QueryPlannerError::Serialization
     );
 }
+
+#[test]
+fn column_msgpack_serialize() {
+    let c = Column {
+        name: "name".into(),
+        r#type: Type::Boolean,
+    };
+
+    assert_eq!(
+        vec![
+            0x82, 0xA4, 0x6E, 0x61, 0x6D, 0x65, 0xA4, 0x6E, 0x61, 0x6D, 0x65, 0xA4, 0x74, 0x79,
+            0x70, 0x65, 0xA7, 0x62, 0x6F, 0x6F, 0x6C, 0x65, 0x61, 0x6E,
+        ],
+        rmp_serde::to_vec(&c).unwrap()
+    );
+
+    let c = Column {
+        name: "name".into(),
+        r#type: Type::String,
+    };
+
+    assert_eq!(
+        vec![
+            0x82, 0xA4, 0x6E, 0x61, 0x6D, 0x65, 0xA4, 0x6E, 0x61, 0x6D, 0x65, 0xA4, 0x74, 0x79,
+            0x70, 0x65, 0xA6, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67
+        ],
+        rmp_serde::to_vec(&c).unwrap()
+    );
+
+    let c = Column {
+        name: "name".into(),
+        r#type: Type::Integer,
+    };
+
+    assert_eq!(
+        vec![
+            0x82, 0xA4, 0x6E, 0x61, 0x6D, 0x65, 0xA4, 0x6E, 0x61, 0x6D, 0x65, 0xA4, 0x74, 0x79,
+            0x70, 0x65, 0xA7, 0x69, 0x6E, 0x74, 0x65, 0x67, 0x65, 0x72,
+        ],
+        rmp_serde::to_vec(&c).unwrap()
+    );
+
+    let c = Column {
+        name: "name".into(),
+        r#type: Type::Unsigned,
+    };
+
+    assert_eq!(
+        vec![
+            0x82, 0xA4, 0x6E, 0x61, 0x6D, 0x65, 0xA4, 0x6E, 0x61, 0x6D, 0x65, 0xA4, 0x74, 0x79,
+            0x70, 0x65, 0xA8, 0x75, 0x6E, 0x73, 0x69, 0x67, 0x6E, 0x65, 0x64,
+        ],
+        rmp_serde::to_vec(&c).unwrap()
+    );
+
+    let c = Column {
+        name: "name".into(),
+        r#type: Type::Number,
+    };
+
+    assert_eq!(
+        vec![
+            0x82, 0xA4, 0x6E, 0x61, 0x6D, 0x65, 0xA4, 0x6E, 0x61, 0x6D, 0x65, 0xA4, 0x74, 0x79,
+            0x70, 0x65, 0xA6, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72,
+        ],
+        rmp_serde::to_vec(&c).unwrap()
+    )
+}
diff --git a/tests/artifactory/ir/relation/table_seg_serialized.yaml b/tests/artifactory/ir/relation/table_seg_serialized.yaml
index 9912785127..a82f39da1b 100644
--- a/tests/artifactory/ir/relation/table_seg_serialized.yaml
+++ b/tests/artifactory/ir/relation/table_seg_serialized.yaml
@@ -8,6 +8,10 @@ Segment:
       type: String
     - name: d
       type: String
+    - name: e
+      type: Integer
+    - name: f
+      type: Unsigned
   name: t
   key:
     - 0
-- 
GitLab