[Tarantool-patches] [PATCH 1/2] Restore partial date/time support in Tarantool SQL

Timur Safin tsafin at tarantool.org
Wed Apr 29 20:52:30 MSK 2020


Commit #3caeb33cdaf4b37974fd5f12e08310502d9e73f3 has disabled
DATETIME support in Tarantool SQL. Now we are restoring it
to make possible to run TPC-H queries. We restore functions
and they will use underlying STRING type, instead of actual
date types. This is better than nothing for today.

We will complete actual date/datetime types support once
DECIMAL type will land here.
---
 extra/mkkeywordhash.c |  10 ++--
 src/box/sql/date.c    |  70 ++++--------------------
 src/box/sql/dateInt.h | 122 ++++++++++++++++++++++++++++++++++++++++++
 src/box/sql/func.c    |  49 ++++++++---------
 src/box/sql/parse.y   |  27 +++++-----
 5 files changed, 174 insertions(+), 104 deletions(-)
 create mode 100644 src/box/sql/dateInt.h

diff --git a/extra/mkkeywordhash.c b/extra/mkkeywordhash.c
index dd42c8f5f..b6e7a687a 100644
--- a/extra/mkkeywordhash.c
+++ b/extra/mkkeywordhash.c
@@ -193,11 +193,11 @@ static Keyword aKeywordTable[] = {
   { "CURRENT",                "TK_STANDARD",    true  },
   { "CURRENT_USER",           "TK_STANDARD",    true  },
   { "CURSOR",                 "TK_STANDARD",    true  },
-  { "CURRENT_DATE",           "TK_STANDARD",    true  },
-  { "CURRENT_TIME",           "TK_STANDARD",    true  },
-  { "CURRENT_TIMESTAMP",      "TK_STANDARD",    true  },
-  { "DATE",                   "TK_STANDARD",    true  },
-  { "DATETIME",               "TK_STANDARD",    true  },
+  { "CURRENT_DATE",           "TK_CTIME_KW",    true  },
+  { "CURRENT_TIME",           "TK_CTIME_KW",    true  },
+  { "CURRENT_TIMESTAMP",      "TK_CTIME_KW",    true  },
+  { "DATE",                   "TK_DATE",        true  },
+  { "DATETIME",               "TK_DATETIME",    true  },
   { "DECIMAL",                "TK_STANDARD",    true  },
   { "DECLARE",                "TK_STANDARD",    true  },
   { "DENSE_RANK",             "TK_STANDARD",    true  },
diff --git a/src/box/sql/date.c b/src/box/sql/date.c
index dffc23616..41bff8b98 100644
--- a/src/box/sql/date.c
+++ b/src/box/sql/date.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2017, Tarantool AUTHORS, please see AUTHORS file.
+ * Copyright 2010-2020, Tarantool AUTHORS, please see AUTHORS file.
  *
  * Redistribution and use in source and binary forms, with or
  * without modification, are permitted provided that the following
@@ -64,17 +64,11 @@
  *      Willmann-Bell, Inc
  *      Richmond, Virginia (USA)
  */
-#include "sqlInt.h"
+#include "dateInt.h"
 #include <stdlib.h>
 #include <assert.h>
 #include <time.h>
 
-/*
- * Till time-like types are implemented as native Tarantool
- * types, built-in functions below make no sense.
- */
-#if 0
-
 /*
  * A structure for holding a single date and time.
  */
@@ -958,7 +952,7 @@ isDate(sql_context * context, int argc, sql_value ** argv, DateTime * p)
  *
  * Return the julian day number of the date specified in the arguments
  */
-static void
+void
 juliandayFunc(sql_context * context, int argc, sql_value ** argv)
 {
 	DateTime x;
@@ -973,7 +967,7 @@ juliandayFunc(sql_context * context, int argc, sql_value ** argv)
  *
  * Return YYYY-MM-DD HH:MM:SS
  */
-static void
+void
 datetimeFunc(sql_context * context, int argc, sql_value ** argv)
 {
 	DateTime x;
@@ -992,7 +986,7 @@ datetimeFunc(sql_context * context, int argc, sql_value ** argv)
  *
  * Return HH:MM:SS
  */
-static void
+void
 timeFunc(sql_context * context, int argc, sql_value ** argv)
 {
 	DateTime x;
@@ -1010,7 +1004,7 @@ timeFunc(sql_context * context, int argc, sql_value ** argv)
  *
  * Return YYYY-MM-DD
  */
-static void
+void
 dateFunc(sql_context * context, int argc, sql_value ** argv)
 {
 	DateTime x;
@@ -1042,7 +1036,7 @@ dateFunc(sql_context * context, int argc, sql_value ** argv)
  *   %Y  year 0000-9999
  *   %%  %
  */
-static void
+void
 strftimeFunc(sql_context * context, int argc, sql_value ** argv)
 {
 	DateTime x;
@@ -1215,7 +1209,7 @@ strftimeFunc(sql_context * context, int argc, sql_value ** argv)
  *
  * This function returns the same value as time('now').
  */
-static void
+void
 ctimeFunc(sql_context * context, int NotUsed, sql_value ** NotUsed2)
 {
 	UNUSED_PARAMETER2(NotUsed, NotUsed2);
@@ -1227,7 +1221,7 @@ ctimeFunc(sql_context * context, int NotUsed, sql_value ** NotUsed2)
  *
  * This function returns the same value as date('now').
  */
-static void
+void
 cdateFunc(sql_context * context, int NotUsed, sql_value ** NotUsed2)
 {
 	UNUSED_PARAMETER2(NotUsed, NotUsed2);
@@ -1239,54 +1233,10 @@ cdateFunc(sql_context * context, int NotUsed, sql_value ** NotUsed2)
  *
  * This function returns the same value as datetime('now').
  */
-static void
+void
 ctimestampFunc(sql_context * context,
 	       int NotUsed, sql_value ** NotUsed2)
 {
 	UNUSED_PARAMETER2(NotUsed, NotUsed2);
 	datetimeFunc(context, 0, 0);
 }
-#endif				/* !defined(SQL_OMIT_DATETIME_FUNCS) */
-
-#ifdef SQL_OMIT_DATETIME_FUNCS
-/*
- * If the library is compiled to omit the full-scale date and time
- * handling (to get a smaller binary), the following minimal version
- * of the functions current_time(), current_date() and current_timestamp()
- * are included instead. This is to support column declarations that
- * include "DEFAULT CURRENT_TIME" etc.
- *
- * This function uses the C-library functions time(), gmtime()
- * and strftime(). The format string to pass to strftime() is supplied
- * as the user-data for the function.
- */
-static void
-currentTimeFunc(sql_context * context, int argc, sql_value ** argv)
-{
-	time_t t;
-	char *zFormat = (char *)sql_user_data(context);
-	sql_int64 iT;
-	struct tm *pTm;
-	struct tm sNow;
-	char zBuf[20];
-
-	UNUSED_PARAMETER(argc);
-	UNUSED_PARAMETER(argv);
-
-	iT = sqlStmtCurrentTime(context);
-	if (iT <= 0)
-		return;
-	t = iT / 1000 - 10000 * (sql_int64) 21086676;
-#if HAVE_GMTIME_R
-	pTm = gmtime_r(&t, &sNow);
-#else
-	pTm = gmtime(&t);
-	if (pTm)
-		memcpy(&sNow, pTm, sizeof(sNow));
-#endif
-	if (pTm) {
-		strftime(zBuf, 20, zFormat, &sNow);
-		sql_result_text(context, zBuf, -1, SQL_TRANSIENT);
-	}
-}
-#endif
diff --git a/src/box/sql/dateInt.h b/src/box/sql/dateInt.h
new file mode 100644
index 000000000..78bc32c07
--- /dev/null
+++ b/src/box/sql/dateInt.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2010-2017, Tarantool AUTHORS, please see AUTHORS file.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Internal interface definitions for datetime support in sql.
+ *
+ */
+
+#ifndef dateINT_H
+#define dateINT_H
+
+#include "sqlInt.h"
+#include "vdbeInt.h"
+
+/*
+ *    julianday( TIMESTRING, MOD, MOD, ...)
+ *
+ * Return the julian day number of the date specified in the arguments
+ */
+void
+juliandayFunc(sql_context * context, int argc, sql_value ** argv);
+
+/*
+ *    datetime( TIMESTRING, MOD, MOD, ...)
+ *
+ * Return YYYY-MM-DD HH:MM:SS
+ */
+void
+datetimeFunc(sql_context * context, int argc, sql_value ** argv);
+
+/*
+ *    time( TIMESTRING, MOD, MOD, ...)
+ *
+ * Return HH:MM:SS
+ */
+void
+timeFunc(sql_context * context, int argc, sql_value ** argv);
+
+/*
+ *    date( TIMESTRING, MOD, MOD, ...)
+ *
+ * Return YYYY-MM-DD
+ */
+void
+dateFunc(sql_context * context, int argc, sql_value ** argv);
+
+/*
+ *    strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
+ *
+ * Return a string described by FORMAT.  Conversions as follows:
+ *
+ *   %d  day of month
+ *   %f  * fractional seconds  SS.SSS
+ *   %H  hour 00-24
+ *   %j  day of year 000-366
+ *   %J  * julian day number
+ *   %m  month 01-12
+ *   %M  minute 00-59
+ *   %s  seconds since 1970-01-01
+ *   %S  seconds 00-59
+ *   %w  day of week 0-6  sunday==0
+ *   %W  week of year 00-53
+ *   %Y  year 0000-9999
+ *   %%  %
+ */
+void
+strftimeFunc(sql_context * context, int argc, sql_value ** argv);
+
+/*
+ * current_time()
+ *
+ * This function returns the same value as time('now').
+ */
+void
+ctimeFunc(sql_context * context, int NotUsed, sql_value ** NotUsed2);
+
+/*
+ * current_date()
+ *
+ * This function returns the same value as date('now').
+ */
+void
+cdateFunc(sql_context * context, int NotUsed, sql_value ** NotUsed2);
+
+/*
+ * current_timestamp()
+ *
+ * This function returns the same value as datetime('now').
+ */
+void
+ctimestampFunc(sql_context * context, int NotUsed, sql_value ** NotUsed2);
+
+
+#endif				/* dateINT_H */
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index 376837217..65eaa50d9 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -36,6 +36,7 @@
  */
 #include "sqlInt.h"
 #include "vdbeInt.h"
+#include "dateInt.h"
 #include "version.h"
 #include "coll/coll.h"
 #include "tarantoolInt.h"
@@ -2306,50 +2307,50 @@ static struct {
 	 .export_to_sql = true,
 	}, {
 	 .name = "CURRENT_DATE",
-	 .call = sql_builtin_stub,
-	 .export_to_sql = false,
+	 .call = cdateFunc,
+	 .export_to_sql = true,
 	 .param_count = -1,
-	 .returns = FIELD_TYPE_ANY,
+	 .returns = FIELD_TYPE_STRING,
 	 .aggregate = FUNC_AGGREGATE_NONE,
 	 .is_deterministic = false,
 	 .flags = 0,
 	 .finalize = NULL,
 	}, {
 	 .name = "CURRENT_TIME",
-	 .call = sql_builtin_stub,
-	 .export_to_sql = false,
+	 .call = ctimeFunc,
+	 .export_to_sql = true,
 	 .param_count = -1,
-	 .returns = FIELD_TYPE_ANY,
+	 .returns = FIELD_TYPE_STRING,
 	 .aggregate = FUNC_AGGREGATE_NONE,
 	 .is_deterministic = false,
 	 .flags = 0,
 	 .finalize = NULL,
 	}, {
 	 .name = "CURRENT_TIMESTAMP",
-	 .call = sql_builtin_stub,
-	 .export_to_sql = false,
+	 .call = ctimestampFunc,
+	 .export_to_sql = true,
 	 .param_count = -1,
-	 .returns = FIELD_TYPE_ANY,
+	 .returns = FIELD_TYPE_STRING,
 	 .aggregate = FUNC_AGGREGATE_NONE,
 	 .is_deterministic = false,
 	 .flags = 0,
 	 .finalize = NULL,
 	}, {
 	 .name = "DATE",
-	 .call = sql_builtin_stub,
-	 .export_to_sql = false,
+	 .call = dateFunc,
+	 .export_to_sql = true,
 	 .param_count = -1,
-	 .returns = FIELD_TYPE_ANY,
+	 .returns = FIELD_TYPE_STRING,
 	 .aggregate = FUNC_AGGREGATE_NONE,
 	 .is_deterministic = false,
 	 .flags = 0,
 	 .finalize = NULL,
 	}, {
 	 .name = "DATETIME",
-	 .call = sql_builtin_stub,
-	 .export_to_sql = false,
+	 .call = datetimeFunc,
+	 .export_to_sql = true,
 	 .param_count = -1,
-	 .returns = FIELD_TYPE_ANY,
+	 .returns = FIELD_TYPE_STRING,
 	 .aggregate = FUNC_AGGREGATE_NONE,
 	 .is_deterministic = false,
 	 .flags = 0,
@@ -2456,10 +2457,10 @@ static struct {
 	 .export_to_sql = true,
 	}, {
 	 .name = "JULIANDAY",
-	 .call = sql_builtin_stub,
-	 .export_to_sql = false,
+	 .call = juliandayFunc,
+	 .export_to_sql = true,
 	 .param_count = -1,
-	 .returns = FIELD_TYPE_ANY,
+	 .returns = FIELD_TYPE_NUMBER,
 	 .aggregate = FUNC_AGGREGATE_NONE,
 	 .is_deterministic = false,
 	 .flags = 0,
@@ -2716,10 +2717,10 @@ static struct {
 	 .finalize = NULL,
 	}, {
 	 .name = "STRFTIME",
-	 .call = sql_builtin_stub,
-	 .export_to_sql = false,
+	 .call = strftimeFunc,
+	 .export_to_sql = true,
 	 .param_count = -1,
-	 .returns = FIELD_TYPE_ANY,
+	 .returns = FIELD_TYPE_STRING,
 	 .aggregate = FUNC_AGGREGATE_NONE,
 	 .is_deterministic = false,
 	 .flags = 0,
@@ -2746,10 +2747,10 @@ static struct {
 	 .export_to_sql = true,
 	}, {
 	 .name = "TIME",
-	 .call = sql_builtin_stub,
-	 .export_to_sql = false,
+	 .call = timeFunc,
+	 .export_to_sql = true,
 	 .param_count = -1,
-	 .returns = FIELD_TYPE_ANY,
+	 .returns = FIELD_TYPE_STRING,
 	 .aggregate = FUNC_AGGREGATE_NONE,
 	 .is_deterministic = false,
 	 .flags = 0,
diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y
index 995875566..ff88751f6 100644
--- a/src/box/sql/parse.y
+++ b/src/box/sql/parse.y
@@ -1178,10 +1178,8 @@ expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP(E). {
   }
 }
 
-/*
- * type_func(A) ::= DATE(A) .
- * type_func(A) ::= DATETIME(A) .
- */
+type_func(A) ::= DATE(A) .
+type_func(A) ::= DATETIME(A) .
 type_func(A) ::= CHAR(A) .
 expr(A) ::= type_func(X) LP distinct(D) exprlist(Y) RP(E). {
   if( Y && Y->nExpr>pParse->db->aLimit[SQL_LIMIT_FUNCTION_ARG] ){
@@ -1202,12 +1200,11 @@ expr(A) ::= id(X) LP STAR RP(E). {
   A.pExpr = sqlExprFunction(pParse, 0, &X);
   spanSet(&A,&X,&E);
 }
-/*
- * term(A) ::= CTIME_KW(OP). {
- *   A.pExpr = sqlExprFunction(pParse, 0, &OP);
- *   spanSet(&A, &OP, &OP);
- * }
- */
+
+term(A) ::= CTIME_KW(OP). {
+  A.pExpr = sqlExprFunction(pParse, 0, &OP);
+  spanSet(&A, &OP, &OP);
+}
 
 %include {
   /* This routine constructs a binary expression node out of two ExprSpan
@@ -1810,11 +1807,11 @@ typedef(A) ::= VARBINARY . { A.type = FIELD_TYPE_VARBINARY; }
 /**
  * Time-like types are temporary disabled, until they are
  * implemented as a native Tarantool types (gh-3694).
- *
- typedef(A) ::= DATE . { A.type = FIELD_TYPE_NUMBER; }
- typedef(A) ::= TIME . { A.type = FIELD_TYPE_NUMBER; }
- typedef(A) ::= DATETIME . { A.type = FIELD_TYPE_NUMBER; }
-*/
+ */
+
+typedef(A) ::= DATE . { A.type = FIELD_TYPE_NUMBER; }
+typedef(A) ::= TIME . { A.type = FIELD_TYPE_NUMBER; }
+typedef(A) ::= DATETIME . { A.type = FIELD_TYPE_NUMBER; }
 
 
 char_len(A) ::= LP INTEGER(B) RP . {
-- 
2.20.1



More information about the Tarantool-patches mailing list