Implement SC_get_localtime() and reduce time()/localtime() calls.
authorHiroshi Inoue <h-inoue@dream.email.ne.jp>
Tue, 9 May 2017 04:10:26 +0000 (13:10 +0900)
committerHiroshi Inoue <h-inoue@dream.email.ne.jp>
Sat, 13 May 2017 23:50:58 +0000 (08:50 +0900)
convert.c
statement.c
statement.h

index 7e5cb6996e4044be0d59560962976f34b536b46b..e46e2841f7dd497f6090b6f1f0788cd99b1a68d6 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -1224,7 +1224,6 @@ copy_and_convert_field(StatementClass *stmt,
    GetDataInfo *gdata = SC_get_GDTI(stmt);
    SQLLEN      len = 0;
    SIMPLE_TIME std_time;
-   struct tm  *tim;
 #ifdef HAVE_LOCALTIME_R
    struct tm  tm;
 #endif /* HAVE_LOCALTIME_R */
@@ -1443,6 +1442,7 @@ inolog("2stime fr=%d\n", std_time.fr);
                 * The timestamp is invalid so set something conspicuous,
                 * like the epoch
                 */
+               struct tm  *tim;
                time_t  t = 0;
 #ifdef HAVE_LOCALTIME_R
                tim = localtime_r(&t, &tm);
@@ -1662,7 +1662,6 @@ inolog("2stime fr=%d\n", std_time.fr);
    }
    else
    {
-       time_t  stmt_t = SC_get_time(stmt);
        SQLGUID g;
 
        /*
@@ -1688,6 +1687,7 @@ inolog("2stime fr=%d\n", std_time.fr);
                len = 6;
                {
                    DATE_STRUCT *ds;
+                   struct tm  *tim;
 
                    if (bind_size > 0)
                        ds = (DATE_STRUCT *) rgbValueBindRow;
@@ -1701,11 +1701,7 @@ inolog("2stime fr=%d\n", std_time.fr);
                     * sanity checks on the existing values before
                     * setting them.
                     */
-#ifdef HAVE_LOCALTIME_R
-                   tim = localtime_r(&stmt_t, &tm);
-#else
-                   tim = localtime(&stmt_t);
-#endif /* HAVE_LOCALTIME_R */
+                   tim = SC_get_localtime(stmt);
                    if (std_time.m == 0)
                        std_time.m = tim->tm_mon + 1;
                    if (std_time.d == 0)
@@ -1738,6 +1734,7 @@ inolog("2stime fr=%d\n", std_time.fr);
            case SQL_C_TYPE_TIMESTAMP:  /* 93 */
                len = 16;
                {
+                   struct tm  *tim;
                    TIMESTAMP_STRUCT *ts;
 
                    if (bind_size > 0)
@@ -1752,11 +1749,7 @@ inolog("2stime fr=%d\n", std_time.fr);
                     * sanity checks on the existing values before
                     * setting them.
                     */
-#ifdef HAVE_LOCALTIME_R
-                   tim = localtime_r(&stmt_t, &tm);
-#else
-                   tim = localtime(&stmt_t);
-#endif /* HAVE_LOCALTIME_R */
+                   tim = SC_get_localtime(stmt);
                    if (std_time.m == 0)
                        std_time.m = tim->tm_mon + 1;
                    if (std_time.d == 0)
@@ -4034,7 +4027,6 @@ ResolveOneParam(QueryBuild *qb, QueryParse *qp, BOOL *isnull, BOOL *isbinary,
    OID         param_pgtype;
    SQLSMALLINT param_ctype, param_sqltype;
    SIMPLE_TIME st;
-   time_t      t;
    struct tm   *tim;
 #ifdef HAVE_LOCALTIME_R
    struct tm   tm;
@@ -4282,7 +4274,6 @@ inolog("ipara=%p paramType=%d %d proc_return=%d\n", ipara, ipara ? ipara->paramT
    param_string[0] = '\0';
    cbuf[0] = '\0';
    memset(&st, 0, sizeof(st));
-   t = SC_get_time(qb->stmt);
 
    ivstruct = (SQL_INTERVAL_STRUCT *) buffer;
    /* Convert input C type to a neutral format */
@@ -4463,12 +4454,7 @@ mylog(" %s:C_WCHAR=%d contents=%s(%d)\n", __FUNCTION__, param_ctype, buffer, use
                 * Initialize date in case conversion destination
                 * expects date part from this source time data.
                 */
-               t = SC_get_time(qb->stmt);
-#ifdef HAVE_LOCALTIME_R
-               tim = localtime_r(&t, &tm);
-#else
-               tim = localtime(&t);
-#endif /* HAVE_LOCALTIME_R */
+               tim = SC_get_localtime(qb->stmt);
                st.m = tim->tm_mon + 1;
                st.d = tim->tm_mday;
                st.y = tim->tm_year + 1900;
index 69ee387a54da68c374e571a161570d71ae4a39c3..05f7c786762a2daafe6aee736f51fe490c88af57 100644 (file)
@@ -1168,6 +1168,8 @@ SC_clear_error(StatementClass *self)
        res->sqlstate[0] = '\0';
    }
    self->stmt_time = 0;
+   memset(&self->localtime, 0, sizeof(self->localtime));
+   self->localtime.tm_sec = -1;
    SC_unref_CC_error(self);
 }
 
@@ -1546,6 +1548,25 @@ SC_get_time(StatementClass *stmt)
    return stmt->stmt_time;
 }
 
+struct tm *
+SC_get_localtime(StatementClass *stmt)
+{
+   struct tm * tim;
+
+   if (stmt->localtime.tm_sec < 0)
+   {
+       SC_get_time(stmt);
+#ifdef HAVE_LOCALTIME_R
+       tim = localtime_r(&stmt->stmt_time, &(stmt->localtime));
+#else
+       tim = localtime(&stmt->stmt_time);
+       stmt->localtime = *tim;
+#endif /* HAVE_LOCALTIME_R */
+   }
+
+   return &(stmt->localtime);
+}
+
 RETCODE
 SC_fetch(StatementClass *self)
 {
index d564c9480100328b1f8aa576916e24253fd4e998..5707d942e47585095d06d4cb0f9f9c27eedb007e 100644 (file)
@@ -290,6 +290,7 @@ struct StatementClass_
    ssize_t     where_pos;
    SQLLEN      last_fetch_count_include_ommitted;
    time_t      stmt_time;
+   struct tm   localtime;
    /* SQL_NEED_DATA Callback list */
    StatementClass  *execute_delegate;
    StatementClass  *execute_parent;
@@ -510,6 +511,7 @@ RETCODE     SC_fetch(StatementClass *self);
 void       SC_free_params(StatementClass *self, char option);
 void       SC_log_error(const char *func, const char *desc, const StatementClass *self);
 time_t     SC_get_time(StatementClass *self);
+struct tm  *SC_get_localtime(StatementClass *self);
 SQLLEN     SC_get_int4_bookmark(StatementClass *self);
 RETCODE        SC_pos_reload(StatementClass *self, SQLULEN index, UInt2 *, Int4);
 RETCODE        SC_pos_update(StatementClass *self, SQLSETPOSIROW irow, SQLULEN index, const KeySet *keyset);