未验证 提交 e6058244 编写于 作者: S shenglian-zhou 提交者: GitHub

Merge pull request #10352 from taosdata/feature/TD-11220

 [TD-11220]<feature>(query): time related functions
......@@ -70,6 +70,10 @@ int tsParseTime(SStrToken *pToken, int64_t *time, char **next, char *error, int1
if (pToken->type == TK_NOW) {
useconds = taosGetTimestamp(timePrec);
} else if (pToken->type == TK_TODAY) {
int64_t factor = (timePrec == TSDB_TIME_PRECISION_MILLI) ? 1000 :
(timePrec == TSDB_TIME_PRECISION_MICRO) ? 1000000 : 1000000000;
useconds = taosGetTimestampToday() * factor;
} else if (strncmp(pToken->z, "0", 1) == 0 && pToken->n == 1) {
// do nothing
} else if (pToken->type == TK_INTEGER) {
......@@ -473,7 +477,7 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, int16_t timePrec, i
}
int16_t type = sToken.type;
if ((type != TK_NOW && type != TK_INTEGER && type != TK_STRING && type != TK_FLOAT && type != TK_BOOL &&
if ((type != TK_NOW && type != TK_TODAY && type != TK_INTEGER && type != TK_STRING && type != TK_FLOAT && type != TK_BOOL &&
type != TK_NULL && type != TK_HEX && type != TK_OCT && type != TK_BIN) ||
(sToken.n == 0) || (type == TK_RP)) {
return tscSQLSyntaxErrMsg(pInsertParam->msg, "invalid data or symbol", sToken.z);
......
......@@ -1861,7 +1861,7 @@ static int32_t handleScalarTypeExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32
if (tscGetErrorMsgLength(pCmd) > 0) {
return ret;
}
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
......@@ -1872,7 +1872,7 @@ static int32_t handleScalarTypeExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32
if (TSDB_COL_IS_TAG(pIndex->flag)) {
tExprTreeDestroy(pNode, NULL);
taosArrayDestroy(&colList);
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
}
......@@ -1884,7 +1884,7 @@ static int32_t handleScalarTypeExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32
if (tscGetErrorMsgLength(pCmd) > 0) {
return ret;
}
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
......@@ -5075,8 +5075,8 @@ static int32_t validateSQLExprItem(SSqlCmd* pCmd, tSqlExpr* pExpr,
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
//now allowing now +/- value in select expr
if (pExpr->tokenId == TK_TIMESTAMP) {
//not allowing now/today keyword arithmetic operation in select expr
if (pExpr->exprToken.type == TK_NOW || pExpr->exprToken.type == TK_TODAY) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
......@@ -5455,6 +5455,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
}else{
colName = &(pLeft->columnName);
}
int32_t ret = TSDB_CODE_SUCCESS;
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
......@@ -5695,7 +5696,7 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr
if (columnLeft && columnRight) {
setNormalExprToCond(&columnLeft, columnRight, (*pExpr)->tokenId);
*columnExpr = columnLeft;
} else {
*columnExpr = columnLeft ? columnLeft : columnRight;
......@@ -5703,7 +5704,7 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr
if (tsLeft && tsRight) {
setNormalExprToCond(&tsLeft, tsRight, (*pExpr)->tokenId);
*tsExpr = tsLeft;
} else {
*tsExpr = tsLeft ? tsLeft : tsRight;
......@@ -5713,7 +5714,7 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr
*type = leftType|rightType;
}
*tbIdx = (leftTbIdx == rightTbIdx) ? leftTbIdx : -1;
return TSDB_CODE_SUCCESS;
}
......@@ -5735,9 +5736,9 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr
}
return TSDB_CODE_SUCCESS;
err_ret:
tSqlExprDestroy(columnLeft);
tSqlExprDestroy(columnRight);
tSqlExprDestroy(tsLeft);
......@@ -5750,7 +5751,7 @@ static void doExtractExprForSTable(SSqlCmd* pCmd, tSqlExpr** pExpr, SQueryInfo*
*pOut = NULL;
return;
}
if (tSqlExprIsParentOfLeaf(*pExpr)) {
tSqlExpr* pLeft = (*pExpr)->pLeft;
......@@ -10436,6 +10437,10 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
(*pExpr)->pVal = calloc(1, sizeof(tVariant));
tVariantAssign((*pExpr)->pVal, &pSqlExpr->value);
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pQueryInfo->curTableIdx);
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
(*pExpr)->precision = tinfo.precision;
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, pQueryInfo->curTableIdx)->pTableMeta;
if (pCols != NULL) {
size_t colSize = taosArrayGetSize(pCols);
......@@ -10598,6 +10603,11 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
*pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TSQL_NODE_FUNC;
(*pExpr)->_func.functionId = pSqlExpr->functionId;
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pQueryInfo->curTableIdx);
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
(*pExpr)->precision = tinfo.precision;
SArray* paramList = pSqlExpr->Expr.paramList;
size_t paramSize = paramList ? taosArrayGetSize(paramList) : 0;
if (paramSize > 0) {
......
......@@ -47,30 +47,38 @@ struct SSchema;
///////////////////////////////////////////
// SCALAR FUNCTIONS
#define TSDB_FUNC_SCALAR_POW (TSDB_FUNC_FLAG_SCALAR | 0x0000)
#define TSDB_FUNC_SCALAR_LOG (TSDB_FUNC_FLAG_SCALAR | 0x0001)
#define TSDB_FUNC_SCALAR_ABS (TSDB_FUNC_FLAG_SCALAR | 0x0002)
#define TSDB_FUNC_SCALAR_ACOS (TSDB_FUNC_FLAG_SCALAR | 0x0003)
#define TSDB_FUNC_SCALAR_ASIN (TSDB_FUNC_FLAG_SCALAR | 0x0004)
#define TSDB_FUNC_SCALAR_ATAN (TSDB_FUNC_FLAG_SCALAR | 0x0005)
#define TSDB_FUNC_SCALAR_COS (TSDB_FUNC_FLAG_SCALAR | 0x0006)
#define TSDB_FUNC_SCALAR_SIN (TSDB_FUNC_FLAG_SCALAR | 0x0007)
#define TSDB_FUNC_SCALAR_TAN (TSDB_FUNC_FLAG_SCALAR | 0x0008)
#define TSDB_FUNC_SCALAR_SQRT (TSDB_FUNC_FLAG_SCALAR | 0x0009)
#define TSDB_FUNC_SCALAR_CEIL (TSDB_FUNC_FLAG_SCALAR | 0x000A)
#define TSDB_FUNC_SCALAR_FLOOR (TSDB_FUNC_FLAG_SCALAR | 0x000B)
#define TSDB_FUNC_SCALAR_ROUND (TSDB_FUNC_FLAG_SCALAR | 0x000C)
#define TSDB_FUNC_SCALAR_CONCAT (TSDB_FUNC_FLAG_SCALAR | 0x000D)
#define TSDB_FUNC_SCALAR_LENGTH (TSDB_FUNC_FLAG_SCALAR | 0x000E)
#define TSDB_FUNC_SCALAR_CONCAT_WS (TSDB_FUNC_FLAG_SCALAR | 0x000F)
#define TSDB_FUNC_SCALAR_CHAR_LENGTH (TSDB_FUNC_FLAG_SCALAR | 0x0010)
#define TSDB_FUNC_SCALAR_CAST (TSDB_FUNC_FLAG_SCALAR | 0x0011)
#define TSDB_FUNC_SCALAR_LOWER (TSDB_FUNC_FLAG_SCALAR | 0x0012)
#define TSDB_FUNC_SCALAR_UPPER (TSDB_FUNC_FLAG_SCALAR | 0x0013)
#define TSDB_FUNC_SCALAR_LTRIM (TSDB_FUNC_FLAG_SCALAR | 0x0014)
#define TSDB_FUNC_SCALAR_RTRIM (TSDB_FUNC_FLAG_SCALAR | 0x0015)
#define TSDB_FUNC_SCALAR_SUBSTR (TSDB_FUNC_FLAG_SCALAR | 0x0016)
#define TSDB_FUNC_SCALAR_NUM_FUNCTIONS 23
#define TSDB_FUNC_SCALAR_POW (TSDB_FUNC_FLAG_SCALAR | 0x0000)
#define TSDB_FUNC_SCALAR_LOG (TSDB_FUNC_FLAG_SCALAR | 0x0001)
#define TSDB_FUNC_SCALAR_ABS (TSDB_FUNC_FLAG_SCALAR | 0x0002)
#define TSDB_FUNC_SCALAR_ACOS (TSDB_FUNC_FLAG_SCALAR | 0x0003)
#define TSDB_FUNC_SCALAR_ASIN (TSDB_FUNC_FLAG_SCALAR | 0x0004)
#define TSDB_FUNC_SCALAR_ATAN (TSDB_FUNC_FLAG_SCALAR | 0x0005)
#define TSDB_FUNC_SCALAR_COS (TSDB_FUNC_FLAG_SCALAR | 0x0006)
#define TSDB_FUNC_SCALAR_SIN (TSDB_FUNC_FLAG_SCALAR | 0x0007)
#define TSDB_FUNC_SCALAR_TAN (TSDB_FUNC_FLAG_SCALAR | 0x0008)
#define TSDB_FUNC_SCALAR_SQRT (TSDB_FUNC_FLAG_SCALAR | 0x0009)
#define TSDB_FUNC_SCALAR_CEIL (TSDB_FUNC_FLAG_SCALAR | 0x000A)
#define TSDB_FUNC_SCALAR_FLOOR (TSDB_FUNC_FLAG_SCALAR | 0x000B)
#define TSDB_FUNC_SCALAR_ROUND (TSDB_FUNC_FLAG_SCALAR | 0x000C)
#define TSDB_FUNC_SCALAR_CONCAT (TSDB_FUNC_FLAG_SCALAR | 0x000D)
#define TSDB_FUNC_SCALAR_LENGTH (TSDB_FUNC_FLAG_SCALAR | 0x000E)
#define TSDB_FUNC_SCALAR_CONCAT_WS (TSDB_FUNC_FLAG_SCALAR | 0x000F)
#define TSDB_FUNC_SCALAR_CHAR_LENGTH (TSDB_FUNC_FLAG_SCALAR | 0x0010)
#define TSDB_FUNC_SCALAR_CAST (TSDB_FUNC_FLAG_SCALAR | 0x0011)
#define TSDB_FUNC_SCALAR_LOWER (TSDB_FUNC_FLAG_SCALAR | 0x0012)
#define TSDB_FUNC_SCALAR_UPPER (TSDB_FUNC_FLAG_SCALAR | 0x0013)
#define TSDB_FUNC_SCALAR_LTRIM (TSDB_FUNC_FLAG_SCALAR | 0x0014)
#define TSDB_FUNC_SCALAR_RTRIM (TSDB_FUNC_FLAG_SCALAR | 0x0015)
#define TSDB_FUNC_SCALAR_SUBSTR (TSDB_FUNC_FLAG_SCALAR | 0x0016)
#define TSDB_FUNC_SCALAR_NOW (TSDB_FUNC_FLAG_SCALAR | 0x0017)
#define TSDB_FUNC_SCALAR_TODAY (TSDB_FUNC_FLAG_SCALAR | 0x0018)
#define TSDB_FUNC_SCALAR_TIMEZONE (TSDB_FUNC_FLAG_SCALAR | 0x0019)
#define TSDB_FUNC_SCALAR_TO_ISO8601 (TSDB_FUNC_FLAG_SCALAR | 0x001A)
#define TSDB_FUNC_SCALAR_TO_UNIXTIMESTAMP (TSDB_FUNC_FLAG_SCALAR | 0x001B)
#define TSDB_FUNC_SCALAR_TIMETRUNCATE (TSDB_FUNC_FLAG_SCALAR | 0x001C)
#define TSDB_FUNC_SCALAR_TIMEDIFF (TSDB_FUNC_FLAG_SCALAR | 0x001D)
#define TSDB_FUNC_SCALAR_NUM_FUNCTIONS 30
#define TSDB_FUNC_SCALAR_NAME_MAX_LEN 16
......@@ -143,6 +151,7 @@ typedef struct tExprNode {
};
int16_t resultType;
int16_t resultBytes;
int32_t precision;
} tExprNode;
typedef struct SExprTraverseSupp {
......
......@@ -92,6 +92,9 @@ double getVectorDoubleValue_FLOAT(void *src, int32_t index) {
double getVectorDoubleValue_DOUBLE(void *src, int32_t index) {
return (double)*((double *)src + index);
}
int64_t getVectorTimestampValue(void *src, int32_t index) {
return (int64_t)*((int64_t *)src + index);
}
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) {
_arithmetic_getVectorDoubleValue_fn_t p = NULL;
if(srcType==TSDB_DATA_TYPE_TINYINT) {
......@@ -176,6 +179,8 @@ _arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) {
p = getVectorValueAddr_FLOAT;
}else if(srcType==TSDB_DATA_TYPE_DOUBLE) {
p = getVectorValueAddr_DOUBLE;
}else if(srcType==TSDB_DATA_TYPE_TIMESTAMP) {
p = getVectorValueAddr_BIGINT;
}else {
assert(0);
}
......@@ -185,35 +190,68 @@ _arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) {
void vectorAdd(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
double *output=(double*)out;
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
if ((len1) == (len2)) {
for (; i < (len2) && i >= 0; i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_DOUBLE_NULL(output);
continue;
if (!IS_TIMESTAMP_TYPE(_left_type) && !IS_TIMESTAMP_TYPE(_right_type)) {
double *output = (double*)out;
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
if ((len1) == (len2)) {
for (; i < (len2) && i >= 0; i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_DOUBLE_NULL(output);
continue;
}
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) + getVectorDoubleValueFnRight(right,i));
}
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) + getVectorDoubleValueFnRight(right,i));
}
} else if ((len1) == 1) {
for (; i >= 0 && i < (len2); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_DOUBLE_NULL(output);
continue;
} else if ((len1) == 1) {
for (; i >= 0 && i < (len2); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_DOUBLE_NULL(output);
continue;
}
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) + getVectorDoubleValueFnRight(right,i));
}
} else if ((len2) == 1) {
for (; i >= 0 && i < (len1); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
SET_DOUBLE_NULL(output);
continue;
}
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) + getVectorDoubleValueFnRight(right,0));
}
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) + getVectorDoubleValueFnRight(right,i));
}
} else if ((len2) == 1) {
for (; i >= 0 && i < (len1); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
SET_DOUBLE_NULL(output);
continue;
} else {
int64_t *output = (int64_t *)out;
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
if ((len1) == (len2)) {
for (; i < (len2) && i >= 0; i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_TIMESTAMP_NULL(output);
continue;
}
SET_TIMESTAMP_VAL(output, getVectorTimestampValue(left,i) + getVectorTimestampValue(right,i));
}
} else if ((len1) == 1) {
for (; i >= 0 && i < (len2); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_TIMESTAMP_NULL(output);
continue;
}
SET_TIMESTAMP_VAL(output, getVectorTimestampValue(left,0) + getVectorTimestampValue(right,i));
}
} else if ((len2) == 1) {
for (; i >= 0 && i < (len1); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
SET_TIMESTAMP_NULL(output);
continue;
}
SET_TIMESTAMP_VAL(output, getVectorTimestampValue(left,i) + getVectorTimestampValue(right,0));
}
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) + getVectorDoubleValueFnRight(right,0));
}
}
}
......@@ -221,35 +259,68 @@ void vectorAdd(void *left, int32_t len1, int32_t _left_type, void *right, int32_
void vectorSub(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
double *output=(double*)out;
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
if ((len1) == (len2)) {
for (; i < (len2) && i >= 0; i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_DOUBLE_NULL(output);
continue;
if (!IS_TIMESTAMP_TYPE(_left_type) && !IS_TIMESTAMP_TYPE(_right_type)) {
double *output=(double*)out;
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
if ((len1) == (len2)) {
for (; i < (len2) && i >= 0; i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_DOUBLE_NULL(output);
continue;
}
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) - getVectorDoubleValueFnRight(right,i));
}
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) - getVectorDoubleValueFnRight(right,i));
}
} else if ((len1) == 1) {
for (; i >= 0 && i < (len2); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_DOUBLE_NULL(output);
continue;
} else if ((len1) == 1) {
for (; i >= 0 && i < (len2); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_DOUBLE_NULL(output);
continue;
}
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) - getVectorDoubleValueFnRight(right,i));
}
} else if ((len2) == 1) {
for (; i >= 0 && i < (len1); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
SET_DOUBLE_NULL(output);
continue;
}
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) - getVectorDoubleValueFnRight(right,0));
}
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) - getVectorDoubleValueFnRight(right,i));
}
} else if ((len2) == 1) {
for (; i >= 0 && i < (len1); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
SET_DOUBLE_NULL(output);
continue;
} else {
int64_t *output = (int64_t *)out;
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
if ((len1) == (len2)) {
for (; i < (len2) && i >= 0; i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_TIMESTAMP_NULL(output);
continue;
}
SET_TIMESTAMP_VAL(output, getVectorTimestampValue(left,i) - getVectorTimestampValue(right,i));
}
} else if ((len1) == 1) {
for (; i >= 0 && i < (len2); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_TIMESTAMP_NULL(output);
continue;
}
SET_TIMESTAMP_VAL(output, getVectorTimestampValue(left,0) - getVectorTimestampValue(right,i));
}
} else if ((len2) == 1) {
for (; i >= 0 && i < (len1); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
SET_TIMESTAMP_NULL(output);
continue;
}
SET_TIMESTAMP_VAL(output, getVectorTimestampValue(left,i) - getVectorTimestampValue(right,0));
}
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) - getVectorDoubleValueFnRight(right,0));
}
}
}
......
此差异已折叠。
......@@ -93,6 +93,8 @@ void tVariantCreateExt(tVariant *pVar, SStrToken *token, int32_t optrType, bool
case TSDB_DATA_TYPE_TIMESTAMP: {
if (optrType == TK_NOW) {
pVar->i64 = taosGetTimestamp(TSDB_TIME_PRECISION_NANO);
} else if (optrType == TK_TODAY) {
pVar->i64 = taosGetTimestampToday() * 1000000000;
} else if (optrType == TK_PLUS || optrType == TK_MINUS) {
char unit = 0;
ret = parseAbsoluteDuration(token->z, token->n, &pVar->i64, &unit, TSDB_TIME_PRECISION_NANO);
......@@ -282,7 +284,7 @@ void tVariantAssign(tVariant *pDst, const tVariant *pSrc) {
}
if (IS_NUMERIC_TYPE(pSrc->nType) || (pSrc->nType == TSDB_DATA_TYPE_BOOL)) {
if (IS_NUMERIC_TYPE(pSrc->nType) || IS_TIMESTAMP_TYPE(pSrc->nType) || (pSrc->nType == TSDB_DATA_TYPE_BOOL)) {
pDst->i64 = pSrc->i64;
} else if (pSrc->nType == TSDB_DATA_TYPE_POINTER_ARRAY) { // this is only for string array
size_t num = taosArrayGetSize(pSrc->arr);
......@@ -540,7 +542,7 @@ static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result
}
errno = 0;
if (IS_SIGNED_NUMERIC_TYPE(pVariant->nType) || (pVariant->nType == TSDB_DATA_TYPE_BOOL)) {
if (IS_SIGNED_NUMERIC_TYPE(pVariant->nType) || IS_TIMESTAMP_TYPE(pVariant->nType) || (pVariant->nType == TSDB_DATA_TYPE_BOOL)) {
*result = pVariant->i64;
} else if (IS_UNSIGNED_NUMERIC_TYPE(pVariant->nType)) {
*result = pVariant->u64;
......
......@@ -106,6 +106,11 @@ extern const int32_t TYPE_BYTES[16];
#define TSDB_TIME_PRECISION_MICRO_STR "us"
#define TSDB_TIME_PRECISION_NANO_STR "ns"
#define TSDB_TIME_PRECISION_SEC_DIGITS 10
#define TSDB_TIME_PRECISION_MILLI_DIGITS 13
#define TSDB_TIME_PRECISION_MICRO_DIGITS 16
#define TSDB_TIME_PRECISION_NANO_DIGITS 19
#define TSDB_TICK_PER_SECOND(precision) ((int64_t)((precision)==TSDB_TIME_PRECISION_MILLI ? 1e3L : ((precision)==TSDB_TIME_PRECISION_MICRO ? 1e6L : 1e9L)))
#define T_MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
......@@ -133,19 +138,21 @@ do { \
float taos_align_get_float(const char* pBuf);
double taos_align_get_double(const char* pBuf);
#define GET_FLOAT_VAL(x) taos_align_get_float(x)
#define GET_DOUBLE_VAL(x) taos_align_get_double(x)
#define SET_FLOAT_VAL(x, y) { float z = (float)(y); (*(int32_t*) x = *(int32_t*)(&z)); }
#define SET_DOUBLE_VAL(x, y) { double z = (double)(y); (*(int64_t*) x = *(int64_t*)(&z)); }
#define SET_FLOAT_PTR(x, y) { (*(int32_t*) x = *(int32_t*)y); }
#define SET_DOUBLE_PTR(x, y) { (*(int64_t*) x = *(int64_t*)y); }
#define GET_FLOAT_VAL(x) taos_align_get_float(x)
#define GET_DOUBLE_VAL(x) taos_align_get_double(x)
#define SET_FLOAT_VAL(x, y) { float z = (float)(y); (*(int32_t*) x = *(int32_t*)(&z)); }
#define SET_DOUBLE_VAL(x, y) { double z = (double)(y); (*(int64_t*) x = *(int64_t*)(&z)); }
#define SET_TIMESTAMP_VAL(x, y) { int64_t z = (int64_t)(y); (*(int64_t*) x = *(int64_t*)(&z)); }
#define SET_FLOAT_PTR(x, y) { (*(int32_t*) x = *(int32_t*)y); }
#define SET_DOUBLE_PTR(x, y) { (*(int64_t*) x = *(int64_t*)y); }
#else
#define GET_FLOAT_VAL(x) (*(float *)(x))
#define GET_DOUBLE_VAL(x) (*(double *)(x))
#define SET_FLOAT_VAL(x, y) { (*(float *)(x)) = (float)(y); }
#define SET_DOUBLE_VAL(x, y) { (*(double *)(x)) = (double)(y); }
#define SET_FLOAT_PTR(x, y) { (*(float *)(x)) = (*(float *)(y)); }
#define SET_DOUBLE_PTR(x, y) { (*(double *)(x)) = (*(double *)(y)); }
#define GET_FLOAT_VAL(x) (*(float *)(x))
#define GET_DOUBLE_VAL(x) (*(double *)(x))
#define SET_FLOAT_VAL(x, y) { (*(float *)(x)) = (float)(y); }
#define SET_DOUBLE_VAL(x, y) { (*(double *)(x)) = (double)(y); }
#define SET_TIMESTAMP_VAL(x, y) { (*(int64_t *)(x)) = (int64_t)(y); }
#define SET_FLOAT_PTR(x, y) { (*(float *)(x)) = (*(float *)(y)); }
#define SET_DOUBLE_PTR(x, y) { (*(double *)(x)) = (*(double *)(y)); }
#endif
// TODO: check if below is necessary
......
......@@ -163,61 +163,62 @@
#define TK_SLIMIT 145
#define TK_SOFFSET 146
#define TK_WHERE 147
#define TK_RESET 148
#define TK_QUERY 149
#define TK_SYNCDB 150
#define TK_ADD 151
#define TK_COLUMN 152
#define TK_MODIFY 153
#define TK_TAG 154
#define TK_CHANGE 155
#define TK_SET 156
#define TK_KILL 157
#define TK_CONNECTION 158
#define TK_STREAM 159
#define TK_COLON 160
#define TK_ABORT 161
#define TK_AFTER 162
#define TK_ATTACH 163
#define TK_BEFORE 164
#define TK_BEGIN 165
#define TK_CASCADE 166
#define TK_CLUSTER 167
#define TK_CONFLICT 168
#define TK_COPY 169
#define TK_DEFERRED 170
#define TK_DELIMITERS 171
#define TK_DETACH 172
#define TK_EACH 173
#define TK_END 174
#define TK_EXPLAIN 175
#define TK_FAIL 176
#define TK_FOR 177
#define TK_IGNORE 178
#define TK_IMMEDIATE 179
#define TK_INITIALLY 180
#define TK_INSTEAD 181
#define TK_KEY 182
#define TK_OF 183
#define TK_RAISE 184
#define TK_REPLACE 185
#define TK_RESTRICT 186
#define TK_ROW 187
#define TK_STATEMENT 188
#define TK_TRIGGER 189
#define TK_VIEW 190
#define TK_IPTOKEN 191
#define TK_SEMI 192
#define TK_NONE 193
#define TK_PREV 194
#define TK_LINEAR 195
#define TK_IMPORT 196
#define TK_TBNAME 197
#define TK_JOIN 198
#define TK_INSERT 199
#define TK_INTO 200
#define TK_VALUES 201
#define TK_FILE 202
#define TK_TODAY 148
#define TK_RESET 149
#define TK_QUERY 150
#define TK_SYNCDB 151
#define TK_ADD 152
#define TK_COLUMN 153
#define TK_MODIFY 154
#define TK_TAG 155
#define TK_CHANGE 156
#define TK_SET 157
#define TK_KILL 158
#define TK_CONNECTION 159
#define TK_STREAM 160
#define TK_COLON 161
#define TK_ABORT 162
#define TK_AFTER 163
#define TK_ATTACH 164
#define TK_BEFORE 165
#define TK_BEGIN 166
#define TK_CASCADE 167
#define TK_CLUSTER 168
#define TK_CONFLICT 169
#define TK_COPY 170
#define TK_DEFERRED 171
#define TK_DELIMITERS 172
#define TK_DETACH 173
#define TK_EACH 174
#define TK_END 175
#define TK_EXPLAIN 176
#define TK_FAIL 177
#define TK_FOR 178
#define TK_IGNORE 179
#define TK_IMMEDIATE 180
#define TK_INITIALLY 181
#define TK_INSTEAD 182
#define TK_KEY 183
#define TK_OF 184
#define TK_RAISE 185
#define TK_REPLACE 186
#define TK_RESTRICT 187
#define TK_ROW 188
#define TK_STATEMENT 189
#define TK_TRIGGER 190
#define TK_VIEW 191
#define TK_IPTOKEN 192
#define TK_SEMI 193
#define TK_NONE 194
#define TK_PREV 195
#define TK_LINEAR 196
#define TK_IMPORT 197
#define TK_TBNAME 198
#define TK_JOIN 199
#define TK_INSERT 200
#define TK_INTO 201
#define TK_VALUES 202
#define TK_FILE 203
#define TK_SPACE 300
......
......@@ -107,7 +107,7 @@ typedef struct {
case TSDB_DATA_TYPE_USMALLINT: \
(_v) = (_finalType)GET_UINT16_VAL(_data); \
break; \
case TSDB_DATA_TYPE_TIMESTAMP:\
case TSDB_DATA_TYPE_TIMESTAMP: \
case TSDB_DATA_TYPE_BIGINT: \
(_v) = (_finalType)(GET_INT64_VAL(_data)); \
break; \
......@@ -145,6 +145,7 @@ typedef struct {
case TSDB_DATA_TYPE_USMALLINT: \
*(uint16_t *)(_v) = (uint16_t)(_data); \
break; \
case TSDB_DATA_TYPE_TIMESTAMP: \
case TSDB_DATA_TYPE_BIGINT: \
*(int64_t *)(_v) = (int64_t)(_data); \
break; \
......@@ -181,6 +182,7 @@ typedef struct {
case TSDB_DATA_TYPE_USMALLINT: \
snprintf(_output, (int32_t)(_outputBytes), "%d", *(uint16_t *)(_input)); \
break; \
case TSDB_DATA_TYPE_TIMESTAMP: \
case TSDB_DATA_TYPE_BIGINT: \
snprintf(_output, (int32_t)(_outputBytes), "%" PRId64, *(int64_t *)(_input)); \
break; \
......@@ -205,6 +207,7 @@ typedef struct {
#define IS_SIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_TINYINT && (_t) <= TSDB_DATA_TYPE_BIGINT)
#define IS_UNSIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_UTINYINT && (_t) <= TSDB_DATA_TYPE_UBIGINT)
#define IS_FLOAT_TYPE(_t) ((_t) == TSDB_DATA_TYPE_FLOAT || (_t) == TSDB_DATA_TYPE_DOUBLE)
#define IS_TIMESTAMP_TYPE(_t) ((_t) == TSDB_DATA_TYPE_TIMESTAMP)
#define IS_NUMERIC_TYPE(_t) ((IS_SIGNED_NUMERIC_TYPE(_t)) || (IS_UNSIGNED_NUMERIC_TYPE(_t)) || (IS_FLOAT_TYPE(_t)))
......@@ -289,6 +292,7 @@ void* getDataMax(int32_t type);
int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bool issigned);
#define SET_DOUBLE_NULL(v) (*(uint64_t *)(v) = TSDB_DATA_DOUBLE_NULL)
#define SET_TIMESTAMP_NULL(v) (*(uint64_t *)(v) = TSDB_DATA_TIMESTAMP_NULL)
#ifdef __cplusplus
}
......
......@@ -77,6 +77,15 @@ static FORCE_INLINE int64_t taosGetTimestamp(int32_t precision) {
}
}
//@return timestamp of today at 00:00:00 in seconds
static FORCE_INLINE int64_t taosGetTimestampToday() {
time_t t = time(NULL);
struct tm * tm= localtime(&t);
tm->tm_hour = 0;
tm->tm_min = 0;
tm->tm_sec = 0;
return (int64_t)mktime(tm);
}
typedef struct SInterval {
int32_t tz; // query client timezone
......
......@@ -83,12 +83,12 @@ void deltaToUtcInitOnce() {
static int64_t parseFraction(char* str, char** end, int32_t timePrec);
static int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim);
static int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec);
static int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec);
static int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char delim);
static int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec, char delim);
static char* forwardToTimeStringEnd(char* str);
static bool checkTzPresent(char *str, int32_t len);
static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t timePrec) = {
static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t timePrec, char delim) = {
parseLocaltime,
parseLocaltimeWithDst
};
......@@ -98,11 +98,17 @@ int32_t taosGetTimestampSec() { return (int32_t)time(NULL); }
int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) {
/* parse datatime string in with tz */
if (strnchr(timestr, 'T', len, false) != NULL) {
return parseTimeWithTz(timestr, time, timePrec, 'T');
} else if (checkTzPresent(timestr, len)) {
return parseTimeWithTz(timestr, time, timePrec, 0);
if (checkTzPresent(timestr, len)) {
return parseTimeWithTz(timestr, time, timePrec, 'T');
} else {
return (*parseLocaltimeFp[day_light])(timestr, time, timePrec, 'T');
}
} else {
return (*parseLocaltimeFp[day_light])(timestr, time, timePrec);
if (checkTzPresent(timestr, len)) {
return parseTimeWithTz(timestr, time, timePrec, 0);
} else {
return (*parseLocaltimeFp[day_light])(timestr, time, timePrec, 0);
}
}
}
......@@ -316,11 +322,19 @@ int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char del
return 0;
}
int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec) {
int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec, char delim) {
*time = 0;
struct tm tm = {0};
char* str = strptime(timestr, "%Y-%m-%d %H:%M:%S", &tm);
char* str;
if (delim == 'T') {
str = strptime(timestr, "%Y-%m-%dT%H:%M:%S", &tm);
} else if (delim == 0) {
str = strptime(timestr, "%Y-%m-%d %H:%M:%S", &tm);
} else {
str = NULL;
}
if (str == NULL) {
return -1;
}
......@@ -332,7 +346,7 @@ int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec) {
#endif
int64_t seconds = user_mktime64(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, timezone);
int64_t fraction = 0;
if (*str == '.') {
......@@ -349,19 +363,27 @@ int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec) {
return 0;
}
int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec) {
int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec, char delim) {
*time = 0;
struct tm tm = {0};
tm.tm_isdst = -1;
char* str = strptime(timestr, "%Y-%m-%d %H:%M:%S", &tm);
char* str;
if (delim == 'T') {
str = strptime(timestr, "%Y-%m-%dT%H:%M:%S", &tm);
} else if (delim == 0) {
str = strptime(timestr, "%Y-%m-%d %H:%M:%S", &tm);
} else {
str = NULL;
}
if (str == NULL) {
return -1;
}
/* mktime will be affected by TZ, set by using taos_options */
int64_t seconds = mktime(&tm);
int64_t fraction = 0;
if (*str == '.') {
......
......@@ -762,6 +762,7 @@ expr(A) ::= MINUS(X) FLOAT(Y). { X.n += Y.n; X.type = TK_FLOAT; A = tSqlExprCr
expr(A) ::= PLUS(X) FLOAT(Y). { X.n += Y.n; X.type = TK_FLOAT; A = tSqlExprCreateIdValue(pInfo, &X, TK_FLOAT);}
expr(A) ::= STRING(X). { A = tSqlExprCreateIdValue(pInfo, &X, TK_STRING);}
expr(A) ::= NOW(X). { A = tSqlExprCreateIdValue(pInfo, &X, TK_NOW); }
expr(A) ::= TODAY(X). { A = tSqlExprCreateIdValue(pInfo, &X, TK_TODAY); }
expr(A) ::= VARIABLE(X). { A = tSqlExprCreateIdValue(pInfo, &X, TK_VARIABLE);}
expr(A) ::= PLUS(X) VARIABLE(Y). { X.n += Y.n; X.type = TK_VARIABLE; A = tSqlExprCreateIdValue(pInfo, &X, TK_VARIABLE);}
expr(A) ::= MINUS(X) VARIABLE(Y). { X.n += Y.n; X.type = TK_VARIABLE; A = tSqlExprCreateIdValue(pInfo, &X, TK_VARIABLE);}
......@@ -986,4 +987,4 @@ cmd ::= KILL QUERY INTEGER(X) COLON(Z) INTEGER(Y). {X.n += (Z.n + Y.n); s
%fallback ID ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CLUSTER CONFLICT COPY DATABASE DEFERRED
DELIMITERS DESC DETACH EACH END EXPLAIN FAIL FOR GLOB IGNORE IMMEDIATE INITIALLY INSTEAD
LIKE MATCH NMATCH KEY OF OFFSET RAISE REPLACE RESTRICT ROW STATEMENT TRIGGER VIEW ALL
NOW IPTOKEN SEMI NONE PREV LINEAR IMPORT TBNAME JOIN STABLE NULL INSERT INTO VALUES FILE.
NOW TODAY IPTOKEN SEMI NONE PREV LINEAR IMPORT TBNAME JOIN STABLE NULL INSERT INTO VALUES FILE.
......@@ -33,6 +33,7 @@ SSqlInfo qSqlParse(const char *pStr) {
sqlInfo.funcs = taosArrayInit(4, sizeof(SStrToken));
int32_t i = 0;
bool inWhere = false;
while (1) {
SStrToken t0 = {0};
......@@ -60,7 +61,7 @@ SSqlInfo qSqlParse(const char *pStr) {
sqlInfo.valid = false;
goto abort_parse;
}
case TK_HEX:
case TK_OCT:
case TK_BIN:{
......@@ -68,6 +69,25 @@ SSqlInfo qSqlParse(const char *pStr) {
sqlInfo.valid = false;
goto abort_parse;
}
case TK_WHERE:{
inWhere = true;
Parse(pParser, t0.type, t0, &sqlInfo);
if (sqlInfo.valid == false) {
goto abort_parse;
}
break;
}
case TK_NOW:
case TK_TODAY: {
//for now(),today() function used in select/where clause
if (pStr[i] == '(' && pStr[i + 1] == ')') {
if (!inWhere) {
t0.type = TK_ID;
} else {
i += 2;
}
}
}
default:
Parse(pParser, t0.type, t0, &sqlInfo);
if (sqlInfo.valid == false) {
......@@ -155,9 +175,13 @@ tSqlExpr *tSqlExprCreateIdValue(SSqlInfo* pInfo, SStrToken *pToken, int32_t optr
}
pSqlExpr->tokenId = optrType;
pSqlExpr->type = SQL_NODE_VALUE;
} else if (optrType == TK_NOW) {
} else if (optrType == TK_NOW || optrType == TK_TODAY) {
// use nanosecond by default TODO set value after getting database precision
pSqlExpr->value.i64 = taosGetTimestamp(TSDB_TIME_PRECISION_NANO);
if (optrType == TK_NOW) {
pSqlExpr->value.i64 = taosGetTimestamp(TSDB_TIME_PRECISION_NANO);
} else {
pSqlExpr->value.i64 = taosGetTimestampToday() * 1000000000;
}
pSqlExpr->value.nType = TSDB_DATA_TYPE_BIGINT;
pSqlExpr->tokenId = TK_TIMESTAMP; // TK_TIMESTAMP used to denote the time value is in microsecond
pSqlExpr->type = SQL_NODE_VALUE;
......@@ -176,7 +200,7 @@ tSqlExpr *tSqlExprCreateIdValue(SSqlInfo* pInfo, SStrToken *pToken, int32_t optr
pSqlExpr->flags |= 1 << EXPR_FLAG_NS_TIMESTAMP;
pSqlExpr->flags |= 1 << EXPR_FLAG_TIMESTAMP_VAR;
pSqlExpr->value.nType = TSDB_DATA_TYPE_BIGINT;
pSqlExpr->value.nType = TSDB_DATA_TYPE_TIMESTAMP;
pSqlExpr->tokenId = TK_TIMESTAMP;
pSqlExpr->type = SQL_NODE_VALUE;
} else if (optrType == TK_AS) {
......@@ -184,7 +208,7 @@ tSqlExpr *tSqlExprCreateIdValue(SSqlInfo* pInfo, SStrToken *pToken, int32_t optr
if (pToken != NULL) {
pSqlExpr->dataType = *(TAOS_FIELD *)pToken;
}
pSqlExpr->tokenId = optrType;
pSqlExpr->type = SQL_NODE_DATA_TYPE;
} else {
......
此差异已折叠。
......@@ -159,6 +159,7 @@ static SKeyword keywordTable[] = {
{"SOFFSET", TK_SOFFSET},
{"WHERE", TK_WHERE},
{"NOW", TK_NOW},
{"TODAY", TK_TODAY},
{"INSERT", TK_INSERT},
{"INTO", TK_INTO},
{"VALUES", TK_VALUES},
......@@ -591,6 +592,7 @@ uint32_t tGetToken(char* z, uint32_t* tokenId) {
for (i = 1; ((z[i] & 0x80) == 0) && isIdChar[(uint8_t) z[i]]; i++) {
}
*tokenId = tKeywordCode(z, i);
return i;
}
}
......@@ -667,6 +669,12 @@ SStrToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr) {
#endif
}
//for now(),today() function used in insert clause
if ((t0.type == TK_NOW || t0.type == TK_TODAY) &&
str[*i + t0.n] == '(' && str[*i + t0.n + 1] == ')') {
t0.n += 2;
}
if (t0.type == TK_SEMI) {
t0.n = 0;
return t0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册