From adb6de0595d1c59cd9c01cc92523748a45453945 Mon Sep 17 00:00:00 2001 From: kailixu Date: Tue, 2 Apr 2024 17:33:11 +0800 Subject: [PATCH 1/6] fix: null value check for target column with pk --- include/util/taoserror.h | 1 + source/libs/executor/src/dataInserter.c | 12 +++++++++++- source/util/src/terror.c | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/util/taoserror.h b/include/util/taoserror.h index affa1f0345..3dc6e5333d 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -766,6 +766,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_PAR_SECOND_COL_PK TAOS_DEF_ERROR_CODE(0, 0x2672) #define TSDB_CODE_PAR_COL_PK_TYPE TAOS_DEF_ERROR_CODE(0, 0x2673) #define TSDB_CODE_PAR_INVALID_PK_OP TAOS_DEF_ERROR_CODE(0, 0x2674) +#define TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL TAOS_DEF_ERROR_CODE(0, 0x2675) #define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF) //planner diff --git a/source/libs/executor/src/dataInserter.c b/source/libs/executor/src/dataInserter.c index 88fb60fc4c..2d481bd273 100644 --- a/source/libs/executor/src/dataInserter.c +++ b/source/libs/executor/src/dataInserter.c @@ -217,6 +217,11 @@ int32_t buildSubmitReqFromBlock(SDataInserterHandle* pInserter, SSubmitReq2** pp case TSDB_DATA_TYPE_VARCHAR: { // TSDB_DATA_TYPE_BINARY ASSERT(pColInfoData->info.type == pCol->type); if (colDataIsNull_s(pColInfoData, j)) { + if ((pCol->flags & COL_IS_KEY)) { + qError("NULL value for primary key, colId:%" PRIi16 ", colType:%" PRIi8, pCol->colId, pCol->type); + terrno = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL; + goto _end; + } SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type); taosArrayPush(pVals, &cv); } else { @@ -240,10 +245,15 @@ int32_t buildSubmitReqFromBlock(SDataInserterHandle* pInserter, SSubmitReq2** pp if (pColInfoData->info.type < TSDB_DATA_TYPE_MAX && pColInfoData->info.type > TSDB_DATA_TYPE_NULL) { if (colDataIsNull_s(pColInfoData, j)) { if (PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId) { - qError("NULL value for primary key"); + qError("NULL value for primary timestamp key"); terrno = TSDB_CODE_PAR_INCORRECT_TIMESTAMP_VAL; goto _end; } + if ((pCol->flags & COL_IS_KEY)) { + qError("NULL value for primary key, colId:%" PRIi16 ", colType:%" PRIi8, pCol->colId, pCol->type); + terrno = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL; + goto _end; + } SColVal cv = COL_VAL_NULL(pCol->colId, pCol->type); // should use pCol->type taosArrayPush(pVals, &cv); diff --git a/source/util/src/terror.c b/source/util/src/terror.c index a64c8642db..99666320f1 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -628,6 +628,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_PAR_TAG_IS_PRIMARY_KEY, "tag can not be prim TAOS_DEFINE_ERROR(TSDB_CODE_PAR_SECOND_COL_PK, "primary key must be second column") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_COL_PK_TYPE, "primary key column must be of type int, uint, bigint, ubigint, and varchar") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_PK_OP, "primary key column can not be added, modified, and dropped") +TAOS_DEFINE_ERROR(TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL, "Primary key column should not be null") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INTERNAL_ERROR, "Parser internal error") //planner From 6e56e61ad52a56b610df1f4bcc4c6cf8dad59110 Mon Sep 17 00:00:00 2001 From: kailixu Date: Tue, 2 Apr 2024 19:49:30 +0800 Subject: [PATCH 2/6] fix: target table has less primary keys than source --- source/libs/parser/src/parTranslater.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 830b7f7396..b06a685c48 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -5088,7 +5088,8 @@ static int32_t translateInsertProject(STranslateContext* pCxt, SInsertStmt* pIns SNode* pPrimaryKeyExpr = NULL; SNode* pBoundCol = NULL; SNode* pProj = NULL; - int16_t numOfPKs = 0; + int16_t numOfSourcePKs = 0; + int16_t numOfTargetPKs = 0; int16_t numOfBoundPKs = 0; FORBOTH(pBoundCol, pInsert->pCols, pProj, pProjects) { SColumnNode* pCol = (SColumnNode*)pBoundCol; @@ -5105,7 +5106,8 @@ static int32_t translateInsertProject(STranslateContext* pCxt, SInsertStmt* pIns snprintf(pExpr->aliasName, sizeof(pExpr->aliasName), "%s", pCol->colName); if (PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId) { pPrimaryKeyExpr = (SNode*)pExpr; - numOfPKs = pCol->numOfPKs; + numOfTargetPKs = pCol->numOfPKs; + numOfSourcePKs = ((SColumnNode*)pProj)->numOfPKs; } if (pCol->isPk) ++numOfBoundPKs; } @@ -5115,10 +5117,16 @@ static int32_t translateInsertProject(STranslateContext* pCxt, SInsertStmt* pIns "Primary timestamp column should not be null"); } - if (numOfBoundPKs != numOfPKs) { + if (numOfBoundPKs != numOfTargetPKs) { return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, "Primary key column should not be none"); } + if (numOfTargetPKs < numOfSourcePKs) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, + "Target table has less primary keys:%" PRIi16 " than source:%" PRIi16, + numOfTargetPKs, numOfSourcePKs); + } + return addOrderByPrimaryKeyToQuery(pCxt, pPrimaryKeyExpr, pInsert->pQuery); } From cc660de9d0ec8160c69b5e1193c7798c39ec3371 Mon Sep 17 00:00:00 2001 From: kailixu Date: Wed, 3 Apr 2024 08:14:30 +0800 Subject: [PATCH 3/6] chore: error prompt for null primary key column --- source/libs/executor/src/dataInserter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/libs/executor/src/dataInserter.c b/source/libs/executor/src/dataInserter.c index 2d481bd273..dfe30c9f96 100644 --- a/source/libs/executor/src/dataInserter.c +++ b/source/libs/executor/src/dataInserter.c @@ -218,7 +218,7 @@ int32_t buildSubmitReqFromBlock(SDataInserterHandle* pInserter, SSubmitReq2** pp ASSERT(pColInfoData->info.type == pCol->type); if (colDataIsNull_s(pColInfoData, j)) { if ((pCol->flags & COL_IS_KEY)) { - qError("NULL value for primary key, colId:%" PRIi16 ", colType:%" PRIi8, pCol->colId, pCol->type); + qError("Primary key column should not be null, colId:%" PRIi16 ", colType:%" PRIi8, pCol->colId, pCol->type); terrno = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL; goto _end; } @@ -245,12 +245,12 @@ int32_t buildSubmitReqFromBlock(SDataInserterHandle* pInserter, SSubmitReq2** pp if (pColInfoData->info.type < TSDB_DATA_TYPE_MAX && pColInfoData->info.type > TSDB_DATA_TYPE_NULL) { if (colDataIsNull_s(pColInfoData, j)) { if (PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId) { - qError("NULL value for primary timestamp key"); + qError("Primary timestamp column should not be null"); terrno = TSDB_CODE_PAR_INCORRECT_TIMESTAMP_VAL; goto _end; } if ((pCol->flags & COL_IS_KEY)) { - qError("NULL value for primary key, colId:%" PRIi16 ", colType:%" PRIi8, pCol->colId, pCol->type); + qError("Primary key column should not be null, colId:%" PRIi16 ", colType:%" PRIi8, pCol->colId, pCol->type); terrno = TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL; goto _end; } From 62ab1b1c41a5e2436630ba29f0bfde6ca0a3845f Mon Sep 17 00:00:00 2001 From: kailixu Date: Wed, 3 Apr 2024 09:39:58 +0800 Subject: [PATCH 4/6] chore: allow source table with primary key --- source/libs/parser/src/parTranslater.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index b06a685c48..a45e4de4d8 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -5088,7 +5088,6 @@ static int32_t translateInsertProject(STranslateContext* pCxt, SInsertStmt* pIns SNode* pPrimaryKeyExpr = NULL; SNode* pBoundCol = NULL; SNode* pProj = NULL; - int16_t numOfSourcePKs = 0; int16_t numOfTargetPKs = 0; int16_t numOfBoundPKs = 0; FORBOTH(pBoundCol, pInsert->pCols, pProj, pProjects) { @@ -5107,7 +5106,6 @@ static int32_t translateInsertProject(STranslateContext* pCxt, SInsertStmt* pIns if (PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId) { pPrimaryKeyExpr = (SNode*)pExpr; numOfTargetPKs = pCol->numOfPKs; - numOfSourcePKs = ((SColumnNode*)pProj)->numOfPKs; } if (pCol->isPk) ++numOfBoundPKs; } @@ -5121,12 +5119,6 @@ static int32_t translateInsertProject(STranslateContext* pCxt, SInsertStmt* pIns return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, "Primary key column should not be none"); } - if (numOfTargetPKs < numOfSourcePKs) { - return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, - "Target table has less primary keys:%" PRIi16 " than source:%" PRIi16, - numOfTargetPKs, numOfSourcePKs); - } - return addOrderByPrimaryKeyToQuery(pCxt, pPrimaryKeyExpr, pInsert->pQuery); } From d4b8460baaceaa79d362d50c02d60669064b8e0f Mon Sep 17 00:00:00 2001 From: slzhou Date: Wed, 3 Apr 2024 15:48:56 +0800 Subject: [PATCH 5/6] fix: change delete condition error message --- source/libs/parser/src/parUtil.c | 2 +- source/util/src/terror.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index 7c82555e63..ce0d719594 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -161,7 +161,7 @@ static char* getSyntaxErrFormat(int32_t errCode) { case TSDB_CODE_PAR_VALUE_TOO_LONG: return "Value too long for column/tag: %s"; case TSDB_CODE_PAR_INVALID_DELETE_WHERE: - return "The DELETE statement must have a definite time window range"; + return "The DELETE statement must only have a definite time window range"; case TSDB_CODE_PAR_INVALID_REDISTRIBUTE_VG: return "The REDISTRIBUTE VGROUP statement only support 1 to 3 dnodes"; case TSDB_CODE_PAR_FILL_NOT_ALLOWED_FUNC: diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 99666320f1..64edb7faad 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -601,7 +601,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_PAR_NOT_ALLOWED_WIN_QUERY, "Window query not su TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_DROP_COL, "No columns can be dropped") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_COL_JSON, "Only tag can be json type") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_VALUE_TOO_LONG, "Value too long for column/tag") -TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_DELETE_WHERE, "The DELETE statement must have a definite time window range") +TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_DELETE_WHERE, "The DELETE statement must only have a definite time window range") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_REDISTRIBUTE_VG, "The REDISTRIBUTE VGROUP statement only support 1 to 3 dnodes") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_FILL_NOT_ALLOWED_FUNC, "Fill not allowed") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_WINDOW_PC, "Invalid windows pc") From 1e8aaa273e89bdd6c1d47cdd8f82fe88d69f2302 Mon Sep 17 00:00:00 2001 From: kailixu Date: Wed, 3 Apr 2024 16:32:59 +0800 Subject: [PATCH 6/6] chore: more logic for num of pks --- source/libs/nodes/src/nodesCloneFuncs.c | 1 + source/libs/nodes/src/nodesCodeFuncs.c | 9 ++++++++- source/libs/nodes/src/nodesMsgFuncs.c | 6 ++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index 3e4b3cad31..e07fe07252 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -121,6 +121,7 @@ static int32_t columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) { COPY_SCALAR_FIELD(slotId); COPY_SCALAR_FIELD(tableHasPk); COPY_SCALAR_FIELD(isPk); + COPY_SCALAR_FIELD(numOfPKs); return TSDB_CODE_SUCCESS; } diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index f000d87fdc..cdf23e512e 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -3618,6 +3618,7 @@ static const char* jkColumnDataBlockId = "DataBlockId"; static const char* jkColumnSlotId = "SlotId"; static const char* jkColumnTableHasPk = "TableHasPk"; static const char* jkColumnIsPk = "IsPk"; +static const char* jkColumnNumOfPKs = "NumOfPKs"; static int32_t columnNodeToJson(const void* pObj, SJson* pJson) { const SColumnNode* pNode = (const SColumnNode*)pObj; @@ -3662,6 +3663,9 @@ static int32_t columnNodeToJson(const void* pObj, SJson* pJson) { if (TSDB_CODE_SUCCESS == code) { code = tjsonAddBoolToObject(pJson, jkColumnIsPk, pNode->isPk); } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkColumnNumOfPKs, pNode->numOfPKs); + } return code; } @@ -3707,7 +3711,10 @@ static int32_t jsonToColumnNode(const SJson* pJson, void* pObj) { } if (TSDB_CODE_SUCCESS == code) { code = tjsonGetBoolValue(pJson, jkColumnIsPk, &pNode->isPk); - } + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetSmallIntValue(pJson, jkColumnNumOfPKs, &pNode->numOfPKs); + } return code; } diff --git a/source/libs/nodes/src/nodesMsgFuncs.c b/source/libs/nodes/src/nodesMsgFuncs.c index 0639a161bd..2cb2995a1d 100644 --- a/source/libs/nodes/src/nodesMsgFuncs.c +++ b/source/libs/nodes/src/nodesMsgFuncs.c @@ -731,6 +731,9 @@ static int32_t columnNodeInlineToMsg(const void* pObj, STlvEncoder* pEncoder) { if (TSDB_CODE_SUCCESS == code) { code = tlvEncodeValueBool(pEncoder, pNode->isPk); } + if (TSDB_CODE_SUCCESS == code) { + code = tlvEncodeValueI16(pEncoder, pNode->numOfPKs); + } return code; } @@ -778,6 +781,9 @@ static int32_t msgToColumnNodeInline(STlvDecoder* pDecoder, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = tlvDecodeValueBool(pDecoder, &pNode->isPk); } + if (TSDB_CODE_SUCCESS == code) { + code = tlvDecodeValueI16(pDecoder, &pNode->numOfPKs); + } return code; }