Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a585c20

Browse files
committed
Tweak parser so that there is a defined representation for datatypes
bpchar, bit, numeric with typmod -1. Alter format_type so that this representation is printed when the typmod is -1. This ensures that tables having such columns can be pg_dump'd and reloaded correctly. Also, remove the rather useless and non-SQL-compliant default precision and scale for type NUMERIC. A numeric column declared as such (with no precision/scale) will now have typmod -1 which means that numeric values of any precision/scale can be stored in it, without conversion to a uniform scale. This seems significantly more useful than the former behavior. Part of response to bug #513.
1 parent 9c9ea41 commit a585c20

File tree

4 files changed

+57
-57
lines changed

4 files changed

+57
-57
lines changed

doc/src/sgml/datatype.sgml

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.68 2001/11/08 23:36:55 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.69 2001/11/12 21:04:45 tgl Exp $
33
-->
44

55
<chapter id="datatype">
@@ -533,14 +533,18 @@ NUMERIC(<replaceable>precision</replaceable>, <replaceable>scale</replaceable>)
533533
<programlisting>
534534
NUMERIC(<replaceable>precision</replaceable>)
535535
</programlisting>
536-
selects a scale of 0. Merely specifying
536+
selects a scale of 0. Specifying
537537
<programlisting>
538538
NUMERIC
539539
</programlisting>
540-
uses a default precision and scale, which is currently (30,6).
541-
(The SQL standard requires a default scale of 0. We find this a
542-
bit useless. If you're concerned about portability, always
543-
specify the precision and scale explicitly.)
540+
without any precision or scale creates a column in which numeric
541+
values of any precision and scale can be stored, up to the implementation
542+
limit on precision. A column of this kind will not coerce input
543+
values to any particular scale, whereas <type>numeric</type> columns
544+
with a declared scale will coerce input values to that scale.
545+
(The SQL standard requires a default scale of 0, ie, coercion to
546+
integer accuracy. We find this a bit useless. If you're concerned about
547+
portability, always specify the precision and scale explicitly.)
544548
</para>
545549

546550
<para>
@@ -852,13 +856,17 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
852856
<para>
853857
The storage requirement for data of these types is 4 bytes plus
854858
the actual string, and in case of <type>character</type> plus the
855-
padding. Long strings will actually be compressed by the system
856-
automatically. In any case, the longest possible character string
859+
padding. Long strings will be compressed by the system
860+
automatically, so the physical requirement on-disk may be less.
861+
In any case, the longest possible character string
857862
that can be stored is about 1 GB. (The maximum value that will be
858863
allowed for <replaceable>n</> in the data type declaration is
859-
actually larger than that. It wouldn't be very useful to change
864+
less than that. It wouldn't be very useful to change
860865
this because with multibyte character encodings the number of
861-
characters and bytes can be quite different anyway.)
866+
characters and bytes can be quite different anyway. If you desire
867+
to store long strings with no specific upper limit, use <type>text</type>
868+
or <type>character varying</type> without a length specifier,
869+
rather than making up an arbitrary length limit.)
862870
</para>
863871

864872
<tip>
@@ -916,7 +924,7 @@ SELECT b, char_length(b) FROM test2;
916924
<productname>Postgres</productname>. The <type>name</type> type
917925
exists <emphasis>only</emphasis> for storage of internal catalog
918926
names and is not intended for use by the general user. Its length
919-
is currently defined as 32 bytes (31 characters plus terminator)
927+
is currently defined as 32 bytes (31 usable characters plus terminator)
920928
but should be referenced using the macro
921929
<symbol>NAMEDATALEN</symbol>. The length is set at compile time
922930
(and is therefore adjustable for special uses); the default

src/backend/parser/analyze.c

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.211 2001/11/05 17:46:26 momjian Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.212 2001/11/12 21:04:45 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -34,7 +34,6 @@
3434
#include "rewrite/rewriteManip.h"
3535
#include "utils/builtins.h"
3636
#include "utils/fmgroids.h"
37-
#include "utils/numeric.h"
3837
#include "utils/relcache.h"
3938
#include "utils/syscache.h"
4039
#include "utils/temprel.h"
@@ -3179,32 +3178,6 @@ transformColumnType(ParseState *pstate, ColumnDef *column)
31793178
TypeName *typename = column->typename;
31803179
Type ctype = typenameType(typename->name);
31813180

3182-
/*
3183-
* If the column doesn't have an explicitly specified typmod, check to
3184-
* see if we want to insert a default length.
3185-
*
3186-
* Note that we deliberately do NOT look at array or set information
3187-
* here; "numeric[]" needs the same default typmod as "numeric".
3188-
*/
3189-
if (typename->typmod == -1)
3190-
{
3191-
switch (typeTypeId(ctype))
3192-
{
3193-
case BPCHAROID:
3194-
/* "char" -> "char(1)" */
3195-
typename->typmod = VARHDRSZ + 1;
3196-
break;
3197-
case NUMERICOID:
3198-
typename->typmod = VARHDRSZ +
3199-
((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE);
3200-
break;
3201-
case BITOID:
3202-
/* 'bit' -> 'bit(1)' */
3203-
typename->typmod = 1;
3204-
break;
3205-
}
3206-
}
3207-
32083181
/*
32093182
* Is this the name of a complex type? If so, implement it as a set.
32103183
*

src/backend/parser/gram.y

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.273 2001/11/10 22:31:49 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.274 2001/11/12 21:04:45 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHOR DATE MAJOR EVENT
@@ -4156,7 +4156,7 @@ opt_numeric: '(' Iconst ',' Iconst ')'
41564156
}
41574157
| /*EMPTY*/
41584158
{
4159-
/* Insert "-1" meaning "default"; may be replaced later */
4159+
/* Insert "-1" meaning "no limit" */
41604160
$$ = -1;
41614161
}
41624162
;
@@ -4182,7 +4182,7 @@ opt_decimal: '(' Iconst ',' Iconst ')'
41824182
}
41834183
| /*EMPTY*/
41844184
{
4185-
/* Insert "-1" meaning "default"; may be replaced later */
4185+
/* Insert "-1" meaning "no limit" */
41864186
$$ = -1;
41874187
}
41884188
;
@@ -4208,8 +4208,11 @@ Bit: bit '(' Iconst ')'
42084208
{
42094209
$$ = makeNode(TypeName);
42104210
$$->name = $1;
4211-
/* default length, if needed, will be inserted later */
4212-
$$->typmod = -1;
4211+
/* bit defaults to bit(1), varbit to no limit */
4212+
if (strcmp($1, "bit") == 0)
4213+
$$->typmod = 1;
4214+
else
4215+
$$->typmod = -1;
42134216
}
42144217
;
42154218

@@ -4259,8 +4262,11 @@ Character: character '(' Iconst ')' opt_charset
42594262
{
42604263
$$ = makeNode(TypeName);
42614264
$$->name = $1;
4262-
/* default length, if needed, will be inserted later */
4263-
$$->typmod = -1;
4265+
/* char defaults to char(1), varchar to no limit */
4266+
if (strcmp($1, "bpchar") == 0)
4267+
$$->typmod = VARHDRSZ + 1;
4268+
else
4269+
$$->typmod = -1;
42644270

42654271
if (($2 != NULL) && (strcmp($2, "sql_text") != 0)) {
42664272
char *type;

src/backend/utils/adt/format_type.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.21 2001/10/25 05:49:44 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.22 2001/11/12 21:04:46 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -163,6 +163,21 @@ format_type_internal(Oid type_oid, int32 typemod, bool allow_invalid)
163163

164164
switch (type_oid)
165165
{
166+
case BITOID:
167+
if (with_typemod)
168+
buf = psnprintf(5 + MAX_INT32_LEN + 1, "bit(%d)",
169+
(int) typemod);
170+
else
171+
{
172+
/*
173+
* bit with no typmod is not the same as BIT, which means
174+
* BIT(1) per SQL spec. Report it as the quoted typename
175+
* so that parser will not assign a bogus typmod.
176+
*/
177+
buf = pstrdup("\"bit\"");
178+
}
179+
break;
180+
166181
case BOOLOID:
167182
buf = pstrdup("boolean");
168183
break;
@@ -172,11 +187,17 @@ format_type_internal(Oid type_oid, int32 typemod, bool allow_invalid)
172187
buf = psnprintf(11 + MAX_INT32_LEN + 1, "character(%d)",
173188
(int) (typemod - VARHDRSZ));
174189
else
175-
buf = pstrdup("character");
190+
{
191+
/*
192+
* bpchar with no typmod is not the same as CHARACTER,
193+
* which means CHARACTER(1) per SQL spec. Report it as
194+
* bpchar so that parser will not assign a bogus typmod.
195+
*/
196+
buf = pstrdup("bpchar");
197+
}
176198
break;
177199

178200
case CHAROID:
179-
180201
/*
181202
* This char type is the single-byte version. You have to
182203
* double-quote it to get at it in the parser.
@@ -329,14 +350,6 @@ format_type_internal(Oid type_oid, int32 typemod, bool allow_invalid)
329350
buf = pstrdup("character varying");
330351
break;
331352

332-
case BITOID:
333-
if (with_typemod)
334-
buf = psnprintf(5 + MAX_INT32_LEN + 1, "bit(%d)",
335-
(int) typemod);
336-
else
337-
buf = pstrdup("bit");
338-
break;
339-
340353
default:
341354
name = NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname);
342355
if (strspn(name, "abcdefghijklmnopqrstuvwxyz0123456789_") != strlen(name)

0 commit comments

Comments
 (0)