static SQLRETURN ODBCFreeDesc_(ODBCDesc *desc) { ODBCStmt *stmt; /* check if descriptor is implicitly allocated */ if (desc->sql_desc_alloc_type == SQL_DESC_ALLOC_AUTO) { /* Invalid use of an automatically allocated * descriptor handle */ addDescError(desc, "HY017", NULL, 0); return SQL_ERROR; } /* all statements using this handle revert to implicitly * allocated descriptor handles */ for (stmt = desc->Dbc->FirstStmt; stmt; stmt = stmt->next) { if (desc == stmt->ApplRowDescr) stmt->ApplRowDescr = stmt->AutoApplRowDescr; if (desc == stmt->ApplParamDescr) stmt->ApplParamDescr = stmt->AutoApplParamDescr; } /* Ready to destroy the desc handle */ destroyODBCDesc(desc); return SQL_SUCCESS; }
/* * Destroys the ODBCStmt object including its own managed data. * * Precondition: stmt must be valid. * Postcondition: stmt is completely destroyed, stmt handle is invalid. */ void destroyODBCStmt(ODBCStmt *stmt) { ODBCStmt **stmtp; assert(isValidStmt(stmt)); /* first set this object to invalid */ stmt->Type = 0; /* remove this stmt from the dbc */ assert(stmt->Dbc); assert(stmt->Dbc->FirstStmt); /* search for stmt in linked list */ stmtp = &stmt->Dbc->FirstStmt; while (*stmtp && *stmtp != stmt) stmtp = &(*stmtp)->next; /* stmtp points to location in list where stmt is found */ assert(*stmtp == stmt); /* we must have found it */ /* now remove it from the linked list */ *stmtp = stmt->next; /* cleanup own managed data */ deleteODBCErrorList(&stmt->Error); destroyODBCDesc(stmt->ImplParamDescr); destroyODBCDesc(stmt->ImplRowDescr); destroyODBCDesc(stmt->AutoApplParamDescr); destroyODBCDesc(stmt->AutoApplRowDescr); if (stmt->hdl) mapi_close_handle(stmt->hdl); free(stmt); }