/* * PrintQueryResults: print out query results as required * * Note: Utility function for use by SendQuery() only. * * Returns true if the query executed successfully, false otherwise. */ static bool PrintQueryResults(PGresult *results) { bool success = false; if (!results) return false; switch (PQresultStatus(results)) { case PGRES_TUPLES_OK: success = PrintQueryTuples(results); break; case PGRES_COMMAND_OK: { char buf[10]; success = true; sprintf(buf, "%u", (unsigned int) PQoidValue(results)); if (!QUIET()) { if (pset.popt.topt.format == PRINT_HTML) { fputs("<p>", pset.queryFout); html_escaped_print(PQcmdStatus(results), pset.queryFout); fputs("</p>\n", pset.queryFout); } else fprintf(pset.queryFout, "%s\n", PQcmdStatus(results)); } SetVariable(pset.vars, "LASTOID", buf); break; } case PGRES_EMPTY_QUERY: success = true; break; case PGRES_COPY_OUT: case PGRES_COPY_IN: /* nothing to do here */ success = true; break; default: break; } fflush(pset.queryFout); return success; }
/* * call-seq: * res.cmd_status() -> String * * Returns the status string of the last query command. */ static VALUE pgresult_cmd_status(VALUE self) { VALUE ret = rb_tainted_str_new2(PQcmdStatus(pgresult_get(self))); ASSOCIATE_INDEX(ret, self); return ret; }
void dlgDirectDbg::OnTargetComplete( wxCommandEvent &event ) { // Extract the result set handle from the event and log the status info PGresult *result = (PGresult *)event.GetClientData(); wxLogInfo( wxT( "OnTargetComplete() called\n" )); wxLogInfo( wxT( "%s\n" ), wxString(PQresStatus( PQresultStatus( result )), wxConvUTF8).c_str()); // If the query failed, write the error message to the status line, otherwise, copy the result set into the grid if(( PQresultStatus( result ) == PGRES_NONFATAL_ERROR ) || ( PQresultStatus( result ) == PGRES_FATAL_ERROR )) { wxString message( PQresultErrorMessage( result ), wxConvUTF8 ); message.Replace( wxT( "\n" ), wxT( " " )); m_parent->getStatusBar()->SetStatusText( message, 1 ); char *state = PQresultErrorField(result, PG_DIAG_SQLSTATE); // Don't bother telling the user that he aborted - he already knows! // Depending on the stage, m_conn might not be set all! so check for // that first if (m_conn) { if (state != NULL && strcmp(state, "57014")) wxLogError( wxT( "%s\n" ), wxString(PQerrorMessage(m_conn->getConnection()), wxConvUTF8).c_str()); else wxLogInfo( wxT( "%s\n" ), wxString(PQerrorMessage(m_conn->getConnection()), wxConvUTF8).c_str()); } } else { wxString message( PQcmdStatus( result ), wxConvUTF8 ); message.Replace( wxT( "\r" ), wxT( "" )); message.Replace( wxT( "\n" ), wxT( " " )); m_parent->getStatusBar()->SetStatusText( message, 1 ); // If this result set has any columns, add a result grid to the code window so // we can show the results to the user if( m_codeWindow && PQnfields( result )) { m_codeWindow->OnResultSet( result ); } } if (m_codeWindow) { m_codeWindow->m_targetComplete = true; m_codeWindow->disableTools( ); } // Do not show if aborted if ( m_codeWindow && m_codeWindow->m_targetAborted ) return; this->Show( true ); }
/* * PrintQueryResults: print out (or store) query results as required * * Note: Utility function for use by SendQuery() only. * * Returns true if the query executed successfully, false otherwise. */ static bool PrintQueryResults(PGresult *results) { bool success; const char *cmdstatus; if (!results) return false; switch (PQresultStatus(results)) { case PGRES_TUPLES_OK: /* store or print the data ... */ if (pset.gset_prefix) success = StoreQueryTuple(results); else success = PrintQueryTuples(results); /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */ cmdstatus = PQcmdStatus(results); if (strncmp(cmdstatus, "INSERT", 6) == 0 || strncmp(cmdstatus, "UPDATE", 6) == 0 || strncmp(cmdstatus, "DELETE", 6) == 0) PrintQueryStatus(results); break; case PGRES_COMMAND_OK: PrintQueryStatus(results); success = true; break; case PGRES_EMPTY_QUERY: success = true; break; case PGRES_COPY_OUT: case PGRES_COPY_IN: /* nothing to do here */ success = true; break; case PGRES_BAD_RESPONSE: case PGRES_NONFATAL_ERROR: case PGRES_FATAL_ERROR: success = false; break; default: success = false; psql_error("unexpected PQresultStatus: %d\n", PQresultStatus(results)); break; } fflush(pset.queryFout); return success; }
/* * PrintQueryStatus: report command status as required * * Note: Utility function for use by PrintQueryResults() only. */ static void PrintQueryStatus(PGresult *results) { char buf[16]; if (!pset.quiet) { if (pset.popt.topt.format == PRINT_HTML) { fputs("<p>", pset.queryFout); html_escaped_print(PQcmdStatus(results), pset.queryFout); fputs("</p>\n", pset.queryFout); } else fprintf(pset.queryFout, "%s\n", PQcmdStatus(results)); } if (pset.logfile) fprintf(pset.logfile, "%s\n", PQcmdStatus(results)); snprintf(buf, sizeof(buf), "%u", (unsigned int) PQoidValue(results)); SetVariable(pset.vars, "LASTOID", buf); }
/* * PrintQueryResults: print out query results as required * * Note: Utility function for use by SendQuery() only. * * Returns true if the query executed successfully, false otherwise. */ static bool PrintQueryResults(PGresult *results) { bool success = false; const char *cmdstatus; if (!results) return false; switch (PQresultStatus(results)) { case PGRES_TUPLES_OK: /* print the data ... */ success = PrintQueryTuples(results); /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */ cmdstatus = PQcmdStatus(results); if (strncmp(cmdstatus, "INSERT", 6) == 0 || strncmp(cmdstatus, "UPDATE", 6) == 0 || strncmp(cmdstatus, "DELETE", 6) == 0) PrintQueryStatus(results); break; case PGRES_COMMAND_OK: PrintQueryStatus(results); success = true; break; case PGRES_EMPTY_QUERY: success = true; break; case PGRES_COPY_OUT: case PGRES_COPY_IN: /* nothing to do here */ success = true; break; default: break; } fflush(pset.queryFout); return success; }
std::string answer() const { return PQcmdStatus(res); }
/* * Display a CdbDispatchResult in the log for debugging. * Call only from main thread, during or after cdbdisp_checkDispatchResults. */ void cdbdisp_debugDispatchResult(CdbDispatchResult * dispatchResult) { int ires; int nres; Assert (dispatchResult != NULL); /* * PGresult messages */ nres = cdbdisp_numPGresult(dispatchResult); for (ires = 0; ires < nres; ++ires) { PGresult *pgresult = cdbdisp_getPGresult(dispatchResult, ires); ExecStatusType resultStatus = PQresultStatus(pgresult); char *whoami = PQresultErrorField(pgresult, PG_DIAG_GP_PROCESS_TAG); if (!whoami) whoami = "no process id"; if (resultStatus == PGRES_COMMAND_OK || resultStatus == PGRES_TUPLES_OK || resultStatus == PGRES_COPY_IN || resultStatus == PGRES_COPY_OUT || resultStatus == PGRES_EMPTY_QUERY) { char *cmdStatus = PQcmdStatus(pgresult); elog(LOG, "DispatchResult from %s: ok %s (%s)", dispatchResult->segdbDesc->whoami, cmdStatus ? cmdStatus : "(no cmdStatus)", whoami); } else { char *sqlstate = PQresultErrorField(pgresult, PG_DIAG_SQLSTATE); char *pri = PQresultErrorField(pgresult, PG_DIAG_MESSAGE_PRIMARY); char *dtl = PQresultErrorField(pgresult, PG_DIAG_MESSAGE_DETAIL); char *sourceFile = PQresultErrorField(pgresult, PG_DIAG_SOURCE_FILE); char *sourceLine = PQresultErrorField(pgresult, PG_DIAG_SOURCE_LINE); int lenpri = (pri == NULL) ? 0 : strlen(pri); if (!sqlstate) sqlstate = "no SQLSTATE"; while (lenpri > 0 && pri[lenpri - 1] <= ' ' && pri[lenpri - 1] > '\0') lenpri--; ereport(LOG, (errmsg("DispatchResult from %s: error (%s) %s %.*s (%s)", dispatchResult->segdbDesc->whoami, sqlstate, PQresStatus(resultStatus), lenpri, pri ? pri : "", whoami), errdetail("(%s:%s) %s", sourceFile ? sourceFile : "unknown file", sourceLine ? sourceLine : "unknown line", dtl ? dtl : ""))); } } /* * Error found on our side of the libpq interface? */ if (dispatchResult->error_message && dispatchResult->error_message->len > 0) { char esqlstate[6]; errcode_to_sqlstate(dispatchResult->errcode, esqlstate); elog(LOG, "DispatchResult from %s: connect error (%s) %s", dispatchResult->segdbDesc->whoami, esqlstate, dispatchResult->error_message->data); } /* * Should have either an error code or an ok result. */ if (dispatchResult->errcode == 0 && dispatchResult->okindex < 0) { elog(LOG, "DispatchResult from %s: No ending status.", dispatchResult->segdbDesc->whoami); } }
/************************************************************* *Returns the status of the command status of last query. *************************************************************/ char * dbi_cmd_status(DBI_result *result_id) { return(PQcmdStatus(result_id)); }
/* * SendQuery: send the query string to the backend * (and print out results) * * Note: This is the "front door" way to send a query. That is, use it to * send queries actually entered by the user. These queries will be subject to * single step mode. * To send "back door" queries (generated by slash commands, etc.) in a * controlled way, use PSQLexec(). * * Returns true if the query executed successfully, false otherwise. */ bool SendQuery(const char *query) { PGresult *results; PGTransactionStatusType transaction_status; double elapsed_msec = 0; bool OK, on_error_rollback_savepoint = false; static bool on_error_rollback_warning = false; if (!pset.db) { psql_error("You are currently not connected to a database.\n"); return false; } if (pset.singlestep) { char buf[3]; printf(_("***(Single step mode: verify command)*******************************************\n" "%s\n" "***(press return to proceed or enter x and return to cancel)********************\n"), query); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) != NULL) if (buf[0] == 'x') return false; } else if (pset.echo == PSQL_ECHO_QUERIES) { puts(query); fflush(stdout); } if (pset.logfile) { fprintf(pset.logfile, _("********* QUERY **********\n" "%s\n" "**************************\n\n"), query); fflush(pset.logfile); } SetCancelConn(); transaction_status = PQtransactionStatus(pset.db); if (transaction_status == PQTRANS_IDLE && !pset.autocommit && !command_no_begin(query)) { results = PQexec(pset.db, "BEGIN"); if (PQresultStatus(results) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(pset.db)); PQclear(results); ResetCancelConn(); return false; } PQclear(results); transaction_status = PQtransactionStatus(pset.db); } if (transaction_status == PQTRANS_INTRANS && pset.on_error_rollback != PSQL_ERROR_ROLLBACK_OFF && (pset.cur_cmd_interactive || pset.on_error_rollback == PSQL_ERROR_ROLLBACK_ON)) { if (on_error_rollback_warning == false && pset.sversion < 80000) { fprintf(stderr, _("The server (version %d.%d) does not support savepoints for ON_ERROR_ROLLBACK.\n"), pset.sversion / 10000, (pset.sversion / 100) % 100); on_error_rollback_warning = true; } else { results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint"); if (PQresultStatus(results) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(pset.db)); PQclear(results); ResetCancelConn(); return false; } PQclear(results); on_error_rollback_savepoint = true; } } if (pset.fetch_count <= 0 || !is_select_command(query)) { /* Default fetch-it-all-and-print mode */ instr_time before, after; if (pset.timing) INSTR_TIME_SET_CURRENT(before); results = PQexec(pset.db, query); /* these operations are included in the timing result: */ ResetCancelConn(); OK = (AcceptResult(results) && ProcessCopyResult(results)); if (pset.timing) { INSTR_TIME_SET_CURRENT(after); INSTR_TIME_SUBTRACT(after, before); elapsed_msec = INSTR_TIME_GET_MILLISEC(after); } /* but printing results isn't: */ if (OK) OK = PrintQueryResults(results); } else { /* Fetch-in-segments mode */ OK = ExecQueryUsingCursor(query, &elapsed_msec); ResetCancelConn(); results = NULL; /* PQclear(NULL) does nothing */ } /* If we made a temporary savepoint, possibly release/rollback */ if (on_error_rollback_savepoint) { const char *svptcmd; transaction_status = PQtransactionStatus(pset.db); if (transaction_status == PQTRANS_INERROR) { /* We always rollback on an error */ svptcmd = "ROLLBACK TO pg_psql_temporary_savepoint"; } else if (transaction_status != PQTRANS_INTRANS) { /* If they are no longer in a transaction, then do nothing */ svptcmd = NULL; } else { /* * Do nothing if they are messing with savepoints themselves: If * the user did RELEASE or ROLLBACK, our savepoint is gone. If * they issued a SAVEPOINT, releasing ours would remove theirs. */ if (results && (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 || strcmp(PQcmdStatus(results), "RELEASE") == 0 || strcmp(PQcmdStatus(results), "ROLLBACK") == 0)) svptcmd = NULL; else svptcmd = "RELEASE pg_psql_temporary_savepoint"; } if (svptcmd) { PGresult *svptres; svptres = PQexec(pset.db, svptcmd); if (PQresultStatus(svptres) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(pset.db)); PQclear(svptres); PQclear(results); ResetCancelConn(); return false; } PQclear(svptres); } } PQclear(results); /* Possible microtiming output */ if (OK && pset.timing) printf(_("Time: %.3f ms\n"), elapsed_msec); /* check for events that may occur during query execution */ if (pset.encoding != PQclientEncoding(pset.db) && PQclientEncoding(pset.db) >= 0) { /* track effects of SET CLIENT_ENCODING */ pset.encoding = PQclientEncoding(pset.db); pset.popt.topt.encoding = pset.encoding; SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding)); } PrintNotifications(); return OK; }
/* * fetch_prompt_rule * * Return the set of parameters to be used to turn the form_name, fieldname * pair into an input prompt. * * The result will contain both locally allocated and PGresult data. * It must be freed with free_prompt_rule. */ struct prompt_rule* fetch_prompt_rule(struct handler_args* h, char* form_name, char* fieldname){ double start = gettime(); bool log_errors = false; char* paramValues[] = {form_name, fieldname, NULL}; PGresult* rs = PQexecPrepared(h->session->conn, "fetch_rule", 2, (const char* const*) ¶mValues, NULL, NULL, 0); if ((PQresultStatus(rs) == PGRES_TUPLES_OK) && (PQntuples(rs) == 1)) { struct prompt_rule* rule = calloc(1,sizeof(struct prompt_rule)); rule->form_name = get_value(rs, 0, "form_name"); rule->fieldname = get_value(rs, 0, "fieldname"); rule->prompt_type = get_value(rs, 0, "prompt_type"); rule->el_class = get_value(rs, 0, "el_class"); rule->readonly = get_bool(rs, 0, "readonly"); rule->publish_pgtype = get_bool(rs, 0, "publish_pgtype"); rule->rows = strtol( get_value(rs, 0, "rows"), NULL, 10); rule->cols = strtol( get_value(rs, 0, "cols"), NULL, 10); rule->size = strtol( get_value(rs, 0, "size"), NULL, 10); rule->maxlength = strtol(get_value(rs, 0, "maxlength"), NULL, 10); rule->tabindex = strtol(get_value(rs, 0, "tabindex"), NULL, 10); rule->regex_pattern = get_value(rs, 0, "regex_pattern"); if (rule->regex_pattern != NULL){ const char* error = NULL; int erroffset = 0; rule->comp_regex = pcre_compile( rule->regex_pattern, PCRE_JAVASCRIPT_COMPAT|PCRE_UTF8, &error, &erroffset, NULL); if (rule->comp_regex == NULL){ fprintf(h->log, "%f %d %s:%d " "regex compile failed form %s field %s offset %d: %s\n", gettime(), h->request_id, __func__, __LINE__, form_name, fieldname, erroffset, error); } } rule->expand_percent_n = get_bool(rs, 0, "expand_percent_n"); // The default value for rule->options is a pointer to a // pg result set. Whether rule->options is overwritten or not, // the pg string will be freed by free_prompt_rule. // In a few cases, the options need to be generated dynamically. // Select pkey and enum are examples. In such a case, the // string which needs to be independently freed is referenced // in free_options. rule->options = get_value(rs, 0, "options"); rule->free_options = NULL; rule->src = get_value(rs, 0, "src"); rule->onblur = get_value(rs, 0, "onblur"); rule->onchange = get_value(rs, 0, "onchange"); rule->onclick = get_value(rs, 0, "onclick"); rule->ondblclick = get_value(rs, 0, "ondblclick"); rule->onfocus = get_value(rs, 0, "onfocus"); rule->onkeypress = get_value(rs, 0, "onkeypress"); rule->onkeyup = get_value(rs, 0, "onkeyup"); rule->onkeydown = get_value(rs, 0, "onkeydown"); rule->onmousedown = get_value(rs, 0, "onmousedown"); rule->onmouseup = get_value(rs, 0, "onmouseup"); rule->onmouseout = get_value(rs, 0, "onmouseout"); rule->onmouseover = get_value(rs, 0, "onmouseover"); rule->onselect = get_value(rs, 0, "onselect"); rule->result = rs; fprintf(h->log, "%f %d %s:%d fetch_prompt_rule (%s,%s) in %f\n", gettime(), h->request_id, __func__, __LINE__, form_name, fieldname, gettime() - start); return rule; }else{ if (log_errors){ fprintf(h->log, "%f %d %s:%d fetch_prompt_rules" "resStatus:%s cmdStatus:%s ErrorMessage:%s\n", gettime(), h->request_id, __func__, __LINE__, PQresStatus(PQresultStatus(rs)), PQcmdStatus(rs), PQresultErrorMessage(rs)); } //ZZZZZZZZZZZZZZZZZZZZZ return default_prompt_rule(h, form_name, fieldname); } }
/* * SendQuery: send the query string to the backend * (and print out results) * * Note: This is the "front door" way to send a query. That is, use it to * send queries actually entered by the user. These queries will be subject to * single step mode. * To send "back door" queries (generated by slash commands, etc.) in a * controlled way, use PSQLexec(). * * Returns true if the query executed successfully, false otherwise. */ bool SendQuery(const char *query) { PGresult *results; PGTransactionStatusType transaction_status; double elapsed_msec = 0; bool OK = false; int i; bool on_error_rollback_savepoint = false; static bool on_error_rollback_warning = false; if (!pset.db) { psql_error("You are currently not connected to a database.\n"); goto sendquery_cleanup; } if (pset.singlestep) { char buf[3]; fflush(stderr); printf(_("***(Single step mode: verify command)*******************************************\n" "%s\n" "***(press return to proceed or enter x and return to cancel)********************\n"), query); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) != NULL) if (buf[0] == 'x') goto sendquery_cleanup; if (cancel_pressed) goto sendquery_cleanup; } else if (pset.echo == PSQL_ECHO_QUERIES) { puts(query); fflush(stdout); } if (pset.logfile) { fprintf(pset.logfile, _("********* QUERY **********\n" "%s\n" "**************************\n\n"), query); fflush(pset.logfile); } SetCancelConn(); transaction_status = PQtransactionStatus(pset.db); if (transaction_status == PQTRANS_IDLE && !pset.autocommit && !command_no_begin(query)) { results = PQexec(pset.db, "BEGIN"); if (PQresultStatus(results) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(pset.db)); ClearOrSaveResult(results); ResetCancelConn(); goto sendquery_cleanup; } ClearOrSaveResult(results); transaction_status = PQtransactionStatus(pset.db); } if (transaction_status == PQTRANS_INTRANS && pset.on_error_rollback != PSQL_ERROR_ROLLBACK_OFF && (pset.cur_cmd_interactive || pset.on_error_rollback == PSQL_ERROR_ROLLBACK_ON)) { if (on_error_rollback_warning == false && pset.sversion < 80000) { char sverbuf[32]; psql_error("The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n", formatPGVersionNumber(pset.sversion, false, sverbuf, sizeof(sverbuf))); on_error_rollback_warning = true; } else { results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint"); if (PQresultStatus(results) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(pset.db)); ClearOrSaveResult(results); ResetCancelConn(); goto sendquery_cleanup; } ClearOrSaveResult(results); on_error_rollback_savepoint = true; } } if (pset.fetch_count <= 0 || pset.gexec_flag || pset.crosstab_flag || !is_select_command(query)) { /* Default fetch-it-all-and-print mode */ instr_time before, after; if (pset.timing) INSTR_TIME_SET_CURRENT(before); results = PQexec(pset.db, query); /* these operations are included in the timing result: */ ResetCancelConn(); OK = ProcessResult(&results); if (pset.timing) { INSTR_TIME_SET_CURRENT(after); INSTR_TIME_SUBTRACT(after, before); elapsed_msec = INSTR_TIME_GET_MILLISEC(after); } /* but printing results isn't: */ if (OK && results) OK = PrintQueryResults(results); } else { /* Fetch-in-segments mode */ OK = ExecQueryUsingCursor(query, &elapsed_msec); ResetCancelConn(); results = NULL; /* PQclear(NULL) does nothing */ } if (!OK && pset.echo == PSQL_ECHO_ERRORS) psql_error("STATEMENT: %s\n", query); /* If we made a temporary savepoint, possibly release/rollback */ if (on_error_rollback_savepoint) { const char *svptcmd = NULL; transaction_status = PQtransactionStatus(pset.db); switch (transaction_status) { case PQTRANS_INERROR: /* We always rollback on an error */ svptcmd = "ROLLBACK TO pg_psql_temporary_savepoint"; break; case PQTRANS_IDLE: /* If they are no longer in a transaction, then do nothing */ break; case PQTRANS_INTRANS: /* * Do nothing if they are messing with savepoints themselves: * If the user did RELEASE or ROLLBACK, our savepoint is gone. * If they issued a SAVEPOINT, releasing ours would remove * theirs. */ if (results && (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 || strcmp(PQcmdStatus(results), "RELEASE") == 0 || strcmp(PQcmdStatus(results), "ROLLBACK") == 0)) svptcmd = NULL; else svptcmd = "RELEASE pg_psql_temporary_savepoint"; break; case PQTRANS_ACTIVE: case PQTRANS_UNKNOWN: default: OK = false; /* PQTRANS_UNKNOWN is expected given a broken connection. */ if (transaction_status != PQTRANS_UNKNOWN || ConnectionUp()) psql_error("unexpected transaction status (%d)\n", transaction_status); break; } if (svptcmd) { PGresult *svptres; svptres = PQexec(pset.db, svptcmd); if (PQresultStatus(svptres) != PGRES_COMMAND_OK) { psql_error("%s", PQerrorMessage(pset.db)); ClearOrSaveResult(svptres); OK = false; PQclear(results); ResetCancelConn(); goto sendquery_cleanup; } PQclear(svptres); } } ClearOrSaveResult(results); /* Possible microtiming output */ if (pset.timing) printf(_("Time: %.3f ms\n"), elapsed_msec); /* check for events that may occur during query execution */ if (pset.encoding != PQclientEncoding(pset.db) && PQclientEncoding(pset.db) >= 0) { /* track effects of SET CLIENT_ENCODING */ pset.encoding = PQclientEncoding(pset.db); pset.popt.topt.encoding = pset.encoding; SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding)); } PrintNotifications(); /* perform cleanup that should occur after any attempted query */ sendquery_cleanup: /* reset \g's output-to-filename trigger */ if (pset.gfname) { free(pset.gfname); pset.gfname = NULL; } /* reset \gset trigger */ if (pset.gset_prefix) { free(pset.gset_prefix); pset.gset_prefix = NULL; } /* reset \gexec trigger */ pset.gexec_flag = false; /* reset \crosstabview trigger */ pset.crosstab_flag = false; for (i = 0; i < lengthof(pset.ctv_args); i++) { pg_free(pset.ctv_args[i]); pset.ctv_args[i] = NULL; } return OK; }
static void thread_DispatchWaitSingle(DispatchCommandParms * pParms) { SegmentDatabaseDescriptor *segdbDesc; CdbDispatchResult *dispatchResult; char *msg = NULL; /* * Assert() cannot be used in threads */ if (pParms->db_count != 1) write_log("Bug... thread_dispatchWaitSingle called with db_count %d", pParms->db_count); dispatchResult = pParms->dispatchResultPtrArray[0]; segdbDesc = dispatchResult->segdbDesc; if (PQstatus(segdbDesc->conn) == CONNECTION_BAD) { msg = PQerrorMessage(segdbDesc->conn); /* * Save error info for later. */ cdbdisp_appendMessage(dispatchResult, DEBUG1, ERRCODE_GP_INTERCONNECTION_ERROR, "Lost connection to %s. %s", segdbDesc->whoami, msg ? msg : ""); /* * Free the PGconn object. */ PQfinish(segdbDesc->conn); segdbDesc->conn = NULL; dispatchResult->stillRunning = false; } else { PQsetnonblocking(segdbDesc->conn, FALSE); for (;;) { PGresult *pRes; ExecStatusType resultStatus; int resultIndex = cdbdisp_numPGresult(dispatchResult); if (DEBUG4 >= log_min_messages) write_log("PQgetResult, resultIndex = %d", resultIndex); /* * Get one message. */ pRes = PQgetResult(segdbDesc->conn); CollectQEWriterTransactionInformation(segdbDesc, dispatchResult); /* * Command is complete when PGgetResult() returns NULL. It is critical * that for any connection that had an asynchronous command sent thru * it, we call PQgetResult until it returns NULL. Otherwise, the next * time a command is sent to that connection, it will return an error * that there's a command pending. */ if (!pRes) { if (DEBUG4 >= log_min_messages) { /* * Don't use elog, it's not thread-safe */ write_log("%s -> idle", segdbDesc->whoami); } break; } /* * Attach the PGresult object to the CdbDispatchResult object. */ cdbdisp_appendResult(dispatchResult, pRes); /* * Did a command complete successfully? */ resultStatus = PQresultStatus(pRes); if (resultStatus == PGRES_COMMAND_OK || resultStatus == PGRES_TUPLES_OK || resultStatus == PGRES_COPY_IN || resultStatus == PGRES_COPY_OUT) { /* * Save the index of the last successful PGresult. Can be given to * cdbdisp_getPGresult() to get tuple count, etc. */ dispatchResult->okindex = resultIndex; if (DEBUG3 >= log_min_messages) { /* * Don't use elog, it's not thread-safe */ char *cmdStatus = PQcmdStatus(pRes); write_log("%s -> ok %s", segdbDesc->whoami, cmdStatus ? cmdStatus : "(no cmdStatus)"); } if (resultStatus == PGRES_COPY_IN || resultStatus == PGRES_COPY_OUT) return; } /* * Note QE error. Cancel the whole statement if requested. */ else { char *sqlstate = PQresultErrorField(pRes, PG_DIAG_SQLSTATE); int errcode = 0; msg = PQresultErrorMessage(pRes); if (DEBUG2 >= log_min_messages) { /* * Don't use elog, it's not thread-safe */ write_log("%s -> %s %s %s", segdbDesc->whoami, PQresStatus(resultStatus), sqlstate ? sqlstate : "(no SQLSTATE)", msg ? msg : ""); } /* * Convert SQLSTATE to an error code (ERRCODE_xxx). Use a generic * nonzero error code if no SQLSTATE. */ if (sqlstate && strlen(sqlstate) == 5) errcode = sqlstate_to_errcode(sqlstate); /* * Save first error code and the index of its PGresult buffer * entry. */ cdbdisp_seterrcode(errcode, resultIndex, dispatchResult); } } if (DEBUG4 >= log_min_messages) write_log("processResultsSingle says we are finished with : %s", segdbDesc->whoami); dispatchResult->stillRunning = false; if (DEBUG1 >= log_min_messages) { char msec_str[32]; switch (check_log_duration(msec_str, false)) { case 1: case 2: write_log ("duration to dispatch result received from thread (seg %d): %s ms", dispatchResult->segdbDesc->segindex, msec_str); break; } } if (PQisBusy(dispatchResult->segdbDesc->conn)) write_log ("We thought we were done, because finished==true, but libpq says we are still busy"); } }
static bool processResults(CdbDispatchResult * dispatchResult) { SegmentDatabaseDescriptor *segdbDesc = dispatchResult->segdbDesc; char *msg; int rc; /* * PQisBusy() has side-effects */ if (DEBUG5 >= log_min_messages) { write_log("processResults. isBusy = %d", PQisBusy(segdbDesc->conn)); if (PQstatus(segdbDesc->conn) == CONNECTION_BAD) goto connection_error; } /* * Receive input from QE. */ rc = PQconsumeInput(segdbDesc->conn); /* * If PQconsumeInput fails, we're hosed. */ if (rc == 0) { /* handle PQconsumeInput error */ goto connection_error; } /* * PQisBusy() has side-effects */ if (DEBUG4 >= log_min_messages && PQisBusy(segdbDesc->conn)) write_log("PQisBusy"); /* * If we have received one or more complete messages, process them. */ while (!PQisBusy(segdbDesc->conn)) { /* loop to call PQgetResult; won't block */ PGresult *pRes; ExecStatusType resultStatus; int resultIndex; /* * PQisBusy() does some error handling, which can * cause the connection to die -- we can't just continue on as * if the connection is happy without checking first. * * For example, cdbdisp_numPGresult() will return a completely * bogus value! */ if (PQstatus(segdbDesc->conn) == CONNECTION_BAD || segdbDesc->conn->sock == -1) { goto connection_error; } resultIndex = cdbdisp_numPGresult(dispatchResult); if (DEBUG4 >= log_min_messages) write_log("PQgetResult"); /* * Get one message. */ pRes = PQgetResult(segdbDesc->conn); CollectQEWriterTransactionInformation(segdbDesc, dispatchResult); /* * Command is complete when PGgetResult() returns NULL. It is critical * that for any connection that had an asynchronous command sent thru * it, we call PQgetResult until it returns NULL. Otherwise, the next * time a command is sent to that connection, it will return an error * that there's a command pending. */ if (!pRes) { if (DEBUG4 >= log_min_messages) { /* * Don't use elog, it's not thread-safe */ write_log("%s -> idle", segdbDesc->whoami); } /* this is normal end of command */ return true; } /* end of results */ /* * Attach the PGresult object to the CdbDispatchResult object. */ cdbdisp_appendResult(dispatchResult, pRes); /* * Did a command complete successfully? */ resultStatus = PQresultStatus(pRes); if (resultStatus == PGRES_COMMAND_OK || resultStatus == PGRES_TUPLES_OK || resultStatus == PGRES_COPY_IN || resultStatus == PGRES_COPY_OUT) { /* * Save the index of the last successful PGresult. Can be given to * cdbdisp_getPGresult() to get tuple count, etc. */ dispatchResult->okindex = resultIndex; if (DEBUG3 >= log_min_messages) { /* * Don't use elog, it's not thread-safe */ char *cmdStatus = PQcmdStatus(pRes); write_log("%s -> ok %s", segdbDesc->whoami, cmdStatus ? cmdStatus : "(no cmdStatus)"); } /* * SREH - get number of rows rejected from QE if any */ if (pRes->numRejected > 0) dispatchResult->numrowsrejected += pRes->numRejected; if (resultStatus == PGRES_COPY_IN || resultStatus == PGRES_COPY_OUT) return true; } /* * Note QE error. Cancel the whole statement if requested. */ else { /* QE reported an error */ char *sqlstate = PQresultErrorField(pRes, PG_DIAG_SQLSTATE); int errcode = 0; msg = PQresultErrorMessage(pRes); if (DEBUG2 >= log_min_messages) { /* * Don't use elog, it's not thread-safe */ write_log("%s -> %s %s %s", segdbDesc->whoami, PQresStatus(resultStatus), sqlstate ? sqlstate : "(no SQLSTATE)", msg ? msg : ""); } /* * Convert SQLSTATE to an error code (ERRCODE_xxx). Use a generic * nonzero error code if no SQLSTATE. */ if (sqlstate && strlen(sqlstate) == 5) errcode = sqlstate_to_errcode(sqlstate); /* * Save first error code and the index of its PGresult buffer * entry. */ cdbdisp_seterrcode(errcode, resultIndex, dispatchResult); } } return false; /* we must keep on monitoring this socket */ connection_error: msg = PQerrorMessage(segdbDesc->conn); if (msg) write_log("Dispatcher encountered connection error on %s: %s", segdbDesc->whoami, msg); /* * Save error info for later. */ cdbdisp_appendMessage(dispatchResult, LOG, ERRCODE_GP_INTERCONNECTION_ERROR, "Error on receive from %s: %s", segdbDesc->whoami, msg ? msg : "unknown error"); /* * Can't recover, so drop the connection. */ PQfinish(segdbDesc->conn); segdbDesc->conn = NULL; dispatchResult->stillRunning = false; return true; /* connection is gone! */ }
/* Complex checking of the query status */ int pgsql_query_checkstatus(PGresult *res) { int status; int nFields; long long nTuples; /* For successful queries, there are two options: either the query returns results or not. If it does not return data, but successfully completed, then the status will be set to PGRES_COMMAND_OK. If success and returns tuples, then it will be set to PGRES_TUPLES_OK */ status = PQresultStatus(res); if (PQresultStatus(res) == PGRES_COMMAND_OK) { /* Success but no results */ IDL_Message(IDL_M_NAMED_GENERIC, IDL_MSG_INFO, PQcmdStatus(res)); return(MYPG_NO_RESULT); } if (PQresultStatus(res) != PGRES_TUPLES_OK) { IDL_Message(IDL_M_NAMED_GENERIC, IDL_MSG_INFO, PQresultErrorMessage(res)); switch (status) { /* No results */ case PGRES_COPY_IN: return(MYPG_NO_RESULT); case PGRES_COPY_OUT: return(MYPG_NO_RESULT); case PGRES_BAD_RESPONSE: return(MYPG_NO_RESULT); case PGRES_NONFATAL_ERROR: return(MYPG_NO_RESULT); /* An error */ case PGRES_FATAL_ERROR: return(MYPG_FATAL_ERROR); default: break; } } /* How many fields and rows did we return? */ nFields = PQnfields(res); nTuples = PQntuples(res); /* Result is empty, either an error or this query returns no data */ if (nTuples == 0) { if (nFields == 0) { /* Query returns no data. Try to print a message to clarify */ IDL_Message(IDL_M_NAMED_GENERIC, IDL_MSG_INFO, PQcmdStatus(res)); return(MYPG_NO_RESULT); } else /* Probably nothing matched the query */ return(MYPG_NO_RESULT); } return(MYPG_SUCCESS); }
static int aPGSQL_query(struct cw_channel *chan, void *data) { char *s1,*s2,*s3,*s4; char s[100] = ""; char *querystring; char *var; int l; int res,nres; PGconn *karoto; PGresult *PGSQLres; int id,id1; char *stringp=NULL; res=0; l=strlen(data)+2; s1=malloc(l); s2=malloc(l); strncpy(s1, data, l - 1); stringp=s1; strsep(&stringp," "); /* eat the first token, we already know it :P */ s3=strsep(&stringp," "); while (1) { /* ugly trick to make branches with break; */ var=s3; s4=strsep(&stringp," "); id=atoi(s4); querystring=strsep(&stringp,"\n"); if ((karoto=find_identifier(id,CW_PGSQL_ID_CONNID))==NULL) { cw_log(LOG_WARNING,"Invalid connection identifier %d passed in aPGSQL_query\n",id); res=-1; break; } PGSQLres=PQexec(karoto,querystring); if (PGSQLres==NULL) { cw_log(LOG_WARNING,"aPGSQL_query: Connection Error (connection identifier = %d, error message : %s)\n",id,PQerrorMessage(karoto)); res=-1; break; } if (PQresultStatus(PGSQLres) == PGRES_BAD_RESPONSE || PQresultStatus(PGSQLres) == PGRES_NONFATAL_ERROR || PQresultStatus(PGSQLres) == PGRES_FATAL_ERROR) { cw_log(LOG_WARNING,"aPGSQL_query: Query Error (connection identifier : %d, error message : %s)\n",id,PQcmdStatus(PGSQLres)); res=-1; break; } nres=PQnfields(PGSQLres); id1=add_identifier(CW_PGSQL_ID_RESID,PGSQLres); snprintf(s, sizeof(s), "%d", id1); pbx_builtin_setvar_helper(chan,var,s); break; } free(s1); free(s2); return(res); }
ngx_int_t ngx_postgres_process_response(ngx_http_request_t *r, PGresult *res) { ngx_postgres_loc_conf_t *pglcf; ngx_postgres_ctx_t *pgctx; ngx_postgres_rewrite_conf_t *pgrcf; ngx_postgres_variable_t *pgvar; ngx_str_t *store; char *affected; size_t affected_len; ngx_uint_t i; ngx_int_t rc; dd("entering"); pglcf = ngx_http_get_module_loc_conf(r, ngx_postgres_module); pgctx = ngx_http_get_module_ctx(r, ngx_postgres_module); /* set $postgres_columns */ pgctx->var_cols = PQnfields(res); /* set $postgres_rows */ pgctx->var_rows = PQntuples(res); /* set $postgres_affected */ if (ngx_strncmp(PQcmdStatus(res), "SELECT", sizeof("SELECT") - 1)) { affected = PQcmdTuples(res); affected_len = ngx_strlen(affected); if (affected_len) { pgctx->var_affected = ngx_atoi((u_char *) affected, affected_len); } } if (pglcf->rewrites) { /* process rewrites */ pgrcf = pglcf->rewrites->elts; for (i = 0; i < pglcf->rewrites->nelts; i++) { rc = pgrcf[i].handler(r, &pgrcf[i]); if (rc != NGX_DECLINED) { if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { dd("returning NGX_DONE, status %d", (int) rc); pgctx->status = rc; return NGX_DONE; } pgctx->status = rc; break; } } } if (pglcf->variables) { /* set custom variables */ pgvar = pglcf->variables->elts; store = pgctx->variables->elts; for (i = 0; i < pglcf->variables->nelts; i++) { store[i] = ngx_postgres_variable_set_custom(r, res, &pgvar[i]); if ((store[i].len == 0) && (pgvar[i].value.required)) { dd("returning NGX_DONE, status NGX_HTTP_INTERNAL_SERVER_ERROR"); pgctx->status = NGX_HTTP_INTERNAL_SERVER_ERROR; return NGX_DONE; } } } if (pglcf->output_handler) { /* generate output */ dd("returning"); return pglcf->output_handler(r, res); } dd("returning NGX_DONE"); return NGX_DONE; }
/* * PSQLexecWatch * * This function is used for \watch command to send the query to * the server and print out the results. * * Returns 1 if the query executed successfully, 0 if it cannot be repeated, * e.g., because of the interrupt, -1 on error. */ int PSQLexecWatch(const char *query, const printQueryOpt *opt) { PGresult *res; double elapsed_msec = 0; instr_time before; instr_time after; if (!pset.db) { psql_error("You are currently not connected to a database.\n"); return 0; } SetCancelConn(); if (pset.timing) INSTR_TIME_SET_CURRENT(before); res = PQexec(pset.db, query); ResetCancelConn(); if (!AcceptResult(res)) { PQclear(res); return 0; } if (pset.timing) { INSTR_TIME_SET_CURRENT(after); INSTR_TIME_SUBTRACT(after, before); elapsed_msec = INSTR_TIME_GET_MILLISEC(after); } /* * If SIGINT is sent while the query is processing, the interrupt * will be consumed. The user's intention, though, is to cancel * the entire watch process, so detect a sent cancellation request and * exit in this case. */ if (cancel_pressed) { PQclear(res); return 0; } switch (PQresultStatus(res)) { case PGRES_TUPLES_OK: printQuery(res, opt, pset.queryFout, pset.logfile); break; case PGRES_COMMAND_OK: fprintf(pset.queryFout, "%s\n%s\n\n", opt->title, PQcmdStatus(res)); break; case PGRES_EMPTY_QUERY: psql_error(_("\\watch cannot be used with an empty query\n")); PQclear(res); return -1; case PGRES_COPY_OUT: case PGRES_COPY_IN: case PGRES_COPY_BOTH: psql_error(_("\\watch cannot be used with COPY\n")); PQclear(res); return -1; default: psql_error(_("unexpected result status for \\watch\n")); PQclear(res); return -1; } PQclear(res); fflush(pset.queryFout); /* Possible microtiming output */ if (pset.timing) printf(_("Time: %.3f ms\n"), elapsed_msec); return 1; }
static void pgsql_cursor_statement_detect (GSQLCursor *cursor) { GSQL_TRACE_FUNC; gchar *stmt_char; gchar *affect = NULL; GSQLEPGSQLCursor *e_cursor = NULL; e_cursor = cursor->spec; e_cursor->count = 0; cursor->stmt_affected_rows = 0; affect = PQcmdTuples(e_cursor->result); stmt_char = PQcmdStatus (e_cursor->result); GSQL_DEBUG("STMT [%s]", stmt_char); switch (0) { case 0: if (g_str_has_prefix (stmt_char, "SELECT")) { GSQL_DEBUG ("'select' statement"); cursor->stmt_type = GSQL_CURSOR_STMT_SELECT; e_cursor->count = PQntuples(e_cursor->result); break; } if (g_str_has_prefix (stmt_char, "INSERT")) { GSQL_DEBUG ("'insert' statement"); cursor->stmt_type = GSQL_CURSOR_STMT_INSERT; cursor->stmt_affected_rows = strtoull (affect, NULL, 10); break; } if (g_str_has_prefix (stmt_char, "UPDATE")) { GSQL_DEBUG ("'update' statement"); cursor->stmt_type = GSQL_CURSOR_STMT_UPDATE; cursor->stmt_affected_rows = strtoull (affect, NULL, 10); break; } if (g_str_has_prefix (stmt_char, "DELETE")) { GSQL_DEBUG ("'delete' statement"); cursor->stmt_type = GSQL_CURSOR_STMT_DELETE; cursor->stmt_affected_rows = strtoull (affect, NULL, 10); break; } if (g_str_has_prefix (stmt_char, "CREATE")) { GSQL_DEBUG ("'create' statement"); cursor->stmt_type = GSQL_CURSOR_STMT_CREATE; break; } if (g_str_has_prefix (stmt_char, "DROP")) { GSQL_DEBUG ("'drop' statement"); cursor->stmt_type = GSQL_CURSOR_STMT_DROP; break; } if (g_str_has_prefix (stmt_char, "ALTER")) { GSQL_DEBUG ("'alter' statement"); cursor->stmt_type = GSQL_CURSOR_STMT_ALTER; break; } default: GSQL_DEBUG ("default 'exec' statement"); cursor->stmt_type = GSQL_CURSOR_STMT_EXEC; } }
/* * Receive and process input from one QE. * * Return true if all input are consumed or the connection went wrong. * Return false if there'er still more data expected. */ static bool processResults(CdbDispatchResult * dispatchResult) { SegmentDatabaseDescriptor *segdbDesc = dispatchResult->segdbDesc; char *msg; /* * Receive input from QE. */ if (PQconsumeInput(segdbDesc->conn) == 0) { msg = PQerrorMessage(segdbDesc->conn); cdbdisp_appendMessageNonThread(dispatchResult, LOG, "Error on receive from %s: %s", segdbDesc->whoami, msg ? msg : "unknown error"); return true; } /* * If we have received one or more complete messages, process them. */ while (!PQisBusy(segdbDesc->conn)) { /* loop to call PQgetResult; won't block */ PGresult *pRes; ExecStatusType resultStatus; int resultIndex; /* * PQisBusy() does some error handling, which can * cause the connection to die -- we can't just continue on as * if the connection is happy without checking first. * * For example, cdbdisp_numPGresult() will return a completely * bogus value! */ if (cdbconn_isBadConnection(segdbDesc)) { msg = PQerrorMessage(segdbDesc->conn); cdbdisp_appendMessageNonThread(dispatchResult, LOG, "Connection lost when receiving from %s: %s", segdbDesc->whoami, msg ? msg : "unknown error"); return true; } /* * Get one message. */ ELOG_DISPATCHER_DEBUG("PQgetResult"); pRes = PQgetResult(segdbDesc->conn); /* * Command is complete when PGgetResult() returns NULL. It is critical * that for any connection that had an asynchronous command sent thru * it, we call PQgetResult until it returns NULL. Otherwise, the next * time a command is sent to that connection, it will return an error * that there's a command pending. */ if (!pRes) { ELOG_DISPATCHER_DEBUG("%s -> idle", segdbDesc->whoami); /* this is normal end of command */ return true; } /* * Attach the PGresult object to the CdbDispatchResult object. */ resultIndex = cdbdisp_numPGresult(dispatchResult); cdbdisp_appendResult(dispatchResult, pRes); /* * Did a command complete successfully? */ resultStatus = PQresultStatus(pRes); if (resultStatus == PGRES_COMMAND_OK || resultStatus == PGRES_TUPLES_OK || resultStatus == PGRES_COPY_IN || resultStatus == PGRES_COPY_OUT || resultStatus == PGRES_EMPTY_QUERY) { ELOG_DISPATCHER_DEBUG("%s -> ok %s", segdbDesc->whoami, PQcmdStatus(pRes) ? PQcmdStatus(pRes) : "(no cmdStatus)"); if (resultStatus == PGRES_EMPTY_QUERY) ELOG_DISPATCHER_DEBUG("QE received empty query."); /* * Save the index of the last successful PGresult. Can be given to * cdbdisp_getPGresult() to get tuple count, etc. */ dispatchResult->okindex = resultIndex; /* * SREH - get number of rows rejected from QE if any */ if (pRes->numRejected > 0) dispatchResult->numrowsrejected += pRes->numRejected; if (resultStatus == PGRES_COPY_IN || resultStatus == PGRES_COPY_OUT) return true; } /* * Note QE error. Cancel the whole statement if requested. */ else { /* QE reported an error */ char *sqlstate = PQresultErrorField(pRes, PG_DIAG_SQLSTATE); int errcode = 0; msg = PQresultErrorMessage(pRes); ELOG_DISPATCHER_DEBUG("%s -> %s %s %s", segdbDesc->whoami, PQresStatus(resultStatus), sqlstate ? sqlstate : "(no SQLSTATE)", msg); /* * Convert SQLSTATE to an error code (ERRCODE_xxx). Use a generic * nonzero error code if no SQLSTATE. */ if (sqlstate && strlen(sqlstate) == 5) errcode = sqlstate_to_errcode(sqlstate); /* * Save first error code and the index of its PGresult buffer * entry. */ cdbdisp_seterrcode(errcode, resultIndex, dispatchResult); } } return false; /* we must keep on monitoring this socket */ }