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 + -
显示快捷键?