summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-12-16 18:39:57 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-12-16 18:39:57 +0000
commitf599d56f5196f25cc128c7fabe9f087773b9c390 (patch)
tree2374c475c517e9b4b322e8474cba8b9326c98343 /src
parent750b3f38255d3e9c5e6021a74224659d18533e1c (diff)
downloadpostgresql-f599d56f5196f25cc128c7fabe9f087773b9c390.tar.gz
Fix ALTER TABLE ADD COLUMN to disallow the same column types that are
disallowed by CREATE TABLE (eg, pseudo-types); also disallow these types from being introduced by the range-function syntax. While at it, allow CREATE TABLE to create zero-column tables, per recent pghackers discussion. I am back-patching this into 7.3 since failure to disallow pseudo-types is arguably a security hole.
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/heap.c83
-rw-r--r--src/backend/commands/tablecmds.c10
-rw-r--r--src/backend/parser/parse_clause.c15
-rw-r--r--src/backend/utils/cache/relcache.c7
-rw-r--r--src/include/catalog/heap.h6
5 files changed, 76 insertions, 45 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index b476a1181e..19ab896ac4 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.232 2002/10/21 22:06:18 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.232.2.1 2002/12/16 18:39:56 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -306,8 +306,8 @@ heap_storage_create(Relation rel)
*
* this is done in 6 steps:
*
- * 1) CheckAttributeNames() is used to make certain the tuple
- * descriptor contains a valid set of attribute names
+ * 1) CheckAttributeNamesTypes() is used to make certain the tuple
+ * descriptor contains a valid set of attribute names and types
*
* 2) pg_class is opened and get_relname_relid()
* performs a scan to ensure that no relation with the
@@ -333,20 +333,25 @@ heap_storage_create(Relation rel)
*/
/* --------------------------------
- * CheckAttributeNames
+ * CheckAttributeNamesTypes
*
* this is used to make certain the tuple descriptor contains a
- * valid set of attribute names. a problem simply generates
- * elog(ERROR) which aborts the current transaction.
+ * valid set of attribute names and datatypes. a problem simply
+ * generates elog(ERROR) which aborts the current transaction.
* --------------------------------
*/
-static void
-CheckAttributeNames(TupleDesc tupdesc, char relkind)
+void
+CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind)
{
int i;
int j;
int natts = tupdesc->natts;
+ /* Sanity check on column count */
+ if (natts < 0 || natts > MaxHeapAttributeNumber)
+ elog(ERROR, "Number of columns is out of range (0 to %d)",
+ MaxHeapAttributeNumber);
+
/*
* first check for collision with system attribute names
*
@@ -379,8 +384,29 @@ CheckAttributeNames(TupleDesc tupdesc, char relkind)
}
/*
- * We also do some checking of the attribute types here.
- *
+ * next check the attribute types
+ */
+ for (i = 0; i < natts; i++)
+ {
+ CheckAttributeType(NameStr(tupdesc->attrs[i]->attname),
+ tupdesc->attrs[i]->atttypid);
+ }
+}
+
+/* --------------------------------
+ * CheckAttributeType
+ *
+ * Verify that the proposed datatype of an attribute is legal.
+ * This is needed because there are types (and pseudo-types)
+ * in the catalogs that we do not support as elements of real tuples.
+ * --------------------------------
+ */
+void
+CheckAttributeType(const char *attname, Oid atttypid)
+{
+ char att_typtype = get_typtype(atttypid);
+
+ /*
* Warn user, but don't fail, if column to be created has UNKNOWN type
* (usually as a result of a 'retrieve into' - jolly)
*
@@ -389,28 +415,20 @@ CheckAttributeNames(TupleDesc tupdesc, char relkind)
* all references to complex types, but for now there's still some
* Berkeley-derived code that thinks it can do this...)
*/
- for (i = 0; i < natts; i++)
+ if (atttypid == UNKNOWNOID)
+ elog(WARNING, "Attribute \"%s\" has an unknown type"
+ "\n\tProceeding with relation creation anyway",
+ attname);
+ else if (att_typtype == 'p')
+ elog(ERROR, "Attribute \"%s\" has pseudo-type %s",
+ attname, format_type_be(atttypid));
+ else if (att_typtype == 'c')
{
- Oid att_type = tupdesc->attrs[i]->atttypid;
- char att_typtype = get_typtype(att_type);
-
- if (att_type == UNKNOWNOID)
- elog(WARNING, "Attribute \"%s\" has an unknown type"
- "\n\tProceeding with relation creation anyway",
- NameStr(tupdesc->attrs[i]->attname));
- if (att_typtype == 'p')
- elog(ERROR, "Attribute \"%s\" has pseudo-type %s",
- NameStr(tupdesc->attrs[i]->attname),
- format_type_be(att_type));
- if (att_typtype == 'c')
- {
- Oid typrelid = get_typ_typrelid(att_type);
+ Oid typrelid = get_typ_typrelid(atttypid);
- if (get_rel_relkind(typrelid) == RELKIND_COMPOSITE_TYPE)
- elog(ERROR, "Attribute \"%s\" has composite type %s",
- NameStr(tupdesc->attrs[i]->attname),
- format_type_be(att_type));
- }
+ if (get_rel_relkind(typrelid) == RELKIND_COMPOSITE_TYPE)
+ elog(ERROR, "Attribute \"%s\" has composite type %s",
+ attname, format_type_be(atttypid));
}
}
@@ -687,11 +705,8 @@ heap_create_with_catalog(const char *relname,
* sanity checks
*/
Assert(IsNormalProcessingMode() || IsBootstrapProcessingMode());
- if (tupdesc->natts <= 0 || tupdesc->natts > MaxHeapAttributeNumber)
- elog(ERROR, "Number of columns is out of range (1 to %d)",
- MaxHeapAttributeNumber);
- CheckAttributeNames(tupdesc, relkind);
+ CheckAttributeNamesTypes(tupdesc, relkind);
if (get_relname_relid(relname, relnamespace))
elog(ERROR, "Relation '%s' already exists", relname);
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 62d61b315c..46d9b70939 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.51 2002/11/02 22:02:08 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.51.2.1 2002/12/16 18:39:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -104,7 +104,6 @@ DefineRelation(CreateStmt *stmt, char relkind)
char relname[NAMEDATALEN];
Oid namespaceId;
List *schema = stmt->tableElts;
- int numberOfAttributes;
Oid relationId;
Relation rel;
TupleDesc descriptor;
@@ -147,10 +146,6 @@ DefineRelation(CreateStmt *stmt, char relkind)
stmt->relation->istemp,
&inheritOids, &old_constraints, &parentHasOids);
- numberOfAttributes = length(schema);
- if (numberOfAttributes <= 0)
- elog(ERROR, "DefineRelation: please inherit from a relation or define an attribute");
-
/*
* Create a relation descriptor from the relation schema and create
* the relation. Note that in this stage only inherited (pre-cooked)
@@ -1784,6 +1779,9 @@ AlterTableAddColumn(Oid myrelid,
typeTuple = typenameType(colDef->typename);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
+ /* make sure datatype is legal for a column */
+ CheckAttributeType(colDef->colname, HeapTupleGetOid(typeTuple));
+
attributeTuple = heap_addheader(Natts_pg_attribute,
false,
ATTRIBUTE_TUPLE_SIZE,
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 245c0ba422..c88ce186e4 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.98 2002/09/18 21:35:22 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.98.2.1 2002/12/16 18:39:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,6 +16,7 @@
#include "postgres.h"
#include "access/heapam.h"
+#include "catalog/heap.h"
#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/tlist.h"
@@ -503,6 +504,18 @@ transformRangeFunction(ParseState *pstate, RangeFunction *r)
}
/*
+ * If a coldeflist is supplied, ensure it defines a legal set of names
+ * (no duplicates) and datatypes (no pseudo-types, for instance).
+ */
+ if (r->coldeflist)
+ {
+ TupleDesc tupdesc;
+
+ tupdesc = BuildDescForRelation(r->coldeflist);
+ CheckAttributeNamesTypes(tupdesc, RELKIND_COMPOSITE_TYPE);
+ }
+
+ /*
* Insist we have a bare function call (explain.c is the only place
* that depends on this, I think). If this fails, it's probably
* because transformExpr interpreted the function notation as a type
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 29fbd5ec06..2fdbfba5e9 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.177 2002/10/14 16:51:30 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.177.2.1 2002/12/16 18:39:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -570,7 +570,8 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
* cases for attnum=1 that used to exist in fastgetattr() and
* index_getattr().
*/
- relation->rd_att->attrs[0]->attcacheoff = 0;
+ if (relation->rd_rel->relnatts > 0)
+ relation->rd_att->attrs[0]->attcacheoff = 0;
/*
* Set up constraint/default info
@@ -2041,7 +2042,7 @@ RelationBuildLocalRelation(const char *relname,
int natts = tupDesc->natts;
int i;
- AssertArg(natts > 0);
+ AssertArg(natts >= 0);
/*
* switch to the cache context to create the relcache entry.
diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h
index 7ff705b1dd..7688c76574 100644
--- a/src/include/catalog/heap.h
+++ b/src/include/catalog/heap.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: heap.h,v 1.57 2002/09/04 20:31:37 momjian Exp $
+ * $Id: heap.h,v 1.57.2.1 2002/12/16 18:39:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -73,4 +73,8 @@ extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno,
extern Form_pg_attribute SystemAttributeByName(const char *attname,
bool relhasoids);
+extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind);
+
+extern void CheckAttributeType(const char *attname, Oid atttypid);
+
#endif /* HEAP_H */