Branch data Line data Source code
1 : : #include "parse/ASTPrinter.hpp" 2 : : 3 : : #include <mutable/catalog/Schema.hpp> 4 : : 5 : : 6 : : using namespace m; 7 : : using namespace m::ast; 8 : : 9 : : 10 : : /*===== Expr =========================================================================================================*/ 11 : : 12 : 0 : void ASTPrinter::operator()(Const<ErrorExpr>&) 13 : : { 14 : 0 : out << "[error-expression]"; 15 : 0 : } 16 : : 17 : 3078 : void ASTPrinter::operator()(Const<Designator> &e) 18 : : { 19 [ + + ]: 3078 : if (e.has_explicit_table_name()) 20 [ + - + - ]: 2052 : out << e.get_table_name() << '.'; 21 : 3078 : out << e.attr_name.text; 22 : 3078 : } 23 : : 24 : 3571 : void ASTPrinter::operator()(Const<Constant> &e) 25 : : { 26 : 3571 : out << e.tok.text; 27 : 3571 : } 28 : : 29 : 85 : void ASTPrinter::operator()(Const<FnApplicationExpr> &e) 30 : : { 31 : 85 : (*this)(*e.fn); 32 : 85 : out << '('; 33 [ + + ]: 167 : for (auto it = e.args.cbegin(), end = e.args.cend(); it != end; ++it) { 34 [ + + ]: 82 : if (it != e.args.cbegin()) out << ", "; 35 : 82 : (*this)(**it); 36 : 82 : } 37 : 85 : out << ')'; 38 : 85 : } 39 : : 40 : 99 : void ASTPrinter::operator()(Const<UnaryExpr> &e) 41 : : { 42 [ + - ]: 99 : out << '(' << e.op().text; 43 [ + - + + ]: 99 : if (e.op() == TK_Not) out << ' '; 44 : 99 : (*this)(*e.expr); 45 : 99 : out << ')'; 46 : 99 : } 47 : : 48 : 376 : void ASTPrinter::operator()(Const<BinaryExpr> &e) 49 : : { 50 : 376 : out << '('; 51 : 376 : (*this)(*e.lhs); 52 [ + - + - ]: 376 : out << ' ' << e.op().text << ' '; 53 : 376 : (*this)(*e.rhs); 54 : 376 : out << ')'; 55 : 376 : } 56 : : 57 : 24 : void ASTPrinter::operator()(Const<QueryExpr> &e) 58 : : { 59 [ - + ]: 24 : if (expand_nested_queries_) { 60 : 0 : out << '('; 61 : 0 : (*this)(*e.query); 62 : 0 : out << ')'; 63 : 0 : } else { 64 : 24 : out << e.alias() << '.' << e.alias(); // name of artificial source followed by name of single result 65 : : } 66 : 24 : } 67 : : 68 : : /*===== Clause =======================================================================================================*/ 69 : : 70 : 0 : void ASTPrinter::operator()(Const<ErrorClause>&) 71 : : { 72 : 0 : out << "[error-clause]"; 73 : 0 : } 74 : 1 : 75 : 44 : void ASTPrinter::operator()(Const<SelectClause> &c) 76 : : { 77 : 44 : out << "SELECT "; 78 [ + + ]: 44 : if (c.select_all) out << '*'; 79 [ + + ]: 75 : for (auto it = c.select.cbegin(), end = c.select.cend(); it != end; ++it) { 80 [ + + + + ]: 31 : if (c.select_all or it != c.select.cbegin()) out << ", "; 81 : 31 : (*this)(*it->first); 82 [ + + ]: 31 : if (it->second) out << " AS " << it->second.text; 83 : 31 : } 84 : 44 : } 85 : : 86 : 27 : void ASTPrinter::operator()(Const<FromClause> &c) 87 : : { 88 : 27 : out << "FROM "; 89 [ + + ]: 62 : for (auto it = c.from.cbegin(), end = c.from.cend(); it != end; ++it) { 90 [ + + ]: 35 : if (it != c.from.cbegin()) out << ", "; 91 [ + + ]: 35 : if (auto tok = std::get_if<Token>(&it->source)) { 92 : 26 : out << tok->text; 93 [ - + ]: 35 : } else if (auto stmt = std::get_if<Stmt*>(&it->source)) { 94 : 9 : out << '('; 95 : 9 : (*this)(**stmt); 96 : 9 : out << ')'; 97 : 9 : } else { 98 : 0 : M_unreachable("illegal variant"); 99 : : } 100 [ + + ]: 35 : if (it->alias) out << " AS " << it->alias.text; 101 : 35 : } 102 : 27 : } 103 : : 104 : 9 : void ASTPrinter::operator()(Const<WhereClause> &c) 105 : : { 106 : 9 : out << "WHERE " << *c.where; 107 : 9 : } 108 : : 109 : 16 : void ASTPrinter::operator()(Const<GroupByClause> &c) 110 : : { 111 : 16 : out << "GROUP BY "; 112 [ + + ]: 35 : for (auto it = c.group_by.cbegin(), end = c.group_by.cend(); it != end; ++it) { 113 [ + + ]: 19 : if (it != c.group_by.cbegin()) out << ", "; 114 : 19 : auto &[grp, alias] = *it; 115 : 19 : (*this)(*grp); 116 [ + + ]: 19 : if (it->second) 117 : 14 : out << " AS " << alias.text; 118 : 19 : } 119 : 16 : } 120 : : 121 : 5 : void ASTPrinter::operator()(Const<HavingClause> &c) 122 : : { 123 : 5 : out << "HAVING " << *c.having; 124 : 5 : } 125 : : 126 : 9 : void ASTPrinter::operator()(Const<OrderByClause> &c) 127 : : { 128 : 9 : out << "ORDER BY "; 129 [ + + ]: 20 : for (auto it = c.order_by.cbegin(), end = c.order_by.cend(); it != end; ++it) { 130 [ + + ]: 11 : if (it != c.order_by.cbegin()) out << ", "; 131 : 11 : (*this)(*it->first); 132 [ + + ]: 11 : if (it->second) out << " ASC"; 133 : 3 : else out << " DESC"; 134 : 11 : } 135 : 9 : } 136 : : 137 : 9 : void ASTPrinter::operator()(Const<LimitClause> &c) 138 : : { 139 : 9 : out << "LIMIT " << c.limit.text; 140 [ + + ]: 9 : if (c.offset) 141 : 3 : out << " OFFSET " << c.offset.text; 142 : 9 : } 143 : : 144 : : /*===== Constraint ===================================================================================================*/ 145 : : 146 : 2 : void ASTPrinter::operator()(Const<PrimaryKeyConstraint>&) 147 : : { 148 : 2 : out << "PRIMARY KEY"; 149 : 2 : } 150 : : 151 : 2 : void ASTPrinter::operator()(Const<UniqueConstraint>&) 152 : : { 153 : 2 : out << "UNIQUE"; 154 : 2 : } 155 : : 156 : 2 : void ASTPrinter::operator()(Const<NotNullConstraint>&) 157 : : { 158 : 2 : out << "NOT NULL"; 159 : 2 : } 160 : : 161 : 2 : void ASTPrinter::operator()(Const<CheckConditionConstraint> &c) 162 : : { 163 : 2 : out << "CHECK (" << *c.cond << ')'; 164 : 2 : } 165 : : 166 : 2 : void ASTPrinter::operator()(Const<ReferenceConstraint> &c) 167 : : { 168 : 2 : out << "REFERENCES " << c.table_name.text << '(' << c.attr_name.text << ')'; 169 : 2 : } 170 : : 171 : : 172 : : /*===== Instruction ==================================================================================================*/ 173 : : 174 : 0 : void ASTPrinter::operator()(Const<Instruction> &inst) 175 : : { 176 : 0 : out << inst.tok.text; 177 : 0 : } 178 : : 179 : : 180 : : /*===== Stmt =========================================================================================================*/ 181 : : 182 : 0 : void ASTPrinter::operator()(Const<ErrorStmt>&) 183 : : { 184 : 0 : out << "[error-statement];"; 185 : 0 : } 186 : : 187 : 1 : void ASTPrinter::operator()(Const<EmptyStmt>&) 188 : : { 189 : 1 : out << ';'; 190 : 1 : } 191 : : 192 : 3 : void ASTPrinter::operator()(Const<CreateDatabaseStmt> &s) 193 : : { 194 : 3 : out << "CREATE DATABASE " << s.database_name.text << ';'; 195 : 3 : } 196 : : 197 : 4 : void ASTPrinter::operator()(Const<DropDatabaseStmt> &s) 198 : : { 199 : 4 : out << "DROP DATABASE "; 200 [ + + ]: 4 : if (s.has_if_exists) 201 : 2 : out << "IF EXISTS "; 202 : 4 : out << s.database_name.text << ';'; 203 : 4 : } 204 : : 205 : 3 : void ASTPrinter::operator()(Const<UseDatabaseStmt> &s) 206 : : { 207 : 3 : out << "USE " << s.database_name.text << ';'; 208 : 3 : } 209 : : 210 : 9 : void ASTPrinter::operator()(Const<CreateTableStmt> &s) 211 : : { 212 : 9 : out << "CREATE TABLE " << s.table_name.text << "\n("; 213 [ + + ]: 19 : for (auto it = s.attributes.cbegin(), end = s.attributes.cend(); it != end; ++it) { 214 : 10 : auto &attr = *it; 215 [ + + ]: 10 : if (it != s.attributes.cbegin()) out << ','; 216 : 10 : out << "\n " << attr->name.text << ' ' << *attr->type; 217 [ + + ]: 20 : for (auto &c : attr->constraints) { 218 : 10 : out << ' '; 219 : 10 : (*this)(*c); 220 : : } 221 : 10 : } 222 : 9 : out << "\n);"; 223 : 9 : } 224 : : 225 : 4 : void ASTPrinter::operator()(Const<DropTableStmt> &s) 226 : : { 227 : 4 : out << "DROP TABLE "; 228 [ + + ]: 4 : if (s.has_if_exists) 229 : 2 : out << "IF EXISTS "; 230 [ + + ]: 10 : for (auto it = s.table_names.cbegin(), end = s.table_names.cend(); it != end; ++it) { 231 : 6 : auto &table_name = *it; 232 [ + + ]: 6 : if (it != s.table_names.cbegin()) out << ", "; 233 : 6 : out << table_name->text; 234 : 6 : } 235 : 4 : out << ';'; 236 : 4 : } 237 : : 238 : 7 : void ASTPrinter::operator()(Const<CreateIndexStmt> &s) 239 : : { 240 : 7 : out << "CREATE "; 241 [ + + ]: 7 : if (s.has_unique) 242 : 2 : out << "UNIQUE "; 243 : 7 : out << "INDEX "; 244 [ + + ]: 7 : if (s.has_if_not_exists) 245 : 2 : out << "IF NOT EXISTS "; 246 [ + + ]: 7 : if (s.index_name) 247 : 4 : out << s.index_name.text << ' '; 248 : 7 : out << "ON " << s.table_name.text; 249 [ + + ]: 7 : if (s.method) 250 : 2 : out << " USING " << s.method.text; 251 : 7 : out << "\n("; 252 [ + + ]: 18 : for (auto it = s.key_fields.cbegin(), end = s.key_fields.cend(); it != end; ++it) { 253 : 11 : auto &field = *it; 254 [ + + ]: 11 : if (it != s.key_fields.cbegin()) out << ','; 255 : 11 : out << "\n "; 256 : 11 : (*this)(*field); 257 : 11 : } 258 : 7 : out << "\n);"; 259 : 7 : } 260 : : 261 : 4 : void ASTPrinter::operator()(Const<DropIndexStmt> &s) 262 : : { 263 : 4 : out << "DROP INDEX "; 264 [ + + ]: 4 : if (s.has_if_exists) 265 : 2 : out << "IF EXISTS "; 266 [ + + ]: 10 : for (auto it = s.index_names.cbegin(), end = s.index_names.cend(); it != end; ++it) { 267 : 6 : auto &idx = *it; 268 [ + + ]: 6 : if (it != s.index_names.cbegin()) out << ", "; 269 : 6 : out << idx->text; 270 : 6 : } 271 : 4 : out << ';'; 272 : 4 : } 273 : : 274 : 20 : void ASTPrinter::operator()(Const<SelectStmt> &s) 275 : : { 276 : 20 : bool was_nested = is_nested_; 277 : 20 : is_nested_ = true; 278 : : 279 : 20 : (*this)(*s.select); 280 : : 281 [ + + ]: 20 : if (s.from) { 282 : 12 : out << '\n'; 283 : 12 : (*this)(*s.from); 284 : 12 : } 285 : : 286 [ + + ]: 20 : if (s.where) { 287 : 4 : out << '\n'; 288 : 4 : (*this)(*s.where); 289 : 4 : } 290 [ + + ]: 20 : if (s.group_by) { 291 : 2 : out << '\n'; 292 : 2 : (*this)(*s.group_by); 293 : 2 : } 294 [ + + ]: 20 : if (s.having) { 295 : 2 : out << '\n'; 296 : 2 : (*this)(*s.having); 297 : 2 : } 298 [ + + ]: 20 : if (s.order_by) { 299 : 2 : out << '\n'; 300 : 2 : (*this)(*s.order_by); 301 : 2 : } 302 [ + + ]: 20 : if (s.limit) { 303 : 2 : out << '\n'; 304 : 2 : (*this)(*s.limit); 305 : 2 : } 306 : : 307 : 20 : is_nested_ = was_nested; 308 [ - + ]: 20 : if (not is_nested_) 309 : 20 : out << ';'; 310 : 20 : } 311 : : 312 : 7 : void ASTPrinter::operator()(Const<InsertStmt> &s) 313 : : { 314 : 7 : out << "INSERT INTO " << s.table_name.text << "\nVALUES\n "; 315 [ + + ]: 16 : for (auto value_it = s.tuples.cbegin(), end = s.tuples.cend(); value_it != end; ++value_it) { 316 [ + + ]: 9 : if (value_it != s.tuples.cbegin()) out << ",\n "; 317 : 9 : out << '('; 318 [ + + ]: 21 : for (auto elem_it = value_it->cbegin(), elem_end = value_it->cend(); elem_it != elem_end; ++elem_it) { 319 [ + + ]: 12 : if (elem_it != value_it->cbegin()) out << ", "; 320 [ - + + + ]: 12 : switch (elem_it->first) { 321 : 3 : case InsertStmt::I_Default: out << "DEFAULT"; break; 322 : 3 : case InsertStmt::I_Null: out << "NULL"; break; 323 : 6 : case InsertStmt::I_Expr: out << *elem_it->second; break; 324 : : } 325 : 12 : } 326 : 9 : out << ')'; 327 : 9 : } 328 : 7 : out << ';'; 329 : 7 : } 330 : : 331 : 6 : void ASTPrinter::operator()(Const<UpdateStmt> &s) 332 : : { 333 : 6 : out << "UPDATE " << s.table_name.text << "\nSET\n"; 334 [ + + ]: 14 : for (auto it = s.set.cbegin(), end = s.set.cend(); it != end; ++it) { 335 [ + + ]: 8 : if (it != s.set.cbegin()) out << ",\n"; 336 : 8 : out << " " << it->first.text << " = " << *it->second; 337 : 8 : } 338 [ + + ]: 6 : if (s.where) out << '\n' << *s.where; 339 : 6 : out << ';'; 340 : 6 : } 341 : : 342 : 5 : void ASTPrinter::operator()(Const<DeleteStmt> &s) 343 : : { 344 : 5 : out << "DELETE FROM " << s.table_name.text; 345 [ + + ]: 5 : if (s.where) out << '\n' << *s.where; 346 : 5 : out << ';'; 347 : 5 : } 348 : : 349 : 14 : void ASTPrinter::operator()(Const<DSVImportStmt> &s) 350 : : { 351 : 14 : out << "IMPORT INTO " << s.table_name.text << " DSV " << s.path.text; 352 [ + - ]: 14 : if (s.rows) 353 : 0 : out << " ROWS " << s.rows.text; 354 [ + + ]: 14 : if (s.delimiter) 355 : 2 : out << " DELIMITER " << s.delimiter.text; 356 [ + + ]: 14 : if (s.has_header) 357 : 2 : out << " HAS HEADER"; 358 [ + + ]: 14 : if (s.skip_header) 359 : 2 : out << " SKIP HEADER"; 360 : 14 : out << ';'; 361 : 14 : }