Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9b43c24

Browse files
committed
Avoid misbehavior in foreign key checks when casting to a datatype for which
the parser supplies a default typmod that can result in data loss (ie,truncation). Currently that appears to be only CHARACTER and BIT.We can avoid the problem by specifying the type's internal name insteadof using SQL-spec syntax. Since the queries generated here are only usedinternally, there's no need to worry about portability. This problem isnew in 8.3; before we just let the parser do whatever it wanted to resolvethe operator, but 8.3 is trying to be sure that the semantics of FK checksare consistent. Per report from Harald Fuchs.
1 parentd9c7f63 commit9b43c24

File tree

1 file changed

+40
-5
lines changed

1 file changed

+40
-5
lines changed

‎src/backend/utils/adt/ri_triggers.c

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
1717
*
18-
* $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.102 2008/01/25 04:46:07 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.103 2008/02/07 22:58:35 tgl Exp $
1919
*
2020
* ----------
2121
*/
@@ -185,6 +185,7 @@ static void ri_GenerateQual(StringInfo buf,
185185
constchar*leftop,Oidleftoptype,
186186
Oidopoid,
187187
constchar*rightop,Oidrightoptype);
188+
staticvoidri_add_cast_to(StringInfobuf,Oidtypid);
188189
staticintri_NullCheck(Relationrel,HeapTupletup,
189190
RI_QueryKey*key,intpairidx);
190191
staticvoidri_BuildQueryKeyFull(RI_QueryKey*key,
@@ -2893,8 +2894,10 @@ quoteRelationName(char *buffer, Relation rel)
28932894
* The idea is to append " sep leftop op rightop" to buf. The complexity
28942895
* comes from needing to be sure that the parser will select the desired
28952896
* operator. We always name the operator using OPERATOR(schema.op) syntax
2896-
* (readability isn't a big priority here). We have to emit casts too,
2897-
* if either input isn't already the input type of the operator.
2897+
* (readability isn't a big priority here), so as to avoid search-path
2898+
* uncertainties. We have to emit casts too, if either input isn't already
2899+
* the input type of the operator; else we are at the mercy of the parser's
2900+
* heuristics for ambiguous-operator resolution.
28982901
*/
28992902
staticvoid
29002903
ri_GenerateQual(StringInfobuf,
@@ -2921,16 +2924,48 @@ ri_GenerateQual(StringInfo buf,
29212924

29222925
appendStringInfo(buf," %s %s",sep,leftop);
29232926
if (leftoptype!=operform->oprleft)
2924-
appendStringInfo(buf,"::%s",format_type_be(operform->oprleft));
2927+
ri_add_cast_to(buf,operform->oprleft);
29252928
appendStringInfo(buf," OPERATOR(%s.",quote_identifier(nspname));
29262929
appendStringInfoString(buf,oprname);
29272930
appendStringInfo(buf,") %s",rightop);
29282931
if (rightoptype!=operform->oprright)
2929-
appendStringInfo(buf,"::%s",format_type_be(operform->oprright));
2932+
ri_add_cast_to(buf,operform->oprright);
29302933

29312934
ReleaseSysCache(opertup);
29322935
}
29332936

2937+
/*
2938+
* Add a cast specification to buf. We spell out the type name the hard way,
2939+
* intentionally not using format_type_be(). This is to avoid corner cases
2940+
* for CHARACTER, BIT, and perhaps other types, where specifying the type
2941+
* using SQL-standard syntax results in undesirable data truncation. By
2942+
* doing it this way we can be certain that the cast will have default (-1)
2943+
* target typmod.
2944+
*/
2945+
staticvoid
2946+
ri_add_cast_to(StringInfobuf,Oidtypid)
2947+
{
2948+
HeapTupletypetup;
2949+
Form_pg_typetypform;
2950+
char*typname;
2951+
char*nspname;
2952+
2953+
typetup=SearchSysCache(TYPEOID,
2954+
ObjectIdGetDatum(typid),
2955+
0,0,0);
2956+
if (!HeapTupleIsValid(typetup))
2957+
elog(ERROR,"cache lookup failed for type %u",typid);
2958+
typform= (Form_pg_type)GETSTRUCT(typetup);
2959+
2960+
typname=NameStr(typform->typname);
2961+
nspname=get_namespace_name(typform->typnamespace);
2962+
2963+
appendStringInfo(buf,"::%s.%s",
2964+
quote_identifier(nspname),quote_identifier(typname));
2965+
2966+
ReleaseSysCache(typetup);
2967+
}
2968+
29342969
/* ----------
29352970
* ri_BuildQueryKeyFull -
29362971
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp