SQLRETURN SQL_API SQLParamData()

in src/odbc/rsodbc/rsexecute.cpp [408:532]


SQLRETURN  SQL_API SQLParamData(SQLHSTMT phstmt, SQLPOINTER *ppValue)
{
    SQLRETURN rc = SQL_SUCCESS;
    RS_STMT_INFO *pStmt = (RS_STMT_INFO *)phstmt;

    if(IS_TRACE_LEVEL_API_CALL())
        TraceSQLParamData(FUNC_CALL, 0, phstmt, ppValue);

    if(!VALID_HSTMT(phstmt))
    {
        rc = SQL_INVALID_HANDLE;
        goto error;
    }

    // Is thread running?
    if(pStmt->pExecThread)
    {
        rc = checkExecutingThread(pStmt);
        if(rc == SQL_STILL_EXECUTING)
            return rc;
        else
        {
            if(pStmt->pExecThread->iExecFromParamData)
            {
                pStmt->pExecThread->iExecFromParamData = 0;
                resetAndReleaseDataAtExec(pStmt);
                waitAndFreeExecThread(pStmt, FALSE);
                return rc;
            }
            else
                rc = SQL_SUCCESS;
        }
    }

    // Clear error list
    pStmt->pErrorList = clearErrorList(pStmt->pErrorList);

    if(pStmt->pCopyCmd && (pStmt->pCopyCmd->iCopyCmdType == COPY_STDIN))
    {
        int endOfCopy = (ppValue == NULL) || (*ppValue == NULL) || (_stricmp((char *)(*ppValue),"end") == 0);

        if(endOfCopy)
        {
            // Copy END 
            if(pStmt->pCopyCmd->iCopyStatus == COPY_IN_BUFFER)
            {
                pStmt->pCopyCmd->iCopyStatus = COPY_IN_ENDED;
                rc = libpqCopyEnd(pStmt, TRUE, NULL);
            }
            else
            if(pStmt->pCopyCmd->iCopyStatus == COPY_IN_STREAM)
            {
                pStmt->pCopyCmd->iCopyStatus = COPY_IN_ENDED;
            }
            else
            {
                rc = SQL_ERROR;
                addError(&pStmt->pErrorList,"HY010", "COPY function sequence error", 0, NULL);
                goto error; 
            } 
        }
        else
        {
            // First call after execute for COPY. unix ODBC DM was giving Function seq. error without it.
            rc = SQL_NEED_DATA;
        }
    }
    else
    {
        if(ppValue == NULL)
        {
            rc = SQL_ERROR;
            addError(&pStmt->pErrorList,"HY009", "Invalid use of null pointer", 0, NULL);
            goto error; 
        }

        if(pStmt->pAPDRecDataAtExec)
        {
            if(pStmt->pAPDRecDataAtExec->pDataAtExec == NULL)
            {
                *ppValue = pStmt->pAPDRecDataAtExec->pValue;
                rc = SQL_NEED_DATA;
            }
            else
            {
                // Move to next data-at-exec
                if(needDataAtExec(pStmt, pStmt->pStmtAttr->pAPD->pDescRecHead,pStmt->lParamProcessedDataAtExec,pStmt->iExecutePreparedDataAtExec))
                {
                    *ppValue = pStmt->pAPDRecDataAtExec->pValue;
                    rc = SQL_NEED_DATA;
                }
                else
                {
                    if(pStmt->pExecThread)
                        pStmt->pExecThread->iExecFromParamData = 1;

                    // If all data-at-exec done then execute it.
                    rc = libpqExecuteDirectOrPrepared(pStmt, pStmt->pszCmdDataAtExec, pStmt->iExecutePreparedDataAtExec);

                    if(rc != SQL_STILL_EXECUTING)
                        resetAndReleaseDataAtExec(pStmt);

                    if(rc == SQL_ERROR)
                        goto error;

                    pStmt->iStatus =  RS_EXECUTE_STMT;

                }
            }
        }
        else
        {
            rc = SQL_ERROR;
            addError(&pStmt->pErrorList,"HY010", "Function sequence error", 0, NULL);
            goto error; 
        }
    } // !COPY

error:

    if(IS_TRACE_LEVEL_API_CALL())
        TraceSQLParamData(FUNC_RETURN, rc, phstmt, ppValue);

    return rc;
}