Skip to content

Instantly share code, notes, and snippets.

@macdice
Created July 27, 2016 02:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save macdice/a1680c9a852158dfb6a149a332a9bf93 to your computer and use it in GitHub Desktop.
Save macdice/a1680c9a852158dfb6a149a332a9bf93 to your computer and use it in GitHub Desktop.
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 1e3ecbc..7958f9e 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -3083,7 +3083,7 @@ errorMissingColumn(ParseState *pstate,
errmsg("column %s.%s does not exist", relname, colname) :
errmsg("column \"%s\" does not exist", colname),
state->rfirst ? closestfirst ?
- errhint("Perhaps you meant to reference the column \"%s.%s\".",
+ errhint("Perhaps you meant to reference the column \"%s\".\"%s\".",
state->rfirst->eref->aliasname, closestfirst) :
errhint("There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query.",
colname, state->rfirst->eref->aliasname) : 0,
@@ -3102,7 +3102,7 @@ errorMissingColumn(ParseState *pstate,
relname ?
errmsg("column %s.%s does not exist", relname, colname) :
errmsg("column \"%s\" does not exist", colname),
- errhint("Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\".",
+ errhint("Perhaps you meant to reference the column \"%s\".\"%s\" or the column \"%s\".\"%s\".",
state->rfirst->eref->aliasname, closestfirst,
state->rsecond->eref->aliasname, closestsecond),
parser_errposition(pstate, location)));
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 3f2cebf..d39b85c 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -613,6 +613,105 @@ exec_command(const char *cmd,
}
}
+ else if (strcmp(cmd, "yes") == 0)
+ {
+ if (!query_buf)
+ {
+ psql_error("no query buffer\n");
+ status = PSQL_CMD_ERROR;
+ }
+ else
+ {
+ bool found = false;
+
+ if (pset.last_error_result != NULL ||
+ PQresultStatus(pset.last_error_result) != PGRES_NONFATAL_ERROR)
+ {
+ char *hint = PQresultErrorField(pset.last_error_result,
+ PG_DIAG_MESSAGE_HINT);
+ char *position = PQresultErrorField(pset.last_error_result,
+ PG_DIAG_STATEMENT_POSITION);
+
+ /*
+ * Here follows some truly awful code that depends on the
+ * exact wording of a hint, only works for English, and then
+ * does horrific pointer arithmetic string manipulation.
+ * - Anonymous
+ */
+
+ if (position != NULL &&
+ hint != NULL &&
+ strstr(hint, "Perhaps you meant to reference the ") == hint)
+ {
+ int begin_old = atoi(position);
+ int end_old = begin_old;
+ int begin_new = -1;
+ int end_new = -1;
+ char *s;
+
+ /* Find the end of the old indentifier. */
+ for (;;)
+ {
+ /** TODO: Deal with quoted identifiers */
+ if (query_buf->data[end_old] == '\0' ||
+ query_buf->data[end_old] == ' ')
+ break;
+ end_old++;
+ }
+
+ /* Find the new identifier. */
+ s = strchr(hint, '\"');
+ if (s != NULL)
+ {
+ begin_new = s - hint;
+ s = strchr(s + 1, '"');
+ if (s != NULL)
+ {
+ ++s;
+ /* May be followed by ."xxx" */
+ if (*s == '.')
+ {
+ ++s;
+ if (*s == '"' && (s = strchr(s + 1, '"')) != NULL)
+ {
+ ++s;
+ end_new = s - hint;
+ }
+ }
+ else
+ end_new = s - hint;
+ }
+ }
+
+ if (begin_new != -1 && end_new != -1)
+ {
+ char *new_query = malloc(begin_old +
+ (end_new - begin_new) +
+ (strlen(query_buf->data) - end_old) +
+ 1);
+
+ new_query[0] = '\0';
+ strncat(new_query, query_buf->data, begin_old - 1);
+ strncat(new_query, hint + begin_new, end_new - begin_new);
+ strcat(new_query, query_buf->data + end_old);
+
+ resetPQExpBuffer(query_buf);
+ appendPQExpBuffer(query_buf, "%s", new_query);
+ free(new_query);
+ status = PSQL_CMD_NEWEDIT;
+ found = true;
+ }
+ }
+ }
+
+ if (!found)
+ {
+ psql_error("there is no suggested correction\n");
+ status = PSQL_CMD_ERROR;
+ }
+ }
+ }
+
/*
* \ef -- edit the named function, or present a blank CREATE FUNCTION
* template if no argument is given
@macdice
Copy link
Author

macdice commented Jul 27, 2016

postgres=# select toth_count from walrus;
ERROR:  column "toth_count" does not exist
LINE 1: select toth_count from walrus;
               ^
HINT:  Perhaps you meant to reference the column "walrus"."tooth_count".
postgres=# \yes
┌─────────────┐
│ tooth_count │
├─────────────┤
│           2 │
└─────────────┘
(1 row)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment