diff --git a/source/shared/core_sqlsrv.h b/source/shared/core_sqlsrv.h index 827a6b44..e143ae93 100644 --- a/source/shared/core_sqlsrv.h +++ b/source/shared/core_sqlsrv.h @@ -1490,10 +1490,11 @@ struct sqlsrv_param_inout : public sqlsrv_param // *** of this column in the corresponding table type. struct sqlsrv_param_tvp : public sqlsrv_param { - sqlsrv_param_tvp* parent_tvp; // For a TVP column to reference to the table-valued parameter. NULL if this is the TVP itself. - std::vector tvp_columns; // The constituent columns of the table-valued parameter - int num_rows; // The total number of rows - int current_row; // A counter to keep track of which row is to be processed + std::map tvp_columns; // The constituent columns of the table-valued parameter + + sqlsrv_param_tvp* parent_tvp; // For a TVP column to reference to the table-valued parameter. NULL if this is the TVP itself. + int num_rows; // The total number of rows + int current_row; // A counter to keep track of which row is to be processed sqlsrv_param_tvp(_In_ SQLUSMALLINT param_num, _In_ SQLSRV_ENCODING enc, _In_ SQLSMALLINT sql_type, _In_ SQLULEN col_size, _In_ SQLSMALLINT dec_digits, _In_ sqlsrv_param_tvp* tvp) : sqlsrv_param(param_num, SQL_PARAM_INPUT, enc, sql_type, col_size, dec_digits), num_rows(0), current_row(0), parent_tvp(tvp) diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 324ffcf0..2ba5132c 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -2075,9 +2075,11 @@ void sqlsrv_param::release_data() { if (Z_TYPE(placeholder_z) == IS_STRING) { zend_string_release(Z_STR(placeholder_z)); - ZVAL_UNDEF(&placeholder_z); } + ZVAL_UNDEF(&placeholder_z); + + buffer = NULL; param_stream = NULL; num_bytes_read = 0; param_ptr_z = NULL; @@ -3060,7 +3062,7 @@ void sqlsrv_param_tvp::get_tvp_metadata(_In_ sqlsrv_stmt* stmt, _In_ zend_string param_ptr = new (sqlsrv_malloc(sizeof(sqlsrv_param_tvp))) sqlsrv_param_tvp(pos, column_encoding, data_type, col_size, dec_digits, this); param_ptr->num_rows = this->num_rows; // Each column inherits the number of rows from the TVP - tvp_columns.push_back(param_ptr); + tvp_columns[pos] = param_ptr.get(); param_ptr.transferred(); pos++; @@ -3075,11 +3077,16 @@ void sqlsrv_param_tvp::get_tvp_metadata(_In_ sqlsrv_stmt* stmt, _In_ zend_string void sqlsrv_param_tvp::release_data() { - // Clean up tvp_columns as well - for (int i = 0; i < tvp_columns.size(); i++) { - tvp_columns[i]->release_data(); - sqlsrv_free(tvp_columns[i]); + // Clean up tvp_columns + std::map::iterator it; + for (it = tvp_columns.begin(); it != tvp_columns.end(); ++it) { + sqlsrv_param_tvp* ptr = it->second; + if (ptr) { + ptr->release_data(); + sqlsrv_free(ptr); + } } + tvp_columns.clear(); sqlsrv_param::release_data(); } @@ -3315,7 +3322,6 @@ void sqlsrv_param_tvp::bind_param(_Inout_ sqlsrv_stmt* stmt) core::SQLSetStmtAttr(stmt, SQL_SOPT_SS_PARAM_FOCUS, reinterpret_cast(ordinal), SQL_IS_INTEGER); // Bind the TVP columns - SQLSRV_ENCODING stmt_encoding = (stmt->encoding() == SQLSRV_ENCODING_DEFAULT) ? stmt->conn->encoding() : stmt->encoding(); HashTable* rows_ht = Z_ARRVAL_P(param_ptr_z); zval* row_z = zend_hash_index_find(rows_ht, 0);