static void test(TDSSOCKET * tds, TDSDYNAMIC * dyn, TDS_INT n, const char *s) { TDSPARAMINFO *params; TDSCOLUMN *curcol; int len = (int)strlen(s); tds_free_input_params(dyn); if (!(params = tds_alloc_param_result(dyn->params))) fatal_error("out of memory!"); dyn->params = params; curcol = params->columns[0]; curcol->column_type = SYBINTN; curcol->on_server.column_type = SYBINTN; curcol->column_size = sizeof(TDS_INT); curcol->on_server.column_size = sizeof(TDS_INT); curcol->column_varint_size = 1; curcol->column_cur_size = sizeof(TDS_INT); /* TODO test error */ tds_alloc_param_data(curcol); memcpy(curcol->column_data, &n, sizeof(n)); if (!(params = tds_alloc_param_result(dyn->params))) fatal_error("out of memory!"); dyn->params = params; curcol = params->columns[1]; tds_set_param_type(tds, curcol, SYBVARCHAR); curcol->column_size = 40; curcol->column_cur_size = len; tds_alloc_param_data(curcol); memcpy(curcol->column_data, s, len); if (tds_submit_execute(tds, dyn) != TDS_SUCCEED) fatal_error("tds_submit_execute() error"); if (discard_result(tds) != TDS_SUCCEED) fatal_error("tds_submit_execute() output error"); }
void TdsPreparedStatement::AllocateParameter(int nPosition) { while ((m_pParameters == NULL) || (nPosition > (m_pParameters->num_cols))) { //m_pParameters = tds_alloc_param_result(m_pStatement->params); m_pParameters = tds_alloc_param_result(m_pParameters); if (m_pParameters == NULL) { //fprintf(stderr, "out of memory!\n"); SetErrorCode(DATABASE_LAYER_ALLOCATION_ERROR); SetErrorMessage(wxT("out of memory")); ThrowDatabaseException(); return; } //m_pStatement->params = m_pParameters; } }
int parse_prepared_query(struct _hstmt *stmt, int compute_row) { /* try setting this parameter */ TDSPARAMINFO *temp_params; int nparam = stmt->params ? stmt->params->num_cols : 0; if (stmt->prepared_pos) return prepared_rpc(stmt, compute_row); tdsdump_log(TDS_DBG_FUNC, "parsing %d parameters\n", nparam); for (; stmt->param_num <= stmt->param_count; ++nparam, ++stmt->param_num) { /* find bound parameter */ if (stmt->param_num > stmt->apd->header.sql_desc_count || stmt->param_num > stmt->ipd->header.sql_desc_count) { tdsdump_log(TDS_DBG_FUNC, "parse_prepared_query: logic_error: parameter out of bounds: " "%d > %d || %d > %d\n", stmt->param_num, stmt->apd->header.sql_desc_count, stmt->param_num, stmt->ipd->header.sql_desc_count); return SQL_ERROR; } /* add a column to parameters */ if (!(temp_params = tds_alloc_param_result(stmt->params))) { odbc_errs_add(&stmt->errs, "HY001", NULL); return SQL_ERROR; } stmt->params = temp_params; switch (odbc_sql2tds (stmt, &stmt->ipd->records[stmt->param_num - 1], &stmt->apd->records[stmt->param_num - 1], stmt->params->columns[nparam], compute_row, stmt->apd, stmt->curr_param_row)) { case SQL_ERROR: return SQL_ERROR; case SQL_NEED_DATA: return SQL_NEED_DATA; } } return SQL_SUCCESS; }
static int prepared_rpc(struct _hstmt *stmt, int compute_row) { int nparam = stmt->params ? stmt->params->num_cols : 0; const char *p = stmt->prepared_pos - 1; TDSCONNECTION *conn = stmt->dbc->tds_socket->conn; for (;;) { TDSPARAMINFO *temp_params; TDSCOLUMN *curcol; TDS_SERVER_TYPE type; const char *start; while (TDS_ISSPACE(*++p)); if (!*p) return SQL_SUCCESS; /* we have certainly a parameter */ if (!(temp_params = tds_alloc_param_result(stmt->params))) { odbc_errs_add(&stmt->errs, "HY001", NULL); return SQL_ERROR; } stmt->params = temp_params; curcol = temp_params->columns[nparam]; switch (*p) { case ',': if (IS_TDS7_PLUS(conn)) { tds_set_param_type(conn, curcol, SYBVOID); curcol->column_size = curcol->column_cur_size = 0; } else { /* TODO is there a better type ? */ tds_set_param_type(conn, curcol, SYBINTN); curcol->column_size = curcol->on_server.column_size = 4; curcol->column_cur_size = -1; } if (compute_row) if (!tds_alloc_param_data(curcol)) { tds_free_param_result(temp_params); return SQL_ERROR; } --p; break; default: /* add next parameter to list */ start = p; if (!(p = parse_const_param(p, &type))) { tds_free_param_result(temp_params); return SQL_ERROR; } tds_set_param_type(conn, curcol, type); switch (type) { case SYBVARCHAR: curcol->column_size = p - start; break; case SYBVARBINARY: curcol->column_size = (p - start) / 2 -1; break; default: assert(0); case SYBINT4: case SYBFLT8: curcol->column_cur_size = curcol->column_size; break; } curcol->on_server.column_size = curcol->column_size; /* TODO support other type other than VARCHAR, do not strip escape in prepare_call */ if (compute_row) { char *dest; int len; CONV_RESULT cr; if (!tds_alloc_param_data(curcol)) { tds_free_param_result(temp_params); return SQL_ERROR; } dest = (char *) curcol->column_data; switch (type) { case SYBVARCHAR: if (*start != '\'') { memcpy(dest, start, p - start); curcol->column_cur_size = p - start; } else { ++start; for (;;) { if (*start == '\'') ++start; if (start >= p) break; *dest++ = *start++; } curcol->column_cur_size = dest - (char *) curcol->column_data; } break; case SYBVARBINARY: cr.cb.len = curcol->column_size; cr.cb.ib = dest; len = tds_convert(NULL, SYBVARCHAR, start, p - start, TDS_CONVERT_BINARY, &cr); if (len >= 0 && len <= curcol->column_size) curcol->column_cur_size = len; break; case SYBINT4: *((TDS_INT *) dest) = strtol(start, NULL, 10); break; case SYBFLT8: *((TDS_FLOAT *) dest) = strtod(start, NULL); break; default: break; } } --p; break; case '?': /* find binded parameter */ if (stmt->param_num > stmt->apd->header.sql_desc_count || stmt->param_num > stmt->ipd->header.sql_desc_count) { tds_free_param_result(temp_params); /* TODO set error */ return SQL_ERROR; } switch (odbc_sql2tds (stmt, &stmt->ipd->records[stmt->param_num - 1], &stmt->apd->records[stmt->param_num - 1], curcol, compute_row, stmt->apd, stmt->curr_param_row)) { case SQL_ERROR: return SQL_ERROR; case SQL_NEED_DATA: return SQL_NEED_DATA; } ++stmt->param_num; break; } ++nparam; while (TDS_ISSPACE(*++p)); if (!*p || *p != ',') return SQL_SUCCESS; stmt->prepared_pos = (char *) p + 1; } }
/** * Allocate memory and copy the rpc information into a TDSPARAMINFO structure. */ static TDSPARAMINFO * param_info_alloc(TDSSOCKET * tds, DBREMOTE_PROC * rpc) { int i; DBREMOTE_PROC_PARAM *p; TDSCOLUMN *pcol; TDSPARAMINFO *params = NULL, *new_params; BYTE *temp_value; int temp_datalen; int temp_type; int param_is_null; /* sanity */ if (rpc == NULL) return NULL; /* see v 1.10 2002/11/23 for first broken attempt */ for (i = 0, p = rpc->param_list; p != NULL; p = p->next, i++) { const unsigned char *prow; if (!(new_params = tds_alloc_param_result(params))) { tds_free_param_results(params); tdsdump_log(TDS_DBG_ERROR, "out of rpc memory!"); return NULL; } params = new_params; /* * Determine whether an input parameter is NULL * or not. */ param_is_null = 0; temp_type = p->type; temp_value = p->value; temp_datalen = p->datalen; if (p->datalen == 0) param_is_null = 1; tdsdump_log(TDS_DBG_INFO1, "parm_info_alloc(): parameter null-ness = %d\n", param_is_null); if (param_is_null || (p->status & DBRPCRETURN)) { if (param_is_null) { temp_datalen = 0; temp_value = NULL; } else if (is_fixed_type(temp_type)) { temp_datalen = tds_get_size_by_type(temp_type); } temp_type = tds_get_null_type(temp_type); } else if (is_fixed_type(temp_type)) { temp_datalen = tds_get_size_by_type(temp_type); } pcol = params->columns[i]; /* meta data */ if (p->name) { tds_strlcpy(pcol->column_name, p->name, sizeof(pcol->column_name)); pcol->column_namelen = strlen(pcol->column_name); } tds_set_param_type(tds, pcol, temp_type); if (p->maxlen > 0) pcol->column_size = p->maxlen; else { if (is_fixed_type(p->type)) { pcol->column_size = tds_get_size_by_type(p->type); } else { pcol->column_size = p->datalen; } } pcol->on_server.column_size = pcol->column_size; pcol->column_output = p->status; pcol->column_cur_size = temp_datalen; prow = param_row_alloc(params, pcol, i, temp_value, temp_datalen); if (!prow) { tds_free_param_results(params); tdsdump_log(TDS_DBG_ERROR, "out of memory for rpc row!"); return NULL; } } return params; }