mirror of
https://github.com/postgres/postgres.git
synced 2025-06-07 00:02:00 -04:00
transformCreateStmt should put Ident nodes, not ColumnDef nodes, into
keys lists of Constraint nodes. This eliminates a type pun that would probably have caused trouble someday, and eliminates circular references in the parsetree that were causing trouble now. Also, change parser's uses of strcasecmp() to strcmp(). Since scan.l has downcased any unquoted identifier, it is never correct to check an identifier with strcasecmp() in the parser. For example, CREATE TABLE FOO (f1 int, UNIQUE("F1")); was accepted, which is wrong, and xlateSqlFunc did more than it should: select datetime(); ERROR: Function 'timestamp()' does not exist (good) select "DateTime"(); ERROR: Function 'timestamp()' does not exist (bad)
This commit is contained in:
parent
8f50f7a291
commit
5c462baebc
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: analyze.c,v 1.140 2000/03/14 23:06:30 thomas Exp $
|
* $Id: analyze.c,v 1.141 2000/03/24 23:34:19 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -570,7 +570,7 @@ CreateIndexName(char *table_name, char *column_name, char *label, List *indices)
|
|||||||
foreach(ilist, indices)
|
foreach(ilist, indices)
|
||||||
{
|
{
|
||||||
IndexStmt *index = lfirst(ilist);
|
IndexStmt *index = lfirst(ilist);
|
||||||
if (strcasecmp(iname, index->idxname) == 0)
|
if (strcmp(iname, index->idxname) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* ran through entire list? then no name conflict found so done */
|
/* ran through entire list? then no name conflict found so done */
|
||||||
@ -679,7 +679,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
|||||||
constraint->name = sname;
|
constraint->name = sname;
|
||||||
constraint->raw_expr = (Node *) funccallnode;
|
constraint->raw_expr = (Node *) funccallnode;
|
||||||
constraint->cooked_expr = NULL;
|
constraint->cooked_expr = NULL;
|
||||||
constraint->keys = NULL;
|
constraint->keys = NIL;
|
||||||
column->constraints = lappend(column->constraints,
|
column->constraints = lappend(column->constraints,
|
||||||
constraint);
|
constraint);
|
||||||
|
|
||||||
@ -766,7 +766,11 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
|||||||
if (constraint->name == NULL)
|
if (constraint->name == NULL)
|
||||||
constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
|
constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
|
||||||
if (constraint->keys == NIL)
|
if (constraint->keys == NIL)
|
||||||
constraint->keys = lappend(constraint->keys, column);
|
{
|
||||||
|
key = makeNode(Ident);
|
||||||
|
key->name = pstrdup(column->colname);
|
||||||
|
constraint->keys = lcons(key, NIL);
|
||||||
|
}
|
||||||
dlist = lappend(dlist, constraint);
|
dlist = lappend(dlist, constraint);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -774,7 +778,11 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
|||||||
if (constraint->name == NULL)
|
if (constraint->name == NULL)
|
||||||
constraint->name = makeObjectName(stmt->relname, column->colname, "key");
|
constraint->name = makeObjectName(stmt->relname, column->colname, "key");
|
||||||
if (constraint->keys == NIL)
|
if (constraint->keys == NIL)
|
||||||
constraint->keys = lappend(constraint->keys, column);
|
{
|
||||||
|
key = makeNode(Ident);
|
||||||
|
key->name = pstrdup(column->colname);
|
||||||
|
constraint->keys = lcons(key, NIL);
|
||||||
|
}
|
||||||
dlist = lappend(dlist, constraint);
|
dlist = lappend(dlist, constraint);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -890,23 +898,21 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
|||||||
index->withClause = NIL;
|
index->withClause = NIL;
|
||||||
index->whereClause = NULL;
|
index->whereClause = NULL;
|
||||||
|
|
||||||
keys = constraint->keys;
|
foreach(keys, constraint->keys)
|
||||||
while (keys != NIL)
|
|
||||||
{
|
{
|
||||||
key = lfirst(keys);
|
key = (Ident *) lfirst(keys);
|
||||||
columns = stmt->tableElts;
|
Assert(IsA(key, Ident));
|
||||||
column = NULL;
|
column = NULL;
|
||||||
while (columns != NIL)
|
foreach(columns, stmt->tableElts)
|
||||||
{
|
{
|
||||||
column = lfirst(columns);
|
column = lfirst(columns);
|
||||||
if (strcasecmp(column->colname, key->name) == 0)
|
Assert(IsA(column, ColumnDef));
|
||||||
|
if (strcmp(column->colname, key->name) == 0)
|
||||||
break;
|
break;
|
||||||
else
|
|
||||||
column = NULL;
|
|
||||||
columns = lnext(columns);
|
|
||||||
}
|
}
|
||||||
if (column == NULL)
|
if (columns == NIL) /* fell off end of list? */
|
||||||
elog(ERROR, "CREATE TABLE column '%s' in key does not exist", key->name);
|
elog(ERROR, "CREATE TABLE: column '%s' named in key does not exist",
|
||||||
|
key->name);
|
||||||
|
|
||||||
if (constraint->contype == CONSTR_PRIMARY)
|
if (constraint->contype == CONSTR_PRIMARY)
|
||||||
column->is_not_null = TRUE;
|
column->is_not_null = TRUE;
|
||||||
@ -919,8 +925,6 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
|
|||||||
|
|
||||||
if (index->idxname == NULL)
|
if (index->idxname == NULL)
|
||||||
index->idxname = CreateIndexName(stmt->relname, iparam->name, "key", ilist);
|
index->idxname = CreateIndexName(stmt->relname, iparam->name, "key", ilist);
|
||||||
|
|
||||||
keys = lnext(keys);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index->idxname == NULL) /* should not happen */
|
if (index->idxname == NULL) /* should not happen */
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.162 2000/03/21 06:00:40 thomas Exp $
|
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.163 2000/03/24 23:34:19 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -3969,7 +3969,7 @@ Character: character '(' Iconst ')'
|
|||||||
character: CHARACTER opt_varying opt_charset
|
character: CHARACTER opt_varying opt_charset
|
||||||
{
|
{
|
||||||
char *type, *c;
|
char *type, *c;
|
||||||
if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
|
if (($3 == NULL) || (strcmp($3, "sql_text") == 0)) {
|
||||||
if ($2) type = xlateSqlType("varchar");
|
if ($2) type = xlateSqlType("varchar");
|
||||||
else type = xlateSqlType("bpchar");
|
else type = xlateSqlType("bpchar");
|
||||||
} else {
|
} else {
|
||||||
@ -5544,11 +5544,11 @@ mapTargetColumns(List *src, List *dst)
|
|||||||
static char *
|
static char *
|
||||||
xlateSqlFunc(char *name)
|
xlateSqlFunc(char *name)
|
||||||
{
|
{
|
||||||
if (!strcasecmp(name,"character_length"))
|
if (!strcmp(name,"character_length"))
|
||||||
return "char_length";
|
return "char_length";
|
||||||
else if (!strcasecmp(name,"datetime"))
|
else if (!strcmp(name,"datetime"))
|
||||||
return "timestamp";
|
return "timestamp";
|
||||||
else if (!strcasecmp(name,"timespan"))
|
else if (!strcmp(name,"timespan"))
|
||||||
return "interval";
|
return "interval";
|
||||||
else
|
else
|
||||||
return name;
|
return name;
|
||||||
@ -5564,21 +5564,21 @@ xlateSqlFunc(char *name)
|
|||||||
static char *
|
static char *
|
||||||
xlateSqlType(char *name)
|
xlateSqlType(char *name)
|
||||||
{
|
{
|
||||||
if (!strcasecmp(name,"int")
|
if (!strcmp(name,"int")
|
||||||
|| !strcasecmp(name,"integer"))
|
|| !strcmp(name,"integer"))
|
||||||
return "int4";
|
return "int4";
|
||||||
else if (!strcasecmp(name, "smallint"))
|
else if (!strcmp(name, "smallint"))
|
||||||
return "int2";
|
return "int2";
|
||||||
else if (!strcasecmp(name, "real")
|
else if (!strcmp(name, "real")
|
||||||
|| !strcasecmp(name, "float"))
|
|| !strcmp(name, "float"))
|
||||||
return "float8";
|
return "float8";
|
||||||
else if (!strcasecmp(name, "decimal"))
|
else if (!strcmp(name, "decimal"))
|
||||||
return "numeric";
|
return "numeric";
|
||||||
else if (!strcasecmp(name, "datetime"))
|
else if (!strcmp(name, "datetime"))
|
||||||
return "timestamp";
|
return "timestamp";
|
||||||
else if (!strcasecmp(name, "timespan"))
|
else if (!strcmp(name, "timespan"))
|
||||||
return "interval";
|
return "interval";
|
||||||
else if (!strcasecmp(name, "boolean"))
|
else if (!strcmp(name, "boolean"))
|
||||||
return "bool";
|
return "bool";
|
||||||
else
|
else
|
||||||
return name;
|
return name;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user