Repository: trafodion Updated Branches: refs/heads/master beb54ad49 -> f04ffee5a
add div operation to map file Project: http://git-wip-us.apache.org/repos/asf/trafodion/repo Commit: http://git-wip-us.apache.org/repos/asf/trafodion/commit/5161f7bf Tree: http://git-wip-us.apache.org/repos/asf/trafodion/tree/5161f7bf Diff: http://git-wip-us.apache.org/repos/asf/trafodion/diff/5161f7bf Branch: refs/heads/master Commit: 5161f7bf2059912ede0617ea2f81178a2f18168a Parents: b4749fc Author: SuJinpei <[email protected]> Authored: Tue Jul 31 15:12:49 2018 +0800 Committer: SuJinpei <[email protected]> Committed: Wed Nov 14 18:40:02 2018 +0800 ---------------------------------------------------------------------- core/conn/odb/src/odb.c | 94 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafodion/blob/5161f7bf/core/conn/odb/src/odb.c ---------------------------------------------------------------------- diff --git a/core/conn/odb/src/odb.c b/core/conn/odb/src/odb.c index 053fad7..d008d82 100755 --- a/core/conn/odb/src/odb.c +++ b/core/conn/odb/src/odb.c @@ -746,6 +746,7 @@ unsigned long tspdiff ( struct timespec *start, struct timespec *end ) ; #endif static int ucs2toutf8 ( SQLCHAR *str, SQLLEN *len, SQLULEN bs, int bu2 ) ; static void addGlobalPointer(void *ptr); +static int is_valid_numeric(const char* str, size_t n); int main(int ac, char *av[]) { @@ -6246,7 +6247,8 @@ static void Oload(int eid) trt[16]; /* translit to array */ char op; /* 1=substr, 2=dconv, 3=tconv, 4=tsconv, 5=replace, 6=toupper, 7=tolower, 8=firstup, 9=csubstr, 10=translit, - 11=comp, 12=comp3, 13=zoned, 14=emptyasconst, 15=emptyasempty */ + 11=comp, 12=comp3, 13=zoned, 14=emptyasconst, 15=emptyasempty, + 16=div */ char **el; /* dataset element array pointer */ unsigned int prec; /* COMP3/ZONED Precision */ unsigned int scale; /* COMP3/ZONED Scale */ @@ -6969,7 +6971,16 @@ static void Oload(int eid) map[j].op = 14; } else if ( !strmicmp ( "emptyasempty", bp, 11 ) ) { map[j].op = 15; - } else { + } else if (!strmicmp("div", bp, 3)) { + map[j].op = 16; + while (*bp && *bp++ != ':'); + map[j].scale = strtol(bp, NULL, 10); + if (map[j].scale == 0) { + fprintf(stderr, "odb [Oload(%d)] - DIV error for %s\n", __LINE__, (char *)etab[eid].td[j].Oname); + goto oload_exit; + } + } + else { map[j].op = 0; } } @@ -7513,6 +7524,24 @@ static void Oload(int eid) if ( ifl == 0 ) ifl = EMPTY ; break; + case 16: + { + if (ifl > 0) { + double dv = 0; + char tformat[64]; + sprintf(tformat, "%%.%dlf", etab[eid].td[rmap[k]].Odec); + + str[ifl] = '\0'; + if (!(is_valid_numeric(str, strlen(str)) && sscanf(str, "%lf", &dv))) { + fprintf(stderr, "odb [Oload(%d)] - DIV field conversion error: row %d col %d. " + "%s is not valid numeric, This row won't be loaded\n", __LINE__, n + 1, k + 1, str); + mi = 0; /* SKIP THIS ROW */ + } + dv = dv / map[rmap[k]].scale; + ifl = sprintf(str, tformat, dv); + } + } + break; } if ( ifl > (int)etab[eid].td[rmap[k]].Osize ) { /* prevent Orowsetl[] overflow */ str[ifl]='\0'; @@ -7534,7 +7563,8 @@ static void Oload(int eid) default: if ( !etab[eid].fldtr ) fprintf ( stderr, "odb [Oload(%d)] - Error: row %d col %d field truncation. Input " - "string: >%s< of length %d. This row won't be loaded\n", __LINE__, n+1, k+1, str, ifl); + "string: >%s< of length %d exceeds %lu. This row won't be loaded\n", __LINE__, + n+1, k+1, str, ifl, (long unsigned)etab[eid].td[rmap[k]].Osize ); mi = 0; /* SKIP THIS ROW */ break; } @@ -9434,10 +9464,10 @@ static void OloadJson(int eid) } /* alocate valuebuf */ - if ((valuebuf = calloc(1, etab[eid].buffsz + 1)) == (void *)NULL) { - fprintf(stderr, "odb [OloadJson(%d)] - Error allocating field buffer: [%d] %s\n", - __LINE__, errno, strerror(errno)); - goto oloadJson_exit; + if ((valuebuf = calloc(1, etab[eid].buffsz + 1)) == (void *)NULL) { + fprintf(stderr, "odb [OloadJson(%d)] - Error allocating field buffer: [%d] %s\n", + __LINE__, errno, strerror(errno)); + goto oloadJson_exit; } /* Open input file */ @@ -14685,6 +14715,56 @@ static void addGlobalPointer(void *ptr) globalPointers[nGlobalPointers++] = ptr; } +/* is_valid_numeric: +* check if the string is valid numeric +* +* Input: str: string to be validate. +* Input: n: length of str +* +* return: if str is valid numeric return 1 else return 0 +*/ +static int is_valid_numeric(const char* str, size_t n) { + int s = 1; + for (size_t i = 0; i < n; ++i) { + switch (s) { + case 1: + if (str[i] == '+' || str[i] == '-') s = 2; + else if (isdigit(str[i])) s = 3; + else return 0; + break; + case 2: + if (!isdigit(str[i])) return 0; + s = 3; + break; + case 3: + if (str[i] == '.') s = 4; + else if (str[i] == 'e') s = 6; + else if (!isdigit(str[i])) return 0; + break; + case 4: + if (!isdigit(str[i])) return 0; + s = 5; + break; + case 5: + if (str[i] == 'e') s = 6; + else if (!isdigit(str[i])) return 0; + break; + case 6: + if (str[i] == '+' || str[i] == '-') s = 7; + else if (isdigit(str[i])) s = 7; + else return 0; + break; + case 7: + if (!isdigit(str[i])) return 0; + break; + default: + return 0; + } + } + if (s == 3 || s == 7 || s == 5) return 1; + return 0; +} + /* usagexit: * print usage message and exit *
