📄 execute.c
字号:
break; case ECPGt_date: { char *str = NULL; int slen; if (var->arrsize > 1) { for (element = 0; element < var->arrsize; element++) { str = quote_postgres(PGTYPESdate_to_asc(*(date *) ((var + var->offset * element)->value)), lineno); slen = strlen(str); if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + sizeof("array [],date "), lineno))) return false; if (!element) strcpy(mallocedval, "array ["); strcpy(mallocedval + strlen(mallocedval), "date "); strncpy(mallocedval + strlen(mallocedval), str, slen + 1); strcpy(mallocedval + strlen(mallocedval), ","); } strcpy(mallocedval + strlen(mallocedval) - 1, "]"); } else { str = quote_postgres(PGTYPESdate_to_asc(*(date *) (var->value)), lineno); slen = strlen(str); if (!(mallocedval = ECPGalloc(slen + sizeof("date ") + 1, lineno))) return false; strcpy(mallocedval, "date "); /* also copy trailing '\0' */ strncpy(mallocedval + strlen(mallocedval), str, slen + 1); } *tobeinserted_p = mallocedval; *malloced_p = true; free(str); } break; case ECPGt_timestamp: { char *str = NULL; int slen; if (var->arrsize > 1) { for (element = 0; element < var->arrsize; element++) { str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) ((var + var->offset * element)->value)), lineno); slen = strlen(str); if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + sizeof("array [], timestamp "), lineno))) return false; if (!element) strcpy(mallocedval, "array ["); strcpy(mallocedval + strlen(mallocedval), "timestamp "); strncpy(mallocedval + strlen(mallocedval), str, slen + 1); strcpy(mallocedval + strlen(mallocedval), ","); } strcpy(mallocedval + strlen(mallocedval) - 1, "]"); } else { str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) (var->value)), lineno); slen = strlen(str); if (!(mallocedval = ECPGalloc(slen + sizeof("timestamp") + 1, lineno))) return false; strcpy(mallocedval, "timestamp "); /* also copy trailing '\0' */ strncpy(mallocedval + strlen(mallocedval), str, slen + 1); } *tobeinserted_p = mallocedval; *malloced_p = true; free(str); } break; case ECPGt_descriptor: break; default: /* Not implemented yet */ ECPGraise(lineno, ECPG_UNSUPPORTED, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (char *) ECPGtype_name(var->type)); return false; break; } } return true;}static boolECPGexecute(struct statement * stmt){ bool status = false; char *copiedquery; char *cmdstat; PGresult *results; PGnotify *notify; struct variable *var; int desc_counter = 0; copiedquery = ECPGstrdup(stmt->command, stmt->lineno); /* * Now, if the type is one of the fill in types then we take the argument * and enter that in the string at the first %s position. Then if there * are any more fill in types we fill in at the next and so on. */ var = stmt->inlist; while (var) { char *newcopy = NULL; const char *tobeinserted; char *p; bool malloced = FALSE; int hostvarl = 0; tobeinserted = NULL; /* * A descriptor is a special case since it contains many variables but * is listed only once. */ if (var->type == ECPGt_descriptor) { /* * We create an additional variable list here, so the same logic * applies. */ struct variable desc_inlist; struct descriptor *desc; struct descriptor_item *desc_item; for (desc = all_descriptors; desc; desc = desc->next) { if (strcmp(var->pointer, desc->name) == 0) break; } if (desc == NULL) { ECPGraise(stmt->lineno, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, var->pointer); return false; } desc_counter++; if (desc->count < 0 || desc->count >= desc_counter) { for (desc_item = desc->items; desc_item; desc_item = desc_item->next) { if (desc_item->num == desc_counter) { desc_inlist.type = ECPGt_char; desc_inlist.value = desc_item->data; desc_inlist.pointer = &(desc_item->data); desc_inlist.varcharsize = strlen(desc_item->data); desc_inlist.arrsize = 1; desc_inlist.offset = 0; if (!desc_item->indicator) { desc_inlist.ind_type = ECPGt_NO_INDICATOR; desc_inlist.ind_value = desc_inlist.ind_pointer = NULL; desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0; } else { desc_inlist.ind_type = ECPGt_int; desc_inlist.ind_value = &(desc_item->indicator); desc_inlist.ind_pointer = &(desc_inlist.ind_value); desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1; desc_inlist.ind_offset = 0; } if (!ECPGstore_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, &malloced)) return false; break; } } if (!desc_item) /* no more entries found in descriptor */ desc_counter = 0; } else desc_counter = 0; } else { if (!ECPGstore_input(stmt->lineno, stmt->force_indicator, var, &tobeinserted, &malloced)) return false; } if (tobeinserted) { /* * Now tobeinserted points to an area that is to be inserted at * the first %s */ if (!(newcopy = (char *) ECPGalloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno))) return false; strcpy(newcopy, copiedquery); if ((p = next_insert(newcopy + hostvarl)) == NULL) { /* * We have an argument but we dont have the matched up string * in the string */ ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL); return false; } else { strcpy(p, tobeinserted); hostvarl = strlen(newcopy); /* * 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 (malloced) { ECPGfree((char *) tobeinserted); tobeinserted = NULL; } ECPGfree(copiedquery); copiedquery = newcopy; } if (desc_counter == 0) var = var->next; } /* Check if there are unmatched things left. */ if (next_insert(copiedquery) != NULL) { ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL); return false; } /* Now the request is built. */ if (stmt->connection->committed && !stmt->connection->autocommit) { if ((results = PQexec(stmt->connection->connection, "begin transaction")) == NULL) { ECPGraise(stmt->lineno, ECPG_TRANS, ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN, NULL); 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); ECPGfree(copiedquery); if (results == NULL) { ECPGlog("ECPGexecute line %d: error: %s", stmt->lineno, PQerrorMessage(stmt->connection->connection)); ECPGraise_backend(stmt->lineno, NULL, stmt->connection->connection, stmt->compat); } else /* * note: since some of the following code is duplicated in * descriptor.c it should go into a separate function */ { bool clear_result = TRUE; struct sqlca_t *sqlca = ECPGget_sqlca(); var = stmt->outlist; switch (PQresultStatus(results)) { int nfields, ntuples, act_field; case PGRES_TUPLES_OK: nfields = PQnfields(results); sqlca->sqlerrd[2] = ntuples = PQntuples(results); ECPGlog("ECPGexecute line %d: Correctly got %d tuples with %d fields\n", stmt->lineno, ntuples, nfields); status = true; if (ntuples < 1) { if (ntuples) ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d\n", stmt->lineno, ntuples); ECPGraise(stmt->lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL); status = false; break; } if (var != NULL && var->type == ECPGt_descriptor) { PGresult **resultpp = ECPGdescriptor_lvalue(stmt->lineno, (const char *) var->pointer); if (resultpp == NULL) status = false; else { if (*resultpp) PQclear(*resultpp); *resultpp = results; clear_result = FALSE; ECPGlog("ECPGexecute putting result (%d tuples) into descriptor '%s'\n", PQntuples(results), (const char *) var->pointer); } var = var->next; } else for (act_field = 0; act_field < nfields && status; act_field++) { if (var != NULL) { status = ECPGstore_result(results, act_field, stmt, var); var = var->next; } else if (!INFORMIX_MODE(stmt->compat)) { ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS, NULL); return (false); } } if (status && var != NULL) { ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS, NULL); status = false; } break; case PGRES_EMPTY_QUERY: /* do nothing */ ECPGraise(stmt->lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL); break; case PGRES_COMMAND_OK: status = true; cmdstat = PQcmdStatus(results); sqlca->sqlerrd[1] = PQoidValue(results); sqlca->sqlerrd[2] = atol(PQcmdTuples(results)); ECPGlog("ECPGexecute line %d Ok: %s\n", stmt->lineno, cmdstat); if (stmt->compat != ECPG_COMPAT_INFORMIX_SE && !sqlca->sqlerrd[2] && (!strncmp(cmdstat, "UPDATE", 6) || !strncmp(cmdstat, "INSERT", 6) || !strncmp(cmdstat, "DELETE", 6))) ECPGraise(stmt->lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL); break; case PGRES_NONFATAL_ERROR: case PGRES_FATAL_ERROR: case PGRES_BAD_RESPONSE: ECPGlog("ECPGexecute line %d: Error: %s", stmt->lineno, PQresultErrorMessage(results)); ECPGraise_backend(stmt->lineno, results, stmt->connection->connection, stmt->compat); status = false; break; case PGRES_COPY_OUT: ECPGlog("ECPGexecute line %d: Got PGRES_COPY_OUT ... tossing.\n", stmt->lineno); PQendcopy(stmt->connection->connection); break; case PGRES_COPY_IN: ECPGlog("ECPGexecute line %d: Got PGRES_COPY_IN ... tossing.\n", stmt->lineno); PQendcopy(stmt->connection->connection); break; default: ECPGlog("ECPGexecute line %d: Got something else, postgres error.\n", stmt->lineno); ECPGraise_backend(stmt->lineno, results, stmt->connection->connection, stmt->compat); status = false; break; } if (clear_result) PQclear(results); } /* check for asynchronous returns */ notify = PQnotifies(stmt->connection->connection); if (notify) { ECPGlog("ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received\n", stmt->lineno, notify->relname, notify->be_pid); PQfreemem(notify); } return status;}boolECPGdo(int lineno, int compat, int force_indicator, const char *connection_name, const char *query,...){ va_list args; struct statement *stmt; struct connection *con = ECPGget_connection(connection_name); bool status; char *oldlocale; /* Make sure we do NOT honor the locale for numeric input/output */ /* since the database wants the standard decimal point */ oldlocale = ECPGstrdup(setlocale(LC_NUMERIC, NULL), lineno); setlocale(LC_NUMERIC, "C"); if (!ECPGinit(con, connection_name, lineno)) { setlocale(LC_NUMERIC, oldlocale); ECPGfree(oldlocale); return (false); } /* construct statement in our own structure */ va_start(args, query); if (create_statement(lineno, compat, force_indicator, con, &stmt, query, args) == false) { setlocale(LC_NUMERIC, oldlocale); ECPGfree(oldlocale); return (false); } va_end(args); /* are we connected? */ if (con == NULL || con->connection == NULL) { free_statement(stmt); ECPGraise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : "<empty>"); setlocale(LC_NUMERIC, oldlocale); ECPGfree(oldlocale); return false; } /* initialize auto_mem struct */ ECPGclear_auto_mem(); status = ECPGexecute(stmt); free_statement(stmt); /* and reset locale value so our application is not affected */ setlocale(LC_NUMERIC, oldlocale); ECPGfree(oldlocale); return (status);}/* old descriptor interface */boolECPGdo_descriptor(int line, const char *connection, const char *descriptor, const char *query){ return ECPGdo(line, ECPG_COMPAT_PGSQL, true, connection, (char *) query, ECPGt_EOIT, ECPGt_descriptor, descriptor, 0L, 0L, 0L, ECPGt_NO_INDICATOR, NULL, 0L, 0L, 0L, ECPGt_EORT);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -