Changeset: 9eed4d57bb08 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/9eed4d57bb08
Modified Files:
        clients/Tests/exports.stable.out
        sql/backends/monet5/sql_result.c
        sql/backends/monet5/sql_scenario.c
        sql/include/sql_relation.h
        sql/server/rel_dump.c
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_prop.c
        sql/server/rel_prop.h
        sql/server/rel_statistics.h
Branch: pp_hashjoin
Log Message:

merged with default


diffs (296 lines):

diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -1641,7 +1641,7 @@ int pqc_read_filemetadata(pqc_file *pq);
 int pqc_read_schema(pqc_file *pq);
 pqc_reader_t *pqc_reader(pqc_reader_t *p, pqc_file *pq, int nr_workers, 
pqc_filemetadata *fmd, int colnr, int64_t nrows, const void *nil);
 void pqc_reader_destroy(pqc_reader_t *r);
-prop *prop_create(allocator *sa, rel_prop kind, prop *pre);
+prop *prop_create(allocator *sa, prop_kind kind, prop *pre);
 InstrPtr pushPtr(MalBlkPtr mb, InstrPtr q, ptr val);
 void qc_delete(qc *cache, cq *q);
 cq *qc_find(qc *cache, int id);
diff --git a/sql/backends/monet5/sql_result.c b/sql/backends/monet5/sql_result.c
--- a/sql/backends/monet5/sql_result.c
+++ b/sql/backends/monet5/sql_result.c
@@ -1572,13 +1572,10 @@ mvc_export_operation(backend *b, stream 
                if (mnstr_printf(s, "&3 " LLFMT " " LLFMT "\n", starttime > 0 ? 
GDKusec() - starttime : 0, mal_optimizer) < 0)
                        return -4;
        } else {
-               if (m->session->auto_commit) {
-                       if (mnstr_write(s, "&4 t\n", 5, 1) != 1)
-                               return -4;
-               } else {
-                       if (mnstr_write(s, "&4 f\n", 5, 1) != 1)
-                               return -4;
-               }
+               /* We used to send notifications of auto commit mode changes 
here but
+                * that has been pulled up to the Scenario level because this 
function
+                * doesn't get executed when an error happens before the end of 
a
+                * transaction. */
        }
 
        if (mvc_export_warning(s, w) != 1)
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
@@ -1782,7 +1782,17 @@ SQLengine_(Client c)
                sqlcleanup(be, 0);
                c->query = NULL;
        } else {
+               bool pre_autocommit = be->mvc->session->auto_commit;
                msg = SQLparser(c, be);
+               bool post_autocommit = be->mvc->session->auto_commit;
+               if (pre_autocommit != post_autocommit && be->out != NULL) {
+                       /* Notify client of change in auto commit mode */
+                       char autocommit_flag = post_autocommit ? 't' : 'f';
+                       char error_message_follows_flag = (msg != NULL) ? 't' : 
'f';
+                       int n = mnstr_printf(be->out, "&4 %c %c\n", 
autocommit_flag, error_message_follows_flag);
+                       if (n < 0 && msg == NULL)
+                               msg = createException(SQL, "SQLparser", 
SQLSTATE(HY002) "Error while sending autocommit notification: %s\n", 
mnstr_peek_error(be->out));
+               }
                if (msg == MAL_SUCCEED && (be->mvc->emode == m_deallocate || 
be->mvc->emode == m_prepare))
                        return msg;
        }
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -13,6 +13,40 @@
 
 #include "sql_catalog.h"
 
+typedef enum prop_kind {
+       PROP_COUNT,     /* Number of expect rows for the relation */
+       PROP_NUNIQUES,  /* Estimated number of distinct rows for the expression 
*/
+       PROP_MIN,       /* min value if available */
+       PROP_MAX,       /* max value if available */
+       PROP_JOINIDX,   /* could use join idx */
+       PROP_HASHIDX,   /* is hash idx */
+       PROP_HASHCOL,   /* could use hash idx */
+       PROP_UKEY,              /* p = list of exps */
+       PROP_REMOTE,    /* uri for remote execution */
+       PROP_USED,      /* number of times exp is used */
+       PROP_GROUPINGS, /* used by ROLLUP/CUBE/GROUPING SETS, value contains 
the list of sets */
+       PROP_UNNESTING, /* used by unnesting rewriter */
+       PROP_SELECTIVITY        /* selectivity estimate for predicates (dbl, 
0.0-1.0) */
+} prop_kind;
+
+typedef struct prop {
+       prop_kind kind;  /* kind of property */
+       sqlid id;               /* optional id of object involved */
+       union {
+               BUN lval; /* property with simple counts */
+               dbl dval; /* property with estimate */
+               void *pval; /* property value */
+       } value;
+       struct prop *p; /* some relations may have many properties, which are 
kept in a chain list */
+} prop;
+
+/* for REMOTE prop we need to keep a list with tids and uris for the remote 
tables */
+typedef struct tid_uri {
+       sqlid id;
+       const char* uri;
+} tid_uri;
+
+
 typedef enum expression_type {
        e_atom,
        e_column,
@@ -71,7 +105,7 @@ typedef struct expression {
         symmetric:1; /* compare between symmetric */
        sql_subtype     tpe;
        int shared;             /* shared variable */
-       void *p;        /* properties for the optimizer */
+       prop *p;        /* properties for the optimizer */
        str comment;
 } sql_exp;
 
@@ -335,7 +369,7 @@ typedef struct relation {
        uint16_t used;
        uint16_t nr_outers;
        int opt;
-       void *p;        /* properties for the optimizer, distribution */
+       prop *p;        /* properties for the optimizer, distribution */
 } sql_rel;
 
 #endif /* SQL_RELATION_H */
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
@@ -1108,7 +1108,7 @@ read_exps(mvc *sql, sql_rel *lrel, sql_r
 }
 
 static sql_exp*
-exp_read_min_or_max(mvc *sql, sql_exp *exp, char *r, int *pos, const char 
*prop_str, rel_prop kind)
+exp_read_min_or_max(mvc *sql, sql_exp *exp, char *r, int *pos, const char 
*prop_str, prop_kind kind)
 {
        atom *a;
        sql_subtype *tpe = exp_subtype(exp);
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -1822,7 +1822,7 @@ exp_is_eqjoin(sql_exp *e, void *dummy)
 }
 
 sql_exp *
-exps_find_prop(list *exps, rel_prop kind)
+exps_find_prop(list *exps, prop_kind kind)
 {
        if (list_empty(exps))
                return NULL;
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -193,7 +193,7 @@ extern bool exp_is_fallible(sql_exp *e);
 extern bool exps_have_fallible(list *l);
 extern bool exps_have_selfref(list *l);
 
-extern sql_exp *exps_find_prop(list *exps, rel_prop kind);
+extern sql_exp *exps_find_prop(list *exps, prop_kind kind);
 
 /* returns 0 when the relation contain the passed expression (or sub 
expressions if subexp is set) else < 0 */
 extern int rel_has_exp(sql_rel *rel, sql_exp *e, bool subexp);
diff --git a/sql/server/rel_prop.c b/sql/server/rel_prop.c
--- a/sql/server/rel_prop.c
+++ b/sql/server/rel_prop.c
@@ -15,7 +15,7 @@
 #include "sql_string.h"
 
 prop *
-prop_create( allocator *sa, rel_prop kind, prop *pre )
+prop_create( allocator *sa, prop_kind kind, prop *pre )
 {
        prop *p = SA_NEW(sa, prop);
 
@@ -70,7 +70,7 @@ prop_remove(allocator *sa, prop *plist, 
 }
 
 prop *
-find_prop(prop *p, rel_prop kind)
+find_prop(prop *p, prop_kind kind)
 {
        while(p) {
                if (p->kind == kind)
@@ -81,7 +81,7 @@ find_prop(prop *p, rel_prop kind)
 }
 
 void *
-find_prop_and_get(prop *p, rel_prop kind)
+find_prop_and_get(prop *p, prop_kind kind)
 {
        prop *found = find_prop(p, kind);
 
diff --git a/sql/server/rel_prop.h b/sql/server/rel_prop.h
--- a/sql/server/rel_prop.h
+++ b/sql/server/rel_prop.h
@@ -11,44 +11,11 @@
 #ifndef _REL_PROP_H_
 #define _REL_PROP_H_
 
-typedef enum rel_prop {
-       PROP_COUNT,     /* Number of expect rows for the relation */
-       PROP_NUNIQUES,  /* Estimated number of distinct rows for the expression 
*/
-       PROP_MIN,       /* min value if available */
-       PROP_MAX,       /* max value if available */
-       PROP_JOINIDX,   /* could use join idx */
-       PROP_HASHIDX,   /* is hash idx */
-       PROP_HASHCOL,   /* could use hash idx */
-       PROP_UKEY,              /* p = list of exps */
-       PROP_REMOTE,    /* uri for remote execution */
-       PROP_USED,      /* number of times exp is used */
-       PROP_GROUPINGS,  /* used by ROLLUP/CUBE/GROUPING SETS, value contains 
the list of sets */
-       PROP_UNNESTING, /* used by unnesting rewriter */
-       PROP_SELECTIVITY        /* selectivity estimate for predicates (dbl, 
0.0-1.0) */
-} rel_prop;
-
-typedef struct prop {
-       rel_prop kind;  /* kind of property */
-       sqlid id;               /* optional id of object involved */
-       union {
-               BUN lval; /* property with simple counts */
-               dbl dval; /* property with estimate */
-               void *pval; /* property value */
-       } value;
-       struct prop *p; /* some relations may have many properties, which are 
kept in a chain list */
-} prop;
-
-/* for REMOTE prop we need to keep a list with tids and uris for the remote 
tables */
-typedef struct tid_uri {
-       sqlid id;
-       const char* uri;
-} tid_uri;
-
-sql_export prop * prop_create( allocator *sa, rel_prop kind, prop *pre );
+sql_export prop * prop_create( allocator *sa, prop_kind kind, prop *pre );
 extern prop * prop_copy( allocator *sa, prop *p);
 extern prop * prop_remove(allocator *sa, prop *plist, prop *p);
-extern prop * find_prop( prop *p, rel_prop kind);
-extern void * find_prop_and_get(prop *p, rel_prop kind);
+extern prop * find_prop( prop *p, prop_kind kind);
+extern void * find_prop_and_get(prop *p, prop_kind kind);
 extern const char * propkind2string( prop *p);
 extern char * propvalue2string(allocator *sa, prop *p);
 extern void free_props(allocator *sa, prop *p);
diff --git a/sql/server/rel_statistics.h b/sql/server/rel_statistics.h
--- a/sql/server/rel_statistics.h
+++ b/sql/server/rel_statistics.h
@@ -69,7 +69,7 @@ statistics_atom_min(mvc *sql, atom *v1, 
 }
 
 static inline void
-set_minmax_property(mvc *sql, sql_exp *e, rel_prop kind, atom *val)
+set_minmax_property(mvc *sql, sql_exp *e, prop_kind kind, atom *val)
 {
        if (val == NULL)
                return;
diff --git a/sql/test/2026/Tests/All b/sql/test/2026/Tests/All
--- a/sql/test/2026/Tests/All
+++ b/sql/test/2026/Tests/All
@@ -1,1 +1,2 @@
 prepared-stmt-bat-leak
+autocommit-after-failed-transaction
diff --git a/sql/test/2026/Tests/autocommit-after-failed-transaction.SQL.py 
b/sql/test/2026/Tests/autocommit-after-failed-transaction.SQL.py
new file mode 100644
--- /dev/null
+++ b/sql/test/2026/Tests/autocommit-after-failed-transaction.SQL.py
@@ -0,0 +1,40 @@
+from os import environ
+import sys
+from MonetDBtesting import tpymonetdb as pymonetdb
+
+
+conn = pymonetdb.connect(database=environ['TSTDB'], port=environ['MAPIPORT'], 
autocommit=True)
+cursor = conn.cursor()
+
+def execute(sqlscript, expected_autocommit, expected_exception=None):
+    print(f'#\n# Execute: {sqlscript}', file=sys.stderr)
+    try:
+        cursor.execute(sqlscript)
+        if expected_exception is not None:
+            print(f"Expected exception containing: {expected_exception}", 
file=sys.stderr)
+            sys.exit(1)
+    except pymonetdb.Error as e:
+        if expected_exception is not None and expected_exception in str(e):
+            print(f"# -> failed as expected: {str(e).strip()}", 
file=sys.stderr)
+        elif isinstance(e, pymonetdb.Error):
+            print(f"# -> {str(e).strip()}", file=sys.stderr)
+            sys.exit(1)
+        else:
+            raise
+    if conn.autocommit == expected_autocommit:
+        print(f"# -> conn.autocommit is {conn.autocommit!r}, as expected", 
file=sys.stderr)
+    else:
+        print(f"conn.autocommit is {conn.autocommit!r}, expected 
{expected_autocommit!r}", file=sys.stderr)
+        sys.exit(1)
+
+
+execute("SELECT 42", True)
+
+# demonstrate happy path
+execute("START TRANSACTION", False)
+execute("COMMIT", True)
+
+execute("START TRANSACTION", False)
+execute("SELECT SELECT FROM SELECT WHERE SELECT = SELECT", False, 
expected_exception='syntax error')
+execute("COMMIT", True, expected_exception='will ROLLBACK')
+
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to