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

Commit 7476e37

Browse files
committed
Assign a typmod of -1 to unadorned CHAR and NUMERIC type specs. This
allows casts without specific length requirements to continue to work as they did before; that is, x::char will not truncate the value of x, whereas x::char(1) will. Likewise for NUMERIC precision/scale. The column length defaults of char(1) and numeric(30,6) are now inserted in analyze.c's processing of CREATE TABLE.
1 parent 08195a4 commit 7476e37

File tree

2 files changed

+62
-34
lines changed

2 files changed

+62
-34
lines changed

src/backend/parser/analyze.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Copyright (c) 1994, Regents of the University of California
77
*
8-
* $Id: analyze.c,v 1.130 2000/01/16 08:21:59 tgl Exp $
8+
* $Id: analyze.c,v 1.131 2000/01/20 02:24:50 tgl Exp $
99
*
1010
*-------------------------------------------------------------------------
1111
*/
@@ -23,7 +23,11 @@
2323
#include "parser/parse_clause.h"
2424
#include "parser/parse_relation.h"
2525
#include "parser/parse_target.h"
26+
#include "parser/parse_type.h"
2627
#include "utils/builtins.h"
28+
#include "utils/numeric.h"
29+
30+
void CheckSelectForUpdate(Query *qry); /* no points for style... */
2731

2832
static Query *transformStmt(ParseState *pstate, Node *stmt);
2933
static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
@@ -38,7 +42,7 @@ static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt);
3842

3943
static void transformForUpdate(Query *qry, List *forUpdate);
4044
static void transformFkeyGetPrimaryKey(FkConstraint *fkconstraint);
41-
void CheckSelectForUpdate(Query *qry);
45+
static void transformColumnType(ParseState *pstate, ColumnDef *column);
4246

4347
/* kluge to return extra info from transformCreateStmt() */
4448
static List *extras_before;
@@ -601,6 +605,8 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
601605
column = (ColumnDef *) element;
602606
columns = lappend(columns, column);
603607

608+
transformColumnType(pstate, column);
609+
604610
/* Special case SERIAL type? */
605611
if (column->is_sequence)
606612
{
@@ -1701,4 +1707,31 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint)
17011707
heap_close(pkrel, AccessShareLock);
17021708
}
17031709

1704-
1710+
/*
1711+
* Special handling of type definition for a column
1712+
*/
1713+
static void
1714+
transformColumnType(ParseState *pstate, ColumnDef *column)
1715+
{
1716+
/*
1717+
* If the column doesn't have an explicitly specified typmod,
1718+
* check to see if we want to insert a default length.
1719+
*
1720+
* Note that we deliberately do NOT look at array or set information
1721+
* here; "numeric[]" needs the same default typmod as "numeric".
1722+
*/
1723+
if (column->typename->typmod == -1)
1724+
{
1725+
switch (typeTypeId(typenameType(column->typename->name)))
1726+
{
1727+
case BPCHAROID:
1728+
/* "char" -> "char(1)" */
1729+
column->typename->typmod = VARHDRSZ + 1;
1730+
break;
1731+
case NUMERICOID:
1732+
column->typename->typmod = VARHDRSZ +
1733+
((NUMERIC_DEFAULT_PRECISION<<16) | NUMERIC_DEFAULT_SCALE);
1734+
break;
1735+
}
1736+
}
1737+
}

src/backend/parser/gram.y

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.131 2000/01/18 23:30:20 petere Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.132 2000/01/20 02:24:50 tgl Exp $
1414
*
1515
* HISTORY
1616
* AUTHOR DATE MAJOR EVENT
@@ -1032,6 +1032,7 @@ columnDef: ColId Typename ColConstraintList
10321032
n->colname = $1;
10331033
n->typename = makeNode(TypeName);
10341034
n->typename->name = xlateSqlType("integer");
1035+
n->typename->typmod = -1;
10351036
n->raw_default = NULL;
10361037
n->cooked_default = NULL;
10371038
n->is_not_null = TRUE;
@@ -2280,6 +2281,7 @@ func_return: set_opt TypeId
22802281
n->name = $2;
22812282
n->setof = $1;
22822283
n->arrayBounds = NULL;
2284+
n->typmod = -1;
22832285
$$ = (Node *)n;
22842286
}
22852287
;
@@ -3643,12 +3645,13 @@ Numeric: FLOAT opt_float
36433645
| DOUBLE PRECISION
36443646
{
36453647
$$ = makeNode(TypeName);
3646-
$$->name = xlateSqlType("float");
3648+
$$->name = xlateSqlType("float8");
3649+
$$->typmod = -1;
36473650
}
36483651
| DECIMAL opt_decimal
36493652
{
36503653
$$ = makeNode(TypeName);
3651-
$$->name = xlateSqlType("numeric");
3654+
$$->name = xlateSqlType("decimal");
36523655
$$->typmod = $2;
36533656
}
36543657
| NUMERIC opt_numeric
@@ -3664,7 +3667,7 @@ numeric: FLOAT
36643667
| DOUBLE PRECISION
36653668
{ $$ = xlateSqlType("float8"); }
36663669
| DECIMAL
3667-
{ $$ = xlateSqlType("numeric"); }
3670+
{ $$ = xlateSqlType("decimal"); }
36683671
| NUMERIC
36693672
{ $$ = xlateSqlType("numeric"); }
36703673
;
@@ -3707,7 +3710,8 @@ opt_numeric: '(' Iconst ',' Iconst ')'
37073710
}
37083711
| /*EMPTY*/
37093712
{
3710-
$$ = ((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE) + VARHDRSZ;
3713+
/* Insert "-1" meaning "default"; may be replaced later */
3714+
$$ = -1;
37113715
}
37123716
;
37133717

@@ -3732,53 +3736,39 @@ opt_decimal: '(' Iconst ',' Iconst ')'
37323736
}
37333737
| /*EMPTY*/
37343738
{
3735-
$$ = ((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE) + VARHDRSZ;
3739+
/* Insert "-1" meaning "default"; may be replaced later */
3740+
$$ = -1;
37363741
}
37373742
;
37383743

37393744

3740-
/* SQL92 character data types
3745+
/*
3746+
* SQL92 character data types
37413747
* The following implements CHAR() and VARCHAR().
37423748
*/
37433749
Character: character '(' Iconst ')'
37443750
{
37453751
$$ = makeNode(TypeName);
3746-
if (strcasecmp($1, "char") == 0)
3747-
$$->name = xlateSqlType("bpchar");
3748-
else if (strcasecmp($1, "varchar") == 0)
3749-
$$->name = xlateSqlType("varchar");
3750-
else
3751-
yyerror("internal parsing error; unrecognized character type");
3752-
3752+
$$->name = xlateSqlType($1);
37533753
if ($3 < 1)
3754-
elog(ERROR,"length for '%s' type must be at least 1",$1);
3754+
elog(ERROR,"length for type '%s' must be at least 1",$1);
37553755
else if ($3 > MaxAttrSize)
37563756
elog(ERROR,"length for type '%s' cannot exceed %ld",$1,
37573757
MaxAttrSize);
37583758

3759-
/* we actually implement this sort of like a varlen, so
3759+
/* we actually implement these like a varlen, so
37603760
* the first 4 bytes is the length. (the difference
3761-
* between this and "text" is that we blank-pad and
3762-
* truncate where necessary
3761+
* between these and "text" is that we blank-pad and
3762+
* truncate where necessary)
37633763
*/
37643764
$$->typmod = VARHDRSZ + $3;
37653765
}
37663766
| character
37673767
{
37683768
$$ = makeNode(TypeName);
3769-
/* Let's try to make all single-character types into bpchar(1)
3770-
* - thomas 1998-05-07
3771-
*/
3772-
if (strcasecmp($1, "char") == 0)
3773-
{
3774-
$$->name = xlateSqlType("bpchar");
3775-
$$->typmod = VARHDRSZ + 1;
3776-
}
3777-
else
3778-
{
3779-
$$->name = xlateSqlType($1);
3780-
$$->typmod = -1;
3781-
}
3769+
$$->name = xlateSqlType($1);
3770+
/* default length, if needed, will be inserted later */
3771+
$$->typmod = -1;
37823772
}
37833773
;
37843774

@@ -5131,6 +5121,7 @@ ColLabel: ColId { $$ = $1; }
51315121
| EXPLAIN { $$ = "explain"; }
51325122
| EXTEND { $$ = "extend"; }
51335123
| FALSE_P { $$ = "false"; }
5124+
| FLOAT { $$ = "float"; }
51345125
| FOREIGN { $$ = "foreign"; }
51355126
| GLOBAL { $$ = "global"; }
51365127
| GROUP { $$ = "group"; }
@@ -5314,6 +5305,10 @@ xlateSqlType(char *name)
53145305
else if (!strcasecmp(name, "real")
53155306
|| !strcasecmp(name, "float"))
53165307
return "float8";
5308+
else if (!strcasecmp(name, "decimal"))
5309+
return "numeric";
5310+
else if (!strcasecmp(name, "char"))
5311+
return "bpchar";
53175312
else if (!strcasecmp(name, "interval"))
53185313
return "timespan";
53195314
else if (!strcasecmp(name, "boolean"))

0 commit comments

Comments
 (0)