From 3bec830f9933a5a647afbc0f278e7dd39f8c0c34 Mon Sep 17 00:00:00 2001 From: "shaoyong.li" Date: Thu, 7 Jun 2018 16:08:57 +0800 Subject: [PATCH 1/6] TRAFODION-3099 --- .../src/odbc/nsksrvr/Interface/odbcs_srvr.cpp | 26 +++++++++++++++++++ core/sql/sqlci/SqlCmd.cpp | 5 +++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp b/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp index a6f6639763..b51afd97d9 100644 --- a/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp +++ b/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp @@ -1778,6 +1778,32 @@ SQLEXECUTE_IOMessage( { inValues = (BYTE *) curptr+inputPosition; inputPosition += inValuesLength; + //if the inValues include charset perfix should delete it + if (inValues[0] != '\'') + { + IDL_long perfix_beg = 0; + while (perfix_beg < inValuesLength-1) + { + if (inValues[perfix_beg] == '\'' && inValues[perfix_beg+2] != '\'') + { + IDL_long perfix_end = perfix_beg+2; + while (perfix_end < inValuesLength) + { + if (inValues[perfix_end] == '\'' && inValues[perfix_end+2] != '\'') + break; + perfix_end += 2; + } + memcpy(inValues, &inValues[perfix_beg+2], perfix_end-perfix_beg-2); + for (IDL_long i=perfix_end-perfix_beg-2; i < perfix_end+1 && i < inValuesLength;) + { + inValues[i++] = (BYTE)' '; + inValues[i++] = 0; + } + break; + } + perfix_beg+=2; + } + } } transactionIDLength = *(IDL_unsigned_long*)(curptr+inputPosition); diff --git a/core/sql/sqlci/SqlCmd.cpp b/core/sql/sqlci/SqlCmd.cpp index 8370aa8205..e359208d9b 100644 --- a/core/sql/sqlci/SqlCmd.cpp +++ b/core/sql/sqlci/SqlCmd.cpp @@ -2673,7 +2673,7 @@ Lng32 Execute::storeParams(char* argument_, short &num_params, char param[MAX_LEN_UNNAMED_PARAM+1]; // buffer for current value size_t i = 0; // len(param)+1 - if ( using_param_charsets && *args == '_' ) { + if ( using_param_charsets && (*args == '_' || TOUPPER(*args) == 'N')) { char* prefixPtr = args+1; while ( *prefixPtr ) { if ( *prefixPtr == '\'' ) { @@ -2692,6 +2692,9 @@ Lng32 Execute::storeParams(char* argument_, short &num_params, // name lookup CharInfo::CharSet cs = CharInfo::getCharSetEnum(upperCaseName); + if ( TOUPPER(*args) == 'N') { + cs = CharInfo::UNICODE; + } delete [] upperCaseName; if (CharInfo::isCharSetFullySupported(cs)) { From d069ad822b6d8adee061afa926119d92d0de55bd Mon Sep 17 00:00:00 2001 From: "shaoyong.li" Date: Thu, 7 Jun 2018 23:40:56 +0800 Subject: [PATCH 2/6] TRAFODION-3099 --- .../src/odbc/nsksrvr/Interface/odbcs_srvr.cpp | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp b/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp index b51afd97d9..6b6769e293 100644 --- a/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp +++ b/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp @@ -1657,6 +1657,32 @@ void LOG_INFO(CError* ierror) LOG_MSG( ierror, EVENTLOG_INFORMATION_TYPE); } +IDL_boolean isDigit(BYTE c) +{ + if ((c >= '0') && (c <= '9')) + return TRUE; + return FALSE; +} + +IDL_short getHexDigitValue(BYTE c) +{ + if (isDigit(c)) + return (IDL_short)c - '0'; + else + { + if ('A' <= c and c <= 'F') + return (IDL_short)c - 'A' + 10; + else + return (IDL_short)c - 'a' + 10; + } + +} + +BYTE HandleCharSetPerfix(BYTE upperBits, BYTE lowerBits) +{ + return getHexDigitValue(upperBits)*16 + getHexDigitValue(lowerBits); +} + void SQLEXECUTE_IOMessage( /* In */ CEE_tag_def objtag_ @@ -1794,6 +1820,24 @@ SQLEXECUTE_IOMessage( perfix_end += 2; } memcpy(inValues, &inValues[perfix_beg+2], perfix_end-perfix_beg-2); + + // handel hex values + if (perfix_beg > 1 && (inValues[perfix_beg-2] == 'x' || inValues[perfix_beg-2] == 'X')) + { + for(IDL_long i = 0; i < perfix_end-perfix_beg-2; i+=4) + { + inValues[i/2] = HandleCharSetPerfix(inValues[i], inValues[i+2]); + inValues[i/2+1] = 0; + if (i != 0) + { + inValues[i] = ' '; + inValues[i+1] = 0; + } + inValues[i+2] = ' '; + inValues[i+3] = 0; + } + } + for (IDL_long i=perfix_end-perfix_beg-2; i < perfix_end+1 && i < inValuesLength;) { inValues[i++] = (BYTE)' '; From 261c630c7459704532c31c9e97c8cd733383a422 Mon Sep 17 00:00:00 2001 From: "shaoyong.li" Date: Sun, 10 Jun 2018 20:27:55 +0800 Subject: [PATCH 3/6] TRAFODION-3099 --- core/sql/cli/CliExpExchange.cpp | 114 +++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 2 deletions(-) diff --git a/core/sql/cli/CliExpExchange.cpp b/core/sql/cli/CliExpExchange.cpp index 7e39da5a7d..53f44e2620 100644 --- a/core/sql/cli/CliExpExchange.cpp +++ b/core/sql/cli/CliExpExchange.cpp @@ -1603,7 +1603,7 @@ InputOutputExpr::outputValues(atp_struct *atp, sourceType = REC_DECIMAL_LSE; } - // 5/18/98: added to handle SJIS encoding charset case. + // 5/18/98: added to handle SJIS encoding charset case. // This is used in ODBC where the target character set is still // ASCII but the actual character set used is SJIS. // @@ -3383,6 +3383,111 @@ InputOutputExpr::inputRowwiseRowsetValues(atp_struct *atp, return ex_expr::EXPR_ERROR; } +void handleCharsetPerfix(char* source, ComDiagsArea *diagsArea, CollHeap*heap, Descriptor * inputDesc) +{ + char perfix[MAX_CHAR_SET_STRING_LENGTH]; + Lng32 endIndex = MAX_CHAR_SET_STRING_LENGTH; + if (source) + { + Lng32 perfix_beg = 0; + Lng32 perfix_end = 0; + if(source[0] == '_' || source[0] =='N' || source[0] == 'n') + { + perfix_beg += 2; + perfix_end = perfix_beg; + + // get charset perfix + while (perfix_end <= endIndex) + { + if(source[perfix_end] == '\'') + { + //charset perfix + Lng32 i; + for(i = 0; i < (perfix_end-perfix_beg)/2; ++i) + perfix[i] = TOUPPER(*(source+perfix_beg+i*2)); + perfix[i] = 0; + break; + } + // not include charset name + if (perfix_end == endIndex) + return; + perfix_end += 2; + } + + // charset name lookup + CharInfo::CharSet cs = CharInfo::getCharSetEnum(perfix); + if(source[0] != '_') + { + perfix_beg = 0; + cs = CharInfo::UNICODE; + } + if (cs == CharInfo::UnknownCharSet) + return; + NABoolean isHex = false; + + if(perfix_end > 4 && (source[perfix_end-2] == 'X' || source[perfix_end-2] == 'x') && + source[perfix-4] == ' ') + { + isHex = true; + } + + +// if(CharInfo::isCharSetFullySupported(cs)) +// { + // get dynamic param value + Lng32 valueBeg = perfix_end + 2; + Lng32 valueEnd = valueBeg; + while(*(source+valueEnd)) + { + if (source[valueEnd] == '\'') + { + NAString* pTempStr = NULL; + pTempStr = unicodeToChar((wchar_t*)&source[valueBeg], (valueEnd-valueBeg)/2, + static_cast(cs), heap); + memcpy(source, &source[valueBeg], valueEnd-valueBeg); + for (Lng32 i =valueEnd - valueBeg; i < valueEnd+2; ++i) + { + if (i%2 == 0) + source[i] = ' '; + else { + source[i] = 0; + } + } +// if (pTempStr) +// { +// memcpy(source, &source[valueBeg], valueEnd-valueBeg); +// NAWchar* utf16StrLit = new NAWchar[pTempStr->length()+1]; +// LocaleStringToUnicode(cs, pTempStr->data(),pTempStr->length(), utf16StrLit, pTempStr->length()+1, TRUE); +// memcpy(source, pTempStr->data(), pTempStr->length()); +// for (Lng32 i =valueEnd - valueBeg; i < valueEnd+2; ++i) +// { +// if (i%2 == 0) +// source[i] = ' '; +// else { +// source[i] = 0; +// } +// } + +// return; +// } +// else +// { +// *diagsArea << DgSqlCode(-8413); +// return; +// } + +// } + valueEnd += 2; + } + } +// else +// { +// *diagsArea << DgSqlCode(-8013); +// } + } + } +} + ex_expr::exp_return_type InputOutputExpr::inputValues(atp_struct *atp, void * inputDesc_, @@ -3639,6 +3744,7 @@ InputOutputExpr::inputValues(atp_struct *atp, // do the conversion source = (char *)&targetRowsetSize; + if (::convDoIt(source, sizeof(Lng32), REC_BIN32_SIGNED, @@ -3804,7 +3910,10 @@ InputOutputExpr::inputValues(atp_struct *atp, if (!source) { continue; } - + if(isOdbc) + { + handleCharsetPerfix(source, diagsArea, heap, inputDesc); + } if (DFS2REC::isSQLVarChar(sourceType)) { Lng32 vcIndLen = inputDesc->getVarIndicatorLength(entry); sourceLen = ExpTupleDesc::getVarLength(source, vcIndLen); @@ -4408,6 +4517,7 @@ ex_expr::exp_return_type InputOutputExpr::addDescInfoIntoStaticDesc } return ex_expr::EXPR_OK; + } Lng32 InputOutputExpr::getMaxParamIdx() From fe285c936e799b4b0db387e839587ef9b85eda0d Mon Sep 17 00:00:00 2001 From: "shaoyong.li" Date: Sun, 10 Jun 2018 20:56:11 +0800 Subject: [PATCH 4/6] TRAFODION-3099 --- core/sql/cli/CliExpExchange.cpp | 48 ++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/core/sql/cli/CliExpExchange.cpp b/core/sql/cli/CliExpExchange.cpp index 53f44e2620..16c45af08f 100644 --- a/core/sql/cli/CliExpExchange.cpp +++ b/core/sql/cli/CliExpExchange.cpp @@ -3383,6 +3383,32 @@ InputOutputExpr::inputRowwiseRowsetValues(atp_struct *atp, return ex_expr::EXPR_ERROR; } +NABoolean isDigit(BYTE c) +{ + if ((c >= '0') && (c <= '9')) + return TRUE; + return FALSE; +} + +Int32 getHexDigitValue(BYTE c) +{ + if (isDigit(c)) + return (Int32)c - '0'; + else + { + if ('A' <= c and c <= 'F') + return (Int32)c - 'A' + 10; + else + return (Int32)c - 'a' + 10; + } + +} + +char HandleHexValue(char upperBits, char lowerBits) +{ + return getHexDigitValue(upperBits)*16 + getHexDigitValue(lowerBits); +} + void handleCharsetPerfix(char* source, ComDiagsArea *diagsArea, CollHeap*heap, Descriptor * inputDesc) { char perfix[MAX_CHAR_SET_STRING_LENGTH]; @@ -3425,8 +3451,7 @@ void handleCharsetPerfix(char* source, ComDiagsArea *diagsArea, CollHeap*heap, return; NABoolean isHex = false; - if(perfix_end > 4 && (source[perfix_end-2] == 'X' || source[perfix_end-2] == 'x') && - source[perfix-4] == ' ') + if(perfix_end > 4 && source[perfix_end-2] == 'X' && source[perfix_end-4] == ' ') { isHex = true; } @@ -3441,10 +3466,27 @@ void handleCharsetPerfix(char* source, ComDiagsArea *diagsArea, CollHeap*heap, { if (source[valueEnd] == '\'') { + NAString* pTempStr = NULL; pTempStr = unicodeToChar((wchar_t*)&source[valueBeg], (valueEnd-valueBeg)/2, static_cast(cs), heap); + memcpy(source, &source[valueBeg], valueEnd-valueBeg); + if(isHex) + { + for (Lng32 i=0; i < valueEnd-valueBeg-2; i+=4) + { + source[i/2] = HandleHexValue(source[i], source[i+2]); + source[i/2+1] = 0; + if(i != 0) + { + source[i] = ' '; + source[i+1] = 0; + } + source[i+2] = ' '; + source[i+3] = 0; + } + } for (Lng32 i =valueEnd - valueBeg; i < valueEnd+2; ++i) { if (i%2 == 0) @@ -3477,8 +3519,8 @@ void handleCharsetPerfix(char* source, ComDiagsArea *diagsArea, CollHeap*heap, // } // } - valueEnd += 2; } + valueEnd += 2; } // else // { From 49b4337aaa85d38482468ef9f8f35a30e4523594 Mon Sep 17 00:00:00 2001 From: "shaoyong.li" Date: Sun, 10 Jun 2018 21:10:47 +0800 Subject: [PATCH 5/6] TRAFODION-3099 --- core/sql/cli/CliExpExchange.cpp | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/core/sql/cli/CliExpExchange.cpp b/core/sql/cli/CliExpExchange.cpp index 16c45af08f..3eb5f5521b 100644 --- a/core/sql/cli/CliExpExchange.cpp +++ b/core/sql/cli/CliExpExchange.cpp @@ -3456,10 +3456,6 @@ void handleCharsetPerfix(char* source, ComDiagsArea *diagsArea, CollHeap*heap, isHex = true; } - -// if(CharInfo::isCharSetFullySupported(cs)) -// { - // get dynamic param value Lng32 valueBeg = perfix_end + 2; Lng32 valueEnd = valueBeg; while(*(source+valueEnd)) @@ -3495,37 +3491,9 @@ void handleCharsetPerfix(char* source, ComDiagsArea *diagsArea, CollHeap*heap, source[i] = 0; } } -// if (pTempStr) -// { -// memcpy(source, &source[valueBeg], valueEnd-valueBeg); -// NAWchar* utf16StrLit = new NAWchar[pTempStr->length()+1]; -// LocaleStringToUnicode(cs, pTempStr->data(),pTempStr->length(), utf16StrLit, pTempStr->length()+1, TRUE); -// memcpy(source, pTempStr->data(), pTempStr->length()); -// for (Lng32 i =valueEnd - valueBeg; i < valueEnd+2; ++i) -// { -// if (i%2 == 0) -// source[i] = ' '; -// else { -// source[i] = 0; -// } -// } - -// return; -// } -// else -// { -// *diagsArea << DgSqlCode(-8413); -// return; -// } - -// } } valueEnd += 2; } -// else -// { -// *diagsArea << DgSqlCode(-8013); -// } } } } From 7ab2522f53efa8d04a39341e876b5c635f0d5738 Mon Sep 17 00:00:00 2001 From: "shaoyong.li" Date: Mon, 11 Jun 2018 13:34:27 +0800 Subject: [PATCH 6/6] TRAFODION-3099 --- .../src/odbc/nsksrvr/Interface/odbcs_srvr.cpp | 70 ------------------- 1 file changed, 70 deletions(-) diff --git a/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp b/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp index 6b6769e293..a6f6639763 100644 --- a/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp +++ b/core/conn/odbc/src/odbc/nsksrvr/Interface/odbcs_srvr.cpp @@ -1657,32 +1657,6 @@ void LOG_INFO(CError* ierror) LOG_MSG( ierror, EVENTLOG_INFORMATION_TYPE); } -IDL_boolean isDigit(BYTE c) -{ - if ((c >= '0') && (c <= '9')) - return TRUE; - return FALSE; -} - -IDL_short getHexDigitValue(BYTE c) -{ - if (isDigit(c)) - return (IDL_short)c - '0'; - else - { - if ('A' <= c and c <= 'F') - return (IDL_short)c - 'A' + 10; - else - return (IDL_short)c - 'a' + 10; - } - -} - -BYTE HandleCharSetPerfix(BYTE upperBits, BYTE lowerBits) -{ - return getHexDigitValue(upperBits)*16 + getHexDigitValue(lowerBits); -} - void SQLEXECUTE_IOMessage( /* In */ CEE_tag_def objtag_ @@ -1804,50 +1778,6 @@ SQLEXECUTE_IOMessage( { inValues = (BYTE *) curptr+inputPosition; inputPosition += inValuesLength; - //if the inValues include charset perfix should delete it - if (inValues[0] != '\'') - { - IDL_long perfix_beg = 0; - while (perfix_beg < inValuesLength-1) - { - if (inValues[perfix_beg] == '\'' && inValues[perfix_beg+2] != '\'') - { - IDL_long perfix_end = perfix_beg+2; - while (perfix_end < inValuesLength) - { - if (inValues[perfix_end] == '\'' && inValues[perfix_end+2] != '\'') - break; - perfix_end += 2; - } - memcpy(inValues, &inValues[perfix_beg+2], perfix_end-perfix_beg-2); - - // handel hex values - if (perfix_beg > 1 && (inValues[perfix_beg-2] == 'x' || inValues[perfix_beg-2] == 'X')) - { - for(IDL_long i = 0; i < perfix_end-perfix_beg-2; i+=4) - { - inValues[i/2] = HandleCharSetPerfix(inValues[i], inValues[i+2]); - inValues[i/2+1] = 0; - if (i != 0) - { - inValues[i] = ' '; - inValues[i+1] = 0; - } - inValues[i+2] = ' '; - inValues[i+3] = 0; - } - } - - for (IDL_long i=perfix_end-perfix_beg-2; i < perfix_end+1 && i < inValuesLength;) - { - inValues[i++] = (BYTE)' '; - inValues[i++] = 0; - } - break; - } - perfix_beg+=2; - } - } } transactionIDLength = *(IDL_unsigned_long*)(curptr+inputPosition);