-
Notifications
You must be signed in to change notification settings - Fork 152
[TRAFODION-3099] Prepare execute fails to handle N'<string>', _iso88591'<string>', _utf8'<string>' for a nchar column #1623
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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,94 @@ InputOutputExpr::inputRowwiseRowsetValues(atp_struct *atp, | |
return ex_expr::EXPR_ERROR; | ||
} | ||
|
||
void handleCharsetPerfix(Descriptor * inputDesc) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of "Perfix" it should say "Prefix". Again, a minor comment. There are several other places below where the same comment applies. |
||
{ | ||
char perfix[MAX_CHAR_SET_STRING_LENGTH]; | ||
|
||
if(inputDesc) | ||
{ | ||
for (Lng32 entry = 1; entry <= inputDesc->getUsedEntryCount(); ++entry) | ||
{ | ||
Lng32 perfix_beg = -1; | ||
Lng32 perfix_end = 0; | ||
char* source = inputDesc->getVarData(entry); | ||
Lng32 valueLength = inputDesc->getVarDataLength(entry); | ||
if (source) | ||
{ | ||
// get charset perfix beg loc | ||
for (Lng32 i = 0; i < valueLength && i < MAX_CHAR_SET_STRING_LENGTH; ++i) | ||
{ | ||
if(source[i] == '_' || TOUPPER(source[i]) =='N') | ||
{ | ||
perfix_beg = i; | ||
break; | ||
} | ||
|
||
if (source[i] == '\'') | ||
return; | ||
} | ||
|
||
if (perfix_beg < 0) | ||
return; | ||
|
||
// get charset perfix end loc | ||
Lng32 perfix_ind = 0; | ||
|
||
if (source[perfix_beg] == 'N') | ||
{ | ||
perfix[perfix_ind] = 'N'; | ||
perfix_ind = 1; | ||
} | ||
|
||
for (Lng32 i = perfix_beg+1; i < valueLength && i < MAX_CHAR_SET_STRING_LENGTH; ++i) | ||
{ | ||
if(source[i] != '\'' && source[i] != 0) | ||
{ | ||
perfix[perfix_ind] = TOUPPER(source[i]); | ||
++perfix_ind; | ||
} | ||
|
||
if(source[i] == '\'') | ||
{ | ||
perfix[perfix_ind] = 0; | ||
perfix_end = i; | ||
break; | ||
} | ||
} | ||
|
||
//perfix_cs | ||
CharInfo::CharSet cs = CharInfo::getCharSetEnum(perfix); | ||
if(str_len(perfix) == 1 AND perfix[0] == 'N') | ||
cs = CharInfo::UNICODE; | ||
|
||
//if perfix_cs is UnknownCharSet direct return | ||
if(cs == CharInfo::UnknownCharSet) | ||
return; | ||
|
||
// remove cs | ||
Lng32 valEnd = 0; | ||
for (Lng32 i = perfix_end+1; i < valueLength; ++i) | ||
{ | ||
if (source[i] == '\'') | ||
{ | ||
valEnd = i-1; | ||
break; | ||
} | ||
} | ||
Lng32 valBeg = perfix_end+1; | ||
if (!source[valBeg]) | ||
{ | ||
valBeg += 1; | ||
} | ||
memcpy(&source[perfix_beg], &source[valBeg], valEnd-valBeg+1); | ||
memcpy(&source[valEnd-valBeg+1+perfix_beg], &source[valEnd+3], valBeg+2); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't this copy uninitialized memory beyond the end of the value? This also shows a problem, that you would need to shorten the string. Another indicator that maybe the bug is in trafci and not here (see comment below). |
||
} | ||
|
||
} | ||
|
||
} | ||
} | ||
|
||
ex_expr::exp_return_type | ||
InputOutputExpr::inputValues(atp_struct *atp, | ||
void * inputDesc_, | ||
|
@@ -3639,6 +3727,7 @@ InputOutputExpr::inputValues(atp_struct *atp, | |
|
||
// do the conversion | ||
source = (char *)&targetRowsetSize; | ||
|
||
if (::convDoIt(source, | ||
sizeof(Lng32), | ||
REC_BIN32_SIGNED, | ||
|
@@ -3804,7 +3893,10 @@ InputOutputExpr::inputValues(atp_struct *atp, | |
if (!source) { | ||
continue; | ||
} | ||
|
||
if(isOdbc) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder whether it is correct that JDBC passses a string of the format _iso88591'ABCD' here. I would have expected that trafci should have already converted this to an unquoted string. You can try the following with your fix and see what you get: trafci Will this insert ABCD into the table or _iso88591'ABCD'? If it inserts ABCD, then I think the real bug is in trafci, not in this method, InputOutputExpr::inputValues(). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not quite was I asked: My statement had quotes around the string. Would you be able to try this command with the quoted string, on a system that has your fix:
trafci does not require quotes around string literals in the "using" clause. So, when it sees _iso88591'ABCD' it interprets that as a string to be inserted. It does not use an SQL parser to parse the string. That is not a bug, in my opinion. It is the correct behavior. I don't think we should allow SQL syntax other than simple constant values in the "using" clause in trafci. In other words, I think that TRAFODION-3099 is not an executor bug. You could change trafci to recognize this specific case, but I don't see a really good reason why. |
||
{ | ||
handleCharsetPerfix(inputDesc); | ||
} | ||
if (DFS2REC::isSQLVarChar(sourceType)) { | ||
Lng32 vcIndLen = inputDesc->getVarIndicatorLength(entry); | ||
sourceLen = ExpTupleDesc::getVarLength(source, vcIndLen); | ||
|
@@ -4408,6 +4500,7 @@ ex_expr::exp_return_type InputOutputExpr::addDescInfoIntoStaticDesc | |
} | ||
|
||
return ex_expr::EXPR_OK; | ||
|
||
} | ||
|
||
Lng32 InputOutputExpr::getMaxParamIdx() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a minor comment, but if you plan to make more changes in Trafodion, you should set your editor to display 8 spaces for each tab, so the indentation is correct. It's good that your editor uses spaces and not tabs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I will set my editor each tab to 8 spaces.