Skip to content

Commit

Permalink
update callProcedure to handle multiple versions of a procedure with …
Browse files Browse the repository at this point in the history
…different parameters

Signed-off-by: Brandon Peterson <117427172+brandonp42@users.noreply.github.com>
  • Loading branch information
brandonp42 committed Mar 25, 2024
1 parent 6ce98c6 commit d00c3ee
Showing 1 changed file with 58 additions and 14 deletions.
72 changes: 58 additions & 14 deletions src/odbc_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,8 @@ class CallProcedureAsyncWorker : public ODBCAsyncWorker {
return;
}

int proceduresFoundCount = data->storedRows.size();

data->deleteColumns(); // delete data in columns for next result set

return_code =
Expand Down Expand Up @@ -1393,27 +1395,69 @@ class CallProcedureAsyncWorker : public ODBCAsyncWorker {
return;
}

if (data->parameterCount != (SQLSMALLINT)data->storedRows.size()) {
SetError("[odbc] The number of parameters the procedure expects and and the number of passed parameters is not equal\0");
return;
}

#define SQLPROCEDURECOLUMNS_COLUMN_TYPE_INDEX 4
#define SQLPROCEDURECOLUMNS_DATA_TYPE_INDEX 5
#define SQLPROCEDURECOLUMNS_COLUMN_SIZE_INDEX 7
#define SQLPROCEDURECOLUMNS_DECIMAL_DIGITS_INDEX 9
#define SQLPROCEDURECOLUMNS_NULLABLE_INDEX 11
#define SQLPROCEDURECOLUMNS_ORDINAL_POSITION 17

int strParamIdx = 0;
int endParamIdx = 0;
int priorOrdinalPos = 0;
int proceduresWithParametersCount = 0;

if (data->storedRows.size() > 0) {
proceduresWithParametersCount++;
}

for (endParamIdx = 0; endParamIdx < (SQLSMALLINT)data->storedRows.size(); endParamIdx++) {
if (endParamIdx > 0 && data->storedRows[endParamIdx][SQLPROCEDURECOLUMNS_ORDINAL_POSITION].integer_data <= priorOrdinalPos) {
// we found a boundary between different versions of the procedure name that should have different parameter counts
proceduresWithParametersCount++;
if (data->parameterCount == priorOrdinalPos)
break;
else
strParamIdx = endParamIdx;
}
priorOrdinalPos = data->storedRows[endParamIdx][SQLPROCEDURECOLUMNS_ORDINAL_POSITION].integer_data;
}

// if there was only one procedure candidate (or we're using the last one), fix the end parameter index
if (endParamIdx > (SQLSMALLINT)data->storedRows.size()) {
endParamIdx = data->storedRows.size();
}

// if we're looking for a procedure with zero parameters then reset the index variables so we don't try to bind any parameters
if (data->parameterCount == 0 && (SQLSMALLINT)(proceduresFoundCount > proceduresWithParametersCount)) {
strParamIdx = 0;
endParamIdx = 0;
}

// verify that the parameter count matches the number of rows that are matched above
if (data->parameterCount != (SQLSMALLINT)(endParamIdx - strParamIdx)) {
char errorString[255];

#ifndef UNICODE
sprintf(errorString, "[odbc] Could not find a procedure named %s with %d parameters", combinedProcedureName, data->parameterCount);
#else
sprintf(errorString, "[odbc] Could not find a procedure named %S with %d parameters", combinedProcedureName, data->parameterCount);
#endif

SetError(errorString);
return;
}

// get stored column parameter data from the result set

for (int i = 0; i < data->parameterCount; i++) {

Parameter *parameter = data->parameters[i];

data->parameters[i]->InputOutputType = data->storedRows[i][SQLPROCEDURECOLUMNS_COLUMN_TYPE_INDEX].smallint_data;
data->parameters[i]->ParameterType = data->storedRows[i][SQLPROCEDURECOLUMNS_DATA_TYPE_INDEX].smallint_data; // DataType -> ParameterType
data->parameters[i]->ColumnSize = data->storedRows[i][SQLPROCEDURECOLUMNS_COLUMN_SIZE_INDEX].integer_data; // ParameterSize -> ColumnSize
data->parameters[i]->Nullable = data->storedRows[i][SQLPROCEDURECOLUMNS_NULLABLE_INDEX].smallint_data;
data->parameters[i]->InputOutputType = data->storedRows[i + strParamIdx][SQLPROCEDURECOLUMNS_COLUMN_TYPE_INDEX].smallint_data;
data->parameters[i]->ParameterType = data->storedRows[i + strParamIdx][SQLPROCEDURECOLUMNS_DATA_TYPE_INDEX].smallint_data; // DataType -> ParameterType
data->parameters[i]->ColumnSize = data->storedRows[i + strParamIdx][SQLPROCEDURECOLUMNS_COLUMN_SIZE_INDEX].integer_data; // ParameterSize -> ColumnSize
data->parameters[i]->Nullable = data->storedRows[i + strParamIdx][SQLPROCEDURECOLUMNS_NULLABLE_INDEX].smallint_data;

// For each parameter, need to manipulate the data buffer and C type
// depending on what the InputOutputType is:
Expand Down Expand Up @@ -1745,36 +1789,36 @@ class CallProcedureAsyncWorker : public ODBCAsyncWorker {
data->parameters[i]->ValueType = SQL_C_CHAR;
data->parameters[i]->ParameterValuePtr = new SQLCHAR[bufferSize];
data->parameters[i]->BufferLength = bufferSize;
data->parameters[i]->DecimalDigits = data->storedRows[i][SQLPROCEDURECOLUMNS_DECIMAL_DIGITS_INDEX].smallint_data;
data->parameters[i]->DecimalDigits = data->storedRows[i + strParamIdx][SQLPROCEDURECOLUMNS_DECIMAL_DIGITS_INDEX].smallint_data;
break;

case SQL_DOUBLE:
case SQL_FLOAT:
data->parameters[i]->ValueType = SQL_C_DOUBLE;
data->parameters[i]->ParameterValuePtr = new SQLDOUBLE();
data->parameters[i]->BufferLength = sizeof(SQLDOUBLE);
data->parameters[i]->DecimalDigits = data->storedRows[i][SQLPROCEDURECOLUMNS_DECIMAL_DIGITS_INDEX].smallint_data;
data->parameters[i]->DecimalDigits = data->storedRows[i + strParamIdx][SQLPROCEDURECOLUMNS_DECIMAL_DIGITS_INDEX].smallint_data;
break;

case SQL_TINYINT:
data->parameters[i]->ValueType = SQL_C_UTINYINT;
data->parameters[i]->ParameterValuePtr = new SQLCHAR();
data->parameters[i]->BufferLength = sizeof(SQLCHAR);
data->parameters[i]->DecimalDigits = data->storedRows[i][SQLPROCEDURECOLUMNS_DECIMAL_DIGITS_INDEX].smallint_data;
data->parameters[i]->DecimalDigits = data->storedRows[i + strParamIdx][SQLPROCEDURECOLUMNS_DECIMAL_DIGITS_INDEX].smallint_data;
break;

case SQL_SMALLINT:
data->parameters[i]->ValueType = SQL_C_SSHORT;
data->parameters[i]->ParameterValuePtr = new SQLSMALLINT();
data->parameters[i]->BufferLength = sizeof(SQLSMALLINT);
data->parameters[i]->DecimalDigits = data->storedRows[i][SQLPROCEDURECOLUMNS_DECIMAL_DIGITS_INDEX].smallint_data;
data->parameters[i]->DecimalDigits = data->storedRows[i + strParamIdx][SQLPROCEDURECOLUMNS_DECIMAL_DIGITS_INDEX].smallint_data;
break;

case SQL_INTEGER:
data->parameters[i]->ValueType = SQL_C_SLONG;
data->parameters[i]->ParameterValuePtr = new SQLINTEGER();
data->parameters[i]->BufferLength = sizeof(SQLINTEGER);
data->parameters[i]->DecimalDigits = data->storedRows[i][SQLPROCEDURECOLUMNS_DECIMAL_DIGITS_INDEX].smallint_data;
data->parameters[i]->DecimalDigits = data->storedRows[i + strParamIdx][SQLPROCEDURECOLUMNS_DECIMAL_DIGITS_INDEX].smallint_data;
break;

case SQL_BIGINT:
Expand Down

0 comments on commit d00c3ee

Please sign in to comment.