]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
O.K. -
authorBruce Momjian <bruce@momjian.us>
Tue, 12 Sep 2000 04:15:58 +0000 (04:15 +0000)
committerBruce Momjian <bruce@momjian.us>
Tue, 12 Sep 2000 04:15:58 +0000 (04:15 +0000)
Here's the multibyte aware version of my patch to fix the truncation
of the rulename autogenerated during a CREATE VIEW. I've modified all
the places in the backend that want to construct the rulename to use
the MakeRetrieveViewRuleName(), where I put the #ifdef MULTIBYTE, so
that's the only place that knows how to construct a view rulename. Except
pg_dump, where I replicated the code, since it's a standalone binary.

The only effect the enduser will see is that views with names len(name)
> NAMEDATALEN-4 will fail to be created, if the derived rulename clases
with an existing rule: i.e. the user is trying to create two views with
long names whose first difference is past NAMEDATALEN-4 (but before
NAMEDATALEN: that'll error out after the viewname truncation.) In no
case will the user get left with a table without a view rule, as the
current code does.

Ross Reedstrom

src/backend/commands/view.c
src/backend/rewrite/rewriteDefine.c
src/backend/utils/adt/ruleutils.c
src/bin/pg_dump/pg_dump.c

index 8503eb3a7eb5ec4402f7a31d01816af2173cda94..01e23d13150268d811efd2a2d0396a1ac59a45da 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *     $Id: view.c,v 1.45 2000/07/04 06:11:30 tgl Exp $
+ *     $Id: view.c,v 1.46 2000/09/12 04:15:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -120,6 +120,14 @@ MakeRetrieveViewRuleName(char *viewName)
        buf = palloc(strlen(viewName) + 5);
        snprintf(buf, strlen(viewName) + 5, "_RET%s", viewName);
 
+#ifdef MULTIBYTE
+       int len;
+       len = pg_mbcliplen(buf,strlen(buf),NAMEDATALEN-1);
+       buf[len] = '\0';
+#else
+       buf[NAMEDATALEN-1] = '\0';
+#endif
+
        return buf;
 }
 
index 5f9907080b374c941b1a324b6efbbce212087002..c9315f6d338fc79d2cca32da0509c6901a47077e 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.49 2000/07/30 22:13:51 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.50 2000/09/12 04:15:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -23,6 +23,7 @@
 #include "parser/parse_relation.h"
 #include "rewrite/rewriteDefine.h"
 #include "rewrite/rewriteSupport.h"
+#include "commands/view.h"
 
 
 /*
@@ -218,7 +219,7 @@ DefineQueryRewrite(RuleStmt *stmt)
                Form_pg_attribute attr;
                char       *attname;
                int                     i;
-               char            expected_name[NAMEDATALEN + 5];
+               char            *expected_name;
 
                /*
                 * So there cannot be INSTEAD NOTHING, ...
@@ -305,12 +306,14 @@ DefineQueryRewrite(RuleStmt *stmt)
                /*
                 * ... and finally the rule must be named _RETviewname.
                 */
-               sprintf(expected_name, "_RET%s", event_obj->relname);
+
+               expected_name = MakeRetrieveViewRuleName(event_obj->relname);
                if (strcmp(expected_name, stmt->rulename) != 0)
                {
                        elog(ERROR, "view rule for %s must be named %s",
                                 event_obj->relname, expected_name);
                }
+               pfree(expected_name);
        }
 
        /*
index 7d44657429d6910085f94866056b4c16f6e840c5..571854d446c7bfd45c31961d0c057d9c7af05ed2 100644 (file)
@@ -3,7 +3,7 @@
  *                       out of its tuple
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.59 2000/08/12 04:04:53 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.60 2000/09/12 04:15:58 momjian Exp $
  *
  *       This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -51,6 +51,7 @@
 #include "parser/parse_expr.h"
 #include "parser/parsetree.h"
 #include "utils/lsyscache.h"
+#include "commands/view.h"
 
 
 /* ----------
@@ -79,7 +80,7 @@ static char *rulename = NULL;
 static void *plan_getrule = NULL;
 static char *query_getrule = "SELECT * FROM pg_rewrite WHERE rulename = $1";
 static void *plan_getview = NULL;
-static char *query_getview = "SELECT * FROM pg_rewrite WHERE rulename = $1 or rulename = $2";
+static char *query_getview = "SELECT * FROM pg_rewrite WHERE rulename = $1";
 static void *plan_getam = NULL;
 static char *query_getam = "SELECT * FROM pg_am WHERE oid = $1";
 static void *plan_getopclass = NULL;
@@ -138,7 +139,7 @@ pg_get_ruledef(PG_FUNCTION_ARGS)
        int                     len;
 
        /* ----------
-        * We need the rules name somewhere deep down
+        * We need the rules name somewhere deep down: rulename is global
         * ----------
         */
        rulename = pstrdup(NameStr(*rname));
@@ -226,23 +227,22 @@ pg_get_ruledef(PG_FUNCTION_ARGS)
 Datum
 pg_get_viewdef(PG_FUNCTION_ARGS)
 {
-       Name            rname = PG_GETARG_NAME(0);
+       Name            vname = PG_GETARG_NAME(0);
        text       *ruledef;
-       Datum           args[2];
-       char            nulls[3];
+       Datum           args[1];
+       char            nulls[2];
        int                     spirc;
        HeapTuple       ruletup;
        TupleDesc       rulettc;
        StringInfoData buf;
        int                     len;
-       char            name1[NAMEDATALEN + 5];
-       char            name2[NAMEDATALEN + 5];
+       char            *name;
 
        /* ----------
-        * We need the rules name somewhere deep down
+        * We need the view name somewhere deep down
         * ----------
         */
-       rulename = pstrdup(NameStr(*rname));
+       rulename = pstrdup(NameStr(*vname));
 
        /* ----------
         * Connect to SPI manager
@@ -259,28 +259,24 @@ pg_get_viewdef(PG_FUNCTION_ARGS)
         */
        if (plan_getview == NULL)
        {
-               Oid                     argtypes[2];
+               Oid                     argtypes[1];
                void       *plan;
 
                argtypes[0] = NAMEOID;
-               argtypes[1] = NAMEOID;
-               plan = SPI_prepare(query_getview, 2, argtypes);
+               plan = SPI_prepare(query_getview, 1, 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
+        * Get the pg_rewrite tuple for this rule: rulename is actually viewname here
         * ----------
         */
-       sprintf(name1, "_RET%s", rulename);
-       sprintf(name2, "_ret%s", rulename);
-       args[0] = PointerGetDatum(name1);
-       args[1] = PointerGetDatum(name2);
+       name = MakeRetrieveViewRuleName(rulename);
+       args[0] = PointerGetDatum(name);
        nulls[0] = ' ';
-       nulls[1] = ' ';
-       nulls[2] = '\0';
+       nulls[1] = '\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);
@@ -302,6 +298,7 @@ pg_get_viewdef(PG_FUNCTION_ARGS)
        VARATT_SIZEP(ruledef) = len;
        memcpy(VARDATA(ruledef), buf.data, buf.len);
        pfree(buf.data);
+       pfree(name);
 
        /* ----------
         * Disconnect from SPI manager
index d581f13a4afdcace83a258d2ca6d26d30332bb1d..372ff9be4c87c958d74fa44988049bb389447207 100644 (file)
@@ -22,7 +22,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.163 2000/08/07 12:32:54 pjw Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.164 2000/09/12 04:15:58 momjian Exp $
  *
  * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
  *
@@ -256,12 +256,22 @@ isViewRule(char *relname)
 {
        PGresult   *res;
        int                     ntups;
+       char       rulename[NAMEDATALEN + 5];
        PQExpBuffer query = createPQExpBuffer();
 
        appendPQExpBuffer(query, "select relname from pg_class, pg_rewrite ");
        appendPQExpBuffer(query, "where pg_class.oid = ev_class ");
        appendPQExpBuffer(query, "and pg_rewrite.ev_type = '1' ");
-       appendPQExpBuffer(query, "and rulename = '_RET%s'", relname);
+       snprintf(rulename,NAMEDATALEN + 5,"_RET%s",relname);
+#ifdef MULTIBYTE
+       int len;
+       len = pg_mbcliplen(rulename,strlen(rulename),NAMEDATALEN-1);
+       rulename[len] = '\0';
+#else
+       rulename[NAMEDATALEN-1] = '\0';
+#endif
+
+       appendPQExpBuffer(query, "and rulename = '%s'", rulename);
 
        res = PQexec(g_conn, query->data);
        if (!res ||