1997-02-19 13:59:07 +01:00
|
|
|
/*------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* geqo_misc.c
|
1997-09-07 07:04:48 +02:00
|
|
|
* misc. printout and debug stuff
|
1997-02-19 13:59:07 +01:00
|
|
|
*
|
2002-06-20 22:29:54 +02:00
|
|
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1997-02-19 13:59:07 +01:00
|
|
|
*
|
2002-09-04 22:31:48 +02:00
|
|
|
* $Id: geqo_misc.c,v 1.34 2002/09/04 20:31:20 momjian Exp $
|
1997-02-19 13:59:07 +01:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* contributed by:
|
|
|
|
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
|
1997-09-07 07:04:48 +02:00
|
|
|
* Martin Utesch * Institute of Automatic Control *
|
|
|
|
= = University of Mining and Technology =
|
|
|
|
* utesch@aut.tu-freiberg.de * Freiberg, Germany *
|
1997-02-19 13:59:07 +01:00
|
|
|
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "postgres.h"
|
1999-08-16 04:17:58 +02:00
|
|
|
|
1997-02-19 13:59:07 +01:00
|
|
|
#include "optimizer/geqo_misc.h"
|
1999-08-16 04:17:58 +02:00
|
|
|
#include "nodes/print.h"
|
|
|
|
|
2002-07-20 06:59:10 +02:00
|
|
|
#ifdef GEQO_DEBUG
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1997-09-08 23:56:23 +02:00
|
|
|
static float avg_pool(Pool *pool);
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1999-02-14 00:22:53 +01:00
|
|
|
/* avg_pool
|
1997-02-19 13:59:07 +01:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
static float
|
1997-09-08 23:56:23 +02:00
|
|
|
avg_pool(Pool *pool)
|
1997-02-19 13:59:07 +01:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int i;
|
|
|
|
double cumulative = 0.0;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
if (pool->size == 0)
|
1998-01-07 22:07:04 +01:00
|
|
|
elog(ERROR, "avg_pool: pool_size of zero");
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
for (i = 0; i < pool->size; i++)
|
|
|
|
cumulative = cumulative + pool->data[i].worth;
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return (float) cumulative / pool->size;
|
1997-02-19 13:59:07 +01:00
|
|
|
}
|
|
|
|
|
1999-02-14 00:22:53 +01:00
|
|
|
/* print_pool
|
1997-02-19 13:59:07 +01:00
|
|
|
*/
|
|
|
|
void
|
1997-09-08 23:56:23 +02:00
|
|
|
print_pool(FILE *fp, Pool *pool, int start, int stop)
|
1997-02-19 13:59:07 +01:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int i,
|
|
|
|
j;
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/* be extra careful that start and stop are valid inputs */
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
if (start < 0)
|
|
|
|
start = 0;
|
|
|
|
if (stop > pool->size)
|
|
|
|
stop = pool->size;
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
if (start + stop > pool->size)
|
|
|
|
{
|
|
|
|
start = 0;
|
|
|
|
stop = pool->size;
|
1997-02-19 13:59:07 +01:00
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
for (i = start; i < stop; i++)
|
|
|
|
{
|
|
|
|
fprintf(fp, "%d)\t", i);
|
|
|
|
for (j = 0; j < pool->string_length; j++)
|
|
|
|
fprintf(fp, "%d ", pool->data[i].string[j]);
|
|
|
|
fprintf(fp, "%f\n", pool->data[i].worth);
|
1997-02-19 13:59:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-02-14 00:22:53 +01:00
|
|
|
/* print_gen
|
1997-02-19 13:59:07 +01:00
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* printout for chromosome: best, worst, mean, average
|
1997-02-19 13:59:07 +01:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
void
|
1997-09-08 23:56:23 +02:00
|
|
|
print_gen(FILE *fp, Pool *pool, int generation)
|
1997-02-19 13:59:07 +01:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int lowest;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
/* Get index to lowest ranking gene in poplulation. */
|
|
|
|
/* Use 2nd to last since last is buffer. */
|
|
|
|
lowest = pool->size > 1 ? pool->size - 2 : 0;
|
|
|
|
|
|
|
|
fprintf(fp,
|
2002-07-20 06:59:10 +02:00
|
|
|
"%5d | Best: %f Worst: %f Mean: %f Avg: %f\n",
|
1997-09-07 07:04:48 +02:00
|
|
|
generation,
|
|
|
|
pool->data[0].worth,
|
|
|
|
pool->data[lowest].worth,
|
|
|
|
pool->data[pool->size / 2].worth,
|
|
|
|
avg_pool(pool));
|
1997-02-19 13:59:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
1997-09-08 23:56:23 +02:00
|
|
|
print_edge_table(FILE *fp, Edge *edge_table, int num_gene)
|
1997-02-19 13:59:07 +01:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int i,
|
|
|
|
j;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
fprintf(fp, "\nEDGE TABLE\n");
|
|
|
|
|
|
|
|
for (i = 1; i <= num_gene; i++)
|
|
|
|
{
|
|
|
|
fprintf(fp, "%d :", i);
|
|
|
|
for (j = 0; j < edge_table[i].unused_edges; j++)
|
|
|
|
fprintf(fp, " %d", edge_table[i].edge_list[j]);
|
|
|
|
fprintf(fp, "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(fp, "\n");
|
1997-02-19 13:59:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************
|
|
|
|
Debug output subroutines
|
|
|
|
*************************************************************/
|
|
|
|
|
|
|
|
void
|
1997-09-08 23:56:23 +02:00
|
|
|
geqo_print_joinclauses(Query *root, List *clauses)
|
1997-02-19 13:59:07 +01:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
List *l;
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
foreach(l, clauses)
|
|
|
|
{
|
1999-02-03 21:15:53 +01:00
|
|
|
RestrictInfo *c = lfirst(l);
|
1997-02-19 13:59:07 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
print_expr((Node *) c->clause, root->rtable);
|
|
|
|
if (lnext(l))
|
|
|
|
printf(" ");
|
|
|
|
}
|
1997-02-19 13:59:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1997-09-08 23:56:23 +02:00
|
|
|
geqo_print_path(Query *root, Path *path, int indent)
|
1997-02-19 13:59:07 +01:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
char *ptype = NULL;
|
1999-02-12 18:25:05 +01:00
|
|
|
JoinPath *jp;
|
1997-09-08 04:41:22 +02:00
|
|
|
bool join = false;
|
|
|
|
int i;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
for (i = 0; i < indent; i++)
|
|
|
|
printf("\t");
|
|
|
|
|
|
|
|
switch (nodeTag(path))
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
case T_Path:
|
|
|
|
ptype = "SeqScan";
|
|
|
|
join = false;
|
|
|
|
break;
|
|
|
|
case T_IndexPath:
|
|
|
|
ptype = "IdxScan";
|
|
|
|
join = false;
|
|
|
|
break;
|
1999-02-12 07:43:53 +01:00
|
|
|
case T_NestPath:
|
1997-09-08 04:41:22 +02:00
|
|
|
ptype = "Nestloop";
|
|
|
|
join = true;
|
|
|
|
break;
|
|
|
|
case T_MergePath:
|
|
|
|
ptype = "MergeJoin";
|
|
|
|
join = true;
|
|
|
|
break;
|
|
|
|
case T_HashPath:
|
|
|
|
ptype = "HashJoin";
|
|
|
|
join = true;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
1997-02-19 13:59:07 +01:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
if (join)
|
|
|
|
{
|
1999-02-12 18:25:05 +01:00
|
|
|
jp = (JoinPath *) path;
|
2000-02-15 21:49:31 +01:00
|
|
|
printf("%s rows=%.0f cost=%.2f..%.2f\n",
|
|
|
|
ptype, path->parent->rows,
|
|
|
|
path->startup_cost, path->total_cost);
|
1997-09-07 07:04:48 +02:00
|
|
|
switch (nodeTag(path))
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
case T_MergePath:
|
|
|
|
case T_HashPath:
|
|
|
|
for (i = 0; i < indent + 1; i++)
|
|
|
|
printf("\t");
|
|
|
|
printf(" clauses=(");
|
2000-02-07 05:41:04 +01:00
|
|
|
geqo_print_joinclauses(root, jp->joinrestrictinfo);
|
1997-09-08 04:41:22 +02:00
|
|
|
printf(")\n");
|
|
|
|
|
|
|
|
if (nodeTag(path) == T_MergePath)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
MergePath *mp = (MergePath *) path;
|
|
|
|
|
|
|
|
if (mp->outersortkeys || mp->innersortkeys)
|
|
|
|
{
|
|
|
|
for (i = 0; i < indent + 1; i++)
|
|
|
|
printf("\t");
|
|
|
|
printf(" sortouter=%d sortinner=%d\n",
|
|
|
|
((mp->outersortkeys) ? 1 : 0),
|
|
|
|
((mp->innersortkeys) ? 1 : 0));
|
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1997-09-08 04:41:22 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
1997-02-19 13:59:07 +01:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
geqo_print_path(root, jp->outerjoinpath, indent + 1);
|
|
|
|
geqo_print_path(root, jp->innerjoinpath, indent + 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int relid = lfirsti(path->parent->relids);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
2000-02-15 21:49:31 +01:00
|
|
|
printf("%s(%d) rows=%.0f cost=%.2f..%.2f\n",
|
|
|
|
ptype, relid, path->parent->rows,
|
|
|
|
path->startup_cost, path->total_cost);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1999-08-16 04:17:58 +02:00
|
|
|
if (IsA(path, IndexPath))
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
1999-08-16 04:17:58 +02:00
|
|
|
printf(" pathkeys=");
|
|
|
|
print_pathkeys(path->pathkeys, root->rtable);
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1997-02-19 13:59:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
void
|
1999-05-26 00:43:53 +02:00
|
|
|
geqo_print_rel(Query *root, RelOptInfo *rel)
|
1997-02-19 13:59:07 +01:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
List *l;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
printf("______________________________\n");
|
|
|
|
printf("(");
|
|
|
|
foreach(l, rel->relids)
|
|
|
|
printf("%d ", lfirsti(l));
|
2000-01-09 01:26:47 +01:00
|
|
|
printf("): rows=%.0f width=%d\n", rel->rows, rel->width);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
printf("\tpath list:\n");
|
|
|
|
foreach(l, rel->pathlist)
|
|
|
|
geqo_print_path(root, lfirst(l), 1);
|
|
|
|
|
2001-05-08 19:25:28 +02:00
|
|
|
printf("\n\tcheapest startup path:\n");
|
2000-02-15 21:49:31 +01:00
|
|
|
geqo_print_path(root, rel->cheapest_startup_path, 1);
|
|
|
|
|
2001-05-08 19:25:28 +02:00
|
|
|
printf("\n\tcheapest total path:\n");
|
2000-02-15 21:49:31 +01:00
|
|
|
geqo_print_path(root, rel->cheapest_total_path, 1);
|
1997-02-19 13:59:07 +01:00
|
|
|
}
|
2002-07-20 06:59:10 +02:00
|
|
|
|
2002-09-04 22:31:48 +02:00
|
|
|
#endif /* GEQO_DEBUG */
|