aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/ruleutils.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>1998-09-01 04:40:42 +0000
committerBruce Momjian <bruce@momjian.us>1998-09-01 04:40:42 +0000
commitfa1a8d6a97068295fe30ac646aec7493a6305bc2 (patch)
tree645f7cef3c78fbab4d6d7bbc7c9a61ad2893d273 /src/backend/utils/adt/ruleutils.c
parentaf74855a608da4cd7ef88ceb2241ec1c75537f39 (diff)
downloadpostgresql-fa1a8d6a97068295fe30ac646aec7493a6305bc2.tar.gz
postgresql-fa1a8d6a97068295fe30ac646aec7493a6305bc2.zip
OK, folks, here is the pgindent output.
Diffstat (limited to 'src/backend/utils/adt/ruleutils.c')
-rw-r--r--src/backend/utils/adt/ruleutils.c2136
1 files changed, 1098 insertions, 1038 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 593d670d374..f9774bf62f5 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3,35 +3,35 @@
* out of it's tuple
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.2 1998/09/01 03:26:17 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.3 1998/09/01 04:32:49 momjian Exp $
*
- * This software is copyrighted by Jan Wieck - Hamburg.
+ * This software is copyrighted by Jan Wieck - Hamburg.
*
- * The author hereby grants permission to use, copy, modify,
- * distribute, and license this software and its documentation
- * for any purpose, provided that existing copyright notices are
- * retained in all copies and that this notice is included
- * verbatim in any distributions. No written agreement, license,
- * or royalty fee is required for any of the authorized uses.
- * Modifications to this software may be copyrighted by their
- * author and need not follow the licensing terms described
- * here, provided that the new terms are clearly indicated on
- * the first page of each file where they apply.
+ * The author hereby grants permission to use, copy, modify,
+ * distribute, and license this software and its documentation
+ * for any purpose, provided that existing copyright notices are
+ * retained in all copies and that this notice is included
+ * verbatim in any distributions. No written agreement, license,
+ * or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their
+ * author and need not follow the licensing terms described
+ * here, provided that the new terms are clearly indicated on
+ * the first page of each file where they apply.
*
- * IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY
- * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
- * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
- * SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
- * IF THE AUTHOR HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
+ * IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY
+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
+ * SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
+ * IF THE AUTHOR HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
*
- * THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON
- * AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAVE NO
- * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
- * ENHANCEMENTS, OR MODIFICATIONS.
+ * THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON
+ * AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAVE NO
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
*
**********************************************************************/
@@ -70,8 +70,8 @@ static char *query_getview = "SELECT * FROM pg_rewrite WHERE rulename = $1 or ru
* Global functions
* ----------
*/
-text *pg_get_ruledef(NameData *rname);
-text *pg_get_viewdef(NameData *rname);
+text *pg_get_ruledef(NameData *rname);
+text *pg_get_viewdef(NameData *rname);
/* ----------
@@ -103,90 +103,91 @@ static bool check_if_rte_used(int rt_index, Node *node, int sup);
text *
pg_get_ruledef(NameData *rname)
{
- text *ruledef;
- Datum args[1];
- char nulls[2];
- int spirc;
- HeapTuple ruletup;
- TupleDesc rulettc;
- char *tmp;
- int len;
-
- /* ----------
- * We need the rules name somewhere deep down
- * ----------
- */
- rulename = nameout(rname);
-
- /* ----------
- * Connect to SPI manager
- * ----------
- */
- if (SPI_connect() != SPI_OK_CONNECT)
- elog(ERROR, "get_ruledef: cannot connect to SPI manager");
-
- /* ----------
- * On the first call prepare the plan to lookup pg_proc.
- * We read pg_proc over the SPI manager instead of using
- * the syscache to be checked for read access on pg_proc.
- * ----------
- */
- if (plan_getrule == NULL) {
- Oid argtypes[1];
- void *plan;
-
- argtypes[0] = NAMEOID;
- plan = SPI_prepare(query_getrule, 1, argtypes);
- if (plan == NULL)
- elog(ERROR, "SPI_prepare() failed for \"%s\"", query_getrule);
- plan_getrule = SPI_saveplan(plan);
- }
-
- /* ----------
- * Get the pg_rewrite tuple for this rule
- * ----------
- */
- args[0] = PointerGetDatum(rulename);
- nulls[0] = (rulename == NULL) ? 'n' : ' ';
- nulls[1] = '\0';
- spirc = SPI_execp(plan_getrule, args, nulls, 1);
- if (spirc != SPI_OK_SELECT) {
- elog(ERROR, "failed to get pg_rewrite tuple for %s", rulename);
- }
- if (SPI_processed != 1) {
- if (SPI_finish() != SPI_OK_FINISH)
- elog(ERROR, "get_ruledef: SPI_finish() failed");
- ruledef = SPI_palloc(VARHDRSZ + 1);
- VARSIZE(ruledef) = VARHDRSZ + 1;
- VARDATA(ruledef)[0] = '-';
+ text *ruledef;
+ Datum args[1];
+ char nulls[2];
+ int spirc;
+ HeapTuple ruletup;
+ TupleDesc rulettc;
+ char *tmp;
+ int len;
+
+ /* ----------
+ * We need the rules name somewhere deep down
+ * ----------
+ */
+ rulename = nameout(rname);
+
+ /* ----------
+ * Connect to SPI manager
+ * ----------
+ */
+ if (SPI_connect() != SPI_OK_CONNECT)
+ elog(ERROR, "get_ruledef: cannot connect to SPI manager");
+
+ /* ----------
+ * On the first call prepare the plan to lookup pg_proc.
+ * We read pg_proc over the SPI manager instead of using
+ * the syscache to be checked for read access on pg_proc.
+ * ----------
+ */
+ if (plan_getrule == NULL)
+ {
+ Oid argtypes[1];
+ void *plan;
+
+ argtypes[0] = NAMEOID;
+ plan = SPI_prepare(query_getrule, 1, argtypes);
+ if (plan == NULL)
+ elog(ERROR, "SPI_prepare() failed for \"%s\"", query_getrule);
+ plan_getrule = SPI_saveplan(plan);
+ }
+
+ /* ----------
+ * Get the pg_rewrite tuple for this rule
+ * ----------
+ */
+ args[0] = PointerGetDatum(rulename);
+ nulls[0] = (rulename == NULL) ? 'n' : ' ';
+ nulls[1] = '\0';
+ spirc = SPI_execp(plan_getrule, args, nulls, 1);
+ if (spirc != SPI_OK_SELECT)
+ elog(ERROR, "failed to get pg_rewrite tuple for %s", rulename);
+ if (SPI_processed != 1)
+ {
+ if (SPI_finish() != SPI_OK_FINISH)
+ elog(ERROR, "get_ruledef: SPI_finish() failed");
+ ruledef = SPI_palloc(VARHDRSZ + 1);
+ VARSIZE(ruledef) = VARHDRSZ + 1;
+ VARDATA(ruledef)[0] = '-';
+ return ruledef;
+ }
+
+ ruletup = SPI_tuptable->vals[0];
+ rulettc = SPI_tuptable->tupdesc;
+
+ /* ----------
+ * Get the rules definition and put it into executors memory
+ * ----------
+ */
+ tmp = make_ruledef(ruletup, rulettc);
+ len = strlen(tmp) + VARHDRSZ;
+ ruledef = SPI_palloc(len);
+ VARSIZE(ruledef) = len;
+ memcpy(VARDATA(ruledef), tmp, len - VARHDRSZ);
+
+ /* ----------
+ * Disconnect from SPI manager
+ * ----------
+ */
+ if (SPI_finish() != SPI_OK_FINISH)
+ elog(ERROR, "get_ruledef: SPI_finish() failed");
+
+ /* ----------
+ * Easy - isn't it?
+ * ----------
+ */
return ruledef;
- }
-
- ruletup = SPI_tuptable->vals[0];
- rulettc = SPI_tuptable->tupdesc;
-
- /* ----------
- * Get the rules definition and put it into executors memory
- * ----------
- */
- tmp = make_ruledef(ruletup, rulettc);
- len = strlen(tmp) + VARHDRSZ;
- ruledef = SPI_palloc(len);
- VARSIZE(ruledef) = len;
- memcpy(VARDATA(ruledef), tmp, len - VARHDRSZ);
-
- /* ----------
- * Disconnect from SPI manager
- * ----------
- */
- if (SPI_finish() != SPI_OK_FINISH)
- elog(ERROR, "get_ruledef: SPI_finish() failed");
-
- /* ----------
- * Easy - isn't it?
- * ----------
- */
- return ruledef;
}
@@ -198,91 +199,92 @@ pg_get_ruledef(NameData *rname)
text *
pg_get_viewdef(NameData *rname)
{
- text *ruledef;
- Datum args[2];
- char nulls[3];
- int spirc;
- HeapTuple ruletup;
- TupleDesc rulettc;
- char *tmp;
- int len;
- char name1[NAMEDATALEN + 5];
- char name2[NAMEDATALEN + 5];
-
- /* ----------
- * We need the rules name somewhere deep down
- * ----------
- */
- rulename = nameout(rname);
-
- /* ----------
- * Connect to SPI manager
- * ----------
- */
- if (SPI_connect() != SPI_OK_CONNECT)
- elog(ERROR, "get_viewdef: cannot connect to SPI manager");
-
- /* ----------
- * On the first call prepare the plan to lookup pg_proc.
- * We read pg_proc over the SPI manager instead of using
- * the syscache to be checked for read access on pg_proc.
- * ----------
- */
- if (plan_getview == NULL) {
- Oid argtypes[2];
- void *plan;
-
- argtypes[0] = NAMEOID;
- argtypes[1] = NAMEOID;
- plan = SPI_prepare(query_getview, 2, argtypes);
- if (plan == NULL)
- elog(ERROR, "SPI_prepare() failed for \"%s\"", query_getview);
- plan_getview = SPI_saveplan(plan);
- }
-
- /* ----------
- * Get the pg_rewrite tuple for this rule
- * ----------
- */
- sprintf(name1, "_RET%s", rulename);
- sprintf(name2, "_ret%s", rulename);
- args[0] = PointerGetDatum(name1);
- args[1] = PointerGetDatum(name2);
- nulls[0] = ' ';
- nulls[1] = ' ';
- nulls[2] = '\0';
- spirc = SPI_execp(plan_getview, args, nulls, 1);
- if (spirc != SPI_OK_SELECT) {
- elog(ERROR, "failed to get pg_rewrite tuple for view %s", rulename);
- }
- if (SPI_processed != 1) {
- tmp = "Not a view";
- } else {
+ text *ruledef;
+ Datum args[2];
+ char nulls[3];
+ int spirc;
+ HeapTuple ruletup;
+ TupleDesc rulettc;
+ char *tmp;
+ int len;
+ char name1[NAMEDATALEN + 5];
+ char name2[NAMEDATALEN + 5];
+
/* ----------
- * Get the rules definition and put it into executors memory
+ * We need the rules name somewhere deep down
* ----------
*/
- ruletup = SPI_tuptable->vals[0];
- rulettc = SPI_tuptable->tupdesc;
- tmp = make_viewdef(ruletup, rulettc);
- }
- len = strlen(tmp) + VARHDRSZ;
- ruledef = SPI_palloc(len);
- VARSIZE(ruledef) = len;
- memcpy(VARDATA(ruledef), tmp, len - VARHDRSZ);
-
- /* ----------
- * Disconnect from SPI manager
- * ----------
- */
- if (SPI_finish() != SPI_OK_FINISH)
- elog(ERROR, "get_viewdef: SPI_finish() failed");
-
- /* ----------
- * Easy - isn't it?
- * ----------
- */
- return ruledef;
+ rulename = nameout(rname);
+
+ /* ----------
+ * Connect to SPI manager
+ * ----------
+ */
+ if (SPI_connect() != SPI_OK_CONNECT)
+ elog(ERROR, "get_viewdef: cannot connect to SPI manager");
+
+ /* ----------
+ * On the first call prepare the plan to lookup pg_proc.
+ * We read pg_proc over the SPI manager instead of using
+ * the syscache to be checked for read access on pg_proc.
+ * ----------
+ */
+ if (plan_getview == NULL)
+ {
+ Oid argtypes[2];
+ void *plan;
+
+ argtypes[0] = NAMEOID;
+ argtypes[1] = NAMEOID;
+ plan = SPI_prepare(query_getview, 2, argtypes);
+ if (plan == NULL)
+ elog(ERROR, "SPI_prepare() failed for \"%s\"", query_getview);
+ plan_getview = SPI_saveplan(plan);
+ }
+
+ /* ----------
+ * Get the pg_rewrite tuple for this rule
+ * ----------
+ */
+ sprintf(name1, "_RET%s", rulename);
+ sprintf(name2, "_ret%s", rulename);
+ args[0] = PointerGetDatum(name1);
+ args[1] = PointerGetDatum(name2);
+ nulls[0] = ' ';
+ nulls[1] = ' ';
+ nulls[2] = '\0';
+ spirc = SPI_execp(plan_getview, args, nulls, 1);
+ if (spirc != SPI_OK_SELECT)
+ elog(ERROR, "failed to get pg_rewrite tuple for view %s", rulename);
+ if (SPI_processed != 1)
+ tmp = "Not a view";
+ else
+ {
+ /* ----------
+ * Get the rules definition and put it into executors memory
+ * ----------
+ */
+ ruletup = SPI_tuptable->vals[0];
+ rulettc = SPI_tuptable->tupdesc;
+ tmp = make_viewdef(ruletup, rulettc);
+ }
+ len = strlen(tmp) + VARHDRSZ;
+ ruledef = SPI_palloc(len);
+ VARSIZE(ruledef) = len;
+ memcpy(VARDATA(ruledef), tmp, len - VARHDRSZ);
+
+ /* ----------
+ * Disconnect from SPI manager
+ * ----------
+ */
+ if (SPI_finish() != SPI_OK_FINISH)
+ elog(ERROR, "get_viewdef: SPI_finish() failed");
+
+ /* ----------
+ * Easy - isn't it?
+ * ----------
+ */
+ return ruledef;
}
@@ -294,135 +296,151 @@ pg_get_viewdef(NameData *rname)
static char *
make_ruledef(HeapTuple ruletup, TupleDesc rulettc)
{
- char *buf;
- char ev_type;
- Oid ev_class;
- int2 ev_attr;
- bool is_instead;
- char *ev_qual;
- char *ev_action;
- List *actions = NIL;
- int fno;
- bool isnull;
-
- /* ----------
- * Allocate space for the returned rule definition text
- * ----------
- */
- buf = palloc(8192);
-
- /* ----------
- * Get the attribute values from the rules tuple
- * ----------
- */
- fno = SPI_fnumber(rulettc, "ev_type");
- ev_type = (char)SPI_getbinval(ruletup, rulettc, fno, &isnull);
-
- fno = SPI_fnumber(rulettc, "ev_class");
- ev_class = (Oid)SPI_getbinval(ruletup, rulettc, fno, &isnull);
-
- fno = SPI_fnumber(rulettc, "ev_attr");
- ev_attr = (int2)SPI_getbinval(ruletup, rulettc, fno, &isnull);
-
- fno = SPI_fnumber(rulettc, "is_instead");
- is_instead = (bool)SPI_getbinval(ruletup, rulettc, fno, &isnull);
-
- fno = SPI_fnumber(rulettc, "ev_qual");
- ev_qual = SPI_getvalue(ruletup, rulettc, fno);
- if (isnull) ev_qual = NULL;
-
- fno = SPI_fnumber(rulettc, "ev_action");
- ev_action = SPI_getvalue(ruletup, rulettc, fno);
- if (isnull) ev_action = NULL;
- if (ev_action != NULL) {
- actions = (List *)stringToNode(ev_action);
- }
-
- /* ----------
- * Build the rules definition text
- * ----------
- */
- strcpy(buf, "CREATE RULE ");
-
- /* The rule name */
- strcat(buf, rulename);
- strcat(buf, " AS ON ");
-
- /* The event the rule is fired for */
- switch (ev_type) {
- case '1': strcat(buf, "SELECT TO ");
+ char *buf;
+ char ev_type;
+ Oid ev_class;
+ int2 ev_attr;
+ bool is_instead;
+ char *ev_qual;
+ char *ev_action;
+ List *actions = NIL;
+ int fno;
+ bool isnull;
+
+ /* ----------
+ * Allocate space for the returned rule definition text
+ * ----------
+ */
+ buf = palloc(8192);
+
+ /* ----------
+ * Get the attribute values from the rules tuple
+ * ----------
+ */
+ fno = SPI_fnumber(rulettc, "ev_type");
+ ev_type = (char) SPI_getbinval(ruletup, rulettc, fno, &isnull);
+
+ fno = SPI_fnumber(rulettc, "ev_class");
+ ev_class = (Oid) SPI_getbinval(ruletup, rulettc, fno, &isnull);
+
+ fno = SPI_fnumber(rulettc, "ev_attr");
+ ev_attr = (int2) SPI_getbinval(ruletup, rulettc, fno, &isnull);
+
+ fno = SPI_fnumber(rulettc, "is_instead");
+ is_instead = (bool) SPI_getbinval(ruletup, rulettc, fno, &isnull);
+
+ fno = SPI_fnumber(rulettc, "ev_qual");
+ ev_qual = SPI_getvalue(ruletup, rulettc, fno);
+ if (isnull)
+ ev_qual = NULL;
+
+ fno = SPI_fnumber(rulettc, "ev_action");
+ ev_action = SPI_getvalue(ruletup, rulettc, fno);
+ if (isnull)
+ ev_action = NULL;
+ if (ev_action != NULL)
+ actions = (List *) stringToNode(ev_action);
+
+ /* ----------
+ * Build the rules definition text
+ * ----------
+ */
+ strcpy(buf, "CREATE RULE ");
+
+ /* The rule name */
+ strcat(buf, rulename);
+ strcat(buf, " AS ON ");
+
+ /* The event the rule is fired for */
+ switch (ev_type)
+ {
+ case '1':
+ strcat(buf, "SELECT TO ");
break;
- case '2': strcat(buf, "UPDATE TO ");
+ case '2':
+ strcat(buf, "UPDATE TO ");
break;
- case '3': strcat(buf, "INSERT TO ");
+ case '3':
+ strcat(buf, "INSERT TO ");
break;
- case '4': strcat(buf, "DELETE TO ");
+ case '4':
+ strcat(buf, "DELETE TO ");
break;
- default:
- elog(ERROR, "get_ruledef: rule %s has unsupported event type %d",
- rulename, ev_type);
- break;
- }
+ default:
+ elog(ERROR, "get_ruledef: rule %s has unsupported event type %d",
+ rulename, ev_type);
+ break;
+ }
- /* The relation the rule is fired on */
- strcat(buf, get_relation_name(ev_class));
- if (ev_attr > 0) {
- strcat(buf, ".");
- strcat(buf, get_attribute_name(ev_class, ev_attr));
- }
+ /* The relation the rule is fired on */
+ strcat(buf, get_relation_name(ev_class));
+ if (ev_attr > 0)
+ {
+ strcat(buf, ".");
+ strcat(buf, get_attribute_name(ev_class, ev_attr));
+ }
- /* If the rule has an event qualification, add it */
- if (ev_qual == NULL) ev_qual = "";
- if (strlen(ev_qual) > 0) {
- Node *qual;
- Query *query;
+ /* If the rule has an event qualification, add it */
+ if (ev_qual == NULL)
+ ev_qual = "";
+ if (strlen(ev_qual) > 0)
+ {
+ Node *qual;
+ Query *query;
- qual = stringToNode(ev_qual);
- query = (Query *)lfirst(actions);
+ qual = stringToNode(ev_qual);
+ query = (Query *) lfirst(actions);
- strcat(buf, " WHERE ");
- strcat(buf, get_rule_expr(query->rtable, 0, qual, TRUE));
- }
+ strcat(buf, " WHERE ");
+ strcat(buf, get_rule_expr(query->rtable, 0, qual, TRUE));
+ }
- strcat(buf, " DO ");
+ strcat(buf, " DO ");
- /* The INSTEAD keyword (if so) */
- if (is_instead)
- strcat(buf, "INSTEAD ");
+ /* The INSTEAD keyword (if so) */
+ if (is_instead)
+ strcat(buf, "INSTEAD ");
- /* Finally the rules actions */
- if (length(actions) > 1) {
- List *action;
- Query *query;
+ /* Finally the rules actions */
+ if (length(actions) > 1)
+ {
+ List *action;
+ Query *query;
- strcat(buf, "(");
- foreach (action, actions) {
- query = (Query *)lfirst(action);
- strcat(buf, get_query_def(query));
- strcat(buf, "; ");
+ strcat(buf, "(");
+ foreach(action, actions)
+ {
+ query = (Query *) lfirst(action);
+ strcat(buf, get_query_def(query));
+ strcat(buf, "; ");
+ }
+ strcat(buf, ");");
}
- strcat(buf, ");");
- } else {
- if (length(actions) == 0) {
- strcat(buf, "NOTHING;");
- } else {
- Query *query;
-
- query = (Query *)lfirst(actions);
- strcat(buf, get_query_def(query));
- strcat(buf, ";");
+ else
+ {
+ if (length(actions) == 0)
+ {
+ strcat(buf, "NOTHING;");
+ }
+ else
+ {
+ Query *query;
+
+ query = (Query *) lfirst(actions);
+ strcat(buf, get_query_def(query));
+ strcat(buf, ";");
+ }
}
- }
- /* ----------
- * That's it
- * ----------
- */
- return buf;
+ /* ----------
+ * That's it
+ * ----------
+ */
+ return buf;
}
@@ -434,61 +452,62 @@ make_ruledef(HeapTuple ruletup, TupleDesc rulettc)
static char *
make_viewdef(HeapTuple ruletup, TupleDesc rulettc)
{
- char buf[8192];
- Query *query;
- char ev_type;
- Oid ev_class;
- int2 ev_attr;
- bool is_instead;
- char *ev_qual;
- char *ev_action;
- List *actions = NIL;
- int fno;
- bool isnull;
-
- /* ----------
- * Get the attribute values from the rules tuple
- * ----------
- */
- fno = SPI_fnumber(rulettc, "ev_type");
- ev_type = (char)SPI_getbinval(ruletup, rulettc, fno, &isnull);
-
- fno = SPI_fnumber(rulettc, "ev_class");
- ev_class = (Oid)SPI_getbinval(ruletup, rulettc, fno, &isnull);
-
- fno = SPI_fnumber(rulettc, "ev_attr");
- ev_attr = (int2)SPI_getbinval(ruletup, rulettc, fno, &isnull);
-
- fno = SPI_fnumber(rulettc, "is_instead");
- is_instead = (bool)SPI_getbinval(ruletup, rulettc, fno, &isnull);
-
- fno = SPI_fnumber(rulettc, "ev_qual");
- ev_qual = SPI_getvalue(ruletup, rulettc, fno);
- if (isnull) ev_qual = "";
-
- fno = SPI_fnumber(rulettc, "ev_action");
- ev_action = SPI_getvalue(ruletup, rulettc, fno);
- if (isnull) ev_action = NULL;
- if (ev_action != NULL) {
- actions = (List *)stringToNode(ev_action);
- }
-
- if (length(actions) != 1)
- return "Not a view";
-
- query = (Query *)lfirst(actions);
-
- if (ev_type != '1' || ev_attr >= 0 || !is_instead || strcmp(ev_qual, ""))
- return "Not a view";
-
- strcpy(buf, get_select_query_def(query));
- strcat(buf, ";");
-
- /* ----------
- * That's it
- * ----------
- */
- return pstrdup(buf);
+ char buf[8192];
+ Query *query;
+ char ev_type;
+ Oid ev_class;
+ int2 ev_attr;
+ bool is_instead;
+ char *ev_qual;
+ char *ev_action;
+ List *actions = NIL;
+ int fno;
+ bool isnull;
+
+ /* ----------
+ * Get the attribute values from the rules tuple
+ * ----------
+ */
+ fno = SPI_fnumber(rulettc, "ev_type");
+ ev_type = (char) SPI_getbinval(ruletup, rulettc, fno, &isnull);
+
+ fno = SPI_fnumber(rulettc, "ev_class");
+ ev_class = (Oid) SPI_getbinval(ruletup, rulettc, fno, &isnull);
+
+ fno = SPI_fnumber(rulettc, "ev_attr");
+ ev_attr = (int2) SPI_getbinval(ruletup, rulettc, fno, &isnull);
+
+ fno = SPI_fnumber(rulettc, "is_instead");
+ is_instead = (bool) SPI_getbinval(ruletup, rulettc, fno, &isnull);
+
+ fno = SPI_fnumber(rulettc, "ev_qual");
+ ev_qual = SPI_getvalue(ruletup, rulettc, fno);
+ if (isnull)
+ ev_qual = "";
+
+ fno = SPI_fnumber(rulettc, "ev_action");
+ ev_action = SPI_getvalue(ruletup, rulettc, fno);
+ if (isnull)
+ ev_action = NULL;
+ if (ev_action != NULL)
+ actions = (List *) stringToNode(ev_action);
+
+ if (length(actions) != 1)
+ return "Not a view";
+
+ query = (Query *) lfirst(actions);
+
+ if (ev_type != '1' || ev_attr >= 0 || !is_instead || strcmp(ev_qual, ""))
+ return "Not a view";
+
+ strcpy(buf, get_select_query_def(query));
+ strcat(buf, ";");
+
+ /* ----------
+ * That's it
+ * ----------
+ */
+ return pstrdup(buf);
}
@@ -501,34 +520,35 @@ make_viewdef(HeapTuple ruletup, TupleDesc rulettc)
static char *
get_query_def(Query *query)
{
- switch (query->commandType) {
- case CMD_SELECT:
- return get_select_query_def(query);
- break;
-
- case CMD_UPDATE:
- return get_update_query_def(query);
- break;
-
- case CMD_INSERT:
- return get_insert_query_def(query);
- break;
-
- case CMD_DELETE:
- return get_delete_query_def(query);
- break;
-
- case CMD_NOTHING:
- return "NOTHING";
- break;
-
- default:
- elog(ERROR, "get_ruledef of %s: query command type %d not implemented yet",
- rulename, query->commandType);
- break;
- }
-
- return NULL;
+ switch (query->commandType)
+ {
+ case CMD_SELECT:
+ return get_select_query_def(query);
+ break;
+
+ case CMD_UPDATE:
+ return get_update_query_def(query);
+ break;
+
+ case CMD_INSERT:
+ return get_insert_query_def(query);
+ break;
+
+ case CMD_DELETE:
+ return get_delete_query_def(query);
+ break;
+
+ case CMD_NOTHING:
+ return "NOTHING";
+ break;
+
+ default:
+ elog(ERROR, "get_ruledef of %s: query command type %d not implemented yet",
+ rulename, query->commandType);
+ break;
+ }
+
+ return NULL;
}
@@ -539,144 +559,162 @@ get_query_def(Query *query)
static char *
get_select_query_def(Query *query)
{
- char buf[8192];
- char *sep;
- TargetEntry *tle;
- RangeTblEntry *rte;
- bool *rt_used;
- int rt_length;
- int rt_numused = 0;
- bool rt_constonly = TRUE;
- int i;
- List *l;
-
- /* ----------
- * First we need need to know which and how many of the
- * range table entries in the query are used in the target list
- * or queries qualification
- * ----------
- */
- rt_length = length(query->rtable);
- rt_used = palloc(sizeof(bool) * rt_length);
- for (i = 0; i < rt_length; i++) {
- if (check_if_rte_used(i + 1, (Node *)(query->targetList), 0)) {
- rt_used[i] = TRUE;
- rt_numused++;
- } else {
- if (check_if_rte_used(i + 1, (Node *)(query->qual), 0)) {
- rt_used[i] = TRUE;
- rt_numused++;
- } else {
- rt_used[i] = FALSE;
- }
- }
- }
-
- /* ----------
- * Now check if any of the used rangetable entries is different
- * from *NEW* and *CURRENT*. If so we must omit the FROM clause
- * later.
- * ----------
- */
- i = 0;
- foreach (l, query->rtable) {
- if (!rt_used[i++])
- continue;
-
- rte = (RangeTblEntry *)lfirst(l);
- if (!strcmp(rte->refname, "*NEW*"))
- continue;
- if (!strcmp(rte->refname, "*CURRENT*"))
- continue;
-
- rt_constonly = FALSE;
- break;
- }
-
- /* ----------
- * Build up the query string - first we say SELECT
- * ----------
- */
- strcpy(buf, "SELECT");
-
- /* Then we tell what to select (the targetlist) */
- sep = " ";
- foreach (l, query->targetList) {
- bool tell_as = FALSE;
-
- tle = (TargetEntry *)lfirst(l);
- strcat(buf, sep);
- sep = ", ";
-
- strcat(buf, get_tle_expr(query->rtable, 0, tle, (rt_numused > 1)));
-
- /* Check if we must say AS ... */
- if (nodeTag(tle->expr) != T_Var) {
- tell_as = strcmp(tle->resdom->resname, "?column?");
- } else {
- Var *var = (Var *)(tle->expr);
- char *attname;
-
- rte = (RangeTblEntry *)nth(var->varno - 1, query->rtable);
- attname = get_attribute_name(rte->relid, var->varattno);
- if (strcmp(attname, tle->resdom->resname))
- tell_as = TRUE;
+ char buf[8192];
+ char *sep;
+ TargetEntry *tle;
+ RangeTblEntry *rte;
+ bool *rt_used;
+ int rt_length;
+ int rt_numused = 0;
+ bool rt_constonly = TRUE;
+ int i;
+ List *l;
+
+ /* ----------
+ * First we need need to know which and how many of the
+ * range table entries in the query are used in the target list
+ * or queries qualification
+ * ----------
+ */
+ rt_length = length(query->rtable);
+ rt_used = palloc(sizeof(bool) * rt_length);
+ for (i = 0; i < rt_length; i++)
+ {
+ if (check_if_rte_used(i + 1, (Node *) (query->targetList), 0))
+ {
+ rt_used[i] = TRUE;
+ rt_numused++;
+ }
+ else
+ {
+ if (check_if_rte_used(i + 1, (Node *) (query->qual), 0))
+ {
+ rt_used[i] = TRUE;
+ rt_numused++;
+ }
+ else
+ rt_used[i] = FALSE;
+ }
}
- /* and do if so */
- if (tell_as) {
- strcat(buf, " AS ");
- strcat(buf, tle->resdom->resname);
+ /* ----------
+ * Now check if any of the used rangetable entries is different
+ * from *NEW* and *CURRENT*. If so we must omit the FROM clause
+ * later.
+ * ----------
+ */
+ i = 0;
+ foreach(l, query->rtable)
+ {
+ if (!rt_used[i++])
+ continue;
+
+ rte = (RangeTblEntry *) lfirst(l);
+ if (!strcmp(rte->refname, "*NEW*"))
+ continue;
+ if (!strcmp(rte->refname, "*CURRENT*"))
+ continue;
+
+ rt_constonly = FALSE;
+ break;
}
- }
- /* If we need other tables that *NEW* or *CURRENT* add the FROM clause */
- if (!rt_constonly && rt_numused > 0) {
- strcat(buf, " FROM");
+ /* ----------
+ * Build up the query string - first we say SELECT
+ * ----------
+ */
+ strcpy(buf, "SELECT");
- i = 0;
+ /* Then we tell what to select (the targetlist) */
sep = " ";
- foreach (l, query->rtable) {
- if (rt_used[i++]) {
- rte = (RangeTblEntry *)lfirst(l);
+ foreach(l, query->targetList)
+ {
+ bool tell_as = FALSE;
- if (!strcmp(rte->refname, "*NEW*"))
- continue;
+ tle = (TargetEntry *) lfirst(l);
+ strcat(buf, sep);
+ sep = ", ";
- if (!strcmp(rte->refname, "*CURRENT*"))
- continue;
+ strcat(buf, get_tle_expr(query->rtable, 0, tle, (rt_numused > 1)));
- strcat(buf, sep); sep = ", ";
- strcat(buf, rte->relname);
- if (rt_numused > 1) {
- strcat(buf, " ");
- strcat(buf, rte->refname);
+ /* Check if we must say AS ... */
+ if (nodeTag(tle->expr) != T_Var)
+ tell_as = strcmp(tle->resdom->resname, "?column?");
+ else
+ {
+ Var *var = (Var *) (tle->expr);
+ char *attname;
+
+ rte = (RangeTblEntry *) nth(var->varno - 1, query->rtable);
+ attname = get_attribute_name(rte->relid, var->varattno);
+ if (strcmp(attname, tle->resdom->resname))
+ tell_as = TRUE;
+ }
+
+ /* and do if so */
+ if (tell_as)
+ {
+ strcat(buf, " AS ");
+ strcat(buf, tle->resdom->resname);
}
- }
}
- }
- /* Add the WHERE clause if given */
- if (query->qual != NULL) {
- strcat(buf, " WHERE ");
- strcat(buf, get_rule_expr(query->rtable, 0, query->qual, (rt_numused > 1)));
- }
+ /* If we need other tables that *NEW* or *CURRENT* add the FROM clause */
+ if (!rt_constonly && rt_numused > 0)
+ {
+ strcat(buf, " FROM");
- /* Add the GROUP BY CLAUSE */
- if (query->groupClause != NULL) {
- strcat(buf, " GROUP BY ");
- sep = "";
- foreach (l, query->groupClause) {
- strcat(buf, sep); sep = ", ";
- strcat(buf, get_rule_expr(query->rtable, 0, lfirst(l), (rt_numused > 1)));
+ i = 0;
+ sep = " ";
+ foreach(l, query->rtable)
+ {
+ if (rt_used[i++])
+ {
+ rte = (RangeTblEntry *) lfirst(l);
+
+ if (!strcmp(rte->refname, "*NEW*"))
+ continue;
+
+ if (!strcmp(rte->refname, "*CURRENT*"))
+ continue;
+
+ strcat(buf, sep);
+ sep = ", ";
+ strcat(buf, rte->relname);
+ if (rt_numused > 1)
+ {
+ strcat(buf, " ");
+ strcat(buf, rte->refname);
+ }
+ }
+ }
+ }
+
+ /* Add the WHERE clause if given */
+ if (query->qual != NULL)
+ {
+ strcat(buf, " WHERE ");
+ strcat(buf, get_rule_expr(query->rtable, 0, query->qual, (rt_numused > 1)));
+ }
+
+ /* Add the GROUP BY CLAUSE */
+ if (query->groupClause != NULL)
+ {
+ strcat(buf, " GROUP BY ");
+ sep = "";
+ foreach(l, query->groupClause)
+ {
+ strcat(buf, sep);
+ sep = ", ";
+ strcat(buf, get_rule_expr(query->rtable, 0, lfirst(l), (rt_numused > 1)));
+ }
}
- }
- /* ----------
- * Copy the query string into allocated space and return it
- * ----------
- */
- return pstrdup(buf);
+ /* ----------
+ * Copy the query string into allocated space and return it
+ * ----------
+ */
+ return pstrdup(buf);
}
@@ -687,92 +725,103 @@ get_select_query_def(Query *query)
static char *
get_insert_query_def(Query *query)
{
- char buf[8192];
- char *sep;
- TargetEntry *tle;
- RangeTblEntry *rte;
- bool *rt_used;
- int rt_length;
- int rt_numused = 0;
- bool rt_constonly = TRUE;
- int i;
- List *l;
-
- /* ----------
- * We need to know if other tables than *NEW* or *CURRENT*
- * are used in the query. If not, it's an INSERT ... VALUES,
- * otherwise an INSERT ... SELECT.
- * ----------
- */
- rt_length = length(query->rtable);
- rt_used = palloc(sizeof(bool) * rt_length);
- for (i = 0; i < rt_length; i++) {
- if (check_if_rte_used(i + 1, (Node *)(query->targetList), 0)) {
- rt_used[i] = TRUE;
- rt_numused++;
- } else {
- if (check_if_rte_used(i + 1, (Node *)(query->qual), 0)) {
- rt_used[i] = TRUE;
- rt_numused++;
- } else {
- rt_used[i] = FALSE;
- }
+ char buf[8192];
+ char *sep;
+ TargetEntry *tle;
+ RangeTblEntry *rte;
+ bool *rt_used;
+ int rt_length;
+ int rt_numused = 0;
+ bool rt_constonly = TRUE;
+ int i;
+ List *l;
+
+ /* ----------
+ * We need to know if other tables than *NEW* or *CURRENT*
+ * are used in the query. If not, it's an INSERT ... VALUES,
+ * otherwise an INSERT ... SELECT.
+ * ----------
+ */
+ rt_length = length(query->rtable);
+ rt_used = palloc(sizeof(bool) * rt_length);
+ for (i = 0; i < rt_length; i++)
+ {
+ if (check_if_rte_used(i + 1, (Node *) (query->targetList), 0))
+ {
+ rt_used[i] = TRUE;
+ rt_numused++;
+ }
+ else
+ {
+ if (check_if_rte_used(i + 1, (Node *) (query->qual), 0))
+ {
+ rt_used[i] = TRUE;
+ rt_numused++;
+ }
+ else
+ rt_used[i] = FALSE;
+ }
}
- }
-
- i = 0;
- foreach (l, query->rtable) {
- if (!rt_used[i++])
- continue;
-
- rte = (RangeTblEntry *)lfirst(l);
- if (!strcmp(rte->refname, "*NEW*"))
- continue;
- if (!strcmp(rte->refname, "*CURRENT*"))
- continue;
-
- rt_constonly = FALSE;
- break;
- }
-
- /* ----------
- * Start the query with INSERT INTO relname
- * ----------
- */
- rte = (RangeTblEntry *)nth(query->resultRelation - 1, query->rtable);
- strcpy(buf, "INSERT INTO ");
- strcat(buf, rte->relname);
-
- /* Add the target list */
- sep = " (";
- foreach (l, query->targetList) {
- tle = (TargetEntry *)lfirst(l);
-
- strcat(buf, sep); sep = ", ";
- strcat(buf, tle->resdom->resname);
- }
- strcat(buf, ") ");
-
- /* Add the VALUES or the SELECT */
- if (rt_constonly && query->qual == NULL) {
- strcat(buf, "VALUES (");
- sep = "";
- foreach (l, query->targetList) {
- tle = (TargetEntry *)lfirst(l);
- strcat(buf, sep); sep = ", ";
- strcat(buf, get_tle_expr(query->rtable, 0, tle, (rt_numused > 1)));
+ i = 0;
+ foreach(l, query->rtable)
+ {
+ if (!rt_used[i++])
+ continue;
+
+ rte = (RangeTblEntry *) lfirst(l);
+ if (!strcmp(rte->refname, "*NEW*"))
+ continue;
+ if (!strcmp(rte->refname, "*CURRENT*"))
+ continue;
+
+ rt_constonly = FALSE;
+ break;
}
- strcat(buf, ")");
- } else {
- strcat(buf, get_select_query_def(query));
- }
-
- /* ----------
- * Copy the query string into allocated space and return it
- * ----------
- */
- return pstrdup(buf);
+
+ /* ----------
+ * Start the query with INSERT INTO relname
+ * ----------
+ */
+ rte = (RangeTblEntry *) nth(query->resultRelation - 1, query->rtable);
+ strcpy(buf, "INSERT INTO ");
+ strcat(buf, rte->relname);
+
+ /* Add the target list */
+ sep = " (";
+ foreach(l, query->targetList)
+ {
+ tle = (TargetEntry *) lfirst(l);
+
+ strcat(buf, sep);
+ sep = ", ";
+ strcat(buf, tle->resdom->resname);
+ }
+ strcat(buf, ") ");
+
+ /* Add the VALUES or the SELECT */
+ if (rt_constonly && query->qual == NULL)
+ {
+ strcat(buf, "VALUES (");
+ sep = "";
+ foreach(l, query->targetList)
+ {
+ tle = (TargetEntry *) lfirst(l);
+
+ strcat(buf, sep);
+ sep = ", ";
+ strcat(buf, get_tle_expr(query->rtable, 0, tle, (rt_numused > 1)));
+ }
+ strcat(buf, ")");
+ }
+ else
+ strcat(buf, get_select_query_def(query));
+
+ /* ----------
+ * Copy the query string into allocated space and return it
+ * ----------
+ */
+ return pstrdup(buf);
}
@@ -783,45 +832,48 @@ get_insert_query_def(Query *query)
static char *
get_update_query_def(Query *query)
{
- char buf[8192];
- char *sep;
- TargetEntry *tle;
- RangeTblEntry *rte;
- List *l;
-
- /* ----------
- * Start the query with UPDATE relname SET
- * ----------
- */
- rte = (RangeTblEntry *)nth(query->resultRelation - 1, query->rtable);
- strcpy(buf, "UPDATE ");
- strcat(buf, rte->relname);
- strcat(buf, " SET ");
-
- /* Add the comma separated list of 'attname = value' */
- sep = "";
- foreach (l, query->targetList) {
- tle = (TargetEntry *)lfirst(l);
-
- strcat(buf, sep); sep = ", ";
- strcat(buf, tle->resdom->resname);
- strcat(buf, " = ");
- strcat(buf, get_tle_expr(query->rtable, query->resultRelation,
- tle, TRUE));
- }
-
- /* Finally add a WHERE clause if given */
- if (query->qual != NULL) {
- strcat(buf, " WHERE ");
- strcat(buf, get_rule_expr(query->rtable, query->resultRelation,
- query->qual, TRUE));
- }
-
- /* ----------
- * Copy the query string into allocated space and return it
- * ----------
- */
- return pstrdup(buf);
+ char buf[8192];
+ char *sep;
+ TargetEntry *tle;
+ RangeTblEntry *rte;
+ List *l;
+
+ /* ----------
+ * Start the query with UPDATE relname SET
+ * ----------
+ */
+ rte = (RangeTblEntry *) nth(query->resultRelation - 1, query->rtable);
+ strcpy(buf, "UPDATE ");
+ strcat(buf, rte->relname);
+ strcat(buf, " SET ");
+
+ /* Add the comma separated list of 'attname = value' */
+ sep = "";
+ foreach(l, query->targetList)
+ {
+ tle = (TargetEntry *) lfirst(l);
+
+ strcat(buf, sep);
+ sep = ", ";
+ strcat(buf, tle->resdom->resname);
+ strcat(buf, " = ");
+ strcat(buf, get_tle_expr(query->rtable, query->resultRelation,
+ tle, TRUE));
+ }
+
+ /* Finally add a WHERE clause if given */
+ if (query->qual != NULL)
+ {
+ strcat(buf, " WHERE ");
+ strcat(buf, get_rule_expr(query->rtable, query->resultRelation,
+ query->qual, TRUE));
+ }
+
+ /* ----------
+ * Copy the query string into allocated space and return it
+ * ----------
+ */
+ return pstrdup(buf);
}
@@ -832,28 +884,29 @@ get_update_query_def(Query *query)
static char *
get_delete_query_def(Query *query)
{
- char buf[8192];
- RangeTblEntry *rte;
-
- /* ----------
- * Start the query with DELETE FROM relname
- * ----------
- */
- rte = (RangeTblEntry *)nth(query->resultRelation - 1, query->rtable);
- strcpy(buf, "DELETE FROM ");
- strcat(buf, rte->relname);
-
- /* Add a WHERE clause if given */
- if (query->qual != NULL) {
- strcat(buf, " WHERE ");
- strcat(buf, get_rule_expr(query->rtable, 0, query->qual, FALSE));
- }
-
- /* ----------
- * Copy the query string into allocated space and return it
- * ----------
- */
- return pstrdup(buf);
+ char buf[8192];
+ RangeTblEntry *rte;
+
+ /* ----------
+ * Start the query with DELETE FROM relname
+ * ----------
+ */
+ rte = (RangeTblEntry *) nth(query->resultRelation - 1, query->rtable);
+ strcpy(buf, "DELETE FROM ");
+ strcat(buf, rte->relname);
+
+ /* Add a WHERE clause if given */
+ if (query->qual != NULL)
+ {
+ strcat(buf, " WHERE ");
+ strcat(buf, get_rule_expr(query->rtable, 0, query->qual, FALSE));
+ }
+
+ /* ----------
+ * Copy the query string into allocated space and return it
+ * ----------
+ */
+ return pstrdup(buf);
}
@@ -864,191 +917,197 @@ get_delete_query_def(Query *query)
static char *
get_rule_expr(List *rtable, int rt_index, Node *node, bool varprefix)
{
- char buf[8192];
+ char buf[8192];
- if (node == NULL)
- return pstrdup("");
+ if (node == NULL)
+ return pstrdup("");
- buf[0] = '\0';
+ buf[0] = '\0';
- /* ----------
- * Up to now I don't know if all the node types below
- * can really occur in rules actions and qualifications.
- * There might be some work left.
- * ----------
- */
- switch(nodeTag(node)) {
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *)node;
-
- return get_rule_expr(rtable, rt_index,
- (Node *)(tle->expr), varprefix);
- }
- break;
-
- case T_Aggreg:
- {
- Aggreg *agg = (Aggreg *)node;
-
- strcat(buf, agg->aggname);
- strcat(buf, "(");
- strcat(buf, get_rule_expr(rtable, rt_index,
- (Node *)(agg->target), varprefix));
- strcat(buf, ")");
- return pstrdup(buf);
- }
- break;
-
- case T_GroupClause:
- {
- GroupClause *grp = (GroupClause *)node;
+ /* ----------
+ * Up to now I don't know if all the node types below
+ * can really occur in rules actions and qualifications.
+ * There might be some work left.
+ * ----------
+ */
+ switch (nodeTag(node))
+ {
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ return get_rule_expr(rtable, rt_index,
+ (Node *) (tle->expr), varprefix);
+ }
+ break;
- return get_rule_expr(rtable, rt_index,
- (Node *)(grp->entry), varprefix);
- }
- break;
+ case T_Aggreg:
+ {
+ Aggreg *agg = (Aggreg *) node;
- case T_Expr:
- {
- Expr *expr = (Expr *)node;
-
- /* ----------
- * Expr nodes have to be handled a bit detailed
- * ----------
- */
- switch (expr->opType) {
- case OP_EXPR:
- strcat(buf, get_rule_expr(rtable, rt_index,
- (Node *)get_leftop(expr),
- varprefix));
- strcat(buf, " ");
- strcat(buf, get_opname(((Oper *)expr->oper)->opno));
- strcat(buf, " ");
- strcat(buf, get_rule_expr(rtable, rt_index,
- (Node *)get_rightop(expr),
- varprefix));
- return pstrdup(buf);
- break;
-
- case OR_EXPR:
+ strcat(buf, agg->aggname);
strcat(buf, "(");
strcat(buf, get_rule_expr(rtable, rt_index,
- (Node *)get_leftop(expr),
- varprefix));
- strcat(buf, ") OR (");
- strcat(buf, get_rule_expr(rtable, rt_index,
- (Node *)get_rightop(expr),
- varprefix));
+ (Node *) (agg->target), varprefix));
strcat(buf, ")");
return pstrdup(buf);
- break;
-
- case AND_EXPR:
- strcat(buf, "(");
- strcat(buf, get_rule_expr(rtable, rt_index,
- (Node *)get_leftop(expr),
- varprefix));
- strcat(buf, ") AND (");
- strcat(buf, get_rule_expr(rtable, rt_index,
- (Node *)get_rightop(expr),
- varprefix));
- strcat(buf, ")");
- return pstrdup(buf);
- break;
-
- case NOT_EXPR:
- strcat(buf, "NOT (");
- strcat(buf, get_rule_expr(rtable, rt_index,
- (Node *)get_leftop(expr),
- varprefix));
- strcat(buf, ")");
- return pstrdup(buf);
- break;
+ }
+ break;
- case FUNC_EXPR:
- return get_func_expr(rtable, rt_index,
- (Expr *)node,
- varprefix);
- break;
+ case T_GroupClause:
+ {
+ GroupClause *grp = (GroupClause *) node;
- default:
- printf("\n%s\n", nodeToString(node));
- elog(ERROR, "Expr not yet supported");
- }
- }
- break;
+ return get_rule_expr(rtable, rt_index,
+ (Node *) (grp->entry), varprefix);
+ }
+ break;
- case T_Var:
- {
- Var *var = (Var *)node;
- RangeTblEntry *rte = (RangeTblEntry *)nth(var->varno - 1, rtable);
-
- if (!strcmp(rte->refname, "*NEW*")) {
- strcat(buf, "new.");
- } else {
- if (!strcmp(rte->refname, "*CURRENT*")) {
- strcat(buf, "current.");
- } else {
- if (varprefix && var->varno != rt_index) {
- strcat(buf, rte->refname);
- strcat(buf, ".");
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
+
+ /* ----------
+ * Expr nodes have to be handled a bit detailed
+ * ----------
+ */
+ switch (expr->opType)
+ {
+ case OP_EXPR:
+ strcat(buf, get_rule_expr(rtable, rt_index,
+ (Node *) get_leftop(expr),
+ varprefix));
+ strcat(buf, " ");
+ strcat(buf, get_opname(((Oper *) expr->oper)->opno));
+ strcat(buf, " ");
+ strcat(buf, get_rule_expr(rtable, rt_index,
+ (Node *) get_rightop(expr),
+ varprefix));
+ return pstrdup(buf);
+ break;
+
+ case OR_EXPR:
+ strcat(buf, "(");
+ strcat(buf, get_rule_expr(rtable, rt_index,
+ (Node *) get_leftop(expr),
+ varprefix));
+ strcat(buf, ") OR (");
+ strcat(buf, get_rule_expr(rtable, rt_index,
+ (Node *) get_rightop(expr),
+ varprefix));
+ strcat(buf, ")");
+ return pstrdup(buf);
+ break;
+
+ case AND_EXPR:
+ strcat(buf, "(");
+ strcat(buf, get_rule_expr(rtable, rt_index,
+ (Node *) get_leftop(expr),
+ varprefix));
+ strcat(buf, ") AND (");
+ strcat(buf, get_rule_expr(rtable, rt_index,
+ (Node *) get_rightop(expr),
+ varprefix));
+ strcat(buf, ")");
+ return pstrdup(buf);
+ break;
+
+ case NOT_EXPR:
+ strcat(buf, "NOT (");
+ strcat(buf, get_rule_expr(rtable, rt_index,
+ (Node *) get_leftop(expr),
+ varprefix));
+ strcat(buf, ")");
+ return pstrdup(buf);
+ break;
+
+ case FUNC_EXPR:
+ return get_func_expr(rtable, rt_index,
+ (Expr *) node,
+ varprefix);
+ break;
+
+ default:
+ printf("\n%s\n", nodeToString(node));
+ elog(ERROR, "Expr not yet supported");
}
- }
}
- strcat(buf, get_attribute_name(rte->relid, var->varattno));
+ break;
- return pstrdup(buf);
- }
- break;
+ case T_Var:
+ {
+ Var *var = (Var *) node;
+ RangeTblEntry *rte = (RangeTblEntry *) nth(var->varno - 1, rtable);
+
+ if (!strcmp(rte->refname, "*NEW*"))
+ strcat(buf, "new.");
+ else
+ {
+ if (!strcmp(rte->refname, "*CURRENT*"))
+ strcat(buf, "current.");
+ else
+ {
+ if (varprefix && var->varno != rt_index)
+ {
+ strcat(buf, rte->refname);
+ strcat(buf, ".");
+ }
+ }
+ }
+ strcat(buf, get_attribute_name(rte->relid, var->varattno));
- case T_List:
- {
- printf("\n%s\n", nodeToString(node));
- elog(ERROR, "List not yet supported");
- }
- break;
+ return pstrdup(buf);
+ }
+ break;
- case T_SubLink:
- {
- SubLink *sublink = (SubLink *)node;
- Query *query = (Query *)(sublink->subselect);
- List *l;
- char *sep;
-
- if (sublink->lefthand != NULL) {
- strcat(buf, "(");
- sep = "";
- foreach (l, sublink->lefthand) {
- strcat(buf, sep); sep = ", ";
- strcat(buf, get_rule_expr(rtable, rt_index,
- lfirst(l), varprefix));
- }
- strcat(buf, ") IN ");
+ case T_List:
+ {
+ printf("\n%s\n", nodeToString(node));
+ elog(ERROR, "List not yet supported");
}
+ break;
- strcat(buf, "(");
- strcat(buf, get_query_def(query));
- strcat(buf, ")");
+ case T_SubLink:
+ {
+ SubLink *sublink = (SubLink *) node;
+ Query *query = (Query *) (sublink->subselect);
+ List *l;
+ char *sep;
+
+ if (sublink->lefthand != NULL)
+ {
+ strcat(buf, "(");
+ sep = "";
+ foreach(l, sublink->lefthand)
+ {
+ strcat(buf, sep);
+ sep = ", ";
+ strcat(buf, get_rule_expr(rtable, rt_index,
+ lfirst(l), varprefix));
+ }
+ strcat(buf, ") IN ");
+ }
- return pstrdup(buf);
- }
- break;
+ strcat(buf, "(");
+ strcat(buf, get_query_def(query));
+ strcat(buf, ")");
- case T_Const:
- {
- return get_const_expr((Const *)node);
- }
- break;
+ return pstrdup(buf);
+ }
+ break;
- default:
- printf("\n%s\n", nodeToString(node));
- elog(ERROR, "get_ruledef of %s: unknown node type %d get_rule_expr()",
- rulename, nodeTag(node));
- break;
- }
+ case T_Const:
+ return get_const_expr((Const *) node);
+ break;
- return FALSE;
+ default:
+ printf("\n%s\n", nodeToString(node));
+ elog(ERROR, "get_ruledef of %s: unknown node type %d get_rule_expr()",
+ rulename, nodeTag(node));
+ break;
+ }
+
+ return FALSE;
}
@@ -1059,61 +1118,66 @@ get_rule_expr(List *rtable, int rt_index, Node *node, bool varprefix)
static char *
get_func_expr(List *rtable, int rt_index, Expr *expr, bool varprefix)
{
- char buf[8192];
- HeapTuple proctup;
- Form_pg_proc procStruct;
- List *l;
- char *sep;
- Func *func = (Func *)(expr->oper);
- char *proname;
-
- /* ----------
- * Get the functions pg_proc tuple
- * ----------
- */
- proctup = SearchSysCacheTuple(PROOID,
- ObjectIdGetDatum(func->funcid), 0, 0, 0);
- if (!HeapTupleIsValid(proctup))
- elog(ERROR, "cache lookup for proc %d failed", func->funcid);
-
- procStruct = (Form_pg_proc) GETSTRUCT(proctup);
- proname = nameout(&(procStruct->proname));
-
- if (procStruct->pronargs == 1 && procStruct->proargtypes[0] == InvalidOid) {
- if (!strcmp(proname, "nullvalue")) {
- strcpy(buf, "(");
- strcat(buf, get_rule_expr(rtable, rt_index, lfirst(expr->args),
- varprefix));
- strcat(buf, ") ISNULL");
- return pstrdup(buf);
+ char buf[8192];
+ HeapTuple proctup;
+ Form_pg_proc procStruct;
+ List *l;
+ char *sep;
+ Func *func = (Func *) (expr->oper);
+ char *proname;
+
+ /* ----------
+ * Get the functions pg_proc tuple
+ * ----------
+ */
+ proctup = SearchSysCacheTuple(PROOID,
+ ObjectIdGetDatum(func->funcid), 0, 0, 0);
+ if (!HeapTupleIsValid(proctup))
+ elog(ERROR, "cache lookup for proc %d failed", func->funcid);
+
+ procStruct = (Form_pg_proc) GETSTRUCT(proctup);
+ proname = nameout(&(procStruct->proname));
+
+ if (procStruct->pronargs == 1 && procStruct->proargtypes[0] == InvalidOid)
+ {
+ if (!strcmp(proname, "nullvalue"))
+ {
+ strcpy(buf, "(");
+ strcat(buf, get_rule_expr(rtable, rt_index, lfirst(expr->args),
+ varprefix));
+ strcat(buf, ") ISNULL");
+ return pstrdup(buf);
+ }
+ if (!strcmp(proname, "nonnullvalue"))
+ {
+ strcpy(buf, "(");
+ strcat(buf, get_rule_expr(rtable, rt_index, lfirst(expr->args),
+ varprefix));
+ strcat(buf, ") NOTNULL");
+ return pstrdup(buf);
+ }
}
- if (!strcmp(proname, "nonnullvalue")) {
- strcpy(buf, "(");
- strcat(buf, get_rule_expr(rtable, rt_index, lfirst(expr->args),
- varprefix));
- strcat(buf, ") NOTNULL");
- return pstrdup(buf);
+
+ /* ----------
+ * Build a string of proname(args)
+ * ----------
+ */
+ strcpy(buf, proname);
+ strcat(buf, "(");
+ sep = "";
+ foreach(l, expr->args)
+ {
+ strcat(buf, sep);
+ sep = ", ";
+ strcat(buf, get_rule_expr(rtable, rt_index, lfirst(l), varprefix));
}
- }
-
- /* ----------
- * Build a string of proname(args)
- * ----------
- */
- strcpy(buf, proname);
- strcat(buf, "(");
- sep = "";
- foreach (l, expr->args) {
- strcat(buf, sep); sep = ", ";
- strcat(buf, get_rule_expr(rtable, rt_index, lfirst(l), varprefix));
- }
- strcat(buf, ")");
-
- /* ----------
- * Copy the function call string into allocated space and return it
- * ----------
- */
- return pstrdup(buf);
+ strcat(buf, ")");
+
+ /* ----------
+ * Copy the function call string into allocated space and return it
+ * ----------
+ */
+ return pstrdup(buf);
}
@@ -1132,75 +1196,67 @@ get_func_expr(List *rtable, int rt_index, Expr *expr, bool varprefix)
static char *
get_tle_expr(List *rtable, int rt_index, TargetEntry *tle, bool varprefix)
{
- HeapTuple proctup;
- Form_pg_proc procStruct;
- Expr *expr;
- Func *func;
- Const *second_arg;
-
- /* ----------
- * Check if the result has an atttypmod and if the
- * expression in the targetlist entry is a function call
- * ----------
- */
- if (tle->resdom->restypmod < 0) {
- return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
- }
- if (nodeTag(tle->expr) != T_Expr) {
- return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
- }
- expr = (Expr *)(tle->expr);
- if (expr->opType != FUNC_EXPR) {
- return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
- }
-
- func = (Func *)(expr->oper);
-
- /* ----------
- * Get the functions pg_proc tuple
- * ----------
- */
- proctup = SearchSysCacheTuple(PROOID,
- ObjectIdGetDatum(func->funcid), 0, 0, 0);
- if (!HeapTupleIsValid(proctup))
- elog(ERROR, "cache lookup for proc %d failed", func->funcid);
-
- procStruct = (Form_pg_proc) GETSTRUCT(proctup);
-
- /* ----------
- * It must be a function with two arguments where the first
- * is of the same type as the return value and the second is
- * an int4.
- * ----------
- */
- if (procStruct->pronargs != 2) {
- return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
- }
- if (procStruct->prorettype != procStruct->proargtypes[0]) {
- return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
- }
- if (procStruct->proargtypes[1] != INT4OID) {
- return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
- }
-
- /* ----------
- * Finally (to be totally safe) the second argument must be a
- * const and match the value in the results atttypmod.
- * ----------
- */
- second_arg = (Const *)nth(1, expr->args);
- if (nodeTag((Node *)second_arg) != T_Const) {
- return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
- }
- if ((int4)(second_arg->constvalue) != tle->resdom->restypmod) {
- return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
- }
-
- /* ----------
- * Whow - got it. Now get rid of the padding function
- * ----------
- */
- return get_rule_expr(rtable, rt_index, lfirst(expr->args), varprefix);
+ HeapTuple proctup;
+ Form_pg_proc procStruct;
+ Expr *expr;
+ Func *func;
+ Const *second_arg;
+
+ /* ----------
+ * Check if the result has an atttypmod and if the
+ * expression in the targetlist entry is a function call
+ * ----------
+ */
+ if (tle->resdom->restypmod < 0)
+ return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
+ if (nodeTag(tle->expr) != T_Expr)
+ return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
+ expr = (Expr *) (tle->expr);
+ if (expr->opType != FUNC_EXPR)
+ return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
+
+ func = (Func *) (expr->oper);
+
+ /* ----------
+ * Get the functions pg_proc tuple
+ * ----------
+ */
+ proctup = SearchSysCacheTuple(PROOID,
+ ObjectIdGetDatum(func->funcid), 0, 0, 0);
+ if (!HeapTupleIsValid(proctup))
+ elog(ERROR, "cache lookup for proc %d failed", func->funcid);
+
+ procStruct = (Form_pg_proc) GETSTRUCT(proctup);
+
+ /* ----------
+ * It must be a function with two arguments where the first
+ * is of the same type as the return value and the second is
+ * an int4.
+ * ----------
+ */
+ if (procStruct->pronargs != 2)
+ return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
+ if (procStruct->prorettype != procStruct->proargtypes[0])
+ return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
+ if (procStruct->proargtypes[1] != INT4OID)
+ return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
+
+ /* ----------
+ * Finally (to be totally safe) the second argument must be a
+ * const and match the value in the results atttypmod.
+ * ----------
+ */
+ second_arg = (Const *) nth(1, expr->args);
+ if (nodeTag((Node *) second_arg) != T_Const)
+ return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
+ if ((int4) (second_arg->constvalue) != tle->resdom->restypmod)
+ return get_rule_expr(rtable, rt_index, tle->expr, varprefix);
+
+ /* ----------
+ * Whow - got it. Now get rid of the padding function
+ * ----------
+ */
+ return get_rule_expr(rtable, rt_index, lfirst(expr->args), varprefix);
}
@@ -1212,29 +1268,29 @@ get_tle_expr(List *rtable, int rt_index, TargetEntry *tle, bool varprefix)
char *
get_const_expr(Const *constval)
{
- HeapTuple typetup;
- Form_pg_type typeStruct;
- FmgrInfo finfo_output;
- char *extval;
- bool isnull = FALSE;
- char buf[8192];
+ HeapTuple typetup;
+ Form_pg_type typeStruct;
+ FmgrInfo finfo_output;
+ char *extval;
+ bool isnull = FALSE;
+ char buf[8192];
- if (constval->constisnull)
- return "NULL";
+ if (constval->constisnull)
+ return "NULL";
- typetup = SearchSysCacheTuple(TYPOID,
- ObjectIdGetDatum(constval->consttype), 0, 0, 0);
- if (!HeapTupleIsValid(typetup))
- elog(ERROR, "cache lookup of type %d failed", constval->consttype);
+ typetup = SearchSysCacheTuple(TYPOID,
+ ObjectIdGetDatum(constval->consttype), 0, 0, 0);
+ if (!HeapTupleIsValid(typetup))
+ elog(ERROR, "cache lookup of type %d failed", constval->consttype);
- typeStruct = (Form_pg_type) GETSTRUCT(typetup);
+ typeStruct = (Form_pg_type) GETSTRUCT(typetup);
- fmgr_info(typeStruct->typoutput, &finfo_output);
- extval = (char *)(*fmgr_faddr(&finfo_output))(constval->constvalue,
- &isnull, -1);
+ fmgr_info(typeStruct->typoutput, &finfo_output);
+ extval = (char *) (*fmgr_faddr(&finfo_output)) (constval->constvalue,
+ &isnull, -1);
- sprintf(buf, "'%s'::%s", extval, nameout(&(typeStruct->typname)));
- return pstrdup(buf);
+ sprintf(buf, "'%s'::%s", extval, nameout(&(typeStruct->typname)));
+ return pstrdup(buf);
}
@@ -1245,16 +1301,16 @@ get_const_expr(Const *constval)
static char *
get_relation_name(Oid relid)
{
- HeapTuple classtup;
- Form_pg_class classStruct;
+ HeapTuple classtup;
+ Form_pg_class classStruct;
- classtup = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(relid), 0, 0, 0);
- if (!HeapTupleIsValid(classtup))
- elog(ERROR, "cache lookup of relation %d failed", relid);
+ classtup = SearchSysCacheTuple(RELOID,
+ ObjectIdGetDatum(relid), 0, 0, 0);
+ if (!HeapTupleIsValid(classtup))
+ elog(ERROR, "cache lookup of relation %d failed", relid);
- classStruct = (Form_pg_class) GETSTRUCT(classtup);
- return nameout(&(classStruct->relname));
+ classStruct = (Form_pg_class) GETSTRUCT(classtup);
+ return nameout(&(classStruct->relname));
}
@@ -1266,17 +1322,17 @@ get_relation_name(Oid relid)
static char *
get_attribute_name(Oid relid, int2 attnum)
{
- HeapTuple atttup;
- Form_pg_attribute attStruct;
+ HeapTuple atttup;
+ Form_pg_attribute attStruct;
- atttup = SearchSysCacheTuple(ATTNUM,
- ObjectIdGetDatum(relid), (Datum)attnum, 0, 0);
- if (!HeapTupleIsValid(atttup))
- elog(ERROR, "cache lookup of attribute %d in relation %d failed",
- attnum, relid);
+ atttup = SearchSysCacheTuple(ATTNUM,
+ ObjectIdGetDatum(relid), (Datum) attnum, 0, 0);
+ if (!HeapTupleIsValid(atttup))
+ elog(ERROR, "cache lookup of attribute %d in relation %d failed",
+ attnum, relid);
- attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
- return nameout(&(attStruct->attname));
+ attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
+ return nameout(&(attStruct->attname));
}
@@ -1289,88 +1345,92 @@ get_attribute_name(Oid relid, int2 attnum)
static bool
check_if_rte_used(int rt_index, Node *node, int sup)
{
- if (node == NULL)
- return FALSE;
+ if (node == NULL)
+ return FALSE;
- switch(nodeTag(node)) {
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *)node;
+ switch (nodeTag(node))
+ {
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
- return check_if_rte_used(rt_index,
- (Node *)(tle->expr), sup);
- }
- break;
+ return check_if_rte_used(rt_index,
+ (Node *) (tle->expr), sup);
+ }
+ break;
- case T_Aggreg:
- {
- Aggreg *agg = (Aggreg *)node;
- return check_if_rte_used(rt_index,
- (Node *)(agg->target), sup);
- }
- break;
+ case T_Aggreg:
+ {
+ Aggreg *agg = (Aggreg *) node;
- case T_GroupClause:
- {
- GroupClause *grp = (GroupClause *)node;
- return check_if_rte_used(rt_index,
- (Node *)(grp->entry), sup);
- }
- break;
+ return check_if_rte_used(rt_index,
+ (Node *) (agg->target), sup);
+ }
+ break;
- case T_Expr:
- {
- Expr *expr = (Expr *)node;
- return check_if_rte_used(rt_index,
- (Node *)(expr->args), sup);
- }
- break;
+ case T_GroupClause:
+ {
+ GroupClause *grp = (GroupClause *) node;
- case T_Var:
- {
- Var *var = (Var *)node;
- return var->varno == rt_index && var->varlevelsup == sup;
- }
- break;
+ return check_if_rte_used(rt_index,
+ (Node *) (grp->entry), sup);
+ }
+ break;
- case T_List:
- {
- List *l;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
- foreach (l, (List *)node) {
- if (check_if_rte_used(rt_index, lfirst(l), sup))
- return TRUE;
+ return check_if_rte_used(rt_index,
+ (Node *) (expr->args), sup);
}
- return FALSE;
- }
- break;
+ break;
- case T_SubLink:
- {
- SubLink *sublink = (SubLink *)node;
- Query *query = (Query *)sublink->subselect;
+ case T_Var:
+ {
+ Var *var = (Var *) node;
- if (check_if_rte_used(rt_index, (Node *)(query->qual), sup + 1))
- return TRUE;
+ return var->varno == rt_index && var->varlevelsup == sup;
+ }
+ break;
- if (check_if_rte_used(rt_index, (Node *)(sublink->lefthand), sup))
- return TRUE;
+ case T_List:
+ {
+ List *l;
- return FALSE;
- }
- break;
+ foreach(l, (List *) node)
+ {
+ if (check_if_rte_used(rt_index, lfirst(l), sup))
+ return TRUE;
+ }
+ return FALSE;
+ }
+ break;
- case T_Const:
- return FALSE;
- break;
+ case T_SubLink:
+ {
+ SubLink *sublink = (SubLink *) node;
+ Query *query = (Query *) sublink->subselect;
- default:
- elog(ERROR, "get_ruledef of %s: unknown node type %d in check_if_rte_used()",
- rulename, nodeTag(node));
- break;
- }
+ if (check_if_rte_used(rt_index, (Node *) (query->qual), sup + 1))
+ return TRUE;
- return FALSE;
-}
+ if (check_if_rte_used(rt_index, (Node *) (sublink->lefthand), sup))
+ return TRUE;
+
+ return FALSE;
+ }
+ break;
+ case T_Const:
+ return FALSE;
+ break;
+
+ default:
+ elog(ERROR, "get_ruledef of %s: unknown node type %d in check_if_rte_used()",
+ rulename, nodeTag(node));
+ break;
+ }
+ return FALSE;
+}