Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5500039

Browse files
committed
Fix optimizer coredump with unary-operator WHERE clauses.
A test case is:create table linetab (x line);select * from linetab where ?| x;which coredumps in 6.4.2 and current sources.
1 parentd8b482b commit5500039

File tree

1 file changed

+89
-99
lines changed

1 file changed

+89
-99
lines changed

‎src/backend/optimizer/util/clauses.c

Lines changed: 89 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
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)
101101
expr->typeOid=InvalidOid;/* assume type checking done */
102102
expr->opType=OP_EXPR;
103103
expr->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);
105108
returnexpr;
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
*/
130133
Var*
131134
get_rightop(Expr*clause)
@@ -470,6 +473,9 @@ is_joinable(Node *clause)
470473
leftop= (Node*)get_leftop((Expr*)clause);
471474
rightop= (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
*/
495502
bool
496503
qual_clause_p(Node*clause)
497504
{
505+
Node*leftop,
506+
*rightop;
507+
498508
if (!is_opclause(clause))
499509
return 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))
504519
return true;
505-
elseif (IsA(get_rightop((Expr*)clause),Var)&&
506-
IsA(get_leftop((Expr*)clause),Const))
520+
if (IsA(rightop,Var)&&IsA(leftop,Const))
507521
return true;
508522
return false;
509523
}
@@ -618,42 +632,35 @@ get_relattval(Node *clause,
618632
Datum*constval,
619633
int*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+
gotodefault_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-
elseif (is_opclause(clause)&&IsA(left,Var)&&IsA(right,Param))
656+
elseif (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-
elseif (is_opclause(clause)&&
655-
is_funcclause((Node*)left)&&
656-
IsA(right,Const))
663+
elseif (is_funcclause((Node*)left)&&IsA(right,Const))
657664
{
658665
List*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-
elseif (is_opclause(clause)&&
666-
is_funcclause((Node*)right)&&
667-
IsA(left,Const))
672+
elseif (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-
elseif (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-
elseif (is_opclause(clause)&&IsA(right,Var)&&IsA(left,Param))
679+
elseif (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+
elseif (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,
733721
int*relid2,
734722
AttrNumber*attno2)
735723
{
736-
Var*left=get_leftop((Expr*)clause);
737-
Var*right=get_rightop((Expr*)clause);
738-
boolvar_left= (IsA(left,Var));
739-
boolvar_right= (IsA(right,Var));
740-
boolvarexpr_left= (bool) ((IsA(left,Func)||IsA(left,Oper))&&
741-
contain_var_clause((Node*)left));
742-
boolvarexpr_right= (bool) ((IsA(right,Func)||IsA(right,Oper))&&
743-
contain_var_clause((Node*)right));
744-
745724
if (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-
elseif (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-
elseif (varexpr_left&&var_right)
729+
if (left&&right)
766730
{
731+
boolvar_left=IsA(left,Var);
732+
boolvar_right=IsA(right,Var);
733+
boolvarexpr_left= (bool) ((IsA(left,Func)||IsA(left,Oper))&&
734+
contain_var_clause((Node*)left));
735+
boolvarexpr_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

783774
void
@@ -813,4 +804,3 @@ CommuteClause(Node *clause)
813804
lfirst(((Expr*)clause)->args)=lsecond(((Expr*)clause)->args);
814805
lsecond(((Expr*)clause)->args)=temp;
815806
}
816-

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp