Skip to content

Instantly share code, notes, and snippets.

@macdice
Created July 27, 2016 02:36
Show Gist options
  • Save macdice/a1680c9a852158dfb6a149a332a9bf93 to your computer and use it in GitHub Desktop.
Save macdice/a1680c9a852158dfb6a149a332a9bf93 to your computer and use it in GitHub Desktop.

Revisions

  1. macdice created this gist Jul 27, 2016.
    132 changes: 132 additions & 0 deletions yes.patch
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,132 @@
    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