diff --git a/src/opserver/opserver.py b/src/opserver/opserver.py index 94450af961a..bd46bd56917 100644 --- a/src/opserver/opserver.py +++ b/src/opserver/opserver.py @@ -1168,6 +1168,58 @@ def _query_chunk(self, request, qid, chunk_id): % (qid, chunk_id, time.time())) # end _query_chunk + def _is_valid_stats_table_query(self, request, tabn): + isT_ = False + isT = False + for key, value in request.iteritems(): + if key == "select_fields": + for select_field in value: + if select_field == STAT_TIME_FIELD: + isT = True + elif select_field.find(STAT_TIMEBIN_FIELD) == 0: + isT_ = True + else: + agg_field = select_field.split('(') + if len(agg_field) == 2: + oper = agg_field[0] + field = agg_field[1].split(')')[0] + if oper != "COUNT": + if field == STAT_TIME_FIELD: + isT = True + elif field == STAT_TIMEBIN_FIELD: + isT_ = True + else: + field_found = False + for column in self._VIRTUAL_TABLES[tabn].schema.columns: + if column.name == field: + if column.datatype != "": + field_found = True + if field_found == False: + reply = bottle.HTTPError(_ERRORS[errno.EINVAL], \ + 'Unknown field %s' %field) + return reply + elif field != tabl.split('.')[2]: + reply = bottle.HTTPError(_ERRORS[errno.EINVAL], \ + 'Invalid COUNT field %s' %field) + return reply + elif len(agg_field) == 1: + field_found = False + for column in self._VIRTUAL_TABLES[tabn].schema.columns: + if column.name == select_field: + if column.datatype != "": + field_found = True + if field_found == False: + reply = bottle.HTTPError(_ERRORS[errno.EINVAL], \ + 'Invalid field %s' %select_field) + return reply + + if isT and isT_: + reply = bottle.HTTPError(_ERRORS[errno.EINVAL], \ + "Stats query cannot have both T and T=") + return reply + return None + # end _is_valid_stats_table_query + def _query(self, request): reply = {} try: @@ -1189,6 +1241,12 @@ def _query(self, request): if self._VIRTUAL_TABLES[i].name == tabl: tabn = i + if (tabn is not None) and (tabl.find("StatTable") == 0): + query_err = self._is_valid_stats_table_query(request.json, tabn) + if query_err is not None: + yield query_err + return + if (tabn is not None): tabtypes = {} for cols in self._VIRTUAL_TABLES[tabn].schema.columns: diff --git a/src/query_engine/stats_select.cc b/src/query_engine/stats_select.cc index bdb3fe694e9..b38bdd889c1 100644 --- a/src/query_engine/stats_select.cc +++ b/src/query_engine/stats_select.cc @@ -219,8 +219,7 @@ void StatsSelect::Merge(const MapBufT& input, MapBufT& output) { StatsSelect::StatsSelect(AnalyticsQuery * m_query, const std::vector & select_fields) : main_query(m_query), select_fields_(select_fields), - ts_period_(0), isT_(false), - isTC_(false), isTBC_(false), count_field_() { + ts_period_(0), isT_(false), count_field_() { QE_ASSERT(main_query->is_stat_table_query(main_query->table())); status_ = false; @@ -228,7 +227,7 @@ StatsSelect::StatsSelect(AnalyticsQuery * m_query, for (size_t j=0; jstats().attr()) { - QE_TRACE(DEBUG,"StatsSelect Invalid COUNT field " << sfield); - return; - } - } - } if (agg == QEOpServerProxy::INVALID) { unik_cols_.insert(select_fields_[j]); - QE_TRACE(DEBUG, "StatsSelect unik field " << select_fields_[j]); + QE_TRACE(DEBUG, "StatsSelect unik field " << select_fields_[j]); } else if (agg == QEOpServerProxy::COUNT) { count_field_ = sfield; QE_TRACE(DEBUG, "StatsSelect COUNT " << sfield);