support having
This commit is contained in:
parent
20e7ae2ce9
commit
d65b541bbf
|
@ -121,6 +121,7 @@ typedef struct SInternalField {
|
|||
bool visible;
|
||||
SExprInfo *pArithExprInfo;
|
||||
SSqlExpr *pSqlExpr;
|
||||
SColumn *pFieldFilters;
|
||||
} SInternalField;
|
||||
|
||||
typedef struct SFieldInfo {
|
||||
|
|
|
@ -1031,6 +1031,41 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static void exchangeExpr(tSQLExpr* pExpr) {
|
||||
tSQLExpr* pLeft = pExpr->pLeft;
|
||||
tSQLExpr* pRight = pExpr->pRight;
|
||||
|
||||
if ((pRight->nSQLOptr == TK_ID || (pRight->nSQLOptr >= TK_COUNT && pRight->nSQLOptr <= TK_AVG_IRATE)) &&
|
||||
(pLeft->nSQLOptr == TK_INTEGER || pLeft->nSQLOptr == TK_FLOAT || pLeft->nSQLOptr == TK_STRING || pLeft->nSQLOptr == TK_BOOL)) {
|
||||
/*
|
||||
* exchange value of the left handside and the value of the right-handside
|
||||
* to make sure that the value of filter expression always locates in
|
||||
* right-handside and
|
||||
* the column-id/function is at the left handside.
|
||||
*/
|
||||
uint32_t optr = 0;
|
||||
switch (pExpr->nSQLOptr) {
|
||||
case TK_LE:
|
||||
optr = TK_GE;
|
||||
break;
|
||||
case TK_LT:
|
||||
optr = TK_GT;
|
||||
break;
|
||||
case TK_GT:
|
||||
optr = TK_LT;
|
||||
break;
|
||||
case TK_GE:
|
||||
optr = TK_LE;
|
||||
break;
|
||||
default:
|
||||
optr = pExpr->nSQLOptr;
|
||||
}
|
||||
|
||||
pExpr->nSQLOptr = optr;
|
||||
SWAP(pExpr->pLeft, pExpr->pRight, void*);
|
||||
}
|
||||
}
|
||||
|
||||
static bool validateTagParams(SArray* pTagsList, SArray* pFieldList, SSqlCmd* pCmd) {
|
||||
assert(pTagsList != NULL);
|
||||
|
||||
|
@ -3062,6 +3097,214 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SColumnIndex* pIndex, tSQLExpr* pExpr, int32_t sqlOptr) {
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
|
||||
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
|
||||
|
||||
const char* msg1 = "non binary column not support like operator";
|
||||
const char* msg2 = "binary column not support this operator";
|
||||
const char* msg3 = "bool column not support this operator";
|
||||
|
||||
SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex);
|
||||
SColumnFilterInfo* pColFilter = NULL;
|
||||
|
||||
/*
|
||||
* in case of TK_AND filter condition, we first find the corresponding column and build the query condition together
|
||||
* the already existed condition.
|
||||
*/
|
||||
if (sqlOptr == TK_AND) {
|
||||
// this is a new filter condition on this column
|
||||
if (pColumn->numOfFilters == 0) {
|
||||
pColFilter = addColumnFilterInfo(pColumn);
|
||||
} else { // update the existed column filter information, find the filter info here
|
||||
pColFilter = &pColumn->filterInfo[0];
|
||||
}
|
||||
|
||||
if (pColFilter == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
} else if (sqlOptr == TK_OR) {
|
||||
// TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2"
|
||||
pColFilter = addColumnFilterInfo(pColumn);
|
||||
if (pColFilter == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
} else { // error;
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
pColFilter->filterstr =
|
||||
((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);
|
||||
|
||||
if (pColFilter->filterstr) {
|
||||
if (pExpr->nSQLOptr != TK_EQ
|
||||
&& pExpr->nSQLOptr != TK_NE
|
||||
&& pExpr->nSQLOptr != TK_ISNULL
|
||||
&& pExpr->nSQLOptr != TK_NOTNULL
|
||||
&& pExpr->nSQLOptr != TK_LIKE
|
||||
) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||
}
|
||||
} else {
|
||||
if (pExpr->nSQLOptr == TK_LIKE) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
if (pSchema->type == TSDB_DATA_TYPE_BOOL) {
|
||||
if (pExpr->nSQLOptr != TK_EQ && pExpr->nSQLOptr != TK_NE) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pColumn->colIndex = *pIndex;
|
||||
return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, pIndex, pExpr);
|
||||
}
|
||||
|
||||
int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr** pExpr, int32_t parentOptr) {
|
||||
if (pExpr == NULL || (*pExpr) == NULL) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
const char* msg1 = "invalid having clause";
|
||||
|
||||
tSQLExpr* pLeft = (*pExpr)->pLeft;
|
||||
tSQLExpr* pRight = (*pExpr)->pRight;
|
||||
|
||||
if ((*pExpr)->nSQLOptr == TK_AND || (*pExpr)->nSQLOptr == TK_OR) {
|
||||
int32_t ret = getHavingExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, (*pExpr)->nSQLOptr);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return getHavingExpr(pCmd, pQueryInfo, &(*pExpr)->pRight, (*pExpr)->nSQLOptr);
|
||||
}
|
||||
|
||||
if ((pLeft->nSQLOptr >= TK_COUNT && pLeft->nSQLOptr <= TK_AVG_IRATE) &&
|
||||
(pRight->nSQLOptr >= TK_COUNT && pRight->nSQLOptr <= TK_AVG_IRATE)) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
if (pLeft->nSQLOptr >= TK_BOOL
|
||||
&& pLeft->nSQLOptr <= TK_BINARY
|
||||
&& pRight->nSQLOptr >= TK_BOOL
|
||||
&& pRight->nSQLOptr <= TK_BINARY) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
exchangeExpr(*pExpr);
|
||||
|
||||
pLeft = (*pExpr)->pLeft;
|
||||
pRight = (*pExpr)->pRight;
|
||||
|
||||
if (!(pLeft->nSQLOptr >= TK_COUNT && pLeft->nSQLOptr <= TK_AVG_IRATE)) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
if (!(pRight->nSQLOptr >= TK_BOOL && pRight->nSQLOptr <= TK_BINARY)) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
if ((*pExpr)->nSQLOptr >= TK_BITAND) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
if (pLeft->pParam == NULL || pLeft->pParam->nExpr < 1) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pLeft->pParam->nExpr; i++) {
|
||||
tSqlExprItem* pParamElem = &(pLeft->pParam->a[i]);
|
||||
if (pParamElem->pNode->nSQLOptr != TK_ALL && pParamElem->pNode->nSQLOptr != TK_ID) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||
if ((getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
|
||||
if (index.columnIndex <= 0 ||
|
||||
index.columnIndex >= tscGetNumOfColumns(pTableMeta)) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
}
|
||||
|
||||
tSqlExprItem item = {.pNode = pLeft, .aliasName = NULL, .distinct = false};
|
||||
|
||||
int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
|
||||
|
||||
// ADD TRUE FOR TEST
|
||||
if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, &item, true) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
int32_t slot = tscNumOfFields(pQueryInfo) - 1;
|
||||
SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, slot);
|
||||
|
||||
if (pInfo->pFieldFilters == NULL) {
|
||||
SColumn* pFieldFilters = calloc(1, sizeof(SColumn));
|
||||
if (pFieldFilters == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pInfo->pFieldFilters = pFieldFilters;
|
||||
}
|
||||
|
||||
return handleExprInHavingClause(pCmd, pQueryInfo, pInfo->pFieldFilters, pExpr, parentOptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t parseHavingClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlCmd* pCmd) {
|
||||
const char* msg1 = "having only works with group by";
|
||||
//const char* msg2 = "invalid column name in having clause";
|
||||
//const char* msg3 = "columns from one table allowed as having columns";
|
||||
//const char* msg4 = "no tag allowed in having clause";
|
||||
const char* msg5 = "invalid expression in having clause";
|
||||
|
||||
/*
|
||||
const char* msg1 = "too many columns in group by clause";
|
||||
const char* msg4 = "join query does not support group by";
|
||||
const char* msg7 = "not support group by expression";
|
||||
const char* msg8 = "not allowed column type for group by";
|
||||
const char* msg9 = "tags not allowed for table query";
|
||||
*/
|
||||
|
||||
// todo : handle two tables situation
|
||||
//STableMetaInfo* pTableMetaInfo = NULL;
|
||||
|
||||
if (pExpr == NULL || (*pExpr) == NULL) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (pQueryInfo->groupbyExpr.numOfGroupCols <= 0) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
if ((*pExpr)->pLeft == NULL || (*pExpr)->pRight == NULL) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||
}
|
||||
|
||||
if (pQueryInfo->colList == NULL) {
|
||||
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
|
||||
}
|
||||
|
||||
int32_t ret = 0;
|
||||
|
||||
if ((ret = getHavingExpr(pCmd, pQueryInfo, pExpr, TK_AND)) != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
|
||||
if (pColumn == NULL) {
|
||||
return NULL;
|
||||
|
@ -3715,40 +3958,7 @@ static bool isValidExpr(tSQLExpr* pLeft, tSQLExpr* pRight, int32_t optr) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static void exchangeExpr(tSQLExpr* pExpr) {
|
||||
tSQLExpr* pLeft = pExpr->pLeft;
|
||||
tSQLExpr* pRight = pExpr->pRight;
|
||||
|
||||
if (pRight->nSQLOptr == TK_ID && (pLeft->nSQLOptr == TK_INTEGER || pLeft->nSQLOptr == TK_FLOAT ||
|
||||
pLeft->nSQLOptr == TK_STRING || pLeft->nSQLOptr == TK_BOOL)) {
|
||||
/*
|
||||
* exchange value of the left handside and the value of the right-handside
|
||||
* to make sure that the value of filter expression always locates in
|
||||
* right-handside and
|
||||
* the column-id is at the left handside.
|
||||
*/
|
||||
uint32_t optr = 0;
|
||||
switch (pExpr->nSQLOptr) {
|
||||
case TK_LE:
|
||||
optr = TK_GE;
|
||||
break;
|
||||
case TK_LT:
|
||||
optr = TK_GT;
|
||||
break;
|
||||
case TK_GT:
|
||||
optr = TK_LT;
|
||||
break;
|
||||
case TK_GE:
|
||||
optr = TK_LE;
|
||||
break;
|
||||
default:
|
||||
optr = pExpr->nSQLOptr;
|
||||
}
|
||||
|
||||
pExpr->nSQLOptr = optr;
|
||||
SWAP(pExpr->pLeft, pExpr->pRight, void*);
|
||||
}
|
||||
}
|
||||
|
||||
static bool validateJoinExprNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr* pExpr, SColumnIndex* pLeftIndex) {
|
||||
const char* msg1 = "illegal column name";
|
||||
|
@ -6729,7 +6939,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
|||
*/
|
||||
if (pQuerySql->from == NULL) {
|
||||
assert(pQuerySql->fillType == NULL && pQuerySql->pGroupby == NULL && pQuerySql->pWhere == NULL &&
|
||||
pQuerySql->pSortOrder == NULL);
|
||||
pQuerySql->pSortOrder == NULL && pQuerySql->pHaving == NULL);
|
||||
return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySql);
|
||||
}
|
||||
|
||||
|
@ -6817,6 +7027,11 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
|||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
// parse the having clause in the first place
|
||||
if (parseHavingClause(pQueryInfo, &pQuerySql->pHaving, pCmd) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
// set where info
|
||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||
|
||||
|
|
|
@ -1061,6 +1061,10 @@ void tscFieldInfoClear(SFieldInfo* pFieldInfo) {
|
|||
|
||||
tfree(pInfo->pArithExprInfo);
|
||||
}
|
||||
|
||||
if (pInfo->pFieldFilters != NULL) {
|
||||
tscColumnDestroy(pInfo->pFieldFilters);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayDestroy(pFieldInfo->internalField);
|
||||
|
|
|
@ -233,6 +233,8 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
#define TK_SPACE 300
|
||||
#define TK_COMMENT 301
|
||||
#define TK_ILLEGAL 302
|
||||
|
|
|
@ -71,6 +71,7 @@ typedef struct SQuerySQL {
|
|||
SLimitVal slimit; // group limit offset [optional]
|
||||
SArray * fillType; // fill type[optional], SArray<tVariantListItem>
|
||||
SStrToken selectToken; // sql string
|
||||
struct tSQLExpr * pHaving; // having clause [optional]
|
||||
} SQuerySQL;
|
||||
|
||||
typedef struct SCreatedTableInfo {
|
||||
|
@ -242,7 +243,7 @@ void tSqlExprListDestroy(tSQLExprList *pList);
|
|||
|
||||
SQuerySQL *tSetQuerySqlElems(SStrToken *pSelectToken, tSQLExprList *pSelection, SArray *pFrom, tSQLExpr *pWhere,
|
||||
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval,
|
||||
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pGLimit);
|
||||
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pGLimit, tSQLExpr *pHaving);
|
||||
|
||||
SCreateTableSQL *tSetCreateSqlElems(SArray *pCols, SArray *pTags, SQuerySQL *pSelect, int32_t type);
|
||||
|
||||
|
|
|
@ -437,7 +437,7 @@ tagitem(A) ::= PLUS(X) FLOAT(Y). {
|
|||
%type select {SQuerySQL*}
|
||||
%destructor select {doDestroyQuerySql($$);}
|
||||
select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) fill_opt(F) sliding_opt(S) groupby_opt(P) orderby_opt(Z) having_opt(N) slimit_opt(G) limit_opt(L). {
|
||||
A = tSetQuerySqlElems(&T, W, X, Y, P, Z, &K, &S, F, &L, &G);
|
||||
A = tSetQuerySqlElems(&T, W, X, Y, P, Z, &K, &S, F, &L, &G, N);
|
||||
}
|
||||
|
||||
%type union {SSubclauseInfo*}
|
||||
|
@ -455,7 +455,7 @@ cmd ::= union(X). { setSqlInfo(pInfo, X, NULL, TSDB_SQL_SELECT); }
|
|||
// select server_version(), select client_version(),
|
||||
// select server_state();
|
||||
select(A) ::= SELECT(T) selcollist(W). {
|
||||
A = tSetQuerySqlElems(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
A = tSetQuerySqlElems(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
// selcollist is a list of expressions that are to become the return
|
||||
|
|
|
@ -531,7 +531,7 @@ void tSqlSetColumnType(TAOS_FIELD *pField, SStrToken *type) {
|
|||
*/
|
||||
SQuerySQL *tSetQuerySqlElems(SStrToken *pSelectToken, tSQLExprList *pSelection, SArray *pFrom, tSQLExpr *pWhere,
|
||||
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval,
|
||||
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pGLimit) {
|
||||
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pGLimit, tSQLExpr *pHaving) {
|
||||
assert(pSelection != NULL);
|
||||
|
||||
SQuerySQL *pQuery = calloc(1, sizeof(SQuerySQL));
|
||||
|
@ -543,6 +543,7 @@ SQuerySQL *tSetQuerySqlElems(SStrToken *pSelectToken, tSQLExprList *pSelection,
|
|||
pQuery->pGroupby = pGroupby;
|
||||
pQuery->pSortOrder = pSortOrder;
|
||||
pQuery->pWhere = pWhere;
|
||||
pQuery->pHaving = pHaving;
|
||||
|
||||
if (pLimit != NULL) {
|
||||
pQuery->limit = *pLimit;
|
||||
|
@ -589,6 +590,9 @@ void doDestroyQuerySql(SQuerySQL *pQuerySql) {
|
|||
|
||||
tSqlExprDestroy(pQuerySql->pWhere);
|
||||
pQuerySql->pWhere = NULL;
|
||||
|
||||
tSqlExprDestroy(pQuerySql->pHaving);
|
||||
pQuerySql->pHaving = NULL;
|
||||
|
||||
taosArrayDestroyEx(pQuerySql->pSortOrder, freeVariant);
|
||||
pQuerySql->pSortOrder = NULL;
|
||||
|
|
|
@ -2864,7 +2864,7 @@ static YYACTIONTYPE yy_reduce(
|
|||
break;
|
||||
case 147: /* select ::= SELECT selcollist from where_opt interval_opt fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */
|
||||
{
|
||||
yylhsminor.yy114 = tSetQuerySqlElems(&yymsp[-11].minor.yy0, yymsp[-10].minor.yy522, yymsp[-9].minor.yy247, yymsp[-8].minor.yy326, yymsp[-4].minor.yy247, yymsp[-3].minor.yy247, &yymsp[-7].minor.yy430, &yymsp[-5].minor.yy0, yymsp[-6].minor.yy247, &yymsp[0].minor.yy204, &yymsp[-1].minor.yy204);
|
||||
yylhsminor.yy114 = tSetQuerySqlElems(&yymsp[-11].minor.yy0, yymsp[-10].minor.yy522, yymsp[-9].minor.yy247, yymsp[-8].minor.yy326, yymsp[-4].minor.yy247, yymsp[-3].minor.yy247, &yymsp[-7].minor.yy430, &yymsp[-5].minor.yy0, yymsp[-6].minor.yy247, &yymsp[0].minor.yy204, &yymsp[-1].minor.yy204, yymsp[-2].minor.yy326);
|
||||
}
|
||||
yymsp[-11].minor.yy114 = yylhsminor.yy114;
|
||||
break;
|
||||
|
@ -2888,7 +2888,7 @@ static YYACTIONTYPE yy_reduce(
|
|||
break;
|
||||
case 153: /* select ::= SELECT selcollist */
|
||||
{
|
||||
yylhsminor.yy114 = tSetQuerySqlElems(&yymsp[-1].minor.yy0, yymsp[0].minor.yy522, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
yylhsminor.yy114 = tSetQuerySqlElems(&yymsp[-1].minor.yy0, yymsp[0].minor.yy522, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
yymsp[-1].minor.yy114 = yylhsminor.yy114;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue