DRILL-748: C++ Client. Support timestamp/date before unix time and handle y2028 
problem.


Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/b90956e3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/b90956e3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/b90956e3

Branch: refs/heads/master
Commit: b90956e3afc96df3968d2e7882b449c506ea0924
Parents: aaa4db7
Author: Xiao Meng <[email protected]>
Authored: Fri May 30 11:31:44 2014 -0700
Committer: Jacques Nadeau <[email protected]>
Committed: Thu Jun 19 20:30:36 2014 -0700

----------------------------------------------------------------------
 LICENSE                                         |  26 +
 contrib/native/client/CMakeLists.txt            |   9 +-
 .../native/client/src/clientlib/CMakeLists.txt  |   2 +-
 .../native/client/src/clientlib/recordBatch.cpp |  80 +-
 .../client/src/clientlib/y2038/CMakeLists.txt   |  40 +
 .../native/client/src/clientlib/y2038/time64.c  | 830 +++++++++++++++++++
 .../native/client/src/clientlib/y2038/time64.h  | 110 +++
 .../client/src/clientlib/y2038/time64_config.h  | 107 +++
 .../client/src/clientlib/y2038/time64_limits.h  | 124 +++
 .../native/client/src/include/drill/drillc.hpp  |   2 +-
 .../client/src/include/drill/recordBatch.hpp    |  23 +-
 11 files changed, 1318 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b90956e3/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index 98d9950..f5352b1 100644
--- a/LICENSE
+++ b/LICENSE
@@ -287,6 +287,7 @@ For
   XML Commons External Components XML APIs 
(http://xml.apache.org/commons/#external) xml-apis:xml-apis:jar:1.0.b2
   XML Commons External Components XML APIs 
(http://xml.apache.org/commons/components/external/) 
xml-apis:xml-apis:jar:1.3.04
   Xml Compatibility extensions for Jackson (http://jackson.codehaus.org) 
org.codehaus.jackson:jackson-xc:jar:1.7.1
+  Y2038 (https://github.com/schwern/y2038)
 
   The Apache License, Version 2.0
 
@@ -678,3 +679,28 @@ For
  Reflections (http://code.google.com/p/reflections/) 
org.reflections:reflections:jar:0.9.8
 
   License: WTFPL  (http://en.wikipedia.org/wiki/WTFPL)
+
+For
+ Y2038 (https://github.com/schwern/y2038)
+
+The MIT License
+
+Copyright (c) 2007-2010 Michael G Schwern
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b90956e3/contrib/native/client/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/contrib/native/client/CMakeLists.txt 
b/contrib/native/client/CMakeLists.txt
index 9ac705b..31ac472 100644
--- a/contrib/native/client/CMakeLists.txt
+++ b/contrib/native/client/CMakeLists.txt
@@ -56,9 +56,12 @@ add_subdirectory("${CMAKE_SOURCE_DIR}/src/protobuf")
 include_directories(${ProtoHeadersDir})
 include_directories(${ProtoIncludesDir})
 
+# Y2038 library
+add_subdirectory("${CMAKE_SOURCE_DIR}/src/clientlib/y2038")
+
 # Build the Client Library as a shared library
 add_subdirectory("${CMAKE_SOURCE_DIR}/src/clientlib")
-include_directories(${CMAKE_SOURCE_DIR}/src/include ${Zookeeper_INCLUDE_DIRS}  
)
+include_directories(${CMAKE_SOURCE_DIR}/src/include ${Zookeeper_INCLUDE_DIRS})
 
 # add a DEBUG preprocessor macro
 set_property(
@@ -71,6 +74,4 @@ link_directories(/usr/local/lib)
 
 add_executable(querySubmitter example/querySubmitter.cpp )
 
-target_link_libraries(querySubmitter ${Boost_LIBRARIES} ${PROTOBUF_LIBRARY} 
drillClient protomsgs )
-
-
+target_link_libraries(querySubmitter ${Boost_LIBRARIES} ${PROTOBUF_LIBRARY} 
drillClient protomsgs y2038)

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b90956e3/contrib/native/client/src/clientlib/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/clientlib/CMakeLists.txt 
b/contrib/native/client/src/clientlib/CMakeLists.txt
index 7cd5dfb..37f4734 100644
--- a/contrib/native/client/src/clientlib/CMakeLists.txt
+++ b/contrib/native/client/src/clientlib/CMakeLists.txt
@@ -41,4 +41,4 @@ set_property(
     )
 
 add_library(drillClient SHARED ${CLIENTLIB_SRC_FILES} )
-target_link_libraries(drillClient ${Boost_LIBRARIES} ${PROTOBUF_LIBRARY} 
${Zookeeper_LIBRARIES} protomsgs)
+target_link_libraries(drillClient ${Boost_LIBRARIES} ${PROTOBUF_LIBRARY} 
${Zookeeper_LIBRARIES} protomsgs y2038)

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b90956e3/contrib/native/client/src/clientlib/recordBatch.cpp
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/clientlib/recordBatch.cpp 
b/contrib/native/client/src/clientlib/recordBatch.cpp
index 27a592d..90fe11a 100644
--- a/contrib/native/client/src/clientlib/recordBatch.cpp
+++ b/contrib/native/client/src/clientlib/recordBatch.cpp
@@ -24,6 +24,10 @@ const uint32_t YEARS_TO_MONTHS=12;
 const uint32_t HOURS_TO_MILLIS=60*60*1000;
 const uint32_t MINUTES_TO_MILLIS=60*1000;
 const uint32_t SECONDS_TO_MILLIS=1000;
+extern "C"
+{
+    #include "y2038/time64.h"
+}
 
 namespace Drill{
 
@@ -196,9 +200,9 @@ ValueVectorBase* 
ValueVectorFactory::allocateValueVector(const Drill::FieldMetad
                 case common::DECIMAL38SPARSE:
                     return new ValueVectorDecimal38Sparse(b,f.getValueCount(), 
f.getScale());
                 case common::DATE:
-                    return new ValueVectorTyped<DateHolder, 
uint64_t>(b,f.getValueCount());
+                    return new ValueVectorTyped<DateHolder, 
int64_t>(b,f.getValueCount());
                 case common::TIMESTAMP:
-                    return new ValueVectorTyped<DateTimeHolder, 
uint64_t>(b,f.getValueCount());
+                    return new ValueVectorTyped<DateTimeHolder, 
int64_t>(b,f.getValueCount());
                 case common::TIME:
                     return new ValueVectorTyped<TimeHolder, 
uint32_t>(b,f.getValueCount());
                 case common::TIMESTAMPTZ:
@@ -235,10 +239,10 @@ ValueVectorBase* 
ValueVectorFactory::allocateValueVector(const Drill::FieldMetad
                     return new 
NullableValueVectorFixed<double>(b,f.getValueCount());
                 case common::DATE:
                     return new NullableValueVectorTyped<DateHolder,
-                           ValueVectorTyped<DateHolder, uint64_t> 
>(b,f.getValueCount());
+                           ValueVectorTyped<DateHolder, int64_t> 
>(b,f.getValueCount());
                 case common::TIMESTAMP:
                     return new NullableValueVectorTyped<DateTimeHolder,
-                           ValueVectorTyped<DateTimeHolder, uint64_t> 
>(b,f.getValueCount());
+                           ValueVectorTyped<DateTimeHolder, int64_t> 
>(b,f.getValueCount());
                 case common::TIME:
                     return new NullableValueVectorTyped<TimeHolder,
                            ValueVectorTyped<TimeHolder, uint32_t> 
>(b,f.getValueCount());
@@ -357,12 +361,48 @@ void DateHolder::load(){
     m_year=1970;
     m_month=1;
     m_day=1;
-
-    time_t  t= m_datetime/1000; // number of seconds since beginning of the 
Unix Epoch.
-    struct tm * tm = gmtime(&t);
-    m_year=tm->tm_year+1900;
-    m_month=tm->tm_mon+1;
-    m_day=tm->tm_mday;
+    const Time64_T  t= m_datetime/1000; // number of seconds since beginning 
of the Unix Epoch.
+    /*
+    TL;DR
+
+    The gmttime in standard libray on windows platform cannot represent the 
date before Unix Epoch.
+    http://msdn.microsoft.com/en-us/library/0z9czt0w(v=vs.100).aspx
+
+    """
+    Both the 32-bit and 64-bit versions of gmtime, mktime, mkgmtime, and 
localtime all use one tm structure per thread for the conversion.
+    Each call to one of these functions destroys the result of any previous 
call.
+    If timer represents a date before midnight, January 1, 1970, gmtime 
returns NULL.  There is no error return.
+
+    _gmtime64, which uses the __time64_t structure, enables dates to be 
expressed up through 23:59:59, December 31, 3000, UTC,
+    whereas _gmtime32 only represent dates through 03:14:07 January 19, 2038, 
UTC.
+    Midnight, January 1, 1970, is the lower bound of the date range for both 
of these functions.
+
+    gmtime is an inline function that evaluates to _gmtime64 and time_t is 
equivalent to __time64_t unless _USE_32BIT_TIME_T is defined.
+    """
+
+    An alternative could be boost date_time libraray.
+
+    ```
+    #include <boost/date_time/posix_time/posix_time.hpp>
+    using namespace boost::posix_time;
+    ptime pt = from_time_t(t);
+    struct tm d = to_tm(pt);
+    ```
+
+    Howerver, boost date_time library still has year 2038 problem which is 
still not fixed.
+    https://svn.boost.org/trac/boost/ticket/4543
+    One reason is that the library converts the 64-bit`time_t t` into 
`seconds` type to get posix time.
+    But boost uses `long` to represent `seconds`, which is 4 bytes on windows 
platform,
+    http://msdn.microsoft.com/en-us/library/s3f49ktz.aspx
+
+    We eventually choose the third-party MIT-licensed library written with 
ANSI C.
+    https://github.com/schwern/y2038
+    */
+    struct TM d;
+    gmtime64_r(&t,&d);
+    m_year=1900 + static_cast<int32_t>(d.tm_year);
+    m_month=d.tm_mon + 1;
+    m_day=d.tm_mday;
 }
 
 std::string DateHolder::toString(){
@@ -400,15 +440,19 @@ void DateTimeHolder::load(){
     m_sec=0;
     m_msec=0;
 
-    time_t  t= m_datetime/1000; // number of seconds since beginning of the 
Unix Epoch.
-    struct tm * tm = gmtime(&t);
-    m_year=tm->tm_year+1900;
-    m_month=tm->tm_mon+1;
-    m_day=tm->tm_mday;
-    m_hr=tm->tm_hour;
-    m_min=tm->tm_min;
-    m_sec=tm->tm_sec;
+    const Time64_T  t=m_datetime/1000; // number of seconds since beginning of 
the Unix Epoch.
+
+    struct TM dt;
+    gmtime64_r(&t,&dt);
+
+    m_year=1900 + dt.tm_year;
+    m_month=dt.tm_mon + 1;
+    m_day=dt.tm_mday;
+    m_hr=dt.tm_hour;
+    m_min=dt.tm_min;
+    m_sec=dt.tm_sec;
     m_msec=m_datetime%1000;
+
 }
 
 std::string DateTimeHolder::toString(){

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b90956e3/contrib/native/client/src/clientlib/y2038/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/clientlib/y2038/CMakeLists.txt 
b/contrib/native/client/src/clientlib/y2038/CMakeLists.txt
new file mode 100644
index 0000000..1cb4d72
--- /dev/null
+++ b/contrib/native/client/src/clientlib/y2038/CMakeLists.txt
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Y2038 library
+
+if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCC)
+    set(CMAKE_CXX_FLAGS "-fPIC")
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCC)
+    set(CMAKE_C_FLAGS "-fPIC")
+endif()
+
+set (Y2038_SRC_FILES
+    ${CMAKE_CURRENT_SOURCE_DIR}/time64.c
+    )
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR} 
${CMAKE_CURRENT_SOURCE_DIR}/../../include )
+
+set_property(
+    DIRECTORY
+    PROPERTY COMPILE_DEFINITIONS_DEBUG DEBUG DEBUG=1 THREADED
+    )
+
+add_library(y2038 STATIC ${Y2038_SRC_FILES} )

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b90956e3/contrib/native/client/src/clientlib/y2038/time64.c
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/clientlib/y2038/time64.c 
b/contrib/native/client/src/clientlib/y2038/time64.c
new file mode 100644
index 0000000..e0d61c8
--- /dev/null
+++ b/contrib/native/client/src/clientlib/y2038/time64.c
@@ -0,0 +1,830 @@
+/* 
+
+Copyright (c) 2007-2010  Michael G Schwern
+
+This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
+
+The MIT License:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+/*
+
+Programmers who have available to them 64-bit time values as a 'long
+long' type can use localtime64_r() and gmtime64_r() which correctly
+converts the time even on 32-bit systems. Whether you have 64-bit time 
+values will depend on the operating system.
+
+localtime64_r() is a 64-bit equivalent of localtime_r().
+
+gmtime64_r() is a 64-bit equivalent of gmtime_r().
+
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include "time64.h"
+#include "time64_limits.h"
+
+
+/* Spec says except for stftime() and the _r() functions, these
+   all return static memory.  Stabbings! */
+static struct TM   Static_Return_Date;
+static char        Static_Return_String[35];
+
+static const char days_in_month[2][12] = {
+    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+};
+
+static const short julian_days_by_month[2][12] = {
+    {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
+    {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335},
+};
+
+static char wday_name[7][4] = {
+    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+};
+
+static char mon_name[12][4] = {
+    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static const short length_of_year[2] = { 365, 366 };
+
+/* Some numbers relating to the gregorian cycle */
+static const Year     years_in_gregorian_cycle   = 400;
+#define               days_in_gregorian_cycle      ((365 * 400) + 100 - 4 + 1)
+static const Time64_T seconds_in_gregorian_cycle = days_in_gregorian_cycle * 
60LL * 60LL * 24LL;
+
+/* Year range we can trust the time funcitons with */
+#define MAX_SAFE_YEAR 2037
+#define MIN_SAFE_YEAR 1971
+
+/* 28 year Julian calendar cycle */
+#define SOLAR_CYCLE_LENGTH 28
+
+/* Year cycle from MAX_SAFE_YEAR down. */
+static const short safe_years_high[SOLAR_CYCLE_LENGTH] = {
+    2016, 2017, 2018, 2019,
+    2020, 2021, 2022, 2023,
+    2024, 2025, 2026, 2027,
+    2028, 2029, 2030, 2031,
+    2032, 2033, 2034, 2035,
+    2036, 2037, 2010, 2011,
+    2012, 2013, 2014, 2015
+};
+
+/* Year cycle from MIN_SAFE_YEAR up */
+static const int safe_years_low[SOLAR_CYCLE_LENGTH] = {
+    1996, 1997, 1998, 1971,
+    1972, 1973, 1974, 1975,
+    1976, 1977, 1978, 1979,
+    1980, 1981, 1982, 1983,
+    1984, 1985, 1986, 1987,
+    1988, 1989, 1990, 1991,
+    1992, 1993, 1994, 1995,
+};
+
+/* This isn't used, but it's handy to look at */
+static const char dow_year_start[SOLAR_CYCLE_LENGTH] = {
+    5, 0, 1, 2,     /* 0       2016 - 2019 */
+    3, 5, 6, 0,     /* 4  */
+    1, 3, 4, 5,     /* 8       1996 - 1998, 1971*/
+    6, 1, 2, 3,     /* 12      1972 - 1975 */
+    4, 6, 0, 1,     /* 16 */
+    2, 4, 5, 6,     /* 20      2036, 2037, 2010, 2011 */
+    0, 2, 3, 4      /* 24      2012, 2013, 2014, 2015 */
+};
+
+/* Let's assume people are going to be looking for dates in the future.
+   Let's provide some cheats so you can skip ahead.
+   This has a 4x speed boost when near 2008.
+*/
+/* Number of days since epoch on Jan 1st, 2008 GMT */
+#define CHEAT_DAYS  (1199145600 / 24 / 60 / 60)
+#define CHEAT_YEARS 108
+
+#define IS_LEAP(n)      ((!(((n) + 1900) % 400) || (!(((n) + 1900) % 4) && 
(((n) + 1900) % 100))) != 0)
+#define WRAP(a,b,m)     ((a) = ((a) <  0  ) ? ((b)--, (a) + (m)) : (a))
+
+#ifdef USE_SYSTEM_LOCALTIME
+#    define SHOULD_USE_SYSTEM_LOCALTIME(a)  (       \
+    (a) <= SYSTEM_LOCALTIME_MAX &&              \
+    (a) >= SYSTEM_LOCALTIME_MIN                 \
+)
+#else
+#    define SHOULD_USE_SYSTEM_LOCALTIME(a)      (0)
+#endif
+
+#ifdef USE_SYSTEM_GMTIME
+#    define SHOULD_USE_SYSTEM_GMTIME(a)     (       \
+    (a) <= SYSTEM_GMTIME_MAX    &&              \
+    (a) >= SYSTEM_GMTIME_MIN                    \
+)
+#else
+#    define SHOULD_USE_SYSTEM_GMTIME(a)         (0)
+#endif
+
+/* Multi varadic macros are a C99 thing, alas */
+#ifdef TIME_64_DEBUG
+#    define TIME64_TRACE(format) (fprintf(stderr, format))
+#    define TIME64_TRACE1(format, var1)    (fprintf(stderr, format, var1))
+#    define TIME64_TRACE2(format, var1, var2)    (fprintf(stderr, format, 
var1, var2))
+#    define TIME64_TRACE3(format, var1, var2, var3)    (fprintf(stderr, 
format, var1, var2, var3))
+#else
+#    define TIME64_TRACE(format) ((void)0)
+#    define TIME64_TRACE1(format, var1) ((void)0)
+#    define TIME64_TRACE2(format, var1, var2) ((void)0)
+#    define TIME64_TRACE3(format, var1, var2, var3) ((void)0)
+#endif
+
+
+static int is_exception_century(Year year)
+{
+    int is_exception = ((year % 100 == 0) && !(year % 400 == 0));
+    TIME64_TRACE1("# is_exception_century: %s\n", is_exception ? "yes" : "no");
+
+    return(is_exception);
+}
+
+
+/* Compare two dates.
+   The result is like cmp.
+   Ignores things like gmtoffset and dst
+*/
+int cmp_date( const struct TM* left, const struct tm* right ) {
+    if( left->tm_year > right->tm_year )
+        return 1;
+    else if( left->tm_year < right->tm_year )
+        return -1;
+
+    if( left->tm_mon > right->tm_mon )
+        return 1;
+    else if( left->tm_mon < right->tm_mon )
+        return -1;
+
+    if( left->tm_mday > right->tm_mday )
+        return 1;
+    else if( left->tm_mday < right->tm_mday )
+        return -1;
+
+    if( left->tm_hour > right->tm_hour )
+        return 1;
+    else if( left->tm_hour < right->tm_hour )
+        return -1;
+
+    if( left->tm_min > right->tm_min )
+        return 1;
+    else if( left->tm_min < right->tm_min )
+        return -1;
+
+    if( left->tm_sec > right->tm_sec )
+        return 1;
+    else if( left->tm_sec < right->tm_sec )
+        return -1;
+
+    return 0;
+}
+
+
+/* Check if a date is safely inside a range.
+   The intention is to check if its a few days inside.
+*/
+int date_in_safe_range( const struct TM* date, const struct tm* min, const 
struct tm* max ) {
+    if( cmp_date(date, min) == -1 )
+        return 0;
+
+    if( cmp_date(date, max) == 1 )
+        return 0;
+
+    return 1;
+}
+
+
+/* timegm() is not in the C or POSIX spec, but it is such a useful
+   extension I would be remiss in leaving it out.  Also I need it
+   for localtime64()
+*/
+Time64_T timegm64(const struct TM *date) {
+    Time64_T days    = 0;
+    Time64_T seconds = 0;
+    Year     year;
+    Year     orig_year = (Year)date->tm_year;
+    int      cycles  = 0;
+
+    if( orig_year > 100 ) {
+        cycles = (orig_year - 100) / 400;
+        orig_year -= cycles * 400;
+        days      += (Time64_T)cycles * days_in_gregorian_cycle;
+    }
+    else if( orig_year < -300 ) {
+        cycles = (orig_year - 100) / 400;
+        orig_year -= cycles * 400;
+        days      += (Time64_T)cycles * days_in_gregorian_cycle;
+    }
+    TIME64_TRACE3("# timegm/ cycles: %d, days: %lld, orig_year: %lld\n", 
cycles, days, orig_year);
+
+    if( orig_year > 70 ) {
+        year = 70;
+        while( year < orig_year ) {
+            days += length_of_year[IS_LEAP(year)];
+            year++;
+        }
+    }
+    else if ( orig_year < 70 ) {
+        year = 69;
+        do {
+            days -= length_of_year[IS_LEAP(year)];
+            year--;
+        } while( year >= orig_year );
+    }
+
+    days += julian_days_by_month[IS_LEAP(orig_year)][date->tm_mon];
+    days += date->tm_mday - 1;
+
+    seconds = days * 60 * 60 * 24;
+
+    seconds += date->tm_hour * 60 * 60;
+    seconds += date->tm_min * 60;
+    seconds += date->tm_sec;
+
+    return(seconds);
+}
+
+
+static int check_tm(struct TM *tm)
+{
+    /* Don't forget leap seconds */
+    assert(tm->tm_sec >= 0);
+    assert(tm->tm_sec <= 61);
+
+    assert(tm->tm_min >= 0);
+    assert(tm->tm_min <= 59);
+
+    assert(tm->tm_hour >= 0);
+    assert(tm->tm_hour <= 23);
+
+    assert(tm->tm_mday >= 1);
+    assert(tm->tm_mday <= days_in_month[IS_LEAP(tm->tm_year)][tm->tm_mon]);
+
+    assert(tm->tm_mon  >= 0);
+    assert(tm->tm_mon  <= 11);
+
+    assert(tm->tm_wday >= 0);
+    assert(tm->tm_wday <= 6);
+    
+    assert(tm->tm_yday >= 0);
+    assert(tm->tm_yday <= length_of_year[IS_LEAP(tm->tm_year)]);
+
+#ifdef HAS_TM_TM_GMTOFF
+    assert(tm->tm_gmtoff >= -24 * 60 * 60);
+    assert(tm->tm_gmtoff <=  24 * 60 * 60);
+#endif
+
+    return 1;
+}
+
+
+/* The exceptional centuries without leap years cause the cycle to
+   shift by 16
+*/
+static Year cycle_offset(Year year)
+{
+    const Year start_year = 2000;
+    Year year_diff  = year - start_year;
+    Year exceptions;
+
+    if( year > start_year )
+        year_diff--;
+
+    exceptions  = year_diff / 100;
+    exceptions -= year_diff / 400;
+
+    TIME64_TRACE3("# year: %lld, exceptions: %lld, year_diff: %lld\n",
+          year, exceptions, year_diff);
+
+    return exceptions * 16;
+}
+
+/* For a given year after 2038, pick the latest possible matching
+   year in the 28 year calendar cycle.
+
+   A matching year...
+   1) Starts on the same day of the week.
+   2) Has the same leap year status.
+
+   This is so the calendars match up.
+
+   Also the previous year must match.  When doing Jan 1st you might
+   wind up on Dec 31st the previous year when doing a -UTC time zone.
+
+   Finally, the next year must have the same start day of week.  This
+   is for Dec 31st with a +UTC time zone.
+   It doesn't need the same leap year status since we only care about
+   January 1st.
+*/
+static int safe_year(const Year year)
+{
+    int safe_year;
+    Year year_cycle;
+
+    if( year >= MIN_SAFE_YEAR && year <= MAX_SAFE_YEAR ) {
+        return (int)year;
+    }
+
+    year_cycle = year + cycle_offset(year);
+
+    /* safe_years_low is off from safe_years_high by 8 years */
+    if( year < MIN_SAFE_YEAR )
+        year_cycle -= 8;
+
+    /* Change non-leap xx00 years to an equivalent */
+    if( is_exception_century(year) )
+        year_cycle += 11;
+
+    /* Also xx01 years, since the previous year will be wrong */
+    if( is_exception_century(year - 1) )
+        year_cycle += 17;
+
+    year_cycle %= SOLAR_CYCLE_LENGTH;
+    if( year_cycle < 0 ) 
+        year_cycle = SOLAR_CYCLE_LENGTH + year_cycle;
+
+    assert( year_cycle >= 0 );
+    assert( year_cycle < SOLAR_CYCLE_LENGTH );
+    if( year < MIN_SAFE_YEAR )
+        safe_year = safe_years_low[year_cycle];
+    else if( year > MAX_SAFE_YEAR )
+        safe_year = safe_years_high[year_cycle];
+    else
+        assert(0);
+
+    TIME64_TRACE3("# year: %lld, year_cycle: %lld, safe_year: %d\n",
+          year, year_cycle, safe_year);
+
+    assert(safe_year <= MAX_SAFE_YEAR && safe_year >= MIN_SAFE_YEAR);
+
+    return safe_year;
+}
+
+
+void copy_tm_to_TM64(const struct tm *src, struct TM *dest) {
+    if( src == NULL ) {
+        memset(dest, 0, sizeof(*dest));
+    }
+    else {
+#       ifdef USE_TM64
+            dest->tm_sec        = src->tm_sec;
+            dest->tm_min        = src->tm_min;
+            dest->tm_hour       = src->tm_hour;
+            dest->tm_mday       = src->tm_mday;
+            dest->tm_mon        = src->tm_mon;
+            dest->tm_year       = (Year)src->tm_year;
+            dest->tm_wday       = src->tm_wday;
+            dest->tm_yday       = src->tm_yday;
+            dest->tm_isdst      = src->tm_isdst;
+
+#           ifdef HAS_TM_TM_GMTOFF
+                dest->tm_gmtoff  = src->tm_gmtoff;
+#           endif
+
+#           ifdef HAS_TM_TM_ZONE
+                dest->tm_zone  = src->tm_zone;
+#           endif
+
+#       else
+            /* They're the same type */
+            memcpy(dest, src, sizeof(*dest));
+#       endif
+    }
+}
+
+
+void copy_TM64_to_tm(const struct TM *src, struct tm *dest) {
+    if( src == NULL ) {
+        memset(dest, 0, sizeof(*dest));
+    }
+    else {
+#       ifdef USE_TM64
+            dest->tm_sec        = src->tm_sec;
+            dest->tm_min        = src->tm_min;
+            dest->tm_hour       = src->tm_hour;
+            dest->tm_mday       = src->tm_mday;
+            dest->tm_mon        = src->tm_mon;
+            dest->tm_year       = (int)src->tm_year;
+            dest->tm_wday       = src->tm_wday;
+            dest->tm_yday       = src->tm_yday;
+            dest->tm_isdst      = src->tm_isdst;
+
+#           ifdef HAS_TM_TM_GMTOFF
+                dest->tm_gmtoff  = src->tm_gmtoff;
+#           endif
+
+#           ifdef HAS_TM_TM_ZONE
+                dest->tm_zone  = src->tm_zone;
+#           endif
+
+#       else
+            /* They're the same type */
+            memcpy(dest, src, sizeof(*dest));
+#       endif
+    }
+}
+
+
+/* Simulate localtime_r() to the best of our ability */
+struct tm * fake_localtime_r(const time_t *time, struct tm *result) {
+    const struct tm *static_result = localtime(time);
+
+    assert(result != NULL);
+
+    if( static_result == NULL ) {
+        memset(result, 0, sizeof(*result));
+        return NULL;
+    }
+    else {
+        memcpy(result, static_result, sizeof(*result));
+        return result;
+    }
+}
+
+
+/* Simulate gmtime_r() to the best of our ability */
+struct tm * fake_gmtime_r(const time_t *time, struct tm *result) {
+    const struct tm *static_result = gmtime(time);
+
+    assert(result != NULL);
+
+    if( static_result == NULL ) {
+        memset(result, 0, sizeof(*result));
+        return NULL;
+    }
+    else {
+        memcpy(result, static_result, sizeof(*result));
+        return result;
+    }
+}
+
+
+static Time64_T seconds_between_years(Year left_year, Year right_year) {
+    int increment = (left_year > right_year) ? 1 : -1;
+    Time64_T seconds = 0;
+    int cycles;
+
+    if( left_year > 2400 ) {
+        cycles = (left_year - 2400) / 400;
+        left_year -= cycles * 400;
+        seconds   += cycles * seconds_in_gregorian_cycle;
+    }
+    else if( left_year < 1600 ) {
+        cycles = (left_year - 1600) / 400;
+        left_year += cycles * 400;
+        seconds   += cycles * seconds_in_gregorian_cycle;
+    }
+
+    while( left_year != right_year ) {
+        seconds += length_of_year[IS_LEAP(right_year - 1900)] * 60 * 60 * 24;
+        right_year += increment;
+    }
+
+    return seconds * increment;
+}
+
+
+Time64_T mktime64(struct TM *input_date) {
+    struct tm safe_date;
+    struct TM date;
+    Time64_T  time;
+    Year      year = input_date->tm_year + 1900;
+
+    if( date_in_safe_range(input_date, &SYSTEM_MKTIME_MIN, &SYSTEM_MKTIME_MAX) 
)
+    {
+        copy_TM64_to_tm(input_date, &safe_date);
+        time = (Time64_T)mktime(&safe_date);
+
+        /* Correct the possibly out of bound input date */
+        copy_tm_to_TM64(&safe_date, input_date);
+        return time;
+    }
+
+    /* Have to make the year safe in date else it won't fit in safe_date */
+    date = *input_date;
+    date.tm_year = safe_year(year) - 1900;
+    copy_TM64_to_tm(&date, &safe_date);
+
+    time = (Time64_T)mktime(&safe_date);
+
+    /* Correct the user's possibly out of bound input date */
+    copy_tm_to_TM64(&safe_date, input_date);
+
+    time += seconds_between_years(year, (Year)(safe_date.tm_year + 1900));
+
+    return time;
+}
+
+
+/* Because I think mktime() is a crappy name */
+Time64_T timelocal64(struct TM *date) {
+    return mktime64(date);
+}
+
+
+struct TM *gmtime64_r (const Time64_T *in_time, struct TM *p)
+{
+    int v_tm_sec, v_tm_min, v_tm_hour, v_tm_mon, v_tm_wday;
+    Time64_T v_tm_tday;
+    int leap;
+    Time64_T m;
+    Time64_T time = *in_time;
+    Year year = 70;
+    int cycles = 0;
+
+    assert(p != NULL);
+
+    /* Use the system gmtime() if time_t is small enough */
+    if( SHOULD_USE_SYSTEM_GMTIME(*in_time) ) {
+        time_t safe_time = (time_t)*in_time;
+        struct tm safe_date;
+        GMTIME_R(&safe_time, &safe_date);
+
+        copy_tm_to_TM64(&safe_date, p);
+        assert(check_tm(p));
+
+        return p;
+    }
+
+#ifdef HAS_TM_TM_GMTOFF
+    p->tm_gmtoff = 0;
+#endif
+    p->tm_isdst  = 0;
+
+#ifdef HAS_TM_TM_ZONE
+    p->tm_zone   = "UTC";
+#endif
+
+    v_tm_sec =  (int)(time % 60);
+    time /= 60;
+    v_tm_min =  (int)(time % 60);
+    time /= 60;
+    v_tm_hour = (int)(time % 24);
+    time /= 24;
+    v_tm_tday = time;
+
+    WRAP (v_tm_sec, v_tm_min, 60);
+    WRAP (v_tm_min, v_tm_hour, 60);
+    WRAP (v_tm_hour, v_tm_tday, 24);
+
+    v_tm_wday = (int)((v_tm_tday + 4) % 7);
+    if (v_tm_wday < 0)
+        v_tm_wday += 7;
+    m = v_tm_tday;
+
+    if (m >= CHEAT_DAYS) {
+        year = CHEAT_YEARS;
+        m -= CHEAT_DAYS;
+    }
+
+    if (m >= 0) {
+        /* Gregorian cycles, this is huge optimization for distant times */
+        cycles = (int)(m / (Time64_T) days_in_gregorian_cycle);
+        if( cycles ) {
+            m -= (cycles * (Time64_T) days_in_gregorian_cycle);
+            year += (cycles * years_in_gregorian_cycle);
+        }
+
+        /* Years */
+        leap = IS_LEAP (year);
+        while (m >= (Time64_T) length_of_year[leap]) {
+            m -= (Time64_T) length_of_year[leap];
+            year++;
+            leap = IS_LEAP (year);
+        }
+
+        /* Months */
+        v_tm_mon = 0;
+        while (m >= (Time64_T) days_in_month[leap][v_tm_mon]) {
+            m -= (Time64_T) days_in_month[leap][v_tm_mon];
+            v_tm_mon++;
+        }
+    } else {
+        year--;
+
+        /* Gregorian cycles */
+        cycles = (int)((m / (Time64_T) days_in_gregorian_cycle) + 1);
+        if( cycles ) {
+            m -= (cycles * (Time64_T) days_in_gregorian_cycle);
+            year += (cycles * years_in_gregorian_cycle);
+        }
+
+        /* Years */
+        leap = IS_LEAP (year);
+        while (m < (Time64_T) -length_of_year[leap]) {
+            m += (Time64_T) length_of_year[leap];
+            year--;
+            leap = IS_LEAP (year);
+        }
+
+        /* Months */
+        v_tm_mon = 11;
+        while (m < (Time64_T) -days_in_month[leap][v_tm_mon]) {
+            m += (Time64_T) days_in_month[leap][v_tm_mon];
+            v_tm_mon--;
+        }
+        m += (Time64_T) days_in_month[leap][v_tm_mon];
+    }
+
+    p->tm_year = year;
+    if( p->tm_year != year ) {
+#ifdef EOVERFLOW
+        errno = EOVERFLOW;
+#endif
+        return NULL;
+    }
+
+    /* At this point m is less than a year so casting to an int is safe */
+    p->tm_mday = (int) m + 1;
+    p->tm_yday = julian_days_by_month[leap][v_tm_mon] + (int)m;
+    p->tm_sec  = v_tm_sec;
+    p->tm_min  = v_tm_min;
+    p->tm_hour = v_tm_hour;
+    p->tm_mon  = v_tm_mon;
+    p->tm_wday = v_tm_wday;
+    
+    assert(check_tm(p));
+
+    return p;
+}
+
+
+struct TM *localtime64_r (const Time64_T *time, struct TM *local_tm)
+{
+    time_t safe_time;
+    struct tm safe_date;
+    struct TM gm_tm;
+    Year orig_year;
+    int month_diff;
+
+    assert(local_tm != NULL);
+
+    /* Use the system localtime() if time_t is small enough */
+    if( SHOULD_USE_SYSTEM_LOCALTIME(*time) ) {
+        safe_time = (time_t)*time;
+
+        TIME64_TRACE1("Using system localtime for %lld\n", *time);
+
+        LOCALTIME_R(&safe_time, &safe_date);
+
+        copy_tm_to_TM64(&safe_date, local_tm);
+        assert(check_tm(local_tm));
+
+        return local_tm;
+    }
+
+    if( gmtime64_r(time, &gm_tm) == NULL ) {
+        TIME64_TRACE1("gmtime64_r returned null for %lld\n", *time);
+        return NULL;
+    }
+
+    orig_year = gm_tm.tm_year;
+
+    if (gm_tm.tm_year > (2037 - 1900) ||
+        gm_tm.tm_year < (1970 - 1900)
+       )
+    {
+        TIME64_TRACE1("Mapping tm_year %lld to safe_year\n", 
(Year)gm_tm.tm_year);
+        gm_tm.tm_year = safe_year((Year)(gm_tm.tm_year + 1900)) - 1900;
+    }
+
+    safe_time = (time_t)timegm64(&gm_tm);
+    if( LOCALTIME_R(&safe_time, &safe_date) == NULL ) {
+        TIME64_TRACE1("localtime_r(%d) returned NULL\n", (int)safe_time);
+        return NULL;
+    }
+
+    copy_tm_to_TM64(&safe_date, local_tm);
+
+    local_tm->tm_year = orig_year;
+    if( local_tm->tm_year != orig_year ) {
+        TIME64_TRACE2("tm_year overflow: tm_year %lld, orig_year %lld\n",
+              (Year)local_tm->tm_year, (Year)orig_year);
+
+#ifdef EOVERFLOW
+        errno = EOVERFLOW;
+#endif
+        return NULL;
+    }
+
+
+    month_diff = local_tm->tm_mon - gm_tm.tm_mon;
+
+    /*  When localtime is Dec 31st previous year and
+        gmtime is Jan 1st next year.
+    */
+    if( month_diff == 11 ) {
+        local_tm->tm_year--;
+    }
+
+    /*  When localtime is Jan 1st, next year and
+        gmtime is Dec 31st, previous year.
+    */
+    if( month_diff == -11 ) {
+        local_tm->tm_year++;
+    }
+
+    /* GMT is Jan 1st, xx01 year, but localtime is still Dec 31st 
+       in a non-leap xx00.  There is one point in the cycle
+       we can't account for which the safe xx00 year is a leap
+       year.  So we need to correct for Dec 31st comming out as
+       the 366th day of the year.
+    */
+    if( !IS_LEAP(local_tm->tm_year) && local_tm->tm_yday == 365 )
+        local_tm->tm_yday--;
+
+    assert(check_tm(local_tm));
+    
+    return local_tm;
+}
+
+
+int valid_tm_wday( const struct TM* date ) {
+    if( 0 <= date->tm_wday && date->tm_wday <= 6 )
+        return 1;
+    else
+        return 0;
+}
+
+int valid_tm_mon( const struct TM* date ) {
+    if( 0 <= date->tm_mon && date->tm_mon <= 11 )
+        return 1;
+    else
+        return 0;
+}
+
+
+char *asctime64_r( const struct TM* date, char *result ) {
+    /* I figure everything else can be displayed, even hour 25, but if
+       these are out of range we walk off the name arrays */
+    if( !valid_tm_wday(date) || !valid_tm_mon(date) )
+        return NULL;
+
+    sprintf(result, TM64_ASCTIME_FORMAT,
+        wday_name[date->tm_wday],
+        mon_name[date->tm_mon],
+        date->tm_mday, date->tm_hour,
+        date->tm_min, date->tm_sec,
+        1900 + date->tm_year);
+
+    return result;
+}
+
+
+char *ctime64_r( const Time64_T* time, char* result ) {
+    struct TM date;
+
+    localtime64_r( time, &date );
+    return asctime64_r( &date, result );
+}
+
+
+/* Non-thread safe versions of the above */
+struct TM *localtime64(const Time64_T *time) {
+    tzset();
+    return localtime64_r(time, &Static_Return_Date);
+}
+
+struct TM *gmtime64(const Time64_T *time) {
+    return gmtime64_r(time, &Static_Return_Date);
+}
+
+char *asctime64( const struct TM* date ) {
+    return asctime64_r( date, Static_Return_String );
+}
+
+char *ctime64( const Time64_T* time ) {
+    tzset();
+    return asctime64(localtime64(time));
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b90956e3/contrib/native/client/src/clientlib/y2038/time64.h
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/clientlib/y2038/time64.h 
b/contrib/native/client/src/clientlib/y2038/time64.h
new file mode 100644
index 0000000..89fbd7c
--- /dev/null
+++ b/contrib/native/client/src/clientlib/y2038/time64.h
@@ -0,0 +1,110 @@
+/* 
+
+Copyright (c) 2007-2010  Michael G Schwern
+
+This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
+
+The MIT License:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+
+#ifndef TIME64_H
+#    define TIME64_H
+
+#include <time.h>
+#include "time64_config.h"
+
+/* Set our custom types */
+typedef INT_64_T        Int64;
+typedef Int64           Time64_T;
+typedef Int64           Year;
+
+
+/* A copy of the tm struct but with a 64 bit year */
+struct TM64 {
+        int     tm_sec;
+        int     tm_min;
+        int     tm_hour;
+        int     tm_mday;
+        int     tm_mon;
+        Year    tm_year;
+        int     tm_wday;
+        int     tm_yday;
+        int     tm_isdst;
+
+#ifdef HAS_TM_TM_GMTOFF
+        long    tm_gmtoff;
+#endif
+
+#ifdef HAS_TM_TM_ZONE
+        char    *tm_zone;
+#endif
+};
+
+
+/* Decide which tm struct to use */
+#ifdef USE_TM64
+#define TM      TM64
+#else
+#define TM      tm
+#endif   
+
+
+/* Declare public functions */
+struct TM *gmtime64_r    (const Time64_T *, struct TM *);
+struct TM *localtime64_r (const Time64_T *, struct TM *);
+struct TM *gmtime64      (const Time64_T *);
+struct TM *localtime64   (const Time64_T *);
+
+char *asctime64          (const struct TM *);
+char *asctime64_r        (const struct TM *, char *);
+
+char *ctime64            (const Time64_T*);
+char *ctime64_r          (const Time64_T*, char*);
+
+Time64_T   timegm64      (const struct TM *);
+Time64_T   mktime64      (struct TM *);
+Time64_T   timelocal64   (struct TM *);
+
+
+/* Not everyone has gm/localtime_r(), provide a replacement */
+#ifdef HAS_LOCALTIME_R
+#    define LOCALTIME_R(clock, result) localtime_r(clock, result)
+#else
+#    define LOCALTIME_R(clock, result) fake_localtime_r(clock, result)
+#endif
+#ifdef HAS_GMTIME_R
+#    define GMTIME_R(clock, result)    gmtime_r(clock, result)
+#else
+#    define GMTIME_R(clock, result)    fake_gmtime_r(clock, result)
+#endif
+
+
+/* Use a different asctime format depending on how big the year is */
+#ifdef USE_TM64
+    #define TM64_ASCTIME_FORMAT "%.3s %.3s%3d %.2d:%.2d:%.2d %lld\n"
+#else
+    #define TM64_ASCTIME_FORMAT "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n"
+#endif
+
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b90956e3/contrib/native/client/src/clientlib/y2038/time64_config.h
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/clientlib/y2038/time64_config.h 
b/contrib/native/client/src/clientlib/y2038/time64_config.h
new file mode 100644
index 0000000..8f68bef
--- /dev/null
+++ b/contrib/native/client/src/clientlib/y2038/time64_config.h
@@ -0,0 +1,107 @@
+/* 
+
+Copyright (c) 2007-2010  Michael G Schwern
+
+This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
+
+The MIT License:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+
+/* Configuration
+   -------------
+   Define as appropriate for your system.
+   Sensible defaults provided.
+*/
+
+
+#ifndef TIME64_CONFIG_H
+#    define TIME64_CONFIG_H
+
+/* Debugging
+   TIME_64_DEBUG
+   Define if you want debugging messages
+*/
+/* #define TIME_64_DEBUG */
+
+
+/* INT_64_T
+   A 64 bit integer type to use to store time and others.
+   Must be defined.
+*/
+#define INT_64_T                long long
+
+
+/* USE_TM64
+   Should we use a 64 bit safe replacement for tm?  This will
+   let you go past year 2 billion but the struct will be incompatible
+   with tm.  Conversion functions will be provided.
+*/
+/* #define USE_TM64 */
+
+
+/* Availability of system functions.
+
+   HAS_GMTIME_R
+   Define if your system has gmtime_r()
+
+   HAS_LOCALTIME_R
+   Define if your system has localtime_r()
+
+   HAS_TIMEGM
+   Define if your system has timegm(), a GNU extension.
+*/
+#ifndef _WIN32
+#define HAS_GMTIME_R
+#define HAS_LOCALTIME_R
+#endif
+/* #define HAS_TIMEGM */
+
+
+/* Details of non-standard tm struct elements.
+
+   HAS_TM_TM_GMTOFF
+   True if your tm struct has a "tm_gmtoff" element.
+   A BSD extension.
+
+   HAS_TM_TM_ZONE
+   True if your tm struct has a "tm_zone" element.
+   A BSD extension.
+*/
+/* #define HAS_TM_TM_GMTOFF */
+/* #define HAS_TM_TM_ZONE */
+
+
+/* USE_SYSTEM_LOCALTIME
+   USE_SYSTEM_GMTIME
+   USE_SYSTEM_MKTIME
+   USE_SYSTEM_TIMEGM
+   Should we use the system functions if the time is inside their range?
+   Your system localtime() is probably more accurate, but our gmtime() is
+   fast and safe.
+*/
+#define USE_SYSTEM_LOCALTIME
+/* #define USE_SYSTEM_GMTIME */
+#define USE_SYSTEM_MKTIME
+/* #define USE_SYSTEM_TIMEGM */
+
+#endif /* TIME64_CONFIG_H */

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b90956e3/contrib/native/client/src/clientlib/y2038/time64_limits.h
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/clientlib/y2038/time64_limits.h 
b/contrib/native/client/src/clientlib/y2038/time64_limits.h
new file mode 100644
index 0000000..e640cae
--- /dev/null
+++ b/contrib/native/client/src/clientlib/y2038/time64_limits.h
@@ -0,0 +1,124 @@
+/* 
+
+Copyright (c) 2007-2010  Michael G Schwern
+
+This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
+
+The MIT License:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+
+/* 
+   Maximum and minimum inputs your system's respective time functions
+   can correctly handle.  time64.h will use your system functions if
+   the input falls inside these ranges and corresponding USE_SYSTEM_*
+   constant is defined.
+*/
+
+#ifndef TIME64_LIMITS_H
+#define TIME64_LIMITS_H
+
+/* Max/min for localtime() */
+#define SYSTEM_LOCALTIME_MAX     2147483647
+#define SYSTEM_LOCALTIME_MIN    -2147483647-1
+
+/* Max/min for gmtime() */
+#define SYSTEM_GMTIME_MAX        2147483647
+#define SYSTEM_GMTIME_MIN       -2147483647-1
+
+/* Max/min for mktime() */
+static const struct tm SYSTEM_MKTIME_MAX = {
+    7,
+    14,
+    19,
+    18,
+    0,
+    138,
+    1,
+    17,
+    0
+#ifdef HAS_TM_TM_GMTOFF
+    ,-28800
+#endif
+#ifdef HAS_TM_TM_ZONE
+    ,"PST"
+#endif
+};
+
+static const struct tm SYSTEM_MKTIME_MIN = {
+    52,
+    45,
+    12,
+    13,
+    11,
+    1,
+    5,
+    346,
+    0
+#ifdef HAS_TM_TM_GMTOFF
+    ,-28800
+#endif
+#ifdef HAS_TM_TM_ZONE
+    ,"PST"
+#endif
+};
+
+/* Max/min for timegm() */
+#ifdef HAS_TIMEGM
+static const struct tm SYSTEM_TIMEGM_MAX = {
+    7,
+    14,
+    3,
+    19,
+    0,
+    138,
+    2,
+    18,
+    0
+    #ifdef HAS_TM_TM_GMTOFF
+        ,0
+    #endif
+    #ifdef HAS_TM_TM_ZONE
+        ,"UTC"
+    #endif
+};
+
+static const struct tm SYSTEM_TIMEGM_MIN = {
+    52,
+    45,
+    20,
+    13,
+    11,
+    1,
+    5,
+    346,
+    0
+    #ifdef HAS_TM_TM_GMTOFF
+        ,0
+    #endif
+    #ifdef HAS_TM_TM_ZONE
+        ,"UTC"
+    #endif
+};
+#endif /* HAS_TIMEGM */
+
+#endif /* TIME64_LIMITS_H */

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b90956e3/contrib/native/client/src/include/drill/drillc.hpp
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/include/drill/drillc.hpp 
b/contrib/native/client/src/include/drill/drillc.hpp
index e5a0d33..817b680 100644
--- a/contrib/native/client/src/include/drill/drillc.hpp
+++ b/contrib/native/client/src/include/drill/drillc.hpp
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-#ifndef DRILL_CLIENT__ALL_H
+#ifndef DRILL_CLIENT_ALL_H
 #define DRILL_CLIENT_ALL_H
 
 #include "drill/common.hpp"

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b90956e3/contrib/native/client/src/include/drill/recordBatch.hpp
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/include/drill/recordBatch.hpp 
b/contrib/native/client/src/include/drill/recordBatch.hpp
index 4ed1e31..dab8b9b 100644
--- a/contrib/native/client/src/include/drill/recordBatch.hpp
+++ b/contrib/native/client/src/include/drill/recordBatch.hpp
@@ -403,19 +403,20 @@ template <typename VALUE_TYPE>
 // more complex and start doing dynamic allocations in these classes.
 
 struct DateTimeBase{
-    DateTimeBase(){m_datetime=0;}
+    DateTimeBase():m_datetime(0){}
     virtual ~DateTimeBase(){}
-    uint64_t m_datetime;
+    int64_t m_datetime;
+    int64_t getMillis() const { return m_datetime; }
     virtual void load() =0;
     virtual std::string toString()=0;
 };
 
 struct DateHolder: public virtual DateTimeBase{
     DateHolder(){};
-    DateHolder(uint64_t d){m_datetime=d; load();}
-    uint32_t m_year;
-    uint32_t m_month;
-    uint32_t m_day;
+    DateHolder(int64_t d){m_datetime=d; load();}
+    int32_t m_year;
+    int32_t m_month;
+    int32_t m_day;
     void load();
     std::string toString();
 };
@@ -433,21 +434,21 @@ struct TimeHolder: public virtual DateTimeBase{
 
 struct DateTimeHolder: public DateHolder, public TimeHolder{
     DateTimeHolder(){};
-    DateTimeHolder(uint64_t d){m_datetime=d; load();}
+    DateTimeHolder(int64_t d){m_datetime=d; load();}
     void load();
     std::string toString();
 };
 
 struct DateTimeTZHolder: public DateTimeHolder{
     DateTimeTZHolder(ByteBuf_t b){
-        m_datetime=*(uint64_t*)b;
+        m_datetime=*(int64_t*)b;
         m_tzIndex=*(uint32_t*)(b+sizeof(uint64_t));
         load();
     }
     void load();
     std::string toString();
     int32_t m_tzIndex;
-    static uint32_t size(){ return sizeof(uint64_t)+sizeof(uint32_t); }
+    static uint32_t size(){ return sizeof(int64_t)+sizeof(uint32_t); }
 
 };
 
@@ -703,8 +704,8 @@ typedef NullableValueVectorTyped<DecimalValue , 
ValueVectorDecimal38Dense> Nulla
 typedef NullableValueVectorTyped<DecimalValue , ValueVectorDecimal28Sparse> 
NullableValueVectorDecimal28Sparse;
 typedef NullableValueVectorTyped<DecimalValue , ValueVectorDecimal38Sparse> 
NullableValueVectorDecimal38Sparse;
 
-typedef ValueVectorTyped<DateHolder, uint64_t> ValueVectorDate;
-typedef ValueVectorTyped<DateTimeHolder, uint64_t> ValueVectorTimestamp;
+typedef ValueVectorTyped<DateHolder, int64_t> ValueVectorDate;
+typedef ValueVectorTyped<DateTimeHolder, int64_t> ValueVectorTimestamp;
 typedef ValueVectorTyped<TimeHolder, uint32_t> ValueVectorTime;
 typedef ValueVectorTypedComposite<DateTimeTZHolder> ValueVectorTimestampTZ;
 typedef ValueVectorTypedComposite<IntervalHolder> ValueVectorInterval;

Reply via email to