예제 #1
0
//LCOV_EXCL_START /* : cnu -- not used on Linux */
// -----------------------------------------------------------------------
// makeSafeFilenamePart() and
// QualifiedName::getQualifiedNameAsAnsiNTFilenameString()
//
// Genesis 10-990113-5782
// Make sure that the end result of this function results in a valid
// file name for the system -- whether NT or OSS.
//
// Convert any invalid NT filename characters to underscores.
//
// A valid NT (or OSS) filename may be up to 255 characters including spaces.
// The characters
//	\/:*?<>|"
// are not allowed in the filename at all.
// Furthermore, a POSIX shell (MKS KornShell on NT, OSS on NSK)
// treats the following specially, so they do not make good chars for filenames:
//	$%&();' and space
//
// SQL identifiers can be up to 128 characters long in regular or
// delimited format.
//
// Regular identifiers begin with A-Z or a-z and can contain digits 0-9 or
// underscores.  Regular identifiers are not case sensitive.  Reserved words
// may not be used in a regular identifier.
//
// Delimited identifiers always begin with a " character, and can contain
// both upper and lowercase Latin-1 characters, as well as
//	\/|<>*?:"
//	$%&();' and space
//	+-=[],.
//	digits 0-9 and underscore
//
// This routine will convert all non-alphanumeric chars
// to the underscore character, and result in a filename which when treated
// as an Ansi qualified name (a MODULE name), is composed only of regular
// identifiers -- no "quoting" needed.
//
// The length of a module name that might get generated
// could be a string of over 255 characters.  128 for each of the three parts.
// 2 characters for each part if delimited plus the period separators not
// counting any quotes which are embedded and doubled which might be
// singled again.
//
// There might still be problems because NT is not case sensitive but
// SQL is where delimited identifiers are concerned and that is not being
// addressed here.  We're just going to assume that we won't have two
// catalogs and schemas that are the same delimited if case is not considered
// that will cause problems in NT.  We will be replacing all characters
// that cause the name to be delimited with underscore.
//
// If we need to truncate any one of the three parts (not generally the
// user supplied portion (mainly just the module name portion), then we
// will need to verify that the truncated result does not result in a
// reserved word.  Might possibly happen depending on how we decide to
// handle the case where the length of 2 of the parts nears the 255
// character file name limit for NT and we decide to truncate one part
// down to a size that might result in a reserved word.
// -----------------------------------------------------------------------
//
static void makeSafeFilenamePart(NAString &ns, const NAString &prefix)
{
  size_t len = ns.length();
  for (size_t i=0; i<len; i++) {
    if (!isalnum(ns[i]) && ns[i] != '_')
      ns[i] = '_';
  }

  if (!len || !isalpha(ns[(size_t)0]))	// must begin with an alphabetic
    ns.prepend(prefix);
}
예제 #2
0
// 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;
}