Message-ID: From: "maimai3478 (@maimai3478)" To: "pgjdbc/pgjdbc" Date: Wed, 24 Jul 2019 05:06:14 +0000 Subject: Re: [pgjdbc/pgjdbc] issue #1136: Show SQL text (and/or binds) in SQLException message In-Reply-To: References: List-Id: X-GitHub-Author-Login: maimai3478 X-GitHub-Comment-Id: 514481089 X-GitHub-Comment-Type: issue_comment X-GitHub-Edited-At: 2019-07-24T05:17:25Z X-GitHub-Issue: 1136 X-GitHub-Repo: pgjdbc/pgjdbc X-GitHub-Type: comment X-GitHub-Url: https://github.com/pgjdbc/pgjdbc/issues/1136#issuecomment-514481089 Content-Type: text/plain; charset=utf-8 > In this case, are more details not possible to be retrieved from the server? I saw the PostgreSQL codes and it seems me it only generate the error message like "syntax error at or near...". I couldn't find the logic which add more details to error message by the server settings during seeing codes. That error is generated in during parsing SQL statement. https://github.com/postgres/postgres/blob/7d81bdc8c0ce838efa248928065e9b2da829f981/src/backend/parser/scan.l#L1145-L1149 ``` ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), /* translator: first %s is typically the translation of "syntax error" */ errmsg("%s at or near \"%s\"", _(message), loc), lexer_errposition())); ``` ereport() is defined like this. https://github.com/postgres/postgres/blob/fd7d387e0548fd371c06a91d75bc4632541ccfdd/src/include/utils/elog.h#L120-L142 ``` #ifdef HAVE__BUILTIN_CONSTANT_P #define ereport_domain(elevel, domain, rest) \ do { \ pg_prevent_errno_in_scope(); \ if (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \ errfinish rest; \ if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \ pg_unreachable(); \ } while(0) #else /* !HAVE__BUILTIN_CONSTANT_P */ #define ereport_domain(elevel, domain, rest) \ do { \ const int elevel_ = (elevel); \ pg_prevent_errno_in_scope(); \ if (errstart(elevel_, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \ errfinish rest; \ if (elevel_ >= ERROR) \ pg_unreachable(); \ } while(0) #endif /* HAVE__BUILTIN_CONSTANT_P */ #define ereport(elevel, rest) \ ereport_domain(elevel, TEXTDOMAIN, rest) ``` errstart() creates an error stack entry and store the given parameters in it. https://github.com/postgres/postgres/blob/fd7d387e0548fd371c06a91d75bc4632541ccfdd/src/backend/utils/error/elog.c#L360-L365 ``` bool errstart(int elevel, const char *filename, int lineno, const char *funcname, const char *domain) { ... /* Initialize data for this error frame */ edata = &errordata[errordata_stack_depth]; MemSet(edata, 0, sizeof(ErrorData)); edata->elevel = elevel; edata->output_to_server = output_to_server; edata->output_to_client = output_to_client; ``` The message "syntax error at or near..." is stored in stack entry at errmsg(). https://github.com/postgres/postgres/blob/fd7d387e0548fd371c06a91d75bc4632541ccfdd/src/backend/utils/error/elog.c#L793 ``` errmsg(const char *fmt,...) { ... edata->message_id = fmt; ``` errfinish() actually process the error report. https://github.com/postgres/postgres/blob/fd7d387e0548fd371c06a91d75bc4632541ccfdd/src/backend/utils/error/elog.c#L464 https://github.com/postgres/postgres/blob/fd7d387e0548fd371c06a91d75bc4632541ccfdd/src/backend/utils/error/elog.c#L1712-L1720 Process jump to Postgresmain and finally EmitErrorReport() will send the error message to client. https://github.com/postgres/postgres/blob/fd7d387e0548fd371c06a91d75bc4632541ccfdd/src/backend/tcop/postgres.c#L4044 ``` PostgresMain(int argc, char *argv[], const char *dbname, const char *username) { ... EmitErrorReport(); ``` (I'm sorry for not knowing how to cite other repositories source code correctly...)