Line data Source code
1 : /* 2 : * SPDX-License-Identifier: MPL-2.0 3 : * 4 : * This Source Code Form is subject to the terms of the Mozilla Public 5 : * License, v. 2.0. If a copy of the MPL was not distributed with this 6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 : * 8 : * Copyright 2024 MonetDB Foundation; 9 : * Copyright August 2008 - 2023 MonetDB B.V.; 10 : * Copyright 1997 - July 2008 CWI. 11 : */ 12 : 13 : /* 14 : * This code was created by Peter Harvey (mostly during Christmas 98/99). 15 : * This code is LGPL. Please ensure that this message remains in future 16 : * distributions and uses of this code (thats about all I get out of it). 17 : * - Peter Harvey pharvey@codebydesign.com 18 : * 19 : * This file has been modified for the MonetDB project. See the file 20 : * Copyright in this directory for more information. 21 : */ 22 : 23 : /********************************************************************** 24 : * SQLFreeHandle() 25 : * CLI compliance: ISO 92 26 : * 27 : * Note: This function also implements the deprecated ODBC functions 28 : * SQLFreeEnv(), SQLFreeConnect() and SQLFreeStmt(with option SQL_DROP) 29 : * Those functions are simply mapped to this function. 30 : * All checks are done in this function. 31 : **********************************************************************/ 32 : 33 : #include "ODBCGlobal.h" 34 : #include "ODBCEnv.h" 35 : #include "ODBCDbc.h" 36 : #include "ODBCStmt.h" 37 : #include "ODBCError.h" 38 : 39 : 40 : static SQLRETURN 41 6 : ODBCFreeEnv_(ODBCEnv *env) 42 : { 43 6 : if (env->sql_attr_odbc_version == 0) { 44 : /* Function sequence error */ 45 0 : addEnvError(env, "HY010", NULL, 0); 46 0 : return SQL_ERROR; 47 : } 48 : 49 : /* check if no associated connections are still active */ 50 6 : if (env->FirstDbc != NULL) { 51 : /* Function sequence error */ 52 0 : addEnvError(env, "HY010", NULL, 0); 53 0 : return SQL_ERROR; 54 : } 55 : 56 : /* Ready to destroy the env handle */ 57 6 : destroyODBCEnv(env); 58 6 : return SQL_SUCCESS; 59 : } 60 : 61 : static SQLRETURN 62 6 : ODBCFreeDbc_(ODBCDbc *dbc) 63 : { 64 : /* check if connection is not active */ 65 6 : if (dbc->Connected) { 66 : /* Function sequence error */ 67 0 : addDbcError(dbc, "HY010", NULL, 0); 68 0 : return SQL_ERROR; 69 : } 70 : 71 : /* check if no associated statements are still active */ 72 6 : if (dbc->FirstStmt != NULL) { 73 : /* There are allocated statements should be closed and 74 : * freed first */ 75 : /* Function sequence error */ 76 0 : addDbcError(dbc, "HY010", NULL, 0); 77 0 : return SQL_ERROR; 78 : } 79 : 80 : /* Ready to destroy the dbc handle */ 81 6 : destroyODBCDbc(dbc); 82 6 : return SQL_SUCCESS; 83 : } 84 : 85 : SQLRETURN 86 13 : ODBCFreeStmt_(ODBCStmt *stmt) 87 : { 88 : /* check if statement is not active */ 89 13 : if (stmt->State >= EXECUTED0) { 90 : /* should be closed first */ 91 4 : if (MNDBFreeStmt(stmt, SQL_CLOSE) == SQL_ERROR) 92 : return SQL_ERROR; 93 : } 94 : 95 : /* Ready to destroy the stmt handle */ 96 13 : destroyODBCStmt(stmt); 97 13 : return SQL_SUCCESS; 98 : } 99 : 100 : static SQLRETURN 101 0 : ODBCFreeDesc_(ODBCDesc *desc) 102 : { 103 0 : ODBCStmt *stmt; 104 : 105 : /* check if descriptor is implicitly allocated */ 106 0 : if (desc->sql_desc_alloc_type == SQL_DESC_ALLOC_AUTO) { 107 : /* Invalid use of an automatically allocated 108 : * descriptor handle */ 109 0 : addDescError(desc, "HY017", NULL, 0); 110 0 : return SQL_ERROR; 111 : } 112 : 113 : /* all statements using this handle revert to implicitly 114 : * allocated descriptor handles */ 115 0 : for (stmt = desc->Dbc->FirstStmt; stmt; stmt = stmt->next) { 116 0 : if (desc == stmt->ApplRowDescr) 117 0 : stmt->ApplRowDescr = stmt->AutoApplRowDescr; 118 : 119 0 : if (desc == stmt->ApplParamDescr) 120 0 : stmt->ApplParamDescr = stmt->AutoApplParamDescr; 121 : } 122 : 123 : /* Ready to destroy the desc handle */ 124 0 : destroyODBCDesc(desc); 125 0 : return SQL_SUCCESS; 126 : } 127 : 128 : SQLRETURN 129 22 : MNDBFreeHandle(SQLSMALLINT HandleType, 130 : SQLHANDLE Handle) 131 : { 132 : /* Check parameter handle */ 133 22 : if (Handle == NULL) { 134 : /* can not set an error message because the handle is NULL */ 135 : return SQL_INVALID_HANDLE; 136 : } 137 : 138 : 139 22 : switch (HandleType) { 140 6 : case SQL_HANDLE_ENV: 141 : { 142 6 : ODBCEnv *env = (ODBCEnv *) Handle; 143 : 144 : /* check it's validity */ 145 6 : if (!isValidEnv(env)) 146 : return SQL_INVALID_HANDLE; 147 6 : clearEnvErrors(env); 148 6 : return ODBCFreeEnv_(env); 149 : } 150 6 : case SQL_HANDLE_DBC: 151 : { 152 6 : ODBCDbc *dbc = (ODBCDbc *) Handle; 153 : 154 : /* check it's validity */ 155 6 : if (!isValidDbc(dbc)) 156 : return SQL_INVALID_HANDLE; 157 6 : clearDbcErrors(dbc); 158 6 : return ODBCFreeDbc_(dbc); 159 : } 160 10 : case SQL_HANDLE_STMT: 161 : { 162 10 : ODBCStmt *stmt = (ODBCStmt *) Handle; 163 : 164 : /* check it's validity */ 165 10 : if (!isValidStmt(stmt)) 166 : return SQL_INVALID_HANDLE; 167 10 : clearStmtErrors(stmt); 168 10 : return ODBCFreeStmt_(stmt); 169 : } 170 0 : case SQL_HANDLE_DESC: 171 : { 172 0 : ODBCDesc *desc = (ODBCDesc *) Handle; 173 : 174 : /* check it's validity */ 175 0 : if (!isValidDesc(desc)) 176 : return SQL_INVALID_HANDLE; 177 0 : clearDescErrors(desc); 178 0 : return ODBCFreeDesc_(desc); 179 : } 180 : default: 181 : return SQL_INVALID_HANDLE; 182 : } 183 : 184 : /* not reached */ 185 : } 186 : 187 : SQLRETURN SQL_API 188 : SQLFreeHandle(SQLSMALLINT HandleType, 189 : SQLHANDLE Handle) 190 : { 191 : #ifdef ODBCDEBUG 192 22 : ODBCLOG("SQLFreeHandle %s %p\n", 193 : HandleType == SQL_HANDLE_ENV ? "Env" : HandleType == SQL_HANDLE_DBC ? "Dbc" : HandleType == SQL_HANDLE_STMT ? "Stmt" : "Desc", 194 : Handle); 195 : #endif 196 : 197 22 : return MNDBFreeHandle(HandleType, Handle); 198 : }