|
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))); |
|