mirror of
https://github.com/postgres/postgres.git
synced 2025-11-24 00:23:06 +03:00
Tweak the API for per-datatype typmodin functions so that they are passed
an array of strings rather than an array of integers, and allow any simple constant or identifier to be used in typmods; for example create table foo (f1 widget(42,'23skidoo',point)); Of course the typmodin function has still got to pack this info into a non-negative int32 for storage, but it's still a useful improvement in flexibility, especially considering that you can do nearly anything if you are willing to keep the info in a side table. We can get away with this change since we have not yet released a version providing user-definable typmods. Per discussion.
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.593 2007/06/11 22:22:41 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.594 2007/06/15 20:56:49 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@@ -6695,7 +6695,7 @@ ConstTypename:
|
||||
* by the standard, including qualified names. We also allow type modifiers.
|
||||
* To avoid parsing conflicts against function invocations, the modifiers
|
||||
* have to be shown as expr_list here, but parse analysis will only accept
|
||||
* integer constants for them.
|
||||
* constants for them.
|
||||
*/
|
||||
GenericType:
|
||||
type_function_name opt_type_modifiers
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.90 2007/05/11 17:57:12 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.91 2007/06/15 20:56:50 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -289,28 +289,55 @@ typenameTypeMod(ParseState *pstate, const TypeName *typename,
|
||||
parser_errposition(pstate, typename->location)));
|
||||
|
||||
/*
|
||||
* Convert the list of (raw grammar output) expressions to an integer
|
||||
* array. Currently, we only allow simple integer constants, though
|
||||
* possibly this could be extended.
|
||||
* Convert the list of raw-grammar-output expressions to a cstring array.
|
||||
* Currently, we allow simple numeric constants, string literals, and
|
||||
* identifiers; possibly this list could be extended.
|
||||
*/
|
||||
datums = (Datum *) palloc(list_length(typename->typmods) * sizeof(Datum));
|
||||
n = 0;
|
||||
foreach(l, typename->typmods)
|
||||
{
|
||||
A_Const *ac = (A_Const *) lfirst(l);
|
||||
Node *tm = (Node *) lfirst(l);
|
||||
char *cstr = NULL;
|
||||
|
||||
if (!IsA(ac, A_Const) ||
|
||||
!IsA(&ac->val, Integer))
|
||||
if (IsA(tm, A_Const))
|
||||
{
|
||||
A_Const *ac = (A_Const *) tm;
|
||||
|
||||
/*
|
||||
* The grammar hands back some integers with ::int4 attached,
|
||||
* so allow a cast decoration if it's an Integer value, but
|
||||
* not otherwise.
|
||||
*/
|
||||
if (IsA(&ac->val, Integer))
|
||||
{
|
||||
cstr = (char *) palloc(32);
|
||||
snprintf(cstr, 32, "%ld", (long) ac->val.val.ival);
|
||||
}
|
||||
else if (ac->typename == NULL) /* no casts allowed */
|
||||
{
|
||||
/* otherwise we can just use the str field directly. */
|
||||
cstr = ac->val.val.str;
|
||||
}
|
||||
}
|
||||
else if (IsA(tm, ColumnRef))
|
||||
{
|
||||
ColumnRef *cr = (ColumnRef *) tm;
|
||||
|
||||
if (list_length(cr->fields) == 1)
|
||||
cstr = strVal(linitial(cr->fields));
|
||||
}
|
||||
if (!cstr)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("type modifiers must be integer constants"),
|
||||
errmsg("type modifiers must be simple constants or identifiers"),
|
||||
parser_errposition(pstate, typename->location)));
|
||||
datums[n++] = Int32GetDatum(ac->val.val.ival);
|
||||
datums[n++] = CStringGetDatum(cstr);
|
||||
}
|
||||
|
||||
/* hardwired knowledge about int4's representation details here */
|
||||
arrtypmod = construct_array(datums, n, INT4OID,
|
||||
sizeof(int4), true, 'i');
|
||||
/* hardwired knowledge about cstring's representation details here */
|
||||
arrtypmod = construct_array(datums, n, CSTRINGOID,
|
||||
-2, false, 'c');
|
||||
|
||||
result = DatumGetInt32(OidFunctionCall1(typmodin,
|
||||
PointerGetDatum(arrtypmod)));
|
||||
|
||||
Reference in New Issue
Block a user