Well, I do a query like this: "SELECT * FROM historial WHERE
id_grupo=grupo_hist ORDER BY grmemb LIMIT 10;", then in transformSortClause
I know it this way:

 /*
 * transformSortClause -
 *      transform an ORDER BY clause
 *
 * ORDER BY items will be added to the targetlist (as resjunk columns)
 * if not already present, so the targetlist must be passed by reference.
 */
List *
transformSortClause(ParseState *pstate,
                    List *orderlist,
                    List **targetlist,
                    bool resolveUnknown)
{
    List       *sortlist = NIL;
    ListCell   *olitem;

    foreach(olitem, orderlist)
    {
        SortBy       *sortby = lfirst(olitem);
        TargetEntry *tle;
        //To find out if it is the membership degree
        char       *namegrmemb = strVal(linitial(((ColumnRef *)
sortby->node)->fields));

        *if (strcmp(namegrmemb, "grmemb")==0)
*            tle = createTargetFuzzyEntry(targetlist);
        else
            tle = findTargetlistEntry(pstate, sortby->node,
                                      targetlist, ORDER_CLAUSE);

        sortlist = addTargetToSortList(pstate, tle,
                                       sortlist, *targetlist,
                                       sortby->sortby_dir,
                                       sortby->sortby_nulls,
                                       sortby->useOp,
                                       resolveUnknown);



    }

    return sortlist;
}

|***************************************************************************************************************************|

Then I created a function that includes a new target entry in the
targetlist:

//To sort the membership degree
TargetEntry *
createTargetFuzzyEntry(List **targetlist){

    /*I just have to create the fuzzy target entry right here */
    TargetEntry    *tfp = makeNode(TargetEntry);
    Const   *cn = makeNode(Const);
    float    val = 1.0;
    TargetEntry *tlast = list_nth(*targetlist, list_length(*targetlist)-1);

    cn = makeConst(700, -1, 4, (Float4GetDatum(val)), false, true);
    tfp->resorigtbl=tlast->resorigtbl;
    tfp->expr = (Expr *) cn;
    tfp->resno = list_length(*targetlist) + 1;
    tfp->resname = "grmemb";
    tfp->resorigcol = list_length(*targetlist) + 1;
    tfp->ressortgroupref = 0;
    tfp->resjunk = false;

    *targetlist = lappend(*targetlist, tfp);

    return tfp;
}

|*************************************************************************************************************************|

Later in planner.c on grouping_planner function I do something like this:

/*
     * If we were not able to make the plan come out in the right order, add
     * an explicit sort step.
     */
    if (parse->sortClause)
    {
        if (!pathkeys_contained_in(sort_pathkeys, current_pathkeys) ||
parse->hasGrMemb)
        {
            result_plan = (Plan *) make_sort_from_pathkeys(root,
                                                           result_plan,
                                                           sort_pathkeys,
                                                           limit_tuples);
            current_pathkeys = sort_pathkeys;
        }
    }


2009/4/26 Martijn van Oosterhout <klep...@svana.org>

> On Sun, Apr 26, 2009 at 04:20:41PM -0430, Werner Echezuria wrote:
> > Hi, I've been trying to sort a column that performs some calculations,
> but
> > postgres says this: ERROR:  invalid attnum: -12851. I was searching on
> the
> > source code, and I guess the error araises around this macro:
>
> I'm pretty sure this is a "not supposed to happen" thing. Do you have a
> repoducable test case? Also, what version of postgres?
>
> > /*
> >      * Copy the given tuple into memory we control, and decrease
> availMem.
> >      * Then call the common code.
> >      */
> >     COPYTUP(state, &stup, (void *) slot);
> >
> > So, I'd like to know what COPYTUP does?, what is availMem?, How can I
> tell
> > postgres it is a valid attnum?
>
> COPYTUP does exactly what the comment says it does. I'm guessing this
> is in the sort code somewhere? An "attnum" is a column number, like the
> first column is attnum 1. Attnum -12851 is definitly bogus.
>
> Have a nice day,
> --
> Martijn van Oosterhout   <klep...@svana.org>   http://svana.org/kleptog/
> > Please line up in a tree and maintain the heap invariant while
> > boarding. Thank you for flying nlogn airlines.
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (GNU/Linux)
>
> iD8DBQFJ9M7xIB7bNG8LQkwRAviuAJ9F9GeldnVLInum3ZaT0IKTNvk3dACdElyo
> 7VZ7cLAgu1q4PncHS8rVYJU=
> =Y5Qw
> -----END PGP SIGNATURE-----
>
>

Reply via email to