On Fri, 2011-07-22 at 23:55 +0100, Thom Brown wrote:
> On 22 July 2011 23:43, Guillaume Lelarge <[email protected]> wrote:
> > Hi,
> >
> > In 9.2, domains and check constraints can be declared not valid. Their
> > validity can be forced later. This patch adds support for this new
> > feature.
> >
> > Comments?
> 
> I can't get the patch to apply as I get several errors.  I'm using
> latest master.
> 

Here is a rebased patch. Sorry for the inconvenience.


-- 
Guillaume
  http://blog.guillaume.lelarge.info
  http://www.dalibo.com
>From 8df46f5a329fa1663b6a37494772603588cf7700 Mon Sep 17 00:00:00 2001
From: Guillaume Lelarge <[email protected]>
Date: Sat, 23 Jul 2011 08:25:52 +0200
Subject: [PATCH] Support for not valid domain and check constraints

In 9.2, domains and check constraints can be declared not valid. Their
validity can be forced later. This patch adds support for this.
---
 pgadmin/dlg/dlgCheck.cpp          |   32 +++++++++++++-
 pgadmin/dlg/dlgDomain.cpp         |   63 ++++++++++++++++++++++++---
 pgadmin/dlg/dlgTable.cpp          |    6 +-
 pgadmin/frm/frmMain.cpp           |    4 ++
 pgadmin/include/dlg/dlgCheck.h    |    2 +
 pgadmin/include/dlg/dlgDomain.h   |    1 +
 pgadmin/include/schema/pgCheck.h  |   28 ++++++++++++
 pgadmin/include/schema/pgDomain.h |   29 +++++++++++-
 pgadmin/schema/pgCheck.cpp        |   88 ++++++++++++++++++++++++++++++++-----
 pgadmin/schema/pgDomain.cpp       |   60 +++++++++++++++++++++++++-
 pgadmin/schema/pgTable.cpp        |    2 +
 pgadmin/ui/dlgCheck.xrc           |   16 ++++++-
 pgadmin/ui/dlgDomain.xrc          |   16 ++++++-
 13 files changed, 320 insertions(+), 27 deletions(-)

diff --git a/pgadmin/dlg/dlgCheck.cpp b/pgadmin/dlg/dlgCheck.cpp
index c388ef9..5306938 100644
--- a/pgadmin/dlg/dlgCheck.cpp
+++ b/pgadmin/dlg/dlgCheck.cpp
@@ -21,10 +21,12 @@
 #include "dlg/dlgCheck.h"
 
 #define txtWhere        CTRL_TEXT("txtWhere")
+#define chkDontValidate CTRL_CHECKBOX("chkDontValidate")
 
 
 BEGIN_EVENT_TABLE(dlgCheck, dlgProperty)
 	EVT_TEXT(XRCID("txtWhere"),                 dlgProperty::OnChange)
+	EVT_CHECKBOX(XRCID("chkDontValidate"),      dlgCheck::OnChangeValidate)
 END_EVENT_TABLE();
 
 
@@ -43,13 +45,16 @@ dlgCheck::dlgCheck(pgaFactory *f, frmMain *frame, pgCheck *node, pgTable *parent
 
 void dlgCheck::CheckChange()
 {
+	bool enable = true;
 	if (check)
 	{
-		EnableOK(txtComment->GetValue() != check->GetComment());
+		enable = txtComment->GetValue() != check->GetComment();
+		if (connection->BackendMinimumVersion(9, 2) && !check->GetValid() && !chkDontValidate->GetValue())
+			enable = true;
+		EnableOK(enable);
 	}
 	else
 	{
-		bool enable = true;
 		txtComment->Enable(!GetName().IsEmpty());
 		CheckValid(enable, !txtWhere->GetValue().IsEmpty(), _("Please specify condition."));
 		EnableOK(enable);
@@ -86,6 +91,12 @@ int dlgCheck::Go(bool modal)
 
 		txtWhere->SetValue(check->GetDefinition());
 		txtWhere->Disable();
+		
+		if (connection->BackendMinimumVersion(9, 2))
+			chkDontValidate->SetValue(!check->GetValid());
+		else
+			chkDontValidate->SetValue(true);
+		chkDontValidate->Enable(connection->BackendMinimumVersion(9, 2) && !check->GetDefinition().IsEmpty() && !check->GetValid());
 	}
 	else
 	{
@@ -96,11 +107,19 @@ int dlgCheck::Go(bool modal)
 			cbClusterSet->Disable();
 			cbClusterSet = 0;
 		}
+		chkDontValidate->Enable(connection->BackendMinimumVersion(9, 2));
 	}
+
 	return dlgProperty::Go(modal);
 }
 
 
+void dlgCheck::OnChangeValidate(wxCommandEvent &ev)
+{
+	CheckChange();
+}
+
+
 wxString dlgCheck::GetSql()
 {
 	wxString sql;
@@ -114,6 +133,12 @@ wxString dlgCheck::GetSql()
 		sql += wxT("\n  CHECK ") + GetDefinition()
 		       + wxT(";\n");
 	}
+	else if (!chkDontValidate->GetValue())
+	{
+		sql = wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier()
+			  + wxT(" VALIDATE CONSTRAINT ") + qtIdent(name) + wxT(";\n");
+	}
+
 	if (!name.IsEmpty())
 		AppendComment(sql, wxT("CONSTRAINT ") + qtIdent(name)
 		              + wxT(" ON ") + table->GetQuotedFullIdentifier(), check);
@@ -127,5 +152,8 @@ wxString dlgCheck::GetDefinition()
 
 	sql = wxT("(") + txtWhere->GetValue() + wxT(")");
 
+	if (chkDontValidate->GetValue())
+		sql += wxT(" NOT VALID");
+
 	return sql;
 }
diff --git a/pgadmin/dlg/dlgDomain.cpp b/pgadmin/dlg/dlgDomain.cpp
index a7e0896..71a5b8d 100644
--- a/pgadmin/dlg/dlgDomain.cpp
+++ b/pgadmin/dlg/dlgDomain.cpp
@@ -28,6 +28,7 @@
 #define txtDefault          CTRL_TEXT("txtDefault")
 #define txtCheck            CTRL_TEXT("txtCheck")
 #define cbCollation         CTRL_COMBOBOX("cbCollation")
+#define chkDontValidate     CTRL_CHECKBOX("chkDontValidate")
 
 BEGIN_EVENT_TABLE(dlgDomain, dlgTypeProperty)
 	EVT_TEXT(XRCID("txtLength"),                    dlgProperty::OnChange)
@@ -37,6 +38,8 @@ BEGIN_EVENT_TABLE(dlgDomain, dlgTypeProperty)
 	EVT_TEXT(XRCID("txLength"),                     dlgProperty::OnChange)
 	EVT_TEXT(XRCID("txtDefault"),                   dlgProperty::OnChange)
 	EVT_CHECKBOX(XRCID("chkNotNull"),               dlgProperty::OnChange)
+	EVT_CHECKBOX(XRCID("chkDontValidate"),          dlgDomain::OnChangeValidate)
+	EVT_TEXT(XRCID("txtCheck"),                     dlgProperty::OnChange)
 END_EVENT_TABLE();
 
 
@@ -84,7 +87,6 @@ int dlgDomain::Go(bool modal)
 
 		txtName->Disable();
 		cbDatatype->Disable();
-		txtCheck->Disable();
 
 		cbCollation->SetValue(domain->GetQuotedCollation());
 		cbCollation->Disable();
@@ -95,6 +97,9 @@ int dlgDomain::Go(bool modal)
 			txtDefault->Disable();
 			chkNotNull->Disable();
 		}
+		
+		if (connection->BackendMinimumVersion(9, 2))
+			chkDontValidate->SetValue(!domain->GetValid());
 	}
 	else
 	{
@@ -126,6 +131,11 @@ int dlgDomain::Go(bool modal)
 			cbCollation->SetSelection(0);
 		}
 	}
+	
+	if (connection->BackendMinimumVersion(9, 2))
+		chkDontValidate->Enable(!domain || (domain && !domain->GetValid()));
+	else
+		chkDontValidate->Enable(false);
 
 	return dlgProperty::Go(modal);
 }
@@ -145,13 +155,18 @@ pgObject *dlgDomain::CreateObject(pgCollection *collection)
 
 void dlgDomain::CheckChange()
 {
+	bool enable;
+
 	if (domain)
 	{
-		EnableOK(txtDefault->GetValue() != domain->GetDefault()
-		         || cbSchema->GetValue() != domain->GetSchema()->GetName()
-		         || chkNotNull->GetValue() != domain->GetNotNull()
-		         || cbOwner->GetValue() != domain->GetOwner()
-		         || txtComment->GetValue() != domain->GetComment());
+		enable = txtDefault->GetValue() != domain->GetDefault()
+ 		         || chkNotNull->GetValue() != domain->GetNotNull()
+		         || txtCheck->GetValue() != domain->GetCheck()
+ 		         || cbOwner->GetValue() != domain->GetOwner()
+		         || txtComment->GetValue() != domain->GetComment();
+		if (connection->BackendMinimumVersion(9, 2) && !domain->GetValid() && !chkDontValidate->GetValue())
+			enable = true;
+		EnableOK(enable);
 	}
 	else
 	{
@@ -189,6 +204,12 @@ void dlgDomain::OnSelChangeTyp(wxCommandEvent &ev)
 }
 
 
+void dlgDomain::OnChangeValidate(wxCommandEvent &ev)
+{
+	CheckChange();
+}
+
+
 wxString dlgDomain::GetSql()
 {
 	wxString sql, name;
@@ -214,6 +235,28 @@ wxString dlgDomain::GetSql()
 			else
 				sql += wxT("\n  SET DEFAULT ") + txtDefault->GetValue() + wxT(";\n");
 		}
+		if (txtCheck->GetValue() != domain->GetCheck())
+		{
+			if (!domain->GetCheck().IsEmpty())
+				sql += wxT("ALTER DOMAIN ") + schema->GetQuotedPrefix() + qtIdent(name)
+					  + wxT(" DROP CONSTRAINT ") + qtIdent(domain->GetCheckConstraintName());
+			
+			if (!txtCheck->GetValue().IsEmpty())
+			{
+				sql += wxT("ALTER DOMAIN ") + schema->GetQuotedPrefix() + qtIdent(name)
+					  + wxT(" ADD ");
+				if (!domain->GetCheck().IsEmpty())
+					sql += wxT("CONSTRAINT ") + qtIdent(domain->GetCheckConstraintName());
+				sql += wxT("\n   CHECK (") + txtCheck->GetValue() + wxT(")");
+				if (chkDontValidate->GetValue())
+					sql += wxT(" NOT VALID");
+			}
+		}
+		if (chkDontValidate->IsEnabled() && !domain->GetValid() && !chkDontValidate->GetValue())
+		{
+			sql += wxT("ALTER DOMAIN ") + schema->GetQuotedPrefix() + qtIdent(name)
+				  + wxT(" VALIDATE CONSTRAINT ") + qtIdent(domain->GetCheckConstraintName()) + wxT(";\n");
+		}
 		AppendOwnerChange(sql, wxT("DOMAIN ") + domain->GetQuotedFullIdentifier());
 		AppendSchemaChange(sql, wxT("DOMAIN ") + domain->GetQuotedFullIdentifier());
 	}
@@ -226,16 +269,24 @@ wxString dlgDomain::GetSql()
 
 		if (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != wxT("pg_catalog.\"default\""))
 			sql += wxT("\n   COLLATE ") + cbCollation->GetValue();
+			
+		if (chkDontValidate->GetValue())
+			sql += wxT(";\nALTER DOMAIN ") + schema->GetQuotedPrefix() + qtIdent(name) + wxT(" ADD ");
 
 		AppendIfFilled(sql, wxT("\n   DEFAULT "), txtDefault->GetValue());
 		if (chkNotNull->GetValue())
 			sql += wxT("\n   NOT NULL");
 		if (!txtCheck->GetValue().IsEmpty())
 			sql += wxT("\n   CHECK (") + txtCheck->GetValue() + wxT(")");
+
+		if (chkDontValidate->GetValue())
+			sql += wxT(" NOT VALID");
+
 		sql += wxT(";\n");
 
 		AppendOwnerNew(sql, wxT("DOMAIN ") + name);
 	}
+
 	AppendComment(sql, wxT("DOMAIN ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), domain);
 
 	return sql;
diff --git a/pgadmin/dlg/dlgTable.cpp b/pgadmin/dlg/dlgTable.cpp
index 746566e..aa76522 100644
--- a/pgadmin/dlg/dlgTable.cpp
+++ b/pgadmin/dlg/dlgTable.cpp
@@ -1291,9 +1291,9 @@ wxString dlgTable::GetSql()
 				needComma = true;
 
 			sql += wxT("\n   ");
-			AppendIfFilled(sql, wxT("CONSTRAINT "), qtIdent(name));
-
-			sql += wxT(" ") + GetItemConstraintType(lstConstraints, pos) + wxT(" ") + definition;
+			if (!name.IsEmpty())
+				sql += wxT("CONSTRAINT ") + qtIdent(name) + wxT(" ");
+			sql += GetItemConstraintType(lstConstraints, pos) + wxT(" ") + definition;
 		}
 
 		if (!typedTable || (typedTable && lstConstraints->GetItemCount() > 0))
diff --git a/pgadmin/frm/frmMain.cpp b/pgadmin/frm/frmMain.cpp
index 809a7ee..77b1b8b 100644
--- a/pgadmin/frm/frmMain.cpp
+++ b/pgadmin/frm/frmMain.cpp
@@ -79,6 +79,8 @@
 #include "slony/slCluster.h"
 #include "slony/slSet.h"
 #include "schema/pgForeignKey.h"
+#include "schema/pgCheck.h"
+#include "schema/pgDomain.h"
 
 
 #if wxDIALOG_UNIT_COMPATIBILITY
@@ -291,6 +293,8 @@ void frmMain::CreateMenus()
 	new disableAllTriggersFactory(menuFactories, toolsMenu, 0);
 	new enableAllTriggersFactory(menuFactories, toolsMenu, 0);
 	new validateForeignKeyFactory(menuFactories, toolsMenu, 0);
+	new validateCheckFactory(menuFactories, toolsMenu, 0);
+	new validateDomainCheckFactory(menuFactories, toolsMenu, 0);
 	toolsMenu->AppendSeparator();
 
 	//--------------------------
diff --git a/pgadmin/include/dlg/dlgCheck.h b/pgadmin/include/dlg/dlgCheck.h
index bfea4a2..e55ca95 100644
--- a/pgadmin/include/dlg/dlgCheck.h
+++ b/pgadmin/include/dlg/dlgCheck.h
@@ -37,6 +37,8 @@ public:
 private:
 	pgCheck *check;
 	pgTable *table;
+	
+	void OnChangeValidate(wxCommandEvent &ev);
 
 	DECLARE_EVENT_TABLE()
 };
diff --git a/pgadmin/include/dlg/dlgDomain.h b/pgadmin/include/dlg/dlgDomain.h
index 497e4f7..91f3ff9 100644
--- a/pgadmin/include/dlg/dlgDomain.h
+++ b/pgadmin/include/dlg/dlgDomain.h
@@ -31,6 +31,7 @@ public:
 
 private:
 	void OnSelChangeTyp(wxCommandEvent &ev);
+	void OnChangeValidate(wxCommandEvent &ev);
 
 	pgSchema *schema;
 	pgDomain *domain;
diff --git a/pgadmin/include/schema/pgCheck.h b/pgadmin/include/schema/pgCheck.h
index b73e00b..7f37d1f 100644
--- a/pgadmin/include/schema/pgCheck.h
+++ b/pgadmin/include/schema/pgCheck.h
@@ -24,6 +24,14 @@ public:
 	pgCheckFactory();
 	virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent);
 	virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString);
+
+	int GetClosedIconId()
+	{
+		return closedId;
+	}
+
+protected:
+	int closedId;
 };
 extern pgCheckFactory checkFactory;
 
@@ -34,6 +42,8 @@ public:
 	pgCheck(pgTable *newTable, const wxString &newName = wxT(""));
 	~pgCheck();
 
+	int GetIconId();
+
 	wxString GetTranslatedMessage(int kindOfMessage) const;
 	void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0);
 
@@ -61,6 +71,14 @@ public:
 	{
 		definition = s;
 	}
+	bool GetValid() const
+	{
+		return valid;
+	}
+	void iSetValid(const bool b)
+	{
+		valid = b;
+	}
 
 	bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded);
 	wxString GetConstraint();
@@ -83,9 +101,11 @@ public:
 	{
 		return true;
 	}
+	void Validate(frmMain *form);
 
 private:
 	wxString definition, fkTable, fkSchema;
+	bool valid;
 };
 
 class pgCheckCollection : public pgSchemaObjCollection
@@ -95,4 +115,12 @@ public:
 	wxString GetTranslatedMessage(int kindOfMessage) const;
 };
 
+class validateCheckFactory : public contextActionFactory
+{
+public:
+	validateCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
+	wxWindow *StartDialog(frmMain *form, pgObject *obj);
+	bool CheckEnable(pgObject *obj);
+};
+
 #endif
diff --git a/pgadmin/include/schema/pgDomain.h b/pgadmin/include/schema/pgDomain.h
index 08a8f18..5fc3a02 100644
--- a/pgadmin/include/schema/pgDomain.h
+++ b/pgadmin/include/schema/pgDomain.h
@@ -164,6 +164,22 @@ public:
 	{
 		typmod = l;
 	}
+	bool GetValid() const
+	{
+		return constraintvalid;
+	}
+	void iSetValid(const bool b)
+	{
+		constraintvalid = b;
+	}
+	wxString GetCheckConstraintName() const
+	{
+		return checkconstraintname;
+	}
+	void iSetCheckConstraintName(const wxString &s)
+	{
+		checkconstraintname = s;
+	}
 
 	bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded);
 	wxString GetSql(ctlTree *browser);
@@ -181,12 +197,13 @@ public:
 	{
 		return true;
 	}
+	void Validate(frmMain *form);
 
 private:
-	wxString basetype, quotedBasetype, defaultVal, delimiter, check, collation, quotedCollation;
+	wxString basetype, quotedBasetype, defaultVal, delimiter, check, collation, quotedCollation, checkconstraintname;
 	long length, precision, dimensions;
 	long typlen, typmod;
-	bool notNull, isDup;
+	bool notNull, isDup, constraintvalid;
 	OID basetypeOid, collationOid;
 };
 
@@ -197,4 +214,12 @@ public:
 	wxString GetTranslatedMessage(int kindOfMessage) const;
 };
 
+class validateDomainCheckFactory : public contextActionFactory
+{
+public:
+	validateDomainCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
+	wxWindow *StartDialog(frmMain *form, pgObject *obj);
+	bool CheckEnable(pgObject *obj);
+};
+
 #endif
diff --git a/pgadmin/schema/pgCheck.cpp b/pgadmin/schema/pgCheck.cpp
index b98b618..c5a9cd6 100644
--- a/pgadmin/schema/pgCheck.cpp
+++ b/pgadmin/schema/pgCheck.cpp
@@ -14,6 +14,7 @@
 
 // App headers
 #include "pgAdmin3.h"
+#include "frm/frmMain.h"
 #include "utils/misc.h"
 #include "schema/pgCheck.h"
 
@@ -94,6 +95,15 @@ wxString pgCheck::GetTranslatedMessage(int kindOfMessage) const
 }
 
 
+int pgCheck::GetIconId()
+{
+	if (!GetDatabase()->BackendMinimumVersion(9, 2) || GetValid())
+		return checkFactory.GetIconId();
+	else
+		return checkFactory.GetClosedIconId();
+}
+
+
 bool pgCheck::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded)
 {
 	wxString sql = wxT("ALTER TABLE ") + qtIdent(fkSchema) + wxT(".") + qtIdent(fkTable)
@@ -106,7 +116,12 @@ bool pgCheck::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded)
 
 wxString pgCheck::GetConstraint()
 {
-	return GetQuotedIdentifier() +  wxT(" CHECK (") + GetDefinition() + wxT(")");
+	sql = GetQuotedIdentifier() +  wxT(" CHECK (") + GetDefinition() + wxT(")");
+
+	if (GetDatabase()->BackendMinimumVersion(9, 2) && !GetValid())
+		sql += wxT(" NOT VALID");
+
+	return sql;
 }
 
 
@@ -141,6 +156,8 @@ void pgCheck::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *prope
 		properties->AppendItem(_("Name"), GetName());
 		properties->AppendItem(_("OID"), GetOid());
 		properties->AppendItem(_("Definition"), GetDefinition());
+		if (GetDatabase()->BackendMinimumVersion(9, 2))
+			properties->AppendItem(_("Valid?"), BoolToYesNo(GetValid()));
 		properties->AppendItem(_("Comment"), firstLineOnly(GetComment()));
 	}
 }
@@ -158,21 +175,34 @@ pgObject *pgCheck::Refresh(ctlTree *browser, const wxTreeItemId item)
 }
 
 
+void pgCheck::Validate(frmMain *form)
+{
+	wxString sql = wxT("ALTER TABLE ") + GetQuotedSchemaPrefix(fkSchema) + qtIdent(fkTable)
+	               + wxT("\n  VALIDATE CONSTRAINT ") + GetQuotedIdentifier();
+	GetDatabase()->ExecuteVoid(sql);
+
+	iSetValid(true);
+	UpdateIcon(form->GetBrowser());
+}
+
 
 pgObject *pgCheckFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction)
 {
 	pgTableObjCollection *collection = (pgTableObjCollection *)coll;
 	pgCheck *check = 0;
-	pgSet *checks = collection->GetDatabase()->ExecuteSet(
-	                    wxT("SELECT c.oid, conname, relname, nspname, description,\n")
-	                    wxT("       pg_get_expr(conbin, conrelid") + collection->GetDatabase()->GetPrettyOption() + wxT(") as consrc\n")
-	                    wxT("  FROM pg_constraint c\n")
-	                    wxT("  JOIN pg_class cl ON cl.oid=conrelid\n")
-	                    wxT("  JOIN pg_namespace nl ON nl.oid=relnamespace\n")
-	                    wxT("  LEFT OUTER JOIN pg_description des ON des.objoid=c.oid\n")
-	                    wxT(" WHERE contype = 'c' AND conrelid =  ") + NumToStr(collection->GetOid())
-	                    + restriction + wxT("::oid\n")
-	                    wxT(" ORDER BY conname"));
+	wxString sql = wxT("SELECT c.oid, conname, relname, nspname, description,\n")
+					wxT("       pg_get_expr(conbin, conrelid") + collection->GetDatabase()->GetPrettyOption() + wxT(") as consrc\n");
+	if (collection->GetDatabase()->BackendMinimumVersion(9, 2))
+		sql += wxT(", convalidated");
+	sql += wxT("  FROM pg_constraint c\n")
+					wxT("  JOIN pg_class cl ON cl.oid=conrelid\n")
+					wxT("  JOIN pg_namespace nl ON nl.oid=relnamespace\n")
+					wxT("  LEFT OUTER JOIN pg_description des ON des.objoid=c.oid\n")
+					wxT(" WHERE contype = 'c' AND conrelid =  ") + NumToStr(collection->GetOid())
+					+ restriction + wxT("::oid\n")
+					wxT(" ORDER BY conname");
+
+	pgSet *checks = collection->GetDatabase()->ExecuteSet(sql);
 
 	if (checks)
 	{
@@ -184,6 +214,8 @@ pgObject *pgCheckFactory::CreateObjects(pgCollection *coll, ctlTree *browser, co
 			check->iSetDefinition(checks->GetVal(wxT("consrc")));
 			check->iSetFkTable(checks->GetVal(wxT("relname")));
 			check->iSetFkSchema(checks->GetVal(wxT("nspname")));
+			if (collection->GetDatabase()->BackendMinimumVersion(9, 2))
+				check->iSetValid(checks->GetBool(wxT("convalidated")));
 			check->iSetComment(checks->GetVal(wxT("description")));
 
 			if (browser)
@@ -225,13 +257,47 @@ wxString pgCheckCollection::GetTranslatedMessage(int kindOfMessage) const
 /////////////////////////////
 
 #include "images/check.pngc"
+#include "images/checkbad.pngc"
 
 pgCheckFactory::pgCheckFactory()
 	: pgTableObjFactory(__("Check"), __("New Check..."), __("Create a new Check constraint."), check_png_img)
 {
 	metaType = PGM_CHECK;
 	collectionFactory = &constraintCollectionFactory;
+	closedId = addIcon(checkbad_png_img);
 }
 
 
 pgCheckFactory checkFactory;
+
+validateCheckFactory::validateCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list)
+{
+	mnu->Append(id, _("Validate check constraint"), _("Validate the selected check constraint."));
+}
+
+
+wxWindow *validateCheckFactory::StartDialog(frmMain *form, pgObject *obj)
+{
+	((pgCheck *)obj)->Validate(form);
+	((pgCheck *)obj)->SetDirty();
+
+	wxTreeItemId item = form->GetBrowser()->GetSelection();
+	if (obj == form->GetBrowser()->GetObject(item))
+	{
+		obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties());
+        form->GetSqlPane()->SetReadOnly(false);
+        form->GetSqlPane()->SetText(((pgCheck *)obj)->GetSql(form->GetBrowser()));
+        form->GetSqlPane()->SetReadOnly(true);
+	}
+	form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar());
+
+	return 0;
+}
+
+
+bool validateCheckFactory::CheckEnable(pgObject *obj)
+{
+	return obj && obj->IsCreatedBy(checkFactory) && obj->CanEdit()
+	       && ((pgCheck *)obj)->GetConnection()->BackendMinimumVersion(9, 2)
+	       && !((pgCheck *)obj)->GetValid();
+}
diff --git a/pgadmin/schema/pgDomain.cpp b/pgadmin/schema/pgDomain.cpp
index 2a2bb2f..71a35e1 100644
--- a/pgadmin/schema/pgDomain.cpp
+++ b/pgadmin/schema/pgDomain.cpp
@@ -14,6 +14,7 @@
 
 // App headers
 #include "pgAdmin3.h"
+#include "frm/frmMain.h"
 #include "utils/misc.h"
 #include "schema/pgDomain.h"
 #include "schema/pgDatatype.h"
@@ -132,7 +133,8 @@ void pgDomain::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *prop
 		if (GetConnection()->BackendMinimumVersion(7, 4))
 		{
 			pgSet *set = ExecuteSet(
-			                 wxT("SELECT conname, pg_get_constraintdef(oid) AS consrc FROM pg_constraint WHERE contypid=") + GetOidStr());
+			                 wxT("SELECT conname, convalidated, pg_get_constraintdef(oid) AS consrc FROM pg_constraint WHERE contypid=") + GetOidStr());
+			check = wxEmptyString;
 			if (set)
 			{
 				while (!set->Eof())
@@ -145,6 +147,14 @@ void pgDomain::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *prop
 					if (!conname.StartsWith(wxT("$")))
 						check += wxT("CONSTRAINT ") + qtIdent(conname) + wxT(" ");
 					check += set->GetVal(wxT("consrc"));
+					
+					// there may be more than one constraint
+					// but there is only one check constraint
+					if (!set->GetBool(wxT("convalidated")))
+					{
+						iSetCheckConstraintName(set->GetVal(wxT("conname")));
+						iSetValid(false);
+					}
 
 					set->MoveNext();
 				}
@@ -186,6 +196,17 @@ pgObject *pgDomain::Refresh(ctlTree *browser, const wxTreeItemId item)
 }
 
 
+void pgDomain::Validate(frmMain *form)
+{
+	wxString sql = wxT("ALTER DOMAIN ") + GetQuotedFullIdentifier()
+	               + wxT("\n  VALIDATE CONSTRAINT ") + GetCheckConstraintName();
+	GetDatabase()->ExecuteVoid(sql);
+
+	iSetValid(true);
+	UpdateIcon(form->GetBrowser());
+}
+
+
 ////////////////////////////////////////////////////
 
 
@@ -250,6 +271,10 @@ pgObject *pgDomainFactory::CreateObjects(pgCollection *collection, ctlTree *brow
 			}
 			else
 				domain->iSetCollationOid(0);
+			
+			// we suppose the constraint valid now
+			// this is checked in ShowTreeDetail for each domain
+			domain->iSetValid(true);
 
 			if (browser)
 			{
@@ -312,3 +337,36 @@ pgCollection *pgDomainFactory::CreateCollection(pgObject *obj)
 
 pgDomainFactory domainFactory;
 static pgaCollectionFactory cf(&domainFactory, __("Domains"), domains_png_img);
+
+validateDomainCheckFactory::validateDomainCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list)
+{
+	mnu->Append(id, _("Validate domain check constraint"), _("Validate the selected domain check constraint."));
+}
+
+
+wxWindow *validateDomainCheckFactory::StartDialog(frmMain *form, pgObject *obj)
+{
+	((pgDomain *)obj)->Validate(form);
+	((pgDomain *)obj)->SetDirty();
+
+	wxTreeItemId item = form->GetBrowser()->GetSelection();
+	if (obj == form->GetBrowser()->GetObject(item))
+	{
+		obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties());
+        form->GetSqlPane()->SetReadOnly(false);
+        form->GetSqlPane()->SetText(((pgDomain *)obj)->GetSql(form->GetBrowser()));
+        form->GetSqlPane()->SetReadOnly(true);
+	}
+	form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar());
+
+	return 0;
+}
+
+
+bool validateDomainCheckFactory::CheckEnable(pgObject *obj)
+{
+	return obj && obj->IsCreatedBy(domainFactory) && obj->CanEdit()
+	       && ((pgDomain *)obj)->GetConnection()->BackendMinimumVersion(9, 2)
+	       && !((pgDomain *)obj)->GetValid();
+}
+
diff --git a/pgadmin/schema/pgTable.cpp b/pgadmin/schema/pgTable.cpp
index a08798d..3aab612 100644
--- a/pgadmin/schema/pgTable.cpp
+++ b/pgadmin/schema/pgTable.cpp
@@ -444,6 +444,8 @@ wxString pgTable::GetSql(ctlTree *browser)
 						break;
 					case PGM_CHECK:
 						cols_sql += wxT("(") + ((pgCheck *)data)->GetDefinition() + wxT(")");
+						if (GetDatabase()->BackendMinimumVersion(9, 2) && !((pgCheck *)data)->GetValid())
+							cols_sql += wxT(" NOT VALID");
 						break;
 				}
 			}
diff --git a/pgadmin/ui/dlgCheck.xrc b/pgadmin/ui/dlgCheck.xrc
index d583e77..1c5ece4 100644
--- a/pgadmin/ui/dlgCheck.xrc
+++ b/pgadmin/ui/dlgCheck.xrc
@@ -73,7 +73,7 @@
             <object class="wxPanel" name="pnlDefinition">
               <object class="wxFlexGridSizer">
                 <cols>2</cols>
-                <rows>1</rows>
+                <rows>2</rows>
                 <vgap>5</vgap>
                 <hgap>5</hgap>
                 <growablerows>0</growablerows>
@@ -92,6 +92,20 @@
                   <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL</flag>
                   <border>4</border>
                 </object>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="stDontValidate">
+                    <label>Don't validate</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxCheckBox" name="chkDontValidate">
+                    <label></label>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
                 <flag>wxEXPAND|wxTOP|wxLEFT|wxRIGHT</flag>
               </object>
             </object>
diff --git a/pgadmin/ui/dlgDomain.xrc b/pgadmin/ui/dlgDomain.xrc
index e594ab7..0871a57 100644
--- a/pgadmin/ui/dlgDomain.xrc
+++ b/pgadmin/ui/dlgDomain.xrc
@@ -115,7 +115,7 @@
             <object class="wxPanel" name="pnlDefinition">
               <object class="wxFlexGridSizer">
                 <cols>2</cols>
-                <rows>6</rows>
+                <rows>7</rows>
                 <vgap>5</vgap>
                 <hgap>5</hgap>
                 <growablerows>2</growablerows>
@@ -162,6 +162,20 @@
                   <border>4</border>
                 </object>
                 <object class="sizeritem">
+                  <object class="wxStaticText" name="stDontValidate">
+                    <label>Don't validate</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxCheckBox" name="chkDontValidate">
+                    <label></label>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
                   <object class="wxStaticText" name="stLength">
                     <label>Length</label>
                   </object>
-- 
1.7.6

-- 
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers

Reply via email to