Skip to content

Commit 0ba0e32

Browse files
committed
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
1 parent b1777d5 commit 0ba0e32

File tree

4 files changed

+44
-26
lines changed

4 files changed

+44
-26
lines changed

src/backend/commands/view.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: view.c,v 1.45 2000/07/04 06:11:30 tgl Exp $
9+
* $Id: view.c,v 1.46 2000/09/12 04:15:56 momjian Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -120,6 +120,14 @@ MakeRetrieveViewRuleName(char *viewName)
120120
buf = palloc(strlen(viewName) + 5);
121121
snprintf(buf, strlen(viewName) + 5, "_RET%s", viewName);
122122

123+
#ifdef MULTIBYTE
124+
int len;
125+
len = pg_mbcliplen(buf,strlen(buf),NAMEDATALEN-1);
126+
buf[len] = '\0';
127+
#else
128+
buf[NAMEDATALEN-1] = '\0';
129+
#endif
130+
123131
return buf;
124132
}
125133

src/backend/rewrite/rewriteDefine.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.49 2000/07/30 22:13:51 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.50 2000/09/12 04:15:57 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -23,6 +23,7 @@
2323
#include "parser/parse_relation.h"
2424
#include "rewrite/rewriteDefine.h"
2525
#include "rewrite/rewriteSupport.h"
26+
#include "commands/view.h"
2627

2728

2829
/*
@@ -218,7 +219,7 @@ DefineQueryRewrite(RuleStmt *stmt)
218219
Form_pg_attribute attr;
219220
char *attname;
220221
int i;
221-
char expected_name[NAMEDATALEN + 5];
222+
char *expected_name;
222223

223224
/*
224225
* So there cannot be INSTEAD NOTHING, ...
@@ -305,12 +306,14 @@ DefineQueryRewrite(RuleStmt *stmt)
305306
/*
306307
* ... and finally the rule must be named _RETviewname.
307308
*/
308-
sprintf(expected_name, "_RET%s", event_obj->relname);
309+
310+
expected_name = MakeRetrieveViewRuleName(event_obj->relname);
309311
if (strcmp(expected_name, stmt->rulename) != 0)
310312
{
311313
elog(ERROR, "view rule for %s must be named %s",
312314
event_obj->relname, expected_name);
313315
}
316+
pfree(expected_name);
314317
}
315318

316319
/*

src/backend/utils/adt/ruleutils.c

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* out of its tuple
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.59 2000/08/12 04:04:53 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.60 2000/09/12 04:15:58 momjian Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -51,6 +51,7 @@
5151
#include "parser/parse_expr.h"
5252
#include "parser/parsetree.h"
5353
#include "utils/lsyscache.h"
54+
#include "commands/view.h"
5455

5556

5657
/* ----------
@@ -79,7 +80,7 @@ static char *rulename = NULL;
7980
static void *plan_getrule = NULL;
8081
static char *query_getrule = "SELECT * FROM pg_rewrite WHERE rulename = $1";
8182
static void *plan_getview = NULL;
82-
static char *query_getview = "SELECT * FROM pg_rewrite WHERE rulename = $1 or rulename = $2";
83+
static char *query_getview = "SELECT * FROM pg_rewrite WHERE rulename = $1";
8384
static void *plan_getam = NULL;
8485
static char *query_getam = "SELECT * FROM pg_am WHERE oid = $1";
8586
static void *plan_getopclass = NULL;
@@ -138,7 +139,7 @@ pg_get_ruledef(PG_FUNCTION_ARGS)
138139
int len;
139140

140141
/* ----------
141-
* We need the rules name somewhere deep down
142+
* We need the rules name somewhere deep down: rulename is global
142143
* ----------
143144
*/
144145
rulename = pstrdup(NameStr(*rname));
@@ -226,23 +227,22 @@ pg_get_ruledef(PG_FUNCTION_ARGS)
226227
Datum
227228
pg_get_viewdef(PG_FUNCTION_ARGS)
228229
{
229-
Name rname = PG_GETARG_NAME(0);
230+
Name vname = PG_GETARG_NAME(0);
230231
text *ruledef;
231-
Datum args[2];
232-
char nulls[3];
232+
Datum args[1];
233+
char nulls[2];
233234
int spirc;
234235
HeapTuple ruletup;
235236
TupleDesc rulettc;
236237
StringInfoData buf;
237238
int len;
238-
char name1[NAMEDATALEN + 5];
239-
char name2[NAMEDATALEN + 5];
239+
char *name;
240240

241241
/* ----------
242-
* We need the rules name somewhere deep down
242+
* We need the view name somewhere deep down
243243
* ----------
244244
*/
245-
rulename = pstrdup(NameStr(*rname));
245+
rulename = pstrdup(NameStr(*vname));
246246

247247
/* ----------
248248
* Connect to SPI manager
@@ -259,28 +259,24 @@ pg_get_viewdef(PG_FUNCTION_ARGS)
259259
*/
260260
if (plan_getview == NULL)
261261
{
262-
Oid argtypes[2];
262+
Oid argtypes[1];
263263
void *plan;
264264

265265
argtypes[0] = NAMEOID;
266-
argtypes[1] = NAMEOID;
267-
plan = SPI_prepare(query_getview, 2, argtypes);
266+
plan = SPI_prepare(query_getview, 1, argtypes);
268267
if (plan == NULL)
269268
elog(ERROR, "SPI_prepare() failed for \"%s\"", query_getview);
270269
plan_getview = SPI_saveplan(plan);
271270
}
272271

273272
/* ----------
274-
* Get the pg_rewrite tuple for this rule
273+
* Get the pg_rewrite tuple for this rule: rulename is actually viewname here
275274
* ----------
276275
*/
277-
sprintf(name1, "_RET%s", rulename);
278-
sprintf(name2, "_ret%s", rulename);
279-
args[0] = PointerGetDatum(name1);
280-
args[1] = PointerGetDatum(name2);
276+
name = MakeRetrieveViewRuleName(rulename);
277+
args[0] = PointerGetDatum(name);
281278
nulls[0] = ' ';
282-
nulls[1] = ' ';
283-
nulls[2] = '\0';
279+
nulls[1] = '\0';
284280
spirc = SPI_execp(plan_getview, args, nulls, 1);
285281
if (spirc != SPI_OK_SELECT)
286282
elog(ERROR, "failed to get pg_rewrite tuple for view %s", rulename);
@@ -302,6 +298,7 @@ pg_get_viewdef(PG_FUNCTION_ARGS)
302298
VARATT_SIZEP(ruledef) = len;
303299
memcpy(VARDATA(ruledef), buf.data, buf.len);
304300
pfree(buf.data);
301+
pfree(name);
305302

306303
/* ----------
307304
* Disconnect from SPI manager

src/bin/pg_dump/pg_dump.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
*
2323
*
2424
* IDENTIFICATION
25-
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.163 2000/08/07 12:32:54 pjw Exp $
25+
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.164 2000/09/12 04:15:58 momjian Exp $
2626
*
2727
* Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
2828
*
@@ -256,12 +256,22 @@ isViewRule(char *relname)
256256
{
257257
PGresult *res;
258258
int ntups;
259+
char rulename[NAMEDATALEN + 5];
259260
PQExpBuffer query = createPQExpBuffer();
260261

261262
appendPQExpBuffer(query, "select relname from pg_class, pg_rewrite ");
262263
appendPQExpBuffer(query, "where pg_class.oid = ev_class ");
263264
appendPQExpBuffer(query, "and pg_rewrite.ev_type = '1' ");
264-
appendPQExpBuffer(query, "and rulename = '_RET%s'", relname);
265+
snprintf(rulename,NAMEDATALEN + 5,"_RET%s",relname);
266+
#ifdef MULTIBYTE
267+
int len;
268+
len = pg_mbcliplen(rulename,strlen(rulename),NAMEDATALEN-1);
269+
rulename[len] = '\0';
270+
#else
271+
rulename[NAMEDATALEN-1] = '\0';
272+
#endif
273+
274+
appendPQExpBuffer(query, "and rulename = '%s'", rulename);
265275

266276
res = PQexec(g_conn, query->data);
267277
if (!res ||

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy