// -----------------------------------------------------------------------
// Method for creating NAType from desc_struct.
// -----------------------------------------------------------------------
NABoolean NAColumn::createNAType(columns_desc_struct *column_desc	/*IN*/,
				 const NATable *table  		/*IN*/,
				 NAType *&type       		/*OUT*/,
				 NAMemory *heap			/*IN*/,
				 Lng32 * errorCode
				 )
{
  //
  // Compute the NAType for this column
  //
  #define REC_INTERVAL REC_MIN_INTERVAL

  DataType datatype = column_desc->datatype;
  if (REC_MIN_INTERVAL <= datatype && datatype <= REC_MAX_INTERVAL)
    datatype = REC_INTERVAL;

  Lng32 charCount = column_desc->length;

  if ( DFS2REC::isAnyCharacter(column_desc->datatype) )
  {
     if ( CharInfo::isCharSetSupported(column_desc->character_set) == FALSE ) {
       if (!errorCode)
       {
         *CmpCommon::diags() << DgSqlCode(-4082)
	       << DgTableName(makeTableName(table, column_desc));
       }
       else
       {
         *errorCode = 4082;
       }
       return TRUE; // error
     }

     if ( CharInfo::is_NCHAR_MP(column_desc->character_set) )
        charCount /= SQL_DBCHAR_SIZE;
  }

  switch (datatype)
    {

    case REC_BPINT_UNSIGNED :
      type = new (heap)
      SQLBPInt(column_desc->precision, column_desc->null_flag, FALSE, heap);
      break;

    case REC_BIN8_SIGNED:
      if (column_desc->precision > 0)
	type = new (heap)
	SQLNumeric(column_desc->length,
		   column_desc->precision,
		   column_desc->scale,
		   TRUE,
		   column_desc->null_flag,
                   heap
		   );
      else
	type = new (heap)
	SQLTiny(TRUE,
		 column_desc->null_flag,
                 heap
		 );
      break;
    case REC_BIN8_UNSIGNED:
      if (column_desc->precision > 0)
	type = new (heap)
	SQLNumeric(column_desc->length,
		   column_desc->precision,
		   column_desc->scale,
		   FALSE,
		   column_desc->null_flag,
                   heap
		   );
      else
	type = new (heap)
	SQLTiny(FALSE,
		 column_desc->null_flag,
                 heap
		 );
      break;

   case REC_BIN16_SIGNED:
      if (column_desc->precision > 0)
	type = new (heap)
	SQLNumeric(column_desc->length,
		   column_desc->precision,
		   column_desc->scale,
		   TRUE,
		   column_desc->null_flag,
                   heap
		   );
      else
	type = new (heap)
	SQLSmall(TRUE,
		 column_desc->null_flag,
                 heap
		 );
      break;
    case REC_BIN16_UNSIGNED:
      if (column_desc->precision > 0)
	type = new (heap)
	SQLNumeric(column_desc->length,
		   column_desc->precision,
		   column_desc->scale,
		   FALSE,
		   column_desc->null_flag,
                   heap
		   );
      else
	type = new (heap)
	SQLSmall(FALSE,
		 column_desc->null_flag,
                 heap
		 );
      break;

    case REC_BIN32_SIGNED:
      if (column_desc->precision > 0)
	type = new (heap)
	SQLNumeric(column_desc->length,
		   column_desc->precision,
		   column_desc->scale,
		   TRUE,
		   column_desc->null_flag,
                   heap
		   );
      else
	type = new (heap)
	SQLInt(TRUE,
	       column_desc->null_flag,
               heap
	       );
      break;
    case REC_BIN32_UNSIGNED:
      if (column_desc->precision > 0)
	type = new (heap)
	SQLNumeric(column_desc->length,
		   column_desc->precision,
		   column_desc->scale,
		   FALSE,
		   column_desc->null_flag,
                   heap
		   );
      else
	type = new (heap)
	SQLInt(FALSE,
	       column_desc->null_flag,
               heap
	       );
      break;
    case REC_BIN64_SIGNED:
      if (column_desc->precision > 0)
	type = new (heap)
	SQLNumeric(column_desc->length,
		   column_desc->precision,
		   column_desc->scale,
		   TRUE,
		   column_desc->null_flag,
                   heap
		   );
      else
	type = new (heap)
	SQLLargeInt(TRUE,
		    column_desc->null_flag,
                    heap
		    );
      break;
    case REC_BIN64_UNSIGNED:
      if (column_desc->precision > 0)
	type = new (heap)
	SQLNumeric(column_desc->length,
		   column_desc->precision,
		   column_desc->scale,
		   FALSE,
		   column_desc->null_flag,
                   heap
		   );
      else
	type = new (heap)
        SQLLargeInt(FALSE,
		    column_desc->null_flag,
                    heap
		    );
      break;
    case REC_DECIMAL_UNSIGNED:
      type = new (heap)
	SQLDecimal(column_desc->length,
		   column_desc->scale,
		   FALSE,
		   column_desc->null_flag,
                   heap
		   );
      break;
    case REC_DECIMAL_LSE:
      type = new (heap)
	SQLDecimal(column_desc->length,
		   column_desc->scale,
		   TRUE,
		   column_desc->null_flag,
                   heap
		   );
      break;
    case REC_NUM_BIG_UNSIGNED:
      type = new (heap)
	SQLBigNum(column_desc->precision,
		  column_desc->scale,
		  TRUE, // is a real bignum
		  FALSE,
		  column_desc->null_flag,
		  heap
		  );
      break;
    case REC_NUM_BIG_SIGNED:
      type = new (heap)
	SQLBigNum(column_desc->precision,
		  column_desc->scale,
		  TRUE, // is a real bignum
		  TRUE,
		  column_desc->null_flag,
		  heap
		  );
      break;

    case REC_FLOAT32:
      type = new (heap)
	SQLReal(column_desc->null_flag, heap, column_desc->precision);
      break;

    case REC_FLOAT64:
      type = new (heap)
	SQLDoublePrecision(column_desc->null_flag, heap, column_desc->precision);
      break;

    case REC_BYTE_F_DOUBLE:
      charCount /= SQL_DBCHAR_SIZE;	    // divide the storage length by 2
      type = new (heap)
	SQLChar(charCount,
		column_desc->null_flag,
		column_desc->upshift,
		column_desc->caseinsensitive,
		FALSE,
		column_desc->character_set,
		column_desc->collation_sequence,
		CharInfo::IMPLICIT
		);
      break;

    case REC_BYTE_F_ASCII:
      if (column_desc->character_set == CharInfo::UTF8 ||
          (column_desc->character_set == CharInfo::SJIS &&
           column_desc->encoding_charset == CharInfo::SJIS))
      {
        Lng32 maxBytesPerChar = CharInfo::maxBytesPerChar(column_desc->character_set);
        Lng32 sizeInChars = charCount ;  // Applies when CharLenUnit == BYTES
        if ( column_desc->precision > 0 )
           sizeInChars = column_desc->precision;
        type = new (heap)
	SQLChar(CharLenInfo(sizeInChars, charCount/*in_bytes*/),
		column_desc->null_flag,
		column_desc->upshift,
		column_desc->caseinsensitive,
		FALSE, // varLenFlag
		column_desc->character_set,
		column_desc->collation_sequence,
		CharInfo::IMPLICIT, // Coercibility
		column_desc->encoding_charset
		);
      }
      else // keep the old behavior
      type = new (heap)
	SQLChar(charCount,
		column_desc->null_flag,
		column_desc->upshift,
		column_desc->caseinsensitive,
		FALSE,
		column_desc->character_set,
		column_desc->collation_sequence,
		CharInfo::IMPLICIT
		);
      break;

    case REC_BYTE_V_DOUBLE:
      charCount /= SQL_DBCHAR_SIZE;	    // divide the storage length by 2
      // fall thru
    case REC_BYTE_V_ASCII:
      if (column_desc->character_set == CharInfo::SJIS ||
          column_desc->character_set == CharInfo::UTF8)
      {
        Lng32 maxBytesPerChar = CharInfo::maxBytesPerChar(column_desc->character_set);
        Lng32 sizeInChars = charCount ;  // Applies when CharLenUnit == BYTES
        if ( column_desc->precision > 0 )
           sizeInChars = column_desc->precision;
        type = new (heap)
	SQLVarChar(CharLenInfo(sizeInChars, charCount/*in_bytes*/),
		   column_desc->null_flag,
		   column_desc->upshift,
		   column_desc->caseinsensitive,
		   column_desc->character_set,
		   column_desc->collation_sequence,
		   CharInfo::IMPLICIT, // Coercibility
		   column_desc->encoding_charset
		   );
      }
      else // keep the old behavior
      type = new (heap)
	SQLVarChar(charCount,
		   column_desc->null_flag,
		   column_desc->upshift,
		   column_desc->caseinsensitive,
		   column_desc->character_set,
		   column_desc->collation_sequence,
		   CharInfo::IMPLICIT
		   );
      break;

    case REC_BYTE_V_ASCII_LONG:
      type = new (heap)
	SQLLongVarChar(charCount,
		       FALSE,
		       column_desc->null_flag,
		       column_desc->upshift,
		       column_desc->caseinsensitive,
		       column_desc->character_set,
		       column_desc->collation_sequence,
		       CharInfo::IMPLICIT
		      );
      break;
    case REC_DATETIME:
      type = DatetimeType::constructSubtype(
					    column_desc->null_flag,
					    column_desc->datetimestart,
					    column_desc->datetimeend,
					    column_desc->datetimefractprec,
					    heap
					    );
      CMPASSERT(type);
      if (!type->isSupportedType())
	{
         column_desc->defaultClass = COM_NO_DEFAULT;           // can't set a default for these, either.
	  // 4030 Column is an unsupported combination of datetime fields
     if (!errorCode)
     {
         *CmpCommon::diags() << DgSqlCode(4030)
	    << DgColumnName(makeColumnName(table, column_desc))
	    << DgInt0(column_desc->datetimestart)
	    << DgInt1(column_desc->datetimeend)
	    << DgInt2(column_desc->datetimefractprec);
     }
     else
     {
       *errorCode = 4030;
     }
	}
      break;
    case REC_INTERVAL:
      type = new (heap)
         SQLInterval(column_desc->null_flag,
		    column_desc->datetimestart,
		    column_desc->intervalleadingprec,
		    column_desc->datetimeend,
		    column_desc->datetimefractprec,
                    heap
		    );
      CMPASSERT(type);
      if (! ((SQLInterval *)type)->checkValid(CmpCommon::diags()))
         return TRUE;                                            // error
      if (!type->isSupportedType())
      {
        column_desc->defaultClass = COM_NO_DEFAULT;           // can't set a default for these, either.
        if (!errorCode)
          *CmpCommon::diags() << DgSqlCode(3044) << DgString0(column_desc->colname);
        else
          *errorCode = 3044;

      }
      break;
    case REC_BLOB :
      type = new (heap)
	SQLBlob(column_desc->precision, Lob_Invalid_Storage,
		column_desc->null_flag);
      break;

    case REC_CLOB :
      type = new (heap)
	SQLClob(column_desc->precision, Lob_Invalid_Storage,
		column_desc->null_flag);
      break;

    default:
      {
	// 4031 Column %s is an unknown data type, %d.
        if (!errorCode)
        {
	*CmpCommon::diags() << DgSqlCode(-4031)
	  << DgColumnName(makeColumnName(table, column_desc))
	  << DgInt0(column_desc->datatype);
        }
        else
        {
          *errorCode = 4031;
        }
	return TRUE;						// error
      }
    } // end switch (column_desc->datatype)

  CMPASSERT(type);

  if (type->getTypeQualifier() == NA_CHARACTER_TYPE) {
    CharInfo::Collation co = ((CharType *)type)->getCollation();

    // a "mini-cache" to avoid proc call, for perf
    static THREAD_P CharInfo::Collation cachedCO = CharInfo::UNKNOWN_COLLATION;
    static THREAD_P Int32         cachedFlags = CollationInfo::ALL_NEGATIVE_SYNTAX_FLAGS;

    if (cachedCO != co) {
      cachedCO = co;
      cachedFlags = CharInfo::getCollationFlags(co);
    }

    if (cachedFlags & CollationInfo::ALL_NEGATIVE_SYNTAX_FLAGS) {
      //
      //## The NCHAR/COLLATE NSK-Rel1 project is forced to disallow all user-
      //	defined collations here.  What we can't handle is:
      //	- full support!  knowledge of how to really collate!
      //	- safe predicate-ability of collated columns, namely
      //	  . ORDER/SEQUENCE/SORT BY
      //	    MIN/MAX
      //	    < <= > >=
      //		These *would* have been disallowed by the
      //		CollationInfo::ORDERED_CMP_ILLEGAL flag.
      //	  . DISTINCT
      //	    GROUP BY
      //	    = <>
      //		These *would* have been disallowed by the
      //		CollationInfo::EQ_NE_CMP_ILLEGAL flag.
      //	  . SELECTing a collated column which is a table or index key
      //		We *would* have done full table scan only, based on flag
      //	  . INS/UPD/DEL involving a collated column which is a key
      //		We *would* have had to disallow this, based on flag;
      //		otherwise we would position in wrong and corrupt either
      //		our partitioning or b-trees or both.
      //	See the "MPcollate.doc" document, and
      //	see sqlcomp/DefaultValidator.cpp ValidateCollationList comments.
      //
	{
	  // 4069 Column TBL.COL uses unsupported collation COLLAT.
	  if (!errorCode)
	  {
	  *CmpCommon::diags() << DgSqlCode(-4069)
	    << DgColumnName(makeColumnName(table, column_desc));
	  }
	  else
	  {
	    *errorCode= 4069;
	  }
	  return TRUE;						// error
	}
    }
  }

  return FALSE;							// no error

} // createNAType()
Exemplo n.º 2
0
static void CmpSPERROR2Diags(const SP_ERROR_STRUCT* spError, 
                             ComDiagsArea* diags)
{
  if ( !diags )
    return;

  if (spError[0].error == arkcmpErrorISPMergeCatDiags)
  {
    // Special error message to indicate that errors should really be
    // merged in from the catalog manager diags area.
    // not supported, raise unsupported error instead
    *diags << DgSqlCode(-4222)
           << DgString0("CmpSPERROR2Diags");
    return;
  }

  for ( Int32 i=0; i< SP_MAX_ERROR_STRUCTS; i++)
  {
    const SP_ERROR_STRUCT* pSET = &(spError[i]);
    if (pSET->error)
    {
      *diags << DgSqlCode(pSET->error);
      if(pSET->error == -20067) { //IDS_UTILITIES_BADSYNTAX = 20067
	// If utilities parser returned syntax error for syntax based 
	// utilities, error IDS_UTILITIES_BADSYNTAX is returned by 
	// utilities code to mxmcp.   
	// pSET->optionalString[1] has the utilities command from command line.
	// pSET->optionalInteger[0] has the approximate position of error in
	// the syntax of the utilities command given by user in command line.
	// The approximate error position is returned by utilities parser.

	// Function  StoreSyntaxError(.....) takes the information to put a 
	// caret (^) in the approximate position of the command and the 
	// information is saved in diags.
 
        StoreSyntaxError(pSET->optionalString[1],  // const char *      input_str
                         pSET->optionalInteger[0], // Int32             input_pos
                         *diags,                   // ComDiagsArea &    diagsArea
                         0,                        // Int32             dgStrNum
                         CharInfo::UTF8,           // CharInfo::CharSet input_str_cs
                         CharInfo::UTF8);          // CharInfo::CharSet terminal_cs
      }
      else{
      if ( pSET->optionalString[0] && 
           pSET->optionalString[0] != (char *) ComDiags_UnInitialized_Int )
        *diags << DgString0(pSET->optionalString[0]);
      if ( pSET->optionalString[1] &&
           pSET->optionalString[1] != (char *)ComDiags_UnInitialized_Int )
        *diags << DgString1(pSET->optionalString[1]);
      if ( pSET->optionalString[2] &&
           pSET->optionalString[2] != (char *)ComDiags_UnInitialized_Int )
        *diags << DgString2(pSET->optionalString[2]);
      if ( pSET->optionalString[3] &&
           pSET->optionalString[3] != (char *)ComDiags_UnInitialized_Int )
        *diags << DgString3(pSET->optionalString[3]);
      if ( pSET->optionalString[4] &&
           pSET->optionalString[4] != (char *)ComDiags_UnInitialized_Int )
        *diags << DgString4(pSET->optionalString[4]);
      if ( pSET->optionalInteger[0] != ComDiags_UnInitialized_Int )
        *diags << DgInt0(pSET->optionalInteger[0]);
      if ( pSET->optionalInteger[1] != ComDiags_UnInitialized_Int )
        *diags << DgInt1(pSET->optionalInteger[1]);
      if ( pSET->optionalInteger[2] != ComDiags_UnInitialized_Int )
        *diags << DgInt2(pSET->optionalInteger[2]);
      if ( pSET->optionalInteger[3] != ComDiags_UnInitialized_Int )
        *diags << DgInt3(pSET->optionalInteger[3]);
      if ( pSET->optionalInteger[4] != ComDiags_UnInitialized_Int )
        *diags << DgInt4(pSET->optionalInteger[4]);
      }
    }
    else if ( i==0 )
    {
      // this is the case that ISP implementation does not return any
      // SP_ERROR_STRUCT info back, but does return with error status.
      *diags << DgSqlCode(arkcmpErrorISPNoSPError);
      break;
    }
    else
      // no more SP_ERROR_STRUCT.
      break;
  }
}