in sources/cg_query_plan.c [507:647]
cql_noexport void cg_query_plan_main(ast_node *head) {
sql_stmt_count = 0; // reset statics
Contract(options.file_names_count == 1);
cql_exit_on_semantic_errors(head);
exit_on_validating_schema();
cg_stmts = symtab_new();
STMT_INIT(create_proc_stmt);
// schema
// * note probably need to add declare select function to this list
// that can be needed to correctly parse the body of triggers or views (which might use the function)
STMT_INIT_DDL(create_table_stmt);
STMT_INIT_DDL(create_index_stmt);
STMT_INIT_DDL(create_view_stmt);
STMT_INIT_DDL(create_trigger_stmt);
// dml
STMT_INIT_EXPL(select_stmt);
STMT_INIT_EXPL(with_select_stmt);
STMT_INIT_EXPL(with_insert_stmt);
STMT_INIT_EXPL(update_stmt);
STMT_INIT_EXPL(delete_stmt);
STMT_INIT_EXPL(with_delete_stmt);
STMT_INIT_EXPL(insert_stmt);
STMT_INIT_EXPL(upsert_stmt);
STMT_INIT_EXPL(drop_table_stmt);
STMT_INIT_EXPL(drop_view_stmt);
STMT_INIT_EXPL(drop_index_stmt);
STMT_INIT_EXPL(begin_trans_stmt);
STMT_INIT_EXPL(commit_trans_stmt);
CHARBUF_OPEN(query_plans_buf);
query_plans = &query_plans_buf;
CHARBUF_OPEN(schema_stmts_buf);
schema_stmts = &schema_stmts_buf;
CHARBUF_OPEN(output_buf);
bprintf(&output_buf, "DECLARE PROC printf NO CHECK;\n");
gen_sql_callbacks callbacks;
init_gen_sql_callbacks(&callbacks);
callbacks.mode = gen_mode_no_annotations;
callbacks.variables_callback = &variables_callback;
cg_qp_callbacks = &callbacks;
cg_qp_stmt_list(head);
if (sql_stmt_count) {
bprintf(&output_buf, rt->source_prefix);
if (options.test) {
while (head->right) {
head = head->right;
}
bprintf(&output_buf, "-- The statement ending at line %d\n\n", head->left->lineno);
}
cg_qp_emit_declare_func(&output_buf);
bprintf(&output_buf, "\n");
cg_qp_emit_create_schema_proc(&output_buf);
bprintf(&output_buf, "\n");
emit_populate_no_table_scan_proc(&output_buf);
bprintf(&output_buf, "\n");
emit_populate_tables_proc(&output_buf);
bprintf(&output_buf, "\n");
emit_populate_table_scan_alert_table_proc(&output_buf);
bprintf(&output_buf, "\n");
emit_populate_b_tree_alert_table_proc(&output_buf);
bprintf(&output_buf, "\n");
emit_print_query_violation_proc(&output_buf);
bprintf(&output_buf, "\n");
emit_print_sql_statement_proc(&output_buf);
bprintf(&output_buf, "\n");
emit_print_query_plan_stat_proc(&output_buf);
bprintf(&output_buf, "\n");
emit_print_query_plan_graph_proc(&output_buf);
bprintf(&output_buf, "\n");
emit_print_query_plan(&output_buf);
bprintf(&output_buf, "\n");
}
// create an empty query_plan method even if there are no statements
// (the helpers above won't be needed)
bprintf(&output_buf, "CREATE PROC query_plan()\n");
bprintf(&output_buf, "BEGIN\n");
if (sql_stmt_count) {
bprintf(&output_buf, " CALL create_schema();\n");
bprintf(&output_buf, " BEGIN TRY\n");
bprintf(&output_buf, " CALL populate_no_table_scan();\n");
bprintf(&output_buf, " END TRY;\n");
bprintf(&output_buf, " BEGIN CATCH\n");
bprintf(&output_buf, " CALL printf(\"failed populating no_table_scan table\\n\");\n");
bprintf(&output_buf, " THROW;\n");
bprintf(&output_buf, " END CATCH;\n");
}
for (int32_t i = 1; i <= sql_stmt_count; i++) {
bprintf(&output_buf, " BEGIN TRY\n");
bprintf(&output_buf, " CALL populate_query_plan_%d();\n", i);
bprintf(&output_buf, " END TRY;\n");
bprintf(&output_buf, " BEGIN CATCH\n");
bprintf(&output_buf, " CALL printf(\"failed populating query %d\\n\");\n", i);
bprintf(&output_buf, " THROW;\n");
bprintf(&output_buf, " END CATCH;\n");
}
bprintf(&output_buf, " CALL printf(\"[\\n\");\n");
if (sql_stmt_count) {
bprintf(&output_buf, " CALL print_query_violation();\n");
}
bprintf(&output_buf, " CALL printf(\"[\\n\");\n");
bprintf(&output_buf, " CALL printf(\"[\\n\");\n");
bprintf(&output_buf, " CALL printf(\"[\\\"Query\\\", \\\"Stat\\\", \\\"Graph\\\"],\\n\");\n");
for (int32_t i = 1; i <= sql_stmt_count; i++) {
bprintf(&output_buf, " CALL print_query_plan(%d);\n", i);
}
bprintf(&output_buf, " CALL printf(\"[]\\n\");\n");
bprintf(&output_buf, " CALL printf(\"]\\n\");\n");
bprintf(&output_buf, " CALL printf(\"],\\n\");\n");
bprintf(&output_buf, " CALL printf(\"[]\\n\");\n");
bprintf(&output_buf, " CALL printf(\"]\");\n");
bprintf(&output_buf, "END;\n");
cql_write_file(options.file_names[0], output_buf.ptr);
CHARBUF_CLOSE(output_buf);
CHARBUF_CLOSE(schema_stmts_buf);
CHARBUF_CLOSE(query_plans_buf);
// Force the globals to null state so that they do not look like roots to LeakSanitizer
// all of these should have been freed already. This is the final safety net to prevent
// non-reporting of leaks.
schema_stmts = NULL;
query_plans = NULL;
cg_qp_callbacks = NULL;
}