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