void StmtModule::applyModuleCatalogSchema(const NAString& cat, 
                                          const NAString& sch)
{
  // apply moduleCatalog if necessary
  if (name().getCatalogName().isNull()) {
    if (!cat.isNull())
      name().setCatalogName(cat);
  }

  // apply moduleSchema if necessary
  if (name().getSchemaName().isNull()) {
    if (!sch.isNull())
      name().setSchemaName(sch);
  }

  // module catalog & schema must be non-null now. Otherwise, a fatal
  // exception can occur in mxsqlc/mxsqlco in
  //   mod_def::setModule() --> mod_def::outputModule()
  //   --> StmtModule::unparseSimple() --> 
  //   QualifiedName::getQualifiedNameAsAnsiString() -->
  //   QualifiedName::getQualifiedNameAsString() -->
  //   CMPASSERT(NOT getSchemaName().isNull());
  // as reported in genesis case 10-030708-8735.
  if (name().getCatalogName().isNull() || name().getSchemaName().isNull()) {
    const SchemaName& defcs =
      ActiveSchemaDB()->getDefaultSchema(
        SchemaDB::REFRESH_CACHE | SchemaDB::FORCE_ANSI_NAMETYPE);
    if (name().getCatalogName().isNull())
      name().setCatalogName(defcs.getCatalogName());
    if (name().getSchemaName().isNull())
      name().setSchemaName(defcs.getSchemaName());
  }
}
// This function copies the above applyDefaults() function
// and includes checking for the object existence and 
// search in the public schema if necessary.
// This is used to replace the above function when 
// we need to consider PUBLIC_SCHEMA_NAME
Int32 QualifiedName::applyDefaultsValidate(const SchemaName& defCatSch,
                                         ComAnsiNameSpace nameSpace)
{
  // need to try public schema if it is specified
  // and the object schema is not specified
  NAString publicSchema = "";
  CmpCommon::getDefault(PUBLIC_SCHEMA_NAME, publicSchema, FALSE);
  ComSchemaName pubSchema(publicSchema);
  NAString pubSchemaIntName = "";
  if ( getSchemaName().isNull() && 
       !pubSchema.isEmpty() )
  {
    pubSchemaIntName = pubSchema.getSchemaNamePart().getInternalName();
  }

  Int32 ret = extractAndDefaultNameParts( defCatSch 
				                              , catalogName_
                                      , schemaName_
                                      , objectName_
                                   );

  // try public schema if the table does not exist 
  if (!pubSchemaIntName.isNull())
  {
    *(CmpCommon::diags()) << DgSqlCode(-4222)
                          << DgString0("Public Access Schema");
  }

  return ret;
}
NABoolean SchemaName::matchDefaultPublicSchema()
{
  if (schemaName_.isNull())
    return TRUE;

  NABoolean matched = FALSE;

  // get default schema
  NAString defCat;
  NAString defSch;
  ActiveSchemaDB()->getDefaults().getCatalogAndSchema(defCat, defSch);
  ToInternalIdentifier(defCat);
  ToInternalIdentifier(defSch);

  // get public schema
  NAString publicSchema = ActiveSchemaDB()->getDefaults().getValue(PUBLIC_SCHEMA_NAME);
  ComSchemaName pubSchema(publicSchema);
  NAString pubCat = pubSchema.getCatalogNamePart().getInternalName();
  NAString pubSch = pubSchema.getSchemaNamePart().getInternalName();

  // if catalog was not specified
  NAString catName = (catalogName_.isNull()? defCat:catalogName_);
  pubCat = (pubCat.isNull()? defCat:pubCat);

  if (((catName==defCat) && (schemaName_==defSch)) ||
      ((catName==pubCat) && (schemaName_==pubSch)))
    matched = TRUE;

  return matched;
}
// The following method returns TRUE if parameter "output" is populated.
NABoolean
ComRoutineActionNamePart::getRoutineActionNameStoredInOBJECTS_OBJECT_NAME
(ComAnsiNamePart &output, // out
 ComBoolean performCheck) // in - default is TRUE
{
  if (NOT isValid())
    return FALSE;

  ComString funnyNameInInternalFormat;
  getUudfUID().convertTo19BytesFixedWidthStringWithZeroesPrefix(funnyNameInInternalFormat/*out*/);
  funnyNameInInternalFormat += "_";
  funnyNameInInternalFormat += getInternalName();

  NAWString ucs2FunnyInternalName;
  ComAnsiNameToUCS2(funnyNameInInternalFormat, ucs2FunnyInternalName /* out */);
  if (performCheck AND ucs2FunnyInternalName.length() > MAX_IDENTIFIER_INT_LEN)
    return FALSE;

  NAString extName = ToAnsiIdentifier(funnyNameInInternalFormat,
                                      performCheck);
  if (extName.isNull()) // the generated external name is invalid
    return FALSE;

  output.setInternalName(funnyNameInInternalFormat);
  output.setExternalName(extName);
  return TRUE;
}
Beispiel #5
0
NABoolean CmpSqlSession::validateVolatileSchemaName(NAString &schName)
{
  if (NOT schName.isNull())
    {
      ComSchemaName csn(schName);

      if (NOT csn.isValid())
	{
	  // Schema name $0~SchemaName is not valid.
	  *CmpCommon::diags() << DgSqlCode(-8009) 
			      << DgSchemaName(schName);
	  return FALSE;
	}

      Lng32 len = MINOF(strlen(csn.getSchemaNamePartAsAnsiString().data()),
		       strlen(COM_VOLATILE_SCHEMA_PREFIX));
      NAString upSch(csn.getSchemaNamePartAsAnsiString().data());
      upSch.toUpper();
      if ((NOT Get_SqlParser_Flags(ALLOW_VOLATILE_SCHEMA_IN_TABLE_NAME)) &&
	  (len > 0) &&
	  (strncmp(upSch.data(), COM_VOLATILE_SCHEMA_PREFIX, len) == 0))
	{
	  *CmpCommon::diags() << DgSqlCode(-4193) 
			      << DgString0(COM_VOLATILE_SCHEMA_PREFIX);
	  return FALSE;
	}
    }

  return TRUE;
}
NABoolean QualifiedName::isHive(const NAString &catName) 
{
  NAString hiveDefCatName = "";
  CmpCommon::getDefault(HIVE_CATALOG, hiveDefCatName, FALSE);
  hiveDefCatName.toUpper();
  
  if (CmpCommon::getDefault(MODE_SEAHIVE) == DF_ON &&
      ((NOT catName.isNull()) &&
       ((catName == HIVE_SYSTEM_CATALOG) ||
	(catName == hiveDefCatName))))
    return TRUE;

  return FALSE;
}
Beispiel #7
0
void CmpSqlSession::setSessionUsername(NAString &userName)
{
  if (NOT userName.isNull())
  {
    /* Prior to Seaquest M4, the string received here would be a
       session ID and we would extract the user name from the session
       ID. This step is no longer needed. The old code is shown here
       in this comment, in case the old scheme ever needs to be
       revived.

    char uName[42];
    Int64 uNameLen = 40;
    
    ComSqlId::getSqlSessionIdAttr
      (ComSqlId::SQLQUERYID_USERNAME, 
       (char*)sessionUsername.data(), 
       sessionUsername.length(),
       uNameLen,
       uName);
    databaseUserName_ = uName;
    databaseUserName_.strip();
    */

    databaseUserName_ = userName;
    databaseUserName_.strip();
    
    short status = 1;
    char ldapName[ComSqlId::MAX_LDAP_USER_NAME_LEN + 1];


    if (status)
    {
      // On NT and Linux: the value of externalUserName_ is always the
      // same as databaseUserName_
      //
      // On NSK: It is a maintenance id if status == 13. Otherwise we
      // just revert to old behaviour and set the LDAP name to be the
      // same as the database user name. Stricter error handling here
      // will need to be tested more.
      strcpy(ldapName, databaseUserName_.data());
    }
    externalUserName_ = ldapName;
    externalUserName_.strip();
  }
}
// *****************************************************************************
// *                                                                           *
// * Function: CmpSeabaseDDL::giveSeabaseSchema                                *
// *                                                                           *
// *    Implements the GIVE SCHEMA command.                                    *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <giveSchemaNode>                StmtDDLGiveSchema *             In       *
// *    is a pointer to a create schema parser node.                           *
// *                                                                           *
// *  <currentCatalogName>            NAString &                      In       *
// *    is the name of the current catalog.                                    *
// *                                                                           *
// *****************************************************************************
void CmpSeabaseDDL::giveSeabaseSchema(
   StmtDDLGiveSchema * giveSchemaNode,
   NAString          & currentCatalogName)
   
{

ComDropBehavior dropBehavior = giveSchemaNode->getDropBehavior(); 
NAString catalogName = giveSchemaNode->getCatalogName();
NAString schemaName = giveSchemaNode->getSchemaName();

   if (catalogName.isNull())
      catalogName = currentCatalogName;  

ExeCliInterface cliInterface(STMTHEAP, NULL, NULL,
CmpCommon::context()->sqlSession()->getParentQid());
Int32 objectOwnerID = 0;
Int32 schemaOwnerID = 0;
ComObjectType objectType;

Int64 schemaUID = getObjectTypeandOwner(&cliInterface,catalogName.data(),
                                        schemaName.data(),SEABASE_SCHEMA_OBJECTNAME,
                                        objectType,schemaOwnerID);
                                       
   if (schemaUID == -1)
   {
      // A Trafodion schema does not exist if the schema object row is not
      // present: CATALOG-NAME.SCHEMA-NAME.__SCHEMA__.
      *CmpCommon::diags() << DgSqlCode(-CAT_SCHEMA_DOES_NOT_EXIST_ERROR)
                          << DgSchemaName(schemaName.data());
      return;
   }
   
// *****************************************************************************
// *                                                                           *
// *    A schema owner can give their own schema to another authID, but they   *
// * cannot give the objects in a shared schema to another authID.  Only       *
// * DB__ROOT or a user with the ALTER_SCHEMA privilege can change the owners  *
// * of objects in a shared schema.  So if the schema is private, or if only   *
// * the schema is being given, we do standard authentication checking.  But   *
// * if giving all the objects in a shared schema, we change the check ID to   *
// * the default user to force the ALTER_SCHEMA privilege check.               *
// *                                                                           *
// *****************************************************************************

int32_t checkID = schemaOwnerID;

   if (objectType == COM_SHARED_SCHEMA_OBJECT && 
       dropBehavior == COM_CASCADE_DROP_BEHAVIOR)
      checkID = NA_UserIdDefault; 

   if (!isDDLOperationAuthorized(SQLOperation::ALTER_SCHEMA,checkID,checkID))
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_NOT_AUTHORIZED);
      return;
   }
 
ComObjectName objName(catalogName,schemaName,NAString("dummy"),COM_TABLE_NAME,TRUE);

   if (isSeabaseReservedSchema(objName) &&
       !Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL))
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_USER_CANNOT_DROP_SMD_SCHEMA)
                          << DgSchemaName(schemaName.data());
      return;
   }
   
bool isVolatile = (memcmp(schemaName.data(),"VOLATILE_SCHEMA",strlen("VOLATILE_SCHEMA")) == 0);

// Can't give a schema whose name begins with VOLATILE_SCHEMA. 
   if (isVolatile)
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_RESERVED_METADATA_SCHEMA_NAME)
                          << DgTableName(schemaName);
      return;
   }
   
int32_t newOwnerID = -1;

   if (ComUser::getAuthIDFromAuthName(giveSchemaNode->getAuthID().data(),
                                      newOwnerID) != 0)
   {
      *CmpCommon::diags() << DgSqlCode(-CAT_AUTHID_DOES_NOT_EXIST_ERROR)
                          << DgString0(giveSchemaNode->getAuthID().data());
      return;
   }

// *****************************************************************************
// *                                                                           *
// *   Drop behavior is only relevant for shared schemas.  For shared schemas, *
// * ownership of the schema OR the schema and all its objects may be given to *
// * another authorization ID.  For private schemas, all objects are owned by  *
// * the schema owner, so the drop behavior is always CASCADE.                 *
// *                                                                           *
// * NOTE: The syntax for drop behavior always defaults to RESTRICT; for       *
// *       private schemas this is simply ignored, as opposed to requiring     *
// *       users to always specify CASCASE.                                    *
// *                                                                           *
// *****************************************************************************

Lng32 cliRC = 0;
char buf[4000];
   
   if (objectType == COM_SHARED_SCHEMA_OBJECT && 
       dropBehavior == COM_RESTRICT_DROP_BEHAVIOR)
   {
      str_sprintf(buf,"UPDATE %s.\"%s\".%s "
                      "SET object_owner = %d "
                      "WHERE object_UID = %Ld",
                  getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS,
                  newOwnerID,schemaUID);
      cliRC = cliInterface.executeImmediate(buf);
      if (cliRC < 0)
         cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
                      
      return;
   }
//
// At this point, we are giving all objects in the schema (as well as the 
// schema itself) to the new authorization ID.  If authentication is enabled,
// update the privileges first.
//
   if (isAuthorizationEnabled())
   {
      int32_t rc = transferObjectPrivs(getSystemCatalog(),catalogName.data(),
                                       schemaName.data(),newOwnerID,
                                       giveSchemaNode->getAuthID().data());
      if (rc != 0)
      {
         if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
         {
          //TODO: add error
         
         }
         return;
      }
   }
   
// Now update the object owner for all objects in the schema.
      
   str_sprintf(buf,"UPDATE %s.\"%s\".%s "
                   "SET object_owner = %d "
                   "WHERE catalog_name = '%s' AND schema_name = '%s'",
               getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS,
               newOwnerID,catalogName.data(),schemaName.data());
   cliRC = cliInterface.executeImmediate(buf);
   if (cliRC < 0)
   {
      cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
      return;
   }             

// Verify all objects in the schema have been given to the new owner.   
   str_sprintf(buf,"SELECT COUNT(*) "
                   "FROM %s.\"%s\".%s "
                   "WHERE catalog_name = '%s' AND schema_name = '%s' AND "
                   "object_name <> '"SEABASE_SCHEMA_OBJECTNAME"' AND "
                   "object_owner <> %d " 
                   "FOR READ COMMITTED ACCESS",
               getSystemCatalog(),SEABASE_MD_SCHEMA,SEABASE_OBJECTS,
               catalogName.data(),schemaName.data(),newOwnerID);
               
int32_t length = 0;
int32_t rowCount = 0;

   cliRC = cliInterface.executeImmediate(buf,(char*)&rowCount,&length,NULL);
  
   if (cliRC < 0)
   {
      cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
      return;
   }
   
   if (rowCount > 0)
   {
      SEABASEDDL_INTERNAL_ERROR("Not all objects in schema were given");
      return;
   }
    
}
// Name parts return in string parameters, defaulted if not yet present;
// this object is not modified.
// Function return value is the number of names that match the default,
// {0, 1, 2} = {no matches, catalog matches, catalog&schema match}.
//
// If NAMETYPE is NSK, the SchemaDB puts the current MPLOC into the defCatSch;
// so this method has to handle **only one** tiny NSK naming detail.
//
Int32 QualifiedName::extractAndDefaultNameParts(const SchemaName& defCatSch
					     , NAString& catName 	// OUT
					     , NAString& schName	// OUT
					     , NAString& objName	// OUT
                                             ) const
{
  catName = getCatalogName();
  schName = getSchemaName();
  objName = getObjectName();
  CMPASSERT(NOT objName.isNull());		// no default for this!

  {
    if (catName.isNull()) {
      if((ActiveSchemaDB()->getDefaults().schSetToUserID()) &&
         (SqlParser_NAMETYPE == DF_SHORTANSI))
      {
        // If NAMETYPE is SHORTANSI and  schema is not set 
        // in DEFAULTS table or by user, for dml, catName  
        // gets \SYS.$VOL from set or default MPLOC. 
        catName =  SqlParser_MPLOC.getSysDotVol();
      }
      else
      {
      // If NAMETYPE NSK, catName will become  \SYS.$VOL
        catName = defCatSch.getCatalogName();
      }
    }
    else if (SqlParser_NAMETYPE == DF_NSK &&
	     *catName.data() == '$' &&
	     SqlParser_MPLOC.hasSystemName()) {
      // If user specified only a $VOL, fill in the current default \SYS.
      catName.prepend(SqlParser_MPLOC.getSystemName() + ".");
    }

    if (schName.isNull()) {
      if((ActiveSchemaDB()->getDefaults().schSetToUserID()) &&
         (SqlParser_NAMETYPE == DF_SHORTANSI))
      {
        // If NAMETYPE is SHORTANSI and  schema is not set 
        // in DEFAULTS table or by user, for dml, schName  
        // gets subvol from set or default MPLOC. 
        schName =  SqlParser_MPLOC.getSubvolName();
      }
      else
        schName = defCatSch.getSchemaName();
    }
  }

  CMPASSERT(NOT catName.isNull());
  CMPASSERT(NOT schName.isNull());

  Int32 defaultMatches = 0;
  if (catName == defCatSch.getCatalogName()) {
    defaultMatches++;
    if (schName == defCatSch.getSchemaName())
      defaultMatches++;
  }

  // Next comes support for table name resolution for SHORTANSI nametype, 
  // implemented as internal feature for ODBC use only. 
  //
  // For the name resolution of table name when nametype is SHORTANSI, 
  // check is made to see if schName contains an '_', thus ensuring
  // the method applyShortAnsiDefault is called only once.
  // Correct syntax for schName is "systemName_volumeName_subvolName"
  // of the MPLoc where the objName is actually located.
  // Complete syntax checking is done inside applyShortAnsiDefault.
  //
  if (SqlParser_NAMETYPE == DF_SHORTANSI && schName.first('_') != NA_NPOS) {
    applyShortAnsiDefault(catName, schName);
  }

  return defaultMatches;
}
StmtDDLPublish::StmtDDLPublish(ElemDDLNode * pPrivileges,
                               const QualifiedName & objectName,
                               const NAString & synonymName,
                               ComBoolean isRole,
                               ElemDDLNode * pGranteeList,
                               ComBoolean isPublish,
                               CollHeap    * heap)
    : StmtDDLNode(DDL_PUBLISH),
      objectName_(heap),
      objectQualName_(objectName, heap),
      synonymName_(synonymName, heap),
      isSynonymNameSpec_(FALSE),
      isRoleList_(isRole),
      isPublish_(isPublish),
      isAllPrivileges_(FALSE),
      privActArray_(heap),
      granteeArray_(heap)
{
    setChild(PUBLISH_PRIVILEGES, pPrivileges);
    setChild(PUBLISH_GRANTEE_LIST, pGranteeList);
    objectName_ = objectQualName_.getQualifiedNameAsAnsiString();

    if (!synonymName.isNull())
        isSynonymNameSpec_ = TRUE;

    //
    // inserts pointers to parse nodes representing privilege
    // actions to privActArray_ so the user can access the
    // information about privilege actions easier.
    //

    ComASSERT(pPrivileges NEQ NULL);
    ElemDDLPrivileges * pPrivsNode = pPrivileges->castToElemDDLPrivileges();
    ComASSERT(pPrivsNode NEQ NULL);
    if (pPrivsNode->isAllPrivileges())
    {
        isAllPrivileges_ = TRUE;
    }
    else
    {
        ElemDDLNode * pPrivActs = pPrivsNode->getPrivilegeActionList();
        for (CollIndex i = 0; i < pPrivActs->entries(); i++)
        {
            ElemDDLPrivAct *pPrivAct = (*pPrivActs)[i]->castToElemDDLPrivAct();
            privActArray_.insert(pPrivAct);
        }
    }

    //
    // copies pointers to parse nodes representing grantee
    // to granteeArray_ so the user can access the information
    // easier.
    //

    ComASSERT(pGranteeList NEQ NULL);
    for (CollIndex i = 0; i < pGranteeList->entries(); i++)
    {
        granteeArray_.insert((*pGranteeList)[i]->castToElemDDLGrantee());
    }

} // StmtDDLPublish::StmtDDLPublish()
ExprNode *
ElemDDLPartitionSystem::bindNode(BindWA * /*pBindWA*/)
{
  //
  // location
  //
  ComLocationName defaultLocName;  // empty object

  if (getLocationName().isNull())
    //
    // location clause not specified (only allowed for primary partition)
    //
    guardianLocation_ =
      defaultLocName.getGuardianFullyQualifiedName();
  else  // LOCATION clause was specified
  {
    ComLocationName locName;         // empty object
    switch (getLocationNameType())
    {
    case ElemDDLLocation::LOCATION_GUARDIAN_NAME :
      locName.copy(getLocationName(),
                   ComLocationName::GUARDIAN_LOCATION_NAME_FORMAT);
      if (NOT locName.isValid())
      {
        // Illegal location name format.
        *SqlParser_Diags << DgSqlCode(-3061) << DgString0(getLocationName());
        guardianLocation_ =
          defaultLocName.getGuardianFullyQualifiedName();
      }
      else  // valid location
        guardianLocation_ =
          locName.getGuardianFullyQualifiedName();
      break;

    case ElemDDLLocation::LOCATION_OSS_NAME :
      locName.copy(getLocationName(),
                   ComLocationName::OSS_LOCATION_NAME_FORMAT);
      if (NOT locName.isValid())
      {
        // Illegal location name format.
        *SqlParser_Diags << DgSqlCode(-3061) << DgString0(getLocationName());
        guardianLocation_ =
          defaultLocName.getGuardianFullyQualifiedName();
      }
      else  // valid location
        guardianLocation_ =
          locName.getGuardianFullyQualifiedName();
      break;

#if 0
      //
      // Currently we do not handle this case
      // The grammar productions don't accept this syntax.
      // So comment out the following code for now.
      //
    case ElemDDLLocation::LOCATION_ENVIRONMENT_VARIABLE :
      {
        NAString envVarName(getLocationName());
        //
        // if the specified OSS environment variable has the
        // dollar sign prefix, removes it.
        //
	    if (envVarName[(size_t) 0] EQU '$')            // NT_PORT FIX SK 07/15/96
        {
          envVarName = envVarName(1/*startpos*/, envVarName.length() - 1);
        }
        const char * pEnvVarValue = getenv((const char *)envVarName);
        NAString locationName;
        if (pEnvVarValue NEQ NULL)
        {
          locationName = pEnvVarValue;
        }
        if (locationName.isNull())
        {
          guardianLocation_ = defaultLocName.
                              getGuardianFullyQualifiedName();
        }
        else
        {
          guardianLocationName = locationName;
          if (guardianLocationName.isValid())
          {
            guardianLocation_ = (guardianLocationName.
                                 getGuardianFullyQualifiedName());
            
          }
          else
          {
            ossLocationName = locationName;
            if (ossLocationName.isValid())
            {
              guardianLocation_ = (ossLocationName.
                                   getGuardianFullyQualifiedName());
            }
            else
            {
              // OSS environment variable $1~string1 contains illegal
              // location name $0~string0.
              *SqlParser_Diags << DgSqlCode(-3061) 
		<< DgString0(locationName)
	        << DgString1(envVarName)
		;
            }
          }
        }
      }
      break;
#endif // 0

    default :
      NAAbort("ElemDDLPartition.C", __LINE__, "internal logic error");
      break;
    }
  }

  markAsBound();
  return this;
}