|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.90 2007/05/11 17:57:12 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.91 2007/06/15 20:56:50 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -289,28 +289,55 @@ typenameTypeMod(ParseState *pstate, const TypeName *typename,
|
289 | 289 | parser_errposition(pstate,typename->location)));
|
290 | 290 |
|
291 | 291 | /*
|
292 |
| - * Convert the list of(rawgrammaroutput) expressions toan integer |
293 |
| - *array.Currently, weonlyallow simpleinteger constants,though |
294 |
| - * possibly this could be extended. |
| 292 | + * Convert the list of raw-grammar-output expressions toa cstring array. |
| 293 | + * Currently, we allow simplenumeric constants,string literals, and |
| 294 | + *identifiers;possibly this list could be extended. |
295 | 295 | */
|
296 | 296 | datums= (Datum*)palloc(list_length(typename->typmods)*sizeof(Datum));
|
297 | 297 | n=0;
|
298 | 298 | foreach(l,typename->typmods)
|
299 | 299 | {
|
300 |
| -A_Const*ac= (A_Const*)lfirst(l); |
| 300 | +Node*tm= (Node*)lfirst(l); |
| 301 | +char*cstr=NULL; |
301 | 302 |
|
302 |
| -if (!IsA(ac,A_Const)|| |
303 |
| -!IsA(&ac->val,Integer)) |
| 303 | +if (IsA(tm,A_Const)) |
| 304 | +{ |
| 305 | +A_Const*ac= (A_Const*)tm; |
| 306 | + |
| 307 | +/* |
| 308 | + * The grammar hands back some integers with ::int4 attached, |
| 309 | + * so allow a cast decoration if it's an Integer value, but |
| 310 | + * not otherwise. |
| 311 | + */ |
| 312 | +if (IsA(&ac->val,Integer)) |
| 313 | +{ |
| 314 | +cstr= (char*)palloc(32); |
| 315 | +snprintf(cstr,32,"%ld", (long)ac->val.val.ival); |
| 316 | +} |
| 317 | +elseif (ac->typename==NULL)/* no casts allowed */ |
| 318 | +{ |
| 319 | +/* otherwise we can just use the str field directly. */ |
| 320 | +cstr=ac->val.val.str; |
| 321 | +} |
| 322 | +} |
| 323 | +elseif (IsA(tm,ColumnRef)) |
| 324 | +{ |
| 325 | +ColumnRef*cr= (ColumnRef*)tm; |
| 326 | + |
| 327 | +if (list_length(cr->fields)==1) |
| 328 | +cstr=strVal(linitial(cr->fields)); |
| 329 | +} |
| 330 | +if (!cstr) |
304 | 331 | ereport(ERROR,
|
305 | 332 | (errcode(ERRCODE_SYNTAX_ERROR),
|
306 |
| -errmsg("type modifiers must beinteger constants"), |
| 333 | +errmsg("type modifiers must besimple constants or identifiers"), |
307 | 334 | parser_errposition(pstate,typename->location)));
|
308 |
| -datums[n++]=Int32GetDatum(ac->val.val.ival); |
| 335 | +datums[n++]=CStringGetDatum(cstr); |
309 | 336 | }
|
310 | 337 |
|
311 |
| -/* hardwired knowledge aboutint4's representation details here */ |
312 |
| -arrtypmod=construct_array(datums,n,INT4OID, |
313 |
| -sizeof(int4), true,'i'); |
| 338 | +/* hardwired knowledge aboutcstring's representation details here */ |
| 339 | +arrtypmod=construct_array(datums,n,CSTRINGOID, |
| 340 | +-2, false,'c'); |
314 | 341 |
|
315 | 342 | result=DatumGetInt32(OidFunctionCall1(typmodin,
|
316 | 343 | PointerGetDatum(arrtypmod)));
|
|