diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 8cd3d6901c..4b60382778 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -9389,29 +9389,6 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' - - operator_precedence_warning (boolean) - - operator_precedence_warning configuration parameter - - - - - When on, the parser will emit a warning for any construct that might - have changed meanings since PostgreSQL 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 off. - - - - See for more information. - - - - quote_all_identifiers (boolean) diff --git a/doc/src/sgml/syntax.sgml b/doc/src/sgml/syntax.sgml index 3fdd87823e..d66560b587 100644 --- a/doc/src/sgml/syntax.sgml +++ b/doc/src/sgml/syntax.sgml @@ -1121,11 +1121,7 @@ SELECT 3 OPERATOR(pg_catalog.+) 4; cases, these changes will result in no behavioral change, or perhaps in no such operator 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 turned on - to see if any warnings are logged. + change behavior without any parsing error being reported. diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 9c73c605a4..8f5e4e71b2 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -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; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index ecff4cd2ac..8f341ac006 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -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) { diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 36002f059d..1e62d31aca 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -39,53 +39,8 @@ #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. * diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 9de0cff833..ce68663cc2 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -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, diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 635d91d50a..dabcbb0736 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -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."), diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 9c9091e601..b7fb2ec1fe 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -740,7 +740,6 @@ #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 diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index ec14fc2036..48a79a7657 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -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 diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h index b01d3b7dec..5668f88302 100644 --- a/src/include/parser/parse_expr.h +++ b/src/include/parser/parse_expr.h @@ -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);