From ff227f875f5bf7b43671bd02584e9acbdd0c65f1 Mon Sep 17 00:00:00 2001
From: Mergen Imeev <imeevma@gmail.com>
Date: Thu, 5 May 2022 12:53:52 +0300
Subject: [PATCH] sql: fix type calculation for DATETIME arithmetic

After this correction DATETIME arithmetic result type will be
calculated correctly. Before this fix the type returned in the metadata
was "scalar".

Follow-up #6773

NO_DOC=Bugfix
NO_CHANGELOG=Bugfix
---
 src/box/sql/expr.c                 |  6 ++++
 test/sql-luatest/datetime_test.lua | 44 ++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index decb42b973..79b0607866 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -417,6 +417,12 @@ sql_type_result(enum field_type lhs, enum field_type rhs)
 		       rhs == FIELD_TYPE_UNSIGNED);
 		return FIELD_TYPE_UNSIGNED;
 	}
+	if ((lhs == FIELD_TYPE_DATETIME && rhs == FIELD_TYPE_DATETIME) ||
+	    (lhs == FIELD_TYPE_INTERVAL && rhs == FIELD_TYPE_INTERVAL))
+		return FIELD_TYPE_INTERVAL;
+	if ((lhs == FIELD_TYPE_INTERVAL && rhs == FIELD_TYPE_DATETIME) ||
+	    (lhs == FIELD_TYPE_DATETIME && rhs == FIELD_TYPE_INTERVAL))
+		return FIELD_TYPE_DATETIME;
 	return FIELD_TYPE_SCALAR;
 }
 
diff --git a/test/sql-luatest/datetime_test.lua b/test/sql-luatest/datetime_test.lua
index ad04e4adec..70bdd6ad4d 100644
--- a/test/sql-luatest/datetime_test.lua
+++ b/test/sql-luatest/datetime_test.lua
@@ -2860,3 +2860,47 @@ g.test_datetime_34_3 = function()
         t.assert_equals(box.execute(sql).rows, {{dt1}})
     end)
 end
+
+-- Properly compute type of result of DATETIME arithmetic.
+g.test_datetime_35 = function()
+    g.server:exec(function()
+        local t = require('luatest')
+        local dt = require('datetime')
+        local dt1 = dt.new({year = 1})
+        local itv1 = dt.interval.new({year = 1})
+
+        box.execute([[CREATE TABLE t(dt DATETIME PRIMARY KEY, itv INTERVAL);]])
+        box.execute([[INSERT INTO t VALUES (?, ?);]], {dt1, itv1})
+
+        local sql = [[SELECT typeof(dt - dt) FROM t;]]
+        t.assert_equals(box.execute(sql).rows, {{'interval'}})
+
+        sql = [[SELECT dt - dt FROM t;]]
+        t.assert_equals(box.execute(sql).metadata[1].type, 'interval')
+
+        sql = [[SELECT typeof(dt - itv) FROM t;]]
+        t.assert_equals(box.execute(sql).rows, {{'datetime'}})
+
+        sql = [[SELECT dt - itv FROM t;]]
+        t.assert_equals(box.execute(sql).metadata[1].type, 'datetime')
+
+        sql = [[SELECT typeof(dt + itv) FROM t;]]
+        t.assert_equals(box.execute(sql).rows, {{'datetime'}})
+
+        sql = [[SELECT dt + itv FROM t;]]
+        t.assert_equals(box.execute(sql).metadata[1].type, 'datetime')
+
+        sql = [[SELECT typeof(itv - itv) FROM t;]]
+        t.assert_equals(box.execute(sql).rows, {{'interval'}})
+
+        sql = [[SELECT itv - itv FROM t;]]
+        t.assert_equals(box.execute(sql).metadata[1].type, 'interval')
+
+        sql = [[SELECT typeof(itv + itv) FROM t;]]
+        t.assert_equals(box.execute(sql).rows, {{'interval'}})
+
+        sql = [[SELECT itv + itv FROM t;]]
+        t.assert_equals(box.execute(sql).metadata[1].type, 'interval')
+        box.execute([[DROP TABLE t;]])
+    end)
+end
-- 
GitLab