OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Execute.h File Reference
#include <algorithm>
#include <atomic>
#include <condition_variable>
#include <cstddef>
#include <cstdlib>
#include <deque>
#include <functional>
#include <limits>
#include <map>
#include <mutex>
#include <queue>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <llvm/IR/Function.h>
#include <llvm/IR/Value.h>
#include <llvm/Linker/Linker.h>
#include <llvm/Transforms/Utils/ValueMapper.h>
#include <rapidjson/document.h>
#include "QueryEngine/AggregatedColRange.h"
#include "QueryEngine/BufferCompaction.h"
#include "QueryEngine/CartesianProduct.h"
#include "QueryEngine/CgenState.h"
#include "QueryEngine/CodeCache.h"
#include "QueryEngine/CodeCacheAccessor.h"
#include "QueryEngine/CompilationOptions.h"
#include "QueryEngine/DateTimeUtils.h"
#include "QueryEngine/Descriptors/QueryCompilationDescriptor.h"
#include "QueryEngine/Descriptors/QueryFragmentDescriptor.h"
#include "QueryEngine/ExecutionKernel.h"
#include "QueryEngine/ExecutorResourceMgr/ExecutorResourceMgr.h"
#include "QueryEngine/ExternalCacheInvalidators.h"
#include "QueryEngine/GpuSharedMemoryContext.h"
#include "QueryEngine/GroupByAndAggregate.h"
#include "QueryEngine/JoinHashTable/HashJoin.h"
#include "QueryEngine/LoopControlFlow/JoinLoop.h"
#include "QueryEngine/NvidiaKernel.h"
#include "QueryEngine/PlanState.h"
#include "QueryEngine/QueryPlanDagCache.h"
#include "QueryEngine/RelAlgExecutionUnit.h"
#include "QueryEngine/RelAlgTranslator.h"
#include "QueryEngine/ResultSetRecyclerHolder.h"
#include "QueryEngine/StringDictionaryGenerations.h"
#include "QueryEngine/TableGenerations.h"
#include "QueryEngine/TargetMetaInfo.h"
#include "QueryEngine/WindowContext.h"
#include "DataMgr/Chunk/Chunk.h"
#include "Logger/Logger.h"
#include "Shared/DbObjectKeys.h"
#include "Shared/LruCache.h"
#include "Shared/SystemParameters.h"
#include "Shared/funcannotations.h"
#include "Shared/heavyai_shared_mutex.h"
#include "Shared/measure.h"
#include "Shared/thread_count.h"
#include "Shared/toString.h"
#include "StringDictionary/StringDictionary.h"
#include "StringDictionary/StringDictionaryProxy.h"
#include "ThriftHandler/CommandLineOptions.h"
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  QuerySessionStatus
 
class  WatchdogException
 
class  CompilationRetryNoLazyFetch
 
class  CompilationRetryNewScanLimit
 
class  TooManyLiterals
 
class  CompilationRetryNoCompaction
 
class  QueryMustRunOnCpu
 
class  ParseIRError
 
class  StringConstInResultSet
 
struct  TableUpdateMetadata
 
class  UpdateLogForFragment
 
struct  CardinalityCacheKey
 
struct  std::hash< CardinalityCacheKey >
 
class  Executor
 
struct  Executor::JoinHashTableOrError
 
struct  Executor::GroupColLLVMValue
 
class  Executor::CgenStateManager
 
class  Executor::FetchCacheAnchor
 
struct  Executor::ExecutorMutexHolder
 

Namespaces

 ExecutorResourceMgr_Namespace
 
 std
 
 foreign_storage
 

Typedefs

using QueryCompilationDescriptorOwned = std::unique_ptr< QueryCompilationDescriptor >
 
using QueryMemoryDescriptorOwned = std::unique_ptr< QueryMemoryDescriptor >
 
using QuerySessionId = std::string
 
using CurrentQueryStatus = std::pair< QuerySessionId, std::string >
 
using InterruptFlagMap = std::map< QuerySessionId, bool >
 
using QuerySessionMap = std::map< const QuerySessionId, std::map< std::string, QuerySessionStatus >>
 
using RowDataProvider = Fragmenter_Namespace::RowDataProvider
 
using ColumnToFragmentsMap = std::map< const ColumnDescriptor *, std::set< int32_t >>
 
using TableToFragmentIds = std::map< int32_t, std::set< int32_t >>
 
using LLVMValueVector = std::vector< llvm::Value * >
 

Enumerations

enum  FragmentSkipStatus { SKIPPABLE, NOT_SKIPPABLE, INVALID }
 

Functions

llvm::Value * get_arg_by_name (llvm::Function *func, const std::string &name)
 
llvm::Value * get_arg_by_index (llvm::Function *func, unsigned const index)
 
unsigned get_index_by_name (llvm::Function *func, const std::string &name)
 
uint32_t log2_bytes (const uint32_t bytes)
 
const ColumnDescriptorget_column_descriptor (const shared::ColumnKey &column_key)
 
const Analyzer::Exprextract_cast_arg (const Analyzer::Expr *expr)
 
std::string numeric_type_name (const SQLTypeInfo &ti)
 
const ColumnDescriptorget_column_descriptor_maybe (const shared::ColumnKey &column_key)
 
const ResultSetPtrget_temporary_table (const TemporaryTables *temporary_tables, const int table_id)
 
const SQLTypeInfo get_column_type (const int col_id, const int table_id, const ColumnDescriptor *cd, const TemporaryTables *temporary_tables)
 
std::ostream & operator<< (std::ostream &, FetchResult const &)
 
std::string get_null_check_suffix (const SQLTypeInfo &lhs_ti, const SQLTypeInfo &rhs_ti)
 
bool is_unnest (const Analyzer::Expr *expr)
 
bool is_constructed_point (const Analyzer::Expr *expr)
 
size_t get_loop_join_size (const std::vector< InputTableInfo > &query_infos, const RelAlgExecutionUnit &ra_exe_unit)
 
std::unordered_set< int > get_available_gpus (const Catalog_Namespace::Catalog &cat)
 
size_t get_context_count (const ExecutorDeviceType device_type, const size_t cpu_count, const size_t gpu_count)
 
RUNTIME_EXPORT void register_buffer_with_executor_rsm (int64_t exec, int8_t *buffer)
 
const Analyzer::Exprremove_cast_to_int (const Analyzer::Expr *expr)
 
std::string toString (const Executor::ExtModuleKinds &kind)
 
void foreign_storage::populate_string_dictionary (int32_t table_id, int32_t col_id, int32_t db_id)
 

Typedef Documentation

using ColumnToFragmentsMap = std::map<const ColumnDescriptor*, std::set<int32_t>>

Definition at line 335 of file Execute.h.

using CurrentQueryStatus = std::pair<QuerySessionId, std::string>

Definition at line 87 of file Execute.h.

using InterruptFlagMap = std::map<QuerySessionId, bool>

Definition at line 88 of file Execute.h.

using LLVMValueVector = std::vector<llvm::Value*>

Definition at line 380 of file Execute.h.

Definition at line 83 of file Execute.h.

Definition at line 85 of file Execute.h.

using QuerySessionId = std::string

Definition at line 86 of file Execute.h.

using QuerySessionMap = std::map<const QuerySessionId, std::map<std::string, QuerySessionStatus>>

Definition at line 155 of file Execute.h.

using TableToFragmentIds = std::map<int32_t, std::set<int32_t>>

Definition at line 336 of file Execute.h.

Enumeration Type Documentation

Enumerator
SKIPPABLE 
NOT_SKIPPABLE 
INVALID 

Definition at line 164 of file Execute.h.

Function Documentation

const Analyzer::Expr* extract_cast_arg ( const Analyzer::Expr expr)
inline

Definition at line 222 of file Execute.h.

References kCAST.

Referenced by CodeGenerator::codegen(), CodeGenerator::createInValuesBitmap(), and anonymous_namespace{ExpressionRewrite.cpp}::OrToInVisitor::visitBinOper().

222  {
223  const auto cast_expr = dynamic_cast<const Analyzer::UOper*>(expr);
224  if (!cast_expr || cast_expr->get_optype() != kCAST) {
225  return expr;
226  }
227  return cast_expr->get_operand();
228 }
Definition: sqldefs.h:48

+ Here is the caller graph for this function:

llvm::Value* get_arg_by_index ( llvm::Function *  func,
unsigned const  index 
)
inline

Definition at line 178 of file Execute.h.

178  {
179 #if 10 <= LLVM_VERSION_MAJOR
180  return index < func->arg_size() ? func->getArg(index) : nullptr;
181 #else
182  return index < func->arg_size() ? func->arg_begin() + index : nullptr;
183 #endif
184 }
llvm::Value* get_arg_by_name ( llvm::Function *  func,
const std::string &  name 
)
inline

Definition at line 168 of file Execute.h.

References CHECK, and setup::name.

Referenced by GroupByAndAggregate::codegen(), TargetExprCodegen::codegenAggregate(), CodeGenerator::codegenFunctionOper(), HashJoin::codegenHashTableLoad(), PerfectJoinHashTable::codegenHashTableLoad(), CodeGenerator::codegenHoistedConstantsLoads(), GroupByAndAggregate::codegenOutputSlot(), CodeGenerator::codegenRowId(), GroupByAndAggregate::getAdditionalLiteral(), Executor::preloadFragOffsets(), query_group_by_template(), and query_template().

168  {
169  for (auto& arg : func->args()) {
170  if (arg.getName() == name) {
171  return &arg;
172  }
173  }
174  CHECK(false);
175  return nullptr;
176 }
#define CHECK(condition)
Definition: Logger.h:291
string name
Definition: setup.in.py:72

+ Here is the caller graph for this function:

std::unordered_set<int> get_available_gpus ( const Catalog_Namespace::Catalog cat)
const ColumnDescriptor* get_column_descriptor ( const shared::ColumnKey column_key)
inline

Definition at line 213 of file Execute.h.

References CHECK, CHECK_GT, shared::ColumnKey::db_id, Catalog_Namespace::get_metadata_for_column(), and shared::ColumnKey::table_id.

Referenced by CodeGenerator::codegenColVar(), CodeGenerator::codegenGeoColumnVar(), RelAlgExecutor::executeSimpleInsert(), get_column_descriptor_maybe(), Executor::getColLazyFetchInfo(), ColumnFetcher::getOneTableColumnFragment(), spatial_type::NPoints::getOperand(), spatial_type::NRings::getOperand(), spatial_type::NumGeometries::getOperand(), PlanState::isLazyFetchColumn(), RelAlgExecutor::isRowidLookup(), ColumnFetcher::linearizeColumnFragments(), and Executor::skipFragment().

214  {
215  CHECK_GT(column_key.db_id, 0);
216  CHECK_GT(column_key.table_id, 0);
217  const auto col_desc = Catalog_Namespace::get_metadata_for_column(column_key);
218  CHECK(col_desc);
219  return col_desc;
220 }
const ColumnDescriptor * get_metadata_for_column(const ::shared::ColumnKey &column_key)
#define CHECK_GT(x, y)
Definition: Logger.h:305
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const ColumnDescriptor* get_column_descriptor_maybe ( const shared::ColumnKey column_key)
inline

Definition at line 241 of file Execute.h.

References get_column_descriptor(), and shared::ColumnKey::table_id.

Referenced by anonymous_namespace{GroupByAndAggregate.cpp}::expr_is_rowid(), BoundingBoxIntersectJoinHashTable::fetchColumnsForDevice(), PerfectJoinHashTable::fetchColumnsForDevice(), BaselineJoinHashTable::fetchColumnsForDevice(), Executor::getColLazyFetchInfo(), Executor::getColumnDescriptor(), ColumnFetcher::getOneColumnFragment(), Executor::getPhysicalColumnDescriptor(), needs_dictionary_translation(), HashJoin::normalizeColumnPair(), anonymous_namespace{QueryMemoryDescriptor.cpp}::target_expr_proj_indices(), and anonymous_namespace{Execute.cpp}::try_get_column_descriptor().

242  {
243  return column_key.table_id > 0 ? get_column_descriptor(column_key) : nullptr;
244 }
const ColumnDescriptor * get_column_descriptor(const shared::ColumnKey &column_key)
Definition: Execute.h:213

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const SQLTypeInfo get_column_type ( const int  col_id,
const int  table_id,
const ColumnDescriptor cd,
const TemporaryTables temporary_tables 
)
inline

Definition at line 254 of file Execute.h.

References CHECK, CHECK_EQ, ColumnDescriptor::columnId, ColumnDescriptor::columnType, get_temporary_table(), and ColumnDescriptor::tableId.

Referenced by ColumnFetcher::getOneTableColumnFragment(), needs_dictionary_translation(), and HashJoin::normalizeColumnPair().

257  {
258  CHECK(cd || temporary_tables);
259  if (cd) {
260  CHECK_EQ(col_id, cd->columnId);
261  CHECK_EQ(table_id, cd->tableId);
262  return cd->columnType;
263  }
264  const auto& temp = get_temporary_table(temporary_tables, table_id);
265  return temp->getColType(col_id);
266 }
#define CHECK_EQ(x, y)
Definition: Logger.h:301
const ResultSetPtr & get_temporary_table(const TemporaryTables *temporary_tables, const int table_id)
Definition: Execute.h:246
#define CHECK(condition)
Definition: Logger.h:291
SQLTypeInfo columnType

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

size_t get_context_count ( const ExecutorDeviceType  device_type,
const size_t  cpu_count,
const size_t  gpu_count 
)

Definition at line 1741 of file Execute.cpp.

References GPU.

Referenced by Executor::executeWorkUnitImpl().

1743  {
1744  return device_type == ExecutorDeviceType::GPU ? gpu_count
1745  : static_cast<size_t>(cpu_count);
1746 }

+ Here is the caller graph for this function:

unsigned get_index_by_name ( llvm::Function *  func,
const std::string &  name 
)
inline

Definition at line 187 of file Execute.h.

References setup::name.

187  {
188  unsigned index = 0;
189  for (auto& arg : func->args()) {
190  if (arg.getName() == name) {
191  break;
192  }
193  ++index;
194  }
195  return index;
196 }
string name
Definition: setup.in.py:72
size_t get_loop_join_size ( const std::vector< InputTableInfo > &  query_infos,
const RelAlgExecutionUnit ra_exe_unit 
)

Definition at line 1880 of file Execute.cpp.

References CHECK, and RelAlgExecutionUnit::input_descs.

Referenced by anonymous_namespace{IRCodegen.cpp}::check_if_loop_join_is_allowed().

1881  {
1882  const auto inner_table_key = ra_exe_unit.input_descs.back().getTableKey();
1883 
1884  std::optional<size_t> inner_table_idx;
1885  for (size_t i = 0; i < query_infos.size(); ++i) {
1886  if (query_infos[i].table_key == inner_table_key) {
1887  inner_table_idx = i;
1888  break;
1889  }
1890  }
1891  CHECK(inner_table_idx);
1892  return query_infos[*inner_table_idx].info.getNumTuples();
1893 }
std::vector< InputDescriptor > input_descs
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the caller graph for this function:

std::string get_null_check_suffix ( const SQLTypeInfo lhs_ti,
const SQLTypeInfo rhs_ti 
)
inline

Definition at line 1678 of file Execute.h.

References CHECK, and SQLTypeInfo::get_notnull().

Referenced by CodeGenerator::codegenCmp(), CodeGenerator::codegenDeciDiv(), CodeGenerator::codegenFpArith(), CodeGenerator::codegenIntArith(), and CodeGenerator::codegenStrCmp().

1679  {
1680  if (lhs_ti.get_notnull() && rhs_ti.get_notnull()) {
1681  return "";
1682  }
1683  std::string null_check_suffix{"_nullable"};
1684  if (lhs_ti.get_notnull()) {
1685  CHECK(!rhs_ti.get_notnull());
1686  null_check_suffix += "_rhs";
1687  } else if (rhs_ti.get_notnull()) {
1688  CHECK(!lhs_ti.get_notnull());
1689  null_check_suffix += "_lhs";
1690  }
1691  return null_check_suffix;
1692 }
#define CHECK(condition)
Definition: Logger.h:291
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:398

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

const ResultSetPtr& get_temporary_table ( const TemporaryTables temporary_tables,
const int  table_id 
)
inline

Definition at line 246 of file Execute.h.

References CHECK, and CHECK_LT.

Referenced by anonymous_namespace{ExternalExecutor.cpp}::create_table_schema(), RelAlgExecutor::executeDelete(), RelAlgExecutor::executeProject(), RelAlgExecutor::executeUpdate(), get_column_type(), get_table_cardinality(), ColumnFetcher::getOneColumnFragment(), and ColumnFetcher::getResultSetColumn().

247  {
248  CHECK_LT(table_id, 0);
249  const auto it = temporary_tables->find(table_id);
250  CHECK(it != temporary_tables->end());
251  return it->second;
252 }
#define CHECK_LT(x, y)
Definition: Logger.h:303
#define CHECK(condition)
Definition: Logger.h:291

+ Here is the caller graph for this function:

bool is_constructed_point ( const Analyzer::Expr expr)
inline

Definition at line 1699 of file Execute.h.

References Analyzer::UOper::get_operand(), and kCAST.

Referenced by anonymous_namespace{FromTableReordering.cpp}::get_join_qual_cost(), CodeGenerator::hashJoinLhs(), CodeGenerator::needCastForHashJoinLhs(), HashJoin::normalizeColumnPair(), and translate_bounding_box_intersect_with_reordering().

1699  {
1700  auto uoper = dynamic_cast<const Analyzer::UOper*>(expr);
1701  auto oper = (uoper && uoper->get_optype() == kCAST) ? uoper->get_operand() : expr;
1702  auto arr = dynamic_cast<const Analyzer::ArrayExpr*>(oper);
1703  return (arr && arr->isLocalAlloc() && arr->get_type_info().is_fixlen_array());
1704 }
Definition: sqldefs.h:48
const Expr * get_operand() const
Definition: Analyzer.h:384

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool is_unnest ( const Analyzer::Expr expr)
inline

Definition at line 1694 of file Execute.h.

References Analyzer::UOper::get_optype(), and kUNNEST.

Referenced by CodeGenerator::codegen(), and CodeGenerator::codegenCmp().

1694  {
1695  return dynamic_cast<const Analyzer::UOper*>(expr) &&
1696  static_cast<const Analyzer::UOper*>(expr)->get_optype() == kUNNEST;
1697 }
SQLOps get_optype() const
Definition: Analyzer.h:383

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

uint32_t log2_bytes ( const uint32_t  bytes)
inline

Definition at line 198 of file Execute.h.

Referenced by CodeGenerator::codegen(), GroupByAndAggregate::codegenAggArg(), CodeGenerator::codegenFunctionOperCastArgs(), CodeGenerator::codegenGeoArgs(), spatial_type::Centroid::codegenLoads(), spatial_type::Distance::codegenLoads(), spatial_type::AreaPerimeter::codegenLoads(), spatial_type::StartEndPoint::codegenLoads(), spatial_type::PointN::codegenLoads(), spatial_type::NPoints::codegenLoads(), spatial_type::NRings::codegenLoads(), spatial_type::NumGeometries::codegenLoads(), and Executor::groupByColumnCodegen().

198  {
199  switch (bytes) {
200  case 1:
201  return 0;
202  case 2:
203  return 1;
204  case 4:
205  return 2;
206  case 8:
207  return 3;
208  default:
209  abort();
210  }
211 }

+ Here is the caller graph for this function:

std::string numeric_type_name ( const SQLTypeInfo ti)
inline

Definition at line 230 of file Execute.h.

References CHECK, SQLTypeInfo::get_compression(), SQLTypeInfo::get_logical_size(), SQLTypeInfo::get_type(), SQLTypeInfo::is_boolean(), SQLTypeInfo::is_decimal(), SQLTypeInfo::is_fp(), SQLTypeInfo::is_integer(), SQLTypeInfo::is_string(), SQLTypeInfo::is_time(), SQLTypeInfo::is_timeinterval(), kDOUBLE, kENCODING_DICT, and to_string().

Referenced by TargetExprCodegen::codegenAggregate(), CodeGenerator::codegenCastBetweenIntTypes(), CodeGenerator::codegenCastBetweenIntTypesOverflowChecks(), CodeGenerator::codegenCastFromFp(), CodeGenerator::codegenCastToFp(), CodeGenerator::codegenCmp(), CodeGenerator::codegenDiv(), CodeGenerator::codegenFpArith(), CodeGenerator::codegenQualifierCmp(), CodeGenerator::codegenUMinus(), CodeGenerator::codgenAdjustFixedEncNull(), Executor::groupByColumnCodegen(), and anonymous_namespace{ArithmeticIR.cpp}::numeric_or_time_interval_type_name().

230  {
231  CHECK(ti.is_integer() || ti.is_decimal() || ti.is_boolean() || ti.is_time() ||
232  ti.is_fp() || (ti.is_string() && ti.get_compression() == kENCODING_DICT) ||
233  ti.is_timeinterval());
234  if (ti.is_integer() || ti.is_decimal() || ti.is_boolean() || ti.is_time() ||
235  ti.is_string() || ti.is_timeinterval()) {
236  return "int" + std::to_string(ti.get_logical_size() * 8) + "_t";
237  }
238  return ti.get_type() == kDOUBLE ? "double" : "float";
239 }
bool is_fp() const
Definition: sqltypes.h:571
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:391
bool is_time() const
Definition: sqltypes.h:577
std::string to_string(char const *&&v)
int get_logical_size() const
Definition: sqltypes.h:419
bool is_integer() const
Definition: sqltypes.h:565
bool is_timeinterval() const
Definition: sqltypes.h:592
bool is_boolean() const
Definition: sqltypes.h:580
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:399
#define CHECK(condition)
Definition: Logger.h:291
bool is_string() const
Definition: sqltypes.h:559
bool is_decimal() const
Definition: sqltypes.h:568

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::ostream& operator<< ( std::ostream &  ,
FetchResult const &   
)

Definition at line 3420 of file Execute.cpp.

References FetchResult::col_buffers, FetchResult::frag_offsets, FetchResult::num_rows, and shared::printContainer().

3420  {
3421  return os << "col_buffers" << shared::printContainer(fetch_result.col_buffers)
3422  << " num_rows" << shared::printContainer(fetch_result.num_rows)
3423  << " frag_offsets" << shared::printContainer(fetch_result.frag_offsets);
3424 }
PrintContainer< CONTAINER > printContainer(CONTAINER &container)
Definition: misc.h:107

+ Here is the call graph for this function:

RUNTIME_EXPORT void register_buffer_with_executor_rsm ( int64_t  exec,
int8_t *  buffer 
)

Definition at line 232 of file ExtensionsIR.cpp.

233  {
234  Executor* exec_ptr = reinterpret_cast<Executor*>(exec);
235  if (buffer != nullptr) {
236  exec_ptr->getRowSetMemoryOwner()->addVarlenBuffer(buffer);
237  }
238 }
const Analyzer::Expr* remove_cast_to_int ( const Analyzer::Expr expr)

Definition at line 618 of file ColumnIR.cpp.

References Analyzer::Expr::get_type_info(), and kCAST.

Referenced by anonymous_namespace{DateTimePlusRewrite.cpp}::get_dt_field(), CodeGenerator::hashJoinLhs(), and CodeGenerator::needCastForHashJoinLhs().

618  {
619  const auto uoper = dynamic_cast<const Analyzer::UOper*>(expr);
620  if (!uoper || uoper->get_optype() != kCAST) {
621  return nullptr;
622  }
623  const auto& target_ti = uoper->get_type_info();
624  if (!target_ti.is_integer()) {
625  return nullptr;
626  }
627  return uoper->get_operand();
628 }
Definition: sqldefs.h:48
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string toString ( const Executor::ExtModuleKinds kind)
inline