user-defined, komplexe typen

Hallo,

hat von Euch jemand Erfahrung damit? Insb. in Verbindung mit jdbc. Ich experimentiere gerade ein Wenig in diesem Thema und stoße (wie erwartet) auf Probleme.

Szenario:

  1. JDBC natürlich :slight_smile:
  2. ich möchte gern PreparedStatements verwenden für meine Inserts und Updates etc. Für komplexe Typen bzw. Objekte gibt es die Methoden setObject(…) … nur leider ereilt mich beim Versuch ein java.sql.Complex Objekt zuzuweisen dieser Fehler:
    Caused by: org.postgresql.util.PSQLException: Unbekannter Typ: 2.002.

Ich habe ein Wenig im PG-Jdbc Treiber gestöbert. Es scheint fast so, dass der aktuelle Treiber sowas garnicht unterstützt. Da er versucht, irgendwelche Datentypen zu erraten. Leider kann ich den Namen des richtigen (von mir gegeben) Namen nicht angeben, sondern nur sowas wie jene aus java.sql.Types.

Lohnt sich das Thema user-defined types überhaupt ? Oder ist das i.d.R. verschwendete Zeit bzw. Perlen vor die Säue :smiley:

Gruß

p.s. ich möchte mich auf komplexe zusammengesetzte Typen beschränken.

Das Thema lohnt sich ganz sicherlich, wenn Du damit in die Lage versetzt wirst, Dein reales Problem realistisch in der DB abzubilden. Ob das mit JDBC funktioniert, vermag ich Dir aber nicht zu sagen. Wäre ich aber an Deiner Stelle, dann würde ich das erst einmal ganz simpel in psql testen, ohne möglicherweise begrenzende Zwischenschicht. Das diese eigene Macken haben können, hast Du ja bereits vor 2-3 Tagen gelernt.

Andreas

Inzwischen kann ich mit komplexen Typen “laufen” … auch was JDBC angeht. Für alle die das interessiert:
JDBC für PG kennt für solche Zwecke nur den Typ java.sql.Types.OTHERS … also selbst wenn man weiss, dass es sich um eine
java.sql.Types.STRUCT handelt muss man immer OTHERS verwenden, wenn man java.sql.PreparedStatement.setObject(…) verwenden möchte. Außerdem sollte man diesem immer ein PGObject übergeben (nicht JBDC Standadrd) dem man bereits den mittels setType(String type) Namen des komplexen PG-Typen und mit setValue(String value) das fertige Literal des Wertes übergeben muss.

Wenn sich die PG-Mailingliste für Bugreports und Vorschläge nicht als so umstaendlich erweisen wuerde, dann hätte ich mich bereits daran gemacht “anzumahnen” auch hier die eigentlich garnicht schwierige Unterstützung der java Interfaces java.sql.Struct, java.sql.Array, usw. vorzuschlagen. Mit diesen kann man nämlich seine eigenen Klassen erlauben dem PreparedStatement.setObject(…) zu helfen - also was für ein Typ bin ich, was hab ich für Felder usw.

Nun kämpf ich aber wieder auf Postgre’Seite :smiley: @ Besserwisser … da ich ja auch gern komplexe Typen sortieren und vergleichen möchte. Mir ist noch nicht ganz klar wieviel Arbeit ich investieren muss um so einen Typ mit allen notwendigen (üblichen) Operatoren auszustatten.

Dafür mach ich mal ein neues Thema auf.

Gruss

Um den Thread zu schließen hier mein Lösungsvorschlag für einen einfachen Umgang mit composite-types …

und zwar erzeugt man sich einfach einen z.B.
create type point( x integer, y integer);

wie wir wissen kann man mit diesem erstmal so noch nicht viel anfangen … weil PG noch nicht weiss wie er den zu sortieren hat oder zu vergleichen oder zu indizieren.

mein wunsch war es ja, ohne grosse CREATE OPERATOR-orgien diesen typ point trotzdem nutzen zu koennen … mir ist nun eingefallen, dass man ja einer ::text eigenschaft - die, wie ich nun weiss eigentlich CAST heisst - auch bei anderen typen zum erfolg geführt wird, weil PG zumindest mit text oder anderen primitiven typen von haus aus umgehen kann …

ich habe mir also gedacht, dass PG mit einem

SELECT point FROM table WHERE point::text == ... ORDER BY point::text

was anfangen könnte … kann es auch - wie ich nun weiss.

diese idee habe ich im thread http://www.pg-forum.de/allgemeines/2462-text-hintergrundwissen.html#post12498
mal aufgegriffen um informationen zu derartigen ::xxxx casts zu erfahren …

für point wären dann noch zwei dinge notwendig. eine einfach function zur erzeugung der text-repräsentation

CREATE FUNCTION point_text(mySchema.point) RETURNS text
    AS $$ 
        SELECT   $1.x || '. ' ||   $1.y
    $$ LANGUAGE SQL;

und die erzeugung eines casts:

CREATE CAST (mySchema.point AS text)

man muss sich halt eine geeignete representation seines composite types einfallen lassen, mit der sich gut arbeiten laesst.


für den etwas komplizierteren fall - nach den komponenten x und y zu suchen order zu sortieren habe ich auch noch eine idee - die ich aber noch nicht geprueft habe - ob es funzt …

ich denke mir, dass man für x und y jeweils einen eigenen simplen user-defined type X und Y erzeugen sollte, die ihrerseits einfach als basistyp z.B. integer sind. Dann sollte man für point selbst noch zwei weitere casts ::X und ::Y erstellen koennen, die in der function point_X(point) AS text eben einfach x als typ X liefern (analog für Y in einer weiteren function und cast)

Wenn man also eine Tabelle hat in der ein Feld fpoint vom typ point existiert, dann sollte man dann in der lage sein z.B.

SELECT ... FROM .. WHERE fpoint::Y > .. ORDER BY fpoint::X

-Abfragen abzusetzen

Wenn irgendwer noch irgendwelche Ideen zum Thema hat - immer her damit.

Gruß