fix: add window_offset translate
This commit is contained in:
parent
19752b020f
commit
84cc80be1c
|
@ -78,7 +78,7 @@ int64_t taosTimeTruncate(int64_t ts, const SInterval* pInterval);
|
|||
int32_t taosTimeCountIntervalForFill(int64_t skey, int64_t ekey, int64_t interval, char unit, int32_t precision, int32_t order);
|
||||
|
||||
int32_t parseAbsoluteDuration(const char* token, int32_t tokenlen, int64_t* ts, char* unit, int32_t timePrecision);
|
||||
int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* duration, char* unit, int32_t timePrecision);
|
||||
int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* duration, char* unit, int32_t timePrecision, bool negativeAllow);
|
||||
|
||||
int32_t taosParseTime(const char* timestr, int64_t* pTime, int32_t len, int32_t timePrec, int8_t dayligth);
|
||||
void deltaToUtcInitOnce();
|
||||
|
|
|
@ -380,6 +380,8 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
#define TK_NK_SPACE 600
|
||||
#define TK_NK_COMMENT 601
|
||||
#define TK_NK_ILLEGAL 602
|
||||
|
|
|
@ -99,10 +99,16 @@ typedef struct STargetNode {
|
|||
SNode* pExpr;
|
||||
} STargetNode;
|
||||
|
||||
#define VALUE_FLAG_IS_DURATION (1 << 0)
|
||||
#define VALUE_FLAG_IS_TIME_OFFSET (1 << 1)
|
||||
|
||||
#define IS_DURATION_VAL(_flag) ((_flag) & VALUE_FLAG_IS_DURATION)
|
||||
#define IS_TIME_OFFSET_VAL(_flag) ((_flag) & VALUE_FLAG_IS_TIME_OFFSET)
|
||||
|
||||
typedef struct SValueNode {
|
||||
SExprNode node; // QUERY_NODE_VALUE
|
||||
char* literal;
|
||||
bool isDuration;
|
||||
int32_t flag;
|
||||
bool translate;
|
||||
bool notReserved;
|
||||
bool isNull;
|
||||
|
|
|
@ -659,12 +659,12 @@ int32_t parseAbsoluteDuration(const char* token, int32_t tokenlen, int64_t* dura
|
|||
return getDuration(timestamp, *unit, duration, timePrecision);
|
||||
}
|
||||
|
||||
int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* duration, char* unit, int32_t timePrecision) {
|
||||
int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* duration, char* unit, int32_t timePrecision, bool negativeAllow) {
|
||||
errno = 0;
|
||||
|
||||
/* get the basic numeric value */
|
||||
*duration = taosStr2Int64(token, NULL, 10);
|
||||
if (*duration < 0 || errno != 0) {
|
||||
if ((*duration < 0 && !negativeAllow) || errno != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ static int32_t invaildFuncParaValueErrMsg(char* pErrBuf, int32_t len, const char
|
|||
#define TIME_UNIT_TOO_SMALL 2
|
||||
|
||||
static int32_t validateTimeUnitParam(uint8_t dbPrec, const SValueNode* pVal) {
|
||||
if (!pVal->isDuration) {
|
||||
if (!IS_DURATION_VAL(pVal->flag)) {
|
||||
return TIME_UNIT_INVALID;
|
||||
}
|
||||
|
||||
|
@ -225,7 +225,6 @@ static int32_t addTimezoneParam(SNodeList* pList) {
|
|||
}
|
||||
|
||||
pVal->literal = strndup(buf, len);
|
||||
pVal->isDuration = false;
|
||||
pVal->translate = true;
|
||||
pVal->node.resType.type = TSDB_DATA_TYPE_BINARY;
|
||||
pVal->node.resType.bytes = len + VARSTR_HEADER_SIZE;
|
||||
|
@ -245,7 +244,6 @@ static int32_t addDbPrecisonParam(SNodeList** pList, uint8_t precision) {
|
|||
}
|
||||
|
||||
pVal->literal = NULL;
|
||||
pVal->isDuration = false;
|
||||
pVal->translate = true;
|
||||
pVal->notReserved = true;
|
||||
pVal->node.resType.type = TSDB_DATA_TYPE_TINYINT;
|
||||
|
|
|
@ -125,7 +125,7 @@ static int32_t columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
|
|||
static int32_t valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, exprNodeCopy);
|
||||
COPY_CHAR_POINT_FIELD(literal);
|
||||
COPY_SCALAR_FIELD(isDuration);
|
||||
COPY_SCALAR_FIELD(flag);
|
||||
COPY_SCALAR_FIELD(translate);
|
||||
COPY_SCALAR_FIELD(notReserved);
|
||||
COPY_SCALAR_FIELD(isNull);
|
||||
|
|
|
@ -3556,7 +3556,7 @@ static int32_t jsonToColumnNode(const SJson* pJson, void* pObj) {
|
|||
|
||||
static const char* jkValueLiteralSize = "LiteralSize";
|
||||
static const char* jkValueLiteral = "Literal";
|
||||
static const char* jkValueDuration = "Duration";
|
||||
static const char* jkValueFlag = "Flag";
|
||||
static const char* jkValueTranslate = "Translate";
|
||||
static const char* jkValueNotReserved = "NotReserved";
|
||||
static const char* jkValueIsNull = "IsNull";
|
||||
|
@ -3640,7 +3640,7 @@ static int32_t valueNodeToJson(const void* pObj, SJson* pJson) {
|
|||
code = tjsonAddStringToObject(pJson, jkValueLiteral, pNode->literal);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkValueDuration, pNode->isDuration);
|
||||
code = tjsonAddBoolToObject(pJson, jkValueFlag, pNode->flag);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddBoolToObject(pJson, jkValueTranslate, pNode->translate);
|
||||
|
@ -3794,7 +3794,7 @@ static int32_t jsonToValueNode(const SJson* pJson, void* pObj) {
|
|||
code = tjsonDupStringValue(pJson, jkValueLiteral, &pNode->literal);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkValueDuration, &pNode->isDuration);
|
||||
code = tjsonGetIntValue(pJson, jkValueFlag, &pNode->flag);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBoolValue(pJson, jkValueTranslate, &pNode->translate);
|
||||
|
|
|
@ -788,7 +788,7 @@ static int32_t msgToColumnNode(STlvDecoder* pDecoder, void* pObj) {
|
|||
enum {
|
||||
VALUE_CODE_EXPR_BASE = 1,
|
||||
VALUE_CODE_LITERAL,
|
||||
VALUE_CODE_IS_DURATION,
|
||||
VALUE_CODE_FLAG,
|
||||
VALUE_CODE_TRANSLATE,
|
||||
VALUE_CODE_NOT_RESERVED,
|
||||
VALUE_CODE_IS_NULL,
|
||||
|
@ -849,7 +849,7 @@ static int32_t valueNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
|||
code = tlvEncodeCStr(pEncoder, VALUE_CODE_LITERAL, pNode->literal);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeBool(pEncoder, VALUE_CODE_IS_DURATION, pNode->isDuration);
|
||||
code = tlvEncodeI32(pEncoder, VALUE_CODE_FLAG, pNode->flag);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tlvEncodeBool(pEncoder, VALUE_CODE_TRANSLATE, pNode->translate);
|
||||
|
@ -972,8 +972,8 @@ static int32_t msgToValueNode(STlvDecoder* pDecoder, void* pObj) {
|
|||
case VALUE_CODE_LITERAL:
|
||||
code = tlvDecodeCStrP(pTlv, &pNode->literal);
|
||||
break;
|
||||
case VALUE_CODE_IS_DURATION:
|
||||
code = tlvDecodeBool(pTlv, &pNode->isDuration);
|
||||
case VALUE_CODE_FLAG:
|
||||
code = tlvDecodeI32(pTlv, &pNode->flag);
|
||||
break;
|
||||
case VALUE_CODE_TRANSLATE:
|
||||
code = tlvDecodeBool(pTlv, &pNode->translate);
|
||||
|
|
|
@ -2396,7 +2396,6 @@ SValueNode* nodesMakeValueNodeFromString(char* literal) {
|
|||
pValNode->datum.p = p;
|
||||
pValNode->literal = tstrdup(literal);
|
||||
pValNode->translate = true;
|
||||
pValNode->isDuration = false;
|
||||
pValNode->isNull = false;
|
||||
}
|
||||
return pValNode;
|
||||
|
@ -2409,7 +2408,6 @@ SValueNode* nodesMakeValueNodeFromBool(bool b) {
|
|||
pValNode->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
|
||||
nodesSetValueNodeValue(pValNode, &b);
|
||||
pValNode->translate = true;
|
||||
pValNode->isDuration = false;
|
||||
pValNode->isNull = false;
|
||||
}
|
||||
return pValNode;
|
||||
|
|
|
@ -111,6 +111,7 @@ SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken*
|
|||
SNodeList* createHintNodeList(SAstCreateContext* pCxt, const SToken* pLiteral);
|
||||
SNode* createIdentifierValueNode(SAstCreateContext* pCxt, SToken* pLiteral);
|
||||
SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral);
|
||||
SNode* createTimeOffsetValueNode(SAstCreateContext* pCxt, const SToken* pLiteral);
|
||||
SNode* createDefaultDatabaseCondValue(SAstCreateContext* pCxt);
|
||||
SNode* createPlaceholderValueNode(SAstCreateContext* pCxt, const SToken* pLiteral);
|
||||
SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, SToken* pAlias);
|
||||
|
|
|
@ -1096,11 +1096,15 @@ join_subtype(A) ::= WINDOW.
|
|||
|
||||
window_offset_clause_opt(A) ::= . { A = NULL; }
|
||||
window_offset_clause_opt(A) ::= WINDOW_OFFSET NK_LP window_offset_literal(B)
|
||||
NK_COMMA window_offset_literal(C) NK_RP. { A = createWindowOffsetNode(pCxt, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)); }
|
||||
|
||||
window_offset_literal(A) ::= NK_VARIABLE(B). { A = createRawExprNode(pCxt, &B, createDurationValueNode(pCxt, &B)); }
|
||||
window_offset_literal(A) ::= NK_INTEGER(B). { A = createRawExprNode(pCxt, &B, createDurationValueNode(pCxt, &B)); }
|
||||
NK_COMMA window_offset_literal(C) NK_RP. { A = createWindowOffsetNode(pCxt, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)); }
|
||||
|
||||
window_offset_literal(A) ::= NK_VARIABLE(B). { A = createRawExprNode(pCxt, &B, createTimeOffsetValueNode(pCxt, &B)); }
|
||||
window_offset_literal(A) ::= NK_MINUS(B) NK_VARIABLE(C). {
|
||||
SToken t = B;
|
||||
t.n = (C.z + C.n) - B.z;
|
||||
A = createRawExprNode(pCxt, &t, createTimeOffsetValueNode(pCxt, &t));
|
||||
}
|
||||
|
||||
jlimit_clause_opt(A) ::= . { A = NULL; }
|
||||
jlimit_clause_opt(A) ::= JLIMIT NK_INTEGER(B). { A = createLimitNode(pCxt, &B, NULL); }
|
||||
|
||||
|
|
|
@ -366,7 +366,6 @@ SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken*
|
|||
if (TSDB_DATA_TYPE_TIMESTAMP == dataType) {
|
||||
val->node.resType.precision = TSDB_TIME_PRECISION_MILLI;
|
||||
}
|
||||
val->isDuration = false;
|
||||
val->translate = false;
|
||||
return (SNode*)val;
|
||||
}
|
||||
|
@ -544,7 +543,7 @@ SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral)
|
|||
val->literal = strndup(pLiteral->z, pLiteral->n);
|
||||
}
|
||||
CHECK_OUT_OF_MEM(val->literal);
|
||||
val->isDuration = true;
|
||||
val->flag |= VALUE_FLAG_IS_DURATION;
|
||||
val->translate = false;
|
||||
val->node.resType.type = TSDB_DATA_TYPE_BIGINT;
|
||||
val->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
|
||||
|
@ -552,6 +551,52 @@ SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral)
|
|||
return (SNode*)val;
|
||||
}
|
||||
|
||||
SNode* createTimeOffsetValueNode(SAstCreateContext* pCxt, const SToken* pLiteral) {
|
||||
CHECK_PARSER_STATUS(pCxt);
|
||||
SValueNode* val = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
|
||||
CHECK_OUT_OF_MEM(val);
|
||||
if (pLiteral->type == TK_NK_STRING) {
|
||||
// like '100s' or "100d"
|
||||
// check format: ^[0-9]+[smwbauhdny]$'
|
||||
if (pLiteral->n < 4) {
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, pLiteral->z);
|
||||
return NULL;
|
||||
}
|
||||
char unit = pLiteral->z[pLiteral->n - 2];
|
||||
switch (unit) {
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'd':
|
||||
case 'h':
|
||||
case 'm':
|
||||
case 's':
|
||||
case 'u':
|
||||
case 'w':
|
||||
break;
|
||||
default:
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, pLiteral->z);
|
||||
return NULL;
|
||||
}
|
||||
for (uint32_t i = 1; i < pLiteral->n - 2; ++i) {
|
||||
if (!isdigit(pLiteral->z[i])) {
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, pLiteral->z);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
val->literal = strndup(pLiteral->z + 1, pLiteral->n - 2);
|
||||
} else {
|
||||
val->literal = strndup(pLiteral->z, pLiteral->n);
|
||||
}
|
||||
CHECK_OUT_OF_MEM(val->literal);
|
||||
val->flag |= VALUE_FLAG_IS_TIME_OFFSET;
|
||||
val->translate = false;
|
||||
val->node.resType.type = TSDB_DATA_TYPE_BIGINT;
|
||||
val->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
|
||||
val->node.resType.precision = TSDB_TIME_PRECISION_MILLI;
|
||||
return (SNode*)val;
|
||||
}
|
||||
|
||||
|
||||
SNode* createDefaultDatabaseCondValue(SAstCreateContext* pCxt) {
|
||||
CHECK_PARSER_STATUS(pCxt);
|
||||
if (NULL == pCxt->pQueryCxt->db) {
|
||||
|
@ -562,7 +607,6 @@ SNode* createDefaultDatabaseCondValue(SAstCreateContext* pCxt) {
|
|||
CHECK_OUT_OF_MEM(val);
|
||||
val->literal = taosStrdup(pCxt->pQueryCxt->db);
|
||||
CHECK_OUT_OF_MEM(val->literal);
|
||||
val->isDuration = false;
|
||||
val->translate = false;
|
||||
val->node.resType.type = TSDB_DATA_TYPE_BINARY;
|
||||
val->node.resType.bytes = strlen(val->literal);
|
||||
|
|
|
@ -1182,13 +1182,23 @@ static int32_t parseBoolFromValueNode(STranslateContext* pCxt, SValueNode* pVal)
|
|||
|
||||
static EDealRes translateDurationValue(STranslateContext* pCxt, SValueNode* pVal) {
|
||||
if (parseNatualDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &pVal->unit,
|
||||
pVal->node.resType.precision) != TSDB_CODE_SUCCESS) {
|
||||
pVal->node.resType.precision, false) != TSDB_CODE_SUCCESS) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
|
||||
}
|
||||
*(int64_t*)&pVal->typeData = pVal->datum.i;
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static EDealRes translateTimeOffsetValue(STranslateContext* pCxt, SValueNode* pVal) {
|
||||
if (parseNatualDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &pVal->unit,
|
||||
pVal->node.resType.precision, true) != TSDB_CODE_SUCCESS) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
|
||||
}
|
||||
*(int64_t*)&pVal->typeData = pVal->datum.i;
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
static EDealRes translateNormalValue(STranslateContext* pCxt, SValueNode* pVal, SDataType targetDt, bool strict) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
switch (targetDt.type) {
|
||||
|
@ -1371,8 +1381,10 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD
|
|||
pVal->node.resType.precision = getPrecisionFromCurrStmt(pCxt->pCurrStmt, targetDt.precision);
|
||||
|
||||
EDealRes res = DEAL_RES_CONTINUE;
|
||||
if (pVal->isDuration) {
|
||||
if (IS_DURATION_VAL(pVal->flag)) {
|
||||
res = translateDurationValue(pCxt, pVal);
|
||||
} else if (IS_TIME_OFFSET_VAL(pVal->flag)) {
|
||||
res = translateTimeOffsetValue(pCxt, pVal);
|
||||
} else {
|
||||
res = translateNormalValue(pCxt, pVal, targetDt, strict);
|
||||
}
|
||||
|
@ -2861,7 +2873,6 @@ static EDealRes doTranslateTbName(SNode** pNode, void* pContext) {
|
|||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
pVal->isDuration = false;
|
||||
pVal->translate = true;
|
||||
pVal->node.resType.type = TSDB_DATA_TYPE_BINARY;
|
||||
pVal->node.resType.bytes = tbLen + VARSTR_HEADER_SIZE;
|
||||
|
@ -2914,6 +2925,7 @@ static int32_t checkJoinTable(STranslateContext* pCxt, SJoinTableNode* pJoinTabl
|
|||
}
|
||||
|
||||
static int32_t translateJoinTable(STranslateContext* pCxt, SJoinTableNode* pJoinTable) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
EJoinType type = pJoinTable->joinType;
|
||||
EJoinSubType* pSType = &pJoinTable->subType;
|
||||
|
||||
|
@ -2935,17 +2947,20 @@ static int32_t translateJoinTable(STranslateContext* pCxt, SJoinTableNode* pJoin
|
|||
break;
|
||||
}
|
||||
|
||||
if (NULL != pJoinTable->pWindowOffset && *pSType != JOIN_STYPE_WIN) {
|
||||
return buildInvalidOperationMsg(&pCxt->msgBuf, "WINDOW_OFFSET only supported for WINDOW join");
|
||||
}
|
||||
if (NULL == pJoinTable->pWindowOffset && *pSType == JOIN_STYPE_WIN) {
|
||||
if (NULL != pJoinTable->pWindowOffset) {
|
||||
if (*pSType != JOIN_STYPE_WIN) {
|
||||
return buildInvalidOperationMsg(&pCxt->msgBuf, "WINDOW_OFFSET only supported for WINDOW join");
|
||||
}
|
||||
code = translateExpr(pCxt, &pJoinTable->pWindowOffset);
|
||||
} else if (*pSType == JOIN_STYPE_WIN) {
|
||||
return buildInvalidOperationMsg(&pCxt->msgBuf, "WINDOW_OFFSET required for WINDOW join");
|
||||
}
|
||||
if (NULL != pJoinTable->pJLimit && *pSType != JOIN_STYPE_ASOF && *pSType != JOIN_STYPE_WIN) {
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pJoinTable->pJLimit && *pSType != JOIN_STYPE_ASOF && *pSType != JOIN_STYPE_WIN) {
|
||||
return buildInvalidOperationMsgExt(&pCxt->msgBuf, "JLIMIT not supported for %s join", getFullJoinTypeString(type, *pSType));
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t translateTable(STranslateContext* pCxt, SNode** pTable) {
|
||||
|
@ -3841,7 +3856,7 @@ static int32_t createDefaultEveryNode(STranslateContext* pCxt, SNode** pOutput)
|
|||
|
||||
pEvery->node.resType.type = TSDB_DATA_TYPE_BIGINT;
|
||||
pEvery->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
|
||||
pEvery->isDuration = true;
|
||||
pEvery->flag |= VALUE_FLAG_IS_DURATION;
|
||||
pEvery->literal = taosStrdup("1s");
|
||||
|
||||
*pOutput = (SNode*)pEvery;
|
||||
|
@ -4746,7 +4761,7 @@ static int64_t getUnitPerMinute(uint8_t precision) {
|
|||
}
|
||||
|
||||
static int64_t getBigintFromValueNode(SValueNode* pVal) {
|
||||
if (pVal->isDuration) {
|
||||
if (IS_DURATION_VAL(pVal->flag)) {
|
||||
return pVal->datum.i / getUnitPerMinute(pVal->node.resType.precision);
|
||||
}
|
||||
return pVal->datum.i;
|
||||
|
@ -4863,12 +4878,12 @@ static int32_t checkDbKeepOption(STranslateContext* pCxt, SDatabaseOptions* pOpt
|
|||
if (DEAL_RES_ERROR == translateValue(pCxt, pVal)) {
|
||||
return pCxt->errCode;
|
||||
}
|
||||
if (pVal->isDuration && TIME_UNIT_MINUTE != pVal->unit && TIME_UNIT_HOUR != pVal->unit &&
|
||||
if (IS_DURATION_VAL(pVal->flag) && TIME_UNIT_MINUTE != pVal->unit && TIME_UNIT_HOUR != pVal->unit &&
|
||||
TIME_UNIT_DAY != pVal->unit) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION,
|
||||
"Invalid option keep unit: %c, only m, h, d allowed", pVal->unit);
|
||||
}
|
||||
if (!pVal->isDuration) {
|
||||
if (!IS_DURATION_VAL(pVal->flag)) {
|
||||
pVal->datum.i = pVal->datum.i * 1440;
|
||||
}
|
||||
}
|
||||
|
@ -5010,16 +5025,16 @@ static int32_t checkDbRetentionsOption(STranslateContext* pCxt, SNodeList* pRete
|
|||
SValueNode* pFreq = (SValueNode*)nodesListGetNode(((SNodeListNode*)pRetention)->pNodeList, 0);
|
||||
SValueNode* pKeep = (SValueNode*)nodesListGetNode(((SNodeListNode*)pRetention)->pNodeList, 1);
|
||||
|
||||
ASSERTS(pFreq->isDuration && pKeep->isDuration, "Retentions freq/keep should have unit");
|
||||
ASSERTS(IS_DURATION_VAL(pFreq->flag) && IS_DURATION_VAL(pKeep->flag), "Retentions freq/keep should have unit");
|
||||
|
||||
// check unit
|
||||
if (pFreq->isDuration && TIME_UNIT_SECOND != pFreq->unit && TIME_UNIT_MINUTE != pFreq->unit &&
|
||||
if (IS_DURATION_VAL(pFreq->flag) && TIME_UNIT_SECOND != pFreq->unit && TIME_UNIT_MINUTE != pFreq->unit &&
|
||||
TIME_UNIT_HOUR != pFreq->unit && TIME_UNIT_DAY != pFreq->unit && TIME_UNIT_WEEK != pFreq->unit) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION,
|
||||
"Invalid option retentions(freq): %s, only s, m, h, d, w allowed", pFreq->literal);
|
||||
}
|
||||
|
||||
if (pKeep->isDuration && TIME_UNIT_MINUTE != pKeep->unit && TIME_UNIT_HOUR != pKeep->unit &&
|
||||
if (IS_DURATION_VAL(pKeep->flag) && TIME_UNIT_MINUTE != pKeep->unit && TIME_UNIT_HOUR != pKeep->unit &&
|
||||
TIME_UNIT_DAY != pKeep->unit) {
|
||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_DB_OPTION,
|
||||
"Invalid option retentions(keep): %s, only m, h, d allowed", pKeep->literal);
|
||||
|
@ -5970,7 +5985,7 @@ static SNode* makeIntervalVal(SRetention* pRetension, int8_t precision) {
|
|||
nodesDestroyNode((SNode*)pVal);
|
||||
return NULL;
|
||||
}
|
||||
pVal->isDuration = true;
|
||||
pVal->flag |= VALUE_FLAG_IS_DURATION;
|
||||
pVal->node.resType.type = TSDB_DATA_TYPE_BIGINT;
|
||||
pVal->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
|
||||
pVal->node.resType.precision = precision;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -557,7 +557,8 @@ static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
|||
// set the output
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
SNodeList* pColList = NULL;
|
||||
if (QUERY_NODE_REAL_TABLE == nodeType(pJoinTable->pLeft) && !pJoin->isLowLevelJoin) {
|
||||
// if (QUERY_NODE_REAL_TABLE == nodeType(pJoinTable->pLeft) && !pJoin->isLowLevelJoin) {
|
||||
if (QUERY_NODE_REAL_TABLE == nodeType(pJoinTable->pLeft)) {
|
||||
code = nodesCollectColumns(pSelect, SQL_CLAUSE_WHERE, ((SRealTableNode*)pJoinTable->pLeft)->table.tableAlias, COLLECT_COL_TYPE_ALL, &pColList);
|
||||
} else {
|
||||
pJoin->node.pTargets = nodesCloneList(pLeft->pTargets);
|
||||
|
@ -573,7 +574,8 @@ static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
|||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
SNodeList* pColList = NULL;
|
||||
if (QUERY_NODE_REAL_TABLE == nodeType(pJoinTable->pRight) && !pJoin->isLowLevelJoin) {
|
||||
// if (QUERY_NODE_REAL_TABLE == nodeType(pJoinTable->pRight) && !pJoin->isLowLevelJoin) {
|
||||
if (QUERY_NODE_REAL_TABLE == nodeType(pJoinTable->pRight)) {
|
||||
code = nodesCollectColumns(pSelect, SQL_CLAUSE_WHERE, ((SRealTableNode*)pJoinTable->pRight)->table.tableAlias, COLLECT_COL_TYPE_ALL, &pColList);
|
||||
} else {
|
||||
if (pJoin->node.pTargets) {
|
||||
|
|
Loading…
Reference in New Issue