diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-09-01 20:42:46 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-09-01 20:42:46 +0000 |
commit | b153c0920960a6059b67969469166fb29c0105d7 (patch) | |
tree | 4e7100ecdca88746c369ae2a6a43468925f3194d /src/backend/parser/parse_expr.c | |
parent | 9ac4299163247645c6e391f5f65735c6cb78ccb9 (diff) | |
download | postgresql-b153c0920960a6059b67969469166fb29c0105d7.tar.gz postgresql-b153c0920960a6059b67969469166fb29c0105d7.zip |
Add a bunch of new error location reports to parse-analysis error messages.
There are still some weak spots around JOIN USING and relation alias lists,
but most errors reported within backend/parser/ now have locations.
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r-- | src/backend/parser/parse_expr.c | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 8496e7291c1..1091d87473d 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.233 2008/08/30 01:39:14 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.234 2008/09/01 20:42:44 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -122,7 +122,7 @@ transformExpr(ParseState *pstate, Node *expr) A_Const *con = (A_Const *) expr; Value *val = &con->val; - result = (Node *) make_const(val, con->location); + result = (Node *) make_const(pstate, val, con->location); break; } @@ -454,6 +454,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref) * "rel.*". */ if (refnameRangeTblEntry(pstate, NULL, name1, + cref->location, &levels_up) != NULL) node = transformWholeRowRef(pstate, NULL, name1, cref->location); @@ -621,7 +622,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref) * return a pointer to it. */ static Oid * -find_param_type(ParseState *pstate, int paramno) +find_param_type(ParseState *pstate, int paramno, int location) { Oid *result; @@ -635,14 +636,15 @@ find_param_type(ParseState *pstate, int paramno) if (paramno <= 0) /* probably can't happen? */ ereport(ERROR, (errcode(ERRCODE_UNDEFINED_PARAMETER), - errmsg("there is no parameter $%d", paramno))); + errmsg("there is no parameter $%d", paramno), + parser_errposition(pstate, location))); if (paramno > pstate->p_numparams) { if (!pstate->p_variableparams) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_PARAMETER), - errmsg("there is no parameter $%d", - paramno))); + errmsg("there is no parameter $%d", paramno), + parser_errposition(pstate, location))); /* Okay to enlarge param array */ if (pstate->p_paramtypes) pstate->p_paramtypes = (Oid *) repalloc(pstate->p_paramtypes, @@ -672,7 +674,7 @@ static Node * transformParamRef(ParseState *pstate, ParamRef *pref) { int paramno = pref->number; - Oid *pptype = find_param_type(pstate, paramno); + Oid *pptype = find_param_type(pstate, paramno, pref->location); Param *param; param = makeNode(Param); @@ -1235,10 +1237,22 @@ transformSubLink(ParseState *pstate, SubLink *sublink) pstate->p_hasSubLinks = true; qtree = parse_sub_analyze(sublink->subselect, pstate); - if (qtree->commandType != CMD_SELECT || - qtree->utilityStmt != NULL || - qtree->intoClause != NULL) - elog(ERROR, "bad query in sub-select"); + + /* + * Check that we got something reasonable. Many of these conditions are + * impossible given restrictions of the grammar, but check 'em anyway. + */ + if (!IsA(qtree, Query) || + qtree->commandType != CMD_SELECT || + qtree->utilityStmt != NULL) + elog(ERROR, "unexpected non-SELECT command in SubLink"); + if (qtree->intoClause) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("subquery cannot have SELECT INTO"), + parser_errposition(pstate, + exprLocation((Node *) qtree->intoClause)))); + sublink->subselect = (Node *) qtree; if (sublink->subLinkType == EXISTS_SUBLINK) @@ -1445,7 +1459,8 @@ transformArrayExpr(ParseState *pstate, A_ArrayExpr *a, ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("could not find element type for data type %s", - format_type_be(array_type)))); + format_type_be(array_type)), + parser_errposition(pstate, a->location))); } else { @@ -1455,7 +1470,8 @@ transformArrayExpr(ParseState *pstate, A_ArrayExpr *a, ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("could not find array type for data type %s", - format_type_be(element_type)))); + format_type_be(element_type)), + parser_errposition(pstate, a->location))); } coerce_hard = false; } @@ -1823,7 +1839,7 @@ transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr) /* If a parameter is used, it must be of type REFCURSOR */ if (cexpr->cursor_name == NULL) { - Oid *pptype = find_param_type(pstate, cexpr->cursor_param); + Oid *pptype = find_param_type(pstate, cexpr->cursor_param, -1); if (pstate->p_variableparams && *pptype == UNKNOWNOID) { @@ -1866,12 +1882,12 @@ transformWholeRowRef(ParseState *pstate, char *schemaname, char *relname, /* Look up the referenced RTE, creating it if needed */ - rte = refnameRangeTblEntry(pstate, schemaname, relname, + rte = refnameRangeTblEntry(pstate, schemaname, relname, location, &sublevels_up); if (rte == NULL) - rte = addImplicitRTE(pstate, makeRangeVar(schemaname, relname), - location); + rte = addImplicitRTE(pstate, + makeRangeVar(schemaname, relname, location)); vnum = RTERangeTablePosn(pstate, rte, &sublevels_up); |