1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* initsplan.c--
|
1997-09-07 07:04:48 +02:00
|
|
|
* Target list, qualification, joininfo initialization routines
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
1999-02-03 22:18:02 +01:00
|
|
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.22 1999/02/03 21:16:35 momjian Exp $
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
1996-10-31 11:59:42 +01:00
|
|
|
#include <sys/types.h>
|
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
#include "postgres.h"
|
|
|
|
|
|
|
|
#include "nodes/pg_list.h"
|
|
|
|
#include "nodes/plannodes.h"
|
|
|
|
#include "nodes/parsenodes.h"
|
|
|
|
#include "nodes/relation.h"
|
|
|
|
#include "nodes/makefuncs.h"
|
|
|
|
|
1998-08-10 04:26:40 +02:00
|
|
|
#include "access/htup.h"
|
|
|
|
|
|
|
|
#include "catalog/pg_type.h"
|
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
#include "utils/lsyscache.h"
|
|
|
|
#include "utils/palloc.h"
|
|
|
|
|
|
|
|
#include "optimizer/internal.h"
|
|
|
|
#include "optimizer/planmain.h"
|
|
|
|
#include "optimizer/joininfo.h"
|
|
|
|
#include "optimizer/pathnode.h"
|
|
|
|
#include "optimizer/tlist.h"
|
|
|
|
#include "optimizer/var.h"
|
|
|
|
#include "optimizer/clauses.h"
|
|
|
|
#include "optimizer/cost.h"
|
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
extern int Quiet;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-08 23:56:23 +02:00
|
|
|
static void add_clause_to_rels(Query *root, List *clause);
|
1999-02-03 21:15:53 +01:00
|
|
|
static void add_join_info_to_rels(Query *root, RestrictInfo * restrictinfo,
|
1998-09-01 06:40:42 +02:00
|
|
|
List *join_relids);
|
1998-08-10 04:26:40 +02:00
|
|
|
static void add_vars_to_targetlist(Query *root, List *vars, List *join_relids);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1998-08-04 18:44:31 +02:00
|
|
|
static MergeOrder *mergejoinop(Expr *clause);
|
1997-09-08 23:56:23 +02:00
|
|
|
static Oid hashjoinop(Expr *clause);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* TARGET LISTS
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1998-08-10 04:26:40 +02:00
|
|
|
* init-base-rel-tlist--
|
1997-09-07 07:04:48 +02:00
|
|
|
* Creates rel nodes for every relation mentioned in the target list
|
|
|
|
* 'tlist' (if a node hasn't already been created) and adds them to
|
|
|
|
* *query-relation-list*. Creates targetlist entries for each member of
|
|
|
|
* 'tlist' and adds them to the tlist field of the appropriate rel node.
|
|
|
|
*
|
|
|
|
* Returns nothing.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
void
|
1998-08-10 04:26:40 +02:00
|
|
|
init_base_rels_tlist(Query *root, List *tlist)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
List *tlist_vars = NIL;
|
|
|
|
List *l = NIL;
|
|
|
|
List *tvar = NIL;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
foreach(l, tlist)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
TargetEntry *entry = (TargetEntry *) lfirst(l);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
tlist_vars = append(tlist_vars, pull_var_clause(entry->expr));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now, the target list only contains Var nodes */
|
|
|
|
foreach(tvar, tlist_vars)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Var *var;
|
|
|
|
Index varno;
|
1998-08-10 04:26:40 +02:00
|
|
|
RelOptInfo *result;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
var = (Var *) lfirst(tvar);
|
|
|
|
varno = var->varno;
|
|
|
|
result = get_base_rel(root, varno);
|
|
|
|
|
|
|
|
add_tl_element(result, var);
|
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
1998-08-10 04:26:40 +02:00
|
|
|
* add_missing-vars-to-tlist--
|
1997-09-07 07:04:48 +02:00
|
|
|
* If we have range variable(s) in the FROM clause that does not appear
|
|
|
|
* in the target list nor qualifications, we add it to the base relation
|
|
|
|
* list. For instance, "select f.x from foo f, foo f2" is a join of f and
|
|
|
|
* f2. Note that if we have "select foo.x from foo f", it also gets turned
|
|
|
|
* into a join.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
void
|
1998-08-10 04:26:40 +02:00
|
|
|
add_missing_vars_to_tlist(Query *root, List *tlist)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
List *l;
|
|
|
|
int varno;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
varno = 1;
|
|
|
|
foreach(l, root->rtable)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
|
|
|
|
List *relids;
|
1998-08-10 04:26:40 +02:00
|
|
|
RelOptInfo *result;
|
1997-09-08 04:41:22 +02:00
|
|
|
Var *var;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
relids = lconsi(varno, NIL);
|
1998-08-10 04:26:40 +02:00
|
|
|
if (rte->inFromCl && !rel_member(relids, root->base_rel_list))
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
1998-08-10 04:26:40 +02:00
|
|
|
var = makeVar(varno, ObjectIdAttributeNumber,
|
|
|
|
OIDOID, -1, 0, varno, ObjectIdAttributeNumber);
|
|
|
|
/* add it to base_rel_list */
|
1997-09-07 07:04:48 +02:00
|
|
|
result = get_base_rel(root, varno);
|
|
|
|
add_tl_element(result, var);
|
|
|
|
}
|
|
|
|
pfree(relids);
|
|
|
|
varno++;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
return;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* QUALIFICATIONS
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1998-08-10 04:26:40 +02:00
|
|
|
* init-base-rels-qual--
|
1999-02-03 21:15:53 +01:00
|
|
|
* Initializes RestrictInfo and JoinInfo fields of relation entries for all
|
1997-09-07 07:04:48 +02:00
|
|
|
* relations appearing within clauses. Creates new relation entries if
|
|
|
|
* necessary, adding them to *query-relation-list*.
|
|
|
|
*
|
|
|
|
* Returns nothing of interest.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
void
|
1998-08-10 04:26:40 +02:00
|
|
|
init_base_rels_qual(Query *root, List *clauses)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
List *clause;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
foreach(clause, clauses)
|
|
|
|
add_clause_to_rels(root, lfirst(clause));
|
|
|
|
return;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1996-07-09 08:22:35 +02:00
|
|
|
* add-clause-to-rels--
|
1999-02-03 21:15:53 +01:00
|
|
|
* Add clause information to either the 'RestrictInfo' or 'JoinInfo' field
|
1997-09-07 07:04:48 +02:00
|
|
|
* of a relation entry(depending on whether or not the clause is a join)
|
1999-02-03 21:15:53 +01:00
|
|
|
* by creating a new RestrictInfo node and setting appropriate fields
|
1997-09-07 07:04:48 +02:00
|
|
|
* within the nodes.
|
|
|
|
*
|
|
|
|
* Returns nothing of interest.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
static void
|
1997-09-08 23:56:23 +02:00
|
|
|
add_clause_to_rels(Query *root, List *clause)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
List *relids;
|
|
|
|
List *vars;
|
1999-02-03 21:15:53 +01:00
|
|
|
RestrictInfo *restrictinfo = makeNode(RestrictInfo);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
|
|
|
* Retrieve all relids and vars contained within the clause.
|
|
|
|
*/
|
1998-08-09 06:59:10 +02:00
|
|
|
clause_get_relids_vars((Node *) clause, &relids, &vars);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1999-02-03 21:15:53 +01:00
|
|
|
restrictinfo->clause = (Expr *) clause;
|
|
|
|
restrictinfo->notclause = contains_not((Node *) clause);
|
|
|
|
restrictinfo->selectivity = 0;
|
|
|
|
restrictinfo->indexids = NIL;
|
|
|
|
restrictinfo->mergejoinorder = (MergeOrder *) NULL;
|
|
|
|
restrictinfo->hashjoinoperator = (Oid) 0;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
if (length(relids) == 1)
|
|
|
|
{
|
1998-08-10 04:26:40 +02:00
|
|
|
RelOptInfo *rel = get_base_rel(root, lfirsti(relids));
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/*
|
1997-09-07 07:04:48 +02:00
|
|
|
* There is only one relation participating in 'clause', so
|
|
|
|
* 'clause' must be a restriction clause.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/*
|
1997-09-07 07:04:48 +02:00
|
|
|
* the selectivity of the clause must be computed regardless of
|
|
|
|
* whether it's a restriction or a join clause
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1997-09-07 07:04:48 +02:00
|
|
|
if (is_funcclause((Node *) clause))
|
|
|
|
{
|
1998-09-01 06:40:42 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
|
|
|
* XXX If we have a func clause set selectivity to 1/3, really
|
|
|
|
* need a true selectivity function.
|
|
|
|
*/
|
1999-02-03 21:15:53 +01:00
|
|
|
restrictinfo->selectivity = (Cost) 0.3333333;
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-02-03 22:18:02 +01:00
|
|
|
restrictinfo->selectivity = compute_clause_selec(root, (Node *) clause, NIL);
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1999-02-03 21:15:53 +01:00
|
|
|
rel->restrictinfo = lcons(restrictinfo, rel->restrictinfo);
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
else
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 'clause' is a join clause, since there is more than one atom in
|
|
|
|
* the relid list.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (is_funcclause((Node *) clause))
|
|
|
|
{
|
1998-09-01 06:40:42 +02:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
|
|
|
* XXX If we have a func clause set selectivity to 1/3, really
|
|
|
|
* need a true selectivity function.
|
|
|
|
*/
|
1999-02-03 21:15:53 +01:00
|
|
|
restrictinfo->selectivity = (Cost) 0.3333333;
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-02-03 22:18:02 +01:00
|
|
|
restrictinfo->selectivity = compute_clause_selec(root, (Node *) clause, NIL);
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1999-02-03 21:15:53 +01:00
|
|
|
add_join_info_to_rels(root, restrictinfo, relids);
|
1998-08-10 04:26:40 +02:00
|
|
|
/* we are going to be doing a join, so add var to targetlist */
|
|
|
|
add_vars_to_targetlist(root, vars, relids);
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1998-08-10 04:26:40 +02:00
|
|
|
* add-join-info-to-rels--
|
1999-02-03 21:15:53 +01:00
|
|
|
* For every relation participating in a join clause, add 'restrictinfo' to
|
1997-09-07 07:04:48 +02:00
|
|
|
* the appropriate joininfo node(creating a new one and adding it to the
|
|
|
|
* appropriate rel node if necessary).
|
|
|
|
*
|
1999-02-03 21:15:53 +01:00
|
|
|
* 'restrictinfo' describes the join clause
|
1996-07-09 08:22:35 +02:00
|
|
|
* 'join-relids' is the list of relations participating in the join clause
|
1997-09-07 07:04:48 +02:00
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
* Returns nothing.
|
1997-09-07 07:04:48 +02:00
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
static void
|
1999-02-03 21:15:53 +01:00
|
|
|
add_join_info_to_rels(Query *root, RestrictInfo * restrictinfo, List *join_relids)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
List *join_relid;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
foreach(join_relid, join_relids)
|
|
|
|
{
|
1998-09-01 06:40:42 +02:00
|
|
|
JoinInfo *joininfo;
|
1997-09-08 04:41:22 +02:00
|
|
|
List *other_rels = NIL;
|
|
|
|
List *rel;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
foreach(rel, join_relids)
|
|
|
|
{
|
|
|
|
if (lfirsti(rel) != lfirsti(join_relid))
|
|
|
|
other_rels = lappendi(other_rels, lfirsti(rel));
|
|
|
|
}
|
|
|
|
|
1998-08-10 04:26:40 +02:00
|
|
|
joininfo = find_joininfo_node(get_base_rel(root, lfirsti(join_relid)),
|
1998-09-01 06:40:42 +02:00
|
|
|
other_rels);
|
1999-02-03 22:18:02 +01:00
|
|
|
joininfo->jinfo_restrictinfo = lcons(copyObject((void *) restrictinfo), joininfo->jinfo_restrictinfo);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1998-08-10 04:26:40 +02:00
|
|
|
* add-vars-to-targetlist--
|
1997-09-07 07:04:48 +02:00
|
|
|
* For each variable appearing in a clause,
|
|
|
|
* (1) If a targetlist entry for the variable is not already present in
|
|
|
|
* the appropriate relation's target list, add one.
|
|
|
|
* (2) If a targetlist entry is already present, but the var is part of a
|
|
|
|
* join clause, add the relids of the join relations to the JoinList
|
|
|
|
* entry of the targetlist entry.
|
|
|
|
*
|
|
|
|
* 'vars' is the list of var nodes
|
|
|
|
* 'join-relids' is the list of relids appearing in the join clause
|
|
|
|
* (if this is a join clause)
|
|
|
|
*
|
|
|
|
* Returns nothing.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
static void
|
1998-08-10 04:26:40 +02:00
|
|
|
add_vars_to_targetlist(Query *root, List *vars, List *join_relids)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Var *var;
|
|
|
|
List *temp = NIL;
|
1998-08-10 04:26:40 +02:00
|
|
|
RelOptInfo *rel = (RelOptInfo *) NULL;
|
1997-09-08 04:41:22 +02:00
|
|
|
TargetEntry *tlistentry;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
foreach(temp, vars)
|
|
|
|
{
|
|
|
|
var = (Var *) lfirst(temp);
|
|
|
|
rel = get_base_rel(root, var->varno);
|
|
|
|
tlistentry = tlistentry_member(var, rel->targetlist);
|
|
|
|
if (tlistentry == NULL)
|
|
|
|
/* add a new entry */
|
|
|
|
add_tl_element(rel, var);
|
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
*
|
1997-09-07 07:04:48 +02:00
|
|
|
* JOININFO
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1998-08-10 04:26:40 +02:00
|
|
|
* init-join-info--
|
1998-08-04 18:44:31 +02:00
|
|
|
* Set the MergeJoinable or HashJoinable field for every joininfo node
|
|
|
|
* (within a rel node) and the MergeJoinOrder or HashJoinOp field for
|
1999-02-03 21:15:53 +01:00
|
|
|
* each restrictinfo node(within a joininfo node) for all relations in a
|
1997-09-07 07:04:48 +02:00
|
|
|
* query.
|
|
|
|
*
|
|
|
|
* Returns nothing.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
void
|
1998-08-10 04:26:40 +02:00
|
|
|
init_join_info(List *rel_list)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
List *x,
|
|
|
|
*y,
|
|
|
|
*z;
|
1998-08-10 04:26:40 +02:00
|
|
|
RelOptInfo *rel;
|
1998-09-01 06:40:42 +02:00
|
|
|
JoinInfo *joininfo;
|
1999-02-03 21:15:53 +01:00
|
|
|
RestrictInfo *restrictinfo;
|
1997-09-08 04:41:22 +02:00
|
|
|
Expr *clause;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
foreach(x, rel_list)
|
|
|
|
{
|
1998-07-18 06:22:52 +02:00
|
|
|
rel = (RelOptInfo *) lfirst(x);
|
1997-09-07 07:04:48 +02:00
|
|
|
foreach(y, rel->joininfo)
|
|
|
|
{
|
1998-09-01 05:29:17 +02:00
|
|
|
joininfo = (JoinInfo *) lfirst(y);
|
1999-02-03 21:15:53 +01:00
|
|
|
foreach(z, joininfo->jinfo_restrictinfo)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
1999-02-03 21:15:53 +01:00
|
|
|
restrictinfo = (RestrictInfo *) lfirst(z);
|
|
|
|
clause = restrictinfo->clause;
|
1998-08-10 04:26:40 +02:00
|
|
|
if (is_joinable((Node *) clause))
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
MergeOrder *sortop = (MergeOrder *) NULL;
|
|
|
|
Oid hashop = (Oid) NULL;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1998-08-04 18:44:31 +02:00
|
|
|
if (_enable_mergejoin_)
|
|
|
|
sortop = mergejoinop(clause);
|
1997-09-07 07:04:48 +02:00
|
|
|
if (_enable_hashjoin_)
|
|
|
|
hashop = hashjoinop(clause);
|
|
|
|
|
|
|
|
if (sortop)
|
|
|
|
{
|
1999-02-03 21:15:53 +01:00
|
|
|
restrictinfo->mergejoinorder = sortop;
|
1998-08-04 18:44:31 +02:00
|
|
|
joininfo->mergejoinable = true;
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
|
|
|
if (hashop)
|
|
|
|
{
|
1999-02-03 21:15:53 +01:00
|
|
|
restrictinfo->hashjoinoperator = hashop;
|
1997-09-07 07:04:48 +02:00
|
|
|
joininfo->hashjoinable = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1998-08-04 18:44:31 +02:00
|
|
|
* mergejoinop--
|
|
|
|
* Returns the mergejoin operator of an operator iff 'clause' is
|
|
|
|
* mergejoinable, i.e., both operands are single vars and the operator is
|
|
|
|
* a mergejoinable operator.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
static MergeOrder *
|
1998-08-04 18:44:31 +02:00
|
|
|
mergejoinop(Expr *clause)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
Oid leftOp,
|
|
|
|
rightOp;
|
|
|
|
bool sortable;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1998-08-04 18:44:31 +02:00
|
|
|
sortable = op_mergejoinable(((Oper *) clause->oper)->opno,
|
1997-09-07 07:04:48 +02:00
|
|
|
(get_leftop(clause))->vartype,
|
|
|
|
(get_rightop(clause))->vartype,
|
|
|
|
&leftOp,
|
|
|
|
&rightOp);
|
|
|
|
|
|
|
|
if (sortable)
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
MergeOrder *morder = makeNode(MergeOrder);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
morder->join_operator = ((Oper *) clause->oper)->opno;
|
|
|
|
morder->left_operator = leftOp;
|
|
|
|
morder->right_operator = rightOp;
|
|
|
|
morder->left_type = (get_leftop(clause))->vartype;
|
|
|
|
morder->right_type = (get_rightop(clause))->vartype;
|
1998-09-01 05:29:17 +02:00
|
|
|
return morder;
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
|
|
|
else
|
1998-09-01 05:29:17 +02:00
|
|
|
return NULL;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
/*
|
1996-07-09 08:22:35 +02:00
|
|
|
* hashjoinop--
|
1997-09-07 07:04:48 +02:00
|
|
|
* Returns the hashjoin operator of an operator iff 'clause' is
|
|
|
|
* hashjoinable, i.e., both operands are single vars and the operator is
|
|
|
|
* a hashjoinable operator.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1997-09-08 04:41:22 +02:00
|
|
|
static Oid
|
1997-09-08 23:56:23 +02:00
|
|
|
hashjoinop(Expr *clause)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-07 07:04:48 +02:00
|
|
|
return (op_hashjoinable(((Oper *) clause->oper)->opno,
|
|
|
|
(get_leftop(clause))->vartype,
|
|
|
|
(get_rightop(clause))->vartype));
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|