diff --git a/pgadmin/dlg/dlgView.cpp b/pgadmin/dlg/dlgView.cpp index fab920d..58ea53c 100644 --- a/pgadmin/dlg/dlgView.cpp +++ b/pgadmin/dlg/dlgView.cpp @@ -29,11 +29,93 @@ #define txtSqlBox CTRL_SQLBOX("txtSqlBox") #define chkSecurityBarrier CTRL_CHECKBOX("chkSecurityBarrier") +/* AutoVacuum Settings */ +#define nbVaccum CTRL_NOTEBOOK("nbVacuum") +#define chkCustomVac CTRL_CHECKBOX("chkCustomVac") +#define chkVacEnabled CTRL_CHECKBOX("chkVacEnabled") +#define txtBaseVac CTRL_TEXT("txtBaseVac") +#define stBaseVacCurr CTRL_STATIC("stBaseVacCurr") +#define txtBaseAn CTRL_TEXT("txtBaseAn") +#define stBaseAnCurr CTRL_STATIC("stBaseAnCurr") +#define txtFactorVac CTRL_TEXT("txtFactorVac") +#define stFactorVacCurr CTRL_STATIC("stFactorVacCurr") +#define txtFactorAn CTRL_TEXT("txtFactorAn") +#define stFactorAnCurr CTRL_STATIC("stFactorAnCurr") +#define txtVacDelay CTRL_TEXT("txtVacDelay") +#define stVacDelayCurr CTRL_STATIC("stVacDelayCurr") +#define txtVacLimit CTRL_TEXT("txtVacLimit") +#define stVacLimitCurr CTRL_STATIC("stVacLimitCurr") +#define txtFreezeMinAge CTRL_TEXT("txtFreezeMinAge") +#define stFreezeMinAgeCurr CTRL_STATIC("stFreezeMinAgeCurr") +#define txtFreezeMaxAge CTRL_TEXT("txtFreezeMaxAge") +#define stFreezeMaxAgeCurr CTRL_STATIC("stFreezeMaxAgeCurr") +#define txtFreezeTableAge CTRL_TEXT("txtFreezeTableAge") +#define stFreezeTableAgeCurr CTRL_STATIC("stFreezeTableAgeCurr") +/* TOAST TABLE AutoVacuum Settings */ +#define chkCustomToastVac CTRL_CHECKBOX("chkCustomToastVac") +#define chkToastVacEnabled CTRL_CHECKBOX("chkToastVacEnabled") +#define txtBaseToastVac CTRL_TEXT("txtBaseToastVac") +#define stBaseToastVacCurr CTRL_STATIC("stBaseToastVacCurr") +#define txtFactorToastVac CTRL_TEXT("txtFactorToastVac") +#define stFactorToastVacCurr CTRL_STATIC("stFactorToastVacCurr") +#define txtToastVacDelay CTRL_TEXT("txtToastVacDelay") +#define stToastVacDelayCurr CTRL_STATIC("stToastVacDelayCurr") +#define txtToastVacLimit CTRL_TEXT("txtToastVacLimit") +#define stToastVacLimitCurr CTRL_STATIC("stToastVacLimitCurr") +#define txtToastFreezeMinAge CTRL_TEXT("txtToastFreezeMinAge") +#define stToastFreezeMinAgeCurr CTRL_STATIC("stToastFreezeMinAgeCurr") +#define txtToastFreezeMaxAge CTRL_TEXT("txtToastFreezeMaxAge") +#define stToastFreezeMaxAgeCurr CTRL_STATIC("stToastFreezeMaxAgeCurr") +#define txtToastFreezeTableAge CTRL_TEXT("txtToastFreezeTableAge") +#define stToastFreezeTableAgeCurr CTRL_STATIC("stToastFreezeTableAgeCurr") + +/* Materialized view Settings */ +#define stMaterializedView CTRL_STATIC("stMaterializedView") +#define chkMaterializedView CTRL_CHECKBOX("chkMaterializedView") +#define stTableSpace CTRL_STATIC("stTableSpace") +#define cboTablespace CTRL_COMBOBOX("cboTablespace") +#define stFillFactor CTRL_STATIC("stFillFactor") +#define txtFillFactor CTRL_TEXT("txtFillFactor") +#define stMatViewWithData CTRL_STATIC("stMatViewWithData") +#define chkMatViewWithData CTRL_CHECKBOX("chkMatViewWithData") BEGIN_EVENT_TABLE(dlgView, dlgSecurityProperty) EVT_STC_MODIFIED(XRCID("txtSqlBox"), dlgProperty::OnChangeStc) EVT_CHECKBOX(XRCID("chkSecurityBarrier"), dlgProperty::OnChange) + + /* Materialized view setting */ + EVT_CHECKBOX(XRCID("chkMaterializedView"), dlgView::OnCheckMaterializedView) + EVT_TEXT(XRCID("txtFillFactor"), dlgView::OnChangeVacuum) + + EVT_COMBOBOX(XRCID("cboTablespace"), dlgView::OnChangeVacuum) + + EVT_CHECKBOX(XRCID("chkMatViewWithData"), dlgProperty::OnChange) + + /* AutoVacuum Settings */ + EVT_CHECKBOX(XRCID("chkCustomVac"), dlgView::OnChangeVacuum) + EVT_CHECKBOX(XRCID("chkVacEnabled"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseVac"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseAn"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorVac"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorAn"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtVacDelay"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtVacLimit"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeMinAge"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeMaxAge"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeTableAge"), dlgView::OnChangeVacuum) + + /* TOAST TABLE AutoVacuum Settings */ + EVT_CHECKBOX(XRCID("chkCustomToastVac"), dlgView::OnChangeVacuum) + EVT_CHECKBOX(XRCID("chkToastVacEnabled"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseToastVac"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorToastVac"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastVacDelay"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastVacLimit"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeMinAge"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeMaxAge"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeTableAge"), dlgView::OnChangeVacuum) + END_EVENT_TABLE(); @@ -47,6 +129,7 @@ dlgView::dlgView(pgaFactory *f, frmMain *frame, pgView *node, pgSchema *sch) { schema = sch; view = node; + forceSecurityBarrierChanged = false; seclabelPage = new ctlSeclabelPanel(nbNotebook); } @@ -71,6 +154,11 @@ int dlgView::Go(bool modal) chkSecurityBarrier->Enable(connection->BackendMinimumVersion(9, 2)); + if (connection->BackendMinimumVersion(9, 3)) + { + PrepareTablespace(cboTablespace); + } + if (view) { // edit mode @@ -78,10 +166,198 @@ int dlgView::Go(bool modal) oldDefinition = view->GetFormattedDefinition(); txtSqlBox->SetText(oldDefinition); chkSecurityBarrier->SetValue(view->GetSecurityBarrier() == wxT("true")); + + if ((connection->BackendMinimumVersion(9, 3) && view)) + { + // While editing the view, if it is materialized view then only change + if (view->IsMaterializedView(view->GetSchema()->GetName(),view->GetName())) + { + // It is materialied view while editing the view so check the box accordingly + chkMaterializedView->SetValue(true); + + // Disable the security barrie as user is editing the materailized view + chkSecurityBarrier->Disable(); + // It is materialized view not allow user to go to normal view + chkMaterializedView->Disable(); + + if (view->GetTablespaceOid() != 0) + cboTablespace->SetKey(view->GetTablespaceOid()); + + txtFillFactor->SetValue(view->GetFillFactor()); + + if (view->GetIsPopulated().Cmp(wxT("t")) == 0) + chkMatViewWithData->SetValue(true); + else + chkMatViewWithData->SetValue(false); + + settingAutoVacuum = false; + + pgSetIterator avSet(connection, + wxT("SELECT name, setting FROM pg_settings WHERE name like '%vacuum%' ORDER BY name")); + while (avSet.RowsLeft()) + { + wxString name = avSet.GetVal(wxT("name")); + wxString setting = avSet.GetVal(wxT("setting")); + + if (name == wxT("autovacuum_vacuum_cost_delay")) + settingCostDelay = setting; + else if (name == wxT("vacuum_cost_delay")) + { + if (StrToLong(settingCostDelay) < 0) + settingCostDelay = setting; + } + else if (name == wxT("autovacuum_vacuum_cost_limit")) + settingCostLimit = setting; + else if (name == wxT("vacuum_cost_limit")) + { + if (StrToLong(settingCostLimit) < 0) + settingCostLimit = setting; + } + else if (name == wxT("autovacuum_vacuum_scale_factor")) + settingVacFactor = setting; + else if (name == wxT("autovacuum_analyze_scale_factor")) + settingAnlFactor = setting; + else if (name == wxT("autovacuum_vacuum_threshold")) + settingVacBaseThr = setting; + else if (name == wxT("autovacuum_analyze_threshold")) + settingAnlBaseThr = setting; + else if (name == wxT("vacuum_freeze_min_age")) + settingFreezeMinAge = setting; + else if (name == wxT("autovacuum_freeze_max_age")) + settingFreezeMaxAge = setting; + else if (name == wxT("vacuum_freeze_table_age")) + settingFreezeTableAge = setting; + else + settingAutoVacuum = avSet.GetBool(wxT("setting")); + } + + tableVacBaseThr = wxT("-1"); + tableAnlBaseThr = wxT("-1"); + tableCostDelay = wxT("-1"); + tableCostLimit = wxT("-1"); + tableFreezeMinAge = wxT("-1"); + tableFreezeMaxAge = wxT("-1"); + tableVacFactor = wxT("-1"); + tableAnlFactor = wxT("-1"); + tableFreezeTableAge = wxT("-1"); + + toastTableVacBaseThr = wxT("-1"); + toastTableCostDelay = wxT("-1"); + toastTableCostLimit = wxT("-1"); + toastTableFreezeMinAge = wxT("-1"); + toastTableFreezeMaxAge = wxT("-1"); + toastTableVacFactor = wxT("-1"); + toastTableFreezeTableAge = wxT("-1"); + + toastTableHasVacuum = false; + toastTableVacEnabled = false; + + if (view) + { + if (view->GetAutoVacuumEnabled() == 2) + tableVacEnabled = settingAutoVacuum; + else + tableVacEnabled = view->GetAutoVacuumEnabled() == 1; + if (!view->GetAutoVacuumVacuumThreshold().IsEmpty()) + tableVacBaseThr = view->GetAutoVacuumVacuumThreshold(); + if (!view->GetAutoVacuumAnalyzeThreshold().IsEmpty()) + tableAnlBaseThr = view->GetAutoVacuumAnalyzeThreshold(); + if (!view->GetAutoVacuumVacuumScaleFactor().IsEmpty()) + tableVacFactor = view->GetAutoVacuumVacuumScaleFactor(); + if (!view->GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + tableAnlFactor = view->GetAutoVacuumAnalyzeScaleFactor(); + if (!view->GetAutoVacuumVacuumCostDelay().IsEmpty()) + tableCostDelay = view->GetAutoVacuumVacuumCostDelay(); + if (!view->GetAutoVacuumVacuumCostLimit().IsEmpty()) + tableCostLimit = view->GetAutoVacuumVacuumCostLimit(); + if (!view->GetAutoVacuumFreezeMinAge().IsEmpty()) + tableFreezeMinAge = view->GetAutoVacuumFreezeMinAge(); + if (!view->GetAutoVacuumFreezeMaxAge().IsEmpty()) + tableFreezeMaxAge = view->GetAutoVacuumFreezeMaxAge(); + if (!view->GetAutoVacuumFreezeTableAge().IsEmpty()) + tableFreezeTableAge = view->GetAutoVacuumFreezeTableAge(); + + hasVacuum = view->GetCustomAutoVacuumEnabled(); + chkVacEnabled->SetValue(hasVacuum ? tableVacEnabled : settingAutoVacuum); + + toastTableVacEnabled = false; + + if (!view->GetHasToastTable()) + { + nbVaccum->GetPage(1)->Enable(false); + } + else + { + toastTableHasVacuum = view->GetToastCustomAutoVacuumEnabled(); + if (toastTableHasVacuum) + { + if (view->GetToastAutoVacuumEnabled() == 2) + toastTableVacEnabled = settingAutoVacuum; + else + toastTableVacEnabled = view->GetToastAutoVacuumEnabled() == 1; + if (!view->GetToastAutoVacuumVacuumThreshold().IsEmpty()) + toastTableVacBaseThr = view->GetToastAutoVacuumVacuumThreshold(); + if (!view->GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + toastTableVacFactor = view->GetToastAutoVacuumVacuumScaleFactor(); + if (!view->GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + toastTableCostDelay = view->GetToastAutoVacuumVacuumCostDelay(); + if (!view->GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + toastTableCostLimit = view->GetToastAutoVacuumVacuumCostLimit(); + if (!view->GetToastAutoVacuumFreezeMinAge().IsEmpty()) + toastTableFreezeMinAge = view->GetToastAutoVacuumFreezeMinAge(); + if (!view->GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + toastTableFreezeMaxAge = view->GetToastAutoVacuumFreezeMaxAge(); + if (!view->GetToastAutoVacuumFreezeTableAge().IsEmpty()) + toastTableFreezeTableAge = view->GetToastAutoVacuumFreezeTableAge(); + } + chkToastVacEnabled->SetValue(toastTableHasVacuum ? toastTableVacEnabled : settingAutoVacuum); + } + } + else + { + hasVacuum = false; + chkVacEnabled->SetValue(settingAutoVacuum); + } + + txtBaseVac->SetValue(tableVacBaseThr); + txtBaseAn->SetValue(tableAnlBaseThr); + txtFactorVac->SetValue(tableVacFactor); + txtFactorAn->SetValue(tableAnlFactor); + txtVacDelay->SetValue(tableCostDelay); + txtVacLimit->SetValue(tableCostLimit); + txtFreezeMinAge->SetValue(tableFreezeMinAge); + txtFreezeMaxAge->SetValue(tableFreezeMaxAge); + + txtFreezeTableAge->SetValue(tableFreezeTableAge); + txtBaseToastVac->SetValue(toastTableVacBaseThr); + txtFactorToastVac->SetValue(toastTableVacFactor); + txtToastVacDelay->SetValue(toastTableCostDelay); + txtToastVacLimit->SetValue(toastTableCostLimit); + txtToastFreezeMinAge->SetValue(toastTableFreezeMinAge); + txtToastFreezeMaxAge->SetValue(toastTableFreezeMaxAge); + txtToastFreezeTableAge->SetValue(toastTableFreezeTableAge); + + chkCustomToastVac->SetValue(toastTableHasVacuum); + chkToastVacEnabled->SetValue(toastTableHasVacuum ? toastTableVacEnabled : settingAutoVacuum); + + chkCustomVac->SetValue(hasVacuum); + wxCommandEvent ev; + OnChangeVacuum(ev); + } + else + { + // It is not materialized view so disabling all the controls + DisableMaterializedView(); + } + } } else { // create mode + cboTablespace->Insert(_(""), 0, (void *)0); + cboTablespace->SetSelection(0); + wxCommandEvent ev; + OnChangeVacuum(ev); } // Find, and disable the RULE ACL option if we're 8.2 @@ -115,6 +391,11 @@ void dlgView::CheckChange() CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); CheckValid(enable, txtSqlBox->GetText().Trim(true).Trim(false).Length() > 0 , _("Please enter function definition.")); + if (!connection->BackendMinimumVersion(9, 3)) + { + DisableMaterializedView(); + } + if(enable) { if (view) @@ -124,6 +405,11 @@ void dlgView::CheckChange() || cbSchema->GetValue() != view->GetSchema()->GetName() || name != view->GetName(); + if (connection->BackendMinimumVersion(9, 3)) + { + enable = !GetSql().IsEmpty(); + } + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); @@ -151,6 +437,7 @@ wxString dlgView::GetSql() { wxString sql; wxString name; + bool editQuery = false; if (view) { @@ -160,13 +447,39 @@ wxString dlgView::GetSql() if (name != view->GetName()) { if (connection->BackendMinimumVersion(8, 3)) - AppendNameChange(sql, wxT("VIEW ") + view->GetQuotedFullIdentifier()); + { + if (connection->BackendMinimumVersion(9, 3)) + { + if (view->IsMaterializedView(view->GetSchema()->GetName(),view->GetName())) + { + AppendNameChange(sql, wxT("MATERIALIZED VIEW ") + view->GetQuotedFullIdentifier()); + editQuery = true; + } + else + AppendNameChange(sql, wxT("VIEW ") + view->GetQuotedFullIdentifier()); + } + else + AppendNameChange(sql, wxT("VIEW ") + view->GetQuotedFullIdentifier()); + } else AppendNameChange(sql, wxT("TABLE ") + view->GetQuotedFullIdentifier()); } if (connection->BackendMinimumVersion(8, 4) && cbSchema->GetName() != view->GetSchema()->GetName()) - AppendSchemaChange(sql, wxT("VIEW " + qtIdent(view->GetSchema()->GetName()) + wxT(".") + qtIdent(name))); + { + if (connection->BackendMinimumVersion(9, 3)) + { + if (view->IsMaterializedView(view->GetSchema()->GetName(),view->GetName())) + { + AppendSchemaChange(sql, wxT("MATERIALIZED VIEW " + qtIdent(view->GetSchema()->GetName()) + wxT(".") + qtIdent(name))); + editQuery = true; + } + else + AppendSchemaChange(sql, wxT("VIEW " + qtIdent(view->GetSchema()->GetName()) + wxT(".") + qtIdent(name))); + } + else + AppendSchemaChange(sql, wxT("VIEW " + qtIdent(view->GetSchema()->GetName()) + wxT(".") + qtIdent(name))); + } else AppendSchemaChange(sql, wxT("TABLE " + qtIdent(view->GetSchema()->GetName()) + wxT(".") + qtIdent(name))); } @@ -175,14 +488,217 @@ wxString dlgView::GetSql() { name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); - sql += wxT("CREATE OR REPLACE VIEW ") + name; + if (editQuery) + { + // Delete the materialized view query + sql += wxT("DROP MATERIALIZED VIEW ") + name + wxT(";"); + } + + // Check if user creates the materialized view + if (!chkMaterializedView->GetValue()) + sql += wxT("CREATE OR REPLACE VIEW ") + name; + else + sql += wxT("CREATE MATERIALIZED VIEW ") + name; if (connection->BackendMinimumVersion(9, 2) && chkSecurityBarrier->GetValue()) sql += wxT(" WITH (security_barrier=true)"); - sql += wxT(" AS\n") - + txtSqlBox->GetText().Trim(true).Trim(false) - + wxT(";\n"); + // Add the parameter of tablespace and storage parameter to create the materilized view + if (connection->BackendMinimumVersion(9, 3) && chkMaterializedView->GetValue()) + { + if (txtFillFactor->GetValue().Trim().Length() > 0 || chkVacEnabled->GetValue() == true || chkToastVacEnabled->GetValue() == true) + { + bool fillFactorFlag,toastTableFlag; + fillFactorFlag = false; + toastTableFlag = false; + + sql += wxT("\nWITH ("); + + if (txtFillFactor->GetValue().Trim().Length() > 0) + { + sql += wxT("\n FILLFACTOR = ") + txtFillFactor->GetValue(); + fillFactorFlag = true; + } + + if (connection->BackendMinimumVersion(9, 3) && chkCustomVac->GetValue()) + { + bool valChanged = false; + wxString newVal; + wxString resetStr; + + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_enabled"), BoolToStr(chkVacEnabled->GetValue())); + + if (!fillFactorFlag) + { + int position = sql.Find(',',true); + if (position != wxNOT_FOUND) + sql.Remove(position,1); + toastTableFlag = true; + } + + newVal = AppendNum(valChanged, txtBaseVac, tableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtBaseAn, tableAnlBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_analyze_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorVac, tableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorAn, tableAnlFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_analyze_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtVacDelay, tableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtVacLimit, tableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMinAge, tableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMaxAge, tableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeTableAge, tableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_table_age"), newVal); + } + } + if (connection->BackendMinimumVersion(9, 3) && chkCustomToastVac->GetValue()) + { + bool valChanged = false; + wxString newVal; + wxString resetStr; + + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_enabled"), BoolToStr(chkToastVacEnabled->GetValue())); + + if (!fillFactorFlag && !toastTableFlag) + { + int position = sql.Find(',',true); + if (position != wxNOT_FOUND) + sql.Remove(position,1); + } + + newVal = AppendNum(valChanged, txtBaseToastVac, toastTableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorToastVac, toastTableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacDelay, toastTableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacLimit, toastTableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMinAge, toastTableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMaxAge, toastTableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeTableAge, toastTableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_table_age"), newVal); + } + } + + sql += wxT("\n)\n"); + } + + if (cboTablespace->GetCurrentSelection() > 0 && cboTablespace->GetOIDKey() > 0) + sql += wxT("\nTABLESPACE ") + qtIdent(cboTablespace->GetValue()); + + wxString sqlDefinition; + bool tmpLoopFlag = true; + sqlDefinition = txtSqlBox->GetText().Trim(true).Trim(false); + + // Remove semicolon from the end of the string + while(tmpLoopFlag) + { + int length = sqlDefinition.Len(); + int position = sqlDefinition.Find(';',true); + if ((position != wxNOT_FOUND) && (position = (length - 1))) + sqlDefinition.Remove(position,1); + else + tmpLoopFlag = false; + } + + sql += wxT(" AS\n") + + sqlDefinition; + + if (chkMatViewWithData->GetValue()) + sql += wxT("\n WITH DATA;\n"); + else + sql += wxT("\n WITH NO DATA;\n"); + } + else + { + sql += wxT(" AS\n") + + txtSqlBox->GetText().Trim(true).Trim(false) + + wxT(";\n"); + } } else if (view) { @@ -193,6 +709,266 @@ wxString dlgView::GetSql() else if (!chkSecurityBarrier->GetValue() && view->GetSecurityBarrier() == wxT("true")) sql += wxT("ALTER VIEW ") + name + wxT("\n SET (security_barrier=false);\n"); } + + if (connection->BackendMinimumVersion(9, 3) && chkMaterializedView->GetValue()) + { + if (txtFillFactor->GetValue() != view->GetFillFactor()) + { + // If fill factor value get changed then set the new value + if (txtFillFactor->GetValue().Trim().Length() > 0) + { + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT("\n SET (FILLFACTOR=") + + txtFillFactor->GetValue() + wxT(");\n"); + } + else + { + // If fill factor value get changed and value is not blank then do the reset + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT(" RESET(\n") + wxT(" FILLFACTOR\n") + wxT(");\n"); + } + } + + bool isPopulatedFlag = false; + + if (view->GetIsPopulated().Cmp(wxT("t")) == 0) + isPopulatedFlag = true; + + if (chkMatViewWithData->GetValue() != isPopulatedFlag) + { + // If checkbox is checked then set WITH NO DATA + if (isPopulatedFlag) + { + sql += wxT("REFRESH MATERIALIZED VIEW ") + name + + wxT(" WITH NO DATA;\n"); + } + else + { + sql += wxT("REFRESH MATERIALIZED VIEW ") + name + + wxT(" WITH DATA;\n"); + } + } + } + + // Alter the storage parameters if it is materialized view + if (connection->BackendMinimumVersion(9, 3) && chkMaterializedView->GetValue()) + { + if (!chkCustomVac->GetValue()) + { + if (hasVacuum) + { + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT(" RESET(\n") + wxT(" autovacuum_enabled,\n") + wxT(" autovacuum_vacuum_threshold,\n") + wxT(" autovacuum_analyze_threshold,\n") + wxT(" autovacuum_vacuum_scale_factor,\n") + wxT(" autovacuum_analyze_scale_factor,\n") + wxT(" autovacuum_vacuum_cost_delay,\n") + wxT(" autovacuum_vacuum_cost_limit,\n") + wxT(" autovacuum_freeze_min_age,\n") + wxT(" autovacuum_freeze_max_age,\n") + wxT(" autovacuum_freeze_table_age\n") + wxT(");\n"); + } + } + else + { + wxString vacStr; + bool changed = (chkVacEnabled->GetValue() != tableVacEnabled); + + bool valChanged = false; + wxString newVal; + wxString setStr; + wxString resetStr; + + if (changed) + { + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_enabled"), BoolToStr(chkVacEnabled->GetValue())); + } + newVal = AppendNum(valChanged, txtBaseVac, tableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtBaseAn, tableAnlBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_analyze_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorVac, tableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorAn, tableAnlFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_analyze_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtVacDelay, tableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtVacLimit, tableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMinAge, tableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMaxAge, tableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeTableAge, tableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_table_age"), newVal); + } + + if (!setStr.IsEmpty()) + { + vacStr = wxT("ALTER MATERIALIZED VIEW ") + name + setStr + wxT("\n);\n");; + changed = true; + } + if (!resetStr.IsEmpty()) + { + vacStr += wxT("ALTER MATERIALIZED VIEW ") + name + resetStr + wxT("\n);\n");; + changed = true; + } + if (changed) + sql += vacStr; + } + } + + if (connection->BackendMinimumVersion(9, 3) && chkMaterializedView->GetValue()) + { + if (!chkCustomToastVac->GetValue()) + { + if (toastTableHasVacuum) + { + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT(" RESET(\n") + wxT(" toast.autovacuum_enabled,\n") + wxT(" toast.autovacuum_vacuum_threshold,\n") + wxT(" toast.autovacuum_analyze_threshold,\n") + wxT(" toast.autovacuum_vacuum_scale_factor,\n") + wxT(" toast.autovacuum_analyze_scale_factor,\n") + wxT(" toast.autovacuum_vacuum_cost_delay,\n") + wxT(" toast.autovacuum_vacuum_cost_limit,\n") + wxT(" toast.autovacuum_freeze_min_age,\n") + wxT(" toast.autovacuum_freeze_max_age,\n") + wxT(" toast.autovacuum_freeze_table_age\n") + wxT(");\n"); + } + } + else + { + wxString vacStr; + bool changed = (chkToastVacEnabled->GetValue() != toastTableVacEnabled); + bool valChanged = false; + wxString newVal; + wxString setStr; + wxString resetStr; + if (changed) + { + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_enabled"), BoolToStr(chkToastVacEnabled->GetValue())); + } + newVal = AppendNum(valChanged, txtBaseToastVac, toastTableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorToastVac, toastTableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacDelay, toastTableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacLimit, toastTableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMinAge, toastTableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMaxAge, toastTableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeTableAge, toastTableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_table_age"), newVal); + } + + if (!setStr.IsEmpty()) + { + vacStr = wxT("ALTER MATERIALIZED VIEW ") + name + setStr + wxT("\n);\n"); + changed = true; + } + if (!resetStr.IsEmpty()) + { + vacStr += wxT("ALTER MATERIALIZED VIEW ") + name + resetStr + wxT("\n);\n"); + changed = true; + } + if (changed) + sql += vacStr; + } + + if (cboTablespace->GetOIDKey() != view->GetTablespaceOid()) + { + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT("\n SET TABLESPACE ") + qtIdent(cboTablespace->GetValue()) + + wxT(";\n"); + } + } } if (view) @@ -223,3 +999,187 @@ void dlgView::OnChange(wxCommandEvent &event) { CheckChange(); } + +void dlgView::OnCheckMaterializedView(wxCommandEvent &ev) +{ + if (chkMaterializedView->GetValue()) + { + // Security barrier and materialized view can not be enabled at the same time so display the message + if (chkSecurityBarrier->GetValue()) + { + wxMessageBox(_("The security barrier option is not applicable to materialized views and has been turned off."), _("View"), wxICON_EXCLAMATION | wxOK, this); + chkSecurityBarrier->SetValue(false); + chkSecurityBarrier->Disable(); + forceSecurityBarrierChanged = true; + } + else + { + chkSecurityBarrier->Disable(); + } + + cboTablespace->Enable(); + txtFillFactor->Enable(); + chkMatViewWithData->Enable(); + chkCustomVac->Enable(); + chkCustomToastVac->Enable(); + } + else + { + if (forceSecurityBarrierChanged) + { + chkSecurityBarrier->Enable(); + chkSecurityBarrier->SetValue(true); + forceSecurityBarrierChanged = false; + } + + DisableStorageParameters(); + chkSecurityBarrier->Enable(); + } +} + +void dlgView::FillAutoVacuumParameters(wxString &setStr, wxString &resetStr, + const wxString ¶meter, const wxString &val) +{ + if (val == wxT("-1")) + { + if (resetStr.IsEmpty()) + resetStr = wxT(" RESET ("); + else + resetStr += wxT(","); + resetStr += wxT("\n ") + parameter; + } + else + { + if (setStr.IsEmpty()) + setStr = wxT(" SET ("); + else + setStr += wxT(","); + setStr += wxT("\n ") + parameter + wxT(" = ") + val; + } +} + +wxString dlgView::AppendNum(bool &changed, wxTextCtrl *ctl, wxString val) +{ + wxString str = ctl->GetValue(); + if (str.IsEmpty() || str.StartsWith(wxT("-"))) + str = wxT("-1"); + + changed |= (str != val); + return str; +} + +void dlgView::OnChangeVacuum(wxCommandEvent &ev) +{ + if (connection->BackendMinimumVersion(9, 3)) + { + bool vacEn = chkCustomVac->GetValue() && chkVacEnabled->GetValue(); + chkCustomVac->Enable(chkMaterializedView->GetValue()); + chkVacEnabled->Enable(chkCustomVac->GetValue()); + cboTablespace->Enable(chkMaterializedView->GetValue()); + txtFillFactor->Enable(chkMaterializedView->GetValue()); + chkMatViewWithData->Enable(chkMaterializedView->GetValue()); + + txtBaseVac->Enable(vacEn); + txtBaseAn->Enable(vacEn); + txtFactorVac->Enable(vacEn); + txtFactorAn->Enable(vacEn); + txtVacDelay->Enable(vacEn); + txtVacLimit->Enable(vacEn); + txtFreezeMinAge->Enable(vacEn); + txtFreezeMaxAge->Enable(vacEn); + + stBaseVacCurr->SetLabel(tableVacBaseThr == wxT("-1") ? settingVacBaseThr : tableVacBaseThr); + stBaseAnCurr->SetLabel(tableAnlBaseThr == wxT("-1") ? settingAnlBaseThr : tableAnlBaseThr); + stFactorVacCurr->SetLabel(tableVacFactor == wxT("-1") ? settingVacFactor : tableVacFactor); + stFactorAnCurr->SetLabel(tableAnlFactor == wxT("-1") ? settingAnlFactor : tableAnlFactor); + stVacDelayCurr->SetLabel(tableCostDelay == wxT("-1") ? settingCostDelay : tableCostDelay); + stVacLimitCurr->SetLabel(tableCostLimit == wxT("-1") ? settingCostLimit : tableCostLimit); + + stFreezeMinAgeCurr->SetLabel(tableFreezeMinAge == wxT("-1") ? settingFreezeMinAge : tableFreezeMinAge); + stFreezeMaxAgeCurr->SetLabel(tableFreezeMaxAge == wxT("-1") ? settingFreezeMaxAge : tableFreezeMaxAge); + + txtFreezeTableAge->Enable(vacEn); + stFreezeTableAgeCurr->SetLabel(tableFreezeTableAge == wxT("-1") ? settingFreezeTableAge : tableFreezeTableAge); + /* Toast Table Vacuum Settings */ + bool toastVacEn = chkCustomToastVac->GetValue() && chkToastVacEnabled->GetValue(); + chkCustomToastVac->Enable(chkMaterializedView->GetValue()); + chkToastVacEnabled->Enable(chkCustomToastVac->GetValue()); + + txtBaseToastVac->Enable(toastVacEn); + txtFactorToastVac->Enable(toastVacEn); + txtToastVacDelay->Enable(toastVacEn); + txtToastVacLimit->Enable(toastVacEn); + txtToastFreezeMinAge->Enable(toastVacEn); + txtToastFreezeMaxAge->Enable(toastVacEn); + txtToastFreezeTableAge->Enable(toastVacEn); + + stBaseToastVacCurr->SetLabel(toastTableVacBaseThr == wxT("-1") ? settingVacBaseThr : toastTableVacBaseThr); + stFactorToastVacCurr->SetLabel(toastTableVacFactor == wxT("-1") ? settingVacFactor : toastTableVacFactor); + stToastVacDelayCurr->SetLabel(toastTableCostDelay == wxT("-1") ? settingCostDelay : toastTableCostDelay); + stToastVacLimitCurr->SetLabel(toastTableCostLimit == wxT("-1") ? settingCostLimit : toastTableCostLimit); + stToastFreezeMinAgeCurr->SetLabel(toastTableFreezeMinAge == wxT("-1") ? settingFreezeMinAge : toastTableFreezeMinAge); + stToastFreezeMaxAgeCurr->SetLabel(toastTableFreezeMaxAge == wxT("-1") ? settingFreezeMaxAge : toastTableFreezeMaxAge); + txtToastFreezeTableAge->Enable(toastVacEn); + stToastFreezeTableAgeCurr->SetLabel(toastTableFreezeTableAge == wxT("-1") ? settingFreezeTableAge : toastTableFreezeTableAge); + } + OnChange(ev); +} + +void dlgView::DisableMaterializedView() +{ + chkMaterializedView->Disable(); + cboTablespace->Disable(); + txtFillFactor->Disable(); + chkMatViewWithData->Disable(); + + chkCustomVac->Disable(); + chkVacEnabled->Disable(); + txtBaseVac->Disable(); + txtBaseAn->Disable(); + txtFactorVac->Disable(); + txtFactorAn->Disable(); + txtVacDelay->Disable(); + txtVacLimit->Disable(); + txtFreezeMinAge->Disable(); + txtFreezeMaxAge->Disable(); + txtFreezeTableAge->Disable(); + + chkToastVacEnabled->Disable(); + chkCustomToastVac->Disable(); + txtBaseToastVac->Disable(); + txtFactorToastVac->Disable(); + txtToastVacDelay->Disable(); + txtToastVacLimit->Disable(); + txtToastFreezeMinAge->Disable(); + txtToastFreezeMaxAge->Disable(); + txtToastFreezeTableAge->Disable(); +} + +void dlgView::DisableStorageParameters() +{ + cboTablespace->Disable(); + txtFillFactor->Disable(); + chkMatViewWithData->Disable(); + + chkCustomVac->Disable(); + chkVacEnabled->Disable(); + txtBaseVac->Disable(); + txtBaseAn->Disable(); + txtFactorVac->Disable(); + txtFactorAn->Disable(); + txtVacDelay->Disable(); + txtVacLimit->Disable(); + txtFreezeMinAge->Disable(); + txtFreezeMaxAge->Disable(); + txtFreezeTableAge->Disable(); + + chkToastVacEnabled->Disable(); + chkCustomToastVac->Disable(); + txtBaseToastVac->Disable(); + txtFactorToastVac->Disable(); + txtToastVacDelay->Disable(); + txtToastVacLimit->Disable(); + txtToastFreezeMinAge->Disable(); + txtToastFreezeMaxAge->Disable(); + txtToastFreezeTableAge->Disable(); +} diff --git a/pgadmin/include/dlg/dlgView.h b/pgadmin/include/dlg/dlgView.h index e8f580a..48d1a20 100644 --- a/pgadmin/include/dlg/dlgView.h +++ b/pgadmin/include/dlg/dlgView.h @@ -39,14 +39,41 @@ public: private: virtual bool IsUpToDate(); + void OnChangeVacuum(wxCommandEvent &ev); + void OnCheckMaterializedView(wxCommandEvent &ev); + void FillAutoVacuumParameters(wxString &setStr, wxString &resetStr,const wxString ¶meter, const wxString &val); + wxString AppendNum(bool &changed, wxTextCtrl *ctl, wxString val); + void DisableMaterializedView(); + void DisableStorageParameters(); pgSchema *schema; pgView *view; ctlSeclabelPanel *seclabelPage; wxString oldDefinition; + wxTextValidator mviewNumericValidator; void OnChange(wxCommandEvent &event); + bool tableVacEnabled, hasVacuum, settingAutoVacuum; + wxString settingVacBaseThr, settingAnlBaseThr, settingCostDelay, + settingCostLimit, settingFreezeMinAge, settingFreezeMaxAge, + settingFreezeTableAge; + wxString tableVacBaseThr, tableAnlBaseThr, tableCostDelay, + tableCostLimit, tableFreezeMinAge, tableFreezeMaxAge, + tableFreezeTableAge; + wxString settingVacFactor, settingAnlFactor; + wxString tableVacFactor, tableAnlFactor; + + /* Toast Table */ + bool toastTableVacEnabled, toastTableHasVacuum; + wxString toastTableVacBaseThr, + toastTableCostDelay, toastTableCostLimit, + toastTableFreezeMinAge, toastTableFreezeMaxAge, + toastTableFreezeTableAge; + wxString toastTableVacFactor; + + bool forceSecurityBarrierChanged; + DECLARE_EVENT_TABLE() }; diff --git a/pgadmin/include/schema/pgView.h b/pgadmin/include/schema/pgView.h index 28c9511..1da6a55 100644 --- a/pgadmin/include/schema/pgView.h +++ b/pgadmin/include/schema/pgView.h @@ -75,6 +75,23 @@ public: security_barrier = s; } + wxString GetTablespace() const + { + return tablespace; + } + void iSetTablespace(const wxString &newVal) + { + tablespace = newVal; + } + OID GetTablespaceOid() const + { + return tablespaceOid; + } + void iSetTablespaceOid(const OID newVal) + { + tablespaceOid = newVal; + } + wxMenu *GetNewMenu(); wxString GetSql(ctlTree *browser); wxString GetSelectSql(ctlTree *browser); @@ -103,11 +120,230 @@ public: bool IsUpToDate(); + wxString GetFillFactor() + { + return fillFactor; + } + void iSetFillFactor(const wxString &s) + { + fillFactor = s; + } + + wxString GetIsPopulated() + { + return isPopulated; + } + void iSetIsPopulated(const wxString &s) + { + isPopulated = s; + } + + bool GetCustomAutoVacuumEnabled() + { + return !reloptions.IsEmpty(); + } + wxString GetRelOptions() + { + return reloptions; + } + void iSetRelOptions(const wxString &s) + { + reloptions = s; + } + int GetAutoVacuumEnabled() + { + return autovacuum_enabled; + } + void iSetAutoVacuumEnabled(int i) + { + autovacuum_enabled = i; + } + wxString GetAutoVacuumVacuumThreshold() + { + return autovacuum_vacuum_threshold; + } + void iSetAutoVacuumVacuumThreshold(const wxString &s) + { + autovacuum_vacuum_threshold = s; + } + wxString GetAutoVacuumVacuumScaleFactor() + { + return autovacuum_vacuum_scale_factor; + } + void iSetAutoVacuumVacuumScaleFactor(const wxString &s) + { + autovacuum_vacuum_scale_factor = s; + } + wxString GetAutoVacuumAnalyzeThreshold() + { + return autovacuum_analyze_threshold; + } + void iSetAutoVacuumAnalyzeThreshold(const wxString &s) + { + autovacuum_analyze_threshold = s; + } + wxString GetAutoVacuumAnalyzeScaleFactor() + { + return autovacuum_analyze_scale_factor; + } + void iSetAutoVacuumAnalyzeScaleFactor(const wxString &s) + { + autovacuum_analyze_scale_factor = s; + } + wxString GetAutoVacuumVacuumCostDelay() + { + return autovacuum_vacuum_cost_delay; + } + void iSetAutoVacuumVacuumCostDelay(const wxString &s) + { + autovacuum_vacuum_cost_delay = s; + } + wxString GetAutoVacuumVacuumCostLimit() + { + return autovacuum_vacuum_cost_limit; + } + void iSetAutoVacuumVacuumCostLimit(const wxString &s) + { + autovacuum_vacuum_cost_limit = s; + } + wxString GetAutoVacuumFreezeMinAge() + { + return autovacuum_freeze_min_age; + } + void iSetAutoVacuumFreezeMinAge(const wxString &s) + { + autovacuum_freeze_min_age = s; + } + wxString GetAutoVacuumFreezeMaxAge() + { + return autovacuum_freeze_max_age; + } + void iSetAutoVacuumFreezeMaxAge(const wxString &s) + { + autovacuum_freeze_max_age = s; + } + wxString GetAutoVacuumFreezeTableAge() + { + return autovacuum_freeze_table_age; + } + void iSetAutoVacuumFreezeTableAge(const wxString &s) + { + autovacuum_freeze_table_age = s; + } + bool GetHasToastTable() + { + return hasToastTable; + } + void iSetHasToastTable(bool b) + { + hasToastTable = b; + } + + /* TOAST TABLE autovacuum settings */ + bool GetToastCustomAutoVacuumEnabled() + { + return !toast_reloptions.IsEmpty(); + } + wxString GetToastRelOptions() + { + return toast_reloptions; + } + void iSetToastRelOptions(const wxString &s) + { + toast_reloptions = s; + } + int GetToastAutoVacuumEnabled() + { + return toast_autovacuum_enabled; + } + void iSetToastAutoVacuumEnabled(int i) + { + toast_autovacuum_enabled = i; + } + wxString GetToastAutoVacuumVacuumThreshold() + { + return toast_autovacuum_vacuum_threshold; + } + void iSetToastAutoVacuumVacuumThreshold(const wxString &s) + { + toast_autovacuum_vacuum_threshold = s; + } + wxString GetToastAutoVacuumVacuumScaleFactor() + { + return toast_autovacuum_vacuum_scale_factor; + } + void iSetToastAutoVacuumVacuumScaleFactor(const wxString &s) + { + toast_autovacuum_vacuum_scale_factor = s; + } + wxString GetToastAutoVacuumVacuumCostDelay() + { + return toast_autovacuum_vacuum_cost_delay; + } + void iSetToastAutoVacuumVacuumCostDelay(const wxString &s) + { + toast_autovacuum_vacuum_cost_delay = s; + } + wxString GetToastAutoVacuumVacuumCostLimit() + { + return toast_autovacuum_vacuum_cost_limit; + } + void iSetToastAutoVacuumVacuumCostLimit(const wxString &s) + { + toast_autovacuum_vacuum_cost_limit = s; + } + wxString GetToastAutoVacuumFreezeMinAge() + { + return toast_autovacuum_freeze_min_age; + } + void iSetToastAutoVacuumFreezeMinAge(const wxString &s) + { + toast_autovacuum_freeze_min_age = s; + } + wxString GetToastAutoVacuumFreezeMaxAge() + { + return toast_autovacuum_freeze_max_age; + } + void iSetToastAutoVacuumFreezeMaxAge(const wxString &s) + { + toast_autovacuum_freeze_max_age = s; + } + wxString GetToastAutoVacuumFreezeTableAge() + { + return toast_autovacuum_freeze_table_age; + } + void iSetToastAutoVacuumFreezeTableAge(const wxString &s) + { + toast_autovacuum_freeze_table_age = s; + } + + bool IsMaterializedView(wxString schemaName, wxString viewName); + private: wxString GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM); void AppendStuff(wxString &sql, ctlTree *browser, pgaFactory &factory); + bool IsMaterializedView(ctlTree *browser); bool hasInsertRule, hasUpdateRule, hasDeleteRule; wxString security_barrier; + + int autovacuum_enabled, toast_autovacuum_enabled; + wxString reloptions, toast_reloptions; + + wxString fillFactor, autovacuum_vacuum_threshold, + autovacuum_vacuum_scale_factor, autovacuum_analyze_threshold, + autovacuum_analyze_scale_factor, autovacuum_vacuum_cost_delay, + autovacuum_vacuum_cost_limit, autovacuum_freeze_min_age, + autovacuum_freeze_max_age, autovacuum_freeze_table_age; + + wxString toast_fillFactor, toast_autovacuum_vacuum_threshold, + toast_autovacuum_vacuum_scale_factor, toast_autovacuum_vacuum_cost_delay, + toast_autovacuum_vacuum_cost_limit, toast_autovacuum_freeze_min_age, + toast_autovacuum_freeze_max_age, toast_autovacuum_freeze_table_age; + + wxString tablespace,isPopulated; + bool hasToastTable; + OID tablespaceOid; + }; class pgViewCollection : public pgSchemaObjCollection diff --git a/pgadmin/schema/pgView.cpp b/pgadmin/schema/pgView.cpp index d98d5d1..3dafee5 100644 --- a/pgadmin/schema/pgView.cpp +++ b/pgadmin/schema/pgView.cpp @@ -118,7 +118,11 @@ wxMenu *pgView::GetNewMenu() bool pgView::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) { - wxString sql = wxT("DROP VIEW ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (IsMaterializedView(browser)) + sql = wxT("DROP MATERIALIZED VIEW ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + else + sql = wxT("DROP VIEW ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) sql += wxT(" CASCADE"); return GetDatabase()->ExecuteVoid(sql); @@ -129,15 +133,171 @@ wxString pgView::GetSql(ctlTree *browser) { if (sql.IsNull()) { - sql = wxT("-- View: ") + GetQuotedFullIdentifier() + wxT("\n\n") - + wxT("-- DROP VIEW ") + GetQuotedFullIdentifier() + wxT(";") - + wxT("\n\nCREATE OR REPLACE VIEW ") + GetQuotedFullIdentifier(); - if (GetConnection()->BackendMinimumVersion(9, 2) && GetSecurityBarrier().Length() > 0) - sql += wxT(" WITH (security_barrier=") + GetSecurityBarrier() + wxT(")"); - sql += wxT(" AS \n") - + GetFormattedDefinition() - + wxT("\n\n") - + GetOwnerSql(7, 3, wxT("TABLE ") + GetQuotedFullIdentifier()); + bool IsMatViewFlag = false; + if (!IsMaterializedView(browser)) + { + sql = wxT("-- View: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP VIEW ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE OR REPLACE VIEW ") + GetQuotedFullIdentifier(); + + if (GetConnection()->BackendMinimumVersion(9, 2) && GetSecurityBarrier().Length() > 0) + sql += wxT(" WITH (security_barrier=") + GetSecurityBarrier() + wxT(")"); + } + else + { + sql = wxT("-- Materialized View: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP MATERIALIZED VIEW ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE MATERIALIZED VIEW ") + GetQuotedFullIdentifier(); + + IsMatViewFlag = true; + + if (GetConnection()->BackendMinimumVersion(9, 3)) + { + if (GetFillFactor().Length() > 0 || GetAutoVacuumEnabled() == 1 || GetToastAutoVacuumEnabled() == 1) + { + bool tmpFlagTable = false; + bool tmpFlagToastTable = false; + + sql += wxT("\nWITH ("); + if (GetFillFactor().Length() > 0) + sql += wxT("\n FILLFACTOR=") + GetFillFactor(); + else + tmpFlagTable = true; + + if (GetCustomAutoVacuumEnabled()) + { + if (GetAutoVacuumEnabled() == 1) + { + if (tmpFlagTable) + sql += wxT("\n autovacuum_enabled=true"); + else + sql += wxT(",\n autovacuum_enabled=true"); + tmpFlagToastTable = true; + } + else if (GetCustomAutoVacuumEnabled() == 0) + { + sql += wxT(",\n autovacuum_enabled=false"); + } + if (!GetAutoVacuumVacuumThreshold().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_threshold=") + GetAutoVacuumVacuumThreshold(); + } + if (!GetAutoVacuumVacuumScaleFactor().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_scale_factor=") + GetAutoVacuumVacuumScaleFactor(); + } + if (!GetAutoVacuumAnalyzeThreshold().IsEmpty()) + { + sql += wxT(",\n autovacuum_analyze_threshold=") + GetAutoVacuumAnalyzeThreshold(); + } + if (!GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + { + sql += wxT(",\n autovacuum_analyze_scale_factor=") + GetAutoVacuumAnalyzeScaleFactor(); + } + if (!GetAutoVacuumVacuumCostDelay().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_cost_delay=") + GetAutoVacuumVacuumCostDelay(); + } + if (!GetAutoVacuumVacuumCostLimit().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_cost_limit=") + GetAutoVacuumVacuumCostLimit(); + } + if (!GetAutoVacuumFreezeMinAge().IsEmpty()) + { + sql += wxT(",\n autovacuum_freeze_min_age=") + GetAutoVacuumFreezeMinAge(); + } + if (!GetAutoVacuumFreezeMaxAge().IsEmpty()) + { + sql += wxT(",\n autovacuum_freeze_max_age=") + GetAutoVacuumFreezeMaxAge(); + } + if (!GetAutoVacuumFreezeTableAge().IsEmpty()) + { + sql += wxT(",\n autovacuum_freeze_table_age=") + GetAutoVacuumFreezeTableAge(); + } + } + if (GetHasToastTable() && GetToastCustomAutoVacuumEnabled()) + { + if (GetToastAutoVacuumEnabled() == 1) + { + if (tmpFlagTable && !tmpFlagToastTable) + sql += wxT("\n toast.autovacuum_enabled=true"); + else + sql += wxT(",\n toast.autovacuum_enabled=true"); + } + else if (GetToastAutoVacuumEnabled() == 0) + sql += wxT(",\n toast.autovacuum_enabled=false"); + if (!GetToastAutoVacuumVacuumThreshold().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_threshold=") + GetToastAutoVacuumVacuumThreshold(); + } + if (!GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_scale_factor=") + GetToastAutoVacuumVacuumScaleFactor(); + } + if (!GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_cost_delay=") + GetToastAutoVacuumVacuumCostDelay(); + } + if (!GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_cost_limit=") + GetToastAutoVacuumVacuumCostLimit(); + } + if (!GetToastAutoVacuumFreezeMinAge().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_freeze_min_age=") + GetToastAutoVacuumFreezeMinAge(); + } + if (!GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_freeze_max_age=") + GetToastAutoVacuumFreezeMaxAge(); + } + if (!GetToastAutoVacuumFreezeTableAge().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_freeze_table_age=") + GetToastAutoVacuumFreezeTableAge(); + } + } + sql += wxT("\n)"); + } + + if (tablespace != GetDatabase()->GetDefaultTablespace()) + sql += wxT("\nTABLESPACE ") + qtIdent(tablespace); + + wxString isPopulated; + if (GetIsPopulated().Cmp(wxT("t")) == 0) + isPopulated = wxT("WITH DATA;"); + else + isPopulated = wxT("WITH NO DATA;"); + + wxString sqlDefinition; + bool tmpLoopFlag = true; + sqlDefinition = GetFormattedDefinition(); + + // Remove semicolon from the end of the string + while(tmpLoopFlag) + { + int length = sqlDefinition.Len(); + int position = sqlDefinition.Find(';',true); + if ((position != wxNOT_FOUND) && (position = (length - 1))) + sqlDefinition.Remove(position,1); + else + tmpLoopFlag = false; + } + + sql += wxT(" AS \n") + + sqlDefinition + + wxT("\n") + + isPopulated + + wxT("\n\n") + + GetOwnerSql(7, 3, wxT("TABLE ") + GetQuotedFullIdentifier()); + } + } + + if (!IsMatViewFlag) + { + sql += wxT(" AS \n") + + GetFormattedDefinition() + + wxT("\n\n") + + GetOwnerSql(7, 3, wxT("TABLE ") + GetQuotedFullIdentifier()); + } if (GetConnection()->BackendMinimumVersion(8, 2)) sql += GetGrant(wxT("arwdxt"), wxT("TABLE ") + GetQuotedFullIdentifier()); @@ -309,6 +469,71 @@ void pgView::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *proper if (GetConnection()->BackendMinimumVersion(9, 2) && GetSecurityBarrier().Length() > 0) properties->AppendItem(_("Security barrier?"), GetSecurityBarrier()); + if (GetConnection()->BackendMinimumVersion(9, 3)) + properties->AppendYesNoItem(_("Materialized view?"), IsMaterializedView(browser)); + + /* Custom AutoVacuum Settings */ + if (GetConnection()->BackendMinimumVersion(9, 3) && IsMaterializedView(browser)) + { + if (!GetFillFactor().IsEmpty()) + properties->AppendItem(_("Fill factor"), GetFillFactor()); + + if (GetCustomAutoVacuumEnabled()) + { + if (GetAutoVacuumEnabled() != 2) + { + properties->AppendItem(_("Table auto-vacuum enabled?"), GetAutoVacuumEnabled() == 1 ? _("Yes") : _("No")); + } + if (!GetAutoVacuumVacuumThreshold().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM base threshold"), GetAutoVacuumVacuumThreshold()); + if (!GetAutoVacuumVacuumScaleFactor().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM scale factor"), GetAutoVacuumVacuumScaleFactor()); + if (!GetAutoVacuumAnalyzeThreshold().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum ANALYZE base threshold"), GetAutoVacuumAnalyzeThreshold()); + if (!GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum ANALYZE scale factor"), GetAutoVacuumAnalyzeScaleFactor()); + if (!GetAutoVacuumVacuumCostDelay().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM cost delay"), GetAutoVacuumVacuumCostDelay()); + if (!GetAutoVacuumVacuumCostLimit().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM cost limit"), GetAutoVacuumVacuumCostLimit()); + if (!GetAutoVacuumFreezeMinAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE minimum age"), GetAutoVacuumFreezeMinAge()); + if (!GetAutoVacuumFreezeMaxAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE maximum age"), GetAutoVacuumFreezeMaxAge()); + if (!GetAutoVacuumFreezeTableAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE table age"), GetAutoVacuumFreezeTableAge()); + } + + if (GetHasToastTable() && GetToastCustomAutoVacuumEnabled()) + { + if (GetToastAutoVacuumEnabled() != 2) + { + properties->AppendItem(_("Toast auto-vacuum enabled?"), GetToastAutoVacuumEnabled() == 1 ? _("Yes") : _("No")); + } + if (!GetToastAutoVacuumVacuumThreshold().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM base threshold"), GetToastAutoVacuumVacuumThreshold()); + if (!GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM scale factor"), GetToastAutoVacuumVacuumScaleFactor()); + if (!GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM cost delay"), GetToastAutoVacuumVacuumCostDelay()); + if (!GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM cost limit"), GetToastAutoVacuumVacuumCostLimit()); + if (!GetToastAutoVacuumFreezeMinAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE minimum age"), GetToastAutoVacuumFreezeMinAge()); + if (!GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE maximum age"), GetToastAutoVacuumFreezeMaxAge()); + if (!GetToastAutoVacuumFreezeTableAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE table age"), GetToastAutoVacuumFreezeTableAge()); + } + + properties->AppendItem(_("Tablespace"), tablespace); + + if (GetIsPopulated().Cmp(wxT("t")) == 0) + properties->AppendItem(_("With data"), _("Yes")); + else + properties->AppendItem(_("With data"), _("No")); + } + if (!GetLabels().IsEmpty()) { wxArrayString seclabels = GetProviderLabelArray(); @@ -375,6 +600,35 @@ void pgView::AppendStuff(wxString &sql, ctlTree *browser, pgaFactory &factory) sql += tmp; } +bool pgView::IsMaterializedView(ctlTree *browser) +{ + if (this->GetConnection()->BackendMinimumVersion(9, 3)) + { + wxString sql = wxT("SELECT count(*) FROM pg_matviews WHERE matviewname = ") + qtDbString(this->GetQuotedFullIdentifier()) + wxT(" AND schemaname = ") + qtDbString(this->GetSchema()->GetQuotedIdentifier()); + + if (!this->GetDatabase()->GetConnection() || this->GetDatabase()->ExecuteScalar(sql) == wxT("0")) + return false; + else + return true; + } + else + return false; +} + +bool pgView::IsMaterializedView(wxString schemaName, wxString viewName) +{ + if (this->GetConnection()->BackendMinimumVersion(9, 3)) + { + wxString sql = wxT("SELECT count(*) FROM pg_matviews WHERE matviewname = ") + qtDbString(viewName) + wxT(" AND schemaname = ") + qtDbString(schemaName); + + if (!this->GetDatabase()->GetConnection() || this->GetDatabase()->ExecuteScalar(sql) == wxT("0")) + return false; + else + return true; + } + else + return false; +} /////////////////////////////////////////////////// @@ -415,8 +669,19 @@ wxString pgViewCollection::GetTranslatedMessage(int kindOfMessage) const pgObject *pgViewFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) { pgView *view = 0; - wxString sql = wxT("SELECT c.oid, c.xmin, c.relname, pg_get_userbyid(c.relowner) AS viewowner, c.relacl, description, ") - wxT("pg_get_viewdef(c.oid") + collection->GetDatabase()->GetPrettyOption() + wxT(") AS definition"); + wxString sql; + + if (collection->GetDatabase()->BackendMinimumVersion(9, 3)) + { + sql = wxT("SELECT c.oid, c.xmin, c.relname,c.reltablespace AS spcoid,c.relispopulated AS ispopulated,spc.spcname, pg_get_userbyid(c.relowner) AS viewowner, c.relacl, description, ") + wxT("pg_get_viewdef(c.oid") + collection->GetDatabase()->GetPrettyOption() + wxT(") AS definition"); + } + else + { + sql = wxT("SELECT c.oid, c.xmin, c.relname,c.reltablespace AS spcoid,spc.spcname, pg_get_userbyid(c.relowner) AS viewowner, c.relacl, description, ") + wxT("pg_get_viewdef(c.oid") + collection->GetDatabase()->GetPrettyOption() + wxT(") AS definition"); + } + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) { sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=c.oid AND sl1.objsubid=0) AS labels"); @@ -426,13 +691,50 @@ pgObject *pgViewFactory::CreateObjects(pgCollection *collection, ctlTree *browse { sql += wxT(",\nsubstring(array_to_string(c.reloptions, ',') FROM 'security_barrier=([a-z|0-9]*)') AS security_barrier"); } + + if (collection->GetConnection()->BackendMinimumVersion(9, 3)) + sql += wxT(", substring(array_to_string(c.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor \n"); + + if (collection->GetConnection()->BackendMinimumVersion(9, 3)) + { + sql += wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS autovacuum_enabled \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS toast_autovacuum_enabled \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age \n") + wxT(", c.reloptions AS reloptions, tst.reloptions AS toast_reloptions \n") + wxT(", (CASE WHEN c.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable\n"); + } + + sql += wxT("\n FROM pg_class c\n") - wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid and des.objsubid=0 AND des.classoid='pg_class'::regclass)\n") - wxT(" WHERE ((c.relhasrules AND (EXISTS (\n") + wxT(" LEFT OUTER JOIN pg_tablespace spc on spc.oid=c.reltablespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid and des.objsubid=0 AND des.classoid='pg_class'::regclass)\n"); + + // Add the toast table for vacuum parameters. + if (collection->GetConnection()->BackendMinimumVersion(9, 3)) + sql += wxT(" LEFT OUTER JOIN pg_class tst ON tst.oid = c.reltoastrelid\n"); + + sql += wxT(" WHERE ((c.relhasrules AND (EXISTS (\n") wxT(" SELECT r.rulename FROM pg_rewrite r\n") wxT(" WHERE ((r.ev_class = c.oid)\n") wxT(" AND (bpchar(r.ev_type) = '1'::bpchar)) ))) OR (c.relkind = 'v'::char))\n") - wxT(" AND relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n") + wxT(" AND c.relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n") + restriction + wxT(" ORDER BY relname"); @@ -460,6 +762,70 @@ pgObject *pgViewFactory::CreateObjects(pgCollection *collection, ctlTree *browse { view->iSetSecurityBarrier(views->GetVal(wxT("security_barrier"))); } + + if (collection->GetConnection()->BackendMinimumVersion(9, 3)) + { + view->iSetFillFactor(views->GetVal(wxT("fillfactor"))); + + if (views->GetOid(wxT("spcoid")) == 0) + view->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid()); + else + view->iSetTablespaceOid(views->GetOid(wxT("spcoid"))); + + view->iSetRelOptions(views->GetVal(wxT("reloptions"))); + + view->iSetIsPopulated(views->GetVal(wxT("ispopulated"))); + + if (view->GetCustomAutoVacuumEnabled()) + { + if (views->GetVal(wxT("autovacuum_enabled")).IsEmpty()) + view->iSetAutoVacuumEnabled(2); + else if (views->GetBool(wxT("autovacuum_enabled"))) + view->iSetAutoVacuumEnabled(1); + else + view->iSetAutoVacuumEnabled(0); + view->iSetAutoVacuumVacuumThreshold(views->GetVal(wxT("autovacuum_vacuum_threshold"))); + view->iSetAutoVacuumVacuumScaleFactor(views->GetVal(wxT("autovacuum_vacuum_scale_factor"))); + view->iSetAutoVacuumAnalyzeThreshold(views->GetVal(wxT("autovacuum_analyze_threshold"))); + view->iSetAutoVacuumAnalyzeScaleFactor(views->GetVal(wxT("autovacuum_analyze_scale_factor"))); + view->iSetAutoVacuumVacuumCostDelay(views->GetVal(wxT("autovacuum_vacuum_cost_delay"))); + view->iSetAutoVacuumVacuumCostLimit(views->GetVal(wxT("autovacuum_vacuum_cost_limit"))); + view->iSetAutoVacuumFreezeMinAge(views->GetVal(wxT("autovacuum_freeze_min_age"))); + view->iSetAutoVacuumFreezeMaxAge(views->GetVal(wxT("autovacuum_freeze_max_age"))); + view->iSetAutoVacuumFreezeTableAge(views->GetVal(wxT("autovacuum_freeze_table_age"))); + } + + view->iSetHasToastTable(views->GetBool(wxT("hastoasttable"))); + + if (view->GetHasToastTable()) + { + view->iSetToastRelOptions(views->GetVal(wxT("toast_reloptions"))); + + if (view->GetToastCustomAutoVacuumEnabled()) + { + if (views->GetVal(wxT("toast_autovacuum_enabled")).IsEmpty()) + view->iSetToastAutoVacuumEnabled(2); + else if (views->GetBool(wxT("toast_autovacuum_enabled"))) + view->iSetToastAutoVacuumEnabled(1); + else + view->iSetToastAutoVacuumEnabled(0); + + view->iSetToastAutoVacuumVacuumThreshold(views->GetVal(wxT("toast_autovacuum_vacuum_threshold"))); + view->iSetToastAutoVacuumVacuumScaleFactor(views->GetVal(wxT("toast_autovacuum_vacuum_scale_factor"))); + view->iSetToastAutoVacuumVacuumCostDelay(views->GetVal(wxT("toast_autovacuum_vacuum_cost_delay"))); + view->iSetToastAutoVacuumVacuumCostLimit(views->GetVal(wxT("toast_autovacuum_vacuum_cost_limit"))); + view->iSetToastAutoVacuumFreezeMinAge(views->GetVal(wxT("toast_autovacuum_freeze_min_age"))); + view->iSetToastAutoVacuumFreezeMaxAge(views->GetVal(wxT("toast_autovacuum_freeze_max_age"))); + view->iSetToastAutoVacuumFreezeTableAge(views->GetVal(wxT("toast_autovacuum_freeze_table_age"))); + } + } + + if (views->GetVal(wxT("spcname")) == wxEmptyString) + view->iSetTablespace(collection->GetDatabase()->GetTablespace()); + else + view->iSetTablespace(views->GetVal(wxT("spcname"))); + } + if (browser) { collection->AppendBrowserItem(browser, view); diff --git a/pgadmin/ui/dlgView.xrc b/pgadmin/ui/dlgView.xrc index bb83c2d..5e4ed70 100644 --- a/pgadmin/ui/dlgView.xrc +++ b/pgadmin/ui/dlgView.xrc @@ -63,8 +63,8 @@ 4 - - + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT 4 @@ -150,6 +150,517 @@ + + + + + 1 + + + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + 2 + 1 + 1 + 1 + + + + + 0 + + + + + 2 + 3 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + 4 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + 3 + + + + + + + + 3 + 4 + 4 + 1 + + 3,3d + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + + + + 3 + 4 + 4 + 1 + + 3,3d + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + 5 + 5 + 0 + 1 + + + wxALL|wxGROW|wxALIGN_CENTRE 3 @@ -195,4 +706,4 @@ - + \ No newline at end of file