Thread: Patch to add typmod's functions to a type's creation statement
Hi all, Here is a patch to support this new PostgreSQL 8.3 feature : the possibility to add type modifier input and ouput functions to a newly created type. I tried many things but wasn't able to test it. If someone has an example of a use of this statement, can he send it to me or can he test my patch ? Thanks. BTW, I discovered a bug on the dlgType.c file. I commited it. pgAdmin appended a string to cbOuput three times instead of once for itself and one for cbReceive and one for cbSend. Regards. -- Guillaume. http://www.postgresqlfr.org http://dalibo.com Index: pgadmin/include/schema/pgType.h =================================================================== --- pgadmin/include/schema/pgType.h (révision 6675) +++ pgadmin/include/schema/pgType.h (copie de travail) @@ -50,6 +50,10 @@ void iSetReceiveFunction(const wxString& s) { receiveFunction=s; } wxString GetSendFunction() const { return sendFunction; } void iSetSendFunction(const wxString& s) { sendFunction=s; } + wxString GetTypmodinFunction() const { return typmodinFunction; } + void iSetTypmodinFunction(const wxString& s) { typmodinFunction=s; } + wxString GetTypmodoutFunction() const { return typmodoutFunction; } + void iSetTypmodoutFunction(const wxString& s) { typmodoutFunction=s; } wxString GetDefault() const { return defaultVal; } void iSetDefault(const wxString& s) { defaultVal=s; } wxString GetElement() { return element; } @@ -87,7 +91,8 @@ private: wxString alias, inputFunction, outputFunction, defaultVal, element, delimiter, alignment, storage, - typesList, quotedTypesList, labelList, quotedLabelList, sendFunction, receiveFunction; + typesList, quotedTypesList, labelList, quotedLabelList, sendFunction, receiveFunction, + typmodinFunction, typmodoutFunction; wxArrayString typesArray, labelArray; long internalLength; int typeClass; Index: pgadmin/schema/pgType.cpp =================================================================== --- pgadmin/schema/pgType.cpp (révision 6675) +++ pgadmin/schema/pgType.cpp (copie de travail) @@ -185,6 +185,11 @@ properties->AppendItem(_("Receive function"), GetReceiveFunction()); properties->AppendItem(_("Send function"), GetSendFunction()); } + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + properties->AppendItem(_("Typmod_in function"), GetTypmodinFunction()); + properties->AppendItem(_("Typmod_out function"), GetTypmodoutFunction()); + } properties->AppendItem(_("Storage"), GetStorage()); } properties->AppendItem(_("System type?"), GetSystemObject()); @@ -262,6 +267,11 @@ type->iSetReceiveFunction(types->GetVal(wxT("typreceive"))); type->iSetSendFunction(types->GetVal(wxT("typsend"))); } + if (collection->GetConnection()->BackendMinimumVersion(8, 3)) + { + type->iSetTypmodinFunction(types->GetVal(wxT("typmodin"))); + type->iSetTypmodoutFunction(types->GetVal(wxT("typmodout"))); + } wxString align=types->GetVal(wxT("typalign")); type->iSetAlignment( align == wxT("c") ? wxT("char") : Index: pgadmin/dlg/dlgType.cpp =================================================================== --- pgadmin/dlg/dlgType.cpp (révision 6675) +++ pgadmin/dlg/dlgType.cpp (copie de travail) @@ -30,6 +30,8 @@ #define cbOutput CTRL_COMBOBOX("cbOutput") #define cbReceive CTRL_COMBOBOX("cbReceive") #define cbSend CTRL_COMBOBOX("cbSend") +#define cbTypmodin CTRL_COMBOBOX("cbTypmodin") +#define cbTypmodout CTRL_COMBOBOX("cbTypmodout") #define chkVariable CTRL_CHECKBOX("chkVariable") #define txtIntLength CTRL_TEXT("txtIntLength") #define txtDefault CTRL_TEXT("txtDefault") @@ -150,6 +152,8 @@ cbOutput->Append(type->GetOutputFunction()); cbOutput->SetSelection(0); cbOutput->Disable(); cbReceive->Append(type->GetReceiveFunction()); cbReceive->SetSelection(0); cbReceive->Disable(); cbSend->Append(type->GetSendFunction()); cbSend->SetSelection(0); cbSend->Disable(); + cbTypmodin->Append(type->GetTypmodinFunction()); cbTypmodin->SetSelection(0); cbTypmodin->Disable(); + cbTypmodout->Append(type->GetTypmodoutFunction()); cbTypmodout->SetSelection(0); cbTypmodout->Disable(); chkVariable->SetValue(type->GetInternalLength() < 0); chkVariable->Disable(); if (type->GetInternalLength() > 0) @@ -193,6 +197,7 @@ cbOwner->Disable(); bool hasSendRcv = connection->BackendMinimumVersion(7, 4); + bool hasTypmod = connection->BackendMinimumVersion(8, 3); if (hasSendRcv) { @@ -205,6 +210,17 @@ cbSend->Disable(); } + if (hasTypmod) + { + cbTypmodin->Append(wxEmptyString); + cbTypmodout->Append(wxEmptyString); + } + else + { + cbTypmodin->Disable(); + cbTypmodout->Disable(); + } + if (!connection->BackendMinimumVersion(8, 3)) rdbType->Enable(TYPE_ENUM, false); @@ -231,6 +247,11 @@ cbOutput->Append(pn); cbOutput->Append(pn); } + if (hasTypmod) + { + cbTypmodin->Append(pn); + cbTypmodout->Append(pn); + } set->MoveNext(); } delete set; @@ -486,6 +507,28 @@ } } + if (connection->BackendMinimumVersion(8, 3)) + { + if (cbTypmodin->GetCurrentSelection() > 0 || cbTypmodout->GetCurrentSelection() > 0) + { + if (cbTypmodin->GetCurrentSelection() > 0) + { + sql += wxT(",\n TYPMOD_IN="); + AppendQuoted(sql, cbTypmodin->GetValue()); + if (cbTypmodout->GetCurrentSelection() > 0) + { + sql += wxT(", TYPMOD_OUT="); + AppendQuoted(sql, cbTypmodout->GetValue()); + } + } + else + { + sql += wxT(",\n TYPMOD_OUT="); + AppendQuoted(sql, cbTypmodout->GetValue()); + } + } + + } sql += wxT(",\n INTERNALLENGTH="); if (chkVariable->GetValue()) sql += wxT("VARIABLE"); Index: pgadmin/ui/dlgType.xrc =================================================================== --- pgadmin/ui/dlgType.xrc (révision 6675) +++ pgadmin/ui/dlgType.xrc (copie de travail) @@ -96,69 +96,89 @@ <size>135,12d</size> <style>wxCB_READONLY|wxCB_DROPDOWN</style> </object> - <object class="wxStaticText" name="stReceive"> - <label>Receive function</label> - <pos>5,37d</pos> - </object> - <object class="wxComboBox" name="cbReceive"> - <content/> - <pos>70,35d</pos> - <size>135,12d</size> - <style>wxCB_READONLY|wxCB_DROPDOWN</style> - </object> - <object class="wxStaticText" name="stSend"> - <label>Send Function</label> - <pos>5,52d</pos> - </object> - <object class="wxComboBox" name="cbSend"> - <content/> - <pos>70,50d</pos> - <size>135,12d</size> - <style>wxCB_READONLY|wxCB_DROPDOWN</style> - </object> + <object class="wxStaticText" name="stReceive"> + <label>Receive function</label> + <pos>5,37d</pos> + </object> + <object class="wxComboBox" name="cbReceive"> + <content/> + <pos>70,35d</pos> + <size>135,12d</size> + <style>wxCB_READONLY|wxCB_DROPDOWN</style> + </object> + <object class="wxStaticText" name="stSend"> + <label>Send function</label> + <pos>5,52d</pos> + </object> + <object class="wxComboBox" name="cbSend"> + <content/> + <pos>70,50d</pos> + <size>135,12d</size> + <style>wxCB_READONLY|wxCB_DROPDOWN</style> + </object> + <object class="wxStaticText" name="stTypmodin"> + <label>Typmod_in fctn</label> + <pos>5,67d</pos> + </object> + <object class="wxComboBox" name="cbTypmodin"> + <content/> + <pos>70,65d</pos> + <size>135,12d</size> + <style>wxCB_READONLY|wxCB_DROPDOWN</style> + </object> + <object class="wxStaticText" name="stTypmodout"> + <label>Typmod_out fctn</label> + <pos>5,82d</pos> + </object> + <object class="wxComboBox" name="cbTypmodout"> + <content/> + <pos>70,80d</pos> + <size>135,12d</size> + <style>wxCB_READONLY|wxCB_DROPDOWN</style> + </object> <object class="wxStaticText" name="stIntLength"> <label>Internal length</label> - <pos>5,67d</pos> + <pos>5,97d</pos> </object> <object class="wxTextCtrl" name="txtIntLength"> - <pos>70,65d</pos> + <pos>70,95d</pos> <size>70,-1d</size> </object> <object class="wxCheckBox" name="chkVariable"> <label>Variable</label> <checked>1</checked> - <pos>150,65d</pos> + <pos>150,95d</pos> <size>70,12d</size> </object> <object class="wxStaticText" name="stDefault"> <label>Default</label> - <pos>5,82d</pos> + <pos>5,112d</pos> </object> <object class="wxTextCtrl" name="txtDefault"> - <pos>70,80d</pos> + <pos>70,110d</pos> <size>135,-1d</size> </object> <object class="wxStaticText" name="stElement"> <label>Element</label> - <pos>5,97d</pos> + <pos>5,127d</pos> </object> <object class="ctlComboBox" name="cbElement"> <content/> - <pos>70,95d</pos> + <pos>70,125d</pos> <size>135,12d</size> <style>wxCB_READONLY|wxCB_DROPDOWN</style> </object> <object class="wxStaticText" name="stDelimiter"> <label>Delimiter</label> - <pos>5,112d</pos> + <pos>5,142d</pos> </object> <object class="wxTextCtrl" name="txtDelimiter"> - <pos>70,110d</pos> + <pos>70,140d</pos> <size>135,-1d</size> </object> <object class="wxStaticText" name="stAlignment"> <label>Alignment</label> - <pos>5,127d</pos> + <pos>5,157d</pos> </object> <object class="wxComboBox" name="cbAlignment"> <content> @@ -167,13 +187,13 @@ <item>int2</item> <item>int4</item> <item>double</item></content> - <pos>70,125d</pos> + <pos>70,155d</pos> <size>135,12d</size> <style>wxCB_READONLY|wxCB_DROPDOWN</style> </object> <object class="wxStaticText" name="stStorage"> <label>Storage</label> - <pos>5,146d</pos> + <pos>5,172d</pos> </object> <object class="wxComboBox" name="cbStorage"> <content> @@ -183,17 +203,17 @@ <item>EXTENDED</item> <item>MAIN</item></content> <selection>0</selection> - <pos>70,144d</pos> + <pos>70,170d</pos> <size>135,12d</size> <style>wxCB_READONLY|wxCB_DROPDOWN</style> </object> <object class="wxCheckBox" name="chkByValue"> <label>Passed by value</label> - <pos>70,160d</pos> + <pos>70,185d</pos> <size>135,12d</size> </object> <pos>0,0</pos> - <size>214,215d</size> + <size>214,200d</size> <style></style> </object> <object class="wxPanel" name="pnlDefinitionComposite"> @@ -247,7 +267,7 @@ <size>50,-1d</size> </object> <pos>0,0</pos> - <size>214,215d</size> + <size>214,200d</size> </object> <object class="wxPanel" name="pnlDefinitionEnum"> <object class="wxListCtrl" name="lstLabels"> @@ -274,7 +294,7 @@ <size>50,-1d</size> </object> <pos>0,0</pos> - <size>214,215d</size> + <size>214,200d</size> </object> </object> </object> @@ -292,7 +312,7 @@ <label>&Cancel</label> <pos>166,220d</pos> </object> - <size>218,238d</size> + <size>218,2223d</size> <style></style> </object> </resource>
Added to my patch queue. Thanks, Dave > ------- Original Message ------- > From: Guillaume Lelarge <guillaume@lelarge.info> > To: pgadmin-hackers@postgresql.org > Sent: 26/09/07, 18:15:25 > Subject: Patch to add typmod's functions to a type's creation statement > > Hi all, > > Here is a patch to support this new PostgreSQL 8.3 feature : the > possibility to add type modifier input and ouput functions to a newly > created type. > > I tried many things but wasn't able to test it. If someone has an > example of a use of this statement, can he send it to me or can he test > my patch ? Thanks. > > BTW, I discovered a bug on the dlgType.c file. I commited it. pgAdmin > appended a string to cbOuput three times instead of once for itself and > one for cbReceive and one for cbSend. > > Regards. > > > -- > Guillaume. > http://www.postgresqlfr.org > http://dalibo.com >
Guillaume Lelarge wrote: > Hi all, > > Here is a patch to support this new PostgreSQL 8.3 feature : the > possibility to add type modifier input and ouput functions to a newly > created type. Unfortunately this still needs some work. I found the following issues: - The typemod in/out functions are not included the reverse engineered SQL displayed on the main window when a type with such functions is selected (for reference, try pg_catalog.time). - I'm not so keen on the labelling. I would suggest: 'Typmod in function'/'Typmod out function' in the properties list. 'Typmod in func'/'Typmod out func' on dlgType. - The code that loads the combo boxes in dlgType is broken. It's currently in loop designed to load the I/O and Send/Receive functions (which is somewhat broken in itself). The doc at http://www.postgresql.org/docs/8.3/static/sql-createtype.html describes the general signature of functions that are appropriate. [as a side note, the code here seems somewhat broken in general wrt the handling of the whole create function/create type chicken and egg scenario - I'll make a note to review that] > I tried many things but wasn't able to test it. If someone has an > example of a use of this statement, can he send it to me or can he test > my patch ? Thanks. Look at the code for the time datatype in pg_catalog. You can create your own experimental types from it's reverse-engineers SQL (once the first item above is fixed). Patch NOT applied. Regards, Dave.
Hi, Dave Page a écrit : > Guillaume Lelarge wrote: >> Here is a patch to support this new PostgreSQL 8.3 feature : the >> possibility to add type modifier input and ouput functions to a newly >> created type. > > Unfortunately this still needs some work. I found the following issues: > > - The typemod in/out functions are not included the reverse engineered > SQL displayed on the main window when a type with such functions is > selected (for reference, try pg_catalog.time). > Fixed. > - I'm not so keen on the labelling. I would suggest: > > 'Typmod in function'/'Typmod out function' in the properties list. > 'Typmod in func'/'Typmod out func' on dlgType. > Fixed too. > - The code that loads the combo boxes in dlgType is broken. It's > currently in loop designed to load the I/O and Send/Receive functions > (which is somewhat broken in itself). The doc at > http://www.postgresql.org/docs/8.3/static/sql-createtype.html describes > the general signature of functions that are appropriate. > If I correctly understand what the code is doing, it selects all functions that has a first argument but no second one, is this right ? it does not check arguments' types. In this case, I think we should change this SQL query SELECT proname, nspname FROM ( SELECT proname, nspname, max(proargtypes[0]) AS arg0, max(proargtypes[1]) AS arg1 FROM pg_proc p JOIN pg_namespace n ON n.oid=pronamespace GROUP BY proname, nspname HAVING count(proname) = 1 ) AS uniquefunc WHERE arg0 <> 0 AND arg1 = 0 with this one SELECT proname, nspname FROM ( SELECT proname, nspname, max(proargtypes[0]) AS arg0, max(proargtypes[1]) AS arg1 FROM pg_proc p JOIN pg_namespace n ON n.oid=pronamespace GROUP BY proname, nspname HAVING count(proname) = 1 ) AS uniquefunc WHERE arg0 <> 0 AND coalesce(arg1, 0) = 0 If I correctly read the CREATE TYPE manpage, I need to check that the type_modifier_input_function function has one argument of type cstring[] and returns an integer. And I need to check that the type_modifier_output_function function has one integer argument and returns a single ctring value. Is this right ? If I'm right, all the code that get input, ouput, send and receive functions is broken. Right ? > [as a side note, the code here seems somewhat broken in general wrt the > handling of the whole create function/create type chicken and egg > scenario - I'll make a note to review that] > +1 Thanks. -- Guillaume. http://www.postgresqlfr.org http://dalibo.com
Guillaume Lelarge a écrit : >> - The code that loads the combo boxes in dlgType is broken. It's >> currently in loop designed to load the I/O and Send/Receive functions >> (which is somewhat broken in itself). The doc at >> http://www.postgresql.org/docs/8.3/static/sql-createtype.html describes >> the general signature of functions that are appropriate. >> > > If I correctly understand what the code is doing, it selects all > functions that has a first argument but no second one, is this right ? > it does not check arguments' types. > > In this case, I think we should change this SQL query > > SELECT proname, nspname > FROM ( > SELECT proname, nspname, max(proargtypes[0]) AS arg0, > max(proargtypes[1]) AS arg1 > FROM pg_proc p > JOIN pg_namespace n ON n.oid=pronamespace > GROUP BY proname, nspname > HAVING count(proname) = 1 ) AS uniquefunc > WHERE arg0 <> 0 AND arg1 = 0 > > with this one > > SELECT proname, nspname > FROM ( > SELECT proname, nspname, max(proargtypes[0]) AS arg0, > max(proargtypes[1]) AS arg1 > FROM pg_proc p > JOIN pg_namespace n ON n.oid=pronamespace > GROUP BY proname, nspname > HAVING count(proname) = 1 ) AS uniquefunc > WHERE arg0 <> 0 AND coalesce(arg1, 0) = 0 > > If I correctly read the CREATE TYPE manpage, I need to check that the > type_modifier_input_function function has one argument of type cstring[] > and returns an integer. And I need to check that the > type_modifier_output_function function has one integer argument and > returns a single ctring value. Is this right ? > If I'm right, this patch does the job (ie, all previous patch's known issues fixed). -- Guillaume. http://www.postgresqlfr.org http://dalibo.com Index: pgadmin/include/schema/pgType.h =================================================================== --- pgadmin/include/schema/pgType.h (révision 6864) +++ pgadmin/include/schema/pgType.h (copie de travail) @@ -50,6 +50,10 @@ void iSetReceiveFunction(const wxString& s) { receiveFunction=s; } wxString GetSendFunction() const { return sendFunction; } void iSetSendFunction(const wxString& s) { sendFunction=s; } + wxString GetTypmodinFunction() const { return typmodinFunction; } + void iSetTypmodinFunction(const wxString& s) { typmodinFunction=s; } + wxString GetTypmodoutFunction() const { return typmodoutFunction; } + void iSetTypmodoutFunction(const wxString& s) { typmodoutFunction=s; } wxString GetDefault() const { return defaultVal; } void iSetDefault(const wxString& s) { defaultVal=s; } wxString GetElement() { return element; } @@ -87,7 +91,8 @@ private: wxString alias, inputFunction, outputFunction, defaultVal, element, delimiter, alignment, storage, - typesList, quotedTypesList, labelList, quotedLabelList, sendFunction, receiveFunction; + typesList, quotedTypesList, labelList, quotedLabelList, sendFunction, receiveFunction, + typmodinFunction, typmodoutFunction; wxArrayString typesArray, labelArray; long internalLength; int typeClass; Index: pgadmin/schema/pgType.cpp =================================================================== --- pgadmin/schema/pgType.cpp (révision 6864) +++ pgadmin/schema/pgType.cpp (copie de travail) @@ -66,6 +66,11 @@ sql +=wxT(",\n INTERNALLENGTH=") + NumToStr(GetInternalLength()) + wxT(", ALIGNMENT=" + GetAlignment() + wxT(", STORAGE=") + GetStorage()); + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + sql +=wxT(",\n TYPMOD_IN=") + GetTypmodinFunction() + + wxT(", TYPMOD_OUT=") + GetTypmodoutFunction(); + } } sql += wxT(");\n") + GetOwnerSql(8, 0) @@ -185,6 +190,13 @@ properties->AppendItem(_("Receive function"), GetReceiveFunction()); properties->AppendItem(_("Send function"), GetSendFunction()); } + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + if (GetTypmodinFunction().Length() > 0) + properties->AppendItem(_("Typmod in function"), GetTypmodinFunction()); + if (GetTypmodoutFunction().Length() > 0) + properties->AppendItem(_("Typmod out function"), GetTypmodoutFunction()); + } properties->AppendItem(_("Storage"), GetStorage()); } properties->AppendItem(_("System type?"), GetSystemObject()); @@ -262,6 +274,11 @@ type->iSetReceiveFunction(types->GetVal(wxT("typreceive"))); type->iSetSendFunction(types->GetVal(wxT("typsend"))); } + if (collection->GetConnection()->BackendMinimumVersion(8, 3)) + { + type->iSetTypmodinFunction(types->GetVal(wxT("typmodin"))); + type->iSetTypmodoutFunction(types->GetVal(wxT("typmodout"))); + } wxString align=types->GetVal(wxT("typalign")); type->iSetAlignment( align == wxT("c") ? wxT("char") : Index: pgadmin/dlg/dlgType.cpp =================================================================== --- pgadmin/dlg/dlgType.cpp (révision 6864) +++ pgadmin/dlg/dlgType.cpp (copie de travail) @@ -30,6 +30,8 @@ #define cbOutput CTRL_COMBOBOX("cbOutput") #define cbReceive CTRL_COMBOBOX("cbReceive") #define cbSend CTRL_COMBOBOX("cbSend") +#define cbTypmodin CTRL_COMBOBOX("cbTypmodin") +#define cbTypmodout CTRL_COMBOBOX("cbTypmodout") #define chkVariable CTRL_CHECKBOX("chkVariable") #define txtIntLength CTRL_TEXT("txtIntLength") #define txtDefault CTRL_TEXT("txtDefault") @@ -137,6 +139,8 @@ int dlgType::Go(bool modal) { + pgSet *set; + if (type) { // Edit Mode @@ -150,6 +154,8 @@ cbOutput->Append(type->GetOutputFunction()); cbOutput->SetSelection(0); cbOutput->Disable(); cbReceive->Append(type->GetReceiveFunction()); cbReceive->SetSelection(0); cbReceive->Disable(); cbSend->Append(type->GetSendFunction()); cbSend->SetSelection(0); cbSend->Disable(); + cbTypmodin->Append(type->GetTypmodinFunction()); cbTypmodin->SetSelection(0); cbTypmodin->Disable(); + cbTypmodout->Append(type->GetTypmodoutFunction()); cbTypmodout->SetSelection(0); cbTypmodout->Disable(); chkVariable->SetValue(type->GetInternalLength() < 0); chkVariable->Disable(); if (type->GetInternalLength() > 0) @@ -193,6 +199,7 @@ cbOwner->Disable(); bool hasSendRcv = connection->BackendMinimumVersion(7, 4); + bool hasTypmod = connection->BackendMinimumVersion(8, 3); if (hasSendRcv) { @@ -205,10 +212,21 @@ cbSend->Disable(); } + if (hasTypmod) + { + cbTypmodin->Append(wxEmptyString); + cbTypmodout->Append(wxEmptyString); + } + else + { + cbTypmodin->Disable(); + cbTypmodout->Disable(); + } + if (!connection->BackendMinimumVersion(8, 3)) rdbType->Enable(TYPE_ENUM, false); - pgSet *set=connection->ExecuteSet( + set = connection->ExecuteSet( wxT("SELECT proname, nspname\n") wxT(" FROM (\n") wxT(" SELECT proname, nspname, max(proargtypes[0]) AS arg0, max(proargtypes[1]) AS arg1\n") @@ -231,10 +249,61 @@ cbReceive->Append(pn); cbSend->Append(pn); } + if (hasTypmod) + { + cbTypmodin->Append(pn); + cbTypmodout->Append(pn); + } set->MoveNext(); } delete set; } + + if (hasTypmod) + { + set = connection->ExecuteSet( + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=(SELECT oid FROM pg_type WHERE typname='int4')") + wxT(" AND proargtypes[0]=(SELECT oid FROM pg_type WHERE typname='_cstring')") + wxT(" AND proargtypes[1] IS NULL") + wxT(" ORDER BY nspname, proname")); + + if (set) + { + while (!set->Eof()) + { + wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + + cbTypmodin->Append(pn); + set->MoveNext(); + } + delete set; + } + + set = connection->ExecuteSet( + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=(SELECT oid FROM pg_type WHERE typname='cstring')") + wxT(" AND proargtypes[0]=(SELECT oid FROM pg_type WHERE typname='int4')") + wxT(" AND proargtypes[1] IS NULL") + wxT(" ORDER BY nspname, proname")); + + if (set) + { + while (!set->Eof()) + { + wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + + cbTypmodout->Append(pn); + set->MoveNext(); + } + delete set; + } + } + FillDatatype(cbDatatype, cbElement); txtLength->SetValidator(numericValidator); } @@ -486,6 +555,28 @@ } } + if (connection->BackendMinimumVersion(8, 3)) + { + if (cbTypmodin->GetCurrentSelection() > 0 || cbTypmodout->GetCurrentSelection() > 0) + { + if (cbTypmodin->GetCurrentSelection() > 0) + { + sql += wxT(",\n TYPMOD_IN="); + AppendQuoted(sql, cbTypmodin->GetValue()); + if (cbTypmodout->GetCurrentSelection() > 0) + { + sql += wxT(", TYPMOD_OUT="); + AppendQuoted(sql, cbTypmodout->GetValue()); + } + } + else + { + sql += wxT(",\n TYPMOD_OUT="); + AppendQuoted(sql, cbTypmodout->GetValue()); + } + } + + } sql += wxT(",\n INTERNALLENGTH="); if (chkVariable->GetValue()) sql += wxT("VARIABLE"); Index: pgadmin/ui/dlgType.xrc =================================================================== --- pgadmin/ui/dlgType.xrc (révision 6864) +++ pgadmin/ui/dlgType.xrc (copie de travail) @@ -96,69 +96,89 @@ <size>135,12d</size> <style>wxCB_READONLY|wxCB_DROPDOWN</style> </object> - <object class="wxStaticText" name="stReceive"> - <label>Receive function</label> - <pos>5,37d</pos> - </object> - <object class="wxComboBox" name="cbReceive"> - <content/> - <pos>70,35d</pos> - <size>135,12d</size> - <style>wxCB_READONLY|wxCB_DROPDOWN</style> - </object> - <object class="wxStaticText" name="stSend"> - <label>Send Function</label> - <pos>5,52d</pos> - </object> - <object class="wxComboBox" name="cbSend"> - <content/> - <pos>70,50d</pos> - <size>135,12d</size> - <style>wxCB_READONLY|wxCB_DROPDOWN</style> - </object> + <object class="wxStaticText" name="stReceive"> + <label>Receive function</label> + <pos>5,37d</pos> + </object> + <object class="wxComboBox" name="cbReceive"> + <content/> + <pos>70,35d</pos> + <size>135,12d</size> + <style>wxCB_READONLY|wxCB_DROPDOWN</style> + </object> + <object class="wxStaticText" name="stSend"> + <label>Send function</label> + <pos>5,52d</pos> + </object> + <object class="wxComboBox" name="cbSend"> + <content/> + <pos>70,50d</pos> + <size>135,12d</size> + <style>wxCB_READONLY|wxCB_DROPDOWN</style> + </object> + <object class="wxStaticText" name="stTypmodin"> + <label>Typmod in func</label> + <pos>5,67d</pos> + </object> + <object class="wxComboBox" name="cbTypmodin"> + <content/> + <pos>70,65d</pos> + <size>135,12d</size> + <style>wxCB_READONLY|wxCB_DROPDOWN</style> + </object> + <object class="wxStaticText" name="stTypmodout"> + <label>Typmod out func</label> + <pos>5,82d</pos> + </object> + <object class="wxComboBox" name="cbTypmodout"> + <content/> + <pos>70,80d</pos> + <size>135,12d</size> + <style>wxCB_READONLY|wxCB_DROPDOWN</style> + </object> <object class="wxStaticText" name="stIntLength"> <label>Internal length</label> - <pos>5,67d</pos> + <pos>5,97d</pos> </object> <object class="wxTextCtrl" name="txtIntLength"> - <pos>70,65d</pos> + <pos>70,95d</pos> <size>70,-1d</size> </object> <object class="wxCheckBox" name="chkVariable"> <label>Variable</label> <checked>1</checked> - <pos>150,65d</pos> + <pos>150,95d</pos> <size>70,12d</size> </object> <object class="wxStaticText" name="stDefault"> <label>Default</label> - <pos>5,82d</pos> + <pos>5,112d</pos> </object> <object class="wxTextCtrl" name="txtDefault"> - <pos>70,80d</pos> + <pos>70,110d</pos> <size>135,-1d</size> </object> <object class="wxStaticText" name="stElement"> <label>Element</label> - <pos>5,97d</pos> + <pos>5,127d</pos> </object> <object class="ctlComboBox" name="cbElement"> <content/> - <pos>70,95d</pos> + <pos>70,125d</pos> <size>135,12d</size> <style>wxCB_READONLY|wxCB_DROPDOWN</style> </object> <object class="wxStaticText" name="stDelimiter"> <label>Delimiter</label> - <pos>5,112d</pos> + <pos>5,142d</pos> </object> <object class="wxTextCtrl" name="txtDelimiter"> - <pos>70,110d</pos> + <pos>70,140d</pos> <size>135,-1d</size> </object> <object class="wxStaticText" name="stAlignment"> <label>Alignment</label> - <pos>5,127d</pos> + <pos>5,157d</pos> </object> <object class="wxComboBox" name="cbAlignment"> <content> @@ -167,13 +187,13 @@ <item>int2</item> <item>int4</item> <item>double</item></content> - <pos>70,125d</pos> + <pos>70,155d</pos> <size>135,12d</size> <style>wxCB_READONLY|wxCB_DROPDOWN</style> </object> <object class="wxStaticText" name="stStorage"> <label>Storage</label> - <pos>5,146d</pos> + <pos>5,172d</pos> </object> <object class="wxComboBox" name="cbStorage"> <content> @@ -183,17 +203,17 @@ <item>EXTENDED</item> <item>MAIN</item></content> <selection>0</selection> - <pos>70,144d</pos> + <pos>70,170d</pos> <size>135,12d</size> <style>wxCB_READONLY|wxCB_DROPDOWN</style> </object> <object class="wxCheckBox" name="chkByValue"> <label>Passed by value</label> - <pos>70,160d</pos> + <pos>70,185d</pos> <size>135,12d</size> </object> <pos>0,0</pos> - <size>214,215d</size> + <size>214,200d</size> <style></style> </object> <object class="wxPanel" name="pnlDefinitionComposite"> @@ -247,7 +267,7 @@ <size>50,-1d</size> </object> <pos>0,0</pos> - <size>214,215d</size> + <size>214,200d</size> </object> <object class="wxPanel" name="pnlDefinitionEnum"> <object class="wxListCtrl" name="lstLabels"> @@ -274,7 +294,7 @@ <size>50,-1d</size> </object> <pos>0,0</pos> - <size>214,215d</size> + <size>214,200d</size> </object> </object> </object> @@ -292,7 +312,7 @@ <label>&Cancel</label> <pos>166,220d</pos> </object> - <size>218,238d</size> + <size>218,2223d</size> <style></style> </object> </resource>
Guillaume Lelarge wrote: > Guillaume Lelarge a écrit : >> If I correctly read the CREATE TYPE manpage, I need to check that the >> type_modifier_input_function function has one argument of type cstring[] >> and returns an integer. And I need to check that the >> type_modifier_output_function function has one integer argument and >> returns a single ctring value. Is this right ? >> > > If I'm right, this patch does the job (ie, all previous patch's known > issues fixed). Thanks, patch applied. Regards, Dave.