On Fri, Mar 30, 2007 at 05:08:42PM -0400, Tom Lane wrote: > David Fetter <[EMAIL PROTECTED]> writes: > > After several rounds of patches, it appears that it might be easier to > > create a new typtype entry, which I'll tentatively call 'a' because it > > seems a little fragile and a lot inelegant and hard to maintain to > > have typtype='c' and typrelid=InvalidOid mean, "this is an array of > > complex types." > > Uh, wouldn't it be typtype = 'c' and typelem != 0 ?
Right. The attached patch passes the current regression tests and at least to a "smoke test" level does what it's supposed to do. I'd really like to help refactor the whole array system to use 'a', tho. Cheers, D -- David Fetter <[EMAIL PROTECTED]> http://fetter.org/ phone: +1 415 235 3778 AIM: dfetter666 Skype: davidfetter Remember to vote! Consider donating to PostgreSQL: http://www.postgresql.org/about/donate
Index: src/backend/catalog/heap.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/catalog/heap.c,v retrieving revision 1.318 diff -c -r1.318 heap.c *** src/backend/catalog/heap.c 2 Apr 2007 03:49:37 -0000 1.318 --- src/backend/catalog/heap.c 2 Apr 2007 20:09:16 -0000 *************** *** 45,50 **** --- 45,51 ---- #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" #include "commands/tablecmds.h" + #include "commands/typecmds.h" #include "miscadmin.h" #include "optimizer/clauses.h" #include "optimizer/var.h" *************** *** 763,768 **** --- 764,770 ---- Relation pg_class_desc; Relation new_rel_desc; Oid new_type_oid; + char *relarrayname; pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock); *************** *** 815,820 **** --- 817,856 ---- relnamespace, relid, relkind); + /* + * Add in the corresponding array types if appropriate. + */ + if (relkind == RELKIND_RELATION || + relkind == RELKIND_VIEW || + relkind == RELKIND_COMPOSITE_TYPE) + { + relarrayname = makeArrayTypeName(relname); + TypeCreate(relarrayname, /* Array type name */ + relnamespace, /* Same namespace as parent */ + InvalidOid, /* relation's type oid, set here to InvalidOid to make dependency work right */ + 0, /* relkind, also N/A here */ + -1, /* Internal size, unlimited */ + 'c', /* It's a complex type */ + DEFAULT_TYPDELIM, /* Use the default */ + F_ARRAY_IN, /* Macro for array input procedure */ + F_ARRAY_OUT, /* Macro for array output procedure */ + F_ARRAY_RECV, /* Macro for array receive (binary input) procedure */ + F_ARRAY_SEND, /* Macro for array send (binary output) procedure */ + InvalidOid, /* No input typmod */ + InvalidOid, /* No output typmod */ + InvalidOid, /* Default ANALYZE procedure */ + new_type_oid, /* The OID just created */ + InvalidOid, /* No base type--this isn't a DOMAIN */ + NULL, /* No default type value */ + NULL, /* Don't send binary */ + false, /* Never passed by value */ + 'd', /* Type alignment. Should this be something else? */ + 'x', /* Always TOASTable */ + -1, /* No typMod for regular composite types. */ + 0, /* Array diminsions of typbasetype */ + false); /* Type NOT NULL */ + pfree(relarrayname); /* Seems like the right thing to do here. */ + } /* * now create an entry in pg_class for the relation. Index: src/backend/commands/tablecmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablecmds.c,v retrieving revision 1.218 diff -c -r1.218 tablecmds.c *** src/backend/commands/tablecmds.c 19 Mar 2007 23:38:29 -0000 1.218 --- src/backend/commands/tablecmds.c 2 Apr 2007 20:09:17 -0000 *************** *** 287,298 **** Datum reloptions; ListCell *listptr; AttrNumber attnum; /* ! * Truncate relname to appropriate length (probably a waste of time, as ! * parser should have done this already). */ ! StrNCpy(relname, stmt->relation->relname, NAMEDATALEN); /* * Check consistency of arguments --- 287,309 ---- Datum reloptions; ListCell *listptr; AttrNumber attnum; + char *relarrayname; /* ! * Truncate relname to appropriate length (probably a waste of time, as * ! * parser should have done this already). Because tables and views now get ! * an array type, this depends on the relkind. */ ! if (relkind == RELKIND_RELATION || ! relkind == RELKIND_VIEW || ! relkind == RELKIND_COMPOSITE_TYPE) ! { ! StrNCpy(relname, stmt->relation->relname, NAMEDATALEN-2); ! } ! else ! { ! StrNCpy(relname, stmt->relation->relname, NAMEDATALEN); ! } /* * Check consistency of arguments *************** *** 6488,6495 **** AlterRelationNamespaceInternal(classRel, relid, oldNspOid, nspOid, true); ! /* Fix the table's rowtype too */ AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false); /* Fix other dependent stuff */ if (rel->rd_rel->relkind == RELKIND_RELATION) --- 6499,6507 ---- AlterRelationNamespaceInternal(classRel, relid, oldNspOid, nspOid, true); ! /* Fix the table's types too */ AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false); + AlterTypeNamespaceInternal(get_array_type(rel->rd_rel->reltype), nspOid, false); /* Fix other dependent stuff */ if (rel->rd_rel->relkind == RELKIND_RELATION) Index: src/backend/commands/typecmds.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/commands/typecmds.c,v retrieving revision 1.101 diff -c -r1.101 typecmds.c *** src/backend/commands/typecmds.c 2 Apr 2007 03:49:38 -0000 1.101 --- src/backend/commands/typecmds.c 2 Apr 2007 20:09:17 -0000 *************** *** 2367,2372 **** --- 2367,2375 ---- /* and do the work */ AlterTypeNamespaceInternal(typeOid, nspOid, true); + typeOid = get_array_type(typeOid); + if (typeOid != InvalidOid) + AlterTypeNamespaceInternal(typeOid, nspOid, true); } /* *************** *** 2431,2442 **** /* Detect whether type is a composite type (but not a table rowtype) */ isCompositeType = ! (typform->typtype == TYPTYPE_COMPOSITE && get_rel_relkind(typform->typrelid) == RELKIND_COMPOSITE_TYPE); /* Enforce not-table-type if requested */ if (typform->typtype == TYPTYPE_COMPOSITE && !isCompositeType && ! errorOnTableType) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("%s is a table's row type", --- 2434,2445 ---- /* Detect whether type is a composite type (but not a table rowtype) */ isCompositeType = ! (typform->typtype == TYPTYPE_COMPOSITE && typform->typrelid != InvalidOid && get_rel_relkind(typform->typrelid) == RELKIND_COMPOSITE_TYPE); /* Enforce not-table-type if requested */ if (typform->typtype == TYPTYPE_COMPOSITE && !isCompositeType && ! typform->typrelid != InvalidOid && errorOnTableType) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("%s is a table's row type", *************** *** 2457,2463 **** * We need to modify the pg_class tuple as well to reflect the change of * schema. */ ! if (isCompositeType) { Relation classRel; --- 2460,2466 ---- * We need to modify the pg_class tuple as well to reflect the change of * schema. */ ! if (isCompositeType && typform->typrelid != InvalidOid) { Relation classRel; *************** *** 2490,2496 **** * Update dependency on schema, if any --- a table rowtype has not got * one. */ ! if (typform->typtype != TYPTYPE_COMPOSITE) if (changeDependencyFor(TypeRelationId, typeOid, NamespaceRelationId, oldNspOid, nspOid) != 1) elog(ERROR, "failed to change schema dependency for type %s", --- 2493,2499 ---- * Update dependency on schema, if any --- a table rowtype has not got * one. */ ! if (typform->typtype != TYPTYPE_COMPOSITE || typform->typrelid == InvalidOid) if (changeDependencyFor(TypeRelationId, typeOid, NamespaceRelationId, oldNspOid, nspOid) != 1) elog(ERROR, "failed to change schema dependency for type %s", Index: src/test/regress/expected/alter_table.out =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/alter_table.out,v retrieving revision 1.101 diff -c -r1.101 alter_table.out *** src/test/regress/expected/alter_table.out 14 Feb 2007 01:58:58 -0000 1.101 --- src/test/regress/expected/alter_table.out 2 Apr 2007 20:09:19 -0000 *************** *** 1456,1468 **** --- 1456,1471 ---- -- clean up drop schema alter2 cascade; + NOTICE: drop cascades to type alter2.ctype[] NOTICE: drop cascades to composite type alter2.ctype NOTICE: drop cascades to type alter2.ctype NOTICE: drop cascades to type alter2.posint NOTICE: drop cascades to function alter2.plus1(integer) + NOTICE: drop cascades to type alter2.v1[] NOTICE: drop cascades to view alter2.v1 NOTICE: drop cascades to rule _RETURN on view alter2.v1 NOTICE: drop cascades to sequence alter2.t1_f1_seq NOTICE: drop cascades to default for table alter2.t1 column f1 + NOTICE: drop cascades to type alter2.t1[] NOTICE: drop cascades to table alter2.t1 NOTICE: drop cascades to constraint t1_f2_check on table alter2.t1 Index: src/test/regress/expected/type_sanity.out =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/type_sanity.out,v retrieving revision 1.29 diff -c -r1.29 type_sanity.out *** src/test/regress/expected/type_sanity.out 2 Apr 2007 03:49:42 -0000 1.29 --- src/test/regress/expected/type_sanity.out 2 Apr 2007 20:09:19 -0000 *************** *** 49,55 **** -- or basic types that do. SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR (p1.typtype != 'c' AND p1.typrelid != 0); oid | typname -----+--------- --- 49,55 ---- -- or basic types that do. SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0 AND p1.typname !~ '^_') OR (p1.typtype != 'c' AND p1.typrelid != 0); oid | typname -----+--------- Index: src/test/regress/sql/type_sanity.sql =================================================================== RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/type_sanity.sql,v retrieving revision 1.29 diff -c -r1.29 type_sanity.sql *** src/test/regress/sql/type_sanity.sql 2 Apr 2007 03:49:42 -0000 1.29 --- src/test/regress/sql/type_sanity.sql 2 Apr 2007 20:09:19 -0000 *************** *** 46,52 **** SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR (p1.typtype != 'c' AND p1.typrelid != 0); -- Look for basic or enum types that don't have an array type. --- 46,52 ---- SELECT p1.oid, p1.typname FROM pg_type as p1 ! WHERE (p1.typtype = 'c' AND p1.typrelid = 0 AND p1.typname !~ '^_') OR (p1.typtype != 'c' AND p1.typrelid != 0); -- Look for basic or enum types that don't have an array type.
---------------------------(end of broadcast)--------------------------- TIP 1: if posting/reading through Usenet, please send an appropriate subscribe-nomail command to [EMAIL PROTECTED] so that your message can get through to the mailing list cleanly