Thread: Bug in user-defined types?

Bug in user-defined types?

From
Adriaan Joubert
Date:
Hi,

    In response to comments made here, I have been rewriting the unsigned
types as externally loadable. Using the same routines that worked fine
when linked statically into the backend gives me core-dumps only.
Creating only a single uint2 type with I/O routines, I get

test=# create table u2 ( u uint2);
CREATE
test=# insert into u2 values (12::uint2);
pqReadData() -- backend closed the channel unexpectedly.
        This probably means the backend terminated abnormally
        before or while processing the request.

Running this under gdb (I tried this on alpha as well)

backend> insert into u2 values (12::uint2);
(no debugging symbols found)...
Program received signal SIGSEGV, Segmentation fault.
0x40115573 in memcpy () from /lib/libc.so.6
(gdb) where
#0  0x40115573 in memcpy () from /lib/libc.so.6
#1  0x80cfb92 in _copyConst ()
#2  0x80d25d9 in copyObject ()
#3  0x80ebad9 in expression_tree_mutator ()
#4  0x80eb407 in eval_const_expressions_mutator ()
#5  0x80ebe42 in expression_tree_mutator ()
#6  0x80eb407 in eval_const_expressions_mutator ()
#7  0x80ebdf2 in expression_tree_mutator ()
#8  0x80eb407 in eval_const_expressions_mutator ()
#9  0x80eaf87 in eval_const_expressions ()
#10 0x80e6d2a in preprocess_expression ()
#11 0x80e6751 in subquery_planner ()
#12 0x80e66c0 in planner ()
#13 0x81036e7 in pg_plan_query ()
#14 0x81038d9 in pg_exec_query_string ()
#15 0x81049d4 in PostgresMain ()
#16 0x80ce884 in main ()
#17 0x400d8a42 in __libc_start_main () from /lib/libc.so.6
(gdb)

It never seems to get to my code. So either I've defined something
incorrectly or there is a bug. I'd appreciate it if somebody more
knowledgable than I could have a look at it. I've included a tar with
the definitions.

BTW it may be good to update the complex example to the new C-calling
interface, as there is no example of creating a type with the new
calling interface.

Cheers,

Adriaan
Attachment

Re: Bug in user-defined types?

From
Tom Lane
Date:
Adriaan Joubert <a.joubert@albourne.com> writes:
>     In response to comments made here, I have been rewriting the unsigned
> types as externally loadable. Using the same routines that worked fine
> when linked statically into the backend gives me core-dumps only.

Seems unlikely that that code could have worked either way, since you
forgot to mark type uint2 as PASSEDBYVALUE...
        regards, tom lane


Re: Bug in user-defined types?

From
Adriaan Joubert
Date:
Tom Lane wrote:
> 
> Seems unlikely that that code could have worked either way, since you
> forgot to mark type uint2 as PASSEDBYVALUE...
> 

Aargh! Thanks! Yes, when implementing it in the backend, that was just a
field to fill in, so I did it there. All seems well now.

One ends up with a vast number of combinations of types combinations for
different operators. As C takes care of the conversions, I wrote a
30-line perl script to generate me nearly 1600 lines of C for all the
type combinations (+ ~1700 lines of sql to define the
functions/operators). I cannot help feeling that that is not the right
way: if it can be done in a few lines of perl and relies on C cross-type
operations underneath anyway, it seems wrong to have to generate all
this code. 

The problem is that there is not a clean hierarchy of SQL types, but for
many cases one could either convert the operands to int4 or float8 and
then numeric(?) and then convert back. At least the conversion operators
check for overflow, which is better than the current situation. And
precision wise it cannot be much worse: after all, large integer
constants already end up as floats. Is the SQL standard pedantic about
this?

BTW I could not find the discussion on entry-points to shared libraries
that Thomas mentioned. I've got some rushed dead-lines at the moment, so
I will not be able to look at anything for the next 3-4 weeks though.

Adriaan


Re: Bug in user-defined types?

From
Thomas Lockhart
Date:
> The problem is that there is not a clean hierarchy of SQL types, but for
> many cases one could either convert the operands to int4 or float8 and
> then numeric(?) and then convert back. At least the conversion operators
> check for overflow, which is better than the current situation. And
> precision wise it cannot be much worse: after all, large integer
> constants already end up as floats. Is the SQL standard pedantic about
> this?

Yes. The implicit "big integer" -> float8 done in the scanner is an
expedient hack to keep from rejecting the large number entirely, but is
likely not in the spirit of the SQL standard.

The Right Way would have us set the large integer string to int8 and/or
numeric, but the scanner does not know about those types at the moment,
mostly for historical reasons.

If we made the scanner aware of integers larger than int4, we would have
to choose between int8 (not supported on all platforms, but mostly OK)
and numeric, which is markedly slower to process and handle. I recall
that Tom Lane had the proposal to use a more loosely categorized "some
kind of numeric type" in the scanner, postponing the hard assignment of
type to later in the parser. That might get around the performance
issues, since numeric would only be used if the context required it.
                         - Thomas


Re: Re: Bug in user-defined types?

From
Tom Lane
Date:
Thomas Lockhart <lockhart@alumni.caltech.edu> writes:
> If we made the scanner aware of integers larger than int4, we would have
> to choose between int8 (not supported on all platforms, but mostly OK)
> and numeric, which is markedly slower to process and handle. I recall
> that Tom Lane had the proposal to use a more loosely categorized "some
> kind of numeric type" in the scanner, postponing the hard assignment of
> type to later in the parser. That might get around the performance
> issues, since numeric would only be used if the context required it.

Yes, I was thinking of treating numerical literals more like we already
treat unknown-type string literals: keep the value in string format
until we deduce from context which type it should be, then convert.
Internally this already happens for literals that don't fit in int4,
but we still prejudge the type sooner than I think we should.

IIRC, the main reason this isn't done yet was that we hadn't come to
a conclusion about the appropriate type promotion hierarchy for
numeric values.
        regards, tom lane