fix the issue #435

This commit is contained in:
slguan 2019-08-29 17:45:10 +08:00
parent 948ab4c50a
commit 343df4e2a0
1 changed files with 32 additions and 36 deletions

View File

@ -108,7 +108,7 @@ static int32_t validateColumnName(char* name);
static int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo); static int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo);
static bool hasTimestampForPointInterpQuery(SSqlCmd* pCmd); static bool hasTimestampForPointInterpQuery(SSqlCmd* pCmd);
static void updateTagColumnIndex(SSqlCmd* pCmd); static void updateTagColumnIndex(SSqlCmd* pCmd);
static int32_t setLimitOffsetValueInfo(SSqlObj* pSql, SQuerySQL* pQuerySql); static int32_t parseLimitClause(SSqlObj* pSql, SQuerySQL* pQuerySql);
static void addRequiredTagColumn(SSqlCmd* pCmd, int32_t tagColIndex); static void addRequiredTagColumn(SSqlCmd* pCmd, int32_t tagColIndex);
static int32_t parseCreateDBOptions(SCreateDBInfo* pCreateDbSql, SSqlCmd* pCmd); static int32_t parseCreateDBOptions(SCreateDBInfo* pCreateDbSql, SSqlCmd* pCmd);
@ -876,7 +876,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
pCmd->limit = pQuerySql->limit; pCmd->limit = pQuerySql->limit;
/* temporarily save the original limitation value */ /* temporarily save the original limitation value */
if ((code = setLimitOffsetValueInfo(pSql, pQuerySql)) != TSDB_CODE_SUCCESS) { if ((code = parseLimitClause(pSql, pQuerySql)) != TSDB_CODE_SUCCESS) {
return code; return code;
} }
@ -3930,20 +3930,29 @@ bool hasTimestampForPointInterpQuery(SSqlCmd* pCmd) {
return (pCmd->stime == pCmd->etime) && (pCmd->stime != 0); return (pCmd->stime == pCmd->etime) && (pCmd->stime != 0);
} }
int32_t setLimitOffsetValueInfo(SSqlObj* pSql, SQuerySQL* pQuerySql) { int32_t parseLimitClause(SSqlObj* pSql, SQuerySQL* pQuerySql) {
SSqlCmd* pCmd = &pSql->cmd; SSqlCmd* pCmd = &pSql->cmd;
bool isMetric = UTIL_METER_IS_METRIC(pCmd);
const char* msg0 = "soffset can not be less than 0"; const char* msg0 = "soffset/offset can not be less than 0";
const char* msg1 = "offset can not be less than 0"; const char* msg1 = "slimit/soffset only available for STable query";
const char* msg2 = "slimit/soffset only available for STable query"; const char* msg2 = "function not supported on table";
const char* msg3 = "function not supported on table"; const char* msg3 = "slimit/soffset can not apply to projection query";
// handle the limit offset value, validate the limit // handle the limit offset value, validate the limit
pCmd->limit = pQuerySql->limit; pCmd->limit = pQuerySql->limit;
pCmd->glimit = pQuerySql->glimit; pCmd->glimit = pQuerySql->glimit;
if (isMetric) { if (pCmd->glimit.offset < 0 || pCmd->limit.offset < 0) {
setErrMsg(pCmd, msg0);
return TSDB_CODE_INVALID_SQL;
}
if (pCmd->limit.limit == 0) {
tscTrace("%p limit 0, no output result", pSql);
pCmd->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
}
if (UTIL_METER_IS_METRIC(pCmd)) {
bool queryOnTags = false; bool queryOnTags = false;
int32_t ret = tscQueryOnlyMetricTags(pCmd, &queryOnTags); int32_t ret = tscQueryOnlyMetricTags(pCmd, &queryOnTags);
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
@ -3952,34 +3961,30 @@ int32_t setLimitOffsetValueInfo(SSqlObj* pSql, SQuerySQL* pQuerySql) {
if (queryOnTags == true) { // local handle the metric tag query if (queryOnTags == true) { // local handle the metric tag query
pCmd->command = TSDB_SQL_RETRIEVE_TAGS; pCmd->command = TSDB_SQL_RETRIEVE_TAGS;
} else {
if (tscProjectionQueryOnMetric(pSql) && (pCmd->glimit.limit > 0 || pCmd->glimit.offset > 0)) {
setErrMsg(pCmd, msg3);
return TSDB_CODE_INVALID_SQL;
}
} }
if (pCmd->glimit.limit == 0 || pCmd->limit.limit == 0) { if (pCmd->glimit.limit == 0) {
tscTrace("%p limit 0, no output result", pSql); tscTrace("%p limit 0, no output result", pSql);
pCmd->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; pCmd->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
if (pCmd->glimit.offset < 0) {
setErrMsg(pCmd, msg0);
return TSDB_CODE_INVALID_SQL;
}
/* /*
* get the distribution of all meters among available vnodes that satisfy query condition from mnode , * get the distribution of all tables among available virtual nodes that satisfy query condition and
* then launching multiple async-queries on referenced vnodes, which is the first-stage query operation] * created according to this super table from management node.
* And then launching multiple async-queries on required virtual nodes, which is the first-stage query operation.
*/ */
int32_t code = tscGetMetricMeta(pSql, pCmd->name); int32_t code = tscGetMetricMeta(pSql, pCmd->name);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
/* //No tables included. No results generated. Query results are empty.
* Query results are empty. Therefore, the result is filled with 0 if count function is employed in selection
* clause.
*
* The fill of empty result is required only when interval clause is absent.
*/
SMetricMeta* pMetricMeta = pCmd->pMetricMeta; SMetricMeta* pMetricMeta = pCmd->pMetricMeta;
if (pCmd->pMeterMeta == NULL || pMetricMeta == NULL || pMetricMeta->numOfVnodes == 0 || if (pCmd->pMeterMeta == NULL || pMetricMeta == NULL || pMetricMeta->numOfVnodes == 0 ||
pMetricMeta->numOfMeters == 0) { pMetricMeta->numOfMeters == 0) {
@ -3991,27 +3996,18 @@ int32_t setLimitOffsetValueInfo(SSqlObj* pSql, SQuerySQL* pQuerySql) {
pCmd->globalLimit = pCmd->limit.limit; pCmd->globalLimit = pCmd->limit.limit;
} else { } else {
if (pCmd->glimit.limit != -1 || pCmd->glimit.offset != 0) { if (pCmd->glimit.limit != -1 || pCmd->glimit.offset != 0) {
setErrMsg(pCmd, msg2); setErrMsg(pCmd, msg1);
return TSDB_CODE_INVALID_SQL; return TSDB_CODE_INVALID_SQL;
} }
// filter the query functions operating on "tbname" column that are not supported by normal columns.
for (int32_t i = 0; i < pCmd->fieldsInfo.numOfOutputCols; ++i) { for (int32_t i = 0; i < pCmd->fieldsInfo.numOfOutputCols; ++i) {
SSqlExpr* pExpr = tscSqlExprGet(pCmd, i); SSqlExpr* pExpr = tscSqlExprGet(pCmd, i);
if (pExpr->colInfo.colIdx == -1) { if (pExpr->colInfo.colIdx == -1) {
setErrMsg(pCmd, msg3); setErrMsg(pCmd, msg2);
return TSDB_CODE_INVALID_SQL; return TSDB_CODE_INVALID_SQL;
} }
} }
if (pCmd->limit.limit == 0) {
tscTrace("%p limit 0, no output result", pSql);
pCmd->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
}
if (pCmd->limit.offset < 0) {
setErrMsg(pCmd, msg1);
return TSDB_CODE_INVALID_SQL;
}
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;