aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/commands/typecmds.c6
-rw-r--r--src/backend/parser/gram.y4
-rw-r--r--src/backend/parser/parse_type.c51
-rw-r--r--src/backend/utils/adt/arrayutils.c33
-rw-r--r--src/backend/utils/adt/date.c4
-rw-r--r--src/backend/utils/adt/numeric.c4
-rw-r--r--src/backend/utils/adt/timestamp.c6
-rw-r--r--src/backend/utils/adt/varbit.c4
-rw-r--r--src/backend/utils/adt/varchar.c4
9 files changed, 80 insertions, 36 deletions
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 5402cde74cd..d9748cf0ea8 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.104 2007/05/12 00:54:59 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.105 2007/06/15 20:56:49 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -1270,9 +1270,9 @@ findTypeTypmodinFunction(List *procname)
Oid procOid;
/*
- * typmodin functions always take one int4[] argument and return int4.
+ * typmodin functions always take one cstring[] argument and return int4.
*/
- argList[0] = INT4ARRAYOID;
+ argList[0] = CSTRINGARRAYOID;
procOid = LookupFuncName(procname, 1, argList, true);
if (!OidIsValid(procOid))
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)));
diff --git a/src/backend/utils/adt/arrayutils.c b/src/backend/utils/adt/arrayutils.c
index 695f4516329..cd59ffb62d6 100644
--- a/src/backend/utils/adt/arrayutils.c
+++ b/src/backend/utils/adt/arrayutils.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/arrayutils.c,v 1.23 2007/01/05 22:19:40 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/arrayutils.c,v 1.24 2007/06/15 20:56:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,6 +17,7 @@
#include "catalog/pg_type.h"
#include "utils/array.h"
+#include "utils/builtins.h"
#include "utils/memutils.h"
@@ -191,16 +192,21 @@ mda_next_tuple(int n, int *curr, const int *span)
}
/*
- * ArrayGetTypmods: verify that argument is a 1-D integer array,
- * return its length and a pointer to the first contained integer.
+ * ArrayGetIntegerTypmods: verify that argument is a 1-D cstring array,
+ * and get the contents converted to integers. Returns a palloc'd array
+ * and places the length at *n.
*/
int32 *
-ArrayGetTypmods(ArrayType *arr, int *n)
+ArrayGetIntegerTypmods(ArrayType *arr, int *n)
{
- if (ARR_ELEMTYPE(arr) != INT4OID)
+ int32 *result;
+ Datum *elem_values;
+ int i;
+
+ if (ARR_ELEMTYPE(arr) != CSTRINGOID)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
- errmsg("typmod array must be type integer[]")));
+ errmsg("typmod array must be type cstring[]")));
if (ARR_NDIM(arr) != 1)
ereport(ERROR,
@@ -212,7 +218,18 @@ ArrayGetTypmods(ArrayType *arr, int *n)
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("typmod array must not contain nulls")));
- *n = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr));
+ /* hardwired knowledge about cstring's representation details here */
+ deconstruct_array(arr, CSTRINGOID,
+ -2, false, 'c',
+ &elem_values, NULL, n);
+
+ result = (int32 *) palloc(*n * sizeof(int32));
+
+ for (i = 0; i < *n; i++)
+ result[i] = pg_atoi(DatumGetCString(elem_values[i]),
+ sizeof(int32), '\0');
+
+ pfree(elem_values);
- return (int32 *) ARR_DATA_PTR(arr);
+ return result;
}
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index 4914736116f..a66680f4772 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.132 2007/06/05 21:31:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.133 2007/06/15 20:56:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,7 +53,7 @@ anytime_typmodin(bool istz, ArrayType *ta)
int32 *tl;
int n;
- tl = ArrayGetTypmods(ta, &n);
+ tl = ArrayGetIntegerTypmods(ta, &n);
/*
* we're not too tense about good error message here because grammar
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 95309cbff47..02523b8a5fc 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -14,7 +14,7 @@
* Copyright (c) 1998-2007, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.104 2007/06/09 15:52:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.105 2007/06/15 20:56:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -547,7 +547,7 @@ numerictypmodin(PG_FUNCTION_ARGS)
int n;
int32 typmod;
- tl = ArrayGetTypmods(ta, &n);
+ tl = ArrayGetIntegerTypmods(ta, &n);
if (n == 2)
{
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index f7c385ad46a..d2019351168 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.177 2007/06/05 21:31:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.178 2007/06/15 20:56:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -64,7 +64,7 @@ anytimestamp_typmodin(bool istz, ArrayType *ta)
int32 *tl;
int n;
- tl = ArrayGetTypmods(ta, &n);
+ tl = ArrayGetIntegerTypmods(ta, &n);
/*
* we're not too tense about good error message here because grammar
@@ -719,7 +719,7 @@ intervaltypmodin(PG_FUNCTION_ARGS)
int n;
int32 typmod;
- tl = ArrayGetTypmods(ta, &n);
+ tl = ArrayGetIntegerTypmods(ta, &n);
/*
* tl[0] - opt_interval
diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c
index a9eef1e0e7d..3126bd689cb 100644
--- a/src/backend/utils/adt/varbit.c
+++ b/src/backend/utils/adt/varbit.c
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.53 2007/02/27 23:48:09 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.54 2007/06/15 20:56:51 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,7 +32,7 @@ anybit_typmodin(ArrayType *ta, const char *typename)
int32 *tl;
int n;
- tl = ArrayGetTypmods(ta, &n);
+ tl = ArrayGetIntegerTypmods(ta, &n);
/*
* we're not too tense about good error message here because grammar
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 77a6ab9c4fc..43315dd9ebc 100644
--- a/src/backend/utils/adt/varchar.c
+++ b/src/backend/utils/adt/varchar.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.123 2007/04/06 04:21:43 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.124 2007/06/15 20:56:51 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,7 +31,7 @@ anychar_typmodin(ArrayType *ta, const char *typename)
int32 *tl;
int n;
- tl = ArrayGetTypmods(ta, &n);
+ tl = ArrayGetIntegerTypmods(ta, &n);
/*
* we're not too tense about good error message here because grammar