From: | "Jason M(dot) Felice" <jfelice(at)cronosys(dot)com> |
---|---|
To: | pgsql-hackers(at)postgresql(dot)org |
Subject: | Re: SQL99 ARRAY support proposal |
Date: | 2003-03-10 17:04:06 |
Message-ID: | 20030310170406.GB2082@argo.eraserhead.net |
Views: | Whole Thread | Raw Message | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Mon, Mar 10, 2003 at 09:49:47AM -0500, Tom Lane wrote:
> Hannu Krosing <hannu(at)tm(dot)ee> writes:
> > Joe Conway kirjutas E, 10.03.2003 kell 05:35:
> >> CREATE OR REPLACE FUNCTION array_push (anyarray, anyscalar)
> >> RETURNS anyarray
>
> > could you make it
> > RETURNS typeof($1)
>
> Not directly --- we have to fit the return-type info into an OID field.
> We could fake it by inventing one or more pseudotypes, "SAMEASPARAMn".
>
> But I think I like better the notion of extending my bound-together-
> ANYARRAY-and-ANYELEMENT proposal,
> http://archives.postgresql.org/pgsql-hackers/2003-03/msg00319.php
>
> Suppose that we do that, and then further say that ANYARRAY or
> ANYELEMENT appearing as the return type implies that the return type
> is actually the common element or array type. Then we have such
> useful behaviors as:
>
> array_push(anyarray, anyelement) returns anyarray
> array_pop(anyarray) returns anyelement
> array_subscript(anyarray, int) yields anyelement
> singleton_array(anyelement) yields anyarray
>
> The last three cases cannot be handled by a SAMEASPARAM construct.
... typeof($1)[], or a ARRAYELEMSAMEASPARAM construct?
I'm really liking this discussion. I know this is sort of "out there", but
I have found in languages like StandardML and Objective CAML that templatized-
type functions are _extremely_ useful. These languages type systems are
amazingly powerful (the language syntax is another matter *sigh*).
I'm not necessarily suggesting implementing this, but I just want to feed the
debate a bit. I view the type system of these guys as "the ideal", and would
be in ecstacy if PostgreSQL had it, but I realize implementing the thing would
prolly be far from practical.
First, there are templatized types. Arrays in PostgreSQL are sort of a
kludge of templatized types, but they would be defined like so:
type a' array = <some definition ...>
which means that you are describing an array of some type a' (the apostrophe
indicates a type variable).
You can also create other neat templatized types as an aside:
type a' Nullable = Null | Value of a'
Which means the expressions:
Value 47 --> of type int Nullable
Null --> of type a' Nullable (determined from context)
But then, you could also say:
int array array
Or even:
int Nullable array
Which is somthing you can't in PostgreSQL but would be very nice. But then
you could say:
let invert_matrix m : a' array array -> a' array array = <code...>
let multiply x : a', y : a' -> a' = <code ...>
You could have more than one type variable in a templatized type or function,
true, but I've never really needed more than one. I can imagine cases where
it would be useful, but just haven't needed one.
Plus:
* get rid of horrible 'int4_' type hacks for array.
Minus:
* can't use oid to represent exact type, rather a string of oids.
* need second table to hold function type constraints when function
is templatized. (or could make it params "oid array array", aka
oid[][]!) Reserve eight or ten oids for template parameter slots
(in other words, for a' through j' or something).
Warning: I have been called the "type nazi" <g>
One other thing from StandardML that I have always wanted in PostgreSQL
(or anywhere else I program, for that matter)- record types. (Warning, this is
also very wishful thinking and "out there").
In ML/CAML, a record type is defined like so:
type myrecord = {
x : int,
y : int,
s : string
};
"myrecord" is actually just type alias, the canonical record definition is:
{s:string, x:int, y:int}
... with the attributes in alphabetical order, because unless you are mucking
with pointers in C, it really doesn't matter what order they are in. The
first advantage become very apparent: Any two records with the same named
attributes of the same types are always of the same type. In PostgreSQL,
this would mean that functions that operate on RECORD{x:int,y:int,s:string}
could operate on a record from any relation with those attributes.
Further, to make inheritance pretty much unnecesary, you could allow a
record with more attributes to satisfy a parameter or return value constraint.
In other words, you could call function foo(RECORD{x:int,y:int}) on a
RECORD{s:string,x:int,y:int}.
I've thought about this trick a lot. In theory there is a possibility of
not getting what you want, but in practice it would almost never happen. The
demostrative case would be calling distance_from_origin(RECORD{x:int,y:int})
on RECORD{x:int,y:int,z:int}, but in this case you need to make a
distance_from_origin(RECORD{x:int,y:int,z:int}).
This way, you could make a function which operates on RECORD{oid:oid} which
could be called on any record from a table. I've wanted to do this sort of
thing on several occasions- one application has notes which can be attached
to any row, sort of like PostgreSQL comments. Another to keep track of what
user changed which fields. Etc.
Alright.... heheh I didn't mean to ramble. /ME gets head out of clouds
and goes back to practical work <g>
>
> regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 1: subscribe and unsubscribe commands go to majordo0mo(at)postgresql(dot)org
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2003-03-10 17:20:26 | Re: SQL99 ARRAY support proposal |
Previous Message | Bruce Momjian | 2003-03-10 16:49:19 | Re: [GENERAL] division by zero |