trafodion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ansha...@apache.org
Subject [06/12] trafodion git commit: nanosecs precision for timestamp/interval datatypes
Date Sat, 23 Jun 2018 22:32:47 GMT
nanosecs precision for timestamp/interval datatypes


Project: http://git-wip-us.apache.org/repos/asf/trafodion/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafodion/commit/319abf81
Tree: http://git-wip-us.apache.org/repos/asf/trafodion/tree/319abf81
Diff: http://git-wip-us.apache.org/repos/asf/trafodion/diff/319abf81

Branch: refs/heads/master
Commit: 319abf81860b6102658f48802172b6ea9aa607a0
Parents: 288ed21
Author: Anoop Sharma <anoop.sharma@esgyn.com>
Authored: Mon Jun 11 18:16:21 2018 +0000
Committer: Anoop Sharma <anoop.sharma@esgyn.com>
Committed: Mon Jun 11 18:16:21 2018 +0000

----------------------------------------------------------------------
 .../trafodion/jdbc/t4/InterfaceResultSet.java   |    7 +-
 core/sql/bin/SqlciErrors.txt                    |    3 +-
 core/sql/cli/Descriptor.cpp                     |    4 +-
 core/sql/common/DateTimeType.cpp                |   28 +-
 core/sql/common/DatetimeType.h                  |    5 +-
 core/sql/common/IntervalType.cpp                |   17 +-
 core/sql/common/IntervalType.h                  |    3 +-
 core/sql/common/NAType.cpp                      |    2 +-
 core/sql/exp/ExpConvMxcs.cpp                    |    2 +-
 core/sql/exp/ExpErrorEnums.h                    |    1 +
 core/sql/exp/exp_arith.cpp                      |  444 +-
 core/sql/exp/exp_bignum.h                       |   17 +-
 core/sql/exp/exp_conv.cpp                       |    6 +
 core/sql/exp/exp_datetime.cpp                   |  243 +-
 core/sql/exp/exp_datetime.h                     |   12 +-
 core/sql/exp/exp_fixup.cpp                      |    6 +-
 core/sql/langman/LmLangManagerJava.cpp          |    4 +-
 core/sql/optimizer/QRDescGenerator.cpp          |   15 +-
 core/sql/parser/StmtDDLMisc.cpp                 |   10 +
 core/sql/regress/core/EXPECTED162               |  762 +--
 core/sql/regress/core/TEST038                   |    2 +-
 core/sql/regress/executor/EXPECTED022.SB        | 6041 ++----------------
 core/sql/regress/executor/TEST022               | 1083 ++--
 core/sql/regress/hive/EXPECTED001               |  762 +--
 core/sql/regress/hive/EXPECTED004               |   28 +-
 core/sql/regress/hive/EXPECTED005               |  130 +-
 core/sql/regress/seabase/EXPECTED002            |  250 +-
 core/sql/regress/udr/EXPECTED100.SB             |   26 +-
 core/sql/regress/udr/TEST100                    |   19 +-
 core/sql/regress/udr/t100.java                  |    4 +
 core/sql/sqlci/SqlCmd.cpp                       |   19 +-
 .../java/org/trafodion/sql/udr/TypeInfo.java    |   18 +-
 32 files changed, 2625 insertions(+), 7348 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceResultSet.java
----------------------------------------------------------------------
diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceResultSet.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceResultSet.java
index 7273338..7232009 100644
--- a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceResultSet.java
+++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/InterfaceResultSet.java
@@ -253,6 +253,7 @@ class InterfaceResultSet {
 				retObj = Date.valueOf(tmpStr);
 				break;
 			case SQLDTCODE_TIMESTAMP:
+                            System.out.println("tmpStr = " + tmpStr);
 				retObj = Timestamp.valueOf(tmpStr);
 				break;
 			case SQLDTCODE_TIME:
@@ -448,9 +449,6 @@ class InterfaceResultSet {
 					if (desc.sqlPrecision_ > 0) {
 						nanoSeconds = Bytes.extractUInt(values, noNullValue + 7, swap);
 
-						if (nanoSeconds > 999999) // returned in microseconds
-							nanoSeconds = 0;
-
 						// apply leading 0's for string conversion
 						tmpStr = "" + nanoSeconds;
 						length = tmpStr.length();
@@ -489,9 +487,6 @@ class InterfaceResultSet {
 						if (desc.sqlPrecision_ > 0) {
 							nanoSeconds = Bytes.extractUInt(values, noNullValue + 3, swap);
 
-							if (nanoSeconds > 999999) // returned in microseconds
-								nanoSeconds = 0;
-
 							String formatStr = "";
 							for(int i=0;i<desc.sqlPrecision_;i++)
 								formatStr += "0";

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/bin/SqlciErrors.txt
----------------------------------------------------------------------
diff --git a/core/sql/bin/SqlciErrors.txt b/core/sql/bin/SqlciErrors.txt
index 23279fb..0053576 100644
--- a/core/sql/bin/SqlciErrors.txt
+++ b/core/sql/bin/SqlciErrors.txt
@@ -887,7 +887,7 @@ $1~String1 --------------------------------
 3131 0A000 99999 BEGINNER MAJOR DBADMIN The statement just entered is currently not supported.
 3132 42000 99999 BEGINNER MAJOR DBADMIN The HEADING for column $0~ColumnName exceeds the maximum size of 128 characters.
 3133 42000 99999 BEGINNER MAJOR DBADMIN PERFORM is valid only in COBOL programs.
-3134 42000 99999 BEGINNER MAJOR DBADMIN The specified TIME or TIMESTAMP precision value, $0~int0, cannot exceed 6.
+3134 42000 99999 BEGINNER MAJOR DBADMIN The specified TIME or TIMESTAMP precision value, $0~int0, cannot exceed 9.
 3135 42000 99999 BEGINNER MAJOR DBADMIN The precision of float, $0~int0, cannot exceed 54.
 3136 42000 99999 BEGINNER MAJOR DBADMIN Only LEFT, RIGHT, and FULL OUTER JOIN are valid in {oj ...}
 3137 0A000 99999 BEGINNER MAJOR DBADMIN UNION JOIN is not yet supported.
@@ -1589,6 +1589,7 @@ $1~String1 --------------------------------
 8450 ZZZZZ 99999 BEGINNER MINOR LOGONLY ESP number ($0~Int0) has processed ($1~Int1) transactions of the LRU operation on table $2~String0.
 8451 ZZZZZ 99999 BEGINNER MINOR LOGONLY Error $0~String0  returned while retrieving region stats from hbase.
 8452 ZZZZZ 99999 BEGINNER MINOR LOGONLY The regular expression is invalid. Cause: $0~String0
+8453 ZZZZZ 99999 BEGINNER MINOR LOGONLY This expression results in an invalid interval value '$0~String0'
 8550 ZZZZZ 99999 ADVANCED MAJOR DBADMIN Error $0~NSKCode was returned by the Data Access Manager.
 8551 ZZZZZ 99999 ADVANCED MAJOR DBADMIN Error $0~NSKCode was returned by the file system on $0~string0$1~string1.
 8552 ZZZZZ 99999 ADVANCED MAJOR DBADMIN Error $0~int0 was returned by the file system while fetching the version of the system $0~string0.

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/cli/Descriptor.cpp
----------------------------------------------------------------------
diff --git a/core/sql/cli/Descriptor.cpp b/core/sql/cli/Descriptor.cpp
index a1a607f..47110c0 100644
--- a/core/sql/cli/Descriptor.cpp
+++ b/core/sql/cli/Descriptor.cpp
@@ -1501,7 +1501,7 @@ void Descriptor::DescItemDefaultsForDatetimeCode(
         case SQLINTCODE_HOUR_SECOND:
         case SQLINTCODE_DAY_SECOND:
           // 17.5 - GR 5-j-i
-          descItem.precision          = 6;
+          descItem.precision          = 9;
           break;
 
         default:
@@ -1519,7 +1519,7 @@ void Descriptor::DescItemDefaultsForDatetimeCode(
         case SQLDTCODE_TIMESTAMP:
         // none with Timezone yet
           // 17.5 - GR 5-i-i
-          descItem.precision          = 6;
+          descItem.precision          = 9;
           break;
 
         case SQLDTCODE_TIME:

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/common/DateTimeType.cpp
----------------------------------------------------------------------
diff --git a/core/sql/common/DateTimeType.cpp b/core/sql/common/DateTimeType.cpp
index de67e74..be5a903 100644
--- a/core/sql/common/DateTimeType.cpp
+++ b/core/sql/common/DateTimeType.cpp
@@ -314,9 +314,13 @@ Int64 DatetimeType::julianTimestampValue(const char * value, const short valueLe
     {
       str_cpy_all((char *) &fraction, datetimeOpData, sizeof(fraction));
       if (fractionPrec > 0)
-        // Adjust the fractional seconds part to be the number of microseconds.
-        fraction *= (Lng32)pow(10, (DatetimeType::MAX_FRACTION_PRECISION
-                                        - fractionPrec));
+        {
+          if (fractionPrec > DatetimeType::MAX_FRACTION_PRECISION_MSEC)
+            // Adjust the fractional seconds part to be the number of microseconds
+            fraction /= (Lng32)pow(10, (fractionPrec - DatetimeType::MAX_FRACTION_PRECISION_MSEC));
+          else 
+            fraction *= (Lng32)pow(10, (DatetimeType::MAX_FRACTION_PRECISION_MSEC - fractionPrec));
+        }
     }
   short timestamp[] = {
     year, month, day, hour, minute, second, (short)(fraction / 1000), (short)(fraction % 1000)
@@ -584,7 +588,7 @@ const NAType* DatetimeType::synthesizeType(enum NATypeSynthRuleEnum synthRule,
                                  (datetime2->supportsSQLnull())) ? TRUE : FALSE);
 
         UInt32 fractionPrecision = MAXOF(datetime1->getFractionPrecision(),
-					   datetime2->getFractionPrecision());
+                                         datetime2->getFractionPrecision());
 
         if ((modeSpecial4) &&
             (fractionPrecision == 0) &&
@@ -597,8 +601,16 @@ const NAType* DatetimeType::synthesizeType(enum NATypeSynthRuleEnum synthRule,
           }
         else
           {
-            return new(h) SQLInterval(h, allowNulls, datetime1->getEndField(),
-                                      12, datetime1->getEndField(),
+            Int32 leadingPrecision = IntervalType::computeLeadingPrecision
+              (datetime1->getEndField(), 
+               SQLInterval::MAX_LEADING_PRECISION, 
+               datetime1->getEndField(),
+               fractionPrecision);
+            
+            return new(h) SQLInterval(h, allowNulls, 
+                                      datetime1->getEndField(),
+                                      leadingPrecision, 
+                                      datetime1->getEndField(),
                                       fractionPrecision);
           }
       }
@@ -1383,7 +1395,7 @@ DatetimeValue::DatetimeValue
 
   ComDiagsArea *diags = NULL;
 
-  Lng32 trueFP = 6;
+  Lng32 trueFP = DatetimeType::MAX_FRACTION_PRECISION;
   ULng32 flags = 0;
   flags |= CONV_NO_HADOOP_DATE_FIX;
   short rc = 
@@ -1399,7 +1411,7 @@ DatetimeValue::DatetimeValue
   if (endField == REC_DATE_SECOND)
     {
       Lng32 fp = trueFP;
-      for (; fp < 6; fp++)
+      for (; fp < DatetimeType::MAX_FRACTION_PRECISION; fp++)
         {
           if (startField == REC_DATE_YEAR)
             *(Lng32*)&dstValue[7] /= 10;

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/common/DatetimeType.h
----------------------------------------------------------------------
diff --git a/core/sql/common/DatetimeType.h b/core/sql/common/DatetimeType.h
index e948fd5..9aa5373 100644
--- a/core/sql/common/DatetimeType.h
+++ b/core/sql/common/DatetimeType.h
@@ -69,7 +69,10 @@ class DatetimeType : public DatetimeIntervalCommonType
 public:
 
   enum { DEFAULT_FRACTION_PRECISION = 0 };      // See ANSI 6.1 SR 25: zero
-  enum { MAX_FRACTION_PRECISION = 6 };  // See ANSI 6.1 SR 26: max is at least 6
+  enum { MAX_FRACTION_PRECISION_MSEC = 6 }; // max microseconds fract precision
+  enum { MAX_FRACTION_PRECISION = 9 };  // See ANSI 6.1 SR 26: max is at least 6.
+                                        // Changed to 9 to support nano secs 
+                                        // fractional precision
 
   enum Subtype { SUBTYPE_ILLEGAL,
                  SUBTYPE_SQLDate, 

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/common/IntervalType.cpp
----------------------------------------------------------------------
diff --git a/core/sql/common/IntervalType.cpp b/core/sql/common/IntervalType.cpp
index e10bf08..778505e 100644
--- a/core/sql/common/IntervalType.cpp
+++ b/core/sql/common/IntervalType.cpp
@@ -251,9 +251,9 @@ UInt32 IntervalType::getPrecision(rec_datetime_field startField,
 } // IntervalType::getPrecision
 
 UInt32 IntervalType::computeLeadingPrecision(rec_datetime_field startField,
-					       UInt32 precision,
-					       rec_datetime_field endField,
-					       UInt32 fractionPrecision)
+                                             UInt32 precision,
+                                             rec_datetime_field endField,
+                                             UInt32 fractionPrecision)
 {
   UInt32 leadingPrecision;
   switch (getIntervalFSDatatype(startField, endField)) {
@@ -298,10 +298,13 @@ Lng32 IntervalType::getStorageSize(rec_datetime_field startField,
 				  rec_datetime_field endField,
 				  UInt32 fractionPrecision)
 {
-  Lng32 size = getBinaryStorageSize(getPrecision(startField, 
-                                                 leadingPrecision,
-                                                 endField,
-                                                 fractionPrecision));
+  Lng32 prec = getPrecision(startField, 
+                            leadingPrecision,
+                            endField,
+                            fractionPrecision);
+  
+  Lng32 size = getBinaryStorageSize(prec);
+
   // interval datatypes are stored as 2(smallint),4(int) or 8(largeint) bytes.
   // If size is tinyint size based on precision, change it to smallint size.
   if (size == SQL_TINY_SIZE)

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/common/IntervalType.h
----------------------------------------------------------------------
diff --git a/core/sql/common/IntervalType.h b/core/sql/common/IntervalType.h
index 378ff76..3315524 100644
--- a/core/sql/common/IntervalType.h
+++ b/core/sql/common/IntervalType.h
@@ -325,7 +325,8 @@ public:
   enum { DEFAULT_LEADING_PRECISION  =  2,	// ANSI 10.1 SR 5: two
 	 MAX_LEADING_PRECISION	    = MAX_NUMERIC_PRECISION, // 10.1 SR 3: >=2
 	 DEFAULT_FRACTION_PRECISION =  6,	// ANSI 10.1 SR 6: six
-	 MAX_FRACTION_PRECISION	    =  6	// ANSI 10.1 SR 4: >=6
+	 MAX_FRACTION_PRECISION_MSEC=  6,	// ANSI 10.1 SR 4: >=6
+	 MAX_FRACTION_PRECISION	    =  9	// ANSI 10.1 SR 4: >=6
        };
 
   // ---------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/common/NAType.cpp
----------------------------------------------------------------------
diff --git a/core/sql/common/NAType.cpp b/core/sql/common/NAType.cpp
index 0271b0c..5845f89 100644
--- a/core/sql/common/NAType.cpp
+++ b/core/sql/common/NAType.cpp
@@ -997,7 +997,7 @@ NAType* NAType::getNATypeForHive(const char* hiveType, NAMemory* heap)
     return new (heap) SQLDoublePrecision(heap, TRUE /* allow NULL*/);
 
   if ( !strcmp(hiveType, "timestamp"))
-    return new (heap) SQLTimestamp(heap, TRUE /* allow NULL */ , 6);
+    return new (heap) SQLTimestamp(heap, TRUE /* allow NULL */ , DatetimeType::MAX_FRACTION_PRECISION);
 
   if ( !strcmp(hiveType, "date"))
     return new (heap) SQLDate(heap, TRUE /* allow NULL */);

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/exp/ExpConvMxcs.cpp
----------------------------------------------------------------------
diff --git a/core/sql/exp/ExpConvMxcs.cpp b/core/sql/exp/ExpConvMxcs.cpp
index 0f7d3ee..7b9d3fb 100644
--- a/core/sql/exp/ExpConvMxcs.cpp
+++ b/core/sql/exp/ExpConvMxcs.cpp
@@ -1329,7 +1329,7 @@ static short convAsciiToIntervalMxcs(char *target,
 	    }
 	  else
 	    {
-	      *(UInt32 *)target = (UInt32) interm;
+              fraction = (UInt32) interm;
 	    }
 	};
 

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/exp/ExpErrorEnums.h
----------------------------------------------------------------------
diff --git a/core/sql/exp/ExpErrorEnums.h b/core/sql/exp/ExpErrorEnums.h
index 8227cb8..3b94897 100644
--- a/core/sql/exp/ExpErrorEnums.h
+++ b/core/sql/exp/ExpErrorEnums.h
@@ -164,6 +164,7 @@ enum ExeErrorCode
   EXE_ERROR_FROM_LOB_INTERFACE          = 8442,
   EXE_INVALID_LOB_HANDLE                = 8443,
   EXE_ERROR_HDFS_SCAN                   = 8447,
+  EXE_INVALID_INTERVAL_RESULT           = 8453,
   EXE_LAST_EXPRESSIONS_ERROR		= 8499,
 
   // ---------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/exp/exp_arith.cpp
----------------------------------------------------------------------
diff --git a/core/sql/exp/exp_arith.cpp b/core/sql/exp/exp_arith.cpp
index efe9b92..0e08354 100644
--- a/core/sql/exp/exp_arith.cpp
+++ b/core/sql/exp/exp_arith.cpp
@@ -48,14 +48,18 @@
 #include "exp_ovfl_ptal.h"
 #include "exp_ieee.h"
 
-
-Int64 EXP_FIXED_OV_ADD(Int64 op1, Int64 op2, short * ov)
+Int64 EXP_FIXED_ARITH_OV_OPER(short operation,
+                              Int64 op1, Int64 op2, short * ov)
 {
+  if (NOT ((operation == ITM_PLUS) || (operation == ITM_MINUS) ||
+           (operation == ITM_TIMES) || (operation == ITM_DIVIDE)))
+    return -1; // invalid operation
+
   short rc = 0;
   *ov = 0;
 
-  BigNum op1BN(16, 20, 0, 0);
-  BigNum op2BN(16, 20, 0, 0);
+  BigNum op1BN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);
+  BigNum op2BN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);
 
   char op1BNdata[100];
   char op2BNdata[100];
@@ -79,82 +83,46 @@ Int64 EXP_FIXED_OV_ADD(Int64 op1, Int64 op2, short * ov)
   op1BN.castFrom(&op1ST, op1_data, NULL, NULL);
   op2BN.castFrom(&op2ST, op2_data, NULL, NULL);
 
-  char * add_data[3];
-  char addBNdata[100];
-  add_data[0] = addBNdata;
-  add_data[1] = op1BNdata;
-  add_data[2] = op2BNdata;
-
-  BigNum addBN(16, 20, 0, 0);
-
-  rc = addBN.add(&op1BN, &op2BN, add_data);
-  if (rc)
-    {
-      *ov = 1;
-      return -1;
-    }
-
-  SimpleType resultST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
-		      ExpTupleDesc::SQLMX_FORMAT,
-		      8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
-  
-  Int64 result;
-  op1_data[0] = (char*)&result; 
-  op1_data[1] = add_data[0];
+  char * oper_data[3];
+  char operBNdata[100];
+  oper_data[0] = operBNdata;
+  oper_data[1] = op1BNdata;
+  oper_data[2] = op2BNdata;
 
-  //  rc = addBN.castTo(&resultST, op1_data);
-  rc = convDoIt(op1_data[1], 16, REC_NUM_BIG_SIGNED, 20, 0,
-		op1_data[0],  8, REC_BIN64_SIGNED, 0, 0,
-		NULL, 0, NULL, NULL);
+  BigNum operBN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);
 
-  if (rc)
+  switch (operation)
     {
-      *ov = 1;
-      return -1;
-    }
-
-  return result;
-}
-
-Int64 EXP_FIXED_OV_SUB(Int64 op1, Int64 op2, short * ov)
-{
-  short rc = 0;
-  *ov = 0;
-
-  BigNum op1BN(16, 20, 0, 0);
-  BigNum op2BN(16, 20, 0, 0);
-
-  char op1BNdata[100];
-  char op2BNdata[100];
-
-  SimpleType op1ST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
-		   ExpTupleDesc::SQLMX_FORMAT,
-		   8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
-  SimpleType op2ST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
-		   ExpTupleDesc::SQLMX_FORMAT,
-		   8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
-
-  char * op1_data[2];
-  char * op2_data[2];
-
-  op1_data[0] = op1BNdata;
-  op1_data[1] = (char*)&op1;
+    case ITM_PLUS:
+      {
+        rc = operBN.add(&op1BN, &op2BN, oper_data);
+      }
+      break;
 
-  op2_data[0] = op2BNdata;
-  op2_data[1] = (char*)&op2;
+    case ITM_MINUS:
+      {
+        rc = operBN.sub(&op1BN, &op2BN, oper_data);
+      }
+      break;
 
-  op1BN.castFrom(&op1ST, op1_data, NULL, NULL);
-  op2BN.castFrom(&op2ST, op2_data, NULL, NULL);
+    case ITM_TIMES:
+      {
+        rc = operBN.mul(&op1BN, &op2BN, oper_data);
+      }
+      break;
 
-  char * sub_data[3];
-  char subBNdata[100];
-  sub_data[0] = subBNdata;
-  sub_data[1] = op1BNdata;
-  sub_data[2] = op2BNdata;
+    case ITM_DIVIDE:
+      {
+        char tempSpace[200];
+        operBN.setTempSpaceInfo(ITM_DIVIDE, (ULong)tempSpace, 200);
+        rc = operBN.div(&op1BN, &op2BN, oper_data, NULL, NULL);
+      }
+      break;
 
-  BigNum subBN(16, 20, 0, 0);
+    default:
+      return -1;
+    } // switch
 
-  rc = subBN.sub(&op1BN, &op2BN, sub_data);
   if (rc)
     {
       *ov = 1;
@@ -163,15 +131,15 @@ Int64 EXP_FIXED_OV_SUB(Int64 op1, Int64 op2, short * ov)
 
   SimpleType resultST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
 		      ExpTupleDesc::SQLMX_FORMAT,
-		      8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
+		      sizeof(Int64), 0, 0, 0, Attributes::NO_DEFAULT, 0);
   
   Int64 result;
   op1_data[0] = (char*)&result; 
-  op1_data[1] = sub_data[0];
+  op1_data[1] = oper_data[0];
 
-  //  rc = subBN.castTo(&resultST, op1_data);
-  rc = convDoIt(op1_data[1], 16, REC_NUM_BIG_SIGNED, 20, 0,
-		op1_data[0],  8, REC_BIN64_SIGNED, 0, 0,
+  rc = convDoIt(op1_data[1], BigNum::BIGNUM_TEMP_LEN, REC_NUM_BIG_SIGNED, 
+                BigNum::BIGNUM_TEMP_PRECISION, 0,
+		op1_data[0],  sizeof(Int64), REC_BIN64_SIGNED, 0, 0,
 		NULL, 0, NULL, NULL);
   if (rc)
     {
@@ -182,159 +150,48 @@ Int64 EXP_FIXED_OV_SUB(Int64 op1, Int64 op2, short * ov)
   return result;
 }
 
-Int64 EXP_FIXED_OV_MUL(Int64 op1, Int64 op2, short * ov)
+Int64 EXP_FIXED_OV_ADD(Int64 op1,Int64 op2, short * ov)
 {
-  short rc = 0;
-  *ov = 0;
-
-  BigNum op1BN(16, 38, 0, 0);
-  BigNum op2BN(16, 38, 0, 0);
-
-  char op1BNdata[100];
-  char op2BNdata[100];
-
-  SimpleType op1ST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
-		   ExpTupleDesc::SQLMX_FORMAT,
-		   8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
-  SimpleType op2ST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
-		   ExpTupleDesc::SQLMX_FORMAT,
-		   8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
-
-  char * op1_data[2];
-  char * op2_data[2];
-
-  op1_data[0] = op1BNdata;
-  op1_data[1] = (char*)&op1;
-
-  op2_data[0] = op2BNdata;
-  op2_data[1] = (char*)&op2;
-
-  op1BN.castFrom(&op1ST, op1_data, NULL, NULL);
-  op2BN.castFrom(&op2ST, op2_data, NULL, NULL);
-
-  char * mul_data[3];
-  char mulBNdata[100];
-  mul_data[0] = mulBNdata;
-  mul_data[1] = op1BNdata;
-  mul_data[2] = op2BNdata;
-
-  BigNum mulBN(16, 38, 0, 0);
-
-  rc = mulBN.mul(&op1BN, &op2BN, mul_data);
-  if (rc)
-    {
-      *ov = 1;
-      return -1;
-    }
-
-  SimpleType resultST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
-		      ExpTupleDesc::SQLMX_FORMAT,
-		      8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
-  
-  Int64 result;
-  op1_data[0] = (char*)&result; 
-  op1_data[1] = mul_data[0];
-
-  //  rc = mulBN.castTo(&resultST, op1_data);
-  rc = convDoIt(op1_data[1], 16, REC_NUM_BIG_SIGNED, 38, 0,
-		op1_data[0],  8, REC_BIN64_SIGNED, 0, 0,
-		NULL, 0, NULL, NULL);
-  if (rc)
-    {
-      *ov = 1;
-      return -1;
-    }
-
-  return result;
+  return EXP_FIXED_ARITH_OV_OPER(ITM_PLUS, op1, op2, ov);
 }
 
-Int64 EXP_FIXED_OV_DIV(Int64 op1, Int64 op2, short * ov)
+Int64 EXP_FIXED_OV_SUB(Int64 op1,Int64 op2, short * ov)
 {
-  short rc = 0;
-  *ov = 0;
-
-  BigNum op1BN(16, 38, 0, 0);
-  BigNum op2BN(16, 38, 0, 0);
-
-  char op1BNdata[100];
-  char op2BNdata[100];
-
-  SimpleType op1ST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
-		   ExpTupleDesc::SQLMX_FORMAT,
-		   8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
-  SimpleType op2ST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
-		   ExpTupleDesc::SQLMX_FORMAT,
-		   8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
-
-  char * op1_data[2];
-  char * op2_data[2];
-
-  op1_data[0] = op1BNdata;
-  op1_data[1] = (char*)&op1;
-
-  op2_data[0] = op2BNdata;
-  op2_data[1] = (char*)&op2;
-
-  op1BN.castFrom(&op1ST, op1_data, NULL, NULL);
-  op2BN.castFrom(&op2ST, op2_data, NULL, NULL);
-
-  char * div_data[3];
-  char divBNdata[100];
-  div_data[0] = divBNdata;
-  div_data[1] = op1BNdata;
-  div_data[2] = op2BNdata;
-
-  BigNum divBN(16, 38, 0, 0);
-  char tempSpace[200];
-  divBN.setTempSpaceInfo(ITM_DIVIDE, (ULong)tempSpace, 200);
-  rc = divBN.div(&op1BN, &op2BN, div_data, NULL, NULL);
-  if (rc)
-    {
-      *ov = 1;
-      return -1;
-    }
-
-  SimpleType resultST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
-		      ExpTupleDesc::SQLMX_FORMAT,
-		      8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
-  
-  Int64 result;
-  op1_data[0] = (char*)&result; 
-  op1_data[1] = div_data[0];
-
-  //rc = divBN.castTo(&resultST, op1_data);
-  rc = convDoIt(op1_data[1], 16, REC_NUM_BIG_SIGNED, 38, 0,
-		op1_data[0],  8, REC_BIN64_SIGNED, 0, 0,
-		NULL, 0, NULL, NULL);
-  if (rc)
-    {
-      *ov = 1;
-      return -1;
-    }
+  return EXP_FIXED_ARITH_OV_OPER(ITM_MINUS, op1, op2, ov);
+}
 
-  return result;
+Int64 EXP_FIXED_OV_MUL(Int64 op1,Int64 op2, short * ov)
+{
+  return EXP_FIXED_ARITH_OV_OPER(ITM_TIMES, op1, op2, ov);
 }
 
-//Int64 EXP_FIXED_OV_SUB(Int64 op1, Int64 op2, short * ov);
-//Int64 EXP_FIXED_OV_MUL(Int64 op1, Int64 op2, short * ov);
-//Int64 EXP_FIXED_OV_DIV(Int64 op1, Int64 op2, short * ov);
+Int64 EXP_FIXED_OV_DIV(Int64 op1,Int64 op2, short * ov)
+{
+  return EXP_FIXED_ARITH_OV_OPER(ITM_DIVIDE, op1, op2, ov);
+}
 
 
-short EXP_FIXED_BIGN_OV_MUL(Attributes * op1,
-                        Attributes * op2,
-                        char * op_data[])
+///////////////////////////////////////////////////////////////
+short EXP_BIGN_ARITH_OPER(short operation,
+                          Attributes * op1,
+                          Attributes * op2,
+                          char * op_data[])
 {
+  if (NOT ((operation == ITM_PLUS) || (operation == ITM_MINUS) ||
+           (operation == ITM_TIMES) || (operation == ITM_DIVIDE)))
+    return -1; // invalid operation
+
   short rc = 0;
-  BigNum op1BN(16, 38, 0, 0);
-  BigNum op2BN(16, 38, 0, 0);
+  BigNum op1BN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);
+  BigNum op2BN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);
 
   char op1BNdata[100];
   char op2BNdata[100];
 
-  char * mul_data[3];
+  char * oper_data[3];
 
   //initialize result place holder.
-  mul_data[0] = op_data[0];
+  oper_data[0] = op_data[0];
 
   //convert op1 & op2 to bignum if not already bignum
   if(op1->isSimpleType())
@@ -345,10 +202,10 @@ short EXP_FIXED_BIGN_OV_MUL(Attributes * op1,
     rc = op1BN.castFrom(op1, op1_data, NULL, NULL);
     if(rc)
       return -1;
-    mul_data[1] = op1BNdata;
+    oper_data[1] = op1BNdata;
   }
   else
-    mul_data[1] = op_data[1]; 
+    oper_data[1] = op_data[1]; 
 
   if(op2->isSimpleType())
   {
@@ -358,84 +215,91 @@ short EXP_FIXED_BIGN_OV_MUL(Attributes * op1,
     rc = op2BN.castFrom(op2, op2_data, NULL, NULL);
     if(rc)
       return -1;
-    mul_data[2] = op2BNdata;
+    oper_data[2] = op2BNdata;
   }
   else
-    mul_data[2] = op_data[2]; 
+    oper_data[2] = op_data[2]; 
 
-  BigNum mulBN(16, 38, 0, 0);
+  BigNum operBN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);
 
-  rc = mulBN.mul(&op1BN, &op2BN, mul_data);
-  if (rc)
-    return -1;
-
-  return 0;
-}
-
-short EXP_FIXED_BIGN_OV_DIV(Attributes * op1,
-                        Attributes * op2,
-                        char * op_data[])
-{
-  short rc = 0;
-  
-  BigNum op1BN(16, 38, 0, 0);
-  BigNum op2BN(16, 38, 0, 0);
+  switch (operation)
+    {
+    case ITM_PLUS:
+      {
+        rc = operBN.add(&op1BN, &op2BN, oper_data);
+      }
+      break;
 
-  char op1BNdata[100];
-  char op2BNdata[100];
+    case ITM_MINUS:
+      {
+        rc = operBN.sub(&op1BN, &op2BN, oper_data);
+      }
+      break;
 
-  char * div_data[3];
+    case ITM_TIMES:
+      {
+        rc = operBN.mul(&op1BN, &op2BN, oper_data);
+      }
+      break;
 
-  //initialize result place holder.
-  div_data[0] = op_data[0];
+    case ITM_DIVIDE:
+      {
+        char tempSpace[200];
+        operBN.setTempSpaceInfo(ITM_DIVIDE, (ULong)tempSpace, 200);
 
-  //convert op1 & op2 to bignum if not already bignum
-  if(op1->isSimpleType())
-  {
-    char * op1_data[2];
-    op1_data[0] = op1BNdata;
-    op1_data[1] = op_data[1];
-    rc = op1BN.castFrom(op1, op1_data, NULL, NULL);
-    if(rc)
-      return -1;
-    div_data[1] = op1BNdata;
-  }
-  else
-    div_data[1] = op_data[1]; 
+        rc = operBN.div(&op1BN, &op2BN, oper_data, NULL, NULL);
+      }
+      break;
 
-  if(op2->isSimpleType())
-  {
-    char * op2_data[2];
-    op2_data[0] = op2BNdata;
-    op2_data[1] = op_data[2];
-    rc = op2BN.castFrom(op2, op2_data, NULL, NULL);
-    if(rc)
+    default:
       return -1;
-    div_data[2] = op2BNdata;
-  }
-  else
-    div_data[2] = op_data[2]; 
+    }
 
-  BigNum divBN(16, 38, 0, 0);
-  char tempSpace[200];
-  divBN.setTempSpaceInfo(ITM_DIVIDE, (ULong)tempSpace, 200);
-  rc = divBN.div(&op1BN, &op2BN, div_data, NULL, NULL);
   if (rc)
     return -1;
 
   return 0;
 }
 
+short EXP_FIXED_BIGN_OV_ADD(Attributes * op1,
+                            Attributes * op2,
+                            char * op_data[])
+{
+  return EXP_BIGN_ARITH_OPER(ITM_PLUS, op1, op2, op_data);
+}
+
+short EXP_FIXED_BIGN_OV_SUB(Attributes * op1,
+                            Attributes * op2,
+                            char * op_data[])
+{
+  return EXP_BIGN_ARITH_OPER(ITM_MINUS, op1, op2, op_data);
+}
+
+short EXP_FIXED_BIGN_OV_MUL(Attributes * op1,
+                            Attributes * op2,
+                            char * op_data[])
+{
+  return EXP_BIGN_ARITH_OPER(ITM_TIMES, op1, op2, op_data);
+}
+
+short EXP_FIXED_BIGN_OV_DIV(Attributes * op1,
+                            Attributes * op2,
+                            char * op_data[])
+{
+  return EXP_BIGN_ARITH_OPER(ITM_DIVIDE, op1, op2, op_data);
+}
+
 Int64 EXP_FIXED_BIGN_OV_MOD(Attributes * op1,
-                        Attributes * op2,
-                        char * op_data[],
-                        short * ov)
+                            Attributes * op2,
+                            char * op_data[],
+                            short * ov,
+                            Int64 * quotient)
 {
   short rc = 0;
   *ov = 0;
 
-  BigNum op1BN(16, 38, 0, 0);
-  BigNum op2BN(16, 38, 0, 0);
+  BigNum op1BN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);
+  BigNum op2BN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);
 
   char op1BNdata[100];
   char op2BNdata[100];
@@ -479,7 +343,7 @@ Int64 EXP_FIXED_BIGN_OV_MOD(Attributes * op1,
   //using basic operators:
   //z=MOD(x,y) then z = x - ((x/y)*(y))
 
-  BigNum modBN(16, 38, 0, 0);
+  BigNum modBN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);
   char * temp_data[3];
   
   //calculate (x/y)
@@ -496,6 +360,26 @@ Int64 EXP_FIXED_BIGN_OV_MOD(Attributes * op1,
     return -1;
   }
 
+  SimpleType resultST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
+                      ExpTupleDesc::SQLMX_FORMAT,
+                      8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
+  
+  // if quotient(x/y) is to be returned, return it
+  if (quotient)
+    {
+      temp_data[0] = (char*)quotient; 
+      temp_data[1] = xByY; //mod_data[0];
+      
+      rc = convDoIt(temp_data[1], BigNum::BIGNUM_TEMP_LEN, REC_NUM_BIG_SIGNED, BigNum::BIGNUM_TEMP_PRECISION, 0,
+                    temp_data[0],  8, REC_BIN64_SIGNED, 0, 0,
+                    NULL, 0, NULL, NULL);
+      if (rc)
+        {
+          *ov = 1;
+          return -1;
+        }
+    }
+
   //calculate (x/y) * y
   char xByYTimesY[100];
   temp_data[0] = xByYTimesY;
@@ -521,16 +405,12 @@ Int64 EXP_FIXED_BIGN_OV_MOD(Attributes * op1,
     return -1;
   }
 
-  SimpleType resultST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
-		      ExpTupleDesc::SQLMX_FORMAT,
-		      8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
-  
   Int64 result;
   temp_data[0] = (char*)&result; 
   temp_data[1] = mod_data[0];
 
   //rc = divBN.castTo(&resultST, op1_data);
-  rc = convDoIt(temp_data[1], 16, REC_NUM_BIG_SIGNED, 38, 0,
+  rc = convDoIt(temp_data[1], BigNum::BIGNUM_TEMP_LEN, REC_NUM_BIG_SIGNED, BigNum::BIGNUM_TEMP_PRECISION, 0,
 		temp_data[0],  8, REC_BIN64_SIGNED, 0, 0,
 		NULL, 0, NULL, NULL);
   if (rc)
@@ -1124,7 +1004,7 @@ ex_expr::exp_return_type ex_arith_clause::eval(char *op_data[],
 		                         ExpTupleDesc::SQLMX_FORMAT,
 		                         8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
                           
-                          BigNum opBN(16, 38, 0, 0);                          
+                          BigNum opBN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);                          
                           
                           while(!vGT5)
 		           {
@@ -1132,8 +1012,8 @@ ex_expr::exp_return_type ex_arith_clause::eval(char *op_data[],
                             op_data[1] = (char *) &dividend;
                             op_data[2] = (char *) &multiplier; 
                             rc = EXP_FIXED_BIGN_OV_MUL(&opST,
-                                                    &opST,
-			                              op_data);
+                                                       &opST,
+                                                       op_data);
                            if (rc)
 	                    {
 	                      //end of digits.
@@ -1144,8 +1024,8 @@ ex_expr::exp_return_type ex_arith_clause::eval(char *op_data[],
                            op_data[1] = result1;
                            op_data[2] = (char *) &divisor;
                            rc = EXP_FIXED_BIGN_OV_DIV(&opBN,
-				                    &opST,
-				                    op_data);
+                                                      &opST,
+                                                      op_data);
 	                    if (rc)
 	                    {
 	                      //Something went wrong, lets consider

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/exp/exp_bignum.h
----------------------------------------------------------------------
diff --git a/core/sql/exp/exp_bignum.h b/core/sql/exp/exp_bignum.h
index 5ae29e0..2f228c9 100644
--- a/core/sql/exp/exp_bignum.h
+++ b/core/sql/exp/exp_bignum.h
@@ -65,6 +65,11 @@ class BigNum : public ComplexType {
   ULong              tempSpacePtr_;         // 24-31 //Put on 8-byte boundary
 
 public:
+  // some internal computation use bignum as temp storage.
+  // Use 38 digit precision and 16 bytes length for them.
+  enum {BIGNUM_TEMP_LEN = 16 };
+  enum {BIGNUM_TEMP_PRECISION = 38 };
+
   BigNum(Lng32 length, Lng32 precision, short scale, short unSigned);
 
   BigNum();
@@ -181,10 +186,18 @@ short EXP_FIXED_BIGN_OV_DIV(Attributes * op1,
                         char * op_data[]);
 
 Int64 EXP_FIXED_BIGN_OV_MOD(Attributes * op1,
+                            Attributes * op2,
+                            char * op_data[],
+                            short * ov,
+                            Int64 * quotient = NULL);
+
+short EXP_FIXED_BIGN_OV_ADD(Attributes * op1,
                         Attributes * op2,
-                        char * op_data[],
-                        short * ov);
+                        char * op_data[]);
 
+short EXP_FIXED_BIGN_OV_SUB(Attributes * op1,
+                        Attributes * op2,
+                        char * op_data[]);
 
  
 

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/exp/exp_conv.cpp
----------------------------------------------------------------------
diff --git a/core/sql/exp/exp_conv.cpp b/core/sql/exp/exp_conv.cpp
index 41b0a67..f4265b7 100644
--- a/core/sql/exp/exp_conv.cpp
+++ b/core/sql/exp/exp_conv.cpp
@@ -11493,6 +11493,12 @@ ex_expr::exp_return_type ex_conv_clause::eval(char *op_data[],
       //move null to target
       if(tgt->getNullFlag())
       {
+        // clear diags area since this error is not being returned
+        if (diagsArea && *diagsArea && ((*diagsArea)->getNumber(DgSqlCode::ERROR_) > 0))
+          {
+            (*diagsArea)->clear();
+          }
+
         ExpTupleDesc::setNullValue( op_data[-2*MAX_OPERANDS],
                                     tgt->getNullBitIndex(),
                                     tgt->getTupleFormat() );

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/exp/exp_datetime.cpp
----------------------------------------------------------------------
diff --git a/core/sql/exp/exp_datetime.cpp b/core/sql/exp/exp_datetime.cpp
index 3a899e7..af4ec03 100644
--- a/core/sql/exp/exp_datetime.cpp
+++ b/core/sql/exp/exp_datetime.cpp
@@ -45,7 +45,7 @@
 #include "exp_interval.h"
 #include "exp_clause_derived.h"
 #include "NAAssert.h"
-
+#include "exp_bignum.h"
 
 
 #undef DllImport
@@ -325,6 +325,9 @@ short ExpDatetime::getDatetimeFields(Lng32 datetimeCode,
   return 0;
 }
 
+static const Lng32 powersOfTen[] = {1, 10 ,100, 1000, 10000, 100000, 1000000,
+                                    10000000, 100000000, 1000000000};
+
 void ExpDatetime::convertDatetimeToInterval
 ( rec_datetime_field datetimeStartField
 , rec_datetime_field datetimeEndField
@@ -332,8 +335,14 @@ void ExpDatetime::convertDatetimeToInterval
 , rec_datetime_field intervalEndField
 , char *datetimeOpData
 , Int64 &interval
+, char * intervalBignum
+, NABoolean &isBignum
 ) const
 {
+  short rc = 0;
+
+  isBignum = FALSE;
+
   interval = 0;
   short year;
   char month;
@@ -375,18 +384,58 @@ void ExpDatetime::convertDatetimeToInterval
       break;
     case REC_DATE_SECOND:
       interval *= 60;
+
       if (field <= datetimeEndField) {
         char second;
         str_cpy_all((char *) &second, datetimeOpData, sizeof(second));
         datetimeOpData += sizeof(second);
         interval = interval + second;
         if (fractionPrecision > 0) {
-          do {
-            interval *= 10;
-          } while (--fractionPrecision > 0);
           Lng32 fraction;
+          Int64 fraction64;
+
           str_cpy_all((char *) &fraction, datetimeOpData, sizeof(fraction));
-          interval = interval + fraction;
+
+          Int64 multiplicator = powersOfTen[fractionPrecision];
+          if (fractionPrecision <= MAX_DATETIME_MICROS_FRACT_PREC) 
+            {
+              interval *= multiplicator;
+              interval = interval + fraction;
+            }
+          else
+            {
+              // Int64 may run into an overflow if fract precision is > 6
+              // Use bignum computation to do:
+              //   interval = interval * multiplicator
+              //   interval = interval + fraction
+              SimpleType op1ST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
+                               ExpTupleDesc::SQLMX_FORMAT,
+                               8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
+
+              char *op_data[3];
+              char mulBignum[BigNum::BIGNUM_TEMP_LEN]; // 16 bytes bignum result length
+
+              op_data[0] = mulBignum; // result
+              op_data[1] = (char*) &interval;
+              op_data[2] = (char*) &multiplicator;
+              rc = EXP_FIXED_BIGN_OV_MUL(&op1ST, &op1ST, op_data);
+
+              BigNum op1BN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);
+              
+              char addBignum[BigNum::BIGNUM_TEMP_LEN];
+              fraction64 = fraction;
+
+              op_data[0] = addBignum;
+              op_data[1] = mulBignum;
+              op_data[2] = (char*)&fraction64;
+              rc = EXP_FIXED_BIGN_OV_ADD(&op1BN, &op1ST, op_data);
+              
+              if (intervalBignum)
+                {
+                  str_cpy_all(intervalBignum, addBignum, BigNum::BIGNUM_TEMP_LEN);
+                  isBignum = TRUE;
+                }
+            }
         }
       }
       break;
@@ -450,11 +499,14 @@ short ExpDatetime::getYearMonthDay(Int64 totalDays,
 }
 
 short ExpDatetime::convertIntervalToDatetime(Int64 interval,
+                                             char * intervalBignum,
                                              rec_datetime_field startField,
                                              rec_datetime_field endField,
                                              short fractionPrecision,
                                              char *datetimeOpData) const
 {
+  short rc = 0;
+
   short year;
   char month;
   char day;
@@ -467,22 +519,44 @@ short ExpDatetime::convertIntervalToDatetime(Int64 interval,
     switch (field) {
     case REC_DATE_SECOND:
       if (fractionPrecision > 0) {
-        Lng32 divisor = 1;
-        short fp = fractionPrecision;
-        do {
-          divisor *= 10;
-        } while (--fp > 0);
-        Int64 dividend = interval;
-        interval = dividend / (Int64) divisor;
-        dividend -= interval * (Int64) divisor;
-        //
-        // Underflow is allowed for time types, so wrap around if necessary.
-        //
-        if (dividend < 0) {
-          dividend += divisor;
-          interval -= 1;
-        }
-        fraction = int64ToInt32(dividend);
+
+        //Int64 multiplicator = powersOfTen[fractionPrecision];
+        Int64 divisor = powersOfTen[fractionPrecision];
+        Int64 dividend = 0;
+        if (fractionPrecision <= MAX_DATETIME_MICROS_FRACT_PREC)
+          {
+            Int64 dividend = interval;
+            interval = dividend / divisor;
+            dividend = dividend - (interval * divisor);
+            //
+            // Underflow is allowed for time types, so wrap around if necessary.
+            //
+            if (dividend < 0) {
+              dividend += divisor;
+              interval -= 1;
+            }
+            fraction = int64ToInt32(dividend);
+          }
+        else
+          {
+            SimpleType opST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
+                            ExpTupleDesc::SQLMX_FORMAT,
+                            8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
+            BigNum opBN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);
+            
+            char *op_data[2];
+            
+            op_data[0] = intervalBignum;
+            op_data[1] = (char*) &divisor;
+            Int64 quotient = -1;
+            short ov;
+            dividend = 
+              EXP_FIXED_BIGN_OV_MOD(&opBN, &opST, op_data, &ov, &quotient);
+            interval = quotient;
+
+            fraction = int64ToInt32(dividend);
+          }
+
       }
       //
       // Underflow is allowed for time types, so wrap around if necessary.
@@ -935,6 +1009,7 @@ ExpDatetime::arithDatetimeInterval(arithOps operation,
                                    CollHeap *heap,
                                    ComDiagsArea** diagsArea)
 {
+  short rc = 0;
 
   if (operation != DATETIME_ADD && 
       operation != DATETIME_SUB) {
@@ -1016,33 +1091,39 @@ ExpDatetime::arithDatetimeInterval(arithOps operation,
   // (endField) as the Interval operand.  We want to make sure we
   // add/subtract MONTHs to MONTHs, etc.
   //
-  Int64 value;
+  Int64 value = -1;
+  char intervalBignum[BigNum::BIGNUM_TEMP_LEN];
+  char resultBignum[BigNum::BIGNUM_TEMP_LEN];
+  NABoolean isBignum = FALSE;
   convertDatetimeToInterval(datetimeStartField,
                             datetimeEndField,
                             datetimeOpType->getScale(),
                             intervalEndField,
                             dateTimeValue,
-                            value);
+                            value,
+                            intervalBignum,
+                            isBignum);
 
   // Perform the arithmetic operation.
   //
+  Int64 interval64 = 0;
   switch (intervalOpType->getLength()) {
   case SQL_SMALL_SIZE: {
     short interval;
     str_cpy_all((char *) &interval, intervalOpData, sizeof(interval));
-    value += ((operation == DATETIME_ADD) ? interval : -interval);
+    interval64 = interval;
     break;
   }
   case SQL_INT_SIZE: {
     Lng32 interval;
     str_cpy_all((char *) &interval, intervalOpData, sizeof(interval));
-    value += ((operation == DATETIME_ADD) ? interval : -interval);
+    interval64 = interval;
     break;
   }
   case SQL_LARGE_SIZE: {
     Int64 interval;
     str_cpy_all((char *) &interval, intervalOpData, sizeof(interval));
-    value += ((operation == DATETIME_ADD) ? interval : -interval);
+    interval64 = interval;
     break;
   }
   default:
@@ -1050,20 +1131,43 @@ ExpDatetime::arithDatetimeInterval(arithOps operation,
     return -1;
   }
 
+  if (NOT isBignum) { // result is not a bignum  
+    value += ((operation == DATETIME_ADD) ? interval64 : -interval64);
+  } else {
+    // result is a bignum
+    char *op_data[3];
+    
+    BigNum op1BN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);
+    SimpleType intST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
+                     ExpTupleDesc::SQLMX_FORMAT,
+                     8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
+
+    op_data[0] = resultBignum;
+    op_data[1] = intervalBignum;
+    op_data[2] = (char*)&interval64;
+    
+    if (operation == DATETIME_ADD) {
+      rc = EXP_FIXED_BIGN_OV_ADD(&op1BN, &intST, op_data);
+    } else {
+      rc = EXP_FIXED_BIGN_OV_SUB(&op1BN, &intST, op_data);
+    }
+  }
+
   // Underflow is ok for time only datetime types.  Arithmetic on the
   // hour field is computed modulo 24.  For datetime types containing
   // a date portion, underflow is an error.
   //
-  if ((value < 0) && (datetimeStartField < REC_DATE_HOUR)) {
+  if ((NOT isBignum) && (value < 0) && 
+      (datetimeStartField < REC_DATE_HOUR)) {
     ExRaiseSqlError(heap, diagsArea, EXE_DATETIME_FIELD_OVERFLOW);
     return -1;
   }
 
-
   // Convert result back to datetime.  Note that this is overlaying the
   // local copy of the datetime value.
   //
   if (convertIntervalToDatetime(value,
+                                (isBignum ?  resultBignum : NULL),
                                 datetimeStartField,
                                 intervalEndField,
                                 datetimeOpType->getScale(),
@@ -1115,6 +1219,8 @@ short ExpDatetime::subDatetimeDatetime(Attributes *datetimeOpType,
                                        CollHeap *heap,
                                        ComDiagsArea** diagsArea) const
 {
+  short rc = 0;
+
   rec_datetime_field datetimeStartField;
   rec_datetime_field datetimeEndField;
   if (getDatetimeFields(datetimeOpType->getPrecision(),
@@ -1146,20 +1252,81 @@ short ExpDatetime::subDatetimeDatetime(Attributes *datetimeOpType,
     }
 
   Int64 value1;
+  char intervalBignum1[BigNum::BIGNUM_TEMP_LEN];
+  NABoolean isBignum1 = FALSE;
+  NABoolean isBignum2 = FALSE;
   convertDatetimeToInterval(datetimeStartField,
                             datetimeEndField,
                             datetimeOpType->getScale(),
                             intervalEndField,
                             datetimeOpData1,
-                            value1);
+                            value1,
+                            intervalBignum1,
+                            isBignum1);
+
   Int64 value2;
+  char intervalBignum2[BigNum::BIGNUM_TEMP_LEN];
   convertDatetimeToInterval(datetimeStartField,
                             datetimeEndField,
                             datetimeOpType->getScale(),
                             intervalEndField,
                             datetimeOpData2,
-                            value2);
-  Int64 result = value1 - value2;
+                            value2,
+                            intervalBignum2,
+                            isBignum2);
+
+  Int64 result = 0;
+
+  if ((NOT isBignum1) && (NOT isBignum2)) // neither is bignum
+    result = value1 - value2;
+  else
+    {
+      BigNum opBN(BigNum::BIGNUM_TEMP_LEN, BigNum::BIGNUM_TEMP_PRECISION, 0, 0);
+      SimpleType opST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
+                      ExpTupleDesc::SQLMX_FORMAT,
+                      8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
+
+      char *op_data[3];
+
+      char resultBN[BigNum::BIGNUM_TEMP_LEN];
+      op_data[0] = resultBN;
+      op_data[1] = (isBignum1 ? intervalBignum1 : (char*)&value1);
+      op_data[2] = (isBignum2 ? intervalBignum2 : (char*)&value2);
+     
+      rc = EXP_FIXED_BIGN_OV_SUB((isBignum1 ? (Attributes*)&opBN : (Attributes*)&opST), 
+                                 (isBignum2 ? (Attributes*)&opBN : (Attributes*)&opST), 
+                                 op_data); 
+      if (rc)
+        {
+          ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
+          return -1;
+        }
+
+      rc = convDoIt(op_data[0], BigNum::BIGNUM_TEMP_LEN, REC_NUM_BIG_SIGNED, BigNum::BIGNUM_TEMP_PRECISION, 0,
+                    (char*)&result,  8, REC_BIN64_SIGNED, 0, 0,
+                    NULL, 0, NULL, NULL);
+      if (rc)
+        {
+          // convert interval value to ascii format
+          char invalidVal[BigNum::BIGNUM_TEMP_PRECISION+1];
+          Int32 len = BigNum::BIGNUM_TEMP_PRECISION;
+          memset(invalidVal, ' ', len);
+          convDoIt(op_data[0], BigNum::BIGNUM_TEMP_LEN, REC_NUM_BIG_SIGNED, BigNum::BIGNUM_TEMP_PRECISION, 0,
+                   invalidVal, BigNum::BIGNUM_TEMP_PRECISION, REC_BYTE_F_ASCII, 0, 0,
+                   NULL, 0, NULL, NULL);
+          len--;
+          while (invalidVal[len] == ' ')
+            len--;
+          len++;
+          invalidVal[len]  = 0;
+
+          ExRaiseSqlError(heap, diagsArea, EXE_INVALID_INTERVAL_RESULT,
+                          NULL, NULL, NULL, NULL,
+                          invalidVal);
+          return -1;
+        }
+    }
+
   //
   // Scale the result to the interval qualifier's fractional precision.
   //
@@ -1222,8 +1389,6 @@ scaleFraction(Int32 srcFractPrec,
 
   Lng32 fraction = 0;
  
-  static const Lng32 powersOfTen[] = {1, 10 ,100, 1000, 10000, 100000, 1000000};
-
   // If there is a fraction value in the destination and there is a
   // fraction value in the source, scale the fraction to the
   // destination precision.
@@ -1546,7 +1711,6 @@ ExpDatetime::convDatetimeDatetime(char *srcData,
     return -1;
   }
 
-
   // Skip over source fields that are not in the destination.
   //
   srcData += sizeofDatetimeFields(srcStartField, 
@@ -1841,9 +2005,9 @@ scanField(char *&src,
   // The maximum lengths of the various fields.  Since the value of
   // REC_DATE_YEAR is 1, the first entry is just a place holder.
   //
-  static const Lng32 maxLens[] =  { 0,    4,  2,  2,  2,  2,  2,      6 };
-  static const Lng32 minValue[] = { 0, 0001, 01, 01, 00, 00, 00, 000000 };
-  static const Lng32 maxValue[] = { 0, 9999, 12, 31, 23, 59, 59, 999999 };
+  static const Lng32 maxLens[] =  { 0,    4,  2,  2,  2,  2,  2,         9 };
+  static const Lng32 minValue[] = { 0, 0001, 01, 01, 00, 00, 00, 000000000 };
+  static const Lng32 maxValue[] = { 0, 9999, 12, 31, 23, 59, 59, 999999999 };
 
   // The length of the scanned field.
   //
@@ -2290,9 +2454,10 @@ ExpDatetime::convAsciiToDatetime(char *srcData,
     // timezone specified. Compute the new datetime value.
 
     // first, convert current datetime value to juliantimestamp
+    Lng32 jtsFraction = fraction / 1000;
     short timestamp[] = {
       year, month, day, hour, minute, second, 
-      (short)(fraction / 1000), (short)(fraction % 1000)
+      (short)(jtsFraction / 1000), (short)(jtsFraction % 1000)
     };
     
     short error;
@@ -2340,7 +2505,7 @@ ExpDatetime::convAsciiToDatetime(char *srcData,
         second = (char) timestamp[5];
         *dst++ = second;
         if (scale) {
-          fraction = timestamp[6] * 1000 + timestamp[7];
+          //fraction = timestamp[6] * 1000 + timestamp[7];
           str_cpy_all(dst, (char *)&fraction, sizeof(fraction));
           dst += sizeof(fraction);
         }

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/exp/exp_datetime.h
----------------------------------------------------------------------
diff --git a/core/sql/exp/exp_datetime.h b/core/sql/exp/exp_datetime.h
index c665d21..7c3f7a7 100644
--- a/core/sql/exp/exp_datetime.h
+++ b/core/sql/exp/exp_datetime.h
@@ -120,7 +120,9 @@ public:
   enum { DATETIME_MAX_NUM_FIELDS = 7 };
   enum { MAX_DATETIME_SIZE = 11 };
 
-  enum { MAX_DATETIME_FRACT_PREC = 6 };
+  enum { MAX_DATETIME_MICROS_FRACT_PREC = 6 };
+  enum { MAX_DATETIME_NANOS_FRACT_PREC = 9 };
+  enum { MAX_DATETIME_FRACT_PREC = 9 };
 
   // MAX Length of Datetime string is 50 -
   // "DATE 'YYYY-MM-DD';"
@@ -143,12 +145,17 @@ public:
                                  rec_datetime_field &startField,
                                  rec_datetime_field &endField);
 
+  static NABoolean fractionStoredAsNanos(rec_datetime_field endField,
+                                         short fractionPrecision);
+
   void convertDatetimeToInterval(rec_datetime_field datetimeStartField,
                                  rec_datetime_field datetimeEndField,
                                  short fractionPrecision,
                                  rec_datetime_field intervalEndField,
                                  char *datetimeOpData,
-                                 Int64 &interval) const;
+                                 Int64 &interval,
+                                 char * intervalBignum,
+                                 NABoolean &isBignum) const;
 
   static short getYearMonthDay(Int64 totalDays,
                                short &year,
@@ -156,6 +163,7 @@ public:
                                char &day);
 
   short convertIntervalToDatetime(Int64 interval,
+                                  char * intervalBignum,
                                   rec_datetime_field startField,
                                   rec_datetime_field endField,
                                   short fractionPrecision,

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/exp/exp_fixup.cpp
----------------------------------------------------------------------
diff --git a/core/sql/exp/exp_fixup.cpp b/core/sql/exp/exp_fixup.cpp
index 756612e..479ff44 100644
--- a/core/sql/exp/exp_fixup.cpp
+++ b/core/sql/exp/exp_fixup.cpp
@@ -536,9 +536,9 @@ const ArithInstruction ex_arith_clause::computeCaseIndex(OperatorTypeEnum op,
 {
   ArithInstruction instruction = ARITH_NOT_SUPPORTED;
 
-  short type_op1;
-  short type_op2;
-  short type_result;
+  short type_op1 = -1;
+  short type_op2 = -1;
+  short type_result = -1;
   getCaseDatatypes(attr1->getDatatype(), attr1->getLength(), type_op1,
                    result->getDatatype(), result->getLength(), type_result,
                    0 /* don't need to take scale difference into account here */);

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/langman/LmLangManagerJava.cpp
----------------------------------------------------------------------
diff --git a/core/sql/langman/LmLangManagerJava.cpp b/core/sql/langman/LmLangManagerJava.cpp
index 58702a3..ca64d9d 100644
--- a/core/sql/langman/LmLangManagerJava.cpp
+++ b/core/sql/langman/LmLangManagerJava.cpp
@@ -3418,8 +3418,8 @@ LmResult LmLanguageManagerJava::convertToTimestamp(
   char *inputChars = ((char *)inputRow) + param->inDataOffset();
   ComUInt32 len = param->actualInDataSize(inputRow);
 
-  // NOTE: jdbc only handles default timestamp: yyyy-mm-dd hh:mm:ss.msssss.
-  len = (len <= 26) ? len :  26;
+  // NOTE: jdbc only handles default timestamp: yyyy-mm-dd hh:mm:ss.nssssssss.
+  len = (len <= 29) ? len :  29;
 
   // First create the java.lang.String from the input bytes
   str_cpy_all(tempbuf, inputChars, (Lng32) len);

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/optimizer/QRDescGenerator.cpp
----------------------------------------------------------------------
diff --git a/core/sql/optimizer/QRDescGenerator.cpp b/core/sql/optimizer/QRDescGenerator.cpp
index 9071018..42719aa 100644
--- a/core/sql/optimizer/QRDescGenerator.cpp
+++ b/core/sql/optimizer/QRDescGenerator.cpp
@@ -252,11 +252,17 @@ NABoolean QRDescGenerator::typeSupported(const NAType* type)
 
               default:
                 // All day-time interval values are expressed in terms of microseconds.
+
+                // If fractional precision is greater than
+                // microsecs, disable rangespec transformation.
+                if (type->getScale() > SQLInterval::MAX_FRACTION_PRECISION_MSEC)
+                  return FALSE;
+
                 return (SQLInterval::MAX_LEADING_PRECISION >=
                         IntervalType::getPrecision(intvType->getStartField(),
                                                    intvType->getLeadingPrecision(),
                                                    REC_DATE_SECOND,
-                                                   SQLInterval::MAX_FRACTION_PRECISION));
+                                                   SQLInterval::MAX_FRACTION_PRECISION_MSEC));
             }
         }
 
@@ -267,6 +273,13 @@ NABoolean QRDescGenerator::typeSupported(const NAType* type)
       //case NA_USER_SUPPLIED_TYPE:
       //case NA_RECORD_TYPE:
       //case NA_ROWSET_TYPE:
+
+        // datetime values are currently converted to Int64 microseconds value
+        // for rangespec constants. If fractional precision is greater than
+        // microsecs, disable rangespec transformation.
+        if (type->getScale() > DatetimeType::MAX_FRACTION_PRECISION_MSEC)
+          return FALSE;
+
         return TRUE;
 
       default:

http://git-wip-us.apache.org/repos/asf/trafodion/blob/319abf81/core/sql/parser/StmtDDLMisc.cpp
----------------------------------------------------------------------
diff --git a/core/sql/parser/StmtDDLMisc.cpp b/core/sql/parser/StmtDDLMisc.cpp
index af2c9d4..ff078e0 100644
--- a/core/sql/parser/StmtDDLMisc.cpp
+++ b/core/sql/parser/StmtDDLMisc.cpp
@@ -112,6 +112,16 @@ StmtDDLCleanupObjects::bindNode(BindWA * pBindWA)
       // remember the original table name specified by user
       origTableQualName_ = *tableQualName_;
 
+      if ((type_ == HIVE_TABLE_) ||
+          (type_ == HIVE_VIEW_))
+        {
+          // add hive catalog/schema names if not specified
+          if (tableQualName_->getCatalogName().isNull())
+            tableQualName_->setCatalogName(HIVE_SYSTEM_CATALOG);
+          if (tableQualName_->getSchemaName().isNull())
+            tableQualName_->setCatalogName(HIVE_SYSTEM_SCHEMA);
+        }
+
       if (applyDefaultsAndValidateObject(pBindWA, tableQualName_))
         {
           pBindWA->setErrStatus();


Mime
View raw message