one idea could be to actually prepare a query using SPI for "select * from table order by <cols>" and then peek inside to see which plan was generated. perhaps you could do this using the existing planner hook.
you might have to watch out for the user's rules or planner hooks (though I don't think referential integrity triggers take any precautions about those dangers) greg On 20 Jan 2010 17:48, "Leonardo F" <m_li...@yahoo.it> wrote: > I read the thread "Our CLUSTER implementation is pessimal" > http://archives.postgresql.org/pgsql... I think I got something up and running to check if a table scan + sort is supposed to be faster than an index scan for a certain CLUSTER operation. The way I did it is (I guess...) wrong: I created the elements needed by get_relation_info, create_seqscan_path, create_index_path, cost_sort. It has been, obviously, a trial and error approach: I added the member values as soon as one function call crashed... and I bet I didn't get all the corner cases. Is there any better way of doing it? Leonardo (this is called in copy_heap_data to decide which path to choose:) static bool use_index_scan(Oid tableOid, Oid indexOid) { RelOptInfo *rel; PlannerInfo *root; Query *query; PlannerGlobal *glob; Path *seqAndSortPath; IndexPath *indexPath; RangeTblEntry *rte; rel = makeNode(RelOptInfo); rel->reloptkind = RELOPT_BASEREL; rel->relid = 1; rel->rtekind = RTE_RELATION; /* needed by get_relation_info */ glob = makeNode(PlannerGlobal); /* needed by get_relation_info: */ query = makeNode(Query); query->resultRelation = 0; root = makeNode(PlannerInfo); root->parse = query; root->glob = glob; get_relation_info(root, tableOid, false, rel); seqAndSortPath = create_seqscan_path(NULL, rel); rel->rows = rel->tuples; rte = makeNode(RangeTblEntry); rte->rtekind = RTE_RELATION; rte->relid = tableOid; root->simple_rel_array_size = 2; root->simple_rte_array = (RangeTblEntry **) palloc0(root->simple_rel_array_size * sizeof(RangeTblEntry *)); root->simple_rte_array[1] = rte; root->total_table_pages = rel->pages; indexPath = create_index_path(root, (IndexOptInfo*)(list_head(rel->indexlist)->data.ptr_value), NULL, NULL, ForwardScanDirection, NULL); cost_sort(seqAndSortPath, root, NULL, seqAndSortPath->total_cost, rel->tuples, rel->width, -1); return indexPath->path.total_cost < seqAndSortPath->total_cost; } -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to you...