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----- > >