Changeset: 366ab43fef89 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/366ab43fef89
Branch: default
Log Message:

merged with mar2025


diffs (truncated from 393 to 300 lines):

diff --git a/clients/ChangeLog.Mar2025 b/clients/ChangeLog.Mar2025
--- a/clients/ChangeLog.Mar2025
+++ b/clients/ChangeLog.Mar2025
@@ -1,3 +1,7 @@
 # ChangeLog file for clients
 # This file is updated with Maddlog
 
+* Fri May  9 2025 Sjoerd Mullender <[email protected]>
+- There is now a \dm command in the interactive mclient to show
+  information about merge tables.
+
diff --git a/clients/mapiclient/dump.c b/clients/mapiclient/dump.c
--- a/clients/mapiclient/dump.c
+++ b/clients/mapiclient/dump.c
@@ -157,7 +157,7 @@ descape(const char *s)
        return d;
 }
 
-static char *
+char *
 sescape(const char *s)
 {
        const char *p;
diff --git a/clients/mapiclient/mclient.1 b/clients/mapiclient/mclient.1
--- a/clients/mapiclient/mclient.1
+++ b/clients/mapiclient/mclient.1
@@ -452,16 +452,16 @@ Dump the given
 \fB\[rs]d\fP
 Alias for \[rs]dvt.
 .TP
-\fB\[rs]d[Stvsfn]+\fP
+\fB\[rs]d[Stvmsfn]+\fP
 List database objects of the given type.
 Multiple type specifiers can be used at the same time.
-The specifiers \fIS\fP, \fIt\fP, \fIv\fP, \fIs\fP, \fIf\fP and \fIn\fP
-stand for System, table, view, sequence, function and schema
+The specifiers \fBS\fP, \fBt\fP, \fBv\fP, \fBm\fP, \fBs\fP, \fBf\fP and \fBn\fP
+stand for System, table, view, merge table, sequence, function and schema
 respectively.
-Note that \fIS\fP simply switches on viewing system catalog objects,
+Note that \fBS\fP simply switches on viewing system catalog objects,
 which is orthogonal to the other specifiers.
 .TP
-\fB\[rs]d[Stvsfn]+\fP \fIobject\fP
+\fB\[rs]d[Stvsfnm]+\fP \fIobject\fP
 Describe the given
 .I object
 in the database using SQL statements that reconstruct the object.
diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c
--- a/clients/mapiclient/mclient.c
+++ b/clients/mapiclient/mclient.c
@@ -38,6 +38,7 @@
 #include "msqldump.h"
 #include "mprompt.h"
 #include "mutils.h"            /* mercurial_revision */
+#include "mstring.h"
 #include "dotmonetdb.h"
 
 #include <locale.h>
@@ -2151,6 +2152,7 @@ showCommands(void)
 #define MD_SEQ      4
 #define MD_FUNC     8
 #define MD_SCHEMA  16
+#define MD_MERGE   32
 
 #define READBLOCK 8192
 
@@ -2438,7 +2440,6 @@ doFile(Mapi mid, stream *fp, bool useins
                                        continue;
                                case 'd': {
                                        bool hasWildcard = false;
-                                       bool hasSchema = false;
                                        bool wantsSystem = false;
                                        unsigned int x = 0;
                                        char *p, *q;
@@ -2466,6 +2467,9 @@ doFile(Mapi mid, stream *fp, bool useins
                                                case 'n':
                                                        x |= MD_SCHEMA;
                                                        break;
+                                               case 'm':
+                                                       x |= MD_MERGE;
+                                                       break;
                                                case 'S':
                                                        wantsSystem = true;
                                                        break;
@@ -2484,6 +2488,8 @@ doFile(Mapi mid, stream *fp, bool useins
                                                ;
 
                                        /* lowercase the object, except for 
quoted parts */
+                                       char *tname = NULL;
+                                       char *sname = NULL;
                                        q = line;
                                        for (p = line; *p != '\0'; p++) {
                                                if (*p == '"') {
@@ -2498,6 +2504,8 @@ doFile(Mapi mid, stream *fp, bool useins
                                                                escaped = true;
                                                        }
                                                } else {
+                                                       if (tname == NULL)
+                                                               tname = p;
                                                        if (!escaped) {
                                                                *q++ = 
tolower((int) *p);
                                                                if (*p == '*') {
@@ -2507,7 +2515,9 @@ doFile(Mapi mid, stream *fp, bool useins
                                                                        *p = 
'_';
                                                                        
hasWildcard = true;
                                                                } else if (*p 
== '.') {
-                                                                       
hasSchema = true;
+                                                                       *p = 
'\0';
+                                                                       sname = 
tname;
+                                                                       tname = 
NULL;
                                                                }
                                                        } else {
                                                                *q++ = *p;
@@ -2521,26 +2531,172 @@ doFile(Mapi mid, stream *fp, bool useins
                                                continue;
                                        }
 
-                                       if (*line && !hasWildcard) {
+                                       if (x & MD_MERGE) {
+                                               const char mquery[] = "select 
s1.name as s1name,"
+                                                       " t1.name as t1name,"
+                                                       " c1.name as c1name,"
+                                                       " s2.name as s2name,"
+                                                       " t2.name as t2name,"
+                                                       " tp.expression,"
+                                                       " tp.type,"
+                                                       " 
''''||replace(rp.minimum, '''', '''''')||'''' as minimum,"
+                                                       " 
''''||replace(rp.maximum, '''', '''''')||'''' as maximum,"
+                                                       " rp.with_nulls,"
+                                                       " 
'('||group_concat(''''||replace(vp.value, '''', '''''')||'''', ',' order by 
vp.value)||')' as values,"
+                                                       " count(vp.value) <> 
count(*) as has_nulls"
+                                                       " from sys.schemas as 
s1,"
+                                                       " sys._tables as t1 
left outer join sys.table_partitions as tp on t1.id = tp.table_id left outer 
join sys._columns as c1 on tp.column_id = c1.id,"
+                                                       " sys.schemas as s2,"
+                                                       " sys._tables as t2 
left outer join sys.range_partitions as rp on t2.id = rp.table_id left outer 
join sys.value_partitions as vp on t2.id = vp.table_id,"
+                                                       " sys.dependencies as d"
+                                                       " where%s%s"
+                                                       " t1.type = 3 and"
+                                                       " s1.id = t1.schema_id 
and"
+                                                       " s2.id = t2.schema_id 
and"
+                                                       " t1.id = d.depend_id 
and"
+                                                       " d.id = t2.id"
+                                                       " group by s1.name, 
t1.name, s2.name, t2.name, c1.name, tp.expression, tp.type, rp.minimum, 
rp.maximum, rp.with_nulls"
+                                                       " order by s1.name, 
t1.name, s2.name, t2.name";
+                                               char *squery = NULL;
+                                               size_t squerylen = 0;
+                                               char *tquery = NULL;
+                                               size_t tquerylen = 0;
+                                               if (sname) {
+                                                       sname = sescape(sname);
+                                                       squerylen = 
strlen(sname) + 21;
+                                                       squery = 
malloc(squerylen);
+                                                       if (hasWildcard)
+                                                               
snprintf(squery, squerylen, " s1.name like '%s' and", sname);
+                                                       else
+                                                               
snprintf(squery, squerylen, " s1.name = '%s' and", sname);
+                                                       free(sname);
+                                                       sname = NULL;
+                                               }
+                                               if (tname) {
+                                                       if (squery == NULL) {
+                                                               squery = 
strdup(" s1.name = current_schema and");
+                                                               squerylen = 
strlen(squery);
+                                                       }
+                                                       tname = sescape(tname);
+                                                       tquerylen = 
strlen(tname) + 21;
+                                                       tquery = 
malloc(tquerylen);
+                                                       if (hasWildcard)
+                                                               
snprintf(tquery, tquerylen, " t1.name like '%s' and", tname);
+                                                       else
+                                                               
snprintf(tquery, tquerylen, " t1.name = '%s' and", tname);
+                                                       free(tname);
+                                                       tname = NULL;
+                                               }
+                                               size_t qlen = sizeof(mquery) + 
squerylen + tquerylen;
+                                               char *query = malloc(qlen);
+                                               snprintf(query, qlen, mquery, 
squery ? squery : "", tquery ? tquery : "");
+                                               free(squery);
+                                               free(tquery);
+                                               hdl = mapi_query(mid, query);
+                                               free(query);
+                                               CHECK_RESULT(mid, hdl, buf, fp);
+                                               char *prevs1name = NULL, 
*prevt1name = NULL;
+                                               while (fetch_row(hdl) > 0) {
+                                                       const char *s1name = 
mapi_fetch_field(hdl, 0);
+                                                       const char *t1name = 
mapi_fetch_field(hdl, 1);
+                                                       const char *c1name = 
mapi_fetch_field(hdl, 2);
+                                                       const char *s2name = 
mapi_fetch_field(hdl, 3);
+                                                       const char *t2name = 
mapi_fetch_field(hdl, 4);
+                                                       const char *expression 
= mapi_fetch_field(hdl, 5);
+                                                       const char *type = 
mapi_fetch_field(hdl, 6);
+                                                       int itype = type ? 
atoi(type) : 0;
+                                                       const char *minimum = 
mapi_fetch_field(hdl, 7);
+                                                       const char *maximum = 
mapi_fetch_field(hdl, 8);
+                                                       const char *with_nulls 
= mapi_fetch_field(hdl, 9);
+                                                       const char *values = 
mapi_fetch_field(hdl, 10);
+                                                       const char *has_nulls = 
mapi_fetch_field(hdl, 11);
+                                                       if (sname && 
strcmp(sname, s1name) != 0)
+                                                               continue;
+                                                       if (tname && 
strcmp(tname, t1name) != 0)
+                                                               continue;
+                                                       if (prevs1name == NULL 
||
+                                                               prevt1name == 
NULL ||
+                                                               
strcmp(prevs1name, s1name) != 0 ||
+                                                               
strcmp(prevt1name, t1name) != 0) {
+                                                               
free(prevs1name);
+                                                               
free(prevt1name);
+                                                               prevs1name = 
strdup(s1name);
+                                                               prevt1name = 
strdup(t1name);
+                                                               
mnstr_printf(toConsole, "MERGE TABLE %s.%s",
+                                                                               
         s1name, t1name);
+                                                               const char *how;
+                                                               if (itype & 1) 
/* PARTITION_RANGE */
+                                                                       how = " 
BY RANGE";
+                                                               else if (itype 
& 2) /* PARTITION_LIST */
+                                                                       how = " 
BY VALUES";
+                                                               else
+                                                                       how = 
"";
+                                                               if (itype & 4) 
/* PARTITION_COLUMN */
+                                                                       
mnstr_printf(toConsole,
+                                                                               
                 " PARTITION%s ON (%s)",
+                                                                               
                 how,
+                                                                               
                 c1name);
+                                                               else if (itype 
& 8) /* PARTITION_EXPRESSION */
+                                                                       
mnstr_printf(toConsole,
+                                                                               
                 " PARTITION%s USING (%s)",
+                                                                               
                 how,
+                                                                               
                 expression);
+                                                               
mnstr_printf(toConsole, "\n");
+                                                       }
+                                                       mnstr_printf(toConsole, 
"  ADD TABLE %s.%s",
+                                                                               
 s2name, t2name);
+                                                       if (itype & 3) {
+                                                               
mnstr_printf(toConsole, " AS PARTITION");
+                                                               if (values) {
+                                                                       
mnstr_printf(toConsole, " IN %s", values);
+                                                                       if 
(has_nulls && strcmp(has_nulls, "true") == 0)
+                                                                               
mnstr_printf(toConsole,
+                                                                               
                         " WITH NULL VALUES");
+                                                               } else if 
(itype & 2 && has_nulls && strcmp(has_nulls, "true") == 0) {
+                                                                       
mnstr_printf(toConsole,
+                                                                               
                 " FOR NULL VALUES");
+                                                               } else {
+                                                                       if 
(minimum)
+                                                                               
mnstr_printf(toConsole, " FROM %s", minimum);
+                                                                       else
+                                                                               
mnstr_printf(toConsole, " FROM RANGE MINVALUE");
+                                                                       if 
(maximum)
+                                                                               
mnstr_printf(toConsole, " TO %s", maximum);
+                                                                       else
+                                                                               
mnstr_printf(toConsole, " TO RANGE MAXVALUE");
+                                                                       if 
(with_nulls && strcmp(with_nulls, "true") == 0)
+                                                                               
mnstr_printf(toConsole, " WITH NULL VALUES");
+                                                               }
+                                                       }
+                                                       mnstr_printf(toConsole, 
"\n");
+                                               }
+                                               free(prevs1name);
+                                               free(prevt1name);
+                                               mapi_close_handle(hdl);
+                                               hdl = NULL;
+                                       }
+                                       if ((sname || tname) && !hasWildcard) {
 #ifdef HAVE_POPEN
                                                stream *saveFD;
 
                                                start_pager(&saveFD);
 #endif
                                                if (x & (MD_TABLE | MD_VIEW))
-                                                       dump_table(mid, NULL, 
line, toConsole, NULL, NULL, true, true, false, false, false, false);
+                                                       dump_table(mid, sname, 
tname, toConsole, NULL, NULL, true, true, false, false, false, false);
                                                if (x & MD_SEQ)
-                                                       describe_sequence(mid, 
NULL, line, toConsole);
+                                                       describe_sequence(mid, 
sname, tname, toConsole);
                                                if (x & MD_FUNC)
-                                                       dump_functions(mid, 
toConsole, 0, NULL, line, NULL);
+                                                       dump_functions(mid, 
toConsole, 0, sname, tname, NULL);
                                                if (x & MD_SCHEMA)
-                                                       describe_schema(mid, 
line, toConsole);
+                                                       describe_schema(mid, 
sname ? sname : tname, toConsole);
 #ifdef HAVE_POPEN
                                                end_pager(saveFD);
 #endif
-                                       } else {
+                                               continue;
+                                       }
+                                       if (x & 
(MD_TABLE|MD_VIEW|MD_SEQ|MD_FUNC|MD_SCHEMA)) {
                                                /* get all object names in 
current schema */
-                                               const char *with_clause =
+                                               const char with_clause[] =
                                                        "with 
describe_all_objects AS (\n"
                                                        "  SELECT s.name AS 
sname,\n"
                                                        "      t.name,\n"
@@ -2591,7 +2747,7 @@ doFile(Mapi mid, stream *fp, bool useins
                                                        "    LEFT OUTER JOIN 
sys.comments c ON s.id = c.id\n"
                                                        "  ORDER BY system, 
name, sname, ntype)\n"
                                                        ;
-                                               size_t len = 
strlen(with_clause) + 400 + strlen(line);
+                                               size_t len = 
strlen(with_clause) + 400 + (sname?strlen(sname):0) + (tname?strlen(tname):0);
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to