aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/varchar.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-12-30 21:21:56 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-12-30 21:21:56 +0000
commit5725b9d9afc8c3ba24e94cbc7020889fe8ad7ef9 (patch)
treee1c8a77dbb660fa0de36528f19dc4f3cb81829d2 /src/backend/utils/adt/varchar.c
parent24b1f14eae0b83ef5d6b269ebf1ecae2f3acbb8c (diff)
downloadpostgresql-5725b9d9afc8c3ba24e94cbc7020889fe8ad7ef9.tar.gz
postgresql-5725b9d9afc8c3ba24e94cbc7020889fe8ad7ef9.zip
Support type modifiers for user-defined types, and pull most knowledge
about typmod representation for standard types out into type-specific typmod I/O functions. Teodor Sigaev, with some editorialization by Tom Lane.
Diffstat (limited to 'src/backend/utils/adt/varchar.c')
-rw-r--r--src/backend/utils/adt/varchar.c89
1 files changed, 88 insertions, 1 deletions
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 937cf96ebef..9cc2f5e34e3 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.119 2006/10/04 00:30:00 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.120 2006/12/30 21:21:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,10 +17,65 @@
#include "access/hash.h"
#include "libpq/pqformat.h"
+#include "utils/array.h"
#include "utils/builtins.h"
#include "mb/pg_wchar.h"
+/* common code for bpchartypmodin and varchartypmodin */
+static int32
+anychar_typmodin(ArrayType *ta, const char *typename)
+{
+ int32 typmod;
+ int32 *tl;
+ int n;
+
+ tl = ArrayGetTypmods(ta, &n);
+
+ /*
+ * we're not too tense about good error message here because grammar
+ * shouldn't allow wrong number of modifiers for CHAR
+ */
+ if (n != 1)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid type modifier")));
+
+ if (*tl < 1)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("length for type %s must be at least 1", typename)));
+ if (*tl > MaxAttrSize)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("length for type %s cannot exceed %d",
+ typename, MaxAttrSize)));
+
+ /*
+ * For largely historical reasons, the typmod is VARHDRSZ plus the
+ * number of characters; there is enough client-side code that knows
+ * about that that we'd better not change it.
+ */
+ typmod = VARHDRSZ + *tl;
+
+ return typmod;
+}
+
+/* common code for bpchartypmodout and varchartypmodout */
+static char *
+anychar_typmodout(int32 typmod)
+{
+ char *res = (char *) palloc(64);
+
+ if (typmod > VARHDRSZ)
+ snprintf(res, 64, "(%d)", (int) (typmod - VARHDRSZ));
+ else
+ *res = '\0';
+
+ return res;
+}
+
+
/*
* CHAR() and VARCHAR() types are part of the ANSI SQL standard. CHAR()
* is for blank-padded string whose length is specified in CREATE TABLE.
@@ -359,6 +414,22 @@ name_bpchar(PG_FUNCTION_ARGS)
PG_RETURN_BPCHAR_P(result);
}
+Datum
+bpchartypmodin(PG_FUNCTION_ARGS)
+{
+ ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
+
+ PG_RETURN_INT32(anychar_typmodin(ta, "char"));
+}
+
+Datum
+bpchartypmodout(PG_FUNCTION_ARGS)
+{
+ int32 typmod = PG_GETARG_INT32(0);
+
+ PG_RETURN_CSTRING(anychar_typmodout(typmod));
+}
+
/*****************************************************************************
* varchar - varchar(n)
@@ -536,6 +607,22 @@ varchar(PG_FUNCTION_ARGS)
PG_RETURN_VARCHAR_P(result);
}
+Datum
+varchartypmodin(PG_FUNCTION_ARGS)
+{
+ ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
+
+ PG_RETURN_INT32(anychar_typmodin(ta, "varchar"));
+}
+
+Datum
+varchartypmodout(PG_FUNCTION_ARGS)
+{
+ int32 typmod = PG_GETARG_INT32(0);
+
+ PG_RETURN_CSTRING(anychar_typmodout(typmod));
+}
+
/*****************************************************************************
* Exported functions