18 #include <HugoQueryBuilder.hpp>
30 operator<<(NdbOut& out,
const HugoQueryBuilder::Op& op)
32 out <<
"[" << op.m_idx <<
" : " << op.m_op->getTable()->getName() <<
": ";
33 switch(op.m_op->getType()){
44 out <<
" : parent: " << op.m_parent <<
" ]";
49 HugoQueryBuilder::init()
56 HugoQueryBuilder::~HugoQueryBuilder()
58 for (
size_t i = 0;
i<m_queries.size();
i++)
59 m_queries[
i]->destroy();
63 HugoQueryBuilder::fixOptions()
79 for (
size_t i = 0;
i<m_tables.size();
i++)
81 if (m_tables[
i].m_table == tab)
101 def.m_unique_indexes.push_back(idx);
105 def.m_ordered_indexes.push_back(idx);
111 m_tables.push_back(def);
115 HugoQueryBuilder::getJoinLevel()
const
117 int m0 = m_joinLevel[0];
118 int m1 = m_joinLevel[1];
130 return m0 + (rand() % d);
136 for (
size_t i = 0;
i<m_tables.size();
i++)
138 if (m_tables[
i].m_table == tab)
146 HugoQueryBuilder::TableDef
147 HugoQueryBuilder::getTable()
const
149 int i = rand() % m_tables.size();
153 HugoQueryBuilder::OpIdx
154 HugoQueryBuilder::getOp()
const
157 TableDef tab = getTable();
159 oi.m_table = tab.m_table;
161 OptionMask save = m_options;
162 if (tab.m_unique_indexes.size() == 0)
166 if (tab.m_ordered_indexes.size() == 0)
191 int cnt = tab.m_unique_indexes.size();
192 oi.m_index = tab.m_unique_indexes[rand() % cnt];
200 int cnt = tab.m_ordered_indexes.size();
201 oi.m_index = tab.m_ordered_indexes[rand() % cnt];
216 bool allow_bind_nullable)
218 for (
size_t c = 0; c < cols.size(); c++)
222 for (
size_t t = 0; !found && t<ops.size(); t++)
246 HugoQueryBuilder::isAncestor(
const Op& parent,
const Op& child)
const
248 int pi = parent.m_idx;
249 int ci = child.m_idx;
254 if (m_query[ci].m_parent == pi)
256 assert(m_query[ci].m_parent != -1);
257 ci = m_query[m_query[ci].m_parent].m_idx;
263 HugoQueryBuilder::checkBusyScan(
Op op)
const
268 while (op.m_parent != -1)
274 op = m_query[op.m_parent];
277 for (
size_t i = op.m_idx + 1; i < m_query.size(); i++)
278 if (isAncestor(op, m_query[i]) && isScan(m_query[i].m_op))
285 HugoQueryBuilder::getParents(OpIdx oi)
290 bool allow_bind_nullable =
false;
291 bool check_bushy_scan =
false;
295 for (
int i = 0; i<oi.m_table->getNoOfColumns(); i++)
296 if (oi.m_table->getColumn(i)->getPrimaryKey())
297 cols.push_back(oi.m_table->getColumn(i));
301 for (
unsigned i = 0; i < oi.m_index->getNoOfColumns(); i++)
302 cols.push_back(oi.m_table->getColumn
303 (oi.m_index->getColumn(i)->getName()));
310 allow_bind_nullable =
true;
311 check_bushy_scan =
true;
312 unsigned cnt = oi.m_index->getNoOfColumns();
314 for (
unsigned i = 0; i < val; i++)
315 cols.push_back(oi.m_table->getColumn
316 (oi.m_index->getColumn(i)->getName()));
319 int r = rand() % m_query.size();
320 int cnt = (int)m_query.size();
321 for (
int i = 0; i < cnt; i++)
324 Op op = m_query[(i + r) % cnt];
325 if (check_bushy_scan && checkBusyScan(op))
333 if (testOption(O_MULTI_PARENT))
335 while (op.m_parent != -1)
337 op = m_query[op.m_parent];
343 if (checkBindable(cols,
set, allow_bind_nullable))
355 bool allow_bind_nullable)
357 int cnt = (int)parents.size();
366 for (
int i = 0; i<cnt; i++)
368 op = parents[(i + r) % cnt];
371 int cntpk = tab->getNoOfPrimaryKeys();
373 for (
int j = 0; j<cntpk; j++)
375 col = tab->getColumn(tab->getPrimaryKey((j + rpk) % cntpk));
387 for (
int i = 0; i<cnt; i++)
389 op = parents[(i + r) % cnt];
392 int cntcol = tab->getNoOfColumns();
394 for (
int j = 0; j<cntcol; j++)
396 col = tab->getColumn((j + rcol) % cntcol);
425 op.m_idx = m_query.size();
427 if (m_query.size() == 0)
437 for (
int a = 0; a<oi.m_table->getNoOfColumns(); a++)
439 if (oi.m_table->getColumn(a)->getPrimaryKey())
441 operands[opNo++] = builder.paramValue();
445 op.m_op = builder.readTuple(oi.m_table, operands);
449 op.m_op = builder.scanTable(oi.m_table);
454 for (
unsigned a = 0; a<oi.m_index->getNoOfColumns(); a++)
456 operands[opNo++] = builder.paramValue();
460 op.m_op = builder.scanIndex(oi.m_index, oi.m_table, &bounds);
466 for (
unsigned a = 0; a<oi.m_index->getNoOfColumns(); a++)
468 operands[opNo++] = builder.paramValue();
471 op.m_op = builder.readTuple(oi.m_index, oi.m_table, operands);
480 if (parents.size() == 0)
489 for (
int a = 0; a<oi.m_table->getNoOfColumns(); a++)
491 if (oi.m_table->getColumn(a)->getPrimaryKey())
493 operands[opNo++] = createLink(builder, oi.m_table->getColumn(a),
499 op.m_parent = parents[0].m_idx;
500 op.m_op = builder.readTuple(oi.m_table, operands);
506 for (
unsigned a = 0; a<oi.m_index->getNoOfColumns(); a++)
510 oi.m_table->getColumn(oi.m_index->getColumn(a)->getName()),
515 op.m_parent = parents[0].m_idx;
516 op.m_op = builder.readTuple(oi.m_index, oi.m_table, operands);
525 for (
unsigned a = 0; a<oi.m_index->getNoOfColumns(); a++)
529 oi.m_table->getColumn(oi.m_index->getColumn(a)->getName()),
534 op.m_parent = parents[0].m_idx;
536 op.m_op = builder.scanIndex(oi.m_index, oi.m_table, &bounds);
539 ndbout <<
"Failed to add to " << endl;
540 for (
size_t i = 0; i<m_query.size(); i++)
541 ndbout << m_query[i] << endl;
543 ndbout <<
"Parents: " << endl;
544 for (
size_t i = 0; i<parents.size(); i++)
545 ndbout << parents[i].m_idx <<
" ";
556 ndbout << err << endl;
560 m_query.push_back(op);
570 ndbout <<
"Failed to create NdbQueryBuilder." << endl;
575 OptionMask save = m_options;
589 OptionMask save = m_options;
596 if (!isScan(m_query[0].m_op))
601 int levels = getJoinLevel();
611 if (def != 0 && !takeOwnership)
613 m_queries.push_back(def);