support having
This commit is contained in:
parent
a18b6723d3
commit
a83cbb75d6
|
@ -129,13 +129,18 @@ typedef struct SColumn {
|
|||
SColumnFilterInfo *filterInfo;
|
||||
} SColumn;
|
||||
|
||||
typedef struct SExprFilter {
|
||||
tSQLExpr *pExpr; //used for having parse
|
||||
SArray *fp;
|
||||
SColumn *pFilters; //having filter info
|
||||
}SExprFilter;
|
||||
|
||||
typedef struct SInternalField {
|
||||
TAOS_FIELD field;
|
||||
bool visible;
|
||||
SExprInfo *pArithExprInfo;
|
||||
SSqlExpr *pSqlExpr;
|
||||
tSQLExpr *pExpr; //used for having parse
|
||||
SColumn *pFieldFilters; //having filter info
|
||||
SExprFilter *pFieldFilters;
|
||||
} SInternalField;
|
||||
|
||||
typedef struct SCond {
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "tscUtil.h"
|
||||
#include "tschemautil.h"
|
||||
#include "tsclient.h"
|
||||
#include "qutil.h"
|
||||
|
||||
typedef struct SCompareParam {
|
||||
SLocalDataSource **pLocalData;
|
||||
|
@ -1229,18 +1230,71 @@ static bool saveGroupResultInfo(SSqlObj *pSql) {
|
|||
return false;
|
||||
}
|
||||
|
||||
int32_t doHavingFilter(SQueryInfo* pQueryInfo) {
|
||||
|
||||
bool doFilterFieldData(SQueryInfo* pQueryInfo, char *input, tFilePage* pOutput, SExprFilter* pFieldFilters, int16_t type, bool* notSkipped) {
|
||||
bool qualified = false;
|
||||
|
||||
for(int32_t k = 0; k < pFieldFilters->pFilters->numOfFilters; ++k) {
|
||||
__filter_func_t fp = taosArrayGetP(pFieldFilters->fp, k);
|
||||
SColumnFilterElem filterElem = {.filterInfo = pFieldFilters->pFilters->filterInfo[k]};
|
||||
|
||||
bool isnull = isNull(input, type);
|
||||
if (isnull) {
|
||||
if (fp == isNullOperator) {
|
||||
qualified = true;
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (fp == notNullOperator) {
|
||||
qualified = true;
|
||||
break;
|
||||
} else if (fp == isNullOperator) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (fp(&filterElem, input, input, type)) {
|
||||
qualified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*notSkipped = qualified;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t doHavingFilter(SQueryInfo* pQueryInfo, tFilePage* pOutput, bool* notSkipped) {
|
||||
*notSkipped = true;
|
||||
|
||||
if (pQueryInfo->havingFieldNum <= 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
//int32_t exprNum = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
|
||||
|
||||
size_t numOfOutput = tscNumOfFields(pQueryInfo);
|
||||
for(int32_t i = 0; i < numOfOutput; ++i) {
|
||||
SColumn* pFieldFilters = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i)->pFieldFilters;
|
||||
if (pFieldFilters != NULL) {
|
||||
SInternalField* pInterField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i);
|
||||
SExprFilter* pFieldFilters = pInterField->pFieldFilters;
|
||||
|
||||
if (pFieldFilters == NULL) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t type = pInterField->field.type;
|
||||
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
char* pInput = pOutput->data + pOutput->num* pExpr->offset;
|
||||
|
||||
doFilterFieldData(pQueryInfo, pInput, pOutput, pFieldFilters, type, notSkipped);
|
||||
if (!notSkipped) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -1287,7 +1341,21 @@ bool genFinalResults(SSqlObj *pSql, SLocalMerger *pLocalMerge, bool noMoreCurren
|
|||
doArithmeticCalculate(pQueryInfo, pResBuf, pModel->rowSize, pLocalMerge->finalModel->rowSize);
|
||||
}
|
||||
|
||||
doHavingFilter(pQueryInfo);
|
||||
bool notSkipped = true;
|
||||
|
||||
doHavingFilter(pQueryInfo, pResBuf, ¬Skipped);
|
||||
|
||||
if (!notSkipped) {
|
||||
pRes->numOfRows = 0;
|
||||
pLocalMerge->discard = !noMoreCurrentGroupRes;
|
||||
|
||||
if (pLocalMerge->discard) {
|
||||
SColumnModel *pInternModel = pLocalMerge->pDesc->pColumnModel;
|
||||
tColModelAppend(pInternModel, pLocalMerge->discardData, pLocalMerge->pTempBuffer->data, 0, 1, 1);
|
||||
}
|
||||
|
||||
return notSkipped;
|
||||
}
|
||||
|
||||
// no interval query, no fill operation
|
||||
if (pQueryInfo->interval.interval == 0 || pQueryInfo->fillType == TSDB_FILL_NONE) {
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "tstoken.h"
|
||||
#include "tstrbuild.h"
|
||||
#include "ttokendef.h"
|
||||
#include "qutil.h"
|
||||
|
||||
#define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0"
|
||||
|
||||
|
@ -6709,17 +6710,26 @@ static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
|
|||
int32_t slot = tscNumOfFields(pQueryInfo) - 1;
|
||||
SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, slot);
|
||||
pInfo->visible = false;
|
||||
pInfo->pExpr = pExpr;
|
||||
|
||||
if (pInfo->pFieldFilters == NULL) {
|
||||
SColumn* pFieldFilters = calloc(1, sizeof(SColumn));
|
||||
SExprFilter* pFieldFilters = calloc(1, sizeof(SExprFilter));
|
||||
if (pFieldFilters == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
SColumn* pFilters = calloc(1, sizeof(SColumn));
|
||||
if (pFilters == NULL) {
|
||||
tfree(pFieldFilters);
|
||||
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pFieldFilters->pFilters = pFilters;
|
||||
pInfo->pFieldFilters = pFieldFilters;
|
||||
}
|
||||
|
||||
pInfo->pFieldFilters->pExpr = pExpr;
|
||||
|
||||
*interField = pInfo;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -6731,7 +6741,7 @@ int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr
|
|||
for (int32_t i = pQueryInfo->havingFieldNum - 1; i >= 0; --i) {
|
||||
pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i);
|
||||
|
||||
if (0 == tSqlExprCompare(pInfo->pExpr, pExpr)) {
|
||||
if (pInfo->pFieldFilters && 0 == tSqlExprCompare(pInfo->pFieldFilters->pExpr, pExpr)) {
|
||||
*pField = pInfo;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -6747,7 +6757,33 @@ int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t genExprFilter(SExprFilter * exprFilter) {
|
||||
exprFilter->fp = taosArrayInit(4, sizeof(__filter_func_t));
|
||||
if (exprFilter->fp == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < exprFilter->pFilters->numOfFilters; ++i) {
|
||||
SColumnFilterInfo *filterInfo = &exprFilter->pFilters->filterInfo[i];
|
||||
|
||||
int32_t lower = filterInfo->lowerRelOptr;
|
||||
int32_t upper = filterInfo->upperRelOptr;
|
||||
if (lower == TSDB_RELATION_INVALID && upper == TSDB_RELATION_INVALID) {
|
||||
tscError("invalid rel optr");
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
__filter_func_t ffp = getFilterOperator(lower, upper);
|
||||
if (ffp == NULL) {
|
||||
tscError("invalid filter info");
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
taosArrayPush(exprFilter->fp, &ffp);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t sqlOptr) {
|
||||
const char* msg1 = "non binary column not support like operator";
|
||||
|
@ -6768,7 +6804,7 @@ static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
|
|||
return ret;
|
||||
}
|
||||
|
||||
pColumn = pInfo->pFieldFilters;
|
||||
pColumn = pInfo->pFieldFilters->pFilters;
|
||||
|
||||
// this is a new filter condition on this column
|
||||
if (pColumn->numOfFilters == 0) {
|
||||
|
@ -6819,7 +6855,12 @@ static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
|
|||
}
|
||||
}
|
||||
|
||||
return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pInfo->field.type, pExpr);
|
||||
int32_t ret = doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pInfo->field.type, pExpr);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return genExprFilter(pInfo->pFieldFilters);
|
||||
}
|
||||
|
||||
int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, int32_t parentOptr) {
|
||||
|
|
|
@ -1081,7 +1081,8 @@ void tscFieldInfoClear(SFieldInfo* pFieldInfo) {
|
|||
}
|
||||
|
||||
if (pInfo->pFieldFilters != NULL) {
|
||||
tscColumnDestroy(pInfo->pFieldFilters);
|
||||
tscColumnDestroy(pInfo->pFieldFilters->pFilters);
|
||||
tfree(pInfo->pFieldFilters);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -213,9 +213,6 @@ bool doFilterData(SQuery *pQuery, int32_t elemPos) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool doFilterDataOnce() {
|
||||
|
||||
}
|
||||
|
||||
int64_t getNumOfResult(SQueryRuntimeEnv *pRuntimeEnv) {
|
||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||
|
|
|
@ -296,6 +296,10 @@ static FORCE_INLINE int32_t tStrTokenCompare(SStrToken* left, SStrToken* right)
|
|||
|
||||
|
||||
int32_t tSqlExprCompare(tSQLExpr *left, tSQLExpr *right) {
|
||||
if ((left == NULL && right) || (left && right == NULL)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (left->nSQLOptr != right->nSQLOptr) {
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue