sql_query_proto_to_string.cc 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <algorithm>
  5. #include <array>
  6. #include <cctype>
  7. #include <cstdint>
  8. #include <iomanip>
  9. #include <map>
  10. #include <sstream>
  11. #include <string>
  12. #include <vector>
  13. #include "third_party/sqlite/fuzz/icu_codes.pb.h"
  14. #include "third_party/sqlite/fuzz/sql_queries.pb.h"
  15. #include "third_party/sqlite/fuzz/sql_query_grammar.pb.h"
  16. #include "third_party/sqlite/fuzz/sql_query_proto_to_string.h"
  17. using namespace sql_query_grammar;
  18. #define CONV_FN(TYPE, VAR_NAME) std::string TYPE##ToString(const TYPE& VAR_NAME)
  19. #define RETURN_IF_DISABLED_QUERY(TYPE) \
  20. if (disabled_queries_.count(#TYPE) != 0) \
  21. return "";
  22. namespace sql_fuzzer {
  23. namespace {
  24. constexpr uint32_t kMaxColumnNumber = 20;
  25. #if !defined(FUZZ_FTS3)
  26. constexpr uint32_t kMaxTableNumber = 8;
  27. #endif
  28. constexpr uint32_t kMaxSchemaNumber = 4;
  29. constexpr uint32_t kMaxWindowNumber = 5;
  30. constexpr uint32_t kMaxColumnConstraintNumber = 10;
  31. constexpr uint32_t kMaxTableConstraintNumber = 10;
  32. constexpr uint32_t kMaxIndexNumber = 10;
  33. // should be less than kMaxTableNumber
  34. constexpr uint32_t kMaxFTS3TableNumber = 2;
  35. constexpr uint32_t kMaxStrLength =
  36. 200; // So these are readable and somewhat performant, keep a maximum
  37. // string length......
  38. #if !defined(FUZZ_OMIT_SAVEPOINT)
  39. constexpr uint32_t kMaxSavePointNumber = 10;
  40. #endif
  41. constexpr uint32_t kMaxViewNumber = 5;
  42. constexpr uint32_t kMaxTriggerNumber = 10;
  43. std::set<std::string> disabled_queries_;
  44. } // namespace
  45. CONV_FN(Expr, expr);
  46. CONV_FN(Select, select);
  47. CONV_FN(TableOrSubquery, tos);
  48. CONV_FN(FTS3Table, ft);
  49. CONV_FN(FTS3NearQuery, fnq);
  50. CONV_FN(FTS3AuxiliaryFn, faf);
  51. CONV_FN(FTS3MatchFormat, fmf);
  52. CONV_FN(DateAndTimeFn, sfn);
  53. CONV_FN(ExprSchemaTableFn, estf);
  54. // ~~~~Numbered values to string~~~
  55. // WARNING does not include space at the end
  56. CONV_FN(Column, col) {
  57. if (col.has_rowid() && col.rowid())
  58. return "rowid";
  59. #if defined(FUZZ_FTS3)
  60. if (col.has_fts3_docid() && col.fts3_docid())
  61. return "docid";
  62. if (col.has_fts3_table())
  63. return FTS3TableToString(col.fts3_table());
  64. #endif
  65. std::string ret("Col");
  66. ret += std::to_string(col.column() % kMaxColumnNumber);
  67. return ret;
  68. }
  69. // WARNING does not include space at the end
  70. CONV_FN(Table, table) {
  71. std::string ret("Table");
  72. #if defined(FUZZ_FTS3)
  73. // only fuzzing FTS3 tables, clamp to the max FTS3 table num.
  74. ret += std::to_string(table.table() & kMaxFTS3TableNumber);
  75. if (table.fts3_content_table())
  76. ret += "_content";
  77. #else
  78. ret += std::to_string(table.table() % kMaxTableNumber);
  79. #endif
  80. return ret;
  81. }
  82. // WARNING does not include space at the end
  83. CONV_FN(Schema, schema) {
  84. if (schema.main()) {
  85. return "main";
  86. }
  87. if (schema.temp()) {
  88. return "temp";
  89. }
  90. std::string ret("Schema");
  91. ret += std::to_string(schema.schema() % kMaxSchemaNumber);
  92. return ret;
  93. }
  94. // WARNING does not include space at the end
  95. CONV_FN(WindowName, win) {
  96. std::string ret("Window");
  97. ret += std::to_string(win.window_name() % kMaxWindowNumber);
  98. return ret;
  99. }
  100. // WARNING does not include space at the end
  101. CONV_FN(ColumnConstraintName, cc) {
  102. std::string ret("ColConstraint");
  103. ret += std::to_string(cc.constraint_name() % kMaxColumnConstraintNumber);
  104. return ret;
  105. }
  106. // WARNING does not include space at the end
  107. CONV_FN(TableConstraintName, tc) {
  108. std::string ret("TableConstraint");
  109. ret += std::to_string(tc.constraint_name() % kMaxTableConstraintNumber);
  110. return ret;
  111. }
  112. // WARNING does not include space at the end
  113. CONV_FN(Index, index) {
  114. std::string ret("Index");
  115. ret += std::to_string(index.index() % kMaxIndexNumber);
  116. return ret;
  117. }
  118. #if !defined(FUZZ_OMIT_SAVEPOINT)
  119. CONV_FN(SavePoint, sp) {
  120. std::string ret("SavePoint");
  121. ret += std::to_string(sp.savepoint_num() % kMaxSavePointNumber);
  122. return ret;
  123. }
  124. #endif
  125. CONV_FN(View, v) {
  126. std::string ret("View");
  127. ret += std::to_string(v.view() % kMaxViewNumber);
  128. return ret;
  129. }
  130. CONV_FN(Trigger, t) {
  131. std::string ret("Trigger");
  132. ret += std::to_string(t.trigger() % kMaxTriggerNumber);
  133. return ret;
  134. }
  135. // ~~~~Utility functions~~~~
  136. std::string AscDescToString(AscDesc a) {
  137. switch (a) {
  138. case ASCDESC_NONE:
  139. return " ";
  140. case ASCDESC_ASC:
  141. return "ASC ";
  142. case ASCDESC_DESC:
  143. return "DESC ";
  144. default:
  145. return " ";
  146. }
  147. }
  148. std::string StrToLower(std::string s) {
  149. std::transform(
  150. s.begin(), s.end(), s.begin(),
  151. [](unsigned char c) -> unsigned char { return std::tolower(c); });
  152. return s;
  153. }
  154. std::string StripTrailingUnderscores(std::string s) {
  155. s.erase(std::find_if(s.rbegin(), s.rend(),
  156. [](unsigned char ch) { return ch != '_'; })
  157. .base(),
  158. s.end());
  159. return s;
  160. }
  161. // Converts underscores to spaces in a string.
  162. // This is because many enums like SET_NULL will be displayed at SET NULL in
  163. // the query, and I want to use protobuf's enum to string function to save time.
  164. std::string EnumStrReplaceUnderscores(std::string s) {
  165. std::transform(s.begin(), s.end(), s.begin(),
  166. [](unsigned char c) -> unsigned char {
  167. if (c == '_')
  168. return ' ';
  169. return c;
  170. });
  171. return s;
  172. }
  173. // Takes garbage data and produces a string, with quotes escaped.
  174. // Caps the number of bytes received from the protobuf at kMaxStrLength.
  175. // The final string could be as much as kMaxStrLength*2 as we added an extra
  176. // single quote for every single quote in the input string.
  177. std::string ConvertToSqlString(const std::string& s) {
  178. std::string ret;
  179. ret.reserve(kMaxStrLength * 2);
  180. for (size_t i = 0; i < s.length() && i < kMaxStrLength; i++) {
  181. ret += s[i];
  182. if (s[i] == '\'')
  183. ret += '\'';
  184. }
  185. return ret;
  186. }
  187. // WARNING does not include space
  188. std::string BytesToHex(const std::string& str) {
  189. std::ostringstream ss;
  190. ss << std::hex << std::setfill('0');
  191. for (size_t i = 0; i < str.size() && i < kMaxStrLength; i++) {
  192. ss << std::setw(2) << static_cast<int>(str[i]);
  193. }
  194. return ss.str();
  195. }
  196. // WARNING no space at end
  197. CONV_FN(ExprSchemaTable, st) {
  198. std::string ret;
  199. if (st.has_schema_name()) {
  200. ret += SchemaToString(st.schema_name());
  201. ret += ".";
  202. }
  203. ret += TableToString(st.table_name());
  204. return ret;
  205. }
  206. CONV_FN(ExprSchemaTableColumn, stc) {
  207. std::string ret;
  208. if (stc.has_schema()) {
  209. ret += SchemaToString(stc.schema());
  210. ret += ".";
  211. }
  212. if (stc.has_table()) {
  213. ret += TableToString(stc.table());
  214. ret += ".";
  215. }
  216. ret += ColumnToString(stc.col());
  217. return ret;
  218. }
  219. // WARNING does not include parentheses, nor a space at the end
  220. CONV_FN(ColumnList, cl) {
  221. std::string ret = ColumnToString(cl.col());
  222. for (int i = 0; i < cl.extra_cols_size(); i++) {
  223. ret += ", ";
  224. ret += ColumnToString(cl.extra_cols(i));
  225. }
  226. return ret;
  227. }
  228. CONV_FN(ExprList, me) {
  229. std::string ret = ExprToString(me.expr());
  230. for (int i = 0; i < me.extra_exprs_size(); i++) {
  231. ret += ", ";
  232. ret += ExprToString(me.extra_exprs(i));
  233. }
  234. return ret;
  235. }
  236. // WARNING does not include space
  237. CONV_FN(CollateType, collate_type) {
  238. std::string ct = CollateType_Name(collate_type);
  239. ct.erase(0, std::string("COLLATE_").length());
  240. return ct;
  241. }
  242. // WARNING does not include space
  243. CONV_FN(IndexedColumn, ic) {
  244. std::string ret;
  245. if (ic.has_expr()) {
  246. ret += ExprToString(ic.expr());
  247. } else {
  248. ret += ColumnToString(ic.col());
  249. }
  250. ret += " ";
  251. if (ic.has_collate_type()) {
  252. ret += "COLLATE ";
  253. ret += CollateTypeToString(ic.collate_type());
  254. ret += " ";
  255. }
  256. ret += AscDescToString(ic.asc_desc());
  257. return ret;
  258. }
  259. CONV_FN(IndexedColumnList, ic_list) {
  260. std::string ret;
  261. ret += IndexedColumnToString(ic_list.indexed_col());
  262. for (int i = 0; i < ic_list.extra_indexed_cols_size(); i++) {
  263. ret += ", ";
  264. ret += IndexedColumnToString(ic_list.extra_indexed_cols(i));
  265. }
  266. return ret;
  267. }
  268. CONV_FN(SchemaTableAsAlias, staa) {
  269. std::string ret;
  270. ret += ExprSchemaTableToString(staa.schema_table());
  271. ret += " ";
  272. if (staa.has_as_table_alias()) {
  273. ret += "AS ";
  274. ret += TableToString(staa.as_table_alias());
  275. ret += " ";
  276. }
  277. return ret;
  278. }
  279. // ~~~~Expression stuff~~~~
  280. // WARNING does not include space
  281. CONV_FN(NumericLiteral, nl) {
  282. static constexpr char hex_digits[] = "0123456789ABCDEF";
  283. static constexpr char digits[] = "0123456789";
  284. std::string ret;
  285. if (nl.hex_digits_size() > 0) {
  286. ret += "0x";
  287. for (int i = 0; i < nl.hex_digits_size(); i++) {
  288. ret += hex_digits[nl.hex_digits(i) % sizeof(hex_digits)];
  289. }
  290. return ret;
  291. }
  292. for (int i = 0; i < nl.digits_size(); i++) {
  293. ret += digits[nl.digits(i) % sizeof(digits)];
  294. }
  295. if (nl.decimal_point()) {
  296. ret += ".";
  297. if (nl.dec_digits_size() == 0) {
  298. ret += "0";
  299. } else {
  300. for (int i = 0; i < nl.dec_digits_size(); i++) {
  301. ret += digits[nl.dec_digits(i) % sizeof(digits)];
  302. }
  303. }
  304. }
  305. if (nl.exp_digits_size() > 0) {
  306. ret += "E";
  307. if (nl.negative_exp())
  308. ret += "-";
  309. if (nl.exp_digits_size() == 0) {
  310. ret += "0";
  311. } else {
  312. for (int i = 0; i < nl.exp_digits_size(); i++) {
  313. ret += digits[nl.exp_digits(i) % sizeof(digits)];
  314. }
  315. }
  316. }
  317. return ret;
  318. }
  319. // WARNING does not include space
  320. CONV_FN(LiteralValue, lit_val) {
  321. std::string ret;
  322. using LitValType = LiteralValue::LitValOneofCase;
  323. switch (lit_val.lit_val_oneof_case()) {
  324. case LitValType::kNumLit:
  325. return std::to_string(lit_val.num_lit());
  326. case LitValType::kStringLit:
  327. ret += '\'';
  328. ret += ConvertToSqlString(lit_val.string_lit());
  329. ret += '\'';
  330. return ret;
  331. case LitValType::kBlobLit:
  332. ret += "x\'";
  333. ret += BytesToHex(lit_val.blob_lit());
  334. ret += '\'';
  335. return ret;
  336. case LitValType::kSpecialVal:
  337. // special case for NULL, TRUE, FALSE
  338. if (lit_val.special_val() == LiteralValue::VAL_NULL)
  339. return "NULL";
  340. if (lit_val.special_val() == LiteralValue::VAL_TRUE)
  341. return "TRUE";
  342. if (lit_val.special_val() == LiteralValue::VAL_FALSE)
  343. return "FALSE";
  344. // do not remove underscores
  345. return LiteralValue_SpecialVal_Name(lit_val.special_val());
  346. case LitValType::kNumericLit:
  347. return NumericLiteralToString(lit_val.numeric_lit());
  348. default:
  349. return "1";
  350. }
  351. }
  352. CONV_FN(UnaryExpr, uexpr) {
  353. std::string ret;
  354. switch (uexpr.unary_op()) {
  355. case UNOP_MINUS:
  356. ret += "-";
  357. break;
  358. case UNOP_PLUS:
  359. ret += "+";
  360. break;
  361. case UNOP_TILDE:
  362. ret += "~";
  363. break;
  364. case UNOP_NOT:
  365. ret += "NOT ";
  366. break;
  367. default:
  368. break;
  369. }
  370. ret += ExprToString(uexpr.expr());
  371. return ret;
  372. }
  373. CONV_FN(BinaryOperator, bop) {
  374. switch (bop) {
  375. case BINOP_CONCAT:
  376. return " || ";
  377. break;
  378. case BINOP_STAR:
  379. return " * ";
  380. break;
  381. case BINOP_SLASH:
  382. return " / ";
  383. break;
  384. case BINOP_PERCENT:
  385. return " % ";
  386. break;
  387. case BINOP_PLUS:
  388. return " + ";
  389. break;
  390. case BINOP_MINUS:
  391. return " - ";
  392. break;
  393. case BINOP_LELE:
  394. return " << ";
  395. break;
  396. case BINOP_GRGR:
  397. return " >> ";
  398. break;
  399. case BINOP_AMPERSAND:
  400. return " & ";
  401. break;
  402. case BINOP_PIPE:
  403. return " | ";
  404. break;
  405. case BINOP_LE:
  406. return " < ";
  407. break;
  408. case BINOP_LEQ:
  409. return " <= ";
  410. break;
  411. case BINOP_GR:
  412. return " > ";
  413. break;
  414. case BINOP_GREQ:
  415. return " >= ";
  416. break;
  417. case BINOP_EQ:
  418. return " = ";
  419. break;
  420. case BINOP_EQEQ:
  421. return " == ";
  422. break;
  423. case BINOP_NOTEQ:
  424. return " != ";
  425. break;
  426. case BINOP_LEGR:
  427. return " <> ";
  428. break;
  429. case BINOP_IS:
  430. return " IS ";
  431. break;
  432. case BINOP_ISNOT:
  433. return " IS NOT ";
  434. break;
  435. case BINOP_IN:
  436. return " IN "; // CORPUS specialize?
  437. break;
  438. case BINOP_LIKE:
  439. return " LIKE "; // CORPUS specialize?
  440. break;
  441. case BINOP_GLOB:
  442. return " GLOB "; // CORPUS
  443. break;
  444. case BINOP_MATCH:
  445. return " MATCH "; // CORPUS
  446. break;
  447. case BINOP_REGEXP:
  448. return " REGEXP "; // CORPUS
  449. break;
  450. case BINOP_AND:
  451. return " AND ";
  452. break;
  453. case BINOP_OR:
  454. return " OR ";
  455. break;
  456. default:
  457. return " AND ";
  458. break;
  459. }
  460. }
  461. // TODO(mpdenton) generate better REGEXP queries in non-fts3 case. (in
  462. // ColumnComparison as well)
  463. // TODO(mpdenton) generate better MATCH queries in non-fts3 case.
  464. CONV_FN(BinaryExpr, bexpr) {
  465. std::string ret;
  466. ret += ExprToString(bexpr.lhs());
  467. ret += BinaryOperatorToString(bexpr.op());
  468. #if defined(FUZZ_FTS3)
  469. if (bexpr.op() == BINOP_MATCH && bexpr.has_fmt()) {
  470. ret += FTS3MatchFormatToString(bexpr.fmt());
  471. return ret;
  472. }
  473. #endif
  474. ret += ExprToString(bexpr.rhs());
  475. return ret;
  476. }
  477. CONV_FN(AggregateFn, af) {
  478. std::string ret;
  479. ret += StrToLower(AggregateFn_FnName_Name(af.fn_name()));
  480. ret += "(";
  481. if (af.fn_name() == AggregateFn::COUNT && af.count_star())
  482. return ret + "*) ";
  483. if (af.distinct())
  484. ret += "DISTINCT ";
  485. if (af.has_col1()) {
  486. ret += ColumnToString(af.col1());
  487. if (af.fn_name() == AggregateFn::GROUP_CONCAT && af.has_col2()) {
  488. ret += ", ";
  489. ret += ColumnToString(af.col2());
  490. }
  491. } else {
  492. ret += ExprToString(af.expr1());
  493. if (af.fn_name() == AggregateFn::GROUP_CONCAT && af.has_expr2()) {
  494. ret += ", ";
  495. ret += ExprToString(af.expr2());
  496. }
  497. }
  498. ret += ") ";
  499. return ret;
  500. }
  501. CONV_FN(ZeroArgFn, zaf) {
  502. std::string func = ZeroArgFn_Name(zaf);
  503. // Remove ZFN_ prefix
  504. func.erase(0, std::string("ZFN_").length());
  505. return StrToLower(func) + "() ";
  506. }
  507. CONV_FN(OneArgFn, oaf) {
  508. std::string ret;
  509. ret += StripTrailingUnderscores(
  510. StrToLower(OneArgFn_OneArgFnEnum_Name(oaf.fn_enum())));
  511. ret += "(";
  512. ret += ExprToString(oaf.arg1());
  513. ret += ") ";
  514. return ret;
  515. }
  516. CONV_FN(TwoArgFn, taf) {
  517. std::string ret;
  518. ret += StrToLower(TwoArgFn_TwoArgFnEnum_Name(taf.fn_enum()));
  519. ret += "(";
  520. ret += ExprToString(taf.arg1());
  521. ret += ", ";
  522. ret += ExprToString(taf.arg2());
  523. ret += ") ";
  524. return ret;
  525. }
  526. CONV_FN(ThreeArgFn, taf) {
  527. std::string ret;
  528. ret += StrToLower(ThreeArgFn_ThreeArgFnEnum_Name(taf.fn_enum()));
  529. ret += "(";
  530. ret += ExprToString(taf.arg1());
  531. ret += ", ";
  532. ret += ExprToString(taf.arg2());
  533. ret += ", ";
  534. ret += ExprToString(taf.arg3());
  535. ret += ") ";
  536. return ret;
  537. }
  538. CONV_FN(VarNumFn, vfn) {
  539. std::string ret;
  540. ret += StrToLower(VarNumFn_VarNumFnEnum_Name(vfn.fn_enum()));
  541. ret += "(";
  542. ret += ExprToString(vfn.arg1());
  543. ret += ", ";
  544. ret += ExprToString(vfn.arg2());
  545. for (int i = 0; i < vfn.other_args_size(); i++) {
  546. ret += ", ";
  547. ret += ExprToString(vfn.other_args(i));
  548. }
  549. ret += ") ";
  550. return ret;
  551. }
  552. CONV_FN(CharFn, cfn) {
  553. std::string ret("char(");
  554. ret += std::to_string(cfn.char_());
  555. for (int i = 0; i < cfn.extra_chars_size(); i++) {
  556. ret += ", ";
  557. ret += std::to_string(cfn.extra_chars(i));
  558. }
  559. ret += ") ";
  560. return ret;
  561. }
  562. CONV_FN(SimpleFn, sfn) {
  563. // oneof
  564. if (sfn.has_zero_arg_fn()) {
  565. return ZeroArgFnToString(sfn.zero_arg_fn());
  566. } else if (sfn.has_one_arg_fn()) {
  567. return OneArgFnToString(sfn.one_arg_fn());
  568. } else if (sfn.has_two_arg_fn()) {
  569. return TwoArgFnToString(sfn.two_arg_fn());
  570. } else if (sfn.has_three_arg_fn()) {
  571. return ThreeArgFnToString(sfn.three_arg_fn());
  572. } else if (sfn.has_varnum_fn()) {
  573. return VarNumFnToString(sfn.varnum_fn());
  574. } else if (sfn.has_char_fn()) {
  575. return CharFnToString(sfn.char_fn());
  576. } else {
  577. return "changes() ";
  578. }
  579. }
  580. CONV_FN(PrintfFormatSpecifier, pfs) {
  581. std::string ret("%");
  582. for (int i = 0; i < pfs.flags_size(); i++) {
  583. switch (pfs.flags(i)) {
  584. case PrintfFormatSpecifier::MINUS:
  585. ret += "-";
  586. break;
  587. case PrintfFormatSpecifier::PLUS:
  588. ret += "+";
  589. break;
  590. case PrintfFormatSpecifier::SPACE:
  591. ret += " ";
  592. break;
  593. case PrintfFormatSpecifier::ZERO:
  594. ret += "0";
  595. break;
  596. case PrintfFormatSpecifier::HASH:
  597. ret += "#";
  598. break;
  599. case PrintfFormatSpecifier::COMMA:
  600. ret += ",";
  601. break;
  602. case PrintfFormatSpecifier::BANG:
  603. ret += "!";
  604. break;
  605. }
  606. }
  607. if (pfs.has_width()) {
  608. ret += std::to_string(pfs.width());
  609. } else if (pfs.width_star()) {
  610. ret += "*";
  611. }
  612. if (pfs.has_precision()) {
  613. ret += ".";
  614. ret += std::to_string(pfs.precision());
  615. }
  616. if (pfs.has_length()) {
  617. if (pfs.length() % 3 == 1) {
  618. ret += "l";
  619. } else if (pfs.length() % 3 == 2) {
  620. ret += "ll";
  621. }
  622. }
  623. if (pfs.percent()) {
  624. ret += "%";
  625. } else {
  626. std::string specifier = PrintfFormatSpecifier_SubType_Name(pfs.sub_type());
  627. if (pfs.lowercase())
  628. specifier = StrToLower(specifier);
  629. ret += specifier;
  630. }
  631. return ret;
  632. }
  633. CONV_FN(Printf, p) {
  634. std::string ret("printf(\'");
  635. for (int i = 0; i < p.specifiers_size(); i++) {
  636. ret += PrintfFormatSpecifierToString(p.specifiers(i));
  637. if (i < p.strings_size()) {
  638. ret += ConvertToSqlString(p.strings(i));
  639. }
  640. }
  641. ret += "\'";
  642. for (int i = 0; i < p.exprs_size(); i++) {
  643. ret += ", ";
  644. ret += ExprToString(p.exprs(i));
  645. }
  646. ret += ") ";
  647. return ret;
  648. }
  649. CONV_FN(Fn, fn) {
  650. // oneof
  651. if (fn.has_simple_fn()) {
  652. return SimpleFnToString(fn.simple_fn());
  653. } else if (fn.has_fts_aux_fn()) {
  654. #if defined(FUZZ_FTS3)
  655. return FTS3AuxiliaryFnToString(fn.fts_aux_fn()) + " ";
  656. #else
  657. return "changes() ";
  658. #endif
  659. } else if (fn.has_dat_fn()) {
  660. return DateAndTimeFnToString(fn.dat_fn());
  661. } else if (fn.has_aggregate_fn()) {
  662. return AggregateFnToString(fn.aggregate_fn());
  663. } else if (fn.has_printf()) {
  664. return PrintfToString(fn.printf());
  665. } else {
  666. return "changes() ";
  667. }
  668. }
  669. CONV_FN(ParenthesesExpr, pexpr) {
  670. std::string ret("(");
  671. ret += ExprToString(pexpr.expr());
  672. for (int i = 0; i < pexpr.other_exprs_size(); i++) {
  673. ret += ", ";
  674. ret += ExprToString(pexpr.other_exprs(i));
  675. }
  676. ret += ") ";
  677. return ret;
  678. }
  679. CONV_FN(CastExpr, cexpr) {
  680. std::string ret("CAST(");
  681. ret += ExprToString(cexpr.expr());
  682. ret += " AS ";
  683. ret += EnumStrReplaceUnderscores(
  684. CastTypeName_CastTypeNameEnum_Name(cexpr.type_name().type_enum()));
  685. ret += ") ";
  686. return ret;
  687. }
  688. CONV_FN(CollateExpr, cexpr) {
  689. std::string ret;
  690. ret += ExprToString(cexpr.expr());
  691. ret += " COLLATE ";
  692. ret += CollateTypeToString(cexpr.collate_type());
  693. return ret;
  694. }
  695. CONV_FN(Expr1, e) {
  696. std::string ret;
  697. ret += ExprToString(e.expr1());
  698. ret += " ";
  699. if (e.not_())
  700. ret += "NOT ";
  701. ret += EnumStrReplaceUnderscores(Expr1_PossibleKeywords_Name(e.keyword()));
  702. ret += " ";
  703. ret += ExprToString(e.expr2());
  704. ret += " "; //
  705. if (e.has_escape_expr()) {
  706. ret += "ESCAPE ";
  707. ret += ExprToString(e.escape_expr());
  708. ret += " "; //
  709. }
  710. return ret;
  711. }
  712. CONV_FN(ExprNullTests, e) {
  713. std::string ret = ExprToString(e.expr());
  714. ret += " ";
  715. ret += EnumStrReplaceUnderscores(
  716. ExprNullTests_PossibleKeywords_Name(e.keyword()));
  717. ret += " ";
  718. return ret;
  719. }
  720. CONV_FN(ExprIs, e) {
  721. std::string ret = ExprToString(e.expr1());
  722. ret += " IS ";
  723. if (e.not_())
  724. ret += "NOT ";
  725. ret += ExprToString(e.expr2());
  726. ret += " "; //
  727. return ret;
  728. }
  729. CONV_FN(ExprBetween, e) {
  730. std::string ret;
  731. ret += ExprToString(e.expr1());
  732. ret += " ";
  733. if (e.not_())
  734. ret += "NOT ";
  735. ret += "BETWEEN ";
  736. ret += ExprToString(e.expr2());
  737. ret += " AND ";
  738. ret += ExprToString(e.expr3());
  739. return ret;
  740. }
  741. CONV_FN(ExprInParen, e) {
  742. std::string ret("(");
  743. // oneof
  744. if (e.has_select()) {
  745. ret += SelectToString(e.select());
  746. } else if (e.has_exprs()) {
  747. ret += ExprListToString(e.exprs());
  748. }
  749. ret += ") ";
  750. return ret;
  751. }
  752. CONV_FN(ExprIn, e) {
  753. std::string ret = ExprToString(e.expr());
  754. ret += " ";
  755. if (e.not_())
  756. ret += "NOT ";
  757. if (e.has_expr_in_paren()) {
  758. ret += ExprInParenToString(e.expr_in_paren());
  759. } else if (e.has_schema_table()) {
  760. ret += ExprSchemaTableToString(e.schema_table());
  761. } else if (e.has_schema_table_fn()) {
  762. ret += ExprSchemaTableFnToString(e.schema_table_fn());
  763. } else {
  764. ret += "()";
  765. }
  766. return ret + " ";
  767. }
  768. CONV_FN(ExprExists, e) {
  769. std::string ret;
  770. if (e.not_())
  771. ret += "NOT EXISTS ";
  772. else if (e.exists())
  773. ret += "EXISTS ";
  774. ret += "(";
  775. ret += SelectToString(e.select());
  776. ret += ") ";
  777. return ret;
  778. }
  779. // WARNING no space at end
  780. CONV_FN(ExprWhenThen, e) {
  781. std::string ret("WHEN ");
  782. ret += ExprToString(e.when_expr());
  783. ret += " THEN ";
  784. ret += ExprToString(e.then_expr());
  785. return ret;
  786. }
  787. CONV_FN(ExprCase, e) {
  788. std::string ret("CASE ");
  789. if (e.has_expr()) {
  790. ret += ExprToString(e.expr());
  791. ret += " ";
  792. }
  793. ret += ExprWhenThenToString(e.when_then());
  794. ret += " ";
  795. for (int i = 0; i < e.extra_when_thens_size(); i++) {
  796. ret += ExprWhenThenToString(e.extra_when_thens(i));
  797. ret += " ";
  798. }
  799. if (e.has_else_expr()) {
  800. ret += "ELSE ";
  801. ret += ExprToString(e.else_expr());
  802. ret += " ";
  803. }
  804. ret += "END ";
  805. return ret;
  806. }
  807. CONV_FN(ExprRaiseFn, e) {
  808. std::string ret("RAISE(");
  809. if (e.ignore()) {
  810. ret += "IGNORE";
  811. } else {
  812. ret +=
  813. EnumStrReplaceUnderscores(ExprRaiseFn_RaiseFnEnum_Name(e.raise_fn()));
  814. ret += " ";
  815. ret += ", \'";
  816. ret += ConvertToSqlString(e.error_msg());
  817. ret += "\'";
  818. }
  819. ret += ") ";
  820. return ret;
  821. }
  822. CONV_FN(ComplicatedExpr, expr) {
  823. using ExprType = ComplicatedExpr::ComplicatedExprOneofCase;
  824. switch (expr.complicated_expr_oneof_case()) {
  825. case ExprType::kExprStc:
  826. return ExprSchemaTableColumnToString(expr.expr_stc());
  827. case ExprType::kUnaryExpr:
  828. return UnaryExprToString(expr.unary_expr());
  829. case ExprType::kBinaryExpr:
  830. return BinaryExprToString(expr.binary_expr());
  831. case ExprType::kFnExpr:
  832. return FnToString(expr.fn_expr());
  833. case ExprType::kParExpr:
  834. return ParenthesesExprToString(expr.par_expr());
  835. case ExprType::kCastExpr:
  836. return CastExprToString(expr.cast_expr());
  837. case ExprType::kCollateExpr:
  838. return CollateExprToString(expr.collate_expr());
  839. case ExprType::kExpr1:
  840. return Expr1ToString(expr.expr1());
  841. case ExprType::kExprNullTests:
  842. return ExprNullTestsToString(expr.expr_null_tests());
  843. case ExprType::kExprIs:
  844. return ExprIsToString(expr.expr_is());
  845. case ExprType::kExprBetween:
  846. return ExprBetweenToString(expr.expr_between());
  847. case ExprType::kExprIn:
  848. return ExprInToString(expr.expr_in());
  849. case ExprType::kExprExists:
  850. return ExprExistsToString(expr.expr_exists());
  851. case ExprType::kExprCase:
  852. return ExprCaseToString(expr.expr_case());
  853. case ExprType::kExprRaise:
  854. return ExprRaiseFnToString(expr.expr_raise());
  855. default:
  856. return "1";
  857. }
  858. }
  859. // TODO(mpdenton) wrap in parentheses???
  860. CONV_FN(Expr, expr) {
  861. if (expr.has_lit_val()) {
  862. return LiteralValueToString(expr.lit_val());
  863. } else if (expr.has_comp_expr()) {
  864. return ComplicatedExprToString(expr.comp_expr());
  865. } else { // default
  866. return "1";
  867. }
  868. }
  869. // ~~~~Other~~~~
  870. std::string ForeignKeyClauseNotMatchToString(
  871. const ForeignKeyClauseNotMatch& nm) {
  872. std::string ret("ON ");
  873. ret += EnumStrReplaceUnderscores(
  874. ForeignKeyClauseNotMatch_DeleteOrUpdate_Name(nm.del_or_update()));
  875. ret += " ";
  876. ret += EnumStrReplaceUnderscores(
  877. ForeignKeyClauseNotMatch_Action_Name(nm.action()));
  878. ret += " ";
  879. return ret;
  880. }
  881. CONV_FN(ForeignKeyClauseCore, fkc) {
  882. if (fkc.has_fkey_not_match())
  883. return ForeignKeyClauseNotMatchToString(fkc.fkey_not_match());
  884. return "MATCH PARTIAL"; // Sqlite does not actually parse MATCH clauses. This
  885. // is assumed to be MATCH SIMPLE.
  886. }
  887. CONV_FN(DeferStrategy, ds) {
  888. std::string ret;
  889. if (ds.not_()) {
  890. ret += "NOT ";
  891. }
  892. ret += "DEFERRABLE ";
  893. ret +=
  894. EnumStrReplaceUnderscores(DeferStrategy_DeferStratEnum_Name(ds.strat()));
  895. return ret;
  896. }
  897. CONV_FN(ForeignKeyClause, fkey_clause) {
  898. std::string ret("REFERENCES ");
  899. ret += TableToString(fkey_clause.foreign_table());
  900. if (fkey_clause.has_col_list()) {
  901. ret += "(";
  902. ret += ColumnListToString(fkey_clause.col_list());
  903. ret += ")";
  904. }
  905. ret += " ";
  906. for (int i = 0; i < fkey_clause.fkey_cores_size(); i++) {
  907. ret += ForeignKeyClauseCoreToString(fkey_clause.fkey_cores(i));
  908. ret += " ";
  909. }
  910. if (fkey_clause.has_defer_strat()) {
  911. ret += DeferStrategyToString(fkey_clause.defer_strat());
  912. ret += " ";
  913. }
  914. return ret;
  915. }
  916. CONV_FN(ConflictClause, conf) {
  917. if (!conf.has_on_conflict())
  918. return " ";
  919. std::string ret("ON CONFLICT ");
  920. ret += EnumStrReplaceUnderscores(
  921. ConflictClause_OnConflict_Name(conf.on_conflict()));
  922. ret += " ";
  923. return ret;
  924. }
  925. CONV_FN(ColConstraintOpt1, opt1) {
  926. std::string ret("PRIMARY KEY ");
  927. ret += AscDescToString(opt1.asc_desc());
  928. // space at the end already
  929. ret += ConflictClauseToString(opt1.conflict());
  930. if (opt1.autoincrement())
  931. ret += "AUTOINCREMENT ";
  932. return ret;
  933. }
  934. CONV_FN(ColConstraintOpt2, opt2) {
  935. std::string ret("DEFAULT ");
  936. if (opt2.has_expr()) {
  937. ret += "(";
  938. ret += ExprToString(opt2.expr());
  939. ret += ")";
  940. } else {
  941. ret += LiteralValueToString(opt2.lit_val());
  942. }
  943. ret += " ";
  944. return ret;
  945. }
  946. CONV_FN(ColumnConstraint, col_constr) {
  947. std::string ret;
  948. if (col_constr.has_constraint_name()) {
  949. ret += "CONSTRAINT ";
  950. ret += ColumnConstraintNameToString(col_constr.constraint_name());
  951. ret += " ";
  952. }
  953. using ColConstrType = ColumnConstraint::ColConstraintOneofCase;
  954. switch (col_constr.col_constraint_oneof_case()) {
  955. case ColConstrType::kOpt1:
  956. ret += ColConstraintOpt1ToString(col_constr.opt1());
  957. break;
  958. case ColConstrType::kNotNullConfClause:
  959. ret += "NOT NULL ";
  960. ret += ConflictClauseToString(col_constr.not_null_conf_clause());
  961. break;
  962. case ColConstrType::kUniqueConfClause:
  963. ret += "UNIQUE ";
  964. ret += ConflictClauseToString(col_constr.unique_conf_clause());
  965. break;
  966. case ColConstrType::kCheckExpr:
  967. ret += "CHECK(";
  968. ret += ExprToString(col_constr.check_expr());
  969. ret += ") ";
  970. break;
  971. case ColConstrType::kOpt2:
  972. ret += ColConstraintOpt2ToString(col_constr.opt2());
  973. break;
  974. case ColConstrType::kCollate:
  975. ret += "COLLATE ";
  976. ret += CollateTypeToString(col_constr.collate());
  977. ret += " ";
  978. break;
  979. case ColConstrType::kFkeyClause:
  980. ret += ForeignKeyClauseToString(col_constr.fkey_clause());
  981. break;
  982. default:
  983. ret += ColConstraintOpt2ToString(col_constr.opt2_fallback());
  984. }
  985. return ret;
  986. }
  987. CONV_FN(TypeName, type_name) {
  988. std::string ret;
  989. ret += EnumStrReplaceUnderscores(
  990. CastTypeName_CastTypeNameEnum_Name(type_name.ctn().type_enum()));
  991. if (type_name.has_sn()) {
  992. ret += "(";
  993. ret += std::to_string(type_name.sn());
  994. ret += ")";
  995. }
  996. ret += " ";
  997. return ret;
  998. }
  999. CONV_FN(ColumnDef, col_def) {
  1000. std::string ret;
  1001. ret += ColumnToString(col_def.col());
  1002. ret += " ";
  1003. if (col_def.has_type_name()) {
  1004. ret += TypeNameToString(col_def.type_name());
  1005. ret += " ";
  1006. }
  1007. for (int i = 0; i < col_def.col_constraints_size(); i++) {
  1008. ret += ColumnConstraintToString(col_def.col_constraints(i));
  1009. ret += " ";
  1010. }
  1011. return ret;
  1012. }
  1013. CONV_FN(TableConstraintOpt1, opt1) {
  1014. std::string ret;
  1015. ret += EnumStrReplaceUnderscores(
  1016. TableConstraintOpt1_ConstraintType_Name(opt1.constraint_type()));
  1017. ret += "(";
  1018. ret += IndexedColumnListToString(opt1.indexed_col_list());
  1019. ret += ") ";
  1020. ret += ConflictClauseToString(opt1.conf_clause());
  1021. return ret;
  1022. }
  1023. CONV_FN(TableConstraintOpt2, opt2) {
  1024. std::string ret("FOREIGN KEY (");
  1025. ret += ColumnListToString(opt2.cols());
  1026. ret += ") ";
  1027. ret += ForeignKeyClauseToString(opt2.fkey_clause());
  1028. return ret;
  1029. }
  1030. CONV_FN(TableConstraint, t_constr) {
  1031. std::string ret;
  1032. if (t_constr.has_name()) {
  1033. ret += "CONSTRAINT ";
  1034. ret += TableConstraintNameToString(t_constr.name());
  1035. ret += " ";
  1036. }
  1037. if (t_constr.has_opt1()) {
  1038. ret += TableConstraintOpt1ToString(t_constr.opt1());
  1039. } else if (t_constr.has_check_expr()) {
  1040. ret += "CHECK(";
  1041. ret += ExprToString(t_constr.check_expr()); // TODO(mpdenton)
  1042. ret += ") ";
  1043. } else if (t_constr.has_opt2()) {
  1044. ret += TableConstraintOpt2ToString(t_constr.opt2());
  1045. } else {
  1046. // default to no constraint
  1047. ret += "CHECK(1)";
  1048. }
  1049. ret += " ";
  1050. return ret;
  1051. }
  1052. CONV_FN(CreateTableOpt1, opt1) {
  1053. std::string ret("(");
  1054. ret += ColumnDefToString(opt1.col_def());
  1055. for (int i = 0; i < opt1.extra_col_defs_size(); i++) {
  1056. ret += ", ";
  1057. ret += ColumnDefToString(opt1.extra_col_defs(i));
  1058. }
  1059. for (int i = 0; i < opt1.table_constraints_size(); i++) {
  1060. ret += ", ";
  1061. ret += TableConstraintToString(opt1.table_constraints(i));
  1062. }
  1063. ret += ") ";
  1064. if (opt1.without_rowid())
  1065. ret += "WITHOUT ROWID ";
  1066. return ret;
  1067. }
  1068. CONV_FN(CreateTable, create_table) {
  1069. RETURN_IF_DISABLED_QUERY(CreateTable);
  1070. #if defined(FUZZ_FTS3)
  1071. return ""; // Don't create normal tables in FTS3 fuzzing mode.
  1072. #endif
  1073. std::string ret("CREATE ");
  1074. if (create_table.has_temp_modifier()) {
  1075. ret += EnumStrReplaceUnderscores(
  1076. TempModifier_Name(create_table.temp_modifier()))
  1077. .erase(0, std::string("TM_").length());
  1078. ret += " ";
  1079. }
  1080. ret += "TABLE ";
  1081. if (create_table.if_not_exists())
  1082. ret += "IF NOT EXISTS ";
  1083. ret += ExprSchemaTableToString(create_table.schema_table());
  1084. ret += " ";
  1085. // TODO(mpdenton) need spaces at the end here???
  1086. using TableCreationType = CreateTable::CreateTableOneofCase;
  1087. switch (create_table.create_table_oneof_case()) {
  1088. case TableCreationType::kOp1:
  1089. ret += CreateTableOpt1ToString(create_table.op1());
  1090. break;
  1091. case TableCreationType::kAsSelectStmt:
  1092. ret += SelectToString(create_table.as_select_stmt());
  1093. break;
  1094. default:
  1095. ret += CreateTableOpt1ToString(create_table.op());
  1096. break;
  1097. }
  1098. return ret; // TODO(mpdenton)
  1099. }
  1100. // ~~~~For INSERT and SELECT~~~~
  1101. CONV_FN(CommonTableExpr, cte) {
  1102. std::string ret;
  1103. ret += TableToString(cte.table());
  1104. if (cte.columns_size() > 0) {
  1105. ret += "(";
  1106. ret += ColumnToString(cte.columns(0));
  1107. for (int i = 1; i < cte.columns_size(); i++) {
  1108. ret += ", ";
  1109. ret += ColumnToString(cte.columns(i));
  1110. }
  1111. ret += ")";
  1112. }
  1113. ret += " AS (";
  1114. ret += SelectToString(cte.select());
  1115. ret += ") ";
  1116. return ret;
  1117. }
  1118. CONV_FN(WithStatement, ws) {
  1119. std::string ret("WITH ");
  1120. if (ws.recursive())
  1121. ret += "RECURSIVE ";
  1122. ret += CommonTableExprToString(ws.table_expr());
  1123. ret += " ";
  1124. for (int i = 0; i < ws.extra_table_exprs_size(); i++) {
  1125. ret += CommonTableExprToString(ws.extra_table_exprs(i));
  1126. ret += " ";
  1127. }
  1128. ret += " ";
  1129. return ret;
  1130. }
  1131. // ~~~~INSERT~~~~
  1132. // WARNING no space at end
  1133. CONV_FN(ColumnComparison, cc) {
  1134. std::string ret;
  1135. ret += ExprSchemaTableColumnToString(cc.col());
  1136. ret += BinaryOperatorToString(cc.op());
  1137. #if defined(FUZZ_FTS3)
  1138. if (cc.op() == BINOP_MATCH && cc.has_fmt()) {
  1139. ret += FTS3MatchFormatToString(cc.fmt());
  1140. return ret;
  1141. }
  1142. #endif
  1143. ret += ExprToString(cc.expr());
  1144. return ret;
  1145. }
  1146. // WARNING no space at end
  1147. CONV_FN(ExprComparisonHighProbability, echp) {
  1148. if (echp.has_cc()) {
  1149. return ColumnComparisonToString(echp.cc());
  1150. } else if (echp.has_expr()) {
  1151. return ExprToString(echp.expr());
  1152. } else {
  1153. return "Col0 = 1"; // default
  1154. }
  1155. }
  1156. CONV_FN(WhereStatement, ws) {
  1157. return "WHERE " + ExprComparisonHighProbabilityToString(ws.expr()) + " ";
  1158. }
  1159. #ifndef SQLITE_OMIT_UPSERT
  1160. CONV_FN(UpsertClausePart1, uc1) {
  1161. std::string ret;
  1162. ret += "(";
  1163. ret += IndexedColumnListToString(uc1.icol_list());
  1164. ret += ") ";
  1165. if (uc1.has_where_stmt()) {
  1166. ret += WhereStatementToString(uc1.where_stmt());
  1167. ret += " ";
  1168. }
  1169. return ret;
  1170. }
  1171. #endif
  1172. // WARNING no space at end
  1173. CONV_FN(ColEqualsExpr, cee) {
  1174. std::string ret;
  1175. if (cee.has_col()) {
  1176. ret += ColumnToString(cee.col());
  1177. } else if (cee.has_col_list()) {
  1178. ret += ColumnListToString(cee.col_list());
  1179. } else {
  1180. ret += "Col0"; // default
  1181. }
  1182. ret += " = ";
  1183. ret += ExprToString(cee.expr());
  1184. return ret;
  1185. }
  1186. CONV_FN(UpsertClausePart2, uc2) {
  1187. std::string ret("SET ");
  1188. ret += ColEqualsExprToString(uc2.cee());
  1189. for (int i = 0; i < uc2.extra_cees_size(); i++) {
  1190. ret += ", ";
  1191. ret += ColEqualsExprToString(uc2.extra_cees(i));
  1192. }
  1193. if (uc2.has_where_stmt()) {
  1194. ret += " ";
  1195. ret += WhereStatementToString(uc2.where_stmt());
  1196. }
  1197. ret += " ";
  1198. return ret;
  1199. }
  1200. CONV_FN(UpsertClause, uc) {
  1201. #ifndef SQLITE_OMIT_UPSERT
  1202. std::string ret("ON CONFLICT ");
  1203. if (uc.has_uclause_p1()) {
  1204. ret += UpsertClausePart1ToString(uc.uclause_p1());
  1205. }
  1206. ret += "DO ";
  1207. if (uc.has_uclause_p2()) {
  1208. ret += "UPDATE ";
  1209. ret += UpsertClausePart2ToString(uc.uclause_p2());
  1210. } else {
  1211. ret += "NOTHING ";
  1212. }
  1213. return ret;
  1214. #else
  1215. return ""; // fine to return empty string here
  1216. #endif
  1217. }
  1218. CONV_FN(ValuesStatement, values) {
  1219. std::string ret("VALUES (");
  1220. ret += ExprListToString(values.expr_list());
  1221. ret += ")";
  1222. for (int i = 0; i < values.extra_expr_lists_size(); i++) {
  1223. ret += ", (";
  1224. ret += ExprListToString(values.extra_expr_lists(i));
  1225. ret += ")";
  1226. }
  1227. ret += " ";
  1228. return ret;
  1229. }
  1230. CONV_FN(Insert, insert) {
  1231. RETURN_IF_DISABLED_QUERY(Insert);
  1232. std::string ret;
  1233. if (insert.has_with()) {
  1234. ret += WithStatementToString(insert.with());
  1235. ret += " ";
  1236. }
  1237. ret +=
  1238. EnumStrReplaceUnderscores(Insert_InsertType_Name(insert.insert_type()));
  1239. ret += " INTO ";
  1240. ret += SchemaTableAsAliasToString(insert.staa());
  1241. if (insert.has_col_list()) {
  1242. ret += "(";
  1243. ret += ColumnListToString(insert.col_list());
  1244. ret += ") ";
  1245. }
  1246. // oneof
  1247. if (insert.has_values()) {
  1248. ret += ValuesStatementToString(insert.values());
  1249. ret += " ";
  1250. } else if (insert.has_select()) {
  1251. ret += SelectToString(insert.select());
  1252. ret += " ";
  1253. } else {
  1254. ret += "DEFAULT VALUES ";
  1255. }
  1256. if (insert.has_upsert_clause()) {
  1257. ret += UpsertClauseToString(insert.upsert_clause());
  1258. ret += " ";
  1259. }
  1260. return ret;
  1261. }
  1262. // ~~~~DELETE~~~~
  1263. CONV_FN(QualifiedTableName, qtn) {
  1264. std::string ret;
  1265. ret += SchemaTableAsAliasToString(qtn.staa());
  1266. ret += " ";
  1267. if (qtn.indexed()) {
  1268. if (qtn.not_indexed()) {
  1269. ret += "NOT INDEXED ";
  1270. } else {
  1271. ret += "INDEXED BY ";
  1272. ret += IndexToString(qtn.indexed_by());
  1273. ret += " ";
  1274. }
  1275. }
  1276. return ret;
  1277. }
  1278. CONV_FN(Delete, delete_) {
  1279. RETURN_IF_DISABLED_QUERY(Delete);
  1280. std::string ret;
  1281. if (delete_.has_with()) {
  1282. ret += WithStatementToString(delete_.with());
  1283. ret += " ";
  1284. }
  1285. ret += "DELETE FROM ";
  1286. ret += QualifiedTableNameToString(delete_.qtn());
  1287. if (delete_.has_where()) {
  1288. ret += WhereStatementToString(delete_.where());
  1289. }
  1290. ret += " ";
  1291. return ret;
  1292. }
  1293. // ~~~~UPDATE~~~~
  1294. // WARNING no space at end
  1295. CONV_FN(Update, update) {
  1296. RETURN_IF_DISABLED_QUERY(Update);
  1297. std::string ret;
  1298. if (update.has_with()) {
  1299. ret += WithStatementToString(update.with());
  1300. ret += " ";
  1301. }
  1302. ret += "UPDATE ";
  1303. if (update.has_update_type()) {
  1304. ret +=
  1305. EnumStrReplaceUnderscores(Update_UpdateType_Name(update.update_type()));
  1306. ret += " ";
  1307. }
  1308. ret += QualifiedTableNameToString(update.qtn());
  1309. ret += " ";
  1310. ret += UpsertClausePart2ToString(update.ucp2());
  1311. return ret;
  1312. }
  1313. // TODO(mpdenton) restrictions on UPDATEs in CREATE TRIGGER????
  1314. // ~~~~SELECT~~~~
  1315. CONV_FN(ExprColAlias, eca) {
  1316. std::string ret;
  1317. ret += ExprToString(eca.expr());
  1318. ret += " ";
  1319. if (eca.has_col_alias()) {
  1320. if (eca.as()) {
  1321. ret += "AS ";
  1322. }
  1323. ret += ColumnToString(eca.col_alias());
  1324. ret += " ";
  1325. }
  1326. return ret;
  1327. }
  1328. // WARNING no space at end
  1329. CONV_FN(ResultColumn, rc) {
  1330. std::string ret;
  1331. // oneof
  1332. if (rc.has_col()) {
  1333. return ColumnToString(rc.col());
  1334. } else if (rc.has_eca()) {
  1335. return ExprColAliasToString(rc.eca());
  1336. } else if (rc.has_table_star()) {
  1337. return TableToString(rc.table_star()) + ".*";
  1338. } else if (rc.has_fts3_fn()) {
  1339. #if defined(FUZZ_FTS3)
  1340. return FTS3AuxiliaryFnToString(rc.fts3_fn());
  1341. #else
  1342. return "*";
  1343. #endif
  1344. } else {
  1345. return "*";
  1346. }
  1347. }
  1348. CONV_FN(AsTableAlias, ata) {
  1349. std::string ret;
  1350. if (ata.as()) {
  1351. ret += "AS ";
  1352. }
  1353. ret += TableToString(ata.table_alias());
  1354. ret += " ";
  1355. return ret;
  1356. }
  1357. // WARNING no space at end
  1358. CONV_FN(JoinOperator, jo) {
  1359. if (jo.comma())
  1360. return ",";
  1361. std::string ret;
  1362. if (jo.natural())
  1363. ret += "NATURAL ";
  1364. if (jo.join_type() != JoinOperator::NONE) {
  1365. ret +=
  1366. EnumStrReplaceUnderscores(JoinOperator_JoinType_Name(jo.join_type()));
  1367. ret += " ";
  1368. }
  1369. ret += "JOIN ";
  1370. return ret;
  1371. }
  1372. CONV_FN(JoinConstraint, jc) {
  1373. // oneof
  1374. if (jc.has_on_expr()) {
  1375. return "ON " + ExprToString(jc.on_expr()) + " ";
  1376. } else if (jc.has_using_expr()) {
  1377. std::string ret("(");
  1378. ret += ColumnListToString(jc.using_expr().col_list());
  1379. ret += ") ";
  1380. return ret;
  1381. }
  1382. return " ";
  1383. }
  1384. CONV_FN(JoinClauseCore, jcc) {
  1385. std::string ret;
  1386. ret += JoinOperatorToString(jcc.join_op());
  1387. ret += " ";
  1388. ret += TableOrSubqueryToString(jcc.tos());
  1389. ret += " ";
  1390. ret += JoinConstraintToString(jcc.join_constraint());
  1391. ret += " ";
  1392. return ret;
  1393. }
  1394. CONV_FN(JoinClause, jc) {
  1395. std::string ret;
  1396. ret += TableOrSubqueryToString(jc.tos());
  1397. ret += " ";
  1398. for (int i = 0; i < jc.clauses_size(); i++) {
  1399. ret += JoinClauseCoreToString(jc.clauses(i));
  1400. }
  1401. ret += " ";
  1402. return ret;
  1403. }
  1404. // TODO(mpdenton) ExprIn needs it schematablefn!!!!!
  1405. CONV_FN(ExprSchemaTableFn, estf) {
  1406. std::string ret;
  1407. const TableFn& tfn = estf.table_fn();
  1408. // oneof for pragma fns
  1409. if (tfn.has_foreign_key_list()) {
  1410. ret += "pragma_foreign_key_list(\'";
  1411. ret += TableToString(tfn.foreign_key_list());
  1412. ret += "\') ";
  1413. } else if (tfn.has_index_info()) {
  1414. ret += "pragma_index_info(\'";
  1415. ret += IndexToString(tfn.index_info());
  1416. ret += "\') ";
  1417. } else if (tfn.has_index_list()) {
  1418. ret += "pragma_index_list(\'";
  1419. ret += TableToString(tfn.index_list());
  1420. ret += "\') ";
  1421. } else if (tfn.has_index_xinfo()) {
  1422. ret += "pragma_index_xinfo(\'";
  1423. ret += IndexToString(tfn.index_xinfo());
  1424. ret += "\') ";
  1425. } else if (tfn.has_integrity_check()) {
  1426. ret += "pragma_integrity_check(\'";
  1427. ret += std::to_string(tfn.integrity_check());
  1428. ret += "\') ";
  1429. } else if (tfn.has_optimize()) {
  1430. ret += "pragma_optimize(\'";
  1431. ret += std::to_string(tfn.optimize());
  1432. ret += "\') ";
  1433. } else if (tfn.has_quick_check()) {
  1434. ret += "pragma_quick_check(\'";
  1435. ret += std::to_string(tfn.quick_check());
  1436. ret += "\') ";
  1437. } else if (tfn.has_table_info()) {
  1438. ret += "pragma_table_info(\'";
  1439. ret += TableToString(tfn.table_info());
  1440. ret += "\') ";
  1441. } else if (tfn.has_table_xinfo()) {
  1442. ret += "pragma_table_xinfo(\'";
  1443. ret += TableToString(tfn.table_xinfo());
  1444. ret += "\') ";
  1445. } else {
  1446. ret += StrToLower(PragmaFnZeroArgOneResult_Name(tfn.no_arg_one_result()))
  1447. .erase(0, std::string("PFN_ZO_").length());
  1448. ret += "() ";
  1449. }
  1450. return ret;
  1451. }
  1452. CONV_FN(TableOrSubqueryOption2, toso2) {
  1453. std::string ret;
  1454. ret += ExprSchemaTableFnToString(toso2.schema_table_fn());
  1455. ret += " ";
  1456. if (toso2.has_as_table_alias()) {
  1457. ret += AsTableAliasToString(toso2.as_table_alias());
  1458. }
  1459. return ret;
  1460. }
  1461. CONV_FN(TableOrSubqueryOption3, tos3) {
  1462. std::string ret;
  1463. if (tos3.tos_list_size() > 0) {
  1464. ret += TableOrSubqueryToString(tos3.tos_list(0));
  1465. for (int i = 1; i < tos3.tos_list_size(); i++) {
  1466. ret += ", ";
  1467. ret += TableOrSubqueryToString(tos3.tos_list(i));
  1468. }
  1469. } else {
  1470. ret += JoinClauseToString(tos3.join_clause());
  1471. }
  1472. return ret;
  1473. }
  1474. CONV_FN(TableOrSubqueryOption4, tos4) {
  1475. std::string ret("(");
  1476. ret += SelectToString(tos4.select());
  1477. ret += ") ";
  1478. if (tos4.has_as_table_alias()) {
  1479. ret += AsTableAliasToString(tos4.as_table_alias());
  1480. ret += " ";
  1481. }
  1482. return ret;
  1483. }
  1484. CONV_FN(TableOrSubquery, tos) {
  1485. // oneof
  1486. if (tos.has_qtn()) {
  1487. return QualifiedTableNameToString(tos.qtn()) + " ";
  1488. } else if (tos.has_toso2()) {
  1489. return TableOrSubqueryOption2ToString(tos.toso2()) + " ";
  1490. } else if (tos.has_toso3()) {
  1491. return "(" + TableOrSubqueryOption3ToString(tos.toso3()) + ") ";
  1492. } else if (tos.has_toso4()) {
  1493. return TableOrSubqueryOption4ToString(tos.toso4()) + " ";
  1494. } else {
  1495. return ExprSchemaTableToString(tos.schema_table_expr()) + " ";
  1496. }
  1497. }
  1498. CONV_FN(FromStatement, fs) {
  1499. return "FROM " + TableOrSubqueryOption3ToString(fs.tos3());
  1500. }
  1501. CONV_FN(GroupByStatement, gbs) {
  1502. std::string ret("GROUP BY ");
  1503. ret += ExprListToString(gbs.exprs());
  1504. ret += " ";
  1505. if (gbs.has_having_expr()) {
  1506. ret += "HAVING ";
  1507. ret += ExprToString(gbs.having_expr());
  1508. ret += " ";
  1509. }
  1510. return ret;
  1511. }
  1512. CONV_FN(WindowStatement, ws) {
  1513. #if !defined(SQLITE_OMIT_WINDOWFUNC)
  1514. return "";
  1515. #else
  1516. return "";
  1517. #endif
  1518. }
  1519. CONV_FN(SelectStatementCore, ssc) {
  1520. std::string ret;
  1521. ret += EnumStrReplaceUnderscores(
  1522. SelectStatementCore_SelectOrDistinct_Name(ssc.s_or_d()));
  1523. ret += " ";
  1524. if (ssc.result_columns_size() == 0) {
  1525. ret += "* ";
  1526. } else {
  1527. ret += ResultColumnToString(ssc.result_columns(0));
  1528. for (int i = 1; i < ssc.result_columns_size(); i++) {
  1529. ret += ", ";
  1530. ret += ResultColumnToString(ssc.result_columns(i));
  1531. }
  1532. ret += " ";
  1533. }
  1534. if (ssc.has_from()) {
  1535. ret += FromStatementToString(ssc.from());
  1536. ret += " ";
  1537. }
  1538. if (ssc.has_where()) {
  1539. ret += WhereStatementToString(ssc.where());
  1540. ret += " ";
  1541. }
  1542. if (ssc.has_groupby()) {
  1543. ret += GroupByStatementToString(ssc.groupby());
  1544. ret += " ";
  1545. }
  1546. if (ssc.has_window()) {
  1547. ret += WindowStatementToString(ssc.window());
  1548. ret += " ";
  1549. }
  1550. return ret;
  1551. }
  1552. CONV_FN(SelectSubStatement, sss) {
  1553. // oneof
  1554. if (sss.has_select_core()) {
  1555. return SelectStatementCoreToString(sss.select_core());
  1556. } else if (sss.has_values()) {
  1557. return ValuesStatementToString(sss.values());
  1558. } else {
  1559. return ValuesStatementToString(sss.values_fallback());
  1560. }
  1561. }
  1562. CONV_FN(ExprOrderingTerm, eot) {
  1563. std::string ret = ExprToString(eot.expr());
  1564. ret += " ";
  1565. if (eot.has_collate_type()) {
  1566. ret += "COLLATE ";
  1567. ret += CollateTypeToString(eot.collate_type());
  1568. ret += " ";
  1569. }
  1570. ret += AscDescToString(eot.asc_desc());
  1571. return ret;
  1572. }
  1573. CONV_FN(OrderByStatement, obs) {
  1574. std::string ret("ORDER BY ");
  1575. ret += ExprOrderingTermToString(obs.ord_term());
  1576. for (int i = 0; i < obs.extra_ord_terms_size(); i++) {
  1577. ret += ", ";
  1578. ret += ExprOrderingTermToString(obs.extra_ord_terms(i));
  1579. }
  1580. ret += " ";
  1581. return ret;
  1582. }
  1583. CONV_FN(LimitStatement, ls) {
  1584. std::string ret("LIMIT ");
  1585. ret += ExprToString(ls.limit_expr());
  1586. ret += " ";
  1587. if (ls.has_second_expr()) {
  1588. if (ls.offset()) {
  1589. ret += "OFFSET ";
  1590. } else {
  1591. ret += ", ";
  1592. }
  1593. ret += ExprToString(ls.second_expr());
  1594. ret += " ";
  1595. }
  1596. return ret;
  1597. }
  1598. CONV_FN(ExtraSelectSubStatement, esss) {
  1599. std::string ret, enum1;
  1600. enum1 = CompoundOperator_Name(esss.compound_op());
  1601. // erase prefix
  1602. enum1.erase(0, std::string("CO_").length());
  1603. ret += EnumStrReplaceUnderscores(enum1);
  1604. ret += " ";
  1605. ret += SelectSubStatementToString(esss.select_substatement());
  1606. return ret;
  1607. }
  1608. CONV_FN(Select, select) {
  1609. RETURN_IF_DISABLED_QUERY(Select);
  1610. std::string ret;
  1611. if (select.has_with()) {
  1612. ret += WithStatementToString(select.with());
  1613. ret += " ";
  1614. }
  1615. ret += SelectStatementCoreToString(select.select_core());
  1616. for (int i = 0; i < select.extra_select_substatements_size(); i++) {
  1617. ret +=
  1618. ExtraSelectSubStatementToString(select.extra_select_substatements(i));
  1619. ret += " ";
  1620. }
  1621. if (select.has_orderby()) {
  1622. ret += OrderByStatementToString(select.orderby());
  1623. ret += " ";
  1624. }
  1625. if (select.has_limit()) {
  1626. ret += LimitStatementToString(select.limit());
  1627. }
  1628. return ret;
  1629. }
  1630. // ~~~~FTS3~~~~
  1631. // CORPUS currently relying on normal SELECTs to generate good compound
  1632. // queries for FTS, like AND, OR, and NOT. Generate a corpus entry with a lot of
  1633. // creative FTS queries.
  1634. CONV_FN(FTS3Table, ft) {
  1635. // std::string ret("FTS3Table");
  1636. std::string ret(
  1637. "Table"); // for now, use the same naming scheme as normal tables.
  1638. ret += std::to_string(ft.table() % kMaxFTS3TableNumber);
  1639. return ret;
  1640. }
  1641. CONV_FN(FTS3MatchToken, fmt) {
  1642. std::string ret;
  1643. if (fmt.has_col()) {
  1644. ret += ColumnToString(fmt.col());
  1645. ret += ":";
  1646. }
  1647. if (fmt.negate()) {
  1648. ret += "-";
  1649. }
  1650. if (fmt.token().length() == 0)
  1651. ret += "a";
  1652. else
  1653. ret += ConvertToSqlString(
  1654. fmt.token()); // TODO(mpdenton) good enough? Need something better????
  1655. if (fmt.prefix())
  1656. ret += "*";
  1657. return ret;
  1658. }
  1659. CONV_FN(FTS3PhraseQuery, fpq) {
  1660. std::string ret("\"");
  1661. ret += FTS3MatchTokenToString(fpq.mt());
  1662. for (int i = 0; i < fpq.extra_mts_size(); i++) {
  1663. ret += " ";
  1664. ret += FTS3MatchTokenToString(fpq.extra_mts(i));
  1665. }
  1666. ret += "\"";
  1667. return ret;
  1668. }
  1669. CONV_FN(FTS3MatchFormatCore, fmfc) {
  1670. // oneof
  1671. if (fmfc.has_pq()) {
  1672. return FTS3PhraseQueryToString(fmfc.pq());
  1673. } else if (fmfc.has_nq()) {
  1674. return FTS3NearQueryToString(fmfc.nq());
  1675. } else {
  1676. return FTS3MatchTokenToString(fmfc.mt_fallback());
  1677. }
  1678. }
  1679. CONV_FN(FTS3NearQuery, fnq) {
  1680. std::string ret = FTS3MatchFormatCoreToString(fnq.format_core1());
  1681. ret += " NEAR";
  1682. if (fnq.has_num_tokens_near()) {
  1683. ret += "/";
  1684. ret += std::to_string(fnq.num_tokens_near());
  1685. }
  1686. ret += " ";
  1687. ret += FTS3MatchFormatCoreToString(fnq.format_core2());
  1688. return ret;
  1689. }
  1690. CONV_FN(FTS3CompoundAndCore, fcac) {
  1691. std::string ret(" ");
  1692. ret += FTS3CompoundAndCore_CompoundOp_Name(fcac.op());
  1693. ret += " ";
  1694. ret += FTS3MatchFormatCoreToString(fcac.core());
  1695. return ret;
  1696. }
  1697. CONV_FN(FTS3MatchCompoundFormat, fmcf) {
  1698. std::string ret = FTS3MatchFormatCoreToString(fmcf.core());
  1699. for (int i = 0; i < fmcf.compound_and_cores_size(); i++) {
  1700. ret += FTS3CompoundAndCoreToString(fmcf.compound_and_cores(i));
  1701. }
  1702. return ret;
  1703. }
  1704. CONV_FN(FTS3MatchFormat, fmf) {
  1705. std::string ret("\'");
  1706. if (fmf.ft_size() > 0) {
  1707. ret += FTS3MatchCompoundFormatToString(fmf.ft(0));
  1708. }
  1709. for (int i = 1; i < fmf.ft_size(); i++) {
  1710. ret += " ";
  1711. ret += FTS3MatchCompoundFormatToString(fmf.ft(i));
  1712. }
  1713. ret += "\'";
  1714. return ret;
  1715. }
  1716. CONV_FN(FTS3SpecialCommand, fsc) {
  1717. RETURN_IF_DISABLED_QUERY(FTS3SpecialCommand);
  1718. std::string ret("INSERT INTO ");
  1719. ret += FTS3TableToString(fsc.table());
  1720. ret += "(";
  1721. ret += FTS3TableToString(fsc.table());
  1722. ret += ") VALUES(\'";
  1723. switch (fsc.command()) {
  1724. case FTS3SpecialCommand::OPTIMIZE:
  1725. ret += "optimize";
  1726. break;
  1727. case FTS3SpecialCommand::REBUILD:
  1728. ret += "rebuild";
  1729. break;
  1730. case FTS3SpecialCommand::INTEGRITY_CHECK:
  1731. ret += "integrity-check";
  1732. break;
  1733. case FTS3SpecialCommand::MERGE:
  1734. ret += "merge=";
  1735. ret += std::to_string(fsc.val1());
  1736. ret += ",";
  1737. ret += std::to_string(fsc.val2());
  1738. break;
  1739. case FTS3SpecialCommand::AUTOMERGE:
  1740. ret += "automerge=";
  1741. ret += std::to_string(fsc.val1() % 16);
  1742. break;
  1743. }
  1744. ret += "\')";
  1745. return ret;
  1746. }
  1747. // WARNING no space at end
  1748. CONV_FN(FTS3SelectMatch, fsm) {
  1749. RETURN_IF_DISABLED_QUERY(FTS3SelectMatch);
  1750. std::string ret("SELECT * FROM ");
  1751. ret += FTS3TableToString(fsm.table());
  1752. ret += " WHERE ";
  1753. ret += ColumnToString(fsm.col());
  1754. ret += " MATCH ";
  1755. ret += FTS3MatchFormatToString(fsm.match_pattern());
  1756. return ret;
  1757. }
  1758. CONV_FN(FTS3SpecificQuery, fsq) {
  1759. RETURN_IF_DISABLED_QUERY(FTS3SpecificQuery);
  1760. #if defined(FUZZ_FTS3)
  1761. // oneof
  1762. if (fsq.has_command()) {
  1763. return FTS3SpecialCommandToString(fsq.command());
  1764. } else if (fsq.has_select()) {
  1765. return FTS3SelectMatchToString(fsq.select());
  1766. } else {
  1767. return "";
  1768. }
  1769. #else
  1770. return "";
  1771. #endif
  1772. }
  1773. CONV_FN(ICULocale, il) {
  1774. std::string ret;
  1775. std::string lc = IsoLangCode_Name(il.iso_lang_code());
  1776. lc.erase(0, std::string("ISO_LANG_CODE_").length());
  1777. ret += lc;
  1778. ret += "_";
  1779. // extract country code from integer
  1780. ret += (char)((il.country_code() & 0xFF) % 26) + 'A';
  1781. ret += (char)(((il.country_code() & 0xFF00) >> 8) % 26) + 'A';
  1782. return ret;
  1783. }
  1784. CONV_FN(CreateFTS3Table, cft) {
  1785. RETURN_IF_DISABLED_QUERY(CreateFTS3Table);
  1786. std::string ret("CREATE VIRTUAL TABLE ");
  1787. if (cft.if_not_exists())
  1788. ret += "IF NOT EXISTS ";
  1789. if (cft.has_schema()) {
  1790. ret += SchemaToString(cft.schema());
  1791. ret += ".";
  1792. }
  1793. ret += FTS3TableToString(cft.table());
  1794. ret += " USING fts3(";
  1795. // TODO(mpdenton) not using schema here, should I???
  1796. if (cft.has_col_list()) {
  1797. ret += ColumnListToString(cft.col_list());
  1798. if (cft.has_tokenizer_type())
  1799. ret += ", ";
  1800. }
  1801. if (cft.has_tokenizer_type()) {
  1802. ret += "tokenize=";
  1803. std::string tt = TokenizerType_Name(cft.tokenizer_type());
  1804. tt.erase(0, std::string("TT_").length());
  1805. tt = StrToLower(tt);
  1806. #if defined(SQLITE_DISABLE_FTS3_UNICODE)
  1807. if (tt == "unicode61")
  1808. tt = "porter";
  1809. #endif
  1810. ret += tt;
  1811. // now generate locales for ICU
  1812. if (cft.tokenizer_type() == TokenizerType::TT_ICU) {
  1813. ret += " ";
  1814. ret += ICULocaleToString(cft.locale());
  1815. } else if (cft.tokenizer_type() == TokenizerType::TT_UNICODE61) {
  1816. // Chrome does not actually enable this option. FIXME in the future.
  1817. }
  1818. }
  1819. ret += ")";
  1820. return ret;
  1821. }
  1822. // WARNING no space at end
  1823. CONV_FN(FTS3OffsetsFn, fof) {
  1824. return "offsets(" + FTS3TableToString(fof.table()) + ")";
  1825. }
  1826. // WARNING no space at end
  1827. CONV_FN(FTS3SnippetsFn, fsf) {
  1828. std::string ret("snippets(");
  1829. ret += FTS3TableToString(fsf.table());
  1830. // Now (possibly) emit the five optional arguments.
  1831. int num_args = (int)fsf.num_optional_args();
  1832. if (num_args >= 1) {
  1833. ret += ", \'";
  1834. ret += ConvertToSqlString(fsf.start_match());
  1835. ret += "\'";
  1836. }
  1837. if (num_args >= 2) {
  1838. ret += ", \'";
  1839. ret += ConvertToSqlString(fsf.end_match());
  1840. ret += "\'";
  1841. }
  1842. if (num_args >= 3) {
  1843. ret += ", \'";
  1844. ret += ConvertToSqlString(fsf.ellipses());
  1845. ret += "\'";
  1846. }
  1847. if (num_args >= 4) {
  1848. ret += ", ";
  1849. if (fsf.has_col_number()) {
  1850. ret += std::to_string(fsf.col_number() % kMaxColumnNumber);
  1851. } else {
  1852. ret += "-1";
  1853. }
  1854. }
  1855. if (num_args >= 5) {
  1856. ret += ", ";
  1857. ret +=
  1858. std::to_string((fsf.num_tokens() % 129) - 64); // clamp into [-64, 64]
  1859. }
  1860. ret += ")";
  1861. return ret;
  1862. }
  1863. // WARNING no space at end
  1864. CONV_FN(FTS3MatchInfoFn, fmi) {
  1865. constexpr static char matchinfo_chars[] = {
  1866. 'p', 'c', 's', 'x', 'y', 'b',
  1867. // 'n', 'a', 'l', // These characters only available for FTS4.
  1868. };
  1869. std::string ret("matchinfo(");
  1870. ret += FTS3TableToString(fmi.table());
  1871. if (fmi.chars_size() > 0) {
  1872. ret += ", \'";
  1873. for (int i = 0; i < fmi.chars_size(); i++) {
  1874. ret += matchinfo_chars[fmi.chars(i) % sizeof(matchinfo_chars)];
  1875. }
  1876. ret += "\'";
  1877. }
  1878. ret += ")";
  1879. return ret;
  1880. }
  1881. // WARNING no space at end
  1882. CONV_FN(FTS3AuxiliaryFn, faf) {
  1883. if (faf.has_snippets()) {
  1884. return FTS3SnippetsFnToString(faf.snippets());
  1885. } else if (faf.has_matchinfo()) {
  1886. return FTS3MatchInfoFnToString(faf.matchinfo());
  1887. } else {
  1888. return FTS3OffsetsFnToString(faf.offsets_fallback());
  1889. }
  1890. }
  1891. CONV_FN(FTS3HiddenTable, fht) {
  1892. std::string tab = FTS3HiddenTable_HiddenTableVal_Name(fht.htv());
  1893. tab = StrToLower(tab);
  1894. return FTS3TableToString(fht.table()) + "_" + tab;
  1895. }
  1896. CONV_FN(FTS3HiddenTableColumn, fhtc) {
  1897. std::string tab = FTS3HiddenTableColumn_Name(fhtc);
  1898. tab = tab.erase(0, std::string("FTS3_HT_").length());
  1899. tab = StrToLower(tab);
  1900. return tab;
  1901. }
  1902. CONV_FN(FTS3HiddenTableInsert, fi) {
  1903. RETURN_IF_DISABLED_QUERY(FTS3HiddenTableInsert);
  1904. std::string ret("INSERT INTO ");
  1905. ret += FTS3HiddenTableToString(fi.fht());
  1906. if (fi.col_vals_size() == 0) {
  1907. ret += " DEFAULT VALUES";
  1908. return ret;
  1909. }
  1910. ret += "(";
  1911. ret += FTS3HiddenTableColumnToString(fi.col_vals(0).col());
  1912. for (int i = 1; i < fi.col_vals_size(); i++) {
  1913. ret += ", ";
  1914. ret += FTS3HiddenTableColumnToString(fi.col_vals(i).col());
  1915. }
  1916. ret += ") VALUES(";
  1917. ret += ExprToString(fi.col_vals(0).expr());
  1918. for (int i = 0; i < fi.col_vals_size(); i++) {
  1919. ret += ", ";
  1920. ret += ExprToString(fi.col_vals(i).expr());
  1921. }
  1922. ret += ")";
  1923. return ret;
  1924. }
  1925. CONV_FN(FTS3HiddenTableUpdate, fu) {
  1926. RETURN_IF_DISABLED_QUERY(FTS3HiddenTableUpdate);
  1927. std::string ret("UPDATE ");
  1928. ret += FTS3HiddenTableToString(fu.fht());
  1929. ret += " ";
  1930. if (fu.col_vals_size() == 0) {
  1931. ret += "start_block = 0";
  1932. return ret;
  1933. }
  1934. ret += "SET ";
  1935. ret += FTS3HiddenTableColumnToString(fu.col_vals(0).col());
  1936. ret += " = ";
  1937. ret += ExprToString(fu.col_vals(0).expr());
  1938. for (int i = 1; i < fu.col_vals_size(); i++) {
  1939. ret += ", ";
  1940. ret += FTS3HiddenTableColumnToString(fu.col_vals(i).col());
  1941. ret += " = ";
  1942. ret += ExprToString(fu.col_vals(i).expr());
  1943. }
  1944. if (fu.has_col_where()) {
  1945. ret += " WHERE ";
  1946. ret += FTS3HiddenTableColumnToString(fu.col_where());
  1947. ret += BinaryOperatorToString(fu.bin_op());
  1948. ret += ExprToString(fu.comp_expr());
  1949. }
  1950. return ret;
  1951. }
  1952. CONV_FN(FTS3HiddenTableDelete, fd) {
  1953. RETURN_IF_DISABLED_QUERY(FTS3HiddenTableDelete);
  1954. std::string ret("DELETE FROM ");
  1955. ret += FTS3HiddenTableToString(fd.fht());
  1956. if (fd.has_col_where()) {
  1957. ret += " WHERE ";
  1958. ret += FTS3HiddenTableColumnToString(fd.col_where());
  1959. ret += BinaryOperatorToString(fd.bin_op());
  1960. ret += ExprToString(fd.comp_expr());
  1961. }
  1962. return ret;
  1963. }
  1964. // ~~~~TRANSACTIONS/SAVEPOINTS
  1965. CONV_FN(BeginTransaction, bt) {
  1966. RETURN_IF_DISABLED_QUERY(BeginTransaction);
  1967. std::string ret("BEGIN ");
  1968. if (bt.has_type()) {
  1969. ret += BeginTransaction_TransactionType_Name(bt.type());
  1970. ret += " ";
  1971. }
  1972. ret += "TRANSACTION";
  1973. return ret;
  1974. }
  1975. CONV_FN(CommitTransaction, ct) {
  1976. RETURN_IF_DISABLED_QUERY(CommitTransaction);
  1977. return EnumStrReplaceUnderscores(
  1978. CommitTransaction_CommitText_Name(ct.text()));
  1979. }
  1980. CONV_FN(RollbackStatement, rt) {
  1981. RETURN_IF_DISABLED_QUERY(RollbackStatement);
  1982. #if !defined(FUZZ_OMIT_SAVEPOINT)
  1983. if (rt.has_save_point()) {
  1984. return "ROLLBACK TO SAVEPOINT " + SavePointToString(rt.save_point());
  1985. }
  1986. #endif
  1987. return "ROLLBACK TRANSACTION";
  1988. }
  1989. #if !defined(FUZZ_OMIT_SAVEPOINT)
  1990. CONV_FN(CreateSavePoint, csp) {
  1991. RETURN_IF_DISABLED_QUERY(CreateSavePoint);
  1992. return "SAVEPOINT " + SavePointToString(csp.save_point());
  1993. }
  1994. CONV_FN(ReleaseSavePoint, rsp) {
  1995. RETURN_IF_DISABLED_QUERY(ReleaseSavePoint);
  1996. return "RELEASE SAVEPOINT " + SavePointToString(rsp.save_point());
  1997. }
  1998. #endif
  1999. CONV_FN(Analyze, a) {
  2000. RETURN_IF_DISABLED_QUERY(Analyze);
  2001. std::string ret("ANALYZE");
  2002. if (a.has_schema_name()) {
  2003. ret += " ";
  2004. ret += SchemaToString(a.schema_name());
  2005. if (a.has_table_name()) {
  2006. ret += ".";
  2007. ret += TableToString(a.table_name());
  2008. } else if (a.has_index_name()) {
  2009. ret += ".";
  2010. ret += IndexToString(a.index_name());
  2011. }
  2012. } else if (a.has_table_name()) {
  2013. ret += " ";
  2014. ret += TableToString(a.table_name());
  2015. } else if (a.has_index_name()) {
  2016. ret += " ";
  2017. ret += IndexToString(a.index_name());
  2018. }
  2019. return ret;
  2020. }
  2021. // ~~~~VACUUM~~~~
  2022. CONV_FN(Vacuum, v) {
  2023. RETURN_IF_DISABLED_QUERY(Vacuum);
  2024. std::string ret("VACUUM");
  2025. if (v.has_schema()) {
  2026. ret += " ";
  2027. ret += SchemaToString(v.schema());
  2028. }
  2029. return ret;
  2030. }
  2031. // ~~~~PRAGMA~~~~
  2032. CONV_FN(Pragma, p) {
  2033. RETURN_IF_DISABLED_QUERY(Pragma);
  2034. #if defined(FUZZ_OMIT_PRAGMA)
  2035. return "";
  2036. #else
  2037. constexpr static const char* locking_modes[] = {"NORMAL", "EXCLUSIVE"};
  2038. constexpr static const char* journal_modes[] = {
  2039. "DELETE", "TRUNCATE", "PERSIST", "MEMORY", "WAL", "OFF"};
  2040. Table table;
  2041. std::string ret("PRAGMA ");
  2042. if (p.has_schema()) {
  2043. ret += SchemaToString(p.schema());
  2044. ret += ".";
  2045. }
  2046. ret += StripTrailingUnderscores(
  2047. StrToLower(Pragma_PragmaCommand_Name(p.command())));
  2048. switch (p.command()) {
  2049. case Pragma::AUTO_VACUUM:
  2050. ret += " = ";
  2051. ret += std::to_string((uint32_t)p.arg1() % 3);
  2052. break;
  2053. case Pragma::WRITEABLE_SCHEMA:
  2054. ret += " = ";
  2055. ret += std::to_string((uint32_t)p.arg1() % 2);
  2056. break;
  2057. case Pragma::LOCKING_MODE:
  2058. ret += " = ";
  2059. ret += locking_modes[(uint32_t)p.arg1() % 2];
  2060. break;
  2061. case Pragma::TEMP_STORE:
  2062. ret += " = ";
  2063. ret += std::to_string((uint32_t)p.arg1() % 3);
  2064. break;
  2065. case Pragma::PAGE_SIZE_:
  2066. ret += " = ";
  2067. ret += std::to_string(p.arg1());
  2068. break;
  2069. case Pragma::TABLE_INFO:
  2070. ret += "(\'";
  2071. table.set_table((uint32_t)p.arg1());
  2072. ret += TableToString(table);
  2073. ret += "\')";
  2074. break;
  2075. case Pragma::JOURNAL_MODE:
  2076. ret += " = ";
  2077. ret += journal_modes[(uint32_t)p.arg1() % 6];
  2078. break;
  2079. case Pragma::MMAP_SIZE:
  2080. ret += " = ";
  2081. ret += std::to_string(p.arg1());
  2082. break;
  2083. }
  2084. return ret;
  2085. #endif
  2086. }
  2087. // ~~~~CREATE INDEX~~~~
  2088. CONV_FN(CreateIndex, ci) {
  2089. RETURN_IF_DISABLED_QUERY(CreateIndex);
  2090. std::string ret("CREATE ");
  2091. if (ci.unique())
  2092. ret += "UNIQUE ";
  2093. ret += "INDEX ";
  2094. if (ci.if_not_exists())
  2095. ret += "IF NOT EXISTS ";
  2096. if (ci.has_schema()) {
  2097. ret += SchemaToString(ci.schema());
  2098. ret += ".";
  2099. }
  2100. ret += IndexToString(ci.index());
  2101. ret += " ON ";
  2102. ret += TableToString(ci.table());
  2103. ret += "(";
  2104. ret += IndexedColumnListToString(ci.icol_list());
  2105. ret += ")";
  2106. if (ci.has_where()) {
  2107. ret += " ";
  2108. ret += WhereStatementToString(ci.where());
  2109. }
  2110. return ret;
  2111. }
  2112. // ~~~~CREATE VIEW~~~~
  2113. CONV_FN(CreateView, cv) {
  2114. RETURN_IF_DISABLED_QUERY(CreateView);
  2115. std::string ret("CREATE ");
  2116. if (cv.has_temp_modifier()) {
  2117. ret += EnumStrReplaceUnderscores(TempModifier_Name(cv.temp_modifier()))
  2118. .erase(0, std::string("TM_").length());
  2119. ret += " ";
  2120. }
  2121. ret += "VIEW ";
  2122. if (cv.if_not_exists())
  2123. ret += "IF NOT EXISTS ";
  2124. if (cv.has_schema()) {
  2125. ret += SchemaToString(cv.schema());
  2126. ret += ".";
  2127. }
  2128. ret += ViewToString(cv.view());
  2129. ret += " ";
  2130. if (cv.has_col_list()) {
  2131. ret += "(";
  2132. ret += ColumnListToString(cv.col_list());
  2133. ret += ") ";
  2134. }
  2135. ret += SelectToString(cv.select());
  2136. return ret;
  2137. }
  2138. // ~~~~CREATE TRIGGER~~~~
  2139. CONV_FN(TypicalQuery, tq) {
  2140. // oneof
  2141. if (tq.has_update())
  2142. return UpdateToString(tq.update());
  2143. else if (tq.has_insert())
  2144. return InsertToString(tq.insert());
  2145. else if (tq.has_select())
  2146. return SelectToString(tq.select());
  2147. else
  2148. return DeleteToString(tq.delete_fallback());
  2149. }
  2150. // WARNING no space at end
  2151. CONV_FN(CreateTrigger, ct) {
  2152. RETURN_IF_DISABLED_QUERY(CreateTrigger);
  2153. std::string ret("CREATE ");
  2154. if (ct.has_temp_modifier()) {
  2155. ret += EnumStrReplaceUnderscores(TempModifier_Name(ct.temp_modifier()))
  2156. .erase(0, std::string("TM_").length());
  2157. ret += " ";
  2158. }
  2159. ret += "TRIGGER ";
  2160. if (ct.if_not_exists())
  2161. ret += "IF NOT EXISTS ";
  2162. if (ct.has_schema()) {
  2163. ret += SchemaToString(ct.schema());
  2164. ret += " ";
  2165. }
  2166. ret += TriggerToString(ct.trigger());
  2167. ret += " ";
  2168. if (ct.has_trigger_type()) {
  2169. ret += EnumStrReplaceUnderscores(
  2170. CreateTrigger_TriggerType_Name(ct.trigger_type()));
  2171. ret += " ";
  2172. }
  2173. ret += CreateTrigger_TriggerInstr_Name(ct.trigger_instr());
  2174. ret += " ";
  2175. if (ct.trigger_instr() == CreateTrigger::UPDATE) {
  2176. ret += "OF ";
  2177. ret += ColumnListToString(ct.col_list());
  2178. ret += " ";
  2179. }
  2180. ret += "ON ";
  2181. ret += TableToString(ct.table());
  2182. ret += " ";
  2183. if (ct.for_each_row())
  2184. ret += "FOR EACH ROW ";
  2185. if (ct.has_when()) {
  2186. ret += "WHEN ";
  2187. ret += ExprComparisonHighProbabilityToString(ct.when());
  2188. ret += " ";
  2189. }
  2190. ret += "BEGIN ";
  2191. ret += TypicalQueryToString(ct.tq());
  2192. ret += "; ";
  2193. for (int i = 0; i < ct.extra_tqs_size(); i++) {
  2194. ret += TypicalQueryToString(ct.extra_tqs(i));
  2195. ret += "; ";
  2196. }
  2197. ret += "END";
  2198. return ret;
  2199. }
  2200. // ~~~~REINDEX~~~~
  2201. CONV_FN(ReIndex, ri) {
  2202. RETURN_IF_DISABLED_QUERY(ReIndex);
  2203. // Chrome doesn't use REINDEX
  2204. #if !defined(SQLITE_OMIT_REINDEX)
  2205. if (ri.empty())
  2206. return "REINDEX";
  2207. std::string ret("REINDEX ");
  2208. if (ri.has_collate_type()) {
  2209. ret += CollateTypeToString(ri.collate_type());
  2210. return ret;
  2211. }
  2212. if (ri.has_schema()) {
  2213. ret += SchemaToString(ri.schema());
  2214. ret += ".";
  2215. }
  2216. if (ri.has_table())
  2217. ret += TableToString(ri.table());
  2218. else
  2219. ret += IndexToString(ri.index());
  2220. return ret;
  2221. #else
  2222. return "";
  2223. #endif
  2224. }
  2225. CONV_FN(Drop, d) {
  2226. RETURN_IF_DISABLED_QUERY(Drop);
  2227. std::string ret("DROP ");
  2228. std::string if_exists("");
  2229. std::string schema("");
  2230. if (d.if_exists())
  2231. if_exists = "IF EXISTS ";
  2232. if (d.has_schema()) {
  2233. schema = SchemaToString(d.schema());
  2234. schema += " ";
  2235. }
  2236. // oneof
  2237. if (d.has_index()) {
  2238. ret += "INDEX ";
  2239. ret += if_exists;
  2240. ret += schema;
  2241. ret += IndexToString(d.index());
  2242. } else if (d.has_table()) {
  2243. ret += "TABLE ";
  2244. ret += if_exists;
  2245. ret += schema;
  2246. ret += TableToString(d.table());
  2247. } else if (d.has_trigger()) {
  2248. ret += "TRIGGER ";
  2249. ret += if_exists;
  2250. ret += schema;
  2251. ret += TriggerToString(d.trigger());
  2252. } else {
  2253. ret += "VIEW ";
  2254. ret += if_exists;
  2255. ret += schema;
  2256. ret += ViewToString(d.view_fallback());
  2257. }
  2258. return ret;
  2259. }
  2260. // ~~~~ALTER TABLE~~~~
  2261. CONV_FN(AlterTable, at) {
  2262. RETURN_IF_DISABLED_QUERY(AlterTable);
  2263. std::string ret("ALTER TABLE ");
  2264. ret += ExprSchemaTableToString(at.schema_table());
  2265. ret += " ";
  2266. if (at.has_col()) {
  2267. ret += "RENAME ";
  2268. if (at.column())
  2269. ret += "COLUMN ";
  2270. ret += ColumnToString(at.col());
  2271. ret += " TO ";
  2272. ret += ColumnToString(at.col_to());
  2273. } else if (at.has_col_def()) {
  2274. ret += "ADD ";
  2275. if (at.column())
  2276. ret += "COLUMN ";
  2277. ret += ColumnDefToString(at.col_def());
  2278. } else {
  2279. ret += "RENAME TO ";
  2280. ret += TableToString(at.table_fallback());
  2281. }
  2282. return ret;
  2283. }
  2284. // ~~~~ATTACH DATABASE~~~~
  2285. CONV_FN(AttachDatabase, ad) {
  2286. RETURN_IF_DISABLED_QUERY(AttachDatabase);
  2287. std::string ret("ATTACH DATABASE \'");
  2288. if (ad.in_memory()) {
  2289. if (ad.file_uri()) {
  2290. ret += "file:";
  2291. std::string add;
  2292. if (ad.has_db_name()) {
  2293. ret += SchemaToString(ad.db_name());
  2294. ret += "?mode=memory";
  2295. add = "&";
  2296. } else {
  2297. ret += ":memory:";
  2298. add = "?";
  2299. }
  2300. if (ad.shared_cache()) {
  2301. ret += add;
  2302. ret += "cache=shared";
  2303. }
  2304. }
  2305. }
  2306. ret += "\' AS ";
  2307. ret += SchemaToString(ad.schema());
  2308. return ret;
  2309. }
  2310. // ~~~~DETACH DATABASE~~~~
  2311. CONV_FN(DetachDatabase, dd) {
  2312. RETURN_IF_DISABLED_QUERY(DetachDatabase);
  2313. std::string ret("DETACH DATABASE ");
  2314. ret += SchemaToString(dd.schema());
  2315. return ret;
  2316. }
  2317. // ~~~~Time and date fns~~~~
  2318. CONV_FN(HoursStuff, hs) {
  2319. std::string ret;
  2320. if (hs.has_hh()) {
  2321. ret += std::to_string(hs.hh() % 100);
  2322. if (hs.has_mm()) {
  2323. ret += ":";
  2324. ret += std::to_string(hs.mm() % 100);
  2325. if (hs.has_ss()) {
  2326. ret += ":";
  2327. ret += std::to_string(hs.ss() % 100);
  2328. if (hs.has_sss()) {
  2329. ret += ".";
  2330. ret += std::to_string(hs.sss() % 1000);
  2331. }
  2332. }
  2333. }
  2334. }
  2335. return ret;
  2336. }
  2337. CONV_FN(TimeString, ts) {
  2338. std::string ret;
  2339. if (ts.has_yyyy()) {
  2340. // FIXME in the future add zeroes for integers < 1000.
  2341. ret += std::to_string(ts.yyyy() % 10000);
  2342. ret += "-";
  2343. ret += std::to_string(ts.mm() % 100);
  2344. ret += "-";
  2345. ret += std::to_string(ts.dd() % 100);
  2346. if (ts.extra_t())
  2347. ret += "T";
  2348. if (ts.has_hs())
  2349. ret += HoursStuffToString(ts.hs());
  2350. } else if (ts.has_hs()) {
  2351. ret += HoursStuffToString(ts.hs());
  2352. } else if (ts.has_dddddddddd()) {
  2353. ret += std::to_string(ts.dddddddddd() % 10000000000);
  2354. } else if (ts.now()) {
  2355. ret += "now";
  2356. } else {
  2357. ret += ConvertToSqlString(ts.random_bytes());
  2358. }
  2359. if (ts.has_tz_plus()) {
  2360. if (ts.z()) {
  2361. ret += "Z";
  2362. } else {
  2363. if (ts.plus())
  2364. ret += "+";
  2365. else
  2366. ret += "-";
  2367. ret += std::to_string(ts.tz_hh() % 100);
  2368. ret += std::to_string(ts.tz_mm() % 100);
  2369. }
  2370. }
  2371. return ret;
  2372. }
  2373. CONV_FN(TimeModifier, tm) {
  2374. std::string ret;
  2375. if (tm.has_nm()) {
  2376. ret += std::to_string(tm.num());
  2377. ret += " ";
  2378. if (tm.has_dot_num()) {
  2379. ret += ".";
  2380. ret += std::to_string(tm.dot_num());
  2381. }
  2382. ret += StrToLower(TimeModifier_NumberedModifiers_Name(tm.nm()));
  2383. } else {
  2384. ret += StrToLower(
  2385. EnumStrReplaceUnderscores(TimeModifier_OtherModifiers_Name(tm.om())));
  2386. }
  2387. if (tm.om() == TimeModifier::WEEKDAY) {
  2388. ret += " ";
  2389. ret += std::to_string(tm.num());
  2390. }
  2391. return ret;
  2392. }
  2393. CONV_FN(SimpleDateAndTimeFn, sfn) {
  2394. std::string ret;
  2395. ret += StrToLower(SimpleDateAndTimeFn_FnName_Name(sfn.fn_name()));
  2396. ret += "(\'";
  2397. ret += TimeStringToString(sfn.time_string());
  2398. ret += "\'";
  2399. for (int i = 0; i < sfn.modifiers_size(); i++) {
  2400. ret += ", \'";
  2401. ret += TimeModifierToString(sfn.modifiers(i));
  2402. ret += "\'";
  2403. }
  2404. ret += ") ";
  2405. return ret;
  2406. }
  2407. CONV_FN(StrftimeFormat, sf) {
  2408. std::string ret;
  2409. if (sf.has_subs()) {
  2410. std::string subs = StrftimeFormat_Substitution_Name(sf.subs());
  2411. if (sf.lowercase())
  2412. subs = StrToLower(subs);
  2413. ret += "%" + subs;
  2414. } else {
  2415. ret += "%%";
  2416. }
  2417. ret += ConvertToSqlString(sf.bytes());
  2418. return ret;
  2419. }
  2420. CONV_FN(StrftimeFn, sfn) {
  2421. std::string ret("strftime(\'");
  2422. for (int i = 0; i < sfn.fmts_size(); i++) {
  2423. ret += StrftimeFormatToString(sfn.fmts(i));
  2424. }
  2425. ret += "\', \'";
  2426. ret += TimeStringToString(sfn.time_string());
  2427. ret += "\'";
  2428. for (int i = 0; i < sfn.modifiers_size(); i++) {
  2429. ret += ", \'";
  2430. ret += TimeModifierToString(sfn.modifiers(i));
  2431. ret += "\'";
  2432. }
  2433. ret += ") ";
  2434. return ret;
  2435. }
  2436. CONV_FN(DateAndTimeFn, dat) {
  2437. if (dat.has_simple())
  2438. return SimpleDateAndTimeFnToString(dat.simple());
  2439. else
  2440. return StrftimeFnToString(dat.strftime());
  2441. }
  2442. // ~~~~QUERY~~~~
  2443. CONV_FN(SQLQuery, query) {
  2444. using QueryType = SQLQuery::QueryOneofCase;
  2445. switch (query.query_oneof_case()) {
  2446. case QueryType::kSelect:
  2447. return SelectToString(query.select());
  2448. case QueryType::kCreateTable:
  2449. return CreateTableToString(query.create_table());
  2450. case QueryType::kInsert:
  2451. return InsertToString(query.insert());
  2452. case QueryType::kDelete:
  2453. return DeleteToString(query.delete_());
  2454. case QueryType::kFts3Table:
  2455. return CreateFTS3TableToString(query.fts3_table());
  2456. case QueryType::kFtsQuery:
  2457. return FTS3SpecificQueryToString(query.fts_query());
  2458. case QueryType::kBeginTxn:
  2459. return BeginTransactionToString(query.begin_txn());
  2460. case QueryType::kCommitTxn:
  2461. return CommitTransactionToString(query.commit_txn());
  2462. case QueryType::kRollbackStmt:
  2463. return RollbackStatementToString(query.rollback_stmt());
  2464. #if !defined(FUZZ_OMIT_SAVEPOINT)
  2465. case QueryType::kCreateSavePoint:
  2466. return CreateSavePointToString(query.create_save_point());
  2467. case QueryType::kReleaseSavePoint:
  2468. return ReleaseSavePointToString(query.release_save_point());
  2469. #endif
  2470. case QueryType::kAnalyze:
  2471. return AnalyzeToString(query.analyze());
  2472. case QueryType::kVacuum:
  2473. return VacuumToString(query.vacuum());
  2474. case QueryType::kPragma:
  2475. return PragmaToString(query.pragma());
  2476. case QueryType::kUpdate:
  2477. return UpdateToString(query.update());
  2478. case QueryType::kCreateIndex:
  2479. return CreateIndexToString(query.create_index());
  2480. case QueryType::kCreateView:
  2481. return CreateViewToString(query.create_view());
  2482. case QueryType::kCreateTrigger:
  2483. return CreateTriggerToString(query.create_trigger());
  2484. case QueryType::kReindex:
  2485. return ReIndexToString(query.reindex());
  2486. case QueryType::kDrop:
  2487. return DropToString(query.drop());
  2488. case QueryType::kAlterTable:
  2489. return AlterTableToString(query.alter_table());
  2490. case QueryType::kAttachDb:
  2491. return AttachDatabaseToString(query.attach_db());
  2492. case QueryType::kDetachDb:
  2493. return DetachDatabaseToString(query.detach_db());
  2494. #if defined(FUZZ_FTS3)
  2495. case QueryType::kFts3Insert:
  2496. return FTS3HiddenTableInsertToString(query.fts3_insert());
  2497. case QueryType::kFts3Update:
  2498. return FTS3HiddenTableUpdateToString(query.fts3_update());
  2499. case QueryType::kFts3Delete:
  2500. return FTS3HiddenTableDeleteToString(query.fts3_delete());
  2501. #endif
  2502. default:
  2503. return "";
  2504. }
  2505. }
  2506. std::vector<std::string> SQLQueriesToVec(const SQLQueries& sql_queries) {
  2507. std::vector<std::string> queries;
  2508. queries.reserve(sql_queries.extra_queries_size() + 1);
  2509. queries.push_back(CreateTableToString(sql_queries.create_table()) + ";");
  2510. for (int i = 0; i < sql_queries.extra_queries_size(); i++) {
  2511. std::string query = SQLQueryToString(sql_queries.extra_queries(i));
  2512. if (query == "")
  2513. continue;
  2514. query += ";";
  2515. queries.push_back(query);
  2516. }
  2517. return queries;
  2518. }
  2519. CONV_FN(SQLQueries, sql_queries) {
  2520. std::string queries;
  2521. for (std::string& query : SQLQueriesToVec(sql_queries)) {
  2522. queries += query;
  2523. queries += "\n";
  2524. }
  2525. return queries;
  2526. }
  2527. void SetDisabledQueries(std::set<std::string> disabled_queries) {
  2528. disabled_queries_ = disabled_queries;
  2529. }
  2530. } // namespace sql_fuzzer