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]

Reply via email to