Commit 0ba0e321 authored by Bruce Momjian's avatar Bruce Momjian

O.K. -

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
parent b1777d5f
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * 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) ...@@ -120,6 +120,14 @@ MakeRetrieveViewRuleName(char *viewName)
buf = palloc(strlen(viewName) + 5); buf = palloc(strlen(viewName) + 5);
snprintf(buf, strlen(viewName) + 5, "_RET%s", viewName); 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; return buf;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -23,6 +23,7 @@
#include "parser/parse_relation.h" #include "parser/parse_relation.h"
#include "rewrite/rewriteDefine.h" #include "rewrite/rewriteDefine.h"
#include "rewrite/rewriteSupport.h" #include "rewrite/rewriteSupport.h"
#include "commands/view.h"
/* /*
...@@ -218,7 +219,7 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -218,7 +219,7 @@ DefineQueryRewrite(RuleStmt *stmt)
Form_pg_attribute attr; Form_pg_attribute attr;
char *attname; char *attname;
int i; int i;
char expected_name[NAMEDATALEN + 5]; char *expected_name;
/* /*
* So there cannot be INSTEAD NOTHING, ... * So there cannot be INSTEAD NOTHING, ...
...@@ -305,12 +306,14 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -305,12 +306,14 @@ DefineQueryRewrite(RuleStmt *stmt)
/* /*
* ... and finally the rule must be named _RETviewname. * ... 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) if (strcmp(expected_name, stmt->rulename) != 0)
{ {
elog(ERROR, "view rule for %s must be named %s", elog(ERROR, "view rule for %s must be named %s",
event_obj->relname, expected_name); event_obj->relname, expected_name);
} }
pfree(expected_name);
} }
/* /*
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* out of its tuple * out of its tuple
* *
* IDENTIFICATION * 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. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parsetree.h" #include "parser/parsetree.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "commands/view.h"
/* ---------- /* ----------
...@@ -79,7 +80,7 @@ static char *rulename = NULL; ...@@ -79,7 +80,7 @@ static char *rulename = NULL;
static void *plan_getrule = NULL; static void *plan_getrule = NULL;
static char *query_getrule = "SELECT * FROM pg_rewrite WHERE rulename = $1"; static char *query_getrule = "SELECT * FROM pg_rewrite WHERE rulename = $1";
static void *plan_getview = NULL; 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 void *plan_getam = NULL;
static char *query_getam = "SELECT * FROM pg_am WHERE oid = $1"; static char *query_getam = "SELECT * FROM pg_am WHERE oid = $1";
static void *plan_getopclass = NULL; static void *plan_getopclass = NULL;
...@@ -138,7 +139,7 @@ pg_get_ruledef(PG_FUNCTION_ARGS) ...@@ -138,7 +139,7 @@ pg_get_ruledef(PG_FUNCTION_ARGS)
int len; 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)); rulename = pstrdup(NameStr(*rname));
...@@ -226,23 +227,22 @@ pg_get_ruledef(PG_FUNCTION_ARGS) ...@@ -226,23 +227,22 @@ pg_get_ruledef(PG_FUNCTION_ARGS)
Datum Datum
pg_get_viewdef(PG_FUNCTION_ARGS) pg_get_viewdef(PG_FUNCTION_ARGS)
{ {
Name rname = PG_GETARG_NAME(0); Name vname = PG_GETARG_NAME(0);
text *ruledef; text *ruledef;
Datum args[2]; Datum args[1];
char nulls[3]; char nulls[2];
int spirc; int spirc;
HeapTuple ruletup; HeapTuple ruletup;
TupleDesc rulettc; TupleDesc rulettc;
StringInfoData buf; StringInfoData buf;
int len; int len;
char name1[NAMEDATALEN + 5]; char *name;
char name2[NAMEDATALEN + 5];
/* ---------- /* ----------
* 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 * Connect to SPI manager
...@@ -259,28 +259,24 @@ pg_get_viewdef(PG_FUNCTION_ARGS) ...@@ -259,28 +259,24 @@ pg_get_viewdef(PG_FUNCTION_ARGS)
*/ */
if (plan_getview == NULL) if (plan_getview == NULL)
{ {
Oid argtypes[2]; Oid argtypes[1];
void *plan; void *plan;
argtypes[0] = NAMEOID; argtypes[0] = NAMEOID;
argtypes[1] = NAMEOID; plan = SPI_prepare(query_getview, 1, argtypes);
plan = SPI_prepare(query_getview, 2, argtypes);
if (plan == NULL) if (plan == NULL)
elog(ERROR, "SPI_prepare() failed for \"%s\"", query_getview); elog(ERROR, "SPI_prepare() failed for \"%s\"", query_getview);
plan_getview = SPI_saveplan(plan); 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); name = MakeRetrieveViewRuleName(rulename);
sprintf(name2, "_ret%s", rulename); args[0] = PointerGetDatum(name);
args[0] = PointerGetDatum(name1);
args[1] = PointerGetDatum(name2);
nulls[0] = ' '; nulls[0] = ' ';
nulls[1] = ' '; nulls[1] = '\0';
nulls[2] = '\0';
spirc = SPI_execp(plan_getview, args, nulls, 1); spirc = SPI_execp(plan_getview, args, nulls, 1);
if (spirc != SPI_OK_SELECT) if (spirc != SPI_OK_SELECT)
elog(ERROR, "failed to get pg_rewrite tuple for view %s", rulename); elog(ERROR, "failed to get pg_rewrite tuple for view %s", rulename);
...@@ -302,6 +298,7 @@ pg_get_viewdef(PG_FUNCTION_ARGS) ...@@ -302,6 +298,7 @@ pg_get_viewdef(PG_FUNCTION_ARGS)
VARATT_SIZEP(ruledef) = len; VARATT_SIZEP(ruledef) = len;
memcpy(VARDATA(ruledef), buf.data, buf.len); memcpy(VARDATA(ruledef), buf.data, buf.len);
pfree(buf.data); pfree(buf.data);
pfree(name);
/* ---------- /* ----------
* Disconnect from SPI manager * Disconnect from SPI manager
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
* *
* *
* IDENTIFICATION * 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 * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
* *
...@@ -256,12 +256,22 @@ isViewRule(char *relname) ...@@ -256,12 +256,22 @@ isViewRule(char *relname)
{ {
PGresult *res; PGresult *res;
int ntups; int ntups;
char rulename[NAMEDATALEN + 5];
PQExpBuffer query = createPQExpBuffer(); PQExpBuffer query = createPQExpBuffer();
appendPQExpBuffer(query, "select relname from pg_class, pg_rewrite "); appendPQExpBuffer(query, "select relname from pg_class, pg_rewrite ");
appendPQExpBuffer(query, "where pg_class.oid = ev_class "); appendPQExpBuffer(query, "where pg_class.oid = ev_class ");
appendPQExpBuffer(query, "and pg_rewrite.ev_type = '1' "); 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); res = PQexec(g_conn, query->data);
if (!res || if (!res ||
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment