aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-06-15 20:56:52 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-06-15 20:56:52 +0000
commit23347231a53bc373710db71559a194d87f60a7cb (patch)
tree04c6e8af0afb299a0a112da5c92124a377d1abb3 /src/backend/parser
parent839fcc9fd09452c406b67fb2e1af87d55d0ad4e2 (diff)
downloadpostgresql-23347231a53bc373710db71559a194d87f60a7cb.tar.gz
postgresql-23347231a53bc373710db71559a194d87f60a7cb.zip
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.
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/gram.y4
-rw-r--r--src/backend/parser/parse_type.c51
2 files changed, 41 insertions, 14 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index da3afda8fb3..8ec562c5e31 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -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
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index d3198f0496a..f86dd43d548 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -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)));