odbcconvert.c

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

C
2,426
字号
		return SQL_ERROR;	slen--;	sval++;	*svalp = sval;	*slenp = slen;	return SQL_SUCCESS;}	static SQLRETURNparsemonthintervalstring(char **svalp, SQLINTEGER *slenp, SQL_INTERVAL_STRUCT *ival){	char *sval = *svalp;	int slen = slenp ? *slenp : (int) strlen(sval);	char *eptr;	long val1 = -1, val2 = -1;	int leadingprecision;	if (slen < 8 || strncasecmp(sval, "interval", 8) != 0)		return SQL_ERROR;	sval += 8;	slen -= 8;	if (slen == 0 || !isspace((int) *sval))		return SQL_ERROR;	while (slen > 0 && isspace((int) *sval)) {		slen--;		sval++;	}	if (slen > 0 && *sval == '-') {		slen--;		sval++;		ival->interval_sign = SQL_TRUE;	} else		ival->interval_sign = SQL_FALSE;	if (slen == 0 || *sval != '\'')		return SQL_ERROR;	slen--;	sval++;	/* make sure there is another quote in the string: this makes	   the calls to strtol safe */	for (eptr = sval, leadingprecision = slen;	     leadingprecision > 0 && *eptr != '\'';	     leadingprecision--, eptr++)		;	if (leadingprecision == 0)		return SQL_ERROR;	if (*sval == '+' || *sval == '-')		return SQL_ERROR;	val1 = strtol(sval, &eptr, 10);	if (eptr == sval)		return SQL_ERROR;	leadingprecision = (int) (eptr - sval);	slen -= leadingprecision;	sval = eptr;	while (isspace((int) *sval)) {		slen--;		sval++;	}	if (*sval == '-') {		slen--;		sval++;		while (isspace((int) *sval)) {			slen--;			sval++;		}		if (*sval == '+' || *sval == '-')			return SQL_ERROR;		val2 = strtol(sval, &eptr, 10);		if (eptr == sval)			return SQL_ERROR;		if (eptr - sval > 2)			return SQL_ERROR;		slen -= (int) (eptr - sval);		sval = eptr;		while (isspace((int) *sval)) {			slen--;			sval++;		}		ival->interval_type = SQL_IS_YEAR_TO_MONTH;		ival->intval.year_month.year = val1;		ival->intval.year_month.month = val2;		if (val2 >= 12)			return SQL_ERROR;	}	if (*sval != '\'')		return SQL_ERROR;	slen--;	sval++;	if (slen == 0 || !isspace((int) *sval))		return SQL_ERROR;	while (slen > 0 && isspace((int) *sval)) {		slen--;		sval++;	}	if (slen >= 4 && strncasecmp(sval, "year", 4) == 0) {		int p = 2;		slen -= 4;		sval += 4;		if (parseoptionalbracketednumber(&sval, &slen, &p, NULL) == SQL_ERROR)			return SQL_ERROR;		if (leadingprecision > p)			return SQL_ERROR;		if (val2 == -1) {			ival->interval_type = SQL_IS_YEAR;			ival->intval.year_month.year = val1;			ival->intval.year_month.month = 0;		}		if (slen > 0 && isspace((int) *sval)) {			while (slen > 0 && isspace((int) *sval)) {				slen--;				sval++;			}			if (slen > 2 && strncasecmp(sval, "to", 2) == 0) {				slen -= 2;				sval += 2;				if (val2 == -1)					return SQL_ERROR;				if (slen == 0 || !isspace((int) *sval))					return SQL_ERROR;				while (slen > 0 && isspace((int) *sval)) {					slen--;					sval++;				}				if (slen >= 5 && strncasecmp(sval, "month", 5) == 0) {					slen -= 5;					sval += 5;					while (slen > 0 && isspace((int) *sval)) {						slen--;						sval++;					}				} else					return SQL_ERROR;			}		}		if (slen > 0)			return SQL_ERROR;	} else if (slen >= 5 && strncasecmp(sval, "month", 5) == 0) {		int p = 2;		slen -= 5;		sval += 5;		if (parseoptionalbracketednumber(&sval, &slen, &p, NULL) == SQL_ERROR)			return SQL_ERROR;		if (leadingprecision > p)			return SQL_ERROR;		while (slen > 0 && isspace((int) *sval)) {			slen--;			sval++;		}		if (slen != 0)			return SQL_ERROR;		ival->interval_type = SQL_IS_MONTH;		ival->intval.year_month.year = val1 / 12;		ival->intval.year_month.month = val1 % 12;	} else		return SQL_ERROR;	return SQL_SUCCESS;}static SQLRETURNparsesecondintervalstring(char **svalp, SQLINTEGER *slenp, SQL_INTERVAL_STRUCT *ival, int *secprecp){	char *sval = *svalp;	int slen = slenp ? *slenp : (int) strlen(sval);	char *eptr;	int leadingprecision;	int secondprecision = 0;	unsigned v1, v2, v3, v4;	int n;	if (slen < 8 || strncasecmp(sval, "interval", 8) != 0)		return SQL_ERROR;	sval += 8;	slen -= 8;	if (slen == 0 || !isspace((int) *sval))		return SQL_ERROR;	while (slen > 0 && isspace((int) *sval)) {		slen--;		sval++;	}	if (slen > 0 && *sval == '-') {		slen--;		sval++;		ival->interval_sign = SQL_TRUE;	} else		ival->interval_sign = SQL_FALSE;	if (slen == 0 || *sval != '\'')		return SQL_ERROR;	slen--;	sval++;	/* make sure there is another quote in the string: this makes	   the calls to sscanf safe */	for (eptr = sval, leadingprecision = slen;	     leadingprecision > 0 && *eptr != '\'';	     leadingprecision--, eptr++)		;	if (leadingprecision == 0)		return SQL_ERROR;	if (*sval == '+' || *sval == '-')		return SQL_ERROR;	(void) strtol(sval, &eptr, 10);	/* we parse the actual value again later */	if (eptr == sval)		return SQL_ERROR;	leadingprecision = (int) (eptr - sval);	ival->interval_type = (SQLINTERVAL)0; /* unknown as yet */	ival->intval.day_second.day = 0;	ival->intval.day_second.hour = 0;	ival->intval.day_second.minute = 0;	ival->intval.day_second.second = 0;	ival->intval.day_second.fraction = 0;	if (sscanf(sval, "%u %2u:%2u:%2u%n", &v1, &v2, &v3, &v4, &n) >= 4) {		ival->interval_type = SQL_IS_DAY_TO_SECOND;		if (v2 >= 24 || v3 >= 60 || v4 >= 60)			return SQL_ERROR;		ival->intval.day_second.day = v1;		ival->intval.day_second.hour = v2;		ival->intval.day_second.minute = v3;		ival->intval.day_second.second = v4;		sval += n;		slen -= n;	} else if (sscanf(sval, "%u %2u:%2u%n", &v1, &v2, &v3, &n) >= 3) {		ival->interval_type = SQL_IS_DAY_TO_MINUTE;		if (v2 >= 24 || v3 >= 60)			return SQL_ERROR;		ival->intval.day_second.day = v1;		ival->intval.day_second.hour = v2;		ival->intval.day_second.minute = v3;		sval += n;		slen -= n;	} else if (sscanf(sval, "%u %2u%n", &v1, &v2, &n) >= 2) {		ival->interval_type = SQL_IS_DAY_TO_HOUR;		if (v2 >= 60)			return SQL_ERROR;		ival->intval.day_second.day = v1;		ival->intval.day_second.hour = v2;		sval += n;		slen -= n;	} else if (sscanf(sval, "%u:%2u:%2u%n", &v1, &v2, &v3, &n) >= 3) {		ival->interval_type = SQL_IS_HOUR_TO_SECOND;		if (v2 >= 60 || v3 >= 60)			return SQL_ERROR;		ival->intval.day_second.day = v1 / 24;		ival->intval.day_second.hour = v1 % 24;		ival->intval.day_second.minute = v2;		ival->intval.day_second.second = v3;		sval += n;		slen -= n;	} else if (sscanf(sval, "%u:%2u%n", &v1, &v2, &n) >= 2) {		sval += n;		slen -= n;		if (*sval == '.') {			ival->interval_type = SQL_IS_MINUTE_TO_SECOND;			if (v2 >= 60)				return SQL_ERROR;			ival->intval.day_second.day = v1 / (24 * 60);			ival->intval.day_second.hour = (v1 / 60) % 24;			ival->intval.day_second.minute = v1 % 60;			ival->intval.day_second.second = v2;		}		n = 2;	/* two valid values */	} else if (sscanf(sval, "%u%n", &v1, &n) >= 1) {		sval += n;		slen -= n;		if (*sval == '.') {			ival->interval_type = SQL_IS_SECOND;			ival->intval.day_second.day = v1 / (24 * 60 * 60);			ival->intval.day_second.hour = (v1 / (60 * 60)) % 24;			ival->intval.day_second.minute = (v1 / 60) % 60;			ival->intval.day_second.second = v1 % 60;		}		n = 1;	/* one valid value */	}	if (*sval == '.') {		if (ival->interval_type != SQL_IS_SECOND &&		    ival->interval_type != SQL_IS_MINUTE_TO_SECOND &&		    ival->interval_type != SQL_IS_HOUR_TO_SECOND &&		    ival->interval_type != SQL_IS_DAY_TO_SECOND)			return SQL_ERROR;		sval++;		slen--;		secondprecision = 0;		while ('0' <= *sval && *sval <= '9') {			if (secondprecision < 9) {				secondprecision++;				ival->intval.day_second.fraction *= 10;				ival->intval.day_second.fraction += *sval - '0';			}			sval++;			slen--;		}	}	while (slen > 0 && isspace((int) *sval)) {		slen--;		sval++;	}	if (*sval != '\'')		return SQL_ERROR;	slen--;	sval++;	if (slen == 0 || !isspace((int) *sval))		return SQL_ERROR;	while (slen > 0 && isspace((int) *sval)) {		slen--;		sval++;	}	if (slen >= 3 && strncasecmp(sval, "day", 3) == 0) {		sval += 3;		slen -= 3;		if (ival->interval_type == 0 && n == 1) {			ival->interval_type = SQL_IS_DAY;			ival->intval.day_second.day = v1;		}		if (ival->interval_type != SQL_IS_DAY &&		    ival->interval_type != SQL_IS_DAY_TO_HOUR &&		    ival->interval_type != SQL_IS_DAY_TO_MINUTE &&		    ival->interval_type != SQL_IS_DAY_TO_SECOND)			return SQL_ERROR;	} else if (slen >= 4 && strncasecmp(sval, "hour", 4) == 0) {		slen -= 4;		sval += 4;		if (ival->interval_type == 0) {			if (n == 1) {				ival->interval_type = SQL_IS_HOUR;				ival->intval.day_second.day = v1 / 24;				ival->intval.day_second.hour = v1 % 24;			} else {				assert(n == 2);				ival->interval_type = SQL_IS_HOUR_TO_MINUTE;				if (v2 >= 60)					return SQL_ERROR;				ival->intval.day_second.day = v1 / 24;				ival->intval.day_second.hour = v1 % 24;				ival->intval.day_second.minute = v2;			}		}		if (ival->interval_type != SQL_IS_HOUR &&		    ival->interval_type != SQL_IS_HOUR_TO_MINUTE &&		    ival->interval_type != SQL_IS_HOUR_TO_SECOND)			return SQL_ERROR;	} else if (slen >= 6 && strncasecmp(sval, "minute", 6) == 0) {		slen -= 6;		sval += 6;		if (ival->interval_type == 0) {			if (n == 1) {				ival->interval_type = SQL_IS_MINUTE;				ival->intval.day_second.day = v1 / (24 * 60);				ival->intval.day_second.hour = (v1 / 60) % 24;				ival->intval.day_second.minute = v1 % 60;			} else {				assert(n == 2);				ival->interval_type = SQL_IS_MINUTE_TO_SECOND;				if (v2 >= 60)					return SQL_ERROR;				ival->intval.day_second.day = v1 / (24 * 60);				ival->intval.day_second.hour = (v1 / 60) % 24;				ival->intval.day_second.minute = v1 % 60;				ival->intval.day_second.second = v2;			}		}		if (ival->interval_type != SQL_IS_MINUTE &&		    ival->interval_type != SQL_IS_MINUTE_TO_SECOND)			return SQL_ERROR;	} else if (slen >= 6 && strncasecmp(sval, "second", 6) == 0) {		slen -= 6;		sval += 6;		if (ival->interval_type == 0) {			if (n == 1) {				ival->interval_type = SQL_IS_SECOND;				ival->intval.day_second.day = v1 / (24 * 60 * 60);				ival->intval.day_second.hour = (v1 / (60 * 60)) % 24;				ival->intval.day_second.minute = (v1 / 60) % 60;				ival->intval.day_second.second = v1 % 60;			}		}		if (ival->interval_type != SQL_IS_SECOND)			return SQL_ERROR;	}	{		int p = 2;		int q = 6;		if (parseoptionalbracketednumber(&sval, &slen, &p, ival->interval_type == SQL_IS_SECOND ? &q : NULL) == SQL_ERROR)			return SQL_ERROR;		if (leadingprecision > p)			return SQL_ERROR;		if (ival->interval_type == SQL_IS_SECOND && secondprecision > q)			return SQL_ERROR;	}	if (slen > 0 && isspace((int) *sval)) {		while (slen > 0 && isspace((int) *sval)) {			slen--;			sval++;		}		if (slen > 2 && strncasecmp(sval, "to", 2) == 0) {			slen -= 2;			sval += 2;			if (slen == 0 || !isspace((int) *sval))				return SQL_ERROR;			while (slen > 0 && isspace((int) *sval)) {				slen--;				sval++;			}			if (slen >= 4 && strncasecmp(sval, "hour", 4) == 0) {				slen -= 4;				sval += 4;				if (ival->interval_type != SQL_IS_DAY_TO_HOUR)					return SQL_ERROR;			} else if (slen >= 6 && strncasecmp(sval, "minute", 6) == 0) {				slen -= 6;				sval += 6;				if (ival->interval_type != SQL_IS_DAY_TO_MINUTE &&				    ival->interval_type != SQL_IS_HOUR_TO_MINUTE)					return SQL_ERROR;			} else if (slen >= 6 && strncasecmp(sval, "second", 6) == 0) {				int p = 6;				slen -= 6;				sval += 6;				if (ival->interval_type != SQL_IS_DAY_TO_SECOND &&				    ival->interval_type != SQL_IS_HOUR_TO_SECOND &&				    ival->interval_type != SQL_IS_MINUTE_TO_SECOND)					return SQL_ERROR;				while (slen > 0 && isspace((int) *sval)) {					slen--;					sval++;				}				if (parseoptionalbracketednumber(&sval, &slen, &p, NULL) == SQL_ERROR)					return SQL_ERROR;				if (p < secondprecision)					return SQL_ERROR;			} else				return SQL_ERROR;			while (slen > 0 && isspace((int) *sval)) {				slen--;				sval++;			}		}	}	if (slen > 0)		return SQL_ERROR;	*secprecp = secondprecision;	return SQL_SUCCESS;}SQLRETURNODBCFetch(ODBCStmt *stmt, SQLUSMALLINT col, SQLSMALLINT type, SQLPOINTER ptr,	  SQLINTEGER buflen, SQLINTEGER *lenp, SQLINTEGER *nullp,	  SQLSMALLINT precision, SQLSMALLINT scale,	  SQLINTEGER datetime_interval_precision, SQLINTEGER offset, int row){	char *data;	SQLSMALLINT sql_type;	SQLUINTEGER maxdatetimeval;	ODBCDesc *ard, *ird;	ODBCDescRec *irdrec, *ardrec;	SQLUINTEGER bind_type;	/* various interpretations of the input data */	bignum_t nval;	SQL_INTERVAL_STRUCT ival;	int ivalprec = 0;	/* interval second precision */	int i;	DATE_STRUCT dval;	TIME_STRUCT tval;	TIMESTAMP_STRUCT tsval;	double fval = 0;	ird = stmt->ImplRowDescr;	ard = stmt->ApplRowDescr;	if (col == 0 || col > ird->sql_desc_count) {		/* Invalid descriptor index */		addStmtError(stmt, "07009", NULL, 0);		return SQL_ERROR;	}	bind_type = ard->sql_desc_bind_type;	irdrec = &ird->descRec[col];	ardrec = col <= ard->sql_desc_count ? &ard->descRec[col] : NULL;	sql_type = irdrec->sql_desc_concise_type;	if (ptr && offset)		ptr = (SQLPOINTER) ((char *) ptr + offset + row * (bind_type == SQL_BIND_BY_COLUMN ? sizeof(SQLPOINTER) : bind_type));

⌨️ 快捷键说明

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