Thread: getTypeIOParam is wrong for domains over array types?
In lsyscache.c we have /* * Array types get their typelem as parameter; everybody else gets their * own type OID as parameter. (This isa change from 8.0, in which only * composite types got their own OID as parameter.) */ if (OidIsValid(typeStruct->typelem)) return typeStruct->typelem; else return HeapTupleGetOid(typeTuple); but it turns out that a domain over an array type has typelem set, and so domain_in gets passed the element type instead of the domain's own OID, leading to this misbehavior reported by Anton Pikhteryev: regression=# create domain ddd as name; CREATE DOMAIN regression=# create table foot(f1 ddd); CREATE TABLE regression=# copy foot from stdin; Enter data to be copied followed by a newline. End with a backslash and a period on a line by itself. >> dd >> \. ERROR: type "char" is not a domain CONTEXT: COPY foot, line 1, column f1: "dd" This failure is new in 8.2 --- in prior releases domain_in didn't exist and it was correct, indeed necessary, for domains to get exactly the same typioparam as their underlying type. I think probably the right solution is to adjust getTypeIOParam so that it only examines typelem for base types (typtype = 'b'). Can anyone see a downside to that? regards, tom lane
On 3/19/07, Tom Lane <tgl@sss.pgh.pa.us> wrote: > In lsyscache.c we have > > /* > * Array types get their typelem as parameter; everybody else gets their > * own type OID as parameter. (This is a change from 8.0, in which only > * composite types got their own OID as parameter.) > */ > if (OidIsValid(typeStruct->typelem)) > return typeStruct->typelem; > else > return HeapTupleGetOid(typeTuple); > > but it turns out that a domain over an array type has typelem set, and > so domain_in gets passed the element type instead of the domain's own > OID, leading to this misbehavior reported by Anton Pikhteryev: > > regression=# create domain ddd as name; > CREATE DOMAIN > regression=# create table foot(f1 ddd); > CREATE TABLE > regression=# copy foot from stdin; > Enter data to be copied followed by a newline. > End with a backslash and a period on a line by itself. > >> dd > >> \. > ERROR: type "char" is not a domain > CONTEXT: COPY foot, line 1, column f1: "dd" > > This failure is new in 8.2 --- in prior releases domain_in didn't exist > and it was correct, indeed necessary, for domains to get exactly the > same typioparam as their underlying type. > > I think probably the right solution is to adjust getTypeIOParam so that > it only examines typelem for base types (typtype = 'b'). Can anyone > see a downside to that? will that skip intermediate check constraints...so that if you have domain d1 int, d2 d1, d3 d2, and d2 has check constraint on it, will d2 constraint still get evaluated? or is this only for purposes if determining type? merlin
"Merlin Moncure" <mmoncure@gmail.com> writes: > On 3/19/07, Tom Lane <tgl@sss.pgh.pa.us> wrote: >> I think probably the right solution is to adjust getTypeIOParam so that >> it only examines typelem for base types (typtype = 'b'). Can anyone >> see a downside to that? > will that skip intermediate check constraints...so that if you have > domain d1 int, d2 d1, d3 d2, and d2 has check constraint on it, will > d2 constraint still get evaluated? Yeah, that'll still work. The point here is that domain_in has to be passed d3's type OID to start with. If we have a stack of nested domains over an array type, they'll all have typelem equal to the array element type (so that they can be subscripted the same as the base type could be). I think you're confusing typelem with typbasetype ... regards, tom lane