77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.29 1999/02/13 23:16:42 momjian Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.30 1999/02/14 22:24:25 tgl Exp $
1111 *
1212 * HISTORY
1313 * AUTHORDATEMAJOR EVENT
@@ -101,7 +101,10 @@ make_opclause(Oper *op, Var *leftop, Var *rightop)
101101expr -> typeOid = InvalidOid ;/* assume type checking done */
102102expr -> opType = OP_EXPR ;
103103expr -> oper = (Node * )op ;
104- expr -> args = makeList (leftop ,rightop ,-1 );
104+ if (rightop )
105+ expr -> args = lcons (leftop ,lcons (rightop ,NIL ));
106+ else
107+ expr -> args = lcons (leftop ,NIL );
105108return expr ;
106109}
107110
@@ -125,7 +128,7 @@ get_leftop(Expr *clause)
125128 * get_rightop
126129 *
127130 * Returns the right operand in a clause of the form (op expr expr).
128- *
131+ * NB: result will be NULL if applied to a unary op clause.
129132 */
130133Var *
131134get_rightop (Expr * clause )
@@ -470,6 +473,9 @@ is_joinable(Node *clause)
470473leftop = (Node * )get_leftop ((Expr * )clause );
471474rightop = (Node * )get_rightop ((Expr * )clause );
472475
476+ if (!rightop )
477+ return false;/* unary opclauses need not apply */
478+
473479/*
474480 * One side of the clause (i.e. left or right operands) must either be
475481 * a var node ...
@@ -491,19 +497,27 @@ is_joinable(Node *clause)
491497 *
492498 * Returns t iff 'clause' is a valid qualification clause.
493499 *
500+ * For now we accept only "var op const" or "const op var".
494501 */
495502bool
496503qual_clause_p (Node * clause )
497504{
505+ Node * leftop ,
506+ * rightop ;
507+
498508if (!is_opclause (clause ))
499509return false;
500510
511+ leftop = (Node * )get_leftop ((Expr * )clause );
512+ rightop = (Node * )get_rightop ((Expr * )clause );
513+
514+ if (!rightop )
515+ return false;/* unary opclauses need not apply */
516+
501517/* How about Param-s ?- vadim 02/03/98 */
502- if (IsA (get_leftop ((Expr * )clause ),Var )&&
503- IsA (get_rightop ((Expr * )clause ),Const ))
518+ if (IsA (leftop ,Var )&& IsA (rightop ,Const ))
504519return true;
505- else if (IsA (get_rightop ((Expr * )clause ),Var )&&
506- IsA (get_leftop ((Expr * )clause ),Const ))
520+ if (IsA (rightop ,Var )&& IsA (leftop ,Const ))
507521return true;
508522return false;
509523}
@@ -618,42 +632,35 @@ get_relattval(Node *clause,
618632Datum * constval ,
619633int * flag )
620634{
621- Var * left = get_leftop (( Expr * ) clause );
622- Var * right = get_rightop (( Expr * ) clause ) ;
635+ Var * left ,
636+ * right ;
623637
624- if (is_opclause (clause )&& IsA (left ,Var )&&
625- IsA (right ,Const ))
626- {
638+ /* Careful; the passed clause might not be a binary operator at all */
627639
628- if (right != NULL )
629- {
640+ if (! is_opclause ( clause ) )
641+ goto default_results ;
630642
631- * relid = left -> varno ;
632- * attno = left -> varattno ;
633- * constval = ((Const * )right )-> constvalue ;
634- * flag = (_SELEC_CONSTANT_RIGHT_ |_SELEC_IS_CONSTANT_ );
643+ left = get_leftop ((Expr * )clause );
644+ right = get_rightop ((Expr * )clause );
635645
636- }
637- else
638- {
646+ if (!right )
647+ gotodefault_results ;
639648
640- * relid = left -> varno ;
641- * attno = left -> varattno ;
642- * constval = 0 ;
643- * flag = ( _SELEC_CONSTANT_RIGHT_ | _SELEC_NOT_CONSTANT_ ) ;
644-
645- }
649+ if ( IsA ( left , Var ) && IsA ( right , Const ))
650+ {
651+ * relid = left -> varno ;
652+ * attno = left -> varattno ;
653+ * constval = (( Const * ) right ) -> constvalue ;
654+ * flag = ( _SELEC_CONSTANT_RIGHT_ | _SELEC_IS_CONSTANT_ );
646655}
647- else if (is_opclause ( clause ) && IsA (left ,Var )&& IsA (right ,Param ))
656+ else if (IsA (left ,Var )&& IsA (right ,Param ))
648657{
649658* relid = left -> varno ;
650659* attno = left -> varattno ;
651660* constval = 0 ;
652661* flag = (_SELEC_NOT_CONSTANT_ );
653662}
654- else if (is_opclause (clause )&&
655- is_funcclause ((Node * )left )&&
656- IsA (right ,Const ))
663+ else if (is_funcclause ((Node * )left )&& IsA (right ,Const ))
657664{
658665List * vars = pull_var_clause ((Node * )left );
659666
@@ -662,52 +669,33 @@ get_relattval(Node *clause,
662669* constval = ((Const * )right )-> constvalue ;
663670* flag = (_SELEC_CONSTANT_RIGHT_ |_SELEC_IS_CONSTANT_ );
664671}
665- else if (is_opclause (clause )&&
666- is_funcclause ((Node * )right )&&
667- IsA (left ,Const ))
672+ else if (IsA (right ,Var )&& IsA (left ,Const ))
668673{
669- List * vars = pull_var_clause ((Node * )right );
670-
671- * relid = ((Var * )lfirst (vars ))-> varno ;
672- * attno = InvalidAttrNumber ;
674+ * relid = right -> varno ;
675+ * attno = right -> varattno ;
673676* constval = ((Const * )left )-> constvalue ;
674677* flag = (_SELEC_IS_CONSTANT_ );
675-
676- }
677- else if (is_opclause (clause )&& IsA (right ,Var )&&
678- IsA (left ,Const ))
679- {
680- if (left != NULL )
681- {
682-
683- * relid = right -> varno ;
684- * attno = right -> varattno ;
685- * constval = ((Const * )left )-> constvalue ;
686- * flag = (_SELEC_IS_CONSTANT_ );
687- }
688- else
689- {
690-
691- * relid = right -> varno ;
692- * attno = right -> varattno ;
693- * constval = 0 ;
694- * flag = (_SELEC_NOT_CONSTANT_ );
695- }
696678}
697- else if (is_opclause ( clause ) && IsA (right ,Var )&& IsA (left ,Param ))
679+ else if (IsA (right ,Var )&& IsA (left ,Param ))
698680{
699681* relid = right -> varno ;
700682* attno = right -> varattno ;
701683* constval = 0 ;
702684* flag = (_SELEC_NOT_CONSTANT_ );
703685}
704- else
686+ else if ( is_funcclause (( Node * ) right ) && IsA ( left , Const ))
705687{
688+ List * vars = pull_var_clause ((Node * )right );
706689
707- /*
708- * One or more of the operands are expressions (e.g., oper
709- * clauses)
710- */
690+ * relid = ((Var * )lfirst (vars ))-> varno ;
691+ * attno = InvalidAttrNumber ;
692+ * constval = ((Const * )left )-> constvalue ;
693+ * flag = (_SELEC_IS_CONSTANT_ );
694+ }
695+ else
696+ {
697+ /* Duh, it's too complicated for me... */
698+ default_results :
711699* relid = _SELEC_VALUE_UNKNOWN_ ;
712700* attno = _SELEC_VALUE_UNKNOWN_ ;
713701* constval = 0 ;
@@ -733,51 +721,54 @@ get_rels_atts(Node *clause,
733721int * relid2 ,
734722AttrNumber * attno2 )
735723{
736- Var * left = get_leftop ((Expr * )clause );
737- Var * right = get_rightop ((Expr * )clause );
738- bool var_left = (IsA (left ,Var ));
739- bool var_right = (IsA (right ,Var ));
740- bool varexpr_left = (bool ) ((IsA (left ,Func )|| IsA (left ,Oper ))&&
741- contain_var_clause ((Node * )left ));
742- bool varexpr_right = (bool ) ((IsA (right ,Func )|| IsA (right ,Oper ))&&
743- contain_var_clause ((Node * )right ));
744-
745724if (is_opclause (clause ))
746725{
747- if ( var_left && var_right )
748- {
726+ Var * left = get_leftop (( Expr * ) clause );
727+ Var * right = get_rightop (( Expr * ) clause );
749728
750- * relid1 = left -> varno ;
751- * attno1 = left -> varoattno ;
752- * relid2 = right -> varno ;
753- * attno2 = right -> varoattno ;
754- return ;
755- }
756- else if (var_left && varexpr_right )
757- {
758-
759- * relid1 = left -> varno ;
760- * attno1 = left -> varoattno ;
761- * relid2 = _SELEC_VALUE_UNKNOWN_ ;
762- * attno2 = _SELEC_VALUE_UNKNOWN_ ;
763- return ;
764- }
765- else if (varexpr_left && var_right )
729+ if (left && right )
766730{
731+ bool var_left = IsA (left ,Var );
732+ bool var_right = IsA (right ,Var );
733+ bool varexpr_left = (bool ) ((IsA (left ,Func )|| IsA (left ,Oper ))&&
734+ contain_var_clause ((Node * )left ));
735+ bool varexpr_right = (bool ) ((IsA (right ,Func )|| IsA (right ,Oper ))&&
736+ contain_var_clause ((Node * )right ));
767737
768- * relid1 = _SELEC_VALUE_UNKNOWN_ ;
769- * attno1 = _SELEC_VALUE_UNKNOWN_ ;
770- * relid2 = right -> varno ;
771- * attno2 = right -> varoattno ;
772- return ;
738+ if (var_left && var_right )
739+ {
740+
741+ * relid1 = left -> varno ;
742+ * attno1 = left -> varoattno ;
743+ * relid2 = right -> varno ;
744+ * attno2 = right -> varoattno ;
745+ return ;
746+ }
747+ if (var_left && varexpr_right )
748+ {
749+
750+ * relid1 = left -> varno ;
751+ * attno1 = left -> varoattno ;
752+ * relid2 = _SELEC_VALUE_UNKNOWN_ ;
753+ * attno2 = _SELEC_VALUE_UNKNOWN_ ;
754+ return ;
755+ }
756+ if (varexpr_left && var_right )
757+ {
758+
759+ * relid1 = _SELEC_VALUE_UNKNOWN_ ;
760+ * attno1 = _SELEC_VALUE_UNKNOWN_ ;
761+ * relid2 = right -> varno ;
762+ * attno2 = right -> varoattno ;
763+ return ;
764+ }
773765}
774766}
775767
776768* relid1 = _SELEC_VALUE_UNKNOWN_ ;
777769* attno1 = _SELEC_VALUE_UNKNOWN_ ;
778770* relid2 = _SELEC_VALUE_UNKNOWN_ ;
779771* attno2 = _SELEC_VALUE_UNKNOWN_ ;
780- return ;
781772}
782773
783774void
@@ -813,4 +804,3 @@ CommuteClause(Node *clause)
813804lfirst (((Expr * )clause )-> args )= lsecond (((Expr * )clause )-> args );
814805lsecond (((Expr * )clause )-> args )= temp ;
815806}
816-