LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-analytics/contrail-query-engine - query.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 653 926 70.5 %
Date: 2026-11-09 02:10:49 Functions: 41 49 83.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : /*
       7             :  * This file will not contain actual query processing code but instead only
       8             :  * the code to 
       9             :  * a) Interact with external interfaces like REDIS etc.
      10             :  * b) Parse JSON strings passed to populate the query structures
      11             :  */
      12             : 
      13             : #include "rapidjson/document.h"
      14             : #include "base/logging.h"
      15             : #include "query.h"
      16             : #include <boost/assign/list_of.hpp>
      17             : #include <boost/foreach.hpp>
      18             : #include <cerrno>
      19             : #include <contrail-collector/vizd_table_desc.h>
      20             : #include "stats_select.h"
      21             : #include "stats_query.h"
      22             : #include "base/regex.h"
      23             : #include "base/connection_info.h"
      24             : #include "utils.h"
      25             : #include <database/cassandra/cql/cql_if.h>
      26             : #include <boost/make_shared.hpp>
      27             : #include "qe_sandesh.h"
      28             : #include <algorithm>
      29             : 
      30             : using std::map;
      31             : using std::string;
      32             : using std::vector;
      33             : using boost::assign::map_list_of;
      34             : using boost::system::error_code;
      35             : using contrail::regex;
      36             : using contrail::regex_match;
      37             : using contrail::regex_search;
      38             : using process::ConnectionState;
      39             : using process::ConnectionType;
      40             : using process::ConnectionStatus;
      41             : 
      42             : int QueryEngine::max_slice_ = 100;
      43             : 
      44             : bool oldDataExists;
      45             : 
      46             : typedef  std::vector< std::pair<std::string, std::string> > spair_vector;
      47             : static spair_vector query_string_to_column_name(0);
      48             : 
      49        3693 : std::string get_column_name(std::string query_string)
      50             : {
      51        3693 :     spair_vector::iterator iter; 
      52             : 
      53        3693 :     for (iter = query_string_to_column_name.begin();
      54        3693 :             iter != query_string_to_column_name.end();
      55           0 :             iter++)
      56             :     {
      57           0 :         if (iter->first == query_string)
      58           0 :             return iter->second;
      59             :     }
      60             : 
      61        3693 :     return query_string;
      62             : }
      63             : 
      64          45 : std::string get_query_string(std::string column_name)
      65             : {
      66          45 :     spair_vector::iterator iter; 
      67             : 
      68          45 :     for (iter = query_string_to_column_name.begin();
      69          45 :             iter != query_string_to_column_name.end();
      70           0 :             iter++)
      71             :     {
      72           0 :         if (iter->second == column_name)
      73           0 :             return iter->first;
      74             :     }
      75             : 
      76          45 :     return column_name;
      77             : }
      78             : 
      79           0 : QueryResultMetaData::~QueryResultMetaData() {
      80           0 : }
      81             : 
      82        1987 : PostProcessingQuery::PostProcessingQuery(
      83             :     const std::map<std::string, std::string>& json_api_data,
      84        1987 :     QueryUnit *main_query) :  QueryUnit(main_query, main_query), 
      85        1987 :         sorted(false), limit(0) {
      86        1987 :     AnalyticsQuery *m_query = (AnalyticsQuery *)main_query;
      87        1987 :     std::map<std::string, std::string>::const_iterator iter;
      88             : 
      89        1987 :     QE_TRACE(DEBUG, __func__ );
      90             : 
      91        1987 :     json_string_ = "";
      92             : 
      93       18895 :     for (iter = json_api_data.begin(); iter != json_api_data.end(); iter++)
      94             :     {
      95       16911 :         if (iter->first == QUERY_SORT_OP)
      96             :         {
      97         126 :             sorted = true;
      98             :             int tmp;
      99         126 :             std::istringstream(iter->second) >> tmp; 
     100         126 :             sorting_type = (sort_op)tmp;
     101         126 :             m_query->merge_needed = true;
     102         126 :             QE_TRACE(DEBUG, "sorting_type :" << sorting_type);
     103         126 :             json_string_ += iter->second;
     104         126 :             json_string_ += " ";
     105             :         }
     106             :         
     107       16913 :         if (iter->first == QUERY_LIMIT)
     108             :         {
     109          85 :             std::istringstream(iter->second) >> limit;
     110          85 :             m_query->merge_needed = true;
     111          85 :             QE_TRACE(DEBUG, "limit :"<< limit);
     112          85 :             json_string_ += iter->second;
     113          85 :             json_string_ += " ";
     114             :         }
     115             : 
     116       16910 :         if (iter->first == QUERY_SORT_FIELDS)
     117             :         {
     118         126 :             contrail_rapidjson::Document d;
     119           0 :             std::string json_string = "{ \"sort_fields\" : " + 
     120         126 :                 iter->second + " }";
     121         126 :             json_string_ += json_string;
     122         126 :             json_string_ += " ";
     123             : 
     124         126 :             d.Parse<0>(const_cast<char *>(json_string.c_str()));
     125             :             const contrail_rapidjson::Value& json_sort_fields =
     126         126 :                 d["sort_fields"]; 
     127         126 :             QE_PARSE_ERROR(json_sort_fields.IsArray());
     128         126 :             QE_TRACE(DEBUG, "# of sort fields:"<< json_sort_fields.Size());
     129         252 :             for (contrail_rapidjson::SizeType i = 0; i<json_sort_fields.Size(); i++) 
     130             :             {
     131         126 :                 QE_PARSE_ERROR(json_sort_fields[i].IsString());
     132         126 :                 std::string sort_str(json_sort_fields[i].GetString());
     133         126 :                 QE_TRACE(DEBUG, "sort field:" << sort_str);
     134         126 :                 std::string datatype(m_query->get_column_field_datatype(sort_str));
     135         126 :                 if (m_query->is_stat_table_query(m_query->table()) &&
     136           0 :                        (m_query->stats().is_stat_table_static())) {
     137             :                     // This is a static StatTable. We can check the schema
     138           0 :                     std::string sfield;
     139             :                     
     140             :                     // If this is an agg field, check underlying data type
     141           0 :                     if (StatsQuery::ParseAgg(sort_str, sfield) !=
     142             :                             QEOpServerProxy::INVALID) {
     143           0 :                         std::string dtype2(m_query->get_column_field_datatype(sfield));
     144           0 :                         QE_INVALIDARG_ERROR(dtype2 != std::string(""));
     145           0 :                     } else {
     146           0 :                         QE_INVALIDARG_ERROR(datatype != std::string(""));
     147             :                     }
     148           0 :                 }
     149         126 :                 QE_INVALIDARG_ERROR(
     150             :                     m_query->is_valid_sort_field(sort_str) != false);
     151         252 :                 sort_field_t sort_field(get_column_name(sort_str), datatype);
     152         126 :                 sort_fields.push_back(sort_field);
     153         126 :             }
     154         126 :         }
     155             : 
     156             :         /*
     157             :          * old filter style is just list of expr ANDed
     158             :          * new filter are list of ANDs over OR
     159             :          * both modes are supported with the below code
     160             :          */
     161       16906 :         if (iter->first == QUERY_FILTER) {
     162         408 :             contrail_rapidjson::Document d;
     163           0 :             std::string json_string = "{ \"filter\" : " + 
     164         408 :                 iter->second + " }";
     165         408 :             json_string_ += json_string;
     166         408 :             json_string_ += " ";
     167             : 
     168         408 :             d.Parse<0>(const_cast<char *>(json_string.c_str()));
     169             :             const contrail_rapidjson::Value& json_filters =
     170         406 :                 d["filter"]; 
     171         407 :             QE_PARSE_ERROR(json_filters.IsArray());
     172         406 :             QE_TRACE(DEBUG, "# of filters:"<< json_filters.Size());
     173         408 :             bool single_list = false;
     174         408 :             if (json_filters.Size()) {
     175         408 :                 contrail_rapidjson::SizeType zeroth = 0;
     176         408 :                 const contrail_rapidjson::Value& json_filters_0 = json_filters[zeroth];
     177         408 :                 if (!json_filters_0.IsArray()) {
     178         374 :                     single_list = true;
     179             :                 }
     180             :             }
     181             : 
     182         408 :             if (single_list) {
     183             :                 //parse the old format 
     184         374 :                 std::vector<filter_match_t> filter_and;
     185         748 :                 for (contrail_rapidjson::SizeType j = 0; j<json_filters.Size(); j++) 
     186             :                   {
     187         374 :                     filter_match_t filter;
     188         374 :                     QE_PARSE_ERROR((json_filters[j].HasMember(WHERE_MATCH_NAME)
     189             :                         && json_filters[j].HasMember(WHERE_MATCH_VALUE)
     190             :                         && json_filters[j].HasMember(WHERE_MATCH_OP)));
     191             :                     const contrail_rapidjson::Value& name_value = 
     192         374 :                         json_filters[j][WHERE_MATCH_NAME];
     193             :                     const contrail_rapidjson::Value&  value_value = 
     194         374 :                         json_filters[j][WHERE_MATCH_VALUE];
     195             :                     const contrail_rapidjson::Value& op_value = 
     196         374 :                         json_filters[j][WHERE_MATCH_OP];
     197             : 
     198             :                     // do some validation checks
     199         374 :                     QE_INVALIDARG_ERROR(name_value.IsString());
     200         374 :                     QE_INVALIDARG_ERROR
     201             :                         ((value_value.IsString() || value_value.IsNumber() ||
     202             :                           value_value.IsDouble()));
     203         374 :                     QE_INVALIDARG_ERROR(op_value.IsNumber());
     204             : 
     205         374 :                     filter.name = name_value.GetString();
     206         374 :                     filter.op = (match_op)op_value.GetInt();
     207             : 
     208             :                     // extract value after type conversion
     209             :                       {
     210         373 :                         if (value_value.IsString())
     211             :                           {
     212         135 :                             filter.value = value_value.GetString();
     213         238 :                           } else if (value_value.IsInt()){
     214             :                               int int_value;
     215         220 :                               std::ostringstream convert;
     216         220 :                               int_value = value_value.GetInt();
     217         220 :                               convert << int_value;
     218         220 :                               filter.value = convert.str();
     219         238 :                           } else if (value_value.IsUint()) {
     220             :                               uint32_t uint_value;
     221           0 :                               std::ostringstream convert;
     222           0 :                               uint_value = value_value.GetUint();
     223           0 :                               convert << uint_value;
     224           0 :                               filter.value = convert.str();
     225          18 :                           } else if (value_value.IsDouble()) {
     226             :                               double dbl_value;
     227          18 :                               std::ostringstream convert;
     228          18 :                               dbl_value = value_value.GetDouble();
     229          18 :                               convert << dbl_value;
     230          18 :                               filter.value = convert.str();
     231          18 :                           }
     232             :                       }
     233             : 
     234         373 :                     if (filter.op == REGEX_MATCH)
     235             :                       {
     236             :                         // compile regex beforehand
     237         301 :                         filter.match_e = regex(filter.value);
     238             :                       }
     239             : 
     240         374 :                     filter_and.push_back(filter);
     241         374 :                   }
     242         373 :                 filter_list.push_back(filter_and);
     243         374 :             } else {
     244             :                 //new OR of ANDs
     245          85 :                 for (contrail_rapidjson::SizeType j = 0; j<json_filters.Size(); j++) {
     246          51 :                     std::vector<filter_match_t> filter_and;
     247          51 :                     const contrail_rapidjson::Value& json_filter_and = json_filters[j];
     248          51 :                     QE_PARSE_ERROR(json_filter_and.IsArray());
     249             : 
     250         102 :                     for (contrail_rapidjson::SizeType k = 0; k<json_filter_and.Size(); k++) {
     251          51 :                         filter_match_t filter;
     252          51 :                         QE_PARSE_ERROR((
     253             :                             json_filter_and[k].HasMember(WHERE_MATCH_NAME)
     254             :                             && json_filter_and[k].HasMember(WHERE_MATCH_VALUE)
     255             :                             && json_filter_and[k].HasMember(WHERE_MATCH_OP)));
     256             :                         const contrail_rapidjson::Value& name_value = 
     257          51 :                             json_filter_and[k][WHERE_MATCH_NAME];
     258             :                         const contrail_rapidjson::Value&  value_value = 
     259          51 :                             json_filter_and[k][WHERE_MATCH_VALUE];
     260             :                         const contrail_rapidjson::Value& op_value = 
     261          51 :                             json_filter_and[k][WHERE_MATCH_OP];
     262             : 
     263             :                         // do some validation checks
     264          51 :                         QE_INVALIDARG_ERROR(name_value.IsString());
     265          51 :                         QE_INVALIDARG_ERROR
     266             :                             ((value_value.IsString() || value_value.IsNumber()));
     267          51 :                         QE_INVALIDARG_ERROR(op_value.IsNumber());
     268             : 
     269          51 :                         filter.name = name_value.GetString();
     270          51 :                         filter.op = (match_op)op_value.GetInt();
     271             : 
     272             :                         // extract value after type conversion
     273          51 :                         if (value_value.IsString()) {
     274          51 :                             filter.value = value_value.GetString();
     275           0 :                         } else if (value_value.IsInt()) {
     276             :                             int int_value;
     277           0 :                             std::ostringstream convert;
     278           0 :                             int_value = value_value.GetInt();
     279           0 :                             convert << int_value;
     280           0 :                             filter.value = convert.str();
     281           0 :                         } else if (value_value.IsUint()) {
     282             :                             uint32_t uint_value;
     283           0 :                             std::ostringstream convert;
     284           0 :                             uint_value = value_value.GetUint();
     285           0 :                             convert << uint_value;
     286           0 :                             filter.value = convert.str();
     287           0 :                         }
     288             : 
     289          51 :                         if (filter.op == REGEX_MATCH) {
     290             :                             // compile regex beforehand
     291           0 :                             filter.match_e = regex(filter.value);
     292             :                         }
     293             : 
     294          51 :                         filter_and.push_back(filter);
     295          51 :                     }
     296          51 :                     filter_list.push_back(filter_and);
     297          51 :                 }
     298             :             }
     299         408 :         }
     300             :     }
     301             : 
     302        1986 :     if (!m_query->wherequery_->filter_list_.empty()) {
     303           0 :         if (filter_list.empty()) {
     304           0 :             filter_list = m_query->wherequery_->filter_list_;
     305             :         } else {
     306           0 :             BOOST_FOREACH(std::vector<filter_match_t> &filter_and, filter_list) {
     307           0 :                 BOOST_FOREACH(const std::vector<filter_match_t> &where_filter_and,
     308             :                         m_query->wherequery_->filter_list_) {
     309           0 :                     filter_and.insert(filter_and.end(), where_filter_and.begin(),
     310             :                         where_filter_and.end());
     311             :                 }
     312             :             }
     313             :         }
     314             :     }
     315             : 
     316             :     // add filter to filter query engine logs if requested
     317        3792 :     if (((AnalyticsQuery *)main_query)->filter_qe_logs &&
     318        1806 :         ((AnalyticsQuery *)main_query)->is_message_table_query()) {
     319         355 :         QE_TRACE(DEBUG,  " Adding filter for QE logs");
     320         355 :         filter_match_t filter;
     321         355 :         filter.name = g_viz_constants.MODULE;
     322             :         filter.value = 
     323         355 :             ((AnalyticsQuery *)main_query)->sandesh_moduleid;
     324         355 :         filter.op = NOT_EQUAL;
     325         355 :         filter.ignore_col_absence = true;
     326         355 :         if (!filter_list.size()) {
     327         177 :             std::vector<filter_match_t> filter_and;
     328         177 :             filter_and.push_back(filter);
     329         176 :             filter_list.push_back(filter_and);
     330         176 :         } else {
     331         373 :             for (unsigned int i = 0; i < filter_list.size(); i++) {
     332         190 :                 filter_list[i].push_back(filter);
     333             :             }
     334             :         }
     335         359 :     }
     336             : 
     337             :     // If the user has specified the sorting field and not the sorting order,
     338             :     // then sort the result in ascending order.
     339        1985 :     if (sort_fields.size() && sorted == false) {
     340           0 :         sorted = true;
     341           0 :         sorting_type = ASCENDING; 
     342             :     }
     343           0 : }
     344             : 
     345          32 : bool AnalyticsQuery::merge_processing(
     346             :     const QEOpServerProxy::BufferT& input, 
     347             :     QEOpServerProxy::BufferT& output) {
     348             : 
     349          32 :     if (status_details != 0)
     350             :     {
     351           0 :         QE_TRACE(DEBUG, 
     352             :              "No need to process query, as there were errors previously");
     353           0 :         return false;
     354             :     }
     355             : 
     356             :     // Have the result ready and processing is done
     357          32 :     status_details = 0;
     358          32 :     return postprocess_->merge_processing(input, output);
     359             : }
     360             : 
     361           4 : bool AnalyticsQuery::final_merge_processing(
     362             : const std::vector<boost::shared_ptr<QEOpServerProxy::BufferT> >& inputs,
     363             :     QEOpServerProxy::BufferT& output) {
     364             : 
     365           4 :     if (status_details != 0)
     366             :     {
     367           0 :         QE_TRACE(DEBUG, 
     368             :              "No need to process query, as there were errors previously");
     369           0 :         return false;
     370             :     }
     371             : 
     372             :     // Have the result ready and processing is done
     373           4 :     status_details = 0;
     374           4 :     return postprocess_->final_merge_processing(inputs, output);
     375             : }
     376             : 
     377             : // this is to get parallelization details once the query is parsed
     378         126 : void AnalyticsQuery::get_query_details(bool& is_merge_needed, bool& is_map_output,
     379             :         std::vector<uint64_t>& chunk_sizes,
     380             :         std::string& where, uint32_t& wterms,
     381             :         std::string& select,
     382             :         std::string& post,
     383             :         uint64_t& time_period,
     384             :         int& parse_status)
     385             : {
     386         126 :     QE_TRACE(DEBUG, "time_slice is " << time_slice);
     387         126 :     if (status_details == 0)
     388             :     {
     389         126 :         for (uint64_t chunk_start = original_from_time; 
     390         982 :                 chunk_start < original_end_time; chunk_start += time_slice)
     391             :         {
     392         856 :             if ((chunk_start+time_slice) <= original_end_time) {
     393         737 :                 chunk_sizes.push_back(time_slice);
     394             :             } else {
     395         119 :                 chunk_sizes.push_back((original_end_time - chunk_start));
     396             :             }
     397             :         }
     398             :     } else {
     399           0 :         chunk_sizes.push_back(0); // just return some dummy value
     400             :     }
     401             : 
     402         126 :     time_period = (end_time_ - from_time_) / 1000000;
     403             : 
     404         126 :     parse_status = status_details;
     405         126 :     if (parse_status != 0) return;
     406             :     
     407         126 :     if (is_stat_table_query(table_)
     408          88 :         || is_session_query(table_)
     409         214 :         || is_flow_query(table_)) {
     410          70 :         is_merge_needed = selectquery_->stats_->IsMergeNeeded();
     411             :     } else {
     412          56 :         is_merge_needed = merge_needed;
     413             :     }
     414             : 
     415         126 :     where = wherequery_->json_string_;
     416         126 :     wterms = wherequery_->wterms_;
     417         126 :     select = selectquery_->json_string_;
     418         126 :     post = postprocess_->json_string_;
     419         252 :     is_map_output = is_stat_table_query(table_)
     420          88 :                         || is_session_query(table_)
     421         214 :                         || is_flow_query(table_);
     422             : }
     423             : 
     424        1985 : bool AnalyticsQuery::can_parallelize_query() {
     425        1985 :     parallelize_query_ = true;
     426        1985 :     if (table_ == g_viz_constants.OBJECT_VALUE_TABLE) {
     427          21 :         parallelize_query_ = false;
     428             :     }
     429        1985 :     return parallelize_query_;
     430             : }
     431             : 
     432             : /* parse the stat name and attribute which can be used
     433             :  * to collect stats. Table name is of the format,
     434             :  * StatTable.TableName.AttrName
     435             :  * The functions sets the stat_name_attr member, which is later
     436             :  * used to collect stats information
     437             :  */
     438         688 : void AnalyticsQuery::ParseStatName(std::string& stat_table_name) {
     439         688 :      string stat_table("StatTable.");
     440         688 :      stat_name_attr = stat_table_name.substr(stat_table.length());
     441         689 :      std::replace(stat_name_attr.begin(), stat_name_attr.end(), '.', ':');
     442         689 : }
     443             : 
     444        2001 : void AnalyticsQuery::Init(const std::string& qid,
     445             :     const std::map<std::string, std::string>& json_api_data,
     446             :     int32_t or_number)
     447             : {
     448        2001 :     std::map<std::string, std::string>::const_iterator iter;
     449             : 
     450        2001 :     QE_TRACE(DEBUG, __func__);
     451             :     
     452             :     // populate fields 
     453        2003 :     query_id = qid;
     454             : 
     455             :     sandesh_moduleid = 
     456        2003 :         g_vns_constants.ModuleNames.find(Module::QUERY_ENGINE)->second;
     457             : 
     458             :     {
     459        2003 :         std::stringstream json_string; json_string << " { ";
     460        2003 :         for (std::map<std::string, 
     461        2003 :                 std::string>::iterator it = json_api_data_.begin();
     462       18904 :                 it != json_api_data_.end(); it++) {
     463             :             json_string << 
     464       33801 :                 ((it != json_api_data_.begin())? " , " : "") <<
     465       16898 :                 it->first << ": " << it->second;
     466             :         }
     467        2002 :         json_string << " } ";
     468        6408 :         QE_LOG_GLOBAL(DEBUG, "json query is: " << json_string.str());
     469        2002 :     }
     470             : 
     471             :     // parse JSON query
     472             :     // FROM field
     473             :     {
     474        2002 :         iter = json_api_data.find(QUERY_TABLE);
     475        2033 :         QE_PARSE_ERROR(iter != json_api_data.end());
     476             : 
     477             :         //strip " from the passed string
     478        1985 :         table_ = iter->second.substr(1, iter->second.size()-2);
     479             : 
     480             :         // boost::to_upper(table);
     481        1986 :         QE_TRACE(DEBUG,  " table is " << table_);
     482        1987 :         if (is_stat_table_query(table_)) {
     483         692 :             stats_.reset(new StatsQuery(table_));
     484         688 :             ParseStatName(table_);
     485             :         }
     486             :     }
     487             : 
     488             :     uint64_t ttl;
     489        1984 :     uint64_t min_start_time = UTCTimestampUsec();
     490        1986 :     uint64_t max_end_time = min_start_time;
     491             : 
     492        1986 :     if (is_stat_table_query(table_)) {
     493         691 :         ttl = ttlmap_.find(TtlType::STATSDATA_TTL)->second;
     494        1295 :     } else if (is_flow_query(table_) || is_session_query(table_)) {
     495         365 :         ttl = ttlmap_.find(TtlType::FLOWDATA_TTL)->second;
     496         930 :     } else if (is_object_table_query(table_)) {
     497         395 :         ttl = ttlmap_.find(TtlType::CONFIGAUDIT_TTL)->second;
     498             :     } else {
     499         535 :         ttl = ttlmap_.find(TtlType::GLOBAL_TTL)->second;
     500             :     }
     501        1984 :     min_start_time = min_start_time-ttl*60*60*1000000;
     502             : 
     503             :     // Start time
     504             :     {
     505        1984 :         iter = json_api_data.find(QUERY_START_TIME);
     506        1983 :         QE_PARSE_ERROR(iter != json_api_data.end());
     507        1983 :         QE_PARSE_ERROR(parse_time(iter->second, &req_from_time_));
     508        1987 :         QE_TRACE(DEBUG,  " from_time is " << req_from_time_);
     509        1987 :         if (req_from_time_ < min_start_time) 
     510             :         {
     511           1 :             from_time_ = min_start_time;
     512           1 :             QE_TRACE(DEBUG, "updated start_time to:" << from_time_);
     513             :         } else {
     514        1986 :             from_time_ = req_from_time_;
     515             :         }
     516             :     }
     517             : 
     518             :     // End time
     519             :     {
     520        1987 :         iter = json_api_data.find(QUERY_END_TIME);
     521        1986 :         QE_PARSE_ERROR(iter != json_api_data.end());
     522        1986 :         QE_PARSE_ERROR(parse_time(iter->second, &req_end_time_));
     523        1987 :         QE_TRACE(DEBUG,  " end_time is " << req_end_time_);
     524             : 
     525        1987 :         if (req_end_time_ > max_end_time) {
     526          70 :             end_time_ = max_end_time;
     527          70 :             QE_TRACE(DEBUG, "updated end_time to:" << end_time_);
     528             :         } else {
     529        1917 :             end_time_ = req_end_time_;
     530             :         }
     531             :     }
     532             : 
     533        1987 :     if (is_stat_fieldnames_table_query(table_)) {
     534          37 :         uint64_t time_period = (end_time_ - from_time_); /* in usec */
     535          37 :         uint64_t cache_time = (1 << (g_viz_constants.RowTimeInBits +
     536          37 :                                      g_viz_constants.CacheTimeInAdditionalBits));
     537          37 :         if (time_period < cache_time) {
     538          19 :             uint64_t diff_time_usec = (cache_time - time_period);
     539          19 :             from_time_ = from_time_ - diff_time_usec;
     540          19 :             if (from_time_ < min_start_time) {
     541           0 :                 from_time_ = min_start_time;
     542             :             }
     543             :         }
     544             :     }
     545             : 
     546             :     // Initialize SELECT/WHERE/Post-Processing components of query
     547             :     // for input validation
     548             : 
     549             :     // where processing initialization
     550        1987 :     std::string where_json_string;
     551             :     {
     552        1987 :         int direction = INGRESS;
     553        1987 :         iter = json_api_data.find(QUERY_FLOW_DIR);
     554        1987 :         if (iter != json_api_data.end()) {
     555           0 :             std::istringstream(iter->second) >> direction;
     556           0 :             QE_TRACE(DEBUG,  "set flow direction to:" << direction);
     557             :         }
     558             : 
     559        1986 :         int is_si = 0;
     560        1986 :         iter = json_api_data.find(QUERY_SESSION_IS_SI);
     561        1986 :         if (iter != json_api_data.end()) {
     562         329 :             std::istringstream(iter->second) >> is_si;
     563         329 :             QE_TRACE(DEBUG,  "set session is_si to:" << is_si);
     564             :         }
     565             : 
     566        1985 :         int session_type = 0;
     567        1985 :         iter = json_api_data.find(QUERY_SESSION_TYPE);
     568        1985 :         if (iter != json_api_data.end()) {
     569         329 :             if (iter->second == "\"client\"") {
     570         306 :                 session_type = 1;
     571          23 :             } else if (iter->second == "\"server\"") {
     572          23 :                 session_type = 0;
     573             :             } else {
     574           0 :                 QE_INVALIDARG_ERROR(false && "session_type_invalid");
     575             :             }
     576         329 :             QE_TRACE(DEBUG,  "set session is_si to:" << session_type);
     577             :         }
     578        1656 :         else if (is_session_query(table_)) {
     579           0 :             QE_LOG_GLOBAL(ERROR, "session_type is required for session queries");
     580           0 :             this->status_details = -1;
     581           0 :             return;
     582             :         }
     583             :         
     584        1985 :         iter = json_api_data.find(QUERY_WHERE);
     585        1985 :         if (iter == json_api_data.end())
     586             :         {
     587         349 :             QE_TRACE(DEBUG, "Where * query");
     588         349 :             where_json_string = std::string("");
     589             :         } else {
     590        1636 :             where_json_string = iter->second;
     591             :         }
     592             : 
     593        1985 :         QE_TRACE(DEBUG,  " Initializing Where Query");
     594        1985 :         wherequery_ = new WhereQuery(where_json_string, session_type,
     595        1987 :                 is_si, direction, or_number, this);
     596        1985 :         this->status_details = wherequery_->status_details;
     597        1985 :         if (this->status_details != 0 )
     598             :         {
     599           0 :             QE_LOG_GLOBAL(DEBUG, "Error in WHERE parsing");
     600           0 :             return;
     601             :         }
     602             :     }
     603             : 
     604             :     // select processing initialization
     605             :     {
     606        1985 :         QE_TRACE(DEBUG,  " Initializing Select Query");
     607        1987 :         selectquery_ = new SelectQuery(this, json_api_data);
     608        1986 :         this->status_details = selectquery_->status_details;
     609        1986 :         if (this->status_details != 0 )
     610             :         {
     611           0 :             QE_LOG_GLOBAL(DEBUG, "Error in SELECT parsing");
     612           0 :             return;
     613             :         }
     614             :         /*
     615             :          * ObjectId queries are special, they are requested from Object* tables,
     616             :          * but the values are extrated from g_viz_constants.OBJECT_VALUE_TABLE
     617             :          */
     618        1986 :         if (is_object_table_query(table_)) {
     619         395 :             if (selectquery_->ObjectIdQuery()) {
     620          21 :                 object_value_key = table_;
     621          21 :                 table_ = g_viz_constants.OBJECT_VALUE_TABLE;
     622             :             }
     623             :         }
     624             :     }
     625             : 
     626             :     // post processing initialization
     627        1986 :     QE_TRACE(DEBUG,  " Initializing PostProcessing Query");
     628        1987 :     postprocess_ = new PostProcessingQuery(json_api_data, this);
     629        1985 :     this->status_details = postprocess_->status_details;
     630        1985 :     if (this->status_details != 0 )
     631             :     {
     632           0 :         QE_LOG_GLOBAL(DEBUG, "Error in PostProcess parsing");
     633           0 :         return;
     634             :     }
     635             : 
     636        1985 :     if (is_stat_table_query(table_)
     637        1293 :         || is_session_query(table_)
     638        3277 :         || is_flow_query(table_)) {
     639        1057 :         selectquery_->stats_->SetSortOrder(postprocess_->sort_fields);
     640             :     }
     641             : 
     642             :     // just to take care of issues with Analytics start time 
     643        1985 :          if (from_time_ > end_time_)
     644           1 :             from_time_ = end_time_ - 1; 
     645             : 
     646             :     // Get the right job slice for parallelization
     647        1985 :     original_from_time = from_time_;
     648        1985 :     original_end_time = end_time_;
     649             : 
     650        1985 :     if (can_parallelize_query()) {
     651        1964 :         uint64_t smax = pow(2,g_viz_constants.RowTimeInBits) * \
     652        1966 :               QueryEngine::max_slice_;
     653             : 
     654        1966 :         time_slice = ((end_time_ - from_time_)/total_parallel_batches) + 1;
     655             : 
     656        1966 :         if (time_slice < (uint64_t)pow(2,g_viz_constants.RowTimeInBits)) {
     657         417 :             time_slice = pow(2,g_viz_constants.RowTimeInBits);
     658             :         }
     659        1966 :         if (time_slice > smax) {
     660           0 :             time_slice = smax;
     661             :         }          
     662        1966 :         QE_TRACE(DEBUG, "time_slice:" << time_slice << " , # of parallel "
     663             :                 "batches:" << total_parallel_batches);
     664             : 
     665             :     } else {
     666             :         // No parallelization
     667          84 :         QE_LOG_GLOBAL(DEBUG, "No parallelization for this query");
     668          21 :         merge_needed = false;
     669          21 :         parallelize_query_ = false;
     670          21 :         time_slice = end_time_ - from_time_;
     671             :     }
     672             : 
     673        1987 :     from_time_ = 
     674        1987 :         original_from_time + time_slice*parallel_batch_num;
     675        1987 :     end_time_ = from_time_ + time_slice;
     676        1987 :     if (from_time_ >= original_end_time)
     677             :     {
     678           0 :         processing_needed = false;
     679        1987 :     } else if (end_time_ > original_end_time) {
     680         246 :         end_time_ = original_end_time;
     681             :     }
     682             : 
     683        1987 :     if (processing_needed)
     684             :     {
     685             :         // change it to trace later TBD
     686        1987 :         QE_TRACE(DEBUG, "For batch:" << parallel_batch_num << " from_time:" << from_time_ << " end_time:" << end_time_ << " time slice:" << time_slice);
     687             :     } else {
     688           0 :         QE_TRACE(DEBUG, "No processing needed for batch:" << parallel_batch_num);
     689             :     }
     690             : 
     691        1987 : }
     692       12064 : QueryUnit::QueryUnit(QueryUnit *p_query, QueryUnit *m_query):
     693       12058 :     parent_query(p_query), main_query(m_query), pending_subqueries(0),
     694       12064 :     query_status(QUERY_PROCESSING_NOT_STARTED), status_details(0) 
     695             : {
     696       12055 :     if (p_query)
     697       10052 :         p_query->sub_queries.push_back(this);
     698       12056 : };
     699             : 
     700       12064 : QueryUnit::~QueryUnit()
     701             : {
     702       12064 :     int num_sub_queries = sub_queries.size();
     703       22127 :     for(int i = 0; i<num_sub_queries; i++)
     704       10065 :         delete sub_queries[i];
     705       12062 : }
     706             : 
     707             : 
     708             : // Get UUID from the info field
     709           0 : void query_result_unit_t::get_uuid(boost::uuids::uuid& u) const
     710             : {
     711             :     try {
     712           0 :         u = boost::get<boost::uuids::uuid>(info.at(0));
     713           0 :     } catch (boost::bad_get& ex) {
     714           0 :         QE_ASSERT(0);
     715             :     }
     716           0 : }
     717             : 
     718         220 : void query_result_unit_t::set_stattable_info(
     719             :         const std::string& attribstr,
     720             :         const boost::uuids::uuid& uuid) {
     721         220 :     info.push_back(attribstr);
     722         220 :     info.push_back(uuid);
     723         220 : }
     724             : 
     725           1 : void query_result_unit_t::get_objectid(std::string& object_id) const {
     726             :     try {
     727           1 :         object_id = boost::get<std::string>(info.at(1));
     728           0 :     } catch (boost::bad_get& ex) {
     729           0 :         QE_ASSERT(0);
     730           0 :     } catch (const std::out_of_range& oor) {
     731           0 :         QE_ASSERT(0);
     732             :     }
     733           1 : }
     734             : 
     735         103 : void  query_result_unit_t::get_stattable_info(
     736             :             std::string& attribstr,
     737             :             boost::uuids::uuid& uuid) const {
     738             : 
     739         103 :     int index = 0;
     740             : 
     741             :     try {
     742         103 :         attribstr = boost::get<std::string>(info.at(index++));
     743           0 :     } catch (boost::bad_get& ex) {
     744           0 :         QE_ASSERT(0);
     745           0 :     } catch (const std::out_of_range& oor) {
     746           0 :         QE_ASSERT(0);
     747             :     }
     748             : 
     749             :     try {
     750         103 :         uuid = boost::get<boost::uuids::uuid>(info.at(index++));
     751           0 :     } catch (boost::bad_get& ex) {
     752           0 :         QE_ASSERT(0);
     753           0 :     } catch (const std::out_of_range& oor) {
     754           0 :         QE_ASSERT(0);
     755             :     }
     756             : 
     757         103 : }
     758             : 
     759         857 : query_status_t AnalyticsQuery::process_query()
     760             : {
     761         857 :     if (status_details != 0)
     762             :     {
     763           0 :         QE_TRACE(DEBUG, 
     764             :              "No need to process query, as there were errors previously");
     765           0 :         return QUERY_FAILURE;
     766             :     }
     767             : 
     768         857 :     QE_TRACE(DEBUG, "Start Select Processing");
     769         857 :     select_start_ = UTCTimestampUsec();
     770         857 :     query_status = selectquery_->process_query();
     771         857 :     status_details = selectquery_->status_details;
     772         857 :     qperf_.chunk_select_time =
     773         857 :             static_cast<uint32_t>((UTCTimestampUsec() - select_start_)/1000);
     774             : 
     775         857 :     if (query_status != QUERY_SUCCESS)
     776             :     {
     777           0 :         QE_LOG(DEBUG, 
     778             :                 "select processing failed with error:"<< query_status);
     779           0 :         return query_status;
     780             :     }
     781         857 :     QE_TRACE(DEBUG, "End Select Processing. row #s:" << 
     782             :             selectquery_->result_->size());
     783         857 :     QE_TRACE(DEBUG, "Start PostProcessing");
     784         857 :     postproc_start_ = UTCTimestampUsec();
     785         857 :     query_status = postprocess_->process_query();
     786         857 :     status_details = postprocess_->status_details;
     787         857 :     qperf_.chunk_postproc_time =
     788         857 :             static_cast<uint32_t>((UTCTimestampUsec() - postproc_start_)/1000);
     789             : 
     790         857 :     final_result = std::move(postprocess_->result_);
     791         857 :     final_mresult = std::move(postprocess_->mresult_);
     792         857 :     if (query_status != QUERY_SUCCESS)
     793             :     {
     794           0 :         QE_LOG(DEBUG, 
     795             :                 "post processing failed with error:"<< query_status);
     796           0 :         return query_status;
     797             :     }
     798         857 :     QE_TRACE(DEBUG, "End PostProcessing. row #s:" << 
     799             :             final_result->size());
     800         857 :     return QUERY_SUCCESS;
     801             : }
     802             : 
     803           0 : AnalyticsQuery::AnalyticsQuery(const std::string& qid, std::map<std::string,
     804             :         std::string>& json_api_data,
     805             :         int or_number,
     806             :         const std::vector<query_result_unit_t> * where_info,
     807             :         const TtlMap& ttlmap,
     808             :         EventManager *evm, std::vector<std::string> cassandra_ips, 
     809             :         std::vector<int> cassandra_ports, int batch,
     810             :         int total_batches, const std::string& cassandra_user,
     811             :         const std::string& cassandra_password,
     812             :         QueryEngine* qe,
     813           0 :         void *handle):
     814             :         QueryUnit(NULL, this),
     815           0 :         filter_qe_logs(true),
     816           0 :         json_api_data_(json_api_data),
     817           0 :         where_info_(where_info),
     818           0 :         ttlmap_(ttlmap),
     819           0 :         where_start_(0),
     820           0 :         select_start_(0),
     821           0 :         postproc_start_(0),
     822           0 :         merge_needed(false),
     823           0 :         parallel_batch_num(batch),
     824           0 :         total_parallel_batches(total_batches),
     825           0 :         processing_needed(true),
     826           0 :         qe_(qe),
     827           0 :         handle_(handle),
     828           0 :         stats_(nullptr)
     829             : {
     830           0 :     assert(dbif_ != NULL);
     831             :     // Need to do this for logging/tracing with query ids
     832           0 :     query_id = qid;
     833             : 
     834           0 :     QE_TRACE(DEBUG, __func__);
     835             : 
     836             :     // Initialize database connection
     837           0 :     QE_TRACE(DEBUG, "Initializing database");
     838             : 
     839           0 :     boost::system::error_code ec;
     840           0 :     if (!dbif_->Db_Init()) {
     841           0 :         QE_LOG(ERROR, "Database initialization failed");
     842           0 :         this->status_details = EIO;
     843             :     }
     844             : 
     845           0 :     if (!dbif_->Db_SetTablespace(qe_->keyspace())) {
     846           0 :         QE_LOG(ERROR,  ": Create/Set KEYSPACE: " <<
     847             :            g_viz_constants.COLLECTOR_KEYSPACE << " FAILED");
     848           0 :         this->status_details = EIO;
     849             :     }   
     850           0 :     for (std::vector<GenDb::NewCf>::const_iterator it = vizd_tables.begin();
     851           0 :             it != vizd_tables.end(); it++) {
     852           0 :         if (!dbif_->Db_UseColumnfamily(*it)) {
     853           0 :             QE_LOG(ERROR, "Database initialization:Db_UseColumnfamily failed");
     854           0 :             this->status_details = EIO;
     855             :         }
     856             :     }
     857           0 :     for (std::vector<GenDb::NewCf>::const_iterator it = vizd_stat_tables.begin();
     858           0 :             it != vizd_stat_tables.end(); it++) {
     859           0 :         if (!dbif_->Db_UseColumnfamily(*it)) {
     860           0 :             QE_LOG(ERROR, "Database initialization:Db_UseColumnfamily failed");
     861           0 :             this->status_details = EIO;
     862             :         }
     863             :     }
     864           0 :     for (std::vector<GenDb::NewCf>::const_iterator it = vizd_session_tables.begin();
     865           0 :             it != vizd_session_tables.end(); it++) {
     866           0 :         if (!dbif_->Db_UseColumnfamily(*it)) {
     867           0 :             QE_LOG(ERROR, "Database initialization:Db_UseColumnfamily failed");
     868           0 :             this->status_details = EIO;
     869             :         }
     870             :     }
     871           0 :     if (this->status_details != 0) {
     872             :         // Update connection info
     873           0 :         ConnectionState::GetInstance()->Update(ConnectionType::DATABASE,
     874           0 :             std::string(), ConnectionStatus::DOWN, dbif_->Db_GetEndpoints(),
     875           0 :             std::string());
     876             :     } else {
     877             :         // Update connection info
     878           0 :         ConnectionState::GetInstance()->Update(ConnectionType::DATABASE,
     879           0 :             std::string(), ConnectionStatus::UP, dbif_->Db_GetEndpoints(),
     880           0 :             std::string());
     881             :     }
     882           0 :     dbif_->Db_SetInitDone(true);
     883           0 :     Init(qid, json_api_data, or_number);
     884           0 : }
     885             : 
     886        2003 : AnalyticsQuery::AnalyticsQuery(const std::string& qid,
     887             :     GenDbIfPtr dbif_ptr,
     888             :     std::map<std::string, std::string> json_api_data,
     889             :     int or_number,
     890             :     const std::vector<query_result_unit_t> * where_info,
     891             :     const TtlMap &ttlmap, int batch, int total_batches,
     892             :     QueryEngine* qe,
     893        2003 :     void *handle) :
     894             :     QueryUnit(NULL, this),
     895        2003 :     dbif_(dbif_ptr),
     896        2003 :     query_id(qid),
     897        2002 :     filter_qe_logs(true),
     898        2002 :     json_api_data_(json_api_data),
     899        1998 :     where_info_(where_info),
     900        1998 :     ttlmap_(ttlmap),
     901        1999 :     where_start_(0), 
     902        1999 :     select_start_(0), 
     903        1999 :     postproc_start_(0),
     904        1998 :     merge_needed(false),
     905        1998 :     parallel_batch_num(batch),
     906        1998 :     total_parallel_batches(total_batches),
     907        1998 :     processing_needed(true),
     908        1998 :     qe_(qe),
     909        1998 :     handle_(handle),
     910        6004 :     stats_(nullptr) {
     911        2001 :     Init(qid, json_api_data, or_number);
     912        2003 : }
     913             : 
     914          19 : QueryEngine::QueryEngine(EventManager *evm,
     915             :             vector<string> redis_ip_ports,
     916             :             const std::string & redis_password,
     917             :             const bool redis_ssl_enable,
     918             :             const std::string & redis_keyfile,
     919             :             const std::string & redis_certfile,
     920             :             const std::string & redis_ca_cert,
     921             :             int max_tasks, int max_slice,
     922             :             const std::string & cassandra_user,
     923             :             const std::string & cassandra_password,
     924             :             bool cassandra_use_ssl,
     925             :             const std::string & cassandra_ca_certs,
     926          19 :             const std::string &host_ip) :
     927          38 :         qosp_(new QEOpServerProxy(evm,
     928             :             this, redis_ip_ports, redis_password, redis_ssl_enable, redis_keyfile,
     929          19 :             redis_certfile, redis_ca_cert, host_ip, max_tasks)),
     930          19 :         evm_(evm),
     931          19 :         cassandra_ports_(0),
     932          19 :         cassandra_user_(cassandra_user),
     933          19 :         cassandra_password_(cassandra_password),
     934          19 :         cassandra_use_ssl_(cassandra_use_ssl),
     935          57 :         cassandra_ca_certs_(cassandra_ca_certs)
     936             : {
     937          19 :     max_slice_ =  max_slice;
     938             :     // default keyspace
     939          19 :     keyspace_ = g_viz_constants.COLLECTOR_KEYSPACE_CQL;
     940          19 :     init_vizd_tables();
     941             : 
     942             :     // Initialize database connection
     943          19 :     QE_LOG_NOQID(DEBUG, "Initializing QE without database!");
     944             : 
     945          19 :     ttlmap_ = g_viz_constants.TtlValuesDefault;
     946          19 :     max_tasks_ = max_tasks;
     947          19 : }
     948             : 
     949          25 : QueryEngine::QueryEngine(EventManager *evm,
     950             :             std::vector<std::string> cassandra_ips,
     951             :             std::vector<int> cassandra_ports,
     952             :             vector<string> redis_ip_ports,
     953             :             const std::string & redis_password,
     954             :             const bool redis_ssl_enable,
     955             :             const std::string & redis_keyfile,
     956             :             const std::string & redis_certfile,
     957             :             const std::string & redis_ca_cert,
     958             :             int max_tasks, int max_slice,
     959             :             const std::string & cassandra_user,
     960             :             const std::string & cassandra_password,
     961             :             bool cassandra_use_ssl,
     962             :             const std::string & cassandra_ca_certs,
     963             :             const std::string & cluster_id,
     964          25 :             const std::string &host_ip) :
     965          50 :         qosp_(new QEOpServerProxy(evm,
     966             :             this, redis_ip_ports, redis_password, redis_ssl_enable, redis_keyfile,
     967          25 :             redis_certfile, redis_ca_cert, host_ip, max_tasks)),
     968          25 :         evm_(evm),
     969          25 :         cassandra_ports_(cassandra_ports),
     970          25 :         cassandra_ips_(cassandra_ips),
     971          25 :         cassandra_user_(cassandra_user),
     972          25 :         cassandra_password_(cassandra_password),
     973          25 :         cassandra_use_ssl_(cassandra_use_ssl),
     974          50 :         cassandra_ca_certs_(cassandra_ca_certs) {
     975          25 :         dbif_.reset(new cass::cql::CqlIf(evm, cassandra_ips,
     976          25 :             cassandra_ports[0], cassandra_user, cassandra_password,
     977          25 :             cassandra_use_ssl_, cassandra_ca_certs_));
     978          25 :         if (cluster_id.empty()) {
     979          25 :             keyspace_ = g_viz_constants.COLLECTOR_KEYSPACE_CQL;
     980             :         } else {
     981           0 :             keyspace_ = g_viz_constants.COLLECTOR_KEYSPACE_CQL + '_' + cluster_id;
     982             :         }
     983          25 :     max_slice_ = max_slice;
     984          25 :     max_tasks_ = max_tasks;
     985          25 :     oldDataExists = true;
     986          25 :     init_vizd_tables();
     987             : 
     988             :     // Initialize database connection
     989          25 :     QE_TRACE_NOQID(DEBUG, "Initializing database");
     990             : 
     991          25 :     boost::system::error_code ec;
     992          25 :     int retries = 0;
     993          25 :     bool retry = true;
     994          50 :     while (retry == true) {
     995          25 :         retry = false;
     996             : 
     997          25 :         if (!dbif_->Db_Init()) {
     998           0 :             QE_LOG_NOQID(ERROR, "Database initialization failed");
     999           0 :             retry = true;
    1000             :         }
    1001             : 
    1002          25 :         if (!retry) {
    1003          25 :             if (!dbif_->Db_SetTablespace(keyspace_)) {
    1004           0 :                 QE_LOG_NOQID(ERROR,  ": Create/Set KEYSPACE: " <<
    1005             :                              keyspace_ << " FAILED");
    1006           0 :                 retry = true;
    1007             :             }
    1008             :         }
    1009             : 
    1010          25 :         if (!retry) {
    1011          25 :             for (std::vector<GenDb::NewCf>::const_iterator it = vizd_tables.begin();
    1012         100 :                     it != vizd_tables.end(); it++) {
    1013          75 :                 if (!dbif_->Db_UseColumnfamily(*it)) {
    1014           0 :                     retry = true;
    1015           0 :                     break;
    1016             :                 }
    1017             :             }
    1018             :         }
    1019             : 
    1020          25 :         if (!retry) {
    1021          25 :             for (std::vector<GenDb::NewCf>::const_iterator it =
    1022          25 :                     vizd_stat_tables.begin();
    1023          50 :                     it != vizd_stat_tables.end(); it++) {
    1024          25 :                 if (!dbif_->Db_UseColumnfamily(*it)) {
    1025           0 :                     retry = true;
    1026           0 :                     break;
    1027             :                 }
    1028             :             }
    1029             : 
    1030             :         }
    1031             : 
    1032          25 :         if (!retry) {
    1033          25 :             for (std::vector<std::string>::const_iterator it = 
    1034          25 :                     g_viz_constants._STATS_TABLES.begin();
    1035          25 :                     it != g_viz_constants._STATS_TABLES.end() - 1; it++) {
    1036          25 :                 if (!dbif_->Db_UseColumnfamily(*it)) {
    1037          25 :                     oldDataExists = false;
    1038          25 :                     QE_LOG_NOQID(DEBUG, "Older table does not exist. will query only the new table");
    1039          25 :                     break;
    1040             :                 }
    1041             :             }
    1042             :         }
    1043          25 :         if (oldDataExists) {
    1044           0 :             QE_LOG_NOQID(DEBUG, "Older table exists. will query both the tables");
    1045             :         }
    1046             : 
    1047          25 :         if (!retry) {
    1048          25 :             for (std::vector<GenDb::NewCf>::const_iterator it =
    1049          25 :                     vizd_session_tables.begin();
    1050          50 :                     it != vizd_session_tables.end(); it++) {
    1051          25 :                 if (!dbif_->Db_UseColumnfamily(*it)) {
    1052           0 :                     retry = true;
    1053           0 :                     break;
    1054             :                 }
    1055             :             }
    1056             : 
    1057             :         }
    1058             : 
    1059          25 :         if (retry) {
    1060           0 :             std::stringstream ss;
    1061           0 :             ss << "initialization of database failed. retrying " << retries++ << " time";
    1062             :             // Update connection info
    1063           0 :             ConnectionState::GetInstance()->Update(ConnectionType::DATABASE,
    1064           0 :                 std::string(), ConnectionStatus::DOWN,
    1065           0 :                 dbif_->Db_GetEndpoints(), std::string());
    1066           0 :             Q_E_LOG_LOG("QeInit", SandeshLevel::SYS_WARN, ss.str());
    1067           0 :             dbif_->Db_Uninit();
    1068           0 :             sleep(5);
    1069           0 :         }
    1070             :     }
    1071             :     {
    1072          25 :         bool init_done = false;
    1073          25 :         retries = 0;
    1074          50 :         while (!init_done && retries < 12) {
    1075          25 :             init_done = true;
    1076             : 
    1077          25 :             GenDb::ColList col_list;
    1078          25 :             std::string cfname = g_viz_constants.SYSTEM_OBJECT_TABLE;
    1079          25 :             GenDb::DbDataValueVec key;
    1080          25 :             key.push_back(g_viz_constants.SYSTEM_OBJECT_ANALYTICS);
    1081             : 
    1082             :             bool ttl_cached[TtlType::GLOBAL_TTL+1];
    1083         125 :             for (int ttli=0; ttli<=TtlType::GLOBAL_TTL; ttli++)
    1084         100 :                 ttl_cached[ttli] = false;
    1085             : 
    1086          25 :             if (dbif_->Db_GetRow(&col_list, cfname, key,
    1087             :                 GenDb::DbConsistency::LOCAL_ONE)) {
    1088          25 :                 for (GenDb::NewColVec::iterator it = col_list.columns_.begin();
    1089         250 :                         it != col_list.columns_.end(); it++) {
    1090         225 :                     std::string col_name;
    1091             :                     try {
    1092         225 :                         col_name = boost::get<std::string>(it->name->at(0));
    1093           0 :                     } catch (boost::bad_get& ex) {
    1094           0 :                         QE_LOG_NOQID(ERROR, __func__ << ": Exception on col_name get");
    1095           0 :                         break;
    1096           0 :                     }
    1097         225 :                     if (col_name == g_viz_constants.SYSTEM_OBJECT_GLOBAL_DATA_TTL) {
    1098             :                             try {
    1099          25 :                                 ttlmap_.insert(std::make_pair(TtlType::GLOBAL_TTL, boost::get<uint64_t>(it->value->at(0))));
    1100          25 :                                 ttl_cached[TtlType::GLOBAL_TTL] = true;
    1101           0 :                             } catch (boost::bad_get& ex) {
    1102           0 :                                 QE_LOG_NOQID(ERROR, __func__ << "Exception for boost::get, what=" << ex.what());
    1103           0 :                             }
    1104         200 :                     } else if (col_name == g_viz_constants.SYSTEM_OBJECT_CONFIG_AUDIT_TTL) {
    1105             :                             try {
    1106          25 :                                 ttlmap_.insert(std::make_pair(TtlType::CONFIGAUDIT_TTL, boost::get<uint64_t>(it->value->at(0))));
    1107          25 :                                 ttl_cached[TtlType::CONFIGAUDIT_TTL] = true;
    1108           0 :                             } catch (boost::bad_get& ex) {
    1109           0 :                                 QE_LOG_NOQID(ERROR, __func__ << "Exception for boost::get, what=" << ex.what());
    1110           0 :                             }
    1111         175 :                     } else if (col_name == g_viz_constants.SYSTEM_OBJECT_STATS_DATA_TTL) {
    1112             :                             try {
    1113          25 :                                 ttlmap_.insert(std::make_pair(TtlType::STATSDATA_TTL, boost::get<uint64_t>(it->value->at(0))));
    1114          25 :                                 ttl_cached[TtlType::STATSDATA_TTL] = true;
    1115           0 :                             } catch (boost::bad_get& ex) {
    1116           0 :                                 QE_LOG_NOQID(ERROR, __func__ << "Exception for boost::get, what=" << ex.what());
    1117           0 :                             }
    1118         150 :                     } else if (col_name == g_viz_constants.SYSTEM_OBJECT_FLOW_DATA_TTL) {
    1119             :                             try {
    1120          25 :                                 ttlmap_.insert(std::make_pair(TtlType::FLOWDATA_TTL, boost::get<uint64_t>(it->value->at(0))));
    1121          25 :                                 ttl_cached[TtlType::FLOWDATA_TTL] = true;
    1122           0 :                             } catch (boost::bad_get& ex) {
    1123           0 :                                 QE_LOG_NOQID(ERROR, __func__ << "Exception for boost::get, what=" << ex.what());
    1124           0 :                             }
    1125             :                     }
    1126         225 :                 }
    1127             :             }
    1128         125 :             for (int ttli=0; ttli<=TtlType::GLOBAL_TTL; ttli++)
    1129         100 :                 if (ttl_cached[ttli] == false)
    1130           0 :                     init_done = false;
    1131             : 
    1132          25 :             retries++;
    1133          25 :             if (!init_done)
    1134           0 :                 sleep(5);
    1135          25 :         }
    1136          25 :         if (!init_done) {
    1137           0 :             ttlmap_ = g_viz_constants.TtlValuesDefault;
    1138           0 :             QE_LOG_NOQID(ERROR, __func__ << "ttls are set manually");
    1139             :         }
    1140             :     }
    1141          25 :     dbif_->Db_SetInitDone(true);
    1142             :     // Update connection info
    1143          50 :     ConnectionState::GetInstance()->Update(ConnectionType::DATABASE,
    1144          50 :         std::string(), ConnectionStatus::UP, dbif_->Db_GetEndpoints(),
    1145          50 :         std::string());
    1146          25 : }
    1147             : 
    1148          98 : QueryEngine::~QueryEngine() {
    1149          49 :     if (dbif_) {
    1150          25 :         dbif_->Db_Uninit();
    1151          25 :         dbif_->Db_SetInitDone(false);
    1152             :     }
    1153          98 : }
    1154             : 
    1155             : using std::vector;
    1156             : 
    1157             : int
    1158         126 : QueryEngine::QueryPrepare(QueryParams qp,
    1159             :         std::vector<uint64_t> &chunk_size,
    1160             :         bool & need_merge, bool & map_output,
    1161             :         std::string& where, uint32_t& wterms,
    1162             :         std::string& select, std::string& post,
    1163             :         uint64_t& time_period, 
    1164             :         std::string &table) {
    1165         126 :     string& qid = qp.qid;
    1166         126 :     QE_LOG_NOQID(INFO, 
    1167             :              " Got Query to prepare for QID " << qid);
    1168             :     int ret_code;
    1169         126 :     if (cassandra_ports_.size() == 1 && cassandra_ports_[0] == 0) {
    1170           0 :         chunk_size.push_back(999);
    1171           0 :         need_merge = false;
    1172           0 :         map_output = false;
    1173           0 :         ret_code = 0;
    1174           0 :         table = string("ObjectCollectorInfo");
    1175             :     } else {
    1176             :         AnalyticsQuery *q;
    1177         252 :         q = new AnalyticsQuery(qid, dbif_, qp.terms, -1, NULL, ttlmap_, 0,
    1178         126 :                 qp.maxChunks, this);
    1179         126 :         chunk_size.clear();
    1180         126 :         q->get_query_details(need_merge, map_output, chunk_size,
    1181             :             where, wterms ,select, post, time_period, ret_code);
    1182         126 :         table = q->table();
    1183         126 :         delete q;
    1184             :     }
    1185         126 :     return ret_code;
    1186             : }
    1187             : 
    1188             : bool
    1189          32 : QueryEngine::QueryAccumulate(QueryParams qp,
    1190             :         const QEOpServerProxy::BufferT& input,
    1191             :         QEOpServerProxy::BufferT& output) {
    1192             : 
    1193          32 :     QE_TRACE_NOQID(DEBUG, "Creating analytics query object for merge_processing");
    1194             :     AnalyticsQuery *q;
    1195          64 :     q = new AnalyticsQuery(qp.qid, dbif_, qp.terms, -1, NULL, ttlmap_, 1,
    1196          32 :                 qp.maxChunks, this);
    1197          32 :     QE_TRACE_NOQID(DEBUG, "Calling merge_processing");
    1198          32 :     bool ret = q->merge_processing(input, output);
    1199          32 :     delete q;
    1200          32 :     return ret;
    1201             : }
    1202             : 
    1203             : bool
    1204           4 : QueryEngine::QueryFinalMerge(QueryParams qp,
    1205             :         const std::vector<boost::shared_ptr<QEOpServerProxy::BufferT> >& inputs,
    1206             :         QEOpServerProxy::BufferT& output) {
    1207             : 
    1208           4 :     QE_TRACE_NOQID(DEBUG, "Creating analytics query object for final_merge_processing");
    1209             :     AnalyticsQuery *q;
    1210           8 :     q = new AnalyticsQuery(qp.qid, dbif_, qp.terms, -1, NULL, ttlmap_, 1,
    1211           4 :                 qp.maxChunks, this);
    1212           4 :     QE_TRACE_NOQID(DEBUG, "Calling final_merge_processing");
    1213           4 :     bool ret = q->final_merge_processing(inputs, output);
    1214           4 :     delete q;
    1215           4 :     return ret;
    1216             : }
    1217             : 
    1218             : bool
    1219          63 : QueryEngine::QueryFinalMerge(QueryParams qp,
    1220             :         const std::vector<boost::shared_ptr<QEOpServerProxy::OutRowMultimapT> >& inputs,
    1221             :         QEOpServerProxy::OutRowMultimapT& output) {
    1222          63 :     QE_TRACE_NOQID(DEBUG, "Creating analytics query object for final_merge_processing");
    1223             :     AnalyticsQuery *q;
    1224         126 :     q = new AnalyticsQuery(qp.qid, dbif_, qp.terms, -1, NULL, ttlmap_, 1,
    1225          63 :                 qp.maxChunks, this);
    1226             : 
    1227          63 :     if (!q->is_stat_table_query(q->table())
    1228          90 :         && !q->is_session_query(q->table())
    1229          90 :         && !q->is_flow_query(q->table())) {
    1230           0 :         QE_TRACE_NOQID(DEBUG, "MultiMap merge_final is for Stats only");
    1231           0 :         delete q;
    1232           0 :         return false;
    1233             :     }
    1234          63 :     QE_TRACE_NOQID(DEBUG, "Calling final_merge_processing for Stats");
    1235             : 
    1236          63 :     q->selectquery_->stats_->MergeFinal(inputs, output);
    1237             :     // apply limit
    1238          65 :     if (q->postprocess_->limit &&
    1239           2 :         output.size() > (size_t)q->postprocess_->limit) {
    1240           0 :             QEOpServerProxy::OutRowMultimapT::iterator it = output.begin();
    1241           0 :             std::advance(it, (size_t)q->postprocess_->limit);
    1242           0 :             output.erase(it, output.end());
    1243             :     }
    1244          63 :     delete q;
    1245          63 :     return true;   
    1246             : }
    1247             : 
    1248             : // Query Execution of WHERE term
    1249             : bool
    1250         899 : QueryEngine::QueryExecWhere(void * handle, QueryParams qp, uint32_t chunk,
    1251             :         uint32_t or_number)
    1252             : {
    1253         899 :     string& qid = qp.qid;
    1254         899 :     QE_TRACE_NOQID(DEBUG,
    1255             :              " Got Where Query to execute for QID " << qid << " chunk:"<< chunk);
    1256         904 :     if (cassandra_ports_.size() == 1 && cassandra_ports_[0] == 0) {
    1257             :         std::unique_ptr<std::vector<query_result_unit_t> > where_output(
    1258           0 :                 new std::vector<query_result_unit_t>());
    1259           0 :         QE_TRACE_NOQID(DEBUG, " Finished NULL query processing for QID " << qid << " chunk:" << chunk);
    1260           0 :         QEOpServerProxy::QPerfInfo qperf(0,0,0);
    1261           0 :         qperf.error = 0;
    1262             : 
    1263           0 :         qosp_->QueryResult(handle, qperf, std::auto_ptr<std::vector<query_result_unit_t>>(where_output.release()));
    1264           0 :         return true;
    1265           0 :     }
    1266        1808 :     boost::shared_ptr<AnalyticsQuery> q(new AnalyticsQuery(qid, dbif_, qp.terms,
    1267        1808 :         or_number, NULL, ttlmap_, chunk, qp.maxChunks, this, handle));
    1268             :     // populate into a vector mainted by QOSP
    1269         904 :     qosp_->AddAnalyticsQuery(qid, q);
    1270         904 :     QE_TRACE_NOQID(DEBUG, " Finished parsing and starting where for QID " << qid << " chunk:" << chunk);
    1271             : 
    1272         904 :     q->where_start_ = UTCTimestampUsec();
    1273             :     // Bind the callback function to where query
    1274         904 :     q->wherequery_->where_query_cb_ = boost::bind(&QEOpServerProxy::QueryResult, qosp_.get(), _1, _2, _3);
    1275         904 :     q->query_status = q->wherequery_->process_query();
    1276         904 :     bool query_status_ = false;
    1277         904 :     switch (q->query_status) {
    1278           0 :         case QUERY_PROCESSING_NOT_STARTED:
    1279             :             /* should not come here */
    1280             :         case QUERY_FAILURE:
    1281           0 :             break;
    1282           7 :         case QUERY_SUCCESS:
    1283          14 :             q->qperf_.chunk_where_time =
    1284           7 :                 static_cast<uint32_t>((UTCTimestampUsec() - q->where_start_)
    1285           7 :                 /1000);
    1286           7 :             q->qperf_.error = q->status_details;
    1287           7 :             qosp_->QueryResult(q->handle_, q->qperf_, std::auto_ptr<std::vector<query_result_unit_t>>(q->wherequery_->where_result_.release()));
    1288         904 :         case QUERY_IN_PROGRESS:
    1289         904 :             query_status_ = true;
    1290         904 :             break;
    1291             :     }
    1292         904 :     return query_status_;
    1293         904 : }
    1294             : 
    1295             : // Query Execution of SELECT and post-processing
    1296             : bool
    1297         856 : QueryEngine::QueryExec(void * handle, QueryParams qp, uint32_t chunk,
    1298             :         const std::vector<query_result_unit_t> * where_info)
    1299             : {
    1300         856 :     string& qid = qp.qid;
    1301         856 :     QE_TRACE_NOQID(DEBUG,
    1302             :              " Got Query to execute for QID " << qid << " chunk:"<< chunk);
    1303             :     //GenDb::GenDbIf *db_if = dbif_.get();
    1304         856 :     if (cassandra_ports_.size() == 1 && cassandra_ports_[0] == 0) {
    1305           0 :         std::unique_ptr<QEOpServerProxy::BufferT> final_output(new QEOpServerProxy::BufferT);
    1306           0 :         QEOpServerProxy::OutRowT outrow = boost::assign::map_list_of(
    1307           0 :             "MessageTS", "1368037623434740")(
    1308           0 :             "Messagetype", "IFMapString")(
    1309           0 :             "ModuleId", "ControlNode")(
    1310           0 :             "Source","b1s1")(
    1311           0 :             "ObjectLog","\n<IFMapString type=\"sandesh\"><message type=\"string\" identifier=\"1\">Cancelling Response timer.</message><file type=\"string\" identifier=\"-32768\">src/ifmap/client/ifmap_state_machine.cc</file><line type=\"i32\" identifier=\"-32767\">578</line></IFMapString>");
    1312           0 :         QEOpServerProxy::MetadataT metadata;
    1313           0 :         std::unique_ptr<QEOpServerProxy::OutRowMultimapT> final_moutput(new QEOpServerProxy::OutRowMultimapT);
    1314           0 :         for (int i = 0 ; i < 100; i++)
    1315           0 :             final_output->push_back(std::make_pair(outrow, metadata));
    1316           0 :         QE_TRACE_NOQID(DEBUG, " Finished query processing for QID " << qid << " chunk:" << chunk);
    1317           0 :         QEOpServerProxy::QPerfInfo qperf(0,0,0);
    1318           0 :         qperf.error = 0;
    1319           0 :         qosp_->QueryResult(handle, qperf, std::auto_ptr<QEOpServerProxy::BufferT>(final_output.release()), std::auto_ptr<QEOpServerProxy::OutRowMultimapT>(final_moutput.release()));
    1320           0 :         return true;
    1321           0 :     }
    1322             :     AnalyticsQuery *q;
    1323        1712 :     q = new AnalyticsQuery(qid, dbif_, qp.terms, -1, where_info, ttlmap_, chunk,
    1324         856 :                 qp.maxChunks, this);
    1325             : 
    1326         856 :     QE_TRACE_NOQID(DEBUG, " Finished parsing and starting processing for QID " << qid << " chunk:" << chunk); 
    1327         856 :     q->process_query(); 
    1328             : 
    1329         856 :     QE_TRACE_NOQID(DEBUG, " Finished query processing for QID " << qid << " chunk:" << chunk);
    1330         856 :     q->qperf_.error = q->status_details;
    1331         856 :     qosp_->QueryResult(handle, q->qperf_, std::auto_ptr<QEOpServerProxy::BufferT>(q->final_result.release()), std::auto_ptr<QEOpServerProxy::OutRowMultimapT>(q->final_mresult.release()));
    1332         856 :     delete q;
    1333         855 :     return true;
    1334             : }
    1335             : 
    1336           4 : bool QueryEngine::GetCumulativeStats(std::vector<GenDb::DbTableInfo> *vdbti,
    1337             :         GenDb::DbErrors *dbe, std::vector<GenDb::DbTableInfo> *vstats_dbti)
    1338             :         const {
    1339             :     {
    1340           4 :         std::scoped_lock lock(smutex_);
    1341           4 :         stable_stats_.GetCumulative(vstats_dbti);
    1342           4 :     }
    1343           4 :     return dbif_->Db_GetCumulativeStats(vdbti, dbe);
    1344             : }
    1345             : 
    1346             : 
    1347           0 : std::ostream &operator<<(std::ostream &out, query_result_unit_t& res)
    1348             : {
    1349           0 :     out << "T:" << res.timestamp << " : Need to extract other information";
    1350             : #if 0
    1351             :     out << "T:" << res.timestamp << " : ";
    1352             : 
    1353             :     if (res.info.length() < 48) {
    1354             :         boost::uuids::uuid tmp_u;
    1355             :         res.get_uuid(tmp_u);
    1356             :         out << " UUID:" << tmp_u;
    1357             :     }
    1358             : #endif
    1359             : 
    1360           0 :     return out;
    1361             : }
    1362             : 
    1363             : bool
    1364      162432 : AnalyticsQuery::is_stat_table_query(const std::string & tname) {
    1365      162432 :     if (tname.compare(0, g_viz_constants.STAT_VT_PREFIX.length(),
    1366             :             g_viz_constants.STAT_VT_PREFIX)) {
    1367      148019 :         return false;
    1368             :     }
    1369       14561 :     return true;
    1370             : }
    1371             : 
    1372             : bool
    1373      157630 : AnalyticsQuery::is_session_query(const std::string & tname) {
    1374      311445 :     return (tname == g_viz_constants.SESSION_SERIES_TABLE ||
    1375      311487 :             tname == g_viz_constants.SESSION_RECORD_TABLE);
    1376             : }
    1377             : 
    1378             : bool
    1379        1987 : AnalyticsQuery::is_stat_fieldnames_table_query(const std::string & tname) {
    1380        1987 :     if (tname.compare(0, g_viz_constants.STAT_VT_FIELDNAMES_PREFIX.length(),
    1381             :             g_viz_constants.STAT_VT_FIELDNAMES_PREFIX)) {
    1382        1950 :         return false;
    1383             :     }
    1384          37 :     return true;
    1385             : }
    1386             : 
    1387      139738 : bool AnalyticsQuery::is_flow_query(const std::string & tname)
    1388             : {
    1389      277375 :     return ((tname == g_viz_constants.FLOW_SERIES_TABLE) ||
    1390      277387 :         (tname == g_viz_constants.FLOW_TABLE));
    1391             : }
    1392             : 
    1393             : // validation functions
    1394        4130 : bool AnalyticsQuery::is_message_table_query(const std::string &tname)
    1395             : {
    1396        4130 :     return (tname == g_viz_constants.MESSAGE_TABLE);
    1397             : }
    1398             : 
    1399        8481 : bool AnalyticsQuery::is_message_table_query()
    1400             : {
    1401        8481 :     return (table_ == g_viz_constants.MESSAGE_TABLE);
    1402             : }
    1403             : 
    1404       19149 : bool AnalyticsQuery::is_object_table_query(const std::string &tname)
    1405             : {
    1406             :     return (
    1407       34897 :         (tname != g_viz_constants.MESSAGE_TABLE) &&
    1408       31499 :         (tname != g_viz_constants.FLOW_TABLE) &&
    1409       31237 :         (tname != g_viz_constants.FLOW_SERIES_TABLE) &&
    1410       15490 :         (tname != g_viz_constants.OBJECT_VALUE_TABLE) &&
    1411       46530 :         !is_stat_table_query(tname) &&
    1412       30782 :         !is_session_query(tname));
    1413             : }
    1414             : 
    1415        2122 : bool AnalyticsQuery::is_valid_where_field(const std::string& where_field)
    1416             : {
    1417       10111 :     for(size_t i = 0; i < g_viz_constants._TABLES.size(); i++)
    1418             :     {
    1419        9000 :         if (g_viz_constants._TABLES[i].name == table_)
    1420             :         {
    1421        6979 :             for (size_t j = 0; 
    1422        6979 :                 j < g_viz_constants._TABLES[i].schema.columns.size(); j++)
    1423             :             {
    1424        6978 :                 if ((g_viz_constants._TABLES[i].schema.columns[j].name ==
    1425        7990 :                         where_field) &&
    1426        1011 :                         g_viz_constants._TABLES[i].schema.columns[j].index)
    1427        1011 :                     return true;
    1428             :             }
    1429           0 :             return false;
    1430             :         }
    1431             :     }
    1432        1109 :     if (is_stat_table_query(table_)) {
    1433         770 :         AnalyticsQuery *m_query = (AnalyticsQuery *)main_query;
    1434         770 :         if (m_query->stats().is_stat_table_static()) {
    1435         465 :             StatsQuery::column_t cdesc = m_query->stats().get_column_desc(where_field);
    1436         466 :             if (cdesc.index) return true;
    1437         466 :         } else {
    1438             :             // For dynamic Stat Table queries, allow anything in the where clause
    1439         305 :             return true;
    1440             :         }
    1441             :     }
    1442         340 :     return true;
    1443             : }
    1444             : 
    1445         126 : bool AnalyticsQuery::is_valid_sort_field(const std::string& sort_field) {
    1446         126 :     if (
    1447         252 :         (sort_field == SELECT_PACKETS) ||
    1448         252 :         (sort_field == SELECT_BYTES) ||
    1449         378 :         (sort_field == SELECT_SUM_PACKETS) ||
    1450         126 :         (sort_field == SELECT_SUM_BYTES)
    1451             :         )
    1452           0 :         return true;
    1453             : 
    1454         126 :     return selectquery_->is_present_in_select_column_fields(sort_field);
    1455             : }
    1456             : 
    1457         126 : std::string AnalyticsQuery::get_column_field_datatype(
    1458             :                                     const std::string& column_field) {
    1459         234 :     for(size_t i = 0; i < g_viz_constants._TABLES.size(); i++) {
    1460         234 :         if (g_viz_constants._TABLES[i].name == table_) {
    1461        1284 :             for (size_t j = 0; 
    1462        1284 :                  j < g_viz_constants._TABLES[i].schema.columns.size(); j++) {
    1463        1284 :                 if (g_viz_constants._TABLES[i].schema.columns[j].name == 
    1464             :                         column_field) {
    1465         126 :                     return g_viz_constants._TABLES[i].schema.columns[j].datatype;
    1466             :                 }
    1467             :             }
    1468           0 :             return std::string("");
    1469             :         }
    1470             :     }
    1471           0 :     if (stats_.get()) {
    1472           0 :         StatsQuery::column_t vt = stats().get_column_desc(column_field);
    1473           0 :         if (vt.datatype == QEOpServerProxy::STRING)
    1474           0 :             return string("string");
    1475           0 :         else if (vt.datatype == QEOpServerProxy::UINT64)
    1476           0 :             return string("int");
    1477           0 :         else if (vt.datatype == QEOpServerProxy::DOUBLE)
    1478           0 :             return string("double");
    1479             :         else
    1480           0 :             return string("");
    1481           0 :     }
    1482           0 :     return std::string("");
    1483             : }
    1484             : 
    1485             : std::map< std::string, int > trace_enable_map;
    1486           0 : void TraceEnable::HandleRequest() const
    1487             : {
    1488           0 :     TraceEnableRes *resp = new TraceEnableRes;
    1489           0 :     std::string status;
    1490           0 :     std::string trace_type = get_TraceType();
    1491           0 :     if (trace_type == WHERE_RESULT_TRACE || trace_type == SELECT_RESULT_TRACE ||
    1492           0 :         trace_type == POSTPROCESS_RESULT_TRACE) {
    1493           0 :         if (get_enable())
    1494             :         {
    1495           0 :             trace_enable_map.insert(std::make_pair(trace_type, 1));
    1496           0 :             status = "Trace buffer Enabled";
    1497             :         } else {
    1498           0 :             trace_enable_map.erase(trace_type);
    1499           0 :             status = "Trace buffer Disabled";
    1500             :         }
    1501             :     } else {
    1502           0 :         status = "Invalid Trace buffer";
    1503             :     }
    1504           0 :     resp->set_enable_disable_status(status);
    1505           0 :     resp->set_TraceType(trace_type);
    1506           0 :     resp->set_context(context());
    1507           0 :     resp->set_more(false);
    1508           0 :     resp->Response();
    1509           0 : }
    1510             : 
    1511           0 : void TraceStatusReq::HandleRequest() const {
    1512           0 :     std::vector<std::string> trace_buf_list;
    1513           0 :     trace_buf_list.push_back(WHERE_RESULT_TRACE);
    1514           0 :     trace_buf_list.push_back(SELECT_RESULT_TRACE);
    1515           0 :     trace_buf_list.push_back(POSTPROCESS_RESULT_TRACE);
    1516           0 :     std::vector<TraceStatusInfo> trace_status_list;
    1517           0 :     for (std::vector<std::string>::const_iterator it = trace_buf_list.begin();
    1518           0 :          it != trace_buf_list.end(); ++it) {
    1519           0 :         TraceStatusInfo trace_status;
    1520           0 :         trace_status.set_TraceType(*it);
    1521           0 :         if (IS_TRACE_ENABLED(*it)) {
    1522           0 :             trace_status.set_enable_disable("Enabled");
    1523             :         } else {
    1524           0 :             trace_status.set_enable_disable("Disabled");
    1525             :         }
    1526           0 :         trace_status_list.push_back(trace_status);
    1527           0 :     }
    1528           0 :     TraceStatusRes *resp = new TraceStatusRes;
    1529           0 :     resp->set_trace_status_list(trace_status_list);
    1530           0 :     resp->set_context(context());
    1531           0 :     resp->set_more(false);
    1532           0 :     resp->Response();
    1533           0 : }
    1534             : 
    1535          23 : bool QueryEngine::GetDiffStats(std::vector<GenDb::DbTableInfo> *vdbti,
    1536             :     GenDb::DbErrors *dbe, std::vector<GenDb::DbTableInfo> *vstats_dbti) {
    1537             :     {
    1538          23 :         std::scoped_lock lock(smutex_);
    1539          23 :         stable_stats_.GetDiffs(vstats_dbti);
    1540          23 :     }
    1541          23 :     return dbif_->Db_GetStats(vdbti, dbe);
    1542             : }
    1543             : 
    1544          39 : bool QueryEngine::GetCqlStats(cass::cql::DbStats *stats) const {
    1545          39 :     cass::cql::CqlIf *cql_if(dynamic_cast<cass::cql::CqlIf *>(dbif_.get()));
    1546          39 :     if (cql_if == NULL) {
    1547          16 :         return false;
    1548             :     }
    1549          23 :     return cql_if->Db_GetCqlStats(stats);
    1550             : }
    1551             : 
    1552           4 : bool QueryEngine::GetCqlMetrics(cass::cql::Metrics *metrics) const {
    1553           4 :     cass::cql::CqlIf *cql_if(dynamic_cast<cass::cql::CqlIf *>(dbif_.get()));
    1554           4 :     if (cql_if == NULL) {
    1555           0 :         return false;
    1556             :     }
    1557           4 :     cql_if->Db_GetCqlMetrics(metrics);
    1558           4 :     return true;
    1559             : }
    1560             : 
    1561           4 : void ShowQEDbStatsReq::HandleRequest() const {
    1562           4 :     std::vector<GenDb::DbTableInfo> vdbti, vstats_dbti;
    1563           4 :     GenDb::DbErrors dbe;
    1564             :     QESandeshContext *qec = static_cast<QESandeshContext *>(
    1565           4 :                                         Sandesh::client_context());
    1566           4 :     assert(qec);
    1567           4 :     ShowQEDbStatsResp *resp(new ShowQEDbStatsResp);
    1568           4 :     qec->QE()->GetCumulativeStats(&vdbti, &dbe, &vstats_dbti);
    1569           4 :     cass::cql::Metrics cmetrics;
    1570           4 :     qec->QE()->GetCqlMetrics(&cmetrics);
    1571           4 :     resp->set_table_info(vdbti);
    1572           4 :     resp->set_errors(dbe);
    1573           4 :     resp->set_statistics_table_info(vstats_dbti);
    1574           4 :     resp->set_cql_metrics(cmetrics);
    1575           4 :     resp->set_context(context());
    1576           4 :     resp->Response();
    1577           4 : }
    1578             : 

Generated by: LCOV version 1.14