Adjust parser so that 'x NOT IN (subselect)' is converted to
authorTom Lane
Thu, 9 Jan 2003 20:50:53 +0000 (20:50 +0000)
committerTom Lane
Thu, 9 Jan 2003 20:50:53 +0000 (20:50 +0000)
'NOT (x IN (subselect))', that is 'NOT (x = ANY (subselect))',
rather than 'x <> ALL (subselect)' as we formerly did.  This
opens the door to optimizing NOT IN the same way as IN, whereas
there's no hope of optimizing the expression using <>.  Also,
convert 'x <> ALL (subselect)' to the NOT(IN) style, so that
the optimization will be available when processing rules dumped
by older Postgres versions.
initdb forced due to small change in SubLink node representation.

src/backend/executor/nodeSubplan.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/backend/optimizer/plan/subselect.c
src/backend/parser/gram.y
src/backend/parser/parse_expr.c
src/backend/utils/adt/ruleutils.c
src/include/catalog/catversion.h
src/include/nodes/primnodes.h

index 5a6950e0bee0959017cff6b96168e9dc3c66f48d..c9a02814bff2c1114ee8fb71e411bc9a3e23285e 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.40 2002/12/26 22:37:42 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.41 2003/01/09 20:50:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -37,7 +37,7 @@ ExecSubPlan(SubPlanState *node,
    SubPlan    *subplan = (SubPlan *) node->xprstate.expr;
    PlanState  *planstate = node->planstate;
    SubLinkType subLinkType = subplan->subLinkType;
-   bool        useor = subplan->useor;
+   bool        useOr = subplan->useOr;
    MemoryContext oldcontext;
    TupleTableSlot *slot;
    Datum       result;
@@ -84,7 +84,7 @@ ExecSubPlan(SubPlanState *node,
     * For all sublink types except EXPR_SUBLINK, the result is boolean as
     * are the results of the combining operators.  We combine results
     * within a tuple (if there are multiple columns) using OR semantics
-    * if "useor" is true, AND semantics if not.  We then combine results
+    * if "useOr" is true, AND semantics if not.  We then combine results
     * across tuples (if the subplan produces more than one) using OR
     * semantics for ANY_SUBLINK or AND semantics for ALL_SUBLINK.
     * (MULTIEXPR_SUBLINK doesn't allow multiple tuples from the subplan.)
@@ -107,7 +107,7 @@ ExecSubPlan(SubPlanState *node,
    {
        HeapTuple   tup = slot->val;
        TupleDesc   tdesc = slot->ttc_tupleDescriptor;
-       Datum       rowresult = BoolGetDatum(!useor);
+       Datum       rowresult = BoolGetDatum(!useOr);
        bool        rownull = false;
        int         col = 1;
 
@@ -212,7 +212,7 @@ ExecSubPlan(SubPlanState *node,
                rowresult = expresult;
                rownull = expnull;
            }
-           else if (useor)
+           else if (useOr)
            {
                /* combine within row per OR semantics */
                if (expnull)
index c3abcfc9e80eeb9d60b19f837556c465dac5fc1e..4b326b75224eb11fc51770d09bd5d92a08e1f39b 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.233 2002/12/14 00:17:50 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.234 2003/01/09 20:50:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -809,7 +809,8 @@ _copySubLink(SubLink *from)
    SubLink    *newnode = makeNode(SubLink);
 
    COPY_SCALAR_FIELD(subLinkType);
-   COPY_SCALAR_FIELD(useor);
+   COPY_SCALAR_FIELD(operIsEquals);
+   COPY_SCALAR_FIELD(useOr);
    COPY_NODE_FIELD(lefthand);
    COPY_NODE_FIELD(oper);
    COPY_NODE_FIELD(subselect);
@@ -826,7 +827,7 @@ _copySubPlan(SubPlan *from)
    SubPlan    *newnode = makeNode(SubPlan);
 
    COPY_SCALAR_FIELD(subLinkType);
-   COPY_SCALAR_FIELD(useor);
+   COPY_SCALAR_FIELD(useOr);
    COPY_NODE_FIELD(oper);
    COPY_NODE_FIELD(plan);
    COPY_SCALAR_FIELD(plan_id);
index 5fc333df3de8a0d48c793f1c6ff19b8808d55807..affa7f48a881d42ecb8e8e792684a927cba05595 100644 (file)
@@ -18,7 +18,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.177 2002/12/14 00:17:51 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.178 2003/01/09 20:50:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -287,7 +287,8 @@ static bool
 _equalSubLink(SubLink *a, SubLink *b)
 {
    COMPARE_SCALAR_FIELD(subLinkType);
-   COMPARE_SCALAR_FIELD(useor);
+   COMPARE_SCALAR_FIELD(operIsEquals);
+   COMPARE_SCALAR_FIELD(useOr);
    COMPARE_NODE_FIELD(lefthand);
    COMPARE_NODE_FIELD(oper);
    COMPARE_NODE_FIELD(subselect);
@@ -299,7 +300,7 @@ static bool
 _equalSubPlan(SubPlan *a, SubPlan *b)
 {
    COMPARE_SCALAR_FIELD(subLinkType);
-   COMPARE_SCALAR_FIELD(useor);
+   COMPARE_SCALAR_FIELD(useOr);
    COMPARE_NODE_FIELD(oper);
    /* should compare plans, but have to settle for comparing plan IDs */
    COMPARE_SCALAR_FIELD(plan_id);
index 97fc9462a27fef92fb71125336efa9a6e65351a2..204c00ad674c36ca2c59c605515ab7d70658dfef 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.190 2002/12/14 00:17:52 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.191 2003/01/09 20:50:50 tgl Exp $
  *
  * NOTES
  *   Every node type that can appear in stored rules' parsetrees *must*
@@ -658,7 +658,8 @@ _outSubLink(StringInfo str, SubLink *node)
    WRITE_NODE_TYPE("SUBLINK");
 
    WRITE_ENUM_FIELD(subLinkType, SubLinkType);
-   WRITE_BOOL_FIELD(useor);
+   WRITE_BOOL_FIELD(operIsEquals);
+   WRITE_BOOL_FIELD(useOr);
    WRITE_NODE_FIELD(lefthand);
    WRITE_NODE_FIELD(oper);
    WRITE_NODE_FIELD(subselect);
@@ -670,7 +671,7 @@ _outSubPlan(StringInfo str, SubPlan *node)
    WRITE_NODE_TYPE("SUBPLAN");
 
    WRITE_ENUM_FIELD(subLinkType, SubLinkType);
-   WRITE_BOOL_FIELD(useor);
+   WRITE_BOOL_FIELD(useOr);
    WRITE_NODE_FIELD(oper);
    WRITE_NODE_FIELD(plan);
    WRITE_INT_FIELD(plan_id);
index 9ecd40f2e1d742a9c1dabab1c64725f273797f37..99afc0438c339ed7714eb9013c30dca3becf316b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.144 2002/12/14 00:17:54 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.145 2003/01/09 20:50:51 tgl Exp $
  *
  * NOTES
  *   Path and Plan nodes do not have any readfuncs support, because we
@@ -531,7 +531,8 @@ _readSubLink(void)
    READ_LOCALS(SubLink);
 
    READ_ENUM_FIELD(subLinkType, SubLinkType);
-   READ_BOOL_FIELD(useor);
+   READ_BOOL_FIELD(operIsEquals);
+   READ_BOOL_FIELD(useOr);
    READ_NODE_FIELD(lefthand);
    READ_NODE_FIELD(oper);
    READ_NODE_FIELD(subselect);
index 840ba975a34e98c4f010cbe7dc591945e4876b28..f8086d9ab6e2b9308b9740b0bfc76c57411ccb1f 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.61 2002/12/14 00:17:55 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.62 2003/01/09 20:50:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -225,7 +225,7 @@ make_subplan(SubLink *slink, List *lefthand)
     * Fill in other fields of the SubPlan node.
     */
    node->subLinkType = slink->subLinkType;
-   node->useor = slink->useor;
+   node->useOr = slink->useOr;
    node->oper = NIL;
    node->setParam = NIL;
    node->parParam = NIL;
@@ -283,7 +283,7 @@ make_subplan(SubLink *slink, List *lefthand)
                                     &node->setParam);
        PlannerInitPlan = lappend(PlannerInitPlan, node);
        if (length(oper) > 1)
-           result = (Node *) (node->useor ? make_orclause(oper) :
+           result = (Node *) (node->useOr ? make_orclause(oper) :
                               make_andclause(oper));
        else
            result = (Node *) lfirst(oper);
index 1809d515461d8e0081481c4ee576c1221a186e6c..7626fe0e449888a4c39dc5b9ecba179cdd58851a 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.391 2003/01/08 00:22:27 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.392 2003/01/09 20:50:51 tgl Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -5420,28 +5420,30 @@ opt_interval:
 
 /* Expressions using row descriptors
  * Define row_descriptor to allow yacc to break the reduce/reduce conflict
- * with singleton expressions. Use SQL99's ROW keyword to allow rows of
- *  one element.
+ * with singleton expressions. Use SQL99's ROW keyword to allow rows of
+ * one element.
  */
 r_expr:  row IN_P select_with_parens
                {
                    SubLink *n = makeNode(SubLink);
                    n->lefthand = $1;
                    n->oper = (List *) makeSimpleA_Expr(OP, "=", NULL, NULL);
-                   n->useor = FALSE;
                    n->subLinkType = ANY_SUBLINK;
+                   /* operIsEquals and useOr will be set later */
                    n->subselect = $3;
                    $$ = (Node *)n;
                }
            | row NOT IN_P select_with_parens
                {
+                   /* Make an IN node */
                    SubLink *n = makeNode(SubLink);
                    n->lefthand = $1;
-                   n->oper = (List *) makeSimpleA_Expr(OP, "<>", NULL, NULL);
-                   n->useor = TRUE;
-                   n->subLinkType = ALL_SUBLINK;
+                   n->oper = (List *) makeSimpleA_Expr(OP, "=", NULL, NULL);
+                   n->subLinkType = ANY_SUBLINK;
+                   /* operIsEquals and useOr will be set later */
                    n->subselect = $4;
-                   $$ = (Node *)n;
+                   /* Stick a NOT on top */
+                   $$ = (Node *) makeA_Expr(NOT, NIL, NULL, (Node *) n);
                }
            | row qual_all_Op sub_type select_with_parens
            %prec Op
@@ -5449,11 +5451,8 @@ r_expr:  row IN_P select_with_parens
                    SubLink *n = makeNode(SubLink);
                    n->lefthand = $1;
                    n->oper = (List *) makeA_Expr(OP, $2, NULL, NULL);
-                   if (strcmp(strVal(llast($2)), "<>") == 0)
-                       n->useor = TRUE;
-                   else
-                       n->useor = FALSE;
                    n->subLinkType = $3;
+                   /* operIsEquals and useOr will be set later */
                    n->subselect = $4;
                    $$ = (Node *)n;
                }
@@ -5463,11 +5462,8 @@ r_expr:  row IN_P select_with_parens
                    SubLink *n = makeNode(SubLink);
                    n->lefthand = $1;
                    n->oper = (List *) makeA_Expr(OP, $2, NULL, NULL);
-                   if (strcmp(strVal(llast($2)), "<>") == 0)
-                       n->useor = TRUE;
-                   else
-                       n->useor = FALSE;
                    n->subLinkType = MULTIEXPR_SUBLINK;
+                   /* operIsEquals and useOr will be set later */
                    n->subselect = $3;
                    $$ = (Node *)n;
                }
@@ -5850,8 +5846,8 @@ a_expr:       c_expr                                  { $$ = $1; }
                            SubLink *n = (SubLink *)$3;
                            n->lefthand = makeList1($1);
                            n->oper = (List *) makeSimpleA_Expr(OP, "=", NULL, NULL);
-                           n->useor = FALSE;
                            n->subLinkType = ANY_SUBLINK;
+                           /* operIsEquals and useOr will be set later */
                            $$ = (Node *)n;
                    }
                    else
@@ -5875,12 +5871,14 @@ a_expr:     c_expr                                  { $$ = $1; }
                    /* in_expr returns a SubLink or a list of a_exprs */
                    if (IsA($4, SubLink))
                    {
+                       /* Make an IN node */
                        SubLink *n = (SubLink *)$4;
                        n->lefthand = makeList1($1);
-                       n->oper = (List *) makeSimpleA_Expr(OP, "<>", NULL, NULL);
-                       n->useor = FALSE;
-                       n->subLinkType = ALL_SUBLINK;
-                       $$ = (Node *)n;
+                       n->oper = (List *) makeSimpleA_Expr(OP, "=", NULL, NULL);
+                       n->subLinkType = ANY_SUBLINK;
+                       /* operIsEquals and useOr will be set later */
+                       /* Stick a NOT on top */
+                       $$ = (Node *) makeA_Expr(NOT, NIL, NULL, (Node *) n);
                    }
                    else
                    {
@@ -5903,8 +5901,8 @@ a_expr:       c_expr                                  { $$ = $1; }
                    SubLink *n = makeNode(SubLink);
                    n->lefthand = makeList1($1);
                    n->oper = (List *) makeA_Expr(OP, $2, NULL, NULL);
-                   n->useor = FALSE; /* doesn't matter since only one col */
                    n->subLinkType = $3;
+                   /* operIsEquals and useOr will be set later */
                    n->subselect = $4;
                    $$ = (Node *)n;
                }
@@ -6447,7 +6445,6 @@ c_expr:       columnref                               { $$ = (Node *) $1; }
                    SubLink *n = makeNode(SubLink);
                    n->lefthand = NIL;
                    n->oper = NIL;
-                   n->useor = FALSE;
                    n->subLinkType = EXPR_SUBLINK;
                    n->subselect = $1;
                    $$ = (Node *)n;
@@ -6457,7 +6454,6 @@ c_expr:       columnref                               { $$ = (Node *) $1; }
                    SubLink *n = makeNode(SubLink);
                    n->lefthand = NIL;
                    n->oper = NIL;
-                   n->useor = FALSE;
                    n->subLinkType = EXISTS_SUBLINK;
                    n->subselect = $2;
                    $$ = (Node *)n;
index 9705ca5d7de558a26c183987e6e68253df8694e6..3701f41dca0b1c192d6ef54cf3a54926ce3e16db 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.138 2002/12/27 20:06:19 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.139 2003/01/09 20:50:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -367,6 +367,8 @@ transformExpr(ParseState *pstate, Node *expr)
                     */
                    sublink->lefthand = NIL;
                    sublink->oper = NIL;
+                   sublink->operIsEquals = FALSE;
+                   sublink->useOr = FALSE;
                }
                else if (sublink->subLinkType == EXPR_SUBLINK)
                {
@@ -391,27 +393,60 @@ transformExpr(ParseState *pstate, Node *expr)
                     */
                    sublink->lefthand = NIL;
                    sublink->oper = NIL;
+                   sublink->operIsEquals = FALSE;
+                   sublink->useOr = FALSE;
                }
                else
                {
                    /* ALL, ANY, or MULTIEXPR: generate operator list */
                    List       *left_list = sublink->lefthand;
                    List       *right_list = qtree->targetList;
+                   int         row_length = length(left_list);
+                   bool        needNot = false;
                    List       *op;
                    char       *opname;
                    List       *elist;
 
+                   /* transform lefthand expressions */
                    foreach(elist, left_list)
                        lfirst(elist) = transformExpr(pstate, lfirst(elist));
 
+                   /* get the combining-operator name */
                    Assert(IsA(sublink->oper, A_Expr));
                    op = ((A_Expr *) sublink->oper)->name;
                    opname = strVal(llast(op));
                    sublink->oper = NIL;
 
+                   /*
+                    * If the expression is "<> ALL" (with unqualified opname)
+                    * then convert it to "NOT IN".  This is a hack to improve
+                    * efficiency of expressions output by pre-7.4 Postgres.
+                    */
+                   if (sublink->subLinkType == ALL_SUBLINK &&
+                       length(op) == 1 && strcmp(opname, "<>") == 0)
+                   {
+                       sublink->subLinkType = ANY_SUBLINK;
+                       opname = pstrdup("=");
+                       op = makeList1(makeString(opname));
+                       needNot = true;
+                   }
+
+                   /* Set operIsEquals if op is unqualified "=" */
+                   if (length(op) == 1 && strcmp(opname, "=") == 0)
+                       sublink->operIsEquals = TRUE;
+                   else
+                       sublink->operIsEquals = FALSE;
+
+                   /* Set useOr if op is "<>" (possibly qualified) */
+                   if (strcmp(opname, "<>") == 0)
+                       sublink->useOr = TRUE;
+                   else
+                       sublink->useOr = FALSE;
+
                    /* Combining operators other than =/<> is dubious... */
-                   if (length(left_list) != 1 &&
-                   strcmp(opname, "=") != 0 && strcmp(opname, "<>") != 0)
+                   if (row_length != 1 &&
+                       strcmp(opname, "=") != 0 &&
+                       strcmp(opname, "<>") != 0)
                        elog(ERROR, "Row comparison cannot use operator %s",
                             opname);
 
@@ -474,6 +509,13 @@ transformExpr(ParseState *pstate, Node *expr)
                    }
                    if (left_list != NIL)
                        elog(ERROR, "Subselect has too few fields");
+
+                   if (needNot)
+                   {
+                       expr = coerce_to_boolean(expr, "NOT");
+                       expr = (Node *) makeBoolExpr(NOT_EXPR,
+                                                    makeList1(expr));
+                   }
                }
                result = (Node *) expr;
                break;
index 0275d8424acc86ce8d75b5f5e46a74847eb64d08..a8679463670859bee1e1f8a2a6efed82c6a294e8 100644 (file)
@@ -3,7 +3,7 @@
  *             back to source text
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.130 2003/01/08 22:54:06 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.131 2003/01/09 20:50:52 tgl Exp $
  *
  *   This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -2660,8 +2660,16 @@ get_sublink_expr(SubLink *sublink, deparse_context *context)
            break;
 
        case ANY_SUBLINK:
-           oper = (OpExpr *) lfirst(sublink->oper);
-           appendStringInfo(buf, "%s ANY ", get_opname(oper->opno));
+           if (sublink->operIsEquals)
+           {
+               /* Represent it as IN */
+               appendStringInfo(buf, "IN ");
+           }
+           else
+           {
+               oper = (OpExpr *) lfirst(sublink->oper);
+               appendStringInfo(buf, "%s ANY ", get_opname(oper->opno));
+           }
            break;
 
        case ALL_SUBLINK:
index 710b5c71ac888ab3c4fb755981189a6bb213185f..9c3e5906adeb9d69788123327e43cc9c71f2b2bd 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: catversion.h,v 1.170 2002/12/12 21:02:25 momjian Exp $
+ * $Id: catversion.h,v 1.171 2003/01/09 20:50:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 200212121
+#define CATALOG_VERSION_NO 200301091
 
 #endif
index 285a0008fdc31d90c94414f5014b2ec1141d5cd3..d9ea05994dd326a46703cf02676cfd0cafdef1cb 100644 (file)
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: primnodes.h,v 1.75 2002/12/14 00:17:59 tgl Exp $
+ * $Id: primnodes.h,v 1.76 2003/01/09 20:50:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -374,7 +374,7 @@ typedef struct BoolExpr
  * MULTIEXPR and EXPR require the subselect to deliver only one row.
  * ALL, ANY, and MULTIEXPR require the combining operators to deliver boolean
  * results.  These are reduced to one result per row using OR or AND semantics
- * depending on the "useor" flag.  ALL and ANY combine the per-row results
+ * depending on the "useOr" flag.  ALL and ANY combine the per-row results
  * using AND and OR semantics respectively.
  *
  * SubLink is classed as an Expr node, but it is not actually executable;
@@ -395,7 +395,11 @@ typedef struct BoolExpr
  * rewriter.
  *
  * In EXISTS and EXPR SubLinks, both lefthand and oper are unused and are
- * always NIL. useor is not significant either for these sublink types.
+ * always NIL. useOr is not significant either for these sublink types.
+ *
+ * The operIsEquals field is TRUE when the combining operator was written as
+ * "=" --- if the subLinkType is ANY_SUBLINK, this means the operation is
+ * equivalent to "IN".  This case allows special optimizations to be used.
  * ----------------
  */
 typedef enum SubLinkType
@@ -408,7 +412,8 @@ typedef struct SubLink
 {
    Expr        xpr;
    SubLinkType subLinkType;    /* EXISTS, ALL, ANY, MULTIEXPR, EXPR */
-   bool        useor;          /* TRUE to combine column results with
+   bool        operIsEquals;   /* TRUE if combining operator is "=" */
+   bool        useOr;          /* TRUE to combine column results with
                                 * "OR" not "AND" */
    List       *lefthand;       /* list of outer-query expressions on the
                                 * left */
@@ -446,7 +451,7 @@ typedef struct SubPlan
    Expr        xpr;
    /* Fields copied from original SubLink: */
    SubLinkType subLinkType;    /* EXISTS, ALL, ANY, MULTIEXPR, EXPR */
-   bool        useor;          /* TRUE to combine column results with
+   bool        useOr;          /* TRUE to combine column results with
                                 * "OR" not "AND" */
    List       *oper;           /* list of executable expressions for
                                 * combining operators (with arguments) */