예제 #1
0
void
tds_check_column_extra(const TDSCOLUMN * column)
{
	int size;
	TDSCONNECTION conn;
	int varint_ok;
	int column_varint_size;

	assert(column);
	column_varint_size = column->column_varint_size;

	/* 8 is for varchar(max) or similar */
	assert(column_varint_size == 8 || (column_varint_size <= 5 && column_varint_size != 3));

	assert(column->column_scale <= column->column_prec);
	assert(column->column_prec <= MAXPRECISION);

	/* I don't like this that much... freddy77 */
	if (column->column_type == 0)
		return;
	assert(column->funcs);
	assert(column->column_type > 0);

	/* check type and server type same or SQLNCHAR -> SQLCHAR */
#define SPECIAL(ttype, server_type, varint) \
	if (column->column_type == ttype && column->on_server.column_type == server_type && column_varint_size == varint) {} else
	SPECIAL(SYBTEXT, XSYBVARCHAR, 8)
	SPECIAL(SYBTEXT, XSYBNVARCHAR, 8)
	SPECIAL(SYBIMAGE, XSYBVARBINARY, 8)
	assert(tds_get_cardinal_type(column->on_server.column_type, column->column_usertype) == column->column_type
		|| (tds_get_conversion_type(column->on_server.column_type, column->column_size) == column->column_type
		&& column_varint_size == 1 && is_fixed_type(column->column_type)));

	varint_ok = 0;
	if (column_varint_size == 8) {
		assert(column->on_server.column_type == XSYBVARCHAR || column->on_server.column_type == XSYBVARBINARY || column->on_server.column_type == XSYBNVARCHAR || column->on_server.column_type == SYBMSXML || column->on_server.column_type == SYBMSUDT);
		varint_ok = 1;
	} else if (is_blob_type(column->column_type)) {
		assert(column_varint_size >= 4);
	} else if (column->column_type == SYBVARIANT) {
		assert(column_varint_size == 4);
	}
	conn.tds_version = 0x500;
	varint_ok = varint_ok || tds_get_varint_size(&conn, column->on_server.column_type) == column_varint_size;
	conn.tds_version = 0x700;
	varint_ok = varint_ok || tds_get_varint_size(&conn, column->on_server.column_type) == column_varint_size;
	assert(varint_ok);

	/* check current size <= size */
	if (is_numeric_type(column->column_type)) {
		/* I don't like that much this difference between numeric and not numeric - freddy77 */
		/* TODO what should be the size ?? */
		assert(column->column_prec >= 1 && column->column_prec <= MAXPRECISION);
		assert(column->column_scale <= column->column_prec);
/*		assert(column->column_cur_size == tds_numeric_bytes_per_prec[column->column_prec] + 2 || column->column_cur_size == -1); */
	} else {
		assert(column->column_cur_size <= column->column_size);
	}

	/* check size of fixed type correct */
	size = tds_get_size_by_type(column->column_type);
	assert(size != 0 || column->column_type == SYBVOID);
	if (size >= 0 && column->column_type != SYBBITN) {
		/* check macro */
		assert(is_fixed_type(column->column_type));
		/* check current size */
		if (column->column_type != SYBMSDATE)
			assert(size == column->column_size);
		/* check cases where server need nullable types */
		if (column->column_type != column->on_server.column_type && (column->column_type != SYBINT8 || column->on_server.column_type != SYB5INT8)) {
			assert(!is_fixed_type(column->on_server.column_type));
			assert(column_varint_size == 1);
			assert(column->column_size == column->column_cur_size || column->column_cur_size == -1);
		} else {
			assert(column_varint_size == 0
				|| (column->column_type == SYBUNIQUE && column_varint_size == 1)
				|| (column->column_type == SYBMSDATE  && column_varint_size == 1));
			assert(column->column_size == column->column_cur_size
				|| (column->column_type == SYBUNIQUE && column->column_cur_size == -1)
				|| (column->column_type == SYBMSDATE  && column->column_cur_size == -1));
		}
		assert(column->column_size == column->on_server.column_size);
	} else {
		assert(!is_fixed_type(column->column_type));
		assert(is_char_type(column->column_type) || (column->on_server.column_size == column->column_size || column->on_server.column_size == 0));
		assert(column_varint_size != 0);
	}

	/* check size of nullable types (ie intN) it's supported */
	if (tds_get_conversion_type(column->column_type, 4) != column->column_type) {
		/* check macro */
		assert(is_nullable_type(column->column_type));
		/* check that size it's correct for this type of nullable */
		assert(tds_get_conversion_type(column->column_type, column->column_size) != column->column_type);
		/* check current size */
		assert(column->column_size >= column->column_cur_size || column->column_cur_size == -1);
		/* check same type and size on server */
		assert(column->column_type == column->on_server.column_type);
		assert(column->column_size == column->on_server.column_size);
	}
}
예제 #2
0
파일: bulk.c 프로젝트: DmitrySigaev/ncbi
/**
 * Add fixed size columns to the row
 * \param bcpinfo BCP information
 * \param get_col_data function to call to retrieve data to be sent
 * \param ignored function to call if we try to send NULL if not allowed (not used)
 * \param offset passed to get_col_data and null_error to specify the row to get
 * \param rowbuffer row buffer to write to
 * \param start row buffer last end position
 * \returns new row length or -1 on error.
 */
static int
tds_bcp_add_fixed_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error,
				int offset, unsigned char * rowbuffer, int start)
{
	TDS_NUMERIC *num;
	int row_pos = start;
	TDSCOLUMN *bcpcol;
	int cpbytes;
	int i, j;
	int bitleft = 0, bitpos;

	assert(bcpinfo);
	assert(rowbuffer);

	tdsdump_log(TDS_DBG_FUNC, "tds_bcp_add_fixed_columns(%p, %p, ignored, %d, %p, %d)\n", bcpinfo, get_col_data, offset, rowbuffer, start);

	for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {

		bcpcol = bcpinfo->bindinfo->columns[i];

        if (is_nullable_type(bcpcol->on_server.column_type)
            || bcpcol->column_nullable)
			continue;

		tdsdump_log(TDS_DBG_FUNC, "tds_bcp_add_fixed_columns column %d is a fixed column\n", i + 1);

		if (TDS_FAILED(get_col_data(bcpinfo, bcpcol, offset))) {
			tdsdump_log(TDS_DBG_INFO1, "get_col_data (column %d) failed\n", i + 1);
			return -1;
		}

        if (bcpcol->bcp_column_data->is_null  &&  null_error) {
			/* No value or default value available and NULL not allowed. */
			null_error(bcpinfo, i, offset);
			return -1;
		}

		if (is_numeric_type(bcpcol->column_type)) {
			num = (TDS_NUMERIC *) bcpcol->bcp_column_data->data;
			cpbytes = tds_numeric_bytes_per_prec[num->precision];
			memcpy(&rowbuffer[row_pos], num->array, cpbytes);
		} else if (bcpcol->column_type == SYBBIT) {
			/* all bit are collapsed together */
			if (!bitleft) {
				bitpos = row_pos++;
				bitleft = 8;
				rowbuffer[bitpos] = 0;
			}
			if (bcpcol->bcp_column_data->data[0])
				rowbuffer[bitpos] |= 256 >> bitleft;
			--bitleft;
			continue;
		} else {
			cpbytes = bcpcol->bcp_column_data->datalen > bcpcol->column_size ?
				  bcpcol->column_size : bcpcol->bcp_column_data->datalen;
			memcpy(&rowbuffer[row_pos], bcpcol->bcp_column_data->data, cpbytes);

			/* CHAR data may need padding out to the database length with blanks */
			/* TODO check binary !!! */
			if (bcpcol->column_type == SYBCHAR && cpbytes < bcpcol->column_size) {
				for (j = cpbytes; j <  bcpcol->column_size; j++)
					rowbuffer[row_pos + j] = ' ';
			}
		}

		row_pos += bcpcol->column_size;
	}
예제 #3
0
파일: scanner.c 프로젝트: ybakos/wayland
static void
start_element(void *data, const char *element_name, const char **atts)
{
	struct parse_context *ctx = data;
	struct interface *interface;
	struct message *message;
	struct arg *arg;
	struct enumeration *enumeration;
	struct entry *entry;
	struct description *description = NULL;
	const char *name = NULL;
	const char *type = NULL;
	const char *interface_name = NULL;
	const char *value = NULL;
	const char *summary = NULL;
	const char *since = NULL;
	const char *allow_null = NULL;
	const char *enumeration_name = NULL;
	const char *bitfield = NULL;
	int i, version = 0;

	ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser);
	for (i = 0; atts[i]; i += 2) {
		if (strcmp(atts[i], "name") == 0)
			name = atts[i + 1];
		if (strcmp(atts[i], "version") == 0) {
			version = strtouint(atts[i + 1]);
			if (version == -1)
				fail(&ctx->loc, "wrong version (%s)", atts[i + 1]);
		}
		if (strcmp(atts[i], "type") == 0)
			type = atts[i + 1];
		if (strcmp(atts[i], "value") == 0)
			value = atts[i + 1];
		if (strcmp(atts[i], "interface") == 0)
			interface_name = atts[i + 1];
		if (strcmp(atts[i], "summary") == 0)
			summary = atts[i + 1];
		if (strcmp(atts[i], "since") == 0)
			since = atts[i + 1];
		if (strcmp(atts[i], "allow-null") == 0)
			allow_null = atts[i + 1];
		if (strcmp(atts[i], "enum") == 0)
			enumeration_name = atts[i + 1];
		if (strcmp(atts[i], "bitfield") == 0)
			bitfield = atts[i + 1];
	}

	ctx->character_data_length = 0;
	if (strcmp(element_name, "protocol") == 0) {
		if (name == NULL)
			fail(&ctx->loc, "no protocol name given");

		ctx->protocol->name = xstrdup(name);
		ctx->protocol->uppercase_name = uppercase_dup(name);
	} else if (strcmp(element_name, "copyright") == 0) {

	} else if (strcmp(element_name, "interface") == 0) {
		if (name == NULL)
			fail(&ctx->loc, "no interface name given");

		if (version == 0)
			fail(&ctx->loc, "no interface version given");

		interface = create_interface(ctx->loc, name, version);
		ctx->interface = interface;
		wl_list_insert(ctx->protocol->interface_list.prev,
			       &interface->link);
	} else if (strcmp(element_name, "request") == 0 ||
		   strcmp(element_name, "event") == 0) {
		if (name == NULL)
			fail(&ctx->loc, "no request name given");

		message = create_message(ctx->loc, name);

		if (strcmp(element_name, "request") == 0)
			wl_list_insert(ctx->interface->request_list.prev,
				       &message->link);
		else
			wl_list_insert(ctx->interface->event_list.prev,
				       &message->link);

		if (type != NULL && strcmp(type, "destructor") == 0)
			message->destructor = 1;

		version = version_from_since(ctx, since);

		if (version < ctx->interface->since)
			warn(&ctx->loc, "since version not increasing\n");
		ctx->interface->since = version;
		message->since = version;

		if (strcmp(name, "destroy") == 0 && !message->destructor)
			fail(&ctx->loc, "destroy request should be destructor type");

		ctx->message = message;
	} else if (strcmp(element_name, "arg") == 0) {
		if (name == NULL)
			fail(&ctx->loc, "no argument name given");

		arg = create_arg(name);
		if (!set_arg_type(arg, type))
			fail(&ctx->loc, "unknown type (%s)", type);

		switch (arg->type) {
		case NEW_ID:
			ctx->message->new_id_count++;
			/* fallthrough */
		case OBJECT:
			if (interface_name)
				arg->interface_name = xstrdup(interface_name);
			break;
		default:
			if (interface_name != NULL)
				fail(&ctx->loc, "interface attribute not allowed for type %s", type);
			break;
		}

		if (allow_null) {
			if (strcmp(allow_null, "true") == 0)
				arg->nullable = 1;
			else if (strcmp(allow_null, "false") != 0)
				fail(&ctx->loc,
				     "invalid value for allow-null attribute (%s)",
				     allow_null);

			if (!is_nullable_type(arg))
				fail(&ctx->loc,
				     "allow-null is only valid for objects, strings, and arrays");
		}

		if (enumeration_name == NULL || strcmp(enumeration_name, "") == 0)
			arg->enumeration_name = NULL;
		else
			arg->enumeration_name = xstrdup(enumeration_name);

		if (summary)
			arg->summary = xstrdup(summary);

		wl_list_insert(ctx->message->arg_list.prev, &arg->link);
		ctx->message->arg_count++;
	} else if (strcmp(element_name, "enum") == 0) {
		if (name == NULL)
			fail(&ctx->loc, "no enum name given");

		enumeration = create_enumeration(name);

		if (bitfield == NULL || strcmp(bitfield, "false") == 0)
			enumeration->bitfield = false;
		else if (strcmp(bitfield, "true") == 0)
			enumeration->bitfield = true;
		else
			fail(&ctx->loc,
			     "invalid value (%s) for bitfield attribute (only true/false are accepted)",
			     bitfield);

		wl_list_insert(ctx->interface->enumeration_list.prev,
			       &enumeration->link);

		ctx->enumeration = enumeration;
	} else if (strcmp(element_name, "entry") == 0) {
		if (name == NULL)
			fail(&ctx->loc, "no entry name given");

		entry = create_entry(name, value);
		version = version_from_since(ctx, since);

		if (version < ctx->enumeration->since)
			warn(&ctx->loc, "since version not increasing\n");
		ctx->enumeration->since = version;
		entry->since = version;

		if (summary)
			entry->summary = xstrdup(summary);
		else
			entry->summary = NULL;
		wl_list_insert(ctx->enumeration->entry_list.prev,
			       &entry->link);
	} else if (strcmp(element_name, "description") == 0) {
		if (summary == NULL)
			fail(&ctx->loc, "description without summary");

		description = xzalloc(sizeof *description);
		description->summary = xstrdup(summary);

		if (ctx->message)
			ctx->message->description = description;
		else if (ctx->enumeration)
			ctx->enumeration->description = description;
		else if (ctx->interface)
			ctx->interface->description = description;
		else
			ctx->protocol->description = description;
		ctx->description = description;
	}
}
예제 #4
0
파일: bulk.c 프로젝트: DmitrySigaev/ncbi
/**
 * Send one row of data to server
 * \tds
 * \param bcpinfo BCP information
 * \param get_col_data function to call to retrieve data to be sent
 * \param ignored function to call if we try to send NULL if not allowed (not used)
 * \param offset passed to get_col_data and null_error to specify the row to get
 * \return TDS_SUCCESS or TDS_FAIL.
 */
TDSRET
tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset)
{
	TDSCOLUMN  *bindcol;
    int i, start_col = bcpinfo->next_col;
	TDSRET rc;

    tdsdump_log(TDS_DBG_FUNC, "tds_bcp_send_bcp_record(%p, %p, %p, %p, %d)\n", tds, bcpinfo, get_col_data, null_error, offset);

	if (tds->out_flag != TDS_BULK || tds_set_state(tds, TDS_WRITING) != TDS_WRITING)
		return TDS_FAIL;

    if (start_col > 0) {
        bindcol = bcpinfo->bindinfo->columns[start_col - 1];
        *bindcol->column_lenbind
            = MIN((TDS_INT) bindcol->column_bindlen - bcpinfo->text_sent,
                  *bindcol->column_lenbind);
        tds_put_n(tds, bindcol->column_varaddr, *bindcol->column_lenbind);
        bcpinfo->text_sent += *bindcol->column_lenbind;
        if ((TDS_UINT) bcpinfo->text_sent < bindcol->column_bindlen) {
            return TDS_SUCCESS; /* That's all for now. */
        } else if (!IS_TDS7_PLUS(tds->conn)) {
            bcpinfo->blob_cols++;
        }
        bcpinfo->next_col  = 0;
        bcpinfo->text_sent = 0;
    }

	if (IS_TDS7_PLUS(tds->conn)) {

        if (start_col == 0) {
            tds_put_byte(tds, TDS_ROW_TOKEN);   /* 0xd1 */
        }
        for (i = start_col; i < bcpinfo->bindinfo->num_cols; i++) {
	
			TDS_INT save_size;
			unsigned char *save_data;
			TDSBLOB blob;
            int /* bool */ has_text = 0;

			bindcol = bcpinfo->bindinfo->columns[i];

			/*
			 * Don't send the (meta)data for timestamp columns or
			 * identity columns unless indentity_insert is enabled.
			 */

			if ((!bcpinfo->identity_insert_on && bindcol->column_identity) || 
                bindcol->column_timestamp ||
                !tds_bcp_is_bound(bcpinfo, bindcol)) {
				continue;
			}

			rc = get_col_data(bcpinfo, bindcol, offset);
            if (rc == TDS_FAIL) {
				tdsdump_log(TDS_DBG_INFO1, "get_col_data (column %d) failed\n", i + 1);
				goto cleanup;
            } else if (rc != TDS_SUCCESS) { /* CS_BLK_HAS_TEXT? */
                has_text = 1;
			}
			tdsdump_log(TDS_DBG_INFO1, "gotten column %d length %d null %d\n",
					i + 1, bindcol->bcp_column_data->datalen, bindcol->bcp_column_data->is_null);

			save_size = bindcol->column_cur_size;
			save_data = bindcol->column_data;
			assert(bindcol->column_data == NULL);
			if (bindcol->bcp_column_data->is_null) {
                if ( !bindcol->column_nullable
                     &&  !is_nullable_type(bindcol->on_server.column_type) ) {
                    return TDS_FAIL;
                }
				bindcol->column_cur_size = -1;
            } else if (has_text) {
                bindcol->column_cur_size = bindcol->bcp_column_data->datalen;
			} else if (is_blob_col(bindcol)) {
				bindcol->column_cur_size = bindcol->bcp_column_data->datalen;
				memset(&blob, 0, sizeof(blob));
				blob.textvalue = (TDS_CHAR *) bindcol->bcp_column_data->data;
				bindcol->column_data = (unsigned char *) &blob;
			} else {
				bindcol->column_cur_size = bindcol->bcp_column_data->datalen;
				bindcol->column_data = bindcol->bcp_column_data->data;
			}
			rc = bindcol->funcs->put_data(tds, bindcol, 1);
			bindcol->column_cur_size = save_size;
			bindcol->column_data = save_data;

			if (TDS_FAILED(rc))
				goto cleanup;
            else if (has_text) {
                bcpinfo->next_col = i + 1;
                /* bcpinfo->text_sent = 0; */
                break;
            }
		}
	}  /* IS_TDS7_PLUS */
	else {
      if (start_col == 0) {
		int row_pos;
		int row_sz_pos;
		int var_cols_written = 0;
		TDS_INT	 old_record_size = bcpinfo->bindinfo->row_size;
		unsigned char *record = bcpinfo->bindinfo->current_row;

		memset(record, '\0', old_record_size);	/* zero the rowbuffer */

		/*
		 * offset 0 = number of var columns
		 * offset 1 = row number.  zeroed (datasever assigns)
		 */
		row_pos = 2;

		rc = TDS_FAIL;
        if ((row_pos = tds_bcp_add_fixed_columns(bcpinfo, get_col_data, null_error, offset, record, row_pos)) < 0)
			goto cleanup;

		row_sz_pos = row_pos;

		/* potential variable columns to write */

        if ((row_pos = tds_bcp_add_variable_columns(bcpinfo, get_col_data, null_error, offset, record, row_pos, &var_cols_written)) < 0)
			goto cleanup;


		if (var_cols_written) {
			TDS_PUT_UA2(&record[row_sz_pos], row_pos);
			record[0] = var_cols_written;
		}

		tdsdump_log(TDS_DBG_INFO1, "old_record_size = %d new size = %d \n", old_record_size, row_pos);

		tds_put_smallint(tds, row_pos);
		tds_put_n(tds, record, row_pos);

		/* row is done, now handle any text/image data */

        bcpinfo->blob_cols = 0;
      }

        for (i = start_col; i < bcpinfo->bindinfo->num_cols; i++) {
			bindcol = bcpinfo->bindinfo->columns[i];
			if (is_blob_type(bindcol->column_type)) {
                /* Elide trailing NULLs */
                if (bindcol->bcp_column_data->is_null) {
                    int j;
                    for (j = i + 1;  j < bcpinfo->bindinfo->num_cols;  ++j) {
                        TDSCOLUMN *bindcol2 = bcpinfo->bindinfo->columns[j];
                        if (is_blob_type(bindcol2->column_type)
                            &&  !bindcol2->bcp_column_data->is_null) {
                            break;
                        }
                    }
                    if (j == bcpinfo->bindinfo->num_cols) {
                        i = j;
                        break;
                    }
                }

				rc = get_col_data(bcpinfo, bindcol, offset);
                if (rc == TDS_FAIL)
					goto cleanup;
				/* unknown but zero */
				tds_put_smallint(tds, 0);
                tds_put_byte(tds, (unsigned char) bindcol->column_type);
                tds_put_byte(tds, 0xff - bcpinfo->blob_cols);
				/*
				 * offset of txptr we stashed during variable
				 * column processing 
				 */
				tds_put_smallint(tds, bindcol->column_textpos);
				tds_put_int(tds, bindcol->bcp_column_data->datalen);
                if (rc != TDS_SUCCESS) { /* CS_BLK_HAS_TEXT? */
                    bcpinfo->next_col = i + 1;
                    /* bcpinfo->text_sent = 0; */
                    break;
                }
				tds_put_n(tds, bindcol->bcp_column_data->data, bindcol->bcp_column_data->datalen);
                bcpinfo->blob_cols++;

			}
		}
	}

    if (i == bcpinfo->bindinfo->num_cols) {
        tds_set_state(tds, TDS_SENDING);
        bcpinfo->next_col = 0;
    }
	return TDS_SUCCESS;

cleanup:
	tds_set_state(tds, TDS_SENDING);
	return rc;
}
예제 #5
0
void
tds_check_column_extra(const TDSCOLUMN * column)
{
	int size;
	TDSCONNECTION conn;
	int varint_ok;
	int column_varint_size;

	assert(column);
	column_varint_size = column->column_varint_size;

	/* 8 is for varchar(max) or similar */
	assert(column_varint_size == 8 || (column_varint_size <= 5 && column_varint_size != 3));

	assert(column->column_scale <= column->column_prec);
	assert(column->column_prec <= MAXPRECISION);

	/* I don't like this that much... freddy77 */
	if (column->column_type == 0)
		return;
	assert(column->funcs);
	assert(column->column_type > 0);

	/* specific checks, if true fully checked */
	if (column->funcs->check(column))
		return;

	/* check type and server type same or SQLNCHAR -> SQLCHAR */
#define SPECIAL(ttype, server_type, varint) \
	if (column->column_type == ttype && column->on_server.column_type == server_type && column_varint_size == varint) {} else
	SPECIAL(SYBTEXT, XSYBVARCHAR, 8)
	SPECIAL(SYBTEXT, XSYBNVARCHAR, 8)
	SPECIAL(SYBIMAGE, XSYBVARBINARY, 8)
	assert(tds_get_cardinal_type(column->on_server.column_type, column->column_usertype) == column->column_type
		|| (tds_get_conversion_type(column->on_server.column_type, column->column_size) == column->column_type
		&& column_varint_size == 1 && is_fixed_type(column->column_type)));

	varint_ok = 0;
	if (column_varint_size == 8) {
		if (column->on_server.column_type == XSYBVARCHAR
		    || column->on_server.column_type == XSYBVARBINARY
		    || column->on_server.column_type == XSYBNVARCHAR)
			varint_ok = 1;
	} else if (is_blob_type(column->column_type)) {
		assert(column_varint_size >= 4);
	} else if (column->column_type == SYBVARIANT) {
		assert(column_varint_size == 4);
	}
	conn.tds_version = 0x500;
	varint_ok = varint_ok || tds_get_varint_size(&conn, column->on_server.column_type) == column_varint_size;
	conn.tds_version = 0x700;
	varint_ok = varint_ok || tds_get_varint_size(&conn, column->on_server.column_type) == column_varint_size;
	assert(varint_ok);

	assert(!is_numeric_type(column->column_type));
	assert(column->column_cur_size <= column->column_size);

	/* check size of fixed type correct */
	size = tds_get_size_by_type(column->column_type);
	assert(size != 0 || column->column_type == SYBVOID);
	/* these peculiar types are variable but have only a possible size */
	if (size >= 0 && (column->column_type != SYBBITN
		  && column->column_type != SYBDATEN && column->column_type != SYBTIMEN)) {
		/* check macro */
		assert(is_fixed_type(column->column_type));
		/* check current size */
		assert(size == column->column_size);
		/* check cases where server need nullable types */
		if (column->column_type != column->on_server.column_type && (column->column_type != SYBINT8 || column->on_server.column_type != SYB5INT8)) {
			assert(!is_fixed_type(column->on_server.column_type));
			assert(column_varint_size == 1);
			assert(column->column_size == column->column_cur_size || column->column_cur_size == -1);
		} else {
			assert(column_varint_size == 0
				|| (column->column_type == SYBUNIQUE && column_varint_size == 1));
			assert(column->column_size == column->column_cur_size
				|| (column->column_type == SYBUNIQUE && column->column_cur_size == -1));
		}
		assert(column->column_size == column->on_server.column_size);
	} else {
		assert(!is_fixed_type(column->column_type));
		assert(is_char_type(column->column_type) || (column->on_server.column_size == column->column_size || column->on_server.column_size == 0));
		assert(column_varint_size != 0);
	}

	/* check size of nullable types (ie intN) it's supported */
	if (tds_get_conversion_type(column->column_type, 4) != column->column_type) {
		/* check macro */
		assert(is_nullable_type(column->column_type));
		/* check that size it's correct for this type of nullable */
		assert(tds_get_conversion_type(column->column_type, column->column_size) != column->column_type);
		/* check current size */
		assert(column->column_size >= column->column_cur_size || column->column_cur_size == -1);
		/* check same type and size on server */
		assert(column->column_type == column->on_server.column_type);
		assert(column->column_size == column->on_server.column_size);
	}
}