未验证 提交 c7383bad 编写于 作者: D dapan1121 提交者: GitHub

Merge pull request #9140 from taosdata/fix/TD-11789

Fix/td 11789 If client and server charset are not the same, error will be appear in where string condition
...@@ -143,6 +143,7 @@ static bool validateDebugFlag(int32_t v); ...@@ -143,6 +143,7 @@ static bool validateDebugFlag(int32_t v);
static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
static int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo); static int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo);
static tSqlExpr* extractExprForSTable(SSqlCmd* pCmd, tSqlExpr** pExpr, SQueryInfo* pQueryInfo, int32_t tableIndex); static tSqlExpr* extractExprForSTable(SSqlCmd* pCmd, tSqlExpr** pExpr, SQueryInfo* pQueryInfo, int32_t tableIndex);
static void convertWhereStringCharset(tSqlExpr* pRight);
int validateTableName(char *tblName, int len, SStrToken* psTblToken, bool *dbIncluded); int validateTableName(char *tblName, int len, SStrToken* psTblToken, bool *dbIncluded);
...@@ -4963,25 +4964,23 @@ static int32_t validateJsonTagExpr(tSqlExpr* pExpr, char* msgBuf) { ...@@ -4963,25 +4964,23 @@ static int32_t validateJsonTagExpr(tSqlExpr* pExpr, char* msgBuf) {
return invalidOperationMsg(msgBuf, msg3); return invalidOperationMsg(msgBuf, msg3);
if (pLeft->pRight && (pLeft->pRight->value.nLen > TSDB_MAX_JSON_KEY_LEN || pLeft->pRight->value.nLen <= 0)) if (pLeft->pRight && (pLeft->pRight->value.nLen > TSDB_MAX_JSON_KEY_LEN || pLeft->pRight->value.nLen <= 0))
return invalidOperationMsg(msgBuf, msg2); return invalidOperationMsg(msgBuf, msg2);
if (pRight->tokenId == TK_NULL && pExpr->tokenId == TK_EQ) {
// transform for json->'key'=null
pRight->tokenId = TK_STRING;
pRight->value.nType = TSDB_DATA_TYPE_BINARY;
pRight->value.nLen = INT_BYTES;
pRight->value.pz = calloc(INT_BYTES, 1);
*(uint32_t*)pRight->value.pz = TSDB_DATA_JSON_null;
return TSDB_CODE_SUCCESS;
}
} }
if (pRight->value.nType == TSDB_DATA_TYPE_BINARY){ // json value store by nchar, so need to convert from binary to nchar if (pRight->value.nType == TSDB_DATA_TYPE_BINARY){ // json value store by nchar, so need to convert from binary to nchar
if(pRight->value.nLen == INT_BYTES && *(uint32_t*)pRight->value.pz == TSDB_DATA_JSON_null){
return TSDB_CODE_SUCCESS;
}
if(pRight->value.nLen == 0){ if(pRight->value.nLen == 0){
pRight->value.nType = TSDB_DATA_TYPE_NCHAR; pRight->value.nType = TSDB_DATA_TYPE_NCHAR;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
char newData[TSDB_MAX_JSON_TAGS_LEN] = {0}; convertWhereStringCharset(pRight);
int len = 0;
if(!taosMbsToUcs4(pRight->value.pz, pRight->value.nLen, newData, TSDB_MAX_JSON_TAGS_LEN, &len)){
tscError("json where condition mbsToUcs4 error");
}
pRight->value.pz = realloc(pRight->value.pz, len);
memcpy(pRight->value.pz, newData, len);
pRight->value.nLen = len;
pRight->value.nType = TSDB_DATA_TYPE_NCHAR;
} }
} }
...@@ -5045,6 +5044,34 @@ int32_t handleNeOptr(tSqlExpr** rexpr, tSqlExpr* expr) { ...@@ -5045,6 +5044,34 @@ int32_t handleNeOptr(tSqlExpr** rexpr, tSqlExpr* expr) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
void convertWhereStringCharset(tSqlExpr* pRight){
if(pRight->value.nType != TSDB_DATA_TYPE_BINARY || pRight->value.nLen == 0){
return;
}
char *newData = calloc(pRight->value.nLen * TSDB_NCHAR_SIZE, 1);
if(!newData){
tscError("convertWhereStringCharset calloc memory error");
return;
}
int len = 0;
if(!taosMbsToUcs4(pRight->value.pz, pRight->value.nLen, newData, pRight->value.nLen * TSDB_NCHAR_SIZE, &len)){
tscError("nchar in where condition mbsToUcs4 error");
free(newData);
return;
}
char* tmp = realloc(pRight->value.pz, len);
if (!tmp){
tscError("convertWhereStringCharset realloc memory error");
free(newData);
return;
}
pRight->value.pz = tmp;
memcpy(pRight->value.pz, newData, len);
pRight->value.nLen = len;
pRight->value.nType = TSDB_DATA_TYPE_NCHAR;
free(newData);
}
static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SCondExpr* pCondExpr, static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SCondExpr* pCondExpr,
int32_t* type, int32_t* tbIdx, int32_t parentOptr, tSqlExpr** columnExpr, int32_t* type, int32_t* tbIdx, int32_t parentOptr, tSqlExpr** columnExpr,
...@@ -5061,14 +5088,6 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql ...@@ -5061,14 +5088,6 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
SStrToken* colName = NULL; SStrToken* colName = NULL;
if(pLeft->tokenId == TK_ARROW){ if(pLeft->tokenId == TK_ARROW){
colName = &(pLeft->pLeft->columnName); colName = &(pLeft->pLeft->columnName);
if (pRight->tokenId == TK_NULL && (*pExpr)->tokenId == TK_EQ) {
// transform for json->'key'=null
pRight->tokenId = TK_STRING;
pRight->value.nType = TSDB_DATA_TYPE_BINARY;
pRight->value.nLen = INT_BYTES;
pRight->value.pz = calloc(INT_BYTES, 1);
*(uint32_t*)pRight->value.pz = TSDB_DATA_JSON_null;
}
}else{ }else{
colName = &(pLeft->columnName); colName = &(pLeft->columnName);
} }
...@@ -5105,6 +5124,11 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql ...@@ -5105,6 +5124,11 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
} }
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
if (pSchema->type == TSDB_DATA_TYPE_NCHAR){
convertWhereStringCharset(pRight);
}
if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP && index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { // query on time range if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP && index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { // query on time range
if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) { if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
......
...@@ -5511,18 +5511,20 @@ int parseJsontoTagData(char* json, SKVRowBuilder* kvRowBuilder, char* errMsg, in ...@@ -5511,18 +5511,20 @@ int parseJsontoTagData(char* json, SKVRowBuilder* kvRowBuilder, char* errMsg, in
if(item->type == cJSON_String){ // add json value format: type|data if(item->type == cJSON_String){ // add json value format: type|data
char *jsonValue = item->valuestring; char *jsonValue = item->valuestring;
outLen = 0; outLen = 0;
char tagVal[TSDB_MAX_JSON_TAGS_LEN] = {0}; char *tagVal = calloc(strlen(jsonValue) * TSDB_NCHAR_SIZE + TSDB_NCHAR_SIZE, 1);
*tagVal = jsonType2DbType(0, item->type); // type *tagVal = jsonType2DbType(0, item->type); // type
char* tagData = POINTER_SHIFT(tagVal,CHAR_BYTES); char* tagData = POINTER_SHIFT(tagVal,CHAR_BYTES);
if (!taosMbsToUcs4(jsonValue, strlen(jsonValue), varDataVal(tagData), if (!taosMbsToUcs4(jsonValue, strlen(jsonValue), varDataVal(tagData),
TSDB_MAX_JSON_TAGS_LEN - CHAR_BYTES - VARSTR_HEADER_SIZE, &outLen)) { (int32_t)(strlen(jsonValue) * TSDB_NCHAR_SIZE), &outLen)) {
tscError("json string error:%s|%s", strerror(errno), jsonValue); tscError("json string error:%s|%s", strerror(errno), jsonValue);
retCode = tscSQLSyntaxErrMsg(errMsg, "serizelize json error", NULL); retCode = tscSQLSyntaxErrMsg(errMsg, "serizelize json error", NULL);
free(tagVal);
goto end; goto end;
} }
varDataSetLen(tagData, outLen); varDataSetLen(tagData, outLen);
tdAddColToKVRow(kvRowBuilder, jsonIndex++, TSDB_DATA_TYPE_NCHAR, tagVal, true); tdAddColToKVRow(kvRowBuilder, jsonIndex++, TSDB_DATA_TYPE_NCHAR, tagVal, true);
free(tagVal);
}else if(item->type == cJSON_Number){ }else if(item->type == cJSON_Number){
if(!isfinite(item->valuedouble)){ if(!isfinite(item->valuedouble)){
tscError("json value is invalidate"); tscError("json value is invalidate");
......
...@@ -4231,7 +4231,6 @@ char* parseTagDatatoJson(void *p){ ...@@ -4231,7 +4231,6 @@ char* parseTagDatatoJson(void *p){
memset(tagJsonKey, 0, sizeof(tagJsonKey)); memset(tagJsonKey, 0, sizeof(tagJsonKey));
memcpy(tagJsonKey, varDataVal(val), varDataLen(val)); memcpy(tagJsonKey, varDataVal(val), varDataLen(val));
}else{ // json value }else{ // json value
char tagJsonValue[TSDB_MAX_JSON_TAGS_LEN] = {0};
char* realData = POINTER_SHIFT(val, CHAR_BYTES); char* realData = POINTER_SHIFT(val, CHAR_BYTES);
char type = *(char*)val; char type = *(char*)val;
if(type == TSDB_DATA_TYPE_BINARY) { if(type == TSDB_DATA_TYPE_BINARY) {
...@@ -4244,14 +4243,16 @@ char* parseTagDatatoJson(void *p){ ...@@ -4244,14 +4243,16 @@ char* parseTagDatatoJson(void *p){
} }
cJSON_AddItemToObject(json, tagJsonKey, value); cJSON_AddItemToObject(json, tagJsonKey, value);
}else if(type == TSDB_DATA_TYPE_NCHAR) { }else if(type == TSDB_DATA_TYPE_NCHAR) {
char *tagJsonValue = calloc(varDataLen(realData), 1);
int32_t length = taosUcs4ToMbs(varDataVal(realData), varDataLen(realData), tagJsonValue); int32_t length = taosUcs4ToMbs(varDataVal(realData), varDataLen(realData), tagJsonValue);
if (length < 0) { if (length < 0) {
tsdbError("charset:%s to %s. val:%s convert json value failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, tsdbError("charset:%s to %s. val:%s convert json value failed.", DEFAULT_UNICODE_ENCODEC, tsCharset,
(char*)val); (char*)val);
free(tagJsonValue);
goto end; goto end;
} }
cJSON* value = cJSON_CreateString(tagJsonValue); cJSON* value = cJSON_CreateString(tagJsonValue);
free(tagJsonValue);
if (value == NULL) if (value == NULL)
{ {
goto end; goto end;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册