Merge PR 1493 [TRAFODION-2821] Trafodion core code base needs to be thread safe
diff --git a/core/sql/exp/exp_function.cpp b/core/sql/exp/exp_function.cpp
index a65c120..8d9426f 100644
--- a/core/sql/exp/exp_function.cpp
+++ b/core/sql/exp/exp_function.cpp
@@ -2550,7 +2550,7 @@
break;
case REC_BIN32_SIGNED:
- *(Lng32 *)sec = labs(*(Lng32 *)op_data[1]);
+ sec = *(Lng32 *)op_data[1];
if(sec < 0 )
{
ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
diff --git a/core/sql/optimizer/Inlining.cpp b/core/sql/optimizer/Inlining.cpp
index f8d7b66..e93e33b 100644
--- a/core/sql/optimizer/Inlining.cpp
+++ b/core/sql/optimizer/Inlining.cpp
@@ -1888,7 +1888,7 @@
NABoolean isIMInsert,
NABoolean useInternalSyskey,
NABoolean isForUpdateOrMergeUpdate,
- NABoolean isForMerge, // mergeDelete OR mergeUpdate
+ NABoolean mergeDeleteWithInsertOrMergeUpdate,
NABoolean isEffUpsert)
{
@@ -1906,7 +1906,8 @@
// that correspond to the base table. Hence we introduce
// robustDelete below. This flag could also be called
// isIMOnAUniqueIndexForMerge
- NABoolean robustDelete = (isForMerge && index->isUniqueIndex()) || (isEffUpsert && index->isUniqueIndex());
+ NABoolean robustDelete = (mergeDeleteWithInsertOrMergeUpdate && index->isUniqueIndex()) ||
+ (isEffUpsert && index->isUniqueIndex());
tableCorrName.setCorrName(isIMInsert ? NEWCorr : OLDCorr);
@@ -2127,8 +2128,15 @@
if (getOperatorType() == REL_UNARY_DELETE ||
getOperatorType() == REL_UNARY_UPDATE ||
isEffUpsert)
-
- indexDelete = indexOp = createIMNode(bindWA,
+ {
+ NABoolean mergeDeleteWithInsertOrMergeUpdate = isMerge();
+ if (mergeDeleteWithInsertOrMergeUpdate &&
+ (getOperatorType() == REL_UNARY_DELETE) &&
+ (!insertValues()))
+ // merge delete without an insert
+ mergeDeleteWithInsertOrMergeUpdate = FALSE;
+
+ indexDelete = indexOp = createIMNode(bindWA,
tableCorrName,
indexCorrName,
index,
@@ -2136,8 +2144,9 @@
FALSE,
useInternalSyskey,
isForUpdateOrMergeUpdate,
- isMerge(),
+ mergeDeleteWithInsertOrMergeUpdate,
isEffUpsert);
+ }
if ((getOperatorType() == REL_UNARY_UPDATE) || isEffUpsert){
indexOp = new (bindWA->wHeap()) Union(indexDelete, indexInsert,
diff --git a/core/sql/sqlcomp/CmpSeabaseDDL.h b/core/sql/sqlcomp/CmpSeabaseDDL.h
index f1f9429..c6ff74b 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDL.h
+++ b/core/sql/sqlcomp/CmpSeabaseDDL.h
@@ -129,10 +129,21 @@
#include "CmpSeabaseDDLmd.h"
-// The value HBase uses for checking key length is HConstants.MAX_ROW_LENGTH.
-// The rowID length limit in HBase is enforced in HBase modules Put.java and
-// Mutation.java. (The above was true as of HBase 1.0.0.)
-#define MAX_HBASE_ROWKEY_LEN 32767
+// The define below gives the maximum rowID length that we will permit
+// for Trafodion tables and indexes. The actual HBase limit is more
+// complicated: For Puts, HBase compares the key length to
+// HConstants.MAX_ROW_LENGTH (= Short.MAX_VALUE = 32767). It raises an
+// exception if the key length is greater than that. But there are also
+// some internal data structures that HBase uses (the WAL perhaps?) that
+// are keyed. Experiments show that a Trafodion key of length n causes
+// a hang if n + strlen(Trafodion object name) + 16 > 32767. The HBase
+// log in these cases shows an IllegalArgumentException Row > 32767 in
+// this case. So it seems best to limit Trafodion key lengths to something
+// sufficiently smaller than 32767 so we don't hit these hangs. A value
+// of 32000 seems safe, since the longest Trafodion table name will be
+// TRAFODION.something.something, with each of the somethings topping out
+// at 256 bytes.
+#define MAX_HBASE_ROWKEY_LEN 32000
#define SEABASEDDL_INTERNAL_ERROR(text) \
*CmpCommon::diags() << DgSqlCode(-CAT_INTERNAL_EXCEPTION_ERROR) \
diff --git a/core/sql/sqlcomp/CmpSeabaseDDLindex.cpp b/core/sql/sqlcomp/CmpSeabaseDDLindex.cpp
index 030d76c..2e35ac0 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDLindex.cpp
+++ b/core/sql/sqlcomp/CmpSeabaseDDLindex.cpp
@@ -239,14 +239,6 @@
keyInfoArray[i].hbaseColQual = new(CTXTHEAP) char[strlen(qualNumStr)+1];
strcpy((char*)keyInfoArray[i].hbaseColQual, qualNumStr);
}
-
- if (keyLength > MAX_HBASE_ROWKEY_LEN )
- {
- *CmpCommon::diags() << DgSqlCode(-CAT_ROWKEY_LEN_TOO_LARGE)
- << DgInt0(keyLength)
- << DgInt1(MAX_HBASE_ROWKEY_LEN);
- return -1;
- }
if ((syskeyOnly) &&
(hasSyskey))
@@ -396,6 +388,14 @@
i++;
}
+ if (keyLength > MAX_HBASE_ROWKEY_LEN )
+ {
+ *CmpCommon::diags() << DgSqlCode(-CAT_ROWKEY_LEN_TOO_LARGE)
+ << DgInt0(keyLength)
+ << DgInt1(MAX_HBASE_ROWKEY_LEN);
+ return -1;
+ }
+
return 0;
}
diff --git a/core/sql/ustat/hs_globals.cpp b/core/sql/ustat/hs_globals.cpp
index a437d97..7267862 100644
--- a/core/sql/ustat/hs_globals.cpp
+++ b/core/sql/ustat/hs_globals.cpp
@@ -5052,7 +5052,7 @@
}
else
{
- sprintf(sbuf, "%d", col.precision+2);
+ sprintf(sbuf, "%d,0", col.precision+2); // for seconds cast below
typeName = getIntTypeForInterval(group, 60 * (Int64)pow(10, col.precision));
}
group->ISSelectExpn.append("cast(cast(")
@@ -5076,7 +5076,7 @@
}
else
{
- sprintf(sbuf, "%d", col.precision+4);
+ sprintf(sbuf, "%d,0", col.precision+4); // for seconds cast below
typeName = getIntTypeForInterval(group, 60 * 60 * (Int64)pow(10, col.precision));
}
group->ISSelectExpn.append("cast(cast(")
@@ -5100,7 +5100,7 @@
}
else
{
- sprintf(sbuf, "%d", col.precision+5);
+ sprintf(sbuf, "%d,0", col.precision+5); // for seconds cast below
typeName = getIntTypeForInterval(group, 24 * 60 * 60 * (Int64)pow(10, col.precision));
}
group->ISSelectExpn.append("cast(cast(")