SQLRETURN SQLFreeStmt_(ODBCStmt *stmt, SQLUSMALLINT Option) { switch (Option) { case SQL_CLOSE: /* Note: this option is also called from SQLCancel() * and SQLCloseCursor(), so be careful when changing * the code */ /* close cursor, discard result set, set to prepared */ setODBCDescRecCount(stmt->ImplRowDescr, 0); stmt->currentRow = 0; stmt->startRow = 0; stmt->rowSetSize = 0; if (stmt->State == EXECUTED0) stmt->State = stmt->queryid >= 0 ? PREPARED0 : INITED; else if (stmt->State >= EXECUTED1) stmt->State = stmt->queryid >= 0 ? PREPARED1 : INITED; /* Important: do not destroy the bind parameters and columns! */ return SQL_SUCCESS; case SQL_DROP: return ODBCFreeStmt_(stmt); case SQL_UNBIND: setODBCDescRecCount(stmt->ApplRowDescr, 0); return SQL_SUCCESS; case SQL_RESET_PARAMS: setODBCDescRecCount(stmt->ApplParamDescr, 0); setODBCDescRecCount(stmt->ImplParamDescr, 0); mapi_clear_params(stmt->hdl); return SQL_SUCCESS; default: /* Invalid attribute/option identifier */ addStmtError(stmt, "HY092", NULL, 0); return SQL_ERROR; } /* not reached */ }
SQLRETURN SQL_API SQLBindCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValuePtr, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind) { ODBCStmt *stmt = (ODBCStmt *) StatementHandle; ODBCDesc *desc; /* Application Row Descriptor */ #ifdef ODBCDEBUG ODBCLOG("SQLBindCol " PTRFMT " %u %s " LENFMT "\n", PTRFMTCAST StatementHandle, (unsigned int) ColumnNumber, translateCType(TargetType), LENCAST BufferLength); #endif if (!isValidStmt(stmt)) return SQL_INVALID_HANDLE; assert(stmt->Dbc); clearStmtErrors(stmt); /* check input parameters */ /* column number 0 (Bookmark column) is not supported */ if (ColumnNumber == 0) { if (TargetType == SQL_C_BOOKMARK || TargetType == SQL_C_VARBOOKMARK) { /* Optional feature not implemented */ addStmtError(stmt, "HYC00", NULL, 0); } else { /* Restricted data type attribute violation */ addStmtError(stmt, "07006", NULL, 0); } return SQL_ERROR; } if (stmt->State >= EXECUTED1 && ColumnNumber > stmt->ImplRowDescr->sql_desc_count) { /* Invalid descriptor index */ addStmtError(stmt, "07009", NULL, 0); return SQL_ERROR; } /* For safety: limit the maximum number of columns to bind */ if (ColumnNumber > MONETDB_MAX_BIND_COLS) { /* General error */ addStmtError(stmt, "HY000", "Maximum number of bind columns (8192) exceeded", 0); return SQL_ERROR; } /* can't let SQLSetDescField below do this check since it returns the wrong error code if the type is incorrect */ switch (TargetType) { case SQL_C_CHAR: case SQL_C_WCHAR: case SQL_C_BINARY: case SQL_C_BIT: case SQL_C_STINYINT: case SQL_C_UTINYINT: case SQL_C_TINYINT: case SQL_C_SSHORT: case SQL_C_USHORT: case SQL_C_SHORT: case SQL_C_SLONG: case SQL_C_ULONG: case SQL_C_LONG: case SQL_C_SBIGINT: case SQL_C_UBIGINT: case SQL_C_NUMERIC: case SQL_C_FLOAT: case SQL_C_DOUBLE: case SQL_C_TYPE_DATE: case SQL_C_TYPE_TIME: case SQL_C_TYPE_TIMESTAMP: case SQL_C_INTERVAL_YEAR: case SQL_C_INTERVAL_MONTH: case SQL_C_INTERVAL_YEAR_TO_MONTH: case SQL_C_INTERVAL_DAY: case SQL_C_INTERVAL_HOUR: case SQL_C_INTERVAL_MINUTE: case SQL_C_INTERVAL_SECOND: case SQL_C_INTERVAL_DAY_TO_HOUR: case SQL_C_INTERVAL_DAY_TO_MINUTE: case SQL_C_INTERVAL_DAY_TO_SECOND: case SQL_C_INTERVAL_HOUR_TO_MINUTE: case SQL_C_INTERVAL_HOUR_TO_SECOND: case SQL_C_INTERVAL_MINUTE_TO_SECOND: case SQL_C_GUID: case SQL_C_DEFAULT: break; default: /* Invalid application buffer type */ addStmtError(stmt, "HY003", NULL, 0); return SQL_ERROR; } if (BufferLength < 0) { /* Invalid string or buffer length */ addStmtError(stmt, "HY090", NULL, 0); return SQL_ERROR; } desc = stmt->ApplRowDescr; if (TargetValuePtr == NULL && ColumnNumber == desc->sql_desc_count) { int i = desc->sql_desc_count - 1; while (i > 0 && desc->descRec[i].sql_desc_data_ptr == NULL) i--; setODBCDescRecCount(desc, i); } else { ODBCDescRec *rec; SQLRETURN rc; if (ColumnNumber > desc->sql_desc_count) setODBCDescRecCount(desc, ColumnNumber); rc = SQLSetDescField_(desc, ColumnNumber, SQL_DESC_CONCISE_TYPE, (SQLPOINTER) (ssize_t) TargetType, 0); if (!SQL_SUCCEEDED(rc)) return rc; rec = &desc->descRec[ColumnNumber]; rec->sql_desc_octet_length = BufferLength; rec->sql_desc_data_ptr = TargetValuePtr; rec->sql_desc_indicator_ptr = StrLen_or_Ind; rec->sql_desc_octet_length_ptr = StrLen_or_Ind; } return SQL_SUCCESS; }
SQLRETURN MNDBSetDescField(ODBCDesc *desc, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER ValuePtr, SQLINTEGER BufferLength) { ODBCDescRec *rec; struct sql_types *tp; if (isAD(desc)) tp = ODBC_c_types; else tp = ODBC_sql_types; switch (FieldIdentifier) { case SQL_DESC_ALLOC_TYPE: /* SQLSMALLINT */ /* Invalid descriptor field identifier */ addDescError(desc, "HY091", NULL, 0); return SQL_ERROR; case SQL_DESC_ARRAY_SIZE: /* SQLULEN */ if ((SQLULEN) (uintptr_t) ValuePtr == 0) { /* Invalid attribute/option identifier */ addDescError(desc, "HY092", NULL, 0); return SQL_ERROR; } if (isAD(desc)) { /* limit size to protect against bugs */ if ((SQLULEN) (uintptr_t) ValuePtr > 10000) { /* Driver does not support this function */ addDescError(desc, "IM001", NULL, 0); return SQL_ERROR; } desc->sql_desc_array_size = (SQLULEN) (uintptr_t) ValuePtr; } return SQL_SUCCESS; case SQL_DESC_ARRAY_STATUS_PTR: /* SQLUSMALLINT * */ desc->sql_desc_array_status_ptr = (SQLUSMALLINT *) ValuePtr; return SQL_SUCCESS; case SQL_DESC_BIND_OFFSET_PTR: /* SQLLEN * */ if (isAD(desc)) desc->sql_desc_bind_offset_ptr = (SQLLEN *) ValuePtr; return SQL_SUCCESS; case SQL_DESC_BIND_TYPE: /* SQLINTEGER */ if (isAD(desc)) desc->sql_desc_bind_type = (SQLINTEGER) (intptr_t) ValuePtr; return SQL_SUCCESS; case SQL_DESC_COUNT: /* SQLSMALLINT */ if (isIRD(desc)) { /* Invalid descriptor field identifier */ addDescError(desc, "HY091", NULL, 0); return SQL_ERROR; } setODBCDescRecCount(desc, (int) (SQLSMALLINT) (intptr_t) ValuePtr); return SQL_SUCCESS; case SQL_DESC_ROWS_PROCESSED_PTR: /* SQLULEN * */ if (desc->Stmt) desc->sql_desc_rows_processed_ptr = (SQLULEN *) ValuePtr; return SQL_SUCCESS; } if (RecNumber <= 0) { /* Invalid descriptor index */ addDescError(desc, "07009", NULL, 0); return SQL_ERROR; } if (RecNumber > desc->sql_desc_count) return SQL_NO_DATA; if (isIRD(desc)) { /* the Implementation Row Descriptor is read-only */ /* Invalid descriptor field identifier */ addDescError(desc, "HY091", NULL, 0); return SQL_ERROR; } rec = &desc->descRec[RecNumber]; /* break for read-only fields since the error is the same as unknown FieldIdentifier */ switch (FieldIdentifier) { case SQL_DESC_AUTO_UNIQUE_VALUE: /* SQLINTEGER */ case SQL_DESC_BASE_COLUMN_NAME: /* SQLCHAR * */ case SQL_DESC_BASE_TABLE_NAME: /* SQLCHAR * */ case SQL_DESC_CASE_SENSITIVE: /* SQLINTEGER */ case SQL_DESC_CATALOG_NAME: /* SQLCHAR * */ case SQL_DESC_DISPLAY_SIZE: /* SQLLEN */ case SQL_DESC_FIXED_PREC_SCALE: /* SQLSMALLINT */ case SQL_DESC_LABEL: /* SQLCHAR * */ case SQL_DESC_LITERAL_PREFIX: /* SQLCHAR * */ case SQL_DESC_LITERAL_SUFFIX: /* SQLCHAR * */ case SQL_DESC_LOCAL_TYPE_NAME: /* SQLCHAR * */ case SQL_DESC_NULLABLE: /* SQLSMALLINT */ case SQL_DESC_ROWVER: /* SQLSMALLINT */ case SQL_DESC_SCHEMA_NAME: /* SQLCHAR * */ case SQL_DESC_SEARCHABLE: /* SQLSMALLINT */ case SQL_DESC_TABLE_NAME: /* SQLCHAR * */ case SQL_DESC_TYPE_NAME: /* SQLCHAR * */ case SQL_DESC_UNSIGNED: /* SQLSMALLINT */ case SQL_DESC_UPDATABLE: /* SQLSMALLINT */ break; /* read-only or unused */ case SQL_DESC_CONCISE_TYPE: /* SQLSMALLINT */ while (tp->concise_type != 0) { if ((intptr_t) tp->concise_type == (intptr_t) ValuePtr) { rec->sql_desc_concise_type = tp->concise_type; rec->sql_desc_type = tp->type; rec->sql_desc_datetime_interval_code = tp->code; if (tp->precision != UNAFFECTED) rec->sql_desc_precision = tp->precision; if (tp->datetime_interval_precision != UNAFFECTED) rec->sql_desc_datetime_interval_precision = tp->datetime_interval_precision; if (tp->length != UNAFFECTED) rec->sql_desc_length = tp->length; if (tp->scale != UNAFFECTED) rec->sql_desc_scale = tp->scale; rec->sql_desc_fixed_prec_scale = tp->fixed; rec->sql_desc_num_prec_radix = tp->radix; return SQL_SUCCESS; } tp++; } /* Invalid attribute/option identifier */ addDescError(desc, "HY092", NULL, 0); return SQL_ERROR; case SQL_DESC_DATA_PTR: /* SQLPOINTER */ /* TODO: consistency check */ rec->sql_desc_data_ptr = ValuePtr; return SQL_SUCCESS; case SQL_DESC_DATETIME_INTERVAL_CODE: /* SQLSMALLINT */ while (tp->concise_type != 0) { if ((intptr_t) tp->code == (intptr_t) ValuePtr && tp->type == rec->sql_desc_type) { rec->sql_desc_concise_type = tp->concise_type; rec->sql_desc_type = tp->type; rec->sql_desc_datetime_interval_code = tp->code; if (tp->precision != UNAFFECTED) rec->sql_desc_precision = tp->precision; if (tp->datetime_interval_precision != UNAFFECTED) rec->sql_desc_datetime_interval_precision = tp->datetime_interval_precision; if (tp->length != UNAFFECTED) rec->sql_desc_length = tp->length; if (tp->scale != UNAFFECTED) rec->sql_desc_scale = tp->scale; rec->sql_desc_fixed_prec_scale = tp->fixed; rec->sql_desc_num_prec_radix = tp->radix; return SQL_SUCCESS; } tp++; } /* Inconsistent descriptor information */ addDescError(desc, "HY021", NULL, 0); return SQL_ERROR; case SQL_DESC_DATETIME_INTERVAL_PRECISION: /* SQLINTEGER */ rec->sql_desc_datetime_interval_precision = (SQLINTEGER) (intptr_t) ValuePtr; return SQL_SUCCESS; case SQL_DESC_INDICATOR_PTR: /* SQLLEN * */ if (isAD(desc)) rec->sql_desc_indicator_ptr = (SQLLEN *) ValuePtr; return SQL_SUCCESS; case SQL_DESC_LENGTH: /* SQLULEN */ rec->sql_desc_length = (SQLULEN) (uintptr_t) ValuePtr; return SQL_SUCCESS; case SQL_DESC_NAME: /* SQLCHAR * */ if (isID(desc)) { fixODBCstring(ValuePtr, BufferLength, SQLINTEGER, addDescError, desc, return SQL_ERROR); if (rec->sql_desc_name != NULL) free(rec->sql_desc_name); rec->sql_desc_name = (SQLCHAR *) dupODBCstring((SQLCHAR *) ValuePtr, (size_t) BufferLength); if (rec->sql_desc_name == NULL) { /* Memory allocation error */ addDescError(desc, "HY001", NULL, 0); return SQL_ERROR; } rec->sql_desc_unnamed = *rec->sql_desc_name ? SQL_NAMED : SQL_UNNAMED; } return SQL_SUCCESS; case SQL_DESC_NUM_PREC_RADIX: rec->sql_desc_num_prec_radix = (SQLINTEGER) (intptr_t) ValuePtr; return SQL_SUCCESS; case SQL_DESC_OCTET_LENGTH: /* SQLLEN */ rec->sql_desc_octet_length = (SQLLEN) (intptr_t) ValuePtr; return SQL_SUCCESS; case SQL_DESC_OCTET_LENGTH_PTR: /* SQLLEN * */ if (isAD(desc)) rec->sql_desc_octet_length_ptr = (SQLLEN *) ValuePtr; return SQL_SUCCESS; case SQL_DESC_PARAMETER_TYPE: /* SQLSMALLINT */ switch ((SQLSMALLINT) (intptr_t) ValuePtr) { case SQL_PARAM_INPUT: break; case SQL_PARAM_INPUT_OUTPUT: case SQL_PARAM_OUTPUT: /* Driver does not support this function */ addDescError(desc, "IM001", NULL, 0); return SQL_ERROR; default: /* Invalid attribute/option identifier */ addDescError(desc, "HY092", NULL, 0); return SQL_ERROR; } if (isIPD(desc)) rec->sql_desc_parameter_type = (SQLSMALLINT) (intptr_t) ValuePtr; return SQL_SUCCESS; case SQL_DESC_PRECISION: /* SQLSMALLINT */ rec->sql_desc_precision = (SQLSMALLINT) (intptr_t) ValuePtr; return SQL_SUCCESS; case SQL_DESC_SCALE: /* SQLSMALLINT */ rec->sql_desc_scale = (SQLSMALLINT) (intptr_t) ValuePtr; return SQL_SUCCESS; case SQL_DESC_TYPE: /* SQLSMALLINT */ while (tp->concise_type != 0) { if ((SQLSMALLINT) (intptr_t) ValuePtr == tp->type && (((SQLSMALLINT) (intptr_t) ValuePtr != SQL_DATETIME && (SQLSMALLINT) (intptr_t) ValuePtr != SQL_INTERVAL) || tp->code == rec->sql_desc_datetime_interval_code)) { rec->sql_desc_concise_type = tp->concise_type; rec->sql_desc_type = tp->type; rec->sql_desc_datetime_interval_code = tp->code; if (tp->precision != UNAFFECTED) rec->sql_desc_precision = tp->precision; if (tp->datetime_interval_precision != UNAFFECTED) rec->sql_desc_datetime_interval_precision = tp->datetime_interval_precision; if (tp->length != UNAFFECTED) rec->sql_desc_length = tp->length; if (tp->scale != UNAFFECTED) rec->sql_desc_scale = tp->scale; rec->sql_desc_fixed_prec_scale = tp->fixed; rec->sql_desc_num_prec_radix = tp->radix; return SQL_SUCCESS; } tp++; } /* Inconsistent descriptor information */ addDescError(desc, "HY021", NULL, 0); return SQL_ERROR; case SQL_DESC_UNNAMED: /* SQLSMALLINT */ if ((SQLSMALLINT) (intptr_t) ValuePtr == SQL_NAMED) { /* Invalid descriptor field identifier */ addDescError(desc, "HY091", NULL, 0); return SQL_ERROR; } else if ((SQLSMALLINT) (intptr_t) ValuePtr == SQL_UNNAMED && isIPD(desc)) { rec->sql_desc_unnamed = SQL_UNNAMED; if (rec->sql_desc_name) free(rec->sql_desc_name); rec->sql_desc_name = NULL; return SQL_SUCCESS; } /* Inconsistent descriptor information */ addDescError(desc, "HY021", NULL, 0); return SQL_ERROR; } /* Invalid descriptor field identifier */ addDescError(desc, "HY091", NULL, 0); return SQL_ERROR; }