Remove operator_precedence_warning.
authorTom Lane <[email protected]>
Tue, 8 Dec 2020 21:29:52 +0000 (16:29 -0500)
committerTom Lane <[email protected]>
Tue, 8 Dec 2020 21:29:52 +0000 (16:29 -0500)
This GUC was always intended as a temporary solution to help with
finding 9.4-to-9.5 migration issues.  Now that all pre-9.5 branches
are out of support, and 9.5 will be too before v14 is released,
it seems like it's okay to drop it.  Doing so allows removal of
several hundred lines of poorly-tested code in parse_expr.c,
which have been a fertile source of bugs when people did use this.

Discussion: https://postgr.es/m/2234320.1607117945@sss.pgh.pa.us

doc/src/sgml/config.sgml
doc/src/sgml/syntax.sgml
src/backend/nodes/outfuncs.c
src/backend/parser/gram.y
src/backend/parser/parse_expr.c
src/backend/parser/parse_target.c
src/backend/utils/misc/guc.c
src/backend/utils/misc/postgresql.conf.sample
src/include/nodes/parsenodes.h
src/include/parser/parse_expr.h

index 8cd3d6901c573c90ceaca33f3b6dfbcd662ed4c3..4b60382778f760f713d63d4b3fa8fbadda99f89b 100644 (file)
@@ -9389,29 +9389,6 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
       </listitem>
      </varlistentry>
 
-     <varlistentry id="guc-operator-precedence-warning" xreflabel="operator_precedence_warning">
-      <term><varname>operator_precedence_warning</varname> (<type>boolean</type>)
-      <indexterm>
-       <primary><varname>operator_precedence_warning</varname> configuration parameter</primary>
-      </indexterm>
-      </term>
-      <listitem>
-       <para>
-        When on, the parser will emit a warning for any construct that might
-        have changed meanings since <productname>PostgreSQL</productname> 9.4 as a result
-        of changes in operator precedence.  This is useful for auditing
-        applications to see if precedence changes have broken anything; but it
-        is not meant to be kept turned on in production, since it will warn
-        about some perfectly valid, standard-compliant SQL code.
-        The default is <literal>off</literal>.
-       </para>
-
-       <para>
-        See <xref linkend="sql-precedence"/> for more information.
-       </para>
-      </listitem>
-     </varlistentry>
-
     <varlistentry id="guc-quote-all-identifiers" xreflabel="quote-all-identifiers">
       <term><varname>quote_all_identifiers</varname> (<type>boolean</type>)
       <indexterm>
index 3fdd87823e0082fab97c2fc6a0e84af1d147de7a..d66560b587c66e99aaf7c79cefe91bf2b3e34917 100644 (file)
@@ -1121,11 +1121,7 @@ SELECT 3 OPERATOR(pg_catalog.+) 4;
      cases, these changes will result in no behavioral change, or perhaps
      in <quote>no such operator</quote> failures which can be resolved by adding
      parentheses.  However there are corner cases in which a query might
-     change behavior without any parsing error being reported.  If you are
-     concerned about whether these changes have silently broken something,
-     you can test your application with the configuration
-     parameter <xref linkend="guc-operator-precedence-warning"/> turned on
-     to see if any warnings are logged.
+     change behavior without any parsing error being reported.
     </para>
    </note>
   </sect2>
index 9c73c605a425cc9d173bf183af8d57f24497598c..8f5e4e71b28f18a68c5502d78bc693dd41befbc1 100644 (file)
@@ -3264,9 +3264,6 @@ _outAExpr(StringInfo str, const A_Expr *node)
            appendStringInfoString(str, " NOT_BETWEEN_SYM ");
            WRITE_NODE_FIELD(name);
            break;
-       case AEXPR_PAREN:
-           appendStringInfoString(str, " PAREN");
-           break;
        default:
            appendStringInfoString(str, " ??");
            break;
index ecff4cd2ac2d07d89440a0504ca1ffb6c900c730..8f341ac00612660b758844ce216e8e0931e1ec33 100644 (file)
@@ -59,7 +59,6 @@
 #include "nodes/nodeFuncs.h"
 #include "parser/gramparse.h"
 #include "parser/parser.h"
-#include "parser/parse_expr.h"
 #include "storage/lmgr.h"
 #include "utils/date.h"
 #include "utils/datetime.h"
@@ -13461,28 +13460,6 @@ c_expr:        columnref                               { $$ = $1; }
                        n->indirection = check_indirection($4, yyscanner);
                        $$ = (Node *)n;
                    }
-                   else if (operator_precedence_warning)
-                   {
-                       /*
-                        * If precedence warnings are enabled, insert
-                        * AEXPR_PAREN nodes wrapping all explicitly
-                        * parenthesized subexpressions; this prevents bogus
-                        * warnings from being issued when the ordering has
-                        * been forced by parentheses.  Take care that an
-                        * AEXPR_PAREN node has the same exprLocation as its
-                        * child, so as not to cause surprising changes in
-                        * error cursor positioning.
-                        *
-                        * In principle we should not be relying on a GUC to
-                        * decide whether to insert AEXPR_PAREN nodes.
-                        * However, since they have no effect except to
-                        * suppress warnings, it's probably safe enough; and
-                        * we'd just as soon not waste cycles on dummy parse
-                        * nodes if we don't have to.
-                        */
-                       $$ = (Node *) makeA_Expr(AEXPR_PAREN, NIL, $2, NULL,
-                                                exprLocation($2));
-                   }
                    else
                        $$ = $2;
                }
@@ -16516,16 +16493,10 @@ doNegateFloat(Value *v)
 static Node *
 makeAndExpr(Node *lexpr, Node *rexpr, int location)
 {
-   Node       *lexp = lexpr;
-
-   /* Look through AEXPR_PAREN nodes so they don't affect flattening */
-   while (IsA(lexp, A_Expr) &&
-          ((A_Expr *) lexp)->kind == AEXPR_PAREN)
-       lexp = ((A_Expr *) lexp)->lexpr;
    /* Flatten "a AND b AND c ..." to a single BoolExpr on sight */
-   if (IsA(lexp, BoolExpr))
+   if (IsA(lexpr, BoolExpr))
    {
-       BoolExpr *blexpr = (BoolExpr *) lexp;
+       BoolExpr *blexpr = (BoolExpr *) lexpr;
 
        if (blexpr->boolop == AND_EXPR)
        {
@@ -16539,16 +16510,10 @@ makeAndExpr(Node *lexpr, Node *rexpr, int location)
 static Node *
 makeOrExpr(Node *lexpr, Node *rexpr, int location)
 {
-   Node       *lexp = lexpr;
-
-   /* Look through AEXPR_PAREN nodes so they don't affect flattening */
-   while (IsA(lexp, A_Expr) &&
-          ((A_Expr *) lexp)->kind == AEXPR_PAREN)
-       lexp = ((A_Expr *) lexp)->lexpr;
    /* Flatten "a OR b OR c ..." to a single BoolExpr on sight */
-   if (IsA(lexp, BoolExpr))
+   if (IsA(lexpr, BoolExpr))
    {
-       BoolExpr *blexpr = (BoolExpr *) lexp;
+       BoolExpr *blexpr = (BoolExpr *) lexpr;
 
        if (blexpr->boolop == OR_EXPR)
        {
index 36002f059d1eddad7988c4e1289348330da30764..1e62d31aca7e9c917dbecdc9b133d1f382e57088 100644 (file)
 #include "utils/xml.h"
 
 /* GUC parameters */
-bool       operator_precedence_warning = false;
 bool       Transform_null_equals = false;
 
-/*
- * Node-type groups for operator precedence warnings
- * We use zero for everything not otherwise classified
- */
-#define PREC_GROUP_POSTFIX_IS  1   /* postfix IS tests (NullTest, etc) */
-#define PREC_GROUP_INFIX_IS        2   /* infix IS (IS DISTINCT FROM, etc) */
-#define PREC_GROUP_LESS            3   /* < > */
-#define PREC_GROUP_EQUAL       4   /* = */
-#define PREC_GROUP_LESS_EQUAL  5   /* <= >= <> */
-#define PREC_GROUP_LIKE            6   /* LIKE ILIKE SIMILAR */
-#define PREC_GROUP_BETWEEN     7   /* BETWEEN */
-#define PREC_GROUP_IN          8   /* IN */
-#define PREC_GROUP_NOT_LIKE        9   /* NOT LIKE/ILIKE/SIMILAR */
-#define PREC_GROUP_NOT_BETWEEN 10  /* NOT BETWEEN */
-#define PREC_GROUP_NOT_IN      11  /* NOT IN */
-#define PREC_GROUP_ANY_ALL     12  /* ANY/ALL */
-#define PREC_GROUP_INFIX_OP        13  /* generic infix operators */
-#define PREC_GROUP_PREFIX_OP   14  /* generic prefix operators */
-
-/*
- * Map precedence groupings to old precedence ordering
- *
- * Old precedence order:
- * 1. NOT
- * 2. =
- * 3. < >
- * 4. LIKE ILIKE SIMILAR
- * 5. BETWEEN
- * 6. IN
- * 7. ANY ALL
- * 8. generic Op, including <= => <>
- * 9. generic prefix Op
- * 10. IS tests (NullTest, BooleanTest, etc)
- *
- * NOT BETWEEN etc map to BETWEEN etc when considered as being on the left,
- * but to NOT when considered as being on the right, because of the buggy
- * precedence handling of those productions in the old grammar.
- */
-static const int oldprecedence_l[] = {
-   0, 10, 10, 3, 2, 8, 4, 5, 6, 4, 5, 6, 7, 8, 9
-};
-static const int oldprecedence_r[] = {
-   0, 10, 10, 3, 2, 8, 4, 5, 6, 1, 1, 1, 7, 8, 9
-};
 
 static Node *transformExprRecurse(ParseState *pstate, Node *expr);
 static Node *transformParamRef(ParseState *pstate, ParamRef *pref);
@@ -127,11 +82,6 @@ static Expr *make_distinct_op(ParseState *pstate, List *opname,
                              Node *ltree, Node *rtree, int location);
 static Node *make_nulltest_from_distinct(ParseState *pstate,
                                         A_Expr *distincta, Node *arg);
-static int operator_precedence_group(Node *node, const char **nodename);
-static void emit_precedence_warnings(ParseState *pstate,
-                                    int opgroup, const char *opname,
-                                    Node *lchild, Node *rchild,
-                                    int location);
 
 
 /*
@@ -242,9 +192,6 @@ transformExprRecurse(ParseState *pstate, Node *expr)
                    case AEXPR_NOT_BETWEEN_SYM:
                        result = transformAExprBetween(pstate, a);
                        break;
-                   case AEXPR_PAREN:
-                       result = transformExprRecurse(pstate, a->lexpr);
-                       break;
                    default:
                        elog(ERROR, "unrecognized A_Expr kind: %d", a->kind);
                        result = NULL;  /* keep compiler quiet */
@@ -315,11 +262,6 @@ transformExprRecurse(ParseState *pstate, Node *expr)
            {
                NullTest   *n = (NullTest *) expr;
 
-               if (operator_precedence_warning)
-                   emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_IS, "IS",
-                                            (Node *) n->arg, NULL,
-                                            n->location);
-
                n->arg = (Expr *) transformExprRecurse(pstate, (Node *) n->arg);
                /* the argument can be any type, so don't coerce it */
                n->argisrow = type_is_rowtype(exprType((Node *) n->arg));
@@ -926,26 +868,6 @@ transformAExprOp(ParseState *pstate, A_Expr *a)
    Node       *rexpr = a->rexpr;
    Node       *result;
 
-   if (operator_precedence_warning)
-   {
-       int         opgroup;
-       const char *opname;
-
-       opgroup = operator_precedence_group((Node *) a, &opname);
-       if (opgroup > 0)
-           emit_precedence_warnings(pstate, opgroup, opname,
-                                    lexpr, rexpr,
-                                    a->location);
-
-       /* Look through AEXPR_PAREN nodes so they don't affect tests below */
-       while (lexpr && IsA(lexpr, A_Expr) &&
-              ((A_Expr *) lexpr)->kind == AEXPR_PAREN)
-           lexpr = ((A_Expr *) lexpr)->lexpr;
-       while (rexpr && IsA(rexpr, A_Expr) &&
-              ((A_Expr *) rexpr)->kind == AEXPR_PAREN)
-           rexpr = ((A_Expr *) rexpr)->lexpr;
-   }
-
    /*
     * Special-case "foo = NULL" and "NULL = foo" for compatibility with
     * standards-broken products (like Microsoft's).  Turn these into IS NULL
@@ -1023,17 +945,8 @@ transformAExprOp(ParseState *pstate, A_Expr *a)
 static Node *
 transformAExprOpAny(ParseState *pstate, A_Expr *a)
 {
-   Node       *lexpr = a->lexpr;
-   Node       *rexpr = a->rexpr;
-
-   if (operator_precedence_warning)
-       emit_precedence_warnings(pstate, PREC_GROUP_ANY_ALL,
-                                strVal(llast(a->name)),
-                                lexpr, NULL,
-                                a->location);
-
-   lexpr = transformExprRecurse(pstate, lexpr);
-   rexpr = transformExprRecurse(pstate, rexpr);
+   Node       *lexpr = transformExprRecurse(pstate, a->lexpr);
+   Node       *rexpr = transformExprRecurse(pstate, a->rexpr);
 
    return (Node *) make_scalar_array_op(pstate,
                                         a->name,
@@ -1046,17 +959,8 @@ transformAExprOpAny(ParseState *pstate, A_Expr *a)
 static Node *
 transformAExprOpAll(ParseState *pstate, A_Expr *a)
 {
-   Node       *lexpr = a->lexpr;
-   Node       *rexpr = a->rexpr;
-
-   if (operator_precedence_warning)
-       emit_precedence_warnings(pstate, PREC_GROUP_ANY_ALL,
-                                strVal(llast(a->name)),
-                                lexpr, NULL,
-                                a->location);
-
-   lexpr = transformExprRecurse(pstate, lexpr);
-   rexpr = transformExprRecurse(pstate, rexpr);
+   Node       *lexpr = transformExprRecurse(pstate, a->lexpr);
+   Node       *rexpr = transformExprRecurse(pstate, a->rexpr);
 
    return (Node *) make_scalar_array_op(pstate,
                                         a->name,
@@ -1073,11 +977,6 @@ transformAExprDistinct(ParseState *pstate, A_Expr *a)
    Node       *rexpr = a->rexpr;
    Node       *result;
 
-   if (operator_precedence_warning)
-       emit_precedence_warnings(pstate, PREC_GROUP_INFIX_IS, "IS",
-                                lexpr, rexpr,
-                                a->location);
-
    /*
     * If either input is an undecorated NULL literal, transform to a NullTest
     * on the other input. That's simpler to process than a full DistinctExpr,
@@ -1183,13 +1082,6 @@ transformAExprIn(ParseState *pstate, A_Expr *a)
    else
        useOr = true;
 
-   if (operator_precedence_warning)
-       emit_precedence_warnings(pstate,
-                                useOr ? PREC_GROUP_IN : PREC_GROUP_NOT_IN,
-                                "IN",
-                                a->lexpr, NULL,
-                                a->location);
-
    /*
     * We try to generate a ScalarArrayOpExpr from IN/NOT IN, but this is only
     * possible if there is a suitable array type available.  If not, we fall
@@ -1342,22 +1234,6 @@ transformAExprBetween(ParseState *pstate, A_Expr *a)
    bexpr = (Node *) linitial(args);
    cexpr = (Node *) lsecond(args);
 
-   if (operator_precedence_warning)
-   {
-       int         opgroup;
-       const char *opname;
-
-       opgroup = operator_precedence_group((Node *) a, &opname);
-       emit_precedence_warnings(pstate, opgroup, opname,
-                                aexpr, cexpr,
-                                a->location);
-       /* We can ignore bexpr thanks to syntactic restrictions */
-       /* Wrap subexpressions to prevent extra warnings */
-       aexpr = (Node *) makeA_Expr(AEXPR_PAREN, NIL, aexpr, NULL, -1);
-       bexpr = (Node *) makeA_Expr(AEXPR_PAREN, NIL, bexpr, NULL, -1);
-       cexpr = (Node *) makeA_Expr(AEXPR_PAREN, NIL, cexpr, NULL, -1);
-   }
-
    /*
     * Build the equivalent comparison expression.  Make copies of
     * multiply-referenced subexpressions for safety.  (XXX this is really
@@ -1964,19 +1840,6 @@ transformSubLink(ParseState *pstate, SubLink *sublink)
        List       *right_list;
        ListCell   *l;
 
-       if (operator_precedence_warning)
-       {
-           if (sublink->operName == NIL)
-               emit_precedence_warnings(pstate, PREC_GROUP_IN, "IN",
-                                        sublink->testexpr, NULL,
-                                        sublink->location);
-           else
-               emit_precedence_warnings(pstate, PREC_GROUP_ANY_ALL,
-                                        strVal(llast(sublink->operName)),
-                                        sublink->testexpr, NULL,
-                                        sublink->location);
-       }
-
        /*
         * If the source was "x IN (select)", convert to "x = ANY (select)".
         */
@@ -2076,11 +1939,6 @@ transformArrayExpr(ParseState *pstate, A_ArrayExpr *a,
        Node       *e = (Node *) lfirst(element);
        Node       *newe;
 
-       /* Look through AEXPR_PAREN nodes so they don't affect test below */
-       while (e && IsA(e, A_Expr) &&
-              ((A_Expr *) e)->kind == AEXPR_PAREN)
-           e = ((A_Expr *) e)->lexpr;
-
        /*
         * If an element is itself an A_ArrayExpr, recurse directly so that we
         * can pass down any target type we were given.
@@ -2389,11 +2247,6 @@ transformXmlExpr(ParseState *pstate, XmlExpr *x)
    ListCell   *lc;
    int         i;
 
-   if (operator_precedence_warning && x->op == IS_DOCUMENT)
-       emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_IS, "IS",
-                                (Node *) linitial(x->args), NULL,
-                                x->location);
-
    newx = makeNode(XmlExpr);
    newx->op = x->op;
    if (x->name)
@@ -2564,11 +2417,6 @@ transformBooleanTest(ParseState *pstate, BooleanTest *b)
 {
    const char *clausename;
 
-   if (operator_precedence_warning)
-       emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_IS, "IS",
-                                (Node *) b->arg, NULL,
-                                b->location);
-
    switch (b->booltesttype)
    {
        case IS_TRUE:
@@ -2702,15 +2550,6 @@ transformTypeCast(ParseState *pstate, TypeCast *tc)
    /* Look up the type name first */
    typenameTypeIdAndMod(pstate, tc->typeName, &targetType, &targetTypmod);
 
-   /*
-    * Look through any AEXPR_PAREN nodes that may have been inserted thanks
-    * to operator_precedence_warning.  Otherwise, ARRAY[]::foo[] behaves
-    * differently from (ARRAY[])::foo[].
-    */
-   while (arg && IsA(arg, A_Expr) &&
-          ((A_Expr *) arg)->kind == AEXPR_PAREN)
-       arg = ((A_Expr *) arg)->lexpr;
-
    /*
     * If the subject of the typecast is an ARRAY[] construct and the target
     * type is an array type, we invoke transformArrayExpr() directly so that
@@ -3117,287 +2956,6 @@ make_nulltest_from_distinct(ParseState *pstate, A_Expr *distincta, Node *arg)
    return (Node *) nt;
 }
 
-/*
- * Identify node's group for operator precedence warnings
- *
- * For items in nonzero groups, also return a suitable node name into *nodename
- *
- * Note: group zero is used for nodes that are higher or lower precedence
- * than everything that changed precedence; we need never issue warnings
- * related to such nodes.
- */
-static int
-operator_precedence_group(Node *node, const char **nodename)
-{
-   int         group = 0;
-
-   *nodename = NULL;
-   if (node == NULL)
-       return 0;
-
-   if (IsA(node, A_Expr))
-   {
-       A_Expr     *aexpr = (A_Expr *) node;
-
-       if (aexpr->kind == AEXPR_OP &&
-           aexpr->lexpr != NULL &&
-           aexpr->rexpr != NULL)
-       {
-           /* binary operator */
-           if (list_length(aexpr->name) == 1)
-           {
-               *nodename = strVal(linitial(aexpr->name));
-               /* Ignore if op was always higher priority than IS-tests */
-               if (strcmp(*nodename, "+") == 0 ||
-                   strcmp(*nodename, "-") == 0 ||
-                   strcmp(*nodename, "*") == 0 ||
-                   strcmp(*nodename, "/") == 0 ||
-                   strcmp(*nodename, "%") == 0 ||
-                   strcmp(*nodename, "^") == 0)
-                   group = 0;
-               else if (strcmp(*nodename, "<") == 0 ||
-                        strcmp(*nodename, ">") == 0)
-                   group = PREC_GROUP_LESS;
-               else if (strcmp(*nodename, "=") == 0)
-                   group = PREC_GROUP_EQUAL;
-               else if (strcmp(*nodename, "<=") == 0 ||
-                        strcmp(*nodename, ">=") == 0 ||
-                        strcmp(*nodename, "<>") == 0)
-                   group = PREC_GROUP_LESS_EQUAL;
-               else
-                   group = PREC_GROUP_INFIX_OP;
-           }
-           else
-           {
-               /* schema-qualified operator syntax */
-               *nodename = "OPERATOR()";
-               group = PREC_GROUP_INFIX_OP;
-           }
-       }
-       else if (aexpr->kind == AEXPR_OP &&
-                aexpr->lexpr == NULL &&
-                aexpr->rexpr != NULL)
-       {
-           /* prefix operator */
-           if (list_length(aexpr->name) == 1)
-           {
-               *nodename = strVal(linitial(aexpr->name));
-               /* Ignore if op was always higher priority than IS-tests */
-               if (strcmp(*nodename, "+") == 0 ||
-                   strcmp(*nodename, "-") == 0)
-                   group = 0;
-               else
-                   group = PREC_GROUP_PREFIX_OP;
-           }
-           else
-           {
-               /* schema-qualified operator syntax */
-               *nodename = "OPERATOR()";
-               group = PREC_GROUP_PREFIX_OP;
-           }
-       }
-       else if (aexpr->kind == AEXPR_OP_ANY ||
-                aexpr->kind == AEXPR_OP_ALL)
-       {
-           *nodename = strVal(llast(aexpr->name));
-           group = PREC_GROUP_ANY_ALL;
-       }
-       else if (aexpr->kind == AEXPR_DISTINCT ||
-                aexpr->kind == AEXPR_NOT_DISTINCT)
-       {
-           *nodename = "IS";
-           group = PREC_GROUP_INFIX_IS;
-       }
-       else if (aexpr->kind == AEXPR_IN)
-       {
-           *nodename = "IN";
-           if (strcmp(strVal(linitial(aexpr->name)), "=") == 0)
-               group = PREC_GROUP_IN;
-           else
-               group = PREC_GROUP_NOT_IN;
-       }
-       else if (aexpr->kind == AEXPR_LIKE)
-       {
-           *nodename = "LIKE";
-           if (strcmp(strVal(linitial(aexpr->name)), "~~") == 0)
-               group = PREC_GROUP_LIKE;
-           else
-               group = PREC_GROUP_NOT_LIKE;
-       }
-       else if (aexpr->kind == AEXPR_ILIKE)
-       {
-           *nodename = "ILIKE";
-           if (strcmp(strVal(linitial(aexpr->name)), "~~*") == 0)
-               group = PREC_GROUP_LIKE;
-           else
-               group = PREC_GROUP_NOT_LIKE;
-       }
-       else if (aexpr->kind == AEXPR_SIMILAR)
-       {
-           *nodename = "SIMILAR";
-           if (strcmp(strVal(linitial(aexpr->name)), "~") == 0)
-               group = PREC_GROUP_LIKE;
-           else
-               group = PREC_GROUP_NOT_LIKE;
-       }
-       else if (aexpr->kind == AEXPR_BETWEEN ||
-                aexpr->kind == AEXPR_BETWEEN_SYM)
-       {
-           Assert(list_length(aexpr->name) == 1);
-           *nodename = strVal(linitial(aexpr->name));
-           group = PREC_GROUP_BETWEEN;
-       }
-       else if (aexpr->kind == AEXPR_NOT_BETWEEN ||
-                aexpr->kind == AEXPR_NOT_BETWEEN_SYM)
-       {
-           Assert(list_length(aexpr->name) == 1);
-           *nodename = strVal(linitial(aexpr->name));
-           group = PREC_GROUP_NOT_BETWEEN;
-       }
-   }
-   else if (IsA(node, NullTest) ||
-            IsA(node, BooleanTest))
-   {
-       *nodename = "IS";
-       group = PREC_GROUP_POSTFIX_IS;
-   }
-   else if (IsA(node, XmlExpr))
-   {
-       XmlExpr    *x = (XmlExpr *) node;
-
-       if (x->op == IS_DOCUMENT)
-       {
-           *nodename = "IS";
-           group = PREC_GROUP_POSTFIX_IS;
-       }
-   }
-   else if (IsA(node, SubLink))
-   {
-       SubLink    *s = (SubLink *) node;
-
-       if (s->subLinkType == ANY_SUBLINK ||
-           s->subLinkType == ALL_SUBLINK)
-       {
-           if (s->operName == NIL)
-           {
-               *nodename = "IN";
-               group = PREC_GROUP_IN;
-           }
-           else
-           {
-               *nodename = strVal(llast(s->operName));
-               group = PREC_GROUP_ANY_ALL;
-           }
-       }
-   }
-   else if (IsA(node, BoolExpr))
-   {
-       /*
-        * Must dig into NOTs to see if it's IS NOT DOCUMENT or NOT IN.  This
-        * opens us to possibly misrecognizing, eg, NOT (x IS DOCUMENT) as a
-        * problematic construct.  We can tell the difference by checking
-        * whether the parse locations of the two nodes are identical.
-        *
-        * Note that when we are comparing the child node to its own children,
-        * we will not know that it was a NOT.  Fortunately, that doesn't
-        * matter for these cases.
-        */
-       BoolExpr   *b = (BoolExpr *) node;
-
-       if (b->boolop == NOT_EXPR)
-       {
-           Node       *child = (Node *) linitial(b->args);
-
-           if (IsA(child, XmlExpr))
-           {
-               XmlExpr    *x = (XmlExpr *) child;
-
-               if (x->op == IS_DOCUMENT &&
-                   x->location == b->location)
-               {
-                   *nodename = "IS";
-                   group = PREC_GROUP_POSTFIX_IS;
-               }
-           }
-           else if (IsA(child, SubLink))
-           {
-               SubLink    *s = (SubLink *) child;
-
-               if (s->subLinkType == ANY_SUBLINK && s->operName == NIL &&
-                   s->location == b->location)
-               {
-                   *nodename = "IN";
-                   group = PREC_GROUP_NOT_IN;
-               }
-           }
-       }
-   }
-   return group;
-}
-
-/*
- * helper routine for delivering 9.4-to-9.5 operator precedence warnings
- *
- * opgroup/opname/location represent some parent node
- * lchild, rchild are its left and right children (either could be NULL)
- *
- * This should be called before transforming the child nodes, since if a
- * precedence-driven parsing change has occurred in a query that used to work,
- * it's quite possible that we'll get a semantic failure while analyzing the
- * child expression.  We want to produce the warning before that happens.
- * In any case, operator_precedence_group() expects untransformed input.
- */
-static void
-emit_precedence_warnings(ParseState *pstate,
-                        int opgroup, const char *opname,
-                        Node *lchild, Node *rchild,
-                        int location)
-{
-   int         cgroup;
-   const char *copname;
-
-   Assert(opgroup > 0);
-
-   /*
-    * Complain if left child, which should be same or higher precedence
-    * according to current rules, used to be lower precedence.
-    *
-    * Exception to precedence rules: if left child is IN or NOT IN the
-    * grouping is syntactically forced regardless of precedence.
-    */
-   cgroup = operator_precedence_group(lchild, &copname);
-   if (cgroup > 0)
-   {
-       if (oldprecedence_l[cgroup] < oldprecedence_r[opgroup] &&
-           cgroup != PREC_GROUP_IN &&
-           cgroup != PREC_GROUP_NOT_IN &&
-           cgroup != PREC_GROUP_ANY_ALL &&
-           cgroup != PREC_GROUP_POSTFIX_IS)
-           ereport(WARNING,
-                   (errmsg("operator precedence change: %s is now lower precedence than %s",
-                           opname, copname),
-                    parser_errposition(pstate, location)));
-   }
-
-   /*
-    * Complain if right child, which should be higher precedence according to
-    * current rules, used to be same or lower precedence.
-    *
-    * Exception to precedence rules: if right child is a prefix operator, the
-    * grouping is syntactically forced regardless of precedence.
-    */
-   cgroup = operator_precedence_group(rchild, &copname);
-   if (cgroup > 0)
-   {
-       if (oldprecedence_r[cgroup] <= oldprecedence_l[opgroup] &&
-           cgroup != PREC_GROUP_PREFIX_OP)
-           ereport(WARNING,
-                   (errmsg("operator precedence change: %s is now lower precedence than %s",
-                           opname, copname),
-                    parser_errposition(pstate, location)));
-   }
-}
-
 /*
  * Produce a string identifying an expression by kind.
  *
index 9de0cff8338962b54ca27c4cf75e58887adfe0f7..ce68663cc2c2ee1763c1e900103a4f8fd5225c19 100644 (file)
@@ -1755,11 +1755,6 @@ FigureColnameInternal(Node *node, char **name)
                *name = "nullif";
                return 2;
            }
-           if (((A_Expr *) node)->kind == AEXPR_PAREN)
-           {
-               /* look through dummy parenthesis node */
-               return FigureColnameInternal(((A_Expr *) node)->lexpr, name);
-           }
            break;
        case T_TypeCast:
            strength = FigureColnameInternal(((TypeCast *) node)->arg,
index 635d91d50ac065fe318c8d1eab7456ad14033adc..dabcbb07360bfe5a7ef501356c9d6ed7245be8b4 100644 (file)
@@ -1878,16 +1878,6 @@ static struct config_bool ConfigureNamesBool[] =
        NULL, NULL, NULL
    },
 
-   {
-       {"operator_precedence_warning", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
-           gettext_noop("Emit a warning for constructs that changed meaning since PostgreSQL 9.4."),
-           NULL,
-       },
-       &operator_precedence_warning,
-       false,
-       NULL, NULL, NULL
-   },
-
    {
        {"quote_all_identifiers", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
            gettext_noop("When generating SQL fragments, quote all identifiers."),
index 9c9091e601ed6e678446dd73403ebb609ded5d2f..b7fb2ec1feb6bf00c493adc0156e9cfa67f4a3be 100644 (file)
 #backslash_quote = safe_encoding   # on, off, or safe_encoding
 #escape_string_warning = on
 #lo_compat_privileges = off
-#operator_precedence_warning = off
 #quote_all_identifiers = off
 #standard_conforming_strings = on
 #synchronize_seqscans = on
index ec14fc2036f16c21899ff24eb49ab43a83d20cb2..48a79a76573485cdd7b221f77ca9887f2a1a3587 100644 (file)
@@ -265,8 +265,7 @@ typedef enum A_Expr_Kind
    AEXPR_BETWEEN,              /* name must be "BETWEEN" */
    AEXPR_NOT_BETWEEN,          /* name must be "NOT BETWEEN" */
    AEXPR_BETWEEN_SYM,          /* name must be "BETWEEN SYMMETRIC" */
-   AEXPR_NOT_BETWEEN_SYM,      /* name must be "NOT BETWEEN SYMMETRIC" */
-   AEXPR_PAREN                 /* nameless dummy node for parentheses */
+   AEXPR_NOT_BETWEEN_SYM       /* name must be "NOT BETWEEN SYMMETRIC" */
 } A_Expr_Kind;
 
 typedef struct A_Expr
index b01d3b7dec55dc0441742e414fa10155c8cb0ffb..5668f88302e8ba67a247a275d801721d9259a356 100644 (file)
@@ -16,7 +16,6 @@
 #include "parser/parse_node.h"
 
 /* GUC parameters */
-extern bool operator_precedence_warning;
 extern bool Transform_null_equals;
 
 extern Node *transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind);