Changeset: b66d4cc9a0b1 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/b66d4cc9a0b1
Modified Files:
        gdk/gdk_heap.c
        gdk/gdk_system.h
        monetdb5/mal/mal_client.c
        sql/backends/monet5/sql_scenario.c
        sql/backends/monet5/sql_user.c
        sql/backends/monet5/sql_user.h
Branch: default
Log Message:

Use max_memory column in sys.db_user_info table for maximum transient heap 
space allowed.


diffs (193 lines):

diff --git a/gdk/gdk_heap.c b/gdk/gdk_heap.c
--- a/gdk/gdk_heap.c
+++ b/gdk/gdk_heap.c
@@ -180,8 +180,16 @@ HEAPalloc(Heap *h, size_t nitems, size_t
        h->newstorage = h->storage;
        if (h->farmid == 1) {
                QryCtx *qc = MT_thread_get_qry_ctx();
-               if (qc)
-                       ATOMIC_ADD(&qc->datasize, h->size);
+               ATOMIC_BASE_TYPE sz = 0;
+               if (qc) {
+                       sz = ATOMIC_ADD(&qc->datasize, h->size);
+                       sz += h->size;
+                       if (qc->maxmem > 0 && sz > qc->maxmem) {
+                               HEAPfree(h, true);
+                               GDKerror("Query using too much memory.\n");
+                               return GDK_FAIL;
+                       }
+               }
        }
        return GDK_SUCCEED;
 }
@@ -249,8 +257,15 @@ HEAPextend(Heap *h, size_t size, bool ma
                        h->base = p;
                        if (h->farmid == 1) {
                                QryCtx *qc = MT_thread_get_qry_ctx();
-                               if (qc)
-                                       ATOMIC_ADD(&qc->datasize, size - osize);
+                               ATOMIC_BASE_TYPE sz = 0;
+                               if (qc) {
+                                       sz = ATOMIC_ADD(&qc->datasize, size - 
osize);
+                                       sz += size - osize;
+                                       if (qc->maxmem > 0 && sz > qc->maxmem) {
+                                               GDKerror("Query using too much 
memory.\n");
+                                               return GDK_FAIL;
+                                       }
+                               }
                        }
                        return GDK_SUCCEED; /* success */
                }
@@ -278,8 +293,15 @@ HEAPextend(Heap *h, size_t size, bool ma
                        if (h->base) {
                                if (h->farmid == 1) {
                                        QryCtx *qc = MT_thread_get_qry_ctx();
-                                       if (qc)
-                                               ATOMIC_ADD(&qc->datasize, size 
- osize);
+                                       ATOMIC_BASE_TYPE sz = 0;
+                                       if (qc) {
+                                               sz = ATOMIC_ADD(&qc->datasize, 
size - osize);
+                                               sz += size - osize;
+                                               if (qc->maxmem > 0 && sz > 
qc->maxmem) {
+                                                       GDKerror("Query using 
too much memory.\n");
+                                                       return GDK_FAIL;
+                                               }
+                                       }
                                }
                                return GDK_SUCCEED; /* success */
                        }
@@ -314,8 +336,15 @@ HEAPextend(Heap *h, size_t size, bool ma
                                        HEAPfree(&bak, false);
                                        if (h->farmid == 1) {
                                                QryCtx *qc = 
MT_thread_get_qry_ctx();
-                                               if (qc)
-                                                       
ATOMIC_ADD(&qc->datasize, h->size);
+                                               ATOMIC_BASE_TYPE sz = 0;
+                                               if (qc) {
+                                                       sz = 
ATOMIC_ADD(&qc->datasize, h->size);
+                                                       sz += h->size;
+                                                       if (qc->maxmem > 0 && 
sz > qc->maxmem) {
+                                                               GDKerror("Query 
using too much memory.\n");
+                                                               return GDK_FAIL;
+                                                       }
+                                               }
                                        }
                                        return GDK_SUCCEED;
                                }
@@ -798,8 +827,16 @@ HEAPload_intern(Heap *h, const char *nme
        h->dirty = false;       /* we just read it, so it's clean */
        if (h->farmid == 1) {
                QryCtx *qc = MT_thread_get_qry_ctx();
-               if (qc)
-                       ATOMIC_ADD(&qc->datasize, h->size);
+               ATOMIC_BASE_TYPE sz = 0;
+               if (qc) {
+                       sz = ATOMIC_ADD(&qc->datasize, h->size);
+                       sz += h->size;
+                       if (qc->maxmem > 0 && sz > qc->maxmem) {
+                               HEAPfree(h, true);
+                               GDKerror("Query using too much memory.\n");
+                               return GDK_FAIL;
+                       }
+               }
        }
        return GDK_SUCCEED;
 }
diff --git a/gdk/gdk_system.h b/gdk/gdk_system.h
--- a/gdk/gdk_system.h
+++ b/gdk/gdk_system.h
@@ -166,6 +166,7 @@ typedef struct QryCtx {
        lng starttime;
        lng querytimeout;
        ATOMIC_TYPE datasize;
+       ATOMIC_BASE_TYPE maxmem;
 } QryCtx;
 
 gdk_export bool MT_thread_init(void);
diff --git a/monetdb5/mal/mal_client.c b/monetdb5/mal/mal_client.c
--- a/monetdb5/mal/mal_client.c
+++ b/monetdb5/mal/mal_client.c
@@ -267,6 +267,7 @@ MCinitClientRecord(Client c, oid user, b
        c->sessiontimeout = 0;
        c->qryctx.starttime = 0;
        ATOMIC_SET(&c->qryctx.datasize, 0);
+       c->qryctx.maxmem = 0;
        c->itrace = 0;
        c->errbuf = 0;
 
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
@@ -269,6 +269,11 @@ SQLprepareClient(Client c, int login)
                        default:
                                break;
                }
+               lng maxmem;
+               if (monet5_user_get_max_memory(m, m->user_id, &maxmem) == 0)
+                       c->qryctx.maxmem = (ATOMIC_BASE_TYPE) (maxmem > 0 ? 
maxmem : 0);
+               else
+                       c->qryctx.maxmem = 0;
        }
 
        if (c->handshake_options) {
diff --git a/sql/backends/monet5/sql_user.c b/sql/backends/monet5/sql_user.c
--- a/sql/backends/monet5/sql_user.c
+++ b/sql/backends/monet5/sql_user.c
@@ -968,3 +968,46 @@ monet5_user_set_def_schema(mvc *m, oid u
        }
        return res;
 }
+
+int
+monet5_user_get_max_memory(mvc *m, int user, lng *maxmem)
+{
+       oid rid;
+       sql_schema *sys = NULL;
+       sql_table *user_info = NULL;
+       sql_table *auths = NULL;
+       str username = NULL;
+       sqlstore *store = m->session->tr->store;
+       lng max_memory = 0;
+
+       if (!m->session->tr->active) {
+               switch (mvc_trans(m)) {
+               case -1:
+                       return -1;
+               case -3:
+                       return -3;
+               default:
+                       break;
+               }
+
+               sys = find_sql_schema(m->session->tr, "sys");
+               auths = find_sql_table(m->session->tr, sys, "auths");
+               user_info = find_sql_table(m->session->tr, sys, "db_user_info");
+
+               rid = store->table_api.column_find_row(m->session->tr, 
find_sql_column(auths, "id"), &user, NULL);
+               if (is_oid_nil(rid))
+                       return -2;
+               if (!(username = 
store->table_api.column_find_value(m->session->tr, find_sql_column(auths, 
"name"), rid)))
+                       return -1;
+               rid = store->table_api.column_find_row(m->session->tr, 
find_sql_column(user_info, "name"), username, NULL);
+               _DELETE(username);
+
+               if (!is_oid_nil(rid))
+                       max_memory = 
store->table_api.column_find_lng(m->session->tr, find_sql_column(user_info, 
"max_memory"), rid);
+               mvc_rollback(m, 0, NULL, false);
+       }
+
+       *maxmem = max_memory > 0 ? max_memory : 0;
+
+       return 0;
+}
diff --git a/sql/backends/monet5/sql_user.h b/sql/backends/monet5/sql_user.h
--- a/sql/backends/monet5/sql_user.h
+++ b/sql/backends/monet5/sql_user.h
@@ -13,6 +13,7 @@
 extern void monet5_user_init(backend_functions *be_funcs);
 extern int monet5_user_set_def_schema(mvc *m, oid user /* mal user id */);
 extern int monet5_user_get_def_schema(mvc *m, int user /* sql user id */, str 
*schema);
+extern int monet5_user_get_max_memory(mvc *m, int user /* sql user id */, lng 
*maxmem);
 
 extern str monet5_password_hash(mvc *m, const char *username);
 
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to