odbcconvert.c

来自「这个是内存数据库的客户端」· C语言 代码 · 共 2,426 行 · 第 1/5 页

C
2,426
字号
				/* Numeric value out of range */				addStmtError(stmt, "22003", NULL, 0);				return SQL_ERROR;			}			*(unsigned char *) ptr = fval >= 1;			if (fval != 0 && fval != 1) {				/* Fractional truncation */				addStmtError(stmt, "01S07", NULL, 0);			}			break;		case SQL_DECIMAL:		case SQL_TINYINT:		case SQL_SMALLINT:		case SQL_INTEGER:		case SQL_BIGINT:		case SQL_BIT: {			int truncated = nval.scale > 0;			while (nval.scale > 0) {				nval.val /= 10;				nval.scale--;			}			/* -0 is ok, but -1 or -0.5 isn't */			if (nval.val > 1 || (!nval.sign && (nval.val == 1 || truncated))) {				/* Numeric value out of range */				addStmtError(stmt, "22003", NULL, 0);				return SQL_ERROR;			}			*(unsigned char *) ptr = (unsigned char) nval.val;			if (truncated) {				/* Fractional truncation */				addStmtError(stmt, "01S07", NULL, 0);			}			break;		}		default:			/* Restricted data type attribute violation */			addStmtError(stmt, "07006", NULL, 0);			return SQL_ERROR;		}		break;	case SQL_C_STINYINT:	case SQL_C_TINYINT:	case SQL_C_SSHORT:	case SQL_C_SHORT:	case SQL_C_SLONG:	case SQL_C_LONG:	case SQL_C_SBIGINT: {		SQLUBIGINT maxval = 1;		switch (type) {		case SQL_C_STINYINT:		case SQL_C_TINYINT:			maxval <<= 7;			if (lenp)				*lenp = sizeof(signed char);			if (ardrec && row > 0)				ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(signed char) : bind_type));			break;		case SQL_C_SSHORT:		case SQL_C_SHORT:			maxval <<= 15;			if (lenp)				*lenp = sizeof(short);			if (ardrec && row > 0)				ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(short) : bind_type));			break;		case SQL_C_SLONG:		case SQL_C_LONG:			maxval <<= 31;			if (lenp)				*lenp = sizeof(long);			if (ardrec && row > 0)				ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(long) : bind_type));			break;		case SQL_C_SBIGINT:			maxval <<= 63;			if (lenp)				*lenp = sizeof(SQLBIGINT);			if (ardrec && row > 0)				ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(SQLBIGINT) : bind_type));			break;		}		switch (sql_type) {		case SQL_CHAR:		case SQL_DOUBLE:		case SQL_REAL:			/* reparse double and float, parse char */			if (!parseint(data, &nval)) {				/* Invalid character value for cast				   specification */				addStmtError(stmt, "22018", NULL, 0);				return SQL_ERROR;			}			/* fall through */		case SQL_DECIMAL:		case SQL_TINYINT:		case SQL_SMALLINT:		case SQL_INTEGER:		case SQL_BIGINT:		case SQL_BIT: {			int truncated = nval.scale > 0;			/* scale is normalized, so if negative, number			   is too large even for SQLUBIGINT */			while (nval.scale > 0) {				nval.val /= 10;				nval.scale--;			}			if (nval.scale < 0 || nval.val > maxval || (nval.val == maxval && nval.sign)) {				/* Numeric value out of range */				addStmtError(stmt, "22003", NULL, 0);				return SQL_ERROR;			}			if (truncated) {				/* Fractional truncation */				addStmtError(stmt, "01S07", NULL, 0);			}			switch (type) {			case SQL_C_STINYINT:			case SQL_C_TINYINT:				*(signed char *) ptr = nval.sign ? (signed char) nval.val : -(signed char) nval.val;				break;			case SQL_C_SSHORT:			case SQL_C_SHORT:				*(short *) ptr = nval.sign ? (short) nval.val : -(short) nval.val;				break;			case SQL_C_SLONG:			case SQL_C_LONG:				*(long *) ptr = nval.sign ? (long) nval.val : -(long) nval.val;				break;			case SQL_C_SBIGINT:				*(SQLBIGINT *) ptr = nval.sign ? (SQLBIGINT) nval.val : -(SQLBIGINT) nval.val;				break;			}			break;		}		default:			/* Restricted data type attribute violation */			addStmtError(stmt, "07006", NULL, 0);			return SQL_ERROR;		}		break;	}	case SQL_C_UTINYINT:	case SQL_C_USHORT:	case SQL_C_ULONG:	case SQL_C_UBIGINT: {		SQLUBIGINT maxval = 1;		switch (type) {		case SQL_C_UTINYINT:			maxval <<= 8;			if (lenp)				*lenp = sizeof(unsigned char);			if (ardrec && row > 0)				ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(unsigned char) : bind_type));			break;		case SQL_C_USHORT:			maxval <<= 16;			if (lenp)				*lenp = sizeof(unsigned short);			if (ardrec && row > 0)				ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(unsigned short) : bind_type));			break;		case SQL_C_ULONG:			maxval <<= 32;			if (lenp)				*lenp = sizeof(unsigned long);			if (ardrec && row > 0)				ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(unsigned long) : bind_type));			break;		case SQL_C_UBIGINT:			if (lenp)				*lenp = sizeof(SQLUBIGINT);			if (ardrec && row > 0)				ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(SQLUBIGINT) : bind_type));			break;		}		maxval--;		switch (sql_type) {		case SQL_CHAR:		case SQL_DOUBLE:		case SQL_REAL:			/* reparse double and float, parse char */			if (!parseint(data, &nval)) {				/* Invalid character value for cast				   specification */				addStmtError(stmt, "22018", NULL, 0);				return SQL_ERROR;			}			/* fall through */		case SQL_DECIMAL:		case SQL_TINYINT:		case SQL_SMALLINT:		case SQL_INTEGER:		case SQL_BIGINT:		case SQL_BIT: {			int truncated = nval.scale > 0;			/* scale is normalized, so if negative, number			   is too large even for SQLUBIGINT */			while (nval.scale > 0) {				nval.val /= 10;				nval.scale--;			}			if (nval.scale < 0 || !nval.sign || (maxval != 0 && nval.val >= maxval)) {				/* Numeric value out of range */				addStmtError(stmt, "22003", NULL, 0);				return SQL_ERROR;			}			if (truncated) {				/* Fractional truncation */				addStmtError(stmt, "01S07", NULL, 0);			}			switch (type) {			case SQL_C_UTINYINT:				*(unsigned char *) ptr = (unsigned char) nval.val;				break;			case SQL_C_USHORT:				*(unsigned short *) ptr = (unsigned short) nval.val;				break;			case SQL_C_ULONG:				*(unsigned long *) ptr = (unsigned long) nval.val;				break;			case SQL_C_UBIGINT:				*(SQLUBIGINT *) ptr = (SQLUBIGINT) nval.val;				break;			}			break;		}		default:			/* Restricted data type attribute violation */			addStmtError(stmt, "07006", NULL, 0);			return SQL_ERROR;		}		break;	}	case SQL_C_NUMERIC:		if (ardrec && row > 0)			ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(SQL_NUMERIC_STRUCT) : bind_type));		switch (sql_type) {		case SQL_CHAR:		case SQL_DOUBLE:		case SQL_REAL:			/* reparse double and float, parse char */			if (!(i = parseint(data, &nval))) {				/* Invalid character value for cast				   specification */				addStmtError(stmt, "22018", NULL, 0);				return SQL_ERROR;			}			if (i == 2) {				/* Fractional truncation */				addStmtError(stmt, "01S07", NULL, 0);			}			/* fall through */		case SQL_DECIMAL:		case SQL_TINYINT:		case SQL_SMALLINT:		case SQL_INTEGER:		case SQL_BIGINT:		case SQL_BIT:			while (nval.precision > precision) {				nval.val /= 10;				nval.scale--;				nval.precision--;			}			while (nval.scale < scale) {				nval.val *= 10;				nval.scale++;			}			while (nval.scale > scale) {				nval.val /= 10;				nval.scale--;				nval.precision--;			}			((SQL_NUMERIC_STRUCT *) ptr)->precision = nval.precision;			((SQL_NUMERIC_STRUCT *) ptr)->scale = nval.scale;			((SQL_NUMERIC_STRUCT *) ptr)->sign = nval.sign;			for (i = 0; i < SQL_MAX_NUMERIC_LEN; i++) {				((SQL_NUMERIC_STRUCT *) ptr)->val[i] = (SQLCHAR) (nval.val & 0xFF);				nval.val >>= 8;			}			break;		default:			/* Restricted data type attribute violation */			addStmtError(stmt, "07006", NULL, 0);			return SQL_ERROR;		}		if (lenp)			*lenp = sizeof(SQL_NUMERIC_STRUCT);		break;	case SQL_C_FLOAT:	case SQL_C_DOUBLE:		switch (sql_type) {		case SQL_CHAR:			if (!parsedouble(data, &fval)) {				/* Invalid character value for cast				   specification */				addStmtError(stmt, "22018", NULL, 0);				return SQL_ERROR;			}			break;		case SQL_DOUBLE:		case SQL_REAL:			break;		case SQL_DECIMAL:		case SQL_TINYINT:		case SQL_SMALLINT:		case SQL_INTEGER:		case SQL_BIGINT:		case SQL_BIT:			fval = (double) (SQLBIGINT) nval.val;			i = 1;			while (nval.scale > 0) {				nval.scale--;				i *= 10;			}			fval /= (double) i;			i = 1;			while (nval.scale < 0) {				nval.scale++;				i *= 10;			}			fval *= (double) i;			if (!nval.sign)				fval = -fval;			break;		default:			/* Restricted data type attribute violation */			addStmtError(stmt, "07006", NULL, 0);			return SQL_ERROR;		}		if (type == SQL_C_FLOAT) {			if (ardrec && row > 0)				ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(float) : bind_type));			*(float *) ptr = (float) fval;			if ((double) *(float *) ptr !=fval) {				/* Numeric value out of range */				addStmtError(stmt, "22003", NULL, 0);				return SQL_ERROR;			}			if (lenp)				*lenp = sizeof(float);		} else {			if (ardrec && row > 0)				ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(double) : bind_type));			*(double *) ptr = fval;			if (lenp)				*lenp = sizeof(double);		}		break;	case SQL_C_TYPE_DATE:		if (ardrec && row > 0)			ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(DATE_STRUCT) : bind_type));		i = 1;		switch (sql_type) {		case SQL_CHAR:			i = parsetimestamp(data, &tsval);			/* fall through */		case SQL_TYPE_TIMESTAMP:	/* note i==1 unless we fell through */			if (i) {				if (tsval.hour || tsval.minute || tsval.second || tsval.fraction || i == 2) {					/* Fractional truncation */					addStmtError(stmt, "01S07", NULL, 0);				}				dval.year = tsval.year;				dval.month = tsval.month;				dval.day = tsval.day;			} else if (!parsedate(data, &dval)) {				/* Invalid character value for cast				   specification */				addStmtError(stmt, "22018", NULL, 0);				return SQL_ERROR;			}			/* fall through */		case SQL_TYPE_DATE:			*(DATE_STRUCT *) ptr = dval;			break;		default:			/* Restricted data type attribute violation */			addStmtError(stmt, "07006", NULL, 0);			return SQL_ERROR;		}		if (lenp)			*lenp = sizeof(DATE_STRUCT);		break;	case SQL_C_TYPE_TIME:		if (ardrec && row > 0)			ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(TIME_STRUCT) : bind_type));		i = 1;		switch (sql_type) {		case SQL_CHAR:			i = parsetimestamp(data, &tsval);			/* fall through */		case SQL_TYPE_TIMESTAMP:	/* note i==1 unless we fell through */			if (i) {				if (tsval.fraction || i == 2) {					/* Fractional truncation */					addStmtError(stmt, "01S07", NULL, 0);				}				tval.hour = tsval.hour;				tval.minute = tsval.minute;				tval.second = tsval.second;			} else if (!parsetime(data, &tval)) {				/* Invalid character value for cast				   specification */				addStmtError(stmt, "22018", NULL, 0);				return SQL_ERROR;			}			/* fall through */		case SQL_TYPE_TIME:			*(TIME_STRUCT *) ptr = tval;			break;		default:			/* Restricted data type attribute violation */			addStmtError(stmt, "07006", NULL, 0);			return SQL_ERROR;		}		if (lenp)			*lenp = sizeof(TIME_STRUCT);		break;	case SQL_C_TYPE_TIMESTAMP:		if (ardrec && row > 0)			ptr = (SQLPOINTER) ((char *) ptr +row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(TIMESTAMP_STRUCT) : bind_type));		i = 1;		switch (sql_type) {		case SQL_CHAR:			i = parsetimestamp(data, &tsval);			if (i == 0) {				i = parsetime(data, &tval);				if (i) {					struct tm tm;					time_t t;		case SQL_TYPE_TIME:					(void) time(&t);#ifdef HAVE_LOCALTIME_R					(void) localtime_r(&t, &tm);#else					tm = *localtime(&t);#endif					tsval.year = tm.tm_year + 1900;					tsval.month = tm.tm_mon + 1;					tsval.day = tm.tm_mday;					tsval.hour = tval.hour;					tsval.minute = tval.minute;					tsval.second = tval.second;					tsval.fraction = 0;				} else {					i = parsedate(data, &dval);					if (i) {		case SQL_TYPE_DATE:						tsval.year = dval.year;						tsval.month = dval.month;						tsval.day = dval.day;						tsval.hour = 0;						tsval.minute = 0;						tsval.second = 0;						tsval.fraction = 0;					} else {						/* Invalid character						   value for cast						   specification */						addStmtError(stmt, "22018", NULL, 0);						return SQL_ERROR;					}				}			}			/* fall through */		case SQL_TYPE_TIMESTAMP:	/* note i==1 unless we fell through */			*(TIMESTAMP_STRUCT *) ptr = tsval;			break;		default:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?