You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-10-24 10:12:58 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			872 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			872 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* Copyright (C) 2014 InfiniDB, Inc.
 | |
|    Copyright (C) 2016 MariaDB Corporaton
 | |
| 
 | |
|    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-1301, USA. */
 | |
| 
 | |
| #define NEED_CALPONT_INTERFACE
 | |
| #include "ha_calpont_impl.h"
 | |
| 
 | |
| #include "ha_calpont_impl_if.h"
 | |
| using namespace cal_impl_if;
 | |
| 
 | |
| #include "configcpp.h"
 | |
| using namespace config;
 | |
| #include "brmtypes.h"
 | |
| using namespace BRM;
 | |
| #include "bytestream.h"
 | |
| using namespace messageqcpp;
 | |
| #include "liboamcpp.h"
 | |
| using namespace oam;
 | |
| #include "cacheutils.h"
 | |
| 
 | |
| #include "errorcodes.h"
 | |
| #include "idberrorinfo.h"
 | |
| #include "errorids.h"
 | |
| using namespace logging;
 | |
| 
 | |
| //#include "resourcemanager.h"
 | |
| 
 | |
| #include "columnstoreversion.h"
 | |
| #include "ha_mcs_sysvars.h"
 | |
| 
 | |
| extern "C"
 | |
| {
 | |
| #define MAXSTRINGLENGTH 50
 | |
| 
 | |
|     const char* PmSmallSideMaxMemory = "pmmaxmemorysmallside";
 | |
| 
 | |
|     const char* SetParmsPrelude = "Updated ";
 | |
|     const char* SetParmsError = "Invalid parameter: ";
 | |
|     const char* InvalidParmSize = "Invalid parameter size: Input value cannot be larger than ";
 | |
| 
 | |
|     const size_t Plen = strlen(SetParmsPrelude);
 | |
|     const size_t Elen = strlen(SetParmsError);
 | |
| 
 | |
|     const char* invalidParmSizeMessage(uint64_t size, size_t& len)
 | |
|     {
 | |
|         static char str[sizeof(InvalidParmSize) + 12] = {0};
 | |
|         std::ostringstream os;
 | |
|         os << InvalidParmSize << size;
 | |
|         len = os.str().length();
 | |
|         strcpy(str, os.str().c_str());
 | |
|         return str;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     const char* calsetparms(UDF_INIT* initid, UDF_ARGS* args,
 | |
|                             char* result, unsigned long* length,
 | |
|                             char* is_null, char* error)
 | |
|     {
 | |
|         char parameter[MAXSTRINGLENGTH];
 | |
|         char valuestr[MAXSTRINGLENGTH];
 | |
|         size_t plen = args->lengths[0];
 | |
|         size_t vlen = args->lengths[1];
 | |
| 
 | |
|         memcpy(parameter, args->args[0], plen);
 | |
|         memcpy(valuestr, args->args[1], vlen);
 | |
| 
 | |
|         parameter[plen] = '\0';
 | |
|         valuestr[vlen] = '\0';
 | |
| 
 | |
|         uint64_t value = Config::uFromText(valuestr);
 | |
| 
 | |
|         THD* thd = current_thd;
 | |
|         uint32_t sessionID = execplan::CalpontSystemCatalog::idb_tid2sid(thd->thread_id);
 | |
| 
 | |
|         const char* msg = SetParmsError;
 | |
|         size_t mlen = Elen;
 | |
|         bool includeInput = true;
 | |
| 
 | |
|         std::string pstr(parameter);
 | |
|         boost::algorithm::to_lower(pstr);
 | |
| 
 | |
|         if (get_fe_conn_info_ptr() == NULL)
 | |
|             set_fe_conn_info_ptr((void*)new cal_connection_info());
 | |
| 
 | |
|         cal_connection_info* ci = reinterpret_cast<cal_connection_info*>(get_fe_conn_info_ptr());
 | |
|         idbassert(ci != 0);
 | |
| 
 | |
|         if (pstr == PmSmallSideMaxMemory)
 | |
|         {
 | |
|             joblist::ResourceManager* rm = joblist::ResourceManager::instance();
 | |
| 
 | |
|             if (rm->getHjTotalUmMaxMemorySmallSide() >= value)
 | |
|             {
 | |
|                 ci->rmParms.push_back(execplan::RMParam(sessionID, execplan::PMSMALLSIDEMEMORY, value));
 | |
| 
 | |
|                 msg = SetParmsPrelude;
 | |
|                 mlen = Plen;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 msg = invalidParmSizeMessage(rm->getHjTotalUmMaxMemorySmallSide(), mlen);
 | |
|                 includeInput = false;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         memcpy(result, msg, mlen);
 | |
| 
 | |
|         if (includeInput)
 | |
|         {
 | |
|             memcpy(result + mlen, parameter, plen);
 | |
|             mlen += plen;
 | |
|             memcpy(result + mlen++, " ", 1);
 | |
|             memcpy(result + mlen, valuestr, vlen);
 | |
|             *length = mlen + vlen;
 | |
|         }
 | |
|         else
 | |
|             *length = mlen;
 | |
| 
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     my_bool calsetparms_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
 | |
|     {
 | |
|         if (args->arg_count != 2 || args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT)
 | |
|         {
 | |
|             strcpy(message, "CALSETPARMS() requires two string arguments");
 | |
|             return 1;
 | |
|         }
 | |
| 
 | |
|         initid->max_length = MAXSTRINGLENGTH;
 | |
| 
 | |
|         char valuestr[MAXSTRINGLENGTH];
 | |
|         size_t vlen = args->lengths[1];
 | |
| 
 | |
|         memcpy(valuestr, args->args[1], vlen--);
 | |
| 
 | |
|         for (size_t i = 0; i < vlen; ++i)
 | |
|             if (!isdigit(valuestr[i]))
 | |
|             {
 | |
|                 strcpy(message, "CALSETPARMS() second argument must be numeric or end in G, M or K");
 | |
|                 return 1;
 | |
|             }
 | |
| 
 | |
|         if (!isdigit(valuestr[vlen]))
 | |
|         {
 | |
|             switch (valuestr[vlen])
 | |
|             {
 | |
|                 case 'G':
 | |
|                 case 'g':
 | |
|                 case 'M':
 | |
|                 case 'm':
 | |
|                 case 'K':
 | |
|                 case 'k':
 | |
|                 case '\0':
 | |
|                     break;
 | |
| 
 | |
|                 default:
 | |
|                     strcpy(message, "CALSETPARMS() second argument must be numeric or end in G, M or K");
 | |
|                     return 1;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     void calsetparms_deinit(UDF_INIT* initid)
 | |
|     {
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     const char* calgetstats(UDF_INIT* initid, UDF_ARGS* args,
 | |
|                             char* result, unsigned long* length,
 | |
|                             char* is_null, char* error)
 | |
|     {
 | |
|         if (get_fe_conn_info_ptr() == NULL)
 | |
|             set_fe_conn_info_ptr((void*)new cal_connection_info());
 | |
| 
 | |
|         cal_connection_info* ci = reinterpret_cast<cal_connection_info*>(get_fe_conn_info_ptr());
 | |
| 
 | |
|         unsigned long l = ci->queryStats.size();
 | |
| 
 | |
|         if (l == 0)
 | |
|         {
 | |
|             *is_null = 1;
 | |
|             return 0;
 | |
|         }
 | |
| 
 | |
|         if (l > 255) l = 255;
 | |
| 
 | |
|         memcpy(result, ci->queryStats.c_str(), l);
 | |
|         *length = l;
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     my_bool calgetstats_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
 | |
|     {
 | |
|         if (args->arg_count != 0)
 | |
|         {
 | |
|             strcpy(message, "CALGETSTATS() takes no arguments");
 | |
|             return 1;
 | |
|         }
 | |
| 
 | |
|         initid->maybe_null = 1;
 | |
|         initid->max_length = 255;
 | |
| 
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     void calgetstats_deinit(UDF_INIT* initid)
 | |
|     {
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     long long calsettrace(UDF_INIT* initid, UDF_ARGS* args,
 | |
|                           char* is_null, char* error)
 | |
|     {
 | |
|         if (get_fe_conn_info_ptr() == NULL)
 | |
|             set_fe_conn_info_ptr((void*)new cal_connection_info());
 | |
| 
 | |
|         cal_connection_info* ci = reinterpret_cast<cal_connection_info*>(get_fe_conn_info_ptr());
 | |
| 
 | |
|         long long oldTrace = ci->traceFlags;
 | |
|         ci->traceFlags = (uint32_t)(*((long long*)args->args[0]));
 | |
|         // keep the vtablemode bit
 | |
|         ci->traceFlags |= (oldTrace & execplan::CalpontSelectExecutionPlan::TRACE_TUPLE_OFF);
 | |
|         ci->traceFlags |= (oldTrace & execplan::CalpontSelectExecutionPlan::TRACE_TUPLE_AUTOSWITCH);
 | |
|         return oldTrace;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     my_bool calsettrace_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
 | |
|     {
 | |
|         if (args->arg_count != 1 || args->arg_type[0] != INT_RESULT)
 | |
|         {
 | |
|             strcpy(message, "CALSETTRACE() requires one INTEGER argument");
 | |
|             return 1;
 | |
|         }
 | |
| 
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     void calsettrace_deinit(UDF_INIT* initid)
 | |
|     {
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
| // Return 1 if system is ready for reads or 0 if not.
 | |
|     long long mcssystemready(UDF_INIT* initid, UDF_ARGS* args,
 | |
|                              char* is_null, char* error)
 | |
|     {
 | |
|         long long rtn = 0;
 | |
|         Oam oam;
 | |
|         DBRM dbrm(true);
 | |
|         SystemStatus systemstatus;
 | |
| 
 | |
|         try
 | |
|         {
 | |
|             oam.getSystemStatus(systemstatus);
 | |
| 
 | |
|             if (systemstatus.SystemOpState == ACTIVE
 | |
|                     && dbrm.getSystemReady()
 | |
|                     && dbrm.getSystemQueryReady())
 | |
|             {
 | |
|                 return 1;
 | |
|             }
 | |
|         }
 | |
|         catch (...)
 | |
|         {
 | |
|             *error = 1;
 | |
|         }
 | |
| 
 | |
|         return rtn;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     my_bool mcssystemready_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
 | |
|     {
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     void mcssystemready_deinit(UDF_INIT* initid)
 | |
|     {
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
| // Return non-zero if system is read only; 0 if writeable
 | |
|     long long mcssystemreadonly(UDF_INIT* initid, UDF_ARGS* args,
 | |
|                                 char* is_null, char* error)
 | |
|     {
 | |
|         long long rtn = 0;
 | |
|         DBRM dbrm(true);
 | |
| 
 | |
|         try
 | |
|         {
 | |
|             if (dbrm.getSystemSuspended())
 | |
|             {
 | |
|                 rtn = 1;
 | |
|             }
 | |
| 
 | |
|             if (dbrm.isReadWrite() > 0) // Returns 0 for writable, 5 for read only
 | |
|             {
 | |
|                 rtn = 2;
 | |
|             }
 | |
|         }
 | |
|         catch (...)
 | |
|         {
 | |
|             *error = 1;
 | |
|             rtn = 1;
 | |
|         }
 | |
| 
 | |
|         return rtn;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     my_bool mcssystemreadonly_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
 | |
|     {
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     void mcssystemreadonly_deinit(UDF_INIT* initid)
 | |
|     {
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
| // Return non-zero if this is the primary UM; 0 if not primary
 | |
|     long long mcssystemprimary(UDF_INIT* initid, UDF_ARGS* args,
 | |
|                                 char* is_null, char* error)
 | |
|     {
 | |
|         long long rtn = 0;
 | |
|         Oam oam;
 | |
|         std::string PrimaryUMModuleName;
 | |
|         std::string localModule;
 | |
|         oamModuleInfo_t st;
 | |
| 
 | |
|         try
 | |
|         {
 | |
|             st = oam.getModuleInfo();
 | |
|             localModule = boost::get<0>(st);
 | |
|             PrimaryUMModuleName = config::Config::makeConfig()->getConfig("SystemConfig", "PrimaryUMModuleName");
 | |
| 
 | |
|             if (boost::iequals(localModule, PrimaryUMModuleName))
 | |
|                 rtn = 1;
 | |
|             if (PrimaryUMModuleName == "unassigned")
 | |
|                 rtn = 1;
 | |
|         }
 | |
|         catch (std::runtime_error& e)
 | |
|         {
 | |
|             // It's difficult to return an error message from a numerical UDF
 | |
|             //string msg = string("ERROR: Problem getting Primary UM Module Name. ") + e.what();
 | |
|             *error = 1;
 | |
|         }
 | |
|         catch (...)
 | |
|         {
 | |
|             *error = 1;
 | |
|         }
 | |
|         return rtn;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     my_bool mcssystemprimary_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
 | |
|     {
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     void mcssystemprimary_deinit(UDF_INIT* initid)
 | |
|     {
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     my_bool calviewtablelock_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
 | |
|     {
 | |
|         if (args->arg_count == 2 && (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT))
 | |
|         {
 | |
|             strcpy(message, "CALVIEWTABLELOCK() requires two string arguments");
 | |
|             return 1;
 | |
|         }
 | |
|         else if ((args->arg_count == 1) && (args->arg_type[0] != STRING_RESULT ) )
 | |
|         {
 | |
|             strcpy(message, "CALVIEWTABLELOCK() requires one string argument");
 | |
|             return 1;
 | |
|         }
 | |
|         else if (args->arg_count > 2 )
 | |
|         {
 | |
|             strcpy(message, "CALVIEWTABLELOCK() takes one or two arguments only");
 | |
|             return 1;
 | |
|         }
 | |
|         else if (args->arg_count == 0 )
 | |
|         {
 | |
|             strcpy(message, "CALVIEWTABLELOCK() requires at least one argument");
 | |
|             return 1;
 | |
|         }
 | |
| 
 | |
|         initid->maybe_null = 1;
 | |
|         initid->max_length = 255;
 | |
| 
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     const char* calviewtablelock(UDF_INIT* initid, UDF_ARGS* args,
 | |
|                                  char* result, unsigned long* length,
 | |
|                                  char* is_null, char* error)
 | |
|     {
 | |
|         THD* thd = current_thd;
 | |
| 
 | |
|         if (get_fe_conn_info_ptr() == NULL)
 | |
|             set_fe_conn_info_ptr((void*)new cal_connection_info());
 | |
| 
 | |
|         cal_connection_info* ci = reinterpret_cast<cal_connection_info*>(get_fe_conn_info_ptr());
 | |
|         execplan::CalpontSystemCatalog::TableName tableName;
 | |
| 
 | |
|         if ( args->arg_count == 2 )
 | |
|         {
 | |
|             tableName.schema = args->args[0];
 | |
|             tableName.table = args->args[1];
 | |
|         }
 | |
|         else if ( args->arg_count == 1 )
 | |
|         {
 | |
|             tableName.table = args->args[0];
 | |
| 
 | |
|             if (thd->db.length)
 | |
|                 tableName.schema = thd->db.str;
 | |
|             else
 | |
|             {
 | |
|               std::string msg("No schema information provided");
 | |
|                 memcpy(result, msg.c_str(), msg.length());
 | |
|                 *length = msg.length();
 | |
|                 return result;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if ( !ci->dmlProc )
 | |
|         {
 | |
|             ci->dmlProc = new MessageQueueClient("DMLProc");
 | |
|             //cout << "viewtablelock starts a new client " << ci->dmlProc << " for session " << thd->thread_id << endl;
 | |
|         }
 | |
| 
 | |
|         std::string lockinfo = ha_calpont_impl_viewtablelock(*ci, tableName);
 | |
| 
 | |
|         memcpy(result, lockinfo.c_str(), lockinfo.length());
 | |
|         *length = lockinfo.length();
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     void calviewtablelock_deinit(UDF_INIT* initid)
 | |
|     {
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     my_bool calcleartablelock_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
 | |
|     {
 | |
|         if ((args->arg_count != 1) || (args->arg_type[0] != INT_RESULT))
 | |
|         {
 | |
|             strcpy(message,
 | |
|                    "CALCLEARTABLELOCK() requires one integer argument (the lockID)");
 | |
|             return 1;
 | |
|         }
 | |
| 
 | |
|         initid->maybe_null = 1;
 | |
|         initid->max_length = 255;
 | |
| 
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     const char* calcleartablelock(UDF_INIT* initid, UDF_ARGS* args,
 | |
|                                   char* result, unsigned long* length,
 | |
|                                   char* is_null, char* error)
 | |
|     {
 | |
|         if (get_fe_conn_info_ptr() == NULL)
 | |
|             set_fe_conn_info_ptr((void*)new cal_connection_info());
 | |
| 
 | |
|         cal_connection_info* ci = reinterpret_cast<cal_connection_info*>(
 | |
|                                       get_fe_conn_info_ptr());
 | |
|         long long lockID = *reinterpret_cast<long long*>(args->args[0]);
 | |
| 
 | |
|         if ( !ci->dmlProc )
 | |
|         {
 | |
|             ci->dmlProc = new MessageQueueClient("DMLProc");
 | |
|             //cout << "cleartablelock starts a new client " << ci->dmlProc << " for session " << thd->thread_id << endl;
 | |
|         }
 | |
| 
 | |
|         unsigned long long uLockID = lockID;
 | |
|         std::string lockinfo = ha_calpont_impl_cleartablelock(*ci, uLockID);
 | |
| 
 | |
|         memcpy(result, lockinfo.c_str(), lockinfo.length());
 | |
|         *length = lockinfo.length();
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     void calcleartablelock_deinit(UDF_INIT* initid)
 | |
|     {
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     my_bool callastinsertid_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
 | |
|     {
 | |
|         if (args->arg_count == 2 && (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT))
 | |
|         {
 | |
|             strcpy(message, "CALLASTINSRTID() requires two string arguments");
 | |
|             return 1;
 | |
|         }
 | |
|         else if ((args->arg_count == 1) && (args->arg_type[0] != STRING_RESULT ) )
 | |
|         {
 | |
|             strcpy(message, "CALLASTINSERTID() requires one string argument");
 | |
|             return 1;
 | |
|         }
 | |
|         else if (args->arg_count > 2 )
 | |
|         {
 | |
|             strcpy(message, "CALLASTINSERTID() takes one or two arguments only");
 | |
|             return 1;
 | |
|         }
 | |
|         else if (args->arg_count == 0 )
 | |
|         {
 | |
|             strcpy(message, "CALLASTINSERTID() requires at least one argument");
 | |
|             return 1;
 | |
|         }
 | |
| 
 | |
|         initid->maybe_null = 1;
 | |
|         initid->max_length = 255;
 | |
| 
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     long long callastinsertid(UDF_INIT* initid, UDF_ARGS* args,
 | |
|                               char* is_null, char* error)
 | |
|     {
 | |
|         THD* thd = current_thd;
 | |
| 
 | |
|         execplan::CalpontSystemCatalog::TableName tableName;
 | |
|         uint64_t nextVal = 0;
 | |
| 
 | |
|         if ( args->arg_count == 2 )
 | |
|         {
 | |
|             tableName.schema = args->args[0];
 | |
|             tableName.table = args->args[1];
 | |
|         }
 | |
|         else if ( args->arg_count == 1 )
 | |
|         {
 | |
|             tableName.table = args->args[0];
 | |
| 
 | |
|             if (thd->db.length)
 | |
|                 tableName.schema = thd->db.str;
 | |
|             else
 | |
|             {
 | |
|                 return -1;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         boost::shared_ptr<execplan::CalpontSystemCatalog> csc =
 | |
|             execplan::CalpontSystemCatalog::makeCalpontSystemCatalog(
 | |
|                 execplan::CalpontSystemCatalog::idb_tid2sid(thd->thread_id));
 | |
|         csc->identity(execplan::CalpontSystemCatalog::FE);
 | |
| 
 | |
|         try
 | |
|         {
 | |
|             nextVal = csc->nextAutoIncrValue(tableName);
 | |
|         }
 | |
|         catch (std::exception&)
 | |
|         {
 | |
|           std::string msg("No such table found during autincrement");
 | |
|             setError(thd, ER_INTERNAL_ERROR, msg);
 | |
|             return nextVal;
 | |
|         }
 | |
| 
 | |
|         if (nextVal == AUTOINCR_SATURATED)
 | |
|         {
 | |
|             setError(thd, ER_INTERNAL_ERROR, IDBErrorInfo::instance()->errorMsg(ERR_EXCEED_LIMIT));
 | |
|             return nextVal;
 | |
|         }
 | |
| 
 | |
|         //@Bug 3559. Return a message for table without autoincrement column.
 | |
|         if (nextVal == 0)
 | |
|         {
 | |
|           std::string msg("Autoincrement does not exist for this table.");
 | |
|             setError(thd, ER_INTERNAL_ERROR, msg);
 | |
|             return nextVal;
 | |
|         }
 | |
| 
 | |
|         return (nextVal - 1);
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     void callastinsertid_deinit(UDF_INIT* initid)
 | |
|     {
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     void calflushcache_deinit(UDF_INIT* initid)
 | |
|     {
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     long long calflushcache(UDF_INIT* initid, UDF_ARGS* args,
 | |
|                             char* is_null, char* error)
 | |
|     {
 | |
|         return static_cast<long long>(cacheutils::flushPrimProcCache());
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     my_bool calflushcache_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
 | |
|     {
 | |
|         if (args->arg_count != 0)
 | |
|         {
 | |
|             strcpy(message, "CALFLUSHCACHE() takes no arguments");
 | |
|             return 1;
 | |
|         }
 | |
| 
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
|     static const unsigned long TraceSize = 16 * 1024;
 | |
| 
 | |
| //mysqld will call this with only 766 bytes available in result no matter what we asked for in calgettrace_init()
 | |
| // if we return a pointer that is not result, mysqld will take our pointer and use it, freeing up result
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     const char* calgettrace(UDF_INIT* initid, UDF_ARGS* args,
 | |
|                             char* result, unsigned long* length,
 | |
|                             char* is_null, char* error)
 | |
|     {
 | |
|         const std::string* msgp;
 | |
|         int flags = 0;
 | |
| 
 | |
|         if (args->arg_count > 0)
 | |
|         {
 | |
|             if (args->arg_type[0] == INT_RESULT)
 | |
|             {
 | |
|                 flags = *reinterpret_cast<int*>(args->args[0]);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (get_fe_conn_info_ptr() == NULL)
 | |
|             set_fe_conn_info_ptr((void*)new cal_connection_info());
 | |
| 
 | |
|         cal_connection_info* ci = reinterpret_cast<cal_connection_info*>(get_fe_conn_info_ptr());
 | |
| 
 | |
|         if (flags > 0)
 | |
|             //msgp = &connMap[sessionID].extendedStats;
 | |
|             msgp = &ci->extendedStats;
 | |
|         else
 | |
|             //msgp = &connMap[sessionID].miniStats;
 | |
|             msgp = &ci->miniStats;
 | |
| 
 | |
|         unsigned long l = msgp->size();
 | |
| 
 | |
|         if (l == 0)
 | |
|         {
 | |
|             *is_null = 1;
 | |
|             return 0;
 | |
|         }
 | |
| 
 | |
|         if (l > TraceSize) l = TraceSize;
 | |
| 
 | |
|         *length = l;
 | |
|         return msgp->c_str();
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     my_bool calgettrace_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
 | |
|     {
 | |
| #if 0
 | |
| 
 | |
|         if (args->arg_count != 0)
 | |
|         {
 | |
|             strcpy(message, "CALGETTRACE() takes no arguments");
 | |
|             return 1;
 | |
|         }
 | |
| 
 | |
| #endif
 | |
|         initid->maybe_null = 1;
 | |
|         initid->max_length = TraceSize;
 | |
| 
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     void calgettrace_deinit(UDF_INIT* initid)
 | |
|     {
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     const char* calgetversion(UDF_INIT* initid, UDF_ARGS* args,
 | |
|                               char* result, unsigned long* length,
 | |
|                               char* is_null, char* error)
 | |
|     {
 | |
|       std::string version(columnstore_version);
 | |
|         *length = version.size();
 | |
|         memcpy(result, version.c_str(), *length);
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     my_bool calgetversion_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
 | |
|     {
 | |
|         if (args->arg_count != 0)
 | |
|         {
 | |
|             strcpy(message, "CALGETVERSION() takes no arguments");
 | |
|             return 1;
 | |
|         }
 | |
| 
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     void calgetversion_deinit(UDF_INIT* initid)
 | |
|     {
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     const char* calgetsqlcount(UDF_INIT* initid, UDF_ARGS* args,
 | |
|                                char* result, unsigned long* length,
 | |
|                                char* is_null, char* error)
 | |
|     {
 | |
|         if (get_fe_conn_info_ptr() == NULL)
 | |
|             set_fe_conn_info_ptr((void*)new cal_connection_info());
 | |
| 
 | |
|         cal_connection_info* ci = reinterpret_cast<cal_connection_info*>(get_fe_conn_info_ptr());
 | |
|         idbassert(ci != 0);
 | |
| 
 | |
|         MessageQueueClient* mqc = 0;
 | |
|         mqc = new MessageQueueClient("ExeMgr1");
 | |
| 
 | |
|         ByteStream msg;
 | |
|         ByteStream::quadbyte runningSql, waitingSql;
 | |
|         ByteStream::quadbyte qb = 5;
 | |
|         msg << qb;
 | |
|         mqc->write(msg);
 | |
| 
 | |
|         //get ExeMgr response
 | |
|         msg.restart();
 | |
|         msg = mqc->read();
 | |
| 
 | |
|         if (msg.length() == 0)
 | |
|         {
 | |
|             memcpy(result, "Lost connection to ExeMgr", *length);
 | |
|             return result;
 | |
|         }
 | |
| 
 | |
|         msg >> runningSql;
 | |
|         msg >> waitingSql;
 | |
|         delete mqc;
 | |
| 
 | |
|         char ans[128];
 | |
|         sprintf(ans, "Running SQL statements %d, Waiting SQL statments %d", runningSql, waitingSql);
 | |
|         *length = strlen(ans);
 | |
|         memcpy(result, ans, *length);
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     my_bool calgetsqlcount_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
 | |
|     {
 | |
|         if (args->arg_count != 0)
 | |
|         {
 | |
|             strcpy(message, "CALGETSQLCOUNT() takes no arguments");
 | |
|             return 1;
 | |
|         }
 | |
| 
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
|     __declspec(dllexport)
 | |
| #endif
 | |
|     void calgetsqlcount_deinit(UDF_INIT* initid)
 | |
|     {
 | |
|     }
 | |
| 
 | |
| 
 | |
| } //extern "C"
 |