// Thanks to Nikolaj who kindly helped with the second reference implementation! virtual table_base * reference_implementation_with_hash(const table_base & t) { group_map group; table_base::iterator it = t.begin(); table_base::iterator end = t.end(); table_fact row, row2; table_element current_value, min_value; for (; it != end; ++it) { it->get_fact(row); current_value = row[m_col]; group_by(row, row2); group_map::entry* entry = group.find_core(row2); if (!entry) { group.insert(row2, current_value); } else if (entry->get_data().m_value > current_value) { entry->get_data().m_value = current_value; } } table_base* result = t.get_plugin().mk_empty(m_sig); table_base::iterator it2 = t.begin(); for (; it2 != end; ++it2) { it2->get_fact(row); current_value = row[m_col]; group_by(row, row2); VERIFY(group.find(row2, min_value)); if (min_value == current_value) { result->add_fact(row); } } return result; }
int CustomQuery(int, char* []) { const auto foo = test::TabFoo{}; const auto bar = test::TabBar{}; auto db = MockDb{}; // Unconditionally compare(__LINE__, custom_query(sqlpp::select(), select_flags(sqlpp::distinct), select_columns(foo.omega), from(foo), sqlpp::unconditionally()), "SELECT DISTINCT tab_foo.omega FROM tab_foo "); // A full select statement made individual clauses compare(__LINE__, custom_query(sqlpp::select(), select_flags(sqlpp::distinct), select_columns(foo.omega), from(foo.join(bar).on(foo.omega == bar.alpha)), where(bar.alpha > 17), group_by(foo.omega), having(avg(bar.alpha) > 19), order_by(foo.omega.asc()), sqlpp::limit(10u), sqlpp::offset(100u)), "SELECT DISTINCT tab_foo.omega FROM tab_foo INNER JOIN tab_bar ON (tab_foo.omega=tab_bar.alpha) WHERE " "(tab_bar.alpha>17) GROUP BY tab_foo.omega HAVING (AVG(tab_bar.alpha)>19) ORDER BY tab_foo.omega ASC " "LIMIT 10 OFFSET 100"); // A full select statement made individual clauses compare( __LINE__, custom_query(sqlpp::select(), dynamic_select_flags(db, sqlpp::distinct), dynamic_select_columns(db, foo.omega), dynamic_from(db, foo.join(bar).on(foo.omega == bar.alpha)), dynamic_where(db, bar.alpha > 17), dynamic_group_by(db, foo.omega), dynamic_having(db, avg(bar.alpha) > 19), dynamic_order_by(db, foo.omega.asc()), sqlpp::dynamic_limit(db), sqlpp::dynamic_offset(db)), "SELECT DISTINCT tab_foo.omega FROM tab_foo INNER JOIN tab_bar ON (tab_foo.omega=tab_bar.alpha) WHERE " "(tab_bar.alpha>17) GROUP BY tab_foo.omega HAVING (AVG(tab_bar.alpha)>19) ORDER BY tab_foo.omega ASC "); // A pragma query for sqlite compare(__LINE__, custom_query(sqlpp::verbatim("PRAGMA user_version")).with_result_type_of(select(sqlpp::value(1).as(pragma))), " PRAGMA user_version"); return 0; }
void test_table_min() { std::cout << "----- test_table_min -----\n"; datalog::table_signature sig; sig.push_back(2); sig.push_back(4); sig.push_back(8); smt_params params; ast_manager ast_m; datalog::register_engine re; datalog::context ctx(ast_m, re, params); datalog::relation_manager & m = ctx.get_rel_context()->get_rmanager(); m.register_plugin(alloc(datalog::bitvector_table_plugin, m)); datalog::table_base* tbl = mk_bv_table(m, sig); datalog::table_base& table = *tbl; datalog::table_fact row, row1, row2, row3; row.push_back(1); row.push_back(2); row.push_back(5); // Group (1,2,*) row1 = row; row[2] = 6; row2 = row; row[2] = 5; row3 = row; table.add_fact(row1); table.add_fact(row2); table.add_fact(row3); // Group (1,3,*) row[1] = 3; row1 = row; row[2] = 7; row2 = row; row[2] = 4; row3 = row; table.add_fact(row1); table.add_fact(row2); table.add_fact(row3); table.display(std::cout); unsigned_vector group_by(2); group_by[0] = 0; group_by[1] = 1; datalog::table_min_fn * min_fn = m.mk_min_fn(table, group_by, 2); datalog::table_base * min_tbl = (*min_fn)(table); min_tbl->display(std::cout); row[1] = 2; row[2] = 5; SASSERT(min_tbl->contains_fact(row)); row[1] = 3; row[2] = 4; SASSERT(min_tbl->contains_fact(row)); dealloc(min_fn); min_tbl->deallocate(); tbl->deallocate(); }
int main(int argc, char** argv) { GroupBy::Option option; while (1) { static struct option long_options[] = { { "width", required_argument, 0, 'w' }, { "fields", required_argument, 0, 'f' }, { "skip", required_argument, 0, 's' }, { "delimiters", required_argument, 0, 'd' }, { "join-delimiter", required_argument, 0, 'j' }, { "help", no_argument, 0, '?' }, { 0, 0 , 0, 0 }, }; int c = getopt_long(argc, argv, "w:d:j:f:s:", long_options, NULL); if (c == -1) { break; } switch(c) { case 'w': option.get_key_mode = GroupBy::Option::GET_KEY_MODE_CHARS; option.key_length = std::atoi(optarg); break; case 'f': option.get_key_mode = GroupBy::Option::GET_KEY_MODE_FIELDS; option.field_length = std::atoi(optarg); break; case 's': option.n_skip = std::atoi(optarg); break; case 'd': option.get_key_mode = GroupBy::Option::GET_KEY_MODE_FIELDS; option.delimiters = optarg; break; case 'j': option.join_delimiter = optarg; break; case '?': Usage(argc, argv, option); return 0; break; default: Usage(argc, argv, option); return -1; } } if (optind < argc) { Usage(argc, argv, option); return -1; } argc -= optind; argv += optind; GroupBy group_by(option); while (std::cin) { std::string line; if (std::getline(std::cin, line).eof()) { break; } group_by.Append(line); } const std::vector<std::string>& buffers = group_by.Buffers(); for (std::vector<std::string>::const_iterator it = buffers.begin(); it != buffers.end(); ++it) { std::cout << *it << std::endl; } return 0; }