Improve parser error location for cases where an INSERT or UPDATE command
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 7 Oct 2008 01:47:55 +0000 (01:47 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 7 Oct 2008 01:47:55 +0000 (01:47 +0000)
supplies an expression that can't be coerced to the target column type.
The code previously attempted to point at the target column name, which
doesn't work at all in an INSERT with omitted column name list, and is
also not remarkably helpful when the problem is buried somewhere in a
long INSERT-multi-VALUES command.  Make it point at the failed expression
instead.

src/backend/parser/analyze.c
src/backend/parser/parse_target.c

index e55eec0b8fc9afe4c46042ab6e852d6a4d4c46df..ac2c7ba84cf3a5de0bc101db05ed864184ba03dd 100644 (file)
@@ -426,11 +426,15 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
                                exprType((Node *) tle->expr) == UNKNOWNOID)
                                expr = tle->expr;
                        else
-                               expr = (Expr *) makeVar(rtr->rtindex,
-                                                                               tle->resno,
-                                                                               exprType((Node *) tle->expr),
-                                                                               exprTypmod((Node *) tle->expr),
-                                                                               0);
+                       {
+                               Var        *var = makeVar(rtr->rtindex,
+                                                                         tle->resno,
+                                                                         exprType((Node *) tle->expr),
+                                                                         exprTypmod((Node *) tle->expr),
+                                                                         0);
+                               var->location = exprLocation((Node *) tle->expr);
+                               expr = (Expr *) var;
+                       }
                        exprList = lappend(exprList, expr);
                }
 
index 4fedc6299a5e239ea0bc9159c825b38ff6fbb6d1..1f19131ae20e9360486a6ad9c7847f60340feaa3 100644 (file)
@@ -343,6 +343,11 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
  * location            error cursor position for the target column, or -1
  *
  * Returns the modified expression.
+ *
+ * Note: location points at the target column name (SET target or INSERT
+ * column name list entry), and must therefore be -1 in an INSERT that
+ * omits the column name list.  So we should usually prefer to use
+ * exprLocation(expr) for errors that can happen in a default INSERT.
  */
 Expr *
 transformAssignedExpr(ParseState *pstate,
@@ -446,9 +451,11 @@ transformAssignedExpr(ParseState *pstate,
                 * For normal non-qualified target column, do type checking and
                 * coercion.
                 */
+               Node   *orig_expr = (Node *) expr;
+
                expr = (Expr *)
                        coerce_to_target_type(pstate,
-                                                                 (Node *) expr, type_id,
+                                                                 orig_expr, type_id,
                                                                  attrtype, attrtypmod,
                                                                  COERCION_ASSIGNMENT,
                                                                  COERCE_IMPLICIT_CAST,
@@ -462,7 +469,7 @@ transformAssignedExpr(ParseState *pstate,
                                                        format_type_be(attrtype),
                                                        format_type_be(type_id)),
                                 errhint("You will need to rewrite or cast the expression."),
-                                        parser_errposition(pstate, location)));
+                                        parser_errposition(pstate, exprLocation(orig_expr))));
        }
 
        return expr;