Postgrsql 12

add PG12 support.
Bug fix
This commit is contained in:
levinsv 2019-10-05 16:38:43 +05:00
parent 10e9e0229c
commit 7e10968209
14 changed files with 89 additions and 25 deletions

View file

@ -75,7 +75,11 @@ This text Russian language.
- добавлен фильтр в окно результатов запроса. Активируется двойным щелчком мыши по ячейке, текст которой и будет являтся условием фильтра. Снимается из контекстного меню.
При нажатом Alt условие отбора инвертируется (Скрыть строки содержащие значение).
- Для избегания ожиданий при получении информации об объектах. Выставляется клиентский параметр SET lock_timeout=15000 для служебного соединения.
04.09.2019
- добавлена поддержка PostgreSQL 12
- добавлена поддержка отображения дополнительных опция для индексов
- в окне запросов добавлена альтернативная кнопка отражающая текущий режим, Transaction (T) или AutoCommit (A)
* исправлена ошибка в окне поиска объектов при поиске в коментариях

Binary file not shown.

View file

@ -45,6 +45,7 @@ BEGIN_EVENT_TABLE(ctlSQLBox, wxStyledTextCtrl)
EVT_MENU(MNU_FIND, ctlSQLBox::OnSearchReplace)
EVT_MENU(MNU_AUTOCOMPLETE, ctlSQLBox::OnAutoComplete)
EVT_KILL_FOCUS(ctlSQLBox::OnKillFocus)
// EVT_ERASE_BACKGROUND(ctlSQLBox::OnBackGround)
#ifdef __WXMAC__
EVT_STC_PAINTED(-1, ctlSQLBox::OnPositionStc)
#else
@ -81,7 +82,12 @@ ctlSQLBox::ctlSQLBox(wxWindow *parent, wxWindowID id, const wxPoint &pos, const
Create(parent, id, pos, size, style);
}
//void ctlSQLBox::OnBackGround(wxEraseEvent &event) {
// wxDC *dc=event.GetDC();
// dc->SetBackground(wxBrush(GetBackgroundColour(), wxSOLID));
// dc->Clear();
//
//}
wxColour ctlSQLBox::SetSQLBoxColourBackground(bool transaction) {
wxColour bgColor = settings->GetSQLBoxColourBackground();
if (settings->GetSQLBoxUseSystemBackground())
@ -90,6 +96,7 @@ wxColour ctlSQLBox::SetSQLBoxColourBackground(bool transaction) {
}
if (transaction) bgColor = wxColour(241, 241, 186);
StyleSetBackground(wxSTC_STYLE_DEFAULT, bgColor);
// SetBackgroundStyle(wxBG_STYLE_CUSTOM);
return bgColor;
}
void ctlSQLBox::SetQueryBook(ctlAuiNotebook *query_book)

View file

@ -556,7 +556,7 @@ void dlgSearchObject::OnSearch(wxCommandEvent &ev)
wxT("inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m') ")
wxT("left join pg_namespace n on t.relnamespace = n.oid ")
wxT("where a.attnum > 0 ")
wxT(" and (ty.typname ilike ") + txtPatternStr + wxT(" or ad.adsrc ilike ") + txtPatternStr + wxT(") ")
wxT(" and (ty.typname ilike ") + txtPatternStr + wxT(" or pg_get_expr(ad.adbin,0) ilike ") + txtPatternStr + wxT(") ")
wxT("UNION ") // View's definition
wxT("SELECT 'Views', c.relname, ")
wxT("':Schemas/' || n.nspname || '/:Views/' || c.relname, n.nspname ")
@ -641,10 +641,10 @@ void dlgSearchObject::OnSearch(wxCommandEvent &ev)
wxT(" LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)")
wxT(" WHERE contype IS NULL")
wxT(" UNION")
wxT(" select CASE WHEN p_t.typname = 'trigger' THEN 'Trigger Functions' ELSE case when p.prokind='p' then 'Procedures' else 'Functions' end END AS type,")
wxT(" select CASE WHEN p_t.typname = 'trigger' THEN 'Trigger Functions' ELSE case when p_.prokind='p' then 'Procedures' else 'Functions' end END AS type,")
wxT(" p_.proname AS objectname,")
wxT(" ':Schemas/' || n.nspname || '/' ||")
wxT(" case when p_t.typname = 'trigger' then ':Trigger Functions/' else case when p.prokind='p' then ':Procedures/' else ':Functions/' end end || p_.proname AS path, n.nspname")
wxT(" case when p_t.typname = 'trigger' then ':Trigger Functions/' else case when p_.prokind='p' then ':Procedures/' else ':Functions/' end end || p_.proname AS path, n.nspname")
wxT(" from ") + pd +
wxT(" join pg_proc p_ on pd.relname = 'pg_proc' and pd.objoid = p_.oid and p_.prokind <> 'a'")
wxT(" left join pg_type p_t on p_.prorettype = p_t.oid")

View file

@ -2327,7 +2327,7 @@ sqlTable::sqlTable(pgConn *conn, pgQueryThread *_thread, const wxString &tabName
pgSet *colSet = connection->ExecuteSet(
wxT("SELECT n.nspname AS nspname, relname, format_type(t.oid,NULL) AS typname, format_type(t.oid, att.atttypmod) AS displaytypname, ")
wxT("nt.nspname AS typnspname, attname, attnum, COALESCE(b.oid, t.oid) AS basetype, atthasdef, adsrc,\n")
wxT("nt.nspname AS typnspname, attname, attnum, COALESCE(b.oid, t.oid) AS basetype, atthasdef, pg_get_expr(def.adbin,0) AS adsrc,\n")
wxT(" CASE WHEN t.typbasetype::oid=0 THEN att.atttypmod else t.typtypmod END AS typmod,\n")
wxT(" CASE WHEN t.typbasetype::oid=0 THEN att.attlen else t.typlen END AS typlen\n")
wxT(" FROM pg_attribute att\n")

View file

@ -87,6 +87,7 @@
#define CTRLID_CONNECTION 4200
#define CTRLID_DATABASELABEL 4201
#define CTL_SQLQUERYBOOK 4202
#define CTL_BUTTONTRANSACTION 4203
#define XML_FROM_WXSTRING(s) ((const xmlChar *)(const char *)s.mb_str(wxConvUTF8))
#define WXSTRING_FROM_XML(s) wxString((char *)s, wxConvUTF8)
@ -191,6 +192,7 @@ BEGIN_EVENT_TABLE(frmQuery, pgFrame)
EVT_SPLITTER_SASH_POS_CHANGED(GQB_HORZ_SASH, frmQuery::OnResizeHorizontally)
EVT_BUTTON(CTL_DELETECURRENTBTN, frmQuery::OnDeleteCurrent)
EVT_BUTTON(CTL_DELETEALLBTN, frmQuery::OnDeleteAll)
EVT_BUTTON(CTL_BUTTONTRANSACTION,frmQuery::OnModeTransaction)
END_EVENT_TABLE()
class DnDFile : public wxFileDropTarget
@ -482,6 +484,24 @@ frmQuery::frmQuery(frmMain *form, const wxString &_title, pgConn *_conn, const w
cbConnection = new wxBitmapComboBox(this, CTRLID_CONNECTION, wxEmptyString, wxDefaultPosition, wxSize(-1, -1), wxArrayString(), wxCB_READONLY | wxCB_DROPDOWN);
cbConnection->Append(conn->GetName(), CreateBitmap(GetServerColour(conn)), (void *)conn);
cbConnection->Append(_("<new connection>"), wxNullBitmap, (void *) NULL);
//CTL_BUTTONTRANSACTION
btnModeTransaction = new wxButton(this, CTL_BUTTONTRANSACTION, "A",wxDefaultPosition,wxSize(-1, -1),wxMINIMIZE_BOX);
btnModeTransaction->SetMaxSize(wxSize(22,22));
// btnModeTransaction->Enable(true);
wxFont stdFont = settings->GetSystemFont();
wxFont boldFont = stdFont;
boldFont.SetWeight(wxBOLD);
btnModeTransaction->SetFont(boldFont);
if (settings->GetAutoCommit())
btnModeTransaction->SetLabel("A");
else
btnModeTransaction->SetLabel("T");
// btnModeTransaction->Fit();
//Create SQL editor notebook
sqlNotebook = new ctlAuiNotebook(this, CTL_NTBKCENTER, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON);
@ -574,6 +594,8 @@ frmQuery::frmQuery(frmMain *form, const wxString &_title, pgConn *_conn, const w
// Kickstart wxAUI
manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false));
manager.AddPane(cbConnection, wxAuiPaneInfo().Name(wxT("databaseBar")).Caption(_("Connection bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false));
manager.AddPane(btnModeTransaction, wxAuiPaneInfo().Name(wxT("ModeTransaction")).Caption(_("Mode transaction")).ToolbarPane().Top().LeftDockable(false).RightDockable(false));
manager.AddPane(outputPane, wxAuiPaneInfo().Name(wxT("outputPane")).Caption(_("Output pane")).Bottom().MinSize(wxSize(200, 100)).BestSize(wxSize(550, 300)));
manager.AddPane(scratchPad, wxAuiPaneInfo().Name(wxT("scratchPad")).Caption(_("Scratch pad")).Right().MinSize(wxSize(100, 100)).BestSize(wxSize(250, 200)));
manager.AddPane(sqlNotebook, wxAuiPaneInfo().Name(wxT("sqlQuery")).Caption(_("SQL query")).Center().CaptionVisible(false).CloseButton(false).MinSize(wxSize(200, 100)).BestSize(wxSize(350, 200)));
@ -586,6 +608,13 @@ frmQuery::frmQuery(frmMain *form, const wxString &_title, pgConn *_conn, const w
// and reset the captions for the current language
manager.GetPane(wxT("toolBar")).Caption(_("Tool bar"));
manager.GetPane(wxT("databaseBar")).Caption(_("Connection bar"));
//manager.GetPane(wxT("ModeTransaction")).Caption(_("Mode transaction"));
if (!manager.GetPane(wxT("ModeTransaction")).IsShown()) {
manager.GetPane(wxT("ModeTransaction")).MaxSize(wxSize(22, 22));
manager.GetPane(wxT("ModeTransaction")).BestSize(wxSize(22, 22));
manager.GetPane(wxT("ModeTransaction")).Show(true);
}
manager.GetPane(wxT("sqlQuery")).Caption(_("SQL query"));
manager.GetPane(wxT("outputPane")).Caption(_("Output pane"));
manager.GetPane(wxT("scratchPad")).Caption(_("Scratch pad"));
@ -971,8 +1000,14 @@ void frmQuery::OnAutoRollback(wxCommandEvent &event)
void frmQuery::OnAutoCommit(wxCommandEvent &event)
{
queryMenu->Check(MNU_AUTOCOMMIT, event.IsChecked());
if(event.IsChecked() && conn->GetTxStatus() != PQTRANS_IDLE)
bool chk=queryMenu->IsChecked(MNU_AUTOCOMMIT);
queryMenu->Check(MNU_AUTOCOMMIT, chk);
if (chk)
btnModeTransaction->SetLabel("A");
else
btnModeTransaction->SetLabel("T");
if(chk && conn->GetTxStatus() != PQTRANS_IDLE)
wxMessageBox(
_("The current transaction is still in progess.\n\nIn order to take the effect of AUTOCOMMIT mode, please complete the transaction by executing COMMIT, or ROLLBACK statement."),
_("Warning - Transaction in progress"), wxICON_INFORMATION | wxOK, this);
@ -2629,7 +2664,6 @@ void frmQuery::OnExecute(wxCommandEvent &event)
if (query.IsNull())
return;
execQuery(query);
sqlQuery->SetFocus();
}
@ -2830,6 +2864,7 @@ void frmQuery::execQuery(const wxString &query, int resultToRetrieve, bool singl
aborted = false;
isfilterresult=false;
sqlResult->ClearFilter();
QueryExecInfo *qi = new QueryExecInfo();
qi->queryOffset = queryOffset;
qi->toFileExportForm = NULL;
@ -3861,8 +3896,11 @@ void frmQuery::OnDeleteCurrent(wxCommandEvent &event)
SaveQueries();
}
}
void frmQuery::OnModeTransaction(wxCommandEvent &event)
{
queryMenu->Check(MNU_AUTOCOMMIT, !queryMenu->IsChecked(MNU_AUTOCOMMIT));
OnAutoCommit(event);
}
void frmQuery::OnDeleteAll(wxCommandEvent &event)
{

View file

@ -56,6 +56,7 @@ public:
void OnAutoComplete(wxCommandEvent &event);
void OnSearchReplace(wxCommandEvent &event);
void OnKillFocus(wxFocusEvent &event);
// void OnBackGround(wxEraseEvent &event);
void SetQueryBook(ctlAuiNotebook *query_book);
ctlAuiNotebook* GetQueryBook()
{

View file

@ -130,6 +130,7 @@ private:
ExplainCanvas *explainCanvas;
wxTextCtrl *msgResult, *msgHistory;
wxBitmapComboBox *cbConnection;
wxButton *btnModeTransaction;
wxTextCtrl *scratchPad;
wxComboBox *sqlQueries;
wxButton *btnDeleteCurrent;
@ -249,6 +250,7 @@ private:
void OnDeleteCurrent(wxCommandEvent &event);
void OnDeleteAll(wxCommandEvent &event);
void OnModeTransaction(wxCommandEvent &event);
void OnTimer(wxTimerEvent &event);

View file

@ -141,6 +141,14 @@ public:
{
idxTable = s;
}
wxString GetRelOptions() const
{
return reloptions;
}
void iSetRelOptions(const wxString &s)
{
reloptions = s;
}
wxString GetIdxSchema() const
{
return idxSchema;
@ -284,7 +292,7 @@ protected:
void ReadColumnDetails();
private:
wxString columnNumbers, columns, quotedColumns, indexType, idxTable, idxSchema, constraint, tablespace;
wxString columnNumbers, columns, quotedColumns, indexType, idxTable, reloptions, idxSchema, constraint, tablespace;
wxString procName, procNamespace, procArgs, procArgTypeList, typedColumns, quotedTypedColumns, operatorClasses, operatorClassList;
long columnCount;
wxArrayString columnList, ordersArray, nullsArray, opclassesArray, collationsArray;

View file

@ -114,7 +114,7 @@ pgObject *gpPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser
pgSet *tables;
query = wxT("SELECT rel.oid, relname, rel.reltablespace AS spcoid, spcname, pg_get_userbyid(relowner) AS relowner, relacl, relhasoids, ")
query = wxT("SELECT rel.oid, relname, rel.reltablespace AS spcoid, spcname, pg_get_userbyid(relowner) AS relowner, relacl, ")
wxT("relhassubclass, reltuples, description, conname, conkey, parname, \n")
wxT(" EXISTS(select 1 FROM pg_trigger\n")
wxT(" JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n")
@ -169,7 +169,7 @@ pgObject *gpPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser
table->iSetTablespace(tables->GetVal(wxT("spcname")));
table->iSetComment(tables->GetVal(wxT("description")));
table->iSetHasOids(tables->GetBool(wxT("relhasoids")));
table->iSetHasOids(false);
table->iSetEstimatedRows(tables->GetDouble(wxT("reltuples")) * gp_segments);
table->iSetFillFactor(tables->GetVal(wxT("fillfactor")));

View file

@ -132,8 +132,11 @@ wxString pgIndexBase::GetCreate()
str += wxT(")");
if (GetConnection()->BackendMinimumVersion(8, 2) && GetFillFactor().Length() > 0)
str += wxT("\n WITH (FILLFACTOR=") + GetFillFactor() + wxT(")");
// if (GetConnection()->BackendMinimumVersion(8, 2) && GetFillFactor().Length() > 0)
// str += wxT("\n WITH (FILLFACTOR=") + GetFillFactor() + wxT(")");
if (GetConnection()->BackendMinimumVersion(8, 2) && GetRelOptions().Length() > 0)
str += wxT("\n WITH (") + GetRelOptions() + wxT(")");
if (GetConnection()->BackendMinimumVersion(8, 0) && tablespace != GetDatabase()->GetDefaultTablespace())
str += wxT("\nTABLESPACE ") + qtIdent(tablespace);
@ -546,7 +549,7 @@ pgObject *pgIndexBaseFactory::CreateObjects(pgCollection *coll, ctlTree *browser
}
query = wxT("SELECT DISTINCT ON(cls.relname) cls.oid, cls.relname as idxname, indrelid, indkey, indisclustered, indisvalid, indisunique, indisprimary, n.nspname,\n")
wxT(" ") + proname + wxT("tab.relname as tabname, indclass, con.oid AS conoid, CASE contype WHEN 'p' THEN desp.description WHEN 'u' THEN desp.description WHEN 'x' THEN desp.description ELSE des.description END AS description,\n")
wxT(" pg_get_expr(indpred, indrelid") + collection->GetDatabase()->GetPrettyOption() + wxT(") as indconstraint, contype, condeferrable, condeferred, amname\n");
wxT(" pg_get_expr(indpred, indrelid") + collection->GetDatabase()->GetPrettyOption() + wxT(") as indconstraint, contype, condeferrable, condeferred, amname, array_to_string(cls.reloptions, ',') reloptions\n");
if (collection->GetConnection()->BackendMinimumVersion(8, 2))
query += wxT(", substring(array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor \n");
query += wxT(" FROM pg_index idx\n")
@ -599,6 +602,7 @@ pgObject *pgIndexBaseFactory::CreateObjects(pgCollection *coll, ctlTree *browser
index->iSetColumnNumbers(indexes->GetVal(wxT("indkey")));
index->iSetIdxSchema(indexes->GetVal(wxT("nspname")));
index->iSetComment(indexes->GetVal(wxT("description")));
index->iSetRelOptions(indexes->GetVal(wxT("reloptions")));
index->iSetIdxTable(indexes->GetVal(wxT("tabname")));
index->iSetRelTableOid(indexes->GetOid(wxT("indrelid")));
if (collection->GetConnection()->BackendMinimumVersion(7, 4))

View file

@ -492,7 +492,7 @@ void pgObject::ShowDependencies(frmMain *form, ctlListView *Dependencies, const
* END
*/
ShowDependency(GetDatabase(), Dependencies,
wxT("SELECT DISTINCT dep.deptype, dep.refclassid, cl.relkind, ad.adbin, ad.adsrc, \n")
wxT("SELECT DISTINCT dep.deptype, dep.refclassid, cl.relkind, ad.adbin, pg_get_expr(ad.adbin,0) adsrc, \n")
wxT(" CASE WHEN cl.relkind IS NOT NULL THEN cl.relkind || COALESCE(dep.refobjsubid::text, '')\n")
wxT(" WHEN tg.oid IS NOT NULL THEN 'T'::text\n")
wxT(" WHEN ty.oid IS NOT NULL THEN 'y'::text\n")
@ -663,7 +663,7 @@ void pgObject::ShowDependents(frmMain *form, ctlListView *referencedBy, const wx
* END
*/
ShowDependency(GetDatabase(), referencedBy,
wxT("SELECT DISTINCT dep.deptype, dep.classid, cl.relkind, ad.adbin, ad.adsrc, \n")
wxT("SELECT DISTINCT dep.deptype, dep.classid, cl.relkind, ad.adbin, pg_get_expr(ad.adbin,0) adsrc, \n")
wxT(" CASE WHEN cl.relkind IS NOT NULL THEN cl.relkind || COALESCE(dep.objsubid::text, '')\n")
wxT(" WHEN tg.oid IS NOT NULL THEN 'T'::text\n")
wxT(" WHEN ty.oid IS NOT NULL THEN 'y'::text\n")

View file

@ -210,7 +210,7 @@ pgObject *pgPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser
pgSet *tables;
query = wxT("SELECT rel.oid, rel.relname, rel.reltablespace AS spcoid, spc.spcname, pg_get_userbyid(rel.relowner) AS relowner, rel.relacl, rel.relhasoids, ")
query = wxT("SELECT rel.oid, rel.relname, rel.reltablespace AS spcoid, spc.spcname, pg_get_userbyid(rel.relowner) AS relowner, rel.relacl, ")
wxT("rel.relhassubclass, rel.reltuples, des.description, con.conname, con.conkey,\n")
wxT(" EXISTS(select 1 FROM pg_trigger\n")
wxT(" JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n")
@ -290,7 +290,7 @@ pgObject *pgPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser
table->iSetOfType(tables->GetVal(wxT("typname")));
table->iSetComment(tables->GetVal(wxT("description")));
table->iSetUnlogged(tables->GetVal(wxT("relpersistence")) == wxT("u"));
table->iSetHasOids(tables->GetBool(wxT("relhasoids")));
table->iSetHasOids(false);
table->iSetEstimatedRows(tables->GetDouble(wxT("reltuples")) * gp_segments);
table->iSetFillFactor(tables->GetVal(wxT("fillfactor")));
if (collection->GetConnection()->BackendMinimumVersion(8, 4))

View file

@ -1455,7 +1455,7 @@ pgObject *pgTableFactory::CreateObjects(pgCollection *collection, ctlTree *brows
pgSet *tables;
if (collection->GetConnection()->BackendMinimumVersion(8, 0))
{
query = wxT("SELECT rel.oid, rel.relname, rel.reltablespace AS spcoid, spc.spcname, pg_get_userbyid(rel.relowner) AS relowner, rel.relacl, rel.relhasoids, ")
query = wxT("SELECT rel.oid, rel.relname, rel.reltablespace AS spcoid, spc.spcname, pg_get_userbyid(rel.relowner) AS relowner, rel.relacl, ")
wxT("rel.relhassubclass, rel.reltuples, des.description, con.conname, con.conkey,\n")
wxT(" EXISTS(select 1 FROM pg_trigger\n")
wxT(" JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n")
@ -1566,7 +1566,7 @@ pgObject *pgTableFactory::CreateObjects(pgCollection *collection, ctlTree *brows
}
else
{
query = wxT("SELECT rel.oid, rel.relname, pg_get_userbyid(rel.relowner) AS relowner, rel.relacl, rel.relhasoids, ")
query = wxT("SELECT rel.oid, rel.relname, pg_get_userbyid(rel.relowner) AS relowner, rel.relacl, ")
wxT("rel.relhassubclass, rel.reltuples, des.description, con.conname, con.conkey,\n")
wxT(" (select count(*) FROM pg_trigger\n")
wxT(" WHERE tgrelid=rel.oid AND tgisconstraint = FALSE) AS triggercount,\n")
@ -1618,7 +1618,7 @@ pgObject *pgTableFactory::CreateObjects(pgCollection *collection, ctlTree *brows
table->iSetUnlogged(tables->GetVal(wxT("relpersistence")) == wxT("u"));
else
table->iSetUnlogged(false);
table->iSetHasOids(tables->GetBool(wxT("relhasoids")));
table->iSetHasOids(false);
table->iSetEstimatedRows(tables->GetDouble(wxT("reltuples")) * gp_segments);
if (collection->GetConnection()->BackendMinimumVersion(8, 2))
{