Beispiel #1
0
static void
data_msdatetime_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver)
{
	int decimals = col->column_prec ? col->column_prec + 1: 0;

	switch (col->on_server.column_type) {
	case SYBMSTIME:
		drec->sql_desc_octet_length = sizeof(SQL_SS_TIME2_STRUCT);
		drec->sql_desc_concise_type = SQL_SS_TIME2;
		/* always hh:mm:ss[.fff] */
		drec->sql_desc_display_size = 8 + decimals;
		SET_INFO2("time", "'", "'", 8 + decimals);
	case SYBMSDATE:
		drec->sql_desc_octet_length = sizeof(DATE_STRUCT);
		drec->sql_desc_concise_type = SQL_TYPE_DATE;
		/* always yyyy-mm-dd ?? */
		drec->sql_desc_display_size = 10;
		SET_INFO2("date", "'", "'", 10);
	case SYBMSDATETIMEOFFSET:
		drec->sql_desc_octet_length = sizeof(SQL_SS_TIMESTAMPOFFSET_STRUCT);
		drec->sql_desc_concise_type = SQL_SS_TIMESTAMPOFFSET;
		/* we always format using yyyy-mm-dd hh:mm:ss[.fff] +HH:MM, see convert_tds2sql.c */
		drec->sql_desc_display_size = 26 + decimals;
		SET_INFO2("datetimeoffset", "'", "'", 26 + decimals);
	case SYBMSDATETIME2:
		drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
		drec->sql_desc_concise_type = SQL_TYPE_TIMESTAMP;
		drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
		/* we always format using yyyy-mm-dd hh:mm:ss[.fff], see convert_tds2sql.c */
		drec->sql_desc_display_size = 19 + decimals;
		SET_INFO2("datetime2", "'", "'", 19 + decimals);
	default:
		break;
	}
}
Beispiel #2
0
static void
data_variant_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver)
{
	drec->sql_desc_concise_type = SQL_SS_VARIANT;
	drec->sql_desc_display_size = 8000;
	drec->sql_desc_octet_length = 0;
	SET_INFO2("sql_variant", "", "", 8000);
}
Beispiel #3
0
static void
data_numeric_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver)
{
	const char *type_name =
		col->on_server.column_type == SYBNUMERIC ? "numeric" : "decimal";

	drec->sql_desc_concise_type = SQL_NUMERIC;
	drec->sql_desc_octet_length = col->column_prec + 2;
	drec->sql_desc_display_size = col->column_prec + 2;
	drec->sql_desc_num_prec_radix = 10;
	SET_INFO2(type_name, "", "", col->column_prec);
}
Beispiel #4
0
static void
data_sybbigtime_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver)
{
	if (col->on_server.column_type == SYB5BIGTIME) {
		drec->sql_desc_concise_type = SQL_SS_TIME2;
		/* we always format using hh:mm:ss[.ffffff], see convert_tds2sql.c */
		drec->sql_desc_display_size = 15;
		drec->sql_desc_octet_length = sizeof(SQL_SS_TIME2_STRUCT);
		drec->sql_desc_precision = 6;
		drec->sql_desc_scale     = 6;
		drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
		SET_INFO2("bigtime", "'", "'", 15);
	}

	assert(col->on_server.column_type == SYB5BIGDATETIME);

	drec->sql_desc_concise_type = SQL_TYPE_TIMESTAMP;
	drec->sql_desc_display_size = 26;
	drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
	drec->sql_desc_precision = 6;
	drec->sql_desc_scale     = 6;
	drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
	SET_INFO2("bigdatetime", "'", "'", 26);
}
Beispiel #5
0
static void
data_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver)
{
	const char *type;

#define SET_INFO(type, prefix, suffix) do { \
	drec->sql_desc_literal_prefix = prefix; \
	drec->sql_desc_literal_suffix = suffix; \
	drec->sql_desc_type_name = type; \
	return; \
	} while(0)
#define SET_INFO2(type, prefix, suffix, len) do { \
	drec->sql_desc_length = (len); \
	SET_INFO(type, prefix, suffix); \
	} while(0)

	drec->sql_desc_unsigned = SQL_FALSE;
	drec->sql_desc_octet_length = drec->sql_desc_length = col->on_server.column_size;

	switch (tds_get_conversion_type(col->column_type, col->column_size)) {
	case XSYBCHAR:
	case SYBCHAR:
		if (col->on_server.column_type == XSYBNCHAR)
			SET_INFO2("nchar", "'", "'", col->on_server.column_size / 2);
		SET_INFO("char", "'", "'");
	case XSYBVARCHAR:
	case SYBVARCHAR:
		type = "varchar";
		if (col->on_server.column_type == SYBNVARCHAR || col->on_server.column_type == XSYBNVARCHAR) {
			drec->sql_desc_length = col->on_server.column_size / 2u;
			type = "nvarchar";
		}
		if (is_blob_col(col))
			drec->sql_desc_octet_length = drec->sql_desc_length =
				SQL_SS_LENGTH_UNLIMITED;
		SET_INFO(type, "'", "'");
	case SYBTEXT:
		if (col->on_server.column_type == SYBNTEXT)
			SET_INFO2("ntext", "'", "'", col->on_server.column_size / 2);
		SET_INFO("text", "'", "'");
	case SYBBIT:
	case SYBBITN:
		drec->sql_desc_unsigned = SQL_TRUE;
		SET_INFO2("bit", "", "", 1);
#if (ODBCVER >= 0x0300)
	case SYBINT8:
		/* TODO return numeric for odbc2 and convert bigint to numeric */
		SET_INFO2("bigint", "", "", 19);
#endif
	case SYBINT4:
		SET_INFO2("int", "", "", 10);
	case SYBINT2:
		SET_INFO2("smallint", "", "", 5);
	case SYBUINT1:
	case SYBINT1:
		drec->sql_desc_unsigned = SQL_TRUE;
		SET_INFO2("tinyint", "", "", 3);
#if (ODBCVER >= 0x0300)
	case SYBUINT8:
		drec->sql_desc_unsigned = SQL_TRUE;
		/* TODO return numeric for odbc2 and convert bigint to numeric */
		SET_INFO2("unsigned bigint", "", "", 19);
#endif
	case SYBUINT4:
		drec->sql_desc_unsigned = SQL_TRUE;
		SET_INFO2("unsigned int", "", "", 10);
	case SYBUINT2:
		drec->sql_desc_unsigned = SQL_TRUE;
		SET_INFO2("unsigned smallint", "", "", 5);
	case SYBREAL:
		SET_INFO2("real", "", "", odbc_ver == SQL_OV_ODBC3 ? 24 : 7);
	case SYBFLT8:
		SET_INFO2("float", "", "", odbc_ver == SQL_OV_ODBC3 ? 53 : 15);
	case SYBMONEY:
		drec->sql_desc_octet_length = 21;
		SET_INFO2("money", "$", "", 19);
	case SYBMONEY4:
		drec->sql_desc_octet_length = 12;
		SET_INFO2("money", "$", "", 10);
	case SYBDATETIME:
		drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
		SET_INFO2("datetime", "'", "'", 23);
	case SYBDATETIME4:
		drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
		SET_INFO2("datetime", "'", "'", 16);
	case SYBBINARY:
		/* handle TIMESTAMP using usertype */
		if (col->column_usertype == 80)
			SET_INFO("timestamp", "0x", "");
		SET_INFO("binary", "0x", "");
	case SYBIMAGE:
		SET_INFO("image", "0x", "");
	case SYBVARBINARY:
		if (is_blob_col(col))
			drec->sql_desc_octet_length = drec->sql_desc_length =
				SQL_SS_LENGTH_UNLIMITED;
		SET_INFO("varbinary", "0x", "");
	case SYBNUMERIC:
		drec->sql_desc_octet_length = col->column_prec + 2;
		SET_INFO2("numeric", "", "", col->column_prec);
	case SYBDECIMAL:
		drec->sql_desc_octet_length = col->column_prec + 2;
		SET_INFO2("decimal", "", "", col->column_prec);
	case SYBINTN:
	case SYBDATETIMN:
	case SYBFLTN:
	case SYBMONEYN:
		assert(0);
	case SYBVOID:
	case SYBNTEXT:
	case SYBNVARCHAR:
	case XSYBNVARCHAR:
	case XSYBNCHAR:
		break;
#if (ODBCVER >= 0x0300)
	case SYBUNIQUE:
		/* FIXME for Sybase ?? */
		SET_INFO2("uniqueidentifier", "'", "'", 36);
	case SYBVARIANT:
		SET_INFO("sql_variant", "", "");
		break;
#endif
	case SYBMSDATETIMEOFFSET:
		SET_INFO2("datetimeoffset", "'", "'", col->column_prec + 27);
	case SYBMSDATETIME2:
		SET_INFO2("datetime2", "'", "'", col->column_prec + 20);
	case SYBMSTIME:
		SET_INFO2("time", "'", "'", col->column_prec + 9);
	case SYBMSDATE:
		SET_INFO2("date", "'", "'", 10);
	case SYBMSXML:
		SET_INFO("xml", "'", "'");
	}
	SET_INFO("", "", "");
#undef SET_INFO
#undef SET_INFO2
}
Beispiel #6
0
static void
data_generic_set_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver)
{
	TDS_SERVER_TYPE col_type = col->on_server.column_type;
	int col_size = col->on_server.column_size;

	switch (tds_get_conversion_type(col_type, col_size)) {
	case XSYBNCHAR:
		drec->sql_desc_concise_type = SQL_WCHAR;
		drec->sql_desc_display_size = col->on_server.column_size / 2;
		SET_INFO2("nchar", "'", "'", col->on_server.column_size / 2);

	case XSYBCHAR:
	case SYBCHAR:
		drec->sql_desc_concise_type = SQL_CHAR;
		drec->sql_desc_display_size = col->on_server.column_size;
		SET_INFO("char", "'", "'");

	/* TODO really sure ?? SYBNVARCHAR sybase only ?? */
	case SYBNVARCHAR:
	case XSYBNVARCHAR:
		drec->sql_desc_concise_type = SQL_WVARCHAR;
		drec->sql_desc_display_size = col->on_server.column_size / 2;
		drec->sql_desc_length = col->on_server.column_size / 2u;
		if (is_blob_col(col)) {
			drec->sql_desc_display_size = SQL_SS_LENGTH_UNLIMITED;
			drec->sql_desc_octet_length = drec->sql_desc_length =
				SQL_SS_LENGTH_UNLIMITED;
		}
		SET_INFO("nvarchar", "'", "'");

	case XSYBVARCHAR:
	case SYBVARCHAR:
		drec->sql_desc_concise_type = SQL_VARCHAR;
		drec->sql_desc_display_size = col->on_server.column_size;
		if (is_blob_col(col)) {
			drec->sql_desc_display_size = SQL_SS_LENGTH_UNLIMITED;
			drec->sql_desc_octet_length = drec->sql_desc_length =
				SQL_SS_LENGTH_UNLIMITED;
		}
		SET_INFO("varchar", "'", "'");

	case SYBNTEXT:
		drec->sql_desc_concise_type = SQL_WLONGVARCHAR;
		drec->sql_desc_display_size = col->on_server.column_size / 2;
		SET_INFO2("ntext", "'", "'", col->on_server.column_size / 2);

	case SYBTEXT:
		drec->sql_desc_concise_type = SQL_LONGVARCHAR;
		drec->sql_desc_display_size = col->on_server.column_size;
		SET_INFO("text", "'", "'");

	case SYBBIT:
	case SYBBITN:
		drec->sql_desc_concise_type = SQL_BIT;
		drec->sql_desc_display_size = 1;
		drec->sql_desc_unsigned = SQL_TRUE;
		SET_INFO2("bit", "", "", 1);

#if (ODBCVER >= 0x0300)
	case SYB5INT8:
	case SYBINT8:
		/* TODO return numeric for odbc2 and convert bigint to numeric */
		drec->sql_desc_concise_type = SQL_BIGINT;
		drec->sql_desc_display_size = 20;
		SET_INFO2("bigint", "", "", 19);
#endif

	case SYBINT4:
		drec->sql_desc_concise_type = SQL_INTEGER;
		drec->sql_desc_display_size = 11;	/* -1000000000 */
		SET_INFO2("int", "", "", 10);

	case SYBINT2:
		drec->sql_desc_concise_type = SQL_SMALLINT;
		drec->sql_desc_display_size = 6;	/* -10000 */
		SET_INFO2("smallint", "", "", 5);

	case SYBUINT1:
	case SYBINT1:
		drec->sql_desc_unsigned = SQL_TRUE;
	case SYBSINT1: /* TODO not another type_name ?? */
		drec->sql_desc_concise_type = SQL_TINYINT;
		drec->sql_desc_display_size = 3;	/* 255 */
		SET_INFO2("tinyint", "", "", 3);

#if (ODBCVER >= 0x0300)
	case SYBUINT8:
		drec->sql_desc_unsigned = SQL_TRUE;
		drec->sql_desc_concise_type = SQL_BIGINT;
		drec->sql_desc_display_size = 20;
		/* TODO return numeric for odbc2 and convert bigint to numeric */
		SET_INFO2("unsigned bigint", "", "", 20);
#endif

	case SYBUINT4:
		drec->sql_desc_unsigned = SQL_TRUE;
		drec->sql_desc_concise_type = SQL_INTEGER;
		drec->sql_desc_display_size = 10;
		SET_INFO2("unsigned int", "", "", 10);

	case SYBUINT2:
		drec->sql_desc_unsigned = SQL_TRUE;
		drec->sql_desc_concise_type = SQL_SMALLINT;
		drec->sql_desc_display_size = 5;	/* 65535 */
		SET_INFO2("unsigned smallint", "", "", 5);

	case SYBREAL:
		drec->sql_desc_concise_type = SQL_REAL;
		drec->sql_desc_display_size = 14;
		SET_INFO2("real", "", "", odbc_ver == SQL_OV_ODBC3 ? 24 : 7);

	case SYBFLT8:
		drec->sql_desc_concise_type = SQL_DOUBLE;
		drec->sql_desc_display_size = 24;	/* FIXME -- what should the correct size be? */
		SET_INFO2("float", "", "", odbc_ver == SQL_OV_ODBC3 ? 53 : 15);

	case SYBMONEY:
		/* TODO check money format returned by propretary ODBC, scale == 4 but we use 2 digits */
		drec->sql_desc_concise_type = SQL_DECIMAL;
		drec->sql_desc_octet_length = 21;
		drec->sql_desc_display_size = 21;
		drec->sql_desc_precision = 19;
		drec->sql_desc_scale     = 4;
		SET_INFO2("money", "$", "", 19);

	case SYBMONEY4:
		drec->sql_desc_concise_type = SQL_DECIMAL;
		drec->sql_desc_octet_length = 12;
		drec->sql_desc_display_size = 12;
		drec->sql_desc_precision = 10;
		drec->sql_desc_scale     = 4;
		SET_INFO2("money", "$", "", 10);

	case SYBDATETIME:
		drec->sql_desc_concise_type = SQL_TYPE_TIMESTAMP;
		drec->sql_desc_display_size = 23;
		drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
		drec->sql_desc_precision = 3;
		drec->sql_desc_scale     = 3;
		drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
		SET_INFO2("datetime", "'", "'", 23);

	case SYBDATETIME4:
		drec->sql_desc_concise_type = SQL_TYPE_TIMESTAMP;
		/* TODO dependent on precision (decimal second digits) */
		/* we always format using yyyy-mm-dd hh:mm:ss[.fff], see convert_tds2sql.c */
		drec->sql_desc_display_size = 19;
		drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
		drec->sql_desc_datetime_interval_code = SQL_CODE_TIMESTAMP;
		SET_INFO2("datetime", "'", "'", 16);

	/* The following two types are just Sybase types but as mainly our ODBC
	 * driver is much more compatible with Windows use attributes similar
	 * to MS one. For instance Sybase ODBC returns TIME into a TIME_STRUCT
	 * however this truncate the precision to 0 as TIME does not have
	 * fraction of seconds. Also Sybase ODBC have different concepts for
	 * PRECISION for many types and making these 2 types compatibles with
	 * Sybase would break this driver compatibility.
	 */
	case SYBTIME:
		drec->sql_desc_concise_type = SQL_SS_TIME2;
		drec->sql_desc_octet_length = sizeof(SQL_SS_TIME2_STRUCT);
		/* we always format using hh:mm:ss[.fff], see convert_tds2sql.c */
		drec->sql_desc_display_size = 12;
		drec->sql_desc_precision = 3;
		drec->sql_desc_scale     = 3;
		SET_INFO2("time", "'", "'", 12);

	case SYBDATE:
		drec->sql_desc_octet_length = sizeof(DATE_STRUCT);
		drec->sql_desc_concise_type = SQL_TYPE_DATE;
		/* we always format using yyyy-mm-dd, see convert_tds2sql.c */
		drec->sql_desc_display_size = 10;
		SET_INFO2("date", "'", "'", 10);

	case XSYBBINARY:
	case SYBBINARY:
		drec->sql_desc_concise_type = SQL_BINARY;
		drec->sql_desc_display_size = col->column_size * 2;
		/* handle TIMESTAMP using usertype */
		if (col->column_usertype == 80)
			SET_INFO("timestamp", "0x", "");
		SET_INFO("binary", "0x", "");

	case SYBLONGBINARY:
	case SYBIMAGE:
		drec->sql_desc_concise_type = SQL_LONGVARBINARY;
		drec->sql_desc_display_size = col->column_size * 2;
		SET_INFO("image", "0x", "");

	case XSYBVARBINARY:
	case SYBVARBINARY:
		drec->sql_desc_concise_type = SQL_VARBINARY;
		drec->sql_desc_display_size = col->column_size * 2;
		if (is_blob_col(col)) {
			drec->sql_desc_display_size = SQL_SS_LENGTH_UNLIMITED;
			drec->sql_desc_octet_length = drec->sql_desc_length =
				SQL_SS_LENGTH_UNLIMITED;
		}
		SET_INFO("varbinary", "0x", "");

	case SYBINTN:
	case SYBDATETIMN:
	case SYBFLTN:
	case SYBMONEYN:
	case SYBUINTN:
	case SYBTIMEN:
	case SYBDATEN:
		assert(0);

	case SYBVOID:
	case SYBINTERVAL:
	case SYBUNITEXT:
	case SYBXML:
	case SYBMSUDT:
		break;

#if (ODBCVER >= 0x0300)
	case SYBUNIQUE:
#ifdef SQL_GUID
		drec->sql_desc_concise_type = SQL_GUID;
#else
		drec->sql_desc_concise_type = SQL_CHAR;
#endif
		drec->sql_desc_display_size = 36;
		/* FIXME for Sybase ?? */
		SET_INFO2("uniqueidentifier", "'", "'", 36);
#endif

	case SYBMSXML:
		drec->sql_desc_concise_type = SQL_SS_XML;
		drec->sql_desc_display_size = SQL_SS_LENGTH_UNLIMITED;
		drec->sql_desc_octet_length = drec->sql_desc_length =
			SQL_SS_LENGTH_UNLIMITED;
		SET_INFO("xml", "'", "'");
	/* types already handled in other types, just to silent warnings */
	case SYBNUMERIC:
	case SYBDECIMAL:
	case SYBVARIANT:
	case SYBMSDATE:
	case SYBMSTIME:
	case SYBMSDATETIME2:
	case SYBMSDATETIMEOFFSET:
	case SYB5BIGDATETIME:
	case SYB5BIGTIME:
		break;
	}
	SET_INFO("", "", "");
}