Changeset: e805d5918203 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/e805d5918203
Branch: default
Log Message:
Merge with less_explain_info branch
diffs (truncated from 17090 to 300 lines):
diff --git a/.editorconfig b/.editorconfig
--- a/.editorconfig
+++ b/.editorconfig
@@ -5,7 +5,7 @@ root = true
end_of_line = lf
insert_final_newline = true
-[*.{c,h}{,.in}]
+[*.{c,h,y}{,.in}]
indent_style = tab
tab_width = 4
indent_size = tab
diff --git a/clients/mapiclient/mhelp.c b/clients/mapiclient/mhelp.c
--- a/clients/mapiclient/mhelp.c
+++ b/clients/mapiclient/mhelp.c
@@ -410,9 +410,16 @@ SQLhelp sqlhelp1[] = {
NULL,
"See also
https://www.monetdb.org/documentation/user-guide/sql-manual/data-manipulation/prepare-statement/"},
{"EXPLAIN",
- "Give MAL execution plan for the SQL statement",
- "EXPLAIN statement",
+ "Display logical or physical execution plan for the SQL statement.",
+ "EXPLAIN [BEFORE|AFTER] [step] [SHOW DETAILS] statement\n"
+ "step [UNNEST|REWRITE|PHYSICAL]",
NULL,
+ "Plain EXPLAIN defaults to logical execution plan.\n"
+ "Use UNNEST|REWRITE|PHYSICAL to specify compilation step to show.\n"
+ "Use BEFORE|AFTER to specify moment of compilation step\n"
+ "to output. The default is AFTER.\n"
+ "SHOW DETAILS displays column properties, rewriter number of changes\n"
+ "and time spent.\n"
"See also
https://www.monetdb.org/documentation/admin-guide/debugging-features/explain-sql-stmt/"},
{"EXTRACT",
"Built-in function",
@@ -446,11 +453,6 @@ SQLhelp sqlhelp1[] = {
"[ WITH cte_list ] MERGE INTO qname [ [AS] ident ] USING table_ref [
[AS] ident ] ON search_condition merge_list",
"cte_list,table_ref,search_condition,merge_list",
"See also:
https://www.monetdb.org/documentation/user-guide/blog-archive/merge-statements/"},
- {"PLAN",
- "Give relational execution plan for the SQL statement",
- "PLAN statement",
- NULL,
- "See also
https://www.monetdb.org/documentation/admin-guide/debugging-features/plan-sql-stmt/"},
{"PREPARE",
"Prepare a SQL DML statement with optional question-mark parameter
markers",
"PREPARE statement",
@@ -551,7 +553,7 @@ SQLhelp sqlhelp1[] = {
"joined_table,join_type",
"See also
https://www.monetdb.org/documentation/user-guide/sql-manual/data-manipulation/table-expressions/"},
{"TRACE",
- "Give execution trace for the SQL statement",
+ "Trace engine execution for the SQL statement. Output can be accessed
via tracelog view.",
"TRACE statement",
NULL,
"See also
https://www.monetdb.org/documentation/admin-guide/debugging-features/trace-sql-stmt/"},
diff --git a/clients/odbc/tests/ODBCgetInfo.c b/clients/odbc/tests/ODBCgetInfo.c
--- a/clients/odbc/tests/ODBCgetInfo.c
+++ b/clients/odbc/tests/ODBCgetInfo.c
@@ -663,7 +663,7 @@ const struct {
"MATCHED,MAXVALUE,MEDIUMINT,MERGE,MINVALUE,"
"NAME,NATIVE,NEW,NOW,NULLS,"
"OBJECT,OFFSET,OLD,OPTIONS,ORDERED,OTHERS,OVER,"
- "PARTITION,PASSWORD,PATH,PLAN,PRECEDING,PREP,QUARTER,"
+ "PARTITION,PASSWORD,PATH,PRECEDING,PREP,QUARTER,"
"RANGE,RECORDS,REFERENCING,RELEASE,REMOTE,RENAME,REPEATABLE,"
"REPLACE,REPLICA,RESTART,RETURN,RETURNS,ROLE,ROLLUP,ROW,"
"SAMPLE,SAVEPOINT,SEED,SEQUENCE,SERIAL,SERIALIZABLE,"
diff --git a/clients/odbc/tests/ODBCmetadata.c
b/clients/odbc/tests/ODBCmetadata.c
--- a/clients/odbc/tests/ODBCmetadata.c
+++ b/clients/odbc/tests/ODBCmetadata.c
@@ -324,7 +324,7 @@ compareResultOptClose(SQLHANDLE stmt, SQ
/*
* Utility function to query the gdk_nr_threads value from the server.
- * The output of some queries (EXPLAIN, TRACE) differ when the server
+ * The output of some queries (EXPLAIN PHYSICAL, TRACE) differ when the server
* is started with 1 thread, as is done in our testweb.
*/
static int
@@ -1519,9 +1519,9 @@ main(int argc, char **argv)
"ORDERID LINES PARTID QUANTITY\n"
"INTEGER INTEGER INTEGER DECIMAL(9,3)\n");
- // test PLAN SELECT query
- ret = SQLExecDirect(stmt, (SQLCHAR *) "PLAN SELECT * from
odbctst.\"LINES\";", SQL_NTS);
- compareResult(stmt, ret, "PLAN SELECT * from odbctst.\"LINES\"",
+ // test EXPLAIN SHOW DETAILS SELECT query
+ ret = SQLExecDirect(stmt, (SQLCHAR *) "EXPLAIN SHOW DETAILS SELECT *
from odbctst.\"LINES\";", SQL_NTS);
+ compareResult(stmt, ret, "EXPLAIN SHOW DETAILS SELECT * from
odbctst.\"LINES\"",
"Resultset with 1 columns\n"
"Resultset with 3 rows\n"
"rel\n"
@@ -1531,15 +1531,15 @@ main(int argc, char **argv)
") [ \"LINES\".\"ORDERID\" NOT NULL UNIQUE HASHCOL ,
\"LINES\".\"LINES\" NOT NULL UNIQUE, \"LINES\".\"PARTID\" NOT NULL UNIQUE,
\"LINES\".\"QUANTITY\" NOT NULL UNIQUE ]\n");
// test EXPLAIN SELECT query
- ret = SQLExecDirect(stmt, (SQLCHAR *) "EXPLAIN SELECT * from
odbctst.\"LINES\";", SQL_NTS);
- compareResult(stmt, ret, "EXPLAIN SELECT * from odbctst.\"LINES\"",
+ ret = SQLExecDirect(stmt, (SQLCHAR *) "EXPLAIN PHYSICAL SELECT * from
odbctst.\"LINES\";", SQL_NTS);
+ compareResult(stmt, ret, "EXPLAIN PHYSICAL SELECT * from
odbctst.\"LINES\"",
nrServerThreads > 1 ?
"Resultset with 1 columns\n"
"Resultset with 17 rows\n"
"mal\n"
"WLONGVARCHAR(174)\n"
"function user.main():void;\n"
- " X_1:void := querylog.define(\"explain select * from
odbctst.\\\"LINES\\\";\":str, \"default_pipe\":str, 26:int);\n"
+ " X_1:void := querylog.define(\"explain physical select *
from odbctst.\\\"LINES\\\";\":str, \"default_pipe\":str, 26:int);\n"
"\n"
" X_33:bat[:int] := bat.new(nil:int);\n"
" X_34:bat[:int] := bat.new(nil:int);\n"
@@ -1560,7 +1560,7 @@ main(int argc, char **argv)
"mal\n"
"WLONGVARCHAR(174)\n"
"function user.main():void;\n"
- " X_1:void := querylog.define(\"explain select * from
odbctst.\\\"LINES\\\";\":str, \"default_pipe\":str, 26:int);\n"
+ " X_1:void := querylog.define(\"explain physical select *
from odbctst.\\\"LINES\\\";\":str, \"default_pipe\":str, 26:int);\n"
" X_33:bat[:int] := bat.new(nil:int);\n"
" X_34:bat[:int] := bat.new(nil:int);\n"
" X_35:bat[:int] := bat.new(nil:int);\n"
diff --git a/sql/ChangeLog b/sql/ChangeLog
--- a/sql/ChangeLog
+++ b/sql/ChangeLog
@@ -1,6 +1,15 @@
# ChangeLog file for sql
# This file is updated with Maddlog
+* Fri Oct 3 2025 Lucas Pereira <[email protected]>
+- EXPLAIN now supports a BEFORE/AFTER UNNEST/REWRITE/PHYSICAL clause
+ to indicate which phase of query compilation to show. A plain
+ EXPLAIN is equivalent to EXPLAIN BEFORE PHYSICAL, which is what PLAN
+ used to do. The old EXPLAIN is now EXPLAIN PHYSICAL. SHOW DETAILS
+ includes more information about properties, rewriters number of
+ changes and time spent.
+- The PLAN keyword has been removed.
+
* Tue Sep 16 2025 Sjoerd Mullender <[email protected]>
- The TRACE prefix for SQL queries now no longer produces two result sets.
Before, the first result set was the result of the query, and the
diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -144,7 +144,8 @@ sql_symbol2relation(backend *be, symbol
lng t_begin = GDKusec();
storage_based_opt = value_based_opt && rel && !is_ddl(rel->op);
- if (rel && !(rel->op == op_ddl && rel->card == CARD_ATOM && rel->flag
== ddl_psm && (be->mvc->emod & mod_exec) != 0)) { /* no need to optimize exec */
+ if (rel && !(rel->op == op_ddl && rel->card == CARD_ATOM &&
+ rel->flag == ddl_psm && (be->mvc->emod ==
mod_exec) != 0)) { /* no need to optimize exec */
if (rel)
rel = sql_processrelation(be->mvc, rel, profile, 1,
value_based_opt, storage_based_opt);
if (rel && (rel_no_mitosis(be->mvc, rel) ||
rel_need_distinct_query(rel)))
@@ -5579,6 +5580,10 @@ SQLread_dump_rel(Client cntxt, MalBlkPtr
if (refs == NULL)
goto bailout;
+ m->step = S_REWRITE;
+ m->temporal = T_AFTER;
+ m->show_details = true;
+
rel_print_refs(m, s, rel, 0, refs, 0);
rel_print_(m, s, rel, 0, refs, 0);
res = buffer_get_buf(b);
diff --git a/sql/backends/monet5/sql_execute.c
b/sql/backends/monet5/sql_execute.c
--- a/sql/backends/monet5/sql_execute.c
+++ b/sql/backends/monet5/sql_execute.c
@@ -60,11 +60,11 @@ SQLrun(Client c, mvc *m)
TRC_INFO(SQL_EXECUTION, "Executing: %s", c->query);
MT_thread_setworking(c->query);
- if (m->emod & mod_explain) {
+ if (m->emod == mod_explain) {
if (c->curprg->def)
printFunction(c->fdout, mb, 0, LIST_MAL_NAME |
LIST_MAL_VALUE | LIST_MAL_TYPE | LIST_MAL_MAPI);
} else {
- if (m->emod & mod_trace){
+ if (m->trace){
if ((msg = startTrace(c)) == MAL_SUCCEED) {
setVariableScope(mb);
MT_lock_set(&mal_contextLock);
diff --git a/sql/backends/monet5/sql_gencode.c
b/sql/backends/monet5/sql_gencode.c
--- a/sql/backends/monet5/sql_gencode.c
+++ b/sql/backends/monet5/sql_gencode.c
@@ -262,6 +262,8 @@ static int
backend bebackup = *be; /* backup current backend */
exception_buffer ebsave = *sa_get_eb(m->sa);
+ m->show_details = true;
+
if (strlen(mod) >= IDLENGTH) {
(void) sql_error(m, 10, SQLSTATE(42000) "Module name '%s' too
large for the backend", mod);
goto bailout;
@@ -912,6 +914,8 @@ static int
Symbol symbackup = c->curprg;
exception_buffer ebsave = *sa_get_eb(m->sa);
+ m->show_details = true;
+
if (list_empty(prp->value.pval)) {
sql_error(m, 003, SQLSTATE(42000) "Missing REMOTE property on
the input relation");
goto bailout;
diff --git a/sql/backends/monet5/sql_scenario.c
b/sql/backends/monet5/sql_scenario.c
--- a/sql/backends/monet5/sql_scenario.c
+++ b/sql/backends/monet5/sql_scenario.c
@@ -1401,6 +1401,10 @@ SQLparser_body(Client c, backend *be)
m->type = Q_PARSE;
m->emode = m_normal;
m->emod = mod_none;
+ m->temporal = T_NONE;
+ m->step = S_NONE;
+ m->show_details = false;
+ m->trace = false;
c->query = NULL;
c->qryctx.starttime = GDKusec();
c->qryctx.endtime = c->querytimeout ? c->qryctx.starttime +
c->querytimeout : 0;
@@ -1486,7 +1490,8 @@ SQLparser_body(Client c, backend *be)
int oldvtop = c->curprg->def->vtop;
int oldstop = c->curprg->def->stop;
(void)runtimeProfileSetTag(c); /* generate and set the tag in
the mal block of the clients current program. */
- if (m->emode != m_prepare || (m->emode == m_prepare && (m->emod
& mod_exec) && is_ddl(r->op)) /* direct execution prepare */) {
+ if (m->emode != m_prepare ||
+ (m->emode == m_prepare && m->emod == mod_exec &&
is_ddl(r->op)) /* direct execution prepare */) {
mvc_query_processed(m);
err = 0;
@@ -1505,9 +1510,9 @@ SQLparser_body(Client c, backend *be)
}
int opt = 0;
- if (m->emode == m_prepare && (m->emod & mod_exec)) {
+ if (m->emode == m_prepare && m->emod == mod_exec) {
/* generated the named parameters for the
placeholders */
- if (backend_dumpstmt(be, c->curprg->def, r->r,
!(m->emod & mod_exec), 0, c->query) < 0) {
+ if (backend_dumpstmt(be, c->curprg->def, r->r,
!(m->emod == mod_exec), 0, c->query) < 0) {
msg = handle_error(m, 0, msg);
err = 1;
MSresetInstructions(c->curprg->def,
oldstop);
@@ -1515,17 +1520,21 @@ SQLparser_body(Client c, backend *be)
}
r = r->l;
m->emode = m_normal;
- m->emod &= ~mod_exec;
+ m->emod = mod_none;
}
- if (!err && backend_dumpstmt(be, c->curprg->def, r,
!(m->emod & mod_exec), 0, c->query) < 0) {
+ if (!err && backend_dumpstmt(be, c->curprg->def, r,
!(m->emod == mod_exec), 0, c->query) < 0) {
msg = handle_error(m, 0, msg);
err = 1;
MSresetInstructions(c->curprg->def, oldstop);
freeVariables(c, c->curprg->def, NULL, oldvtop);
freeException(c->curprg->def->errors);
c->curprg->def->errors = NULL;
- } else
- opt = ((m->emod & mod_exec) == 0); /* no need
to optimize prepare - execute */
+ } else {
+ opt = ((m->emod == mod_exec) == 0); /* no need
to optimize prepare - execute */
+ }
+
+ if (be->mvc->emod == mod_explain && be->mvc->step ==
S_PHYSICAL && be->mvc->temporal == T_BEFORE)
+ opt = 0;
if (err)
m->session->status = -10;
diff --git a/sql/backends/monet5/sql_upgrades.c
b/sql/backends/monet5/sql_upgrades.c
--- a/sql/backends/monet5/sql_upgrades.c
+++ b/sql/backends/monet5/sql_upgrades.c
@@ -5167,6 +5167,7 @@ sql_update_default(Client c, mvc *sql, s
sql->session->status = 0; /* if the function was not found
clean the error */
sql->errstr[0] = '\0';
}
+
return err;
}
diff --git a/sql/scripts/10_sys_schema_extension.sql
b/sql/scripts/10_sys_schema_extension.sql
--- a/sql/scripts/10_sys_schema_extension.sql
+++ b/sql/scripts/10_sys_schema_extension.sql
@@ -200,7 +200,6 @@ INSERT INTO sys.keywords (keyword) VALUE
('PARTITION'),
('PASSWORD'),
('PATH'),
- ('PLAN'),
('POSITION'),
('PRECEDING'),
('PRECISION'),
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -368,24 +368,24 @@ exp_print(mvc *sql, stream *fout, sql_ex
default:
;
}
- if (e->type != e_atom && e->type != e_cmp && is_partitioning(e))
- mnstr_printf(fout, " PART");
- if (e->type != e_atom && e->type != e_cmp && is_ascending(e))
- mnstr_printf(fout, " ASC");
- if (e->type != e_atom && e->type != e_cmp && nulls_last(e))
- mnstr_printf(fout, " NULLS LAST");
- if (e->type != e_atom && e->type != e_cmp && !has_nil(e))
- mnstr_printf(fout, " NOT NULL");
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]