SQLsmith  v1.2.1-5-gfacd7a8
A random SQL query generator
monetdb.cc
1 #include <stdexcept>
2 #include <cassert>
3 #include "monetdb.hh"
4 #include <iostream>
5 
6 #ifndef HAVE_BOOST_REGEX
7 #include <regex>
8 #else
9 #include <boost/regex.hpp>
10 using boost::regex;
11 using boost::smatch;
12 using boost::regex_match;
13 #endif
14 
15 using namespace std;
16 
17 extern "C" {
18 #include <mapi.h>
19 #include <unistd.h>
20 }
21 
22 // connect montetdb
23 monetdb_connection::monetdb_connection(std::string &conninfo)
24 {
25  dbh = mapi_mapiuri(conninfo.c_str(), "monetdb", "monetdb", "sql");
26  if (mapi_error(dbh)) {
27  if (dbh != NULL) {
28  mapi_explain(dbh, stderr);
29  mapi_destroy(dbh);
30  } else {
31  fprintf(stderr, "command failed\n");
32  }
33  exit(-1);
34  }
35  mapi_reconnect(dbh);
36  if (mapi_error(dbh)) {
37  mapi_explain(dbh, stderr);
38  mapi_destroy(dbh);
39  exit(-1);
40  }
41 }
42 
43 // execute queries on MonetDB
44 void monetdb_connection::q(const char* query)
45 {
46  MapiHdl hdl = mapi_query(dbh, query);
47  if (mapi_result_error(hdl) != NULL)
48  mapi_explain_result(hdl, stderr);
49  mapi_close_handle(hdl);
50 }
51 
52 // disconnect MonetDB
53 monetdb_connection::~monetdb_connection()
54 {
55  mapi_destroy(dbh);
56 }
57 
58 //load schema from MonetDB
59 schema_monetdb::schema_monetdb(std::string &conninfo):monetdb_connection(conninfo)
60 {
61 
62 
63  cerr << "init booltype, inttype, internaltype, arraytype here" << endl;
64  booltype = sqltype::get("boolean");
65  inttype = sqltype::get("int");
66  internaltype = sqltype::get("internal");
67  arraytype = sqltype::get("ARRAY");
68 
69  cerr << "Loading tables from database: " << conninfo << endl;
70 // string qry = "select t.name, s.name, t.system, t.type from sys.tables t, sys.schemas s where t.schema_id=s.id and t.system=false";
71  string qry = "select t.name, s.name, t.system, t.type from sys.tables t, sys.schemas s where t.schema_id=s.id ";
72  MapiHdl hdl = mapi_query(dbh,qry.c_str());
73  while (mapi_fetch_row(hdl)) {
74  tables.push_back(table(mapi_fetch_field(hdl,0),mapi_fetch_field(hdl,1),strcmp(mapi_fetch_field(hdl,2),"false")==0 ? true : false , atoi(mapi_fetch_field(hdl,3))==0 ? false : true));
75  }
76  mapi_close_handle(hdl);
77  cerr << " done." << endl;
78 
79  cerr << "Loading columns and constraints...";
80  for (auto t = tables.begin(); t!=tables.end(); t++) {
81  string q("select col.name,"
82  " col.type "
83  " from sys.columns col, sys.tables tab"
84  " where tab.name= '");
85  q += t->name;
86  q += "' and tab.id = col.table_id";
87 
88  hdl = mapi_query(dbh,q.c_str());
89  while (mapi_fetch_row(hdl)) {
90  column c(mapi_fetch_field(hdl,0), sqltype::get(mapi_fetch_field(hdl,1)));
91  t->columns().push_back(c);
92  }
93  mapi_close_handle(hdl);
94  }
95  // TODO: confirm with Martin or Stefan about column
96  // constraints in MonetDB
97  cerr << " done." << endl;
98 
99  cerr << "Loading operators...";
100  string opq("select f.func, a.type, b.type, c.type"
101  " from sys.functions f, sys.args a, sys.args b, sys.args c"
102  " where f.id=a.func_id and f.id=b.func_id and f.id=c.func_id and a.name='arg_1' and b.name='arg_2' and c.number=0");
103  hdl = mapi_query(dbh,opq.c_str());
104  while (mapi_fetch_row(hdl)) {
105  op o(mapi_fetch_field(hdl,0),sqltype::get(mapi_fetch_field(hdl,1)),sqltype::get(mapi_fetch_field(hdl,2)),sqltype::get(mapi_fetch_field(hdl,3)));
106  register_operator(o);
107  }
108  mapi_close_handle(hdl);
109  cerr << " done." << endl;
110 
111 
112  cerr << "Loading routines...";
113  string routq("select s.name, f.id, a.type, f.name from sys.schemas s, sys.args a, sys.types t, sys.functions f where f.schema_id = s.id and f.id=a.func_id and a.number=0 and a.type = t.sqlname and f.mod<>'aggr'");
114  hdl = mapi_query(dbh,routq.c_str());
115  while (mapi_fetch_row(hdl)) {
116  routine proc(mapi_fetch_field(hdl,0),mapi_fetch_field(hdl,1),sqltype::get(mapi_fetch_field(hdl,2)),mapi_fetch_field(hdl,3));
117  register_routine(proc);
118  }
119  mapi_close_handle(hdl);
120  cerr << " done." << endl;
121 
122  cerr << "Loading routine parameters...";
123  for (auto &proc : routines) {
124  string routpq ("select a.type from sys.args a,"
125  " sys.functions f "
126  " where f.id = a.func_id and a.number <> 0 and f.id = '");
127  routpq += proc.specific_name;
128  routpq += "'";
129  hdl = mapi_query(dbh,routpq.c_str());
130  while (mapi_fetch_row(hdl)) {
131  proc.argtypes.push_back(sqltype::get(mapi_fetch_field(hdl,0)));
132  }
133  mapi_close_handle(hdl);
134  }
135  cerr << " done."<< endl;
136 
137 
138 
139  cerr << "Loading aggregates...";
140  string aggq("select s.name, f.id, a.type, f.name from sys.schemas s, sys.args a, sys.types t, sys.functions f where f.schema_id = s.id and f.id=a.func_id and a.number=0 and a.type = t.sqlname and f.mod='aggr'");
141 
142  hdl = mapi_query(dbh,aggq.c_str());
143  while (mapi_fetch_row(hdl)) {
144  routine proc(mapi_fetch_field(hdl,0),mapi_fetch_field(hdl,1),sqltype::get(mapi_fetch_field(hdl,2)),mapi_fetch_field(hdl,3));
145  register_aggregate(proc);
146  }
147  mapi_close_handle(hdl);
148  cerr << " done." << endl;
149 
150  cerr << "Loading aggregates parameters...";
151  for (auto &proc: aggregates) {
152  string aggpq ("select a.type from sys.args a, sys.functions f "
153  "where f.id = a.func_id and a.number <> 0 and f.id = '");
154  aggpq += proc.specific_name;
155  aggpq += "'";
156  hdl = mapi_query(dbh,aggpq.c_str());
157  while (mapi_fetch_row(hdl)) {
158  proc.argtypes.push_back(sqltype::get(mapi_fetch_field(hdl,0)));
159  }
160  mapi_close_handle(hdl);
161  }
162  cerr << " done."<< endl;
163 
164  mapi_destroy(dbh);
165  generate_indexes();
166 
167 // cerr << "print loaded information to check correctness" << endl;
168 // cerr << "Loaded tables.... " << endl;
169 /* for (auto item : tables) {
170  cerr << item.name << "; " << item.schema << "; " << item.is_insertable << "; " << item.is_base_table << endl;
171  }
172 */
173 // cerr << "Loaded columns... " << endl;
174 /* for (auto tab : tables) {
175  for (auto col: tab.columns())
176  cerr << tab.name << "; " << col.name << "; "<<col.type->name << endl;
177  }
178 */
179 // cerr << "Loaded aggregates and parameters... " << endl;
180 /* for (auto &proc : aggregates) {
181  cerr << proc.specific_name << "; " << proc.schema << "; " << proc.name <<"; " << proc.restype->name ;
182  for (auto item : proc.argtypes)
183  cerr << "; " << item->name;
184  cerr << endl;
185  }
186 */
187 }
188 
189 dut_monetdb::dut_monetdb(std::string &conninfo):monetdb_connection(conninfo)
190 {
191  //build connection
192 }
193 
194 void dut_monetdb::test(const std::string &stmt)
195 {
196  MapiHdl hdl = mapi_query(dbh,"CALL sys.settimeout(1)");
197  mapi_close_handle(hdl);
198  hdl = mapi_query(dbh,stmt.c_str());
199 
200  if (mapi_error(dbh)!=MOK) {
201 
202  try {
203  const char *error_string = mapi_result_error(hdl);
204 
205  if (!error_string)
206  error_string = "unknown error";
207 
208  const char *sqlstate = mapi_result_errorcode(hdl);
209  if (!sqlstate)
210  sqlstate = "XXXXX";
211 
212  /* monetdb appears to report sqlstate 42000 for all
213  errors, so we need to match the error string to
214  figure out actual syntax errors */
215 
216  static regex re_syntax("^syntax error,.*", regex::extended);
217 
218  if (mapi_error(dbh)==MERROR)
219  throw dut::syntax(error_string, sqlstate);
220  else if (mapi_error(dbh)==MTIMEOUT)
221  throw dut::timeout(error_string, sqlstate);
222  else if (regex_match(error_string, re_syntax))
223  throw dut::syntax(error_string, sqlstate);
224  else
225  throw dut::failure(error_string, sqlstate);
226 
227  } catch (dut::failure &e) {
228  mapi_close_handle(hdl);
229  throw;
230  }
231  }
232  mapi_close_handle(hdl);
233 }
schema and dut classes for MonetDB
Definition: relmodel.hh:117