Handle case of GROUP BY target list column number out of range.

This commit is contained in:
Thomas G. Lockhart 1998-07-09 14:34:05 +00:00
parent a3c9cce930
commit fa2a1d7d52
1 changed files with 39 additions and 21 deletions

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.19 1998/07/08 14:04:10 thomas Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.20 1998/07/09 14:34:05 thomas Exp $
*
*-------------------------------------------------------------------------
*/
@ -136,12 +136,12 @@ parseFromClause(ParseState *pstate, List *frmList)
static TargetEntry *
find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
{
List *i;
int real_rtable_pos = 0,
target_pos = 0;
List *i;
int real_rtable_pos = 0,
target_pos = 0;
TargetEntry *target_result = NULL;
if (sortgroupby->range)
if (sortgroupby->range != NULL)
real_rtable_pos = refnameRangeTablePosn(pstate, sortgroupby->range, NULL);
foreach(i, tlist)
@ -152,7 +152,8 @@ find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
char *resname = resnode->resname;
int test_rtable_pos = var->varno;
if (!sortgroupby->name)
/* no name specified? then must have been a column number instead... */
if (sortgroupby->name == NULL)
{
if (sortgroupby->resno == ++target_pos)
{
@ -160,11 +161,13 @@ find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
break;
}
}
/* otherwise, try to match name... */
else
{
if (!strcmp(resname, sortgroupby->name))
/* same name? */
if (strcmp(resname, sortgroupby->name) == 0)
{
if (sortgroupby->range)
if (sortgroupby->range != NULL)
{
if (real_rtable_pos == test_rtable_pos)
{
@ -185,20 +188,33 @@ find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
}
}
/* BEGIN add missing target entry hack.
/* No name specified and no target found?
* Then must have been an out-of-range column number instead...
* - thomas 1998-07-09
*/
if ((sortgroupby->name == NULL) && (target_result == NULL))
{
elog(ERROR, "ORDER/GROUP BY position %d is not in target list",
sortgroupby->resno);
}
/* BEGIN add missing target entry hack.
*
* Prior to this hack, this function returned NIL if no target_result.
* Thus, ORDER/GROUP BY required the attributes be in the target list.
* Now it constructs a new target entry which is appended to the end of
* the target list. This target is set to be resjunk = TRUE so that
* it will not be projected into the final tuple.
* daveh@insightdist.com 5/20/98
* Prior to this hack, this function returned NIL if no target_result.
* Thus, ORDER/GROUP BY required the attributes be in the target list.
* Now it constructs a new target entry which is appended to the end of
* the target list. This target is set to be resjunk = TRUE so that
* it will not be projected into the final tuple.
* daveh@insightdist.com 5/20/98
*/
if ( ! target_result && sortgroupby->name) {
if ((target_result == NULL) && (sortgroupby->name != NULL)) {
List *p_target = tlist;
TargetEntry *tent = makeNode(TargetEntry);
if (sortgroupby->range) {
if (sortgroupby->range != NULL) {
Attr *missingAttr = (Attr *)makeNode(Attr);
missingAttr->type = T_Attr;
@ -211,7 +227,8 @@ find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
&missingAttr->relname, NULL,
missingAttr->relname, TRUE);
}
else {
else
{
Ident *missingIdent = (Ident *)makeNode(Ident);
missingIdent->type = T_Ident;
@ -224,7 +241,7 @@ find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
}
/* Add to the end of the target list */
while (lnext(p_target) != NIL) {
while (lnext(p_target) != NIL) {
p_target = lnext(p_target);
}
lnext(p_target) = lcons(tent, NIL);
@ -253,6 +270,7 @@ transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
Resdom *resdom;
restarget = find_targetlist_entry(pstate, lfirst(grouplist), targetlist);
grpcl->entry = restarget;
resdom = restarget->resdom;
grpcl->grpOpoid = oprid(oper("<",
@ -306,8 +324,8 @@ transformSortClause(ParseState *pstate,
TargetEntry *restarget;
Resdom *resdom;
restarget = find_targetlist_entry(pstate, sortby, targetlist);
sortcl->resdom = resdom = restarget->resdom;
sortcl->opoid = oprid(oper(sortby->useOp,
resdom->restype,