Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b985d48

Browse files
committed
Further code review for range types patch.
Fix some bugs in coercion logic and pg_dump; more comment cleanup; minor cosmetic improvements.
1 parent 40d3503 commit b985d48

File tree

13 files changed

+275
-265
lines changed

13 files changed

+275
-265
lines changed

doc/src/sgml/datatype.sgml

+11-11
Original file line numberDiff line numberDiff line change
@@ -4506,15 +4506,21 @@ SELECT * FROM pg_attribute
45064506
<entry>Indicates that a function accepts any input data type.</entry>
45074507
</row>
45084508

4509+
<row>
4510+
<entry><type>anyelement</></entry>
4511+
<entry>Indicates that a function accepts any data type
4512+
(see <xref linkend="extend-types-polymorphic">).</entry>
4513+
</row>
4514+
45094515
<row>
45104516
<entry><type>anyarray</></entry>
45114517
<entry>Indicates that a function accepts any array data type
45124518
(see <xref linkend="extend-types-polymorphic">).</entry>
45134519
</row>
45144520

45154521
<row>
4516-
<entry><type>anyelement</></entry>
4517-
<entry>Indicates that a function accepts any data type
4522+
<entry><type>anynonarray</></entry>
4523+
<entry>Indicates that a function accepts any non-array data type
45184524
(see <xref linkend="extend-types-polymorphic">).</entry>
45194525
</row>
45204526

@@ -4532,12 +4538,6 @@ SELECT * FROM pg_attribute
45324538
<xref linkend="rangetypes">).</entry>
45334539
</row>
45344540

4535-
<row>
4536-
<entry><type>anynonarray</></entry>
4537-
<entry>Indicates that a function accepts any non-array data type
4538-
(see <xref linkend="extend-types-polymorphic">).</entry>
4539-
</row>
4540-
45414541
<row>
45424542
<entry><type>cstring</></entry>
45434543
<entry>Indicates that a function accepts or returns a null-terminated C string.</entry>
@@ -4595,9 +4595,9 @@ SELECT * FROM pg_attribute
45954595
languages all forbid use of a pseudo-type as argument type, and allow
45964596
only <type>void</> and <type>record</> as a result type (plus
45974597
<type>trigger</> when the function is used as a trigger). Some also
4598-
support polymorphic functions using the types <type>anyarray</>,
4599-
<type>anyelement</>, <type>anyenum</>, <type>anyrange</>, and
4600-
<type>anynonarray</>.
4598+
support polymorphic functions using the types <type>anyelement</>,
4599+
<type>anyarray</>, <type>anynonarray</>, <type>anyenum</>, and
4600+
<type>anyrange</>.
46014601
</para>
46024602

46034603
<para>

src/backend/catalog/pg_proc.c

+27-20
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ ProcedureCreate(const char *procedureName,
9191
int parameterCount;
9292
int allParamCount;
9393
Oid *allParams;
94-
char *modes = NULL;
94+
char *paramModes = NULL;
9595
bool genericInParam = false;
9696
bool genericOutParam = false;
9797
bool anyrangeInParam = false;
@@ -130,6 +130,7 @@ ProcedureCreate(const char *procedureName,
130130
FUNC_MAX_ARGS)));
131131
/* note: the above is correct, we do NOT count output arguments */
132132

133+
/* Deconstruct array inputs */
133134
if (allParameterTypes != PointerGetDatum(NULL))
134135
{
135136
/*
@@ -169,28 +170,27 @@ ProcedureCreate(const char *procedureName,
169170
ARR_HASNULL(modesArray) ||
170171
ARR_ELEMTYPE(modesArray) != CHAROID)
171172
elog(ERROR, "parameterModes is not a 1-D char array");
172-
modes = (char *) ARR_DATA_PTR(modesArray);
173+
paramModes = (char *) ARR_DATA_PTR(modesArray);
173174
}
174175

175-
176176
/*
177-
* Do not allow polymorphic return type unless at least one input argument
178-
* is polymorphic. Also, do not allow return type INTERNAL unless at
179-
* least one input argument is INTERNAL.
177+
* Detect whether we have polymorphic or INTERNAL arguments. The first
178+
* loop checks input arguments, the second output arguments.
180179
*/
181180
for (i = 0; i < parameterCount; i++)
182181
{
183182
switch (parameterTypes->values[i])
184183
{
185-
case ANYRANGEOID:
186-
anyrangeInParam = true;
187-
/* FALL THROUGH */
188184
case ANYARRAYOID:
189185
case ANYELEMENTOID:
190186
case ANYNONARRAYOID:
191187
case ANYENUMOID:
192188
genericInParam = true;
193189
break;
190+
case ANYRANGEOID:
191+
genericInParam = true;
192+
anyrangeInParam = true;
193+
break;
194194
case INTERNALOID:
195195
internalInParam = true;
196196
break;
@@ -201,30 +201,37 @@ ProcedureCreate(const char *procedureName,
201201
{
202202
for (i = 0; i < allParamCount; i++)
203203
{
204-
if (modes == NULL ||
205-
(modes[i] != PROARGMODE_OUT &&
206-
modes[i] != PROARGMODE_INOUT &&
207-
modes[i] != PROARGMODE_TABLE))
208-
continue;
204+
if (paramModes == NULL ||
205+
paramModes[i] == PROARGMODE_IN ||
206+
paramModes[i] == PROARGMODE_VARIADIC)
207+
continue; /* ignore input-only params */
209208

210209
switch (allParams[i])
211210
{
212-
case ANYRANGEOID:
213-
anyrangeOutParam = true;
214-
/* FALL THROUGH */
215211
case ANYARRAYOID:
216212
case ANYELEMENTOID:
217213
case ANYNONARRAYOID:
218214
case ANYENUMOID:
219215
genericOutParam = true;
220216
break;
217+
case ANYRANGEOID:
218+
genericOutParam = true;
219+
anyrangeOutParam = true;
220+
break;
221221
case INTERNALOID:
222222
internalOutParam = true;
223223
break;
224224
}
225225
}
226226
}
227227

228+
/*
229+
* Do not allow polymorphic return type unless at least one input argument
230+
* is polymorphic. ANYRANGE return type is even stricter: must have an
231+
* ANYRANGE input (since we can't deduce the specific range type from
232+
* ANYELEMENT). Also, do not allow return type INTERNAL unless at least
233+
* one input argument is INTERNAL.
234+
*/
228235
if ((IsPolymorphicType(returnType) || genericOutParam)
229236
&& !genericInParam)
230237
ereport(ERROR,
@@ -259,7 +266,7 @@ ProcedureCreate(const char *procedureName,
259266
procedureName,
260267
format_type_be(parameterTypes->values[0]))));
261268

262-
if (modes != NULL)
269+
if (paramModes != NULL)
263270
{
264271
/*
265272
* Only the last input parameter can be variadic; if it is, save its
@@ -268,7 +275,7 @@ ProcedureCreate(const char *procedureName,
268275
*/
269276
for (i = 0; i < allParamCount; i++)
270277
{
271-
switch (modes[i])
278+
switch (paramModes[i])
272279
{
273280
case PROARGMODE_IN:
274281
case PROARGMODE_INOUT:
@@ -298,7 +305,7 @@ ProcedureCreate(const char *procedureName,
298305
}
299306
break;
300307
default:
301-
elog(ERROR, "invalid parameter mode '%c'", modes[i]);
308+
elog(ERROR, "invalid parameter mode '%c'", paramModes[i]);
302309
break;
303310
}
304311
}

src/backend/commands/typecmds.c

+6-5
Original file line numberDiff line numberDiff line change
@@ -654,9 +654,9 @@ RemoveTypeById(Oid typeOid)
654654
EnumValuesDelete(typeOid);
655655

656656
/*
657-
* If it is a range type, delete the pg_range entries too; we don't bother
658-
* with making dependency entries for those, so it has to be done "by
659-
* hand" here.
657+
* If it is a range type, delete the pg_range entry too; we don't bother
658+
* with making a dependency entry for that, so it has to be done "by hand"
659+
* here.
660660
*/
661661
if (((Form_pg_type) GETSTRUCT(tup))->typtype == TYPTYPE_RANGE)
662662
RangeDelete(typeOid);
@@ -1475,8 +1475,9 @@ makeRangeConstructor(char *name, Oid namespace, Oid rangeOid, Oid subtype)
14751475
0.0); /* prorows */
14761476

14771477
/*
1478-
* Make the constructor internally-dependent on the range type so that
1479-
* the user doesn't have to treat them as separate objects.
1478+
* Make the constructors internally-dependent on the range type so
1479+
* that they go away silently when the type is dropped. Note that
1480+
* pg_dump depends on this choice to avoid dumping the constructors.
14801481
*/
14811482
myself.classId = ProcedureRelationId;
14821483
myself.objectId = procOid;

0 commit comments

Comments
 (0)