Backpatch fix for unary operators in rule deparser.
authorTom Lane <[email protected]>
Sun, 5 Sep 1999 22:55:28 +0000 (22:55 +0000)
committerTom Lane <[email protected]>
Sun, 5 Sep 1999 22:55:28 +0000 (22:55 +0000)
src/backend/utils/adt/ruleutils.c

index ee15bdd9f08a75a93100954bc602d88f60ffd749..e6afcfad78e31c5a1df3de4f5f7319b5d000bd23 100644 (file)
@@ -3,7 +3,7 @@
  *           out of it's tuple
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.18.2.2 1999/08/29 19:22:24 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.18.2.3 1999/09/05 22:55:28 tgl Exp $
  *
  *   This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -42,8 +42,9 @@
 #include "executor/spi.h"
 #include "optimizer/clauses.h"
 #include "utils/lsyscache.h"
-#include "catalog/pg_shadow.h"
 #include "catalog/pg_index.h"
+#include "catalog/pg_operator.h"
+#include "catalog/pg_shadow.h"
 
 #define BUFSIZE 8192
 
@@ -1269,6 +1270,7 @@ get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix)
        case T_Expr:
            {
                Expr       *expr = (Expr *) node;
+               List       *args = expr->args;
 
                /* ----------
                 * Expr nodes have to be handled a bit detailed
@@ -1278,15 +1280,56 @@ get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix)
                {
                    case OP_EXPR:
                        strcat(buf, "(");
-                       strcat(buf, get_rule_expr(qh, rt_index,
-                                              (Node *) get_leftop(expr),
-                                                 varprefix));
-                       strcat(buf, " ");
-                       strcat(buf, get_opname(((Oper *) expr->oper)->opno));
-                       strcat(buf, " ");
-                       strcat(buf, get_rule_expr(qh, rt_index,
-                                             (Node *) get_rightop(expr),
-                                                 varprefix));
+                       if (length(args) == 2)
+                       {
+                           /* binary operator */
+                           strcat(buf,
+                                  get_rule_expr(qh, rt_index,
+                                                (Node *) lfirst(args),
+                                                varprefix));
+                           strcat(buf, " ");
+                           strcat(buf,
+                                  get_opname(((Oper *) expr->oper)->opno));
+                           strcat(buf, " ");
+                           strcat(buf,
+                                  get_rule_expr(qh, rt_index,
+                                                (Node *) lsecond(args),
+                                                varprefix));
+                       }
+                       else
+                       {
+                           /* unary operator --- but which side? */
+                           Oid         opno = ((Oper *) expr->oper)->opno;
+                           HeapTuple   tp;
+                           Form_pg_operator optup;
+
+                           tp = SearchSysCacheTuple(OPROID,
+                                                    ObjectIdGetDatum(opno),
+                                                    0, 0, 0);
+                           Assert(HeapTupleIsValid(tp));
+                           optup = (Form_pg_operator) GETSTRUCT(tp);
+                           switch (optup->oprkind)
+                           {
+                               case 'l':
+                                   strcat(buf, get_opname(opno));
+                                   strcat(buf, " ");
+                                   strcat(buf,
+                                          get_rule_expr(qh, rt_index,
+                                                        (Node *) lfirst(args),
+                                                        varprefix));
+                                   break;
+                               case 'r':
+                                   strcat(buf,
+                                          get_rule_expr(qh, rt_index,
+                                                        (Node *) lfirst(args),
+                                                        varprefix));
+                                   strcat(buf, " ");
+                                   strcat(buf, get_opname(opno));
+                                   break;
+                               default:
+                                   elog(ERROR, "get_rule_expr: bogus oprkind");
+                           }
+                       }
                        strcat(buf, ")");
                        return pstrdup(buf);
                        break;
@@ -1294,12 +1337,18 @@ get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix)
                    case OR_EXPR:
                        strcat(buf, "(");
                        strcat(buf, get_rule_expr(qh, rt_index,
-                                              (Node *) get_leftop(expr),
-                                                 varprefix));
-                       strcat(buf, " OR ");
-                       strcat(buf, get_rule_expr(qh, rt_index,
-                                             (Node *) get_rightop(expr),
+                                                 (Node *) lfirst(args),
                                                  varprefix));
+                       /* It's not clear that we can ever see N-argument
+                        * OR/AND clauses here, but might as well cope...
+                        */
+                       while ((args = lnext(args)) != NIL)
+                       {
+                           strcat(buf, " OR ");
+                           strcat(buf, get_rule_expr(qh, rt_index,
+                                                     (Node *) lfirst(args),
+                                                     varprefix));
+                       }
                        strcat(buf, ")");
                        return pstrdup(buf);
                        break;
@@ -1307,12 +1356,15 @@ get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix)
                    case AND_EXPR:
                        strcat(buf, "(");
                        strcat(buf, get_rule_expr(qh, rt_index,
-                                              (Node *) get_leftop(expr),
-                                                 varprefix));
-                       strcat(buf, " AND ");
-                       strcat(buf, get_rule_expr(qh, rt_index,
-                                             (Node *) get_rightop(expr),
+                                                 (Node *) lfirst(args),
                                                  varprefix));
+                       while ((args = lnext(args)) != NIL)
+                       {
+                           strcat(buf, " AND ");
+                           strcat(buf, get_rule_expr(qh, rt_index,
+                                                     (Node *) lfirst(args),
+                                                     varprefix));
+                       }
                        strcat(buf, ")");
                        return pstrdup(buf);
                        break;
@@ -1334,7 +1386,7 @@ get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix)
 
                    default:
                        printf("\n%s\n", nodeToString(node));
-                       elog(ERROR, "Expr type not supported");
+                       elog(ERROR, "get_rule_expr: expr type not supported");
                }
            }
            break;