ALTER TABLE DROP COLUMN works. Patch by Christopher Kings-Lynne,

code review by Tom Lane.  Remaining issues: functions that take or
return tuple types are likely to break if one drops (or adds!)
a column in the table defining the type.  Need to think about what
to do here.

Along the way: some code review for recent COPY changes; mark system
columns attnotnull = true where appropriate, per discussion a month ago.
This commit is contained in:
Tom Lane 2002-08-02 18:15:10 +00:00
parent 5e6528adf7
commit 38bb77a5d1
44 changed files with 1823 additions and 891 deletions

View File

@ -829,8 +829,9 @@ dblink_replace_text(PG_FUNCTION_ARGS)
left_text = DatumGetTextP(DirectFunctionCall3(text_substr, PointerGetDatum(buf_text), 1, DatumGetInt32(DirectFunctionCall2(textpos, PointerGetDatum(buf_text), PointerGetDatum(from_sub_text))) - 1));
right_text = DatumGetTextP(DirectFunctionCall3(text_substr, PointerGetDatum(buf_text), DatumGetInt32(DirectFunctionCall2(textpos, PointerGetDatum(buf_text), PointerGetDatum(from_sub_text))) + from_sub_text_len, -1));
appendStringInfo(str, DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(left_text))));
appendStringInfo(str, to_sub_str);
appendStringInfo(str, "%s",
DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(left_text))));
appendStringInfo(str, "%s", to_sub_str);
pfree(buf_text);
pfree(left_text);
@ -838,7 +839,8 @@ dblink_replace_text(PG_FUNCTION_ARGS)
curr_posn = DatumGetInt32(DirectFunctionCall2(textpos, PointerGetDatum(buf_text), PointerGetDatum(from_sub_text)));
}
appendStringInfo(str, DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(buf_text))));
appendStringInfo(str, "%s",
DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(buf_text))));
pfree(buf_text);
ret_str = pstrdup(str->data);
@ -1013,10 +1015,11 @@ get_sql_insert(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattval
TupleDesc tupdesc;
int natts;
StringInfo str = makeStringInfo();
char *sql = NULL;
char *val = NULL;
char *sql;
char *val;
int16 key;
unsigned int i;
int i;
bool needComma;
/*
* Open relation using relid
@ -1029,12 +1032,19 @@ get_sql_insert(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattval
tuple = get_tuple_of_interest(relid, pkattnums, pknumatts, src_pkattvals);
appendStringInfo(str, "INSERT INTO %s(", quote_ident_cstr(relname));
needComma = false;
for (i = 0; i < natts; i++)
{
if (i > 0)
if (tupdesc->attrs[i]->attisdropped)
continue;
if (needComma)
appendStringInfo(str, ",");
appendStringInfo(str, NameStr(tupdesc->attrs[i]->attname));
appendStringInfo(str, "%s",
quote_ident_cstr(NameStr(tupdesc->attrs[i]->attname)));
needComma = true;
}
appendStringInfo(str, ") VALUES(");
@ -1042,9 +1052,13 @@ get_sql_insert(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattval
/*
* remember attvals are 1 based
*/
needComma = false;
for (i = 0; i < natts; i++)
{
if (i > 0)
if (tupdesc->attrs[i]->attisdropped)
continue;
if (needComma)
appendStringInfo(str, ",");
if (tgt_pkattvals != NULL)
@ -1059,11 +1073,12 @@ get_sql_insert(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattval
if (val != NULL)
{
appendStringInfo(str, quote_literal_cstr(val));
appendStringInfo(str, "%s", quote_literal_cstr(val));
pfree(val);
}
else
appendStringInfo(str, "NULL");
needComma = true;
}
appendStringInfo(str, ")");
@ -1083,9 +1098,9 @@ get_sql_delete(Oid relid, int16 *pkattnums, int16 pknumatts, char **tgt_pkattval
TupleDesc tupdesc;
int natts;
StringInfo str = makeStringInfo();
char *sql = NULL;
char *val = NULL;
unsigned int i;
char *sql;
char *val;
int i;
/*
* Open relation using relid
@ -1103,21 +1118,24 @@ get_sql_delete(Oid relid, int16 *pkattnums, int16 pknumatts, char **tgt_pkattval
if (i > 0)
appendStringInfo(str, " AND ");
appendStringInfo(str, NameStr(tupdesc->attrs[pkattnum - 1]->attname));
appendStringInfo(str, "%s",
quote_ident_cstr(NameStr(tupdesc->attrs[pkattnum - 1]->attname)));
if (tgt_pkattvals != NULL)
val = pstrdup(tgt_pkattvals[i]);
else
{
elog(ERROR, "Target key array must not be NULL");
val = NULL; /* keep compiler quiet */
}
if (val != NULL)
{
appendStringInfo(str, "=");
appendStringInfo(str, quote_literal_cstr(val));
appendStringInfo(str, " = %s", quote_literal_cstr(val));
pfree(val);
}
else
appendStringInfo(str, "IS NULL");
appendStringInfo(str, " IS NULL");
}
sql = pstrdup(str->data);
@ -1137,10 +1155,11 @@ get_sql_update(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattval
TupleDesc tupdesc;
int natts;
StringInfo str = makeStringInfo();
char *sql = NULL;
char *val = NULL;
char *sql;
char *val;
int16 key;
int i;
bool needComma;
/*
* Open relation using relid
@ -1154,13 +1173,17 @@ get_sql_update(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattval
appendStringInfo(str, "UPDATE %s SET ", quote_ident_cstr(relname));
needComma = false;
for (i = 0; i < natts; i++)
{
if (i > 0)
appendStringInfo(str, ",");
if (tupdesc->attrs[i]->attisdropped)
continue;
appendStringInfo(str, NameStr(tupdesc->attrs[i]->attname));
appendStringInfo(str, "=");
if (needComma)
appendStringInfo(str, ", ");
appendStringInfo(str, "%s = ",
quote_ident_cstr(NameStr(tupdesc->attrs[i]->attname)));
if (tgt_pkattvals != NULL)
key = get_attnum_pk_pos(pkattnums, pknumatts, i + 1);
@ -1174,11 +1197,12 @@ get_sql_update(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattval
if (val != NULL)
{
appendStringInfo(str, quote_literal_cstr(val));
appendStringInfo(str, "%s", quote_literal_cstr(val));
pfree(val);
}
else
appendStringInfo(str, "NULL");
needComma = true;
}
appendStringInfo(str, " WHERE ");
@ -1190,7 +1214,8 @@ get_sql_update(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattval
if (i > 0)
appendStringInfo(str, " AND ");
appendStringInfo(str, NameStr(tupdesc->attrs[pkattnum - 1]->attname));
appendStringInfo(str, "%s",
quote_ident_cstr(NameStr(tupdesc->attrs[pkattnum - 1]->attname)));
if (tgt_pkattvals != NULL)
val = pstrdup(tgt_pkattvals[i]);
@ -1199,12 +1224,11 @@ get_sql_update(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattval
if (val != NULL)
{
appendStringInfo(str, "=");
appendStringInfo(str, quote_literal_cstr(val));
appendStringInfo(str, " = %s", quote_literal_cstr(val));
pfree(val);
}
else
appendStringInfo(str, "IS NULL");
appendStringInfo(str, " IS NULL");
}
sql = pstrdup(str->data);
@ -1297,7 +1321,7 @@ get_tuple_of_interest(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_p
* Build sql statement to look up tuple of interest
* Use src_pkattvals as the criteria.
*/
appendStringInfo(str, "SELECT * from %s WHERE ", relname);
appendStringInfo(str, "SELECT * FROM %s WHERE ", quote_ident_cstr(relname));
for (i = 0; i < pknumatts; i++)
{
@ -1306,17 +1330,17 @@ get_tuple_of_interest(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_p
if (i > 0)
appendStringInfo(str, " AND ");
appendStringInfo(str, NameStr(tupdesc->attrs[pkattnum - 1]->attname));
appendStringInfo(str, "%s",
quote_ident_cstr(NameStr(tupdesc->attrs[pkattnum - 1]->attname)));
val = pstrdup(src_pkattvals[i]);
if (val != NULL)
{
appendStringInfo(str, "=");
appendStringInfo(str, quote_literal_cstr(val));
appendStringInfo(str, " = %s", quote_literal_cstr(val));
pfree(val);
}
else
appendStringInfo(str, "IS NULL");
appendStringInfo(str, " IS NULL");
}
sql = pstrdup(str->data);

View File

@ -1,6 +1,6 @@
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.50 2002/07/31 17:19:49 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.51 2002/08/02 18:15:04 tgl Exp $
-->
<chapter id="catalogs">
@ -810,6 +810,17 @@
</entry>
</row>
<row>
<entry>attisdropped</entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>
This column has been dropped and is no longer valid. A dropped
column is still physically present in the table, but is
ignored by the parser and so cannot be accessed via SQL.
</entry>
</row>
</tbody>
</tgroup>
</table>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.47 2002/07/31 17:19:50 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.48 2002/08/02 18:15:04 tgl Exp $
PostgreSQL documentation
-->
@ -23,6 +23,8 @@ PostgreSQL documentation
<synopsis>
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
ADD [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> <replaceable class="PARAMETER">type</replaceable> [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
DROP [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> [ RESTRICT | CASCADE ]
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> { SET DEFAULT <replaceable class="PARAMETER">value</replaceable> | DROP DEFAULT }
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
@ -126,6 +128,26 @@ ALTER TABLE <replaceable class="PARAMETER">table</replaceable>
</listitem>
</varlistentry>
<varlistentry>
<term>CASCADE</term>
<listitem>
<para>
Automatically drop objects that depend on the dropped column
or constraint (for example, views referencing the column).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>RESTRICT</term>
<listitem>
<para>
Refuse to drop the column or constraint if there are any dependent
objects. This is the default behavior.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
@ -186,6 +208,19 @@ ALTER TABLE <replaceable class="PARAMETER">table</replaceable>
</listitem>
</varlistentry>
<varlistentry>
<term>DROP COLUMN</term>
<listitem>
<para>
This form drops a column from a table. Note that indexes and
table constraints involving the column will be automatically
dropped as well. You will need to say <literal>CASCADE</> if
anything outside the table depends on the column --- for example,
foreign key references, views, etc.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>SET/DROP DEFAULT</term>
<listitem>
@ -317,6 +352,22 @@ ALTER TABLE <replaceable class="PARAMETER">table</replaceable>
form after you've entered non-null values for the column in all rows.
</para>
<para>
The <literal>DROP COLUMN</literal> command does not physically remove
the column, but simply makes it invisible to SQL operations. Subsequent
inserts and updates of the table will store a NULL for the column.
Thus, dropping a column is quick but it will not immediately reduce the
on-disk size of your table, as the space occupied
by the dropped column is not reclaimed. The space will be
reclaimed over time as existing rows are updated.
To reclaim the space at once, do a dummy <command>UPDATE</> of all rows
and then vacuum, as in:
<programlisting>
UPDATE table SET col = col;
VACUUM FULL table;
</programlisting>
</para>
<para>
Changing any part of the schema of a system
catalog is not permitted.
@ -342,6 +393,13 @@ ALTER TABLE distributors ADD COLUMN address VARCHAR(30);
</programlisting>
</para>
<para>
To drop a column from a table:
<programlisting>
ALTER TABLE distributors DROP COLUMN address RESTRICT;
</programlisting>
</para>
<para>
To rename an existing column:
<programlisting>
@ -420,38 +478,6 @@ ALTER TABLE distributors ADD PRIMARY KEY (dist_id);
The <literal>ALTER COLUMN</literal> form is in full compliance.
</para>
<para>
SQL92 specifies some additional capabilities for <command>ALTER TABLE</command>
statement which are not yet directly supported by <productname>PostgreSQL</productname>:
<variablelist>
<varlistentry>
<term>
<synopsis>
ALTER TABLE <replaceable class="PARAMETER">table</replaceable> DROP [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> { RESTRICT | CASCADE }
</synopsis>
</term>
<listitem>
<para>
Removes a column from a table.
Currently, to remove an existing column the table must be
recreated and reloaded:
<programlisting>
CREATE TABLE temp AS SELECT did, city FROM distributors;
DROP TABLE distributors;
CREATE TABLE distributors (
did DECIMAL(3) DEFAULT 1,
name VARCHAR(40) NOT NULL
);
INSERT INTO distributors SELECT * FROM temp;
DROP TABLE temp;
</programlisting>
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
The clauses to rename tables, columns, indexes, and sequences are
<productname>PostgreSQL</productname> extensions from SQL92.

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/copy.sgml,v 1.34 2002/07/30 16:55:05 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/copy.sgml,v 1.35 2002/08/02 18:15:04 tgl Exp $
PostgreSQL documentation
-->
@ -21,16 +21,14 @@ PostgreSQL documentation
<date>1999-12-11</date>
</refsynopsisdivinfo>
<synopsis>
COPY <replaceable class="parameter">table</replaceable>
[ ( <replaceable class="parameter">column</replaceable> [, ...] ) ]
COPY <replaceable class="parameter">table</replaceable> [ ( <replaceable class="parameter">column</replaceable> [, ...] ) ]
FROM { '<replaceable class="parameter">filename</replaceable>' | <filename>stdin</filename> }
[ [ WITH ]
[ BINARY ]
[ OIDS ]
[ DELIMITER [ AS ] '<replaceable class="parameter">delimiter</replaceable>' ]
[ NULL [ AS ] '<replaceable class="parameter">null string</replaceable>' ] ]
COPY <replaceable class="parameter">table</replaceable>
[ ( <replaceable class="parameter">column</replaceable> [, ...] ) ]
COPY <replaceable class="parameter">table</replaceable> [ ( <replaceable class="parameter">column</replaceable> [, ...] ) ]
TO { '<replaceable class="parameter">filename</replaceable>' | <filename>stdout</filename> }
[ [ WITH ]
[ BINARY ]
@ -201,10 +199,10 @@ ERROR: <replaceable>reason</replaceable>
<para>
If a list of columns is specified, <command>COPY</command> will
only copy the data in the specified columns to or from the table.
If there are any columns in the table that are not in the table,
<command>COPY FROM</command> will insert the default value for
that column.
only copy the data in the specified columns to or from the file.
If there are any columns in the table that are not in the file,
<command>COPY FROM</command> will insert the default values for
those columns.
</para>
<para>
@ -266,8 +264,8 @@ ERROR: <replaceable>reason</replaceable>
</para>
<para>
<command>COPY FROM</command> will invoke any triggers or check
constraints. However, it will not invoke rules.
<command>COPY FROM</command> will invoke any triggers and check
constraints on the destination table. However, it will not invoke rules.
</para>
<para>
@ -330,12 +328,9 @@ ERROR: <replaceable>reason</replaceable>
The attribute values themselves are strings generated by the
output function, or acceptable to the input function, of each
attribute's data type. The specified null-value string is used in
place of attributes that are NULL. When using <command>COPY
FROM</command> without a column list, each row of the input file
must contain data for each attribute in the table: no missing data
is allowed. Similarly, <command>COPY FROM</command> will raise
an error if it encounters any data in the input file that would
not be inserted into the table: extra data is not allowed.
place of attributes that are NULL.
<command>COPY FROM</command> will raise an error if any line of the
input file contains more or fewer columns than are expected.
</para>
<para>
If OIDS is specified, the OID is read or written as the first column,

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.144 2002/07/29 22:14:10 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.145 2002/08/02 18:15:04 tgl Exp $
-->
<appendix id="release">
@ -24,6 +24,8 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters.
-->
<literallayout><![CDATA[
COPY accepts a list of columns to copy
ALTER TABLE DROP COLUMN
CREATE OPERATOR CLASS/DROP OPERATOR CLASS
CREATE CAST/DROP CAST
Sequences created by SERIAL column definitions now auto-drop with the column

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.82 2002/07/31 17:19:51 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.83 2002/08/02 18:15:04 tgl Exp $
*
* NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be
@ -111,7 +111,7 @@ CreateTupleDescCopy(TupleDesc tupdesc)
for (i = 0; i < desc->natts; i++)
{
desc->attrs[i] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);
memmove(desc->attrs[i],
memcpy(desc->attrs[i],
tupdesc->attrs[i],
ATTRIBUTE_TUPLE_SIZE);
desc->attrs[i]->attnotnull = false;
@ -146,7 +146,7 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
for (i = 0; i < desc->natts; i++)
{
desc->attrs[i] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);
memmove(desc->attrs[i],
memcpy(desc->attrs[i],
tupdesc->attrs[i],
ATTRIBUTE_TUPLE_SIZE);
}
@ -263,6 +263,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
return false;
if (attr1->attnotnull != attr2->attnotnull)
return false;
if (attr1->attisdropped != attr2->attisdropped)
return false;
}
if (tupdesc1->constr != NULL)
{
@ -385,6 +387,7 @@ TupleDescInitEntry(TupleDesc desc,
att->attnotnull = false;
att->atthasdef = false;
att->attisdropped = false;
tuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(oidtypeid),

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.133 2002/07/20 05:16:56 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.134 2002/08/02 18:15:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -522,19 +522,6 @@ boot_openrel(char *relname)
(char *) boot_reldesc->rd_att->attrs[i],
ATTRIBUTE_TUPLE_SIZE);
/* Some old pg_attribute tuples might not have attisset. */
/*
* If the attname is attisset, don't look for it - it may not be
* defined yet.
*/
if (namestrcmp(&attrtypes[i]->attname, "attisset") == 0)
attrtypes[i]->attisset =
get_attisset(RelationGetRelid(boot_reldesc),
NameStr(attrtypes[i]->attname));
else
attrtypes[i]->attisset = false;
{
Form_pg_attribute at = attrtypes[i];
@ -598,15 +585,19 @@ DefineAttr(char *name, char *type, int attnum)
closerel(relname);
}
typeoid = gettype(type);
if (attrtypes[attnum] == (Form_pg_attribute) NULL)
attrtypes[attnum] = AllocateAttribute();
MemSet(attrtypes[attnum], 0, ATTRIBUTE_TUPLE_SIZE);
namestrcpy(&attrtypes[attnum]->attname, name);
elog(DEBUG3, "column %s %s", NameStr(attrtypes[attnum]->attname), type);
attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
typeoid = gettype(type);
if (Typ != (struct typmap **) NULL)
{
attrtypes[attnum]->atttypid = Ap->am_oid;
namestrcpy(&attrtypes[attnum]->attname, name);
elog(DEBUG3, "column %s %s", NameStr(attrtypes[attnum]->attname), type);
attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
attlen = attrtypes[attnum]->attlen = Ap->am_typ.typlen;
attrtypes[attnum]->attbyval = Ap->am_typ.typbyval;
attrtypes[attnum]->attstorage = Ap->am_typ.typstorage;
@ -615,9 +606,6 @@ DefineAttr(char *name, char *type, int attnum)
else
{
attrtypes[attnum]->atttypid = Procid[typeoid].oid;
namestrcpy(&attrtypes[attnum]->attname, name);
elog(DEBUG3, "column %s %s", NameStr(attrtypes[attnum]->attname), type);
attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
attlen = attrtypes[attnum]->attlen = Procid[typeoid].len;
/*
@ -656,6 +644,23 @@ DefineAttr(char *name, char *type, int attnum)
}
attrtypes[attnum]->attcacheoff = -1;
attrtypes[attnum]->atttypmod = -1;
/*
* Mark as "not null" if type is fixed-width and prior columns are too.
* This corresponds to case where column can be accessed directly via
* C struct declaration.
*/
if (attlen > 0)
{
int i;
for (i = 0; i < attnum; i++)
{
if (attrtypes[i]->attlen <= 0)
break;
}
if (i == attnum)
attrtypes[attnum]->attnotnull = true;
}
}
@ -896,8 +901,8 @@ gettype(char *type)
* AllocateAttribute
* ----------------
*/
static Form_pg_attribute /* XXX */
AllocateAttribute()
static Form_pg_attribute
AllocateAttribute(void)
{
Form_pg_attribute attribute = (Form_pg_attribute) malloc(ATTRIBUTE_TUPLE_SIZE);

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.7 2002/07/29 22:14:10 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.8 2002/08/02 18:15:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -567,7 +567,8 @@ doDeletion(const ObjectAddress *object)
else
{
if (object->objectSubId != 0)
elog(ERROR, "DROP COLUMN not implemented yet");
RemoveAttributeById(object->objectId,
object->objectSubId);
else
heap_drop_with_catalog(object->objectId);
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.214 2002/07/31 17:19:51 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.215 2002/08/02 18:15:05 tgl Exp $
*
*
* INTERFACE ROUTINES
@ -97,37 +97,37 @@ static void RemoveStatistics(Relation rel);
static FormData_pg_attribute a1 = {
0, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData),
SelfItemPointerAttributeNumber, 0, -1, -1,
false, 'p', false, 'i', true, false
false, 'p', false, 'i', true, false, false
};
static FormData_pg_attribute a2 = {
0, {"oid"}, OIDOID, 0, sizeof(Oid),
ObjectIdAttributeNumber, 0, -1, -1,
true, 'p', false, 'i', true, false
true, 'p', false, 'i', true, false, false
};
static FormData_pg_attribute a3 = {
0, {"xmin"}, XIDOID, 0, sizeof(TransactionId),
MinTransactionIdAttributeNumber, 0, -1, -1,
true, 'p', false, 'i', true, false
true, 'p', false, 'i', true, false, false
};
static FormData_pg_attribute a4 = {
0, {"cmin"}, CIDOID, 0, sizeof(CommandId),
MinCommandIdAttributeNumber, 0, -1, -1,
true, 'p', false, 'i', true, false
true, 'p', false, 'i', true, false, false
};
static FormData_pg_attribute a5 = {
0, {"xmax"}, XIDOID, 0, sizeof(TransactionId),
MaxTransactionIdAttributeNumber, 0, -1, -1,
true, 'p', false, 'i', true, false
true, 'p', false, 'i', true, false, false
};
static FormData_pg_attribute a6 = {
0, {"cmax"}, CIDOID, 0, sizeof(CommandId),
MaxCommandIdAttributeNumber, 0, -1, -1,
true, 'p', false, 'i', true, false
true, 'p', false, 'i', true, false, false
};
/*
@ -139,7 +139,7 @@ static FormData_pg_attribute a6 = {
static FormData_pg_attribute a7 = {
0, {"tableoid"}, OIDOID, 0, sizeof(Oid),
TableOidAttributeNumber, 0, -1, -1,
true, 'p', false, 'i', true, false
true, 'p', false, 'i', true, false, false
};
static Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
@ -892,6 +892,78 @@ DeleteAttributeTuples(Oid relid)
heap_close(attrel, RowExclusiveLock);
}
/*
* RemoveAttributeById
*
* This is the guts of ALTER TABLE DROP COLUMN: actually mark the attribute
* deleted in pg_attribute. (Everything else needed, such as getting rid
* of any pg_attrdef entry, is handled by dependency.c.)
*/
void
RemoveAttributeById(Oid relid, AttrNumber attnum)
{
Relation rel;
Relation attr_rel;
HeapTuple tuple;
Form_pg_attribute attStruct;
char newattname[NAMEDATALEN];
/*
* Grab an exclusive lock on the target table, which we will NOT
* release until end of transaction. (In the simple case where
* we are directly dropping this column, AlterTableDropColumn already
* did this ... but when cascading from a drop of some other object,
* we may not have any lock.)
*/
rel = heap_open(relid, AccessExclusiveLock);
attr_rel = heap_openr(AttributeRelationName, RowExclusiveLock);
tuple = SearchSysCacheCopy(ATTNUM,
ObjectIdGetDatum(relid),
Int16GetDatum(attnum),
0, 0);
if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
elog(ERROR, "RemoveAttributeById: Failed to find attribute %d in relation %u",
attnum, relid);
attStruct = (Form_pg_attribute) GETSTRUCT(tuple);
/* Mark the attribute as dropped */
attStruct->attisdropped = true;
/* Remove any NOT NULL constraint the column may have */
attStruct->attnotnull = false;
/* We don't want to keep stats for it anymore */
attStruct->attstattarget = 0;
/* Change the column name to something that isn't likely to conflict */
snprintf(newattname, NAMEDATALEN, "........pg.dropped.%d........", attnum);
namestrcpy(&(attStruct->attname), newattname);
simple_heap_update(attr_rel, &tuple->t_self, tuple);
/* keep the system catalog indices current */
if (RelationGetForm(attr_rel)->relhasindex)
{
Relation idescs[Num_pg_attr_indices];
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_attr_indices, attr_rel, tuple);
CatalogCloseIndices(Num_pg_attr_indices, idescs);
}
/*
* Because updating the pg_attribute row will trigger a relcache flush
* for the target relation, we need not do anything else to notify
* other backends of the change.
*/
heap_close(attr_rel, RowExclusiveLock);
heap_close(rel, NoLock);
}
/*
* RemoveAttrDefault
*

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.81 2002/07/24 19:11:09 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.82 2002/08/02 18:15:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -327,9 +327,9 @@ checkretval(Oid rettype, List *queryTreeList)
Oid typerelid;
Oid restype;
Relation reln;
Oid relid;
int relnatts;
int i;
int relnatts; /* physical number of columns in rel */
int rellogcols; /* # of nondeleted columns in rel */
int colindex; /* physical column index */
/* guard against empty function body; OK only if no return type */
if (queryTreeList == NIL)
@ -404,42 +404,55 @@ checkretval(Oid rettype, List *queryTreeList)
/*
* By here, the procedure returns a tuple or set of tuples. This part
* of the typechecking is a hack. We look up the relation that is the
* declared return type, and be sure that attributes 1 .. n in the
* target list match the declared types.
* declared return type, and scan the non-deleted attributes to ensure
* that they match the datatypes of the non-resjunk columns.
*/
reln = heap_open(typerelid, AccessShareLock);
relid = reln->rd_id;
relnatts = reln->rd_rel->relnatts;
rellogcols = 0; /* we'll count nondeleted cols as we go */
colindex = 0;
if (tlistlen != relnatts)
elog(ERROR, "function declared to return %s does not SELECT the right number of columns (%d)",
format_type_be(rettype), relnatts);
/* expect attributes 1 .. n in order */
i = 0;
foreach(tlistitem, tlist)
{
TargetEntry *tle = (TargetEntry *) lfirst(tlistitem);
Form_pg_attribute attr;
Oid tletype;
Oid atttype;
if (tle->resdom->resjunk)
continue;
do {
colindex++;
if (colindex > relnatts)
elog(ERROR, "function declared to return %s does not SELECT the right number of columns (%d)",
format_type_be(rettype), rellogcols);
attr = reln->rd_att->attrs[colindex - 1];
} while (attr->attisdropped);
rellogcols++;
tletype = exprType(tle->expr);
atttype = reln->rd_att->attrs[i]->atttypid;
atttype = attr->atttypid;
if (!IsBinaryCompatible(tletype, atttype))
elog(ERROR, "function declared to return %s returns %s instead of %s at column %d",
format_type_be(rettype),
format_type_be(tletype),
format_type_be(atttype),
i + 1);
i++;
rellogcols);
}
/* this shouldn't happen, but let's just check... */
if (i != relnatts)
for (;;)
{
colindex++;
if (colindex > relnatts)
break;
if (!reln->rd_att->attrs[colindex - 1]->attisdropped)
rellogcols++;
}
if (tlistlen != rellogcols)
elog(ERROR, "function declared to return %s does not SELECT the right number of columns (%d)",
format_type_be(rettype), relnatts);
format_type_be(rettype), rellogcols);
heap_close(reln, AccessShareLock);
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.39 2002/07/31 17:19:51 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.40 2002/08/02 18:15:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -27,6 +27,7 @@
#include "commands/vacuum.h"
#include "miscadmin.h"
#include "parser/parse_oper.h"
#include "parser/parse_relation.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
@ -147,7 +148,6 @@ void
analyze_rel(Oid relid, VacuumStmt *vacstmt)
{
Relation onerel;
Form_pg_attribute *attr;
int attr_cnt,
tcnt,
i;
@ -234,9 +234,6 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
*
* Note that system attributes are never analyzed.
*/
attr = onerel->rd_att->attrs;
attr_cnt = onerel->rd_att->natts;
if (vacstmt->va_cols != NIL)
{
List *le;
@ -248,15 +245,8 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
{
char *col = strVal(lfirst(le));
for (i = 0; i < attr_cnt; i++)
{
if (namestrcmp(&(attr[i]->attname), col) == 0)
break;
}
if (i >= attr_cnt)
elog(ERROR, "ANALYZE: there is no attribute %s in %s",
col, RelationGetRelationName(onerel));
vacattrstats[tcnt] = examine_attribute(onerel, i + 1);
i = attnameAttNum(onerel, col, false);
vacattrstats[tcnt] = examine_attribute(onerel, i);
if (vacattrstats[tcnt] != NULL)
tcnt++;
}
@ -264,12 +254,13 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
}
else
{
attr_cnt = onerel->rd_att->natts;
vacattrstats = (VacAttrStats **) palloc(attr_cnt *
sizeof(VacAttrStats *));
tcnt = 0;
for (i = 0; i < attr_cnt; i++)
for (i = 1; i <= attr_cnt; i++)
{
vacattrstats[tcnt] = examine_attribute(onerel, i + 1);
vacattrstats[tcnt] = examine_attribute(onerel, i);
if (vacattrstats[tcnt] != NULL)
tcnt++;
}
@ -388,6 +379,10 @@ examine_attribute(Relation onerel, int attnum)
Oid ltopr = InvalidOid;
VacAttrStats *stats;
/* Don't analyze dropped columns */
if (attr->attisdropped)
return NULL;
/* Don't analyze column if user has specified not to */
if (attr->attstattarget == 0)
return NULL;

View File

@ -7,7 +7,7 @@
* Copyright (c) 1996-2001, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.53 2002/07/29 23:46:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.54 2002/08/02 18:15:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -382,8 +382,8 @@ CommentAttribute(List *qualname, char *comment)
attnum = get_attnum(RelationGetRelid(relation), attrname);
if (attnum == InvalidAttrNumber)
elog(ERROR, "\"%s\" is not an attribute of class \"%s\"",
attrname, RelationGetRelationName(relation));
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
RelationGetRelationName(relation), attrname);
/* Create the comment using the relation's oid */

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.161 2002/07/30 16:55:06 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.162 2002/08/02 18:15:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -31,6 +31,7 @@
#include "rewrite/rewriteHandler.h"
#include "libpq/libpq.h"
#include "miscadmin.h"
#include "parser/parse_relation.h"
#include "tcop/pquery.h"
#include "tcop/tcopprot.h"
#include "utils/acl.h"
@ -53,13 +54,15 @@ typedef enum CopyReadResult
} CopyReadResult;
/* non-export function prototypes */
static void CopyTo(Relation rel, List *attlist, bool binary, bool oids, FILE *fp, char *delim, char *null_print);
static void CopyFrom(Relation rel, List *attlist, bool binary, bool oids, FILE *fp, char *delim, char *null_print);
static void CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
FILE *fp, char *delim, char *null_print);
static void CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
FILE *fp, char *delim, char *null_print);
static Oid GetInputFunction(Oid type);
static Oid GetTypeElement(Oid type);
static char *CopyReadAttribute(FILE *fp, const char *delim, CopyReadResult *result);
static void CopyAttributeOut(FILE *fp, char *string, char *delim);
static void CopyCheckAttlist(Relation rel, List *attlist);
static List *CopyGetAttnums(Relation rel, List *attnamelist);
static const char BinarySignature[12] = "PGBCOPY\n\377\r\n\0";
@ -275,7 +278,8 @@ DoCopy(const CopyStmt *stmt)
bool is_from = stmt->is_from;
bool pipe = (stmt->filename == NULL);
List *option;
List *attlist = stmt->attlist;
List *attnamelist = stmt->attlist;
List *attnumlist;
bool binary = false;
bool oids = false;
char *delim = NULL;
@ -373,6 +377,11 @@ DoCopy(const CopyStmt *stmt)
elog(ERROR, "COPY: table \"%s\" does not have OIDs",
RelationGetRelationName(rel));
/*
* Generate or convert list of attributes to process
*/
attnumlist = CopyGetAttnums(rel, attnamelist);
/*
* Set up variables to avoid per-attribute overhead.
*/
@ -382,26 +391,6 @@ DoCopy(const CopyStmt *stmt)
server_encoding = GetDatabaseEncoding();
#endif
if (attlist == NIL)
{
/* get list of attributes in the relation */
TupleDesc desc = RelationGetDescr(rel);
int i;
for (i = 0; i < desc->natts; ++i)
{
Ident *id = makeNode(Ident);
id->name = NameStr(desc->attrs[i]->attname);
attlist = lappend(attlist,id);
}
}
else
{
if (binary)
elog(ERROR,"COPY: BINARY format cannot be used with specific column list");
CopyCheckAttlist(rel, attlist);
}
if (is_from)
{ /* copy from file to database */
if (rel->rd_rel->relkind != RELKIND_RELATION)
@ -442,10 +431,10 @@ DoCopy(const CopyStmt *stmt)
if (S_ISDIR(st.st_mode))
{
FreeFile(fp);
elog(ERROR, "COPY: %s is a directory.", filename);
elog(ERROR, "COPY: %s is a directory", filename);
}
}
CopyFrom(rel, attlist, binary, oids, fp, delim, null_print);
CopyFrom(rel, attnumlist, binary, oids, fp, delim, null_print);
}
else
{ /* copy from database to file */
@ -483,7 +472,7 @@ DoCopy(const CopyStmt *stmt)
*/
if (filename[0] != '/')
elog(ERROR, "Relative path not allowed for server side"
" COPY command.");
" COPY command");
oumask = umask((mode_t) 022);
fp = AllocateFile(filename, PG_BINARY_W);
@ -498,10 +487,10 @@ DoCopy(const CopyStmt *stmt)
if (S_ISDIR(st.st_mode))
{
FreeFile(fp);
elog(ERROR, "COPY: %s is a directory.", filename);
elog(ERROR, "COPY: %s is a directory", filename);
}
}
CopyTo(rel, attlist, binary, oids, fp, delim, null_print);
CopyTo(rel, attnumlist, binary, oids, fp, delim, null_print);
}
if (!pipe)
@ -529,14 +518,14 @@ DoCopy(const CopyStmt *stmt)
* Copy from relation TO file.
*/
static void
CopyTo(Relation rel, List *attlist, bool binary, bool oids,
CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
FILE *fp, char *delim, char *null_print)
{
HeapTuple tuple;
TupleDesc tupDesc;
HeapScanDesc scandesc;
int attr_count,
i;
int num_phys_attrs;
int attr_count;
Form_pg_attribute *attr;
FmgrInfo *out_functions;
Oid *elements;
@ -544,48 +533,33 @@ CopyTo(Relation rel, List *attlist, bool binary, bool oids,
int16 fld_size;
char *string;
Snapshot mySnapshot;
int copy_attr_count;
int *attmap;
int p = 0;
List *cur;
tupDesc = rel->rd_att;
attr_count = rel->rd_att->natts;
attr = rel->rd_att->attrs;
copy_attr_count = length(attlist);
attmap = (int *) palloc(copy_attr_count * sizeof(int));
foreach(cur, attlist)
{
const char *currAtt = strVal(lfirst(cur));
for (i = 0; i < attr_count; i++)
{
if (namestrcmp(&attr[i]->attname, currAtt) == 0)
{
attmap[p++] = i;
continue;
}
}
}
attr = tupDesc->attrs;
num_phys_attrs = tupDesc->natts;
attr_count = length(attnumlist);
/*
* Get info about the columns we need to process.
*
* For binary copy we really only need isvarlena, but compute it
* all...
*/
out_functions = (FmgrInfo *) palloc(attr_count * sizeof(FmgrInfo));
elements = (Oid *) palloc(attr_count * sizeof(Oid));
isvarlena = (bool *) palloc(attr_count * sizeof(bool));
for (i = 0; i < attr_count; i++)
out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
elements = (Oid *) palloc(num_phys_attrs * sizeof(Oid));
isvarlena = (bool *) palloc(num_phys_attrs * sizeof(bool));
foreach(cur, attnumlist)
{
int attnum = lfirsti(cur);
Oid out_func_oid;
if (!getTypeOutputInfo(attr[i]->atttypid,
&out_func_oid, &elements[i], &isvarlena[i]))
if (!getTypeOutputInfo(attr[attnum-1]->atttypid,
&out_func_oid, &elements[attnum-1],
&isvarlena[attnum-1]))
elog(ERROR, "COPY: couldn't lookup info for type %u",
attr[i]->atttypid);
fmgr_info(out_func_oid, &out_functions[i]);
attr[attnum-1]->atttypid);
fmgr_info(out_func_oid, &out_functions[attnum-1]);
}
if (binary)
@ -650,14 +624,14 @@ CopyTo(Relation rel, List *attlist, bool binary, bool oids,
}
}
for (i = 0; i < copy_attr_count; i++)
foreach(cur, attnumlist)
{
int attnum = lfirsti(cur);
Datum origvalue,
value;
bool isnull;
int mi = attmap[i];
origvalue = heap_getattr(tuple, mi + 1, tupDesc, &isnull);
origvalue = heap_getattr(tuple, attnum, tupDesc, &isnull);
if (!binary)
{
@ -686,25 +660,25 @@ CopyTo(Relation rel, List *attlist, bool binary, bool oids,
* (or for binary case, becase we must output untoasted
* value).
*/
if (isvarlena[mi])
if (isvarlena[attnum-1])
value = PointerGetDatum(PG_DETOAST_DATUM(origvalue));
else
value = origvalue;
if (!binary)
{
string = DatumGetCString(FunctionCall3(&out_functions[mi],
string = DatumGetCString(FunctionCall3(&out_functions[attnum-1],
value,
ObjectIdGetDatum(elements[mi]),
Int32GetDatum(attr[mi]->atttypmod)));
ObjectIdGetDatum(elements[attnum-1]),
Int32GetDatum(attr[attnum-1]->atttypmod)));
CopyAttributeOut(fp, string, delim);
pfree(string);
}
else
{
fld_size = attr[mi]->attlen;
fld_size = attr[attnum-1]->attlen;
CopySendData(&fld_size, sizeof(int16), fp);
if (isvarlena[mi])
if (isvarlena[attnum-1])
{
/* varlena */
Assert(fld_size == -1);
@ -712,7 +686,7 @@ CopyTo(Relation rel, List *attlist, bool binary, bool oids,
VARSIZE(value),
fp);
}
else if (!attr[mi]->attbyval)
else if (!attr[attnum-1]->attbyval)
{
/* fixed-length pass-by-reference */
Assert(fld_size > 0);
@ -767,36 +741,36 @@ CopyTo(Relation rel, List *attlist, bool binary, bool oids,
* Copy FROM file to relation.
*/
static void
CopyFrom(Relation rel, List *attlist, bool binary, bool oids,
CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
FILE *fp, char *delim, char *null_print)
{
HeapTuple tuple;
TupleDesc tupDesc;
Form_pg_attribute *attr;
AttrNumber attr_count, copy_attr_count, def_attr_count;
AttrNumber num_phys_attrs, attr_count, num_defaults;
FmgrInfo *in_functions;
Oid *elements;
int i;
List *cur;
Oid in_func_oid;
Datum *values;
char *nulls;
int done = 0;
bool done = false;
ResultRelInfo *resultRelInfo;
EState *estate = CreateExecutorState(); /* for ExecConstraints() */
TupleTable tupleTable;
TupleTableSlot *slot;
bool file_has_oids;
int *attmap = NULL;
int *defmap = NULL;
Node **defexprs = NULL; /* array of default att expressions */
int *defmap;
Node **defexprs; /* array of default att expressions */
ExprContext *econtext; /* used for ExecEvalExpr for default atts */
ExprDoneCond isdone;
MemoryContext oldcontext = CurrentMemoryContext;
tupDesc = RelationGetDescr(rel);
attr = tupDesc->attrs;
attr_count = tupDesc->natts;
copy_attr_count = length(attlist);
def_attr_count = 0;
num_phys_attrs = tupDesc->natts;
attr_count = length(attnumlist);
num_defaults = 0;
/*
* We need a ResultRelInfo so we can use the regular executor's
@ -819,50 +793,40 @@ CopyFrom(Relation rel, List *attlist, bool binary, bool oids,
slot = ExecAllocTableSlot(tupleTable);
ExecSetSlotDescriptor(slot, tupDesc, false);
if (!binary)
/*
* pick up the input function and default expression (if any) for
* each attribute in the relation. (We don't actually use the
* input function if it's a binary copy.)
*/
defmap = (int *) palloc(sizeof(int) * num_phys_attrs);
defexprs = (Node **) palloc(sizeof(Node *) * num_phys_attrs);
in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo));
elements = (Oid *) palloc(num_phys_attrs * sizeof(Oid));
for (i = 0; i < num_phys_attrs; i++)
{
/*
* pick up the input function and default expression (if any) for
* each attribute in the relation.
*/
attmap = (int *) palloc(sizeof(int) * attr_count);
defmap = (int *) palloc(sizeof(int) * attr_count);
defexprs = (Node **) palloc(sizeof(Node *) * attr_count);
in_functions = (FmgrInfo *) palloc(attr_count * sizeof(FmgrInfo));
elements = (Oid *) palloc(attr_count * sizeof(Oid));
for (i = 0; i < attr_count; i++)
/* We don't need info for dropped attributes */
if (attr[i]->attisdropped)
continue;
in_func_oid = (Oid) GetInputFunction(attr[i]->atttypid);
fmgr_info(in_func_oid, &in_functions[i]);
elements[i] = GetTypeElement(attr[i]->atttypid);
/* if column not specified, use default value if one exists */
if (!intMember(i + 1, attnumlist))
{
List *l;
int p = 0;
bool specified = false;
in_func_oid = (Oid) GetInputFunction(attr[i]->atttypid);
fmgr_info(in_func_oid, &in_functions[i]);
elements[i] = GetTypeElement(attr[i]->atttypid);
foreach(l, attlist)
defexprs[num_defaults] = build_column_default(rel, i + 1);
if (defexprs[num_defaults] != NULL)
{
if (namestrcmp(&attr[i]->attname, strVal(lfirst(l))) == 0)
{
attmap[p] = i;
specified = true;
continue;
}
p++;
}
/* if column not specified, use default value if one exists */
if (! specified)
{
defexprs[def_attr_count] = build_column_default(rel, i + 1);
if (defexprs[def_attr_count] != NULL)
{
defmap[def_attr_count] = i;
def_attr_count++;
}
defmap[num_defaults] = i;
num_defaults++;
}
}
}
if (!binary)
{
file_has_oids = oids; /* must rely on user to tell us this... */
}
else
@ -898,13 +862,10 @@ CopyFrom(Relation rel, List *attlist, bool binary, bool oids,
if (CopyGetEof(fp))
elog(ERROR, "COPY BINARY: bogus file header (wrong length)");
}
in_functions = NULL;
elements = NULL;
}
values = (Datum *) palloc(attr_count * sizeof(Datum));
nulls = (char *) palloc(attr_count * sizeof(char));
values = (Datum *) palloc(num_phys_attrs * sizeof(Datum));
nulls = (char *) palloc(num_phys_attrs * sizeof(char));
copy_lineno = 0;
fe_eof = false;
@ -914,58 +875,77 @@ CopyFrom(Relation rel, List *attlist, bool binary, bool oids,
while (!done)
{
bool skip_tuple;
Oid loaded_oid;
Oid loaded_oid = InvalidOid;
CHECK_FOR_INTERRUPTS();
copy_lineno++;
/* Reset the per-output-tuple exprcontext */
/* Reset the per-tuple exprcontext */
ResetPerTupleExprContext(estate);
/* Switch to and reset per-tuple memory context, too */
MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
MemoryContextReset(CurrentMemoryContext);
/* Initialize all values for row to NULL */
MemSet(values, 0, attr_count * sizeof(Datum));
MemSet(nulls, 'n', attr_count * sizeof(char));
MemSet(values, 0, num_phys_attrs * sizeof(Datum));
MemSet(nulls, 'n', num_phys_attrs * sizeof(char));
if (!binary)
{
CopyReadResult result;
CopyReadResult result = NORMAL_ATTR;
char *string;
if (file_has_oids)
{
string = CopyReadAttribute(fp, delim, &result);
if (result == END_OF_FILE)
done = 1;
else if (string == NULL || strcmp(string, null_print) == 0)
elog(ERROR, "COPY TEXT: NULL Oid");
if (result == END_OF_FILE && *string == '\0')
{
/* EOF at start of line: all is well */
done = true;
break;
}
if (strcmp(string, null_print) == 0)
elog(ERROR, "NULL Oid");
else
{
loaded_oid = DatumGetObjectId(DirectFunctionCall1(oidin,
CStringGetDatum(string)));
if (loaded_oid == InvalidOid)
elog(ERROR, "COPY TEXT: Invalid Oid");
elog(ERROR, "Invalid Oid");
}
}
/*
* here, we only try to read as many attributes as
* were specified.
/*
* Loop to read the user attributes on the line.
*/
for (i = 0; i < copy_attr_count && !done; i++)
foreach(cur, attnumlist)
{
int m = attmap[i];
int attnum = lfirsti(cur);
int m = attnum - 1;
/*
* If prior attr on this line was ended by newline or EOF,
* complain.
*/
if (result != NORMAL_ATTR)
elog(ERROR, "Missing data for column \"%s\"",
NameStr(attr[m]->attname));
string = CopyReadAttribute(fp, delim, &result);
/* If we got an end-of-line before we expected, bail out */
if (result == END_OF_LINE && i < (copy_attr_count - 1))
elog(ERROR, "COPY TEXT: Missing data for attribute %d", i + 1);
if (result == END_OF_FILE && *string == '\0' &&
cur == attnumlist && !file_has_oids)
{
/* EOF at start of line: all is well */
done = true;
break; /* out of per-attr loop */
}
if (result == END_OF_FILE)
done = 1;
else if (strcmp(string, null_print) == 0)
if (strcmp(string, null_print) == 0)
{
/* we read an SQL NULL, no need to do anything */
}
@ -979,124 +959,149 @@ CopyFrom(Relation rel, List *attlist, bool binary, bool oids,
}
}
if (result == NORMAL_ATTR && !done)
elog(ERROR, "COPY TEXT: Extra data encountered");
if (done)
break; /* out of per-row loop */
/* Complain if there are more fields on the input line */
if (result == NORMAL_ATTR)
elog(ERROR, "Extra data after last expected column");
/*
* as above, we only try a default lookup if one is
* known to be available
* If we got some data on the line, but it was ended by EOF,
* process the line normally but set flag to exit the loop
* when we return to the top.
*/
for (i = 0; i < def_attr_count && !done; i++)
{
bool isnull;
values[defmap[i]] = ExecEvalExpr(defexprs[i], econtext,
&isnull, &isdone);
if (! isnull)
nulls[defmap[i]] = ' ';
}
if (result == END_OF_FILE)
done = true;
}
else
{ /* binary */
{
/* binary */
int16 fld_count,
fld_size;
CopyGetData(&fld_count, sizeof(int16), fp);
if (CopyGetEof(fp) || fld_count == -1)
done = 1;
else
{
if (fld_count <= 0 || fld_count > attr_count)
elog(ERROR, "COPY BINARY: tuple field count is %d, expected %d",
(int) fld_count, attr_count);
done = true;
break;
}
if (file_has_oids)
if (fld_count != attr_count)
elog(ERROR, "COPY BINARY: tuple field count is %d, expected %d",
(int) fld_count, attr_count);
if (file_has_oids)
{
CopyGetData(&fld_size, sizeof(int16), fp);
if (CopyGetEof(fp))
elog(ERROR, "COPY BINARY: unexpected EOF");
if (fld_size != (int16) sizeof(Oid))
elog(ERROR, "COPY BINARY: sizeof(Oid) is %d, expected %d",
(int) fld_size, (int) sizeof(Oid));
CopyGetData(&loaded_oid, sizeof(Oid), fp);
if (CopyGetEof(fp))
elog(ERROR, "COPY BINARY: unexpected EOF");
if (loaded_oid == InvalidOid)
elog(ERROR, "COPY BINARY: Invalid Oid");
}
i = 0;
foreach(cur, attnumlist)
{
int attnum = lfirsti(cur);
i++;
CopyGetData(&fld_size, sizeof(int16), fp);
if (CopyGetEof(fp))
elog(ERROR, "COPY BINARY: unexpected EOF");
if (fld_size == 0)
continue; /* it's NULL; nulls[attnum-1] already set */
if (fld_size != attr[attnum-1]->attlen)
elog(ERROR, "COPY BINARY: sizeof(field %d) is %d, expected %d",
i, (int) fld_size, (int) attr[attnum-1]->attlen);
if (fld_size == -1)
{
CopyGetData(&fld_size, sizeof(int16), fp);
/* varlena field */
int32 varlena_size;
Pointer varlena_ptr;
CopyGetData(&varlena_size, sizeof(int32), fp);
if (CopyGetEof(fp))
elog(ERROR, "COPY BINARY: unexpected EOF");
if (fld_size != (int16) sizeof(Oid))
elog(ERROR, "COPY BINARY: sizeof(Oid) is %d, expected %d",
(int) fld_size, (int) sizeof(Oid));
CopyGetData(&loaded_oid, sizeof(Oid), fp);
if (varlena_size < (int32) sizeof(int32))
elog(ERROR, "COPY BINARY: bogus varlena length");
varlena_ptr = (Pointer) palloc(varlena_size);
VARATT_SIZEP(varlena_ptr) = varlena_size;
CopyGetData(VARDATA(varlena_ptr),
varlena_size - sizeof(int32),
fp);
if (CopyGetEof(fp))
elog(ERROR, "COPY BINARY: unexpected EOF");
if (loaded_oid == InvalidOid)
elog(ERROR, "COPY BINARY: Invalid Oid");
values[attnum-1] = PointerGetDatum(varlena_ptr);
}
else if (!attr[attnum-1]->attbyval)
{
/* fixed-length pass-by-reference */
Pointer refval_ptr;
Assert(fld_size > 0);
refval_ptr = (Pointer) palloc(fld_size);
CopyGetData(refval_ptr, fld_size, fp);
if (CopyGetEof(fp))
elog(ERROR, "COPY BINARY: unexpected EOF");
values[attnum-1] = PointerGetDatum(refval_ptr);
}
else
{
/* pass-by-value */
Datum datumBuf;
/*
* We need this horsing around because we don't
* know how shorter data values are aligned within
* a Datum.
*/
Assert(fld_size > 0 && fld_size <= sizeof(Datum));
CopyGetData(&datumBuf, fld_size, fp);
if (CopyGetEof(fp))
elog(ERROR, "COPY BINARY: unexpected EOF");
values[attnum-1] = fetch_att(&datumBuf, true, fld_size);
}
for (i = 0; i < (int) fld_count; i++)
{
CopyGetData(&fld_size, sizeof(int16), fp);
if (CopyGetEof(fp))
elog(ERROR, "COPY BINARY: unexpected EOF");
if (fld_size == 0)
continue; /* it's NULL; nulls[i] already set */
if (fld_size != attr[i]->attlen)
elog(ERROR, "COPY BINARY: sizeof(field %d) is %d, expected %d",
i + 1, (int) fld_size, (int) attr[i]->attlen);
if (fld_size == -1)
{
/* varlena field */
int32 varlena_size;
Pointer varlena_ptr;
CopyGetData(&varlena_size, sizeof(int32), fp);
if (CopyGetEof(fp))
elog(ERROR, "COPY BINARY: unexpected EOF");
if (varlena_size < (int32) sizeof(int32))
elog(ERROR, "COPY BINARY: bogus varlena length");
varlena_ptr = (Pointer) palloc(varlena_size);
VARATT_SIZEP(varlena_ptr) = varlena_size;
CopyGetData(VARDATA(varlena_ptr),
varlena_size - sizeof(int32),
fp);
if (CopyGetEof(fp))
elog(ERROR, "COPY BINARY: unexpected EOF");
values[i] = PointerGetDatum(varlena_ptr);
}
else if (!attr[i]->attbyval)
{
/* fixed-length pass-by-reference */
Pointer refval_ptr;
Assert(fld_size > 0);
refval_ptr = (Pointer) palloc(fld_size);
CopyGetData(refval_ptr, fld_size, fp);
if (CopyGetEof(fp))
elog(ERROR, "COPY BINARY: unexpected EOF");
values[i] = PointerGetDatum(refval_ptr);
}
else
{
/* pass-by-value */
Datum datumBuf;
/*
* We need this horsing around because we don't
* know how shorter data values are aligned within
* a Datum.
*/
Assert(fld_size > 0 && fld_size <= sizeof(Datum));
CopyGetData(&datumBuf, fld_size, fp);
if (CopyGetEof(fp))
elog(ERROR, "COPY BINARY: unexpected EOF");
values[i] = fetch_att(&datumBuf, true, fld_size);
}
nulls[i] = ' ';
}
nulls[attnum-1] = ' ';
}
}
if (done)
break;
/*
* Now compute and insert any defaults available for the
* columns not provided by the input data. Anything not
* processed here or above will remain NULL.
*/
for (i = 0; i < num_defaults; i++)
{
bool isnull;
values[defmap[i]] = ExecEvalExpr(defexprs[i], econtext,
&isnull, NULL);
if (!isnull)
nulls[defmap[i]] = ' ';
}
/*
* And now we can form the input tuple.
*/
tuple = heap_formtuple(tupDesc, values, nulls);
if (oids && file_has_oids)
HeapTupleSetOid(tuple, loaded_oid);
/*
* Triggers and stuff need to be invoked in query context.
*/
MemoryContextSwitchTo(oldcontext);
skip_tuple = false;
/* BEFORE ROW INSERT Triggers */
@ -1118,6 +1123,7 @@ CopyFrom(Relation rel, List *attlist, bool binary, bool oids,
if (!skip_tuple)
{
/* Place tuple in tuple slot */
ExecStoreTuple(tuple, slot, InvalidBuffer, false);
/*
@ -1138,8 +1144,6 @@ CopyFrom(Relation rel, List *attlist, bool binary, bool oids,
if (resultRelInfo->ri_TrigDesc)
ExecARInsertTriggers(estate, resultRelInfo, tuple);
}
heap_freetuple(tuple);
}
/*
@ -1147,6 +1151,8 @@ CopyFrom(Relation rel, List *attlist, bool binary, bool oids,
*/
copy_lineno = 0;
MemoryContextSwitchTo(oldcontext);
pfree(values);
pfree(nulls);
@ -1197,12 +1203,11 @@ GetTypeElement(Oid type)
/*
* Read the value of a single attribute.
*
* Results are returned in the status indicator, as well as the
* return value. If a value was successfully read but there is
* more to read before EOL, NORMAL_ATTR is set and the value read
* is returned. If a value was read and we hit EOL, END_OF_LINE
* is set and the value read is returned. If we hit the EOF,
* END_OF_FILE is set and NULL is returned.
* *result is set to indicate what terminated the read:
* NORMAL_ATTR: column delimiter
* END_OF_LINE: newline
* END_OF_FILE: EOF indication
* In all cases, the string read up to the terminator is returned.
*
* Note: This function does not care about SQL NULL values -- it
* is the caller's responsibility to check if the returned string
@ -1215,8 +1220,7 @@ static char *
CopyReadAttribute(FILE *fp, const char *delim, CopyReadResult *result)
{
int c;
int delimc = (unsigned char)delim[0];
int delimc = (unsigned char) delim[0];
#ifdef MULTIBYTE
int mblen;
unsigned char s[2];
@ -1230,7 +1234,7 @@ CopyReadAttribute(FILE *fp, const char *delim, CopyReadResult *result)
attribute_buf.len = 0;
attribute_buf.data[0] = '\0';
/* set default */
/* set default status */
*result = NORMAL_ATTR;
for (;;)
@ -1239,7 +1243,7 @@ CopyReadAttribute(FILE *fp, const char *delim, CopyReadResult *result)
if (c == EOF)
{
*result = END_OF_FILE;
return NULL;
goto copy_eof;
}
if (c == '\n')
{
@ -1254,7 +1258,7 @@ CopyReadAttribute(FILE *fp, const char *delim, CopyReadResult *result)
if (c == EOF)
{
*result = END_OF_FILE;
return NULL;
goto copy_eof;
}
switch (c)
{
@ -1286,7 +1290,7 @@ CopyReadAttribute(FILE *fp, const char *delim, CopyReadResult *result)
if (c == EOF)
{
*result = END_OF_FILE;
return NULL;
goto copy_eof;
}
CopyDonePeek(fp, c, false /* put back */ );
}
@ -1296,7 +1300,7 @@ CopyReadAttribute(FILE *fp, const char *delim, CopyReadResult *result)
if (c == EOF)
{
*result = END_OF_FILE;
return NULL;
goto copy_eof;
}
CopyDonePeek(fp, c, false /* put back */ );
}
@ -1336,7 +1340,7 @@ CopyReadAttribute(FILE *fp, const char *delim, CopyReadResult *result)
if (c != '\n')
elog(ERROR, "CopyReadAttribute: end of record marker corrupted");
*result = END_OF_FILE;
return NULL;
goto copy_eof;
}
}
appendStringInfoCharMacro(&attribute_buf, c);
@ -1353,7 +1357,7 @@ CopyReadAttribute(FILE *fp, const char *delim, CopyReadResult *result)
if (c == EOF)
{
*result = END_OF_FILE;
return NULL;
goto copy_eof;
}
appendStringInfoCharMacro(&attribute_buf, c);
}
@ -1361,6 +1365,8 @@ CopyReadAttribute(FILE *fp, const char *delim, CopyReadResult *result)
#endif
}
copy_eof:
#ifdef MULTIBYTE
if (client_encoding != server_encoding)
{
@ -1468,50 +1474,51 @@ CopyAttributeOut(FILE *fp, char *server_string, char *delim)
}
/*
* CopyCheckAttlist: elog(ERROR,...) if the specified attlist
* is not valid for the Relation
* CopyGetAttnums - build an integer list of attnums to be copied
*
* The input attnamelist is either the user-specified column list,
* or NIL if there was none (in which case we want all the non-dropped
* columns).
*/
static void
CopyCheckAttlist(Relation rel, List *attlist)
static List *
CopyGetAttnums(Relation rel, List *attnamelist)
{
TupleDesc tupDesc;
int attr_count;
List *l;
List *attnums = NIL;
if (attlist == NIL)
return;
tupDesc = RelationGetDescr(rel);
Assert(tupDesc != NULL);
/*
* make sure there aren't more columns specified than are in the table
*/
attr_count = tupDesc->natts;
if (attr_count < length(attlist))
elog(ERROR, "COPY: Too many columns specified");
/*
* make sure no columns are specified that don't exist in the table
*/
foreach(l, attlist)
if (attnamelist == NIL)
{
char *colName = strVal(lfirst(l));
bool found = false;
int i;
/* Generate default column list */
TupleDesc tupDesc = RelationGetDescr(rel);
Form_pg_attribute *attr = tupDesc->attrs;
int attr_count = tupDesc->natts;
int i;
for (i = 0; i < attr_count; i++)
{
if (namestrcmp(&tupDesc->attrs[i]->attname, colName) == 0)
{
found = true;
break;
}
if (attr[i]->attisdropped)
continue;
attnums = lappendi(attnums, i + 1);
}
if (!found)
elog(ERROR, "COPY: Specified column \"%s\" does not exist",
colName);
}
}
else
{
/* Validate the user-supplied list and extract attnums */
List *l;
foreach(l, attnamelist)
{
char *name = strVal(lfirst(l));
int attnum;
/* Lookup column name, elog on failure */
/* Note we disallow system columns here */
attnum = attnameAttNum(rel, name, false);
/* Check for duplicates */
if (intMember(attnum, attnums))
elog(ERROR, "Attribute \"%s\" specified more than once", name);
attnums = lappendi(attnums, attnum);
}
}
return attnums;
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.79 2002/07/29 23:46:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.80 2002/08/02 18:15:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -294,10 +294,7 @@ FuncIndexArgs(IndexInfo *indexInfo,
HeapTuple tuple;
Form_pg_attribute att;
tuple = SearchSysCache(ATTNAME,
ObjectIdGetDatum(relId),
PointerGetDatum(arg),
0, 0);
tuple = SearchSysCacheAttName(relId, arg);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "DefineIndex: attribute \"%s\" not found", arg);
att = (Form_pg_attribute) GETSTRUCT(tuple);
@ -387,10 +384,7 @@ NormIndexAttrs(IndexInfo *indexInfo,
if (attribute->name == NULL)
elog(ERROR, "missing attribute for define index");
atttuple = SearchSysCache(ATTNAME,
ObjectIdGetDatum(relId),
PointerGetDatum(attribute->name),
0, 0);
atttuple = SearchSysCacheAttName(relId, attribute->name);
if (!HeapTupleIsValid(atttuple))
elog(ERROR, "DefineIndex: attribute \"%s\" not found",
attribute->name);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.25 2002/07/31 17:19:51 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.26 2002/08/02 18:15:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -503,7 +503,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
/*
* newattno[] will contain the child-table attribute numbers for
* the attributes of this parent table. (They are not the same
* for parents after the first one.)
* for parents after the first one, nor if we have dropped columns.)
*/
newattno = (AttrNumber *) palloc(tupleDesc->natts * sizeof(AttrNumber));
@ -516,6 +516,19 @@ MergeAttributes(List *schema, List *supers, bool istemp,
ColumnDef *def;
TypeName *typename;
/*
* Ignore dropped columns in the parent.
*/
if (attribute->attisdropped)
{
/*
* change_varattnos_of_a_node asserts that this is greater than
* zero, so if anything tries to use it, we should find out.
*/
newattno[parent_attno - 1] = 0;
continue;
}
/*
* Does it conflict with some previously inherited column?
*/
@ -1062,17 +1075,17 @@ renameatt(Oid relid,
attrelation = heap_openr(AttributeRelationName, RowExclusiveLock);
atttup = SearchSysCacheCopy(ATTNAME,
ObjectIdGetDatum(relid),
PointerGetDatum(oldattname),
0, 0);
atttup = SearchSysCacheCopyAttName(relid, oldattname);
if (!HeapTupleIsValid(atttup))
elog(ERROR, "renameatt: attribute \"%s\" does not exist", oldattname);
elog(ERROR, "renameatt: attribute \"%s\" does not exist",
oldattname);
if (((Form_pg_attribute) GETSTRUCT(atttup))->attnum < 0)
elog(ERROR, "renameatt: system attribute \"%s\" not renamed", oldattname);
elog(ERROR, "renameatt: system attribute \"%s\" may not be renamed",
oldattname);
/* should not already exist */
/* this test is deliberately not attisdropped-aware */
if (SearchSysCacheExists(ATTNAME,
ObjectIdGetDatum(relid),
PointerGetDatum(newattname),
@ -1126,10 +1139,7 @@ renameatt(Oid relid,
* Okay, look to see if any column name of the index matches the
* old attribute name.
*/
atttup = SearchSysCacheCopy(ATTNAME,
ObjectIdGetDatum(indexoid),
PointerGetDatum(oldattname),
0, 0);
atttup = SearchSysCacheCopyAttName(indexoid, oldattname);
if (!HeapTupleIsValid(atttup))
continue; /* Nope, so ignore it */
@ -1634,6 +1644,10 @@ AlterTableAddColumn(Oid myrelid,
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
RelationGetRelationName(rel));
/*
* this test is deliberately not attisdropped-aware, since if one tries
* to add a column matching a dropped column name, it's gonna fail anyway.
*/
if (SearchSysCacheExists(ATTNAME,
ObjectIdGetDatum(myrelid),
PointerGetDatum(colDef->colname),
@ -1681,6 +1695,7 @@ AlterTableAddColumn(Oid myrelid,
attribute->attnotnull = colDef->is_not_null;
attribute->atthasdef = (colDef->raw_default != NULL ||
colDef->cooked_default != NULL);
attribute->attisdropped = false;
ReleaseSysCache(typeTuple);
@ -1821,17 +1836,11 @@ AlterTableAlterColumnDropNotNull(Oid myrelid,
/*
* get the number of the attribute
*/
tuple = SearchSysCache(ATTNAME,
ObjectIdGetDatum(myrelid),
PointerGetDatum(colName),
0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
attnum = get_attnum(myrelid, colName);
if (attnum == InvalidAttrNumber)
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
RelationGetRelationName(rel), colName);
attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
ReleaseSysCache(tuple);
/* Prevent them from altering a system attribute */
if (attnum < 0)
elog(ERROR, "ALTER TABLE: Cannot alter system attribute \"%s\"",
@ -1884,10 +1893,7 @@ AlterTableAlterColumnDropNotNull(Oid myrelid,
*/
attr_rel = heap_openr(AttributeRelationName, RowExclusiveLock);
tuple = SearchSysCacheCopy(ATTNAME,
ObjectIdGetDatum(myrelid),
PointerGetDatum(colName),
0, 0);
tuple = SearchSysCacheCopyAttName(myrelid, colName);
if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
RelationGetRelationName(rel), colName);
@ -1971,17 +1977,11 @@ AlterTableAlterColumnSetNotNull(Oid myrelid,
/*
* get the number of the attribute
*/
tuple = SearchSysCache(ATTNAME,
ObjectIdGetDatum(myrelid),
PointerGetDatum(colName),
0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
attnum = get_attnum(myrelid, colName);
if (attnum == InvalidAttrNumber)
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
RelationGetRelationName(rel), colName);
attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
ReleaseSysCache(tuple);
/* Prevent them from altering a system attribute */
if (attnum < 0)
elog(ERROR, "ALTER TABLE: Cannot alter system attribute \"%s\"",
@ -2014,10 +2014,7 @@ AlterTableAlterColumnSetNotNull(Oid myrelid,
*/
attr_rel = heap_openr(AttributeRelationName, RowExclusiveLock);
tuple = SearchSysCacheCopy(ATTNAME,
ObjectIdGetDatum(myrelid),
PointerGetDatum(colName),
0, 0);
tuple = SearchSysCacheCopyAttName(myrelid, colName);
if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
RelationGetRelationName(rel), colName);
@ -2051,7 +2048,6 @@ AlterTableAlterColumnDefault(Oid myrelid,
Node *newDefault)
{
Relation rel;
HeapTuple tuple;
AttrNumber attnum;
rel = heap_open(myrelid, AccessExclusiveLock);
@ -2106,16 +2102,15 @@ AlterTableAlterColumnDefault(Oid myrelid,
/*
* get the number of the attribute
*/
tuple = SearchSysCache(ATTNAME,
ObjectIdGetDatum(myrelid),
PointerGetDatum(colName),
0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
attnum = get_attnum(myrelid, colName);
if (attnum == InvalidAttrNumber)
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
RelationGetRelationName(rel), colName);
attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
ReleaseSysCache(tuple);
/* Prevent them from altering a system attribute */
if (attnum < 0)
elog(ERROR, "ALTER TABLE: Cannot alter system attribute \"%s\"",
colName);
/*
* Remove any old default for the column. We use RESTRICT here for
@ -2254,10 +2249,7 @@ AlterTableAlterColumnFlags(Oid myrelid,
attrelation = heap_openr(AttributeRelationName, RowExclusiveLock);
tuple = SearchSysCacheCopy(ATTNAME,
ObjectIdGetDatum(myrelid),
PointerGetDatum(colName),
0, 0);
tuple = SearchSysCacheCopyAttName(myrelid, colName);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
RelationGetRelationName(rel), colName);
@ -2309,7 +2301,99 @@ AlterTableDropColumn(Oid myrelid,
bool inh, const char *colName,
DropBehavior behavior)
{
elog(ERROR, "ALTER TABLE / DROP COLUMN is not implemented");
Relation rel;
AttrNumber attnum;
AttrNumber n;
TupleDesc tupleDesc;
bool success;
ObjectAddress object;
rel = heap_open(myrelid, AccessExclusiveLock);
if (rel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
RelationGetRelationName(rel));
if (!allowSystemTableMods
&& IsSystemRelation(rel))
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
RelationGetRelationName(rel));
if (!pg_class_ownercheck(myrelid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
/*
* get the number of the attribute
*/
attnum = get_attnum(myrelid, colName);
if (attnum == InvalidAttrNumber)
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
RelationGetRelationName(rel), colName);
/* Can't drop a system attribute */
if (attnum < 0)
elog(ERROR, "ALTER TABLE: Cannot drop system attribute \"%s\"",
colName);
/*
* Make sure there will be at least one user column left in the relation
* after we drop this one. Zero-length tuples tend to confuse us.
*/
tupleDesc = RelationGetDescr(rel);
success = false;
for (n = 1; n <= tupleDesc->natts; n++)
{
Form_pg_attribute attribute = tupleDesc->attrs[n - 1];
if (!attribute->attisdropped && n != attnum)
{
success = true;
break;
}
}
if (!success)
elog(ERROR, "ALTER TABLE: Cannot drop last column from table \"%s\"",
RelationGetRelationName(rel));
/*
* Propagate to children if desired
*/
if (inh)
{
List *child,
*children;
/* this routine is actually in the planner */
children = find_all_inheritors(myrelid);
/*
* find_all_inheritors does the recursive search of the
* inheritance hierarchy, so all we have to do is process all of
* the relids in the list that it returns.
*/
foreach(child, children)
{
Oid childrelid = lfirsti(child);
if (childrelid == myrelid)
continue;
AlterTableDropColumn(childrelid,
false, colName, behavior);
}
}
/*
* Perform the actual deletion
*/
object.classId = RelOid_pg_class;
object.objectId = myrelid;
object.objectSubId = attnum;
performDeletion(&object, behavior);
heap_close(rel, NoLock); /* close rel, but keep lock! */
}
@ -2722,8 +2806,13 @@ createForeignKeyConstraint(Relation rel, Relation pkrel,
foreach(l, fkconstraint->fk_attrs)
{
Ident *id = (Ident *) lfirst(l);
AttrNumber attno;
fkattr[i++] = get_attnum(RelationGetRelid(rel), id->name);
attno = get_attnum(RelationGetRelid(rel), id->name);
if (attno == InvalidAttrNumber)
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
RelationGetRelationName(rel), id->name);
fkattr[i++] = attno;
}
/* The same for the referenced primary key attrs */
@ -2733,8 +2822,13 @@ createForeignKeyConstraint(Relation rel, Relation pkrel,
foreach(l, fkconstraint->pk_attrs)
{
Ident *id = (Ident *) lfirst(l);
AttrNumber attno;
pkattr[i++] = get_attnum(RelationGetRelid(pkrel), id->name);
attno = get_attnum(RelationGetRelid(pkrel), id->name);
if (attno == InvalidAttrNumber)
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
RelationGetRelationName(pkrel), id->name);
pkattr[i++] = attno;
}
/* Now we can make the pg_constraint entry */

View File

@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.53 2002/06/20 20:29:31 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.54 2002/08/02 18:15:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -165,6 +165,8 @@ expand_targetlist(List *tlist, int command_type,
*
* For UPDATE, generate a Var reference to the existing value of
* the attribute, so that it gets copied to the new tuple.
* But generate a NULL for dropped columns (we want to drop any
* old values).
*/
Oid atttype = att_tup->atttypid;
int32 atttypmod = att_tup->atttypmod;
@ -182,11 +184,21 @@ expand_targetlist(List *tlist, int command_type,
false);
break;
case CMD_UPDATE:
new_expr = (Node *) makeVar(result_relation,
attrno,
atttype,
atttypmod,
0);
/* Insert NULLs for dropped columns */
if (att_tup->attisdropped)
new_expr = (Node *) makeConst(atttype,
att_tup->attlen,
(Datum) 0,
true, /* isnull */
att_tup->attbyval,
false, /* not a set */
false);
else
new_expr = (Node *) makeVar(result_relation,
attrno,
atttype,
atttypmod,
0);
break;
default:
elog(ERROR, "expand_targetlist: unexpected command_type");
@ -210,7 +222,8 @@ expand_targetlist(List *tlist, int command_type,
* the end of the new tlist, making sure they have resnos higher than
* the last real attribute. (Note: although the rewriter already did
* such renumbering, we have to do it again here in case we are doing
* an UPDATE in an inheritance child table with more columns.)
* an UPDATE in a table with dropped columns, or an inheritance child
* table with extra columns.)
*/
while (tlist)
{

View File

@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.74 2002/06/20 20:29:31 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.75 2002/08/02 18:15:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -797,9 +797,16 @@ adjust_inherited_attrs_mutator(Node *node,
{
var->varno = context->new_rt_index;
if (var->varattno > 0)
var->varattno = get_attnum(context->new_relid,
get_attname(context->old_relid,
var->varattno));
{
char *attname = get_attname(context->old_relid,
var->varattno);
var->varattno = get_attnum(context->new_relid, attname);
if (var->varattno == InvalidAttrNumber)
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
get_rel_name(context->new_relid), attname);
pfree(attname);
}
}
return (Node *) var;
}

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.239 2002/07/16 22:12:19 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.240 2002/08/02 18:15:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1143,6 +1143,8 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
Form_pg_attribute inhattr = rel->rd_att->attrs[count];
char *inhname = NameStr(inhattr->attname);
if (inhattr->attisdropped)
continue;
if (strcmp(key->name, inhname) == 0)
{
found = true;
@ -1178,10 +1180,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
/* ALTER TABLE case: does column already exist? */
HeapTuple atttuple;
atttuple = SearchSysCache(ATTNAME,
ObjectIdGetDatum(cxt->relOid),
PointerGetDatum(key->name),
0, 0);
atttuple = SearchSysCacheAttName(cxt->relOid, key->name);
if (HeapTupleIsValid(atttuple))
{
found = true;
@ -2369,7 +2368,7 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
origTarget = (ResTarget *) lfirst(origTargetList);
updateTargetListEntry(pstate, tle, origTarget->name,
attnameAttNum(pstate->p_target_relation,
origTarget->name),
origTarget->name, true),
origTarget->indirection);
origTargetList = lnext(origTargetList);
}
@ -2820,11 +2819,14 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname)
inh->relname);
for (count = 0; count < rel->rd_att->natts; count++)
{
char *name = NameStr(rel->rd_att->attrs[count]->attname);
Form_pg_attribute inhattr = rel->rd_att->attrs[count];
char *inhname = NameStr(inhattr->attname);
if (strcmp(name, colname) == 0)
if (inhattr->attisdropped)
continue;
if (strcmp(inhname, colname) == 0)
{
result = rel->rd_att->attrs[count]->atttypid;
result = inhattr->atttypid;
heap_close(rel, NoLock);
return result;
}
@ -2836,10 +2838,7 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname)
{
HeapTuple atttuple;
atttuple = SearchSysCache(ATTNAME,
ObjectIdGetDatum(cxt->relOid),
PointerGetDatum(colname),
0, 0);
atttuple = SearchSysCacheAttName(cxt->relOid, colname);
if (HeapTupleIsValid(atttuple))
{
result = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.132 2002/06/20 20:29:32 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.133 2002/08/02 18:15:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1150,6 +1150,9 @@ setup_field_select(Node *input, char *attname, Oid relid)
AttrNumber attno;
attno = get_attnum(relid, attname);
if (attno == InvalidAttrNumber)
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
get_rel_name(relid), attname);
fselect->arg = input;
fselect->fieldnum = attno;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.70 2002/06/20 20:29:33 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.71 2002/08/02 18:15:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -37,7 +37,9 @@ static Node *scanNameSpaceForRefname(ParseState *pstate, Node *nsnode,
static Node *scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte,
char *colname);
static bool isForUpdate(ParseState *pstate, char *refname);
static int specialAttNum(char *a);
static bool get_rte_attribute_is_dropped(RangeTblEntry *rte,
AttrNumber attnum);
static int specialAttNum(const char *attname);
static void warnAutoRange(ParseState *pstate, RangeVar *relation);
@ -267,12 +269,28 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname)
/*
* Scan the user column names (or aliases) for a match. Complain if
* multiple matches.
*
* Note: because eref->colnames may include names of dropped columns,
* we need to check for non-droppedness before accepting a match.
* This takes an extra cache lookup, but we can skip the lookup most
* of the time by exploiting the knowledge that dropped columns are
* assigned dummy names starting with '.', which is an unusual choice
* for actual column names.
*
* Should the user try to fool us by altering pg_attribute.attname
* for a dropped column, we'll still catch it by virtue of the checks
* in get_rte_attribute_type(), which is called by make_var(). That
* routine has to do a cache lookup anyway, so the check there is
* cheap.
*/
foreach(c, rte->eref->colnames)
{
attnum++;
if (strcmp(strVal(lfirst(c)), colname) == 0)
{
if (colname[0] == '.' && /* see note above */
get_rte_attribute_is_dropped(rte, attnum))
continue;
if (result)
elog(ERROR, "Column reference \"%s\" is ambiguous", colname);
result = (Node *) make_var(pstate, rte, attnum);
@ -962,6 +980,9 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
{
Form_pg_attribute attr = rel->rd_att->attrs[varattno];
if (attr->attisdropped)
continue;
if (colnames)
{
char *label;
@ -1051,6 +1072,9 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
{
Form_pg_attribute attr = rel->rd_att->attrs[varattno];
if (attr->attisdropped)
continue;
if (colnames)
{
char *label;
@ -1246,9 +1270,16 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
0, 0);
/* this shouldn't happen... */
if (!HeapTupleIsValid(tp))
elog(ERROR, "Relation %s does not have attribute %d",
elog(ERROR, "Relation \"%s\" does not have attribute %d",
get_rel_name(rte->relid), attnum);
att_tup = (Form_pg_attribute) GETSTRUCT(tp);
/*
* If dropped column, pretend it ain't there. See notes
* in scanRTEForColumn.
*/
if (att_tup->attisdropped)
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
get_rel_name(rte->relid), NameStr(att_tup->attname));
*vartype = att_tup->atttypid;
*vartypmod = att_tup->atttypmod;
ReleaseSysCache(tp);
@ -1298,6 +1329,14 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
elog(ERROR, "Relation %s does not have attribute %d",
get_rel_name(funcrelid), attnum);
att_tup = (Form_pg_attribute) GETSTRUCT(tp);
/*
* If dropped column, pretend it ain't there. See notes
* in scanRTEForColumn.
*/
if (att_tup->attisdropped)
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
get_rel_name(funcrelid),
NameStr(att_tup->attname));
*vartype = att_tup->atttypid;
*vartypmod = att_tup->atttypmod;
ReleaseSysCache(tp);
@ -1329,6 +1368,86 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
}
}
/*
* get_rte_attribute_is_dropped
* Check whether attempted attribute ref is to a dropped column
*/
static bool
get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
{
bool result;
switch (rte->rtekind)
{
case RTE_RELATION:
{
/* Plain relation RTE --- get the attribute's type info */
HeapTuple tp;
Form_pg_attribute att_tup;
tp = SearchSysCache(ATTNUM,
ObjectIdGetDatum(rte->relid),
Int16GetDatum(attnum),
0, 0);
/* this shouldn't happen... */
if (!HeapTupleIsValid(tp))
elog(ERROR, "Relation \"%s\" does not have attribute %d",
get_rel_name(rte->relid), attnum);
att_tup = (Form_pg_attribute) GETSTRUCT(tp);
result = att_tup->attisdropped;
ReleaseSysCache(tp);
}
break;
case RTE_SUBQUERY:
case RTE_JOIN:
/* Subselect and join RTEs never have dropped columns */
result = false;
break;
case RTE_FUNCTION:
{
/* Function RTE */
Oid funcrettype = exprType(rte->funcexpr);
Oid funcrelid = typeidTypeRelid(funcrettype);
if (OidIsValid(funcrelid))
{
/*
* Composite data type, i.e. a table's row type
* Same as ordinary relation RTE
*/
HeapTuple tp;
Form_pg_attribute att_tup;
tp = SearchSysCache(ATTNUM,
ObjectIdGetDatum(funcrelid),
Int16GetDatum(attnum),
0, 0);
/* this shouldn't happen... */
if (!HeapTupleIsValid(tp))
elog(ERROR, "Relation %s does not have attribute %d",
get_rel_name(funcrelid), attnum);
att_tup = (Form_pg_attribute) GETSTRUCT(tp);
result = att_tup->attisdropped;
ReleaseSysCache(tp);
}
else
{
/*
* Must be a base data type, i.e. scalar
*/
result = false;
}
}
break;
default:
elog(ERROR, "get_rte_attribute_is_dropped: unsupported RTE kind %d",
(int) rte->rtekind);
result = false; /* keep compiler quiet */
}
return result;
}
/*
* given relation and att name, return id of variable
*
@ -1337,23 +1456,30 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
* for access to non-opened relations.
*/
int
attnameAttNum(Relation rd, char *a)
attnameAttNum(Relation rd, const char *attname, bool sysColOK)
{
int i;
for (i = 0; i < rd->rd_rel->relnatts; i++)
if (namestrcmp(&(rd->rd_att->attrs[i]->attname), a) == 0)
return i + 1;
if ((i = specialAttNum(a)) != InvalidAttrNumber)
{
if (i != ObjectIdAttributeNumber || rd->rd_rel->relhasoids)
return i;
Form_pg_attribute att = rd->rd_att->attrs[i];
if (namestrcmp(&(att->attname), attname) == 0 && !att->attisdropped)
return i + 1;
}
if (sysColOK)
{
if ((i = specialAttNum(attname)) != InvalidAttrNumber)
{
if (i != ObjectIdAttributeNumber || rd->rd_rel->relhasoids)
return i;
}
}
/* on failure */
elog(ERROR, "Relation '%s' does not have attribute '%s'",
RelationGetRelationName(rd), a);
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
RelationGetRelationName(rd), attname);
return InvalidAttrNumber; /* lint */
}
@ -1367,11 +1493,12 @@ attnameAttNum(Relation rd, char *a)
* at least in the case of "oid", which is now optional.
*/
static int
specialAttNum(char *a)
specialAttNum(const char *attname)
{
Form_pg_attribute sysatt;
sysatt = SystemAttributeByName(a, true /* "oid" will be accepted */ );
sysatt = SystemAttributeByName(attname,
true /* "oid" will be accepted */ );
if (sysatt != NULL)
return sysatt->attnum;
return InvalidAttrNumber;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.85 2002/06/20 20:29:33 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.86 2002/08/02 18:15:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -385,8 +385,12 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
for (i = 0; i < numcol; i++)
{
ResTarget *col = makeNode(ResTarget);
ResTarget *col;
if (attr[i]->attisdropped)
continue;
col = makeNode(ResTarget);
col->name = pstrdup(NameStr(attr[i]->attname));
col->indirection = NIL;
col->val = NULL;
@ -407,7 +411,7 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
int attrno;
/* Lookup column name, elog on failure */
attrno = attnameAttNum(pstate->p_target_relation, name);
attrno = attnameAttNum(pstate->p_target_relation, name, false);
/* Check for duplicates */
if (intMember(attrno, *attrnos))
elog(ERROR, "Attribute '%s' specified more than once", name);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.46 2002/07/29 23:46:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.47 2002/08/02 18:15:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -85,8 +85,8 @@ LookupTypeName(const TypeName *typename)
relid = RangeVarGetRelid(rel, false);
attnum = get_attnum(relid, field);
if (attnum == InvalidAttrNumber)
elog(ERROR, "'%s' is not an attribute of class '%s'",
field, rel->relname);
elog(ERROR, "Relation \"%s\" has no column \"%s\"",
rel->relname, field);
restype = get_atttype(relid, attnum);
/* this construct should never have an array indicator */

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.75 2002/07/16 05:53:34 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.76 2002/08/02 18:15:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -257,6 +257,16 @@ DefineQueryRewrite(RuleStmt *stmt)
attr = event_relation->rd_att->attrs[i - 1];
attname = NameStr(attr->attname);
/*
* Disallow dropped columns in the relation. This won't happen
* in the cases we actually care about (namely creating a view
* via CREATE TABLE then CREATE RULE). Trying to cope with it
* is much more trouble than it's worth, because we'd have to
* modify the rule to insert dummy NULLs at the right positions.
*/
if (attr->attisdropped)
elog(ERROR, "cannot convert relation containing dropped columns to view");
if (strcmp(resdom->resname, attname) != 0)
elog(ERROR, "select rule's target entry %d has different column name from %s", i, attname);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.104 2002/07/18 04:43:50 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.105 2002/08/02 18:15:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -264,6 +264,10 @@ rewriteTargetList(Query *parsetree, Relation target_relation)
Form_pg_attribute att_tup = target_relation->rd_att->attrs[attrno-1];
TargetEntry *new_tle = NULL;
/* We can ignore deleted attributes */
if (att_tup->attisdropped)
continue;
/*
* Look for targetlist entries matching this attr. We match by
* resno, but the resname should match too.

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.30 2002/06/20 20:29:37 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.31 2002/08/02 18:15:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -28,9 +28,9 @@
#include "access/heapam.h"
#include "catalog/namespace.h"
#include "parser/parse_relation.h"
#include "utils/builtins.h"
static int my_varattno(Relation rd, char *a);
/* ----------------------------------------------------------------
*
@ -65,15 +65,10 @@ int4notin(PG_FUNCTION_ARGS)
relrv = makeRangeVarFromNameList(names);
/* Open the relation and get a relation descriptor */
relation_to_scan = heap_openrv(relrv, AccessShareLock);
/* Find the column to search */
attrid = my_varattno(relation_to_scan, attribute);
if (attrid < 0)
elog(ERROR, "int4notin: unknown attribute %s for relation %s",
attribute, RelationGetRelationName(relation_to_scan));
attrid = attnameAttNum(relation_to_scan, attribute, true);
scan_descriptor = heap_beginscan(relation_to_scan, SnapshotNow,
0, (ScanKey) NULL);
@ -118,21 +113,3 @@ oidnotin(PG_FUNCTION_ARGS)
/* XXX assume oid maps to int4 */
return int4notin(fcinfo);
}
/*
* XXX
* If varattno (in parser/catalog_utils.h) ever is added to
* cinterface.a, this routine should go away
*/
static int
my_varattno(Relation rd, char *a)
{
int i;
for (i = 0; i < rd->rd_rel->relnatts; i++)
{
if (namestrcmp(&rd->rd_att->attrs[i]->attname, a) == 0)
return i + 1;
}
return -1;
}

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.76 2002/07/12 18:43:18 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.77 2002/08/02 18:15:08 tgl Exp $
*
* NOTES
* Eventually, the index information should go through here, too.
@ -115,16 +115,15 @@ get_attname(Oid relid, AttrNumber attnum)
*
* Given the relation id and the attribute name,
* return the "attnum" field from the attribute relation.
*
* Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
*/
AttrNumber
get_attnum(Oid relid, char *attname)
get_attnum(Oid relid, const char *attname)
{
HeapTuple tp;
tp = SearchSysCache(ATTNAME,
ObjectIdGetDatum(relid),
PointerGetDatum(attname),
0, 0);
tp = SearchSysCacheAttName(relid, attname);
if (HeapTupleIsValid(tp))
{
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
@ -166,32 +165,6 @@ get_atttype(Oid relid, AttrNumber attnum)
return InvalidOid;
}
/* This routine uses the attname instead of the attnum because it
* replaces the routine find_atttype, which is called sometimes when
* only the attname, not the attno, is available.
*/
bool
get_attisset(Oid relid, char *attname)
{
HeapTuple tp;
tp = SearchSysCache(ATTNAME,
ObjectIdGetDatum(relid),
PointerGetDatum(attname),
0, 0);
if (HeapTupleIsValid(tp))
{
Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
bool result;
result = att_tup->attisset;
ReleaseSysCache(tp);
return result;
}
else
return false;
}
/*
* get_atttypmod
*

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.84 2002/07/25 10:07:12 ishii Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.85 2002/08/02 18:15:08 tgl Exp $
*
* NOTES
* These routines allow the parser/planner/executor to perform
@ -622,6 +622,71 @@ GetSysCacheOid(int cacheId,
return result;
}
/*
* SearchSysCacheAttName
*
* This routine is equivalent to SearchSysCache on the ATTNAME cache,
* except that it will return NULL if the found attribute is marked
* attisdropped. This is convenient for callers that want to act as
* though dropped attributes don't exist.
*/
HeapTuple
SearchSysCacheAttName(Oid relid, const char *attname)
{
HeapTuple tuple;
tuple = SearchSysCache(ATTNAME,
ObjectIdGetDatum(relid),
CStringGetDatum(attname),
0, 0);
if (!HeapTupleIsValid(tuple))
return NULL;
if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped)
{
ReleaseSysCache(tuple);
return NULL;
}
return tuple;
}
/*
* SearchSysCacheCopyAttName
*
* As above, an attisdropped-aware version of SearchSysCacheCopy.
*/
HeapTuple
SearchSysCacheCopyAttName(Oid relid, const char *attname)
{
HeapTuple tuple,
newtuple;
tuple = SearchSysCacheAttName(relid, attname);
if (!HeapTupleIsValid(tuple))
return tuple;
newtuple = heap_copytuple(tuple);
ReleaseSysCache(tuple);
return newtuple;
}
/*
* SearchSysCacheExistsAttName
*
* As above, an attisdropped-aware version of SearchSysCacheExists.
*/
bool
SearchSysCacheExistsAttName(Oid relid, const char *attname)
{
HeapTuple tuple;
tuple = SearchSysCacheAttName(relid, attname);
if (!HeapTupleIsValid(tuple))
return false;
ReleaseSysCache(tuple);
return true;
}
/*
* SysCacheGetAttr
*

View File

@ -22,7 +22,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.278 2002/07/31 17:19:52 tgl Exp $
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.279 2002/08/02 18:15:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -863,13 +863,15 @@ dumpClasses_nodumpData(Archive *fout, char *oid, void *dctxv)
{
appendPQExpBuffer(q, "COPY %s %s WITH OIDS TO stdout;",
fmtQualifiedId(tbinfo->relnamespace->nspname,
classname),column_list);
classname),
column_list);
}
else
{
appendPQExpBuffer(q, "COPY %s %s TO stdout;",
fmtQualifiedId(tbinfo->relnamespace->nspname,
classname), column_list);
classname),
column_list);
}
res = PQexec(g_conn, q->data);
if (!res ||
@ -1193,10 +1195,13 @@ dumpClasses(const TableInfo *tblinfo, const int numTables, Archive *fout,
if (!dumpData)
{
/* Dump/restore using COPY */
const char *column_list;
dumpFn = dumpClasses_nodumpData;
column_list = fmtCopyColumnList(&(tblinfo[i]));
sprintf(copyBuf, "COPY %s %s %sFROM stdin;\n",
fmtQualifiedId(tblinfo[i].relnamespace->nspname,tblinfo[i].relname),
fmtCopyColumnList(&(tblinfo[i])),
fmtId(tblinfo[i].relname, force_quotes),
column_list,
(oids && tblinfo[i].hasoids) ? "WITH OIDS " : "");
copyStmt = copyBuf;
}
@ -2347,6 +2352,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
int i_attstattarget;
int i_attnotnull;
int i_atthasdef;
int i_attisdropped;
PGresult *res;
int ntups;
bool hasdefaults;
@ -2386,7 +2392,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
if (g_fout->remoteVersion >= 70300)
{
appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, attstattarget, "
"attnotnull, atthasdef, "
"attnotnull, atthasdef, attisdropped, "
"pg_catalog.format_type(atttypid,atttypmod) as atttypname "
"from pg_catalog.pg_attribute a "
"where attrelid = '%s'::pg_catalog.oid "
@ -2402,7 +2408,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
* explicitly set or was just a default.
*/
appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, -1 as attstattarget, "
"attnotnull, atthasdef, "
"attnotnull, atthasdef, false as attisdropped, "
"format_type(atttypid,atttypmod) as atttypname "
"from pg_attribute a "
"where attrelid = '%s'::oid "
@ -2414,7 +2420,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
{
/* format_type not available before 7.1 */
appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, -1 as attstattarget, "
"attnotnull, atthasdef, "
"attnotnull, atthasdef, false as attisdropped, "
"(select typname from pg_type where oid = atttypid) as atttypname "
"from pg_attribute a "
"where attrelid = '%s'::oid "
@ -2439,12 +2445,14 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
i_attstattarget = PQfnumber(res, "attstattarget");
i_attnotnull = PQfnumber(res, "attnotnull");
i_atthasdef = PQfnumber(res, "atthasdef");
i_attisdropped = PQfnumber(res, "attisdropped");
tblinfo[i].numatts = ntups;
tblinfo[i].attnames = (char **) malloc(ntups * sizeof(char *));
tblinfo[i].atttypnames = (char **) malloc(ntups * sizeof(char *));
tblinfo[i].atttypmod = (int *) malloc(ntups * sizeof(int));
tblinfo[i].attstattarget = (int *) malloc(ntups * sizeof(int));
tblinfo[i].attisdropped = (bool *) malloc(ntups * sizeof(bool));
tblinfo[i].notnull = (bool *) malloc(ntups * sizeof(bool));
tblinfo[i].adef_expr = (char **) malloc(ntups * sizeof(char *));
tblinfo[i].inhAttrs = (bool *) malloc(ntups * sizeof(bool));
@ -2458,6 +2466,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
tblinfo[i].atttypnames[j] = strdup(PQgetvalue(res, j, i_atttypname));
tblinfo[i].atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod));
tblinfo[i].attstattarget[j] = atoi(PQgetvalue(res, j, i_attstattarget));
tblinfo[i].attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't');
tblinfo[i].notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't');
tblinfo[i].adef_expr[j] = NULL; /* fix below */
if (PQgetvalue(res, j, i_atthasdef)[0] == 't')
@ -4999,8 +5008,8 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo)
actual_atts = 0;
for (j = 0; j < tbinfo->numatts; j++)
{
/* Is this one of the table's own attrs ? */
if (!tbinfo->inhAttrs[j])
/* Is this one of the table's own attrs, and not dropped ? */
if (!tbinfo->inhAttrs[j] && !tbinfo->attisdropped[j])
{
/* Format properly if not first attr */
if (actual_atts > 0)
@ -5161,7 +5170,8 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo)
*/
for (j = 0; j < tbinfo->numatts; j++)
{
if (tbinfo->attstattarget[j] >= 0)
if (tbinfo->attstattarget[j] >= 0 &&
!tbinfo->attisdropped[j])
{
appendPQExpBuffer(q, "ALTER TABLE %s ",
fmtId(tbinfo->relname, force_quotes));
@ -6274,7 +6284,7 @@ fmtQualifiedId(const char *schema, const char *id)
}
/*
* return a column list clause for the qualified relname.
* return a column list clause for the given relation.
* returns an empty string if the remote server is older than
* 7.3.
*/
@ -6284,9 +6294,11 @@ fmtCopyColumnList(const TableInfo* ti)
static PQExpBuffer q = NULL;
int numatts = ti->numatts;
char** attnames = ti->attnames;
bool* attisdropped = ti->attisdropped;
bool needComma;
int i;
if (g_fout->remoteVersion < 70300 )
if (g_fout->remoteVersion < 70300)
return "";
if (q) /* first time through? */
@ -6295,15 +6307,18 @@ fmtCopyColumnList(const TableInfo* ti)
q = createPQExpBuffer();
resetPQExpBuffer(q);
appendPQExpBuffer(q,"(");
appendPQExpBuffer(q, "(");
needComma = false;
for (i = 0; i < numatts; i++)
{
if( i > 0 )
appendPQExpBuffer(q,",");
appendPQExpBuffer(q, fmtId(attnames[i], force_quotes));
if (attisdropped[i])
continue;
if (needComma)
appendPQExpBuffer(q, ",");
appendPQExpBuffer(q, "%s", fmtId(attnames[i], force_quotes));
needComma = true;
}
appendPQExpBuffer(q, ")");
return q->data;
}

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_dump.h,v 1.93 2002/07/31 17:19:53 tgl Exp $
* $Id: pg_dump.h,v 1.94 2002/08/02 18:15:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -128,6 +128,7 @@ typedef struct _tableInfo
* all interesting tables so that we can tell which constraints were
* inherited.
*/
bool *attisdropped; /* true if attr is dropped; don't dump it */
bool *notnull; /* Not null constraints on attributes */
char **adef_expr; /* DEFAULT expressions */
bool *inhAttrs; /* true if each attribute is inherited */

View File

@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.56 2002/07/20 05:57:31 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.57 2002/08/02 18:15:08 tgl Exp $
*/
#include "postgres_fe.h"
#include "describe.h"
@ -536,7 +536,7 @@ describeTableDetails(const char *name, bool desc)
appendPQExpBuffer(&buf, "\nFROM pg_class c, pg_attribute a");
if (tableinfo.relkind == 'i')
appendPQExpBuffer(&buf, ", pg_index i");
appendPQExpBuffer(&buf, "\nWHERE c.relname = '%s'\n AND a.attnum > 0 AND a.attrelid = c.oid", name);
appendPQExpBuffer(&buf, "\nWHERE c.relname = '%s'\n AND a.attnum > 0 AND NOT a.attisdropped AND a.attrelid = c.oid", name);
if (tableinfo.relkind == 'i')
appendPQExpBuffer(&buf, " AND a.attrelid = i.indexrelid");
appendPQExpBuffer(&buf, "\nORDER BY a.attnum");

View File

@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.53 2002/07/31 17:19:53 tgl Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.54 2002/08/02 18:15:09 tgl Exp $
*/
/*----------------------------------------------------------------------
@ -156,7 +156,7 @@ pgsql_thing_t words_after_create[] = {
#define Query_for_list_of_tables words_after_create[9].query
#define Query_for_list_of_indexes words_after_create[4].query
#define Query_for_list_of_databases words_after_create[1].query
#define Query_for_list_of_attributes "SELECT a.attname FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c WHERE c.oid = a.attrelid and a.attnum>0 and substr(a.attname,1,%d)='%s' and c.relname='%s'"
#define Query_for_list_of_attributes "SELECT a.attname FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c WHERE c.oid = a.attrelid and a.attnum>0 and not a.attisdropped and substr(a.attname,1,%d)='%s' and c.relname='%s'"
#define Query_for_list_of_users words_after_create[14].query
/* A couple of macros to ease typing. You can use these to complete the given

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: catversion.h,v 1.143 2002/07/25 10:07:12 ishii Exp $
* $Id: catversion.h,v 1.144 2002/08/02 18:15:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200207251
#define CATALOG_VERSION_NO 200208011
#endif

View File

@ -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.54 2002/07/15 16:33:31 tgl Exp $
* $Id: heap.h,v 1.55 2002/08/02 18:15:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -63,6 +63,7 @@ extern int RemoveRelConstraints(Relation rel, const char *constrName,
extern void DeleteRelationTuple(Oid relid);
extern void DeleteAttributeTuples(Oid relid);
extern void RemoveAttributeById(Oid relid, AttrNumber attnum);
extern void RemoveAttrDefault(Oid relid, AttrNumber attnum,
DropBehavior behavior, bool complain);
extern void RemoveAttrDefaultById(Oid attrdefId);

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_attribute.h,v 1.95 2002/07/31 17:19:54 tgl Exp $
* $Id: pg_attribute.h,v 1.96 2002/08/02 18:15:09 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -143,6 +143,9 @@ CATALOG(pg_attribute) BOOTSTRAP BKI_WITHOUT_OIDS
/* Has DEFAULT value or not */
bool atthasdef;
/* Is dropped (ie, logically invisible) or not */
bool attisdropped;
} FormData_pg_attribute;
/*
@ -151,7 +154,7 @@ CATALOG(pg_attribute) BOOTSTRAP BKI_WITHOUT_OIDS
* because of alignment padding at the end of the struct.)
*/
#define ATTRIBUTE_TUPLE_SIZE \
(offsetof(FormData_pg_attribute,atthasdef) + sizeof(bool))
(offsetof(FormData_pg_attribute,attisdropped) + sizeof(bool))
/* ----------------
* Form_pg_attribute corresponds to a pointer to a tuple with
@ -165,7 +168,7 @@ typedef FormData_pg_attribute *Form_pg_attribute;
* ----------------
*/
#define Natts_pg_attribute 15
#define Natts_pg_attribute 16
#define Anum_pg_attribute_attrelid 1
#define Anum_pg_attribute_attname 2
#define Anum_pg_attribute_atttypid 3
@ -181,6 +184,7 @@ typedef FormData_pg_attribute *Form_pg_attribute;
#define Anum_pg_attribute_attalign 13
#define Anum_pg_attribute_attnotnull 14
#define Anum_pg_attribute_atthasdef 15
#define Anum_pg_attribute_attisdropped 16
@ -211,264 +215,266 @@ typedef FormData_pg_attribute *Form_pg_attribute;
* ----------------
*/
#define Schema_pg_type \
{ 1247, {"typname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', false, 'i', false, false }, \
{ 1247, {"typnamespace"}, 26, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typowner"}, 23, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typlen"}, 21, 0, 2, 4, 0, -1, -1, true, 'p', false, 's', false, false }, \
{ 1247, {"typbyval"}, 16, 0, 1, 5, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1247, {"typtype"}, 18, 0, 1, 6, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1247, {"typisdefined"}, 16, 0, 1, 7, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1247, {"typdelim"}, 18, 0, 1, 8, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1247, {"typrelid"}, 26, 0, 4, 9, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typelem"}, 26, 0, 4, 10, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typinput"}, 24, 0, 4, 11, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typoutput"}, 24, 0, 4, 12, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typalign"}, 18, 0, 1, 13, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1247, {"typstorage"}, 18, 0, 1, 14, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1247, {"typnotnull"}, 16, 0, 1, 15, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1247, {"typbasetype"}, 26, 0, 4, 16, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typtypmod"}, 23, 0, 4, 17, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typndims"}, 23, 0, 4, 18, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1247, {"typdefaultbin"}, 25, 0, -1, 19, 0, -1, -1, false, 'x', false, 'i', false, false }, \
{ 1247, {"typdefault"}, 25, 0, -1, 20, 0, -1, -1, false, 'x', false, 'i', false, false }
{ 1247, {"typname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', false, 'i', true, false, false }, \
{ 1247, {"typnamespace"}, 26, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1247, {"typowner"}, 23, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1247, {"typlen"}, 21, 0, 2, 4, 0, -1, -1, true, 'p', false, 's', true, false, false }, \
{ 1247, {"typbyval"}, 16, 0, 1, 5, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1247, {"typtype"}, 18, 0, 1, 6, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1247, {"typisdefined"}, 16, 0, 1, 7, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1247, {"typdelim"}, 18, 0, 1, 8, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1247, {"typrelid"}, 26, 0, 4, 9, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1247, {"typelem"}, 26, 0, 4, 10, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1247, {"typinput"}, 24, 0, 4, 11, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1247, {"typoutput"}, 24, 0, 4, 12, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1247, {"typalign"}, 18, 0, 1, 13, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1247, {"typstorage"}, 18, 0, 1, 14, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1247, {"typnotnull"}, 16, 0, 1, 15, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1247, {"typbasetype"}, 26, 0, 4, 16, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1247, {"typtypmod"}, 23, 0, 4, 17, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1247, {"typndims"}, 23, 0, 4, 18, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1247, {"typdefaultbin"}, 25, 0, -1, 19, 0, -1, -1, false, 'x', false, 'i', false, false, false }, \
{ 1247, {"typdefault"}, 25, 0, -1, 20, 0, -1, -1, false, 'x', false, 'i', false, false, false }
DATA(insert ( 1247 typname 19 -1 NAMEDATALEN 1 0 -1 -1 f p f i f f));
DATA(insert ( 1247 typnamespace 26 0 4 2 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typowner 23 0 4 3 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typlen 21 0 2 4 0 -1 -1 t p f s f f));
DATA(insert ( 1247 typbyval 16 0 1 5 0 -1 -1 t p f c f f));
DATA(insert ( 1247 typtype 18 0 1 6 0 -1 -1 t p f c f f));
DATA(insert ( 1247 typisdefined 16 0 1 7 0 -1 -1 t p f c f f));
DATA(insert ( 1247 typdelim 18 0 1 8 0 -1 -1 t p f c f f));
DATA(insert ( 1247 typrelid 26 0 4 9 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typelem 26 0 4 10 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typinput 24 0 4 11 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typoutput 24 0 4 12 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typalign 18 0 1 13 0 -1 -1 t p f c f f));
DATA(insert ( 1247 typstorage 18 0 1 14 0 -1 -1 t p f c f f));
DATA(insert ( 1247 typnotnull 16 0 1 15 0 -1 -1 t p f c f f));
DATA(insert ( 1247 typbasetype 26 0 4 16 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typtypmod 23 0 4 17 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typndims 23 0 4 18 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typdefaultbin 25 0 -1 19 0 -1 -1 f x f i f f));
DATA(insert ( 1247 typdefault 25 0 -1 20 0 -1 -1 f x f i f f));
DATA(insert ( 1247 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
DATA(insert ( 1247 oid 26 0 4 -2 0 -1 -1 t p f i f f));
DATA(insert ( 1247 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
DATA(insert ( 1247 cmin 29 0 4 -4 0 -1 -1 t p f i f f));
DATA(insert ( 1247 xmax 28 0 4 -5 0 -1 -1 t p f i f f));
DATA(insert ( 1247 cmax 29 0 4 -6 0 -1 -1 t p f i f f));
DATA(insert ( 1247 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
DATA(insert ( 1247 typname 19 -1 NAMEDATALEN 1 0 -1 -1 f p f i t f f));
DATA(insert ( 1247 typnamespace 26 0 4 2 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 typowner 23 0 4 3 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 typlen 21 0 2 4 0 -1 -1 t p f s t f f));
DATA(insert ( 1247 typbyval 16 0 1 5 0 -1 -1 t p f c t f f));
DATA(insert ( 1247 typtype 18 0 1 6 0 -1 -1 t p f c t f f));
DATA(insert ( 1247 typisdefined 16 0 1 7 0 -1 -1 t p f c t f f));
DATA(insert ( 1247 typdelim 18 0 1 8 0 -1 -1 t p f c t f f));
DATA(insert ( 1247 typrelid 26 0 4 9 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 typelem 26 0 4 10 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 typinput 24 0 4 11 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 typoutput 24 0 4 12 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 typalign 18 0 1 13 0 -1 -1 t p f c t f f));
DATA(insert ( 1247 typstorage 18 0 1 14 0 -1 -1 t p f c t f f));
DATA(insert ( 1247 typnotnull 16 0 1 15 0 -1 -1 t p f c t f f));
DATA(insert ( 1247 typbasetype 26 0 4 16 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 typtypmod 23 0 4 17 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 typndims 23 0 4 18 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 typdefaultbin 25 0 -1 19 0 -1 -1 f x f i f f f));
DATA(insert ( 1247 typdefault 25 0 -1 20 0 -1 -1 f x f i f f f));
DATA(insert ( 1247 ctid 27 0 6 -1 0 -1 -1 f p f i t f f));
DATA(insert ( 1247 oid 26 0 4 -2 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 xmin 28 0 4 -3 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 cmin 29 0 4 -4 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 xmax 28 0 4 -5 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 cmax 29 0 4 -6 0 -1 -1 t p f i t f f));
DATA(insert ( 1247 tableoid 26 0 4 -7 0 -1 -1 t p f i t f f));
/* ----------------
* pg_database
* ----------------
*/
DATA(insert ( 1262 datname 19 0 NAMEDATALEN 1 0 -1 -1 f p f i f f));
DATA(insert ( 1262 datdba 23 0 4 2 0 -1 -1 t p f i f f));
DATA(insert ( 1262 encoding 23 0 4 3 0 -1 -1 t p f i f f));
DATA(insert ( 1262 datistemplate 16 0 1 4 0 -1 -1 t p f c f f));
DATA(insert ( 1262 datallowconn 16 0 1 5 0 -1 -1 t p f c f f));
DATA(insert ( 1262 datlastsysoid 26 0 4 6 0 -1 -1 t p f i f f));
DATA(insert ( 1262 datvacuumxid 28 0 4 7 0 -1 -1 t p f i f f));
DATA(insert ( 1262 datfrozenxid 28 0 4 8 0 -1 -1 t p f i f f));
DATA(insert ( 1262 datname 19 0 NAMEDATALEN 1 0 -1 -1 f p f i t f f));
DATA(insert ( 1262 datdba 23 0 4 2 0 -1 -1 t p f i t f f));
DATA(insert ( 1262 encoding 23 0 4 3 0 -1 -1 t p f i t f f));
DATA(insert ( 1262 datistemplate 16 0 1 4 0 -1 -1 t p f c t f f));
DATA(insert ( 1262 datallowconn 16 0 1 5 0 -1 -1 t p f c t f f));
DATA(insert ( 1262 datlastsysoid 26 0 4 6 0 -1 -1 t p f i t f f));
DATA(insert ( 1262 datvacuumxid 28 0 4 7 0 -1 -1 t p f i t f f));
DATA(insert ( 1262 datfrozenxid 28 0 4 8 0 -1 -1 t p f i t f f));
/* do not mark datpath as toastable; GetRawDatabaseInfo won't cope */
DATA(insert ( 1262 datpath 25 0 -1 9 0 -1 -1 f p f i f f));
DATA(insert ( 1262 datconfig 1009 0 -1 10 0 -1 -1 f x f i f f));
DATA(insert ( 1262 datacl 1034 0 -1 11 0 -1 -1 f x f i f f));
DATA(insert ( 1262 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
DATA(insert ( 1262 oid 26 0 4 -2 0 -1 -1 t p f i f f));
DATA(insert ( 1262 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
DATA(insert ( 1262 cmin 29 0 4 -4 0 -1 -1 t p f i f f));
DATA(insert ( 1262 xmax 28 0 4 -5 0 -1 -1 t p f i f f));
DATA(insert ( 1262 cmax 29 0 4 -6 0 -1 -1 t p f i f f));
DATA(insert ( 1262 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
DATA(insert ( 1262 datpath 25 0 -1 9 0 -1 -1 f p f i t f f));
DATA(insert ( 1262 datconfig 1009 0 -1 10 0 -1 -1 f x f i f f f));
DATA(insert ( 1262 datacl 1034 0 -1 11 0 -1 -1 f x f i f f f));
DATA(insert ( 1262 ctid 27 0 6 -1 0 -1 -1 f p f i t f f));
DATA(insert ( 1262 oid 26 0 4 -2 0 -1 -1 t p f i t f f));
DATA(insert ( 1262 xmin 28 0 4 -3 0 -1 -1 t p f i t f f));
DATA(insert ( 1262 cmin 29 0 4 -4 0 -1 -1 t p f i t f f));
DATA(insert ( 1262 xmax 28 0 4 -5 0 -1 -1 t p f i t f f));
DATA(insert ( 1262 cmax 29 0 4 -6 0 -1 -1 t p f i t f f));
DATA(insert ( 1262 tableoid 26 0 4 -7 0 -1 -1 t p f i t f f));
/* ----------------
* pg_proc
* ----------------
*/
#define Schema_pg_proc \
{ 1255, {"proname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', false, 'i', false, false }, \
{ 1255, {"pronamespace"}, 26, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1255, {"proowner"}, 23, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1255, {"prolang"}, 26, 0, 4, 4, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1255, {"proisagg"}, 16, 0, 1, 5, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1255, {"prosecdef"}, 16, 0, 1, 6, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1255, {"proisstrict"}, 16, 0, 1, 7, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1255, {"proretset"}, 16, 0, 1, 8, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1255, {"provolatile"}, 18, 0, 1, 9, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1255, {"pronargs"}, 21, 0, 2, 10, 0, -1, -1, true, 'p', false, 's', false, false }, \
{ 1255, {"prorettype"}, 26, 0, 4, 11, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1255, {"proargtypes"}, 30, 0, INDEX_MAX_KEYS*4, 12, 0, -1, -1, false, 'p', false, 'i', false, false }, \
{ 1255, {"prosrc"}, 25, 0, -1, 13, 0, -1, -1, false, 'x', false, 'i', false, false }, \
{ 1255, {"probin"}, 17, 0, -1, 14, 0, -1, -1, false, 'x', false, 'i', false, false }, \
{ 1255, {"proacl"}, 1034, 0, -1, 15, 0, -1, -1, false, 'x', false, 'i', false, false }
{ 1255, {"proname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', false, 'i', true, false, false }, \
{ 1255, {"pronamespace"}, 26, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1255, {"proowner"}, 23, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1255, {"prolang"}, 26, 0, 4, 4, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1255, {"proisagg"}, 16, 0, 1, 5, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1255, {"prosecdef"}, 16, 0, 1, 6, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1255, {"proisstrict"}, 16, 0, 1, 7, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1255, {"proretset"}, 16, 0, 1, 8, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1255, {"provolatile"}, 18, 0, 1, 9, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1255, {"pronargs"}, 21, 0, 2, 10, 0, -1, -1, true, 'p', false, 's', true, false, false }, \
{ 1255, {"prorettype"}, 26, 0, 4, 11, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1255, {"proargtypes"}, 30, 0, INDEX_MAX_KEYS*4, 12, 0, -1, -1, false, 'p', false, 'i', true, false, false }, \
{ 1255, {"prosrc"}, 25, 0, -1, 13, 0, -1, -1, false, 'x', false, 'i', false, false, false }, \
{ 1255, {"probin"}, 17, 0, -1, 14, 0, -1, -1, false, 'x', false, 'i', false, false, false }, \
{ 1255, {"proacl"}, 1034, 0, -1, 15, 0, -1, -1, false, 'x', false, 'i', false, false, false }
DATA(insert ( 1255 proname 19 -1 NAMEDATALEN 1 0 -1 -1 f p f i f f));
DATA(insert ( 1255 pronamespace 26 0 4 2 0 -1 -1 t p f i f f));
DATA(insert ( 1255 proowner 23 0 4 3 0 -1 -1 t p f i f f));
DATA(insert ( 1255 prolang 26 0 4 4 0 -1 -1 t p f i f f));
DATA(insert ( 1255 proisagg 16 0 1 5 0 -1 -1 t p f c f f));
DATA(insert ( 1255 prosecdef 16 0 1 6 0 -1 -1 t p f c f f));
DATA(insert ( 1255 proisstrict 16 0 1 7 0 -1 -1 t p f c f f));
DATA(insert ( 1255 proretset 16 0 1 8 0 -1 -1 t p f c f f));
DATA(insert ( 1255 provolatile 18 0 1 9 0 -1 -1 t p f c f f));
DATA(insert ( 1255 pronargs 21 0 2 10 0 -1 -1 t p f s f f));
DATA(insert ( 1255 prorettype 26 0 4 11 0 -1 -1 t p f i f f));
DATA(insert ( 1255 proargtypes 30 0 INDEX_MAX_KEYS*4 12 0 -1 -1 f p f i f f));
DATA(insert ( 1255 prosrc 25 0 -1 13 0 -1 -1 f x f i f f));
DATA(insert ( 1255 probin 17 0 -1 14 0 -1 -1 f x f i f f));
DATA(insert ( 1255 proacl 1034 0 -1 15 0 -1 -1 f x f i f f));
DATA(insert ( 1255 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
DATA(insert ( 1255 oid 26 0 4 -2 0 -1 -1 t p f i f f));
DATA(insert ( 1255 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
DATA(insert ( 1255 cmin 29 0 4 -4 0 -1 -1 t p f i f f));
DATA(insert ( 1255 xmax 28 0 4 -5 0 -1 -1 t p f i f f));
DATA(insert ( 1255 cmax 29 0 4 -6 0 -1 -1 t p f i f f));
DATA(insert ( 1255 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
DATA(insert ( 1255 proname 19 -1 NAMEDATALEN 1 0 -1 -1 f p f i t f f));
DATA(insert ( 1255 pronamespace 26 0 4 2 0 -1 -1 t p f i t f f));
DATA(insert ( 1255 proowner 23 0 4 3 0 -1 -1 t p f i t f f));
DATA(insert ( 1255 prolang 26 0 4 4 0 -1 -1 t p f i t f f));
DATA(insert ( 1255 proisagg 16 0 1 5 0 -1 -1 t p f c t f f));
DATA(insert ( 1255 prosecdef 16 0 1 6 0 -1 -1 t p f c t f f));
DATA(insert ( 1255 proisstrict 16 0 1 7 0 -1 -1 t p f c t f f));
DATA(insert ( 1255 proretset 16 0 1 8 0 -1 -1 t p f c t f f));
DATA(insert ( 1255 provolatile 18 0 1 9 0 -1 -1 t p f c t f f));
DATA(insert ( 1255 pronargs 21 0 2 10 0 -1 -1 t p f s t f f));
DATA(insert ( 1255 prorettype 26 0 4 11 0 -1 -1 t p f i t f f));
DATA(insert ( 1255 proargtypes 30 0 INDEX_MAX_KEYS*4 12 0 -1 -1 f p f i t f f));
DATA(insert ( 1255 prosrc 25 0 -1 13 0 -1 -1 f x f i f f f));
DATA(insert ( 1255 probin 17 0 -1 14 0 -1 -1 f x f i f f f));
DATA(insert ( 1255 proacl 1034 0 -1 15 0 -1 -1 f x f i f f f));
DATA(insert ( 1255 ctid 27 0 6 -1 0 -1 -1 f p f i t f f));
DATA(insert ( 1255 oid 26 0 4 -2 0 -1 -1 t p f i t f f));
DATA(insert ( 1255 xmin 28 0 4 -3 0 -1 -1 t p f i t f f));
DATA(insert ( 1255 cmin 29 0 4 -4 0 -1 -1 t p f i t f f));
DATA(insert ( 1255 xmax 28 0 4 -5 0 -1 -1 t p f i t f f));
DATA(insert ( 1255 cmax 29 0 4 -6 0 -1 -1 t p f i t f f));
DATA(insert ( 1255 tableoid 26 0 4 -7 0 -1 -1 t p f i t f f));
/* ----------------
* pg_shadow
* ----------------
*/
DATA(insert ( 1260 usename 19 -1 NAMEDATALEN 1 0 -1 -1 f p f i f f));
DATA(insert ( 1260 usesysid 23 -1 4 2 0 -1 -1 t p f i f f));
DATA(insert ( 1260 usecreatedb 16 0 1 3 0 -1 -1 t p f c f f));
DATA(insert ( 1260 usesuper 16 0 1 4 0 -1 -1 t p f c f f));
DATA(insert ( 1260 usecatupd 16 0 1 5 0 -1 -1 t p f c f f));
DATA(insert ( 1260 passwd 25 0 -1 6 0 -1 -1 f x f i f f));
DATA(insert ( 1260 valuntil 702 0 4 7 0 -1 -1 t p f i f f));
DATA(insert ( 1260 useconfig 1009 0 -1 8 0 -1 -1 f x f i f f));
DATA(insert ( 1260 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
DATA(insert ( 1260 usename 19 -1 NAMEDATALEN 1 0 -1 -1 f p f i t f f));
DATA(insert ( 1260 usesysid 23 -1 4 2 0 -1 -1 t p f i t f f));
DATA(insert ( 1260 usecreatedb 16 0 1 3 0 -1 -1 t p f c t f f));
DATA(insert ( 1260 usesuper 16 0 1 4 0 -1 -1 t p f c t f f));
DATA(insert ( 1260 usecatupd 16 0 1 5 0 -1 -1 t p f c t f f));
DATA(insert ( 1260 passwd 25 0 -1 6 0 -1 -1 f x f i f f f));
DATA(insert ( 1260 valuntil 702 0 4 7 0 -1 -1 t p f i f f f));
DATA(insert ( 1260 useconfig 1009 0 -1 8 0 -1 -1 f x f i f f f));
DATA(insert ( 1260 ctid 27 0 6 -1 0 -1 -1 f p f i t f f));
/* no OIDs in pg_shadow */
DATA(insert ( 1260 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
DATA(insert ( 1260 cmin 29 0 4 -4 0 -1 -1 t p f i f f));
DATA(insert ( 1260 xmax 28 0 4 -5 0 -1 -1 t p f i f f));
DATA(insert ( 1260 cmax 29 0 4 -6 0 -1 -1 t p f i f f));
DATA(insert ( 1260 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
DATA(insert ( 1260 xmin 28 0 4 -3 0 -1 -1 t p f i t f f));
DATA(insert ( 1260 cmin 29 0 4 -4 0 -1 -1 t p f i t f f));
DATA(insert ( 1260 xmax 28 0 4 -5 0 -1 -1 t p f i t f f));
DATA(insert ( 1260 cmax 29 0 4 -6 0 -1 -1 t p f i t f f));
DATA(insert ( 1260 tableoid 26 0 4 -7 0 -1 -1 t p f i t f f));
/* ----------------
* pg_group
* ----------------
*/
DATA(insert ( 1261 groname 19 -1 NAMEDATALEN 1 0 -1 -1 f p f i f f));
DATA(insert ( 1261 grosysid 23 -1 4 2 0 -1 -1 t p f i f f));
DATA(insert ( 1261 grolist 1007 0 -1 3 0 -1 -1 f x f i f f));
DATA(insert ( 1261 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
DATA(insert ( 1261 groname 19 -1 NAMEDATALEN 1 0 -1 -1 f p f i t f f));
DATA(insert ( 1261 grosysid 23 -1 4 2 0 -1 -1 t p f i t f f));
DATA(insert ( 1261 grolist 1007 0 -1 3 0 -1 -1 f x f i f f f));
DATA(insert ( 1261 ctid 27 0 6 -1 0 -1 -1 f p f i t f f));
/* no OIDs in pg_group */
DATA(insert ( 1261 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
DATA(insert ( 1261 cmin 29 0 4 -4 0 -1 -1 t p f i f f));
DATA(insert ( 1261 xmax 28 0 4 -5 0 -1 -1 t p f i f f));
DATA(insert ( 1261 cmax 29 0 4 -6 0 -1 -1 t p f i f f));
DATA(insert ( 1261 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
DATA(insert ( 1261 xmin 28 0 4 -3 0 -1 -1 t p f i t f f));
DATA(insert ( 1261 cmin 29 0 4 -4 0 -1 -1 t p f i t f f));
DATA(insert ( 1261 xmax 28 0 4 -5 0 -1 -1 t p f i t f f));
DATA(insert ( 1261 cmax 29 0 4 -6 0 -1 -1 t p f i t f f));
DATA(insert ( 1261 tableoid 26 0 4 -7 0 -1 -1 t p f i t f f));
/* ----------------
* pg_attribute
* ----------------
*/
#define Schema_pg_attribute \
{ 1249, {"attrelid"}, 26, -1, 4, 1, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1249, {"attname"}, 19, -1, NAMEDATALEN, 2, 0, -1, -1, false, 'p', false, 'i', false, false }, \
{ 1249, {"atttypid"}, 26, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1249, {"attstattarget"}, 23, 0, 4, 4, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1249, {"attlen"}, 21, 0, 2, 5, 0, -1, -1, true, 'p', false, 's', false, false }, \
{ 1249, {"attnum"}, 21, 0, 2, 6, 0, -1, -1, true, 'p', false, 's', false, false }, \
{ 1249, {"attndims"}, 23, 0, 4, 7, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1249, {"attcacheoff"}, 23, 0, 4, 8, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1249, {"atttypmod"}, 23, 0, 4, 9, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1249, {"attbyval"}, 16, 0, 1, 10, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1249, {"attstorage"}, 18, 0, 1, 11, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1249, {"attisset"}, 16, 0, 1, 12, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1249, {"attalign"}, 18, 0, 1, 13, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1249, {"attnotnull"}, 16, 0, 1, 14, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1249, {"atthasdef"}, 16, 0, 1, 15, 0, -1, -1, true, 'p', false, 'c', false, false }
{ 1249, {"attrelid"}, 26, -1, 4, 1, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1249, {"attname"}, 19, -1, NAMEDATALEN, 2, 0, -1, -1, false, 'p', false, 'i', true, false, false }, \
{ 1249, {"atttypid"}, 26, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1249, {"attstattarget"}, 23, 0, 4, 4, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1249, {"attlen"}, 21, 0, 2, 5, 0, -1, -1, true, 'p', false, 's', true, false, false }, \
{ 1249, {"attnum"}, 21, 0, 2, 6, 0, -1, -1, true, 'p', false, 's', true, false, false }, \
{ 1249, {"attndims"}, 23, 0, 4, 7, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1249, {"attcacheoff"}, 23, 0, 4, 8, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1249, {"atttypmod"}, 23, 0, 4, 9, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1249, {"attbyval"}, 16, 0, 1, 10, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1249, {"attstorage"}, 18, 0, 1, 11, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1249, {"attisset"}, 16, 0, 1, 12, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1249, {"attalign"}, 18, 0, 1, 13, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1249, {"attnotnull"}, 16, 0, 1, 14, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1249, {"atthasdef"}, 16, 0, 1, 15, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1249, {"attisdropped"}, 16, 0, 1, 16, 0, -1, -1, true, 'p', false, 'c', true, false, false }
DATA(insert ( 1249 attrelid 26 -1 4 1 0 -1 -1 t p f i f f));
DATA(insert ( 1249 attname 19 -1 NAMEDATALEN 2 0 -1 -1 f p f i f f));
DATA(insert ( 1249 atttypid 26 0 4 3 0 -1 -1 t p f i f f));
DATA(insert ( 1249 attstattarget 23 0 4 4 0 -1 -1 t p f i f f));
DATA(insert ( 1249 attlen 21 0 2 5 0 -1 -1 t p f s f f));
DATA(insert ( 1249 attnum 21 0 2 6 0 -1 -1 t p f s f f));
DATA(insert ( 1249 attndims 23 0 4 7 0 -1 -1 t p f i f f));
DATA(insert ( 1249 attcacheoff 23 0 4 8 0 -1 -1 t p f i f f));
DATA(insert ( 1249 atttypmod 23 0 4 9 0 -1 -1 t p f i f f));
DATA(insert ( 1249 attbyval 16 0 1 10 0 -1 -1 t p f c f f));
DATA(insert ( 1249 attstorage 18 0 1 11 0 -1 -1 t p f c f f));
DATA(insert ( 1249 attisset 16 0 1 12 0 -1 -1 t p f c f f));
DATA(insert ( 1249 attalign 18 0 1 13 0 -1 -1 t p f c f f));
DATA(insert ( 1249 attnotnull 16 0 1 14 0 -1 -1 t p f c f f));
DATA(insert ( 1249 atthasdef 16 0 1 15 0 -1 -1 t p f c f f));
DATA(insert ( 1249 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
DATA(insert ( 1249 attrelid 26 -1 4 1 0 -1 -1 t p f i t f f));
DATA(insert ( 1249 attname 19 -1 NAMEDATALEN 2 0 -1 -1 f p f i t f f));
DATA(insert ( 1249 atttypid 26 0 4 3 0 -1 -1 t p f i t f f));
DATA(insert ( 1249 attstattarget 23 0 4 4 0 -1 -1 t p f i t f f));
DATA(insert ( 1249 attlen 21 0 2 5 0 -1 -1 t p f s t f f));
DATA(insert ( 1249 attnum 21 0 2 6 0 -1 -1 t p f s t f f));
DATA(insert ( 1249 attndims 23 0 4 7 0 -1 -1 t p f i t f f));
DATA(insert ( 1249 attcacheoff 23 0 4 8 0 -1 -1 t p f i t f f));
DATA(insert ( 1249 atttypmod 23 0 4 9 0 -1 -1 t p f i t f f));
DATA(insert ( 1249 attbyval 16 0 1 10 0 -1 -1 t p f c t f f));
DATA(insert ( 1249 attstorage 18 0 1 11 0 -1 -1 t p f c t f f));
DATA(insert ( 1249 attisset 16 0 1 12 0 -1 -1 t p f c t f f));
DATA(insert ( 1249 attalign 18 0 1 13 0 -1 -1 t p f c t f f));
DATA(insert ( 1249 attnotnull 16 0 1 14 0 -1 -1 t p f c t f f));
DATA(insert ( 1249 atthasdef 16 0 1 15 0 -1 -1 t p f c t f f));
DATA(insert ( 1249 attisdropped 16 0 1 16 0 -1 -1 t p f c t f f));
DATA(insert ( 1249 ctid 27 0 6 -1 0 -1 -1 f p f i t f f));
/* no OIDs in pg_attribute */
DATA(insert ( 1249 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
DATA(insert ( 1249 cmin 29 0 4 -4 0 -1 -1 t p f i f f));
DATA(insert ( 1249 xmax 28 0 4 -5 0 -1 -1 t p f i f f));
DATA(insert ( 1249 cmax 29 0 4 -6 0 -1 -1 t p f i f f));
DATA(insert ( 1249 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
DATA(insert ( 1249 xmin 28 0 4 -3 0 -1 -1 t p f i t f f));
DATA(insert ( 1249 cmin 29 0 4 -4 0 -1 -1 t p f i t f f));
DATA(insert ( 1249 xmax 28 0 4 -5 0 -1 -1 t p f i t f f));
DATA(insert ( 1249 cmax 29 0 4 -6 0 -1 -1 t p f i t f f));
DATA(insert ( 1249 tableoid 26 0 4 -7 0 -1 -1 t p f i t f f));
/* ----------------
* pg_class
* ----------------
*/
#define Schema_pg_class \
{ 1259, {"relname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', false, 'i', false, false }, \
{ 1259, {"relnamespace"}, 26, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1259, {"reltype"}, 26, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1259, {"relowner"}, 23, 0, 4, 4, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1259, {"relam"}, 26, 0, 4, 5, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1259, {"relfilenode"}, 26, 0, 4, 6, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1259, {"relpages"}, 23, 0, 4, 7, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1259, {"reltuples"}, 700, 0, 4, 8, 0, -1, -1, false, 'p', false, 'i', false, false }, \
{ 1259, {"reltoastrelid"}, 26, 0, 4, 9, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1259, {"reltoastidxid"}, 26, 0, 4, 10, 0, -1, -1, true, 'p', false, 'i', false, false }, \
{ 1259, {"relhasindex"}, 16, 0, 1, 11, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1259, {"relisshared"}, 16, 0, 1, 12, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1259, {"relkind"}, 18, 0, 1, 13, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1259, {"relnatts"}, 21, 0, 2, 14, 0, -1, -1, true, 'p', false, 's', false, false }, \
{ 1259, {"relchecks"}, 21, 0, 2, 15, 0, -1, -1, true, 'p', false, 's', false, false }, \
{ 1259, {"reltriggers"}, 21, 0, 2, 16, 0, -1, -1, true, 'p', false, 's', false, false }, \
{ 1259, {"relukeys"}, 21, 0, 2, 17, 0, -1, -1, true, 'p', false, 's', false, false }, \
{ 1259, {"relfkeys"}, 21, 0, 2, 18, 0, -1, -1, true, 'p', false, 's', false, false }, \
{ 1259, {"relrefs"}, 21, 0, 2, 19, 0, -1, -1, true, 'p', false, 's', false, false }, \
{ 1259, {"relhasoids"}, 16, 0, 1, 20, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1259, {"relhaspkey"}, 16, 0, 1, 21, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1259, {"relhasrules"}, 16, 0, 1, 22, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1259, {"relhassubclass"},16, 0, 1, 23, 0, -1, -1, true, 'p', false, 'c', false, false }, \
{ 1259, {"relacl"}, 1034, 0, -1, 24, 0, -1, -1, false, 'x', false, 'i', false, false }
{ 1259, {"relname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', false, 'i', true, false, false }, \
{ 1259, {"relnamespace"}, 26, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1259, {"reltype"}, 26, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1259, {"relowner"}, 23, 0, 4, 4, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1259, {"relam"}, 26, 0, 4, 5, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1259, {"relfilenode"}, 26, 0, 4, 6, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1259, {"relpages"}, 23, 0, 4, 7, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1259, {"reltuples"}, 700, 0, 4, 8, 0, -1, -1, false, 'p', false, 'i', true, false, false }, \
{ 1259, {"reltoastrelid"}, 26, 0, 4, 9, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1259, {"reltoastidxid"}, 26, 0, 4, 10, 0, -1, -1, true, 'p', false, 'i', true, false, false }, \
{ 1259, {"relhasindex"}, 16, 0, 1, 11, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1259, {"relisshared"}, 16, 0, 1, 12, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1259, {"relkind"}, 18, 0, 1, 13, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1259, {"relnatts"}, 21, 0, 2, 14, 0, -1, -1, true, 'p', false, 's', true, false, false }, \
{ 1259, {"relchecks"}, 21, 0, 2, 15, 0, -1, -1, true, 'p', false, 's', true, false, false }, \
{ 1259, {"reltriggers"}, 21, 0, 2, 16, 0, -1, -1, true, 'p', false, 's', true, false, false }, \
{ 1259, {"relukeys"}, 21, 0, 2, 17, 0, -1, -1, true, 'p', false, 's', true, false, false }, \
{ 1259, {"relfkeys"}, 21, 0, 2, 18, 0, -1, -1, true, 'p', false, 's', true, false, false }, \
{ 1259, {"relrefs"}, 21, 0, 2, 19, 0, -1, -1, true, 'p', false, 's', true, false, false }, \
{ 1259, {"relhasoids"}, 16, 0, 1, 20, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1259, {"relhaspkey"}, 16, 0, 1, 21, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1259, {"relhasrules"}, 16, 0, 1, 22, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1259, {"relhassubclass"},16, 0, 1, 23, 0, -1, -1, true, 'p', false, 'c', true, false, false }, \
{ 1259, {"relacl"}, 1034, 0, -1, 24, 0, -1, -1, false, 'x', false, 'i', false, false, false }
DATA(insert ( 1259 relname 19 -1 NAMEDATALEN 1 0 -1 -1 f p f i f f));
DATA(insert ( 1259 relnamespace 26 0 4 2 0 -1 -1 t p f i f f));
DATA(insert ( 1259 reltype 26 0 4 3 0 -1 -1 t p f i f f));
DATA(insert ( 1259 relowner 23 0 4 4 0 -1 -1 t p f i f f));
DATA(insert ( 1259 relam 26 0 4 5 0 -1 -1 t p f i f f));
DATA(insert ( 1259 relfilenode 26 0 4 6 0 -1 -1 t p f i f f));
DATA(insert ( 1259 relpages 23 0 4 7 0 -1 -1 t p f i f f));
DATA(insert ( 1259 reltuples 700 0 4 8 0 -1 -1 f p f i f f));
DATA(insert ( 1259 reltoastrelid 26 0 4 9 0 -1 -1 t p f i f f));
DATA(insert ( 1259 reltoastidxid 26 0 4 10 0 -1 -1 t p f i f f));
DATA(insert ( 1259 relhasindex 16 0 1 11 0 -1 -1 t p f c f f));
DATA(insert ( 1259 relisshared 16 0 1 12 0 -1 -1 t p f c f f));
DATA(insert ( 1259 relkind 18 0 1 13 0 -1 -1 t p f c f f));
DATA(insert ( 1259 relnatts 21 0 2 14 0 -1 -1 t p f s f f));
DATA(insert ( 1259 relchecks 21 0 2 15 0 -1 -1 t p f s f f));
DATA(insert ( 1259 reltriggers 21 0 2 16 0 -1 -1 t p f s f f));
DATA(insert ( 1259 relukeys 21 0 2 17 0 -1 -1 t p f s f f));
DATA(insert ( 1259 relfkeys 21 0 2 18 0 -1 -1 t p f s f f));
DATA(insert ( 1259 relrefs 21 0 2 19 0 -1 -1 t p f s f f));
DATA(insert ( 1259 relhasoids 16 0 1 20 0 -1 -1 t p f c f f));
DATA(insert ( 1259 relhaspkey 16 0 1 21 0 -1 -1 t p f c f f));
DATA(insert ( 1259 relhasrules 16 0 1 22 0 -1 -1 t p f c f f));
DATA(insert ( 1259 relhassubclass 16 0 1 23 0 -1 -1 t p f c f f));
DATA(insert ( 1259 relacl 1034 0 -1 24 0 -1 -1 f x f i f f));
DATA(insert ( 1259 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
DATA(insert ( 1259 oid 26 0 4 -2 0 -1 -1 t p f i f f));
DATA(insert ( 1259 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
DATA(insert ( 1259 cmin 29 0 4 -4 0 -1 -1 t p f i f f));
DATA(insert ( 1259 xmax 28 0 4 -5 0 -1 -1 t p f i f f));
DATA(insert ( 1259 cmax 29 0 4 -6 0 -1 -1 t p f i f f));
DATA(insert ( 1259 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
DATA(insert ( 1259 relname 19 -1 NAMEDATALEN 1 0 -1 -1 f p f i t f f));
DATA(insert ( 1259 relnamespace 26 0 4 2 0 -1 -1 t p f i t f f));
DATA(insert ( 1259 reltype 26 0 4 3 0 -1 -1 t p f i t f f));
DATA(insert ( 1259 relowner 23 0 4 4 0 -1 -1 t p f i t f f));
DATA(insert ( 1259 relam 26 0 4 5 0 -1 -1 t p f i t f f));
DATA(insert ( 1259 relfilenode 26 0 4 6 0 -1 -1 t p f i t f f));
DATA(insert ( 1259 relpages 23 0 4 7 0 -1 -1 t p f i t f f));
DATA(insert ( 1259 reltuples 700 0 4 8 0 -1 -1 f p f i t f f));
DATA(insert ( 1259 reltoastrelid 26 0 4 9 0 -1 -1 t p f i t f f));
DATA(insert ( 1259 reltoastidxid 26 0 4 10 0 -1 -1 t p f i t f f));
DATA(insert ( 1259 relhasindex 16 0 1 11 0 -1 -1 t p f c t f f));
DATA(insert ( 1259 relisshared 16 0 1 12 0 -1 -1 t p f c t f f));
DATA(insert ( 1259 relkind 18 0 1 13 0 -1 -1 t p f c t f f));
DATA(insert ( 1259 relnatts 21 0 2 14 0 -1 -1 t p f s t f f));
DATA(insert ( 1259 relchecks 21 0 2 15 0 -1 -1 t p f s t f f));
DATA(insert ( 1259 reltriggers 21 0 2 16 0 -1 -1 t p f s t f f));
DATA(insert ( 1259 relukeys 21 0 2 17 0 -1 -1 t p f s t f f));
DATA(insert ( 1259 relfkeys 21 0 2 18 0 -1 -1 t p f s t f f));
DATA(insert ( 1259 relrefs 21 0 2 19 0 -1 -1 t p f s t f f));
DATA(insert ( 1259 relhasoids 16 0 1 20 0 -1 -1 t p f c t f f));
DATA(insert ( 1259 relhaspkey 16 0 1 21 0 -1 -1 t p f c t f f));
DATA(insert ( 1259 relhasrules 16 0 1 22 0 -1 -1 t p f c t f f));
DATA(insert ( 1259 relhassubclass 16 0 1 23 0 -1 -1 t p f c t f f));
DATA(insert ( 1259 relacl 1034 0 -1 24 0 -1 -1 f x f i f f f));
DATA(insert ( 1259 ctid 27 0 6 -1 0 -1 -1 f p f i t f f));
DATA(insert ( 1259 oid 26 0 4 -2 0 -1 -1 t p f i t f f));
DATA(insert ( 1259 xmin 28 0 4 -3 0 -1 -1 t p f i t f f));
DATA(insert ( 1259 cmin 29 0 4 -4 0 -1 -1 t p f i t f f));
DATA(insert ( 1259 xmax 28 0 4 -5 0 -1 -1 t p f i t f f));
DATA(insert ( 1259 cmax 29 0 4 -6 0 -1 -1 t p f i t f f));
DATA(insert ( 1259 tableoid 26 0 4 -7 0 -1 -1 t p f i t f f));
/* ----------------
* pg_xactlock - this is not a real relation, but is a placeholder
@ -478,6 +484,6 @@ DATA(insert ( 1259 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
* table; and this entry is just to link to that one.
* ----------------
*/
DATA(insert ( 376 xactlockfoo 26 0 4 1 0 -1 -1 t p f i f f));
DATA(insert ( 376 xactlockfoo 26 0 4 1 0 -1 -1 t p f i t f f));
#endif /* PG_ATTRIBUTE_H */

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_class.h,v 1.69 2002/07/24 19:11:12 petere Exp $
* $Id: pg_class.h,v 1.70 2002/08/02 18:15:09 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -136,7 +136,7 @@ typedef FormData_pg_class *Form_pg_class;
DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 f f r 20 0 0 0 0 0 t f f f _null_ ));
DESCR("");
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 f f r 15 0 0 0 0 0 f f f f _null_ ));
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 f f r 16 0 0 0 0 0 f f f f _null_ ));
DESCR("");
DATA(insert OID = 1255 ( pg_proc PGNSP 81 PGUID 0 1255 0 0 0 0 f f r 15 0 0 0 0 0 t f f f _null_ ));
DESCR("");

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: executor.h,v 1.72 2002/07/20 15:12:55 tgl Exp $
* $Id: executor.h,v 1.73 2002/08/02 18:15:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -159,7 +159,6 @@ extern void ExecAssignScanType(CommonScanState *csstate,
TupleDesc tupDesc, bool shouldFree);
extern void ExecAssignScanTypeFromOuterPlan(Plan *node,
CommonScanState *csstate);
extern Form_pg_attribute ExecGetTypeInfo(Relation relDesc);
extern ExprContext *MakeExprContext(TupleTableSlot *slot,
MemoryContext queryContext);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parse_relation.h,v 1.34 2002/06/20 20:29:51 momjian Exp $
* $Id: parse_relation.h,v 1.35 2002/08/02 18:15:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -58,7 +58,7 @@ extern RangeTblEntry *addImplicitRTE(ParseState *pstate, RangeVar *relation);
extern void expandRTE(ParseState *pstate, RangeTblEntry *rte,
List **colnames, List **colvars);
extern List *expandRelAttrs(ParseState *pstate, RangeTblEntry *rte);
extern int attnameAttNum(Relation rd, char *a);
extern int attnameAttNum(Relation rd, const char *attname, bool sysColOK);
extern Name attnumAttName(Relation rd, int attid);
extern Oid attnumTypeId(Relation rd, int attid);

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: lsyscache.h,v 1.55 2002/07/12 18:43:19 tgl Exp $
* $Id: lsyscache.h,v 1.56 2002/08/02 18:15:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -18,9 +18,8 @@
extern bool op_in_opclass(Oid opno, Oid opclass);
extern bool op_requires_recheck(Oid opno, Oid opclass);
extern char *get_attname(Oid relid, AttrNumber attnum);
extern AttrNumber get_attnum(Oid relid, char *attname);
extern AttrNumber get_attnum(Oid relid, const char *attname);
extern Oid get_atttype(Oid relid, AttrNumber attnum);
extern bool get_attisset(Oid relid, char *attname);
extern int32 get_atttypmod(Oid relid, AttrNumber attnum);
extern void get_atttypetypmod(Oid relid, AttrNumber attnum,
Oid *typid, int32 *typmod);

View File

@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: syscache.h,v 1.51 2002/07/25 10:07:13 ishii Exp $
* $Id: syscache.h,v 1.52 2002/08/02 18:15:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -78,6 +78,10 @@ extern bool SearchSysCacheExists(int cacheId,
extern Oid GetSysCacheOid(int cacheId,
Datum key1, Datum key2, Datum key3, Datum key4);
extern HeapTuple SearchSysCacheAttName(Oid relid, const char *attname);
extern HeapTuple SearchSysCacheCopyAttName(Oid relid, const char *attname);
extern bool SearchSysCacheExistsAttName(Oid relid, const char *attname);
extern Datum SysCacheGetAttr(int cacheId, HeapTuple tup,
AttrNumber attributeNumber, bool *isNull);

View File

@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.42 2002/06/15 19:54:24 momjian Exp $
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.43 2002/08/02 18:15:09 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@ -1037,10 +1037,7 @@ plpgsql_parse_dblwordtype(char *string)
/*
* Fetch the named table field and it's type
*/
attrtup = SearchSysCache(ATTNAME,
ObjectIdGetDatum(classOid),
PointerGetDatum(word2),
0, 0);
attrtup = SearchSysCacheAttName(classOid, word2);
if (!HeapTupleIsValid(attrtup))
{
ReleaseSysCache(classtup);

View File

@ -635,9 +635,9 @@ delete from atacc1;
alter table atacc1 alter test set not null;
-- try altering a non-existent column, should fail
alter table atacc1 alter bar set not null;
ERROR: ALTER TABLE: relation "atacc1" has no column "bar"
ERROR: Relation "atacc1" has no column "bar"
alter table atacc1 alter bar drop not null;
ERROR: ALTER TABLE: relation "atacc1" has no column "bar"
ERROR: Relation "atacc1" has no column "bar"
-- try altering the oid column, should fail
alter table atacc1 alter oid set not null;
ERROR: ALTER TABLE: Cannot alter system attribute "oid"
@ -707,7 +707,7 @@ ERROR: pg_atoi: error in "wrong_datatype": can't parse "wrong_datatype"
alter table def_test alter column c2 set default 20;
-- set defaults on a non-existent column: this should fail
alter table def_test alter column c3 set default 30;
ERROR: ALTER TABLE: relation "def_test" has no column "c3"
ERROR: Relation "def_test" has no column "c3"
-- set defaults on views: we need to create a view, add a rule
-- to allow insertions into it, and then alter the view to add
-- a default
@ -735,3 +735,291 @@ select * from def_view_test;
drop rule def_view_test_ins on def_view_test;
drop view def_view_test;
drop table def_test;
-- alter table / drop column tests
-- try altering system catalogs, should fail
alter table pg_class drop column relname;
ERROR: ALTER TABLE: relation "pg_class" is a system catalog
-- try altering non-existent table, should fail
alter table foo drop column bar;
ERROR: Relation "foo" does not exist
-- test dropping columns
create table atacc1 (a int4 not null, b int4, c int4 not null, d int4);
insert into atacc1 values (1, 2, 3, 4);
alter table atacc1 drop a;
alter table atacc1 drop a;
ERROR: Relation "atacc1" has no column "a"
-- SELECTs
select * from atacc1;
b | c | d
---+---+---
2 | 3 | 4
(1 row)
select * from atacc1 order by a;
ERROR: Attribute "a" not found
select * from atacc1 order by "........pg.dropped.1........";
ERROR: Attribute "........pg.dropped.1........" not found
select * from atacc1 group by a;
ERROR: Attribute "a" not found
select * from atacc1 group by "........pg.dropped.1........";
ERROR: Attribute "........pg.dropped.1........" not found
select atacc1.* from atacc1;
b | c | d
---+---+---
2 | 3 | 4
(1 row)
select a from atacc1;
ERROR: Attribute "a" not found
select atacc1.a from atacc1;
ERROR: No such attribute atacc1.a
select b,c,d from atacc1;
b | c | d
---+---+---
2 | 3 | 4
(1 row)
select a,b,c,d from atacc1;
ERROR: Attribute "a" not found
select * from atacc1 where a = 1;
ERROR: Attribute "a" not found
select "........pg.dropped.1........" from atacc1;
ERROR: Attribute "........pg.dropped.1........" not found
select atacc1."........pg.dropped.1........" from atacc1;
ERROR: No such attribute atacc1.........pg.dropped.1........
select "........pg.dropped.1........",b,c,d from atacc1;
ERROR: Attribute "........pg.dropped.1........" not found
select * from atacc1 where "........pg.dropped.1........" = 1;
ERROR: Attribute "........pg.dropped.1........" not found
-- UPDATEs
update atacc1 set a = 3;
ERROR: Relation "atacc1" has no column "a"
update atacc1 set b = 2 where a = 3;
ERROR: Attribute "a" not found
update atacc1 set "........pg.dropped.1........" = 3;
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
update atacc1 set b = 2 where "........pg.dropped.1........" = 3;
ERROR: Attribute "........pg.dropped.1........" not found
-- INSERTs
insert into atacc1 values (10, 11, 12, 13);
ERROR: INSERT has more expressions than target columns
insert into atacc1 values (default, 11, 12, 13);
ERROR: INSERT has more expressions than target columns
insert into atacc1 values (11, 12, 13);
insert into atacc1 (a) values (10);
ERROR: Relation "atacc1" has no column "a"
insert into atacc1 (a) values (default);
ERROR: Relation "atacc1" has no column "a"
insert into atacc1 (a,b,c,d) values (10,11,12,13);
ERROR: Relation "atacc1" has no column "a"
insert into atacc1 (a,b,c,d) values (default,11,12,13);
ERROR: Relation "atacc1" has no column "a"
insert into atacc1 (b,c,d) values (11,12,13);
insert into atacc1 ("........pg.dropped.1........") values (10);
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
insert into atacc1 ("........pg.dropped.1........") values (default);
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
insert into atacc1 ("........pg.dropped.1........",b,c,d) values (10,11,12,13);
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
insert into atacc1 ("........pg.dropped.1........",b,c,d) values (default,11,12,13);
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
-- DELETEs
delete from atacc1 where a = 3;
ERROR: Attribute "a" not found
delete from atacc1 where "........pg.dropped.1........" = 3;
ERROR: Attribute "........pg.dropped.1........" not found
delete from atacc1;
-- try dropping a non-existent column, should fail
alter table atacc1 drop bar;
ERROR: Relation "atacc1" has no column "bar"
-- try dropping the oid column, should fail
alter table atacc1 drop oid;
ERROR: ALTER TABLE: Cannot drop system attribute "oid"
-- try creating a view and altering that, should fail
create view myview as select * from atacc1;
select * from myview;
b | c | d
---+---+---
(0 rows)
alter table myview drop d;
ERROR: ALTER TABLE: relation "myview" is not a table
drop view myview;
-- test some commands to make sure they fail on the dropped column
analyze atacc1(a);
ERROR: Relation "atacc1" has no column "a"
analyze atacc1("........pg.dropped.1........");
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
vacuum analyze atacc1(a);
ERROR: Relation "atacc1" has no column "a"
vacuum analyze atacc1("........pg.dropped.1........");
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
comment on column atacc1.a is 'testing';
ERROR: Relation "atacc1" has no column "a"
comment on column atacc1."........pg.dropped.1........" is 'testing';
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 alter a set storage plain;
ERROR: ALTER TABLE: relation "atacc1" has no column "a"
alter table atacc1 alter "........pg.dropped.1........" set storage plain;
ERROR: ALTER TABLE: relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 alter a set statistics 0;
ERROR: ALTER TABLE: relation "atacc1" has no column "a"
alter table atacc1 alter "........pg.dropped.1........" set statistics 0;
ERROR: ALTER TABLE: relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 alter a set default 3;
ERROR: Relation "atacc1" has no column "a"
alter table atacc1 alter "........pg.dropped.1........" set default 3;
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 alter a drop default;
ERROR: Relation "atacc1" has no column "a"
alter table atacc1 alter "........pg.dropped.1........" drop default;
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 alter a set not null;
ERROR: Relation "atacc1" has no column "a"
alter table atacc1 alter "........pg.dropped.1........" set not null;
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 alter a drop not null;
ERROR: Relation "atacc1" has no column "a"
alter table atacc1 alter "........pg.dropped.1........" drop not null;
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 rename a to x;
ERROR: renameatt: attribute "a" does not exist
alter table atacc1 rename "........pg.dropped.1........" to x;
ERROR: renameatt: attribute "........pg.dropped.1........" does not exist
alter table atacc1 add primary key(a);
ERROR: ALTER TABLE: column "a" named in key does not exist
alter table atacc1 add primary key("........pg.dropped.1........");
ERROR: ALTER TABLE: column "........pg.dropped.1........" named in key does not exist
alter table atacc1 add unique(a);
ERROR: ALTER TABLE: column "a" named in key does not exist
alter table atacc1 add unique("........pg.dropped.1........");
ERROR: ALTER TABLE: column "........pg.dropped.1........" named in key does not exist
alter table atacc1 add check (a > 3);
ERROR: Attribute "a" not found
alter table atacc1 add check ("........pg.dropped.1........" > 3);
ERROR: Attribute "........pg.dropped.1........" not found
create table atacc2 (id int4 unique);
NOTICE: CREATE TABLE / UNIQUE will create implicit index 'atacc2_id_key' for table 'atacc2'
alter table atacc1 add foreign key (a) references atacc2(id);
NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
ERROR: ALTER TABLE: column "a" referenced in foreign key constraint does not exist
alter table atacc1 add foreign key ("........pg.dropped.1........") references atacc2(id);
NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
ERROR: ALTER TABLE: column "........pg.dropped.1........" referenced in foreign key constraint does not exist
alter table atacc2 add foreign key (id) references atacc1(a);
NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
ERROR: UNIQUE constraint matching given keys for referenced table "atacc1" not found
alter table atacc2 add foreign key (id) references atacc1("........pg.dropped.1........");
NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
ERROR: UNIQUE constraint matching given keys for referenced table "atacc1" not found
drop table atacc2;
create index "testing_idx" on atacc1(a);
ERROR: DefineIndex: attribute "a" not found
create index "testing_idx" on atacc1("........pg.dropped.1........");
ERROR: DefineIndex: attribute "........pg.dropped.1........" not found
-- test create as and select into
insert into atacc1 values (21, 22, 23);
create table test1 as select * from atacc1;
select * from test1;
b | c | d
----+----+----
21 | 22 | 23
(1 row)
drop table test1;
select * into test2 from atacc1;
select * from test2;
b | c | d
----+----+----
21 | 22 | 23
(1 row)
drop table test2;
-- try dropping all columns
alter table atacc1 drop c;
alter table atacc1 drop d;
alter table atacc1 drop b;
ERROR: ALTER TABLE: Cannot drop last column from table "atacc1"
select * from atacc1;
b
----
21
(1 row)
drop table atacc1;
-- test inheritance
create table parent (a int, b int, c int);
insert into parent values (1, 2, 3);
alter table parent drop a;
create table child (d varchar(255)) inherits (parent);
insert into child values (12, 13, 'testing');
select * from parent;
b | c
----+----
2 | 3
12 | 13
(2 rows)
select * from child;
b | c | d
----+----+---------
12 | 13 | testing
(1 row)
alter table parent drop c;
select * from parent;
b
----
2
12
(2 rows)
select * from child;
b | d
----+---------
12 | testing
(1 row)
drop table child;
drop table parent;
-- test copy in/out
create table test (a int4, b int4, c int4);
insert into test values (1,2,3);
alter table test drop a;
copy test to stdout;
2 3
copy test(a) to stdout;
ERROR: Relation "test" has no column "a"
copy test("........pg.dropped.1........") to stdout;
ERROR: Relation "test" has no column "........pg.dropped.1........"
copy test from stdin;
ERROR: copy: line 1, Extra data after last expected column
lost synchronization with server, resetting connection
select * from test;
b | c
---+---
2 | 3
(1 row)
copy test from stdin;
select * from test;
b | c
----+----
2 | 3
21 | 22
(2 rows)
copy test(a) from stdin;
ERROR: Relation "test" has no column "a"
copy test("........pg.dropped.1........") from stdin;
ERROR: Relation "test" has no column "........pg.dropped.1........"
copy test(b,c) from stdin;
select * from test;
b | c
----+----
2 | 3
21 | 22
31 | 32
(3 rows)
drop table test;

View File

@ -29,26 +29,44 @@ COPY x (b, d) from stdin;
COPY x (a, b, c, d, e) from stdin;
-- non-existent column in column list: should fail
COPY x (xyz) from stdin;
ERROR: COPY: Specified column "xyz" does not exist
ERROR: Relation "x" has no column "xyz"
-- too many columns in column list: should fail
COPY x (a, b, c, d, e, d, c) from stdin;
ERROR: COPY: Too many columns specified
ERROR: Attribute "d" specified more than once
-- missing data: should fail
COPY x from stdin;
ERROR: copy: line 1, COPY TEXT: Missing data for attribute 1
ERROR: copy: line 1, Missing data for column "b"
lost synchronization with server, resetting connection
COPY x from stdin;
ERROR: copy: line 1, COPY TEXT: Missing data for attribute 4
ERROR: copy: line 1, Missing data for column "e"
lost synchronization with server, resetting connection
COPY x from stdin;
ERROR: copy: line 1, COPY TEXT: Missing data for attribute 4
ERROR: copy: line 1, Missing data for column "e"
lost synchronization with server, resetting connection
-- extra data: should fail
COPY x from stdin;
ERROR: copy: line 1, COPY TEXT: Extra data encountered
ERROR: copy: line 1, Extra data after last expected column
lost synchronization with server, resetting connection
-- various COPY options: delimiters, oids, NULL string
COPY x (b, c, d, e) from stdin with oids delimiter ',' null 'x';
-- check results of copy in
SELECT * FROM x;
a | b | c | d | e
-------+----+-------+--------+----------------------
10000 | 21 | 31 | 41 | before trigger fired
10001 | 22 | 32 | 42 | before trigger fired
10002 | 23 | 33 | 43 | before trigger fired
10003 | 24 | 34 | 44 | before trigger fired
10004 | 25 | 35 | 45 | before trigger fired
10005 | 26 | 36 | 46 | before trigger fired
6 | | 45 | 80 | before trigger fired
1 | 1 | stuff | test_1 | after trigger fired
2 | 2 | stuff | test_2 | after trigger fired
3 | 3 | stuff | test_3 | after trigger fired
4 | 4 | stuff | test_4 | after trigger fired
5 | 5 | stuff | test_5 | after trigger fired
(12 rows)
-- COPY w/ oids on a table w/o oids should fail
CREATE TABLE no_oids (
a int,
@ -61,6 +79,7 @@ COPY no_oids FROM stdin WITH OIDS;
ERROR: COPY: table "no_oids" does not have OIDs
COPY no_oids TO stdout WITH OIDS;
ERROR: COPY: table "no_oids" does not have OIDs
-- check copy out
COPY x TO stdout;
10000 21 31 41 before trigger fired
10001 22 32 42 before trigger fired
@ -87,6 +106,19 @@ stuff after trigger fired
stuff after trigger fired
stuff after trigger fired
stuff after trigger fired
COPY x (b, e) TO stdout WITH NULL 'I''m null';
21 before trigger fired
22 before trigger fired
23 before trigger fired
24 before trigger fired
25 before trigger fired
26 before trigger fired
I'm null before trigger fired
1 after trigger fired
2 after trigger fired
3 after trigger fired
4 after trigger fired
5 after trigger fired
DROP TABLE x;
DROP FUNCTION fn_x_before();
DROP FUNCTION fn_x_after();

View File

@ -571,3 +571,163 @@ select * from def_view_test;
drop rule def_view_test_ins on def_view_test;
drop view def_view_test;
drop table def_test;
-- alter table / drop column tests
-- try altering system catalogs, should fail
alter table pg_class drop column relname;
-- try altering non-existent table, should fail
alter table foo drop column bar;
-- test dropping columns
create table atacc1 (a int4 not null, b int4, c int4 not null, d int4);
insert into atacc1 values (1, 2, 3, 4);
alter table atacc1 drop a;
alter table atacc1 drop a;
-- SELECTs
select * from atacc1;
select * from atacc1 order by a;
select * from atacc1 order by "........pg.dropped.1........";
select * from atacc1 group by a;
select * from atacc1 group by "........pg.dropped.1........";
select atacc1.* from atacc1;
select a from atacc1;
select atacc1.a from atacc1;
select b,c,d from atacc1;
select a,b,c,d from atacc1;
select * from atacc1 where a = 1;
select "........pg.dropped.1........" from atacc1;
select atacc1."........pg.dropped.1........" from atacc1;
select "........pg.dropped.1........",b,c,d from atacc1;
select * from atacc1 where "........pg.dropped.1........" = 1;
-- UPDATEs
update atacc1 set a = 3;
update atacc1 set b = 2 where a = 3;
update atacc1 set "........pg.dropped.1........" = 3;
update atacc1 set b = 2 where "........pg.dropped.1........" = 3;
-- INSERTs
insert into atacc1 values (10, 11, 12, 13);
insert into atacc1 values (default, 11, 12, 13);
insert into atacc1 values (11, 12, 13);
insert into atacc1 (a) values (10);
insert into atacc1 (a) values (default);
insert into atacc1 (a,b,c,d) values (10,11,12,13);
insert into atacc1 (a,b,c,d) values (default,11,12,13);
insert into atacc1 (b,c,d) values (11,12,13);
insert into atacc1 ("........pg.dropped.1........") values (10);
insert into atacc1 ("........pg.dropped.1........") values (default);
insert into atacc1 ("........pg.dropped.1........",b,c,d) values (10,11,12,13);
insert into atacc1 ("........pg.dropped.1........",b,c,d) values (default,11,12,13);
-- DELETEs
delete from atacc1 where a = 3;
delete from atacc1 where "........pg.dropped.1........" = 3;
delete from atacc1;
-- try dropping a non-existent column, should fail
alter table atacc1 drop bar;
-- try dropping the oid column, should fail
alter table atacc1 drop oid;
-- try creating a view and altering that, should fail
create view myview as select * from atacc1;
select * from myview;
alter table myview drop d;
drop view myview;
-- test some commands to make sure they fail on the dropped column
analyze atacc1(a);
analyze atacc1("........pg.dropped.1........");
vacuum analyze atacc1(a);
vacuum analyze atacc1("........pg.dropped.1........");
comment on column atacc1.a is 'testing';
comment on column atacc1."........pg.dropped.1........" is 'testing';
alter table atacc1 alter a set storage plain;
alter table atacc1 alter "........pg.dropped.1........" set storage plain;
alter table atacc1 alter a set statistics 0;
alter table atacc1 alter "........pg.dropped.1........" set statistics 0;
alter table atacc1 alter a set default 3;
alter table atacc1 alter "........pg.dropped.1........" set default 3;
alter table atacc1 alter a drop default;
alter table atacc1 alter "........pg.dropped.1........" drop default;
alter table atacc1 alter a set not null;
alter table atacc1 alter "........pg.dropped.1........" set not null;
alter table atacc1 alter a drop not null;
alter table atacc1 alter "........pg.dropped.1........" drop not null;
alter table atacc1 rename a to x;
alter table atacc1 rename "........pg.dropped.1........" to x;
alter table atacc1 add primary key(a);
alter table atacc1 add primary key("........pg.dropped.1........");
alter table atacc1 add unique(a);
alter table atacc1 add unique("........pg.dropped.1........");
alter table atacc1 add check (a > 3);
alter table atacc1 add check ("........pg.dropped.1........" > 3);
create table atacc2 (id int4 unique);
alter table atacc1 add foreign key (a) references atacc2(id);
alter table atacc1 add foreign key ("........pg.dropped.1........") references atacc2(id);
alter table atacc2 add foreign key (id) references atacc1(a);
alter table atacc2 add foreign key (id) references atacc1("........pg.dropped.1........");
drop table atacc2;
create index "testing_idx" on atacc1(a);
create index "testing_idx" on atacc1("........pg.dropped.1........");
-- test create as and select into
insert into atacc1 values (21, 22, 23);
create table test1 as select * from atacc1;
select * from test1;
drop table test1;
select * into test2 from atacc1;
select * from test2;
drop table test2;
-- try dropping all columns
alter table atacc1 drop c;
alter table atacc1 drop d;
alter table atacc1 drop b;
select * from atacc1;
drop table atacc1;
-- test inheritance
create table parent (a int, b int, c int);
insert into parent values (1, 2, 3);
alter table parent drop a;
create table child (d varchar(255)) inherits (parent);
insert into child values (12, 13, 'testing');
select * from parent;
select * from child;
alter table parent drop c;
select * from parent;
select * from child;
drop table child;
drop table parent;
-- test copy in/out
create table test (a int4, b int4, c int4);
insert into test values (1,2,3);
alter table test drop a;
copy test to stdout;
copy test(a) to stdout;
copy test("........pg.dropped.1........") to stdout;
copy test from stdin;
10 11 12
\.
select * from test;
copy test from stdin;
21 22
\.
select * from test;
copy test(a) from stdin;
copy test("........pg.dropped.1........") from stdin;
copy test(b,c) from stdin;
31 32
\.
select * from test;
drop table test;

View File

@ -76,6 +76,9 @@ COPY x (b, c, d, e) from stdin with oids delimiter ',' null 'x';
500000,x,45,80,90
\.
-- check results of copy in
SELECT * FROM x;
-- COPY w/ oids on a table w/o oids should fail
CREATE TABLE no_oids (
a int,
@ -89,8 +92,11 @@ INSERT INTO no_oids (a, b) VALUES (20, 30);
COPY no_oids FROM stdin WITH OIDS;
COPY no_oids TO stdout WITH OIDS;
-- check copy out
COPY x TO stdout;
COPY x (c, e) TO stdout;
COPY x (b, e) TO stdout WITH NULL 'I''m null';
DROP TABLE x;
DROP FUNCTION fn_x_before();
DROP FUNCTION fn_x_after();