1
/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2
* Copyright (C) 2004, 2005 Frediano Ziglio
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Library General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Library General Public License for more details.
14
* You should have received a copy of the GNU Library General Public
15
* License along with this library; if not, write to the
16
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
* Boston, MA 02111-1307, USA.
21
#endif /* HAVE_CONFIG_H */
30
#endif /* HAVE_STDLIB_H */
34
#endif /* HAVE_STRING_H */
39
#include "tdsconvert.h"
40
#include "tdsstring.h"
41
#include "tds_checks.h"
47
TDS_RCSID(var, "$Id: tds_checks.c,v 1.20 2007/06/21 07:21:21 freddy77 Exp $");
49
#if ENABLE_EXTRA_CHECKS
52
tds_check_tds_extra(const TDSSOCKET * tds)
54
const int invalid_state = 0;
57
TDSDYNAMIC *cur_dyn = NULL;
58
TDSCURSOR *cur_cursor = NULL;
62
/* teset state and connection */
71
assert(invalid_state);
74
assert(tds->state == TDS_DEAD || !TDS_IS_SOCKET_INVALID(tds->s));
75
assert(tds->state != TDS_DEAD || TDS_IS_SOCKET_INVALID(tds->s));
78
tds_check_env_extra(&tds->env);
80
/* test buffers and positions */
81
assert(tds->in_pos <= tds->in_len && tds->in_len <= tds->in_buf_max);
82
/* TODO remove blocksize from env and use out_len ?? */
83
/* assert(tds->out_pos <= tds->out_len); */
84
/* assert(tds->out_len == 0 || tds->out_buf != NULL); */
85
assert(tds->out_pos <= tds->env.block_size);
86
assert(tds->env.block_size == 0 || tds->out_buf != NULL);
87
assert(tds->in_buf_max == 0 || tds->in_buf != NULL);
91
tds_check_resultinfo_extra(tds->res_info);
92
if (tds->current_results == tds->res_info)
96
/* test num_comp_info, comp_info */
97
assert(tds->num_comp_info >= 0);
98
for (i = 0; i < tds->num_comp_info; ++i) {
99
assert(tds->comp_info);
100
tds_check_resultinfo_extra(tds->comp_info[i]);
101
if (tds->current_results == tds->comp_info[i])
106
if (tds->param_info) {
107
tds_check_resultinfo_extra(tds->param_info);
108
if (tds->current_results == tds->param_info)
114
for (cur_cursor = tds->cursors; cur_cursor != NULL; cur_cursor = cur_cursor->next) {
115
tds_check_cursor_extra(cur_cursor);
116
if (tds->current_results == cur_cursor->res_info)
118
if (cur_cursor == tds->cur_cursor)
121
assert(found || tds->cur_cursor == NULL);
123
/* test num_dyms, cur_dyn, dyns */
125
for (cur_dyn = tds->dyns; cur_dyn != NULL; cur_dyn = cur_dyn->next) {
126
if (cur_dyn == tds->cur_dyn)
128
tds_check_dynamic_extra(cur_dyn);
129
if (tds->current_results == cur_dyn->res_info)
132
assert(found || tds->cur_dyn == NULL);
135
tds_check_context_extra(tds->tds_ctx);
137
/* TODO test char_conv_count, char_convs */
139
/* current_results should be one of res_info, comp_info, param_info or dynamic */
141
* TODO this test was here to check that current_results was an alias
142
* but with cursor and reference counting current_results can point
143
* to a cursor result available on upper layer
144
* Perhaps we should free results on deallocate and enable
147
/* assert(result_found || tds->current_results == NULL); */
149
/* we can't have compute and no results */
150
assert(tds->num_comp_info == 0 || tds->res_info != NULL);
152
/* we can't have normal and parameters results */
153
/* TODO too strict ?? */
154
/* assert(tds->param_info == NULL || tds->res_info == NULL); */
158
tds_check_context_extra(const TDSCONTEXT * ctx)
164
tds_check_env_extra(const TDSENV * env)
168
assert(env->block_size >= 0 && env->block_size <= 65536);
172
tds_check_column_extra(const TDSCOLUMN * column)
180
assert(column->column_varint_size <= 5 && column->column_varint_size != 3);
182
assert(column->column_scale <= column->column_prec);
183
assert(column->column_prec <= 77);
185
/* I don't like this that much... freddy77 */
186
if (column->column_type == 0)
189
assert(strlen(column->table_name) < sizeof(column->table_name));
190
assert(strlen(column->column_name) < sizeof(column->column_name));
192
/* check type and server type same or SQLNCHAR -> SQLCHAR */
193
assert(tds_get_cardinal_type(column->on_server.column_type) == column->column_type
194
|| (tds_get_null_type(column->column_type) == column->on_server.column_type
195
&& column->column_varint_size == 1 && is_fixed_type(column->column_type)));
196
tds.minor_version = 0;
197
tds.major_version = 5;
198
varint_ok = tds_get_varint_size(&tds, column->on_server.column_type) == column->column_varint_size;
199
tds.major_version = 7;
200
varint_ok = varint_ok || tds_get_varint_size(&tds, column->on_server.column_type) == column->column_varint_size;
203
/* check current size <= size */
204
if (is_numeric_type(column->column_type)) {
205
/* I don't like that much this difference between numeric and not numeric - freddy77 */
206
/* TODO what should be the size ?? */
207
assert(column->column_prec >= 1 && column->column_prec <= 77);
208
assert(column->column_scale <= column->column_prec);
209
/* assert(column->column_cur_size == tds_numeric_bytes_per_prec[column->column_prec] + 2 || column->column_cur_size == -1); */
211
assert(column->column_cur_size <= column->column_size);
214
/* check size of fixed type correct */
215
size = tds_get_size_by_type(column->column_type);
216
assert(size != 0 || column->column_type == SYBVOID);
217
if (size >= 0 && column->column_type != SYBBITN) {
219
assert(is_fixed_type(column->column_type));
220
/* check current size */
221
assert(size == column->column_size);
222
/* check cases where server need nullable types */
223
if (column->column_type != column->on_server.column_type && (column->column_type != SYBINT8 || column->on_server.column_type != SYB5INT8)) {
224
assert(!is_fixed_type(column->on_server.column_type));
225
assert(column->column_varint_size == 1);
226
assert(column->column_size == column->column_cur_size || column->column_cur_size == -1);
228
assert(column->column_varint_size == 0 || (column->column_type == SYBUNIQUE && column->column_varint_size == 1));
229
assert(column->column_size == column->column_cur_size ||
230
(column->column_type == SYBUNIQUE && column->column_cur_size == -1));
232
assert(column->column_size == column->on_server.column_size);
234
assert(!is_fixed_type(column->column_type));
235
assert(column->char_conv || (column->on_server.column_size == column->column_size || column->on_server.column_size == 0));
236
assert(column->column_varint_size != 0);
239
/* check size of nullable types (ie intN) it's supported */
240
if (tds_get_conversion_type(column->column_type, 4) != column->column_type) {
242
assert(is_nullable_type(column->column_type));
243
/* check that size it's correct for this type of nullable */
244
assert(tds_get_conversion_type(column->column_type, column->column_size) != column->column_type);
245
/* check current size */
246
assert(column->column_size >= column->column_cur_size || column->column_cur_size == -1);
247
/* check same type and size on server */
248
assert(column->column_type == column->on_server.column_type);
249
assert(column->column_size == column->on_server.column_size);
254
tds_check_resultinfo_extra(const TDSRESULTINFO * res_info)
259
assert(res_info->num_cols >= 0);
260
assert(res_info->ref_count > 0);
261
for (i = 0; i < res_info->num_cols; ++i) {
262
assert(res_info->columns);
263
tds_check_column_extra(res_info->columns[i]);
264
assert(res_info->columns[i]->column_data != NULL || res_info->row_size == 0);
267
assert(res_info->row_size >= 0);
269
assert(res_info->computeid >= 0);
271
assert(res_info->by_cols >= 0);
272
assert(res_info->by_cols == 0 || res_info->bycolumns);
276
tds_check_cursor_extra(const TDSCURSOR * cursor)
281
tds_check_dynamic_extra(const TDSDYNAMIC * dyn)
286
tds_check_resultinfo_extra(dyn->res_info);
288
tds_check_resultinfo_extra(dyn->params);
290
assert(!dyn->emulated || dyn->query);
293
#endif /* ENABLE_EXTRA_CHECKS */