OmniSciDB  085a039ca4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SharedDictionaryValidator.cpp File Reference
#include "SharedDictionaryValidator.h"
#include <memory>
#include "Logger/Logger.h"
+ Include dependency graph for SharedDictionaryValidator.cpp:

Go to the source code of this file.

Namespaces

 anonymous_namespace{SharedDictionaryValidator.cpp}
 

Functions

const Parser::SharedDictionaryDef compress_reference_path (Parser::SharedDictionaryDef cur_node, const std::vector< Parser::SharedDictionaryDef > &shared_dict_defs)
 
void validate_shared_dictionary_order (const Parser::CreateTableBaseStmt *stmt, const Parser::SharedDictionaryDef *shared_dict_def, const std::vector< Parser::SharedDictionaryDef > &shared_dict_defs, const std::list< ColumnDescriptor > &columns)
 
const ColumnDescriptoranonymous_namespace{SharedDictionaryValidator.cpp}::lookup_column (const std::string &name, const std::list< ColumnDescriptor > &columns)
 
const ColumnDescriptoranonymous_namespace{SharedDictionaryValidator.cpp}::lookup_column (const std::string &name, const std::list< const ColumnDescriptor * > &columns)
 
const Parser::CompressDefanonymous_namespace{SharedDictionaryValidator.cpp}::get_compression_for_column (const std::string &name, const std::list< std::unique_ptr< Parser::TableElement >> &table_element_list)
 
void validate_shared_dictionary (const Parser::CreateTableBaseStmt *stmt, const Parser::SharedDictionaryDef *shared_dict_def, const std::list< ColumnDescriptor > &columns, const std::vector< Parser::SharedDictionaryDef > &shared_dict_defs_so_far, const Catalog_Namespace::Catalog &catalog)
 

Function Documentation

const Parser::SharedDictionaryDef compress_reference_path ( Parser::SharedDictionaryDef  cur_node,
const std::vector< Parser::SharedDictionaryDef > &  shared_dict_defs 
)

Definition at line 23 of file SharedDictionaryValidator.cpp.

References CHECK_LT, Parser::SharedDictionaryDef::get_column(), Parser::SharedDictionaryDef::get_foreign_column(), and Parser::SharedDictionaryDef::get_foreign_table().

Referenced by Catalog_Namespace::Catalog::setColumnSharedDictionary().

25  {
26  size_t idx = 0;
27  for (; idx < shared_dict_defs.size(); idx++) {
28  if (!shared_dict_defs[idx].get_column().compare(cur_node.get_column()) &&
29  !shared_dict_defs[idx].get_foreign_table().compare(
30  cur_node.get_foreign_table()) &&
31  !shared_dict_defs[idx].get_foreign_column().compare(
32  cur_node.get_foreign_column())) {
33  break;
34  }
35  }
36  // Make sure we have found the shared dictionary definition
37  CHECK_LT(idx, shared_dict_defs.size());
38 
39  size_t ret_val_idx = idx;
40  for (size_t j = 0; j < shared_dict_defs.size(); j++) {
41  for (size_t i = 0; i < shared_dict_defs.size(); ++i) {
42  if (!shared_dict_defs[i].get_column().compare(
43  shared_dict_defs[ret_val_idx].get_foreign_column())) {
44  ret_val_idx = i;
45  break;
46  }
47  }
48  if (shared_dict_defs[ret_val_idx].get_foreign_table().compare(
49  cur_node.get_foreign_table())) {
50  // found a dictionary share definition which shares the dict outside this table to
51  // be created
52  break;
53  }
54  }
55 
56  return shared_dict_defs[ret_val_idx];
57 }
const std::string & get_foreign_table() const
Definition: ParserNode.h:932
const std::string & get_column() const
Definition: ParserNode.h:930
const std::string & get_foreign_column() const
Definition: ParserNode.h:934
#define CHECK_LT(x, y)
Definition: Logger.h:233

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void validate_shared_dictionary ( const Parser::CreateTableBaseStmt stmt,
const Parser::SharedDictionaryDef shared_dict_def,
const std::list< ColumnDescriptor > &  columns,
const std::vector< Parser::SharedDictionaryDef > &  shared_dict_defs_so_far,
const Catalog_Namespace::Catalog catalog 
)

Definition at line 129 of file SharedDictionaryValidator.cpp.

References CHECK, ColumnDescriptor::columnName, Parser::SharedDictionaryDef::get_column(), anonymous_namespace{SharedDictionaryValidator.cpp}::get_compression_for_column(), Parser::SharedDictionaryDef::get_foreign_column(), Parser::SharedDictionaryDef::get_foreign_table(), Parser::CreateTableBaseStmt::get_table(), Parser::CreateTableBaseStmt::get_table_element_list(), Catalog_Namespace::Catalog::getAllColumnMetadataForTable(), Catalog_Namespace::Catalog::getMetadataForTable(), kENCODING_DICT, anonymous_namespace{SharedDictionaryValidator.cpp}::lookup_column(), and validate_shared_dictionary_order().

Referenced by Parser::CreateDataframeStmt::execute(), and Parser::CreateTableStmt::executeDryRun().

134  {
135  CHECK(shared_dict_def);
136  auto table_name = stmt->get_table();
137  const auto cd_ptr = lookup_column(shared_dict_def->get_column(), columns);
138  const auto col_qualified_name = *table_name + "." + shared_dict_def->get_column();
139  if (!cd_ptr) {
140  throw std::runtime_error("Column " + col_qualified_name + " doesn't exist");
141  }
142  if (!cd_ptr->columnType.is_string() ||
143  cd_ptr->columnType.get_compression() != kENCODING_DICT) {
144  throw std::runtime_error("Column " + col_qualified_name +
145  " must be a dictionary encoded string");
146  }
147  const std::list<std::unique_ptr<Parser::TableElement>>& table_element_list =
148  stmt->get_table_element_list();
149  if (get_compression_for_column(shared_dict_def->get_column(), table_element_list)) {
150  throw std::runtime_error(
151  "Column " + col_qualified_name +
152  " shouldn't specify an encoding, it borrows it from the referenced column");
153  }
154 
155  // NOTE(Misiu): Unfortunately we have overloaded the term "foreign table" here. In
156  // SharedDictionaryDef the "foreign table" is a table that is sharing a dictionary
157  // which it did not create. This is different from an FSI (HeavyConnect) "foreign
158  // table" which is a specific type of table who's data is stored outside of the database
159  // system. Currently string dictionaries have some unique handling in FSI (they are
160  // populated lazily) so we cannot share them with non-foreign (non-FSI) tables.
161  const auto foreign_table_name = shared_dict_def->get_foreign_table();
162  const auto foreign_td = catalog.getMetadataForTable(foreign_table_name);
163  if (!foreign_td && table_name->compare(foreign_table_name)) {
164  throw std::runtime_error("Table " + foreign_table_name + " doesn't exist");
165  }
166 
167  if (foreign_td) { // Dictionary is shared with another table
168  if (foreign_td->isForeignTable()) { // FSI foreign table
169  // The 'create foreign table' syntax does not support sharing dictionaries, so we
170  // only have to worry about foreign tables being the target of sharing, not the
171  // source.
172  throw std::runtime_error(
173  "Attempting to share dictionary with foreign table " + foreign_table_name +
174  ". Foreign table dictionaries cannot currently be shared.");
175  }
176  const auto reference_columns =
177  catalog.getAllColumnMetadataForTable(foreign_td->tableId, false, false, false);
178  const auto reference_cd_ptr =
179  lookup_column(shared_dict_def->get_foreign_column(), reference_columns);
180  if (!reference_cd_ptr) {
181  throw std::runtime_error("Could not find referenced column " +
182  shared_dict_def->get_foreign_column() + " in table " +
183  foreign_td->tableName);
184  }
185  if (!reference_cd_ptr->columnType.is_string() ||
186  reference_cd_ptr->columnType.get_compression() != kENCODING_DICT) {
187  const auto reference_col_qualified_name =
188  reference_cd_ptr->columnName + "." + shared_dict_def->get_foreign_column();
189  throw std::runtime_error("Referenced column " + reference_col_qualified_name +
190  " must be a dictionary encoded string column");
191  }
192  } else {
193  // The dictionary is to be shared within table
194  const auto reference_col_qualified_name =
195  *table_name + "." + shared_dict_def->get_foreign_column();
196  const auto reference_cd_ptr =
197  lookup_column(shared_dict_def->get_foreign_column(), columns);
198  if (!reference_cd_ptr) {
199  throw std::runtime_error("Column " + reference_col_qualified_name +
200  " doesn't exist");
201  }
202  if (!reference_cd_ptr->columnType.is_string() ||
203  reference_cd_ptr->columnType.get_compression() != kENCODING_DICT) {
204  throw std::runtime_error("Column " + reference_col_qualified_name +
205  " must be a dictionary encoded string");
206  }
208  stmt, shared_dict_def, shared_dict_defs_so_far, columns);
209  }
210  const auto it =
211  std::find_if(shared_dict_defs_so_far.begin(),
212  shared_dict_defs_so_far.end(),
213  [shared_dict_def](const Parser::SharedDictionaryDef& elem) {
214  return elem.get_column() == shared_dict_def->get_column();
215  });
216  if (it != shared_dict_defs_so_far.end()) {
217  throw std::runtime_error("Duplicate shared dictionary hint for column " +
218  *table_name + "." + shared_dict_def->get_column());
219  }
220 }
virtual const std::list< std::unique_ptr< TableElement > > & get_table_element_list() const =0
const std::string & get_foreign_table() const
Definition: ParserNode.h:932
const std::string & get_column() const
Definition: ParserNode.h:930
void validate_shared_dictionary_order(const Parser::CreateTableBaseStmt *stmt, const Parser::SharedDictionaryDef *shared_dict_def, const std::vector< Parser::SharedDictionaryDef > &shared_dict_defs, const std::list< ColumnDescriptor > &columns)
const ColumnDescriptor * lookup_column(const std::string &name, const std::list< ColumnDescriptor > &columns)
const Parser::CompressDef * get_compression_for_column(const std::string &name, const std::list< std::unique_ptr< Parser::TableElement >> &table_element_list)
virtual const std::string * get_table() const =0
const std::string & get_foreign_column() const
Definition: ParserNode.h:934
std::list< const ColumnDescriptor * > getAllColumnMetadataForTable(const int tableId, const bool fetchSystemColumns, const bool fetchVirtualColumns, const bool fetchPhysicalColumns) const
Returns a list of pointers to constant ColumnDescriptor structs for all the columns from a particular...
Definition: Catalog.cpp:1941
#define CHECK(condition)
Definition: Logger.h:223
const TableDescriptor * getMetadataForTable(const std::string &tableName, const bool populateFragmenter=true) const
Returns a pointer to a const TableDescriptor struct matching the provided tableName.
std::string columnName

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void validate_shared_dictionary_order ( const Parser::CreateTableBaseStmt stmt,
const Parser::SharedDictionaryDef shared_dict_def,
const std::vector< Parser::SharedDictionaryDef > &  shared_dict_defs,
const std::list< ColumnDescriptor > &  columns 
)

Definition at line 60 of file SharedDictionaryValidator.cpp.

References CHECK, Parser::SharedDictionaryDef::get_column(), Parser::SharedDictionaryDef::get_foreign_column(), Parser::SharedDictionaryDef::get_foreign_table(), and Parser::CreateTableBaseStmt::get_table().

Referenced by validate_shared_dictionary().

64  {
65  std::string reference_col_qualified_name =
66  shared_dict_def->get_foreign_column() + "." + shared_dict_def->get_foreign_table();
67  if (!shared_dict_def->get_column().compare(shared_dict_def->get_foreign_column())) {
68  throw std::runtime_error(
69  "Dictionary cannot be shared with itself. For dictionary : " +
70  reference_col_qualified_name);
71  }
72  auto table_name = stmt->get_table();
73  CHECK(!shared_dict_def->get_foreign_table().compare(*table_name));
74  auto col = std::find_if(
75  columns.rbegin(), columns.rend(), [shared_dict_def](const ColumnDescriptor& elem) {
76  return !elem.columnName.compare(shared_dict_def->get_column());
77  });
78  CHECK(col != columns.rend());
79  auto ref_col =
80  std::find_if(col, columns.rend(), [shared_dict_def](const ColumnDescriptor& elem) {
81  return !elem.columnName.compare(shared_dict_def->get_foreign_column());
82  });
83 
84  if (ref_col == columns.rend()) {
85  throw std::runtime_error("Dictionary dependencies might create a cycle for " +
86  shared_dict_def->get_column() + "referencing " +
87  reference_col_qualified_name);
88  }
89 }
const std::string & get_foreign_table() const
Definition: ParserNode.h:932
const std::string & get_column() const
Definition: ParserNode.h:930
virtual const std::string * get_table() const =0
const std::string & get_foreign_column() const
Definition: ParserNode.h:934
specifies the content in-memory of a row in the column metadata table
#define CHECK(condition)
Definition: Logger.h:223

+ Here is the call graph for this function:

+ Here is the caller graph for this function: