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]