Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include <cstdlib>
6 : #include <limits>
7 : #include <string>
8 : #include <sstream>
9 : #include <boost/foreach.hpp>
10 : #include <boost/algorithm/string/case_conv.hpp>
11 : #include "rapidjson/document.h"
12 : #include <boost/foreach.hpp>
13 : #include "query.h"
14 : #include "json_parse.h"
15 : #include "base/regex.h"
16 : #include "base/string_util.h"
17 : #include "database/gendb_constants.h"
18 : #include "database/gendb_if.h"
19 : #include "utils.h"
20 : #include "query.h"
21 : #include "stats_query.h"
22 :
23 : using contrail::regex;
24 : using contrail::regex_match;
25 : using contrail::regex_search;
26 : using std::string;
27 :
28 2605 : static std::string ToString(const contrail_rapidjson::Value& value_value) {
29 2605 : std::string svalue;
30 2605 : if (value_value.IsString())
31 : {
32 1473 : svalue = value_value.GetString();
33 1132 : } else if (value_value.IsInt()){
34 : int int_value;
35 72 : std::ostringstream convert;
36 72 : int_value = value_value.GetInt();
37 72 : convert << int_value;
38 72 : svalue = convert.str();
39 1131 : } else if (value_value.IsUint()) {
40 : uint32_t uint_value;
41 0 : std::ostringstream convert;
42 0 : uint_value = value_value.GetUint();
43 0 : convert << uint_value;
44 0 : svalue = convert.str();
45 1060 : } else if (value_value.IsDouble()) {
46 : double dbl_value;
47 0 : std::ostringstream convert;
48 0 : dbl_value = value_value.GetDouble();
49 0 : convert << dbl_value;
50 0 : svalue = convert.str();
51 0 : }
52 2605 : return svalue;
53 0 : }
54 :
55 755 : static GenDb::DbDataValue ToDbDataValue(const std::string& value, QEOpServerProxy::VarType desc) {
56 755 : GenDb::DbDataValue smpl;
57 755 : if (desc == QEOpServerProxy::STRING ||
58 36 : desc == QEOpServerProxy::MAP_ELEM ||
59 : desc == QEOpServerProxy::LIST) {
60 719 : smpl = value;
61 36 : } else if (desc == QEOpServerProxy::UINT64) {
62 36 : smpl = (uint64_t) strtoul(value.c_str(), NULL, 10);
63 0 : } else if (desc == QEOpServerProxy::DOUBLE) {
64 0 : smpl = (double) strtod(value.c_str(), NULL);
65 : }
66 754 : return smpl;
67 0 : }
68 :
69 2119 : static GenDb::DbDataValue ToDbDataValue(const contrail_rapidjson::Value& val) {
70 2119 : GenDb::DbDataValue ret;
71 2119 : if (val.IsString()) {
72 1005 : ret = std::string(val.GetString());
73 1114 : } else if (val.IsUint()) {
74 54 : ret = (uint64_t) val.GetUint();
75 1060 : } else if (val.IsInt()) {
76 0 : ret = (uint64_t) val.GetInt();
77 1060 : } else if (val.IsDouble()) {
78 1 : ret = (double) val.GetDouble();
79 : }
80 2119 : return ret;
81 0 : }
82 :
83 0 : static QEOpServerProxy::VarType ToDbDataType(string val) {
84 0 : QEOpServerProxy::VarType ret = QEOpServerProxy::BLANK;
85 0 : if (val == "int") {
86 0 : ret = QEOpServerProxy::UINT64;
87 0 : } else if (val == "string") {
88 0 : ret = QEOpServerProxy::STRING;
89 0 : } else if (val == "uuid") {
90 0 : ret = QEOpServerProxy::UUID;
91 0 : } else if (val == "double") {
92 0 : ret = QEOpServerProxy::DOUBLE;
93 0 : } else if (val == "map") {
94 0 : ret = QEOpServerProxy::MAP_ELEM;
95 0 : } else if (val == "set" || val == "list") {
96 0 : ret = QEOpServerProxy::LIST;
97 : }
98 0 : return ret;
99 : }
100 :
101 0 : static StatsQuery::column_t get_column_desc(std::map<std::string,StatsQuery::column_t> table_schema, std::string pname) {
102 0 : StatsQuery::column_t cdesc;
103 : std::map<std::string,StatsQuery::column_t>::const_iterator st =
104 0 : table_schema.find(pname);
105 0 : if (st!=table_schema.end()) {
106 0 : cdesc = st->second;
107 : } else {
108 0 : size_t pos = pname.find_last_of(".");
109 0 : std::string mapstr(pname.substr(0,pos) + ".*");
110 0 : st = table_schema.find(mapstr);
111 0 : if (st != table_schema.end()) {
112 0 : cdesc = st->second;
113 : } else {
114 0 : cdesc.datatype = QEOpServerProxy::BLANK;
115 0 : cdesc.index = false;
116 0 : cdesc.output = false;
117 : }
118 0 : }
119 0 : return cdesc;
120 0 : }
121 :
122 : bool
123 788 : WhereQuery::StatTermParse(QueryUnit *main_query, const contrail_rapidjson::Value& where_term,
124 : std::string& pname, match_op& pop, GenDb::DbDataValue& pval, GenDb::DbDataValue& pval2,
125 : std::string& sname, match_op& sop, GenDb::DbDataValue& sval, GenDb::DbDataValue& sval2) {
126 :
127 788 : AnalyticsQuery *m_query = (AnalyticsQuery *)main_query;
128 788 : QE_ASSERT(m_query->is_stat_table_query(m_query->table()));
129 :
130 789 : contrail_rapidjson::Document dd;
131 788 : std::string srvalstr, srval2str;
132 :
133 789 : if (!where_term.HasMember(WHERE_MATCH_NAME))
134 0 : return false;
135 789 : const contrail_rapidjson::Value& name_value = where_term[WHERE_MATCH_NAME];
136 790 : if (!name_value.IsString()) return false;
137 790 : pname = name_value.GetString();
138 :
139 790 : const contrail_rapidjson::Value& prval = where_term[WHERE_MATCH_VALUE];
140 789 : if (!((prval.IsString() || prval.IsNumber()))) return false;
141 789 : contrail_rapidjson::Value prval2;
142 789 : if (where_term.HasMember(WHERE_MATCH_VALUE2)) {
143 754 : prval2.CopyFrom(where_term[WHERE_MATCH_VALUE2], dd.GetAllocator());
144 : }
145 :
146 : // For dynamic stat tables, convert types as per query json
147 789 : pval = ToDbDataValue(prval);
148 790 : pval2 = ToDbDataValue(prval2);
149 :
150 790 : if (!where_term.HasMember(WHERE_MATCH_OP))
151 0 : return false;
152 790 : const contrail_rapidjson::Value& op_value = where_term[WHERE_MATCH_OP];
153 790 : if (!op_value.IsNumber()) return false;
154 790 : pop = (match_op)op_value.GetInt();
155 :
156 790 : QE_TRACE(DEBUG, "StatTable Where Term Prefix " << pname << " val " << ToString(prval)
157 : << " val2 " << ToString(prval2) << " op " << pop);
158 :
159 790 : sname = std::string();
160 790 : sop = (match_op)0;
161 790 : if (where_term.HasMember(WHERE_MATCH_SUFFIX)) {
162 754 : const contrail_rapidjson::Value& suffix = where_term[WHERE_MATCH_SUFFIX];
163 754 : if (suffix.IsObject()) {
164 : // For prefix-suffix where terms, prefix operator MUST be "EQUAL"
165 270 : if (pop != EQUAL) return false;
166 :
167 : // For prefix-suffix where terms, prefix value2 MUST be Null
168 270 : if (!prval2.IsNull()) return false;
169 :
170 270 : if (!suffix.HasMember(WHERE_MATCH_VALUE))
171 0 : return false;
172 : const contrail_rapidjson::Value& svalue_value =
173 270 : suffix[WHERE_MATCH_VALUE];
174 270 : if (!((svalue_value.IsString() || svalue_value.IsNumber()))) return false;
175 270 : srvalstr = ToString(svalue_value);
176 : // For dynamic stat tables, convert types as per query json
177 270 : sval = ToDbDataValue(svalue_value);
178 :
179 270 : contrail_rapidjson::Value svalue2_value;
180 270 : if (suffix.HasMember(WHERE_MATCH_VALUE2)) {
181 270 : svalue2_value.CopyFrom(suffix[WHERE_MATCH_VALUE2],
182 : dd.GetAllocator());
183 : }
184 270 : srval2str = ToString(svalue2_value);
185 : // For dynamic stat tables, convert types as per query json
186 270 : sval2 = ToDbDataValue(svalue2_value);
187 :
188 270 : if (!suffix.HasMember(WHERE_MATCH_OP))
189 0 : return false;
190 : const contrail_rapidjson::Value& sop_value =
191 270 : suffix[WHERE_MATCH_OP];
192 270 : if (!sop_value.IsNumber()) return false;
193 270 : sop = (match_op)sop_value.GetInt();
194 :
195 270 : if (!suffix.HasMember(WHERE_MATCH_NAME))
196 0 : return false;
197 : const contrail_rapidjson::Value& sname_value =
198 270 : suffix[WHERE_MATCH_NAME];
199 270 : if (!sname_value.IsString()) return false;
200 270 : sname = sname_value.GetString();
201 270 : }
202 754 : QE_TRACE(DEBUG, "StatTable Where Term Suffix" << sname << " val " <<
203 : srvalstr << " val2 " << srval2str << " op " << sop);
204 : }
205 :
206 790 : StatsQuery::column_t cdesc;
207 790 : cdesc.datatype = QEOpServerProxy::BLANK;
208 790 : std::map<std::string, StatsQuery::column_t> table_schema;
209 790 : if (m_query->stats().is_stat_table_static()) {
210 : // For static tables, check that prefix is valid and convert types as per schema
211 485 : cdesc = m_query->stats().get_column_desc(pname);
212 : } else {
213 : // Get the stable schema from query if sent
214 305 : AnalyticsQuery *aQuery = (AnalyticsQuery *)m_query;
215 305 : std::map<std::string, std::string>::iterator iter, iter2;
216 305 : iter = aQuery->json_api_data_.find(QUERY_TABLE_SCHEMA);
217 305 : if (iter != aQuery->json_api_data_.end()) {
218 305 : contrail_rapidjson::Document d;
219 305 : std::string json_string = "{ \"schema\" : " + iter->second + " }";
220 305 : d.Parse<0>(const_cast<char *>(json_string.c_str()));
221 305 : const contrail_rapidjson::Value& json_schema = d["schema"];
222 : // If schema is not passed, proceed without suffix information
223 305 : if (json_schema.Size() == 0) {
224 305 : return true;
225 : }
226 0 : for (contrail_rapidjson::SizeType j = 0; j<json_schema.Size(); j++) {
227 0 : if (!(json_schema[j].HasMember(WHERE_MATCH_NAME) &&
228 0 : json_schema[j].HasMember(QUERY_TABLE_SCHEMA_DATATYPE) &&
229 0 : json_schema[j].HasMember(QUERY_TABLE_SCHEMA_INDEX) &&
230 0 : json_schema[j].HasMember(QUERY_TABLE_SCHEMA_SUFFIXES)))
231 0 : return false;
232 0 : const contrail_rapidjson::Value& name = json_schema[j][WHERE_MATCH_NAME];
233 : const contrail_rapidjson::Value& datatype =
234 0 : json_schema[j][QUERY_TABLE_SCHEMA_DATATYPE];
235 : const contrail_rapidjson::Value& index =
236 0 : json_schema[j][QUERY_TABLE_SCHEMA_INDEX];
237 : const contrail_rapidjson::Value& suffixes =
238 0 : json_schema[j][QUERY_TABLE_SCHEMA_SUFFIXES];
239 0 : StatsQuery::column_t cdesc;
240 0 : std::string vstr = datatype.GetString();
241 0 : cdesc.datatype = ToDbDataType(vstr);
242 0 : cdesc.index = index.GetBool()? true : false;
243 :
244 0 : if (suffixes.IsArray() && suffixes.Size() > 0) {
245 0 : for (contrail_rapidjson::SizeType k = 0; k<suffixes.Size(); k++) {
246 0 : const contrail_rapidjson::Value& suffix_name = suffixes[k];
247 0 : cdesc.suffixes.insert(suffix_name.GetString());
248 : }
249 : }
250 0 : table_schema[name.GetString()] = cdesc;
251 0 : }
252 610 : }
253 0 : cdesc = get_column_desc(table_schema, pname);
254 : }
255 :
256 485 : if (cdesc.datatype == QEOpServerProxy::BLANK) return false;
257 485 : if (!cdesc.index) return false;
258 485 : if (cdesc.datatype == QEOpServerProxy::LIST && pop != CONTAINS) return false;
259 :
260 485 : QE_TRACE(DEBUG, "StatTable Where prefix Schema match " << cdesc.datatype);
261 : // Now fill in the prefix value and value2 based on types in schema
262 485 : std::string vstr = ToString(prval);
263 485 : pval = ToDbDataValue(vstr, cdesc.datatype);
264 485 : if (!prval2.IsNull()) {
265 0 : std::string vstr = ToString(prval2);
266 0 : pval2 = ToDbDataValue(vstr, cdesc.datatype);
267 0 : }
268 :
269 485 : if (cdesc.suffixes.empty()) {
270 : // We need to use a onetag cf as the index
271 36 : if (!sname.empty()) return false;
272 36 : if (sop) return false;
273 36 : if (!srvalstr.empty()) return false;
274 36 : if (!srval2str.empty()) return false;
275 : } else {
276 : // We will need to use a twotag cf as the index
277 449 : if (sname.empty()) {
278 : // Where Query did not specify a suffix. Insert a NULL suffix
279 179 : sname = *(cdesc.suffixes.begin());
280 :
281 : // The suffix attribute MUST exist in the schema
282 179 : StatsQuery::column_t cdesc2;
283 179 : if (m_query->stats().is_stat_table_static()) {
284 179 : cdesc2 = m_query->stats().get_column_desc(sname);
285 : } else {
286 0 : cdesc2 = get_column_desc(table_schema, sname);;
287 : }
288 :
289 179 : if (cdesc2.datatype == QEOpServerProxy::STRING) {
290 179 : sval = std::string("");
291 0 : } else if (cdesc2.datatype == QEOpServerProxy::UINT64){
292 0 : sval = (uint64_t) 0;
293 : } else {
294 0 : QE_ASSERT(0);
295 : }
296 179 : QE_TRACE(DEBUG, "StatTable Where Suffix creation of " << sname);
297 179 : } else {
298 : // Where query specified a suffix. Check that it is valid
299 270 : if (cdesc.suffixes.find(sname)==cdesc.suffixes.end()) return false;
300 :
301 : // The suffix attribute MUST exist in the schema
302 270 : StatsQuery::column_t cdesc2;
303 270 : if (m_query->stats().is_stat_table_static()) {
304 270 : cdesc2 = m_query->stats().get_column_desc(sname);
305 : } else {
306 0 : cdesc2 = get_column_desc(table_schema, sname);;
307 : }
308 270 : QE_ASSERT ((cdesc2.datatype == QEOpServerProxy::STRING) ||
309 : (cdesc2.datatype == QEOpServerProxy::UINT64));
310 :
311 : // Now fill in the suffix value and value2 based on types in schema
312 270 : sval = ToDbDataValue(srvalstr, cdesc2.datatype);
313 270 : if (!srval2str.empty()) {
314 0 : sval2 = ToDbDataValue(srval2str, cdesc2.datatype);
315 : }
316 270 : QE_TRACE(DEBUG, "StatTable Where Suffix match of " << cdesc2.datatype);
317 270 : }
318 : }
319 :
320 485 : return true;
321 790 : }
322 :
323 0 : static bool StatSlicer(DbQueryUnit *db_query, match_op op,
324 : const GenDb::DbDataValue& val, const GenDb::DbDataValue& val2) {
325 0 : if (val.which() == GenDb::DB_VALUE_STRING) {
326 0 : if (!((op == EQUAL) || (op == PREFIX))) return false;
327 : } else {
328 0 : if (!((op == EQUAL) || (op == IN_RANGE))) return false;
329 : }
330 0 : db_query->cr.start_.push_back(val);
331 0 : if (op == PREFIX) {
332 0 : std::string str_smpl2(boost::get<std::string>(val) + "\x7f");
333 0 : db_query->cr.finish_.push_back(str_smpl2);
334 0 : } else if (op == IN_RANGE) {
335 0 : db_query->cr.finish_.push_back(val2);
336 : } else {
337 0 : db_query->cr.finish_.push_back(val);
338 : }
339 0 : return true;
340 : }
341 :
342 0 : bool WhereQuery::StatTermProcess(const contrail_rapidjson::Value& where_term,
343 : QueryUnit* and_node, QueryUnit *main_query) {
344 :
345 0 : AnalyticsQuery *m_query = (AnalyticsQuery *)main_query;
346 0 : std::string pname,sname,cfname;
347 : match_op pop,sop;
348 0 : GenDb::DbDataValue pval, pval2, sval, sval2;
349 :
350 0 : bool res = StatTermParse(main_query, where_term,
351 : pname, pop, pval, pval2, sname, sop, sval, sval2);
352 :
353 0 : if (!res) return false;
354 :
355 0 : bool twotag = true;
356 0 : if ((sop==(match_op)0)&&(sname.empty())) {
357 : // We need to look at the single-tag stat index tables
358 0 : twotag = false;
359 0 : if (pval.which() == GenDb::DB_VALUE_STRING) {
360 0 : cfname = g_viz_constants.STATS_TABLE_BY_STR_TAG;
361 0 : } else if (pval.which() == GenDb::DB_VALUE_UINT64) {
362 0 : cfname = g_viz_constants.STATS_TABLE_BY_U64_TAG;
363 0 : } else if (pval.which() == GenDb::DB_VALUE_DOUBLE) {
364 0 : cfname = g_viz_constants.STATS_TABLE_BY_DBL_TAG;
365 : } else {
366 0 : QE_TRACE(DEBUG, "For single-tag index table, wrong WHERE type " <<
367 : pval.which());
368 0 : return false;
369 : }
370 : } else {
371 0 : if (pval.which() == GenDb::DB_VALUE_STRING) {
372 0 : if (sval.which() == GenDb::DB_VALUE_STRING) {
373 0 : cfname = g_viz_constants.STATS_TABLE_BY_STR_STR_TAG;
374 0 : } else if (sval.which() == GenDb::DB_VALUE_UINT64) {
375 0 : cfname = g_viz_constants.STATS_TABLE_BY_STR_U64_TAG;
376 : } else {
377 0 : QE_TRACE(DEBUG, "For two-tag STR table, wrong WHERE suffix type " <<
378 : sval.which());
379 0 : return false;
380 : }
381 0 : } else if (pval.which() == GenDb::DB_VALUE_UINT64) {
382 0 : if (sval.which() == GenDb::DB_VALUE_STRING) {
383 0 : cfname = g_viz_constants.STATS_TABLE_BY_U64_STR_TAG;
384 0 : } else if (sval.which() == GenDb::DB_VALUE_UINT64) {
385 0 : cfname = g_viz_constants.STATS_TABLE_BY_U64_U64_TAG;
386 : } else {
387 0 : QE_TRACE(DEBUG, "For two-tag U64 table, wrong WHERE suffix type " <<
388 : sval.which());
389 0 : return false;
390 : }
391 : } else {
392 0 : QE_TRACE(DEBUG, "For two-tag index table, wrong WHERE prefix type " <<
393 : pval.which());
394 0 : return false;
395 : }
396 : }
397 0 : QE_TRACE(DEBUG, "Query Stat Index " << cfname << " twotag " << twotag);
398 0 : DbQueryUnit *db_query = new DbQueryUnit(and_node, main_query);
399 :
400 0 : db_query->t_only_col = false;
401 0 : db_query->t_only_row = false;
402 0 : db_query->cfname = cfname;
403 :
404 : size_t tpos,apos;
405 0 : std::string tname = m_query->table();
406 0 : tpos = tname.find('.');
407 0 : apos = tname.find('.', tpos+1);
408 :
409 0 : std::string tstr = tname.substr(tpos+1, apos-tpos-1);
410 0 : std::string astr = tname.substr(apos+1, std::string::npos);
411 :
412 0 : db_query->row_key_suffix.push_back(tstr);
413 0 : db_query->row_key_suffix.push_back(astr);
414 0 : db_query->row_key_suffix.push_back(pname);
415 :
416 0 : if (twotag) {
417 0 : db_query->row_key_suffix.push_back(sname);
418 0 : if (sop==(match_op)0) {
419 : // We will only be using the prefix value for querying
420 0 : if (!StatSlicer(db_query, pop, pval, pval2)) return false;
421 :
422 0 : if (sval.which() == GenDb::DB_VALUE_STRING) {
423 0 : db_query->cr.start_.push_back(std::string("\x00"));
424 0 : db_query->cr.finish_.push_back(std::string("\x7f"));
425 : } else {
426 0 : db_query->cr.start_.push_back((uint64_t)0);
427 0 : db_query->cr.finish_.push_back((uint64_t)0xffffffffffffffff);
428 : }
429 : } else {
430 : // We will be using the suffix value for querying
431 0 : if (!(pop == EQUAL)) return false;
432 0 : db_query->cr.start_.push_back(pval);
433 0 : db_query->cr.finish_.push_back(pval);
434 :
435 0 : if (!StatSlicer(db_query, sop, sval, sval2)) return false;
436 : }
437 :
438 : } else {
439 0 : if (!StatSlicer(db_query, pop, pval, pval2)) return false;
440 : }
441 :
442 0 : return true;
443 0 : }
444 :
445 716 : void GetStatTableAttrName(const std::string& tname, std::string *tstr, std::string *astr) {
446 : size_t tpos,apos;
447 716 : tpos = tname.find('.');
448 718 : apos = tname.find('.', tpos+1);
449 :
450 718 : *tstr = tname.substr(tpos+1, apos-tpos-1);
451 717 : *astr = tname.substr(apos+1, std::string::npos);
452 718 : }
453 :
454 717 : void populate_stats_where_vec_list(std::vector<GenDb::WhereIndexInfoVec> *where_vec_list,
455 : const GenDb::WhereIndexInfoVec& where_vec_stats,
456 : const std::vector<GenDb::WhereIndexInfoVec>& where_vec_tags_stats) {
457 717 : uint16_t max_tags(0);
458 6437 : BOOST_FOREACH(const GenDb::WhereIndexInfoVec& where_vec, where_vec_tags_stats) {
459 2860 : if (max_tags < where_vec.size()) {
460 412 : max_tags = where_vec.size();
461 : }
462 : }
463 716 : if (!max_tags) {
464 304 : where_vec_list->push_back(where_vec_stats);
465 304 : return;
466 : } else {
467 825 : for (size_t i = 0; i < max_tags; ++i) {
468 412 : GenDb::WhereIndexInfoVec where_vec(where_vec_stats);
469 3697 : BOOST_FOREACH(const GenDb::WhereIndexInfoVec& where_vec_tags, where_vec_tags_stats) {
470 1644 : if (i < where_vec_tags.size()) {
471 465 : where_vec.push_back(where_vec_tags[i]);
472 : }
473 : }
474 411 : where_vec_list->push_back(where_vec);
475 413 : }
476 : }
477 : }
478 :
479 465 : static inline unsigned int djb_hash (const char *str, size_t len) {
480 465 : unsigned int hash = 5381;
481 3643 : for (size_t i = 0 ; i < len ; i++)
482 3178 : hash = ((hash << 5) + hash) + str[i];
483 465 : return hash;
484 : }
485 :
486 2004 : WhereQuery::WhereQuery(const std::string& where_json_string, int session_type,
487 2004 : int is_si, int direction, int32_t or_number, QueryUnit *main_query):
488 2004 : QueryUnit(main_query, main_query), direction_ing(direction),
489 2004 : json_string_(where_json_string), wterms_(0) {
490 2004 : AnalyticsQuery *m_query = (AnalyticsQuery *)main_query;
491 2004 : where_result_.reset(new std::vector<query_result_unit_t>);
492 2004 : if (where_json_string == std::string(""))
493 : {
494 348 : if (or_number == -1) wterms_ = 1;
495 348 : DbQueryUnit *db_query = new DbQueryUnit(this, main_query);
496 :
497 : //TBD not sure if this will work for Message table or Object Log
498 348 : if (m_query->is_message_table_query()) {
499 77 : db_query->cfname = g_viz_constants.COLLECTOR_GLOBAL_TABLE;
500 77 : db_query->t_only_col = true;
501 77 : db_query->t_only_row = true;
502 272 : } else if
503 272 : ((m_query->table() == g_viz_constants.FLOW_TABLE)
504 271 : || (m_query->table() == g_viz_constants.FLOW_SERIES_TABLE)) {
505 0 : DbQueryUnit *db_query_client = new DbQueryUnit(this, main_query);
506 : {
507 0 : db_query->cfname = g_viz_constants.SESSION_TABLE;
508 0 : db_query->row_key_suffix.push_back((uint8_t)is_si);
509 0 : db_query->row_key_suffix.push_back(
510 0 : (uint8_t)SessionType::SERVER_SESSION);
511 : // starting value for clustering key range
512 0 : db_query->cr.start_.push_back((uint16_t)0);
513 :
514 : // ending value for clustering key range
515 0 : db_query->cr.finish_.push_back((uint16_t)0xffff);
516 0 : db_query->cr.finish_.push_back((uint16_t)0xffff);
517 : }
518 : {
519 0 : db_query_client->cfname = g_viz_constants.SESSION_TABLE;
520 0 : db_query_client->row_key_suffix.push_back((uint8_t)is_si);
521 0 : db_query_client->row_key_suffix.push_back(
522 0 : (uint8_t)SessionType::CLIENT_SESSION);
523 : // starting value for clustering key range
524 0 : db_query_client->cr.start_.push_back((uint16_t)0);
525 :
526 : // ending value for clustering key range
527 0 : db_query_client->cr.finish_.push_back((uint16_t)0xffff);
528 0 : db_query_client->cr.finish_.push_back((uint16_t)0xffff);
529 :
530 : }
531 272 : } else if (m_query->is_session_query(m_query->table())) {
532 :
533 215 : db_query->row_key_suffix.push_back((uint8_t)is_si);
534 215 : db_query->row_key_suffix.push_back((uint8_t)session_type);
535 214 : db_query->cfname = g_viz_constants.SESSION_TABLE;
536 :
537 : // starting value for clustering key range
538 214 : db_query->cr.start_.push_back((uint16_t)0);
539 :
540 : // ending value for clustering key range
541 215 : db_query->cr.finish_.push_back((uint16_t)0xffff);
542 215 : db_query->cr.finish_.push_back((uint16_t)0xffff);
543 :
544 57 : } else if (m_query->is_object_table_query(m_query->table())) {
545 54 : db_query->cfname = g_viz_constants.COLLECTOR_GLOBAL_TABLE;
546 54 : db_query->t_only_col = true;
547 54 : db_query->t_only_row = true;
548 54 : bool object_id_specified = false;
549 :
550 : // handling where * for object table is similar to
551 : // and subset of object-id=X handling
552 54 : handle_object_type_value(m_query, db_query, object_id_specified);
553 55 : QE_TRACE(DEBUG, "where * for object table" << m_query->table());
554 :
555 : }
556 : // This is "where *" query, no need to do JSON parsing
557 349 : return;
558 : }
559 :
560 : // Do JSON parsing
561 1656 : contrail_rapidjson::Document d;
562 1656 : std::string json_string = "{ \"where\" : " +
563 1656 : where_json_string + " }";
564 :
565 1656 : QE_TRACE(DEBUG, "where query:" << json_string);
566 1656 : d.Parse<0>(const_cast<char *>(json_string.c_str()));
567 1656 : const contrail_rapidjson::Value& json_or_list = d["where"];
568 1656 : QE_PARSE_ERROR(json_or_list.IsArray());
569 :
570 1656 : QE_TRACE(DEBUG, "number of OR terms in where :" << json_or_list.Size());
571 :
572 1656 : if (or_number == -1) wterms_ = json_or_list.Size();
573 :
574 3488 : for (contrail_rapidjson::SizeType i = 0; i < json_or_list.Size(); i++)
575 : {
576 1834 : const contrail_rapidjson::Value& json_or_node = json_or_list[i];
577 1834 : QE_PARSE_ERROR(json_or_list[i].IsArray());
578 1834 : QE_INVALIDARG_ERROR(json_or_list[i].Size() != 0);
579 :
580 : // If the or_number is -1, we are in query prepare.
581 : // We have no intention of actually executing the query.
582 : // But, we parse everything to catch errors.
583 1834 : if (or_number != -1) {
584 : // Only execute the requested OR term
585 863 : if (or_number != (int)i) continue;
586 : }
587 :
588 1738 : QE_TRACE(DEBUG, "number of AND term in " << (i+1) <<
589 : "th OR term is " <<json_or_node.Size());
590 :
591 : // these are needed because flow index table queries
592 : // span multiple WHERE match component
593 1738 : bool vr_match = false; GenDb::DbDataValue vr, vr2; int vr_op = 0;
594 1738 : bool svn_match = false; GenDb::DbDataValue svn, svn2; int svn_op = 0;
595 1738 : bool dvn_match = false; GenDb::DbDataValue dvn, dvn2; int dvn_op = 0;
596 1738 : bool sip_match = false; GenDb::DbDataValue sip, sip2; int sip_op = 0;
597 1738 : bool dip_match = false; GenDb::DbDataValue dip, dip2; int dip_op = 0;
598 1738 : bool proto_match = false; GenDb::DbDataValue proto, proto2; int proto_op = 0;
599 1738 : bool sport_match = false; GenDb::DbDataValue sport, sport2; int sport_op = 0;
600 1738 : bool dport_match = false; GenDb::DbDataValue dport, dport2; int dport_op = 0;
601 1738 : bool name_match = false; GenDb::DbDataValue sname_val; int name_op = 0;
602 1738 : bool object_id_specified = false;
603 1738 : bool isSession = m_query->is_session_query(m_query->table());
604 1738 : GenDb::WhereIndexInfoVec labels_vec, remote_labels_vec;
605 1738 : GenDb::WhereIndexInfoVec custom_tags_vec, remote_custom_tags_vec;
606 1738 : GenDb::WhereIndexInfoVec where_vec_session_rest, where_vec_stats;
607 1738 : std::vector<GenDb::WhereIndexInfoVec> where_vec_tags_stats(4);
608 1738 : std::vector<filter_match_t> filter_and;
609 :
610 : // All where parameters in subquery are AND.
611 : // So they are in the same msg_table_db_query object.
612 : // If there are no where-params, this would result in no-op.
613 1738 : DbQueryUnit *msg_table_db_query = NULL;
614 2946 : if (m_query->is_message_table_query() ||
615 2946 : m_query->is_object_table_query(m_query->table())) {
616 :
617 870 : msg_table_db_query = new DbQueryUnit(this, main_query);
618 870 : msg_table_db_query->cfname = g_viz_constants.COLLECTOR_GLOBAL_TABLE;
619 870 : msg_table_db_query->t_only_row = true;
620 870 : msg_table_db_query->t_only_col = true;
621 : }
622 :
623 3878 : for (contrail_rapidjson::SizeType j = 0; j < json_or_node.Size(); j++)
624 : {
625 2142 : QE_PARSE_ERROR((json_or_node[j].HasMember(WHERE_MATCH_NAME) &&
626 : json_or_node[j].HasMember(WHERE_MATCH_VALUE) &&
627 : json_or_node[j].HasMember(WHERE_MATCH_OP)));
628 : const contrail_rapidjson::Value& name_value =
629 2142 : json_or_node[j][WHERE_MATCH_NAME];
630 : const contrail_rapidjson::Value& value_value =
631 2142 : json_or_node[j][WHERE_MATCH_VALUE];
632 : const contrail_rapidjson::Value& op_value =
633 2141 : json_or_node[j][WHERE_MATCH_OP];
634 :
635 : // do some validation checks
636 2141 : QE_INVALIDARG_ERROR(name_value.IsString());
637 2141 : QE_INVALIDARG_ERROR
638 : ((value_value.IsString() || value_value.IsNumber()));
639 2141 : QE_INVALIDARG_ERROR(op_value.IsNumber());
640 :
641 2141 : std::string name = name_value.GetString();
642 2141 : QE_INVALIDARG_ERROR(m_query->is_valid_where_field(name));
643 :
644 : // extract value after type conversion
645 2141 : std::string value;
646 : {
647 2141 : if (value_value.IsString())
648 : {
649 1977 : value = value_value.GetString();
650 164 : } else if (value_value.IsInt()){
651 : int int_value;
652 164 : std::ostringstream convert;
653 164 : int_value = value_value.GetInt();
654 164 : convert << int_value;
655 164 : value = convert.str();
656 164 : } else if (value_value.IsUint()) {
657 : uint32_t uint_value;
658 0 : std::ostringstream convert;
659 0 : uint_value = value_value.GetUint();
660 0 : convert << uint_value;
661 0 : value = convert.str();
662 0 : } else if (value_value.IsDouble()) {
663 : double dbl_value;
664 0 : std::ostringstream convert;
665 0 : dbl_value = value_value.GetDouble();
666 0 : convert << dbl_value;
667 0 : value = convert.str();
668 0 : }
669 : }
670 :
671 2141 : match_op op = (match_op)op_value.GetInt();
672 :
673 2141 : name = get_column_name(name); // Get actual Cassandra name
674 :
675 : // this is for range queries
676 2141 : std::string value2;
677 2141 : if (op == IN_RANGE)
678 : {
679 0 : QE_PARSE_ERROR(json_or_node[j].HasMember(WHERE_MATCH_VALUE2));
680 : const contrail_rapidjson::Value& value_value2 =
681 0 : json_or_node[j][WHERE_MATCH_VALUE2];
682 :
683 : // extract value2 after type conversion
684 0 : if (value_value2.IsString())
685 : {
686 0 : value2 = value_value2.GetString();
687 0 : } else if (value_value2.IsInt()){
688 : int int_value;
689 0 : std::ostringstream convert;
690 0 : int_value = value_value2.GetInt();
691 0 : convert << int_value;
692 0 : value2 = convert.str();
693 0 : } else if (value_value2.IsUint()) {
694 : uint32_t uint_value;
695 0 : std::ostringstream convert;
696 0 : uint_value = value_value2.GetUint();
697 0 : convert << uint_value;
698 0 : value2 = convert.str();
699 0 : } else if (value_value2.IsDouble()) {
700 : double dbl_value;
701 0 : std::ostringstream convert;
702 0 : dbl_value = value_value2.GetDouble();
703 0 : convert << dbl_value;
704 0 : value2 = convert.str();
705 0 : }
706 : }
707 :
708 2141 : bool isStat = m_query->is_stat_table_query(m_query->table());
709 2141 : if ((name == g_viz_constants.SOURCE) && (!isStat))
710 : {
711 299 : QE_INVALIDARG_ERROR((op == EQUAL) || (op == PREFIX));
712 299 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
713 : &(msg_table_db_query->where_vec), name,
714 : get_gendb_op_from_op(op), value));
715 299 : QE_TRACE(DEBUG, "where match term for source " << value);
716 : }
717 :
718 :
719 2141 : if ((name == g_viz_constants.MODULE) && (!isStat))
720 : {
721 367 : QE_INVALIDARG_ERROR((op == EQUAL) || (op == PREFIX));
722 367 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
723 : &(msg_table_db_query->where_vec), name,
724 : get_gendb_op_from_op(op), value));
725 :
726 : // dont filter query engine logs if the query is about query
727 : // engine
728 366 : if (value == m_query->sandesh_moduleid)
729 180 : m_query->filter_qe_logs = false;
730 :
731 366 : QE_TRACE(DEBUG, "where match term for module " << value);
732 : }
733 :
734 2141 : if ((name == g_viz_constants.MESSAGE_TYPE) && (!isStat))
735 : {
736 34 : QE_INVALIDARG_ERROR((op == EQUAL) || (op == PREFIX));
737 34 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
738 : &(msg_table_db_query->where_vec), name,
739 : get_gendb_op_from_op(op), value));
740 34 : QE_TRACE(DEBUG, "where match term for msg-type " << value);
741 : }
742 :
743 2141 : if (name == OBJECTID)
744 : {
745 340 : QE_INVALIDARG_ERROR((op == EQUAL) || (op == PREFIX));
746 :
747 : // Object-id is saved in column[6..11] in MessageTablev2 in the format
748 : // T2:ObjectType:ObjectId
749 : // T2: is prefixed later, we need to prefix ObjectType: here.
750 680 : std::string val = m_query->table() + ":" + value;
751 340 : std::string col_name = g_viz_constants.OBJECT_TYPE_NAME1;
752 340 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
753 : &(msg_table_db_query->where_vec),
754 : col_name, get_gendb_op_from_op(op), val));
755 340 : object_id_specified = true;
756 340 : QE_TRACE(DEBUG, "where match term for objectid " << value);
757 340 : }
758 :
759 2141 : if (m_query->is_session_query(m_query->table())) {
760 264 : if (name == g_viz_constants.SessionRecordNames[
761 264 : SessionRecordFields::SESSION_PROTOCOL])
762 : {
763 58 : proto_match = true; proto_op = op;
764 : uint16_t proto_value, proto_value2;
765 58 : std::istringstream(value) >> proto_value;
766 58 : proto = proto_value;
767 58 : if (proto_op == IN_RANGE)
768 : {
769 0 : std::istringstream(value2) >> proto_value2;
770 0 : proto2 = proto_value2;
771 : } else {
772 58 : QE_INVALIDARG_ERROR(proto_op == EQUAL);
773 : }
774 58 : QE_TRACE(DEBUG, "where match term for proto_value " << value);
775 : }
776 206 : else if (name == g_viz_constants.SessionRecordNames[
777 206 : SessionRecordFields::SESSION_SPORT])
778 : {
779 58 : sport_match = true; sport_op = op;
780 : uint16_t sport_value, sport_value2;
781 58 : std::istringstream(value) >> sport_value;
782 58 : sport = sport_value;
783 58 : if (sport_op == IN_RANGE)
784 : {
785 0 : std::istringstream(value2) >> sport_value2;
786 0 : sport2 = sport_value2;
787 : } else {
788 58 : QE_INVALIDARG_ERROR(sport_op == EQUAL);
789 : }
790 58 : QE_TRACE(DEBUG, "where match term for sport_value " << value);
791 148 : } else if (name == g_viz_constants.SessionRecordNames[
792 148 : SessionRecordFields::SESSION_LABELS]) {
793 34 : QE_INVALIDARG_ERROR(op == CONTAINS);
794 34 : value = "%" + value;
795 34 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
796 : &labels_vec, name, GenDb::Op::LIKE, value));
797 114 : } else if (name == g_viz_constants.SessionRecordNames[
798 114 : SessionRecordFields::SESSION_REMOTE_LABELS]) {
799 22 : QE_INVALIDARG_ERROR(op == CONTAINS);
800 22 : value = "%" + value;
801 22 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
802 : &remote_labels_vec, name, GenDb::Op::LIKE, value));
803 92 : } else if (name == g_viz_constants.SessionRecordNames[
804 92 : SessionRecordFields::SESSION_CUSTOM_TAGS]) {
805 10 : QE_INVALIDARG_ERROR(op == CONTAINS);
806 10 : value = "%" + value;
807 10 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
808 : &custom_tags_vec, name, GenDb::Op::LIKE, value));
809 82 : } else if (name == g_viz_constants.SessionRecordNames[
810 82 : SessionRecordFields::SESSION_REMOTE_CUSTOM_TAGS]) {
811 10 : QE_INVALIDARG_ERROR(op == CONTAINS);
812 10 : value = "%" + value;
813 10 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
814 : &remote_custom_tags_vec, name, GenDb::Op::LIKE, value));
815 : } else {
816 : GenDb::Op::type comparator;
817 72 : if (op == PREFIX) {
818 0 : comparator = GenDb::Op::LIKE;
819 : } else {
820 72 : comparator = GenDb::Op::EQ;
821 : }
822 72 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
823 : &where_vec_session_rest, name, comparator, value));
824 : }
825 1876 : } else if (m_query->is_flow_query(m_query->table())){
826 48 : if (name == g_viz_constants.FlowRecordNames[
827 48 : FlowRecordFields::FLOWREC_PROTOCOL])
828 : {
829 12 : proto_match = true; proto_op = op;
830 : uint16_t proto_value, proto_value2;
831 12 : std::istringstream(value) >> proto_value;
832 12 : proto = proto_value;
833 12 : if (proto_op == IN_RANGE)
834 : {
835 0 : std::istringstream(value2) >> proto_value2;
836 0 : proto2 = proto_value2;
837 : } else {
838 12 : QE_INVALIDARG_ERROR(proto_op == EQUAL);
839 : }
840 12 : QE_TRACE(DEBUG, "where match term for proto_value " << value);
841 : }
842 48 : if (name == g_viz_constants.FlowRecordNames[
843 48 : FlowRecordFields::FLOWREC_SOURCEVN])
844 : {
845 24 : svn_match = true; svn_op = op;
846 24 : svn = value;
847 24 : QE_INVALIDARG_ERROR((svn_op == EQUAL)||(svn_op == PREFIX));
848 :
849 24 : QE_TRACE(DEBUG, "where match term for sourcevn " << value);
850 : }
851 48 : if (name == g_viz_constants.FlowRecordNames[
852 48 : FlowRecordFields::FLOWREC_DESTVN])
853 : {
854 12 : dvn_match = true; dvn_op = op;
855 12 : dvn = value;
856 12 : QE_INVALIDARG_ERROR((dvn_op == EQUAL)||(dvn_op == PREFIX));
857 :
858 12 : QE_TRACE(DEBUG, "where match term for sourcevn " << value);
859 : }
860 48 : if (name == g_viz_constants.FlowRecordNames[
861 48 : FlowRecordFields::FLOWREC_SOURCEIP])
862 : {
863 0 : sip_match = true; sip_op = op;
864 0 : sip = value;
865 0 : QE_TRACE(DEBUG, "where match term for sourceip " << value);
866 0 : if (sip_op == IN_RANGE)
867 : {
868 0 : sip2 = value2;
869 : } else {
870 0 : QE_INVALIDARG_ERROR(sip_op == EQUAL);
871 : }
872 0 : if (direction_ing == 0) {
873 0 : filter_match_t filter;
874 0 : filter.name = "sourceip";
875 0 : filter.op = (match_op)sip_op;
876 0 : filter.value = boost::get<std::string>(sip);
877 0 : filter_and.push_back(filter);
878 0 : additional_select_.push_back(filter.name);
879 0 : }
880 : }
881 48 : if (name == g_viz_constants.FlowRecordNames[
882 48 : FlowRecordFields::FLOWREC_DESTIP])
883 : {
884 0 : dip_match = true; dip_op = op;
885 0 : dip = value;
886 0 : QE_TRACE(DEBUG, "where match term for destip " << value);
887 0 : if (dip_op == IN_RANGE)
888 : {
889 0 : dip2 = value2;
890 : } else {
891 0 : QE_INVALIDARG_ERROR(dip_op == EQUAL);
892 : }
893 0 : if (direction_ing == 1) {
894 0 : filter_match_t filter;
895 0 : filter.name = "destip";
896 0 : filter.op = (match_op)dip_op;
897 0 : filter.value = boost::get<std::string>(dip);
898 0 : filter_and.push_back(filter);
899 0 : additional_select_.push_back(filter.name);
900 0 : }
901 : }
902 48 : if (name == g_viz_constants.FlowRecordNames[FlowRecordFields::FLOWREC_SPORT])
903 : {
904 0 : sport_match = true; sport_op = op;
905 :
906 : uint16_t sport_value;
907 0 : std::istringstream(value) >> sport_value;
908 :
909 0 : sport = sport_value;
910 0 : if (sport_op == IN_RANGE)
911 : {
912 : uint16_t sport_value2;
913 0 : std::istringstream(value2) >> sport_value2;
914 0 : sport2 = sport_value2;
915 : } else {
916 0 : QE_INVALIDARG_ERROR(sport_op == EQUAL);
917 : }
918 :
919 0 : filter_match_t filter;
920 0 : filter.name = "sport";
921 0 : filter.op = (match_op)sport_op;
922 0 : std::ostringstream convert;
923 0 : convert << boost::get<uint16_t>(sport);
924 0 : filter.value = convert.str();
925 0 : filter_and.push_back(filter);
926 0 : additional_select_.push_back(filter.name);
927 :
928 0 : QE_TRACE(DEBUG, "where match term for sport " << value);
929 0 : }
930 48 : if (name == g_viz_constants.FlowRecordNames[FlowRecordFields::FLOWREC_DPORT])
931 : {
932 0 : dport_match = true; dport_op = op;
933 :
934 : uint16_t dport_value;
935 0 : std::istringstream(value) >> dport_value;
936 0 : dport = dport_value;
937 0 : if (dport_op == IN_RANGE)
938 : {
939 : uint16_t dport_value2;
940 0 : std::istringstream(value2) >> dport_value2;
941 0 : dport2 = dport_value2;
942 : } else {
943 0 : QE_INVALIDARG_ERROR(dport_op == EQUAL);
944 : }
945 :
946 0 : filter_match_t filter;
947 0 : filter.name = "dport";
948 0 : filter.op = (match_op)dport_op;
949 0 : std::ostringstream convert;
950 0 : convert << boost::get<uint16_t>(dport);
951 0 : filter.value = convert.str();
952 0 : filter_and.push_back(filter);
953 0 : additional_select_.push_back(filter.name);
954 :
955 0 : QE_TRACE(DEBUG, "where match term for dport " << value);
956 0 : }
957 48 : if (name == g_viz_constants.FlowRecordNames[FlowRecordFields::FLOWREC_VROUTER])
958 : {
959 0 : vr_match = true;
960 0 : vr_op = op;
961 0 : vr = value;
962 0 : QE_INVALIDARG_ERROR((vr_op == EQUAL)||(vr_op == PREFIX));
963 :
964 0 : QE_TRACE(DEBUG, "where match term for vrouter " << value);
965 0 : filter_match_t filter;
966 0 : filter.name = "vrouter";
967 0 : if (vr_op != PREFIX) {
968 0 : filter.op = (match_op)vr_op;
969 : } else {
970 0 : filter.op = REGEX_MATCH;
971 : }
972 0 : filter.value = boost::get<std::string>(vr);
973 0 : if (filter.op == REGEX_MATCH) {
974 0 : filter.match_e = regex(filter.value);
975 : }
976 : if (vr_match) {
977 : }
978 0 : filter_and.push_back(filter);
979 0 : additional_select_.push_back(filter.name);
980 0 : }
981 : }
982 2140 : if (isStat)
983 : {
984 788 : if (oldDataExists) {
985 : // Call StatTermProcess to handle the query into older tables
986 0 : StatTermProcess(json_or_node[j], this, main_query);
987 : }
988 :
989 788 : std::string pname, sname;
990 : match_op pop,sop;
991 788 : GenDb::DbDataValue pval, pval2, sval, sval2;
992 :
993 788 : if (!StatTermParse(main_query, json_or_node[j],
994 : pname, pop, pval, pval2, sname, sop, sval, sval2)) {
995 0 : QE_INVALIDARG_ERROR(false);
996 : }
997 :
998 790 : if (pname == g_viz_constants.STATS_NAME_FIELD) {
999 593 : name_match = true;
1000 593 : sname_val = pval;
1001 593 : name_op = pop;
1002 197 : } else if (pname == g_viz_constants.STATS_SOURCE_FIELD ||
1003 394 : boost::algorithm::ends_with(pname, g_viz_constants.STATS_KEY_FIELD) ||
1004 197 : boost::algorithm::ends_with(pname, g_viz_constants.STATS_PROXY_FIELD)) {
1005 0 : if (boost::algorithm::ends_with(pname, g_viz_constants.STATS_KEY_FIELD)) {
1006 0 : pname = g_viz_constants.STATS_KEY_FIELD;
1007 : }
1008 0 : if (boost::algorithm::ends_with(pname, g_viz_constants.STATS_PROXY_FIELD)) {
1009 0 : pname = g_viz_constants.STATS_PROXY_FIELD;
1010 : }
1011 0 : QE_INVALIDARG_ERROR(pop == EQUAL || pop == PREFIX);
1012 : GenDb::Op::type db_op;
1013 0 : if (pop == EQUAL) {
1014 0 : db_op = GenDb::Op::EQ;
1015 0 : QE_INVALIDARG_ERROR(populate_where_vec(m_query, &where_vec_stats,
1016 : pname, db_op, GenDb::DbDataValueToString(pval)));
1017 : } else {
1018 0 : std::string val(GenDb::DbDataValueToString(pval));
1019 0 : if (!val.empty()) {
1020 0 : db_op = GenDb::Op::LIKE;
1021 0 : QE_INVALIDARG_ERROR(populate_where_vec(m_query, &where_vec_stats,
1022 : pname, db_op, val));
1023 : }
1024 0 : }
1025 : } else {
1026 : GenDb::Op::type db_op;
1027 197 : pval = "%" + pname + "=" + GenDb::DbDataValueToString(pval);
1028 196 : db_op = GenDb::Op::LIKE;
1029 196 : size_t idx = djb_hash(pname.c_str(), pname.length())
1030 196 : % g_viz_constants.NUM_STATS_TAGS_FIELD;
1031 196 : QE_INVALIDARG_ERROR(populate_where_vec(m_query, &where_vec_tags_stats[idx],
1032 : g_viz_constants.STATS_TAGS_FIELD + integerToString(idx),
1033 : db_op, GenDb::DbDataValueToString(pval)));
1034 : }
1035 788 : if (sop != 0) {
1036 270 : if (sname == g_viz_constants.STATS_NAME_FIELD) {
1037 0 : name_match = true;
1038 0 : sname_val = sval;
1039 0 : name_op = sop;
1040 270 : } else if (sname == g_viz_constants.STATS_SOURCE_FIELD ||
1041 540 : boost::algorithm::ends_with(pname, g_viz_constants.STATS_KEY_FIELD) ||
1042 270 : boost::algorithm::ends_with(pname, g_viz_constants.STATS_PROXY_FIELD)) {
1043 0 : if (boost::algorithm::ends_with(pname, g_viz_constants.STATS_KEY_FIELD)) {
1044 0 : pname = g_viz_constants.STATS_KEY_FIELD;
1045 : }
1046 0 : if (boost::algorithm::ends_with(pname, g_viz_constants.STATS_PROXY_FIELD)) {
1047 0 : pname = g_viz_constants.STATS_PROXY_FIELD;
1048 : }
1049 :
1050 0 : QE_INVALIDARG_ERROR(sop == EQUAL || sop == PREFIX);
1051 : GenDb::Op::type db_op;
1052 0 : if (sop == EQUAL) {
1053 0 : db_op = GenDb::Op::EQ;
1054 : } else {
1055 0 : db_op = GenDb::Op::LIKE;
1056 : }
1057 0 : QE_INVALIDARG_ERROR(populate_where_vec(m_query, &where_vec_stats,
1058 : sname, db_op, GenDb::DbDataValueToString(sval)));
1059 : } else {
1060 270 : QE_INVALIDARG_ERROR(sop == EQUAL || sop == PREFIX);
1061 : GenDb::Op::type db_op;
1062 270 : sval = "%" + sname + "=" + GenDb::DbDataValueToString(sval);
1063 270 : db_op = GenDb::Op::LIKE;
1064 270 : size_t idx = djb_hash(sname.c_str(), sname.length())
1065 270 : % g_viz_constants.NUM_STATS_TAGS_FIELD;
1066 270 : QE_INVALIDARG_ERROR(populate_where_vec(m_query, &where_vec_tags_stats[idx],
1067 : g_viz_constants.STATS_TAGS_FIELD + integerToString(idx),
1068 : db_op, GenDb::DbDataValueToString(sval)));
1069 : }
1070 : }
1071 787 : object_id_specified = true;
1072 787 : }
1073 2139 : }
1074 :
1075 1736 : if (m_query->is_stat_table_query(m_query->table())) {
1076 717 : std::vector<GenDb::WhereIndexInfoVec> where_vec_list;
1077 717 : populate_stats_where_vec_list(&where_vec_list, where_vec_stats,
1078 : where_vec_tags_stats);
1079 2151 : BOOST_FOREACH(const GenDb::WhereIndexInfoVec &where_vec, where_vec_list) {
1080 716 : DbQueryUnit *db_query = new DbQueryUnit(this, main_query);
1081 716 : db_query->cfname = g_viz_constants.STATS_TABLE;
1082 716 : std::string tstr, astr;
1083 716 : GetStatTableAttrName(m_query->table(), &tstr, &astr);
1084 718 : db_query->row_key_suffix.push_back(tstr);
1085 717 : db_query->row_key_suffix.push_back(astr);
1086 718 : db_query->where_vec = where_vec;
1087 718 : if (name_match) {
1088 593 : db_query->cr.start_.push_back(sname_val);
1089 593 : if (name_op == EQUAL) {
1090 576 : db_query->cr.finish_.push_back(sname_val);
1091 17 : } else if (name_op == PREFIX) {
1092 17 : db_query->cr.finish_.push_back(
1093 34 : GenDb::DbDataValueToString(sname_val) + "\x7f");
1094 : } else {
1095 0 : QE_INVALIDARG_ERROR(false);
1096 : }
1097 : } else {
1098 125 : db_query->cr.start_.push_back("\x00");
1099 125 : db_query->cr.finish_.push_back("\x7f");
1100 : }
1101 718 : }
1102 718 : }
1103 :
1104 : // common handling similar to object table where * case
1105 2945 : if (m_query->is_message_table_query() ||
1106 2944 : m_query->is_object_table_query(m_query->table())) {
1107 870 : handle_object_type_value(m_query, msg_table_db_query,
1108 : object_id_specified);
1109 : }
1110 :
1111 1737 : if (isSession) {
1112 114 : std::vector<GenDb::WhereIndexInfoVec> where_vec_list;
1113 114 : populate_session_where_vec_list(&where_vec_list, where_vec_session_rest, labels_vec, remote_labels_vec,
1114 : custom_tags_vec, remote_custom_tags_vec);
1115 :
1116 366 : BOOST_FOREACH(const GenDb::WhereIndexInfoVec &where_vec, where_vec_list) {
1117 126 : DbQueryUnit *session_db_query = new DbQueryUnit(this, main_query);
1118 126 : session_db_query->cfname = g_viz_constants.SESSION_TABLE;
1119 126 : session_db_query->row_key_suffix.push_back((uint8_t)is_si);
1120 126 : session_db_query->row_key_suffix.push_back((uint8_t)session_type);
1121 126 : session_db_query->where_vec = where_vec;
1122 :
1123 126 : if (proto_match) {
1124 58 : session_db_query->cr.start_.push_back(proto);
1125 58 : if (proto_op == EQUAL) {
1126 58 : session_db_query->cr.finish_.push_back(proto);
1127 0 : } else if (proto_op == IN_RANGE) {
1128 0 : session_db_query->cr.finish_.push_back(proto2);
1129 : }
1130 : } else {
1131 68 : session_db_query->cr.start_.push_back((uint16_t)0);
1132 68 : session_db_query->cr.finish_.push_back((uint16_t)0xffff);
1133 : }
1134 126 : if (sport_match) {
1135 58 : QE_INVALIDARG_ERROR(proto_match);
1136 58 : session_db_query->cr.start_.push_back(sport);
1137 58 : if(sport_op == EQUAL) {
1138 58 : session_db_query->cr.finish_.push_back(sport);
1139 0 : } else if (sport_op == IN_RANGE) {
1140 0 : session_db_query->cr.finish_.push_back(sport2);
1141 : }
1142 : } else {
1143 68 : session_db_query->cr.finish_.push_back((uint16_t)0xffff);
1144 : }
1145 : }
1146 114 : }
1147 1623 : else if (m_query->is_flow_query(m_query->table())) {
1148 36 : if (!filter_and.empty()) {
1149 0 : filter_list_.push_back(filter_and);
1150 : }
1151 : {
1152 36 : DbQueryUnit *client_session_query = new DbQueryUnit(this, main_query);
1153 36 : client_session_query->cfname = g_viz_constants.SESSION_TABLE;
1154 36 : client_session_query->row_key_suffix.push_back(
1155 36 : (uint8_t)SessionType::CLIENT_SESSION);
1156 36 : if (proto_match) {
1157 12 : client_session_query->cr.start_.push_back(proto);
1158 12 : if (proto_op == EQUAL) {
1159 12 : client_session_query->cr.finish_.push_back(proto);
1160 0 : } else if (proto_op == IN_RANGE) {
1161 0 : client_session_query->cr.finish_.push_back(proto2);
1162 : }
1163 : } else {
1164 24 : client_session_query->cr.start_.push_back(((uint16_t)0));
1165 24 : client_session_query->cr.finish_.push_back(((uint16_t)0xffff));
1166 : }
1167 36 : if ((direction_ing == 0 && sport_match) ||
1168 36 : (direction_ing == 1 && dport_match)) {
1169 0 : QE_INVALIDARG_ERROR(proto_match);
1170 0 : client_session_query->cr.start_.push_back(direction_ing?
1171 : dport:sport);
1172 0 : int op = direction_ing?dport_op:sport_op;
1173 0 : if (op == EQUAL) {
1174 0 : client_session_query->cr.finish_.push_back(direction_ing?
1175 : dport:sport);
1176 0 : } else if (op == IN_RANGE) {
1177 0 : client_session_query->cr.finish_.push_back(direction_ing?
1178 : dport2:sport2);
1179 : }
1180 0 : } else {
1181 36 : client_session_query->cr.finish_.push_back((uint16_t)0xffff);
1182 : }
1183 36 : if ((direction_ing == 0 && dip_match) ||
1184 36 : (direction_ing == 1 && sip_match)) {
1185 :
1186 0 : int op = direction_ing?sip_op:dip_op;
1187 0 : std::string val = direction_ing?
1188 0 : (boost::get<std::string>(sip)):(boost::get<std::string>(dip));
1189 : GenDb::Op::type comparator;
1190 0 : if (op == PREFIX) {
1191 0 : comparator = GenDb::Op::LIKE;
1192 : } else {
1193 0 : comparator = GenDb::Op::EQ;
1194 : }
1195 0 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
1196 : &(client_session_query->where_vec), "local_ip", comparator, val));
1197 0 : }
1198 36 : if ((direction_ing == 0 && dvn_match) ||
1199 36 : (direction_ing == 1 && svn_match)) {
1200 24 : int op = direction_ing?svn_op:dvn_op;
1201 24 : std::string val = direction_ing?
1202 24 : (boost::get<std::string>(svn)):(boost::get<std::string>(dvn));
1203 : GenDb::Op::type comparator;
1204 24 : if (op == PREFIX) {
1205 12 : comparator = GenDb::Op::LIKE;
1206 : } else {
1207 12 : comparator = GenDb::Op::EQ;
1208 : }
1209 24 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
1210 : &(client_session_query->where_vec), "vn", comparator, val));
1211 24 : }
1212 36 : if ((direction_ing == 0 && svn_match) ||
1213 36 : (direction_ing == 1 && dvn_match)) {
1214 12 : int op = (direction_ing?dvn_op:svn_op);
1215 : GenDb::Op::type comparator;
1216 12 : std::string val = direction_ing?
1217 12 : (boost::get<std::string>(dvn)):(boost::get<std::string>(svn));
1218 12 : if (op == PREFIX) {
1219 0 : comparator = GenDb::Op::LIKE;
1220 : } else {
1221 12 : comparator = GenDb::Op::EQ;
1222 : }
1223 12 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
1224 : &(client_session_query->where_vec), "remote_vn", comparator, val));
1225 12 : }
1226 : }
1227 : {
1228 36 : DbQueryUnit *server_session_query = new DbQueryUnit(this, main_query);
1229 36 : server_session_query->cfname = g_viz_constants.SESSION_TABLE;
1230 36 : server_session_query->row_key_suffix.push_back(
1231 36 : (uint8_t)SessionType::SERVER_SESSION);
1232 36 : if (proto_match) {
1233 12 : server_session_query->cr.start_.push_back(proto);
1234 12 : if(proto_op == EQUAL) {
1235 12 : server_session_query->cr.finish_.push_back(proto);
1236 : }
1237 0 : else if (proto_op == IN_RANGE) {
1238 0 : server_session_query->cr.finish_.push_back(proto2);
1239 : }
1240 : } else {
1241 24 : server_session_query->cr.start_.push_back(((uint16_t)0));
1242 24 : server_session_query->cr.finish_.push_back(((uint16_t)0xffff));
1243 : }
1244 36 : if ((direction_ing == 0 && dport_match) ||
1245 36 : (direction_ing == 1 && sport_match)) {
1246 0 : QE_INVALIDARG_ERROR(proto_match);
1247 0 : server_session_query->cr.start_.push_back(direction_ing?
1248 : sport:dport);
1249 0 : int op = direction_ing?sport_op:dport_op;
1250 0 : if(op == EQUAL) {
1251 0 : server_session_query->cr.finish_.push_back(direction_ing?
1252 : sport:dport);
1253 0 : } else if (op == IN_RANGE) {
1254 0 : server_session_query->cr.finish_.push_back(direction_ing?
1255 : sport2:dport2);
1256 : }
1257 0 : } else {
1258 36 : server_session_query->cr.finish_.push_back((uint16_t)0xffff);
1259 : }
1260 36 : if ((direction_ing == 0 && dip_match) ||
1261 36 : (direction_ing == 1 && sip_match)) {
1262 0 : int op = direction_ing?sip_op:dip_op;
1263 0 : std::string val = direction_ing?
1264 0 : (boost::get<std::string>(sip)):(boost::get<std::string>(dip));
1265 : GenDb::Op::type comparator;
1266 0 : if (op == PREFIX) {
1267 0 : comparator = GenDb::Op::LIKE;
1268 : } else {
1269 0 : comparator = GenDb::Op::EQ;
1270 : }
1271 0 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
1272 : &(server_session_query->where_vec), "local_ip", comparator, val));
1273 0 : }
1274 36 : if ((direction_ing == 0 && dvn_match) ||
1275 36 : (direction_ing == 1 && svn_match)) {
1276 24 : int op = (direction_ing?svn_op:dvn_op);
1277 24 : std::string val = direction_ing?
1278 24 : (boost::get<std::string>(svn)):(boost::get<std::string>(dvn));
1279 : GenDb::Op::type comparator;
1280 24 : if (op == PREFIX) {
1281 12 : comparator = GenDb::Op::LIKE;
1282 : } else {
1283 12 : comparator = GenDb::Op::EQ;
1284 : }
1285 24 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
1286 : &(server_session_query->where_vec), "vn", comparator, val));
1287 23 : }
1288 36 : if ((direction_ing == 0 && svn_match) ||
1289 36 : (direction_ing == 1 && dvn_match)) {
1290 12 : int op = (direction_ing?dvn_op:svn_op);
1291 : GenDb::Op::type comparator;
1292 12 : std::string val = direction_ing?
1293 12 : (boost::get<std::string>(dvn)):(boost::get<std::string>(svn));
1294 12 : if (op == PREFIX) {
1295 0 : comparator = GenDb::Op::LIKE;
1296 : } else {
1297 12 : comparator = GenDb::Op::EQ;
1298 : }
1299 12 : QE_INVALIDARG_ERROR(populate_where_vec(m_query,
1300 : &(server_session_query->where_vec), "remote_vn", comparator, val));
1301 12 : }
1302 : }
1303 : }
1304 1743 : }
1305 1654 : }
1306 :
1307 : // For UT
1308 1 : WhereQuery::WhereQuery(QueryUnit *mq): QueryUnit(mq, mq){
1309 1 : }
1310 :
1311 114 : void WhereQuery::populate_session_where_vec_list(std::vector<GenDb::WhereIndexInfoVec> *where_vec_list,
1312 : const GenDb::WhereIndexInfoVec &rest_where_vec,
1313 : const GenDb::WhereIndexInfoVec &labels_vec,
1314 : const GenDb::WhereIndexInfoVec &remote_labels_vec,
1315 : const GenDb::WhereIndexInfoVec &custom_tags_vec,
1316 : const GenDb::WhereIndexInfoVec &remote_custom_tags_vec) {
1317 :
1318 114 : uint16_t max_random_attr = std::max(std::max(std::max(labels_vec.size(),
1319 114 : remote_labels_vec.size()), custom_tags_vec.size()),
1320 114 : remote_custom_tags_vec.size());
1321 114 : if (max_random_attr == 0) {
1322 82 : where_vec_list->push_back(rest_where_vec);
1323 : } else {
1324 76 : for (size_t i = 0; i < max_random_attr; ++i) {
1325 44 : GenDb::WhereIndexInfoVec where_vec(rest_where_vec);
1326 44 : if (i < labels_vec.size()) {
1327 34 : where_vec.push_back(labels_vec[i]);
1328 : }
1329 44 : if (i < remote_labels_vec.size()) {
1330 22 : where_vec.push_back(remote_labels_vec[i]);
1331 : }
1332 44 : if (i < custom_tags_vec.size()) {
1333 10 : where_vec.push_back(custom_tags_vec[i]);
1334 : }
1335 44 : if (i < remote_custom_tags_vec.size()) {
1336 10 : where_vec.push_back(remote_custom_tags_vec[i]);
1337 : }
1338 44 : where_vec_list->push_back(where_vec);
1339 44 : }
1340 : }
1341 114 : }
1342 :
1343 1807 : void WhereQuery::subquery_processed(QueryUnit *subquery) {
1344 1807 : AnalyticsQuery *m_query = (AnalyticsQuery *)main_query;
1345 : {
1346 1807 : std::scoped_lock lock(vector_push_mutex_);
1347 1807 : int sub_query_id = ((DbQueryUnit *)subquery)->sub_query_id;
1348 1807 : if (((DbQueryUnit *)subquery)->cfname == g_viz_constants.OBJECT_TABLE) {
1349 0 : inp.insert(inp.begin(), sub_queries[sub_query_id]->query_result.get());
1350 1807 : } else if (((DbQueryUnit *)subquery)->cfname == g_viz_constants.STATS_TABLE) {
1351 320 : inp_new_data.push_back((sub_queries[sub_query_id]->query_result.get()));
1352 : } else {
1353 1487 : inp.push_back((sub_queries[sub_query_id]->query_result.get()));
1354 : }
1355 1806 : if (subquery->query_status == QUERY_FAILURE) {
1356 0 : QE_QUERY_FETCH_ERROR();
1357 : }
1358 1806 : if (sub_queries.size() != inp.size() + inp_new_data.size()) {
1359 901 : return;
1360 : }
1361 1806 : }
1362 :
1363 : // Handle if any of the sub query has failed.
1364 906 : if (m_query->qperf_.error) {
1365 0 : m_query->qperf_.chunk_where_time =
1366 0 : static_cast<uint32_t>((UTCTimestampUsec() - m_query->where_start_)
1367 0 : /1000);
1368 0 : where_query_cb_(m_query->handle_, m_query->qperf_, std::auto_ptr<std::vector<query_result_unit_t>>(where_result_.release()));
1369 0 : return;
1370 : }
1371 2716 : if (m_query->is_message_table_query()
1372 1554 : || m_query->is_object_table_query(m_query->table())
1373 1555 : || m_query->is_flow_query(m_query->table())
1374 : ) {
1375 447 : SetOperationUnit::op_or(((AnalyticsQuery *)(this->main_query))->query_id,
1376 447 : *where_result_, inp);
1377 458 : } else if (m_query->is_stat_table_query(m_query->table())) {
1378 320 : std::vector<WhereResultT*> inp_final;
1379 319 : if (inp.size() != 0) {
1380 : std::unique_ptr<WhereResultT>
1381 0 : where_result_old(new std::vector<query_result_unit_t>);
1382 0 : SetOperationUnit::op_and(((AnalyticsQuery *)(this->main_query))->query_id,
1383 0 : *where_result_old, inp);
1384 0 : inp_final.push_back(where_result_old.get());
1385 0 : }
1386 : std::unique_ptr<WhereResultT>
1387 319 : where_result_new(new std::vector<query_result_unit_t>);
1388 319 : SetOperationUnit::op_and(((AnalyticsQuery *)(this->main_query))->query_id,
1389 319 : *where_result_new, inp_new_data);
1390 320 : inp_final.push_back(where_result_new.get());
1391 640 : SetOperationUnit::op_or(((AnalyticsQuery *)(this->main_query))->query_id,
1392 320 : *where_result_, inp_final);
1393 320 : } else {
1394 139 : SetOperationUnit::op_and(((AnalyticsQuery *)(this->main_query))->query_id,
1395 139 : *where_result_, inp);
1396 : }
1397 906 : m_query->query_status = query_status;
1398 :
1399 906 : QE_TRACE(DEBUG, "Set ops returns # of rows:" << where_result_->size());
1400 :
1401 : // Have the result ready and processing is done
1402 906 : QE_TRACE(DEBUG, "WHERE processing done row #s:" <<
1403 : where_result_->size());
1404 906 : QE_TRACE_NOQID(DEBUG, " Finished where processing for QID " << m_query->query_id
1405 : << " chunk:" << m_query->parallel_batch_num);
1406 906 : status_details = 0;
1407 906 : parent_query->subquery_processed(this);
1408 906 : m_query->status_details = status_details;
1409 906 : m_query->qperf_.chunk_where_time =
1410 906 : static_cast<uint32_t>((UTCTimestampUsec() - m_query->where_start_)
1411 906 : /1000);
1412 906 : where_query_cb_(m_query->handle_, m_query->qperf_,std::auto_ptr<std::vector<query_result_unit_t>>(where_result_.release()));
1413 : }
1414 :
1415 912 : query_status_t WhereQuery::process_query()
1416 : {
1417 912 : AnalyticsQuery *m_query = (AnalyticsQuery *)main_query;
1418 :
1419 912 : if (status_details != 0)
1420 : {
1421 0 : QE_TRACE(DEBUG,
1422 : "No need to process query, as there were errors previously");
1423 0 : return QUERY_FAILURE;
1424 : }
1425 :
1426 912 : QE_TRACE(DEBUG, "WhereQuery" );
1427 :
1428 912 : QE_TRACE(DEBUG, "Starting processing of " << sub_queries.size() <<
1429 : " subqueries");
1430 :
1431 912 : if (m_query->table() == g_viz_constants.OBJECT_VALUE_TABLE) {
1432 7 : status_details = 0;
1433 7 : parent_query->subquery_processed(this);
1434 7 : return QUERY_SUCCESS;
1435 : }
1436 905 : unsigned int v_size = sub_queries.size();
1437 : // invoke processing of all the sub queries
1438 : // TBD: Handle ASYNC processing
1439 2710 : for (unsigned int i = 0; i < v_size; i++)
1440 : {
1441 1805 : query_status = sub_queries[i]->process_query();
1442 1805 : if (query_status == QUERY_FAILURE) {
1443 0 : return query_status;
1444 : }
1445 : }
1446 905 : return query_status;
1447 : }
1448 :
1449 : // We need to cover 2 cases here in MessageTablev2
1450 : // (a) --object-type is specified without any --object-id
1451 : // (b) --object-type and --object-id are specified
1452 :
1453 : // (a) ObjectTypeValue fields are stored in following format
1454 : // T2:ObjectType:ObjectId
1455 : // We need to query for T2:ObjectType*
1456 : // (b) We have 6 columns to save OBJECTID.
1457 : // Any OBJECTID could be in any of the 6 columns.
1458 : // For OBJECTID query, we need to check each of the 6 columns.
1459 : // Since its an OR operation, we need to create 6 queries, one
1460 : // for each column.
1461 : // Combining (a) & (b) we end up creating 6 queries 1 for each
1462 : // ObjectTypeValue[1..6] column.
1463 924 : void WhereQuery::handle_object_type_value(
1464 : AnalyticsQuery *m_query,
1465 : DbQueryUnit *db_query,
1466 : bool object_id_specified)
1467 : {
1468 924 : if (m_query->is_object_table_query(m_query->table())) {
1469 394 : QE_TRACE(DEBUG, "object-type-value handling");
1470 : std::string column1 = query_column_to_cass_column(m_query,
1471 395 : g_viz_constants.OBJECT_TYPE_NAME1);
1472 395 : if (column1.empty()) {
1473 0 : QE_INVALIDARG_ERROR(false);
1474 : }
1475 395 : if (object_id_specified == false) {
1476 : // create db_query entry for OBJECT_TYPE_NAME1
1477 : // as done for OBJECTID case above.
1478 : // rest falls in place as with --object-id case.
1479 55 : match_op op = PREFIX;
1480 55 : std::string val(m_query->table() + ":");
1481 55 : std::string col_name = g_viz_constants.OBJECT_TYPE_NAME1;
1482 55 : QE_INVALIDARG_ERROR(populate_where_vec(m_query, &(db_query->where_vec),
1483 : col_name, get_gendb_op_from_op(op), val));
1484 55 : }
1485 :
1486 : // regular --object-id processing from here
1487 395 : int index = 0;
1488 790 : BOOST_FOREACH(GenDb::WhereIndexInfo &where_info, db_query->where_vec) {
1489 395 : if (column1 == where_info.get<0>()) {
1490 395 : break;
1491 : }
1492 0 : index++;
1493 : }
1494 :
1495 : // OBJECT_TYPE_NAME1 is already done above
1496 2368 : for (int i = 2;
1497 2368 : i <= g_viz_constants.MSG_TABLE_MAX_OBJECTS_PER_MSG;
1498 : i++) {
1499 1974 : DbQueryUnit *msg_table_db_query2 = new DbQueryUnit(this, main_query);
1500 1974 : msg_table_db_query2->cfname = g_viz_constants.COLLECTOR_GLOBAL_TABLE;
1501 1974 : msg_table_db_query2->t_only_row = true;
1502 1974 : msg_table_db_query2->t_only_col = true;
1503 1974 : msg_table_db_query2->where_vec = db_query->where_vec;
1504 :
1505 1972 : GenDb::WhereIndexInfo *where_info2 = &msg_table_db_query2->where_vec[index];
1506 1972 : std::string col_name = g_viz_constants.OBJECT_TYPE_NAME_PFX;
1507 1972 : col_name.append(integerToString(i));
1508 :
1509 1975 : std::string columnN = query_column_to_cass_column(m_query, col_name);
1510 1973 : if (column1.empty()) {
1511 0 : QE_INVALIDARG_ERROR(false);
1512 : }
1513 1973 : where_info2->get<0>() = columnN;
1514 1973 : }
1515 394 : }
1516 : }
1517 :
1518 1780 : bool WhereQuery::populate_where_vec(AnalyticsQuery *m_query,
1519 : GenDb::WhereIndexInfoVec *where_vec,
1520 : const std::string& query_col,
1521 : const GenDb::Op::type db_op,
1522 : const std::string& value) {
1523 1780 : std::string columnN = query_column_to_cass_column(m_query, query_col);
1524 1779 : if (columnN.empty()) {
1525 0 : return false;
1526 : }
1527 1779 : std::string val(value);
1528 1780 : switch (db_op) {
1529 671 : case GenDb::Op::LIKE:
1530 : {
1531 671 : val += "%";
1532 671 : break;
1533 : }
1534 1109 : default:
1535 1109 : break;
1536 : }
1537 1780 : if (val == "%") {
1538 24 : return true;
1539 : }
1540 : GenDb::WhereIndexInfo where_info =
1541 1758 : boost::make_tuple(columnN, db_op, val);
1542 1755 : where_vec->push_back(where_info);
1543 1754 : return true;
1544 1777 : }
1545 :
1546 4150 : std::string WhereQuery::query_column_to_cass_column(AnalyticsQuery *m_query,
1547 : const std::string& query_column) {
1548 4150 : std::map<std::string, table_schema> schema;
1549 4147 : std::string table_name;
1550 11735 : if (m_query->is_message_table_query(m_query->table()) ||
1551 7591 : m_query->is_object_table_query(m_query->table())) {
1552 3458 : schema = g_viz_constants._VIZD_TABLE_SCHEMA;
1553 3453 : table_name = g_viz_constants.COLLECTOR_GLOBAL_TABLE;
1554 1908 : } else if (m_query->is_session_query(m_query->table()) ||
1555 1222 : m_query->is_flow_query(m_query->table())) {
1556 220 : schema = g_viz_constants._VIZD_SESSION_TABLE_SCHEMA;
1557 220 : table_name = g_viz_constants.SESSION_TABLE;
1558 465 : } else if (m_query->is_stat_table_query(m_query->table())) {
1559 466 : schema = g_viz_constants._VIZD_STAT_TABLE_SCHEMA;
1560 466 : table_name = g_viz_constants.STATS_TABLE;
1561 : }
1562 4140 : std::map<std::string, table_schema>::const_iterator it = schema.find(table_name);
1563 4137 : QE_ASSERT(it != schema.end());
1564 : std::map<string, string>::const_iterator itr =
1565 4137 : it->second.index_column_to_column.find(query_column);
1566 4133 : if (itr == (it->second.index_column_to_column.end())) {
1567 0 : return "";
1568 : }
1569 4133 : return itr->second;
1570 4130 : }
|