summaryrefslogtreecommitdiffstats
path: root/storage/connect/user_connect.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/connect/user_connect.cc')
-rw-r--r--storage/connect/user_connect.cc192
1 files changed, 192 insertions, 0 deletions
diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc
new file mode 100644
index 00000000..ba446a3e
--- /dev/null
+++ b/storage/connect/user_connect.cc
@@ -0,0 +1,192 @@
+/* Copyright (C) MariaDB Corporation Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+/**
+ @file user_connect.cc
+
+ @brief
+ Implements the user_connect class.
+
+ @details
+ To support multi_threading, each query creates and use a PlugDB "user"
+ that is a connection with its personnal memory allocation.
+
+ @note
+ Author Olivier Bertrand
+*/
+
+/****************************************************************************/
+/* Author: Olivier Bertrand -- bertrandop@gmail.com -- 2004-2020 */
+/****************************************************************************/
+#ifdef USE_PRAGMA_IMPLEMENTATION
+#pragma implementation // gcc: Class implementation
+#endif
+
+#define DONT_DEFINE_VOID
+#define MYSQL_SERVER
+#include <my_global.h>
+#include "sql_class.h"
+#undef OFFSET
+
+#define NOPARSE
+#include "osutil.h"
+#include "global.h"
+#include "plgdbsem.h"
+#include "connect.h"
+#include "user_connect.h"
+#include "mycat.h"
+
+extern pthread_mutex_t usrmut;
+
+/****************************************************************************/
+/* Initialize the user_connect static member. */
+/****************************************************************************/
+PCONNECT user_connect::to_users= NULL;
+
+/****************************************************************************/
+/* Get the work_size SESSION variable value . */
+/****************************************************************************/
+size_t GetWorkSize(void);
+void SetWorkSize(size_t);
+
+/* -------------------------- class user_connect -------------------------- */
+
+/****************************************************************************/
+/* Constructor. */
+/****************************************************************************/
+user_connect::user_connect(THD *thd)
+{
+ thdp= thd;
+ next= NULL;
+ previous= NULL;
+ g= NULL;
+ last_query_id= 0;
+ count= 0;
+
+ // Statistics
+ nrd= fnd= nfd= 0;
+ tb1= 0;
+} // end of user_connect constructor
+
+
+/****************************************************************************/
+/* Destructor. */
+/****************************************************************************/
+user_connect::~user_connect()
+{
+ // Terminate CONNECT and Plug-like environment, should return NULL
+ g= CntExit(g);
+} // end of user_connect destructor
+
+
+/****************************************************************************/
+/* Initialization. */
+/****************************************************************************/
+bool user_connect::user_init()
+{
+ // Initialize Plug-like environment
+ size_t worksize= GetWorkSize();
+ PACTIVITY ap= NULL;
+ PDBUSER dup= NULL;
+
+ // Areasize= 64M because of VEC tables. Should be parameterisable
+//g= PlugInit(NULL, 67108864);
+//g= PlugInit(NULL, 134217728); // 128M was because of old embedded tests
+ g= PlugInit(NULL, (size_t)worksize);
+
+ // Check whether the initialization is complete
+ if (!g || !g->Sarea || PlugSubSet(g->Sarea, g->Sarea_Size)
+ || !(dup= PlgMakeUser(g))) {
+ if (g)
+ printf("%s\n", g->Message);
+
+ (void) PlugExit(g);
+
+ if (dup)
+ free(dup);
+
+ return true;
+ } // endif g->
+
+ dup->Catalog= new MYCAT(NULL);
+
+ ap= new ACTIVITY;
+ memset(ap, 0, sizeof(ACTIVITY));
+ strcpy(ap->Ap_Name, "CONNECT");
+ g->Activityp= ap;
+ g->Activityp->Aptr= dup;
+
+ pthread_mutex_lock(&usrmut);
+ next= to_users;
+ to_users= this;
+
+ if (next)
+ next->previous= this;
+
+ count = 1;
+ pthread_mutex_unlock(&usrmut);
+
+ last_query_id= thdp->query_id;
+ return false;
+} // end of user_init
+
+
+void user_connect::SetHandler(ha_connect *hc)
+{
+ PDBUSER dup= (PDBUSER)g->Activityp->Aptr;
+ MYCAT *mc= (MYCAT*)dup->Catalog;
+ mc->SetHandler(hc);
+}
+
+/****************************************************************************/
+/* Check whether we begin a new query and if so cleanup the previous one. */
+/****************************************************************************/
+bool user_connect::CheckCleanup(bool force)
+{
+ if (thdp->query_id > last_query_id || force) {
+ size_t worksize = GetWorkSize();
+
+ PlugCleanup(g, true);
+
+ if (worksize != g->Sarea_Size) {
+ FreeSarea(g);
+ g->Saved_Size = g->Sarea_Size;
+
+ // Check whether the work area could be allocated
+ if (AllocSarea(g, worksize)) {
+ AllocSarea(g, g->Saved_Size);
+ SetWorkSize(g->Sarea_Size); // Was too big
+ } // endif sarea
+
+ } // endif worksize
+
+ PlugSubSet(g->Sarea, g->Sarea_Size);
+ g->Xchk = NULL;
+ g->Createas = false;
+ g->Alchecked = 0;
+ g->Mrr = 0;
+ g->More = 0;
+ g->Saved_Size = 0;
+ last_query_id= thdp->query_id;
+
+ if (trace(65) && !force)
+ printf("=====> Begin new query %llu\n", last_query_id);
+
+ return true;
+ } // endif query_id
+
+ return false;
+} // end of CheckCleanup
+