void odbc_errs_add(struct _sql_errors *errs, const char *sqlstate, const char *msg) { int n; assert(sqlstate); if (!errs) return; n = errs->num_errors; if (!TDS_RESIZE(errs->errs, n + 1)) { errs->lastrc = SQL_ERROR; return; } memset(&errs->errs[n], 0, sizeof(struct _sql_error)); errs->errs[n].native = 0; strlcpy(errs->errs[n].state3, sqlstate, 6); odbc_get_v2state(errs->errs[n].state3, errs->errs[n].state2); /* TODO why driver ?? -- freddy77 */ errs->errs[n].server = strdup("DRIVER"); errs->errs[n].msg = msg ? strdup(msg) : odbc_get_msg(errs->errs[n].state3); ++errs->num_errors; /* updated last error */ if (!strcmp(sqlstate, "01004") || !strcmp(sqlstate, "01S02")) { if (errs->lastrc != SQL_ERROR) errs->lastrc = SQL_SUCCESS_WITH_INFO; } else { errs->lastrc = SQL_ERROR; } tdsdump_log(TDS_DBG_FUNC, "odbc_errs_add: \"%s\"\n", errs->errs[n].msg); }
static void tds_alloc_new_sid(TDSSOCKET *tds) { int sid = -1; TDSCONNECTION *conn = tds->conn; TDSSOCKET **s; tds_mutex_lock(&conn->list_mtx); tds->sid = -1; for (sid = 0; sid < conn->num_sessions; ++sid) if (!conn->sessions[sid]) break; if (sid == conn->num_sessions) { /* extend array */ s = (TDSSOCKET **) TDS_RESIZE(conn->sessions, sid+64); if (!s) goto error; memset(s + conn->num_sessions, 0, sizeof(*s) * 64); conn->num_sessions += 64; } conn->sessions[sid] = tds; tds->sid = sid; error: tds_mutex_unlock(&conn->list_mtx); }
SQLRETURN desc_alloc_records(TDS_DESC * desc, unsigned count) { struct _drecord *drec; int i; /* shrink records */ if (desc->header.sql_desc_count >= count) { for (i = count; i < desc->header.sql_desc_count; ++i) desc_free_record(&desc->records[i]); desc->header.sql_desc_count = count; return SQL_SUCCESS; } if (!TDS_RESIZE(desc->records, count)) return SQL_ERROR; memset(desc->records + desc->header.sql_desc_count, 0, sizeof(struct _drecord) * (count - desc->header.sql_desc_count)); for (i = desc->header.sql_desc_count; i < count; ++i) { drec = &desc->records[i]; #define STR_OP(name) tds_dstr_init(&drec->name) SQL_DESC_STRINGS; #undef STR_OP switch (desc->type) { case DESC_IRD: case DESC_IPD: drec->sql_desc_parameter_type = SQL_PARAM_INPUT; break; case DESC_ARD: case DESC_APD: drec->sql_desc_concise_type = SQL_C_DEFAULT; drec->sql_desc_type = SQL_C_DEFAULT; break; } } desc->header.sql_desc_count = count; return SQL_SUCCESS; }
int continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN StrLen_or_Ind) { struct _drecord *drec_apd, *drec_ipd; SQLLEN len; int need_bytes; TDSCOLUMN *curcol; TDSBLOB *blob; int sql_src_type; assert(stmt); tdsdump_log(TDS_DBG_FUNC, "continue_parse_prepared_query with parameter %d\n", stmt->param_num); if (!stmt->params) { tdsdump_log(TDS_DBG_FUNC, "error? continue_parse_prepared_query: no parameters provided"); return SQL_ERROR; } if (stmt->param_num > stmt->apd->header.sql_desc_count || stmt->param_num > stmt->ipd->header.sql_desc_count) return SQL_ERROR; drec_apd = &stmt->apd->records[stmt->param_num - 1]; drec_ipd = &stmt->ipd->records[stmt->param_num - 1]; curcol = stmt->params->columns[stmt->param_num - (stmt->prepared_query_is_func ? 2 : 1)]; blob = NULL; if (is_blob_col(curcol)) blob = (TDSBLOB *) curcol->column_data; assert(curcol->column_cur_size <= curcol->column_size); need_bytes = curcol->column_size - curcol->column_cur_size; if (DataPtr == NULL) { switch(StrLen_or_Ind) { case SQL_NULL_DATA: case SQL_DEFAULT_PARAM: break; /* OK */ default: odbc_errs_add(&stmt->errs, "HY009", NULL); /* Invalid use of null pointer */ return SQL_ERROR; } } /* get C type */ sql_src_type = drec_apd->sql_desc_concise_type; if (sql_src_type == SQL_C_DEFAULT) sql_src_type = odbc_sql_to_c_type_default(drec_ipd->sql_desc_concise_type); switch(StrLen_or_Ind) { case SQL_NTS: if (sql_src_type == SQL_C_WCHAR) len = sqlwcslen((SQLWCHAR *) DataPtr); else len = strlen((char *) DataPtr); break; case SQL_NULL_DATA: len = 0; break; case SQL_DEFAULT_PARAM: /* FIXME: use the default if the parameter has one. */ odbc_errs_add(&stmt->errs, "07S01", NULL); /* Invalid use of default parameter */ return SQL_ERROR; default: if (DataPtr && StrLen_or_Ind < 0) { /* * "The argument DataPtr was not a null pointer, and * the argument StrLen_or_Ind was less than 0 * but not equal to SQL_NTS or SQL_NULL_DATA." */ odbc_errs_add(&stmt->errs, "HY090", NULL); return SQL_ERROR; } len = StrLen_or_Ind; break; } if (!blob && len > need_bytes) len = need_bytes; /* copy to destination */ if (blob) { TDS_CHAR *p; int binary_convert = 0; SQLLEN orig_len = len; if (sql_src_type == SQL_C_CHAR || sql_src_type == SQL_C_WCHAR) { TDS_SERVER_TYPE type = tds_get_conversion_type(curcol->column_type, curcol->column_size); if (is_binary_type(type)) { if (len && sql_src_type == SQL_C_CHAR && !*((char*)DataPtr+len-1)) --len; if (sql_src_type == SQL_C_WCHAR) len /= sizeof(SQLWCHAR); if (!len) return SQL_SUCCESS; binary_convert = 1; orig_len = len; len = len / 2u + 1u; } } if (!len) return SQL_SUCCESS; assert(blob->textvalue || curcol->column_cur_size == 0); p = (TDS_CHAR *) TDS_RESIZE(blob->textvalue, len + curcol->column_cur_size); if (!p) { odbc_errs_add(&stmt->errs, "HY001", NULL); /* Memory allocation error */ return SQL_ERROR; } p += curcol->column_cur_size; if (binary_convert) { int res; len = orig_len; if (curcol->column_cur_size > 0 && curcol->column_text_sqlputdatainfo) { SQLWCHAR data[2]; data[0] = curcol->column_text_sqlputdatainfo; data[1] = (sql_src_type == SQL_C_CHAR) ? *(unsigned char*)DataPtr : *(SQLWCHAR*)DataPtr; res = odbc_wchar2hex(p, 1, data, 2); if (res < 0) { odbc_convert_err_set(&stmt->errs, res); return SQL_ERROR; } p += res; DataPtr = (SQLPOINTER) (((char*)DataPtr) + (sql_src_type == SQL_C_CHAR ? 1 : sizeof(SQLWCHAR))); --len; } if (len&1) { --len; curcol->column_text_sqlputdatainfo = (sql_src_type == SQL_C_CHAR) ? ((char*)DataPtr)[len] : ((SQLWCHAR*)DataPtr)[len]; } res = (sql_src_type == SQL_C_CHAR) ? tds_char2hex(p, len / 2u, (const TDS_CHAR*) DataPtr, len): odbc_wchar2hex(p, len / 2u, (const SQLWCHAR*) DataPtr, len); if (res < 0) { odbc_convert_err_set(&stmt->errs, res); return SQL_ERROR; } p += res; len = p - (blob->textvalue + curcol->column_cur_size); } else { memcpy(blob->textvalue + curcol->column_cur_size, DataPtr, len); } } else { memcpy(curcol->column_data + curcol->column_cur_size, DataPtr, len); } curcol->column_cur_size += len; if (blob && curcol->column_cur_size > curcol->column_size) curcol->column_size = curcol->column_cur_size; return SQL_SUCCESS; }