[td-3188]
This commit is contained in:
parent
af7ff7c87d
commit
778270f435
|
@ -1753,6 +1753,18 @@ static int32_t checkForUdf(SSqlObj* pSql, tSQLExprList* pSelection) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SUdfInfo* isValidUdf(SArray* pUdfInfo, const char* name, int32_t len) {
|
||||||
|
size_t t = taosArrayGetSize(pUdfInfo);
|
||||||
|
for(int32_t i = 0; i < t; ++i) {
|
||||||
|
SUdfInfo* pUdf = taosArrayGet(pUdfInfo, i);
|
||||||
|
if (strlen(pUdf->name) == len && strncasecmp(pUdf->name, name, len) == 0) {
|
||||||
|
return pUdf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery, bool timeWindowQuery) {
|
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery, bool timeWindowQuery) {
|
||||||
assert(pSelection != NULL && pCmd != NULL);
|
assert(pSelection != NULL && pCmd != NULL);
|
||||||
|
|
||||||
|
@ -1780,16 +1792,11 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
|
||||||
if (type == SQL_NODE_SQLFUNCTION) {
|
if (type == SQL_NODE_SQLFUNCTION) {
|
||||||
pItem->pNode->functionId = isValidFunction(pItem->pNode->operand.z, pItem->pNode->operand.n);
|
pItem->pNode->functionId = isValidFunction(pItem->pNode->operand.z, pItem->pNode->operand.n);
|
||||||
if (pItem->pNode->functionId < 0) {
|
if (pItem->pNode->functionId < 0) {
|
||||||
// extract all possible user defined function
|
SUdfInfo* pUdfInfo = isValidUdf(pCmd->pUdfInfo, pItem->pNode->operand.z, pItem->pNode->operand.n);
|
||||||
struct SUdfInfo info = {0};
|
if (pUdfInfo == NULL) {
|
||||||
memcpy(info.name, pItem->pNode->operand.z, pItem->pNode->operand.n);
|
|
||||||
if (pCmd->pUdfInfo == NULL) {
|
|
||||||
pCmd->pUdfInfo = taosArrayInit(4, sizeof(struct SUdfInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
taosArrayPush(pCmd->pUdfInfo, &info);
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// sql function in selection clause, append sql function info in pSqlCmd structure sequentially
|
// sql function in selection clause, append sql function info in pSqlCmd structure sequentially
|
||||||
if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, pItem, true) != TSDB_CODE_SUCCESS) {
|
if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, pItem, true) != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -2641,10 +2648,50 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default: {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
SUdfInfo* pUdfInfo = isValidUdf(pCmd->pUdfInfo, pItem->pNode->operand.z, pItem->pNode->operand.n);
|
||||||
|
|
||||||
|
tSqlExprItem* pParamElem = &(pItem->pNode->pParam->a[0]);
|
||||||
|
if (pParamElem->pNode->tokenId != TK_ID) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||||
|
if (getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
|
||||||
|
}
|
||||||
|
|
||||||
|
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
|
||||||
|
|
||||||
|
// functions can not be applied to tags
|
||||||
|
if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
|
||||||
|
}
|
||||||
|
|
||||||
|
SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, pUdfInfo->resType, pUdfInfo->resBytes,
|
||||||
|
getNewResColId(pQueryInfo), pUdfInfo->resBytes, false);
|
||||||
|
|
||||||
|
memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
|
||||||
|
getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1);
|
||||||
|
|
||||||
|
SColumnList ids = getColumnList(1, 0, index.columnIndex);
|
||||||
|
if (finalResult) {
|
||||||
|
insertResultField(pQueryInfo, colIndex, &ids, pUdfInfo->resBytes, pUdfInfo->resType, pExpr->aliasName, pExpr);
|
||||||
|
} else {
|
||||||
|
for (int32_t i = 0; i < ids.num; ++i) {
|
||||||
|
tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo refactor
|
// todo refactor
|
||||||
|
|
|
@ -758,6 +758,12 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pQueryMsg->sw.gap = htobe64(pQueryInfo->sessionWindow.gap);
|
pQueryMsg->sw.gap = htobe64(pQueryInfo->sessionWindow.gap);
|
||||||
pQueryMsg->sw.primaryColId = htonl(PRIMARYKEY_TIMESTAMP_COL_INDEX);
|
pQueryMsg->sw.primaryColId = htonl(PRIMARYKEY_TIMESTAMP_COL_INDEX);
|
||||||
|
|
||||||
|
if (pCmd->pUdfInfo != NULL) {
|
||||||
|
pQueryMsg->udfNum = htonl((uint32_t) taosArrayGetSize(pCmd->pUdfInfo));
|
||||||
|
} else {
|
||||||
|
pQueryMsg->udfNum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
pQueryMsg->numOfOutput = htons((int16_t)numOfOutput); // this is the stage one output column number
|
pQueryMsg->numOfOutput = htons((int16_t)numOfOutput); // this is the stage one output column number
|
||||||
|
|
||||||
|
@ -1056,6 +1062,23 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pQueryMsg->tsNumOfBlocks = htonl(pQueryMsg->tsNumOfBlocks);
|
pQueryMsg->tsNumOfBlocks = htonl(pQueryMsg->tsNumOfBlocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// support only one udf
|
||||||
|
if (pCmd->pUdfInfo != NULL) {
|
||||||
|
assert(taosArrayGetSize(pCmd->pUdfInfo) == 1);
|
||||||
|
|
||||||
|
pQueryMsg->udfContentOffset = htonl((int32_t) (pMsg - pCmd->payload));
|
||||||
|
for(int32_t i = 0; i < taosArrayGetSize(pCmd->pUdfInfo); ++i) {
|
||||||
|
SUdfInfo* pUdfInfo = taosArrayGet(pCmd->pUdfInfo, i);
|
||||||
|
STR_TO_VARSTR(pMsg, pUdfInfo->name);
|
||||||
|
|
||||||
|
pMsg += varDataTLen(pMsg);
|
||||||
|
pQueryMsg->udfContentLen = htonl(pUdfInfo->contLen);
|
||||||
|
memcpy(pMsg, pUdfInfo->content, pUdfInfo->contLen);
|
||||||
|
|
||||||
|
pMsg += pUdfInfo->contLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(pMsg, pSql->sqlstr, sqlLen);
|
memcpy(pMsg, pSql->sqlstr, sqlLen);
|
||||||
pMsg += sqlLen;
|
pMsg += sqlLen;
|
||||||
|
|
||||||
|
@ -2103,8 +2126,8 @@ int tscProcessRetrieveFuncRsp(SSqlObj* pSql) {
|
||||||
info.resType = htons(pFunc->resType);
|
info.resType = htons(pFunc->resType);
|
||||||
info.funcType = TSDB_UDF_TYPE_SCALAR;
|
info.funcType = TSDB_UDF_TYPE_SCALAR;
|
||||||
|
|
||||||
info.contLen = htons(pFunc->contentLen);
|
info.contLen = htonl(pFunc->len);
|
||||||
info.content = malloc(pFunc->contentLen);
|
info.content = malloc(pFunc->len);
|
||||||
memcpy(info.content, pFunc->content, info.contLen);
|
memcpy(info.content, pFunc->content, info.contLen);
|
||||||
|
|
||||||
taosArrayPush(pCmd->pUdfInfo, &info);
|
taosArrayPush(pCmd->pUdfInfo, &info);
|
||||||
|
|
|
@ -511,6 +511,9 @@ typedef struct {
|
||||||
int32_t numOfTags; // number of tags columns involved
|
int32_t numOfTags; // number of tags columns involved
|
||||||
int32_t sqlstrLen; // sql query string
|
int32_t sqlstrLen; // sql query string
|
||||||
int32_t prevResultLen; // previous result length
|
int32_t prevResultLen; // previous result length
|
||||||
|
int32_t udfNum; // number of udf function
|
||||||
|
int32_t udfContentOffset;
|
||||||
|
int32_t udfContentLen;
|
||||||
SColumnInfo colList[];
|
SColumnInfo colList[];
|
||||||
} SQueryTableMsg;
|
} SQueryTableMsg;
|
||||||
|
|
||||||
|
@ -592,7 +595,7 @@ typedef struct {
|
||||||
char name[TSDB_FUNC_NAME_LEN];
|
char name[TSDB_FUNC_NAME_LEN];
|
||||||
int16_t resType;
|
int16_t resType;
|
||||||
int16_t resBytes;
|
int16_t resBytes;
|
||||||
int16_t contentLen;
|
int32_t len;
|
||||||
char content[];
|
char content[];
|
||||||
} SFunctionInfoMsg;
|
} SFunctionInfoMsg;
|
||||||
|
|
||||||
|
|
|
@ -216,12 +216,14 @@ typedef struct SUserObj {
|
||||||
|
|
||||||
typedef struct SFuncObj {
|
typedef struct SFuncObj {
|
||||||
char name[TSDB_FUNC_NAME_LEN];
|
char name[TSDB_FUNC_NAME_LEN];
|
||||||
char path[PATH_MAX];
|
char path[128];
|
||||||
int32_t codeLen;
|
int32_t contLen;
|
||||||
char code[TSDB_FUNC_CODE_LEN];
|
char cont[TSDB_FUNC_CODE_LEN];
|
||||||
int64_t createdTime;
|
int64_t createdTime;
|
||||||
uint8_t outputType;
|
uint8_t resType;
|
||||||
int16_t outputLen;
|
int16_t resBytes;
|
||||||
|
int64_t sig; // partial md5 sign
|
||||||
|
int16_t type; // [lua script|so|js]
|
||||||
int8_t reserved[64];
|
int8_t reserved[64];
|
||||||
int8_t updateEnd[4];
|
int8_t updateEnd[4];
|
||||||
int32_t refCount;
|
int32_t refCount;
|
||||||
|
|
|
@ -52,7 +52,7 @@ static int32_t mnodeFuncActionDestroy(SSdbRow *pRow) {
|
||||||
static int32_t mnodeFuncActionInsert(SSdbRow *pRow) {
|
static int32_t mnodeFuncActionInsert(SSdbRow *pRow) {
|
||||||
SFuncObj *pFunc = pRow->pObj;
|
SFuncObj *pFunc = pRow->pObj;
|
||||||
|
|
||||||
mTrace("func:%s, length: %d, insert into sdb", pFunc->name, pFunc->codeLen);
|
mTrace("func:%s, contLen: %d, insert into sdb", pFunc->name, pFunc->contLen);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ static int32_t mnodeFuncActionInsert(SSdbRow *pRow) {
|
||||||
static int32_t mnodeFuncActionDelete(SSdbRow *pRow) {
|
static int32_t mnodeFuncActionDelete(SSdbRow *pRow) {
|
||||||
SFuncObj *pFunc = pRow->pObj;
|
SFuncObj *pFunc = pRow->pObj;
|
||||||
|
|
||||||
mTrace("func:%s, length: %d, delete from sdb", pFunc->name, pFunc->codeLen);
|
mTrace("func:%s, length: %d, delete from sdb", pFunc->name, pFunc->contLen);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -73,8 +73,8 @@ static int32_t mnodeFuncActionUpdate(SSdbRow *pRow) {
|
||||||
memcpy(pSaved, pFunc, tsFuncUpdateSize);
|
memcpy(pSaved, pFunc, tsFuncUpdateSize);
|
||||||
free(pFunc);
|
free(pFunc);
|
||||||
}
|
}
|
||||||
mnodeDecFuncRef(pSaved);
|
|
||||||
|
|
||||||
|
mnodeDecFuncRef(pSaved);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,12 +230,14 @@ int32_t mnodeCreateFunc(SAcctObj *pAcct, char *name, int32_t codeLen, char *code
|
||||||
|
|
||||||
pFunc = calloc(1, sizeof(SFuncObj));
|
pFunc = calloc(1, sizeof(SFuncObj));
|
||||||
tstrncpy(pFunc->name, name, TSDB_FUNC_NAME_LEN);
|
tstrncpy(pFunc->name, name, TSDB_FUNC_NAME_LEN);
|
||||||
tstrncpy(pFunc->path, path, PATH_MAX);
|
tstrncpy(pFunc->path, path, tListLen(pFunc->path));
|
||||||
tstrncpy(pFunc->code, codeScript, TSDB_FUNC_CODE_LEN);
|
tstrncpy(pFunc->cont, codeScript, codeLen);
|
||||||
pFunc->codeLen = codeLen;
|
pFunc->contLen = codeLen;
|
||||||
pFunc->createdTime = taosGetTimestampMs();
|
pFunc->createdTime = taosGetTimestampMs();
|
||||||
pFunc->outputType = outputType;
|
pFunc->resType = outputType;
|
||||||
pFunc->outputLen = outputLen;
|
pFunc->resBytes = outputLen;
|
||||||
|
pFunc->sig = 0;
|
||||||
|
pFunc->type = 1; //lua script, refactor
|
||||||
|
|
||||||
SSdbRow row = {
|
SSdbRow row = {
|
||||||
.type = SDB_OPER_GLOBAL,
|
.type = SDB_OPER_GLOBAL,
|
||||||
|
@ -380,7 +382,7 @@ static int32_t mnodeRetrieveFuncs(SShowObj *pShow, char *data, int32_t rows, voi
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, mnodeGenTypeStr(buf, TSDB_TYPE_STR_MAX_LEN, pFunc->outputType, pFunc->outputLen), pShow->bytes[cols]);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, mnodeGenTypeStr(buf, TSDB_TYPE_STR_MAX_LEN, pFunc->resType, pFunc->resBytes), pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
@ -388,11 +390,11 @@ static int32_t mnodeRetrieveFuncs(SShowObj *pShow, char *data, int32_t rows, voi
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
*(int32_t *)pWrite = pFunc->codeLen;
|
*(int32_t *)pWrite = pFunc->contLen;
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pFunc->code, pShow->bytes[cols]);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pFunc->cont, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
numOfRows++;
|
numOfRows++;
|
||||||
|
@ -442,9 +444,11 @@ static int32_t mnodeProcessRetrieveFuncImplMsg(SMnodeMsg *pMsg) {
|
||||||
SFunctionInfoMsg* pFuncInfo = (SFunctionInfoMsg*) pOutput;
|
SFunctionInfoMsg* pFuncInfo = (SFunctionInfoMsg*) pOutput;
|
||||||
|
|
||||||
strcpy(pFuncInfo->name, buf);
|
strcpy(pFuncInfo->name, buf);
|
||||||
pFuncInfo->contentLen = htonl(pFuncObj->codeLen);
|
pFuncInfo->len = htonl(pFuncObj->contLen);
|
||||||
pFuncInfo->resType = htons(pFuncObj->outputType);
|
memcpy(pFuncInfo->content, pFuncObj->cont, pFuncObj->contLen);
|
||||||
pOutput += sizeof(SFunctionInfoMsg) + pFuncObj->codeLen;
|
|
||||||
|
pFuncInfo->resType = htons(pFuncObj->resType);
|
||||||
|
pOutput += sizeof(SFunctionInfoMsg) + pFuncObj->contLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMsg->rpcRsp.rsp = pFuncMsg;
|
pMsg->rpcRsp.rsp = pFuncMsg;
|
||||||
|
|
Loading…
Reference in New Issue