📄 ecpglib.c
字号:
tobeinserted = buff; break; case ECPGt_bool: sprintf(buff, "'%c'", (*(char *) var->value ? 't' : 'f')); tobeinserted = buff; break; case ECPGt_char: case ECPGt_unsigned_char: { /* set slen to string length if type is char * */ int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : var->varcharsize; char *tmp; if (!(newcopy = ecpg_alloc(slen + 1, stmt->lineno))) return false; strncpy(newcopy, (char *) var->value, slen); newcopy[slen] = '\0'; if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno))) return false; strcpy(mallocedval, "'"); tmp = quote_postgres(newcopy, stmt->lineno); if (!tmp) return false; strcat(mallocedval, tmp); strcat(mallocedval, "'"); free(newcopy); tobeinserted = mallocedval; } break; case ECPGt_char_variable: { int slen = strlen((char *) var->value); char *tmp; if (!(newcopy = ecpg_alloc(slen + 1, stmt->lineno))) return false; strncpy(newcopy, (char *) var->value, slen); newcopy[slen] = '\0'; tobeinserted = newcopy; } break; case ECPGt_varchar: { struct ECPGgeneric_varchar *variable = (struct ECPGgeneric_varchar *) (var->value); char *tmp; if (!(newcopy = (char *) ecpg_alloc(variable->len + 1, stmt->lineno))) return false; strncpy(newcopy, variable->arr, variable->len); newcopy[variable->len] = '\0'; if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno))) return false; strcpy(mallocedval, "'"); tmp = quote_postgres(newcopy, stmt->lineno); if (!tmp) return false; strcat(mallocedval, tmp); strcat(mallocedval, "'"); free(newcopy); tobeinserted = mallocedval; } break; default: /* Not implemented yet */ register_error(ECPG_UNSUPPORTED, "Unsupported type %s on line %d.", ECPGtype_name(var->type), stmt->lineno); return false; break; } } else tobeinserted = buff; /* * Now tobeinserted points to an area that is to be inserted at * the first %s */ if (!(newcopy = (char *) ecpg_alloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno))) return false; strcpy(newcopy, copiedquery); if ((p = next_insert(newcopy)) == NULL) { /* * We have an argument but we dont have the matched up string * in the string */ register_error(ECPG_TOO_MANY_ARGUMENTS, "Too many arguments line %d.", stmt->lineno); return false; } else { strcpy(p, tobeinserted); /* * The strange thing in the second argument is the rest of the * string from the old string */ strcat(newcopy, copiedquery + (p - newcopy) + sizeof("?") - 1 /* don't count the '\0' */ ); } /* * Now everything is safely copied to the newcopy. Lets free the * oldcopy and let the copiedquery get the var->value from the * newcopy. */ if (mallocedval != NULL) { free(mallocedval); mallocedval = NULL; } free(copiedquery); copiedquery = newcopy; var = var->next; } /* Check if there are unmatched things left. */ if (next_insert(copiedquery) != NULL) { register_error(ECPG_TOO_FEW_ARGUMENTS, "Too few arguments line %d.", stmt->lineno); return false; } /* Now the request is built. */ if (stmt->connection->committed && !stmt->connection->autocommit) { if ((results = PQexec(stmt->connection->connection, "begin transaction")) == NULL) { register_error(ECPG_TRANS, "Error in transaction processing line %d.", stmt->lineno); return false; } PQclear(results); stmt->connection->committed = false; } ECPGlog("ECPGexecute line %d: QUERY: %s on connection %s\n", stmt->lineno, copiedquery, stmt->connection->name); results = PQexec(stmt->connection->connection, copiedquery); free(copiedquery); if (results == NULL) { ECPGlog("ECPGexecute line %d: error: %s", stmt->lineno, PQerrorMessage(stmt->connection->connection)); register_error(ECPG_PGSQL, "Postgres error: %s line %d.", PQerrorMessage(stmt->connection->connection), stmt->lineno); } else { sqlca.sqlerrd[2] = 0; var = stmt->outlist; switch (PQresultStatus(results)) { int nfields, ntuples, act_tuple, act_field; case PGRES_TUPLES_OK: nfields = PQnfields(results); sqlca.sqlerrd[2] = ntuples = PQntuples(results); status = true; if (ntuples < 1) { ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d\n", stmt->lineno, ntuples); register_error(ECPG_NOT_FOUND, "No data found line %d.", stmt->lineno); status = false; break; } for (act_field = 0; act_field < nfields && status; act_field++) { char *pval; char *scan_length; if (var == NULL) { ECPGlog("ECPGexecute line %d: Too few arguments.\n", stmt->lineno); register_error(ECPG_TOO_FEW_ARGUMENTS, "Too few arguments line %d.", stmt->lineno); return (false); } /* * if we don't have enough space, we cannot read all * tuples */ if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize)) { ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n", stmt->lineno, ntuples, var->arrsize); register_error(ECPG_TOO_MANY_MATCHES, "Too many matches line %d.", stmt->lineno); status = false; break; } /* * allocate memory for NULL pointers */ if ((var->arrsize == 0 || var->varcharsize == 0) && var->value == NULL) { int len = 0; switch (var->type) { case ECPGt_char: case ECPGt_unsigned_char: var->varcharsize = 0; /* check strlen for each tuple */ for (act_tuple = 0; act_tuple < ntuples; act_tuple++) { int len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1; if (len > var->varcharsize) var->varcharsize = len; } var->offset *= var->varcharsize; len = var->offset * ntuples; break; case ECPGt_varchar: len = ntuples * (var->varcharsize + sizeof(int)); break; default: len = var->offset * ntuples; break; } var->value = (void *) ecpg_alloc(len, stmt->lineno); *((void **) var->pointer) = var->value; add_mem(var->value, stmt->lineno); } for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++) { pval = PQgetvalue(results, act_tuple, act_field); ECPGlog("ECPGexecute line %d: RESULT: %s\n", stmt->lineno, pval ? pval : ""); /* Now the pval is a pointer to the value. */ /* We will have to decode the value */ /* * check for null value and set indicator * accordingly */ switch (var->ind_type) { case ECPGt_short: case ECPGt_unsigned_short: ((short *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); break; case ECPGt_int: case ECPGt_unsigned_int: ((int *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); break; case ECPGt_long: case ECPGt_unsigned_long: ((long *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); break; default: break; } switch (var->type) { long res; unsigned long ures; double dres; case ECPGt_short: case ECPGt_int: case ECPGt_long: if (pval) { res = strtol(pval, &scan_length, 10); if (*scan_length != '\0') /* Garbage left */ { register_error(ECPG_INT_FORMAT, "Not correctly formatted int type: %s line %d.", pval, stmt->lineno); status = false; res = 0L; } } else res = 0L; /* Again?! Yes */ switch (var->type) { case ECPGt_short: ((short *) var->value)[act_tuple] = (short) res; break; case ECPGt_int: ((int *) var->value)[act_tuple] = (int) res; break; case ECPGt_long: ((long *) var->value)[act_tuple] = res; break; default: /* Cannot happen */ break; } break; case ECPGt_unsigned_short: case ECPGt_unsigned_int: case ECPGt_unsigned_long: if (pval) { ures = strtoul(pval, &scan_length, 10); if (*scan_length != '\0') /* Garbage left */ { register_error(ECPG_UINT_FORMAT, "Not correctly formatted unsigned type: %s line %d.", pval, stmt->lineno); status = false; ures = 0L; } } else ures = 0L; /* Again?! Yes */ switch (var->type) { case ECPGt_unsigned_short: ((unsigned short *) var->value)[act_tuple] = (unsigned short) ures; break; case ECPGt_unsigned_int: ((unsigned int *) var->value)[act_tuple] = (unsigned int) ures; break; case ECPGt_unsigned_long: ((unsigned long *) var->value)[act_tuple] = ures; break; default: /* Cannot happen */ break; } break; case ECPGt_float: case ECPGt_double: if (pval) { dres = strtod(pval, &scan_length); if (*scan_length != '\0') /* Garbage left */ { register_error(ECPG_FLOAT_FORMAT, "Not correctly formatted floating point type: %s line %d.", pval, stmt->lineno); status = false; dres = 0.0; } } else dres = 0.0; /* Again?! Yes */ switch (var->type) { case ECPGt_float: ((float *) var->value)[act_tuple] = dres; break; case ECPGt_double: ((double *) var->value)[act_tuple] = dres; break; default: /* Cannot happen */ break; } break; case ECPGt_bool: if (pval) { if (pval[0] == 'f' && pval[1] == '\0') { ((char *) var->value)[act_tuple] = false; break; } else if (pval[0] == 't' && pval[1] == '\0') { ((char *) var->value)[act_tuple] = true; break; } } register_error(ECPG_CONVERT_BOOL, "Unable to convert %s to bool on line %d.", (pval ? pval : "NULL"), stmt->lineno); status = false; break; case ECPGt_char: case ECPGt_unsigned_char: { strncpy((char *) ((long) var->value + var->offset * act_tuple), pval, var->varcharsize); if (var->varcharsize && var->varcharsize < strlen(pval)) { /* truncation */ switch (var->ind_type) { case ECPGt_short: case ECPGt_unsigned_short: ((short *) var->ind_value)[act_tuple] = var->varcharsize; break; case ECPGt_int: case ECPGt_unsigned_int: ((int *) var->ind_value)[act_tuple] = var->varcharsize; break; case ECPGt_long: case ECPGt_unsigned_long: ((long *) var->ind_value)[act_tuple] = var->varcharsize; break; default: break; } sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W'; } } break; case ECPGt_varchar: { struct ECPGgeneric_varchar *variable = (struct ECPGgeneric_varchar *) ((long) var->value + var->offset * act_tuple); if (var->varcharsize == 0) strncpy(variable->arr, pval, strlen(pval)); else strncpy(variable->arr, pval, var->varcharsize); variable->len = strlen(pval); if (var->varcharsize > 0 && variable->len > var->varcharsize) { /* truncation */ switch (var->ind_type) { case ECPGt_short: case ECPGt_unsigned_short: ((short *) var->ind_value)[act_tuple] = var->varcharsize; break; case ECPGt_int: case ECPGt_unsigned_int: ((int *) var->ind_value)[act_tuple] = var->varcharsize; break; case ECPGt_long: case ECPGt_unsigned_long: ((long *) var->ind_value)[act_tuple] = var->varcharsize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -