feat:[TS-4893] Support MYSQL functions.

Add more functions:
 - Numeric Functions: PI(),ROUND(),TRUNC(),EXP(),LN(),SIGN(),DEGREES(),RADIANS().
 - String Functions: CHAR(),ASCII(),POSITION(),TRIM(),REPLACE(),REPEAT().
 - Date and Time Functions: WEEKDAY(),DAYOFWEEK(),WEEK(),WEEKOFYEAR().
 - Aggregate Functions: VAR_POP().
Modify some functions:
 - ROUND(): support round to given decimal places.
 - CHAR_LENGTH(): support calculate multi-byte character's length.
 - TIMEDIFF(): result will be negative when expr1 < expr2.
 - STDDEV(): add alias name STDDEV_POP().
 - SUBSTR(): add alias name SUBSTRING().
             support new syntax SUBSTRING/SUBSTR(expr FROM pos [FOR len]).
This commit is contained in:
sima 2024-07-31 14:42:38 +08:00
parent 264bfe3f28
commit a54019211f
26 changed files with 9290 additions and 7790 deletions

View File

@ -281,118 +281,125 @@
#define TK_IROWTS 263 #define TK_IROWTS 263
#define TK_ISFILLED 264 #define TK_ISFILLED 264
#define TK_CAST 265 #define TK_CAST 265
#define TK_NOW 266 #define TK_POSITION 266
#define TK_TODAY 267 #define TK_IN 267
#define TK_TIMEZONE 268 #define TK_FOR 268
#define TK_CLIENT_VERSION 269 #define TK_NOW 269
#define TK_SERVER_VERSION 270 #define TK_TODAY 270
#define TK_SERVER_STATUS 271 #define TK_SUBSTR 271
#define TK_CURRENT_USER 272 #define TK_SUBSTRING 272
#define TK_CASE 273 #define TK_BOTH 273
#define TK_WHEN 274 #define TK_TRAILING 274
#define TK_THEN 275 #define TK_LEADING 275
#define TK_ELSE 276 #define TK_TIMEZONE 276
#define TK_BETWEEN 277 #define TK_CLIENT_VERSION 277
#define TK_IS 278 #define TK_SERVER_VERSION 278
#define TK_NK_LT 279 #define TK_SERVER_STATUS 279
#define TK_NK_GT 280 #define TK_CURRENT_USER 280
#define TK_NK_LE 281 #define TK_PI 281
#define TK_NK_GE 282 #define TK_CASE 282
#define TK_NK_NE 283 #define TK_WHEN 283
#define TK_MATCH 284 #define TK_THEN 284
#define TK_NMATCH 285 #define TK_ELSE 285
#define TK_CONTAINS 286 #define TK_BETWEEN 286
#define TK_IN 287 #define TK_IS 287
#define TK_JOIN 288 #define TK_NK_LT 288
#define TK_INNER 289 #define TK_NK_GT 289
#define TK_LEFT 290 #define TK_NK_LE 290
#define TK_RIGHT 291 #define TK_NK_GE 291
#define TK_OUTER 292 #define TK_NK_NE 292
#define TK_SEMI 293 #define TK_MATCH 293
#define TK_ANTI 294 #define TK_NMATCH 294
#define TK_ASOF 295 #define TK_CONTAINS 295
#define TK_WINDOW 296 #define TK_JOIN 296
#define TK_WINDOW_OFFSET 297 #define TK_INNER 297
#define TK_JLIMIT 298 #define TK_LEFT 298
#define TK_SELECT 299 #define TK_RIGHT 299
#define TK_NK_HINT 300 #define TK_OUTER 300
#define TK_DISTINCT 301 #define TK_SEMI 301
#define TK_WHERE 302 #define TK_ANTI 302
#define TK_PARTITION 303 #define TK_ASOF 303
#define TK_BY 304 #define TK_WINDOW 304
#define TK_SESSION 305 #define TK_WINDOW_OFFSET 305
#define TK_STATE_WINDOW 306 #define TK_JLIMIT 306
#define TK_EVENT_WINDOW 307 #define TK_SELECT 307
#define TK_COUNT_WINDOW 308 #define TK_NK_HINT 308
#define TK_SLIDING 309 #define TK_DISTINCT 309
#define TK_FILL 310 #define TK_WHERE 310
#define TK_VALUE 311 #define TK_PARTITION 311
#define TK_VALUE_F 312 #define TK_BY 312
#define TK_NONE 313 #define TK_SESSION 313
#define TK_PREV 314 #define TK_STATE_WINDOW 314
#define TK_NULL_F 315 #define TK_EVENT_WINDOW 315
#define TK_LINEAR 316 #define TK_COUNT_WINDOW 316
#define TK_NEXT 317 #define TK_SLIDING 317
#define TK_HAVING 318 #define TK_FILL 318
#define TK_RANGE 319 #define TK_VALUE 319
#define TK_EVERY 320 #define TK_VALUE_F 320
#define TK_ORDER 321 #define TK_NONE 321
#define TK_SLIMIT 322 #define TK_PREV 322
#define TK_SOFFSET 323 #define TK_NULL_F 323
#define TK_LIMIT 324 #define TK_LINEAR 324
#define TK_OFFSET 325 #define TK_NEXT 325
#define TK_ASC 326 #define TK_HAVING 326
#define TK_NULLS 327 #define TK_RANGE 327
#define TK_ABORT 328 #define TK_EVERY 328
#define TK_AFTER 329 #define TK_ORDER 329
#define TK_ATTACH 330 #define TK_SLIMIT 330
#define TK_BEFORE 331 #define TK_SOFFSET 331
#define TK_BEGIN 332 #define TK_LIMIT 332
#define TK_BITAND 333 #define TK_OFFSET 333
#define TK_BITNOT 334 #define TK_ASC 334
#define TK_BITOR 335 #define TK_NULLS 335
#define TK_BLOCKS 336 #define TK_ABORT 336
#define TK_CHANGE 337 #define TK_AFTER 337
#define TK_COMMA 338 #define TK_ATTACH 338
#define TK_CONCAT 339 #define TK_BEFORE 339
#define TK_CONFLICT 340 #define TK_BEGIN 340
#define TK_COPY 341 #define TK_BITAND 341
#define TK_DEFERRED 342 #define TK_BITNOT 342
#define TK_DELIMITERS 343 #define TK_BITOR 343
#define TK_DETACH 344 #define TK_BLOCKS 344
#define TK_DIVIDE 345 #define TK_CHANGE 345
#define TK_DOT 346 #define TK_COMMA 346
#define TK_EACH 347 #define TK_CONCAT 347
#define TK_FAIL 348 #define TK_CONFLICT 348
#define TK_FOR 349 #define TK_COPY 349
#define TK_GLOB 350 #define TK_DEFERRED 350
#define TK_ID 351 #define TK_DELIMITERS 351
#define TK_IMMEDIATE 352 #define TK_DETACH 352
#define TK_IMPORT 353 #define TK_DIVIDE 353
#define TK_INITIALLY 354 #define TK_DOT 354
#define TK_INSTEAD 355 #define TK_EACH 355
#define TK_ISNULL 356 #define TK_FAIL 356
#define TK_MODULES 357 #define TK_GLOB 357
#define TK_NK_BITNOT 358 #define TK_ID 358
#define TK_NK_SEMI 359 #define TK_IMMEDIATE 359
#define TK_NOTNULL 360 #define TK_IMPORT 360
#define TK_OF 361 #define TK_INITIALLY 361
#define TK_PLUS 362 #define TK_INSTEAD 362
#define TK_PRIVILEGE 363 #define TK_ISNULL 363
#define TK_RAISE 364 #define TK_MODULES 364
#define TK_RESTRICT 365 #define TK_NK_BITNOT 365
#define TK_ROW 366 #define TK_NK_SEMI 366
#define TK_STAR 367 #define TK_NOTNULL 367
#define TK_STATEMENT 368 #define TK_OF 368
#define TK_STRICT 369 #define TK_PLUS 369
#define TK_STRING 370 #define TK_PRIVILEGE 370
#define TK_TIMES 371 #define TK_RAISE 371
#define TK_VALUES 372 #define TK_RESTRICT 372
#define TK_VARIABLE 373 #define TK_ROW 373
#define TK_WAL 374 #define TK_STAR 374
#define TK_ENCODE 375 #define TK_STATEMENT 375
#define TK_COMPRESS 376 #define TK_STRICT 376
#define TK_LEVEL 377 #define TK_STRING 377
#define TK_TIMES 378
#define TK_VALUES 379
#define TK_VARIABLE 380
#define TK_WAL 381
#define TK_ENCODE 382
#define TK_COMPRESS 383
#define TK_LEVEL 384
#define TK_NK_SPACE 600 #define TK_NK_SPACE 600
#define TK_NK_COMMENT 601 #define TK_NK_COMMENT 601

View File

@ -45,6 +45,7 @@ typedef enum EFunctionType {
FUNCTION_TYPE_TWA, FUNCTION_TYPE_TWA,
FUNCTION_TYPE_HISTOGRAM, FUNCTION_TYPE_HISTOGRAM,
FUNCTION_TYPE_HYPERLOGLOG, FUNCTION_TYPE_HYPERLOGLOG,
FUNCTION_TYPE_STDVAR,
// nonstandard SQL function // nonstandard SQL function
FUNCTION_TYPE_BOTTOM = 500, FUNCTION_TYPE_BOTTOM = 500,
@ -77,6 +78,15 @@ typedef enum EFunctionType {
FUNCTION_TYPE_ASIN, FUNCTION_TYPE_ASIN,
FUNCTION_TYPE_ACOS, FUNCTION_TYPE_ACOS,
FUNCTION_TYPE_ATAN, FUNCTION_TYPE_ATAN,
FUNCTION_TYPE_PI,
FUNCTION_TYPE_EXP,
FUNCTION_TYPE_LN,
FUNCTION_TYPE_MOD,
FUNCTION_TYPE_RAND,
FUNCTION_TYPE_SIGN,
FUNCTION_TYPE_DEGREES,
FUNCTION_TYPE_RADIANS,
FUNCTION_TYPE_TRUNCATE,
// string function // string function
FUNCTION_TYPE_LENGTH = 1500, FUNCTION_TYPE_LENGTH = 1500,
@ -89,6 +99,13 @@ typedef enum EFunctionType {
FUNCTION_TYPE_RTRIM, FUNCTION_TYPE_RTRIM,
FUNCTION_TYPE_SUBSTR, FUNCTION_TYPE_SUBSTR,
FUNCTION_TYPE_MD5, FUNCTION_TYPE_MD5,
FUNCTION_TYPE_CHAR,
FUNCTION_TYPE_ASCII,
FUNCTION_TYPE_POSITION,
FUNCTION_TYPE_TRIM,
FUNCTION_TYPE_REPLACE,
FUNCTION_TYPE_REPEAT,
FUNCTION_TYPE_SUBSTR_IDX,
// conversion function // conversion function
FUNCTION_TYPE_CAST = 2000, FUNCTION_TYPE_CAST = 2000,
@ -104,6 +121,10 @@ typedef enum EFunctionType {
FUNCTION_TYPE_TIMETRUNCATE, FUNCTION_TYPE_TIMETRUNCATE,
FUNCTION_TYPE_TIMEZONE, FUNCTION_TYPE_TIMEZONE,
FUNCTION_TYPE_TODAY, FUNCTION_TYPE_TODAY,
FUNCTION_TYPE_WEEK,
FUNCTION_TYPE_WEEKDAY,
FUNCTION_TYPE_WEEKOFYEAR,
FUNCTION_TYPE_DAYOFWEEK,
// system function // system function
FUNCTION_TYPE_DATABASE = 3000, FUNCTION_TYPE_DATABASE = 3000,
@ -162,8 +183,9 @@ typedef enum EFunctionType {
FUNCTION_TYPE_LAST_MERGE, FUNCTION_TYPE_LAST_MERGE,
FUNCTION_TYPE_AVG_PARTIAL, FUNCTION_TYPE_AVG_PARTIAL,
FUNCTION_TYPE_AVG_MERGE, FUNCTION_TYPE_AVG_MERGE,
FUNCTION_TYPE_STDDEV_PARTIAL, FUNCTION_TYPE_STD_PARTIAL,
FUNCTION_TYPE_STDDEV_MERGE, FUNCTION_TYPE_STDDEV_MERGE,
FUNCTION_TYPE_STDVAR_MERGE,
FUNCTION_TYPE_IRATE_PARTIAL, FUNCTION_TYPE_IRATE_PARTIAL,
FUNCTION_TYPE_IRATE_MERGE, FUNCTION_TYPE_IRATE_MERGE,
FUNCTION_TYPE_AVG_STATE, FUNCTION_TYPE_AVG_STATE,
@ -174,8 +196,8 @@ typedef enum EFunctionType {
FUNCTION_TYPE_LAST_STATE_MERGE, FUNCTION_TYPE_LAST_STATE_MERGE,
FUNCTION_TYPE_SPREAD_STATE, FUNCTION_TYPE_SPREAD_STATE,
FUNCTION_TYPE_SPREAD_STATE_MERGE, FUNCTION_TYPE_SPREAD_STATE_MERGE,
FUNCTION_TYPE_STDDEV_STATE, FUNCTION_TYPE_STD_STATE,
FUNCTION_TYPE_STDDEV_STATE_MERGE, FUNCTION_TYPE_STD_STATE_MERGE,
FUNCTION_TYPE_HYPERLOGLOG_STATE, FUNCTION_TYPE_HYPERLOGLOG_STATE,
FUNCTION_TYPE_HYPERLOGLOG_STATE_MERGE, FUNCTION_TYPE_HYPERLOGLOG_STATE_MERGE,

View File

@ -170,6 +170,12 @@ typedef struct SNodeListNode {
SNodeList* pNodeList; SNodeList* pNodeList;
} SNodeListNode; } SNodeListNode;
typedef enum ETrimType {
TRIM_TYPE_LEADING = 1,
TRIM_TYPE_TRAILING,
TRIM_TYPE_BOTH,
} ETrimType;
typedef struct SFunctionNode { typedef struct SFunctionNode {
SExprNode node; // QUERY_NODE_FUNCTION SExprNode node; // QUERY_NODE_FUNCTION
char functionName[TSDB_FUNC_NAME_LEN]; char functionName[TSDB_FUNC_NAME_LEN];
@ -181,6 +187,7 @@ typedef struct SFunctionNode {
int32_t pkBytes; int32_t pkBytes;
bool hasOriginalFunc; bool hasOriginalFunc;
int32_t originalFuncId; int32_t originalFuncId;
ETrimType trimType;
} SFunctionNode; } SFunctionNode;
typedef struct STableNode { typedef struct STableNode {

View File

@ -61,6 +61,15 @@ int32_t atanFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
int32_t ceilFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t ceilFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t floorFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t floorFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t roundFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t roundFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t truncFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t piFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t expFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t lnFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t modFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t signFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t degreesFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t radiansFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
/* String functions */ /* String functions */
int32_t lengthFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t lengthFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
@ -73,6 +82,13 @@ int32_t ltrimFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOut
int32_t rtrimFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t rtrimFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t substrFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t substrFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t md5Function(SScalarParam* pInput, int32_t inputNum, SScalarParam* pOutput); int32_t md5Function(SScalarParam* pInput, int32_t inputNum, SScalarParam* pOutput);
int32_t charFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t asciiFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t positionFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t trimFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t replaceFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t repeatFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t substrIdxFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
/* Conversion functions */ /* Conversion functions */
int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
@ -89,6 +105,10 @@ int32_t timeDiffFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *p
int32_t nowFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t nowFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t todayFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t todayFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t timezoneFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t timezoneFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t weekdayFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t dayofweekFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t weekFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t weekofyearFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
bool getTimePseudoFuncEnv(struct SFunctionNode *pFunc, SFuncExecEnv *pEnv); bool getTimePseudoFuncEnv(struct SFunctionNode *pFunc, SFuncExecEnv *pEnv);
@ -106,7 +126,7 @@ int32_t sumScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *
int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t maxScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t maxScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t avgScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t avgScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t stddevScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t stdScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t leastSQRScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t leastSQRScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t percentileScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t percentileScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t apercentileScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t apercentileScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);

View File

@ -877,6 +877,7 @@ int32_t taosGetErrSize();
#define TSDB_CODE_FUNC_TIME_UNIT_TOO_SMALL TAOS_DEF_ERROR_CODE(0, 0x280B) #define TSDB_CODE_FUNC_TIME_UNIT_TOO_SMALL TAOS_DEF_ERROR_CODE(0, 0x280B)
#define TSDB_CODE_FUNC_INVALID_VALUE_RANGE TAOS_DEF_ERROR_CODE(0, 0x280C) #define TSDB_CODE_FUNC_INVALID_VALUE_RANGE TAOS_DEF_ERROR_CODE(0, 0x280C)
#define TSDB_CODE_FUNC_SETUP_ERROR TAOS_DEF_ERROR_CODE(0, 0x280D) #define TSDB_CODE_FUNC_SETUP_ERROR TAOS_DEF_ERROR_CODE(0, 0x280D)
#define TSDB_CODE_FUNC_INVALID_RES_LENGTH TAOS_DEF_ERROR_CODE(0, 0x280E)
//udf //udf

File diff suppressed because one or more lines are too long

View File

@ -96,19 +96,20 @@ int32_t avgInvertFunction(SqlFunctionCtx* pCtx);
int32_t avgCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx); int32_t avgCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
int32_t getAvgInfoSize(); int32_t getAvgInfoSize();
bool getStddevFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv); bool getStdFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
int32_t stddevFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo); int32_t stdFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo);
int32_t stddevFunction(SqlFunctionCtx* pCtx); int32_t stdFunction(SqlFunctionCtx* pCtx);
int32_t stddevFunctionMerge(SqlFunctionCtx* pCtx); int32_t stdFunctionMerge(SqlFunctionCtx* pCtx);
int32_t stddevFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); int32_t stddevFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
int32_t stddevPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); int32_t stdvarFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
int32_t stdPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
#ifdef BUILD_NO_CALL #ifdef BUILD_NO_CALL
int32_t stddevInvertFunction(SqlFunctionCtx* pCtx); int32_t stdInvertFunction(SqlFunctionCtx* pCtx);
#endif #endif
int32_t stddevCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx); int32_t stdCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
int32_t getStddevInfoSize(); int32_t getStdInfoSize();
bool getLeastSQRFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv); bool getLeastSQRFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
int32_t leastSQRFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo); int32_t leastSQRFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo);

View File

@ -247,7 +247,7 @@ static int32_t addTimezoneParam(SNodeList* pList) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t addDbPrecisonParam(SNodeList** pList, uint8_t precision) { static int32_t addUint8Param(SNodeList** pList, uint8_t param) {
SValueNode* pVal = NULL; SValueNode* pVal = NULL;
int32_t code = nodesMakeNode(QUERY_NODE_VALUE, (SNode**)&pVal); int32_t code = nodesMakeNode(QUERY_NODE_VALUE, (SNode**)&pVal);
if (pVal == NULL) { if (pVal == NULL) {
@ -259,9 +259,9 @@ static int32_t addDbPrecisonParam(SNodeList** pList, uint8_t precision) {
pVal->notReserved = true; pVal->notReserved = true;
pVal->node.resType.type = TSDB_DATA_TYPE_TINYINT; pVal->node.resType.type = TSDB_DATA_TYPE_TINYINT;
pVal->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_TINYINT].bytes; pVal->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_TINYINT].bytes;
pVal->node.resType.precision = precision; pVal->node.resType.precision = param;
pVal->datum.i = (int64_t)precision; pVal->datum.i = (int64_t)param;
pVal->typeData = (int64_t)precision; pVal->typeData = (int64_t)param;
code = nodesListMakeAppend(pList, (SNode*)pVal); code = nodesListMakeAppend(pList, (SNode*)pVal);
if (TSDB_CODE_SUCCESS != code) { if (TSDB_CODE_SUCCESS != code) {
@ -493,7 +493,7 @@ static int32_t translateAvgStateMerge(SFunctionNode* pFunc, char* pErrBuf, int32
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t translateStddevPartial(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { static int32_t translateStdPartial(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (1 != LIST_LENGTH(pFunc->pParameterList)) { if (1 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
} }
@ -503,11 +503,11 @@ static int32_t translateStddevPartial(SFunctionNode* pFunc, char* pErrBuf, int32
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
} }
pFunc->node.resType = (SDataType){.bytes = getStddevInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; pFunc->node.resType = (SDataType){.bytes = getStdInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t translateStddevMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { static int32_t translateStdMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (1 != LIST_LENGTH(pFunc->pParameterList)) { if (1 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
} }
@ -522,7 +522,7 @@ static int32_t translateStddevMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t translateStddevState(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { static int32_t translateStdState(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (1 != LIST_LENGTH(pFunc->pParameterList)) { if (1 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
} }
@ -532,11 +532,11 @@ static int32_t translateStddevState(SFunctionNode* pFunc, char* pErrBuf, int32_t
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
} }
pFunc->node.resType = (SDataType){.bytes = getStddevInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; pFunc->node.resType = (SDataType){.bytes = getStdInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t translateStddevStateMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { static int32_t translateStdStateMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (1 != LIST_LENGTH(pFunc->pParameterList)) { if (1 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
} }
@ -546,7 +546,7 @@ static int32_t translateStddevStateMerge(SFunctionNode* pFunc, char* pErrBuf, in
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
} }
pFunc->node.resType = (SDataType){.bytes = getStddevInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY}; pFunc->node.resType = (SDataType){.bytes = getStdInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -563,7 +563,7 @@ static int32_t translateNowToday(SFunctionNode* pFunc, char* pErrBuf, int32_t le
// add database precision as param // add database precision as param
uint8_t dbPrec = pFunc->node.resType.precision; uint8_t dbPrec = pFunc->node.resType.precision;
int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); int32_t code = addUint8Param(&pFunc->pParameterList, dbPrec);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
@ -573,6 +573,53 @@ static int32_t translateNowToday(SFunctionNode* pFunc, char* pErrBuf, int32_t le
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t translatePi(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
pFunc->node.resType =
(SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes, .type = TSDB_DATA_TYPE_DOUBLE};
return TSDB_CODE_SUCCESS;
}
static int32_t translateRound(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (2 != LIST_LENGTH(pFunc->pParameterList) && 1 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
} else if (IS_NULL_TYPE(paraType)) {
paraType = TSDB_DATA_TYPE_BIGINT;
}
if (2 == LIST_LENGTH(pFunc->pParameterList)) {
uint8_t paraType2 = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
if (!IS_NUMERIC_TYPE(paraType2) && !IS_NULL_TYPE(paraType2)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
}
pFunc->node.resType = (SDataType){.bytes = tDataTypes[paraType].bytes, .type = paraType};
return TSDB_CODE_SUCCESS;
}
static int32_t translateTrunc(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (2 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
if (!IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t paraType2 = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
if (!IS_NUMERIC_TYPE(paraType2) && !IS_NULL_TYPE(paraType2)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
pFunc->node.resType = (SDataType){.bytes = tDataTypes[paraType].bytes, .type = paraType};
return TSDB_CODE_SUCCESS;
}
static int32_t translateTimePseudoColumn(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { static int32_t translateTimePseudoColumn(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
// pseudo column do not need to check parameters // pseudo column do not need to check parameters
@ -1745,7 +1792,7 @@ static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
// add database precision as param // add database precision as param
uint8_t dbPrec = pFunc->node.resType.precision; uint8_t dbPrec = pFunc->node.resType.precision;
int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); int32_t code = addUint8Param(&pFunc->pParameterList, dbPrec);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
@ -1776,7 +1823,7 @@ static int32_t translateIrateImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t l
// add database precision as param // add database precision as param
uint8_t dbPrec = pFunc->node.resType.precision; uint8_t dbPrec = pFunc->node.resType.precision;
int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); int32_t code = addUint8Param(&pFunc->pParameterList, dbPrec);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
@ -2032,7 +2079,22 @@ static int32_t translateLength(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
} }
if (!IS_STR_DATA_TYPE(getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type)) { uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
if (!IS_STR_DATA_TYPE(paraType) && !IS_NULL_TYPE(paraType)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT};
return TSDB_CODE_SUCCESS;
}
static int32_t translateCharLength(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
if (paraType == TSDB_DATA_TYPE_VARBINARY || (!IS_STR_DATA_TYPE(paraType) && !IS_NULL_TYPE(paraType))) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
} }
@ -2124,31 +2186,182 @@ static int32_t translateSubstr(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
uint8_t para0Type = pPara0->resType.type; uint8_t para0Type = pPara0->resType.type;
uint8_t para1Type = pPara1->resType.type; uint8_t para1Type = pPara1->resType.type;
if (TSDB_DATA_TYPE_VARBINARY == para0Type || !IS_STR_DATA_TYPE(para0Type) || !IS_INTEGER_TYPE(para1Type)) { if (TSDB_DATA_TYPE_VARBINARY == para0Type ||
(!IS_STR_DATA_TYPE(para0Type) && !IS_NULL_TYPE(para0Type)) ||
(!IS_INTEGER_TYPE(para1Type) && !IS_NULL_TYPE(para1Type))) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
} }
if (((SValueNode*)pPara1)->datum.i == 0) {
return invaildFuncParaValueErrMsg(pErrBuf, len, pFunc->functionName);
}
if (3 == numOfParams) { if (3 == numOfParams) {
SExprNode* pPara2 = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 2); SExprNode* pPara2 = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 2);
uint8_t para2Type = pPara2->resType.type; uint8_t para2Type = pPara2->resType.type;
if (!IS_INTEGER_TYPE(para2Type)) { if (!IS_INTEGER_TYPE(para2Type) && !IS_NULL_TYPE(para2Type)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
} }
int64_t v = ((SValueNode*)pPara2)->datum.i; int64_t v = ((SValueNode*)pPara2)->datum.i;
if (v < 0) {
return invaildFuncParaValueErrMsg(pErrBuf, len, pFunc->functionName);
}
} }
pFunc->node.resType = (SDataType){.bytes = pPara0->resType.bytes, .type = pPara0->resType.type}; pFunc->node.resType = (SDataType){.bytes = pPara0->resType.bytes, .type = pPara0->resType.type};
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t translateSubstrIdx(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (3 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
SExprNode* pPara0 = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
SExprNode* pPara1 = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 1);
SExprNode* pPara2 = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 2);
uint8_t para0Type = pPara0->resType.type;
uint8_t para1Type = pPara1->resType.type;
uint8_t para2Type = pPara2->resType.type;
if (TSDB_DATA_TYPE_VARBINARY == para0Type || (!IS_STR_DATA_TYPE(para0Type) && !IS_NULL_TYPE(para0Type)) ||
TSDB_DATA_TYPE_VARBINARY == para1Type || (!IS_STR_DATA_TYPE(para1Type) && !IS_NULL_TYPE(para1Type)) ||
(!IS_INTEGER_TYPE(para2Type) && !IS_NULL_TYPE(para2Type))) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
pFunc->node.resType = (SDataType){.bytes = pPara0->resType.bytes, .type = pPara0->resType.type};
return TSDB_CODE_SUCCESS;
}
static int32_t translateChar(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
SNode *node;
FOREACH(node, pFunc->pParameterList) {
uint8_t paraType = getSDataTypeFromNode(node)->type;
if (paraType == TSDB_DATA_TYPE_VARBINARY ||
(!IS_STR_DATA_TYPE(paraType) && !IS_NUMERIC_TYPE(paraType) && !IS_NULL_TYPE(paraType))) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
}
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
pFunc->node.resType = (SDataType){.bytes = 4 * numOfParams + 2, .type = TSDB_DATA_TYPE_VARCHAR};
return TSDB_CODE_SUCCESS;
}
static int32_t translateAscii(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
if (paraType == TSDB_DATA_TYPE_VARBINARY ||
(!IS_STR_DATA_TYPE(paraType) && !IS_NULL_TYPE(paraType))) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_UTINYINT].bytes, .type = TSDB_DATA_TYPE_UTINYINT};
return TSDB_CODE_SUCCESS;
}
static int32_t translatePosition(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (2 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t para0Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
if (para0Type == TSDB_DATA_TYPE_VARBINARY ||
(!IS_STR_DATA_TYPE(para0Type) && !IS_NULL_TYPE(para0Type))) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
if (para1Type == TSDB_DATA_TYPE_VARBINARY ||
(!IS_STR_DATA_TYPE(para1Type) && !IS_NULL_TYPE(para1Type))) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT};
return TSDB_CODE_SUCCESS;
}
static int32_t translateTrim(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (2 != LIST_LENGTH(pFunc->pParameterList) && 1 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t para0Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
if (para0Type == TSDB_DATA_TYPE_VARBINARY ||
(!IS_STR_DATA_TYPE(para0Type) && !IS_NULL_TYPE(para0Type))) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
int32_t resLen = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->bytes;
uint8_t type = para0Type;
if (2 == LIST_LENGTH(pFunc->pParameterList)) {
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
if (para1Type == TSDB_DATA_TYPE_VARBINARY ||
(!IS_STR_DATA_TYPE(para1Type) && !IS_NULL_TYPE(para1Type))) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
resLen = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->bytes;
type = para1Type;
}
if (type == TSDB_DATA_TYPE_NCHAR) {
resLen *= TSDB_NCHAR_SIZE;
}
uint8_t trimType = pFunc->trimType;
int32_t code = addUint8Param(&pFunc->pParameterList, trimType);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
pFunc->node.resType = (SDataType){.bytes = resLen, .type = type};
return TSDB_CODE_SUCCESS;
}
static int32_t translateReplace(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (3 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
for (int32_t i = 0; i < 3; ++i) {
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, i))->type;
if (paraType == TSDB_DATA_TYPE_VARBINARY ||
(!IS_STR_DATA_TYPE(paraType) && !IS_NULL_TYPE(paraType))) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
}
uint8_t type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
int32_t orgLen = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->bytes;
int32_t fromLen = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->bytes;
int32_t toLen = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->bytes;
int32_t resLen = orgLen + orgLen / fromLen * (toLen - fromLen);
pFunc->node.resType = (SDataType){.bytes = resLen, .type = type};
return TSDB_CODE_SUCCESS;
}
static int32_t translateRepeat(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (2 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t para0Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
if (para0Type == TSDB_DATA_TYPE_VARBINARY ||
(!IS_STR_DATA_TYPE(para0Type) && !IS_NULL_TYPE(para0Type))) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
if (!IS_INTEGER_TYPE(para1Type) && !IS_NULL_TYPE(para1Type)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
int32_t orgLen = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->bytes;
int32_t count = TMAX((int32_t)((SValueNode*)nodesListGetNode(pFunc->pParameterList, 1))->datum.i, 1);
int32_t resLen = orgLen * count;
pFunc->node.resType = (SDataType){.bytes = resLen, .type = type};
return TSDB_CODE_SUCCESS;
}
static int32_t translateCast(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { static int32_t translateCast(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
// The number of parameters has been limited by the syntax definition // The number of parameters has been limited by the syntax definition
@ -2180,7 +2393,7 @@ static int32_t translateCast(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
// add database precision as param // add database precision as param
uint8_t dbPrec = pFunc->node.resType.precision; uint8_t dbPrec = pFunc->node.resType.precision;
int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); int32_t code = addUint8Param(&pFunc->pParameterList, dbPrec);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
@ -2251,7 +2464,7 @@ static int32_t translateToUnixtimestamp(SFunctionNode* pFunc, char* pErrBuf, int
// add database precision as param // add database precision as param
uint8_t dbPrec = pFunc->node.resType.precision; uint8_t dbPrec = pFunc->node.resType.precision;
int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); int32_t code = addUint8Param(&pFunc->pParameterList, dbPrec);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
@ -2325,7 +2538,7 @@ static int32_t translateTimeTruncate(SFunctionNode* pFunc, char* pErrBuf, int32_
// add database precision as param // add database precision as param
code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); code = addUint8Param(&pFunc->pParameterList, dbPrec);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
@ -2375,7 +2588,7 @@ static int32_t translateTimeDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t le
} }
} }
int32_t code = addDbPrecisonParam(&pFunc->pParameterList, dbPrec); int32_t code = addUint8Param(&pFunc->pParameterList, dbPrec);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
@ -2384,6 +2597,91 @@ static int32_t translateTimeDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t le
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t translateWeekday(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
if ((!IS_STR_DATA_TYPE(para1Type) && !IS_INTEGER_TYPE(para1Type) &&
!IS_TIMESTAMP_TYPE(para1Type) && !IS_NULL_TYPE(para1Type))) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
// add database precision as param
uint8_t dbPrec = pFunc->node.resType.precision;
int32_t code = addUint8Param(&pFunc->pParameterList, dbPrec);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
pFunc->node.resType =
(SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT};
return TSDB_CODE_SUCCESS;
}
static int32_t translateWeek(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (1 != LIST_LENGTH(pFunc->pParameterList) && 2 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
if ((!IS_STR_DATA_TYPE(para1Type) && !IS_INTEGER_TYPE(para1Type) &&
!IS_TIMESTAMP_TYPE(para1Type)) && !IS_NULL_TYPE(para1Type)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
if (2 == LIST_LENGTH(pFunc->pParameterList)) {
uint8_t para2Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type;
if (!IS_INTEGER_TYPE(para2Type) && !IS_NULL_TYPE(para2Type)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
if (IS_INTEGER_TYPE(para2Type)) {
SValueNode* pValue = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 1);
if (pValue->datum.i < 0 || pValue->datum.i > 7) {
return invaildFuncParaValueErrMsg(pErrBuf, len, pFunc->functionName);
}
}
}
// add database precision as param
uint8_t dbPrec = pFunc->node.resType.precision;
int32_t code = addUint8Param(&pFunc->pParameterList, dbPrec);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
pFunc->node.resType =
(SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT};
return TSDB_CODE_SUCCESS;
}
static int32_t translateWeekofyear(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t para1Type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
if ((!IS_STR_DATA_TYPE(para1Type) && !IS_INTEGER_TYPE(para1Type) &&
!IS_TIMESTAMP_TYPE(para1Type)) && !IS_NULL_TYPE(para1Type)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
// add database precision as param
uint8_t dbPrec = pFunc->node.resType.precision;
int32_t code = addUint8Param(&pFunc->pParameterList, dbPrec);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
pFunc->node.resType =
(SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT};
return TSDB_CODE_SUCCESS;
}
static int32_t translateToJson(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { static int32_t translateToJson(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
if (1 != LIST_LENGTH(pFunc->pParameterList)) { if (1 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
@ -2618,54 +2916,106 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.pStateFunc = "max", .pStateFunc = "max",
.pMergeFunc = "max" .pMergeFunc = "max"
}, },
{
.name = "stddev_pop",
.type = FUNCTION_TYPE_STDDEV,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TSMA_FUNC,
.translateFunc = translateInNumOutDou,
.getEnvFunc = getStdFuncEnv,
.initFunc = stdFunctionSetup,
.processFunc = stdFunction,
.sprocessFunc = stdScalarFunction,
.finalizeFunc = stddevFinalize,
#ifdef BUILD_NO_CALL
.invertFunc = stdInvertFunction,
#endif
.combineFunc = stdCombine,
.pPartialFunc = "_std_partial",
.pStateFunc = "_std_state",
.pMergeFunc = "_stddev_merge"
},
{ {
.name = "stddev", .name = "stddev",
.type = FUNCTION_TYPE_STDDEV, .type = FUNCTION_TYPE_STDDEV,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TSMA_FUNC, .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TSMA_FUNC,
.translateFunc = translateInNumOutDou, .translateFunc = translateInNumOutDou,
.getEnvFunc = getStddevFuncEnv, .getEnvFunc = getStdFuncEnv,
.initFunc = stddevFunctionSetup, .initFunc = stdFunctionSetup,
.processFunc = stddevFunction, .processFunc = stdFunction,
.sprocessFunc = stddevScalarFunction, .sprocessFunc = stdScalarFunction,
.finalizeFunc = stddevFinalize, .finalizeFunc = stddevFinalize,
#ifdef BUILD_NO_CALL #ifdef BUILD_NO_CALL
.invertFunc = stddevInvertFunction, .invertFunc = stdInvertFunction,
#endif #endif
.combineFunc = stddevCombine, .combineFunc = stdCombine,
.pPartialFunc = "_stddev_partial", .pPartialFunc = "_std_partial",
.pStateFunc = "_stddev_state", .pStateFunc = "_std_state",
.pMergeFunc = "_stddev_merge" .pMergeFunc = "_stddev_merge"
}, },
{ {
.name = "_stddev_partial", .name = "var_pop",
.type = FUNCTION_TYPE_STDDEV_PARTIAL, .type = FUNCTION_TYPE_STDVAR,
.classification = FUNC_MGT_AGG_FUNC, .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TSMA_FUNC,
.translateFunc = translateStddevPartial, .translateFunc = translateInNumOutDou,
.getEnvFunc = getStddevFuncEnv, .getEnvFunc = getStdFuncEnv,
.initFunc = stddevFunctionSetup, .initFunc = stdFunctionSetup,
.processFunc = stddevFunction, .processFunc = stdFunction,
.finalizeFunc = stddevPartialFinalize, .sprocessFunc = stdScalarFunction,
.finalizeFunc = stdvarFinalize,
#ifdef BUILD_NO_CALL #ifdef BUILD_NO_CALL
.invertFunc = stddevInvertFunction, .invertFunc = stdInvertFunction,
#endif #endif
.combineFunc = stddevCombine, .combineFunc = stdCombine,
.pPartialFunc = "_std_partial",
.pStateFunc = "_std_state",
.pMergeFunc = "_stdvar_merge"
},
{
.name = "_std_partial",
.type = FUNCTION_TYPE_STD_PARTIAL,
.classification = FUNC_MGT_AGG_FUNC,
.translateFunc = translateStdPartial,
.getEnvFunc = getStdFuncEnv,
.initFunc = stdFunctionSetup,
.processFunc = stdFunction,
.finalizeFunc = stdPartialFinalize,
#ifdef BUILD_NO_CALL
.invertFunc = stdInvertFunction,
#endif
.combineFunc = stdCombine,
}, },
{ {
.name = "_stddev_merge", .name = "_stddev_merge",
.type = FUNCTION_TYPE_STDDEV_MERGE, .type = FUNCTION_TYPE_STDDEV_MERGE,
.classification = FUNC_MGT_AGG_FUNC, .classification = FUNC_MGT_AGG_FUNC,
.translateFunc = translateStddevMerge, .translateFunc = translateStdMerge,
.getEnvFunc = getStddevFuncEnv, .getEnvFunc = getStdFuncEnv,
.initFunc = stddevFunctionSetup, .initFunc = stdFunctionSetup,
.processFunc = stddevFunctionMerge, .processFunc = stdFunctionMerge,
.finalizeFunc = stddevFinalize, .finalizeFunc = stddevFinalize,
#ifdef BUILD_NO_CALL #ifdef BUILD_NO_CALL
.invertFunc = stddevInvertFunction, .invertFunc = stdInvertFunction,
#endif #endif
.combineFunc = stddevCombine, .combineFunc = stdCombine,
.pPartialFunc = "_stddev_state_merge", .pPartialFunc = "_std_state_merge",
.pMergeFunc = "_stddev_merge", .pMergeFunc = "_stddev_merge",
}, },
{
.name = "_stdvar_merge",
.type = FUNCTION_TYPE_STDVAR_MERGE,
.classification = FUNC_MGT_AGG_FUNC,
.translateFunc = translateStdMerge,
.getEnvFunc = getStdFuncEnv,
.initFunc = stdFunctionSetup,
.processFunc = stdFunctionMerge,
.finalizeFunc = stdvarFinalize,
#ifdef BUILD_NO_CALL
.invertFunc = stdInvertFunction,
#endif
.combineFunc = stdCombine,
.pPartialFunc = "_std_state_merge",
.pMergeFunc = "_stdvar_merge",
},
{ {
.name = "leastsquares", .name = "leastsquares",
.type = FUNCTION_TYPE_LEASTSQUARES, .type = FUNCTION_TYPE_LEASTSQUARES,
@ -3409,7 +3759,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.name = "round", .name = "round",
.type = FUNCTION_TYPE_ROUND, .type = FUNCTION_TYPE_ROUND,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInOutNum, .translateFunc = translateRound,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = roundFunction, .sprocessFunc = roundFunction,
@ -3475,6 +3825,96 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.sprocessFunc = atanFunction, .sprocessFunc = atanFunction,
.finalizeFunc = NULL .finalizeFunc = NULL
}, },
{
.name = "pi",
.type = FUNCTION_TYPE_PI,
.classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translatePi,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = piFunction,
.finalizeFunc = NULL
},
{
.name = "exp",
.type = FUNCTION_TYPE_EXP,
.classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInNumOutDou,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = expFunction,
.finalizeFunc = NULL
},
{
.name = "ln",
.type = FUNCTION_TYPE_LN,
.classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInNumOutDou,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = lnFunction,
.finalizeFunc = NULL
},
{
.name = "mod",
.type = FUNCTION_TYPE_MOD,
.classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateIn2NumOutDou,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = modFunction,
.finalizeFunc = NULL
},
{
.name = "sign",
.type = FUNCTION_TYPE_SIGN,
.classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInOutNum,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = signFunction,
.finalizeFunc = NULL
},
{
.name = "degrees",
.type = FUNCTION_TYPE_DEGREES,
.classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInNumOutDou,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = degreesFunction,
.finalizeFunc = NULL
},
{
.name = "radians",
.type = FUNCTION_TYPE_RADIANS,
.classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInNumOutDou,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = radiansFunction,
.finalizeFunc = NULL
},
{
.name = "truncate",
.type = FUNCTION_TYPE_TRUNCATE,
.classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateTrunc,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = truncFunction,
.finalizeFunc = NULL
},
{
.name = "trunc",
.type = FUNCTION_TYPE_TRUNCATE,
.classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateTrunc,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = truncFunction,
.finalizeFunc = NULL
},
{ {
.name = "length", .name = "length",
.type = FUNCTION_TYPE_LENGTH, .type = FUNCTION_TYPE_LENGTH,
@ -3489,7 +3929,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.name = "char_length", .name = "char_length",
.type = FUNCTION_TYPE_CHAR_LENGTH, .type = FUNCTION_TYPE_CHAR_LENGTH,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC, .classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateLength, .translateFunc = translateCharLength,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = charLengthFunction, .sprocessFunc = charLengthFunction,
@ -3565,6 +4005,26 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.sprocessFunc = substrFunction, .sprocessFunc = substrFunction,
.finalizeFunc = NULL .finalizeFunc = NULL
}, },
{
.name = "substring",
.type = FUNCTION_TYPE_SUBSTR,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateSubstr,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = substrFunction,
.finalizeFunc = NULL
},
{
.name = "substring_index",
.type = FUNCTION_TYPE_SUBSTR_IDX,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateSubstrIdx,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = substrIdxFunction,
.finalizeFunc = NULL
},
{ {
.name = "cast", .name = "cast",
.type = FUNCTION_TYPE_CAST, .type = FUNCTION_TYPE_CAST,
@ -3575,6 +4035,66 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.sprocessFunc = castFunction, .sprocessFunc = castFunction,
.finalizeFunc = NULL .finalizeFunc = NULL
}, },
{
.name = "char",
.type = FUNCTION_TYPE_CHAR,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateChar,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = charFunction,
.finalizeFunc = NULL
},
{
.name = "ascii",
.type = FUNCTION_TYPE_ASCII,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateAscii,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = asciiFunction,
.finalizeFunc = NULL
},
{
.name = "position",
.type = FUNCTION_TYPE_POSITION,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translatePosition,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = positionFunction,
.finalizeFunc = NULL
},
{
.name = "trim",
.type = FUNCTION_TYPE_TRIM,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateTrim,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = trimFunction,
.finalizeFunc = NULL
},
{
.name = "replace",
.type = FUNCTION_TYPE_REPLACE,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateReplace,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = replaceFunction,
.finalizeFunc = NULL
},
{
.name = "repeat",
.type = FUNCTION_TYPE_REPEAT,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateRepeat,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = repeatFunction,
.finalizeFunc = NULL
},
{ {
.name = "to_iso8601", .name = "to_iso8601",
.type = FUNCTION_TYPE_TO_ISO8601, .type = FUNCTION_TYPE_TO_ISO8601,
@ -3645,6 +4165,46 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.sprocessFunc = timezoneFunction, .sprocessFunc = timezoneFunction,
.finalizeFunc = NULL .finalizeFunc = NULL
}, },
{
.name = "weekday",
.type = FUNCTION_TYPE_WEEKDAY,
.classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateWeekday,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = weekdayFunction,
.finalizeFunc = NULL
},
{
.name = "dayofweek",
.type = FUNCTION_TYPE_DAYOFWEEK,
.classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateWeekday,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = dayofweekFunction,
.finalizeFunc = NULL
},
{
.name = "week",
.type = FUNCTION_TYPE_WEEK,
.classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateWeek,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = weekFunction,
.finalizeFunc = NULL
},
{
.name = "weekofyear",
.type = FUNCTION_TYPE_WEEKOFYEAR,
.classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateWeekofyear,
.getEnvFunc = NULL,
.initFunc = NULL,
.sprocessFunc = weekofyearFunction,
.finalizeFunc = NULL
},
{ {
.name = "tbname", .name = "tbname",
.type = FUNCTION_TYPE_TBNAME, .type = FUNCTION_TYPE_TBNAME,
@ -3998,26 +4558,26 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.finalizeFunc = NULL .finalizeFunc = NULL
}, },
{ {
.name = "_stddev_state", .name = "_std_state",
.type = FUNCTION_TYPE_STDDEV_STATE, .type = FUNCTION_TYPE_STD_STATE,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TSMA_FUNC, .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TSMA_FUNC,
.translateFunc = translateStddevState, .translateFunc = translateStdState,
.getEnvFunc = getStddevFuncEnv, .getEnvFunc = getStdFuncEnv,
.initFunc = stddevFunctionSetup, .initFunc = stdFunctionSetup,
.processFunc = stddevFunction, .processFunc = stdFunction,
.finalizeFunc = stddevPartialFinalize, .finalizeFunc = stdPartialFinalize,
.pPartialFunc = "_stddev_partial", .pPartialFunc = "_std_partial",
.pMergeFunc = "_stddev_state_merge", .pMergeFunc = "_std_state_merge",
}, },
{ {
.name = "_stddev_state_merge", .name = "_std_state_merge",
.type = FUNCTION_TYPE_STDDEV_STATE_MERGE, .type = FUNCTION_TYPE_STD_STATE_MERGE,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TSMA_FUNC, .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TSMA_FUNC,
.translateFunc = translateStddevStateMerge, .translateFunc = translateStdStateMerge,
.getEnvFunc = getStddevFuncEnv, .getEnvFunc = getStdFuncEnv,
.initFunc = stddevFunctionSetup, .initFunc = stdFunctionSetup,
.processFunc = stddevFunctionMerge, .processFunc = stdFunctionMerge,
.finalizeFunc = stddevPartialFinalize, .finalizeFunc = stdPartialFinalize,
}, },
{ {
.name = "_avg_state", .name = "_avg_state",

View File

@ -63,7 +63,7 @@ typedef struct STopBotRes {
STopBotResItem* pItems; STopBotResItem* pItems;
} STopBotRes; } STopBotRes;
typedef struct SStddevRes { typedef struct SStdRes {
double result; double result;
int64_t count; int64_t count;
union { union {
@ -77,7 +77,7 @@ typedef struct SStddevRes {
uint64_t usum; uint64_t usum;
}; };
int16_t type; int16_t type;
} SStddevRes; } SStdRes;
typedef struct SLeastSQRInfo { typedef struct SLeastSQRInfo {
double matrix[2][3]; double matrix[2][3];
@ -1300,14 +1300,14 @@ int32_t maxCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
return minMaxCombine(pDestCtx, pSourceCtx, 0); return minMaxCombine(pDestCtx, pSourceCtx, 0);
} }
int32_t getStddevInfoSize() { return (int32_t)sizeof(SStddevRes); } int32_t getStdInfoSize() { return (int32_t)sizeof(SStdRes); }
bool getStddevFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) { bool getStdFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
pEnv->calcMemSize = sizeof(SStddevRes); pEnv->calcMemSize = sizeof(SStdRes);
return true; return true;
} }
int32_t stddevFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) { int32_t stdFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) {
if (pResultInfo->initialized) { if (pResultInfo->initialized) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -1315,20 +1315,20 @@ int32_t stddevFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultIn
return TSDB_CODE_FUNC_SETUP_ERROR; return TSDB_CODE_FUNC_SETUP_ERROR;
} }
SStddevRes* pRes = GET_ROWCELL_INTERBUF(pResultInfo); SStdRes* pRes = GET_ROWCELL_INTERBUF(pResultInfo);
(void)memset(pRes, 0, sizeof(SStddevRes)); (void)memset(pRes, 0, sizeof(SStdRes));
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t stddevFunction(SqlFunctionCtx* pCtx) { int32_t stdFunction(SqlFunctionCtx* pCtx) {
int32_t numOfElem = 0; int32_t numOfElem = 0;
// Only the pre-computing information loaded and actual data does not loaded // Only the pre-computing information loaded and actual data does not loaded
SInputColumnInfoData* pInput = &pCtx->input; SInputColumnInfoData* pInput = &pCtx->input;
int32_t type = pInput->pData[0]->info.type; int32_t type = pInput->pData[0]->info.type;
SStddevRes* pStddevRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); SStdRes* pStdRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
pStddevRes->type = type; pStdRes->type = type;
// computing based on the true data block // computing based on the true data block
SColumnInfoData* pCol = pInput->pData[0]; SColumnInfoData* pCol = pInput->pData[0];
@ -1350,9 +1350,9 @@ int32_t stddevFunction(SqlFunctionCtx* pCtx) {
} }
numOfElem += 1; numOfElem += 1;
pStddevRes->count += 1; pStdRes->count += 1;
pStddevRes->isum += plist[i]; pStdRes->isum += plist[i];
pStddevRes->quadraticISum += plist[i] * plist[i]; pStdRes->quadraticISum += plist[i] * plist[i];
} }
break; break;
@ -1366,9 +1366,9 @@ int32_t stddevFunction(SqlFunctionCtx* pCtx) {
} }
numOfElem += 1; numOfElem += 1;
pStddevRes->count += 1; pStdRes->count += 1;
pStddevRes->isum += plist[i]; pStdRes->isum += plist[i];
pStddevRes->quadraticISum += plist[i] * plist[i]; pStdRes->quadraticISum += plist[i] * plist[i];
} }
break; break;
} }
@ -1381,9 +1381,9 @@ int32_t stddevFunction(SqlFunctionCtx* pCtx) {
} }
numOfElem += 1; numOfElem += 1;
pStddevRes->count += 1; pStdRes->count += 1;
pStddevRes->isum += plist[i]; pStdRes->isum += plist[i];
pStddevRes->quadraticISum += plist[i] * plist[i]; pStdRes->quadraticISum += plist[i] * plist[i];
} }
break; break;
@ -1397,9 +1397,9 @@ int32_t stddevFunction(SqlFunctionCtx* pCtx) {
} }
numOfElem += 1; numOfElem += 1;
pStddevRes->count += 1; pStdRes->count += 1;
pStddevRes->isum += plist[i]; pStdRes->isum += plist[i];
pStddevRes->quadraticISum += plist[i] * plist[i]; pStdRes->quadraticISum += plist[i] * plist[i];
} }
break; break;
} }
@ -1412,9 +1412,9 @@ int32_t stddevFunction(SqlFunctionCtx* pCtx) {
} }
numOfElem += 1; numOfElem += 1;
pStddevRes->count += 1; pStdRes->count += 1;
pStddevRes->usum += plist[i]; pStdRes->usum += plist[i];
pStddevRes->quadraticUSum += plist[i] * plist[i]; pStdRes->quadraticUSum += plist[i] * plist[i];
} }
break; break;
@ -1428,9 +1428,9 @@ int32_t stddevFunction(SqlFunctionCtx* pCtx) {
} }
numOfElem += 1; numOfElem += 1;
pStddevRes->count += 1; pStdRes->count += 1;
pStddevRes->usum += plist[i]; pStdRes->usum += plist[i];
pStddevRes->quadraticUSum += plist[i] * plist[i]; pStdRes->quadraticUSum += plist[i] * plist[i];
} }
break; break;
} }
@ -1443,9 +1443,9 @@ int32_t stddevFunction(SqlFunctionCtx* pCtx) {
} }
numOfElem += 1; numOfElem += 1;
pStddevRes->count += 1; pStdRes->count += 1;
pStddevRes->usum += plist[i]; pStdRes->usum += plist[i];
pStddevRes->quadraticUSum += plist[i] * plist[i]; pStdRes->quadraticUSum += plist[i] * plist[i];
} }
break; break;
@ -1459,9 +1459,9 @@ int32_t stddevFunction(SqlFunctionCtx* pCtx) {
} }
numOfElem += 1; numOfElem += 1;
pStddevRes->count += 1; pStdRes->count += 1;
pStddevRes->usum += plist[i]; pStdRes->usum += plist[i];
pStddevRes->quadraticUSum += plist[i] * plist[i]; pStdRes->quadraticUSum += plist[i] * plist[i];
} }
break; break;
} }
@ -1474,9 +1474,9 @@ int32_t stddevFunction(SqlFunctionCtx* pCtx) {
} }
numOfElem += 1; numOfElem += 1;
pStddevRes->count += 1; pStdRes->count += 1;
pStddevRes->dsum += plist[i]; pStdRes->dsum += plist[i];
pStddevRes->quadraticDSum += plist[i] * plist[i]; pStdRes->quadraticDSum += plist[i] * plist[i];
} }
break; break;
} }
@ -1489,9 +1489,9 @@ int32_t stddevFunction(SqlFunctionCtx* pCtx) {
} }
numOfElem += 1; numOfElem += 1;
pStddevRes->count += 1; pStdRes->count += 1;
pStddevRes->dsum += plist[i]; pStdRes->dsum += plist[i];
pStddevRes->quadraticDSum += plist[i] * plist[i]; pStdRes->quadraticDSum += plist[i] * plist[i];
} }
break; break;
} }
@ -1506,7 +1506,7 @@ _stddev_over:
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static void stddevTransferInfo(SStddevRes* pInput, SStddevRes* pOutput) { static void stdTransferInfo(SStdRes* pInput, SStdRes* pOutput) {
if (IS_NULL_TYPE(pInput->type)) { if (IS_NULL_TYPE(pInput->type)) {
return; return;
} }
@ -1525,7 +1525,7 @@ static void stddevTransferInfo(SStddevRes* pInput, SStddevRes* pOutput) {
pOutput->count += pInput->count; pOutput->count += pInput->count;
} }
int32_t stddevFunctionMerge(SqlFunctionCtx* pCtx) { int32_t stdFunctionMerge(SqlFunctionCtx* pCtx) {
SInputColumnInfoData* pInput = &pCtx->input; SInputColumnInfoData* pInput = &pCtx->input;
SColumnInfoData* pCol = pInput->pData[0]; SColumnInfoData* pCol = pInput->pData[0];
@ -1538,13 +1538,13 @@ int32_t stddevFunctionMerge(SqlFunctionCtx* pCtx) {
return TSDB_CODE_FUNC_FUNTION_PARA_TYPE; return TSDB_CODE_FUNC_FUNTION_PARA_TYPE;
} }
SStddevRes* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); SStdRes* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
for (int32_t i = pInput->startRowIndex; i < pInput->startRowIndex + pInput->numOfRows; ++i) { for (int32_t i = pInput->startRowIndex; i < pInput->startRowIndex + pInput->numOfRows; ++i) {
if (colDataIsNull_s(pCol, i)) continue; if (colDataIsNull_s(pCol, i)) continue;
char* data = colDataGetData(pCol, i); char* data = colDataGetData(pCol, i);
SStddevRes* pInputInfo = (SStddevRes*)varDataVal(data); SStdRes* pInputInfo = (SStdRes*)varDataVal(data);
stddevTransferInfo(pInputInfo, pInfo); stdTransferInfo(pInputInfo, pInfo);
} }
SET_VAL(GET_RES_INFO(pCtx), 1, 1); SET_VAL(GET_RES_INFO(pCtx), 1, 1);
@ -1552,14 +1552,14 @@ int32_t stddevFunctionMerge(SqlFunctionCtx* pCtx) {
} }
#ifdef BUILD_NO_CALL #ifdef BUILD_NO_CALL
int32_t stddevInvertFunction(SqlFunctionCtx* pCtx) { int32_t stdInvertFunction(SqlFunctionCtx* pCtx) {
int32_t numOfElem = 0; int32_t numOfElem = 0;
// Only the pre-computing information loaded and actual data does not loaded // Only the pre-computing information loaded and actual data does not loaded
SInputColumnInfoData* pInput = &pCtx->input; SInputColumnInfoData* pInput = &pCtx->input;
int32_t type = pInput->pData[0]->info.type; int32_t type = pInput->pData[0]->info.type;
SStddevRes* pStddevRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); SStdRes* pStdRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
// computing based on the true data block // computing based on the true data block
SColumnInfoData* pCol = pInput->pData[0]; SColumnInfoData* pCol = pInput->pData[0];
@ -1569,43 +1569,43 @@ int32_t stddevInvertFunction(SqlFunctionCtx* pCtx) {
switch (type) { switch (type) {
case TSDB_DATA_TYPE_TINYINT: { case TSDB_DATA_TYPE_TINYINT: {
LIST_STDDEV_SUB_N(pStddevRes->isum, int8_t); LIST_STDDEV_SUB_N(pStdRes->isum, int8_t);
break; break;
} }
case TSDB_DATA_TYPE_SMALLINT: { case TSDB_DATA_TYPE_SMALLINT: {
LIST_STDDEV_SUB_N(pStddevRes->isum, int16_t); LIST_STDDEV_SUB_N(pStdRes->isum, int16_t);
break; break;
} }
case TSDB_DATA_TYPE_INT: { case TSDB_DATA_TYPE_INT: {
LIST_STDDEV_SUB_N(pStddevRes->isum, int32_t); LIST_STDDEV_SUB_N(pStdRes->isum, int32_t);
break; break;
} }
case TSDB_DATA_TYPE_BIGINT: { case TSDB_DATA_TYPE_BIGINT: {
LIST_STDDEV_SUB_N(pStddevRes->isum, int64_t); LIST_STDDEV_SUB_N(pStdRes->isum, int64_t);
break; break;
} }
case TSDB_DATA_TYPE_UTINYINT: { case TSDB_DATA_TYPE_UTINYINT: {
LIST_STDDEV_SUB_N(pStddevRes->isum, uint8_t); LIST_STDDEV_SUB_N(pStdRes->isum, uint8_t);
break; break;
} }
case TSDB_DATA_TYPE_USMALLINT: { case TSDB_DATA_TYPE_USMALLINT: {
LIST_STDDEV_SUB_N(pStddevRes->isum, uint16_t); LIST_STDDEV_SUB_N(pStdRes->isum, uint16_t);
break; break;
} }
case TSDB_DATA_TYPE_UINT: { case TSDB_DATA_TYPE_UINT: {
LIST_STDDEV_SUB_N(pStddevRes->isum, uint32_t); LIST_STDDEV_SUB_N(pStdRes->isum, uint32_t);
break; break;
} }
case TSDB_DATA_TYPE_UBIGINT: { case TSDB_DATA_TYPE_UBIGINT: {
LIST_STDDEV_SUB_N(pStddevRes->isum, uint64_t); LIST_STDDEV_SUB_N(pStdRes->isum, uint64_t);
break; break;
} }
case TSDB_DATA_TYPE_FLOAT: { case TSDB_DATA_TYPE_FLOAT: {
LIST_STDDEV_SUB_N(pStddevRes->dsum, float); LIST_STDDEV_SUB_N(pStdRes->dsum, float);
break; break;
} }
case TSDB_DATA_TYPE_DOUBLE: { case TSDB_DATA_TYPE_DOUBLE: {
LIST_STDDEV_SUB_N(pStddevRes->dsum, double); LIST_STDDEV_SUB_N(pStdRes->dsum, double);
break; break;
} }
default: default:
@ -1620,7 +1620,7 @@ int32_t stddevInvertFunction(SqlFunctionCtx* pCtx) {
int32_t stddevFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { int32_t stddevFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
SInputColumnInfoData* pInput = &pCtx->input; SInputColumnInfoData* pInput = &pCtx->input;
SStddevRes* pStddevRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); SStdRes* pStddevRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
int32_t type = pStddevRes->type; int32_t type = pStddevRes->type;
double avg; double avg;
@ -1648,10 +1648,40 @@ int32_t stddevFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
return functionFinalize(pCtx, pBlock); return functionFinalize(pCtx, pBlock);
} }
int32_t stddevPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { int32_t stdvarFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
SInputColumnInfoData* pInput = &pCtx->input;
SStdRes* pStdvarRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
int32_t type = pStdvarRes->type;
double avg;
if (pStdvarRes->count == 0) {
GET_RES_INFO(pCtx)->numOfRes = 0;
return functionFinalize(pCtx, pBlock);
}
if (IS_SIGNED_NUMERIC_TYPE(type)) {
avg = pStdvarRes->isum / ((double)pStdvarRes->count);
pStdvarRes->result = fabs(pStdvarRes->quadraticISum / ((double)pStdvarRes->count) - avg * avg);
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
avg = pStdvarRes->usum / ((double)pStdvarRes->count);
pStdvarRes->result = fabs(pStdvarRes->quadraticUSum / ((double)pStdvarRes->count) - avg * avg);
} else {
avg = pStdvarRes->dsum / ((double)pStdvarRes->count);
pStdvarRes->result = fabs(pStdvarRes->quadraticDSum / ((double)pStdvarRes->count) - avg * avg);
}
// check for overflow
if (isinf(pStdvarRes->result) || isnan(pStdvarRes->result)) {
GET_RES_INFO(pCtx)->numOfRes = 0;
}
return functionFinalize(pCtx, pBlock);
}
int32_t stdPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
SStddevRes* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); SStdRes* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
int32_t resultBytes = getStddevInfoSize(); int32_t resultBytes = getStdInfoSize();
char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char)); char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char));
if (NULL == res) { if (NULL == res) {
@ -1673,15 +1703,15 @@ int32_t stddevPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
return code; return code;
} }
int32_t stddevCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) { int32_t stdCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx); SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx);
SStddevRes* pDBuf = GET_ROWCELL_INTERBUF(pDResInfo); SStdRes* pDBuf = GET_ROWCELL_INTERBUF(pDResInfo);
SResultRowEntryInfo* pSResInfo = GET_RES_INFO(pSourceCtx); SResultRowEntryInfo* pSResInfo = GET_RES_INFO(pSourceCtx);
SStddevRes* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo); SStdRes* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo);
int16_t type = pDBuf->type == TSDB_DATA_TYPE_NULL ? pSBuf->type : pDBuf->type; int16_t type = pDBuf->type == TSDB_DATA_TYPE_NULL ? pSBuf->type : pDBuf->type;
stddevTransferInfo(pSBuf, pDBuf); stdTransferInfo(pSBuf, pDBuf);
pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes); pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes);
pDResInfo->isNullRes &= pSResInfo->isNullRes; pDResInfo->isNullRes &= pSResInfo->isNullRes;

View File

@ -4254,6 +4254,7 @@ static const char* jkFunctionHasPk = "HasPk";
static const char* jkFunctionPkBytes = "PkBytes"; static const char* jkFunctionPkBytes = "PkBytes";
static const char* jkFunctionIsMergeFunc = "IsMergeFunc"; static const char* jkFunctionIsMergeFunc = "IsMergeFunc";
static const char* jkFunctionMergeFuncOf = "MergeFuncOf"; static const char* jkFunctionMergeFuncOf = "MergeFuncOf";
static const char* jkFunctionTrimType = "TrimType";
static int32_t functionNodeToJson(const void* pObj, SJson* pJson) { static int32_t functionNodeToJson(const void* pObj, SJson* pJson) {
const SFunctionNode* pNode = (const SFunctionNode*)pObj; const SFunctionNode* pNode = (const SFunctionNode*)pObj;
@ -4286,7 +4287,9 @@ static int32_t functionNodeToJson(const void* pObj, SJson* pJson) {
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkFunctionMergeFuncOf, pNode->originalFuncId); code = tjsonAddIntegerToObject(pJson, jkFunctionMergeFuncOf, pNode->originalFuncId);
} }
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkFunctionTrimType, pNode->trimType);
}
return code; return code;
} }
@ -4321,6 +4324,9 @@ static int32_t jsonToFunctionNode(const SJson* pJson, void* pObj) {
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkFunctionMergeFuncOf, &pNode->originalFuncId); code = tjsonGetIntValue(pJson, jkFunctionMergeFuncOf, &pNode->originalFuncId);
} }
if (TSDB_CODE_SUCCESS == code) {
tjsonGetNumberValue(pJson, jkFunctionTrimType, pNode->trimType, code);
}
return code; return code;
} }

View File

@ -1112,6 +1112,7 @@ enum {
FUNCTION_NODE_PK_BYTES, FUNCTION_NODE_PK_BYTES,
FUNCTION_CODE_IS_MERGE_FUNC, FUNCTION_CODE_IS_MERGE_FUNC,
FUNCTION_CODE_MERGE_FUNC_OF, FUNCTION_CODE_MERGE_FUNC_OF,
FUNCTION_CODE_TRIM_TYPE,
}; };
static int32_t functionNodeToMsg(const void* pObj, STlvEncoder* pEncoder) { static int32_t functionNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
@ -1145,6 +1146,9 @@ static int32_t functionNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeI32(pEncoder, FUNCTION_CODE_MERGE_FUNC_OF, pNode->originalFuncId); code = tlvEncodeI32(pEncoder, FUNCTION_CODE_MERGE_FUNC_OF, pNode->originalFuncId);
} }
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeEnum(pEncoder, FUNCTION_CODE_TRIM_TYPE, pNode->trimType);
}
return code; return code;
} }
@ -1186,6 +1190,9 @@ static int32_t msgToFunctionNode(STlvDecoder* pDecoder, void* pObj) {
case FUNCTION_CODE_MERGE_FUNC_OF: case FUNCTION_CODE_MERGE_FUNC_OF:
code = tlvDecodeI32(pTlv, &pNode->originalFuncId); code = tlvDecodeI32(pTlv, &pNode->originalFuncId);
break; break;
case FUNCTION_CODE_TRIM_TYPE:
code = tlvDecodeEnum(pTlv, &pNode->trimType, sizeof(pNode->trimType));
break;
default: default:
break; break;
} }

View File

@ -136,6 +136,11 @@ SNode* createBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft,
SNode* createNotBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, SNode* pRight); SNode* createNotBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, SNode* pRight);
SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList); SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList);
SNode* createCastFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, SDataType dt); SNode* createCastFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, SDataType dt);
SNode* createPositionFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, SNode* pExpr2);
SNode* createTrimFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, ETrimType type);
SNode* createTrimFunctionNodeExt(SAstCreateContext* pCxt, SNode* pExpr, SNode* pExpr2, ETrimType type);
SNode* createSubstrFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, SNode* pExpr2);
SNode* createSubstrFunctionNodeExt(SAstCreateContext* pCxt, SNode* pExpr, SNode* pExpr2, SNode* pExpr3);
SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList); SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList);
SNode* createNodeListNodeEx(SAstCreateContext* pCxt, SNode* p1, SNode* p2); SNode* createNodeListNodeEx(SAstCreateContext* pCxt, SNode* p1, SNode* p2);
SNode* createRealTableNode(SAstCreateContext* pCxt, SToken* pDbName, SToken* pTableName, SToken* pTableAlias); SNode* createRealTableNode(SAstCreateContext* pCxt, SToken* pDbName, SToken* pTableName, SToken* pTableAlias);

View File

@ -1189,13 +1189,39 @@ function_expression(A) ::=
CAST(B) NK_LP expr_or_subquery(C) AS type_name(D) NK_RP(E). { A = createRawExprNodeExt(pCxt, &B, &E, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, C), D)); } CAST(B) NK_LP expr_or_subquery(C) AS type_name(D) NK_RP(E). { A = createRawExprNodeExt(pCxt, &B, &E, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, C), D)); }
function_expression(A) ::= function_expression(A) ::=
CAST(B) NK_LP expr_or_subquery(C) AS type_name_default_len(D) NK_RP(E). { A = createRawExprNodeExt(pCxt, &B, &E, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, C), D)); } CAST(B) NK_LP expr_or_subquery(C) AS type_name_default_len(D) NK_RP(E). { A = createRawExprNodeExt(pCxt, &B, &E, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, C), D)); }
function_expression(A) ::=
POSITION(B) NK_LP expr_or_subquery(C) IN expr_or_subquery(D) NK_RP(E). { A = createRawExprNodeExt(pCxt, &B, &E, createPositionFunctionNode(pCxt, releaseRawExprNode(pCxt, C), releaseRawExprNode(pCxt, D))); }
function_expression(A) ::=
TRIM(B) NK_LP expr_or_subquery(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createTrimFunctionNode(pCxt, releaseRawExprNode(pCxt, C), TRIM_TYPE_BOTH)); }
function_expression(A) ::=
TRIM(B) NK_LP trim_specification_type(C) FROM expr_or_subquery(D) NK_RP(E). { A = createRawExprNodeExt(pCxt, &B, &E, createTrimFunctionNode(pCxt, releaseRawExprNode(pCxt, D), C)); }
function_expression(A) ::=
TRIM(B) NK_LP trim_specification_type(C) expr_or_subquery(D) FROM expr_or_subquery(E) NK_RP(F). { A = createRawExprNodeExt(pCxt, &B, &F, createTrimFunctionNodeExt(pCxt, releaseRawExprNode(pCxt, D), releaseRawExprNode(pCxt, E), C)); }
function_expression(A) ::=
substr_func(B) NK_LP expression_list(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); }
function_expression(A) ::=
substr_func(B) NK_LP expr_or_subquery(C) FROM expr_or_subquery(D) NK_RP(E). { A = createRawExprNodeExt(pCxt, &B, &E, createSubstrFunctionNode(pCxt, releaseRawExprNode(pCxt, C), releaseRawExprNode(pCxt, D))); }
function_expression(A) ::=
substr_func(B) NK_LP expr_or_subquery(C) FROM expr_or_subquery(D) FOR expr_or_subquery(E) NK_RP(F). { A = createRawExprNodeExt(pCxt, &B, &F, createSubstrFunctionNodeExt(pCxt, releaseRawExprNode(pCxt, C), releaseRawExprNode(pCxt, D), releaseRawExprNode(pCxt, E))); }
function_expression(A) ::= REPLACE(B) NK_LP expression_list(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); }
function_expression(A) ::= literal_func(B). { A = B; } function_expression(A) ::= literal_func(B). { A = B; }
literal_func(A) ::= noarg_func(B) NK_LP NK_RP(C). { A = createRawExprNodeExt(pCxt, &B, &C, createFunctionNode(pCxt, &B, NULL)); } literal_func(A) ::= noarg_func(B) NK_LP NK_RP(C). { A = createRawExprNodeExt(pCxt, &B, &C, createFunctionNode(pCxt, &B, NULL)); }
literal_func(A) ::= NOW(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } literal_func(A) ::= NOW(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
literal_func(A) ::= TODAY(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } literal_func(A) ::= TODAY(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
%type substr_func { SToken }
%destructor substr_func { }
substr_func(A) ::= SUBSTR(B). { A = B; }
substr_func(A) ::= SUBSTRING(B). { A = B; }
%type trim_specification_type ETrimType
%destructor trim_specification_type { }
trim_specification_type(A) ::= . { A = TRIM_TYPE_BOTH; }
trim_specification_type(A) ::= BOTH. { A = TRIM_TYPE_BOTH; }
trim_specification_type(A) ::= TRAILING. { A = TRIM_TYPE_TRAILING; }
trim_specification_type(A) ::= LEADING. { A = TRIM_TYPE_LEADING; }
%type noarg_func { SToken } %type noarg_func { SToken }
%destructor noarg_func { } %destructor noarg_func { }
noarg_func(A) ::= NOW(B). { A = B; } noarg_func(A) ::= NOW(B). { A = B; }
@ -1207,6 +1233,7 @@ noarg_func(A) ::= SERVER_VERSION(B).
noarg_func(A) ::= SERVER_STATUS(B). { A = B; } noarg_func(A) ::= SERVER_STATUS(B). { A = B; }
noarg_func(A) ::= CURRENT_USER(B). { A = B; } noarg_func(A) ::= CURRENT_USER(B). { A = B; }
noarg_func(A) ::= USER(B). { A = B; } noarg_func(A) ::= USER(B). { A = B; }
noarg_func(A) ::= PI(B). { A = B; }
%type star_func { SToken } %type star_func { SToken }
%destructor star_func { } %destructor star_func { }

View File

@ -997,6 +997,73 @@ SNode* createCastFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, SDataType d
return (SNode*)func; return (SNode*)func;
} }
SNode* createPositionFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, SNode* pExpr2) {
CHECK_PARSER_STATUS(pCxt);
SFunctionNode* func = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_FUNCTION, (SNode**)&func);
CHECK_MAKE_NODE(func);
strcpy(func->functionName, "position");
pCxt->errCode = nodesListMakeAppend(&func->pParameterList, pExpr);
CHECK_PARSER_STATUS(pCxt);
pCxt->errCode = nodesListMakeAppend(&func->pParameterList, pExpr2);
CHECK_PARSER_STATUS(pCxt);
return (SNode*)func;
}
SNode* createTrimFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, ETrimType type) {
CHECK_PARSER_STATUS(pCxt);
SFunctionNode* func = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_FUNCTION, (SNode**)&func);
CHECK_MAKE_NODE(func);
strcpy(func->functionName, "trim");
func->trimType = type;
pCxt->errCode = nodesListMakeAppend(&func->pParameterList, pExpr);
CHECK_PARSER_STATUS(pCxt);
return (SNode*)func;
}
SNode* createTrimFunctionNodeExt(SAstCreateContext* pCxt, SNode* pExpr, SNode* pExpr2, ETrimType type) {
CHECK_PARSER_STATUS(pCxt);
SFunctionNode* func = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_FUNCTION, (SNode**)&func);
CHECK_MAKE_NODE(func);
strcpy(func->functionName, "trim");
func->trimType = type;
pCxt->errCode = nodesListMakeAppend(&func->pParameterList, pExpr);
CHECK_PARSER_STATUS(pCxt);
pCxt->errCode = nodesListMakeAppend(&func->pParameterList, pExpr2);
CHECK_PARSER_STATUS(pCxt);
return (SNode*)func;
}
SNode* createSubstrFunctionNode(SAstCreateContext* pCxt, SNode* pExpr, SNode* pExpr2) {
CHECK_PARSER_STATUS(pCxt);
SFunctionNode* func = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_FUNCTION, (SNode**)&func);
CHECK_MAKE_NODE(func);
strcpy(func->functionName, "substr");
pCxt->errCode = nodesListMakeAppend(&func->pParameterList, pExpr);
CHECK_PARSER_STATUS(pCxt);
pCxt->errCode = nodesListMakeAppend(&func->pParameterList, pExpr2);
CHECK_PARSER_STATUS(pCxt);
return (SNode*)func;
}
SNode* createSubstrFunctionNodeExt(SAstCreateContext* pCxt, SNode* pExpr, SNode* pExpr2, SNode* pExpr3) {
CHECK_PARSER_STATUS(pCxt);
SFunctionNode* func = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_FUNCTION, (SNode**)&func);
CHECK_MAKE_NODE(func);
strcpy(func->functionName, "substr");
pCxt->errCode = nodesListMakeAppend(&func->pParameterList, pExpr);
CHECK_PARSER_STATUS(pCxt);
pCxt->errCode = nodesListMakeAppend(&func->pParameterList, pExpr2);
CHECK_PARSER_STATUS(pCxt);
pCxt->errCode = nodesListMakeAppend(&func->pParameterList, pExpr3);
CHECK_PARSER_STATUS(pCxt);
return (SNode*)func;
}
SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList) { SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList) {
CHECK_PARSER_STATUS(pCxt); CHECK_PARSER_STATUS(pCxt);
SNodeListNode* list = NULL; SNodeListNode* list = NULL;

View File

@ -52,6 +52,7 @@ static SKeyword keywordTable[] = {
{"BNODE", TK_BNODE}, {"BNODE", TK_BNODE},
{"BNODES", TK_BNODES}, {"BNODES", TK_BNODES},
{"BOOL", TK_BOOL}, {"BOOL", TK_BOOL},
{"BOTH", TK_BOTH},
{"BUFFER", TK_BUFFER}, {"BUFFER", TK_BUFFER},
{"BUFSIZE", TK_BUFSIZE}, {"BUFSIZE", TK_BUFSIZE},
{"BY", TK_BY}, {"BY", TK_BY},
@ -111,6 +112,7 @@ static SKeyword keywordTable[] = {
{"FLOAT", TK_FLOAT}, {"FLOAT", TK_FLOAT},
{"FLUSH", TK_FLUSH}, {"FLUSH", TK_FLUSH},
{"FROM", TK_FROM}, {"FROM", TK_FROM},
{"FOR", TK_FOR},
{"FORCE", TK_FORCE}, {"FORCE", TK_FORCE},
{"FULL", TK_FULL}, {"FULL", TK_FULL},
{"FUNCTION", TK_FUNCTION}, {"FUNCTION", TK_FUNCTION},
@ -148,6 +150,7 @@ static SKeyword keywordTable[] = {
{"LAST", TK_LAST}, {"LAST", TK_LAST},
{"LAST_ROW", TK_LAST_ROW}, {"LAST_ROW", TK_LAST_ROW},
{"LEADER", TK_LEADER}, {"LEADER", TK_LEADER},
{"LEADING", TK_LEADING},
{"LEFT", TK_LEFT}, {"LEFT", TK_LEFT},
{"LICENCES", TK_LICENCES}, {"LICENCES", TK_LICENCES},
{"LIKE", TK_LIKE}, {"LIKE", TK_LIKE},
@ -191,6 +194,7 @@ static SKeyword keywordTable[] = {
{"PARTITION_FIRST", TK_PARTITION_FIRST}, {"PARTITION_FIRST", TK_PARTITION_FIRST},
{"PASS", TK_PASS}, {"PASS", TK_PASS},
{"PORT", TK_PORT}, {"PORT", TK_PORT},
{"POSITION", TK_POSITION},
{"PPS", TK_PPS}, {"PPS", TK_PPS},
{"PRIMARY", TK_PRIMARY}, {"PRIMARY", TK_PRIMARY},
{"PRECISION", TK_PRECISION}, {"PRECISION", TK_PRECISION},
@ -201,6 +205,7 @@ static SKeyword keywordTable[] = {
{"QTIME", TK_QTIME}, {"QTIME", TK_QTIME},
{"QUERIES", TK_QUERIES}, {"QUERIES", TK_QUERIES},
{"QUERY", TK_QUERY}, {"QUERY", TK_QUERY},
{"PI", TK_PI},
{"RANGE", TK_RANGE}, {"RANGE", TK_RANGE},
{"RATIO", TK_RATIO}, {"RATIO", TK_RATIO},
{"PAUSE", TK_PAUSE}, {"PAUSE", TK_PAUSE},
@ -250,6 +255,8 @@ static SKeyword keywordTable[] = {
{"STT_TRIGGER", TK_STT_TRIGGER}, {"STT_TRIGGER", TK_STT_TRIGGER},
{"SUBSCRIBE", TK_SUBSCRIBE}, {"SUBSCRIBE", TK_SUBSCRIBE},
{"SUBSCRIPTIONS", TK_SUBSCRIPTIONS}, {"SUBSCRIPTIONS", TK_SUBSCRIPTIONS},
{"SUBSTR", TK_SUBSTR},
{"SUBSTRING", TK_SUBSTRING},
{"SUBTABLE", TK_SUBTABLE}, {"SUBTABLE", TK_SUBTABLE},
{"SYSINFO", TK_SYSINFO}, {"SYSINFO", TK_SYSINFO},
{"SYSTEM", TK_SYSTEM}, {"SYSTEM", TK_SYSTEM},
@ -268,6 +275,7 @@ static SKeyword keywordTable[] = {
{"TODAY", TK_TODAY}, {"TODAY", TK_TODAY},
{"TOPIC", TK_TOPIC}, {"TOPIC", TK_TOPIC},
{"TOPICS", TK_TOPICS}, {"TOPICS", TK_TOPICS},
{"TRAILING", TK_TRAILING},
{"TRANSACTION", TK_TRANSACTION}, {"TRANSACTION", TK_TRANSACTION},
{"TRANSACTIONS", TK_TRANSACTIONS}, {"TRANSACTIONS", TK_TRANSACTIONS},
{"TRIGGER", TK_TRIGGER}, {"TRIGGER", TK_TRIGGER},

File diff suppressed because it is too large Load Diff

View File

@ -54,6 +54,52 @@ typedef struct SScalarCtx {
#define SCL_DOWNGRADE_DATETYPE(_type) \ #define SCL_DOWNGRADE_DATETYPE(_type) \
((_type) == TSDB_DATA_TYPE_BIGINT || TSDB_DATA_TYPE_DOUBLE == (_type) || (_type) == TSDB_DATA_TYPE_UBIGINT) ((_type) == TSDB_DATA_TYPE_BIGINT || TSDB_DATA_TYPE_DOUBLE == (_type) || (_type) == TSDB_DATA_TYPE_UBIGINT)
/** Flags for calculateWeekNum() function. */
#define WEEK_FLAG_MONDAY_FIRST 1 /* If set this, monday is first day of week, else, sunday is first day.*/
#define WEEK_FLAG_FROM_ONE 2 /* If set this, week start from 1, else, week start from 0. */
#define WEEK_FLAG_INCLUDE_FIRST_DAY 4 /* If set this, week contains 'first day of week' is week one,
* else, weeks are numbered according to ISO 8601:1988. */
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288 /* pi */
#endif
#ifndef M_1_PI
#define M_1_PI 0.318309886183790671537767526745028724 /* 1/pi */
#endif
#define INT1TOCHAR(T, A) \
{ \
const unsigned long def_temp = (unsigned long)(A); \
((unsigned char *)(T))[0] = (unsigned char)(def_temp); \
T += 1; \
}
#define INT2TOCHAR(T, A) \
{ \
const unsigned long def_temp = (unsigned long)(A); \
((unsigned char *)(T))[1] = (unsigned char)(def_temp); \
((unsigned char *)(T))[0] = (unsigned char)(def_temp >> 8); \
T += 2; \
}
#define INT3TOCHAR(T, A) \
{ \
const unsigned long def_temp = (unsigned long)(A); \
((unsigned char *)(T))[2] = (unsigned char)(def_temp); \
((unsigned char *)(T))[1] = (unsigned char)(def_temp >> 8); \
((unsigned char *)(T))[0] = (unsigned char)(def_temp >> 16); \
T += 3; \
}
#define INT4TOCHAR(T, A) \
{ \
const unsigned long def_temp = (unsigned long)(A); \
((unsigned char *)(T))[3] = (unsigned char)(def_temp); \
((unsigned char *)(T))[2] = (unsigned char)(def_temp >> 8); \
((unsigned char *)(T))[1] = (unsigned char)(def_temp >> 16); \
((unsigned char *)(T))[0] = (unsigned char)(def_temp >> 24); \
T += 4; \
}
#define sclFatal(...) qFatal(__VA_ARGS__) #define sclFatal(...) qFatal(__VA_ARGS__)
#define sclError(...) qError(__VA_ARGS__) #define sclError(...) qError(__VA_ARGS__)
#define sclWarn(...) qWarn(__VA_ARGS__) #define sclWarn(...) qWarn(__VA_ARGS__)

File diff suppressed because it is too large Load Diff

View File

@ -723,6 +723,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_TIME_UNIT_INVALID, "Invalid function tim
TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_TIME_UNIT_TOO_SMALL, "Function time unit cannot be smaller than db precision") TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_TIME_UNIT_TOO_SMALL, "Function time unit cannot be smaller than db precision")
TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_INVALID_VALUE_RANGE, "Function got invalid value range") TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_INVALID_VALUE_RANGE, "Function got invalid value range")
TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_SETUP_ERROR, "Function set up failed") TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_SETUP_ERROR, "Function set up failed")
TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_INVALID_RES_LENGTH, "Function result exceed max length")
//udf //udf
TAOS_DEFINE_ERROR(TSDB_CODE_UDF_STOPPING, "udf is stopping") TAOS_DEFINE_ERROR(TSDB_CODE_UDF_STOPPING, "udf is stopping")

View File

@ -262,9 +262,9 @@ class TDTestCase(TBase):
sql1 = f"select substr(bin,1) from {self.db}.d0 order by ts desc limit 100" sql1 = f"select substr(bin,1) from {self.db}.d0 order by ts desc limit 100"
sql2 = f"select bin from {self.db}.d0 order by ts desc limit 100" sql2 = f"select bin from {self.db}.d0 order by ts desc limit 100"
self.checkSameResult(sql1, sql2) self.checkSameResult(sql1, sql2)
#substr error input pos is zero
sql = f"select substr(bin,0,3) from {self.db}.d0 order by ts desc limit 100" sql = f"select substr(bin,0,3) from {self.db}.d0 order by ts desc limit 100"
tdSql.error(sql) tdSql.query(sql)
tdSql.checkData(0, 0, "")
# cast # cast
nch = 99 nch = 99

View File

@ -13,7 +13,7 @@ sql insert into tb1 values ('2022-07-10 16:31:00', 1, '1');
sql insert into tb1 values ('2022-07-10 16:32:00', 2, '2'); sql insert into tb1 values ('2022-07-10 16:32:00', 2, '2');
sql insert into tb1 values ('2022-07-10 16:33:00', 3, '3'); sql insert into tb1 values ('2022-07-10 16:33:00', 3, '3');
sql insert into tb1 values ('2022-07-10 16:34:00', 4, '4'); sql insert into tb1 values ('2022-07-10 16:34:00', 4, '4');
sql select * from (select ts,TIMETRUNCATE(ts,1d),TIMETRUNCATE(ts,1h),timediff(TIMETRUNCATE(ts,1d),TIMETRUNCATE(ts,1h),1h) as td from tb1 where ts >='2022-06-01 00:00:00' and ts <='2022-11-3 23:59:59' ) t where td >12; sql select * from (select ts,TIMETRUNCATE(ts,1d),TIMETRUNCATE(ts,1h), abs(timediff(TIMETRUNCATE(ts,1d),TIMETRUNCATE(ts,1h),1h)) as td from tb1 where ts >='2022-06-01 00:00:00' and ts <='2022-11-3 23:59:59' ) t where td >12;
if $rows != 4 then if $rows != 4 then
return -1 return -1
endi endi

View File

@ -176,52 +176,52 @@ class TDTestCase:
def checkTimeMacro(self): def checkTimeMacro(self):
# 2 week # 2 week
val = 2 val = 2
nsval = val*7*24*60*60*1000*1000*1000 nsval = -val*7*24*60*60*1000*1000*1000
expectVal = self.childCnt * self.childRow expectVal = self.childCnt * self.childRow
sql = f"select count(ts) from st where timediff(ts - {val}w, ts1) = {nsval} " sql = f"select count(ts) from st where timediff(ts - {val}w, ts1) = {nsval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)
# 20 day # 20 day
val = 20 val = 20
nsval = val*24*60*60*1000*1000*1000 nsval = -val*24*60*60*1000*1000*1000
uint = "d" uint = "d"
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} " sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)
# 30 hour # 30 hour
val = 30 val = 30
nsval = val*60*60*1000*1000*1000 nsval = -val*60*60*1000*1000*1000
uint = "h" uint = "h"
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} " sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)
# 90 minutes # 90 minutes
val = 90 val = 90
nsval = val*60*1000*1000*1000 nsval = -val*60*1000*1000*1000
uint = "m" uint = "m"
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} " sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)
# 2s # 2s
val = 2 val = 2
nsval = val*1000*1000*1000 nsval = -val*1000*1000*1000
uint = "s" uint = "s"
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} " sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)
# 20a # 20a
val = 5 val = 5
nsval = val*1000*1000 nsval = -val*1000*1000
uint = "a" uint = "a"
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} " sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)
# 300u # 300u
val = 300 val = 300
nsval = val*1000 nsval = -val*1000
uint = "u" uint = "u"
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} " sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)
# 8b # 8b
val = 8 val = 8
sql = f"select timediff(ts - {val}b, ts1) from st " sql = f"select timediff(ts1, ts - {val}b) from st "
self.checkExpect(sql, val) self.checkExpect(sql, val)
# timetruncate check # timetruncate check
@ -249,14 +249,14 @@ class TDTestCase:
timediff(ts,ts+1w,1w) timediff(ts,ts+1w,1w)
from t0 order by ts desc limit 1;''' from t0 order by ts desc limit 1;'''
tdSql.query(sql) tdSql.query(sql)
tdSql.checkData(0,1, 1) tdSql.checkData(0,1, -1)
tdSql.checkData(0,2, 1) tdSql.checkData(0,2, -1)
tdSql.checkData(0,3, 1) tdSql.checkData(0,3, -1)
tdSql.checkData(0,4, 1) tdSql.checkData(0,4, -1)
tdSql.checkData(0,5, 1) tdSql.checkData(0,5, -1)
tdSql.checkData(0,6, 1) tdSql.checkData(0,6, -1)
tdSql.checkData(0,7, 1) tdSql.checkData(0,7, -1)
tdSql.checkData(0,8, 1) tdSql.checkData(0,8, -1)
# init # init
def init(self, conn, logSql, replicaVar=1): def init(self, conn, logSql, replicaVar=1):

View File

@ -174,46 +174,46 @@ class TDTestCase:
def checkTimeMacro(self): def checkTimeMacro(self):
# 2 week # 2 week
val = 2 val = 2
usval = val*7*24*60*60*1000*1000 usval = -val*7*24*60*60*1000*1000
expectVal = self.childCnt * self.childRow expectVal = self.childCnt * self.childRow
sql = f"select count(ts) from st where timediff(ts - {val}w, ts1) = {usval} " sql = f"select count(ts) from st where timediff(ts - {val}w, ts1) = {usval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)
# 20 day # 20 day
val = 20 val = 20
usval = val*24*60*60*1000*1000 usval = -val*24*60*60*1000*1000
uint = "d" uint = "d"
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} " sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)
# 30 hour # 30 hour
val = 30 val = 30
usval = val*60*60*1000*1000 usval = -val*60*60*1000*1000
uint = "h" uint = "h"
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} " sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)
# 90 minutes # 90 minutes
val = 90 val = 90
usval = val*60*1000*1000 usval = -val*60*1000*1000
uint = "m" uint = "m"
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} " sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)
# 2s # 2s
val = 2 val = 2
usval = val*1000*1000 usval = -val*1000*1000
uint = "s" uint = "s"
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} " sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)
# 20a # 20a
val = 20 val = 20
usval = val*1000 usval = -val*1000
uint = "a" uint = "a"
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} " sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)
# 300u # 300u
val = 300 val = 300
usval = val*1 usval = -val*1
uint = "u" uint = "u"
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} " sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} "
self.checkExpect(sql, expectVal) self.checkExpect(sql, expectVal)

View File

@ -178,8 +178,8 @@ class TDTestCase:
queryparam[0].binary('中文字符') queryparam[0].binary('中文字符')
rows=self.stmtExe(conn,"select CHAR_LENGTH(?) from log ",queryparam) rows=self.stmtExe(conn,"select CHAR_LENGTH(?) from log ",queryparam)
tdLog.debug("assert 4th case %s"%rows) tdLog.debug("assert 4th case %s"%rows)
assert rows[0][0] == 12, '4th case is failed' assert rows[0][0] == 4, '4th case is failed'
assert rows[1][0] == 12, '4th case is failed' assert rows[1][0] == 4, '4th case is failed'
queryparam=new_bind_params(1) queryparam=new_bind_params(1)
queryparam[0].binary('123') queryparam[0].binary('123')
@ -209,8 +209,8 @@ class TDTestCase:
queryparam[0].timestamp(1626861392591112) queryparam[0].timestamp(1626861392591112)
rows=self.stmtExe(conn,"select timediff('2021-07-21 17:56:32.590111',?,1a) from log",queryparam) rows=self.stmtExe(conn,"select timediff('2021-07-21 17:56:32.590111',?,1a) from log",queryparam)
tdLog.debug("assert 7th case %s"%rows) tdLog.debug("assert 7th case %s"%rows)
assert rows[0][0] == 1, '7th case is failed' assert rows[0][0] == -1, '7th case is failed'
assert rows[1][0] == 1, '7th case is failed' assert rows[1][0] == -1, '7th case is failed'
#query: aggregate Functions #query: aggregate Functions
queryparam=new_bind_params(1) queryparam=new_bind_params(1)

View File

@ -99,8 +99,8 @@ class TDTestCase:
# f"select round(tbname+1) from {dbname}.t1 ", # f"select round(tbname+1) from {dbname}.t1 ",
f"select round(123--123)==1 from {dbname}.t1", f"select round(123--123)==1 from {dbname}.t1",
f"select round(c1) as 'd1' from {dbname}.t1", f"select round(c1) as 'd1' from {dbname}.t1",
f"select round(c1 ,c2 ) from {dbname}.t1", # f"select round(c1 ,c2 ) from {dbname}.t1",
f"select round(c1 ,NULL) from {dbname}.t1", # f"select round(c1 ,NULL) from {dbname}.t1",
f"select round(,) from {dbname}.t1;", f"select round(,) from {dbname}.t1;",
f"select round(round(c1) ab from {dbname}.t1)", f"select round(round(c1) ab from {dbname}.t1)",
f"select round(c1) as int from {dbname}.t1", f"select round(c1) as int from {dbname}.t1",
@ -113,8 +113,8 @@ class TDTestCase:
# f"select round(tbname+1) from {dbname}.stb1 ", # f"select round(tbname+1) from {dbname}.stb1 ",
f"select round(123--123)==1 from {dbname}.stb1", f"select round(123--123)==1 from {dbname}.stb1",
f"select round(c1) as 'd1' from {dbname}.stb1", f"select round(c1) as 'd1' from {dbname}.stb1",
f"select round(c1 ,c2 ) from {dbname}.stb1", # f"select round(c1 ,c2 ) from {dbname}.stb1",
f"select round(c1 ,NULL) from {dbname}.stb1", # f"select round(c1 ,NULL) from {dbname}.stb1",
f"select round(,) from {dbname}.stb1;", f"select round(,) from {dbname}.stb1;",
f"select round(round(c1) ab from {dbname}.stb1)", f"select round(round(c1) ab from {dbname}.stb1)",
f"select round(c1) as int from {dbname}.stb1" f"select round(c1) as int from {dbname}.stb1"

View File

@ -79,7 +79,7 @@ class TDTestCase:
groups = ["", substr_group_having, substr_group_no_having] groups = ["", substr_group_having, substr_group_no_having]
if pos < 1: if pos < 1:
tdSql.error(f"select substr( {condition}, {pos}, {lens}) , {condition} from {tbname} ") tdSql.query(f"select substr( {condition}, {pos}, {lens}) , {condition} from {tbname} ")
break break
tdSql.query(f"select substr( {condition}, {pos}, {lens}) , {condition} from {tbname} ") tdSql.query(f"select substr( {condition}, {pos}, {lens}) , {condition} from {tbname} ")