SQLRETURN SQL_API my_SQLBindParameter()

in driver/prepare.cc [117:250]


SQLRETURN SQL_API my_SQLBindParameter( SQLHSTMT     StatementHandle,
                                       SQLUSMALLINT ParameterNumber,
                                       SQLSMALLINT  InputOutputType,
                                       SQLSMALLINT  ValueType,
                                       SQLSMALLINT  ParameterType,
                                       SQLULEN      ColumnSize,
                                       SQLSMALLINT  DecimalDigits,
                                       SQLPOINTER   ParameterValuePtr,
                                       SQLLEN       BufferLength,
                                       SQLLEN *     StrLen_or_IndPtr )
{
    STMT *stmt= (STMT *)StatementHandle;
    DESCREC *aprec= desc_get_rec(stmt->apd, ParameterNumber - 1, TRUE);
    DESCREC *iprec= desc_get_rec(stmt->ipd, ParameterNumber - 1, TRUE);
    SQLRETURN rc;
    /* TODO if this function fails, the SQL_DESC_COUNT should be unchanged in apd, ipd */

    CLEAR_STMT_ERROR(stmt);

    if (ParameterNumber < 1)
    {
        stmt->set_error(MYERR_S1093,NULL,0);
        return SQL_ERROR;
    }

    aprec->par.reset();

    /* reset all param fields */
    aprec->reset_to_defaults();
    iprec->reset_to_defaults();

    /* first, set apd fields */
    if (ValueType == SQL_C_DEFAULT)
    {
      ValueType= default_c_type(ParameterType);
      /*
        Access treats BIGINT as a string on linked tables.
        The value is read correctly, but bound as a string.
      */
      if (ParameterType == SQL_BIGINT && stmt->dbc->ds->opt_DFLT_BIGINT_BIND_STR)
        ValueType= SQL_C_CHAR;
    }
    if (!SQL_SUCCEEDED(rc = stmt_SQLSetDescField(stmt, stmt->apd,
                                                 ParameterNumber,
                                                 SQL_DESC_CONCISE_TYPE,
                                                 (SQLPOINTER)(SQLLEN)ValueType,
                                                 SQL_IS_SMALLINT)))
        return rc;

    if (!SQL_SUCCEEDED(rc= stmt_SQLSetDescField(stmt, stmt->apd, ParameterNumber,
                                                SQL_DESC_OCTET_LENGTH,
                                                (SQLPOINTER)BufferLength,
                                                SQL_IS_INTEGER)))
        return rc;
    /* these three *must* be the last APD params bound */
    if (!SQL_SUCCEEDED(rc= stmt_SQLSetDescField(stmt, stmt->apd, ParameterNumber,
                                                SQL_DESC_DATA_PTR,
                                                ParameterValuePtr, SQL_IS_POINTER)))
        return rc;
    if (!SQL_SUCCEEDED(rc= stmt_SQLSetDescField(stmt, stmt->apd, ParameterNumber,
                                                SQL_DESC_OCTET_LENGTH_PTR,
                                                StrLen_or_IndPtr, SQL_IS_POINTER)))
        return rc;
    if (!SQL_SUCCEEDED(rc= stmt_SQLSetDescField(stmt, stmt->apd, ParameterNumber,
                                                SQL_DESC_INDICATOR_PTR,
                                                StrLen_or_IndPtr, SQL_IS_POINTER)))
        return rc;

    /* now the ipd fields */
    if (!SQL_SUCCEEDED(rc= stmt_SQLSetDescField(stmt, stmt->ipd,
                                                ParameterNumber,
                                                SQL_DESC_CONCISE_TYPE,
                                                (SQLPOINTER)(size_t)ParameterType,
                                                SQL_IS_SMALLINT)))
        return rc;

    if (!SQL_SUCCEEDED(rc= stmt_SQLSetDescField(stmt, stmt->ipd,
                                                ParameterNumber,
                                                SQL_DESC_PARAMETER_TYPE,
                                                (SQLPOINTER)(size_t)InputOutputType,
                                                SQL_IS_SMALLINT)))
        return rc;

    /* set fields from ColumnSize and DecimalDigits */
    switch (ParameterType)
    {
    case SQL_TYPE_TIME:
    case SQL_TYPE_TIMESTAMP:
    case SQL_INTERVAL_SECOND:
    case SQL_INTERVAL_DAY_TO_SECOND:
    case SQL_INTERVAL_HOUR_TO_SECOND:
    case SQL_INTERVAL_MINUTE_TO_SECOND:
        rc= stmt_SQLSetDescField(stmt, stmt->ipd, ParameterNumber,
                                 SQL_DESC_PRECISION,
                                 (SQLPOINTER)(size_t)DecimalDigits,
                                 SQL_IS_SMALLINT);
        break;
    case SQL_CHAR:
    case SQL_VARCHAR:
    case SQL_LONGVARCHAR:
    case SQL_BINARY:
    case SQL_VARBINARY:
    case SQL_LONGVARBINARY:
        rc= stmt_SQLSetDescField(stmt, stmt->ipd, ParameterNumber,
                                 SQL_DESC_LENGTH, (SQLPOINTER)ColumnSize,
                                 SQL_IS_ULEN);
        break;
    case SQL_NUMERIC:
    case SQL_DECIMAL:
        rc= stmt_SQLSetDescField(stmt, stmt->ipd, ParameterNumber,
                                 SQL_DESC_SCALE,
                                 (SQLPOINTER)(size_t)DecimalDigits,
                                 SQL_IS_SMALLINT);
        if (!SQL_SUCCEEDED(rc))
            return rc;
        /* fall through */
    case SQL_FLOAT:
    case SQL_REAL:
    case SQL_DOUBLE:
        rc= stmt_SQLSetDescField(stmt, stmt->ipd, ParameterNumber,
                                 SQL_DESC_PRECISION,
                                 (SQLPOINTER)ColumnSize,
                                 SQL_IS_ULEN);
        break;
    default:
        rc= SQL_SUCCESS;
    }
    if (!SQL_SUCCEEDED(rc))
        return rc;

    aprec->par.real_param_done= TRUE;

    return SQL_SUCCESS;
}