OmniSciDB  2e3a973ef4
AlterForeignServerCommand Class Reference

#include <DdlCommandExecutor.h>

+ Inheritance diagram for AlterForeignServerCommand:
+ Collaboration diagram for AlterForeignServerCommand:

Public Member Functions

 AlterForeignServerCommand (const rapidjson::Value &ddl_payload, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
 
void execute (TQueryResult &_return) override
 
- Public Member Functions inherited from DdlCommand
 DdlCommand (const rapidjson::Value &ddl_payload, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
 

Private Member Functions

void changeForeignServerOwner ()
 
void renameForeignServer ()
 
void setForeignServerOptions ()
 
void setForeignServerDataWrapper ()
 
bool hasAlterServerPrivileges ()
 

Additional Inherited Members

- Protected Member Functions inherited from DdlCommand
bool isDefaultServer (const std::string &server_name)
 
- Protected Attributes inherited from DdlCommand
const rapidjson::Value & ddl_payload_
 
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
 

Detailed Description

Definition at line 60 of file DdlCommandExecutor.h.

Constructor & Destructor Documentation

◆ AlterForeignServerCommand()

AlterForeignServerCommand::AlterForeignServerCommand ( const rapidjson::Value &  ddl_payload,
std::shared_ptr< Catalog_Namespace::SessionInfo const >  session_ptr 
)

Definition at line 194 of file DdlCommandExecutor.cpp.

References CHECK, and UNREACHABLE.

197  : DdlCommand(ddl_payload, session_ptr) {
198  CHECK(ddl_payload.HasMember("serverName"));
199  CHECK(ddl_payload["serverName"].IsString());
200  CHECK(ddl_payload.HasMember("alterType"));
201  CHECK(ddl_payload["alterType"].IsString());
202  if (ddl_payload["alterType"] == "SET_OPTIONS") {
203  CHECK(ddl_payload.HasMember("options"));
204  CHECK(ddl_payload["options"].IsObject());
205  } else if (ddl_payload["alterType"] == "SET_DATA_WRAPPER") {
206  CHECK(ddl_payload.HasMember("dataWrapper"));
207  CHECK(ddl_payload["dataWrapper"].IsString());
208  } else if (ddl_payload["alterType"] == "RENAME_SERVER") {
209  CHECK(ddl_payload.HasMember("newServerName"));
210  CHECK(ddl_payload["newServerName"].IsString());
211  } else if (ddl_payload["alterType"] == "CHANGE_OWNER") {
212  CHECK(ddl_payload.HasMember("newOwner"));
213  CHECK(ddl_payload["newOwner"].IsString());
214  } else {
215  UNREACHABLE(); // not-implemented alterType
216  }
217 }
#define UNREACHABLE()
Definition: Logger.h:241
DdlCommand(const rapidjson::Value &ddl_payload, std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr)
#define CHECK(condition)
Definition: Logger.h:197

Member Function Documentation

◆ changeForeignServerOwner()

void AlterForeignServerCommand::changeForeignServerOwner ( )
private

Definition at line 244 of file DdlCommandExecutor.cpp.

References cat(), DdlCommand::ddl_payload_, Catalog_Namespace::SysCatalog::instance(), ServerDBObjectType, DdlCommand::session_ptr_, and Catalog_Namespace::UserMetadata::userId.

Referenced by execute().

244  {
245  std::string server_name = ddl_payload_["serverName"].GetString();
246  std::string new_owner = ddl_payload_["newOwner"].GetString();
247  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
248  if (!session_ptr_->get_currentUser().isSuper) {
249  throw std::runtime_error(
250  "Only a super user can change a foreign server's owner. "
251  "Current user is not a super-user. "
252  "Foreign server with name \"" +
253  server_name + "\" will not have owner changed.");
254  }
255  Catalog_Namespace::UserMetadata user, original_owner;
256  if (!sys_cat.getMetadataForUser(new_owner, user)) {
257  throw std::runtime_error("User with username \"" + new_owner + "\" does not exist. " +
258  "Foreign server with name \"" + server_name +
259  "\" can not have owner changed.");
260  }
261  auto& cat = session_ptr_->getCatalog();
262  // get original owner metadata
263  bool original_owner_exists = sys_cat.getMetadataForUserById(
264  cat.getForeignServer(server_name)->user_id, original_owner);
265  // update catalog
266  cat.changeForeignServerOwner(server_name, user.userId);
267  try {
268  // update permissions
269  DBObject db_object(server_name, DBObjectType::ServerDBObjectType);
270  sys_cat.changeDBObjectOwnership(
271  user, original_owner, db_object, cat, original_owner_exists);
272  } catch (const std::runtime_error& e) {
273  // update permissions failed, revert catalog update
274  cat.changeForeignServerOwner(server_name, original_owner.userId);
275  throw;
276  }
277 }
static SysCatalog & instance()
Definition: SysCatalog.h:286
std::string cat(Ts &&... args)
const rapidjson::Value & ddl_payload_
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ execute()

void AlterForeignServerCommand::execute ( TQueryResult &  _return)
overridevirtual

Executes the DDL command corresponding to provided JSON payload.

Parameters
_returnresult of DDL command execution (if applicable)

Implements DdlCommand.

Definition at line 219 of file DdlCommandExecutor.cpp.

References changeForeignServerOwner(), DdlCommand::ddl_payload_, hasAlterServerPrivileges(), DdlCommand::isDefaultServer(), renameForeignServer(), DdlCommand::session_ptr_, setForeignServerDataWrapper(), and setForeignServerOptions().

219  {
220  std::string server_name = ddl_payload_["serverName"].GetString();
221  if (isDefaultServer(server_name)) {
222  throw std::runtime_error{"OmniSci default servers cannot be altered."};
223  }
224  if (!session_ptr_->getCatalog().getForeignServer(server_name)) {
225  throw std::runtime_error{"Foreign server with name \"" + server_name +
226  "\" does not exist and can not be altered."};
227  }
228  if (!hasAlterServerPrivileges()) {
229  throw std::runtime_error("Server " + server_name +
230  " can not be altered. User has no ALTER SERVER privileges.");
231  }
232  std::string alter_type = ddl_payload_["alterType"].GetString();
233  if (alter_type == "CHANGE_OWNER") {
235  } else if (alter_type == "SET_DATA_WRAPPER") {
237  } else if (alter_type == "SET_OPTIONS") {
239  } else if (alter_type == "RENAME_SERVER") {
241  }
242 }
bool isDefaultServer(const std::string &server_name)
const rapidjson::Value & ddl_payload_
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
+ Here is the call graph for this function:

◆ hasAlterServerPrivileges()

bool AlterForeignServerCommand::hasAlterServerPrivileges ( )
private

Definition at line 329 of file DdlCommandExecutor.cpp.

References AccessPrivileges::ALTER_SERVER, DdlCommand::ddl_payload_, ServerDBObjectType, and DdlCommand::session_ptr_.

Referenced by execute().

329  {
330  // TODO: implement `GRANT/REVOKE ALTER_SERVER` DDL commands
331  std::string server_name = ddl_payload_["serverName"].GetString();
332  return session_ptr_->checkDBAccessPrivileges(
334 }
static const AccessPrivileges ALTER_SERVER
Definition: DBObject.h:191
const rapidjson::Value & ddl_payload_
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
+ Here is the caller graph for this function:

◆ renameForeignServer()

void AlterForeignServerCommand::renameForeignServer ( )
private

Definition at line 279 of file DdlCommandExecutor.cpp.

References cat(), DdlCommand::ddl_payload_, Catalog_Namespace::SysCatalog::instance(), DdlCommand::isDefaultServer(), ServerDBObjectType, and DdlCommand::session_ptr_.

Referenced by execute().

279  {
280  std::string server_name = ddl_payload_["serverName"].GetString();
281  std::string new_server_name = ddl_payload_["newServerName"].GetString();
282  if (isDefaultServer(new_server_name)) {
283  throw std::runtime_error{"OmniSci prefix can not be used for new name of server."};
284  }
285  auto& cat = session_ptr_->getCatalog();
286  // check for a conflicting server
287  if (cat.getForeignServer(new_server_name)) {
288  throw std::runtime_error("Foreign server with name \"" + server_name +
289  "\" can not be renamed to \"" + new_server_name + "\"." +
290  "Foreign server with name \"" + new_server_name +
291  "\" exists.");
292  }
293  // update catalog
294  cat.renameForeignServer(server_name, new_server_name);
295  try {
296  // migrate object privileges
297  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
298  sys_cat.renameDBObject(server_name,
299  new_server_name,
301  cat.getForeignServer(new_server_name)->id,
302  cat);
303  } catch (const std::runtime_error& e) {
304  // permission migration failed, revert catalog update
305  cat.renameForeignServer(new_server_name, server_name);
306  throw;
307  }
308 }
static SysCatalog & instance()
Definition: SysCatalog.h:286
std::string cat(Ts &&... args)
bool isDefaultServer(const std::string &server_name)
const rapidjson::Value & ddl_payload_
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setForeignServerDataWrapper()

void AlterForeignServerCommand::setForeignServerDataWrapper ( )
private

Definition at line 321 of file DdlCommandExecutor.cpp.

References cat(), DdlCommand::ddl_payload_, and DdlCommand::session_ptr_.

Referenced by execute().

321  {
322  std::string server_name = ddl_payload_["serverName"].GetString();
323  std::string data_wrapper = ddl_payload_["dataWrapper"].GetString();
324  auto& cat = session_ptr_->getCatalog();
325  // update catalog
326  cat.setForeignServerDataWrapper(server_name, data_wrapper);
327 }
std::string cat(Ts &&... args)
const rapidjson::Value & ddl_payload_
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setForeignServerOptions()

void AlterForeignServerCommand::setForeignServerOptions ( )
private

Definition at line 310 of file DdlCommandExecutor.cpp.

References cat(), DdlCommand::ddl_payload_, foreign_storage::OptionsContainer::getOptionsAsJsonString(), foreign_storage::OptionsContainer::populateOptionsMap(), and DdlCommand::session_ptr_.

Referenced by execute().

310  {
311  std::string server_name = ddl_payload_["serverName"].GetString();
312  auto& cat = session_ptr_->getCatalog();
313  // update catalog
314  const auto foreign_server = cat.getForeignServer(server_name);
316  opt.populateOptionsMap(foreign_server->getOptionsAsJsonString());
317  opt.populateOptionsMap(ddl_payload_["options"]);
318  cat.setForeignServerOptions(server_name, opt.getOptionsAsJsonString());
319 }
std::string getOptionsAsJsonString() const
void populateOptionsMap(const rapidjson::Value &ddl_options)
std::string cat(Ts &&... args)
const rapidjson::Value & ddl_payload_
std::shared_ptr< Catalog_Namespace::SessionInfo const > session_ptr_
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

The documentation for this class was generated from the following files: