SQLRETURN SQL_API RsDesc::RS_SQLSetDescField()

in src/odbc/rsodbc/rsdesc.cpp [711:1013]


SQLRETURN  SQL_API RsDesc::RS_SQLSetDescField(SQLHDESC phdesc,
                                    SQLSMALLINT hRecNumber, 
                                    SQLSMALLINT hFieldIdentifier,
                                    SQLPOINTER pValue, 
                                    SQLINTEGER cbLen,
                                    int iInternal)
{
    SQLRETURN rc = SQL_SUCCESS;
    RS_DESC_INFO *pDesc = (RS_DESC_INFO *)phdesc;
    RS_DESC_HEADER &pDescHeader = pDesc->pDescHeader;;
    RS_DESC_REC *pDescRec = NULL;
    int iVal = (int)(long)pValue;
    long lVal = 0;
    short hVal = (short)(long)pValue;
    int iIsHeaderField;
    int iIsWritableField;

    lVal = (long)iVal;

    if(!VALID_HDESC(phdesc))
    {
        rc = SQL_INVALID_HANDLE;
        goto error;
    }

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

    iIsWritableField = (iInternal) ? TRUE : isWritableField(pDesc, hFieldIdentifier);

    if(!iIsWritableField)
    {
        rc = SQL_ERROR;
        addError(&pDesc->pErrorList,"HY000", "Field is not writable", 0, NULL);
        goto error;
    }

    iIsHeaderField = isHeaderField(hFieldIdentifier);

    if(!iIsHeaderField)
    {
        // Check for record number.
        if(hRecNumber <= 0)
        {
            rc = SQL_ERROR;
            addError(&pDesc->pErrorList,"07009", "Invalid descriptor index", 0, NULL);
            goto error; 
        }

        // Find if rec already exist otherwise add.
        pDescRec = checkAndAddDescRec(pDesc, hRecNumber, TRUE, NULL);
        if(pDescRec == NULL)
        {
            rc = SQL_ERROR;
            if(pDesc->iRecListType ==  RS_DESC_RECS_ARRAY_LIST)
                addError(&pDesc->pErrorList,"HY000", "Cannot add new rec in an array", 0, NULL);
            else
                addError(&pDesc->pErrorList,"HY001", "Memory allocation error", 0, NULL);
            goto error;
        }
    }
    else
    {
        if(pDesc->pDescHeader.valid == false)
        {
            rc = SQL_ERROR;
            addError(&pDesc->pErrorList,"HY000", "Null pointer found", 0, NULL);
            goto error;
        }
    }

    switch(hFieldIdentifier)
    {
        // Header fields
        case SQL_DESC_ARRAY_SIZE:
        {
            if(lVal <= 0)
            {
                rc = SQL_ERROR;
                addError(&pDesc->pErrorList,"HY024", "Invalid attribute/option identifier", 0, NULL);
                goto error;
            }

            pDescHeader.lArraySize = lVal;

            break;
        }

        case SQL_DESC_ARRAY_STATUS_PTR:
        {
            pDescHeader.phArrayStatusPtr = (short *)pValue;

            break;
        }

        case SQL_DESC_BIND_OFFSET_PTR:
        {
            pDescHeader.plBindOffsetPtr = (SQLLEN *)pValue;
            break;
        }

        case SQL_DESC_BIND_TYPE:
        {
            if(lVal != SQL_BIND_BY_COLUMN 
                && !(lVal >= 0))
            {
                rc = SQL_ERROR;
                addError(&pDesc->pErrorList,"HY024", "Invalid attribute/option identifier", 0, NULL);
                goto error;
            }

            pDescHeader.lBindType = lVal;

            break;
        }

        case SQL_DESC_COUNT:
        {
            RS_DESC_REC *pTempDescRec;
            RS_DESC_REC *pTempNextDescRec;
            int zeroAllowed = ((pDesc->iType == RS_APD || pDesc->iType == RS_ARD)
                                && (pDesc->iRecListType == RS_DESC_RECS_LINKED_LIST));

            if(hVal < 0 || (hVal == 0 && !zeroAllowed))
            {
                rc = SQL_ERROR;
                addError(&pDesc->pErrorList,"HY024", "Invalid attribute/option identifier", 0, NULL);
                goto error;
            }

            pDescHeader.hHighestCount = hVal;

            if(hVal != 0)
            {
                // Check if we need to create the record
                pDescRec = checkAndAddDescRec(pDesc, hVal, TRUE, NULL);
            }

            // Remove records above the given number
            // For ARD and APD if count is 0 then we remove all records.
            // Loop through rec list
            for(pTempDescRec  = pDesc->pDescRecHead;pTempDescRec != NULL;pTempDescRec = pTempNextDescRec)
            {
                pTempNextDescRec = pTempDescRec->pNext;
                if(pTempDescRec->hRecNumber > hVal)
                    releaseDescriptorRec(pDesc, pTempDescRec);
            }

            break;
        }

        case SQL_DESC_ROWS_PROCESSED_PTR:
        {
            pDescHeader.plRowsProcessedPtr = (long *)pValue;

            break;
        }

        // Rec fields

        case SQL_DESC_DATA_PTR:
        {
            pDescRec->pValue = pValue;
            break;
        }

        case SQL_DESC_INDICATOR_PTR:
        {
            pDescRec->pcbLenInd = (SQLLEN *)pValue;
            break;
        }

        case SQL_DESC_LENGTH:
        {
            pDescRec->iSize = iVal;
            break;
        }

        case SQL_DESC_NAME:
        {
            copyStrDataSmallLen((char *)pValue, cbLen, pDescRec->szName, MAX_IDEN_LEN, NULL);
            break;
        }

        case SQL_DESC_NUM_PREC_RADIX:
        {
            pDescRec->iNumPrecRadix = iVal;
            break;
        }

        case SQL_DESC_OCTET_LENGTH:
        {
            pDescRec->iOctetLen = iVal;

            if(pDesc->iType == RS_APD
                 || pDesc->iType == RS_ARD)
            {
                if(pDescRec->cbLen == 0)
                {
                    pDescRec->cbLen  = iVal;
                }
            }

            break;
        }

        case SQL_DESC_OCTET_LENGTH_PTR:
        {
            pDescRec->plOctetLen = (SQLINTEGER *)pValue;
            break;
        }

        case SQL_DESC_PARAMETER_TYPE:
        {
            pDescRec->hInOutType = hVal;
            break;
        }

        case SQL_DESC_PRECISION:
        {
            pDescRec->iPrecision = hVal;
            break;
        }

        case SQL_DESC_SCALE:
        {
            pDescRec->hScale = hVal;
            break;
        }

        case SQL_DESC_TYPE:
        {
            pDescRec->hType = hVal;
            break;
        }

        case SQL_DESC_CONCISE_TYPE:
        {
            pDescRec->hConciseType = hVal;

            if(pDesc->iType == RS_APD
                 || pDesc->iType == RS_ARD
                 || pDesc->iType == RS_IPD)
            {
                pDescRec->hType = getCTypeFromConciseType(hVal, pDescRec->hDateTimeIntervalCode, pDescRec->hType);
            }

            break;
        }

        case SQL_DESC_UNNAMED:
        {
            pDescRec->iUnNamed = hVal;
            break;
        }

        case SQL_DESC_AUTO_UNIQUE_VALUE:
        case SQL_DESC_BASE_COLUMN_NAME:
        case SQL_DESC_BASE_TABLE_NAME:
        case SQL_DESC_CASE_SENSITIVE:
        case SQL_DESC_CATALOG_NAME:
        case SQL_DESC_DISPLAY_SIZE:
        case SQL_DESC_FIXED_PREC_SCALE:
        case SQL_DESC_LABEL:
        case SQL_DESC_LITERAL_PREFIX:
        case SQL_DESC_LITERAL_SUFFIX:
        case SQL_DESC_LOCAL_TYPE_NAME:
        case SQL_DESC_NULLABLE:
        case SQL_DESC_SCHEMA_NAME:
        case SQL_DESC_SEARCHABLE:
        case SQL_DESC_TABLE_NAME:
        case SQL_DESC_TYPE_NAME:
        case SQL_DESC_UNSIGNED:
        case SQL_DESC_UPDATABLE:
        {
            // Do nothing. Unused.
            break;
        }

        case SQL_DESC_DATETIME_INTERVAL_CODE:
        {
            pDescRec->hDateTimeIntervalCode = hVal;
            break;
        }

        case SQL_DESC_DATETIME_INTERVAL_PRECISION:
        {
            pDescRec->iDateTimeIntervalPrecision = iVal;
            break;
        } 

        default:
        {
            rc = SQL_ERROR;
            addError(&pDesc->pErrorList,"HY091", "Invalid descriptor field identifier", 0, NULL);
            goto error;
        }
    } // Switch

error:

    return rc;
}