LmResult LmRoutineCppObj::dealloc(ComDiagsArea *diagsArea)
{
  LmResult result = LM_OK;

  delete invocationInfo_;
  invocationInfo_ = NULL;

  for (CollIndex i=0; i<planInfos_.getUsedLength(); i++)
    if (planInfos_.used(i))
      delete planInfos_[i];
  planInfos_.clear();

  if (paramRow_)
    {
      NADELETEBASIC(paramRow_, collHeap());
      paramRow_ = NULL;
    }

  if (inputRows_)
    {
      for (int i=0; i<numInputTables_; i++)
        if (inputRows_[i])
          NADELETEBASIC((inputRows_[i]), collHeap());
      NADELETEBASIC(inputRows_, collHeap());
      inputRows_ = NULL;
    }
  if (outputRow_)
    {
      // actually allocated buffer started where the wall starts
      NADELETEBASIC((outputRow_ - WALL_STRING_LEN), collHeap());
      outputRow_ = NULL;
    }

  try
    {
      // delete the interface object, the virtual destructor may call user code
      delete interfaceObj_;
    }
  catch (tmudr::UDRException e)
    {
      *diagsArea << DgSqlCode(-LME_UDR_METHOD_ERROR)
                 << DgString0("destructor")
                 << DgString1(getNameForDiags())
                 << DgString2(e.getMessage().c_str());
      result = LM_ERR;
    }
  catch (...)
    {
      *diagsArea << DgSqlCode(-LME_UDR_METHOD_ERROR)
                 << DgString0("destructor")
                 << DgString1(getNameForDiags())
                 << DgString2("General exception.");
      result = LM_ERR;
    }

  interfaceObj_ = NULL;

  return result;
}
//////////////////////////////////////////////////////////////////////
//
// Class LmRoutineCppObj
// If we get errors in creating this object, fill diagsArea and return
// error. Caller is responsbile to cleanup by calling destructor.
//
//////////////////////////////////////////////////////////////////////
LmRoutineCppObj::LmRoutineCppObj(
  tmudr::UDRInvocationInfo *invocationInfo,
  tmudr::UDRPlanInfo    *planInfo,
  tmudr::UDR            *interfaceObj,
  const char            *sqlName,
  const char            *externalName,
  const char            *librarySqlName,
  ComUInt32              maxResultSets,
  ComRoutineTransactionAttributes transactionAttrs,
  ComRoutineSQLAccess    sqlAccessMode,
  ComRoutineExternalSecurity externalSecurity,
  Int32                  routineOwnerId,
  LmLanguageManagerC    *lm,
  LmContainer           *container,
  ComDiagsArea          *diags)
  : LmRoutine(container,
              (LmHandle) interfaceObj,
              sqlName,
              externalName,
              librarySqlName,
              0,
              maxResultSets,
              COM_LANGUAGE_CPP,
              COM_STYLE_CPP_OBJ,
              transactionAttrs,
              sqlAccessMode,
              externalSecurity, 
              routineOwnerId,
              invocationInfo->getQueryId().c_str(),
              invocationInfo->par().getRecordLength(),
              invocationInfo->out().getRecordLength(),
              invocationInfo->getCurrentUser().c_str(),
              invocationInfo->getSessionUser().c_str(),
              NULL,
              lm),
    planInfos_(collHeap()),
    invocationInfo_(invocationInfo),
    interfaceObj_(interfaceObj),
    paramRow_(NULL),
    inputRows_(NULL),
    outputRow_(NULL)
{
  if (planInfo)
    planInfos_.insertAt(0, planInfo);
  interfaceObj_->getNextRowPtr_ = NULL; // set these with setFunctionPtrs()
  interfaceObj_->emitRowPtr_    = NULL;
  numInputTables_   = invocationInfo->getNumTableInputs();

  if (inputParamRowLen_ > 0)
    {
      paramRow_ = new(collHeap()) char[inputParamRowLen_];
      memset(paramRow_,0,inputParamRowLen_);
      const_cast<tmudr::ParameterListInfo &>(invocationInfo->par()).setRowPtr(paramRow_);
    }

  // inputRows_ and outputRow_ will be allocated in setRuntimeInfo() 
}
LmResult LmRoutineCppObj::setRuntimeInfo(
     const char   *parentQid,
     int           totalNumInstances,
     int           myInstanceNum,
     ComDiagsArea *da)
{
  invocationInfo_->setQueryId(parentQid);
  invocationInfo_->setTotalNumInstances(totalNumInstances);
  invocationInfo_->setMyInstanceNum(myInstanceNum);

  // allocate row buffers
  if (numInputTables_ > 0)
    {
      inputRows_ = new (collHeap()) char *[numInputTables_];
      for (int i=0; i<numInputTables_; i++)
        {
          int inputRowLength = invocationInfo_->in(i).recordLength_;

          if (inputRowLength > 0)
            {
              inputRows_[i] = new(collHeap()) char[inputRowLength];
              memset(inputRows_[i], 0, inputRowLength);
              const_cast<tmudr::TableInfo &>(
                   invocationInfo_->in(i)).setRowPtr(inputRows_[i]);
            }
          else
            // at compile time, input rows are not specified
            inputRows_[i] = NULL;
        }
    }
  else
    {
      inputRows_ = NULL;
    }

  if (outputRowLen_ > 0)
    {
      outputRow_ = new (collHeap()) char[outputRowLen_ + 2*WALL_STRING_LEN];
      // remember the pointer to the actually usable
      // buffer, not where the wall starts
      outputRow_ += WALL_STRING_LEN;
      memset(outputRow_, 0, outputRowLen_);
      setUpWall(outputRow_, outputRowLen_);
      invocationInfo_->out().setRowPtr(outputRow_);
    }
  else
    outputRow_ = NULL;

  return LM_OK;
}
LmRoutineJava::~LmRoutineJava()
{
  JNIEnv *jni = (JNIEnv*)getLM()->jniEnv_;
  jvalue *jval = (jvalue*)javaParams_;

  // Free LmResultSet objects
  // This will also close the Java result set objects
  // and the Java connections that they are part of.
  cleanupResultSets();

  // Free LmConnection objects for default connections
  // Closes any open default connections that do not have 
  // result sets associated with them
  closeDefConnWithNoRS();

  connectionList_.clear();
    
  // Release array refs for params, indicated
  // by non-null object.
  for (Int32 i = 0; i < (Int32)numParamsInSig_; i++)
  {
    if (jval[i].l != NULL)
      jni->DeleteLocalRef(jval[i].l);
  }

  // Free the Java parameter array
  if (javaParams_)
    NADELETEBASIC((jvalue *)javaParams_, collHeap());
}
Exemple #5
0
LmHandle LmLanguageManagerC::loadContainer(
  const char   *containerName,
  const char   *externalPath,
  LmHandle     extLoader,
  ComUInt32    *containerSize,
  ComDiagsArea *da)
{
  return loadDll(containerName, externalPath, extLoader, 
                          containerSize, da, collHeap());
}
// This method creates a LmResultSetJava object for the 
// passed in java.sql.ResultSet object (newRS) and inserts 
// it into resultSetList_.
//
// Parameters:
// newRS    - A java.sql.ResultSet object
// paramPos - The position (1-based) of newRS
//            in the Java method signature.
// da       - ComDiagsArea object to report any errors. 
//            This object should not be NULL.
LmResult LmRoutineJava::populateResultSetInfo(LmHandle newRS, Int32 paramPos, 
                                              ComDiagsArea *da)
{
  LmResult result = LM_OK;
  jobject newRSRef = (jobject)newRS;

  LM_ASSERT(da != NULL);

  // SPJ method can return same java.sql.ResultSet object in 
  // multiple OUT params but we ignore such duplicates.
  // We also ignore a NULL java.sql.ResultSet object.
  if( newRSRef == NULL || isDuplicateRS( newRSRef ))
    return result;

  LmResultSetJava::LmResultSetInfoStatus rsInfoStatus;

  LmResultSetJava *newLmRS = 
			  new (collHeap()) LmResultSetJava( getLM(),
                                          (LmHandle)newRSRef,
                                          paramPos,
                                          getNameForDiags(),
                                          rsInfoStatus,
                                          connectionList_,
                                          da );

  // If the constructor returned a success status then insert 
  // the newLmRS object into resultSetList_ otherwise delete it.
  if( rsInfoStatus == LmResultSetJava::RS_INFO_OK ) {

    // Order the objects inserted in the resultSetList_ based on
    // the order in which the result set cursors were opened.
    ComUInt32 i;
    LmResultSetJava *lmRS;
    for( i = 0; i < resultSetList_.entries(); i++ )
    {
      lmRS = (LmResultSetJava *)resultSetList_[i];
      if( newLmRS->rsCounter_ < lmRS->rsCounter_ )
        break;
    }
    resultSetList_.insertAt( i, newLmRS );
  }
  else {
    delete newLmRS;
    newLmRS = NULL;

    // Ignore closed result sets
    if( rsInfoStatus == LmResultSetJava::RS_INFO_CLOSED )
      result = LM_OK;
    else
      result = LM_ERR;
  }

  return result;
}
Exemple #7
0
LmLanguageManagerC::LmLanguageManagerC(
  LmResult &result,
  NABoolean commandLineMode,
  ComDiagsArea *diagsArea)
  : LmLanguageManager(commandLineMode),
    diagsArea_(diagsArea)
{
  setRoutineIsActive(FALSE);
  contManager_ = new (collHeap()) LmContainerManagerSimple(this);
  result = LM_OK;
}
UniqueConstraint::~UniqueConstraint()
{
  NAHeap *heap = (NAHeap *)collHeap();
  CollIndex entryCount = refConstraintsReferencingMe_.entries();
  if (heap != NULL) { 
     for (CollIndex i = 0 ; i < entryCount; i++) {
          NADELETE(refConstraintsReferencingMe_[i], ComplementaryRIConstraint, heap);
     }
  }
  else {
     for (CollIndex i = 0 ; i < entryCount; i++) 
          delete refConstraintsReferencingMe_[i];
  }
  refConstraintsReferencingMe_.clear();
}
AbstractRIConstraint::~AbstractRIConstraint()
{
  NAHeap *heap = (NAHeap *)collHeap();
  CollIndex entryCount = keyColumns_.entries();
  if (heap != NULL) {
     for (CollIndex i = 0 ; i < entryCount; i++) {
          NADELETE(keyColumns_[i], NAColumn, heap);
     }
  }
  else {
     for (CollIndex i = 0 ; i < entryCount; i++) 
          delete keyColumns_[i];
  }
  keyColumns_.clear();
}
LmRoutineCSql::LmRoutineCSql(const char   *sqlName,
                             const char   *externalName,
                             const char   *librarySqlName,
                             ComUInt32    numSqlParam,
                             char         *routineSig,
                             ComUInt32    maxResultSets,
                             ComRoutineTransactionAttributes transactionAttrs,
                             ComRoutineSQLAccess sqlAccessMode,
                             ComRoutineExternalSecurity externalSecurity,
                             Int32 routineOwnerId,
                             const char   *parentQid,
                             ComUInt32    inputRowLen,
                             ComUInt32    outputRowLen,
                             const char   *currentUserName,
                             const char   *sessionUserName,
                             LmParameter  *parameters,
                             LmLanguageManagerC *lm,
                             LmHandle     routine,
                             LmContainer  *container,
                             ComDiagsArea *diagsArea)
  : LmRoutineC(sqlName, externalName, librarySqlName, numSqlParam, routineSig,
               maxResultSets,
               COM_LANGUAGE_C,
               COM_STYLE_SQL,
               transactionAttrs,
               sqlAccessMode,
               externalSecurity, 
	       routineOwnerId,
               parentQid, inputRowLen, outputRowLen,
               currentUserName, sessionUserName, 
               parameters, lm, routine, container, diagsArea),
    cBuf_(NULL),
    data_(NULL),
    ind_(numSqlParam * sizeof(short))
{
  ComUInt32 i = 0;
  data_ = (char **) collHeap()->allocateMemory(numSqlParam * sizeof(char *));
  
  // Allocate C data buffers. Each LmCBuffer instance points to a C
  // buffer and the data_ buffer is an array of pointers to the C data
  // buffers. The LmCBuffer is mainly used to track the actual size of
  // the C buffers because each buffer has some extra bytes at the end
  // to protect against buffer overwrites.
  //
  // cBuf_ -> LmCBuffer  LmCBuffer  LmCBuffer ...
  //            |          |          |
  //            v          v          v
  //           buffer     buffer     buffer   ...
  //             ^          ^          ^
  //             |          |          |
  //          data_[0]   data_[1]   data_[2]  ...
  //

  // NOTE: the cBuf_ array is allocated on the C++ heap because we
  // want to manage the collection as a single array, and we want
  // constructors and destructors to be called when the collection is
  // created and destroyed. Right now, NAMemory and NABasic object
  // interfaces do not provide the appropriate array versions of new
  // and delete operators to accomplish these things.
  cBuf_ = new LmCBuffer[numSqlParam_];
  LM_ASSERT(cBuf_);

  for (i = 0; i < numSqlParam_; i++)
  {
    LmParameter &p = lmParams_[i];
    LmCBuffer &cBuf = cBuf_[i];
    ComUInt32 dataBytes = 0;

    switch (p.direction())
    {
      // NOTE: The code currently supports IN and OUT parameters for C
      // routines. There is no reason we couldn't support INOUT as
      // well, which will be needed if we ever provide stored
      // procedures written in C. But the INOUT code paths have not
      // been implemented yet.
      case COM_INPUT_COLUMN:
        dataBytes = p.inSize();
        break;
      case COM_OUTPUT_COLUMN:
        dataBytes = p.outSize();
        break;
      default:
        LM_ASSERT(0);
        break;
    }

    switch (p.fsType())
    {
      case COM_VCHAR_FSDT:
      case COM_VCHAR_DBL_FSDT:
      {
        // VARCHAR(N) CHARACTER SET ISO88591
        // VARCHAR(N) CHARACTER SET UCS2

        // This is a VARCHAR parameter. Allocate one buffer that will
        // hold the VC struct and the data. Data will begin at the first
        // 8-byte boundary following the VC struct.
        ComUInt32 vcBytes = ROUND8(sizeof(SQLUDR_VC_STRUCT)) + dataBytes;
        cBuf.init(vcBytes);
        data_[i] = cBuf.getBuffer();
        
        // Initialize the VC struct
        SQLUDR_VC_STRUCT *vc = (SQLUDR_VC_STRUCT *) cBuf.getBuffer();
        char *charPtr = (char *) vc;
        vc->data = charPtr + ROUND8(sizeof(SQLUDR_VC_STRUCT));
        vc->length = dataBytes;
      }
      break;

      case COM_FCHAR_FSDT:
      case COM_FCHAR_DBL_FSDT:
      case COM_SIGNED_DECIMAL_FSDT:
      case COM_UNSIGNED_DECIMAL_FSDT:
      case COM_DATETIME_FSDT:
      case COM_SIGNED_NUM_BIG_FSDT:
      case COM_UNSIGNED_NUM_BIG_FSDT:
      {
        // CHAR(N) CHARACTER SET ISO88591
        // CHAR(N) CHARACTER SET UCS2
        // DECIMAL [UNSIGNED]
        // DATE, TIME, TIMESTAMP
        // NUMERIC precision > 18

        // These types require a null-terminated C string. Add one to
        // dataBytes to account for the null terminator.
        cBuf.init(dataBytes + 1);
        data_[i] = cBuf.getBuffer();
      }
      break;

      default:
      {
        // All other types
        cBuf.init(dataBytes);
        data_[i] = cBuf.getBuffer();
      }
      break;

    } // switch (p.fsType())
  } // for each param
    
} // LmRoutineCSql::LmRoutineCSql
//////////////////////////////////////////////////////////////////////
//
// Class LmRoutineJava
// If we get errors in creating this object, fill diagsArea and return
// error. Caller is responsbile to cleanup by calling destructor.
//
//////////////////////////////////////////////////////////////////////
LmRoutineJava::LmRoutineJava(
  const char            *sqlName,
  const char            *externalName,
  const char            *librarySqlName,
  ComUInt32              numSqlParam,
  LmParameter           *returnValue,
  ComUInt32              maxResultSets,
  char                  *routineSig,
  ComRoutineParamStyle   paramStyle,
  ComRoutineTransactionAttributes transactionAttrs,
  ComRoutineSQLAccess    sqlAccessMode,
  ComRoutineExternalSecurity externalSecurity,
  Int32                 routineOwnerId,
  const char            *parentQid,
  ComUInt32              inputRowLen,
  ComUInt32              outputRowLen,
  const char            *currentUserName,
  const char            *sessionUserName,
  LmParameter           *parameters,
  LmLanguageManagerJava *lm,
  LmHandle               routine,
  LmContainer           *container,
  ComDiagsArea          *da)
  : LmRoutine(container, routine, sqlName, externalName, librarySqlName,
              numSqlParam, maxResultSets,
              COM_LANGUAGE_JAVA, paramStyle, transactionAttrs, sqlAccessMode,
              externalSecurity, 
	      routineOwnerId,
              parentQid, inputRowLen, outputRowLen, 
              currentUserName, sessionUserName, 
	      parameters, lm),
    javaParams_(NULL),
    retType_(LmJavaType::JT_NONE),
    defaultCatSch_(FALSE),
    connectionList_(collHeap())
{
  JNIEnv *jni = (JNIEnv*)getLM()->jniEnv_;

  setUdrForJavaMain((str_cmp_ne(externalName, "main") == 0) ? TRUE : FALSE);

  // this is the internal SPJ used in CREATE PROCEDURE
  // mark it for examining Java exceptions to determine SQL diagnostics later

  if ((str_cmp_ne(container->getName(), "org.trafodion.sql.udr.LmUtility") == 0) &&
      (str_cmp_ne(externalName, "validateMethod") == 0))
    setIsInternalSPJ(TRUE);
  else
    setIsInternalSPJ(FALSE);

  if (paramStyle == COM_STYLE_JAVA_OBJ)
    return;
 
  // Get method return type.
  retType_ = LmJavaType(returnValue).getType();

  //
  // Now setup the parameters to the method.
  //
  // UDR-MAIN gets special treatment
  //
  // Allocate only one jvalue because main() takes only
  // one parameter of type String[].
  //
  // Then create java.lang.String array of size numSqlParam_
  // which equals to numSqlParam
  //
  if (isUdrForJavaMain())
  {
    numParamsInSig_ = 1;  // Number of parameters in Java main method

    javaParams_ = new (collHeap()) jvalue[1];
    memset((char*)javaParams_, 0, sizeof(jvalue));

    ((jvalue *)javaParams_)->l = jni->NewObjectArray((jsize)numSqlParam_,
                                      (jclass)lm->stringClass_,
                                      NULL);
    if (((jvalue *)javaParams_)->l == NULL)
    {
      *da << DgSqlCode(-LME_JVM_OUT_OF_MEMORY);
      getLM()->exceptionReporter_->checkJVMException(da, 0);
    }

    return;
  }

  // For a Java main method we would have already returned and 
  // do not get this far. Logic in the rest of this method does 
  // not need to consider main methods as a special case.

  // Get the total number of parameters present in the method 
  // signature.
  LmJavaSignature lmSig(routineSig, collHeap());
  Int32 result = lmSig.getParamCount();
  if( result < (Int32)numSqlParam_ ) {
    *da << DgSqlCode(-LME_INTERNAL_ERROR)
        << DgString0(": LmJavaSignature::getParamCount() returned an invalid value.");
    return;
  }
  numParamsInSig_ = (ComUInt32)result;

  //
  // Setup Paramters for Non-main methods
  //
  // Allocate Java method parameter array for SQL
  // and result set params
  if (numParamsInSig_ > 0)
  {
    javaParams_ = new (collHeap()) jvalue[numParamsInSig_];
    memset((char*)javaParams_, 0, numParamsInSig_ * sizeof(jvalue));
  }

 
  // Allocate a 1-element array for each OUT/INOUT mode parameter.
  jvalue *jval = (jvalue*)javaParams_;

  Int32 i = 0;
  for (i = 0; i < (Int32)numSqlParam_; i++)
  {
    LmParameter &p = lmParams_[i];

    if (p.direction() == COM_INPUT_COLUMN)
      continue;

    jobjectArray ja = NULL;

    switch (LmJavaType(&p).getType())
    {
    case LmJavaType::JT_SHORT:
      jval[i].l = (jobject)jni->NewShortArray(1);
      break;

    case LmJavaType::JT_INT:
      jval[i].l = (jobject)jni->NewIntArray(1);
      break;

    case LmJavaType::JT_LONG:
      jval[i].l = (jobject)jni->NewLongArray(1);
      break;

    case LmJavaType::JT_FLOAT:
      jval[i].l = (jobject)jni->NewFloatArray(1);
      break;

    case LmJavaType::JT_DOUBLE:
      jval[i].l = (jobject)jni->NewDoubleArray(1);
      break;

    case LmJavaType::JT_LANG_STRING:
      ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->stringClass_, NULL);
      break;

    case LmJavaType::JT_MATH_BIGDEC:
      ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->bigdecClass_, NULL);
      break;

    case LmJavaType::JT_SQL_DATE:
      ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->dateClass_, NULL);
      break;

    case LmJavaType::JT_SQL_TIME:
      ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->timeClass_, NULL);
      break;

    case LmJavaType::JT_SQL_TIMESTAMP:
      ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->stampClass_, NULL);
      break;

    case LmJavaType::JT_LANG_INTEGER:
      ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->intClass_, NULL);
      break;

    case LmJavaType::JT_LANG_LONG:
      ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->longClass_, NULL);
      break;

    case LmJavaType::JT_LANG_FLOAT:
      ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->floatClass_, NULL);
      break;

    case LmJavaType::JT_LANG_DOUBLE:
      ja = (jobjectArray) jni->NewObjectArray(1, (jclass)lm->doubleClass_, NULL);
      break;

    default:
      char str[LMJ_ERR_SIZE_256];
      sprintf (str,
               ": Unknown parameter type at parameter position %d.",
               i+1);
      *da << DgSqlCode(-LME_INTERNAL_ERROR)
          << DgString0(str);
      return;
    }// switch()

    if (ja != NULL)
      jval[i].l = ja;

    if (jval[i].l == NULL)
    {
      // OutOfMemory is the only error that could happen here.
      *da << DgSqlCode(-LME_JVM_OUT_OF_MEMORY);

      getLM()->exceptionReporter_->checkJVMException(da, 0);
      return;
    }

  } // for()

  // Allocate a 1-element array for each result set parameter.
  for (i = (Int32)numSqlParam_; i < (Int32)numParamsInSig_; i++)
  {
    jobjectArray ja = NULL;

    ja = jni->NewObjectArray(1, (jclass)lm->resultSetClass_, NULL);
    if (ja != NULL)
      jval[i].l = ja;

    if (jval[i].l == NULL)
    {
      // OutOfMemory is the only error that could happen here.
      *da << DgSqlCode(-LME_JVM_OUT_OF_MEMORY);

      getLM()->exceptionReporter_->checkJVMException(da, 0);
      return;
    }
  }

  return;
}
LmResult LmRoutineJava::invokeRoutine(void *inputRow,
				      void *outputRow,
				      ComDiagsArea *da)
{
  // Delete the LmResultSet objects for re-invocations
  // This will also close the Java result set objects
  // and the Java connections that they are part of
  cleanupResultSets(da);

  // This will close any default connections that do not have 
  // result sets associated with them
  closeDefConnWithNoRS(da);

  // Cleanup the list maintained in LmUtlity.cpp file that will get
  // populated with default connection objects that may get created
  // during this routine's invocation.
  lmUtilityInitConnList((JNIEnv*)getLM()->jniEnv_, (jmethodID)getLM()->connCloseId_);

  // Set the default catalog & schema as system properties. These
  // values are then retrieved by LmSQLMXDriver class for setting
  // it on a getConnection() call
  if (getDefaultCatSchFlag())
  {
    // Determine the catalog & schema values that will be in effect for
    // this UDR. If the values are set globally(with catalog/schema
    // props in CQD) they are used else the catalog/schema of
    // the UDR are used. 
    const char *catalog =
      (getLM()->sysCatalog_) ? getLM()->sysCatalog_ : udrCatalog_;
    const char *schema =
      (getLM()->sysSchema_) ? getLM()->sysSchema_ : udrSchema_;

    if (getLM()->setSystemProperty("sqlmx.udr.catalog", catalog, da) == LM_ERR)
      return LM_ERR;
    if (getLM()->setSystemProperty("sqlmx.udr.schema", schema, da) == LM_ERR)
      return LM_ERR;
  }

  const char *parentQid;
  if ((parentQid = getParentQid()) == NULL)
    parentQid = "NONE";
  if (getLM()->setSystemProperty("sqlmx.udr.parentQid", parentQid, da) == LM_ERR)
      return LM_ERR;
  // Set SQL access mode in LmUtility. This will be checked while SPJ
  // is trying to make a JDBC connection.
  lmUtilitySetSqlAccessMode(getSqlAccessMode());
  
  // Set Transaction Attribute in LmUtility. This will be checked while SPJ
  // is trying to join a transaction.
  lmUtilitySetTransactionAttrs(getTransactionAttrs());

  LmResult result = LM_OK;

  // Set the Definer Authentication Token as system property for
  // Definer Rights SPJs. This value is then retrieved by LmSQLMXDriver class 
  // for setting the password property in getConnection() call.
  if ( externalSecurity_ == COM_ROUTINE_EXTERNAL_SECURITY_DEFINER )
  {
      char *defAuthToken = new (collHeap()) char[DR_SPJ_TOKEN_LEN + 1];
      result = generateDefAuthToken(defAuthToken, da);
      if (result != LM_ERR)
         result = getLM()->setSystemProperty("sqlmx.udr.defAuthToken", defAuthToken, da);
      NADELETEBASIC(defAuthToken, collHeap());
      if (result == LM_ERR)
      {
        char errStr[LMJ_ERR_SIZE_256];
        sprintf (errStr,
                 ": Error returned from setting System Property:  %s.",
       	         "sqlmx.udr.defAuthToken");
        *da << DgSqlCode(-LME_INTERNAL_ERROR)
            << DgString0(errStr);
        return LM_ERR;
      }
  }

  lm_->setRoutineIsActive(TRUE);

  switch (retType_)
  {
    case LmJavaType::JT_VOID:
      result = voidRoutine(outputRow, NULL);
      break;
    default:
      // Other return types are not supported. In the future if we
      // support routines with non-void return types we will need to
      // add case blocks to this switch statement.
      LM_ASSERT(0);
      break;
  }
  
  lm_->setRoutineIsActive(FALSE);

  // Reset the sqlmx.udr.defAuthToken system property for
  // Definer Rights SPJs. 
  if ( externalSecurity_ == COM_ROUTINE_EXTERNAL_SECURITY_DEFINER )
  {
      result = getLM()->clearSystemProperty("sqlmx.udr.defAuthToken", da);
      if (result == LM_ERR)
      {
        char errStr[LMJ_ERR_SIZE_256];
        sprintf (errStr,
                 ": Error returned from Resetting System Property:  %s.",
       	         "sqlmx.udr.defAuthToken");
        *da << DgSqlCode(-LME_INTERNAL_ERROR)
            << DgString0(errStr);
        return LM_ERR;
      }
  }

  // Get the list containing the default connection objects
  // from LmUtility.cpp and create a LmConnection object for 
  // each item in that list.
  NAList<jobject> &connList = lmUtilityGetConnList();
  while(connList.entries())
  {
    jobject conn = connList[0];
    LmConnection *lmConn = 
      new (collHeap()) LmConnection(getLM(), conn,
                                    LmConnection::DEFAULT_CONN, getTransactionAttrs());
    
    connectionList_.insert( lmConn );
    connList.removeAt(0);
  }

  // reset SQL Access mode to COM_UNKNOWN_ROUTINE_SQL_ACCESS
  lmUtilitySetSqlAccessMode(COM_UNKNOWN_ROUTINE_SQL_ACCESS);
  
  // reset Transaction Attributes to COM_UNKNOWN_ROUTINE_TRANSACTION_ATTRIBUTE
  lmUtilitySetTransactionAttrs(COM_UNKNOWN_ROUTINE_TRANSACTION_ATTRIBUTE);

  return result;
}
Exemple #13
0
LmResult LmLanguageManagerC::getRoutine(
  ComUInt32    numSqlParam,
  LmParameter  parameters[],
  ComUInt32   numTableInfo,
  LmTableInfo tableInfo[],
  LmParameter  *returnValue,
  ComRoutineParamStyle paramStyle,
  ComRoutineTransactionAttributes transactionAttrs,
  ComRoutineSQLAccess sqlAccessMode,
  const char   *parentQid,
  ComUInt32    inputRowLen,
  ComUInt32    outputRowLen,
  const char   *sqlName,
  const char   *externalName,
  const char   *routineSig,
  const char   *containerName,
  const char   *externalPath,
  const char   *librarySqlName,
  const char   *currentUserName,
  const char   *sessionUserName,
  ComRoutineExternalSecurity externalSecurity,
  Int32        routineOwnerId,
  LmRoutine    **handle,
  LmHandle     getNextRowPtr,
  LmHandle     emitRowPtr,
  ComUInt32    maxResultSets,
  ComDiagsArea *diagsArea)
{
  *handle = NULL;
  LmContainer *container = NULL;
  LmResult result = LM_OK;

  ComDiagsArea *da = (diagsArea != NULL) ? diagsArea : diagsArea_;

  // Get the requested container from the CM.
  result = contManager_->getContainer(containerName, externalPath,
                                      &container, da);
  if (result == LM_ERR)
    return LM_ERR;
  
  // Get a handle to the requested routine
  LmHandle routinePtr = NULL;
  routinePtr = getRoutinePtr(container->getHandle(), externalName);

  const char *operation = "dlsym";
  if (routinePtr == NULL)
  {
    char *libraryName = new (collHeap())
      char[str_len(externalPath) + str_len(containerName) + 2];
    sprintf(libraryName, "%s/%s", externalPath, containerName);

    *da << DgSqlCode(-LME_DLL_METHOD_NOT_FOUND)
        << DgString0(externalName)
        << DgString1(libraryName);

    addDllErrors(*da, operation, FALSE);

    NADELETEBASIC(libraryName, collHeap());
    return LM_ERR;
  }

  // allocate an LM handle for the external method.
  LmRoutine *routineHandle = NULL;
  if (paramStyle == COM_STYLE_SQL)
  {
    routineHandle =
      new (collHeap()) LmRoutineCSql(sqlName,
                                     externalName,
                                     librarySqlName,
                                     numSqlParam,
                                     (char *)routineSig,
                                     maxResultSets,
                                     transactionAttrs,
                                     sqlAccessMode,
                                     externalSecurity,
                                     routineOwnerId,
                                     parentQid,
                                     inputRowLen,
                                     outputRowLen,
                                     currentUserName,
                                     sessionUserName,
                                     parameters,
                                     this,
                                     routinePtr,
                                     container,
                                     da);
  }
  else if (paramStyle == COM_STYLE_SQLROW)
  {
    routineHandle =
      new (collHeap()) LmRoutineCSqlRow(sqlName,
                                        externalName,
                                        librarySqlName,
                                        numSqlParam,
                                        (char *)routineSig,
                                        maxResultSets,
                                        transactionAttrs,
                                        sqlAccessMode,
                                        externalSecurity,
                                        routineOwnerId,
                                        parentQid,
                                        inputRowLen,
                                        outputRowLen,
                                        currentUserName,
                                        sessionUserName,
                                        parameters,
                                        this,
                                        routinePtr,
                                        container,
                                        da);
  }
  else if (paramStyle == COM_STYLE_TM)
  {
    routineHandle =
      new (collHeap()) LmRoutineCSqlRowTM(sqlName,
                                        externalName,
                                        librarySqlName,
                                        numSqlParam,
                                        numTableInfo,
                                        tableInfo,
                                        (char *)routineSig,
                                        maxResultSets,
                                        transactionAttrs,
                                        sqlAccessMode,
                                        externalSecurity,
                                        routineOwnerId,
                                        parentQid,
                                        inputRowLen,
                                        outputRowLen,
                                        currentUserName,
                                        sessionUserName,
                                        parameters,
                                        this,
                                        routinePtr,
                                        getNextRowPtr,
                                        emitRowPtr,
                                        container,
                                        da);
  }
  else 
  {
    // XXX LM_ASSERT(0);
    char *paramStyleMsg = new (collHeap())
      char[100];
    sprintf(paramStyleMsg, "Unknown ParameterStyle(%d)", paramStyle);

    *da << DgSqlCode(-LME_VALIDATION_FAILED)
        << DgString0(externalName)
        << DgString1(paramStyleMsg);

    addDllErrors(*da, operation, FALSE);
  }

  // Verify the handle.
  if (routineHandle == NULL)
  {
    // DiagsArea is already filled
    if (container)
      contManager_->putContainer(container);
    return LM_ERR;
  }
  else
  {
    *handle = routineHandle;
    return LM_OK;
  }
}
Exemple #14
0
LmHandle LmLanguageManagerC::createLoader(
  const char   *externalPath,
  ComDiagsArea *da)
{
  return new (collHeap()) LmCLoader();
}