*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: analyze.c,v 1.130 2000/01/16 08:21:59 tgl Exp $
+ * $Id: analyze.c,v 1.131 2000/01/20 02:24:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "parser/parse_clause.h"
#include "parser/parse_relation.h"
#include "parser/parse_target.h"
+#include "parser/parse_type.h"
#include "utils/builtins.h"
+#include "utils/numeric.h"
+
+void CheckSelectForUpdate(Query *qry); /* no points for style... */
static Query *transformStmt(ParseState *pstate, Node *stmt);
static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
static void transformForUpdate(Query *qry, List *forUpdate);
static void transformFkeyGetPrimaryKey(FkConstraint *fkconstraint);
-void CheckSelectForUpdate(Query *qry);
+static void transformColumnType(ParseState *pstate, ColumnDef *column);
/* kluge to return extra info from transformCreateStmt() */
static List *extras_before;
column = (ColumnDef *) element;
columns = lappend(columns, column);
+ transformColumnType(pstate, column);
+
/* Special case SERIAL type? */
if (column->is_sequence)
{
heap_close(pkrel, AccessShareLock);
}
-
+/*
+ * Special handling of type definition for a column
+ */
+static void
+transformColumnType(ParseState *pstate, ColumnDef *column)
+{
+ /*
+ * If the column doesn't have an explicitly specified typmod,
+ * check to see if we want to insert a default length.
+ *
+ * Note that we deliberately do NOT look at array or set information
+ * here; "numeric[]" needs the same default typmod as "numeric".
+ */
+ if (column->typename->typmod == -1)
+ {
+ switch (typeTypeId(typenameType(column->typename->name)))
+ {
+ case BPCHAROID:
+ /* "char" -> "char(1)" */
+ column->typename->typmod = VARHDRSZ + 1;
+ break;
+ case NUMERICOID:
+ column->typename->typmod = VARHDRSZ +
+ ((NUMERIC_DEFAULT_PRECISION<<16) | NUMERIC_DEFAULT_SCALE);
+ break;
+ }
+ }
+}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.131 2000/01/18 23:30:20 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.132 2000/01/20 02:24:50 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
n->colname = $1;
n->typename = makeNode(TypeName);
n->typename->name = xlateSqlType("integer");
+ n->typename->typmod = -1;
n->raw_default = NULL;
n->cooked_default = NULL;
n->is_not_null = TRUE;
n->name = $2;
n->setof = $1;
n->arrayBounds = NULL;
+ n->typmod = -1;
$$ = (Node *)n;
}
;
| DOUBLE PRECISION
{
$$ = makeNode(TypeName);
- $$->name = xlateSqlType("float");
+ $$->name = xlateSqlType("float8");
+ $$->typmod = -1;
}
| DECIMAL opt_decimal
{
$$ = makeNode(TypeName);
- $$->name = xlateSqlType("numeric");
+ $$->name = xlateSqlType("decimal");
$$->typmod = $2;
}
| NUMERIC opt_numeric
| DOUBLE PRECISION
{ $$ = xlateSqlType("float8"); }
| DECIMAL
- { $$ = xlateSqlType("numeric"); }
+ { $$ = xlateSqlType("decimal"); }
| NUMERIC
{ $$ = xlateSqlType("numeric"); }
;
}
| /*EMPTY*/
{
- $$ = ((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE) + VARHDRSZ;
+ /* Insert "-1" meaning "default"; may be replaced later */
+ $$ = -1;
}
;
}
| /*EMPTY*/
{
- $$ = ((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE) + VARHDRSZ;
+ /* Insert "-1" meaning "default"; may be replaced later */
+ $$ = -1;
}
;
-/* SQL92 character data types
+/*
+ * SQL92 character data types
* The following implements CHAR() and VARCHAR().
*/
Character: character '(' Iconst ')'
{
$$ = makeNode(TypeName);
- if (strcasecmp($1, "char") == 0)
- $$->name = xlateSqlType("bpchar");
- else if (strcasecmp($1, "varchar") == 0)
- $$->name = xlateSqlType("varchar");
- else
- yyerror("internal parsing error; unrecognized character type");
-
+ $$->name = xlateSqlType($1);
if ($3 < 1)
- elog(ERROR,"length for '%s' type must be at least 1",$1);
+ elog(ERROR,"length for type '%s' must be at least 1",$1);
else if ($3 > MaxAttrSize)
elog(ERROR,"length for type '%s' cannot exceed %ld",$1,
MaxAttrSize);
- /* we actually implement this sort of like a varlen, so
+ /* we actually implement these like a varlen, so
* the first 4 bytes is the length. (the difference
- * between this and "text" is that we blank-pad and
- * truncate where necessary
+ * between these and "text" is that we blank-pad and
+ * truncate where necessary)
*/
$$->typmod = VARHDRSZ + $3;
}
| character
{
$$ = makeNode(TypeName);
- /* Let's try to make all single-character types into bpchar(1)
- * - thomas 1998-05-07
- */
- if (strcasecmp($1, "char") == 0)
- {
- $$->name = xlateSqlType("bpchar");
- $$->typmod = VARHDRSZ + 1;
- }
- else
- {
- $$->name = xlateSqlType($1);
- $$->typmod = -1;
- }
+ $$->name = xlateSqlType($1);
+ /* default length, if needed, will be inserted later */
+ $$->typmod = -1;
}
;
| EXPLAIN { $$ = "explain"; }
| EXTEND { $$ = "extend"; }
| FALSE_P { $$ = "false"; }
+ | FLOAT { $$ = "float"; }
| FOREIGN { $$ = "foreign"; }
| GLOBAL { $$ = "global"; }
| GROUP { $$ = "group"; }
else if (!strcasecmp(name, "real")
|| !strcasecmp(name, "float"))
return "float8";
+ else if (!strcasecmp(name, "decimal"))
+ return "numeric";
+ else if (!strcasecmp(name, "char"))
+ return "bpchar";
else if (!strcasecmp(name, "interval"))
return "timespan";
else if (!strcasecmp(name, "boolean"))